feat(web_search): enable parallel execution for read-only search tool#2509
feat(web_search): enable parallel execution for read-only search tool#2509Implementist wants to merge 1 commit into
Conversation
Override `supports_parallel()` to return `true` in `WebSearchTool`, allowing the engine to batch multiple concurrent web_search calls into a `FuturesUnordered` parallel group instead of serializing them. The tool is already read-only, auto-approved, and non-interactive — parallel-safe by all other criteria. This change removes the final gate (`supports_parallel() -> false` default) so co-issued searches run concurrently rather than one-at-a-time. Closes the ~55s serial wall-clock for 3 simultaneous web searches (now ~20s, the slowest individual call). Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Code Review
This pull request updates the WebSearchTool implementation of the ToolSpec trait in crates/tui/src/tools/web_search.rs to support parallel execution by implementing the supports_parallel method and returning true. There are no review comments, and I have no additional feedback to provide.
| fn supports_parallel(&self) -> bool { | ||
| true | ||
| } |
There was a problem hiding this comment.
No regression test pins
supports_parallel() to true. A future refactor that accidentally removes or moves this override would silently re-serialize all web searches with no failing test to catch it. Adding assert!(WebSearchTool.supports_parallel()) in the existing #[cfg(test)] block would lock the contract.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
Thanks @Implementist. I reviewed this after CI and Greptile were green, including Windows, and harvested the narrow Local verification on the harvest branch:
I am leaving this PR open until #2504 lands or a maintainer closes it as superseded, but the contributor credit is now preserved in #2504. |
Summary
Override
supports_parallel()to returntrueinWebSearchTool, allowing the engine to batch multiple concurrentweb_searchcalls into aFuturesUnorderedparallel group instead of serializing them.The tool is already read-only, auto-approved, and non-interactive — parallel-safe by all other criteria. This change removes the final gate (
supports_parallel() -> falsedefault) so co-issued searches run concurrently rather than one-at-a-time.Closes the ~55s serial wall-clock for 3 simultaneous web searches (now ~20s, the slowest individual call).
Background
Why parallel execution matters for Volcengine users
Volcengine's web search uses an LLM-summarized pipeline (Ark Responses API) where the model performs the search and returns structured JSON. A single call takes ~20 seconds — acceptable on its own, but when the agent issues 3 co-occurring searches, serial execution stacks them to ~55s total.
Prior to this change, observing the third search returning at ~50s led to the mistaken conclusion that individual Volcengine responses could take 50+ seconds, which drove the existing 90s timeout floor. In reality, a single call completes in ~20s; the 50s was accumulated serial latency from three sequential calls.
For users in regions where DuckDuckGo/Bing work reliably and return results quickly, this change is a nice-to-have. For Volcengine users who rely on the LLM-summarized pipeline, it is critical — without parallel execution, multi-search turns are painfully slow despite each individual call being reasonably fast.
Root cause
ToolSpec::supports_parallel()defaults tofalse.WebSearchTooldid not override it.tool_plan_is_parallel_safe()indispatch.rsrequires all four conditions:read_only(true)supports_parallel(was false — the blocker)!approval_required(true)!interactive(true)Changes
crates/tui/src/tools/web_search.rs: addsupports_parallel() -> trueoverride inimpl ToolSpec for WebSearchTool(4 lines)Testing
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-featurescargo test --workspace --all-features(4101 passed, 0 failed, 8 ignored)Checklist
web_searchtests all pass)Greptile Summary
This PR enables parallel execution for
WebSearchToolby overridingsupports_parallel()to returntrue, unlocking the engine'sFuturesUnorderedbatching path for concurrentweb_searchcalls. The tool already satisfied the other threetool_plan_is_parallel_safeconditions (read_only,!approval_required,!interactive), making this a minimal and targeted unlock.supports_parallel() -> trueoverride inimpl ToolSpec for WebSearchTool; no logic changes to any provider path.Confidence Score: 4/5
Safe to merge — the change is a single boolean method override with no side effects on any execution path.
The change is minimal and correct:
WebSearchToolwas already read-only, auto-approved, and non-interactive, so enabling parallel execution requires no defensive guards. All providers create independentreqwest::Clientinstances per call and share no mutable state. The only open items are style-level: a missing regression test to pin thesupports_parallelcontract, and a code comment about the Volcengine 90 s timeout floor whose original motivation no longer fully applies.No files require special attention; the single changed file touches only the
ToolSpectrait impl.Important Files Changed
supports_parallel() -> trueoverride toWebSearchTool; the tool is stateless, read-only, and auto-approved — all fourtool_plan_is_parallel_safeconditions are now satisfied.Sequence Diagram
sequenceDiagram participant Engine as turn_loop participant Dispatcher as dispatch.rs participant S1 as WebSearch #1 participant S2 as WebSearch #2 participant S3 as WebSearch #3 Engine->>Dispatcher: plan_tool_execution_batches([search1, search2, search3]) Note over Dispatcher: tool_plan_is_parallel_safe:<br/>read_only=true, supports_parallel=true,<br/>approval_required=false, interactive=false Dispatcher-->>Engine: ToolExecutionBatch::Parallel([s1, s2, s3]) par FuturesUnordered Engine->>S1: execute(query1) Engine->>S2: execute(query2) Engine->>S3: execute(query3) end S1-->>Engine: results (~20s) S2-->>Engine: results (~20s) S3-->>Engine: results (~20s) Note over Engine: Total wall-clock: ~20s (was ~55s serial)Comments Outside Diff (1)
crates/tui/src/tools/web_search.rs, line 777-779 (link)Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (1): Last reviewed commit: "feat(web_search): enable parallel execut..." | Re-trigger Greptile