Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/hive-runtime
Repository files (latest commit first)
Filename Latest commit message Latest commit date
atlas c2bdf30e05 hive-agent: export ACP-reported cost and context fill over OTLP
An ACP agent's `usage_update` carries `cost.{amount,currency}`, the
session's running total (opencode sums every assistant message in the
session). hive-runtime now reads it and turns the running total into
what each report added: a new session counts from zero, a session loaded
into a freshly started agent only baselines on its first report, and a
falling total adds nothing. The spend is held on the runtime until
`Runtime::take_reported_cost` drains it; claude's runtime reports none,
since the claude binary already exports `claude_code.cost.usage`.

hive-agent's existing turn-metrics meter records three new instruments:

- `hyperhive.agent.cost.usage` (counter, `model` + `currency`), ACP only;
- `hyperhive.agent.context.used` / `.size` (gauges, no attributes), for
  every backend: the two numbers the web UI's ctx% divides.

The `hyperhive · agents` dashboard gets ACP cost panels on its cost tab
and a context-fill panel on its health tab.

Refs #4845
2026-09-30 22:24:06 +02:00
..
src hive-agent: export ACP-reported cost and context fill over OTLP 2026-09-30 22:24:06 +02:00
Cargo.toml hive-runtime: record a new ACP session only once its first prompt is answered 2026-09-29 22:29:36 +02:00
README.md hive-runtime, hive-agent: model/effort picker for ACP agents from configOptions 2026-09-30 10:53:53 +02:00

hive-runtime

The layer an agent's turns are driven through: one Runtime interface (run, compact, archive, canceller, choices) with a backend per runtime.

  • claude — claude --print through the hive-claude crate's InfiniteSession. A pass-through: same spawn, same session handling, same errors.
  • acp — any Agent Client Protocol agent, spawned from a command, args and env handed to it (RuntimeSpec, read from HIVE_RUNTIME / HIVE_ACP_COMMAND / HIVE_ACP_ARGS / HIVE_ACP_ENV). It knows no agent by name; which agent runs, and how it is configured, is decided in nix (services.hyperhive.agent.runtime, services.hyperhive.agent.acp.*).

Both backends report a turn through hive_claude::Sink in claude's stream-json shape. The ACP backend translates session/update notifications into it (text and thought chunks as whole blocks, tool calls as tool_use + tool_result, MCP tools named mcp__<server>__<tool>), so the harness's stream consumers read either backend unchanged. Context usage comes from ACP usage_update.

The crate depends on no hyperhive binary crate, so hive-agent and hive-subagent-mcp can both drive turns through it.

ACP backend: what it needs from the agent

  • mcpCapabilities.http in its initialize response. The hyperhive tools are only served over HTTP, so an agent without it is refused at startup.
  • loadSession, to pick its session back up after a harness restart. Without it every restart starts a new session.

ACP backend: stopping a turn

A turn is stopped with session/cancel: by the Canceller handle, or by the idle watchdog once no session/update has arrived for Config::idle_timeout. An agent that has not answered the prompt 10s later is killed, and the next turn respawns it. A watchdog stop fails the turn with AcpError::IdleTimeout (IdleKilled if the agent was killed). This is the only way a provider error the agent retries without reporting it, such as an HTTP 429, ends the turn.

ACP backend: compaction

The same CompactionPolicy as the claude backend decides when: after a turn past the watermark, or on compact (the operator's /compact, the agent's compact tool).

  • If the agent advertises a compact command (available_commands_update), it is sent as the prompt /compact on the same session, as the ACP spec runs any advertised command. A proactive compaction runs the policy's checkpoint turn first, as on claude.
  • Otherwise the policy's checkpoint turn runs, then the session is archived, and the next turn starts a new one, carrying the system prompt again.
  • A compact command that fails, or sends nothing for 180s (the turn's idle window if that is shorter), is cancelled and handled as the case above; the checkpoint turn is not run a second time. So a compaction always leaves a smaller session behind, and a failed one is not retried on the next turn.

ACP backend: model and effort

Before each prompt, Config::model and then Config::effort are set on the session with session/set_config_option, as the value of its first model and thought_level config option. A value the session does not offer, or already holds, is not sent, so a claude alias such as haiku does nothing on an ACP agent. Model goes first because the effort levels on offer depend on it. The Choices handle (Runtime::choices) reads what the session offers now, including after a config_option_update. It is empty until a session is attached.