//! Wire-protocol size limits shared across the agent + manager //! sockets. Caps on inline message bodies stop a single chatty agent //! (or a misbehaving extra-MCP server) from flooding the broker //! sqlite with megabyte-sized rows that then bloat every recipient's //! wake-prompt context. Anything genuinely larger should be written //! to a state file and the path sent as the body. //! //! Reminders get a separate auto-file escape hatch (see //! `agent_server::handle_remind`) so callers don't have to think //! about it — oversized reminder bodies get persisted to disk //! transparently and the inbox sees a pointer. /// Per-message body cap. Applies to `send`, `ask` question text, /// `answer` body, and the stored inline form of a reminder. 4 KiB /// catches the bulk of conversational overflow (status reports, /// bullet-list summaries, short proposals) while staying small /// enough that a backed-up inbox of ~10 unread messages only adds /// ~40 KiB to the recipient's wake-prompt context. Genuinely /// long-form artifacts (audit reports, full diffs, transcripts) /// still belong in a state file — the error message on overflow /// points callers at that escape hatch. pub const MESSAGE_MAX_BYTES: usize = 4096; /// Validate that `body` fits under [`MESSAGE_MAX_BYTES`]. Returns a /// caller-ready error string (caller wraps in /// `AgentResponse::Err`/`ManagerResponse::Err`) on failure. /// /// `label` shows up in the error message verbatim — pass a short /// noun like `"send"`, `"question"`, `"broadcast"` so the model can /// tell which call got rejected. pub fn check_size(label: &str, body: &str) -> Result<(), String> { if body.len() > MESSAGE_MAX_BYTES { Err(format!( "{label} body too long ({} bytes, max {MESSAGE_MAX_BYTES}); write the \ payload to a file under your `/agents//state/` dir and send the \ path as the body instead", body.len() )) } else { Ok(()) } } #[cfg(test)] mod tests { use super::*; #[test] fn accepts_short_body() { assert!(check_size("send", "hello").is_ok()); assert!(check_size("send", &"x".repeat(MESSAGE_MAX_BYTES)).is_ok()); } #[test] fn rejects_oversize_body() { let err = check_size("send", &"x".repeat(MESSAGE_MAX_BYTES + 1)).unwrap_err(); assert!(err.contains("send body too long")); assert!(err.contains(&format!("max {MESSAGE_MAX_BYTES}"))); } #[test] fn label_threads_through() { let err = check_size("question", &"x".repeat(MESSAGE_MAX_BYTES + 1)).unwrap_err(); assert!(err.starts_with("question body too long")); } }