Skip to content

feat(flow-chat): add full-process / result-only scopes to copy and session export - #1765

Merged
bobleer merged 1 commit into
GCWing:mainfrom
bobleer:feat/transcript-export-scopes
Jul 26, 2026
Merged

feat(flow-chat): add full-process / result-only scopes to copy and session export#1765
bobleer merged 1 commit into
GCWing:mainfrom
bobleer:feat/transcript-export-scopes

Conversation

@bobleer

@bobleer bobleer commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a "full process" / "result only" choice everywhere a transcript leaves the app, and adds Markdown export for a whole session.

  • Copy dialog (round footer button + right-click context menu) now asks which scope to copy: 拷贝完整过程 (thinking + tool calls) or 拷贝结果 (user message + assistant prose only).
  • Session list three-dot menu gains 导出为 Markdown, which opens a second menu level with the same two scopes. This is session-granularity, unlike the turn-granularity copy above.

Both paths share one formatter. The turn-extraction logic previously existed in three near-identical copies — ModelRoundItem.tsx, useFlowChatCopyDialog.ts, and flow_chat/hooks/useCopyDialog.ts (dead code, exported but never imported; now deleted) — which is why #1657 reproduced regardless of entry point.

Fixes #1657
Fixes #1506
Fixes #1495

Type and Areas

Type: Feature (with a bug fix for #1657) + small refactor to remove duplication.

Areas: web UI (flow_chat, NavPanel sessions section, context menu provider), locales.

Motivation / Impact

Users copying a reply got the whole reasoning trace and every tool call, so archiving a clean answer meant editing the clipboard by hand (#1657, #1506). Sessions had no Markdown export at all (#1495).

New shared module flow_chat/utils/dialogTranscriptExport.ts normalizes the runtime (DialogTurn) and persisted (DialogTurnData) shapes into one intermediate form, then renders either clipboard text or a Markdown document per scope.

Session export reads turns from persistence rather than the in-memory store, so a history session that has only hydrated its tail still exports in full. Desktop saves through the Tauri save dialog; the browser build falls back to a download.

Two correctness improvements the old copy path lacked, now applied on the persisted side:

  • Items are ordered by orderIndex instead of being grouped text → tool → thinking.
  • Superseded retry attempts are dropped (same "effective attempt" rule the Rust transcript renderer uses).

Tool payloads are wrapped in width-adjusted code fences, so a result containing ``` can no longer break out of its block.

Exported Markdown

# LangGraph state management

- Session ID: `sess-abc`
- Workspace: `/repo`
- Exported at: 2026-07-25T09:00:00.000Z
- Turns: 1
- Scope: Result only

---

## Turn 1

### 👤 User

How does langgraph handle state?

### 🤖 Assistant

LangGraph persists state through **checkpointers**:
...

Verification

pnpm run type-check:web        # pass
pnpm run lint:web              # pass
pnpm --dir src/web-ui run test:run   # 323 files, 2054 tests pass
pnpm run i18n:contract:test    # pass
pnpm run i18n:audit            # Passed with 0 warning(s)
pnpm run check:repo-hygiene    # pass

20 new unit tests cover both scopes, orderIndex ordering, retry-attempt filtering, <user_query> unwrapping, export file-name sanitization, and fence widening.

Manually verified in the desktop app: both copy scopes from the round footer, and both export scopes from the session menu.

Testing level: fully tested (automated + manual desktop run). AI-assisted change.

Reviewer Notes

  • No screenshots attached — the UI additions are a two-item popover on the existing copy button and two extra rows in the existing session menu; no layout or visual redesign.
  • Two incidental de-duplications, both in service of the above and kept minimal:
    • cleanRemoteUserInput was byte-identical in FlowChatStore and EventHandlerModule; extracted to flow_chat/utils/userInputText.ts so the exporter did not become a third copy.
    • downloadMarkdownInBrowser was copied from CodeReviewReportExportActions.tsx; extracted to shared/utils/browserDownload.ts and both now import it.
  • contextMenu.copyDialog was replaced by copyDialogFull / copyDialogResult in all three locales.
  • The '__TAURI__' in window check is duplicated locally (as it is in ~20 other places in this repo); left alone to keep the PR focused.
  • No Rust changes; the existing export_session_transcript command is a different feature (agent-facing transcript for the session-history tool) and is untouched.

…ssion export

Copying a dialog turn always included thinking and tool calls, so archiving a
clean answer meant hand-editing the clipboard. Sessions had no Markdown export
at all.

- Copy dialog (round footer + context menu) now offers "full process" and
  "result only".
- Session list menu gains "Export as Markdown", with the same two scopes at a
  second menu level. Turns are read from persistence, so a partially hydrated
  history session still exports in full.
- Both paths share one formatter that normalizes the runtime and persisted turn
  shapes; the extraction logic previously existed in three near-identical
  copies, one of which was dead code (flow_chat/hooks/useCopyDialog.ts).

The persisted path also gains behavior the old copy lacked: items are ordered
by orderIndex, and superseded retry attempts are dropped. Tool payloads are
wrapped in width-adjusted code fences so content containing ``` cannot break
out of the block.

Fixes GCWing#1657
Fixes GCWing#1506
Fixes GCWing#1495
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant