fix(frontend): drop dead identity ternary and add opt-in export tests

Address review feedback on the previous export commit:

1. Removed the no-op `typeof msg.content === "string" ? msg.content : msg.content`
   expression in `formatThreadAsJSON`. Both branches returned the same value;
   the message content now flows through unchanged whether it is a string or
   the rich `MessageContent[]` shape (LangChain JSON-serialises the array
   structure correctly already).

2. Expanded the JSDoc on `ExportOptions` to make it clearer that the four
   flags are not currently wired to any UI control — callers wanting a debug
   export must build the options object explicitly. The default behaviour
   continues to match the explicit prescription in
   bytedance/deer-flow#3107 BUG-006.

3. Added opt-in coverage. The previous tests only exercised the
   `options = {}` default path; the new cases verify each flag flips the
   corresponding payload back into the export so a future debug-export
   surface does not silently break the contract.

Refs: bytedance/deer-flow#3107 (BUG-006)
This commit is contained in:
fancyboi999
2026-05-21 16:26:25 +08:00
parent 9b0d4f8069
commit 530df255b2
2 changed files with 68 additions and 7 deletions
+8 -7
View File
@@ -15,12 +15,13 @@ import { titleOfThread } from "./utils";
/**
* Optional debug switches for advanced exports.
*
* Bytedance/deer-flow issue #3107 BUG-006: by default, the user-facing chat
* export must include only the visible transcript. Internal payloads —
* `hide_from_ui` messages, reasoning content, tool calls, and tool result
* messages — stay out unless the caller explicitly opts in. There is no UI
* surface for this today; the flags exist so a future "debug export" can
* reuse the same formatter instead of forking it.
* Bytedance/deer-flow issue #3107 BUG-006 explicitly prescribes that the
* default export includes only the user-visible transcript and excludes
* thinking/reasoning content, tool calls, tool results, hidden messages,
* memory injection, and `<system-reminder>` payloads. These options let a
* future "debug export" surface re-include any of those categories without
* forking the formatter. They are not currently wired to any UI control —
* callers that want them must construct the options object explicitly.
*/
export interface ExportOptions {
includeReasoning?: boolean;
@@ -134,7 +135,7 @@ export function formatThreadAsJSON(
messages: visibleMessages(messages, options).map((msg) => ({
type: msg.type,
id: msg.id,
content: typeof msg.content === "string" ? msg.content : msg.content,
content: msg.content,
...(options.includeToolCalls &&
msg.type === "ai" &&
msg.tool_calls?.length