cancel_thread: new mcp tool — unify reminder + question cancel on both surfaces

This commit is contained in:
damocles 2026-05-18 18:07:44 +02:00
parent fcd407da11
commit b1d0a62cb9
11 changed files with 331 additions and 25 deletions

View file

@ -26,9 +26,12 @@ use crate::coordinator::Coordinator;
/// we keep the rule per-agent so the manager's MCP surface gets
/// the same shape via a different code path);
/// - unanswered questions where `agent` is the asker (waiting on
/// someone) OR the target (owes a reply).
/// someone) OR the target (owes a reply);
/// - pending reminders this agent scheduled (`owner == self`).
///
/// Newest-first within each kind, approvals before questions.
/// Ordered approvals → questions → reminders within the returned
/// vector. Within each kind, source-of-truth ordering (sqlite's
/// `pending()` queries return newest-first within their indexes).
pub fn for_agent(coord: &Coordinator, agent: &str) -> Result<Vec<OpenThread>> {
let now = now_unix();
let mut out = Vec::new();
@ -60,13 +63,25 @@ pub fn for_agent(coord: &Coordinator, agent: &str) -> Result<Vec<OpenThread>> {
age_seconds: saturating_age(now, q.asked_at),
});
}
for r in coord.broker.list_pending_reminders()? {
if r.agent != agent {
continue;
}
out.push(OpenThread::Reminder {
id: r.id,
owner: r.agent,
message: r.message,
due_at: r.due_at,
age_seconds: saturating_age(now, r.created_at),
});
}
Ok(out)
}
/// Hive-wide loose-ends view: EVERY pending approval + EVERY
/// unanswered question. Manager surface only; sub-agents can't see
/// each other's threads via the agent surface (`for_agent` filters
/// by name).
/// unanswered question + EVERY pending reminder. Manager surface
/// only; sub-agents can't see each other's threads via the agent
/// surface (`for_agent` filters by name).
pub fn hive_wide(coord: &Coordinator) -> Result<Vec<OpenThread>> {
let now = now_unix();
let mut out = Vec::new();
@ -88,6 +103,15 @@ pub fn hive_wide(coord: &Coordinator) -> Result<Vec<OpenThread>> {
age_seconds: saturating_age(now, q.asked_at),
});
}
for r in coord.broker.list_pending_reminders()? {
out.push(OpenThread::Reminder {
id: r.id,
owner: r.agent,
message: r.message,
due_at: r.due_at,
age_seconds: saturating_age(now, r.created_at),
});
}
Ok(out)
}