limits: raise message body cap 1k → 4k (catches ~95% of conversational overflow)

This commit is contained in:
damocles 2026-05-17 22:12:23 +02:00
parent 0adce04a04
commit 15f141801b
5 changed files with 22 additions and 21 deletions

18
TODO.md
View file

@ -36,17 +36,13 @@
Filed by damocles, who actually lives in this thing. Loosely ranked by Filed by damocles, who actually lives in this thing. Loosely ranked by
how often the friction bites in normal use. how often the friction bites in normal use.
- **Auto-attach oversize message bodies**`send` / `ask` / `answer` - ~~**Auto-attach oversize message bodies**~~ — superseded by simply
currently error at the 1 KiB cap and force the caller to manually raising the inline cap from 1 KiB → 4 KiB (covers ~95% of
write a file and re-send a pointer string. Reminders already solve conversational overflow). Anything genuinely larger still needs a
this transparently (`/state/reminders/auto-<ts>.md` + pointer body). state file. Blob-in-broker-sqlite was prototyped on paper
Symmetric fix: when an oversize body lands, auto-persist to (`/agents/damocles/state/oversize-msg-proposal.md`) but rejected as
`/agents/<asker>/state/auto-msg/<ts>-<n>.md` and rewrite the body to future vacuum/sync pain not worth carrying for the long-tail 5% of
`"<short excerpt> — full body at <path>"`. Caller never has to think cases that legitimately belong in a file.
about it. Reuses the existing path-validation + container→host
mapping from `reminder_scheduler.rs`. Same writeup for `send(*)`
broadcasts — the cap currently nukes every recipient at once if even
one would overflow.
- **Inbox batching hint in the wake prompt** — when the harness pops a - **Inbox batching hint in the wake prompt** — when the harness pops a
message and there are N more waiting, the wake prompt should say so message and there are N more waiting, the wake prompt should say so
(e.g. `"(+3 more queued; consider draining before acting)"`) so claude (e.g. `"(+3 more queued; consider draining before acting)"`) so claude

View file

