From 50c552f7632733fd34fb47e511c5a59e4a812900 Mon Sep 17 00:00:00 2001 From: Simon Klee Date: Tue, 8 Sep 2026 11:24:29 +0200 Subject: [PATCH] tui: add tool filtering option to Markdown exports (#47929) --- packages/tui/src/routes/session/index.tsx | 6 ++- packages/tui/src/ui/dialog-export-options.tsx | 47 ++++++++++++++++++- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index 4fc7982831c..dd34e40459c 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -1153,7 +1153,7 @@ export function Session(props: { const content = options.format === "markdown" - ? formatSessionTranscript(sessionData, messages(), options.thinking) + ? formatSessionTranscript(sessionData, messages(), options.thinking, options.tools) : JSON.stringify( await client.api.session.export({ sessionID: sessionData.id, sanitize: options.sanitize }), null, @@ -3839,7 +3839,7 @@ function recordValue(value: unknown): Record | undefined { return isRecord(value) ? value : undefined } -function formatSessionTranscript(session: SessionInfo, messages: SessionMessageInfo[], thinking: boolean) { +function formatSessionTranscript(session: SessionInfo, messages: SessionMessageInfo[], thinking: boolean, tools = true) { const body = messages.flatMap((message) => { if (message.type === "user") return [`## User\n\n${message.text}`] if (message.type === "shell") @@ -3848,6 +3848,7 @@ function formatSessionTranscript(session: SessionInfo, messages: SessionMessageI const content = message.content.flatMap((item) => { if (item.type === "text") return [item.text] if (item.type === "reasoning") return thinking ? [`_Thinking:_\n\n${item.text}`] : [] + if (!tools) return [] const input = typeof item.state.input === "string" ? item.state.input : JSON.stringify(item.state.input, null, 2) const output = item.state.status === "error" @@ -3859,6 +3860,7 @@ function formatSessionTranscript(session: SessionInfo, messages: SessionMessageI .join("\n") return [`**Tool: ${item.name}**\n\n**Input:**\n\`\`\`json\n${input}\n\`\`\`\n\n${output}`] }) + if (content.length === 0) return [] return [`## Assistant\n\n${content.join("\n\n")}`] }) return `# ${withTimestampedFallback(session)}\n\n**Session ID:** ${session.id}\n**Created:** ${new Date(session.time.created).toLocaleString()}\n**Updated:** ${new Date(session.time.updated).toLocaleString()}\n\n---\n\n${body.join("\n\n---\n\n")}\n` diff --git a/packages/tui/src/ui/dialog-export-options.tsx b/packages/tui/src/ui/dialog-export-options.tsx index 242923c2ed9..eef090b974a 100644 --- a/packages/tui/src/ui/dialog-export-options.tsx +++ b/packages/tui/src/ui/dialog-export-options.tsx @@ -13,12 +13,13 @@ export type DialogExportOptionsProps = { action: "copy" | "export" format: ExportFormat thinking: boolean + tools: boolean sanitize: boolean }) => void onCancel?: () => void } -type Active = ExportFormat | "thinking" | "sanitize" | "copy" | "export" +type Active = ExportFormat | "thinking" | "tools" | "sanitize" | "copy" | "export" export function DialogExportOptions(props: DialogExportOptionsProps) { const dialog = useDialog() @@ -27,6 +28,7 @@ export function DialogExportOptions(props: DialogExportOptionsProps) { const [store, setStore] = createStore({ format: "markdown" as ExportFormat, thinking: props.defaultThinking, + tools: true, sanitize: false, active: "markdown" as Active, }) @@ -36,6 +38,7 @@ export function DialogExportOptions(props: DialogExportOptionsProps) { action, format: store.format, thinking: store.thinking, + tools: store.tools, sanitize: store.sanitize, }) @@ -45,6 +48,7 @@ export function DialogExportOptions(props: DialogExportOptionsProps) { return } if (store.active === "thinking") setStore("thinking", !store.thinking) + if (store.active === "tools") setStore("tools", !store.tools) if (store.active === "sanitize") setStore("sanitize", !store.sanitize) if (store.active === "copy" || store.active === "export") confirm(store.active) } @@ -59,7 +63,7 @@ export function DialogExportOptions(props: DialogExportOptionsProps) { run: () => { const order: Active[] = store.format === "markdown" - ? ["markdown", "json", "thinking", "copy", "export"] + ? ["markdown", "json", "thinking", "tools", "copy", "export"] : ["markdown", "json", "sanitize", "copy", "export"] setStore("active", order[(order.indexOf(store.active) + 1) % order.length]) }, @@ -160,6 +164,44 @@ export function DialogExportOptions(props: DialogExportOptionsProps) { Include thinking + { + setStore("active", "tools") + setStore("tools", !store.tools) + }} + > + + {store.tools ? "[x]" : "[ ]"} + + + Include tools + + action: "copy" | "export" format: ExportFormat thinking: boolean + tools: boolean sanitize: boolean } | null>((resolve) => { dialog.replace(