From 2895425869c1dd37a7936d9e9e0006c88c5f3957 Mon Sep 17 00:00:00 2001 From: wuyang6 Date: Thu, 14 May 2026 20:06:55 +0800 Subject: [PATCH] Stream assistant content to chat output --- frontend/app/app/api/chat/route.ts | 11 +++++---- .../assistant-ui/activity-panel.tsx | 24 ------------------- .../components/assistant-ui/thread-list.tsx | 24 ------------------- 3 files changed, 6 insertions(+), 53 deletions(-) diff --git a/frontend/app/app/api/chat/route.ts b/frontend/app/app/api/chat/route.ts index e71a5c3..e61b4d1 100644 --- a/frontend/app/app/api/chat/route.ts +++ b/frontend/app/app/api/chat/route.ts @@ -507,11 +507,12 @@ function writeRuntimeEvent( }); } if (event.type === "content_delta" && event.delta) { - writer.write({ - type: "reasoning-delta", - id: "reasoning-1", - delta: event.delta, - }); + if (!streamState?.textStarted) { + writer.write({ type: "text-start", id: "text-1" }); + if (streamState) streamState.textStarted = true; + } + writer.write({ type: "text-delta", id: "text-1", delta: event.delta }); + if (streamState) streamState.textStreamed = true; } if (event.type === "tool_call_delta") { const key = diff --git a/frontend/app/components/assistant-ui/activity-panel.tsx b/frontend/app/components/assistant-ui/activity-panel.tsx index 5532092..f2abd68 100644 --- a/frontend/app/components/assistant-ui/activity-panel.tsx +++ b/frontend/app/components/assistant-ui/activity-panel.tsx @@ -984,18 +984,7 @@ function summarizeLiveRunEvents( events: readonly LiveRunEvent[], ) { const lines: string[] = []; - let contentBuffer = ""; - const flushContentBuffer = () => { - const preview = compactLiveContentDelta(contentBuffer); - contentBuffer = ""; - if (preview) lines.push(`输出:${preview}`); - }; for (const event of events) { - if (event.type === "content_delta") { - contentBuffer += event.delta ?? ""; - continue; - } - flushContentBuffer(); if (event.type === "run_queued") { lines.push("当前会话已有任务在执行,本轮正在排队。"); } @@ -1024,7 +1013,6 @@ function summarizeLiveRunEvents( lines.push("正在整理回复"); } } - flushContentBuffer(); if (runStatus.current_stage && lines.at(-1) !== runStatus.current_stage) { lines.push(runStatus.current_stage); } @@ -1038,18 +1026,6 @@ function summarizeLiveRunEvents( return lines.slice(-40); } -function isNoisyLiveDelta(value: string) { - return value === "。" || value === "," || value === "," || value.length <= 1; -} - -function compactLiveContentDelta(value: string) { - const normalized = value.replace(/\s+/g, " ").trim(); - if (!normalized || isNoisyLiveDelta(normalized)) return ""; - return normalized.length <= 36 - ? normalized - : `${normalized.slice(Math.max(0, normalized.length - 35))}…`; -} - function collectActivityItems(messages: readonly MessageState[]) { const items: ActivityItem[] = []; diff --git a/frontend/app/components/assistant-ui/thread-list.tsx b/frontend/app/components/assistant-ui/thread-list.tsx index c0004b5..64da9fc 100644 --- a/frontend/app/components/assistant-ui/thread-list.tsx +++ b/frontend/app/components/assistant-ui/thread-list.tsx @@ -647,18 +647,7 @@ function buildActiveRunParts(runStatus: ClawActiveRunStatus) { function summarizeRunEvents(runStatus: ClawActiveRunStatus) { const lines: string[] = []; - let contentBuffer = ""; - const flushContentBuffer = () => { - const preview = compactLiveContentDelta(contentBuffer); - contentBuffer = ""; - if (preview) lines.push(`输出:${preview}`); - }; for (const event of runStatus.events ?? []) { - if (event.type === "content_delta") { - contentBuffer += event.delta ?? ""; - continue; - } - flushContentBuffer(); if (event.type === "run_queued") { lines.push("当前会话已有任务在执行,本轮正在排队。"); } @@ -690,25 +679,12 @@ function summarizeRunEvents(runStatus: ClawActiveRunStatus) { lines.push("等待用户 review"); } } - flushContentBuffer(); if (runStatus.current_stage && lines.at(-1) !== runStatus.current_stage) { lines.push(runStatus.current_stage); } return lines.slice(-40); } -function isNoisyLiveDelta(value: string) { - return value === "。" || value === "," || value === "," || value.length <= 1; -} - -function compactLiveContentDelta(value: string) { - const normalized = value.replace(/\s+/g, " ").trim(); - if (!normalized || isNoisyLiveDelta(normalized)) return ""; - return normalized.length <= 36 - ? normalized - : `${normalized.slice(Math.max(0, normalized.length - 35))}…`; -} - function buildRunToolParts(events: readonly ClawRunEvent[]) { const resultById = new Map(); for (const event of events) {