archetypes: prefill the create form from flake-declared agent archetypes
A flake declares agent archetypes in its `hyperhiveArchetypes` output,
`<name> = { module; meta; }`. The hyperhive flake ships `reviewer`
(default permissions without `execution`).
swarm-builder answers `$SWARM.builder.archetypes` with the `meta` of
every archetype its own hyperhive source declares. swarm-controller asks
once the queue connects and every 10 minutes, checks each archetype as
`POST /api/agents` checks its settings, and stores the result in the
`agent-archetypes` KV bucket when it changed. `GET /api/archetypes`
serves it, and the create form's archetype select prefills permissions,
resource caps and inference from it.
The agent created is an ordinary agent with its own config repo; the
archetype's module is not applied yet.
Refs #5386
This commit is contained in:
parent
eb92e83c95
commit
51035eac1d
22 changed files with 1244 additions and 30 deletions
|
|
@ -91,6 +91,8 @@ declarations.
|
|||
(planned, not implemented yet).
|
||||
- **Does an agent config PR build before it's merged?** →
|
||||
[`swarm/builder.md`](swarm/builder.md).
|
||||
- **How do I create an agent from a ready-made set of permissions and
|
||||
settings?** → [`swarm/archetypes.md`](swarm/archetypes.md).
|
||||
- **How long do CI runs take, per repo and PR, and where does the board get
|
||||
it?** → [`swarm/ci-metrics.md`](swarm/ci-metrics.md).
|
||||
- **How do I log an agent in to claude from the swarm UI, and why doesn't a
|
||||
|
|
|
|||
87
docs/swarm/archetypes.md
Normal file
87
docs/swarm/archetypes.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Agent archetypes
|
||||
|
||||
An archetype is a named set of settings to create an agent from. 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.
|
||||
|
||||
The agent you create this way is an ordinary agent: it gets its own
|
||||
`agent-configs/<name>` repo like any other, and the request carries only the
|
||||
fields as the form shows them. Nothing records which archetype you picked.
|
||||
|
||||
## The built-in archetypes
|
||||
|
||||
The hyperhive flake ships these:
|
||||
|
||||
| archetype | what it sets |
|
||||
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `reviewer` | permissions `messaging`, `meta`, `inbox`: the default set without `execution`. It has no shell, so it can't run `hive-forge`, `git` or any command. |
|
||||
|
||||
## Where an archetype comes from
|
||||
|
||||
A flake declares archetypes in its `hyperhiveArchetypes` output:
|
||||
|
||||
```nix
|
||||
hyperhiveArchetypes.reviewer = {
|
||||
module = { };
|
||||
meta = {
|
||||
description = "Reviews what it is sent.";
|
||||
permissions = [ "messaging" "meta" "inbox" ];
|
||||
limits = { memory_max = "4G"; };
|
||||
inference = { effort = "high"; };
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
- `meta` is plain data: no derivation, no path, no function. The swarm
|
||||
evaluates `meta` alone.
|
||||
- Every archetype needs a `description`. `permissions`, `limits` and
|
||||
`inference` are optional and take the shapes `POST /api/agents` takes. The swarm ignores
|
||||
other keys in `meta`.
|
||||
- `module` is a NixOS module for the agent's container. The swarm doesn't
|
||||
apply it yet.
|
||||
|
||||
Today the swarm reads one flake: the hyperhive source the
|
||||
[builder](builder.md)'s host runs, so only the built-ins appear.
|
||||
|
||||
## How the list stays current
|
||||
|
||||
1. swarm-controller asks the builder for the list on the queue subject
|
||||
`$SWARM.builder.archetypes` once the queue connects, and every 10 minutes
|
||||
after that.
|
||||
2. The builder evaluates the `meta` of each `hyperhiveArchetypes` entry on
|
||||
its own hyperhive and nixpkgs sources, and answers with the JSON or the
|
||||
last lines `nix` printed:
|
||||
|
||||
```sh
|
||||
nix eval --json <hyperhive>#hyperhiveArchetypes \
|
||||
--apply 'builtins.mapAttrs (_: a: a.meta)'
|
||||
```
|
||||
|
||||
3. The controller checks each archetype the way `POST /api/agents` checks
|
||||
its settings and stores the result in the `agent-archetypes` KV bucket,
|
||||
under the key `hyperhive`, 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's `refused` map and the controller's journal.
|
||||
4. `GET /api/archetypes` answers 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:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "/nix/store/…-hyperhive-flake-source",
|
||||
"archetypes": {
|
||||
"reviewer": {
|
||||
"description": "…",
|
||||
"permissions": ["messaging", "meta", "inbox"]
|
||||
}
|
||||
},
|
||||
"refused": { "broken": "limits: …" }
|
||||
}
|
||||
```
|
||||
|
|
@ -61,6 +61,14 @@ Where it runs and how it's enabled: [`services.md`](services.md#builder).
|
|||
push. The jobs graph is in memory, so a controller restart drops a build in
|
||||
flight and leaves its status `pending`.
|
||||
|
||||
## Archetype evaluation
|
||||
|
||||
The builder also answers `$SWARM.builder.archetypes`: it evaluates the
|
||||
`meta` of every agent archetype its own hyperhive source declares, with no
|
||||
forge token, and answers with the JSON. An evaluation doesn't wait for a
|
||||
build in progress and has two minutes. What the controller does with the
|
||||
answer: [`archetypes.md`](archetypes.md).
|
||||
|
||||
## Credentials
|
||||
|
||||
| What | Where | Who reads it |
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ domain, covers host-level detail for one hive.
|
|||
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/` | the start page: the swarm's name over a digital-rain backdrop, plus a paperclip offering to set up an agent while no `ruth` exists (it opens the create form with `ruth` filled in); the swarm name in the header links here |
|
||||
| `/hives` | the hive directory, each hive with its last reported status |
|
||||
| `/agents` | every agent: status, config PR, wanted state, inference settings, resource caps; create agents (with their permissions), link forge, matrix and GitHub accounts |
|
||||
| `/agents` | every agent: status, config PR, wanted state, inference settings, resource caps; create agents (with their permissions, optionally from an [archetype](archetypes.md)), link forge, matrix and GitHub accounts |
|
||||
| `/agents/<name>/terminal` | one agent's live terminal |
|
||||
| `/agents/<name>/subagents/<subagent>/terminal` | one of that agent's subagents' live terminal |
|
||||
| `/alerts` | the alerts the swarm's Grafana holds now (firing, pending, no data, error), read through the controller with a Viewer service-account token |
|
||||
|
|
|
|||
Loading…
Reference in a new issue