FEAT: Add conversation export button to the GUI chat view - #2259
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a frontend-only “Export conversation” control to the CoPyRIT chat ribbon, enabling users to download the currently displayed conversation as Markdown (readable transcript) or JSON (structured data) entirely client-side.
Changes:
- Added a new
conversationExport.tsutility to serialize conversations (Markdown/JSON), build safe filenames, and trigger Blob-based downloads. - Integrated an Export menu into
ChatWindowwith gating logic so export is only enabled for a stable, viewable conversation. - Added unit tests (serializer + UI) and Playwright E2E coverage for real downloads; updated GUI documentation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/utils/conversationExport.ts | New export/serialization and download helper utilities for Markdown/JSON exports. |
| frontend/src/utils/conversationExport.test.ts | Unit tests covering serialization, filename building, and download helper behavior. |
| frontend/src/components/Chat/ChatWindow.tsx | Adds export menu button to the ribbon and enables/disables it based on conversation state. |
| frontend/src/components/Chat/ChatWindow.test.tsx | Integration tests for export gating and menu-driven export behavior. |
| frontend/e2e/chat.spec.ts | Playwright tests validating actual downloaded bytes for Markdown and JSON exports. |
| doc/gui/0_gui.md | Documents the new Export button and its behavior/security note. |
|
Could you provide some screenshots / video of what the user experience looks like here? :) |
|
@jsong468 Added screenshots! 🙂 One shows the Export button in the ribbon, the other the Markdown/JSON menu. Also pushed fixes for your other notes: the gate now ignores a lone system prompt (+test), and conversationToJson now takes the same exportedAt and writes an exported_at field so it's symmetric with Markdown. Left the activeConversationId fallback as-is |
|
Why is the button greyed out? Makes it look inactive as if it wasn't usable. |
@romanlutz It was the timing of the screenshot! It was transitioning between inactive (light grey) and active (darker grey). Then it appears blue when you hover over the icon and it is active/clickable. Export is intentionally disabled while a message is in flight (so you can't export a half-finished turn), hence it is greyed out in the second prompt. |
Add an Export control to the CoPyRIT chat ribbon that downloads the currently displayed conversation as Markdown or JSON. The file is serialized client-side from the in-view messages (WYSIWYG), including the system prompt shown in the banner; no conversation data is sent to the server. - conversationExport.ts: pure Markdown/JSON serializers, filename builder, and Blob-based download helper - ChatWindow.tsx: Export menu button (Markdown / JSON) enabled only for a viewable, settled conversation - Unit tests plus a real-browser Playwright E2E; GUI docs updated
Refine the conversation export button based on PR review: - Add exported_at (ISO 8601) to the JSON envelope so the timestamp is self-describing and matches the filename, keeping Markdown and JSON consistent. - Disable export for a lone system prompt: the gate now requires at least one non-loading, non-system message. - Rewrite longestBacktickRun as a single-pass scan with no intermediate match array. - Add tests for the JSON timestamp, shared-timestamp agreement, and the system-only disabled state; clarify the GUI docs.
99795fa to
f46eef1
Compare


Description
Adds an Export control to the CoPyRIT chat ribbon that downloads the currently
displayed conversation as Markdown or JSON. Serialization is fully
client-side (from the in-view messages) — no backend changes and no
conversation data leaves the browser.
conversationExport.ts(new): pure Markdown/JSON serializers, timestampedfilename builder, and a Blob-based download helper. Hardened for safety —
dynamically-sized code fences, sanitized filenames, strips non-serializable
Filehandles and in-flight loading placeholders, and revokes the object URL.ChatWindow.tsx: Export menu button (Markdown / JSON) enabled only when aviewable, settled conversation is shown; exports the displayed branch. Uses a
Fluent
Tooltiplabel to match the sibling ribbon buttons.Frontend-only; no Python/API changes.
Tests and Documentation
Tests
(
conversationExport.test.ts).ChatWindowexport menu (gating, format selection,Markdown/JSON output).
actual downloaded Markdown/JSON bytes (
chat.spec.ts).Documentation
doc/gui/0_gui.mdto document the export button and itsbehavior (including the system prompt shown in the banner).
needed.