feat(gateway,loop): A1 流式帧附加 sessionId/turnId — 多会话并发流式可路由
- model.StreamEvent 增 SessionID/TurnID(适配器在 loop 之下,恒留零值) - loop 在回合边界注入;覆盖 stream.go 与 tools.go 的 tool_execution 发射点 - 网关 runTurn 每回合生成 turnID 并经 loop.WithTurnID 挂进运行上下文(编排层与 legacy 直连的唯一收口点);broadcastStream 填充 wsEvent - Docs/api-client v0.36 契约与变更日志;v0.10 条目标注为已被补齐 - 新增 loop/gateway 测试,含变异验证
This commit is contained in:
1 parent
29aa60d0eb
commit
61cc32c44b
9 files changed
+332
-10
No files matched your search
@@ -948,8 +948,10 @@ func TestHubBroadcastStream(t *testing.T) {
|
||||
|
||||
// A text_delta StreamEvent on the OnStream→bus→relay path becomes a typed
|
||||
// message.delta frame carrying the delta text and a monotonically increasing
|
||||
// seq, leaving the legacy stream_chunk shape out of the way.
|
||||
hb.broadcastStream(model.StreamEvent{Kind: model.StreamKindTextDelta, Delta: "Hel", Index: 0})
|
||||
// seq, leaving the legacy stream_chunk shape out of the way. The loop stamps
|
||||
// the session/turn identity on the event and the hub must carry it onto the
|
||||
// frame, so a client can route the delta to the active session (design/16 §4.2).
|
||||
hb.broadcastStream(model.StreamEvent{Kind: model.StreamKindTextDelta, Delta: "Hel", Index: 0, SessionID: "web", TurnID: "turn-abc"})
|
||||
ev := readFakeFrame(t, c)
|
||||
if ev.Type != "message.delta" {
|
||||
t.Fatalf("frame type = %q, want message.delta (frame=%+v)", ev.Type, ev)
|
||||
@@ -961,6 +963,9 @@ func TestHubBroadcastStream(t *testing.T) {
|
||||
if ev.Seq != 1 {
|
||||
t.Fatalf("frame seq = %d, want 1", ev.Seq)
|
||||
}
|
||||
if ev.SessionID != "web" || ev.TurnID != "turn-abc" {
|
||||
t.Fatalf("frame scope = session %q turn %q, want session web turn turn-abc", ev.SessionID, ev.TurnID)
|
||||
}
|
||||
|
||||
// A tool_call event maps to tool_call.*; a non-StreamEvent payload is dropped.
|
||||
hb.broadcastStream(model.StreamEvent{Kind: model.StreamKindToolCallEnd, ID: "toolu_1", Index: 0})
|
||||
|
||||
Reference in new issue
Block a user