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 // SessionID is the conversation the streamed event belongs to. It is stamped // by the loop at the turn boundary (loop.streamStep), which reads the session // the Run was started for; a model adapter, running below the loop and with no // notion of a session, leaves it zero. A consumer that routes the event (the // WS hub) reads it to target the right conversation. SessionID string // TurnID is the assistant turn the event belongs to. Like SessionID it is // stamped by the loop, which reads the turn identity the caller attached with // loop.WithTurnID; it is zero when no turn id was attached, so a consumer must // treat both fields as best-effort correlation rather than a hard guarantee. TurnID string }