Skip to main content

neuron_types/
stream.rs

1//! Streaming event types for incremental LLM responses.
2
3use std::fmt;
4use std::pin::Pin;
5
6use futures::Stream;
7
8use crate::types::{Message, TokenUsage};
9
10/// Error information from a stream event.
11#[derive(Debug, Clone)]
12pub struct StreamError {
13    /// Human-readable error message.
14    pub message: String,
15    /// Whether the error is retryable (e.g., rate limit, transient network).
16    pub is_retryable: bool,
17}
18
19impl StreamError {
20    /// Create a non-retryable error from a message string.
21    #[must_use]
22    pub fn non_retryable(message: impl Into<String>) -> Self {
23        Self {
24            message: message.into(),
25            is_retryable: false,
26        }
27    }
28
29    /// Create a retryable error from a message string.
30    #[must_use]
31    pub fn retryable(message: impl Into<String>) -> Self {
32        Self {
33            message: message.into(),
34            is_retryable: true,
35        }
36    }
37}
38
39impl fmt::Display for StreamError {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        write!(f, "{}", self.message)
42    }
43}
44
45/// An event emitted during streaming completion.
46#[derive(Debug, Clone)]
47pub enum StreamEvent {
48    /// Incremental text content.
49    TextDelta(String),
50    /// Incremental thinking/reasoning content.
51    ThinkingDelta(String),
52    /// Incremental signature content for thinking verification.
53    SignatureDelta(String),
54    /// A tool use block has started.
55    ToolUseStart {
56        /// Tool call identifier.
57        id: String,
58        /// Tool name.
59        name: String,
60    },
61    /// Incremental tool input JSON.
62    ToolUseInputDelta {
63        /// Tool call identifier (matches `ToolUseStart.id`).
64        id: String,
65        /// JSON fragment.
66        delta: String,
67    },
68    /// A tool use block has ended.
69    ToolUseEnd {
70        /// Tool call identifier.
71        id: String,
72    },
73    /// The complete assembled message (sent at the end of the stream).
74    MessageComplete(Message),
75    /// Token usage statistics for the stream.
76    Usage(TokenUsage),
77    /// An error occurred during streaming.
78    Error(StreamError),
79}
80
81/// Handle to a streaming completion response.
82pub struct StreamHandle {
83    /// The stream of events. Consume with `StreamExt::next()`.
84    pub receiver: Pin<Box<dyn Stream<Item = StreamEvent> + Send>>,
85}
86
87impl fmt::Debug for StreamHandle {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        f.debug_struct("StreamHandle").finish_non_exhaustive()
90    }
91}