manager: needs_login / logged_in / needs_update events + update tool
crash_watch grows two more state-axes alongside running/stopped: - logged-in (claude session dir populated for the agent) - up-to-date (recorded flake rev matches current) per-tick transitions emit HelperEvent::NeedsLogin / LoggedIn / NeedsUpdate. seed-on-first-tick semantics retained — nothing fires on harness boot for agents that were already in their state. only needs_update fires the 'stale appeared' direction; the resolved direction is already covered by Rebuilt. new mcp__hyperhive__update(name) on the manager surface: idempotent rebuild via auto_update::rebuild_agent. transient-aware (Rebuilding) so the dashboard shows the spinner. login intentionally has NO tool — it's interactive OAuth, only the operator can complete it. prompts + approvals doc + turn-loop doc updated. todo grows a 'show per-agent applied config in dashboard' entry (separate follow-up).
This commit is contained in:
parent
b374f39b0d
commit
80229c6af9
8 changed files with 230 additions and 34 deletions
|
|
@ -8,6 +8,7 @@ Tools (hyperhive surface):
|
|||
- `mcp__hyperhive__kill(name)` — graceful stop on a sub-agent. No approval required.
|
||||
- `mcp__hyperhive__start(name)` — start a stopped sub-agent. No approval required.
|
||||
- `mcp__hyperhive__restart(name)` — stop + start a sub-agent. No approval required.
|
||||
- `mcp__hyperhive__update(name)` — rebuild a sub-agent (re-applies the current hyperhive flake + agent.nix, restarts the container). No approval required — idempotent. Use when you receive a `needs_update` system event.
|
||||
- `mcp__hyperhive__request_apply_commit(agent, commit_ref)` — submit a config change for any agent (`hm1nd` for self) for operator approval.
|
||||
- `mcp__hyperhive__ask_operator(question, options?, multi?, ttl_seconds?)` — surface a question on the dashboard. Returns immediately with a question id; the operator's answer arrives later as a system `operator_answered` event in your inbox. Options are advisory: the dashboard always lets the operator type a free-text answer in addition. Set `multi: true` to render options as checkboxes (operator can pick multiple); the answer comes back as `, `-separated. Set `ttl_seconds` to auto-cancel after a deadline — useful when the decision becomes moot if the operator hasn't responded in time; on expiry the answer is `[expired]`. Do not poll inside the same turn — finish the current work and react when the event lands.
|
||||
|
||||
|
|
@ -26,7 +27,13 @@ You're the policy gate between sub-agents and the operator's approval queue —
|
|||
|
||||
Two ways to talk to the operator: `send(to: "operator", ...)` for fire-and-forget status / pointers (surfaces in the operator inbox), or `ask_operator(question, options?)` when you need a decision. `ask_operator` is non-blocking — it queues the question and returns an id immediately; the answer arrives on a future turn as an `operator_answered` system event. Prefer `ask_operator` over an open-ended `send` for anything you actually need to wait on.
|
||||
|
||||
Messages from sender `system` are hyperhive helper events (JSON body, `event` field discriminates): `approval_resolved`, `spawned`, `rebuilt`, `killed`, `destroyed`, `container_crash`, `operator_answered`. Use these to react to lifecycle changes — e.g. greet a freshly-spawned agent, retry a failed rebuild, restart an agent whose container crashed, or pick up the operator's answer to a question you previously asked.
|
||||
Messages from sender `system` are hyperhive helper events (JSON body, `event` field discriminates): `approval_resolved`, `spawned`, `rebuilt`, `killed`, `destroyed`, `container_crash`, `needs_login`, `logged_in`, `needs_update`, `operator_answered`. Use these to react to lifecycle changes:
|
||||
|
||||
- `needs_login` — agent has no claude session yet. You can't help directly (login is interactive OAuth on the operator side); flag the operator if it's been long.
|
||||
- `logged_in` — agent just completed login; first useful turn is imminent. Good time to brief them on what to do.
|
||||
- `needs_update` — agent's flake rev is stale. Call `update(name)` to rebuild — it's idempotent and doesn't need approval.
|
||||
- `container_crash` — restart with `start(name)`. If it crashes again, ask the operator.
|
||||
- otherwise greet freshly-spawned agents, retry failed rebuilds, pick up the operator's answer to questions you asked.
|
||||
|
||||
Durable knowledge:
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,12 @@ pub struct RestartArgs {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct UpdateArgs {
|
||||
/// Sub-agent name (without the `h-` container prefix).
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct AskOperatorArgs {
|
||||
/// The question to surface on the dashboard.
|
||||
|
|
@ -400,6 +406,23 @@ impl ManagerServer {
|
|||
.await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Rebuild a sub-agent: re-applies the current hyperhive flake + agent.nix \
|
||||
and restarts the container. No approval required — idempotent. Use when you receive a \
|
||||
`needs_update` system event for an agent."
|
||||
)]
|
||||
async fn update(&self, Parameters(args): Parameters<UpdateArgs>) -> String {
|
||||
let log = format!("{args:?}");
|
||||
let name = args.name.clone();
|
||||
run_tool_envelope("update", log, async move {
|
||||
let resp = self
|
||||
.dispatch(hive_sh4re::ManagerRequest::Update { name: args.name })
|
||||
.await;
|
||||
format_ack(resp, "update", format!("updated {name}"))
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Surface a question to the operator on the dashboard. Returns immediately \
|
||||
with a question id — do NOT wait inline. When the operator answers, a system message \
|
||||
|
|
@ -512,6 +535,7 @@ pub fn allowed_mcp_tools(flavor: Flavor) -> Vec<String> {
|
|||
"kill",
|
||||
"start",
|
||||
"restart",
|
||||
"update",
|
||||
"request_apply_commit",
|
||||
"ask_operator",
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue