diff --git a/.openhands/microagents/repo.md b/.openhands/microagents/repo.md new file mode 100644 index 0000000..c0fbdc9 --- /dev/null +++ b/.openhands/microagents/repo.md @@ -0,0 +1,60 @@ +# 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/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 + +### 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 `JsonlViewer` component's Entry Metadata panel to display the same patch files +- The `handleFileEditClick` function in `RunDetails.tsx` updates the artifact content with patch data when a file edit is clicked + +### 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 `JsonlViewer` component's Entry Metadata panel also renders the patch data using the `DiffViewer` component \ No newline at end of file diff --git a/src/components/RunDetails.tsx b/src/components/RunDetails.tsx index cc03998..f11b7dd 100644 --- a/src/components/RunDetails.tsx +++ b/src/components/RunDetails.tsx @@ -134,9 +134,11 @@ const RunDetails: React.FC = ({ 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]); diff --git a/src/components/jsonl-viewer/JsonlViewer.tsx b/src/components/jsonl-viewer/JsonlViewer.tsx index 7825ef5..2c4a143 100644 --- a/src/components/jsonl-viewer/JsonlViewer.tsx +++ b/src/components/jsonl-viewer/JsonlViewer.tsx @@ -5,6 +5,7 @@ import { getNestedValue, formatValueForDisplay } from '../../utils/object-utils' import { TrajectoryItem } from '../../types/share'; import JsonVisualizer from '../json-visualizer/JsonVisualizer'; import { DEFAULT_JSONL_VIEWER_SETTINGS } from '../../config/jsonl-viewer-config'; +import { DiffViewer } from '../diff-viewer'; import { isAgentStateChange, isUserMessage, @@ -356,7 +357,30 @@ const JsonlViewer: React.FC = ({ content }) => {
{currentEntryWithoutHistory ? ( - +
+ {/* Instance Patch Diff Viewer */} + {entries[currentEntryIndex]?.instance?.patch && ( +
+

Instance Patch

+
+ +
+
+ )} + + {/* Git Patch Diff Viewer */} + {entries[currentEntryIndex]?.test_result?.git_patch && ( +
+

Git Patch

+
+ +
+
+ )} + + {/* JSON Visualizer for other metadata */} + +
) : (
No metadata available diff --git a/src/components/timeline/components/EntryMetadataPanel.tsx b/src/components/timeline/components/EntryMetadataPanel.tsx new file mode 100644 index 0000000..85b1893 --- /dev/null +++ b/src/components/timeline/components/EntryMetadataPanel.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { TimelineEntry } from '../types'; +import { DiffViewer } from '../../diff-viewer'; + +interface EntryMetadataPanelProps { + entry: TimelineEntry; +} + +const EntryMetadataPanel: React.FC = ({ entry }) => { + // Check for patch files in the metadata + const instancePatch = entry.metadata?.instance?.patch; + const gitPatch = entry.metadata?.test_result?.git_patch; + + if (!instancePatch && !gitPatch) { + return null; + } + + return ( +
+ {/* Instance Patch Diff Viewer */} + {instancePatch && ( +
+

Instance Patch

+
+ +
+
+ )} + + {/* Git Patch Diff Viewer */} + {gitPatch && ( +
+

Git Patch

+
+ +
+
+ )} +
+ ); +}; + +export default EntryMetadataPanel; \ No newline at end of file diff --git a/src/components/timeline/components/TimelineStep.tsx b/src/components/timeline/components/TimelineStep.tsx index e8b327a..c50b2a8 100644 --- a/src/components/timeline/components/TimelineStep.tsx +++ b/src/components/timeline/components/TimelineStep.tsx @@ -110,6 +110,8 @@ export const TimelineStep: React.FC = memo(({ )}
)} + + {/* Entry metadata is now shown in the right panel */}