mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
spawn_parallel_agents: opt out of the 120s per-tool timeout so the fan-out isn't truncated (#4686)
This commit is contained in:
@@ -14,7 +14,9 @@ use crate::openhuman::agent_orchestration::spawn_parallel_graph::{
|
||||
SpawnParallelGraphOutcome, SpawnParallelTaskValidationError,
|
||||
};
|
||||
use crate::openhuman::tinyagents::current_run_cancellation;
|
||||
use crate::openhuman::tools::traits::{PermissionLevel, Tool, ToolCallOptions, ToolResult};
|
||||
use crate::openhuman::tools::traits::{
|
||||
PermissionLevel, Tool, ToolCallOptions, ToolResult, ToolTimeout,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use serde_json::json;
|
||||
use tinyagents::harness::tool::ToolExecutionContext;
|
||||
@@ -95,6 +97,20 @@ impl Tool for SpawnParallelAgentsTool {
|
||||
PermissionLevel::Execute
|
||||
}
|
||||
|
||||
/// Run **without** the global per-tool wall-clock deadline. This is a
|
||||
/// fan-out primitive: it spawns N independent sub-agents and awaits them
|
||||
/// concurrently via `spawn_parallel_graph`'s bounded `map_reduce`. Under the
|
||||
/// default `Inherit` policy the whole fan-out is hard-killed at the
|
||||
/// single-tool timeout (120s by default) — so a group of long workers is
|
||||
/// truncated at one worker's budget instead of running to ~the slowest, and
|
||||
/// each worker's research is cut short. The fan-out is already bounded
|
||||
/// internally — by `max_concurrency`, the run cancellation token, and each
|
||||
/// sub-agent's own iteration/turn caps — so it governs its own lifetime,
|
||||
/// like the long-running scripting tools (`shell`, `node_exec`).
|
||||
fn timeout_policy(&self, _args: &serde_json::Value) -> ToolTimeout {
|
||||
ToolTimeout::Unbounded
|
||||
}
|
||||
|
||||
async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
|
||||
self.execute_with_context(args, ToolCallOptions::default(), None)
|
||||
.await
|
||||
|
||||
@@ -16,6 +16,7 @@ use crate::openhuman::inference::provider::{
|
||||
ChatRequest, ChatResponse, ConversationMessage, Provider, ToolCall,
|
||||
};
|
||||
use crate::openhuman::memory::{Memory, MemoryCategory, MemoryEntry, NamespaceSummary, RecallOpts};
|
||||
use crate::openhuman::tools::traits::ToolTimeout;
|
||||
use crate::openhuman::tools::{PermissionLevel, Tool, ToolResult};
|
||||
use async_trait::async_trait;
|
||||
use parking_lot::Mutex;
|
||||
@@ -899,3 +900,15 @@ async fn agent_turn_runs_long_parallel_subagent_flow_with_many_nested_tool_calls
|
||||
"each subagent should run three tool calls plus a final completion iteration"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_parallel_agents_opts_out_of_the_global_tool_timeout() {
|
||||
// A fan-out of N long sub-agents must not be hard-killed at the single-tool
|
||||
// wall-clock default (120s): that truncates every worker and bounds the whole
|
||||
// group at one worker's budget. The tool governs its own lifetime via its
|
||||
// internal max_concurrency, cancellation token, and per-sub-agent caps.
|
||||
assert_eq!(
|
||||
SpawnParallelAgentsTool::new().timeout_policy(&json!({})),
|
||||
ToolTimeout::Unbounded,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user