9.5 KiB
Agent archetypes
An archetype is a named agent setup: settings to create the agent with, and a NixOS module its container runs. The swarm UI's create form lists the archetypes the swarm knows. Picking one fills the form's permissions, resource caps and inference fields from it, and you can still change each field before you create the agent.
An agent created from an archetype has no agent-configs/<name> repo of its
own. The swarm's internal/meta flake builds it from the archetype's module,
so every agent of that archetype runs the same configuration. To change what it runs, change the
archetype. Picking "none" creates a custom agent, with its own config repo. The
swarm can also turn an archetype agent into a custom one later
(below).
The built-in archetypes
The hyperhive flake ships these:
| archetype | what it sets |
|---|---|
reviewer |
permissions messaging, inbox, execution: the default set without meta. With execution it can run hive-forge, git and other commands. |
android-dev |
installs android-tools (adb, fastboot), Gradle and a JDK; default permissions. |
reverse-engineer |
sets services.hyperhive.agent.rea.enable: installs REA, Ghidra 12.1 and procps, and allows all REA MCP tools; default permissions and the agent's normal memory cap. |
Where an archetype comes from
A flake declares archetypes in its hyperhiveArchetypes output:
hyperhiveArchetypes.reviewer = {
module = { };
meta = {
description = "Reviews what it is sent.";
permissions = [ "messaging" "inbox" "execution" ];
limits = { memory_max = "4G"; };
inference = { effort = "high"; };
};
};
metais plain data: no derivation, no path, no function. The swarm evaluatesmetaalone.- Every archetype needs a
description.permissions,limitsandinferenceare optional and take the shapesPOST /api/agentstakes. The swarm ignores other keys inmeta. moduleis a NixOS module for the agent's container. The meta flake imports it into each agent created from the archetype.
Today the swarm reads one flake: the hyperhive source the
builder's host runs, so only the built-ins appear. The meta
flake has one archetype source too, its own hyperhive input, and refuses
an archetype from any other source name.
How the list stays current
-
swarm-controller asks the builder for the list on the queue subject
$SWARM.builder.archetypesonce the queue connects, and every 10 minutes after that. -
The builder evaluates the
metaof eachhyperhiveArchetypesentry on its own hyperhive and nixpkgs sources, and answers with the JSON or the last linesnixprinted:nix eval --json <hyperhive>#hyperhiveArchetypes \ --apply 'builtins.mapAttrs (_: a: a.meta)' -
The controller checks each archetype the way
POST /api/agentschecks its settings and stores the result in theagent-archetypesKV bucket, under the keyhyperhive, when it differs from the stored one. The list leaves out an archetype that fails the check, and its name and reason go into the record'srefusedmap and the controller's journal. -
GET /api/archetypesanswers from that record, and the create form lists from it.
A builder host redeploy can change the list. The next pass, within 10 minutes, picks it up. When no builder answers, the controller keeps the stored list and logs a warning on each pass. A swarm with no builder enabled shows no archetype select.
The stored value:
{
"source": "/nix/store/…-hyperhive-flake-source",
"archetypes": {
"reviewer": {
"description": "…",
"permissions": ["messaging", "inbox", "execution"]
}
},
"refused": { "broken": "limits: …" }
}
Creating an agent from an archetype
The create form sends the picked archetype as archetype on
POST /api/agents, { "source": "hyperhive", "name": "reviewer" }. The
controller refuses with 400 an archetype the stored list doesn't hold, then:
- stores the choice in the
agent-archetypeKV bucket, keyed by agent name, next to the agent's permissions, caps and inference; - queues the creation graph without
CreateRepo,AddRepoMemberandInitAgentConfigRepo. Identity, forge user, docs read, the mints and the wanted state stay, and the deploy waits on those alone.
Destroying the agent deletes its key.
Every hive may read any key of the bucket
($JS.API.DIRECT.GET.KV_agent-archetype.>) and write none; only the
controller writes it.
Deploy swarm-nats-auth before the hives: every provision reads the
agent's key, and a hive whose queue connection predates the grant gets a
refused read, so its Provision nodes fail until it reconnects.
swarm-controller renders internal/meta's flake.nix with the
hive-meta-flake crate, and reads each agent's archetype from the
agent-archetype bucket to do so. For an archetype agent the render:
- adds no
agent-<name>input and reads no config repo, and lists the agent asmkAgent { …; archetype = { source = "hyperhive"; name = "<name>"; }; }; - makes
mkAgentimporthyperhive.hyperhiveArchetypes.<name>.modulein place of the agent's own flake, and setHIVE_ARCHETYPEin the harness environment.
The swarm builds from internal/meta alone and the hive deploys that closure. The hive reads the agent's key when it
provisions the agent and on every rebuild, and keeps the last value read in
/var/lib/hyperhive/swarm-agent-archetypes.json. When the read fails, a rebuild keeps the stored value. For an
archetype agent the hive also:
- deploys the closure its record declares, as every agent does.
The agent's system prompt says it has no config repo and names its archetype.
The module comes from the hyperhive input that internal/meta pins, not
from the hive's own. When that pin predates the archetype, the agent's build
fails with this hive's hyperhive input has no archetype <name>; update that input. Update the hyperhive pin in internal/meta to fix it.
Turn into custom
An archetype agent can become a custom agent with its own
agent-configs/<name> repo, either from the agent's overview in the swarm UI
(the "turn into custom" button asks first) or with POST /api/agents/{name}/custom.
The agent keeps its state, permissions, caps, inference settings and accounts.
Its configuration stays the same, except that it no longer has HIVE_ARCHETYPE
in its environment. Keeping the config current is then up to the repo's owner.
Nothing here undoes it.
The controller refuses with 409 an agent that no hive or more than one hive
places, and one whose hive doesn't list the
no-config-checkout capability (see below). Otherwise it queues a job graph:
-
CreateRepo,CreateForgeUserandAddRepoMember: the repo and the agent's access to the repo, as for any custom agent. Each is a no-op for what exists. -
SeedArchetypeConfigcommits two files to the repo. It copies nothing from the archetype:flake.nixdeclares the archetype's source as an input, at the URLinternal/metaholds for that source today (a pinned rev, which is the input's only pin: the repo has no lock, and a source meta doesn't pin to a commit fails the node), and importsinputs.<source>.hyperhiveArchetypes.<name>.modulenext to./agent.nix;agent.nixis an empty module for the owner's edits.
The node leaves a repo whose
flake.nixalready is this file alone, whatever URL it pins. Any otherflake.nixfails the node. -
DropArchetypedeletes the agent'sagent-archetypekey, only after the seed and the member grant succeeded. A failure before it leaves the agent archetype-built and working, and you can send the same request again. -
UpdateMeta, then the build and the deploy, as for a merged config PR. If the build fails, the agent is custom and has no key. Sending the request again then queues only this step, as the earlier ones have run.
When the source is hyperhive, the meta flake sets
agent-<name>.inputs.hyperhive.follows = "hyperhive" for an agent whose
flake.nix or flake.lock declares a hyperhive input, so the lock holds one
hyperhive, and the module comes from the pin internal/meta holds. Any other
source keeps the pinned URL from its seeded flake.nix, and the meta lock
records that rev. The follows applies to every custom agent whose flake.nix
declares a hyperhive input, not only converted ones. A hyperhive node left
in a lock doesn't count.
Which hives may convert
A hive that keeps a checkout of a custom agent's config would create one for
the converted agent, under the container's running mount. A hive that lists
no-config-checkout under capabilities in the status it publishes (the
document GET /api/hives/status serves as snapshot) keeps none: it deploys a
custom agent's closure from the swarm alone, and the agent clones its own repo from
the forge. The controller reads the agent's hive's latest status and refuses
unless it's fresh and lists the capability; an older hive lists none. Deploy
the release to every hive that places archetype agents before converting theirs.