repoint remind/cancel_loose_end/get_loose_ends to the local reminder socket (#2635 inc 1)

This commit is contained in:
damocles 2026-07-22 21:05:15 +02:00 committed by mara
commit e8d101d663
2 changed files with 59 additions and 15 deletions

View file

@ -35,8 +35,9 @@ pub use args::{
pub use render::{annotate_retries, format_ack, format_agent_meta, format_recv};
use render::{
format_matrix_summary, local_todos, loose_end_kind_label, mark_local_todo_done,
matrix_unread_summary, parse_loose_end_kind, render_loose_ends, reply_err,
dial_agent_socket, format_matrix_summary, local_reminders, local_todos, loose_end_kind_label,
mark_local_todo_done, matrix_unread_summary, parse_loose_end_kind, render_loose_ends,
reply_err,
};
/// Write (or remove) the status file in the agent's own `state/` directory.
@ -343,6 +344,12 @@ impl AgentServer {
if is_self_query && let Some(todos) = local_todos().await {
loose_ends.extend(todos);
}
// Merge local pending reminders (#2635 inc 1 — same self-query-only
// restriction: a manager asking for a child's loose-ends no longer
// sees the child's reminders, matching the todos precedent above).
if is_self_query && let Some(reminders) = local_reminders().await {
loose_ends.extend(reminders);
}
annotate_retries(render_loose_ends(&loose_ends), retries)
})
.await
@ -446,6 +453,26 @@ impl AgentServer {
Err(e) => return e,
};
let kind_label = loose_end_kind_label(kind);
// Reminders are harness-local (#2635 inc 1) — dial the in-agent
// socket directly instead of the broker; every other kind
// (question/approval) still lives in c0re.
if kind == hive_sh4re::CancelLooseEndKind::Reminder {
return match dial_agent_socket(&hive_agent_sock::Request::CancelReminder { id })
.await
{
Some(hive_agent_sock::Response::Acked { count }) if count > 0 => {
format!("cancelled {kind_label} {id}")
}
Some(hive_agent_sock::Response::Acked { .. }) => {
format!("cancel_loose_end failed: no pending {kind_label} {id}")
}
Some(hive_agent_sock::Response::Err { message }) => {
format!("cancel_loose_end failed: {message}")
}
Some(other) => format!("cancel_loose_end unexpected response: {other:?}"),
None => "cancel_loose_end failed: in-agent socket unavailable".to_owned(),
};
}
let (resp, retries) = self
.dispatch(hive_core_agent_sock::Request::CancelLooseEnd { kind, id })
.await;
@ -516,17 +543,22 @@ impl AgentServer {
(Some(s), None) => hive_sh4re::ReminderTiming::InSeconds { seconds: s },
(None, Some(t)) => hive_sh4re::ReminderTiming::At { unix_timestamp: t },
};
let (resp, retries) = self
.dispatch(hive_core_agent_sock::Request::Remind {
message: args.message,
timing,
file_path: args.file_path,
})
.await;
annotate_retries(
format_ack(resp, "remind", "reminder scheduled".to_string()),
retries,
)
// Reminders are harness-local (#2635 inc 1) — dial the in-agent
// socket directly instead of the broker.
match dial_agent_socket(&hive_agent_sock::Request::StoreReminder {
message: args.message,
timing,
file_path: args.file_path,
})
.await
{
Some(hive_agent_sock::Response::Ok) => "reminder scheduled".to_owned(),
Some(hive_agent_sock::Response::Err { message }) => {
format!("remind failed: {message}")
}
Some(other) => format!("remind unexpected response: {other:?}"),
None => "remind failed: in-agent socket unavailable".to_owned(),
}
})
.await
}

View file

@ -304,8 +304,10 @@ pub(super) async fn matrix_unread_summary() -> Option<Vec<MatrixRoomUnread>> {
/// best-effort, single-shot (no retry, unlike the broker's
/// `client::request_retried`): this socket lives in the SAME container, so
/// a connect failure means the harness itself isn't up, which a retry
/// won't fix within a tool call's budget. Shared by [`local_todos`] and
/// [`mark_local_todo_done`].
/// won't fix within a tool call's budget. Shared by [`local_todos`],
/// [`mark_local_todo_done`], and [`local_reminders`]; `remind`/
/// `cancel_loose_end`(reminder) in `mod.rs` dial it directly since their
/// happy path is a plain `Ok`/`Err`, not a `Vec<LooseEnd>` to merge.
pub(super) async fn dial_agent_socket(
req: &hive_agent_sock::Request,
) -> Option<hive_agent_sock::Response> {
@ -335,6 +337,16 @@ pub(super) async fn local_todos() -> Option<Vec<hive_sh4re::LooseEnd>> {
}
}
/// Query the harness's in-agent socket for this agent's local pending
/// reminders (#2635 inc 1 — was a broker query before reminders moved
/// in-container). Same best-effort contract as [`local_todos`].
pub(super) async fn local_reminders() -> Option<Vec<hive_sh4re::LooseEnd>> {
match dial_agent_socket(&hive_agent_sock::Request::ListReminders).await? {
hive_agent_sock::Response::LooseEnds { loose_ends } => Some(loose_ends),
_ => None,
}
}
/// Mark one of this agent's local todos (loose-ends v2) done by id, via
/// the harness's in-agent socket — reachable through `cancel_loose_end`
/// kind `"todo"` so clearing a todo never has to shell out through a