diff --git a/hive-ag3nt/prompts/manager.md b/hive-ag3nt/prompts/manager.md index d26bc973..a50e10a5 100644 --- a/hive-ag3nt/prompts/manager.md +++ b/hive-ag3nt/prompts/manager.md @@ -10,7 +10,6 @@ Tools (hyperhive surface): - `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_update_meta_inputs(inputs?, description?)` — queue an approval for the operator to run `nix flake update [inputs...]` on the meta flake. Pass specific input names (e.g. `["bitburner-agent"]`) or omit / pass `[]` for all inputs. Returns immediately; lock update runs on operator approval. Does NOT trigger rebuilds — call `update(name)` on affected agents after approval resolves. - `mcp__hyperhive__get_logs(agent, lines?)` — fetch recent journal lines for a sub-agent container. Use to diagnose MCP-server registration failures, startup crashes, or harness issues you can't see from inside. Pass the plain logical agent name; `lines` defaults to 50 (capped at 500). - `mcp__hyperhive__request_apply_commit(agent, commit_ref, description?)` — submit a config change for any agent (`hm1nd` for self) for operator approval. Pass an optional `description` and it appears on the dashboard approval card so the operator knows what changed without opening the diff. At submit time hive-c0re fetches your commit into the agent's applied repo and pins it as `proposal/`; from that moment your proposed-side commit can be amended or force-pushed freely without changing what the operator will build. - `mcp__hyperhive__ask(question, options?, multi?, ttl_seconds?, to?)` — surface a structured question to the operator (default, or `to: "operator"`) OR a sub-agent (`to: ""`). Returns immediately with a question id; the answer arrives later as a system `question_answered { id, question, answer, answerer }` 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 (capped at 6h server-side) — on expiry the answer is `[expired]` and `answerer` is `"ttl-watchdog"`. Do not poll inside the same turn — finish the current work and react when the event lands. diff --git a/hive-ag3nt/src/mcp.rs b/hive-ag3nt/src/mcp.rs index eb41797d..fd3ad1ad 100644 --- a/hive-ag3nt/src/mcp.rs +++ b/hive-ag3nt/src/mcp.rs @@ -807,17 +807,6 @@ pub struct RequestApplyCommitArgs { pub description: Option, } -#[derive(Debug, serde::Deserialize, schemars::JsonSchema)] -pub struct UpdateMetaInputsArgs { - /// Flake input names to update (e.g. `["bitburner-agent", "nixpkgs"]`). - /// Pass an empty list to update ALL inputs. - #[serde(default)] - pub inputs: Vec, - /// Optional description shown on the dashboard approval card. - #[serde(default)] - pub description: Option, -} - #[derive(Debug, serde::Deserialize, schemars::JsonSchema)] pub struct GetLogsArgs { /// Logical agent name to fetch logs for (e.g. `gui`, `hm1nd`). @@ -1033,43 +1022,6 @@ impl ManagerServer { .await } - #[tool( - description = "Queue an approval for the operator to run `nix flake update` on the \ - meta flake and commit the resulting lock changes. Pass specific input names to update \ - only those inputs (e.g. `[\"bitburner-agent\"]`), or pass an empty list to update ALL \ - inputs. Returns immediately — the lock update runs when the operator approves. \ - Does NOT trigger container rebuilds — call `update` on each affected agent \ - separately after the approval resolves." - )] - async fn request_update_meta_inputs( - &self, - Parameters(args): Parameters, - ) -> String { - let log = format!("{args:?}"); - run_tool_envelope("request_update_meta_inputs", log, async move { - let label = if args.inputs.is_empty() { - "all inputs".to_string() - } else { - args.inputs.join(", ") - }; - let (resp, retries) = self - .dispatch(hive_sh4re::ManagerRequest::RequestUpdateMetaInputs { - inputs: args.inputs, - description: args.description, - }) - .await; - annotate_retries( - format_ack( - resp, - "request_update_meta_inputs", - format!("approval queued: {label}"), - ), - retries, - ) - }) - .await - } - #[tool( description = "Surface a structured question to either the operator OR a sub-agent. \ Returns immediately with a question id — do NOT wait inline. When the recipient \ diff --git a/hive-c0re/src/actions.rs b/hive-c0re/src/actions.rs index 2443a6e9..0fa05606 100644 --- a/hive-c0re/src/actions.rs +++ b/hive-c0re/src/actions.rs @@ -69,14 +69,6 @@ pub async fn approve(coord: Arc, id: i64) -> Result<()> { .await; finish_approval(&coord, &approval, result, None) } - ApprovalKind::UpdateMetaInputs => { - // Decode the inputs from the commit_ref field (stored as JSON - // by submit_apply_commit's counterpart in manager_server.rs). - let inputs: Vec = - serde_json::from_str(&approval.commit_ref).unwrap_or_default(); - let result = crate::meta::lock_update(&inputs).await; - finish_approval(&coord, &approval, result, None) - } ApprovalKind::Spawn => { // Run the spawn in the background so the approve POST returns // immediately. The dashboard reads `transient` to render a spinner. @@ -166,7 +158,6 @@ fn finish_approval( ApprovalKind::Spawn => "spawn", ApprovalKind::ApplyCommit => "apply_commit", ApprovalKind::InitConfig => "init_config", - ApprovalKind::UpdateMetaInputs => "update_meta_inputs", }; let sha_short = approval .fetched_sha @@ -208,9 +199,6 @@ fn finish_approval( sha: approval.fetched_sha.clone(), tag: terminal_tag, }), - // UpdateMetaInputs: ApprovalResolved already carries the result. - // No separate lifecycle event needed. - ApprovalKind::UpdateMetaInputs => {} } result } @@ -474,7 +462,6 @@ pub async fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<() ApprovalKind::Spawn => "spawn", ApprovalKind::ApplyCommit => "apply_commit", ApprovalKind::InitConfig => "init_config", - ApprovalKind::UpdateMetaInputs => "update_meta_inputs", }; let sha_short = sha.as_deref().map(|s| s[..s.len().min(12)].to_owned()); let description = a.description.clone(); diff --git a/hive-c0re/src/approvals.rs b/hive-c0re/src/approvals.rs index 9afc7090..ba9f9f2b 100644 --- a/hive-c0re/src/approvals.rs +++ b/hive-c0re/src/approvals.rs @@ -285,7 +285,6 @@ fn row_to_approval(row: &rusqlite::Row<'_>) -> rusqlite::Result { "apply_commit" => ApprovalKind::ApplyCommit, "spawn" => ApprovalKind::Spawn, "init_config" => ApprovalKind::InitConfig, - "update_meta_inputs" => ApprovalKind::UpdateMetaInputs, other => { return Err(rusqlite::Error::FromSqlConversionFailure( 2, @@ -327,7 +326,6 @@ fn kind_to_str(kind: ApprovalKind) -> &'static str { ApprovalKind::ApplyCommit => "apply_commit", ApprovalKind::Spawn => "spawn", ApprovalKind::InitConfig => "init_config", - ApprovalKind::UpdateMetaInputs => "update_meta_inputs", } } @@ -336,7 +334,6 @@ fn kind_from_str(s: &str) -> Result { "apply_commit" => ApprovalKind::ApplyCommit, "spawn" => ApprovalKind::Spawn, "init_config" => ApprovalKind::InitConfig, - "update_meta_inputs" => ApprovalKind::UpdateMetaInputs, other => bail!("unknown approval kind '{other}'"), }) } diff --git a/hive-c0re/src/dashboard.rs b/hive-c0re/src/dashboard.rs index bbce25de..e66296a3 100644 --- a/hive-c0re/src/dashboard.rs +++ b/hive-c0re/src/dashboard.rs @@ -575,7 +575,6 @@ fn history_view(a: Approval) -> ApprovalHistoryView { hive_sh4re::ApprovalKind::ApplyCommit => "apply_commit", hive_sh4re::ApprovalKind::Spawn => "spawn", hive_sh4re::ApprovalKind::InitConfig => "init_config", - hive_sh4re::ApprovalKind::UpdateMetaInputs => "update_meta_inputs", }; ApprovalHistoryView { id: a.id, @@ -624,14 +623,6 @@ async fn build_approval_views(approvals: Vec) -> Vec { diff: None, description: a.description, }, - hive_sh4re::ApprovalKind::UpdateMetaInputs => ApprovalView { - id: a.id, - agent: a.agent, - kind: "update_meta_inputs", - sha_short: None, - diff: None, - description: a.description, - }, }); } out diff --git a/hive-c0re/src/manager_server.rs b/hive-c0re/src/manager_server.rs index d045b2cd..75b60752 100644 --- a/hive-c0re/src/manager_server.rs +++ b/hive-c0re/src/manager_server.rs @@ -311,48 +311,6 @@ async fn dispatch(req: &ManagerRequest, coord: &Arc) -> ManagerResp }, } } - ManagerRequest::RequestUpdateMetaInputs { - inputs, - description, - } => { - let label = if inputs.is_empty() { - "all inputs".to_string() - } else { - inputs.join(", ") - }; - tracing::info!(%label, "manager: request_update_meta_inputs"); - // Encode the inputs list as JSON and store it in commit_ref - // (there's no git commit involved; the field carries the - // payload for the approval handler to decode at run time). - let commit_ref = serde_json::to_string(inputs).unwrap_or_default(); - let id = match coord - .approvals - .submit_kind( - hive_sh4re::MANAGER_AGENT, - hive_sh4re::ApprovalKind::UpdateMetaInputs, - &commit_ref, - description.as_deref(), - ) - .map_err(|e| anyhow::anyhow!("{e:#}")) - { - Ok(id) => id, - Err(e) => { - return ManagerResponse::Err { - message: format!("queue update_meta_inputs approval: {e:#}"), - } - } - }; - tracing::info!(%id, %label, "update_meta_inputs approval queued"); - coord.emit_approval_added( - id, - hive_sh4re::MANAGER_AGENT, - "update_meta_inputs", - None, - None, - description.clone(), - ); - ManagerResponse::Ok - } ManagerRequest::Ask { question, options, diff --git a/hive-c0re/src/meta.rs b/hive-c0re/src/meta.rs index c5899bef..d7aa44ca 100644 --- a/hive-c0re/src/meta.rs +++ b/hive-c0re/src/meta.rs @@ -190,12 +190,14 @@ pub async fn lock_update_for_rebuild(name: &str) -> Result<()> { /// Used by the dashboard's "update meta inputs" form so the /// operator can bulk-bump `hyperhive` + selected agents in one /// shot. Each input name is passed verbatim to -/// Run `nix flake update [inputs...]` on the meta flake and commit the -/// resulting lock changes. When `inputs` is empty, updates ALL inputs -/// (bare `nix flake update`). The caller is responsible for picking -/// real input keys (e.g. via `inputs_view()` snapshotted from the lock -/// file) when targeting specific inputs. +/// `nix flake update`; the caller is responsible for picking +/// real input keys (e.g. via `inputs_view()` snapshotted from +/// the lock file). +#[allow(dead_code)] // wired up by dashboard handler in the same commit pub async fn lock_update(inputs: &[String]) -> Result<()> { + if inputs.is_empty() { + return Ok(()); + } let _guard = META_LOCK.lock().await; let dir = meta_dir(); let mut args: Vec<&str> = vec!["flake", "update"]; @@ -207,9 +209,7 @@ pub async fn lock_update(inputs: &[String]) -> Result<()> { return Ok(()); } git(&dir, &["add", "flake.lock"]).await?; - let msg = if inputs.is_empty() { - "lock update: all inputs".to_string() - } else if inputs.len() == 1 { + let msg = if inputs.len() == 1 { format!("lock update: {}", inputs[0]) } else { format!("lock update: {}", inputs.join(", ")) diff --git a/hive-sh4re/src/lib.rs b/hive-sh4re/src/lib.rs index 39f591da..6b59aa38 100644 --- a/hive-sh4re/src/lib.rs +++ b/hive-sh4re/src/lib.rs @@ -105,11 +105,6 @@ pub enum ApprovalKind { /// template but does NOT create the container - that requires a /// subsequent `RequestSpawn` approval. InitConfig, - /// Run `nix flake update [inputs...]` on the meta flake and commit - /// the resulting lock changes. The `commit_ref` field stores the - /// JSON-encoded inputs array (`"[]"` = all inputs). Agent field is - /// set to `hm1nd` (the requesting manager). - UpdateMetaInputs, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] @@ -847,19 +842,6 @@ pub enum ManagerRequest { /// message into the manager's own broker inbox. `from` is caller- /// chosen; `body` becomes the wake prompt body. Wake { from: String, body: String }, - /// Queue an approval to run `nix flake update [inputs...]` on the - /// meta flake. `inputs` is the list of named inputs to update - /// (e.g. `["bitburner-agent", "nixpkgs"]`). Pass an empty list to - /// update ALL inputs. On operator approval hive-c0re runs the lock - /// update and commits the result. The `UpdateMetaInputs` approval - /// resolves with `ApprovalResolved` in the manager inbox. - RequestUpdateMetaInputs { - #[serde(default)] - inputs: Vec, - /// Optional description shown on the dashboard approval card. - #[serde(default, skip_serializing_if = "Option::is_none")] - description: Option, - }, } #[derive(Debug, Clone, Serialize, Deserialize)]