scheduled prompts: fire-now operator + manager surfaces (closes #467)

This commit is contained in:
damocles 2026-05-26 13:43:04 +02:00 committed by Mara
commit 3cd9240594
6 changed files with 251 additions and 1 deletions

View file

@ -959,6 +959,14 @@ pub struct RequestSchedulePromptArgs {
pub description: Option<String>,
}
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct FireScheduleNowArgs {
/// Schedule id to fire out of band. Get this from a prior
/// `list_schedules` call or the approval-resolved event for
/// the originating `request_schedule_prompt`.
pub id: i64,
}
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CancelScheduleArgs {
/// Schedule id from a prior `list_schedules` call or the
@ -1269,6 +1277,33 @@ impl ManagerServer {
.await
}
#[tool(
description = "Fire a scheduled prompt out of band — runs the per-target fan-out \
once immediately without disturbing the schedule's cadence. Recurring schedules \
keep their next_fire_at unchanged (the manual fire is additive). One-shot \
schedules are CONSUMED by the manual fire (cancelled afterwards): the operator's \
intent on a one-shot is 'send this now, the scheduled time was wrong'. \n\n\
Authorization mirrors `cancel_schedule`: you can fire your own schedules + any \
owned by a sub-agent in your subtree per topology.json."
)]
async fn fire_schedule_now(
&self,
Parameters(args): Parameters<FireScheduleNowArgs>,
) -> String {
let log = format!("{args:?}");
run_tool_envelope("fire_schedule_now", log, async move {
let id = args.id;
let (resp, retries) = self
.dispatch(hive_sh4re::ManagerRequest::FireScheduleNow { id })
.await;
annotate_retries(
format_ack(resp, "fire_schedule_now", format!("fired #{id} now")),
retries,
)
})
.await
}
#[tool(
description = "Cancel a scheduled prompt. With no `targets` field, cancels the \
whole schedule (all recipients flipped). With a non-empty `targets` list, cancels \