- 新增 model/stream.go:StreamKind(text/thinking/tool_call 各 start/delta/end + tool_execution)
+ StreamEvent{Kind,Delta,Index,ID}。
- ChatStream 签名 onChunk func(delta string)→onEvent func(StreamEvent);loop OnStream 同改;
streamStep 转发结构化事件。
- openai:text_delta + text_start/text_end(正文三段式);anthropic:文本块 text_*/tool_call_*
按块 Index(content_block_stop 分支)真分段;fallback:有事件即交付。
- ws_hub:wsEvent 壳补 turnId/seq;新增 broadcastStream;streamChat 每帧打 turnId+seq;
stream.go 把事件 publish 到 bus ws.stream。
- ws_bridge:streamEventData 映射 text_*→message.start/delta/end、thinking_*→thinking.*、
tool_call_*→tool_call.*、tool_execution_update→tool_execution.update,未知回退 stream_chunk。
- 前端 ws.ts:解析 message.start/delta/end、thinking.start/delta/end(pendingThinking)、
tool_call.start/end→addTool、tool_execution.update;保留旧 stream_chunk/thinking/tool_used 兼容;
types.ts 补 turnId/seq。Docs/api-client.md 增 §3.1 v0.4。
已知限制(注释/文档标注):turnId 在 OnStream→bus→relay 路径暂为空(StreamEvent 无 turnId 字段,
bus ws.stream 载荷不带 turn);OpenAI adapter 未解析 tool_call 段;thinking 段两 adapter 暂不发;
tool_execution.update 是保留项(随工具循环钩子后置)。go build/vet/test + 前端 tsc 全绿。
61 lines
2.9 KiB
Go
61 lines
2.9 KiB
Go
package model
|
|
|
|
// StreamKind enumerates the kinds of structured events produced while a
|
|
// completion streams. It mirrors OpenClaw's AssistantMessageEvent segments
|
|
// (text / thinking / tool_call) plus a tool-execution progress event, so the
|
|
// frontend can render each segment into its own surface (body, collapsed
|
|
// thinking block, tool card) rather than accumulating a single opaque token
|
|
// stream.
|
|
type StreamKind string
|
|
|
|
const (
|
|
// StreamKindTextStart opens the body-text segment. The single text segment
|
|
// of a response is bracketed by TextStart/TextEnd; deltas fill it.
|
|
StreamKindTextStart StreamKind = "text_start"
|
|
// StreamKindTextDelta is one body-text token fragment.
|
|
StreamKindTextDelta StreamKind = "text_delta"
|
|
// StreamKindTextEnd closes the body-text segment.
|
|
StreamKindTextEnd StreamKind = "text_end"
|
|
|
|
// StreamKindThinkingStart opens a chain-of-thought segment (frontend
|
|
// collapsed block). Reserved: adapters that report reasoning emit it.
|
|
StreamKindThinkingStart StreamKind = "thinking_start"
|
|
// StreamKindThinkingDelta is one reasoning token fragment.
|
|
StreamKindThinkingDelta StreamKind = "thinking_delta"
|
|
// StreamKindThinkingEnd closes a reasoning segment.
|
|
StreamKindThinkingEnd StreamKind = "thinking_end"
|
|
|
|
// StreamKindToolCallStart opens a tool invocation's streaming form.
|
|
StreamKindToolCallStart StreamKind = "tool_call_start"
|
|
// StreamKindToolCallDelta is a fragment of the tool arguments (e.g. the
|
|
// incremental input_json of an Anthropic tool_use block).
|
|
StreamKindToolCallDelta StreamKind = "tool_call_delta"
|
|
// StreamKindToolCallEnd closes a tool invocation block.
|
|
StreamKindToolCallEnd StreamKind = "tool_call_end"
|
|
|
|
// StreamKindToolExecution reports intermediate progress while the loop runs
|
|
// a tool that the model requested (design/04 §1.1 tool_execution_update). It
|
|
// is emitted by the tool loop, not the model adapter; reserved for a later
|
|
// milestone, but the wire mapping is defined so the frontend can react.
|
|
StreamKindToolExecution StreamKind = "tool_execution_update"
|
|
)
|
|
|
|
// StreamEvent is a single structured event in a streamed completion. It replaces
|
|
// the former plain text delta as the unit delivered by Adapter.ChatStream, so a
|
|
// consumer can distinguish body text from tool calls (and, in time, reasoning
|
|
// segments) and track each by Index/ID.
|
|
type StreamEvent struct {
|
|
// Kind classifies the event (see StreamKind).
|
|
Kind StreamKind
|
|
// Delta carries the incremental payload: body text for TextDelta, reasoning
|
|
// text for ThinkingDelta, or a partial_argument fragment for ToolCallDelta.
|
|
Delta string
|
|
// Index is the zero-based content-block index the event belongs to, when the
|
|
// provider reports one. The frontend uses it to correlate a segment's
|
|
// start/delta/end events.
|
|
Index int
|
|
// ID is the provider block/index identifier for a tool call (e.g. Anthropic's
|
|
// tool_use block id). Empty for text segments.
|
|
ID string
|
|
}
|