claude_agent/agent/
events.rs1use super::state::{AgentMetrics, AgentState};
4use crate::types::{Message, StopReason, Usage};
5
6#[derive(Debug, Clone)]
8pub enum AgentEvent {
9 Text(String),
10 Thinking(String),
11 ToolComplete {
12 id: String,
13 name: String,
14 output: String,
15 is_error: bool,
16 duration_ms: u64,
17 },
18 ToolBlocked {
19 id: String,
20 name: String,
21 reason: String,
22 },
23 ContextUpdate {
24 used_tokens: u64,
25 max_tokens: u64,
26 },
27 Complete(Box<AgentResult>),
28}
29
30#[derive(Debug, Clone)]
32pub struct AgentResult {
33 pub text: String,
34 pub usage: Usage,
35 pub tool_calls: usize,
36 pub iterations: usize,
37 pub stop_reason: StopReason,
38 pub state: AgentState,
39 pub metrics: AgentMetrics,
40 pub session_id: String,
41 pub structured_output: Option<serde_json::Value>,
42 pub messages: Vec<Message>,
43 pub uuid: String,
45}
46
47impl AgentResult {
48 pub(crate) fn new(
49 text: String,
50 usage: Usage,
51 iterations: usize,
52 stop_reason: StopReason,
53 metrics: AgentMetrics,
54 session_id: String,
55 structured_output: Option<serde_json::Value>,
56 messages: Vec<Message>,
57 ) -> Self {
58 Self {
59 tool_calls: metrics.tool_calls,
60 state: AgentState::Completed,
61 uuid: uuid::Uuid::new_v4().to_string(),
62 text,
63 usage,
64 iterations,
65 stop_reason,
66 metrics,
67 session_id,
68 structured_output,
69 messages,
70 }
71 }
72
73 #[must_use]
74 pub fn text(&self) -> &str {
75 &self.text
76 }
77
78 #[must_use]
79 pub fn total_tokens(&self) -> u32 {
80 self.usage.total()
81 }
82
83 #[must_use]
84 pub fn metrics(&self) -> &AgentMetrics {
85 &self.metrics
86 }
87
88 #[must_use]
89 pub fn session_id(&self) -> &str {
90 &self.session_id
91 }
92
93 pub fn extract<T: serde::de::DeserializeOwned>(&self) -> crate::Result<T> {
94 let value = self
95 .structured_output
96 .as_ref()
97 .ok_or_else(|| crate::Error::Parse("No structured output available".to_string()))?;
98 serde_json::from_value(value.clone()).map_err(|e| crate::Error::Parse(e.to_string()))
99 }
100}