Implement Export feature for V1 conversations with comprehensive unit tests#12030
Implement Export feature for V1 conversations with comprehensive unit tests#12030
Conversation
- Add 5 comprehensive test methods covering success, error, and edge cases - Test pagination handling with iterate function usage - Test ZIP file creation and content validation - Test error handling for missing conversations - Test empty events scenario and large pagination - Verify model_dump_json() usage and service interactions - All tests pass with proper mocking and assertions Co-authored-by: openhands <openhands@all-hands.dev>
… menu - Add onDownloadTrajectory prop to ConversationNameContextMenu component - Implement handleDownloadTrajectory in useConversationNameContextMenu hook - Add Download Trajectory menu item for V1 conversations only - Update divider logic to show separators for V1 conversations with download options - Pass onDownloadTrajectory handler from conversation-name.tsx - Remove showOptions condition from conversation card actions for Download Trajectory - Ensure Download Trajectory appears in both conversation card and conversation name menus Co-authored-by: openhands <openhands@all-hands.dev>
…ad Trajectory' - Replace BUTTON$DOWNLOAD_TRAJECTORY with BUTTON$EXPORT_CONVERSATION in all menu items - Remove duplicate BUTTON$DOWNLOAD_TRAJECTORY key from translation files - Both V0 and V1 conversation export features now use the same user-friendly 'Export Conversation' label - Maintain separate functionality: V0 uses getTrajectory API, V1 uses downloadTrajectory API - Clean up i18n files to remove unused translation keys Co-authored-by: openhands <openhands@all-hands.dev>
5c33f00 to
a9a5375
Compare
- Remove console.error statement (no-console rule) - Fix prettier formatting for shouldShowDownloadConversation indentation - All lint checks now pass for the conversation export feature Co-authored-by: openhands <openhands@all-hands.dev>
…om/OpenHands/OpenHands into add-download-trajectory-unit-tests
|
question: I have verified the pull request locally, and it functions correctly for both v0 and v1. On the conversation page for both versions, the Export Conversation option is available. However, there is an inconsistency in behavior within the conversation panel UI when hovering over the menu icon:
This discrepancy may lead to user confusion. Please refer to the video below for additional details. Thank you! 🙏 Screen.Recording.2025-12-16.at.19.05.04.mov |
|
question: In v0, exporting a conversation results in a file name with the format trajectory-{conversation_id}. In v1, the exported file name follows the format conversation_{conversation_id}. Should we align v1 with v0 to ensure consistency? |
I actually think we should steer away from the term "trajectory", and just call it "Download Conversation". I did not update the label in the UI yet for consistency. |
|
Looks like there are a few issues preventing this PR from being merged!
If you'd like me to help, just leave a comment, like Feel free to include any additional details that might help me get this PR into a better state. You can manage your notification settings |
…onversationService The LiveStatusAppConversationService dataclass now requires an event_service field, but several tests were not updated to provide this field when instantiating the service. - Added event_service=MagicMock() to test_delete_v1_conversation_with_sub_conversations - Added event_service=MagicMock() to test_delete_v1_conversation_with_no_sub_conversations - Added event_service=MagicMock() to test_delete_v1_conversation_sub_conversation_deletion_error - Added event_service=Mock() to test_experiment_manager_called_with_correct_parameters_in_context__noop_pass_through Co-authored-by: openhands <openhands@all-hands.dev>
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||||||||||||||
Summary of PR
This PR implements the complete "Download Trajectory" feature for V1 conversations, allowing users to download conversation events and metadata as a ZIP file. The implementation includes both backend API endpoints and frontend UI components, along with comprehensive unit tests.
Backend Implementation:
New API Endpoint:
GET /api/v1/conversations/{conversation_id}/download-trajectory- Downloads conversation as ZIP filemeta.json) and all events as individual JSON filesiteratefunction fromsearch_utils.pyfor efficient event retrievalService Layer Improvements:
LiveStatusAppConversationService.download_conversation_trajectory()methodconversation_info.model_dump_json()for metadata serialization (as requested)iteratefunction for better pagination handlingEventPageobjectsUtility Enhancements:
search_utils.pywith improvediteratefunction for paginationFrontend Implementation:
UI Components:
API Integration:
v1-conversation-service.api.tsInternationalization:
Comprehensive Unit Tests:
5 Test Methods Added:
test_download_conversation_trajectory_success- Tests successful download with multiple paginated events, ZIP file creation, and content validationtest_download_conversation_trajectory_conversation_not_found- Tests error handling when conversation doesn't existtest_download_conversation_trajectory_empty_events- Tests behavior with conversations that have no eventstest_download_conversation_trajectory_large_pagination- Tests pagination with multiple pages (4 pages × 3 events = 12 total)test_download_conversation_trajectory_iterate_function_usage- Tests that the method correctly uses theiteratefunctionTest Features:
Technical Improvements:
iteratefunctionmodel_dump_json()for consistent JSON outputUser Experience:
Change Type
Checklist
Fixes
Implements the "Download Trajectory" feature for V1 conversations as requested, including backend endpoint, frontend UI, and comprehensive unit tests.
Release Notes
New Feature: Added "Download Trajectory" functionality for V1 conversations, allowing users to download conversation events and metadata as a structured ZIP file for analysis and backup purposes.
To run this PR locally, use the following command:
GUI with Docker: