Apply contraction fixes across ~40 doc files (setup, integrations, lifecycle, networking, scheduler, swarm, tools, trust-boundary, UI, etc.). Skipped 14 hits: - 10 where words appear in ALL CAPS for deliberate emphasis (is NOT, do NOT, etc.) - 4 where text could not be safely located due to markdown formatting or column position Applied via systematic scan with checks for fenced code blocks, inline code spans, and intentional caps. Preserves sentence-initial capitalization throughout.
302 lines
14 KiB
Markdown
302 lines
14 KiB
Markdown
# Agent config knobs
|
|
|
|
Optional per-agent knobs, set under `hyperhive.*` in the agent's own
|
|
`agent.nix` and 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 agent user gets root explicitly via `sudo` rather
|
|
than running as root itself.
|
|
|
|
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-lifecycle/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 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. The harness's own web UI
|
|
(`agent_links` in `hive-agent/src/web_ui/state.rs`) reads the file on
|
|
each `/api/state` snapshot and appends the entries to the per-agent
|
|
nav as `kind = External` links — no `hive-c0re` / operator-dashboard
|
|
involvement, and no code change needed to pick up a new entry.
|
|
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
|
|
doesn't 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 aren't generated at all: an absent integration rather than a
|
|
misdirected one. You don't 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
|
|
`chat.<swarm-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" — same reasoning as
|
|
`forge.url` above** (a loopback default would resolve inside the
|
|
agent's own netns to the agent itself, not the homeserver). 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.
|
|
Three per-agent `agent.nix` options control this:
|
|
|
|
```nix
|
|
hyperhive.claudeMarketplaces = [ # default
|
|
"anthropics/claude-plugins-official"
|
|
"${hyperhive.packages.claude-plugins}" # hive's own local marketplace, registered as `hyperhive`
|
|
];
|
|
hyperhive.claudePlugins = [ # default
|
|
"skill-creator@claude-plugins-official"
|
|
"base@hyperhive"
|
|
];
|
|
hyperhive.claudePluginsAutoUpdate = false; # default
|
|
```
|
|
|
|
- **`claudeMarketplaces`** — list of marketplace sources passed to
|
|
`claude plugin marketplace add <source>`. Defaults to Anthropic's
|
|
official marketplace plus hyperhive's own `claude-plugins` nix
|
|
package (see `nix/packages/claude-plugins.nix`) — a local-path
|
|
marketplace registered under the name `hyperhive`, so a hive-authored
|
|
skill needs no forge repo or git remote to ship. 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
|
|
don't abort boot. Defaults to Anthropic's `skill-creator` (so every
|
|
agent can author, refine, and evaluate its own skills) plus
|
|
hyperhive's own `base` plugin — skills that apply to every agent
|
|
regardless of role (currently just `state-hygiene`) — all without
|
|
any per-agent wiring.
|
|
|
|
> Both plugin lists follow ordinary NixOS list-option semantics: a
|
|
> per-agent definition **replaces** the default, it doesn't extend it.
|
|
> An agent that sets `claudePlugins` and still wants the defaults has
|
|
> to list `skill-creator@claude-plugins-official` and `base@hyperhive`
|
|
> explicitly alongside its own entries — likewise for the two default
|
|
> entries 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 don't pass `--message-format json` themselves.
|
|
|
|
## API-key backend (`useApiKey` / `backendEnvironmentFile`)
|
|
|
|
```nix
|
|
hyperhive.useApiKey = true; # default: false
|
|
hyperhive.backendEnvironmentFile =
|
|
"/agents/myagent/harness/openrouter.env"; # default: null
|
|
hyperhive.model = "anthropic/claude-3.5-sonnet"; # provider-specific model string
|
|
```
|
|
|
|
Runs this agent's `claude` against an API-key backend (e.g. OpenRouter)
|
|
instead of a Claude subscription via OAuth. Two options, paired — each
|
|
is a no-op without the other:
|
|
|
|
- **`useApiKey`** tells the harness itself not to wait for a Claude OAuth
|
|
session: at boot, `LoginState::from_dir` reports `Online` without
|
|
checking `~/.claude/` (`hive_agent::login::using_api_key`, reads
|
|
`HIVE_USE_API_KEY`), and the fact is stamped into the consolidated
|
|
harness state file so the operator dashboard also stops reading this
|
|
agent's empty `~/.claude/` as "needs login". An api-key agent that hits
|
|
a real 401 (the key itself is bad) still surfaces `needs_login` — only
|
|
the boot-time "have I ever logged in" check is bypassed, not the
|
|
auth-failure path.
|
|
- **`backendEnvironmentFile`** points at an operator-managed file
|
|
(outside the nix store, one `KEY=value` per line, systemd
|
|
`EnvironmentFile` syntax) supplying the credentials `claude` itself
|
|
reads from the environment — typically `ANTHROPIC_API_KEY` and
|
|
`ANTHROPIC_BASE_URL`. Loaded as an _optional_ `EnvironmentFile`
|
|
(leading `-`), so setting the option before the file exists doesn't
|
|
strand the harness at boot.
|
|
|
|
Provision the file once, out of band (never through nix — an API key in
|
|
the store is world-readable and travels with the flake closure):
|
|
|
|
```sh
|
|
# on the host, once per agent that should use an api-key backend
|
|
sudo install -m 0600 -o root /dev/stdin \
|
|
/var/lib/hyperhive/agents/<name>/harness/openrouter.env <<KEYS
|
|
ANTHROPIC_BASE_URL=https://openrouter.ai/api/v1
|
|
ANTHROPIC_API_KEY=sk-or-...
|
|
KEYS
|
|
```
|
|
|
|
The file lives in the agent's bind-mounted **harness** dir, not `state/`
|
|
— `harness/` survives container rebuilds exactly like `state/` does, but
|
|
(unlike `state/`) is never bind-mounted into a parent agent's container
|
|
(see `docs/agent-lifecycle/persistence.md`'s "Parent access to child state"), so an API
|
|
key placed here is reachable by nothing but this agent and the host.
|
|
|
|
⚠️ Verified end-to-end against OpenRouter hasn't happened as of this
|
|
writing — `ANTHROPIC_BASE_URL` support in the shipped Claude CLI is
|
|
documented behavior, not something this hive has run a live turn
|
|
against yet. Tool use, streaming, and MCP all need to keep working
|
|
through a non-Anthropic base URL; treat the first real agent on this
|
|
path as the actual verification, not this doc.
|
|
|
|
Switching an already-provisioned OAuth agent to `useApiKey` leaves
|
|
`~/.claude/credentials.json` in place but unused — harmless, not
|
|
cleaned up automatically. Cost shape also changes: subscription pricing
|
|
→ per-request billing with no built-in monthly cap, worth knowing before
|
|
pointing a busy agent at a metered backend.
|