recv: optional wait_seconds parameter, capped at 60s

AgentRequest::Recv and ManagerRequest::Recv grow an optional
wait_seconds field (default None → 30s, capped at 60s server-side).
agent_server / manager_server clamp via recv_timeout(). MCP tool
schemas advertise the param so claude can pick its own poll window
— useful when an agent wants to throttle wakes without entering a
distinct nap state.

both harness loops still pass None, keeping the existing 30s
default behaviour for system-level Recvs.
This commit is contained in:
müde 2026-05-15 20:49:33 +02:00
parent 637085644d
commit f65ee88269
6 changed files with 73 additions and 21 deletions

View file

@ -69,7 +69,17 @@ async fn serve(stream: UnixStream, coord: Arc<Coordinator>) -> Result<()> {
}
}
const MANAGER_RECV_LONG_POLL: std::time::Duration = std::time::Duration::from_secs(30);
/// Default and max long-poll window for manager `Recv`. Caller can
/// request a shorter or longer (up to MAX) wait via `wait_seconds`.
const MANAGER_RECV_LONG_POLL_DEFAULT: std::time::Duration = std::time::Duration::from_secs(30);
const MANAGER_RECV_LONG_POLL_MAX: std::time::Duration = std::time::Duration::from_secs(60);
fn manager_recv_timeout(wait_seconds: Option<u64>) -> std::time::Duration {
match wait_seconds {
Some(s) => std::time::Duration::from_secs(s).min(MANAGER_RECV_LONG_POLL_MAX),
None => MANAGER_RECV_LONG_POLL_DEFAULT,
}
}
#[allow(clippy::too_many_lines)]
async fn dispatch(req: &ManagerRequest, coord: &Arc<Coordinator>) -> ManagerResponse {
@ -106,9 +116,9 @@ async fn dispatch(req: &ManagerRequest, coord: &Arc<Coordinator>) -> ManagerResp
message: format!("{e:#}"),
},
},
ManagerRequest::Recv => match coord
ManagerRequest::Recv { wait_seconds } => match coord
.broker
.recv_blocking(MANAGER_AGENT, MANAGER_RECV_LONG_POLL)
.recv_blocking(MANAGER_AGENT, manager_recv_timeout(*wait_seconds))
.await
{
Ok(Some(msg)) => ManagerResponse::Message {