feat: add set_status MCP tool and status field to whoami/dashboard (closes #325)
This commit is contained in:
parent
6f3b56ad84
commit
fe2933b213
8 changed files with 170 additions and 16 deletions
|
|
@ -10,7 +10,8 @@ Tools (hyperhive surface):
|
|||
- `mcp__hyperhive__get_loose_ends()` — list your loose ends: unanswered questions where you're asker (waiting on someone) or target (owing a reply), plus reminders you've scheduled that haven't fired. No args, cheap server-side sweep. Useful at turn start to remember what's outstanding without scanning inbox archaeology.
|
||||
- `mcp__hyperhive__cancel_loose_end(kind, id)` — cancel one of your own open threads. `kind` is `"question"` (the asker — you, in this case — gets a `[cancelled by <you>]` answer so the waiter unblocks) or `"reminder"` (hard-deleted before it fires). `id` from the matching `get_loose_ends` row or the original submission reply.
|
||||
- `mcp__hyperhive__remind(message, delay_seconds? | at_unix_timestamp?, file_path?)` — schedule a message to land in your *own* inbox at a future time (sender shows as `reminder`). Set exactly one of `delay_seconds` (relative) or `at_unix_timestamp` (absolute). Use for self-paced follow-ups instead of blocking a whole turn on a long `recv` wait. A large `message` auto-spills to a file under `/agents/{label}/state/reminders/`; pass `file_path` to point at one yourself. Each agent's pending-reminder count is capped (default 50) — the tool will error if the cap is already reached.
|
||||
- `mcp__hyperhive__whoami()` — self-introspection: returns your canonical agent name (from socket identity, not the prompt-substituted label), role, and current hyperhive rev. No args. Use it when you want a trustworthy identity stamp for state files, commit messages, or cross-agent attribution that won't drift across renames.
|
||||
- `mcp__hyperhive__whoami()` — self-introspection: returns your canonical agent name (from socket identity, not the prompt-substituted label), role, and current hyperhive rev. No args. Use it when you want a trustworthy identity stamp for state files, commit messages, or cross-agent attribution that won't drift across renames or session-continue boundaries where the system-prompt label could be stale.
|
||||
- `mcp__hyperhive__set_status(text)` — set a free-text status visible on the operator dashboard. **Call this at the start of every task** to say what you're working on (e.g. `"reviewing PR #42"`, `"fixing #319 model priority"`, `"idle"`). Pass an empty string to clear. Persists across harness restarts.
|
||||
- `mcp__hyperhive__request_next_turn()` — ask the harness to start another turn immediately after this one ends, even if the inbox is empty. Use for multi-turn tasks (long builds, sequential steps) where you want to continue without waiting for an external message. The next turn starts with `from: "self"` and `body: "continue"`. No-op if new inbox messages arrive before this turn ends (the harness already loops immediately on pending messages). No args.
|
||||
|
||||
Need new packages, env vars, or other NixOS config for yourself? You can't edit your own config directly — message the manager (recipient `manager`) describing what you need + why. The manager evaluates the request (it doesn't rubber-stamp), edits `/agents/{label}/config/agent.nix` on your behalf, commits, and submits an approval that the operator can accept on the dashboard; on approve hive-c0re rebuilds your container with the new config.
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ pub enum SocketReply {
|
|||
name: String,
|
||||
role: String,
|
||||
hyperhive_rev: Option<String>,
|
||||
status_text: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -74,10 +75,12 @@ impl From<hive_sh4re::AgentResponse> for SocketReply {
|
|||
name,
|
||||
role,
|
||||
hyperhive_rev,
|
||||
status_text,
|
||||
} => Self::Whoami {
|
||||
name,
|
||||
role,
|
||||
hyperhive_rev,
|
||||
status_text,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -102,10 +105,12 @@ impl From<hive_sh4re::ManagerResponse> for SocketReply {
|
|||
name,
|
||||
role,
|
||||
hyperhive_rev,
|
||||
status_text,
|
||||
} => Self::Whoami {
|
||||
name,
|
||||
role,
|
||||
hyperhive_rev,
|
||||
status_text,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -269,9 +274,14 @@ pub fn format_whoami(resp: Result<SocketReply, anyhow::Error>) -> String {
|
|||
name,
|
||||
role,
|
||||
hyperhive_rev,
|
||||
status_text,
|
||||
}) => {
|
||||
let rev = hyperhive_rev.as_deref().unwrap_or("<unknown>");
|
||||
format!("name: {name}\nrole: {role}\nhyperhive_rev: {rev}")
|
||||
let mut out = format!("name: {name}\nrole: {role}\nhyperhive_rev: {rev}");
|
||||
if let Some(s) = status_text {
|
||||
out.push_str(&format!("\nstatus: {s}"));
|
||||
}
|
||||
out
|
||||
}
|
||||
Ok(SocketReply::Err(m)) => format!("whoami failed: {m}"),
|
||||
Ok(other) => format!("whoami unexpected response: {other:?}"),
|
||||
|
|
@ -551,8 +561,9 @@ impl AgentServer {
|
|||
#[tool(
|
||||
description = "Self-introspection: returns your own canonical agent name (the \
|
||||
socket-identity name, NOT the prompt-substituted label), role (`agent`), and \
|
||||
the current hyperhive rev hive-c0re is running against. No args. Useful when \
|
||||
you want a trustworthy identity stamp for state files / commit messages / \
|
||||
the current hyperhive rev hive-c0re is running against. Also returns the \
|
||||
current `status` text if one has been set via `set_status`. No args. Useful \
|
||||
when you want a trustworthy identity stamp for state files / commit messages / \
|
||||
cross-agent attribution that won't drift across renames or session-continue \
|
||||
boundaries where the system-prompt label could be stale."
|
||||
)]
|
||||
|
|
@ -564,6 +575,22 @@ impl AgentServer {
|
|||
.await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Set a free-text status string visible on the operator dashboard. \
|
||||
Call this at the START of every task to describe what you're working on (e.g. \
|
||||
`\"reviewing PR #42\"`, `\"fixing bitburner crash\"`, `\"idle\"`). Pass an empty \
|
||||
string to clear. The status is shown on your dashboard card and persists across \
|
||||
harness restarts."
|
||||
)]
|
||||
async fn set_status(&self, Parameters(args): Parameters<SetStatusArgs>) -> String {
|
||||
run_tool_envelope("set_status", args.text.clone(), async move {
|
||||
let (resp, retries) =
|
||||
self.dispatch(hive_sh4re::AgentRequest::SetStatus { text: args.text }).await;
|
||||
annotate_retries(format_ack(resp, "set_status", "status updated".to_owned()), retries)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Cancel an open thread you own — a `question` you asked (the \
|
||||
asker gets `[cancelled by <you>]` as the answer and unblocks) or a `reminder` \
|
||||
|
|
@ -724,6 +751,12 @@ pub struct KillArgs {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct SetStatusArgs {
|
||||
/// Status text to display on the dashboard card. Pass an empty string to clear.
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct StartArgs {
|
||||
/// Sub-agent name (without the `h-` container prefix).
|
||||
|
|
@ -1246,7 +1279,8 @@ impl ManagerServer {
|
|||
|
||||
#[tool(
|
||||
description = "Self-introspection for the manager: returns canonical name \
|
||||
(`manager`), role (`manager`), and the current hyperhive rev. Same shape as \
|
||||
(`manager`), role (`manager`), and the current hyperhive rev. Also returns \
|
||||
the current `status` text if one has been set via `set_status`. Same shape as \
|
||||
the agent flavour; useful for cross-agent attribution / boot announcements / \
|
||||
state-file headers without trusting prompt substitution."
|
||||
)]
|
||||
|
|
@ -1258,6 +1292,20 @@ impl ManagerServer {
|
|||
.await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Set a free-text status string visible on the operator dashboard. \
|
||||
Call this at the START of every task to describe what you're working on. \
|
||||
Pass an empty string to clear. Persists across harness restarts."
|
||||
)]
|
||||
async fn set_status(&self, Parameters(args): Parameters<SetStatusArgs>) -> String {
|
||||
run_tool_envelope("set_status", args.text.clone(), async move {
|
||||
let (resp, retries) =
|
||||
self.dispatch(hive_sh4re::ManagerRequest::SetStatus { text: args.text }).await;
|
||||
annotate_retries(format_ack(resp, "set_status", "status updated".to_owned()), retries)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Cancel any open thread in the swarm — a `question` (cancels \
|
||||
with the operator-override sentinel so the asker unblocks) or a `reminder` \
|
||||
|
|
@ -1377,6 +1425,7 @@ pub fn allowed_mcp_tools(flavor: Flavor) -> Vec<String> {
|
|||
"remind",
|
||||
"get_loose_ends",
|
||||
"whoami",
|
||||
"set_status",
|
||||
"cancel_loose_end",
|
||||
],
|
||||
Flavor::Manager => &[
|
||||
|
|
@ -1395,6 +1444,7 @@ pub fn allowed_mcp_tools(flavor: Flavor) -> Vec<String> {
|
|||
"get_loose_ends",
|
||||
"remind",
|
||||
"whoami",
|
||||
"set_status",
|
||||
"cancel_loose_end",
|
||||
],
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue