From faff09ef23cf847f8137b35b1efb46b758c98ca1 Mon Sep 17 00:00:00 2001 From: damocles Date: Wed, 3 Jun 2026 15:27:29 +0200 Subject: [PATCH] feat(#1147): add optional wait_seconds to bash_status --- hive-ag3nt/src/mcp.rs | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/hive-ag3nt/src/mcp.rs b/hive-ag3nt/src/mcp.rs index 4426e0f1..d98a4977 100644 --- a/hive-ag3nt/src/mcp.rs +++ b/hive-ag3nt/src/mcp.rs @@ -522,6 +522,12 @@ fn default_bash_run_wait() -> Option { pub struct BashStatusArgs { /// Task ID returned by `bash_run`. pub id: String, + /// Optional inline wait: if set, `bash_status` polls for up to + /// `wait_seconds` (capped at 30) before returning. When the task + /// finishes within the window the full status is returned immediately. + /// Useful to avoid a separate round-trip when a task is expected to + /// finish soon. + pub wait_seconds: Option, } /// Format the result of `bash_status` from a task ID. @@ -1008,15 +1014,38 @@ impl AgentServer { description = "Check the status of a background bash task by its ID (from `bash_run`). \ Returns the current status (pending/running/done/timed_out/interrupted), exit code \ if finished, and a tail of stdout/stderr. Full output lives in \ - `harness/bash-tasks/.out` / `.err`." + `harness/bash-tasks/.out` / `.err`. \ + Pass `wait_seconds` (capped at 30) to wait inline for the task to finish: when the \ + task finishes within the window the full status is returned immediately. Useful to \ + avoid a separate round-trip when the task is expected to finish soon." )] async fn bash_status(&self, Parameters(args): Parameters) -> String { let log = format!("{args:?}"); - run_tool_envelope( - "bash_status", - log, - async move { format_bash_status(&args.id) }, - ) + run_tool_envelope("bash_status", log, async move { + // Inline wait: if the task isn't terminal yet, poll until done or deadline. + if let Some(wait) = args.wait_seconds { + const MAX_WAIT_SECS: u64 = 30; + const POLL_MS: u64 = 100; + let deadline = tokio::time::Instant::now() + + std::time::Duration::from_secs(wait.min(MAX_WAIT_SECS)); + loop { + if let Some(task) = crate::bash_runner::read_task(&args.id) { + use crate::bash_runner::TaskStatus; + if matches!( + task.status, + TaskStatus::Done | TaskStatus::TimedOut | TaskStatus::Interrupted + ) { + break; + } + } + if tokio::time::Instant::now() >= deadline { + break; + } + tokio::time::sleep(std::time::Duration::from_millis(POLL_MS)).await; + } + } + format_bash_status(&args.id) + }) .await }