docs(#1251): split MCP tool docs into docs/tools/ sub-mds by feature
This commit is contained in:
parent
5ec1306c7b
commit
78a00d1258
6 changed files with 350 additions and 268 deletions
|
|
@ -354,6 +354,8 @@ docs/
|
|||
web-ui/agent.md (header, terminal, composer,
|
||||
inbox, live view, per-agent endpoints, stats)
|
||||
turn-loop.md claude invocation, wake prompt, MCP tool surface
|
||||
tools/ per-group tool docs (bash.md, lifecycle.md,
|
||||
scheduling.md, matrix.md)
|
||||
approvals.md approval flow, manager policy, helper events
|
||||
persistence.md sqlite dbs, retention, state dir layout
|
||||
terminal-rendering.md per-agent terminal row taxonomy (as built)
|
||||
|
|
|
|||
49
docs/tools/bash.md
Normal file
49
docs/tools/bash.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Bash execution tools (`execution` tool group)
|
||||
|
||||
Background shell execution via `hive-bash-mcp`. Tools land as
|
||||
`mcp__bash__<tool>` (the MCP server name is `bash`, not `hyperhive`).
|
||||
Enabled for any agent whose tool groups include `execution` — the
|
||||
default preset (`AGENT_DEFAULT`) includes it.
|
||||
|
||||
## Tools
|
||||
|
||||
### `run(cmd, timeout_secs?)`
|
||||
|
||||
Submit a shell command for background execution (`sh -c <cmd>`).
|
||||
Returns a task ID immediately; the command runs asynchronously in a
|
||||
harness-managed tokio task. Stdout and stderr stream to
|
||||
`harness/bash-tasks/<id>.{out,err}`. When the task completes (or
|
||||
times out, or the process errors), the harness wakes the agent with a
|
||||
summary body — handle on a future turn. Optional `timeout_secs`: pass
|
||||
a value for a deadline, or omit for no timeout (runs until natural exit).
|
||||
|
||||
Exposed as `mcp__bash__run`.
|
||||
|
||||
### `status(id)`
|
||||
|
||||
Poll the status of a task submitted with `run`. Returns:
|
||||
|
||||
- `status` — `pending` / `running` / `done` / `timed_out` / `interrupted`
|
||||
- `exit_code` — set when done
|
||||
- run duration
|
||||
- last 4 KiB of stdout and stderr (full output in the `.out` / `.err` files)
|
||||
|
||||
Tasks marked `interrupted` had their process killed by a harness
|
||||
restart; a best-effort wake was still sent so the agent is not
|
||||
silently blocked.
|
||||
|
||||
Exposed as `mcp__bash__status`.
|
||||
|
||||
## Namespace note
|
||||
|
||||
`run` and `status` live in the `bash` MCP server, not `hyperhive`. So
|
||||
the tool names in claude are `mcp__bash__run` and `mcp__bash__status`.
|
||||
The `Bash` built-in tool is blocked — all shell execution goes through
|
||||
this structured path so tasks get task-id tracking and structured output.
|
||||
|
||||
## Tool whitelist cross-reference
|
||||
|
||||
`mcp__bash__run` and `mcp__bash__status` are unconditionally in
|
||||
`--allowedTools` whenever the harness spawns claude (they are not
|
||||
gated by the `execution` group at the `--allowedTools` level — the
|
||||
group only gates whether the MCP server registers the tools at all).
|
||||
91
docs/tools/lifecycle.md
Normal file
91
docs/tools/lifecycle.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# Lifecycle and approvals tools
|
||||
|
||||
Two tool groups govern agent lifecycle management and config changes.
|
||||
Both are scoped to **direct children only** (topology-enforced: the
|
||||
server rejects any name that is not a direct child of the calling
|
||||
agent per `topology.json`). Privileged agents (e.g. ruth) may operate
|
||||
on any sub-agent — the topology scope applies to all others.
|
||||
|
||||
## `lifecycle` tool group
|
||||
|
||||
No operator approval required. Direct children only.
|
||||
|
||||
### `kill(name)`
|
||||
|
||||
Graceful stop. Container state is preserved; recreating the agent
|
||||
reuses prior config and credentials.
|
||||
|
||||
### `start(name)`
|
||||
|
||||
Start a stopped sub-agent.
|
||||
|
||||
### `restart(name)`
|
||||
|
||||
Stop + start in one call.
|
||||
|
||||
### `update(name)`
|
||||
|
||||
Rebuild: re-applies the current hyperhive flake + `agent.nix`,
|
||||
then restarts. Idempotent — safe to call repeatedly. Used in response
|
||||
to `needs_update` system events.
|
||||
|
||||
### `list_containers()`
|
||||
|
||||
List all **descendant** containers (children + their subtrees) with
|
||||
running status. Topology-scoped to descendants only.
|
||||
|
||||
## `approvals` tool group
|
||||
|
||||
Config changes and new-agent spawns route through the operator
|
||||
approval queue. Direct children only (topology-enforced).
|
||||
|
||||
### `request_init_config(name, description?)`
|
||||
|
||||
Step 1 of spawning a new direct child agent. Queues an `InitConfig`
|
||||
approval; on operator approve, hive-c0re seeds the proposed config
|
||||
repo at `/agents/<name>/config/agent.nix` with a default template and
|
||||
delivers a `config_ready` system event. Then edit `agent.nix`, commit,
|
||||
and call `request_apply_commit` with the commit sha — the first
|
||||
`ApplyCommit` on a freshly-init'd config creates the container.
|
||||
|
||||
Fails if a proposed config repo for `name` already exists.
|
||||
`name` is ≤ 9 characters. The operator can also spawn an empty agent
|
||||
via the dashboard `◆ R3QU3ST SP4WN` button, which routes via
|
||||
`HostRequest::RequestSpawn`.
|
||||
|
||||
### `request_apply_commit(agent, commit_ref, description?)`
|
||||
|
||||
Step 2 of spawning (or updating an existing child's config). Submit a
|
||||
commit sha from the child's proposed config repo for operator
|
||||
approval. On approve, hive-c0re rebuilds the container with the
|
||||
pinned commit.
|
||||
|
||||
`commit_ref` must be a 7-40 char hex sha (branch/tag names are
|
||||
rejected — the approval pins the exact commit). `agent` must be a
|
||||
direct child. Topology-enforced.
|
||||
|
||||
### `request_update_meta_inputs(inputs?, description?)`
|
||||
|
||||
Queue an approval to run `nix flake update [inputs...]` on the meta
|
||||
flake. Pass specific input names (e.g. `["bitburner-agent"]`) or omit
|
||||
/ pass `[]` for all inputs. Returns immediately; the lock update runs
|
||||
on operator approval.
|
||||
|
||||
Does NOT trigger container rebuilds — call `update(name)` on affected
|
||||
agents after the approval resolves.
|
||||
|
||||
## Boundary summary
|
||||
|
||||
| Operation | Requires approval? | Scope |
|
||||
|---|---|---|
|
||||
| `kill` / `start` / `restart` / `update` | No | Direct children |
|
||||
| `list_containers` | No | All descendants |
|
||||
| `request_init_config` | Yes (InitConfig) | New direct child only |
|
||||
| `request_apply_commit` | Yes (ApplyCommit) | Direct children |
|
||||
| `request_update_meta_inputs` | Yes (MetaUpdate) | Meta flake (global) |
|
||||
|
||||
## See also
|
||||
|
||||
- [`docs/approvals.md`](../approvals.md) — full approval flow, kinds,
|
||||
helper events (`config_ready`, `approval_resolved`), flake.lock
|
||||
validation.
|
||||
62
docs/tools/matrix.md
Normal file
62
docs/tools/matrix.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Matrix MCP tools and extra MCP servers
|
||||
|
||||
## Built-in matrix MCP (`mcp__matrix__*`)
|
||||
|
||||
When `hyperhive.matrix.enable = true` and the host-level matrix
|
||||
tuwunel is configured, the harness auto-injects `hive-matrix-mcp` as
|
||||
a second stdio MCP server. Tools land as `mcp__matrix__<name>`:
|
||||
|
||||
### Messaging
|
||||
|
||||
- `send_message(room, body)` — send a markdown message; `room`
|
||||
accepts `!id:server` or `#alias:server`, daemon resolves either
|
||||
- `send_dm(user_id, body)` — send a direct message to a matrix user
|
||||
- `send_reply(room, event_id, body)` — threaded reply to a specific
|
||||
event
|
||||
- `send_reaction(room, event_id, key)` — react to a message with an
|
||||
emoji key
|
||||
|
||||
### Reading
|
||||
|
||||
- `read_room(room, limit?)` — recent timeline events
|
||||
- `list_rooms()` — enumerate joined rooms
|
||||
(`{ id, canonical_alias, name, member_count }` per room)
|
||||
- `list_room_members(room)` — members of a room
|
||||
|
||||
### Receipts
|
||||
|
||||
- `mark_read(room, event_id)` — advance the read receipt
|
||||
|
||||
## Architecture
|
||||
|
||||
The daemon (`hive-matrix-daemon`) holds the long-running matrix-sdk
|
||||
`Client` + sync loop; the stdio bridge (`hive-matrix-mcp`) is spawned
|
||||
per turn and forwards tool calls over `/run/hive-matrix.sock`. Both
|
||||
silently exit when `<state>/matrix-token` is absent (account not yet
|
||||
provisioned).
|
||||
|
||||
Incoming room events wake the agent via `AgentRequest::Wake` with
|
||||
`from: "matrix"` and a teaser body
|
||||
(`[matrix] <sender> in <room>: <first-100c>…`).
|
||||
|
||||
See [`docs/matrix.md`](../matrix.md) for the homeserver setup,
|
||||
provisioning flow, and federation config.
|
||||
|
||||
## Extra MCP servers (per-agent)
|
||||
|
||||
Each agent's NixOS config can declare additional MCP servers via
|
||||
`hyperhive.extraMcpServers.<key> = { command, args, env,
|
||||
allowedTools }`. The module writes the map to
|
||||
`/etc/hyperhive/extra-mcp.json`; the harness reads it at boot and
|
||||
merges every entry into `--mcp-config` (under `mcpServers.<key>`)
|
||||
and `--allowedTools` (as `mcp__<key>__<pattern>`).
|
||||
|
||||
The agent's `flake.nix` forwards every flake input to `agent.nix` as
|
||||
the `flakeInputs` module arg, so external MCP-server flakes are pulled
|
||||
in by adding them to `inputs.*` and referenced as
|
||||
`flakeInputs.<name>.packages.${pkgs.system}.default` — the resolved
|
||||
sha lands in the agent's own `flake.lock` and rolls up to meta's.
|
||||
|
||||
`allowedTools` defaults to `["*"]`, which expands to
|
||||
`mcp__<key>__*` (every tool from that server auto-approved). Restrict
|
||||
to specific tool names when you want finer control.
|
||||
68
docs/tools/scheduling.md
Normal file
68
docs/tools/scheduling.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Scheduling and diagnostics tools
|
||||
|
||||
## `scheduling` tool group
|
||||
|
||||
Scheduled prompts fan a message body out to one or more agent inboxes
|
||||
at a future time, optionally recurring. All scheduling ops go through
|
||||
the operator approval queue (even self-targeted schedules — use
|
||||
`remind` for unapproved self-wake). Authorization for read/cancel/edit
|
||||
ops: you can act on schedules you own or any owned by a sub-agent in
|
||||
your topology subtree.
|
||||
|
||||
### `request_schedule_prompt(targets, body, first_fire_at_unix, interval_seconds?, description?)`
|
||||
|
||||
Queue an operator-approval for a scheduled prompt. On approve,
|
||||
`body` is fanned out to each agent in `targets` at
|
||||
`first_fire_at_unix` (Unix timestamp). Recurring when `interval_seconds`
|
||||
is set, one-shot otherwise.
|
||||
|
||||
Catch-up clamp: if hive-c0re is down across multiple intervals, only
|
||||
ONE delayed fire happens on resume (per recurring schedule). The
|
||||
skipped-cycle count surfaces in the per-target `last_result` for
|
||||
audit.
|
||||
|
||||
### `edit_schedule(id, body?, description?, interval_seconds?, next_fire_at_unix?, targets_add?, targets_remove?)`
|
||||
|
||||
Partial-update a schedule. Pass only the fields to change; absent
|
||||
fields are left alone. `targets_add` / `targets_remove` mutate the
|
||||
recipient list in the same transaction — re-adding a previously
|
||||
cancelled target drops its tombstone and starts fresh. Clearing
|
||||
`interval_seconds` to null flips recurring → one-shot. Refuses
|
||||
cancelled rows (terminal state).
|
||||
|
||||
### `cancel_schedule(id, targets?)`
|
||||
|
||||
Cancel a schedule. Omit `targets` / pass empty to cancel the whole
|
||||
schedule; pass a list to cancel just those recipients (the schedule
|
||||
auto-cancels when every target is removed).
|
||||
|
||||
### `fire_schedule_now(id)`
|
||||
|
||||
Fire a scheduled prompt out of band immediately. Recurring schedules
|
||||
keep their cadence — the manual fire is additive. One-shot schedules
|
||||
are consumed by the manual fire and cancelled afterwards.
|
||||
|
||||
### `list_schedules()`
|
||||
|
||||
Snapshot every schedule (active + cancelled-but-not-reaped): id,
|
||||
owner, body, per-target `last_fired_at` + `last_result`,
|
||||
`next_fire_at_unix`, `interval_seconds`. Use to look up an id before
|
||||
cancelling, or to audit upcoming wake-ups across the swarm.
|
||||
|
||||
## `diagnostics` tool group
|
||||
|
||||
### `get_logs(agent, lines?)`
|
||||
|
||||
Fetch recent journal lines for a sub-agent container. Useful for
|
||||
diagnosing MCP-registration failures, startup crashes, plugin install
|
||||
errors, or any harness issue you can't see from inside the container.
|
||||
|
||||
Pass the plain logical agent name (e.g. `"gui"`) — hive-c0re resolves
|
||||
the machine name (`h-<name>`). `lines` defaults to 50, host-capped at 500.
|
||||
|
||||
## See also
|
||||
|
||||
- `remind` (no-approval self-wake path) — documented in
|
||||
[`docs/turn-loop.md`](../turn-loop.md).
|
||||
- [`docs/approvals.md`](../approvals.md) — approval flow for
|
||||
`request_schedule_prompt`.
|
||||
|
|
@ -5,9 +5,8 @@ claude has access to in return.
|
|||
|
||||
## The loop
|
||||
|
||||
Each agent harness (`hive serve`, with role picked from `$HIVE_ROLE`
|
||||
— `"agent"` for sub-agents, `"manager"` for the manager — one
|
||||
binary, not two) runs:
|
||||
Each agent harness (`hive serve`, role set via `$HIVE_ROLE` — always
|
||||
`"agent"`, one binary) runs:
|
||||
|
||||
1. Long-poll `Recv` on its socket. The host-side broker
|
||||
(`broker.rs::recv_blocking_batch`) returns immediately if there's
|
||||
|
|
@ -292,115 +291,74 @@ The harness ships an embedded MCP server (rmcp 1.7). Claude launches
|
|||
it as a stdio child via `--mcp-config`. The hyperhive socket name is
|
||||
`hyperhive`, so the tools land in claude as `mcp__hyperhive__<tool>`.
|
||||
|
||||
### Sub-agent tools
|
||||
Tool access is gated by tool groups (`HIVE_TOOL_GROUPS`). The default
|
||||
preset (`AGENT_DEFAULT`) includes `messaging`, `meta`, `inbox`, and
|
||||
`execution`. Privileged groups (`lifecycle`, `approvals`, `scheduling`,
|
||||
`diagnostics`) are opt-in via the P3RM1SS10NS tab.
|
||||
|
||||
- `send(to, body, in_reply_to?)` — message a peer (logical agent
|
||||
name), another agent, or the operator (recipient `operator`,
|
||||
surfaces in the dashboard inbox). Use `to: "<parent>"` to
|
||||
address the agent's topology parent without knowing its label;
|
||||
the broker resolves the sentinel at delivery time (falls back
|
||||
to `operator` for root agents). Optional `in_reply_to: i64`
|
||||
links this message to a prior message id for thread rendering
|
||||
in the dashboard message flow and the per-agent inbox.
|
||||
- `recv(wait_seconds?, max?)` — drain inbox messages. Without
|
||||
`wait_seconds` (or with `0`) returns immediately, a cheap
|
||||
"anything pending?" peek. Positive value parks the turn up
|
||||
to that many seconds (cap 180) — incoming messages wake
|
||||
instantly, otherwise returns empty at the timeout. `max`
|
||||
(default 1, server-side cap 32) drains up to N popped rows
|
||||
in one round-trip; `wait_seconds` applies to the *first*
|
||||
message, then the call drains up to `max` total.
|
||||
- `ask(question, options?, multi?, ttl_seconds?, to?)` —
|
||||
surface a structured question. Same shape as the manager's;
|
||||
recipient defaults to the operator (dashboard) but can be set
|
||||
to a peer agent name via `to: "<agent>"`. Answer routes back
|
||||
to the asker's own inbox as `HelperEvent::QuestionAnswered`
|
||||
via `coord.notify_agent`. For peer questions the recipient
|
||||
sees a `HelperEvent::QuestionAsked` event and replies with
|
||||
`answer(id, answer)`.
|
||||
- `answer(id, answer)` — respond to a `question_asked` event
|
||||
routed to this agent. Authorisation is strict: only the
|
||||
declared target (or the operator via the dashboard) can
|
||||
answer.
|
||||
- `get_loose_ends()` — list everything still pending against
|
||||
this agent: unanswered questions it asked / was asked, plus
|
||||
reminders it scheduled. Each row carries an id + kind for
|
||||
### Core tools (always available)
|
||||
|
||||
**Messaging** (`messaging` group): `send(to, body, in_reply_to?)`,
|
||||
`recv(wait_seconds?, max?)`, `ask(question, options?, multi?,
|
||||
ttl_seconds?, to?)`, `answer(id, answer)`.
|
||||
|
||||
- `send` — message a peer (logical name) or the operator
|
||||
(`to: "operator"`). Use `to: "<parent>"` to address the topology
|
||||
parent without hardcoding the label; the broker resolves the
|
||||
sentinel at delivery time. Optional `in_reply_to: i64` links the
|
||||
message to a prior id for thread rendering.
|
||||
- `recv` — drain inbox. Without `wait_seconds` (or `0`) returns
|
||||
immediately. Positive value parks the turn up to that many seconds
|
||||
(cap 180) — incoming messages wake instantly. `max` (default 1, cap
|
||||
32) drains up to N rows; `wait_seconds` applies to the first, then
|
||||
drains up to `max` total.
|
||||
- `ask` — surface a structured question to the operator (default) or
|
||||
a peer agent (`to: "<agent>"`). Non-blocking — returns a question
|
||||
id; the answer arrives as a `question_answered` system event in the
|
||||
asker's inbox. `options` is advisory; `multi=true` renders as
|
||||
checkboxes; `ttl_seconds` auto-cancels with answer `[expired]`.
|
||||
- `answer` — respond to a `question_asked` event routed to this
|
||||
agent. Strict authorisation: only the declared target can answer.
|
||||
|
||||
**Inbox** (`inbox` group): `get_loose_ends()`,
|
||||
`cancel_loose_end(kind, id)`, `remind(message, delay_seconds? |
|
||||
at_unix_timestamp?)`, `request_next_turn()`.
|
||||
|
||||
- `get_loose_ends` — list pending questions (asked/owed) and
|
||||
scheduled reminders. Each row carries an id + kind for
|
||||
`cancel_loose_end`.
|
||||
- `cancel_loose_end(kind, id)` — withdraw a `question`
|
||||
(posts `[cancelled by <self>]` to unblock the asker), a
|
||||
`reminder` (hard-delete before fire), or (manager only) an
|
||||
`approval` (transitions to `Cancelled`; sub-agents refused with a
|
||||
clear error). Sub-agents may only cancel rows they own.
|
||||
- `remind(message, due)` — schedule a reminder that lands in
|
||||
this agent's own inbox at a future time (sender shows as
|
||||
`reminder`). Large payloads spill to
|
||||
`/agents/<self>/state/reminders/` with the inbox message a
|
||||
short pointer. Each agent's pending-reminder count is capped
|
||||
(default 50, override via `HIVE_REMIND_MAX_PENDING_PER_AGENT`);
|
||||
scheduling a new one fails if the cap is already hit.
|
||||
- `set_status(text)` — set a free-text status string visible on
|
||||
the operator dashboard. Persisted to
|
||||
`{state_dir}/hyperhive-status`; survives harness restarts. Pass
|
||||
an empty string to clear. Validated: must be a single line and
|
||||
≤ 200 Unicode characters; the server rejects multi-line or
|
||||
over-length text with a clear error.
|
||||
- `get_agent_meta(name?)` — fetch identity + status metadata for
|
||||
an agent: `{ name, role, hyperhive_rev, running, status_text,
|
||||
status_set_at, hive_name?, swarm_name? }`. Pass `name` to query
|
||||
a peer (e.g. check whether a sub-agent is idle before sending it
|
||||
work). Omit `name` to get your own identity stamp — replaces the
|
||||
previous `whoami` tool. `running` is `true` when the container is
|
||||
up. When `running` is `false` the host clears `status_text` /
|
||||
`status_set_at` (they would be stale snapshots from before the
|
||||
container stopped) before serving the response. Status fields are
|
||||
also `None` when the target has never called `set_status` or has
|
||||
cleared it. `hive_name` and `swarm_name` are present when
|
||||
`services.hyperhive.hiveName` / `services.hyperhive.swarmName`
|
||||
are configured on the host; omitted in single-hive deployments.
|
||||
- `request_next_turn()` — ask the harness to start another turn
|
||||
immediately after this one ends, even if the inbox is empty. Use for
|
||||
multi-turn tasks (long builds, sequential steps) where you want to
|
||||
continue without waiting for an external message. The next turn starts
|
||||
with `from: "self"` and `body: "continue"`. No-op if new inbox
|
||||
messages arrive before this turn ends. No args.
|
||||
- `run(cmd, timeout_secs?)` — submit a shell command for
|
||||
background execution (`sh -c <cmd>`). Returns a task ID immediately;
|
||||
the command runs asynchronously in a harness-managed tokio task. Stdout
|
||||
and stderr stream to `harness/bash-tasks/<id>.{out,err}`. When the
|
||||
task completes (or times out, or the process errors), the harness wakes
|
||||
the agent with a summary body — handle on a future turn. Optional
|
||||
`timeout_secs`: pass a value for a deadline, or omit for no timeout
|
||||
(runs until natural exit). Requires the `execution` tool group.
|
||||
Exposed as `mcp__bash__run`.
|
||||
- `status(id)` — poll the status of a task submitted with
|
||||
`run`. Returns status (`pending`/`running`/`done`/`timed_out`/
|
||||
`interrupted`), exit code, run duration, and the last 4 KiB of stdout
|
||||
and stderr (full output in the `.out`/`.err` files). Tasks marked
|
||||
`interrupted` had their process killed by a harness restart; a best-
|
||||
effort wake was still sent so the agent is not silently blocked.
|
||||
Exposed as `mcp__bash__status`.
|
||||
- `cancel_loose_end` — withdraw a `question` (posts `[cancelled by
|
||||
<self>]`) or hard-delete a `reminder`. Agents may only cancel rows
|
||||
they own.
|
||||
- `remind` — schedule a reminder in this agent's own inbox. Large
|
||||
payloads spill to `/agents/<self>/state/reminders/`. Pending count
|
||||
capped at 50 per agent (`HIVE_REMIND_MAX_PENDING_PER_AGENT`).
|
||||
- `request_next_turn` — ask the harness to start another turn
|
||||
immediately after this one ends, even if the inbox is empty.
|
||||
Next turn fires with `from: "self"` and `body: "continue"`.
|
||||
|
||||
**Agent lifecycle + config tools** (direct children only; requires
|
||||
`lifecycle` or `approvals` tool group):
|
||||
**Meta** (`meta` group): `set_status(text)`, `get_agent_meta(name?)`.
|
||||
|
||||
- `kill(name)`, `start(name)`, `restart(name)`, `update(name)` — manage
|
||||
a direct child sub-agent (graceful stop, start, stop+start, rebuild).
|
||||
No approval required. Topology-enforced: `name` must be a direct child
|
||||
per `topology.json`. Server rejects all other agent names. Requires
|
||||
`lifecycle` tool group.
|
||||
- `list_containers()` — list all descendant containers with running
|
||||
status. Topology-enforced (descendants only). Requires `lifecycle`
|
||||
tool group.
|
||||
- `request_init_config(name, description?)` — step 1 of spawning a new
|
||||
direct child agent. Queues an `InitConfig` approval; on operator
|
||||
approve, hive-c0re seeds the proposed config repo with a default
|
||||
`agent.nix` template. `name` must be a direct child. Topology-enforced.
|
||||
Fails if config already exists. Requires `approvals` tool group.
|
||||
- `request_apply_commit(agent, commit_ref, description?)` — step 2 of
|
||||
spawning a new direct child (or updating an existing child's config).
|
||||
Submit a commit sha from the child's proposed config repo for operator
|
||||
approval. `agent` must be a direct child. Topology-enforced. `commit_ref`
|
||||
must be a 7-40 char hex sha. Requires `approvals` tool group.
|
||||
- `set_status` — set a free-text status string visible on the
|
||||
dashboard. Single line, ≤ 200 chars. Persisted to
|
||||
`{state_dir}/hyperhive-status`. Pass `""` to clear.
|
||||
- `get_agent_meta` — fetch identity + status metadata for an agent:
|
||||
`{ name, hyperhive_rev, running, status_text, status_set_at,
|
||||
hive_name?, swarm_name? }`. Omit `name` to query self.
|
||||
|
||||
### Privileged tools (by tool group)
|
||||
|
||||
- **Bash execution** (`execution`) — background shell tasks. See
|
||||
[`docs/tools/bash.md`](tools/bash.md).
|
||||
- **Lifecycle + config** (`lifecycle`, `approvals`) — manage child
|
||||
agents, spawn new ones, apply config commits. See
|
||||
[`docs/tools/lifecycle.md`](tools/lifecycle.md).
|
||||
- **Scheduling + diagnostics** (`scheduling`, `diagnostics`) —
|
||||
scheduled prompts, `get_logs`. See
|
||||
[`docs/tools/scheduling.md`](tools/scheduling.md).
|
||||
- **Matrix MCP + extra servers** — `mcp__matrix__*` tools and
|
||||
per-agent extra MCP config. See
|
||||
[`docs/tools/matrix.md`](tools/matrix.md).
|
||||
|
||||
### Waking the agent from inside the container
|
||||
|
||||
|
|
@ -411,170 +369,22 @@ socket at `/run/hive/mcp.sock`. Two equivalent paths:
|
|||
- **Shell out to `hive wake --from <label> --body <text>`**
|
||||
(use `--body -` to read body from stdin). Already on the
|
||||
container's `PATH` since the harness binary is in
|
||||
`systemPackages`. Convenient for shell-script integrations.
|
||||
Works for both `agent` and `manager` roles.
|
||||
`systemPackages`. Convenient for shell-script integrations and
|
||||
co-process daemons (matrix bridge, webhook listeners, scrapers).
|
||||
|
||||
- **Speak the wire protocol directly** — JSON-line over the
|
||||
unix socket: `{"cmd":"wake","from":"matrix","body":"new dm
|
||||
from @alice"}\n`. Same shape any other AgentRequest uses;
|
||||
from @alice"}\n`. Same shape as any other `AgentRequest`;
|
||||
see `hive-sh4re::AgentRequest::Wake`.
|
||||
|
||||
The wake event lands in the broker as `{from:<label>,
|
||||
to:<agent>, body}`, which wakes whatever `recv` call the
|
||||
harness is currently blocked on. Next turn fires with the
|
||||
wake prompt formed from that message — claude sees "from:
|
||||
matrix" (or whatever label) and reacts.
|
||||
to:<agent>, body}`, waking whatever `recv` call the harness
|
||||
is currently blocked on. The next turn fires with the wake
|
||||
prompt formed from that message.
|
||||
|
||||
Identity = socket: anything that can connect to
|
||||
`/run/hive/mcp.sock` is implicitly trusted to inject these,
|
||||
which is fine because the bind-mount is the agent's own
|
||||
container only.
|
||||
|
||||
### Built-in matrix MCP (`mcp__matrix__*`)
|
||||
|
||||
When `hyperhive.matrix.enable = true` (default) and the host-level
|
||||
matrix tuwunel is configured, the harness auto-injects `hive-matrix-mcp`
|
||||
as a second stdio MCP server. Tools land as `mcp__matrix__<name>`:
|
||||
|
||||
- `send_message(room, body)` — send a markdown message; `room` accepts
|
||||
`!id:server` or `#alias:server`, daemon resolves either
|
||||
- `send_dm(user_id, body)` — send a direct message to a matrix user
|
||||
- `send_reaction(room, event_id, key)` — react to a message
|
||||
- `send_reply(room, event_id, body)` — threaded reply
|
||||
- `mark_read(room, event_id)` — advance the read receipt
|
||||
- `list_rooms()` — enumerate joined rooms
|
||||
(`{ id, canonical_alias, name, member_count }` per room)
|
||||
- `list_room_members(room)` — members of a room
|
||||
- `read_room(room, limit?)` — recent timeline events
|
||||
|
||||
The daemon (`hive-matrix-daemon`) holds the long-running matrix-sdk
|
||||
`Client` + sync loop; the stdio bridge (`hive-matrix-mcp`) is spawned
|
||||
per turn and forwards tool calls over `/run/hive-matrix.sock`. Both
|
||||
silently exit when `<state>/matrix-token` is absent (account not yet
|
||||
provisioned). Incoming room events wake the agent via `AgentRequest::Wake`
|
||||
with `from: "matrix"` and a teaser body
|
||||
(`[matrix] <sender> in <room>: <first-100c>…` where `<sender>` is
|
||||
the matrix user id and `<room>` is the alias or id as reported by
|
||||
the SDK).
|
||||
|
||||
### Extra MCP servers (per-agent)
|
||||
|
||||
Each agent's NixOS config can declare additional MCP servers via
|
||||
`hyperhive.extraMcpServers.<key> = { command, args, env,
|
||||
allowedTools }`. The module writes the map to
|
||||
`/etc/hyperhive/extra-mcp.json`; the harness reads it at boot and
|
||||
merges every entry into `--mcp-config` (under `mcpServers.<key>`)
|
||||
and `--allowedTools` (as `mcp__<key>__<pattern>`). The agent's
|
||||
flake.nix forwards every flake input to `agent.nix` as the
|
||||
`flakeInputs` module arg, so external MCP-server flakes are pulled
|
||||
in by adding them to `inputs.*` and referenced as
|
||||
`flakeInputs.<name>.packages.${pkgs.system}.default` — the
|
||||
resolved sha lands in the agent's own `flake.lock` and rolls up to
|
||||
meta's.
|
||||
|
||||
### Manager tools (in addition to send/recv)
|
||||
|
||||
- `request_init_config(name, description?)` — first step of a
|
||||
two-step spawn. Queues an `InitConfig` approval (≤9 char name);
|
||||
on operator approve, hive-c0re seeds the proposed config repo
|
||||
with a default `agent.nix` template and sends the manager a
|
||||
`HelperEvent::ConfigReady { agent }`. The manager then edits
|
||||
`agent.nix`, commits the changes, and calls `request_apply_commit`
|
||||
with the commit sha — the first ApplyCommit on a freshly-init'd
|
||||
config creates the container. Fails if a proposed repo for this
|
||||
name already exists. (The operator can also direct-spawn an empty
|
||||
agent from the dashboard's `◆ R3QU3ST SP4WN` button, which routes
|
||||
via `HostRequest::RequestSpawn`.) Also available to agents for direct
|
||||
children only (requires `approvals` tool group; see agent lifecycle
|
||||
tools section above).
|
||||
- `kill(name)` — graceful stop. No approval required. Also available to
|
||||
agents for direct children only (requires `lifecycle` tool group; see
|
||||
agent lifecycle tools section above).
|
||||
- `start(name)` — start a stopped sub-agent. No approval. Also available
|
||||
to agents for direct children only.
|
||||
- `restart(name)` — stop + start. No approval. Also available to agents
|
||||
for direct children only.
|
||||
- `update(name)` — rebuild (re-applies the current hyperhive flake
|
||||
+ agent.nix, restarts). No approval, idempotent. Manager calls
|
||||
this on receipt of a `needs_update` system event. Also available to
|
||||
agents for direct children only.
|
||||
- `request_apply_commit(agent, commit_ref)` — submit a config
|
||||
change for any agent (`root` for the manager's own config) for
|
||||
operator approval. Also available to agents for direct children only
|
||||
(requires `approvals` tool group; see agent lifecycle tools section
|
||||
above).
|
||||
- `request_update_meta_inputs(inputs?, description?)` — queue an
|
||||
approval to run `nix flake update [inputs...]` on the meta flake.
|
||||
Pass specific input names (e.g. `["bitburner-agent"]`) or omit
|
||||
for all. Returns immediately; lock update runs on operator
|
||||
approval. Does NOT trigger rebuilds — call `update(name)` on
|
||||
affected agents after approval resolves.
|
||||
- `ask(question, options?, multi?, ttl_seconds?, to?)` —
|
||||
surface a structured question to the operator (default) or a
|
||||
sub-agent (`to: "<agent>"`). Non-blocking — returns the
|
||||
queued question id; the answer arrives later as
|
||||
`HelperEvent::QuestionAnswered { id, question, answer,
|
||||
answerer }` in the asker's inbox. Options always render
|
||||
alongside a free-text fallback; `multi=true` renders options
|
||||
as checkboxes. `ttl_seconds` auto-cancels with answer
|
||||
`[expired]` (and `answerer: "ttl-watchdog"`) after the
|
||||
deadline (useful for time-sensitive decisions that become moot
|
||||
if no one has responded). The operator can also manually
|
||||
cancel with `[cancelled]` via the dashboard.
|
||||
- `answer(id, answer)` — respond to a `question_asked` event
|
||||
that was routed to the manager (a sub-agent did
|
||||
`ask(to: "manager", ...)`). Surfaces in the asker's inbox as
|
||||
the same `question_answered` event.
|
||||
- `get_logs(agent, lines?)` — fetch recent journal lines for a
|
||||
sub-agent container (diagnose MCP-registration failures,
|
||||
startup crashes, etc.). Pass the plain logical agent name;
|
||||
hive-c0re resolves the machine name (`h-<name>`, manager
|
||||
`root`). `lines` defaults to 50, host-capped at 500.
|
||||
- `request_schedule_prompt(targets, body, first_fire_at_unix, interval_seconds?, description?)` —
|
||||
queue an operator-approval for a scheduled prompt. On approve,
|
||||
`body` is fanned out to each `targets` agent at
|
||||
`first_fire_at_unix`; recurring if `interval_seconds` is set,
|
||||
one-shot otherwise. Even self-targeted schedules go through
|
||||
approval (use `remind` for unapproved self-wake). Long downtime
|
||||
fires once per recurring row on resume (catch-up clamp).
|
||||
- `edit_schedule(id, body?, description?, interval_seconds?, next_fire_at_unix?, targets_add?, targets_remove?)` —
|
||||
partial-update a schedule. Pass only the fields to
|
||||
change; absent fields are left alone. `targets_add` / `targets_remove`
|
||||
mutate the recipient list in the same transaction; re-adding a
|
||||
previously-cancelled target drops its tombstone + history (fresh
|
||||
start). Clearing a scalar (e.g. `interval_seconds: null`) flips
|
||||
recurring→one-shot. Refuses cancelled rows. Same authorization as
|
||||
`cancel_schedule`.
|
||||
- `cancel_schedule(id, targets?)` — cancel a schedule. Omit
|
||||
`targets` / pass empty to cancel the whole schedule; pass a list
|
||||
to cancel just those recipients (auto-cancels when every target
|
||||
is removed). Authorization: manager can cancel schedules it owns
|
||||
or any owned by a sub-agent in its topology subtree.
|
||||
- `fire_schedule_now(id)` — fire a scheduled prompt out of band.
|
||||
Runs the per-target fan-out once immediately. Recurring schedules
|
||||
keep their cadence (the manual fire is additive); one-shot
|
||||
schedules are consumed by the fire and cancelled afterwards. Same
|
||||
authorization rules as `cancel_schedule`.
|
||||
- `list_schedules()` — snapshot every schedule (active +
|
||||
cancelled-but-not-reaped): id, owner, body, per-target
|
||||
`last_fired_at` + `last_result`, `next_fire_at_unix`,
|
||||
`interval_seconds`. Use to look up an id before cancelling or to
|
||||
audit upcoming wake-ups across the swarm.
|
||||
- `remind` / `get_loose_ends` / `cancel_loose_end` / `set_status`
|
||||
/ `get_agent_meta` — same as the sub-agent tools above.
|
||||
`get_loose_ends` scopes to the manager's own items by default;
|
||||
pass `agent: "*"` for a hive-wide view, or `agent: "<name>"`
|
||||
to inspect one agent.
|
||||
`cancel_loose_end` may cancel any agent's row.
|
||||
|
||||
The boundary: lifecycle ops on *existing* direct children
|
||||
(`kill`/`start`/`restart`/`update`) are discretionary — no operator
|
||||
approval required (manager can do so for any sub-agent; agents can do so
|
||||
only for direct children with `lifecycle` tool group). Creating a new
|
||||
agent (`request_init_config` → `request_apply_commit` for the first sha)
|
||||
and changing any agent's config (`request_apply_commit`) still go through
|
||||
the approval queue (same topology scoping for agents: direct children only
|
||||
with `approvals` tool group).
|
||||
`/run/hive/mcp.sock` is implicitly trusted to inject these —
|
||||
the bind-mount is the agent's own container only.
|
||||
|
||||
### Authoritative state
|
||||
|
||||
|
|
@ -604,7 +414,7 @@ status hint moved to the wake prompt + UI header.
|
|||
`web_tools` tool group is enabled — see P3RM1SS10NS tab).
|
||||
- Denied by omission or `claude-settings.json` deny list: `Bash`,
|
||||
`Task`, `NotebookEdit`, `TodoWrite`.
|
||||
- Allowed MCP tools: as listed above per flavor.
|
||||
- Allowed MCP tools: as listed above (by tool group).
|
||||
|
||||
`Bash` is disallowed — shell execution goes through
|
||||
`mcp__bash__run` (background tasks with structured output +
|
||||
|
|
|
|||
Loading…
Reference in a new issue