From 3f76780fffac0d139f3e4f6bc96e1e1259293ab1 Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Wed, 25 Feb 2026 03:18:18 +0800 Subject: [PATCH] fix: avoid empty text action on stream --- static/src/composables/useLegacySocket.ts | 13 ++++++++-- ...026-02-25_031714_minimax_thinking_tool_stack.md | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 奇奇怪怪的bug/2026-02-25_031714_minimax_thinking_tool_stack.md diff --git a/static/src/composables/useLegacySocket.ts b/static/src/composables/useLegacySocket.ts index b8be6db..7e1cf9d 100644 --- a/static/src/composables/useLegacySocket.ts +++ b/static/src/composables/useLegacySocket.ts @@ -380,6 +380,11 @@ export async function initializeLegacySocket(ctx: any) { remainderToAppendLength: remainderToAppend.length, finalLength: finalText.length }); + if (finalText && !ensureActiveTextAction()) { + ensureActiveMessageBinding(); + const action = ctx.chatStartTextAction(); + streamingState.activeTextAction = action || ensureActiveTextAction(); + } if (remainderToAppend) { applyTextChunk(remainderToAppend); } @@ -930,10 +935,9 @@ export async function initializeLegacySocket(ctx: any) { logStreamingDebug('socket:text_start'); finalizeStreamingText({ force: true }); resetStreamingBuffer(); - const action = ctx.chatStartTextAction(); streamingState.activeMessageIndex = typeof ctx.currentMessageIndex === 'number' ? ctx.currentMessageIndex : null; - streamingState.activeTextAction = action || ensureActiveTextAction(); + streamingState.activeTextAction = null; ensureActiveMessageBinding(); ctx.$forceUpdate(); }); @@ -958,6 +962,11 @@ export async function initializeLegacySocket(ctx: any) { console.warn('上报chunk日志失败:', error); } if (data && typeof data.content === 'string' && data.content.length) { + if (!ensureActiveTextAction()) { + ensureActiveMessageBinding(); + const action = ctx.chatStartTextAction(); + streamingState.activeTextAction = action || ensureActiveTextAction(); + } if (STREAMING_ENABLED) { enqueueStreamingContent(data.content); } else { diff --git a/奇奇怪怪的bug/2026-02-25_031714_minimax_thinking_tool_stack.md b/奇奇怪怪的bug/2026-02-25_031714_minimax_thinking_tool_stack.md new file mode 100644 index 0000000..5174916 --- /dev/null +++ b/奇奇怪怪的bug/2026-02-25_031714_minimax_thinking_tool_stack.md @@ -0,0 +1,26 @@ +# 诡异Bug记录 + +- 诡异程度:★★★★☆ +- 发现时间:2026-02-25 03:17:14 +- 场景/模块:前端聊天流式渲染(思考块/工具块堆叠) +- 关联模型:minimax-m2.5 + +## 描述 +使用 minimax 模型时,思考块与紧接的工具块在实时流式阶段无法堆叠,呈现为“两个两个分开”的块;但刷新后历史记录显示又正常。 + +## Debug 过程 +1. 复现并对比:其他模型堆叠正常,只有 minimax 异常。 +2. 查看前端堆叠逻辑:堆叠依赖 actions 顺序连续(thinking/tool)。 +3. 加入前端调试日志,捕获“空白文本 action”。 +4. 复现后日志显示出现 `text` action,但 `content` 为空,且正好夹在 thinking 与 tool 之间。 + +## 找到的问题 +minimax 流式会触发 `text_start`,但没有任何 `text_chunk`(或最终内容为空),导致前端创建一个空的 `text` action,打断 `thinking -> tool` 的连续性,从而破坏堆叠。 + +## 修复方案 +前端改为: +- `text_start` 不立即创建 text action; +- 只有收到首个非空 `text_chunk`(或最终 `text_end` 有内容)时才创建; +- 无实际正文时不生成 text action,避免空 action 插入。 + +结果:minimax 实时堆叠恢复正常,刷新与实时显示一致。