新增: 跨端用户消息同步

This commit is contained in:
2026-06-24 00:27:08 +08:00
parent 698d981962
commit 78b48d871b
3 changed files with 66 additions and 1 deletions

View File

@@ -47,6 +47,19 @@ let _legacyWatchdog: ReturnType<typeof setTimeout> | null = null
* (legacy fallback 路径)时不带 convId,generatingConvs 不动(全局兜底,行为对齐旧版)。
*/
export function onStreamTimeout(convId?: string) {
// 根治守卫(TD-260621-01 遗留):看门狗 reset(doSend 走 legacy _legacyWatchdog)/clear
// (AiCompleted 走 per-conv _watchdogTimers Map)路径不对齐,clear 传 convId 时只清 Map 不动 legacy,
// 致正常收尾(AiCompleted 已清 streaming)后 legacy timer 残留,130s 到期触发本函数补
// "⚠ 工具已执行完成,后续回复中断"误报气泡(实测:用户报"回复完后输出该报错")。
// 守卫:触发时若该 conv 已不在生成态(已正常收尾),判定为残留 timer,静默清不补错误消息。
// 真卡死(streaming/generating 仍 true)不受影响,仍走原 forceReset + 报错兜底。
const stillGenerating = convId
? state.generatingConvs.has(convId)
: state.streaming
if (!stillGenerating) {
clearStreamWatchdog(convId)
return
}
// 卡死兜底走 guard 的 forceResetStreaming(复位 streaming + 清 currentText/queue + warn 日志)。
// TD-260621-01:携带 convId 时仅清该 conv 的 generatingConvs(per-conv);不传时全局兜底不动 Set。
forceResetStreaming('onStreamTimeout(130s 无数据)', convId)
@@ -108,6 +121,9 @@ export function resetStreamWatchdog(convId?: string) {
if (old) clearTimeout(old)
const timer = setTimeout(() => onStreamTimeout(convId), STREAM_TIMEOUT_MS)
_watchdogTimers.set(convId, timer)
// 根治(TD-260621-01 遗留):切到 per-conv 时清 legacy(doSend 启动的 legacy timer 与活跃事件
// per-conv 共存期,legacy 是残留)。防 AiCompleted clear(convId) 清不到 legacy 致 130s 误报。
if (_legacyWatchdog) { clearTimeout(_legacyWatchdog); _legacyWatchdog = null }
} else {
// 禁动域 fallback:行为对齐旧版单 timer。
if (_legacyWatchdog) clearTimeout(_legacyWatchdog)
@@ -126,6 +142,10 @@ export function clearStreamWatchdog(convId?: string) {
if (convId) {
const timer = _watchdogTimers.get(convId)
if (timer) { clearTimeout(timer); _watchdogTimers.delete(convId) }
// 根治(TD-260621-01 遗留):doSend reset 走 legacy,AiCompleted clear 走 per-conv Map,clear 清不到
// legacy 致 130s 残留误报。批2 单 loop 阶段 legacy 单例只属当前会话,clear(convId) 兜底清 legacy 安全;
// 批3+ 多会话落地时 useAiSend reset 迁 per-conv + 删 legacy fallback,此兜底随之移除。
if (_legacyWatchdog) { clearTimeout(_legacyWatchdog); _legacyWatchdog = null }
} else {
if (_legacyWatchdog) { clearTimeout(_legacyWatchdog); _legacyWatchdog = null }
}