1.8 KiB
1.8 KiB
H5 会话 SSE 断线续播守卫
症状
后台 h5_agent_runs 已经是 succeeded、Goose 也已发送 Finish,但 H5 输入区仍显示“正在执行任务…”。常见触发条件是手机切后台、锁屏或网络切换发生在 ActiveRequests 与 Finish 之间。
根因
Portal 对 SSE 帧使用本地持久化游标。该游标可能是 Portal 生成的 UUID,并不一定是 Goose 能识别的上游事件 ID。若重连时把 Portal UUID 原样作为 Last-Event-ID 发送给 Goose,Goose 无法续播,浏览器就收不到遗漏的 Finish。
必须保留的行为
- Portal 游标只用于查询
h5_session_stream_events,不得原样传给 Goose。 - 连接 Goose 时,只能使用已持久化的
upstream_event_id。 - 当前游标或重放尾部没有可用
upstream_event_id时,必须省略Last-Event-ID,让 Goose 从权威事件流重新回放。 - 本地重放最后一条已经是
Finish或Error时,不再连接 Goose。 - 重放不得破坏现有消息 ID 合并、Finish 幂等计费和 MindSpace Finish 同步守卫。
关键路径
session-stream.mjssession-stream-store.mjstkmind-proxy.mjssrc/hooks/useTKMindChat.ts
回归测试
node --test session-stream.test.mjs session-stream-store.test.mjs chat-agent-run-gate.test.mjs
node --test --test-name-pattern='proxySessionEvents' tkmind-proxy.test.mjs
npm run verify:h5-session-patches
node --test billing-session-concurrency.test.mjs
必须覆盖:
- Portal 游标存在但
upstream_event_id为空时,不向 Goose 发送错误游标,并能收到Finish。 - 有映射时,Portal 游标正确转换成 Goose 游标。
- 多轮会话中选择最新可映射的上游游标,不被上一轮 Finish 截断。
- Finish 重放不重复扣费,消息合并与页面同步守卫继续通过。