atomcode_core/stream/mod.rs
1use crate::tool::ToolCall;
2
3#[derive(Debug, Clone)]
4pub struct TokenUsage {
5 pub prompt_tokens: usize,
6 pub completion_tokens: usize,
7 /// Tokens served from provider's prompt cache (0 if not supported).
8 pub cached_tokens: usize,
9}
10
11#[derive(Debug, Clone)]
12pub enum StreamEvent {
13 Delta(String),
14 /// Reasoning-model thinking content (e.g. MiniMax-M2.7, DeepSeek-R1,
15 /// o1-series). Some OpenAI-compatible gateways route the full response
16 /// here when `content` is empty — `TurnRunner` promotes it to the
17 /// final text on `Done` if `content` ends up empty, which keeps us from
18 /// silently returning 0-token "Nailed it" responses for reasoning models.
19 Reasoning(String),
20 /// One complete Anthropic extended-thinking content block. Emitted at
21 /// `content_block_stop` by claude.rs after both `thinking_delta` and
22 /// `signature_delta` have streamed in for a given block. The runner
23 /// accumulates these into `MessageContent::AssistantWithToolCalls.
24 /// thinking_blocks` so the next request can echo them back verbatim
25 /// (Anthropic 400s otherwise: `The content[].thinking in the thinking
26 /// mode must be passed back to the API`). Atomic per-block (vs
27 /// streaming text + signature separately) keeps the runner from
28 /// having to pair up out-of-order deltas across content blocks.
29 ThinkingBlock {
30 text: String,
31 signature: String,
32 },
33 ToolCallStart {
34 id: String,
35 name: String,
36 },
37 ToolCallDelta(String),
38 ToolCallDone(ToolCall),
39 Usage(TokenUsage),
40 /// Stream finished. `truncated` = true means finish_reason was "length"
41 /// (model hit max_tokens and was cut off, should continue).
42 Done {
43 truncated: bool,
44 },
45 Error(String),
46 /// Non-fatal advisory the provider wants surfaced to the user. Unlike
47 /// `Error`, the stream and the turn continue normally — the warning
48 /// is a heads-up (e.g. "your proxy looks like it's truncating
49 /// input"), not a failure. The runner forwards it to
50 /// `TurnEvent::Warning` so the TUI can render it without aborting.
51 Warning(String),
52}