Skip to main content

shuttle_rs/
message.rs

1use crate::core::{Event, EventFilter, EventStore, EventType, NewEvent, Result};
2use serde_json::json;
3
4pub fn new_message(
5    workspace_id: String,
6    from_agent: String,
7    session_id: String,
8    to_agent: String,
9    content: String,
10) -> Event {
11    Event::new(NewEvent {
12        event_type: EventType::Message,
13        workspace_id,
14        repo_id: None,
15        repo_path: None,
16        git_remote: None,
17        bit_repo_id: None,
18        branch: None,
19        commit: None,
20        repo_dirty: None,
21        agent: from_agent,
22        session_id,
23        title: None,
24        content,
25        tags: Vec::new(),
26        metadata_json: json!({ "to": to_agent }),
27    })
28}
29
30pub async fn inbox(store: &impl EventStore, agent: &str) -> Result<Vec<Event>> {
31    let mut events = store
32        .list(EventFilter {
33            event_type: Some(EventType::Message),
34            recipient: Some(agent.to_owned()),
35            ..EventFilter::default()
36        })
37        .await?;
38    events.extend(
39        store
40            .list(EventFilter {
41                event_type: Some(EventType::Handoff),
42                recipient: Some(agent.to_owned()),
43                ..EventFilter::default()
44            })
45            .await?,
46    );
47    events.sort_by(|left, right| right.created_at.cmp(&left.created_at));
48    Ok(events)
49}
50
51pub async fn history(store: &impl EventStore) -> Result<Vec<Event>> {
52    store
53        .list(EventFilter {
54            event_type: Some(EventType::Message),
55            ..EventFilter::default()
56        })
57        .await
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn message_uses_recipient_metadata() {
66        let event = new_message(
67            "workspace".into(),
68            "codex".into(),
69            "session".into(),
70            "claude".into(),
71            "review this".into(),
72        );
73        assert_eq!(event.event_type, EventType::Message);
74        assert!(event.tags.is_empty());
75        assert_eq!(event.metadata_json["to"], "claude");
76    }
77}