1mod recover_max_tokens;
8
9pub use recover_max_tokens::recover_message_on_max_tokens_reached;
10
11use std::any::Any;
12use std::collections::HashMap;
13
14use crate::agent::AgentResult;
15use crate::hooks::Interrupt;
16use crate::telemetry::EventLoopMetrics;
17use crate::types::citations::Citation;
18use crate::types::content::Message;
19use crate::types::streaming::{ContentBlockDelta, Metrics, StopReason, StreamEvent, Usage};
20use crate::types::tools::{ToolResult as ToolResultType, ToolUse};
21
22pub trait TypedEventBase: Send + Sync + std::fmt::Debug {
24 fn is_callback_event(&self) -> bool {
26 true
27 }
28
29 fn as_dict(&self) -> HashMap<String, serde_json::Value>;
31
32 fn prepare(&mut self, _invocation_state: &HashMap<String, serde_json::Value>) {}
34
35 fn as_any(&self) -> &dyn Any;
37}
38
39#[derive(Debug, Clone, Default)]
41pub struct InitEventLoopEvent {
42 pub state: HashMap<String, serde_json::Value>,
43}
44
45impl InitEventLoopEvent {
46 pub fn new() -> Self {
47 Self {
48 state: HashMap::new(),
49 }
50 }
51}
52
53impl TypedEventBase for InitEventLoopEvent {
54 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
55 let mut map = HashMap::new();
56 map.insert("init_event_loop".to_string(), serde_json::Value::Bool(true));
57 map.extend(self.state.clone());
58 map
59 }
60
61 fn prepare(&mut self, invocation_state: &HashMap<String, serde_json::Value>) {
62 self.state.extend(invocation_state.clone());
63 }
64
65 fn as_any(&self) -> &dyn Any {
66 self
67 }
68}
69
70#[derive(Debug, Clone, Default)]
72pub struct StartEvent;
73
74impl TypedEventBase for StartEvent {
75 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
76 let mut map = HashMap::new();
77 map.insert("start".to_string(), serde_json::Value::Bool(true));
78 map
79 }
80
81 fn as_any(&self) -> &dyn Any {
82 self
83 }
84}
85
86#[derive(Debug, Clone, Default)]
88pub struct StartEventLoopEvent;
89
90impl TypedEventBase for StartEventLoopEvent {
91 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
92 let mut map = HashMap::new();
93 map.insert("start_event_loop".to_string(), serde_json::Value::Bool(true));
94 map
95 }
96
97 fn as_any(&self) -> &dyn Any {
98 self
99 }
100}
101
102#[derive(Debug, Clone)]
104pub struct ModelStreamChunkEvent {
105 pub chunk: StreamEvent,
106}
107
108impl ModelStreamChunkEvent {
109 pub fn new(chunk: StreamEvent) -> Self {
110 Self { chunk }
111 }
112}
113
114impl TypedEventBase for ModelStreamChunkEvent {
115 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
116 let mut map = HashMap::new();
117 map.insert(
118 "event".to_string(),
119 serde_json::to_value(&self.chunk).unwrap_or_default(),
120 );
121 map
122 }
123
124 fn as_any(&self) -> &dyn Any {
125 self
126 }
127}
128
129#[derive(Debug, Clone, Default)]
131pub struct ModelStreamEvent {
132 pub delta_data: HashMap<String, serde_json::Value>,
133}
134
135impl ModelStreamEvent {
136 pub fn new(delta_data: HashMap<String, serde_json::Value>) -> Self {
137 Self { delta_data }
138 }
139}
140
141impl TypedEventBase for ModelStreamEvent {
142 fn is_callback_event(&self) -> bool {
143 !self.delta_data.is_empty()
144 }
145
146 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
147 self.delta_data.clone()
148 }
149
150 fn prepare(&mut self, invocation_state: &HashMap<String, serde_json::Value>) {
151 if self.delta_data.contains_key("delta") {
152 self.delta_data.extend(invocation_state.clone());
153 }
154 }
155
156 fn as_any(&self) -> &dyn Any {
157 self
158 }
159}
160
161#[derive(Debug, Clone)]
163pub struct ToolUseStreamEvent {
164 pub delta: ContentBlockDelta,
165 pub current_tool_use: HashMap<String, serde_json::Value>,
166}
167
168impl ToolUseStreamEvent {
169 pub fn new(delta: ContentBlockDelta, current_tool_use: HashMap<String, serde_json::Value>) -> Self {
170 Self { delta, current_tool_use }
171 }
172}
173
174impl TypedEventBase for ToolUseStreamEvent {
175 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
176 let mut map = HashMap::new();
177 map.insert("type".to_string(), serde_json::Value::String("tool_use_stream".to_string()));
178 map.insert("delta".to_string(), serde_json::to_value(&self.delta).unwrap_or_default());
179 map.insert("current_tool_use".to_string(), serde_json::to_value(&self.current_tool_use).unwrap_or_default());
180 map
181 }
182
183 fn as_any(&self) -> &dyn Any {
184 self
185 }
186}
187
188#[derive(Debug, Clone)]
190pub struct TextStreamEvent {
191 pub delta: ContentBlockDelta,
192 pub text: String,
193}
194
195impl TextStreamEvent {
196 pub fn new(delta: ContentBlockDelta, text: impl Into<String>) -> Self {
197 Self { delta, text: text.into() }
198 }
199}
200
201impl TypedEventBase for TextStreamEvent {
202 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
203 let mut map = HashMap::new();
204 map.insert("data".to_string(), serde_json::Value::String(self.text.clone()));
205 map.insert("delta".to_string(), serde_json::to_value(&self.delta).unwrap_or_default());
206 map
207 }
208
209 fn as_any(&self) -> &dyn Any {
210 self
211 }
212}
213
214#[derive(Debug, Clone)]
216pub struct CitationStreamEvent {
217 pub delta: ContentBlockDelta,
218 pub citation: Citation,
219}
220
221impl CitationStreamEvent {
222 pub fn new(delta: ContentBlockDelta, citation: Citation) -> Self {
223 Self { delta, citation }
224 }
225}
226
227impl TypedEventBase for CitationStreamEvent {
228 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
229 let mut map = HashMap::new();
230 map.insert("citation".to_string(), serde_json::to_value(&self.citation).unwrap_or_default());
231 map.insert("delta".to_string(), serde_json::to_value(&self.delta).unwrap_or_default());
232 map
233 }
234
235 fn as_any(&self) -> &dyn Any {
236 self
237 }
238}
239
240#[derive(Debug, Clone)]
242pub struct ReasoningTextStreamEvent {
243 pub delta: ContentBlockDelta,
244 pub reasoning_text: Option<String>,
245}
246
247impl ReasoningTextStreamEvent {
248 pub fn new(delta: ContentBlockDelta, reasoning_text: Option<String>) -> Self {
249 Self { delta, reasoning_text }
250 }
251}
252
253impl TypedEventBase for ReasoningTextStreamEvent {
254 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
255 let mut map = HashMap::new();
256 map.insert("reasoningText".to_string(), serde_json::to_value(&self.reasoning_text).unwrap_or_default());
257 map.insert("delta".to_string(), serde_json::to_value(&self.delta).unwrap_or_default());
258 map.insert("reasoning".to_string(), serde_json::Value::Bool(true));
259 map
260 }
261
262 fn as_any(&self) -> &dyn Any {
263 self
264 }
265}
266
267#[derive(Debug, Clone)]
269pub struct ReasoningRedactedContentStreamEvent {
270 pub delta: ContentBlockDelta,
271 pub redacted_content: Option<Vec<u8>>,
272}
273
274impl ReasoningRedactedContentStreamEvent {
275 pub fn new(delta: ContentBlockDelta, redacted_content: Option<Vec<u8>>) -> Self {
276 Self { delta, redacted_content }
277 }
278}
279
280impl TypedEventBase for ReasoningRedactedContentStreamEvent {
281 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
282 let mut map = HashMap::new();
283 map.insert("reasoningRedactedContent".to_string(), serde_json::to_value(&self.redacted_content).unwrap_or_default());
284 map.insert("delta".to_string(), serde_json::to_value(&self.delta).unwrap_or_default());
285 map.insert("reasoning".to_string(), serde_json::Value::Bool(true));
286 map
287 }
288
289 fn as_any(&self) -> &dyn Any {
290 self
291 }
292}
293
294#[derive(Debug, Clone)]
296pub struct ReasoningSignatureStreamEvent {
297 pub delta: ContentBlockDelta,
298 pub reasoning_signature: Option<String>,
299}
300
301impl ReasoningSignatureStreamEvent {
302 pub fn new(delta: ContentBlockDelta, reasoning_signature: Option<String>) -> Self {
303 Self { delta, reasoning_signature }
304 }
305}
306
307impl TypedEventBase for ReasoningSignatureStreamEvent {
308 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
309 let mut map = HashMap::new();
310 map.insert("reasoning_signature".to_string(), serde_json::to_value(&self.reasoning_signature).unwrap_or_default());
311 map.insert("delta".to_string(), serde_json::to_value(&self.delta).unwrap_or_default());
312 map.insert("reasoning".to_string(), serde_json::Value::Bool(true));
313 map
314 }
315
316 fn as_any(&self) -> &dyn Any {
317 self
318 }
319}
320
321#[derive(Debug, Clone)]
323pub struct ModelStopReasonEvent {
324 pub stop_reason: StopReason,
325 pub message: Message,
326 pub usage: Usage,
327 pub metrics: Metrics,
328}
329
330impl ModelStopReasonEvent {
331 pub fn new(stop_reason: StopReason, message: Message, usage: Usage, metrics: Metrics) -> Self {
332 Self { stop_reason, message, usage, metrics }
333 }
334}
335
336impl TypedEventBase for ModelStopReasonEvent {
337 fn is_callback_event(&self) -> bool {
338 false
339 }
340
341 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
342 let mut map = HashMap::new();
343 map.insert(
344 "stop".to_string(),
345 serde_json::json!([
346 self.stop_reason,
347 self.message,
348 self.usage,
349 self.metrics
350 ]),
351 );
352 map
353 }
354
355 fn as_any(&self) -> &dyn Any {
356 self
357 }
358}
359
360#[derive(Debug, Clone)]
362pub struct EventLoopStopEvent {
363 pub stop_reason: StopReason,
364 pub message: Message,
365 pub metrics: EventLoopMetrics,
366 pub request_state: serde_json::Value,
367 pub interrupts: Option<Vec<Interrupt>>,
368 pub structured_output: Option<serde_json::Value>,
369}
370
371impl EventLoopStopEvent {
372 pub fn new(
373 stop_reason: StopReason,
374 message: Message,
375 metrics: EventLoopMetrics,
376 request_state: serde_json::Value,
377 ) -> Self {
378 Self {
379 stop_reason,
380 message,
381 metrics,
382 request_state,
383 interrupts: None,
384 structured_output: None,
385 }
386 }
387
388 pub fn with_interrupts(mut self, interrupts: Vec<Interrupt>) -> Self {
389 self.interrupts = Some(interrupts);
390 self
391 }
392
393 pub fn with_structured_output(mut self, output: serde_json::Value) -> Self {
394 self.structured_output = Some(output);
395 self
396 }
397
398 fn interrupts_to_json(&self) -> serde_json::Value {
399 match &self.interrupts {
400 Some(interrupts) => serde_json::Value::Array(
401 interrupts
402 .iter()
403 .map(|i| {
404 serde_json::json!({
405 "id": i.id,
406 "name": i.name,
407 "reason": i.reason
408 })
409 })
410 .collect(),
411 ),
412 None => serde_json::Value::Null,
413 }
414 }
415}
416
417impl TypedEventBase for EventLoopStopEvent {
418 fn is_callback_event(&self) -> bool {
419 false
420 }
421
422 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
423 let mut map = HashMap::new();
424 map.insert(
425 "stop".to_string(),
426 serde_json::json!([
427 self.stop_reason,
428 self.message,
429 self.metrics.get_summary(),
430 self.request_state,
431 self.interrupts_to_json(),
432 self.structured_output
433 ]),
434 );
435 map
436 }
437
438 fn as_any(&self) -> &dyn Any {
439 self
440 }
441}
442
443#[derive(Debug, Clone)]
445pub struct StructuredOutputEvent {
446 pub structured_output: serde_json::Value,
447}
448
449impl StructuredOutputEvent {
450 pub fn new(structured_output: serde_json::Value) -> Self {
451 Self { structured_output }
452 }
453}
454
455impl TypedEventBase for StructuredOutputEvent {
456 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
457 let mut map = HashMap::new();
458 map.insert("structured_output".to_string(), self.structured_output.clone());
459 map
460 }
461
462 fn as_any(&self) -> &dyn Any {
463 self
464 }
465}
466
467#[derive(Debug, Clone)]
469pub struct EventLoopThrottleEvent {
470 pub delay: u32,
471 pub state: HashMap<String, serde_json::Value>,
472}
473
474impl EventLoopThrottleEvent {
475 pub fn new(delay: u32) -> Self {
476 Self {
477 delay,
478 state: HashMap::new(),
479 }
480 }
481}
482
483impl TypedEventBase for EventLoopThrottleEvent {
484 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
485 let mut map = HashMap::new();
486 map.insert("event_loop_throttled_delay".to_string(), serde_json::Value::Number(self.delay.into()));
487 map.extend(self.state.clone());
488 map
489 }
490
491 fn prepare(&mut self, invocation_state: &HashMap<String, serde_json::Value>) {
492 self.state.extend(invocation_state.clone());
493 }
494
495 fn as_any(&self) -> &dyn Any {
496 self
497 }
498}
499
500#[derive(Debug, Clone)]
502pub struct ToolResultEvent {
503 pub tool_result: ToolResultType,
504}
505
506impl ToolResultEvent {
507 pub fn new(tool_result: ToolResultType) -> Self {
508 Self { tool_result }
509 }
510
511 pub fn tool_use_id(&self) -> &str {
512 &self.tool_result.tool_use_id
513 }
514}
515
516impl TypedEventBase for ToolResultEvent {
517 fn is_callback_event(&self) -> bool {
518 false
519 }
520
521 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
522 let mut map = HashMap::new();
523 map.insert("type".to_string(), serde_json::Value::String("tool_result".to_string()));
524 map.insert("tool_result".to_string(), serde_json::to_value(&self.tool_result).unwrap_or_default());
525 map
526 }
527
528 fn as_any(&self) -> &dyn Any {
529 self
530 }
531}
532
533#[derive(Debug, Clone)]
535pub struct ToolStreamEvent {
536 pub tool_use: ToolUse,
537 pub tool_stream_data: serde_json::Value,
538}
539
540impl ToolStreamEvent {
541 pub fn new(tool_use: ToolUse, tool_stream_data: serde_json::Value) -> Self {
542 Self { tool_use, tool_stream_data }
543 }
544
545 pub fn tool_use_id(&self) -> &str {
546 &self.tool_use.tool_use_id
547 }
548}
549
550impl TypedEventBase for ToolStreamEvent {
551 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
552 let mut map = HashMap::new();
553 map.insert("type".to_string(), serde_json::Value::String("tool_stream".to_string()));
554 map.insert(
555 "tool_stream_event".to_string(),
556 serde_json::json!({
557 "tool_use": self.tool_use,
558 "data": self.tool_stream_data
559 }),
560 );
561 map
562 }
563
564 fn as_any(&self) -> &dyn Any {
565 self
566 }
567}
568
569#[derive(Debug, Clone)]
571pub struct ToolCancelEvent {
572 pub tool_use: ToolUse,
573 pub message: String,
574}
575
576impl ToolCancelEvent {
577 pub fn new(tool_use: ToolUse, message: impl Into<String>) -> Self {
578 Self { tool_use, message: message.into() }
579 }
580
581 pub fn tool_use_id(&self) -> &str {
582 &self.tool_use.tool_use_id
583 }
584}
585
586impl TypedEventBase for ToolCancelEvent {
587 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
588 let mut map = HashMap::new();
589 map.insert(
590 "tool_cancel_event".to_string(),
591 serde_json::json!({
592 "tool_use": self.tool_use,
593 "message": self.message
594 }),
595 );
596 map
597 }
598
599 fn as_any(&self) -> &dyn Any {
600 self
601 }
602}
603
604#[derive(Debug, Clone)]
606pub struct ToolInterruptEvent {
607 pub tool_use: ToolUse,
608 pub interrupts: Vec<Interrupt>,
609}
610
611impl ToolInterruptEvent {
612 pub fn new(tool_use: ToolUse, interrupts: Vec<Interrupt>) -> Self {
613 Self { tool_use, interrupts }
614 }
615
616 pub fn tool_use_id(&self) -> &str {
617 &self.tool_use.tool_use_id
618 }
619}
620
621impl TypedEventBase for ToolInterruptEvent {
622 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
623 let mut map = HashMap::new();
624 map.insert(
625 "tool_interrupt_event".to_string(),
626 serde_json::json!({
627 "tool_use": self.tool_use,
628 "interrupts": self.interrupts.iter().map(|i| {
629 serde_json::json!({
630 "id": i.id,
631 "name": i.name,
632 "reason": i.reason
633 })
634 }).collect::<Vec<_>>()
635 }),
636 );
637 map
638 }
639
640 fn as_any(&self) -> &dyn Any {
641 self
642 }
643}
644
645#[derive(Debug, Clone)]
647pub struct ModelMessageEvent {
648 pub message: Message,
649}
650
651impl ModelMessageEvent {
652 pub fn new(message: Message) -> Self {
653 Self { message }
654 }
655}
656
657impl TypedEventBase for ModelMessageEvent {
658 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
659 let mut map = HashMap::new();
660 map.insert("message".to_string(), serde_json::to_value(&self.message).unwrap_or_default());
661 map
662 }
663
664 fn as_any(&self) -> &dyn Any {
665 self
666 }
667}
668
669#[derive(Debug, Clone)]
671pub struct ToolResultMessageEvent {
672 pub message: Message,
673}
674
675impl ToolResultMessageEvent {
676 pub fn new(message: Message) -> Self {
677 Self { message }
678 }
679}
680
681impl TypedEventBase for ToolResultMessageEvent {
682 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
683 let mut map = HashMap::new();
684 map.insert("message".to_string(), serde_json::to_value(&self.message).unwrap_or_default());
685 map
686 }
687
688 fn as_any(&self) -> &dyn Any {
689 self
690 }
691}
692
693#[derive(Debug, Clone)]
695pub struct ForceStopEvent {
696 pub reason: String,
697}
698
699impl ForceStopEvent {
700 pub fn new(reason: impl Into<String>) -> Self {
701 Self { reason: reason.into() }
702 }
703
704 pub fn from_error(err: &dyn std::error::Error) -> Self {
705 Self { reason: err.to_string() }
706 }
707}
708
709impl TypedEventBase for ForceStopEvent {
710 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
711 let mut map = HashMap::new();
712 map.insert("force_stop".to_string(), serde_json::Value::Bool(true));
713 map.insert("force_stop_reason".to_string(), serde_json::Value::String(self.reason.clone()));
714 map
715 }
716
717 fn as_any(&self) -> &dyn Any {
718 self
719 }
720}
721
722#[derive(Debug, Clone)]
724pub struct AgentResultEvent {
725 pub result: AgentResult,
726}
727
728impl AgentResultEvent {
729 pub fn new(result: AgentResult) -> Self {
730 Self { result }
731 }
732}
733
734impl TypedEventBase for AgentResultEvent {
735 fn as_dict(&self) -> HashMap<String, serde_json::Value> {
736 let mut map = HashMap::new();
737 map.insert("result".to_string(), serde_json::to_value(&self.result).unwrap_or_default());
738 map
739 }
740
741 fn as_any(&self) -> &dyn Any {
742 self
743 }
744}
745
746#[derive(Debug, Clone)]
748pub enum TypedEvent {
749 InitEventLoop(InitEventLoopEvent),
750 Start(StartEvent),
751 StartEventLoop(StartEventLoopEvent),
752 ModelStreamChunk(ModelStreamChunkEvent),
753 ModelStream(ModelStreamEvent),
754 ToolUseStream(ToolUseStreamEvent),
755 TextStream(TextStreamEvent),
756 CitationStream(CitationStreamEvent),
757 ReasoningTextStream(ReasoningTextStreamEvent),
758 ReasoningRedactedContentStream(ReasoningRedactedContentStreamEvent),
759 ReasoningSignatureStream(ReasoningSignatureStreamEvent),
760 ModelStopReason(ModelStopReasonEvent),
761 EventLoopStop(EventLoopStopEvent),
762 StructuredOutput(StructuredOutputEvent),
763 EventLoopThrottle(EventLoopThrottleEvent),
764 ToolResult(ToolResultEvent),
765 ToolStream(ToolStreamEvent),
766 ToolCancel(ToolCancelEvent),
767 ToolInterrupt(ToolInterruptEvent),
768 ModelMessage(ModelMessageEvent),
769 ToolResultMessage(ToolResultMessageEvent),
770 ForceStop(ForceStopEvent),
771 AgentResult(AgentResultEvent),
772}
773
774impl TypedEvent {
775 pub fn is_result(&self) -> bool {
776 matches!(self, Self::AgentResult(_) | Self::EventLoopStop(_))
777 }
778
779 pub fn as_result(&self) -> Option<&AgentResult> {
780 match self {
781 Self::AgentResult(e) => Some(&e.result),
782 _ => None,
783 }
784 }
785
786 pub fn as_model_message(&self) -> Option<&Message> {
787 match self {
788 Self::ModelMessage(e) => Some(&e.message),
789 _ => None,
790 }
791 }
792
793 pub fn as_text(&self) -> Option<String> {
794 match self {
795 Self::TextStream(e) => Some(e.text.clone()),
796 Self::ModelMessage(e) => Some(e.message.text_content()),
797 Self::AgentResult(e) => Some(e.result.text()),
798 _ => None,
799 }
800 }
801
802 pub fn as_text_delta(&self) -> Option<&str> {
803 match self {
804 Self::TextStream(e) => Some(&e.text),
805 Self::ModelStreamChunk(e) => e.chunk.as_text_delta(),
806 _ => None,
807 }
808 }
809
810 pub fn is_callback_event(&self) -> bool {
811 match self {
812 Self::InitEventLoop(e) => e.is_callback_event(),
813 Self::Start(e) => e.is_callback_event(),
814 Self::StartEventLoop(e) => e.is_callback_event(),
815 Self::ModelStreamChunk(e) => e.is_callback_event(),
816 Self::ModelStream(e) => e.is_callback_event(),
817 Self::ToolUseStream(e) => e.is_callback_event(),
818 Self::TextStream(e) => e.is_callback_event(),
819 Self::CitationStream(e) => e.is_callback_event(),
820 Self::ReasoningTextStream(e) => e.is_callback_event(),
821 Self::ReasoningRedactedContentStream(e) => e.is_callback_event(),
822 Self::ReasoningSignatureStream(e) => e.is_callback_event(),
823 Self::ModelStopReason(e) => e.is_callback_event(),
824 Self::EventLoopStop(e) => e.is_callback_event(),
825 Self::StructuredOutput(e) => e.is_callback_event(),
826 Self::EventLoopThrottle(e) => e.is_callback_event(),
827 Self::ToolResult(e) => e.is_callback_event(),
828 Self::ToolStream(e) => e.is_callback_event(),
829 Self::ToolCancel(e) => e.is_callback_event(),
830 Self::ToolInterrupt(e) => e.is_callback_event(),
831 Self::ModelMessage(e) => e.is_callback_event(),
832 Self::ToolResultMessage(e) => e.is_callback_event(),
833 Self::ForceStop(e) => e.is_callback_event(),
834 Self::AgentResult(e) => e.is_callback_event(),
835 }
836 }
837
838 pub fn as_dict(&self) -> HashMap<String, serde_json::Value> {
839 match self {
840 Self::InitEventLoop(e) => e.as_dict(),
841 Self::Start(e) => e.as_dict(),
842 Self::StartEventLoop(e) => e.as_dict(),
843 Self::ModelStreamChunk(e) => e.as_dict(),
844 Self::ModelStream(e) => e.as_dict(),
845 Self::ToolUseStream(e) => e.as_dict(),
846 Self::TextStream(e) => e.as_dict(),
847 Self::CitationStream(e) => e.as_dict(),
848 Self::ReasoningTextStream(e) => e.as_dict(),
849 Self::ReasoningRedactedContentStream(e) => e.as_dict(),
850 Self::ReasoningSignatureStream(e) => e.as_dict(),
851 Self::ModelStopReason(e) => e.as_dict(),
852 Self::EventLoopStop(e) => e.as_dict(),
853 Self::StructuredOutput(e) => e.as_dict(),
854 Self::EventLoopThrottle(e) => e.as_dict(),
855 Self::ToolResult(e) => e.as_dict(),
856 Self::ToolStream(e) => e.as_dict(),
857 Self::ToolCancel(e) => e.as_dict(),
858 Self::ToolInterrupt(e) => e.as_dict(),
859 Self::ModelMessage(e) => e.as_dict(),
860 Self::ToolResultMessage(e) => e.as_dict(),
861 Self::ForceStop(e) => e.as_dict(),
862 Self::AgentResult(e) => e.as_dict(),
863 }
864 }
865}
866
867impl TypedEvent {
868 pub fn init_event_loop() -> Self {
869 Self::InitEventLoop(InitEventLoopEvent::new())
870 }
871
872 pub fn start() -> Self {
873 Self::Start(StartEvent)
874 }
875
876 pub fn start_event_loop() -> Self {
877 Self::StartEventLoop(StartEventLoopEvent)
878 }
879
880 pub fn text_stream(delta: ContentBlockDelta, text: impl Into<String>) -> Self {
881 Self::TextStream(TextStreamEvent::new(delta, text))
882 }
883
884 pub fn model_message(message: Message) -> Self {
885 Self::ModelMessage(ModelMessageEvent::new(message))
886 }
887
888 pub fn tool_result(tool_result: ToolResultType) -> Self {
889 Self::ToolResult(ToolResultEvent::new(tool_result))
890 }
891
892 pub fn agent_result(result: AgentResult) -> Self {
893 Self::AgentResult(AgentResultEvent::new(result))
894 }
895
896 pub fn force_stop(reason: impl Into<String>) -> Self {
897 Self::ForceStop(ForceStopEvent::new(reason))
898 }
899
900 pub fn throttle(delay: u32) -> Self {
901 Self::EventLoopThrottle(EventLoopThrottleEvent::new(delay))
902 }
903}
904
905#[cfg(test)]
906mod tests {
907 use super::*;
908
909 #[test]
910 fn test_init_event_loop_event() {
911 let event = InitEventLoopEvent::new();
912 let dict = event.as_dict();
913 assert_eq!(dict.get("init_event_loop"), Some(&serde_json::Value::Bool(true)));
914 }
915
916 #[test]
917 fn test_start_event() {
918 let event = StartEvent;
919 let dict = event.as_dict();
920 assert_eq!(dict.get("start"), Some(&serde_json::Value::Bool(true)));
921 }
922
923 #[test]
924 fn test_force_stop_event() {
925 let event = ForceStopEvent::new("Test reason");
926 let dict = event.as_dict();
927 assert_eq!(dict.get("force_stop"), Some(&serde_json::Value::Bool(true)));
928 assert_eq!(dict.get("force_stop_reason"), Some(&serde_json::Value::String("Test reason".to_string())));
929 }
930
931 #[test]
932 fn test_typed_event_enum() {
933 let event = TypedEvent::start();
934 assert!(!event.is_result());
935
936 let event = TypedEvent::force_stop("error");
937 let dict = event.as_dict();
938 assert!(dict.contains_key("force_stop"));
939 }
940}