add ack_until: bulk-ack inbox messages by id + surface msg ids in wake prompts and recv (closes #2125)

This commit is contained in:
damocles 2026-07-02 11:45:12 +02:00 committed by mara
commit 34374fd10a
8 changed files with 221 additions and 16 deletions

View file

@ -679,6 +679,15 @@ pub enum Request {
/// Harness↔broker pairing fired after `TurnOutcome::Ok`. See
/// `docs/conventions.md::Broker delivery + ack cycle`.
AckTurn,
/// Mark every inbox message with broker row id `<= up_to` as
/// handled (`acked_at` set), whether still pending or already
/// delivered. The agent-facing bulk-triage escape hatch for a
/// redelivered / accumulated backlog: instead of popping and
/// re-reading dozens of already-handled messages one turn at a
/// time, the agent acks everything up to the id it has seen.
/// Recipient-scoped — an agent can only ack its own rows. See
/// `docs/conventions.md::Broker delivery + ack cycle`.
AckUntil { up_to: i64 },
/// Requeue every popped-but-unacked message back into the inbox.
/// Harness fires this once at boot to recover from
/// crashed-mid-turn sessions. See
@ -811,12 +820,15 @@ pub enum Response {
/// `Recv` result: zero or more messages, FIFO-ordered, never
/// longer than the `max` the caller passed. Empty vec = nothing
/// pending (the "(empty)" path for the formatter). Per-row `id` +
/// `redelivered` carry the broker's row id (opaque to claude;
/// tracked by the harness for `AckTurn`) and the "previously
/// `redelivered` carry the broker's row id (tracked by the harness
/// for `AckTurn`, and surfaced to claude as a `[msg #<id>]` marker
/// so `AckUntil` has something to reference) and the "previously
/// popped, not acked" flag — see `DeliveredMessage` for details.
Messages { messages: Vec<DeliveredMessage> },
/// `Status` result: how many pending messages are in this agent's inbox.
Status { unread: u64 },
/// `AckUntil` result: how many rows were newly marked handled.
Acked { count: u64 },
/// `Recent` result: newest-first inbox rows.
Recent { rows: Vec<InboxRow> },
/// `Ask` result: the queued question id. The answer lands later
@ -1132,7 +1144,7 @@ impl ToolGroup {
#[must_use]
pub fn tools(self) -> &'static [&'static str] {
match self {
Self::Messaging => &["send", "recv", "ask", "answer"],
Self::Messaging => &["send", "recv", "ack_until", "ask", "answer"],
Self::Meta => &["get_agent_meta"],
Self::Inbox => &[
"get_loose_ends",