- 16.4.5:非激活会话的帧**不再丢弃**,按自己的 sessionId 落进该会话桶(新增 store/sessionCache.ts 纯函数 + useAppStore.sessionMessages/flowGraphs);切会话改为「存回/取出」而非清空;流式增量 O(1) 定位桶、 只延长已存在的助手气泡(不凭一帧 delta 凭空造消息) - 16.4.2:图按会话入桶(上限 12 个),Backthink 页取 sess-backthink 的图而不再被用户会话图顶替; 空态区分「实时通道未连接」与「尚未产生链路图」;wire_runtime 的图源白名单注释按裁决口径重写(零行为改动) - 修 16.4.1 的缺口:handlers/session.ts 补 `session_idle` / `session_interrupted`(此前落到未知帧兜底 ⇒ sessionBusy 可能卡 true ⇒ 预约永不落地);忙态**置忙与置闲两侧**统一按 frameIsActive 过滤(只过滤置闲 会让后台会话的忙帧点亮徽标而它自己的 idle 被丢 ⇒ 永久卡忙) - 清理:删除 lib/streamScope.ts(口径已被 16.4.5 推翻)与只剩测试在用的 messageEventApplies - 复核:tsc 0 错 + vite build 成功;messageSync 69 / session 19 项逻辑测试;4 条变异反证
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { frameSessionId, type FrameEvent, type FramePayload, type StoreState } from "./shared";
|
|
import { parseTool, parseToolCall } from "../../wsParse";
|
|
|
|
/** 工具帧处理组:tool_call.start / tool_call.end / tool_call.delta /
|
|
* tool_execution.update + 遗留 tool_used。命中(含组内主动丢弃)返回 true,
|
|
* 未命中返回 false 交给下一组。
|
|
*
|
|
* 裁决 16.4.5:工具卡按帧的 `sessionId` 落在该会话的助手气泡上(其它会话的调用
|
|
* 卡不会跑到屏幕上的这一轮里)。 */
|
|
export function handleToolEvent(ev: FrameEvent, r: FramePayload, s: StoreState): boolean {
|
|
switch (ev.type) {
|
|
case "tool_call.start":
|
|
case "tool_call.end": {
|
|
const tool = parseToolCall(ev.data);
|
|
if (tool) s.addTool(tool, frameSessionId(ev, r));
|
|
return true;
|
|
}
|
|
case "tool_call.delta": {
|
|
// Argument fragments stream between start/end; the card is added at the
|
|
// boundary so mid-stream reconnects do not drop it.
|
|
return true;
|
|
}
|
|
case "tool_execution.update": {
|
|
// Same card as tool_call.* — same routing.
|
|
const tool = parseToolCall(ev.data);
|
|
if (tool) s.addTool(tool, frameSessionId(ev, r));
|
|
return true;
|
|
}
|
|
case "tool_used": {
|
|
// Legacy tool echo — same card as tool_call.*.
|
|
const tool = parseTool(ev.data);
|
|
if (tool) s.addTool(tool, frameSessionId(ev, r));
|
|
return true;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
}
|