1use serde::{Deserialize, Serialize};
8
9use crate::types::content::Message;
10use crate::types::interrupt::Interrupt;
11use crate::types::streaming::{ContentBlockDelta, Metrics, StopReason, StreamEvent, Usage};
12use crate::types::tools::{ToolResult, ToolUse};
13use crate::types::citations::Citation;
14
15pub trait TypedEvent: Send + Sync {
17 fn is_callback_event(&self) -> bool { true }
19
20 fn as_dict(&self) -> serde_json::Value;
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct InitEventLoopEvent {
27 pub init_event_loop: bool,
28}
29
30impl InitEventLoopEvent {
31 pub fn new() -> Self {
32 Self { init_event_loop: true }
33 }
34}
35
36impl Default for InitEventLoopEvent {
37 fn default() -> Self { Self::new() }
38}
39
40impl TypedEvent for InitEventLoopEvent {
41 fn as_dict(&self) -> serde_json::Value {
42 serde_json::json!({ "init_event_loop": self.init_event_loop })
43 }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct StartEvent {
49 pub start: bool,
50}
51
52impl StartEvent {
53 pub fn new() -> Self {
54 Self { start: true }
55 }
56}
57
58impl Default for StartEvent {
59 fn default() -> Self { Self::new() }
60}
61
62impl TypedEvent for StartEvent {
63 fn as_dict(&self) -> serde_json::Value {
64 serde_json::json!({ "start": self.start })
65 }
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct StartEventLoopEvent {
71 pub start_event_loop: bool,
72}
73
74impl StartEventLoopEvent {
75 pub fn new() -> Self {
76 Self { start_event_loop: true }
77 }
78}
79
80impl Default for StartEventLoopEvent {
81 fn default() -> Self { Self::new() }
82}
83
84impl TypedEvent for StartEventLoopEvent {
85 fn as_dict(&self) -> serde_json::Value {
86 serde_json::json!({ "start_event_loop": self.start_event_loop })
87 }
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct ModelStreamChunkEvent {
93 pub event: StreamEvent,
94}
95
96impl ModelStreamChunkEvent {
97 pub fn new(chunk: StreamEvent) -> Self {
98 Self { event: chunk }
99 }
100
101 pub fn chunk(&self) -> &StreamEvent {
102 &self.event
103 }
104}
105
106impl TypedEvent for ModelStreamChunkEvent {
107 fn as_dict(&self) -> serde_json::Value {
108 serde_json::json!({ "event": self.event })
109 }
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct ModelStreamEvent {
115 #[serde(skip_serializing_if = "Option::is_none")]
116 pub data: Option<String>,
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub delta: Option<ContentBlockDelta>,
119 #[serde(skip_serializing_if = "Option::is_none")]
120 pub reasoning_text: Option<String>,
121 #[serde(skip_serializing_if = "Option::is_none")]
122 pub current_tool_use: Option<serde_json::Value>,
123}
124
125impl ModelStreamEvent {
126 pub fn text(delta: ContentBlockDelta, text: String) -> Self {
127 Self {
128 data: Some(text),
129 delta: Some(delta),
130 reasoning_text: None,
131 current_tool_use: None,
132 }
133 }
134
135 pub fn tool_use(delta: ContentBlockDelta, current_tool_use: serde_json::Value) -> Self {
136 Self {
137 data: None,
138 delta: Some(delta),
139 reasoning_text: None,
140 current_tool_use: Some(current_tool_use),
141 }
142 }
143
144 pub fn reasoning(delta: ContentBlockDelta, reasoning_text: String) -> Self {
145 Self {
146 data: None,
147 delta: Some(delta),
148 reasoning_text: Some(reasoning_text),
149 current_tool_use: None,
150 }
151 }
152}
153
154impl Default for ModelStreamEvent {
155 fn default() -> Self {
156 Self {
157 data: None,
158 delta: None,
159 reasoning_text: None,
160 current_tool_use: None,
161 }
162 }
163}
164
165impl TypedEvent for ModelStreamEvent {
166 fn is_callback_event(&self) -> bool {
167 self.data.is_some() || self.reasoning_text.is_some() || self.current_tool_use.is_some()
168 }
169
170 fn as_dict(&self) -> serde_json::Value {
171 serde_json::to_value(self).unwrap_or_default()
172 }
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct TextStreamEvent {
178 pub data: String,
179 pub delta: ContentBlockDelta,
180}
181
182impl TextStreamEvent {
183 pub fn new(delta: ContentBlockDelta, text: String) -> Self {
184 Self { data: text, delta }
185 }
186}
187
188impl TypedEvent for TextStreamEvent {
189 fn as_dict(&self) -> serde_json::Value {
190 serde_json::json!({ "data": self.data, "delta": self.delta })
191 }
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct CitationStreamEvent {
197 pub citation: Citation,
198 pub delta: ContentBlockDelta,
199}
200
201impl CitationStreamEvent {
202 pub fn new(delta: ContentBlockDelta, citation: Citation) -> Self {
203 Self { citation, delta }
204 }
205}
206
207impl TypedEvent for CitationStreamEvent {
208 fn as_dict(&self) -> serde_json::Value {
209 serde_json::json!({ "citation": self.citation, "delta": self.delta })
210 }
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct ReasoningTextStreamEvent {
216 pub reasoning_text: Option<String>,
217 pub delta: ContentBlockDelta,
218 pub reasoning: bool,
219}
220
221impl ReasoningTextStreamEvent {
222 pub fn new(delta: ContentBlockDelta, reasoning_text: Option<String>) -> Self {
223 Self { reasoning_text, delta, reasoning: true }
224 }
225}
226
227impl TypedEvent for ReasoningTextStreamEvent {
228 fn as_dict(&self) -> serde_json::Value {
229 serde_json::json!({ "reasoningText": self.reasoning_text, "delta": self.delta, "reasoning": self.reasoning })
230 }
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct ModelStopReason {
236 pub stop_reason: StopReason,
237 pub message: Message,
238 pub usage: Usage,
239 pub metrics: Metrics,
240}
241
242impl ModelStopReason {
243 pub fn new(stop_reason: StopReason, message: Message, usage: Usage, metrics: Metrics) -> Self {
244 Self { stop_reason, message, usage, metrics }
245 }
246}
247
248impl TypedEvent for ModelStopReason {
249 fn is_callback_event(&self) -> bool { false }
250
251 fn as_dict(&self) -> serde_json::Value {
252 serde_json::json!({ "stop": [self.stop_reason, self.message, self.usage, self.metrics] })
253 }
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct EventLoopStopEvent {
259 pub stop_reason: StopReason,
260 pub message: Message,
261 pub request_state: serde_json::Value,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 pub interrupts: Option<Vec<Interrupt>>,
264 #[serde(skip_serializing_if = "Option::is_none")]
265 pub structured_output: Option<serde_json::Value>,
266}
267
268impl EventLoopStopEvent {
269 pub fn new(
270 stop_reason: StopReason,
271 message: Message,
272 request_state: serde_json::Value,
273 ) -> Self {
274 Self {
275 stop_reason,
276 message,
277 request_state,
278 interrupts: None,
279 structured_output: None,
280 }
281 }
282
283 pub fn with_interrupts(mut self, interrupts: Vec<Interrupt>) -> Self {
284 self.interrupts = Some(interrupts);
285 self
286 }
287
288 pub fn with_structured_output(mut self, output: serde_json::Value) -> Self {
289 self.structured_output = Some(output);
290 self
291 }
292}
293
294impl TypedEvent for EventLoopStopEvent {
295 fn is_callback_event(&self) -> bool { false }
296
297 fn as_dict(&self) -> serde_json::Value {
298 serde_json::to_value(self).unwrap_or_default()
299 }
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize)]
304pub struct EventLoopThrottleEvent {
305 pub event_loop_throttled_delay: u64,
306}
307
308impl EventLoopThrottleEvent {
309 pub fn new(delay: u64) -> Self {
310 Self { event_loop_throttled_delay: delay }
311 }
312}
313
314impl TypedEvent for EventLoopThrottleEvent {
315 fn as_dict(&self) -> serde_json::Value {
316 serde_json::json!({ "event_loop_throttled_delay": self.event_loop_throttled_delay })
317 }
318}
319
320#[derive(Debug, Clone, Serialize, Deserialize)]
322pub struct ToolResultEvent {
323 pub tool_result: ToolResult,
324}
325
326impl ToolResultEvent {
327 pub fn new(tool_result: ToolResult) -> Self {
328 Self { tool_result }
329 }
330
331 pub fn tool_use_id(&self) -> &str {
332 &self.tool_result.tool_use_id
333 }
334}
335
336impl TypedEvent for ToolResultEvent {
337 fn is_callback_event(&self) -> bool { false }
338
339 fn as_dict(&self) -> serde_json::Value {
340 serde_json::json!({ "type": "tool_result", "tool_result": self.tool_result })
341 }
342}
343
344#[derive(Debug, Clone, Serialize, Deserialize)]
346pub struct ToolStreamEvent {
347 pub tool_use: ToolUse,
348 pub data: serde_json::Value,
349}
350
351impl ToolStreamEvent {
352 pub fn new(tool_use: ToolUse, data: serde_json::Value) -> Self {
353 Self { tool_use, data }
354 }
355
356 pub fn tool_use_id(&self) -> &str {
357 &self.tool_use.tool_use_id
358 }
359}
360
361impl TypedEvent for ToolStreamEvent {
362 fn as_dict(&self) -> serde_json::Value {
363 serde_json::json!({ "type": "tool_stream", "tool_stream_event": { "tool_use": self.tool_use, "data": self.data } })
364 }
365}
366
367#[derive(Debug, Clone, Serialize, Deserialize)]
369pub struct ToolCancelEvent {
370 pub tool_use: ToolUse,
371 pub message: String,
372}
373
374impl ToolCancelEvent {
375 pub fn new(tool_use: ToolUse, message: String) -> Self {
376 Self { tool_use, message }
377 }
378
379 pub fn tool_use_id(&self) -> &str {
380 &self.tool_use.tool_use_id
381 }
382}
383
384impl TypedEvent for ToolCancelEvent {
385 fn as_dict(&self) -> serde_json::Value {
386 serde_json::json!({ "tool_cancel_event": { "tool_use": self.tool_use, "message": self.message } })
387 }
388}
389
390#[derive(Debug, Clone, Serialize, Deserialize)]
392pub struct ToolInterruptEvent {
393 pub tool_use: ToolUse,
394 pub interrupts: Vec<Interrupt>,
395}
396
397impl ToolInterruptEvent {
398 pub fn new(tool_use: ToolUse, interrupts: Vec<Interrupt>) -> Self {
399 Self { tool_use, interrupts }
400 }
401
402 pub fn tool_use_id(&self) -> &str {
403 &self.tool_use.tool_use_id
404 }
405}
406
407impl TypedEvent for ToolInterruptEvent {
408 fn as_dict(&self) -> serde_json::Value {
409 serde_json::json!({ "tool_interrupt_event": { "tool_use": self.tool_use, "interrupts": self.interrupts } })
410 }
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize)]
415pub struct ModelMessageEvent {
416 pub message: Message,
417}
418
419impl ModelMessageEvent {
420 pub fn new(message: Message) -> Self {
421 Self { message }
422 }
423}
424
425impl TypedEvent for ModelMessageEvent {
426 fn as_dict(&self) -> serde_json::Value {
427 serde_json::json!({ "message": self.message })
428 }
429}
430
431#[derive(Debug, Clone, Serialize, Deserialize)]
433pub struct ToolResultMessageEvent {
434 pub message: Message,
435}
436
437impl ToolResultMessageEvent {
438 pub fn new(message: Message) -> Self {
439 Self { message }
440 }
441}
442
443impl TypedEvent for ToolResultMessageEvent {
444 fn as_dict(&self) -> serde_json::Value {
445 serde_json::json!({ "message": self.message })
446 }
447}
448
449#[derive(Debug, Clone, Serialize, Deserialize)]
451pub struct ForceStopEvent {
452 pub force_stop: bool,
453 pub force_stop_reason: String,
454}
455
456impl ForceStopEvent {
457 pub fn new(reason: impl Into<String>) -> Self {
458 Self {
459 force_stop: true,
460 force_stop_reason: reason.into(),
461 }
462 }
463}
464
465impl TypedEvent for ForceStopEvent {
466 fn as_dict(&self) -> serde_json::Value {
467 serde_json::json!({ "force_stop": self.force_stop, "force_stop_reason": self.force_stop_reason })
468 }
469}
470
471#[derive(Debug, Clone, Serialize, Deserialize)]
473pub struct MultiAgentNodeStartEvent {
474 pub node_id: String,
475 pub node_type: String,
476}
477
478impl MultiAgentNodeStartEvent {
479 pub fn new(node_id: impl Into<String>, node_type: impl Into<String>) -> Self {
480 Self {
481 node_id: node_id.into(),
482 node_type: node_type.into(),
483 }
484 }
485}
486
487impl TypedEvent for MultiAgentNodeStartEvent {
488 fn as_dict(&self) -> serde_json::Value {
489 serde_json::json!({ "type": "multiagent_node_start", "node_id": self.node_id, "node_type": self.node_type })
490 }
491}
492
493#[derive(Debug, Clone, Serialize, Deserialize)]
495pub struct MultiAgentNodeStopEvent {
496 pub node_id: String,
497 pub node_result: serde_json::Value,
498}
499
500impl MultiAgentNodeStopEvent {
501 pub fn new(node_id: impl Into<String>, node_result: serde_json::Value) -> Self {
502 Self {
503 node_id: node_id.into(),
504 node_result,
505 }
506 }
507}
508
509impl TypedEvent for MultiAgentNodeStopEvent {
510 fn as_dict(&self) -> serde_json::Value {
511 serde_json::json!({ "type": "multiagent_node_stop", "node_id": self.node_id, "node_result": self.node_result })
512 }
513}
514
515#[derive(Debug, Clone, Serialize, Deserialize)]
517pub struct MultiAgentHandoffEvent {
518 pub from_node_ids: Vec<String>,
519 pub to_node_ids: Vec<String>,
520 #[serde(skip_serializing_if = "Option::is_none")]
521 pub message: Option<String>,
522}
523
524impl MultiAgentHandoffEvent {
525 pub fn new(from_node_ids: Vec<String>, to_node_ids: Vec<String>) -> Self {
526 Self {
527 from_node_ids,
528 to_node_ids,
529 message: None,
530 }
531 }
532
533 pub fn with_message(mut self, message: impl Into<String>) -> Self {
534 self.message = Some(message.into());
535 self
536 }
537}
538
539impl TypedEvent for MultiAgentHandoffEvent {
540 fn as_dict(&self) -> serde_json::Value {
541 let mut value = serde_json::json!({
542 "type": "multiagent_handoff",
543 "from_node_ids": self.from_node_ids,
544 "to_node_ids": self.to_node_ids,
545 });
546 if let Some(ref msg) = self.message {
547 value["message"] = serde_json::json!(msg);
548 }
549 value
550 }
551}
552
553#[derive(Debug, Clone, Serialize, Deserialize)]
555pub struct MultiAgentNodeStreamEvent {
556 pub node_id: String,
557 pub event: serde_json::Value,
558}
559
560impl MultiAgentNodeStreamEvent {
561 pub fn new(node_id: impl Into<String>, event: serde_json::Value) -> Self {
562 Self {
563 node_id: node_id.into(),
564 event,
565 }
566 }
567}
568
569impl TypedEvent for MultiAgentNodeStreamEvent {
570 fn as_dict(&self) -> serde_json::Value {
571 serde_json::json!({ "type": "multiagent_node_stream", "node_id": self.node_id, "event": self.event })
572 }
573}
574
575#[derive(Debug, Clone, Serialize, Deserialize)]
577pub struct MultiAgentNodeCancelEvent {
578 pub node_id: String,
579 pub message: String,
580}
581
582impl MultiAgentNodeCancelEvent {
583 pub fn new(node_id: impl Into<String>, message: impl Into<String>) -> Self {
584 Self {
585 node_id: node_id.into(),
586 message: message.into(),
587 }
588 }
589}
590
591impl TypedEvent for MultiAgentNodeCancelEvent {
592 fn as_dict(&self) -> serde_json::Value {
593 serde_json::json!({ "type": "multiagent_node_cancel", "node_id": self.node_id, "message": self.message })
594 }
595}
596
597#[derive(Debug, Clone, Serialize, Deserialize)]
599pub struct MultiAgentNodeInterruptEvent {
600 pub node_id: String,
601 pub interrupts: Vec<Interrupt>,
602}
603
604impl MultiAgentNodeInterruptEvent {
605 pub fn new(node_id: impl Into<String>, interrupts: Vec<Interrupt>) -> Self {
606 Self {
607 node_id: node_id.into(),
608 interrupts,
609 }
610 }
611}
612
613impl TypedEvent for MultiAgentNodeInterruptEvent {
614 fn as_dict(&self) -> serde_json::Value {
615 serde_json::json!({ "type": "multiagent_node_interrupt", "node_id": self.node_id, "interrupts": self.interrupts })
616 }
617}
618
619#[derive(Debug, Clone, Serialize, Deserialize)]
621#[serde(tag = "type")]
622pub enum AgentEvent {
623 InitEventLoop(InitEventLoopEvent),
624 Start(StartEvent),
625 StartEventLoop(StartEventLoopEvent),
626 ModelStreamChunk(ModelStreamChunkEvent),
627 ModelStream(ModelStreamEvent),
628 TextStream(TextStreamEvent),
629 CitationStream(CitationStreamEvent),
630 ReasoningTextStream(ReasoningTextStreamEvent),
631 ModelStopReason(ModelStopReason),
632 EventLoopStop(EventLoopStopEvent),
633 EventLoopThrottle(EventLoopThrottleEvent),
634 ToolResult(ToolResultEvent),
635 ToolStream(ToolStreamEvent),
636 ToolCancel(ToolCancelEvent),
637 ToolInterrupt(ToolInterruptEvent),
638 ModelMessage(ModelMessageEvent),
639 ToolResultMessage(ToolResultMessageEvent),
640 ForceStop(ForceStopEvent),
641 MultiAgentNodeStart(MultiAgentNodeStartEvent),
642 MultiAgentNodeStop(MultiAgentNodeStopEvent),
643 MultiAgentHandoff(MultiAgentHandoffEvent),
644 MultiAgentNodeStream(MultiAgentNodeStreamEvent),
645 MultiAgentNodeCancel(MultiAgentNodeCancelEvent),
646 MultiAgentNodeInterrupt(MultiAgentNodeInterruptEvent),
647}
648
649impl AgentEvent {
650 pub fn is_callback_event(&self) -> bool {
651 match self {
652 AgentEvent::ModelStopReason(_) => false,
653 AgentEvent::EventLoopStop(_) => false,
654 AgentEvent::ToolResult(_) => false,
655 AgentEvent::ModelStream(e) => e.is_callback_event(),
656 _ => true,
657 }
658 }
659
660 pub fn as_dict(&self) -> serde_json::Value {
661 match self {
662 AgentEvent::InitEventLoop(e) => e.as_dict(),
663 AgentEvent::Start(e) => e.as_dict(),
664 AgentEvent::StartEventLoop(e) => e.as_dict(),
665 AgentEvent::ModelStreamChunk(e) => e.as_dict(),
666 AgentEvent::ModelStream(e) => e.as_dict(),
667 AgentEvent::TextStream(e) => e.as_dict(),
668 AgentEvent::CitationStream(e) => e.as_dict(),
669 AgentEvent::ReasoningTextStream(e) => e.as_dict(),
670 AgentEvent::ModelStopReason(e) => e.as_dict(),
671 AgentEvent::EventLoopStop(e) => e.as_dict(),
672 AgentEvent::EventLoopThrottle(e) => e.as_dict(),
673 AgentEvent::ToolResult(e) => e.as_dict(),
674 AgentEvent::ToolStream(e) => e.as_dict(),
675 AgentEvent::ToolCancel(e) => e.as_dict(),
676 AgentEvent::ToolInterrupt(e) => e.as_dict(),
677 AgentEvent::ModelMessage(e) => e.as_dict(),
678 AgentEvent::ToolResultMessage(e) => e.as_dict(),
679 AgentEvent::ForceStop(e) => e.as_dict(),
680 AgentEvent::MultiAgentNodeStart(e) => e.as_dict(),
681 AgentEvent::MultiAgentNodeStop(e) => e.as_dict(),
682 AgentEvent::MultiAgentHandoff(e) => e.as_dict(),
683 AgentEvent::MultiAgentNodeStream(e) => e.as_dict(),
684 AgentEvent::MultiAgentNodeCancel(e) => e.as_dict(),
685 AgentEvent::MultiAgentNodeInterrupt(e) => e.as_dict(),
686 }
687 }
688}
689
690#[cfg(test)]
691mod tests {
692 use super::*;
693
694 #[test]
695 fn test_init_event_loop_event() {
696 let event = InitEventLoopEvent::new();
697 assert!(event.is_callback_event());
698 let dict = event.as_dict();
699 assert_eq!(dict["init_event_loop"], true);
700 }
701
702 #[test]
703 fn test_model_stream_event() {
704 let delta = ContentBlockDelta::default();
705 let event = ModelStreamEvent::text(delta, "Hello".to_string());
706 assert!(event.is_callback_event());
707 }
708
709 #[test]
710 fn test_empty_model_stream_event() {
711 let event = ModelStreamEvent::default();
712 assert!(!event.is_callback_event());
713 }
714
715 #[test]
716 fn test_force_stop_event() {
717 let event = ForceStopEvent::new("Test reason");
718 assert!(event.force_stop);
719 assert_eq!(event.force_stop_reason, "Test reason");
720 }
721}
722