nix: wire the independent hive-subagent-daemon systemd unit and MCP server
This commit is contained in:
parent
7699db6500
commit
c280664d74
6 changed files with 77 additions and 2 deletions
|
|
@ -93,6 +93,7 @@
|
|||
hive-matrix-daemon
|
||||
hive-metric
|
||||
hive-screen-mcp
|
||||
hive-subagent-daemon
|
||||
assets
|
||||
frontend
|
||||
reference-docs
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ pub(super) async fn get_journal(
|
|||
"hive-agent.service",
|
||||
"hive-mcp-http.service",
|
||||
"hive-bash-daemon.service",
|
||||
"hive-subagent-daemon.service",
|
||||
"hive-matrix-daemon.service",
|
||||
];
|
||||
let unit = if u.ends_with(".service") {
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@
|
|||
# unreachable from inside a container — wrapped with
|
||||
# `wireguard-tools` for `hivectl wg`). The daemon/harness/MCP bins
|
||||
# the harness execs (hive-agent{,-mcp}, hive-bash-daemon,
|
||||
# hive-matrix-daemon, hive-matrix-mcp) are wired via their own
|
||||
# hive-subagent-daemon, hive-matrix-daemon, hive-matrix-mcp) are
|
||||
# wired via their own
|
||||
# ExecStart/command lines in the sibling modules — they don't need
|
||||
# to be on PATH too. Only this one is actually looked up on PATH
|
||||
# by claude/shell code inside the container:
|
||||
|
|
|
|||
|
|
@ -197,6 +197,23 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.mcp.subagentHttpPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8793;
|
||||
example = 8794;
|
||||
description = ''
|
||||
Loopback port `hive-subagent-daemon` serves its MCP tools
|
||||
(`start`/`continue`/`interrupt`) on. Independent daemon (own crate,
|
||||
`hive-subagent-mcp`) — a subagent spawns a full nested `claude`
|
||||
process, a much heavier capability than a bash command, worth its own
|
||||
deployable/restartable unit. Same shape/reasoning as
|
||||
`hyperhive.mcp.bashHttpPort` otherwise: sole transport, self-healing
|
||||
restart, loopback-only so no auth token is needed. Shipped default-on
|
||||
for every agent today, same as `bash` — expected to become a real
|
||||
opt-in capability gate later, not yet.
|
||||
'';
|
||||
};
|
||||
|
||||
config = {
|
||||
# Assert the transport-specific required field is actually set —
|
||||
# `command`/`url` are both `nullOr` so the submodule schema stays
|
||||
|
|
@ -225,6 +242,17 @@ in
|
|||
allowedTools = [ "*" ];
|
||||
};
|
||||
|
||||
# Auto-inject the subagent MCP server — default-on for every agent for
|
||||
# now (operator's call: "default on for now, should be a capability
|
||||
# later" — not gated behind an enable option yet, unlike `matrix.nix`'s
|
||||
# pattern). `lib.mkDefault` so an agent.nix can still override/disable
|
||||
# the entry in the meantime.
|
||||
hyperhive.extraMcpServers.subagent = lib.mkDefault {
|
||||
type = "http";
|
||||
url = "http://127.0.0.1:${toString config.hyperhive.mcp.subagentHttpPort}/mcp";
|
||||
allowedTools = [ "*" ];
|
||||
};
|
||||
|
||||
environment.etc."hyperhive/extra-mcp.json".text = builtins.toJSON config.hyperhive.extraMcpServers;
|
||||
|
||||
environment.etc."hyperhive/send-allow.json".text =
|
||||
|
|
@ -278,6 +306,49 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
# Subagent task runner daemon — independent of `hive-bash-daemon` (own
|
||||
# crate, own process): spawns nested claude sessions on request, serves
|
||||
# the `start`/`continue`/`interrupt` MCP tools directly over
|
||||
# streamable-http on `hyperhive.mcp.subagentHttpPort`. No task files —
|
||||
# this daemon's only state is an in-memory map of currently-running
|
||||
# processes, live only as long as the process is (see
|
||||
# `hive-subagent-mcp/src/session.rs`'s module doc); a restart stops
|
||||
# whatever's running, the actual claude session survives independently.
|
||||
systemd.services.hive-subagent-daemon = {
|
||||
description = "subagent task runner + MCP daemon for hive-subagent";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "hive-agent.service" ];
|
||||
# A subagent task runs its own nested `claude` invocation (via
|
||||
# `hive-claude`), which needs to resolve `claude` itself off PATH —
|
||||
# same reasoning as `hive-bash-daemon`'s `path` above, even though
|
||||
# this daemon never shells out to `bash -c` directly.
|
||||
path = [
|
||||
"/run/wrappers"
|
||||
"/run/current-system/sw"
|
||||
];
|
||||
environment = {
|
||||
# Same in-agent todo socket as `hive-bash-daemon` — both push task
|
||||
# todos to the one harness socket. Must match the harness's
|
||||
# HIVE_AGENT_SOCKET (agent-service.nix).
|
||||
HIVE_AGENT_SOCKET = "/run/hive-agent/${userName}/agent.sock";
|
||||
RUST_LOG = "info";
|
||||
# HYPERHIVE_HARNESS_DIR / HYPERHIVE_STATE_DIR: see
|
||||
# `hive-bash-daemon`'s own comment above — same global injection,
|
||||
# same reasoning.
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${config.hyperhive.packages.hive-subagent-daemon}/bin/hive-subagent-daemon --http 127.0.0.1:${toString config.hyperhive.mcp.subagentHttpPort}";
|
||||
SyslogIdentifier = "hive-subagent-daemon";
|
||||
# `always`, same reasoning as `hive-bash-daemon`: the MCP tool is
|
||||
# served in-process, so a down window is total loss of
|
||||
# `spawn_subagent` with no stdio fallback.
|
||||
Restart = "always";
|
||||
RestartSec = 3;
|
||||
User = userName;
|
||||
Group = userName;
|
||||
};
|
||||
};
|
||||
|
||||
# Persistent streamable-http MCP daemon for the built-in hyperhive
|
||||
# surface — the *sole* transport for that surface; always
|
||||
# wired. Long-lived so claude reconnects to the stable URL each turn
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
description = ''
|
||||
hyperhive package outputs consumed by the harness modules: the
|
||||
per-binary daemon/CLI packages (`hive-agent`, `hive-agent-mcp`,
|
||||
`hive-bash-daemon`,
|
||||
`hive-bash-daemon`, `hive-subagent-daemon`,
|
||||
`hive-forge`, `hive-forge-notify`, `hive-github-notify`,
|
||||
`hive-matrix-daemon`,
|
||||
`hive-metric`, `hive-screen-mcp`) plus the `assets`, `frontend`,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ let
|
|||
hive-agent = "hyperhive in-container agent harness serve loop";
|
||||
hive-agent-mcp = "hyperhive agent-surface MCP server";
|
||||
hive-bash-daemon = "hyperhive per-agent bash-task runner daemon (serves its MCP tools directly over streamable-http)";
|
||||
hive-subagent-daemon = "hyperhive per-agent claude-subagent task runner daemon (serves its MCP tools directly over streamable-http)";
|
||||
hive-matrix-daemon = "hyperhive per-agent matrix-sdk daemon (serves its MCP tools directly over streamable-http)";
|
||||
hive-metric = "hyperhive agent-emitted custom metrics CLI";
|
||||
hive-screen-mcp = "hyperhive screen MCP bridge (screenshot + input for GUI agents)";
|
||||
|
|
|
|||
Loading…
Reference in a new issue