Skip to content

fix(agent_orchestration): Unbounded timeout for delegation tools — delegate_tools_agent, run_code (#4734)#4741

Open
oxoxDev wants to merge 1 commit into
tinyhumansai:mainfrom
oxoxDev:fix/4734-delegation-tool-timeout
Open

fix(agent_orchestration): Unbounded timeout for delegation tools — delegate_tools_agent, run_code (#4734)#4741
oxoxDev wants to merge 1 commit into
tinyhumansai:mainfrom
oxoxDev:fix/4734-delegation-tool-timeout

Conversation

@oxoxDev

@oxoxDev oxoxDev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Delegation tools (delegate_tools_agent, run_code, and any other archetype-delegate tool) now opt out of the global 120s per-tool wall-clock, so a sub-agent run that legitimately takes longer than two minutes is no longer hard-killed mid-flight.
  • Fixes two high-volume Sentry crashes with one change: TAURI-RUST-K29 (delegate_tools_agent, 1236 events / 71 users) and TAURI-RUST-8HB (run_code, 755 events / 51 users).

Problem

Both delegate_tools_agent and run_code are synthesized by the same type, ArchetypeDelegationTool. It never overrode timeout_policy(), so it inherited ToolTimeout::Inherit = the global per-tool cap (tool_timeout::DEFAULT_TIMEOUT_SECS = 120). Every tool call is wrapped in tokio::time::timeout(deadline, exec), so a delegation whose sub-agent runs past 120s was hard-killed at exactly 120.000s and truncated — surfacing as tool '<name>' timed out after 120 seconds. The delegated agents are internally bounded (their agent.toml max_iterations, the run cancellation token, and each inner tool's own timeout), so the 120s cap doesn't protect against runaway work — it just truncates legitimate long-running delegation.

The sibling spawn_parallel_agents tool had this exact bug fixed in #4686 (timeout_policy -> Unbounded); the long-running scripting tools (shell, node_exec, npm_exec) are already Unbounded-by-default. ArchetypeDelegationTool was simply missed.

Solution

Override timeout_policy() -> ToolTimeout::Unbounded on ArchetypeDelegationTool, mirroring #4686. The child agent governs its own lifetime, so the delegation primitive should not impose the single-tool wall-clock. Adds a unit test asserting the override (mirrors spawn_parallel_agents_tests).

Scope is deliberately narrow: SkillDelegationTool (→ integrations_agent, quick Composio actions) and the base DelegateTool route to short-lived agents and are intentionally left on the default — no speculative widening.

RCA-vs-suppress: Bucket = real-defect (a wrong timeout policy truncating internally-bounded work). This corrects the policy; it is not a suppression.

Submission Checklist

  • Tests added or updated (happy path + edge case) — unit test asserts timeout_policy() == Unbounded; existing ArchetypeDelegationTool tests cover the delegation happy/blank-prompt paths
  • Diff coverage ≥ 80% — verified locally via cargo-llvm-cov + diff-cover --compare-branch=upstream/main: 100% on changed lines (7/7)
  • Coverage matrix updated — N/A: behaviour-only reliability change (no feature row)
  • All affected feature IDs listed under ## RelatedN/A
  • No new external network dependencies introduced
  • Manual smoke checklist updated if release-cut surfaces touched — N/A: internal tool-timeout policy
  • Linked issue closed via Closes #NNN in ## Related

Impact

  • Platform: desktop (all) — agent delegation path.
  • Behavior: long delegated sub-agent runs complete instead of dying at 120s. No change to healthy short delegations. The child is still bounded by its own iteration cap + run cancellation token, so this cannot cause an unbounded runaway.
  • No schema, API, or migration change. One-line policy override + test.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

Commit & Branch

Validation Run

  • pnpm --filter openhuman-app format:check — N/A (no app/ changes)
  • pnpm typecheck — N/A (no TS changes)
  • Focused tests: delegation_opts_out_of_the_global_tool_timeoutpasses (test result: ok. 1 passed)
  • Rust fmt/check (if changed): cargo fmt --check clean, cargo check --lib clean, cargo clippy --lib clean on the changed file
  • Tauri fmt/check (if changed): N/A

Behavior Changes

  • Intended behavior change: archetype-delegation tools run without the 120s single-tool wall-clock.
  • User-visible effect: long agent-delegation tasks complete instead of failing with a 120s timeout.

Parity Contract

Duplicate / Superseded PR Handling

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 31 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f2014a8b-c3c9-4028-92de-e20b2973b9c9

📥 Commits

Reviewing files that changed from the base of the PR and between 54511e6 and 5df7911.

📒 Files selected for processing (1)
  • src/openhuman/agent_orchestration/tools/archetype_delegation.rs

Comment @coderabbitai help to get the list of available commands.

…yhumansai#4734)

ArchetypeDelegationTool synthesizes delegate_tools_agent (tools_agent) and
run_code (code_executor). It defaulted to ToolTimeout::Inherit = the global
120s per-tool cap, so any delegated sub-agent run exceeding two minutes was
hard-killed and truncated (Sentry TAURI-RUST-K29: 1236 events / 71 users;
TAURI-RUST-8HB: 755 / 51). The child bounds its own lifetime via max_iterations,
the run cancellation token, and each inner tool's timeout, so override
timeout_policy -> Unbounded, matching spawn_parallel_agents (tinyhumansai#4686) and the
long-running scripting tools. Adds a unit test asserting the override.
@oxoxDev oxoxDev force-pushed the fix/4734-delegation-tool-timeout branch from c408115 to 5df7911 Compare July 9, 2026 21:04
@oxoxDev oxoxDev marked this pull request as ready for review July 9, 2026 21:26
@oxoxDev oxoxDev requested a review from a team July 9, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Delegation tools (delegate_tools_agent, run_code) hard-killed at 120s: ArchetypeDelegationTool needs Unbounded timeout_policy

1 participant