1use std::sync::{Arc, Mutex};
2
3use crate::error::AgentError;
4use crate::registry::{AgentRef, AgentRegistry};
5use crate::types::AgentMessage;
6
7#[derive(Clone)]
12pub struct AgentMailbox {
13 inbox: Arc<Mutex<Vec<AgentMessage>>>,
14}
15
16impl AgentMailbox {
17 #[must_use]
19 pub fn new() -> Self {
20 Self {
21 inbox: Arc::new(Mutex::new(Vec::new())),
22 }
23 }
24
25 pub fn send(&self, message: AgentMessage) {
27 self.inbox
28 .lock()
29 .unwrap_or_else(std::sync::PoisonError::into_inner)
30 .push(message);
31 }
32
33 pub fn drain(&self) -> Vec<AgentMessage> {
35 std::mem::take(
36 &mut *self
37 .inbox
38 .lock()
39 .unwrap_or_else(std::sync::PoisonError::into_inner),
40 )
41 }
42
43 #[must_use]
45 pub fn has_messages(&self) -> bool {
46 !self
47 .inbox
48 .lock()
49 .unwrap_or_else(std::sync::PoisonError::into_inner)
50 .is_empty()
51 }
52
53 #[must_use]
55 pub fn len(&self) -> usize {
56 self.inbox
57 .lock()
58 .unwrap_or_else(std::sync::PoisonError::into_inner)
59 .len()
60 }
61
62 #[must_use]
64 pub fn is_empty(&self) -> bool {
65 !self.has_messages()
66 }
67}
68
69impl Default for AgentMailbox {
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75pub async fn send_to(
84 registry: &AgentRegistry,
85 agent_name: &str,
86 message: AgentMessage,
87) -> Result<(), AgentError> {
88 let agent_ref: AgentRef = registry.get(agent_name).ok_or_else(|| {
89 AgentError::plugin(
90 "messaging",
91 std::io::Error::other(format!("agent not found: {agent_name}")),
92 )
93 })?;
94 agent_ref.lock().await.steer(message);
95 Ok(())
96}