mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-04 00:03:59 +00:00
fix(ohos): 历史刷新不再整表替换,避免刚发出的消息凭空消失
sync_required 触发的 reloadHistory 会与刚发出的 POST 竞争:若历史快照 里还没有这条 user 消息,整表替换会让它消失(“客户端侧发出的消息不显示”)。 改为合并:历史为权威,但保留本地两类消息追加在末尾—— - user 且 source 为空(乐观消息)且内容未出现在历史里; - assistant 且 !isFinal(仍在流式输出)。
This commit is contained in:
@ -35,6 +35,36 @@ export const K_CHAT_CONNECTED: string = 'chatSseUp';
|
|||||||
|
|
||||||
const SSE_RECONNECT_MS: number = 5000;
|
const SSE_RECONNECT_MS: number = 5000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把服务端历史与本地消息合并:历史是权威,但本地刚发出、尚未被服务端
|
||||||
|
* 回显的消息不能丢。
|
||||||
|
*
|
||||||
|
* 保留两类本地消息,追加在历史末尾:
|
||||||
|
* - user 且 source 为空(本地乐观消息),且内容未出现在历史里;
|
||||||
|
* - assistant 且 !isFinal(仍在流式输出)。
|
||||||
|
*/
|
||||||
|
function mergeHistoryWithLocal(history: ChatMessage[], local: ChatMessage[]): ChatMessage[] {
|
||||||
|
const merged: ChatMessage[] = history.slice();
|
||||||
|
for (let i = 0; i < local.length; i++) {
|
||||||
|
const m: ChatMessage = local[i];
|
||||||
|
if (m.role === 'user' && (m.source ?? '').length === 0) {
|
||||||
|
let dup: boolean = false;
|
||||||
|
for (let j = 0; j < history.length; j++) {
|
||||||
|
if (history[j].role === 'user' && history[j].content === m.content) {
|
||||||
|
dup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dup) {
|
||||||
|
merged.push(m);
|
||||||
|
}
|
||||||
|
} else if (m.role === 'assistant' && m.isFinal !== true) {
|
||||||
|
merged.push(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
class ChatStore implements ChatStreamSink {
|
class ChatStore implements ChatStreamSink {
|
||||||
private msgs: ChatMessage[] = [];
|
private msgs: ChatMessage[] = [];
|
||||||
private nextId: number = 1;
|
private nextId: number = 1;
|
||||||
@ -287,7 +317,13 @@ class ChatStore implements ChatStreamSink {
|
|||||||
if (parsed.msgs.length === 0) {
|
if (parsed.msgs.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.msgs = parsed.msgs;
|
// 与本地未回显的消息合并,而不是整表替换。
|
||||||
|
//
|
||||||
|
// 为什么:sync_required 触发的 reloadHistory 会与刚发出的 POST 竞争;
|
||||||
|
// 若历史快照里还没有这条 user 消息,整表替换会让它凭空消失
|
||||||
|
// (“客户端侧发出的消息不显示”)。同理,仍在流的助消息也不能被
|
||||||
|
// 快照截断。
|
||||||
|
this.msgs = mergeHistoryWithLocal(parsed.msgs, this.msgs);
|
||||||
this.offset = parsed.offset;
|
this.offset = parsed.offset;
|
||||||
this.hasEarlier = parsed.hasMore;
|
this.hasEarlier = parsed.hasMore;
|
||||||
this.forceRefresh();
|
this.forceRefresh();
|
||||||
|
|||||||
Reference in New Issue
Block a user