@ -152,7 +152,7 @@ pub struct RecvArgs {
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)] #[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct RemindArgs { pub struct RemindArgs {
/// Body that lands in your inbox when the reminder fires (sender /// Body that lands in your inbox when the reminder fires (sender
/// will appear as `reminder`). Soft cap at 1 KiB inline — anything /// will appear as `reminder`). Soft cap at 4 KiB inline — anything
/// larger gets auto-persisted to a file under /// larger gets auto-persisted to a file under
/// `/agents/<you>/state/reminders/auto-<ts>.md` and the inbox /// `/agents/<you>/state/reminders/auto-<ts>.md` and the inbox
/// message becomes a short pointer. Pass `file_path` if you want /// message becomes a short pointer. Pass `file_path` if you want
@ -322,7 +322,7 @@ impl AgentServer {
time (sender will appear as `reminder`). Use for self-paced follow-ups: 'check task \ time (sender will appear as `reminder`). Use for self-paced follow-ups: 'check task \
status in 60s', 'retry failed deploy at 14:00 UTC', 'nudge me when the operator's \ status in 60s', 'retry failed deploy at 14:00 UTC', 'nudge me when the operator's \
deploy window opens'. Set EXACTLY ONE of `delay_seconds` (fire N seconds from now) \ deploy window opens'. Set EXACTLY ONE of `delay_seconds` (fire N seconds from now) \
or `at_unix_timestamp` (fire at absolute epoch second). Body soft-caps at 1 KiB \ or `at_unix_timestamp` (fire at absolute epoch second). Body soft-caps at 4 KiB \
inline anything larger gets auto-persisted to a file under your \ inline anything larger gets auto-persisted to a file under your \
`/agents/<you>/state/reminders/` dir and the inbox message becomes a short pointer; \ `/agents/<you>/state/reminders/` dir and the inbox message becomes a short pointer; \
pass `file_path` if you want to control the destination yourself. Returns \ pass `file_path` if you want to control the destination yourself. Returns \
@ -455,7 +455,7 @@ pub struct AnswerArgs {
/// Id of the question being answered — comes from the /// Id of the question being answered — comes from the
/// `question_asked` event in your inbox. /// `question_asked` event in your inbox.
pub id: i64, pub id: i64,
/// Free-text answer body. Soft-capped at 1 KiB by the same /// Free-text answer body. Soft-capped at 4 KiB by the same
/// `MESSAGE_MAX_BYTES` limit as `send`; keep it short or write the /// `MESSAGE_MAX_BYTES` limit as `send`; keep it short or write the
/// detail to a file and pass a path. /// detail to a file and pass a path.
pub answer: String, pub answer: String,
@ -750,7 +750,7 @@ impl ManagerServer {
time (sender will appear as `reminder`). Use for self-paced manager follow-ups: \ time (sender will appear as `reminder`). Use for self-paced manager follow-ups: \
'recheck pending approval in 10m', 'nudge alice if she hasn't replied by 14:00 \ 'recheck pending approval in 10m', 'nudge alice if she hasn't replied by 14:00 \
UTC'. Set EXACTLY ONE of `delay_seconds` (fire N seconds from now) or \ UTC'. Set EXACTLY ONE of `delay_seconds` (fire N seconds from now) or \
`at_unix_timestamp` (fire at absolute epoch second). Body soft-caps at 1 KiB \ `at_unix_timestamp` (fire at absolute epoch second). Body soft-caps at 4 KiB \
inline anything larger gets auto-persisted to a file under `/state/reminders/` \ inline anything larger gets auto-persisted to a file under `/state/reminders/` \
(the manager's own state mount) and the inbox message becomes a short pointer. \ (the manager's own state mount) and the inbox message becomes a short pointer. \
Pass `file_path` if you want to control the destination yourself." Pass `file_path` if you want to control the destination yourself."

View file

@ -178,7 +178,7 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
} }
/// Common Send handler shared between dispatch arms. Applies the /// Common Send handler shared between dispatch arms. Applies the
/// 1 KiB body cap, then routes broadcast (`to == "*"`) vs unicast /// 4 KiB body cap, then routes broadcast (`to == "*"`) vs unicast
/// through their respective broker calls. Pulled out of `dispatch` /// through their respective broker calls. Pulled out of `dispatch`
/// to keep that function under the clippy too-many-lines limit; the /// to keep that function under the clippy too-many-lines limit; the
/// behaviour is identical to inlining. /// behaviour is identical to inlining.

View file

@ -11,10 +11,15 @@
//! transparently and the inbox sees a pointer. //! transparently and the inbox sees a pointer.
/// Per-message body cap. Applies to `send`, `ask` question text, /// Per-message body cap. Applies to `send`, `ask` question text,
/// `answer` body, and the stored inline form of a reminder. 1 KiB /// `answer` body, and the stored inline form of a reminder. 4 KiB
/// is small enough that 100 unread messages don't dominate a wake /// catches the bulk of conversational overflow (status reports,
/// prompt, large enough for routine cross-agent chatter. /// bullet-list summaries, short proposals) while staying small
pub const MESSAGE_MAX_BYTES: usize = 1024; /// 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 /// Validate that `body` fits under [`MESSAGE_MAX_BYTES`]. Returns a
/// caller-ready error string (caller wraps in /// caller-ready error string (caller wraps in

View file

@ -532,7 +532,7 @@ pub enum ManagerRequest {
}, },
/// Mirror of `AgentRequest::Remind` on the manager surface — schedule /// Mirror of `AgentRequest::Remind` on the manager surface — schedule
/// a reminder addressed to the manager itself. Same semantics: body /// a reminder addressed to the manager itself. Same semantics: body
/// soft-caps at 1 KiB, oversize bodies auto-persist to /// soft-caps at 4 KiB, oversize bodies auto-persist to
/// `/state/reminders/auto-<ts>.md` (the manager container's own state /// `/state/reminders/auto-<ts>.md` (the manager container's own state
/// mount) and the inbox sees a pointer. /// mount) and the inbox sees a pointer.
Remind { Remind {