feat(#1021): query_agent_state capability for agent socket GetLooseEnds/CountPendingReminders/ReminderRollup

This commit is contained in:
damocles 2026-06-01 21:21:25 +02:00
commit 4834ca413c
3 changed files with 109 additions and 30 deletions

View file

@ -661,11 +661,14 @@ impl AgentServer {
at turn start to remember what you owe / what's owed to you without scrolling \
inbox history. Output is a short bulleted list with ids, ages in seconds, and \
the relevant context. Each `question` or `reminder` row can be cancelled by \
passing its id + kind to `cancel_loose_end`. Empty result is reported clearly."
passing its id + kind to `cancel_loose_end`. Empty result is reported clearly.\n\
Pass `agent: \"<name>\"` to inspect a specific peer agent's threads — requires \
the `query_agent_state` capability; without it the field is ignored and results \
are scoped to you."
)]
async fn get_loose_ends(&self) -> String {
async fn get_loose_ends(&self, Parameters(args): Parameters<AgentGetLooseEndsArgs>) -> String {
run_tool_envelope("get_loose_ends", String::new(), async move {
let (resp, retries) = self.dispatch(hive_sh4re::AgentRequest::GetLooseEnds { agent: None }).await;
let (resp, retries) = self.dispatch(hive_sh4re::AgentRequest::GetLooseEnds { agent: args.agent }).await;
let mut out = annotate_retries(format_loose_ends(resp), retries);
// Append any local bash tasks still in pending/running state so
// the agent sees all outstanding work in one call.
@ -1056,6 +1059,18 @@ pub struct GetLooseEndsArgs {
pub agent: Option<String>,
}
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct AgentGetLooseEndsArgs {
/// Whose loose ends to list. Omit (or `null`) for your own. Pass a
/// specific agent name to inspect that agent's threads — requires
/// the `query_agent_state` capability; without it the field is
/// ignored and results are scoped to you. The `"*"` hive-wide value
/// is not available on the agent socket; use the manager socket for
/// swarm-wide scans.
#[serde(default)]
pub agent: Option<String>,
}
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct RequestApplyCommitArgs {
/// Logical agent name whose config repo the commit lives in.
@ -1925,6 +1940,11 @@ fn allowed_capability_tools() -> Vec<String> {
// manage_root_agent doesn't expose new MCP tools (it gates
// existing lifecycle tools via the topology enforcement).
"manage_root_agent" => {}
// query_agent_state doesn't expose new MCP tools; it unlocks
// the `agent` field in get_loose_ends / count_pending_reminders
// / reminder_rollup on the agent socket (c0re enforces the cap
// server-side; the harness honours it by passing the field).
"query_agent_state" => {}
unknown => {
tracing::warn!(capability = %unknown, "unrecognised capability in HIVE_CAPABILITIES — skipped");
}