use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentEvent {
IterationStarted {
index: usize,
max_iterations: usize,
},
AssistantDelta {
text: String,
},
ReasoningDelta {
text: String,
},
ToolCallDelta {
name: Option<String>,
args_delta: String,
},
ToolCallStarted {
name: String,
args_preview: String,
call_id: String,
},
ToolCallFinished {
name: String,
result: String,
is_error: bool,
call_id: String,
},
FinalResponse {
content: String,
},
Error {
message: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentBusEvent {
pub channel: String,
pub chat_id: String,
pub event: AgentEvent,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InboundMessage {
pub channel: String,
pub sender_id: String,
pub chat_id: String,
pub content: String,
pub timestamp: DateTime<Utc>,
pub media: Vec<String>,
pub metadata: HashMap<String, serde_json::Value>,
}
impl InboundMessage {
pub fn new(
channel: impl Into<String>,
sender_id: impl Into<String>,
chat_id: impl Into<String>,
content: impl Into<String>,
) -> Self {
Self {
channel: channel.into(),
sender_id: sender_id.into(),
chat_id: chat_id.into(),
content: content.into(),
timestamp: Utc::now(),
media: Vec::new(),
metadata: HashMap::new(),
}
}
pub fn session_key(&self) -> String {
format!("{}:{}", self.channel, self.chat_id)
}
pub fn with_media(mut self, url: impl Into<String>) -> Self {
self.media.push(url.into());
self
}
pub fn with_metadata(
mut self,
key: impl Into<String>,
value: impl Into<serde_json::Value>,
) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OutboundMessage {
pub channel: String,
pub chat_id: String,
pub content: String,
pub reply_to: Option<String>,
pub media: Vec<String>,
pub reasoning_content: Option<String>,
pub metadata: HashMap<String, serde_json::Value>,
}
impl OutboundMessage {
pub fn new(
channel: impl Into<String>,
chat_id: impl Into<String>,
content: impl Into<String>,
) -> Self {
Self {
channel: channel.into(),
chat_id: chat_id.into(),
content: content.into(),
reply_to: None,
media: Vec::new(),
reasoning_content: None,
metadata: HashMap::new(),
}
}
pub fn reply_to(mut self, message_id: impl Into<String>) -> Self {
self.reply_to = Some(message_id.into());
self
}
pub fn with_media(mut self, url: impl Into<String>) -> Self {
self.media.push(url.into());
self
}
pub fn with_metadata(
mut self,
key: impl Into<String>,
value: impl Into<serde_json::Value>,
) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
}