`docs/tools/subagent.md` and `docs/tools/bash.md` both described their MCP server as injected "unconditionally". Both entries are `lib.mkDefault`, and the module says why one line above each: "so an agent.nix can still override/disable the entry", "so the operator's own agent.nix can override the entry". The word matters for the subagent one in particular. The same comment block records the framing that it is default-on for now and should become a real capability gate later, so "can I turn this off today?" is a question an operator has — and "unconditionally" answers it as "patch nix/" when the answer is one override in agent.nix. Both pages now say default, and say what the default yields to. The other direction on the same page: `subagentHttpPort`'s option description and the unit comment beside it both listed three tools, `start`/`continue`/`interrupt`. The daemon serves four. #4101, which introduced it, is titled with the three-verb phrasing, so `status` landed afterwards and never reached either description — while `subagent.md` had the full set all along. The option description renders into the generated options doc, so it is the one an operator reads. Closes #4231.
56 lines
2.6 KiB
Markdown
56 lines
2.6 KiB
Markdown
# Subagent daemon
|
|
|
|
`hive-subagent-daemon` (crate `hive-subagent-mcp`) spawns nested headless
|
|
`claude` sessions on request. Own process, own systemd unit, own MCP
|
|
server (`subagent`, not `hyperhive`) — independent of `hive-bash-daemon`:
|
|
a subagent is a full nested claude process, a materially heavier
|
|
capability than a background shell command, so it gets its own
|
|
deployable/restartable unit rather than living inside the bash daemon.
|
|
|
|
Shipped default-on for every agent — `nix/agent-modules/mcp.nix` injects
|
|
`subagent` into `hyperhive.extraMcpServers` via `lib.mkDefault`
|
|
(`allowedTools = ["*"]`), same as `bash`. Default-on rather than
|
|
unconditional: an `agent.nix` can override or drop the entry, which is
|
|
what `mkDefault` is there for. The operator's own framing: default-on for
|
|
now, a real opt-in capability later.
|
|
|
|
For what the tools do and when an agent should reach for them, see the
|
|
`subagent` MCP server's own tool descriptions and the
|
|
`base:claude-subagents` skill — this page covers the daemon as deployed
|
|
infrastructure, not the agent-facing API.
|
|
|
|
## Tools
|
|
|
|
Served under the `subagent` MCP server (`mcp__subagent__<tool>`): `start`,
|
|
`continue`, `status`, `interrupt`.
|
|
|
|
## State
|
|
|
|
In-memory only: a map of currently running processes, live only as long
|
|
as the daemon process is. A daemon restart stops whatever was running
|
|
rather than adopting it. The durable record of a subagent's existence is
|
|
claude's own on-disk session (`hive_claude::SessionStore`), which
|
|
`continue` reattaches to independent of the daemon's own lifetime — a
|
|
restart loses the _in-flight turn_, not the subagent's history.
|
|
|
|
## Compaction trade-off
|
|
|
|
Built on `hive_claude::Claude::spawn` + `RunningClaude::wait` directly
|
|
rather than `InfiniteSession::run`, since only the low-level driver
|
|
exposes a cancel handle to stop a turn mid-flight — that's what makes
|
|
`interrupt` genuinely stop a running turn rather than only cancelling a
|
|
still-pending one. The cost: a turn that overflows the context window
|
|
surfaces as an error rather than self-healing via reactive compaction.
|
|
Subagents are meant to be bounded, single-batch work, not sessions
|
|
long-lived enough to need in-place compaction — a real follow-up if that
|
|
assumption stops holding.
|
|
|
|
## Configuration
|
|
|
|
`hyperhive.mcp.subagentHttpPort` — the daemon's streamable-http listen
|
|
port. Same pattern as `bashHttpPort`/`matrixHttpPort`: a per-agent default
|
|
assigned by `nix/agent-modules/mcp.nix`, only worth overriding for an
|
|
agent that needs a stable or non-default port.
|
|
|
|
Own systemd unit, defined alongside the other per-agent MCP daemons in
|
|
`nix/agent-modules/mcp.nix`.
|