lc_agents/streaming/
state.rs1use serde_json::Value;
4
5#[derive(Debug, Clone)]
7pub enum ToolCallState {
8 Started {
10 tool_name: String,
12 call_id: String,
14 },
15 ArgumentsStreaming {
17 tool_name: String,
19 call_id: String,
21 partial_args: String,
23 },
24 ArgumentsComplete {
26 tool_name: String,
28 call_id: String,
30 args: Value,
32 },
33 Executing {
35 tool_name: String,
37 call_id: String,
39 },
40 Completed {
42 tool_name: String,
44 call_id: String,
46 result: String,
48 },
49 Failed {
51 tool_name: String,
53 call_id: String,
55 error: String,
57 },
58}
59
60impl ToolCallState {
61 pub fn tool_name(&self) -> &str {
63 match self {
64 ToolCallState::Started { tool_name, .. }
65 | ToolCallState::ArgumentsStreaming { tool_name, .. }
66 | ToolCallState::ArgumentsComplete { tool_name, .. }
67 | ToolCallState::Executing { tool_name, .. }
68 | ToolCallState::Completed { tool_name, .. }
69 | ToolCallState::Failed { tool_name, .. } => tool_name,
70 }
71 }
72
73 pub fn call_id(&self) -> &str {
75 match self {
76 ToolCallState::Started { call_id, .. }
77 | ToolCallState::ArgumentsStreaming { call_id, .. }
78 | ToolCallState::ArgumentsComplete { call_id, .. }
79 | ToolCallState::Executing { call_id, .. }
80 | ToolCallState::Completed { call_id, .. }
81 | ToolCallState::Failed { call_id, .. } => call_id,
82 }
83 }
84}
85
86#[derive(Debug, Clone)]
88pub enum AgentStreamEvent {
89 Text {
91 content: String,
93 },
94
95 ToolCall {
97 state: ToolCallState,
99 },
100
101 ToolStart {
103 name: String,
105 input: String,
107 },
108
109 ToolEnd {
111 name: String,
113 output: String,
115 },
116
117 PipelineStep {
120 step: String,
122 detail: Option<String>,
124 },
125
126 FinalAnswer {
128 content: String,
130 },
131
132 Error {
134 message: String,
136 },
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn test_tool_call_state_accessors() {
145 let s = ToolCallState::Started {
146 tool_name: "calc".to_string(),
147 call_id: "call_1".to_string(),
148 };
149 assert_eq!(s.tool_name(), "calc");
150 assert_eq!(s.call_id(), "call_1");
151 }
152
153 #[test]
154 fn test_completed_state() {
155 let s = ToolCallState::Completed {
156 tool_name: "search".to_string(),
157 call_id: "call_2".to_string(),
158 result: "结果".to_string(),
159 };
160 assert_eq!(s.tool_name(), "search");
161 assert_eq!(s.call_id(), "call_2");
162 }
163
164 #[test]
165 fn test_agent_stream_event_text() {
166 let e = AgentStreamEvent::Text {
167 content: "hello".to_string(),
168 };
169 assert!(matches!(e, AgentStreamEvent::Text { .. }));
170 }
171
172 #[test]
173 fn test_agent_stream_event_final() {
174 let e = AgentStreamEvent::FinalAnswer {
175 content: "done".to_string(),
176 };
177 assert!(matches!(e, AgentStreamEvent::FinalAnswer { .. }));
178 }
179
180 #[test]
181 fn test_agent_stream_event_error() {
182 let e = AgentStreamEvent::Error {
183 message: "stream failed".to_string(),
184 };
185 assert!(matches!(e, AgentStreamEvent::Error { .. }));
186 }
187}