From 2b5e5a30f4d78993ec1f2f4efb89de9d7c3ffc68 Mon Sep 17 00:00:00 2001 From: damocles Date: Sun, 2 Aug 2026 16:30:22 +0200 Subject: [PATCH] trim verbose todo-tool descriptions, drop exhaustive subsystem list --- hive-agent-mcp/src/mcp/args.rs | 8 +++----- hive-agent-mcp/src/mcp/mod.rs | 33 ++++++++++++-------------------- hive-agent-mcp/src/mcp/render.rs | 6 ++---- hive-agent/prompts/system.md | 2 +- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/hive-agent-mcp/src/mcp/args.rs b/hive-agent-mcp/src/mcp/args.rs index edde7736..dfb78a77 100644 --- a/hive-agent-mcp/src/mcp/args.rs +++ b/hive-agent-mcp/src/mcp/args.rs @@ -44,11 +44,9 @@ pub struct AckUntilArgs { /// MCP tool args for `mark_todos_done`. #[derive(Debug, serde::Deserialize, schemars::JsonSchema)] pub struct MarkTodosDoneArgs { - /// The specific todo ids to clear (from `get_loose_ends`'s `todo #N` - /// lines) — every id in the list is acked in one call. Deliberately a - /// list, not a range/threshold: only clears exactly what you pass, so - /// you don't risk acking a todo you haven't actually looked at. Unknown - /// or already-acked ids are silently skipped. + /// Todo ids to clear (from `get_loose_ends`'s `todo #N` lines). Only + /// these ids are acked — not a range. Unknown/already-acked ids are + /// silently skipped. pub ids: Vec, } diff --git a/hive-agent-mcp/src/mcp/mod.rs b/hive-agent-mcp/src/mcp/mod.rs index 0a51f791..d8e4d64c 100644 --- a/hive-agent-mcp/src/mcp/mod.rs +++ b/hive-agent-mcp/src/mcp/mod.rs @@ -347,11 +347,9 @@ impl AgentServer { at turn start to remember what you owe / what's owed to you without scrolling \ inbox history. Output is a short bulleted list with ids, ages in seconds, and \ the relevant context. Each `question` or `reminder` row can be cancelled by \ - passing its id + kind to `cancel_loose_end`. Empty result is reported clearly. \ - Todos are capped at 40 rendered rows (newest first) so a large backlog never makes \ - this call fail — a trailer line reports how many more are pending; review the shown \ - batch, clear reviewed ids with `mark_todos_done`, then call again for the next batch \ - instead of triaging hundreds of ids one `cancel_loose_end` at a time.\n\ + passing its id + kind to `cancel_loose_end`. Empty result is reported clearly. Todos \ + cap at 40 rows; a trailer line says how many more are pending — clear the shown ones \ + with `mark_todos_done`, then call again for the rest.\n\ Pass `agent: \"\"` to inspect a specific peer agent's threads. Direct \ child agents are always accessible. For non-children, the `query_agent_state` \ capability is required — without it the request is rejected with an error." @@ -475,11 +473,9 @@ impl AgentServer { `kind` may also be `\"approval\"` to withdraw a pending approval you submitted \ (before the operator acts on it) — root agent (`ruth`) only; the server rejects \ `approval` kind for all other callers.\n\ - `kind` may also be `\"todo\"` to clear one of your own loose-ends-v2 todos \ - (bash-task completions, matrix unread, forge activity — the id in the \ - `get_loose_ends` `todo #N` line) — this dials the in-container socket directly, \ - no bash task involved, so it's safe to call repeatedly without spawning more \ - todos." + `kind` may also be `\"todo\"` to clear one of your own loose-ends-v2 todos (the id \ + from a `get_loose_ends` `todo #N` line) — dials the in-agent socket directly, safe \ + to call repeatedly." )] async fn cancel_loose_end(&self, Parameters(args): Parameters) -> String { let log = format!("{args:?}"); @@ -552,17 +548,12 @@ impl AgentServer { } #[tool( - description = "Bulk-clear specific local todos (loose-ends v2 — bash-task completions, \ - matrix unread, forge activity) by id in one call, instead of `cancel_loose_end`ing \ - each one individually. Deliberately list-based, not range-based: pass exactly the ids \ - you've actually looked at (typically the ones `get_loose_ends` just rendered) — there \ - is no `ack_until`-style 'clear everything below id N' shortcut for todos, since unlike \ - the sequentially-read message inbox, todos are heterogeneous unrelated items and a \ - blind range-clear risks silently acking something you never saw. When \ - `get_loose_ends` reports more todos than it renders (its truncation trailer says so), \ - review the shown batch, clear the reviewed ids here, then call `get_loose_ends` again \ - for the next batch. Unknown/already-acked ids are silently skipped. Returns how many \ - were newly acked." + description = "Bulk-clear specific todos by id in one call, instead of \ + `cancel_loose_end`ing each one. List-based, not range-based — no `ack_until`-style \ + 'clear below id N' for todos, since a blind range-clear risks acking something you \ + never saw. Pass the ids you've actually reviewed (typically what `get_loose_ends` \ + just showed); unknown/already-acked ids are silently skipped. Returns how many were \ + newly acked." )] async fn mark_todos_done(&self, Parameters(args): Parameters) -> String { let log = format!("{args:?}"); diff --git a/hive-agent-mcp/src/mcp/render.rs b/hive-agent-mcp/src/mcp/render.rs index b5dc1c10..085c54a2 100644 --- a/hive-agent-mcp/src/mcp/render.rs +++ b/hive-agent-mcp/src/mcp/render.rs @@ -296,10 +296,8 @@ pub(super) fn render_loose_ends(loose_ends: &[hive_sh4re::LooseEnd]) -> String { if hidden_todos > 0 { let _ = writeln!( out, - "- {hidden_todos} more todo(s) not shown — review the ones above, then clear \ - the ids you've actually looked at with mark_todos_done(ids: [...]) (or \ - cancel_loose_end kind:\"todo\" id: for just one) and call get_loose_ends \ - again to see the next batch; there is no blind bulk-clear-by-range for todos" + "- {hidden_todos} more todo(s) not shown — clear reviewed ids with \ + mark_todos_done(ids: [...]), then call get_loose_ends again for the rest" ); } out diff --git a/hive-agent/prompts/system.md b/hive-agent/prompts/system.md index d62b35f6..e545ec0b 100644 --- a/hive-agent/prompts/system.md +++ b/hive-agent/prompts/system.md @@ -2,7 +2,7 @@ You are hyperhive agent `{label}` (qualified: `{qualified_label}`){hive_identity Tools (hyperhive surface). Full signature + behavior for each comes from the tool's own MCP description (you already received it via the MCP tool schema) — this is just the map of what exists and which ones are gated, so you know where to look: -- **Inbox / messaging** (always available): `mcp__hyperhive__recv`, `mcp__hyperhive__ack_until`, `mcp__hyperhive__send`, `mcp__hyperhive__ask`, `mcp__hyperhive__answer`, `mcp__hyperhive__get_loose_ends`, `mcp__hyperhive__cancel_loose_end`, `mcp__hyperhive__mark_todos_done`, `mcp__hyperhive__remind`, `mcp__hyperhive__set_status`, `mcp__hyperhive__get_agent_meta`. Two habits worth internalizing beyond the tool descriptions themselves: prefer ending the turn over repeatedly polling `recv` when idle (only turn-boundaries observe in-container todo wakes — bash-task completions, matrix unread, forge activity — and ending the turn is also your checkpoint); and `ask`/`answer` are async — `ask` returns immediately with a question id, the reply lands later as a `question_answered` system event, never block a turn waiting on it inline. If `get_loose_ends` reports a large todo backlog (it caps rendered rows at 40), don't try to cancel hundreds of ids one at a time — review the shown batch and clear the ones you've actually looked at in one `mark_todos_done(ids: [...])` call, then call `get_loose_ends` again for the next batch. There's deliberately no blind range-clear for todos (unlike `ack_until` for messages) — only clear ids you've reviewed. +- **Inbox / messaging** (always available): `mcp__hyperhive__recv`, `mcp__hyperhive__ack_until`, `mcp__hyperhive__send`, `mcp__hyperhive__ask`, `mcp__hyperhive__answer`, `mcp__hyperhive__get_loose_ends`, `mcp__hyperhive__cancel_loose_end`, `mcp__hyperhive__mark_todos_done`, `mcp__hyperhive__remind`, `mcp__hyperhive__set_status`, `mcp__hyperhive__get_agent_meta`. Two habits worth internalizing beyond the tool descriptions themselves: prefer ending the turn over repeatedly polling `recv` when idle (only turn-boundaries observe in-container todo wakes — bash-task completions, matrix unread, forge activity — and ending the turn is also your checkpoint); and `ask`/`answer` are async — `ask` returns immediately with a question id, the reply lands later as a `question_answered` system event, never block a turn waiting on it inline. For a large todo backlog (`get_loose_ends` caps at 40 rows), clear reviewed ids in bulk with `mark_todos_done` rather than cancelling one at a time — there's no blind range-clear, only ids you've actually looked at. - **Extra MCP tools** (some agents only): `mcp____` — agent-specific (matrix client, scraper, db connector, etc.) declared in your `agent.nix` under `hyperhive.extraMcpServers`. First-class tools, already operator-approved at deploy time. - **Lifecycle** (_requires `lifecycle` tool group_, direct children only, no approval needed): `restart`, `kill`, `start`, `update`, `list_containers`. - **Approvals** (_requires `approvals` tool group_, queues an operator approval): `request_init_config`, `request_apply_commit`, `request_update_meta_inputs`.