Skip to main content

synwire_core/agents/
streaming.rs

1//! Streaming events for agents.
2
3use crate::agents::usage::Usage;
4use crate::tools::ToolOutput;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// Agent streaming event.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(tag = "type")]
11#[non_exhaustive]
12pub enum AgentEvent {
13    /// Text delta (streaming).
14    #[serde(rename = "text_delta")]
15    TextDelta {
16        /// Content chunk.
17        content: String,
18    },
19
20    /// Tool call started.
21    #[serde(rename = "tool_call_start")]
22    ToolCallStart {
23        /// Tool call ID.
24        id: String,
25        /// Tool name.
26        name: String,
27    },
28
29    /// Tool call arguments delta (streaming).
30    #[serde(rename = "tool_call_delta")]
31    ToolCallDelta {
32        /// Tool call ID.
33        id: String,
34        /// Arguments delta.
35        arguments_delta: String,
36    },
37
38    /// Tool call ended.
39    #[serde(rename = "tool_call_end")]
40    ToolCallEnd {
41        /// Tool call ID.
42        id: String,
43    },
44
45    /// Tool execution result.
46    #[serde(rename = "tool_result")]
47    ToolResult {
48        /// Tool call ID.
49        id: String,
50        /// Tool output.
51        output: ToolOutput,
52    },
53
54    /// Tool execution progress.
55    #[serde(rename = "tool_progress")]
56    ToolProgress {
57        /// Tool call ID.
58        id: String,
59        /// Progress message.
60        message: String,
61        /// Progress percentage (0.0-1.0).
62        progress_pct: Option<f32>,
63    },
64
65    /// State update patch.
66    #[serde(rename = "state_update")]
67    StateUpdate {
68        /// JSON patch for state.
69        patch: Value,
70    },
71
72    /// Directive emitted by agent.
73    #[serde(rename = "directive_emitted")]
74    DirectiveEmitted {
75        /// Directive (serialized as Value to avoid circular dependency).
76        directive: Value,
77    },
78
79    /// Status update.
80    #[serde(rename = "status_update")]
81    StatusUpdate {
82        /// Status message.
83        status: String,
84        /// Progress percentage (0.0-1.0).
85        progress_pct: Option<f32>,
86    },
87
88    /// Usage statistics update.
89    #[serde(rename = "usage_update")]
90    UsageUpdate {
91        /// Token usage.
92        usage: Usage,
93    },
94
95    /// Rate limit information.
96    #[serde(rename = "rate_limit_info")]
97    RateLimitInfo {
98        /// Utilization percentage (0.0-1.0).
99        utilization_pct: f32,
100        /// Reset timestamp (Unix seconds).
101        reset_at: i64,
102        /// Whether request was allowed.
103        allowed: bool,
104    },
105
106    /// Task notification.
107    #[serde(rename = "task_notification")]
108    TaskNotification {
109        /// Task ID.
110        task_id: String,
111        /// Event kind.
112        kind: TaskEventKind,
113        /// Event payload.
114        payload: Value,
115    },
116
117    /// Prompt suggestion.
118    #[serde(rename = "prompt_suggestion")]
119    PromptSuggestion {
120        /// Suggested prompts.
121        suggestions: Vec<String>,
122    },
123
124    /// Turn completed.
125    #[serde(rename = "turn_complete")]
126    TurnComplete {
127        /// Termination reason.
128        reason: TerminationReason,
129    },
130
131    /// Error occurred.
132    #[serde(rename = "error")]
133    Error {
134        /// Error message.
135        message: String,
136    },
137}
138
139impl AgentEvent {
140    /// Returns whether this event signals the final response.
141    #[must_use]
142    pub const fn is_final_response(&self) -> bool {
143        matches!(self, Self::TurnComplete { .. } | Self::Error { .. })
144    }
145}
146
147/// Task event kind.
148#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
149#[non_exhaustive]
150pub enum TaskEventKind {
151    /// Task started.
152    #[serde(rename = "started")]
153    Started,
154    /// Task progressed.
155    #[serde(rename = "progress")]
156    Progress,
157    /// Task completed.
158    #[serde(rename = "completed")]
159    Completed,
160    /// Task failed.
161    #[serde(rename = "failed")]
162    Failed,
163}
164
165/// Termination reason for turn completion.
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
167#[non_exhaustive]
168pub enum TerminationReason {
169    /// Agent finished normally.
170    #[serde(rename = "complete")]
171    Complete,
172    /// Turn limit reached.
173    #[serde(rename = "max_turns_exceeded")]
174    MaxTurnsExceeded,
175    /// Cost limit reached.
176    #[serde(rename = "budget_exceeded")]
177    BudgetExceeded,
178    /// Graceful stop requested.
179    #[serde(rename = "stopped")]
180    Stopped,
181    /// Force stop.
182    #[serde(rename = "aborted")]
183    Aborted,
184    /// Terminated due to error.
185    #[serde(rename = "error")]
186    Error,
187}