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:
parent
637085644d
commit
f65ee88269
6 changed files with 73 additions and 21 deletions
|
|
@ -116,7 +116,8 @@ async fn serve(
|
|||
let label = std::env::var("HIVE_LABEL").unwrap_or_else(|_| "hive-ag3nt".into());
|
||||
let system_prompt = turn::write_system_prompt(socket, &label, mcp::Flavor::Agent).await?;
|
||||
loop {
|
||||
let recv: Result<AgentResponse> = client::request(socket, &AgentRequest::Recv).await;
|
||||
let recv: Result<AgentResponse> =
|
||||
client::request(socket, &AgentRequest::Recv { wait_seconds: None }).await;
|
||||
match recv {
|
||||
Ok(AgentResponse::Message { from, body }) => {
|
||||
tracing::info!(%from, %body, "inbox");
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ async fn serve(socket: &Path, interval: Duration, bus: Bus) -> Result<()> {
|
|||
let label = std::env::var("HIVE_LABEL").unwrap_or_else(|_| "hm1nd".into());
|
||||
let system_prompt = turn::write_system_prompt(socket, &label, mcp::Flavor::Manager).await?;
|
||||
loop {
|
||||
let recv: Result<ManagerResponse> = client::request(socket, &ManagerRequest::Recv).await;
|
||||
let recv: Result<ManagerResponse> =
|
||||
client::request(socket, &ManagerRequest::Recv { wait_seconds: None }).await;
|
||||
match recv {
|
||||
Ok(ManagerResponse::Message { from, body }) => {
|
||||
if from == SYSTEM_SENDER {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,14 @@ pub struct SendArgs {
|
|||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct RecvArgs {}
|
||||
pub struct RecvArgs {
|
||||
/// How long to long-poll for a new message before returning the
|
||||
/// empty marker. Capped at 60s server-side. Default (None) is
|
||||
/// 30s. Useful when an agent wants to throttle wakes without
|
||||
/// actually napping — pick a longer wait to coalesce bursts.
|
||||
#[serde(default)]
|
||||
pub wait_seconds: Option<u64>,
|
||||
}
|
||||
|
||||
/// Per-agent tool surface. Holds the socket path so each tool call doesn't
|
||||
/// re-derive it; the socket itself is the per-container `/run/hive/mcp.sock`.
|
||||
|
|
@ -158,13 +165,17 @@ impl AgentServer {
|
|||
|
||||
#[tool(
|
||||
description = "Pop one message from this agent's inbox. Returns the sender and body, \
|
||||
or an empty marker if nothing is waiting."
|
||||
or an empty marker if nothing is waiting. Optional `wait_seconds` long-polls \
|
||||
for that many seconds (capped at 60) before returning empty — default 30."
|
||||
)]
|
||||
async fn recv(&self, Parameters(_args): Parameters<RecvArgs>) -> String {
|
||||
run_tool_envelope("recv", String::new(), async move {
|
||||
async fn recv(&self, Parameters(args): Parameters<RecvArgs>) -> String {
|
||||
let log = format!("{args:?}");
|
||||
run_tool_envelope("recv", log, async move {
|
||||
let resp = client::request::<_, hive_sh4re::AgentResponse>(
|
||||
&self.socket,
|
||||
&hive_sh4re::AgentRequest::Recv,
|
||||
&hive_sh4re::AgentRequest::Recv {
|
||||
wait_seconds: args.wait_seconds,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map(SocketReply::from);
|
||||
|
|
@ -303,11 +314,17 @@ impl ManagerServer {
|
|||
|
||||
#[tool(
|
||||
description = "Pop one message from the manager inbox. Returns sender + body, or \
|
||||
empty."
|
||||
empty. Optional `wait_seconds` long-polls (capped at 60, default 30) so the \
|
||||
manager can sit on Recv when there's nothing to do without burning turns."
|
||||
)]
|
||||
async fn recv(&self, Parameters(_args): Parameters<RecvArgs>) -> String {
|
||||
run_tool_envelope("recv", String::new(), async move {
|
||||
let resp = self.dispatch(hive_sh4re::ManagerRequest::Recv).await;
|
||||
async fn recv(&self, Parameters(args): Parameters<RecvArgs>) -> String {
|
||||
let log = format!("{args:?}");
|
||||
run_tool_envelope("recv", log, async move {
|
||||
let resp = self
|
||||
.dispatch(hive_sh4re::ManagerRequest::Recv {
|
||||
wait_seconds: args.wait_seconds,
|
||||
})
|
||||
.await;
|
||||
format_recv(resp)
|
||||
})
|
||||
.await
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue