//! The request and reply shapes swarm services exchange over the queue: the //! subjects, their deadlines and the serde types that travel each way. //! //! Serde only, with no queue client and no secret-store client. A crate that //! names a contract (the sender, the answerer, the auth-callout responder that //! grants the subject) depends on this one without linking either. pub mod agent_icon; pub mod agent_inference; pub mod agent_limits; pub mod agent_login; pub mod agent_permissions; pub mod agent_schedules; pub mod agent_status; pub mod agent_term; pub mod builder; pub mod claude_login; pub mod notices; pub mod review_classifier; pub mod subagent_term; pub mod wanted; /// The subject `agent` publishes its terminal rows on. One leaf per agent, so /// a subscriber can follow one agent without filtering the swarm's whole /// terminal traffic. /// /// Shared by the publisher (`hive-agent`), the relay that streams it to /// swarm-ui (`swarm-controller`) and the queue's subscribe grant for readers /// (`swarm-nats-auth`), which spells [`term_subject_wildcard`] — so a rename /// moves all three together. #[must_use] pub fn term_subject(agent: &str) -> String { format!("{TERM_SUBJECT_PREFIX}.{agent}") } /// Every [`term_subject`] at once: the reader's subscribe grant, which has no /// roster to enumerate agents from. #[must_use] pub fn term_subject_wildcard() -> String { term_subject("*") } /// Shared by [`term_subject`] and [`subagent_term`], whose subjects sit under /// the same prefix. pub const TERM_SUBJECT_PREFIX: &str = "$SWARM.term"; #[cfg(test)] mod tests { use super::*; /// The names the publishers, the relays and the queue's grant all spell. #[test] fn term_subjects_are_the_agreed_names() { assert_eq!(term_subject("mara"), "$SWARM.term.mara"); assert_eq!(term_subject_wildcard(), "$SWARM.term.*"); assert_eq!(subagent_term::subject_wildcard(), "$SWARM.term.*.sub.*"); } }