diff --git a/CLAUDE.md b/CLAUDE.md index b28be55..bc82dcb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -169,6 +169,10 @@ Manager additionally: - `mcp__hyperhive__kill(name)` — graceful stop. - `mcp__hyperhive__request_apply_commit(agent, commit_ref)` — submit a config change for any agent (including `hm1nd` for self-mods). +- `mcp__hyperhive__ask_operator(question, options?)` — non-blocking; + queues a question on the dashboard, returns the question id. Operator's + answer arrives later as a `HelperEvent::OperatorAnswered` in the + manager inbox. The shared per-turn plumbing lives in `hive_ag3nt::turn::{write_mcp_config, write_settings, write_system_prompt, run_turn, drive_turn, emit_turn_end, @@ -274,9 +278,13 @@ manager itself now. rubber-stamp sub-agent config requests. It verifies (role match, package legitimacy, cheaper alternative, blast radius) before committing + calling `request_apply_commit`. For ambiguous cases or anything that -needs human signal, the manager forwards the question to the operator -via `send(to: "operator", ...)` — a dedicated `mcp__hyperhive__ask_operator` -tool with proper pause/resume semantics is in [TODO.md](TODO.md). +needs human signal, the manager calls `ask_operator(question, options?)` +which queues the question on the dashboard and returns the id +immediately; the operator's answer arrives later as +`HelperEvent::OperatorAnswered` in the manager inbox. Store at +`hive-c0re::operator_questions` (sqlite); answer flow: +`POST /answer-question/{id}` → `OperatorQuestions::answer` → +`notify_manager(OperatorAnswered { ... })`. ## Helper events to the manager @@ -296,6 +304,9 @@ turn so the manager can react. Variants (ApplyCommit). - `Killed { agent }` — admin `HostRequest::Kill` + dashboard `/kill`. - `Destroyed { agent }` — `actions::destroy`. +- `OperatorAnswered { id, question, answer }` — `dashboard::post_answer_question` + fires this after the operator submits the answer form for a question + the manager queued via `ask_operator`. To add a new event: new `HelperEvent` variant + call sites + update `prompts/manager.md` so the manager knows the new shape. diff --git a/TODO.md b/TODO.md index d9d5647..6f5c5e6 100644 --- a/TODO.md +++ b/TODO.md @@ -33,43 +33,12 @@ Pick anything from here when relevant. Cross-cutting design notes live in ## Manager → operator question channel -- **`mcp__hyperhive__ask_operator(question, options?)` tool** on the manager - MCP surface. The manager turn pauses; the question gets surfaced as a - prominent prompt on the dashboard (its own section, or interleaved with - the operator inbox); the operator's typed answer comes back as the tool - result. Modelled after Claude Code's `AskUserQuestion` tool. - - Design open questions: - - - **Storage.** New sqlite table `operator_questions(id, asker, question, - options_json, asked_at, answered_at, answer)` — or piggyback on the - existing message broker with a new envelope kind. Probably a new - table because the lifecycle (pending → answered) is different from - fire-and-forget messages. - - - **Waiting semantics.** The MCP tool call needs to block until - answered. Two options: - 1. Long-poll from inside the tool handler (broker-style — broadcast - on insert, await via `tokio::sync::broadcast`). Simple but the - claude turn stays alive for the whole wait, eating context-window - budget. - 2. Tool returns a `question_id` immediately; manager re-enters its - inbox loop and a `HelperEvent::OperatorAnswered { id, answer }` - wakes it. Cheaper context-wise but two-step. - - - **Dashboard UX.** New "◆ M1ND H4S QU3STI0NS ◆" section at the top - when any question is pending. Inline `