Third and last of #2860's agent-facing URL fallbacks. The operator's ruling was "any special casing is done on the nix side - same binaries, no hard coded fallback", so the default is deleted rather than replaced. Every layer guessed the same wrong thing, and each guess was only ever correct for a process sharing the host netns: - nix/agent-modules/matrix.nix: matrixUrlDefault = localhost:8008, both as the option's default and as a sentinel the daemon unit compared against to decide whether to write HIVE_MATRIX_URL. Now nullOr str, default null, the guard is != null, and the doc says what forge.url's already says: null means "no matrix", not "guess one". - nix/host-modules/hive-c0re/environment.nix: forwarded http://127.0.0.1:<port> when no gatewayHost was set. hive-c0re shares the host netns so it reads as harmless, but the value is handed to agents, which do not -- there it names the agent itself. Now forwarded only when there is a gateway vhost to name, matching the guard HIVE_MATRIX_PUBLIC_URL already uses twelve lines below. - hive-matrix-mcp: paths::DEFAULT_HOMESERVER was the same address compiled in, so dropping the nix defaults alone would have left the daemon dialling loopback inside the agent's own netns -- the very bug, one layer down. homeserver_url() is now Option, and an account with no homeserver is skipped with a log, exactly as one with no token is. discover_token_accounts already refused to guess for the same reason. Two comments taught the assumption back to the next reader ("shared host netns means every agent container resolves localhost to the same machine"); both now say which side of the netns boundary they describe. MATRIX_HTTP keeps its value -- hive-c0re really does share the host netns -- but no longer claims agents do. Gated with nix eval against the extended agent-base config, as a pair: with no url set the daemon unit carries no HIVE_MATRIX_URL, and with one set it carries exactly that. Either check alone passes on a broken guard.
228 lines
9.8 KiB
Markdown
228 lines
9.8 KiB
Markdown
# Agent config knobs
|
|
|
|
Optional per-agent knobs the meta flake wires into the container from
|
|
`services.hyperhive.agents.<name>`, read at boot or per turn by the harness.
|
|
Absent means the default. (The claude spawn + compaction themselves live in
|
|
[claude-invocation](claude-invocation.md).)
|
|
|
|
## Reference docs (`hyperhive.docs.enable`)
|
|
|
|
```nix
|
|
hyperhive.docs.enable = true; # default: false (true for the manager agent)
|
|
```
|
|
|
|
Makes the hyperhive `docs/` tree available inside the container at a nix
|
|
store path read from `$HIVE_DOCS_DIR`, and injects a single pointer
|
|
sentence into the agent's system prompt so it knows the docs exist and
|
|
where to find them. The tree is served by `claude --add-dir` so the full
|
|
markdown is readable during every turn.
|
|
|
|
Enabled by default only for the root/manager agent (`nix/templates/ruth.nix`). Any
|
|
agent can opt in by adding the line above to its `agent.nix`.
|
|
|
|
The `docs/` source is a narrow flake input (`hyperhive-docs`) tracked
|
|
separately from the main `hyperhive` flake so editing docs re-locks only
|
|
that input — not every agent's container gets rebuilt on a doc-only change.
|
|
|
|
## Agent icon
|
|
|
|
```nix
|
|
hyperhive.icon = ./icon.svg; # default: null (falls back to shared hyperhive logo)
|
|
```
|
|
|
|
Path to an SVG file used as this agent's visual identity — shown in
|
|
the per-agent page header, as the page favicon, and uploaded to the
|
|
agent's Forgejo profile avatar (via the `forge-avatar-sync` boot
|
|
unit) and Matrix profile avatar (set by `hive-matrix-daemon` over its
|
|
live Client). Commit the SVG next to `agent.nix` in the config repo
|
|
and reference it as a relative path.
|
|
|
|
When `null` (the default), the agent falls back to the shared
|
|
hyperhive branding mark. The harness serves whichever icon is active
|
|
at `GET /icon` on the per-agent web port.
|
|
|
|
## `user.passwordlessSudo`
|
|
|
|
```nix
|
|
hyperhive.user.passwordlessSudo = true; # default
|
|
```
|
|
|
|
Grants the per-agent unix user passwordless `sudo` (`NOPASSWD: ALL`).
|
|
Enabled by default so claude's shell tools work for operations that
|
|
need root inside the container (`systemctl`, package managers in dev
|
|
shells, etc.) — the same privilege surface the previous root-user shape
|
|
had, now elevated explicitly rather than implicitly.
|
|
|
|
Set to `false` for agents that should be strictly unprivileged.
|
|
Any tool invocation that needs root then fails loudly with the standard
|
|
sudo rejection rather than silently succeeding — easier to audit.
|
|
|
|
`hyperhive.user.uid`, `hyperhive.user.gid`, and
|
|
`hyperhive.user.name` are the companion options; see
|
|
`docs/agent-hierarchy.md` — "Harness systemd unit shape" for the full
|
|
`user.*` surface.
|
|
|
|
## Dashboard links
|
|
|
|
```nix
|
|
hyperhive.dashboardLinks = [
|
|
{ label = "Stats"; icon = "📊"; url = "http://localhost:9001/stats"; }
|
|
{ label = "Scratchpad"; url = "http://localhost:8080"; }
|
|
];
|
|
```
|
|
|
|
Declares extra navigation links that appear on the agent's dashboard
|
|
card and in the per-agent page header alongside the built-in forge /
|
|
config / container links. Each entry has:
|
|
|
|
| Field | Required | Description |
|
|
|-------|----------|-------------|
|
|
| `label` | yes | Display text shown in the icon strip tooltip and meta-nav. |
|
|
| `url` | yes | Absolute URL — may include a different port (the dashboard renders it as a plain anchor). |
|
|
| `icon` | no | Emoji or short glyph prefix. Defaults to empty string. |
|
|
|
|
The list is written to `<state>/hyperhive-dashboard-links.json` by a
|
|
one-shot systemd unit at container boot. `hive-c0re` reads the file on
|
|
each container-view snapshot and attaches the links to the agent card
|
|
(`kind = External`) without any code change. Omitting the option
|
|
(default empty) produces no extra links.
|
|
|
|
## Custom static files
|
|
|
|
```nix
|
|
hyperhive.frontend.extraFiles = {
|
|
"games/bitburner" = {
|
|
source = ./bitburner-dist; # path relative to agent.nix
|
|
# target defaults to attribute name: "games/bitburner"
|
|
};
|
|
"my-page" = {
|
|
source = ./my-page.html;
|
|
target = "my-page.html"; # explicit override
|
|
};
|
|
};
|
|
```
|
|
|
|
Layers additional files over the default per-agent web UI dist. Each
|
|
attribute defines one overlay entry:
|
|
|
|
- **`source`** — a Nix path (file or directory) copied into the merged
|
|
static tree. Evaluated at nix build time; the resulting derivation is
|
|
pointed at by `HIVE_STATIC_DIR`.
|
|
- **`target`** — destination path within the merged tree, used as both
|
|
the served URL prefix (`/<target>/…`) and the on-disk layout.
|
|
Defaults to the attribute name. Forward slashes create nested layouts
|
|
(`"games/bitburner"` serves at `/games/bitburner/…`).
|
|
|
|
Constraints: `target` must start with an alphanumeric or `_` and
|
|
contain only alphanumerics, `_`, `.`, `/`, `-`. `..` segments are
|
|
rejected by a config assertion. The merge step refuses to overwrite
|
|
files already present in the default dist — pick a target name that
|
|
does not collide with existing paths (`static/`, `index.html`, etc.).
|
|
|
|
The default dist ships at `hyperhive.frontend.dist` (the
|
|
`hyperhive-frontend` package output, read-only). To replace the
|
|
entire UI rather than layer on top, override `frontend.dist` directly.
|
|
|
|
## Connectivity overrides
|
|
|
|
Two `hyperhive.forge.*` / `hyperhive.matrix.*` options override where
|
|
the per-agent daemons connect. Both rarely need changing on a standard
|
|
single-host deploy, but are useful for multi-hive or custom-network
|
|
setups.
|
|
|
|
```nix
|
|
hyperhive.forge.url = "http://forge.example:3000"; # default: null
|
|
hyperhive.matrix.url = "https://matrix.example"; # default: null
|
|
```
|
|
|
|
**`hyperhive.forge.url`** — base URL of the Forgejo instance. Used by
|
|
a one-shot boot unit (`tea-login`) that writes `~/.config/tea/config.yml`
|
|
directly from the agent's `forge-token`, so `tea` and `hive-forge`
|
|
work without an interactive auth step. The unit is a no-op when
|
|
`forge-token` is absent. Override when the agent should connect to a
|
|
Forgejo on a different host or port (e.g. a swarm peer's forge).
|
|
Validated: must be an `http://` or `https://` URL, or `null`.
|
|
|
|
**Defaults to `null`, meaning "no forge" — not a guessed address.** A
|
|
loopback default would only ever be correct when the forge shares the
|
|
agent's network namespace, and inside a container `localhost` is the
|
|
agent itself, so the default was a value that built fine and then talked
|
|
to the wrong machine. With `null` the `tea-login` and `forge-avatar-sync`
|
|
units are not generated at all: an absent integration rather than a
|
|
misdirected one. You do not normally set this — hive-c0re renders the
|
|
host's real forge URL into every agent, and refuses to write a meta
|
|
flake without one, so `null` only survives where the agent modules are
|
|
evaluated outside a hive.
|
|
|
|
**`hyperhive.matrix.url`** — homeserver URL used by
|
|
`hive-matrix-daemon` when connecting via the matrix-sdk. hive-c0re
|
|
writes it into every agent at deploy time as the gateway-routed
|
|
`matrix.<domain>` URL, so isolated agents can reach the homeserver.
|
|
Override per-agent when an agent should talk to a different homeserver
|
|
— for example a remote hive's tuwunel reached over a VPN, or an
|
|
external Matrix server for a federation-only agent.
|
|
|
|
**Defaults to `null`, meaning "no matrix" — for the same reason
|
|
`forge.url` does.** The homeserver may live on another host, and a
|
|
loopback default resolves inside the agent's own netns to the agent,
|
|
so it would be a value that evaluates fine and then talks to the wrong
|
|
machine. With `null` the daemon has no homeserver and no-ops exactly as
|
|
it does without a token. The hive only forwards `HIVE_MATRIX_URL` when
|
|
it actually has a matrix vhost to name, so `null` survives where a hive
|
|
runs no homeserver, or where the agent modules are evaluated outside a
|
|
hive.
|
|
|
|
## Claude Code plugins
|
|
|
|
The harness installs Claude Code plugins before the serve loop opens.
|
|
Two per-agent `agent.nix` options control this:
|
|
|
|
```nix
|
|
hyperhive.claudeMarketplaces = [ "anthropics/claude-plugins-official" ]; # default
|
|
hyperhive.claudePlugins = [ "skill-creator@claude-plugins-official" ]; # default
|
|
hyperhive.claudePluginsAutoUpdate = false; # default
|
|
```
|
|
|
|
- **`claudeMarketplaces`** — list of marketplace sources passed to
|
|
`claude plugin marketplace add <source>`. The official Anthropic
|
|
marketplace is pre-configured by default; override or extend to add
|
|
custom marketplaces. Idempotent — re-adding an existing source is
|
|
a no-op.
|
|
- **`claudePlugins`** — list of plugin specs passed to
|
|
`claude plugin install <spec>`. Each spec is installed on every boot
|
|
(`install` is expected to be idempotent); failures log a warning but
|
|
do not abort boot. Defaults to Anthropic's `skill-creator`, so every
|
|
agent can author, refine, and evaluate its own skills without any
|
|
per-agent wiring.
|
|
|
|
> Both plugin lists follow ordinary NixOS list-option semantics: a
|
|
> per-agent definition **replaces** the default, it does not extend it.
|
|
> An agent that sets `claudePlugins` and still wants `skill-creator`
|
|
> has to list it explicitly alongside its own entries — likewise for
|
|
> the official marketplace in `claudeMarketplaces`.
|
|
- **`claudePluginsAutoUpdate`** — when `true`, runs
|
|
`claude plugin marketplace update` before installing plugins to pull
|
|
the latest index. Disabled by default to keep boot times short and
|
|
plugin versions pinned.
|
|
|
|
## `cargo.shortMessages`
|
|
|
|
```nix
|
|
hyperhive.cargo.shortMessages = true; # default
|
|
```
|
|
|
|
When enabled (the default), the harness injects a `cargo` shell
|
|
function into `/etc/hyperhive/bash-env.sh` that transparently appends
|
|
`--message-format short` to compile subcommands (`build`, `check`,
|
|
`clippy`, `test`, `run`, `doc`, `bench`, `install`, `rustc`, `fix`).
|
|
This suppresses the per-crate progress lines that flood the response
|
|
window, leaving only warnings and errors.
|
|
|
|
The function handles `+toolchain` selectors (`cargo +nightly build`)
|
|
and passes through cleanly when `--message-format` is already present.
|
|
Non-compile subcommands (`new`, `add`, third-party `cargo-*`) are
|
|
left untouched.
|
|
|
|
Set to `false` for agents that parse cargo's JSON output
|
|
programmatically and do not pass `--message-format json` themselves.
|
|
|