Repository navigation
ADFA-6247 | Export and import chats as .txt - #110
Conversation
Chat row menu: Rename, Export, Delete; Export saves via the system file picker and is dimmed for an empty chat. The + menu adds Import chat, which opens an exported file as a new chat. Transcript I/O runs in ChatViewModel off the main thread; menus are a shared Material 3 popup that TalkBack can read.
alome007
left a comment
There was a problem hiding this comment.
IMPORTANT
- ChatTranscript.kt:180 -
historyTextnot exported, so an imported chat feeds the model its bubble text
MINOR
- ChatTranscript.kt:147 -
trimEndloses a message's own trailing newlines
Reviewed at medium effort. Each finding was re-checked against 49d64cd. This repo has no written approve/request-changes rule, so the default applied. Checked and clean: header-lookalike escaping (leading backslashes, trailing whitespace), timestamp round trip, preamble keys (a name containing :), ActivityNotFoundException handling, the pending-export id across process death, the snackbar after view destroy, cancellation during export, popup dismissal with the sidebar, and tooltip anchoring on the menu button.
Daniel-ADFA
left a comment
There was a problem hiding this comment.
IMPORTANT
- ChatTranscript.kt:180 -
historyTextnot exported, so an imported chat feeds the model its bubble text
MINOR
- ChatTranscript.kt:147 -
trimEndloses a message's own trailing newlines
Reviewed at medium effort. Each finding was re-checked against 49d64cd. This repo has no written approve/request-changes rule, so the default applied. Checked and clean: header-lookalike escaping (leading backslashes, trailing whitespace), timestamp round trip, preamble keys (a name containing :), ActivityNotFoundException handling, the pending-export id across process death, the snackbar after view destroy, cancellation during export, popup dismissal with the sidebar, and tooltip anchoring on the menu button.
…pts (ADFA-6247) Export the model's own words under a `--- MODEL WROTE` marker when they differ from the bubble, so an imported chat doesn't hand the model its rendered text as its earlier turn. On import, drop only the one blank separator line instead of every trailing newline.
Daniel-ADFA
left a comment
There was a problem hiding this comment.
Round 2, verified against 3a5361e.
MINOR
- viewmodel/ChatViewModel.kt:1679 - import buffers up to 20 MB of any
text/*file before the header check (plausible, not reproduced)
Re-check of round 1
historyTextdropped: fixed. Written after a--- MODEL WROTEline and read back intomessage(). Body lines that look like the marker or a header are escaped (isStructural), including lines with leading backslashes.trimEndlosing trailing newlines: fixed. Parse drops exactly one trailing empty line, so"foo\n\n","\n\n"and""round-trip, including as the last message.
Only a plausible MINOR remains, which does not block by itself. The round-1 CHANGES_REQUESTED review is still on the PR.
Daniel-ADFA
left a comment
There was a problem hiding this comment.
Round 3, verified against 271ea29. Approving: what remains is MINOR.
MINOR
- models/ChatTranscript.kt:41 - export can write a chat the 4 MB import limit then refuses
Re-check of round 2
- Import buffered 20 MB before the header check: fixed.
read()runsopensWithMagicas the stream arrives and throwsInvalidTranscriptExceptiononce the first non-blank line is notMAGIC, or afterMAX_MAGIC_SEARCH_BYTESwith no complete line. It finds that line the wayparsedoes (BOM removed, same whitespace rule), and it re-decodes the whole prefix, so a line or BOM split across reads is handled.
Description
Implemented the ability to export and import Agent conversations as plain
.txtfiles. This ensures users can back up important chats, share them with teammates, or continue conversations across different devices. To support the UI requirements, the standard options menu was replaced with a custom Material 3 menu.Details
⋮), saving transcripts locally via the system file picker.ChatTranscriptmodel to handle strict parsing, ensuring imported chats accurately retain senders, timestamps, and order while assigning fresh IDs to prevent overwriting existing chats.ChatFragmentwith ActivityResultContracts to handle system file picker intents for creating and opening documents.Screen_Recording_20260925_151127_Code.on.the.Go.mp4
Ticket
ADFA-6247
Observation
The standard
PopupMenuwas replaced with a customSidebarPopupMenubecause the host's tooltip relies on aPopupWindow. Anchoring a tooltip inside a standard popup menu throws aBadTokenExceptionthat crashes the IDE. The custom menu safely handles long-press tooltips and supports displaying disabled state explanations, such as when attempting to export an empty chat.