agents: remove the hive-level /effort control too
mara on #5034: "effort shares /models fate". The per-agent web UI no longer sets effort: the `/effort` slash command, the effort picker, `POST /api/effort`, `Bus::set_effort`, the `hyperhive-effort` writer, `EFFORT_LEVELS`/`is_valid_effort` and the ACP effort-list payload are gone, and `lib/modelEffort.ts` with them. The effort chip is display-only and shows its source (`effort_source` in `/api/state`); on ACP it stays hidden while the session offers no effort level. The read side is unchanged: with no swarm value an agent runs an existing `hyperhive-effort` file, else its agent.nix effort, else medium. Existing files are not touched. Refs #5034
This commit is contained in:
parent
594693f4c7
commit
ed271e655f
25 changed files with 170 additions and 464 deletions
|
|
@ -313,7 +313,8 @@ Under `/var/lib/hyperhive/agents/<name>/`:
|
|||
tables above.
|
||||
- `hyperhive-events.sqlite` — turn-loop event log.
|
||||
- `hyperhive-turn-stats.sqlite` — per-turn timing stats.
|
||||
- `hyperhive-model` — single-line model name file, read-only fallback.
|
||||
- `hyperhive-model` / `hyperhive-effort` — single-line model name and
|
||||
effort level files, read-only fallbacks.
|
||||
- `work/` — the agent's working space for git worktrees, build dirs
|
||||
and other large working data. Bind-mounted RW to
|
||||
`/agents/<name>/work` inside the container and owned by the agent
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@ swarmctl agent inference clear iris
|
|||
|
||||
The full flag reference is [`swarmctl-cli.md`](../tools/swarmctl-cli.md). The
|
||||
swarm UI's agents page edits the same settings; see [UI](ui.md). The
|
||||
swarm is the only place to change an agent's model at runtime: its web UI
|
||||
shows the model but has no picker and no `/model` command.
|
||||
swarm is the only place to change an agent's model or effort at runtime:
|
||||
its web UI shows both but has no picker and no `/model` or `/effort`
|
||||
command.
|
||||
|
||||
## What an agent runs on
|
||||
|
||||
|
|
@ -48,14 +49,15 @@ Each running value names where it comes from:
|
|||
| ------------ | -------------------------------------------------------------------------- |
|
||||
| `swarm` | the value set here |
|
||||
| `agent_nix` | `services.hyperhive.agent.model` or `effortLevel` in the agent's agent.nix |
|
||||
| `local_file` | an `/effort` pick in the agent's web UI, or a `hyperhive-model` file |
|
||||
| `local_file` | a `hyperhive-model` or `hyperhive-effort` file in the agent's harness dir |
|
||||
| `default` | the harness's built-in default (`haiku`, `medium`) |
|
||||
|
||||
When the agent starts without a swarm value, its agent.nix model wins over
|
||||
a `hyperhive-model` file, and its `/effort` pick wins over its agent.nix
|
||||
effort. A `hyperhive-model` file comes from a runtime model pick the
|
||||
agent's web UI no longer offers; the agent still reads it but never writes
|
||||
it.
|
||||
a `hyperhive-model` file, and a `hyperhive-effort` file wins over its
|
||||
agent.nix effort. These files come from runtime picks the agent's web UI no
|
||||
longer offers; the agent still reads them but never writes them, so a
|
||||
`local_file` value stays until the swarm sets that field or someone deletes
|
||||
the file.
|
||||
|
||||
The agent reports these whenever they change, and again once a minute.
|
||||
swarm-controller keeps only what it has received since it started, so for up
|
||||
|
|
@ -67,13 +69,11 @@ Each agent reads its settings every 10 seconds and switches on the next
|
|||
read: its next turn runs on the new model or effort, and its web UI badge
|
||||
shows it. A turn already running keeps what it started with.
|
||||
|
||||
- **Its own value is the one it runs without the swarm**: its agent.nix, an
|
||||
`/effort` pick in its web UI, or a `hyperhive-model` file. Setting a swarm
|
||||
value doesn't overwrite it.
|
||||
- **Its own value is the one it runs without the swarm**: its agent.nix or a
|
||||
`hyperhive-model` / `hyperhive-effort` file. Setting a swarm value doesn't
|
||||
overwrite it.
|
||||
- **Clearing a field** (or the whole key) puts the agent back on its own
|
||||
value on the next read.
|
||||
- **An `/effort` pick while the swarm sets effort** changes the agent's own
|
||||
value, but the swarm value comes back on the next read.
|
||||
- **After a restart**, the agent runs its own values until its first read
|
||||
of its settings succeeds.
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ Queues and returns, the same way `agent create` does — watch the swarm UI's jo
|
|||
|
||||
Show or change the model, effort and subagent models the swarm sets for an agent.
|
||||
|
||||
A field the swarm sets wins over the agent's own value (its agent.nix, its `/effort` pick, or a `hyperhive-model` file) from its next turn on; the agent reads its settings every ten seconds. A field the swarm doesn't set, or clears, leaves the agent on its own value.
|
||||
A field the swarm sets wins over the agent's own value (its agent.nix or a `hyperhive-model`/`hyperhive-effort` file) from its next turn on; the agent reads its settings every ten seconds. A field the swarm doesn't set, or clears, leaves the agent on its own value.
|
||||
|
||||
**Usage:** `swarmctl agent inference <COMMAND>`
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Hive-enforced settings ship at `/etc/claude-code/managed-settings.json`
|
|||
read-only, un-overridable), wired in `nix/agent-modules/claude-settings.nix`
|
||||
from the `prompts/claude-settings.json` asset. `effortLevel` is
|
||||
deliberately not in that file — the `--effort` flag
|
||||
(`HIVE_DEFAULT_EFFORT` / the per-agent UI slider) controls effort
|
||||
(`HIVE_DEFAULT_EFFORT` / the swarm's effort setting) controls effort
|
||||
live, which managed scope would otherwise lock.
|
||||
|
||||
The harness reads `<name>` from `Bus::model()` on each turn.
|
||||
|
|
|
|||
|
|
@ -47,21 +47,20 @@ at a given viewport width. Two columns:
|
|||
`◌ needs login` / `◌ logging in` / `○ offline` / `… connecting`.
|
||||
- **State badge**: `💤 idle` / `🧠 thinking` / `📦 compacting` /
|
||||
`○ offline` / `… booting` + age suffix.
|
||||
- **Model badge** (`model · <name>`): display only. Its tooltip says where
|
||||
the model comes from (`state.model_source`: set on the swarm, agent.nix,
|
||||
an existing `hyperhive-model` file, or the built-in default) and what the
|
||||
last turn resolved it to. The model is set on the swarm: the swarm UI's
|
||||
agents page, or `swarmctl agent inference set`
|
||||
- **Model and effort badges** (`model · <name>`, `effort · <level>`):
|
||||
display only. Each tooltip says where the value comes from
|
||||
(`state.model_source` / `state.effort_source`: set on the swarm,
|
||||
agent.nix, an existing `hyperhive-model` / `hyperhive-effort` file, or
|
||||
the built-in default); the model's also says what the last turn
|
||||
resolved it to. Both are set on the swarm: the swarm UI's agents page,
|
||||
or `swarmctl agent inference set`
|
||||
([`inference.md`](../swarm/inference.md)).
|
||||
- **Effort badge** (`effort · <level> ▾`): a real picker — selecting it
|
||||
opens a `Dropdown` of `state.available_efforts` and POSTs `/api/effort`
|
||||
immediately. Shown when `state.available_efforts` is non-empty.
|
||||
- On an ACP agent the model badge shows the session's own model when it
|
||||
doesn't offer the requested one, and the effort picker lists the levels
|
||||
its session offers (its `thought_level` config option), empty until the
|
||||
first turn has attached a session. The effort picker is hidden when the
|
||||
model offers no effort levels, and while a newly picked model waits for
|
||||
the next turn, since the levels come with the model.
|
||||
- On an ACP agent each badge shows the session's own value when it
|
||||
doesn't offer the requested one. The effort badge is hidden
|
||||
(`state.effort` is `null`) until the first turn has attached a
|
||||
session, when the model offers no effort levels, and while a newly
|
||||
set model waits for the next turn, since the levels come with the
|
||||
model.
|
||||
- **Ctx / cost badges**: `ctx · 142k` (last inference's prompt size,
|
||||
tooltip shows % of context window) / `cost · 1.3M` (cumulative
|
||||
tokens billed across every inference in the last turn).
|
||||
|
|
@ -85,8 +84,8 @@ at a given viewport width. Two columns:
|
|||
(`GET /api/state`'s `links` field) also feeds
|
||||
`DashboardState.links` for the dashboard card's icon strip —
|
||||
`agent_links()` in hive-agent is the single source of truth for
|
||||
both. The dashboard link lives in this 🔗 popover; the effort picker
|
||||
is a real badge above; and `/new-session` / `/logout` are
|
||||
both. The dashboard link lives in this 🔗 popover, and
|
||||
`/new-session` / `/logout` are
|
||||
typed slash commands with their own type-twice confirm (see
|
||||
below).
|
||||
- `/cancel` (slash command, below) is the only cancel-turn path; the
|
||||
|
|
@ -237,10 +236,6 @@ Slash commands today:
|
|||
runs the `/compact` at the next turn boundary (end of the in-flight
|
||||
turn, or `turn::run_pending_compact` when idle); output streams into
|
||||
the live panel. Works mid-turn, not only when idle.
|
||||
- `/effort <level>` — `POST /api/effort` setting the claude effort
|
||||
level (`low` / `medium` / `high` / `xhigh` / `max`). Takes effect on the next
|
||||
turn. `StatusChips`' effort badge calls the same endpoint; both stay
|
||||
in sync via `StateSnapshot.effort`.
|
||||
- `/new-session` — `POST /api/new-session` (confirms first).
|
||||
Arms a one-shot on the Bus; next turn runs without
|
||||
`--continue`, dropping the resume session entirely.
|
||||
|
|
@ -275,15 +270,6 @@ shaped).
|
|||
turn — only the stdin payload differs). Flips state to
|
||||
`Compacting` via `Bus::set_state`, which emits
|
||||
`TurnStateChanged`.
|
||||
- `POST /api/effort` (`effort=<level>`) — switch the claude
|
||||
effort level for future sessions. Validated server-side against
|
||||
`EFFORT_LEVELS` (`low`/`medium`/`high`/`xhigh`/`max`) — unknown values are
|
||||
rejected rather than forwarded to `claude --effort`. Persists via
|
||||
`Bus::set_effort`, which emits `EffortChanged`. Applies on the next
|
||||
session start (no mid-session swap).
|
||||
- On an ACP agent, `/api/effort` accepts only values the session offers,
|
||||
and the runtime sets the level with `session/set_config_option` before
|
||||
the next prompt.
|
||||
- `POST /api/new-session` — arm a one-shot for the next turn to
|
||||
drop `--continue`. Emits a `LiveEvent::Note`.
|
||||
- `POST /api/logout` — three-step teardown that re-uses the
|
||||
|
|
@ -317,7 +303,7 @@ shaped).
|
|||
the frontend (`useAgentState.ts`) on page load and, on a poll, while
|
||||
`status === 'needs_login_in_progress'`. Includes `turn_state`,
|
||||
`context_window_tokens`, `qualified_label`,
|
||||
`model`, `model_source`, `effort`, `available_efforts`, `links`, and
|
||||
`model`, `model_source`, `effort`, `effort_source`, `links`, and
|
||||
other fields described inline throughout this document. All
|
||||
subsequent state updates arrive via SSE.
|
||||
- `GET /api/dashboard-state` — lean snapshot of agent-owned fields
|
||||
|
|
@ -391,9 +377,8 @@ Bus events (new vocabulary on `/events/stream`):
|
|||
429 response and clears it when the retry sleep expires.
|
||||
- `model_changed { model }` — drives the model chip. The harness emits it
|
||||
when it applies or clears a swarm value.
|
||||
- `effort_changed { effort }` — drives the effort picker chip.
|
||||
Emitted from `Bus::set_effort` on `POST /api/effort`; applies on
|
||||
the next session start.
|
||||
- `effort_changed { effort }` — drives the effort chip. The harness
|
||||
emits it when it applies or clears a swarm value.
|
||||
- `token_usage_changed { ctx: TokenUsage, cost: TokenUsage }`
|
||||
— drives the ctx + cost badges. Emitted from
|
||||
`Bus::record_turn_usage` at turn-end; `ctx` is the last
|
||||
|
|
|
|||
Loading…
Reference in a new issue