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

@ -77,9 +77,19 @@ async fn serve(stream: UnixStream, agent: String, broker: Arc<Broker>) -> Result
}
}
/// How long the long-poll `Recv` holds a connection open waiting for new
/// mail. Set well below typical TCP/proxy idle limits.
const RECV_LONG_POLL: std::time::Duration = std::time::Duration::from_secs(30);
/// Default and max long-poll window for `Recv`. Caller can request a
/// shorter (or longer up to `RECV_LONG_POLL_MAX`) wait via the
/// `wait_seconds` field; values above the cap are clamped. Set well
/// below typical TCP / proxy idle limits.
const RECV_LONG_POLL_DEFAULT: std::time::Duration = std::time::Duration::from_secs(30);
const RECV_LONG_POLL_MAX: std::time::Duration = std::time::Duration::from_secs(60);
fn recv_timeout(wait_seconds: Option<u64>) -> std::time::Duration {
match wait_seconds {
Some(s) => std::time::Duration::from_secs(s).min(RECV_LONG_POLL_MAX),
None => RECV_LONG_POLL_DEFAULT,
}
}
async fn dispatch(req: &AgentRequest, agent: &str, broker: &Broker) -> AgentResponse {
match req {
@ -95,7 +105,10 @@ async fn dispatch(req: &AgentRequest, agent: &str, broker: &Broker) -> AgentResp
},
}
}
AgentRequest::Recv => match broker.recv_blocking(agent, RECV_LONG_POLL).await {
AgentRequest::Recv { wait_seconds } => match broker
.recv_blocking(agent, recv_timeout(*wait_seconds))
.await
{
Ok(Some(msg)) => AgentResponse::Message {
from: msg.from,
body: msg.body,