fix: output_send 气泡时序(chatFinalIdx 插入)与 channel_output 后流式丢失

This commit is contained in:
JianFeeeee
2026-08-14 00:58:41 +08:00
parent 147d0baaf9
commit d3bd4c2fe6
3 changed files with 39 additions and 5 deletions

8
.gitignore vendored
View File

@ -34,3 +34,11 @@ third_party/homeagent-sdk/example/
# codegraph 本地索引配置(含嵌套 SDK 仓放行,仅本地生效) # codegraph 本地索引配置(含嵌套 SDK 仓放行,仅本地生效)
codegraph.json codegraph.json
# 运行时产物(不提交)
adapters/
knowledge/
memory/
scripts/
terminal_locked_log.txt

View File

@ -22,6 +22,7 @@ let state = {
chatStick: true, chatStick: true,
pendingTools: [], pendingTools: [],
eventSource: null, eventSource: null,
chatFinalIdx: -1,
lang: localStorage.getItem('ha-lang') || 'zh', lang: localStorage.getItem('ha-lang') || 'zh',
connections: [], currentConn: null, connections: [], currentConn: null,
@ -828,6 +829,7 @@ async function sendChat() {
var text = inp.value.trim(); var text = inp.value.trim();
if (!text || state.chatLoading) return; if (!text || state.chatLoading) return;
state.chatStick = true; state.chatStick = true;
state.chatFinalIdx = -1;
state.messages.push({ role: 'user', content: text }); state.messages.push({ role: 'user', content: text });
inp.value = ''; inp.value = '';
rerenderChat(); rerenderChat();
@ -858,6 +860,7 @@ async function sendChat() {
_grow: true _grow: true
}); });
} }
state.chatFinalIdx = state.messages.length - 1;
rerenderChat(); rerenderChat();
} catch(e) { } catch(e) {
state.messages.push({ role: 'assistant', content: __('错误: ','Error: ') + e.message, _final: true }); state.messages.push({ role: 'assistant', content: __('错误: ','Error: ') + e.message, _final: true });
@ -1947,7 +1950,13 @@ async function connectFetchSSE(url) {
if (type === 'agent_output') { if (type === 'agent_output') {
state.chatStage = __('AI 回复中...','AI replying...'); state.chatStage = __('AI 回复中...','AI replying...');
if (p.kind === 'channel_output') { if (p.kind === 'channel_output') {
state.messages.push({ role: 'assistant', content: p.content || '', source: p.channel || '', _final: true, _grow: true }); var cm = { role: 'assistant', content: p.content || '', source: p.channel || '', _final: true, _grow: true };
if (state.chatFinalIdx >= 0 && state.chatFinalIdx < state.messages.length) {
state.messages.splice(state.chatFinalIdx, 0, cm);
state.chatFinalIdx++;
} else {
state.messages.push(cm);
}
rerenderChatIfActive(); return; rerenderChatIfActive(); return;
} }
var last = state.messages.length > 0 ? state.messages[state.messages.length - 1] : null; var last = state.messages.length > 0 ? state.messages[state.messages.length - 1] : null;
@ -1956,7 +1965,7 @@ async function connectFetchSSE(url) {
last.content += (p.content || ''); last.content += (p.content || '');
rerenderChatIfActive(); return; rerenderChatIfActive(); return;
} }
if (last && last.role === 'assistant' && last._final) { return; } if (last && last.role === 'assistant' && last._final && !last.source) { return; }
state.messages.push({ role: 'assistant', content: p.content || '', _streaming: true, _grow: true }); state.messages.push({ role: 'assistant', content: p.content || '', _streaming: true, _grow: true });
rerenderChatIfActive(); rerenderChatIfActive();
} else if (type === 'reasoning') { } else if (type === 'reasoning') {

View File

@ -1980,6 +1980,7 @@
chatStick: true, chatStick: true,
pendingTools: [], pendingTools: [],
eventSource: null, eventSource: null,
chatFinalIdx: -1,
lang: localStorage.getItem("ha-lang") || "zh", lang: localStorage.getItem("ha-lang") || "zh",
}; };
@ -3296,6 +3297,7 @@
var text = inp.value.trim(); var text = inp.value.trim();
if (!text || state.chatLoading) return; if (!text || state.chatLoading) return;
state.chatStick = true; state.chatStick = true;
state.chatFinalIdx = -1;
state.messages.push({ role: "user", content: text }); state.messages.push({ role: "user", content: text });
inp.value = ""; inp.value = "";
rerenderChat(); rerenderChat();
@ -3348,6 +3350,7 @@
_grow: true, _grow: true,
}); });
} }
state.chatFinalIdx = state.messages.length - 1;
rerenderChat(); rerenderChat();
} catch (e) { } catch (e) {
state.messages.push({ state.messages.push({
@ -3739,13 +3742,22 @@
if (!p.content) return; if (!p.content) return;
state.chatStage = __("AI 回复中...", "AI replying..."); state.chatStage = __("AI 回复中...", "AI replying...");
if (p.kind === "channel_output") { if (p.kind === "channel_output") {
state.messages.push({ var cm = {
role: "assistant", role: "assistant",
content: p.content, content: p.content,
source: p.channel || "", source: p.channel || "",
_final: true, _final: true,
_grow: true, _grow: true,
}); };
if (
state.chatFinalIdx >= 0 &&
state.chatFinalIdx < state.messages.length
) {
state.messages.splice(state.chatFinalIdx, 0, cm);
state.chatFinalIdx++;
} else {
state.messages.push(cm);
}
rerenderChat(); rerenderChat();
return; return;
} }
@ -3762,7 +3774,12 @@
rerenderChat(); rerenderChat();
return; return;
} }
if (lastM2 && lastM2.role === "assistant" && lastM2._final) { if (
lastM2 &&
lastM2.role === "assistant" &&
lastM2._final &&
!lastM2.source
) {
return; return;
} }
state.messages.push({ state.messages.push({