Skip to main content

agent_diva_core/bus/
events.rs

1//! Event types for the message bus
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7/// Streaming events emitted by the agent
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub enum AgentEvent {
10    IterationStarted {
11        index: usize,
12        max_iterations: usize,
13    },
14    AssistantDelta {
15        text: String,
16    },
17    ReasoningDelta {
18        text: String,
19    },
20    ToolCallDelta {
21        name: Option<String>,
22        args_delta: String,
23    },
24    ToolCallStarted {
25        name: String,
26        args_preview: String,
27        call_id: String,
28    },
29    ToolCallFinished {
30        name: String,
31        result: String,
32        is_error: bool,
33        call_id: String,
34    },
35    FinalResponse {
36        content: String,
37    },
38    Error {
39        message: String,
40    },
41}
42
43/// Event with context for the bus
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct AgentBusEvent {
46    pub channel: String,
47    pub chat_id: String,
48    pub event: AgentEvent,
49}
50
51/// Message received from a chat channel
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct InboundMessage {
54    /// Channel identifier (e.g., "telegram", "discord")
55    pub channel: String,
56    /// User identifier
57    pub sender_id: String,
58    /// Chat/channel identifier
59    pub chat_id: String,
60    /// Message text content
61    pub content: String,
62    /// Message timestamp
63    pub timestamp: DateTime<Utc>,
64    /// Media URLs (if any)
65    pub media: Vec<String>,
66    /// Channel-specific metadata
67    pub metadata: HashMap<String, serde_json::Value>,
68}
69
70impl InboundMessage {
71    /// Create a new inbound message
72    pub fn new(
73        channel: impl Into<String>,
74        sender_id: impl Into<String>,
75        chat_id: impl Into<String>,
76        content: impl Into<String>,
77    ) -> Self {
78        Self {
79            channel: channel.into(),
80            sender_id: sender_id.into(),
81            chat_id: chat_id.into(),
82            content: content.into(),
83            timestamp: Utc::now(),
84            media: Vec::new(),
85            metadata: HashMap::new(),
86        }
87    }
88
89    /// Get the unique session key for this message
90    pub fn session_key(&self) -> String {
91        format!("{}:{}", self.channel, self.chat_id)
92    }
93
94    /// Add media URL to the message
95    pub fn with_media(mut self, url: impl Into<String>) -> Self {
96        self.media.push(url.into());
97        self
98    }
99
100    /// Add metadata to the message
101    pub fn with_metadata(
102        mut self,
103        key: impl Into<String>,
104        value: impl Into<serde_json::Value>,
105    ) -> Self {
106        self.metadata.insert(key.into(), value.into());
107        self
108    }
109}
110
111/// Message to send to a chat channel
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct OutboundMessage {
114    /// Channel identifier
115    pub channel: String,
116    /// Target chat/channel identifier
117    pub chat_id: String,
118    /// Message text content
119    pub content: String,
120    /// Optional message to reply to
121    pub reply_to: Option<String>,
122    /// Media URLs to attach
123    pub media: Vec<String>,
124    /// Reasoning content (if any)
125    pub reasoning_content: Option<String>,
126    /// Channel-specific metadata
127    pub metadata: HashMap<String, serde_json::Value>,
128}
129
130impl OutboundMessage {
131    /// Create a new outbound message
132    pub fn new(
133        channel: impl Into<String>,
134        chat_id: impl Into<String>,
135        content: impl Into<String>,
136    ) -> Self {
137        Self {
138            channel: channel.into(),
139            chat_id: chat_id.into(),
140            content: content.into(),
141            reply_to: None,
142            media: Vec::new(),
143            reasoning_content: None,
144            metadata: HashMap::new(),
145        }
146    }
147
148    /// Set the reply-to message ID
149    pub fn reply_to(mut self, message_id: impl Into<String>) -> Self {
150        self.reply_to = Some(message_id.into());
151        self
152    }
153
154    /// Add media URL to the message
155    pub fn with_media(mut self, url: impl Into<String>) -> Self {
156        self.media.push(url.into());
157        self
158    }
159
160    /// Add metadata to the message
161    pub fn with_metadata(
162        mut self,
163        key: impl Into<String>,
164        value: impl Into<serde_json::Value>,
165    ) -> Self {
166        self.metadata.insert(key.into(), value.into());
167        self
168    }
169}