Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .openhands/microagents/repo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Trajectory Visualizer Repository Information

## Project Overview
The Trajectory Visualizer is a web application for visualizing OpenHands Resolver execution trajectories. It provides a timeline view of actions and observations during the execution of OpenHands agents.

## Repository Structure
- `/src/components/`: React components
- `/src/components/timeline/`: Timeline visualization components
- `/src/components/timeline/components/`: Timeline subcomponents
- `/src/components/artifacts/`: Artifact details components
- `/src/components/diff-viewer.tsx`: Diff viewer component for file changes
- `/src/components/jsonl-viewer/`: JSONL viewer components
- `/src/components/jsonl-viewer/CollapsableDiffPanel.tsx`: Collapsable panel for displaying diffs
- `/src/components/share/`: Shared components for trajectory visualization
- `/src/services/`: API services
- `/src/utils/`: Utility functions
- `/src/types/`: TypeScript type definitions

## Common Commands
- `npm start`: Start development server
- `npm build`: Build production-ready app
- `npm test`: Run tests

## Code Style Preferences
- React functional components with TypeScript
- Tailwind CSS for styling
- React hooks for state management

## Key Components

### Timeline Components
- `Timeline.tsx`: Main timeline component that renders a list of timeline steps
- `TimelineStep.tsx`: Individual timeline step component
- `TimelineEntry`: Interface for timeline entry data

### JSONL Viewer Components
- `JsonlViewer.tsx`: Component for viewing JSONL files with trajectory data
- `JsonlViewerSettings.tsx`: Settings for the JSONL viewer
- `CollapsableDiffPanel.tsx`: Collapsable panel for displaying diffs above the trajectory

### Artifact Components
- `ArtifactDetails.tsx`: Component for displaying artifact details, including diff views for patches

### Diff Viewer
- `diff-viewer.tsx`: Component for displaying file diffs using `react-diff-viewer-continued`

## Implementation Details

### Diff File View
- The diff viewer is implemented in `/src/components/diff-viewer.tsx`
- It uses `react-diff-viewer-continued` to display file diffs
- The diff viewer is used in two places:
1. In the `ArtifactDetails` component to display `.instance.patch` and `.test_result.git_patch` files
2. In the `CollapsableDiffPanel` component to display the same patch files in a collapsable panel above the trajectory
- The `handleFileEditClick` function in `RunDetails.tsx` updates the artifact content with patch data when a file edit is clicked

### Collapsable Diff Panel
- The `CollapsableDiffPanel` component is a collapsable panel that displays file changes
- It is collapsed by default and can be expanded by clicking on it
- It uses the `parse-diff` library to properly parse git diff format
- It displays the diffs in a more readable format with file names and changes
- It provides more space for displaying diffs compared to the Entry Metadata panel
- It uses helper functions `extractOldContent` and `extractNewContent` to extract old and new content from parsed diffs
- It displays "Groundtruth Patch" instead of "Instance Patch" in the UI (while keeping the field name the same)
- It properly handles the git diff format with the example format:
```
diff --git a/astropy/modeling/separable.py b/astropy/modeling/separable.py
--- a/astropy/modeling/separable.py
+++ b/astropy/modeling/separable.py
@@ -242,7 +242,7 @@ def _cstack(left, right):
cright = _coord_matrix(right, 'right', noutp)
else:
cright = np.zeros((noutp, right.shape[1]))
- cright[-right.shape[0]:, -right.shape[1]:] = 1
+ cright[-right.shape[0]:, -right.shape[1]:] = right

return np.hstack([cleft, right])
```

### Data Flow
1. Timeline entries are loaded from the artifact content
2. When a file edit is clicked, the patch data is extracted from the entry metadata
3. The patch data is added to the artifact content
4. The `ArtifactDetails` component renders the patch data using the `DiffViewer` component
5. The `CollapsableDiffPanel` component renders the patch data using the `DiffViewer` component in a collapsable panel above the trajectory
41 changes: 41 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
"private": true,
"type": "module",
"dependencies": {
"@heroicons/react": "^2.2.0",
"axios": "^1.6.8",
"browser-process-hrtime": "^1.0.0",
"clsx": "^2.1.1",
"diff": "^7.0.0",
"diff-parse": "^0.0.13",
"jszip": "^3.10.1",
"parse-diff": "^0.11.1",
"path-browserify": "^1.0.1",
"react": "^18.2.0",
"react-diff-viewer-continued": "^3.4.0",
Expand Down
8 changes: 5 additions & 3 deletions src/components/RunDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ const RunDetails: React.FC<RunDetailsProps> = ({ owner, repo, run, initialConten
if (timelineEntries && timelineEntries.length > selectedStepIndex) {
const entry = timelineEntries[selectedStepIndex];

// Show file changes in an alert for now
if (entry.path) {
alert(`File: ${entry.path}\n\nChanges are not available in this view. This would typically show a diff of the changes made to the file.`);
// If the entry has a path and metadata with file edit information, we can show it
if (entry.path && entry.metadata) {
// The diff viewer is now shown directly in the timeline entry via the EntryMetadataPanel
// We just need to ensure the entry is selected
setSelectedStepIndex(selectedStepIndex);
}
}
}, [getTimelineEntries, selectedStepIndex]);
Expand Down
33 changes: 32 additions & 1 deletion src/components/artifacts/ArtifactDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { DiffViewer } from '../diff-viewer';

interface Issue {
title: string;
Expand All @@ -14,6 +15,12 @@ interface ArtifactContent {
issue?: Issue;
metrics?: Metrics;
success?: boolean;
instance?: {
patch?: string;
};
test_result?: {
git_patch?: string;
};
}

interface ArtifactDetailsProps {
Expand All @@ -29,8 +36,12 @@ export const ArtifactDetails: React.FC<ArtifactDetailsProps> = ({ content }) =>
);
}

// Check for patch files
const instancePatch = content.instance?.patch;
const gitPatch = content.test_result?.git_patch;

return (
<div className="space-y-2">
<div className="space-y-4">
{content.issue && (
<div className="bg-gray-50/50 dark:bg-gray-700/50 rounded px-2 py-1.5">
<p className="text-xs font-medium text-gray-900 dark:text-white line-clamp-1">{content.issue.title}</p>
Expand All @@ -57,6 +68,26 @@ export const ArtifactDetails: React.FC<ArtifactDetailsProps> = ({ content }) =>
</div>
</div>
)}

{/* Instance Patch Diff Viewer (displayed as Groundtruth Patch) */}
{instancePatch && (
<div className="mt-4">
<h4 className="text-sm font-medium mb-2 text-gray-700 dark:text-gray-300">Groundtruth Patch</h4>
<div className="border border-gray-200 dark:border-gray-700 rounded-md overflow-hidden">
<DiffViewer oldStr="" newStr={instancePatch} splitView={false} />
</div>
</div>
)}

{/* Git Patch Diff Viewer */}
{gitPatch && (
<div className="mt-4">
<h4 className="text-sm font-medium mb-2 text-gray-700 dark:text-gray-300">Git Patch</h4>
<div className="border border-gray-200 dark:border-gray-700 rounded-md overflow-hidden">
<DiffViewer oldStr="" newStr={gitPatch} splitView={false} />
</div>
</div>
)}
</div>
);
};
Expand Down
Loading