App-server: support opt-in parallel execution for dynamic tools
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What variant of Codex are you using?
Codex app-server (codex-cli 0.154.0), integrated through OpenClaw 2026.9.5 on macOS arm64.
What feature would you like to see?
An explicit, default-off per-function capability allowing trusted app-server clients to opt eligible dynamic tools into parallel execution, for both direct and namespaced dynamic functions, including nested Code Mode calls.
This is distinct from encouraging the model to request multiple calls. In the inspected implementation, dynamic tools remain serialized even when the caller explicitly submits independent calls together. Please retain conservative serialization by default; this is not a request to make every dynamic tool concurrent or introduce hidden batching.
Observed behavior
In a live GPT-6 Astra session (medium reasoning, fast mode off), we submitted three independent timed, read-only fixture reads in one explicit Promise.allSettled cell per route:
- Native
exec_command: approximately 1.020 seconds from earliest start to latest end, with approximately 1.000 second of common overlap. - OpenClaw app-server dynamic-tool route: approximately 3.400 seconds from earliest start to latest end, with no execution overlap.
Each read deliberately held for approximately one second and returned the expected fixture value. These are single process-level scheduling probes, not repeated latency benchmarks or a claim about production speedup. The general shell tool is only a diagnostic comparison, not a proposed blanket concurrency allowlist entry.
Source explanation
Pinned public release source: rust-v0.154.0, commit 6b9826e3aa83b1a5947db50f4332cb9c65f1b340:
ToolExecutor::supports_parallel_tool_callsdefaults tofalse.DynamicToolHandlerdoes not override it and awaits the client's individual response.DynamicToolFunctionSpechas no per-function concurrency capability. The installed binary's generated experimental app-server schema also has no such field.ToolCallRuntimeuses a shared read lock for parallel-capable tools and an exclusive write lock otherwise, retaining the guard through awaited dispatch.- Nested Code Mode calls use clones sharing that runtime gate:
delegate.rsandsubmit_nested_tool.
The inspected main snapshot at 595cc91e8cbb1c2ca822d0311dcf12709410c582 retains the same dynamic-handler default and protocol limitation. This is public-source evidence consistent with the live observation, not a reproducible-build attestation for the installed binary. The lock scope is the shared ToolCallRuntime, not a process-global lock.
Suggested contract
- Add per-function eligibility, default false, and retain the existing scheduler gate.
- Provide a supported capability/version negotiation mechanism so clients do not advertise concurrency that an older runtime silently ignores.
- Keep trusted host policy authoritative. Model-generated arguments must not enable concurrency. Begin with dedicated immutable-read tools whose reentrancy is known.
- Tell the model that eligible independent calls may overlap and complete out of order; dependent calls must explicitly await prerequisites. Eligibility permits overlap but does not guarantee timing.
- Preserve individual call IDs/results, approvals, hooks, cancellation and partial-failure handling. Do not replay successful siblings automatically.
- Preserve absent/false behavior through direct/namespaced schemas, legacy conversion, persisted sessions, resume and tool replacement. Keep tool eligibility separate from model parallel-call support.
Useful regression tests would prove eligible-call overlap, serial barriers in mixed workloads, out-of-order result association, cancellation before/during execution, and backward compatibility, through both direct and nested paths.
Additional information
Related: #32503 and #35050 concern model/prompt behavior and avoidable Code Mode round trips. This request concerns native dynamic-tool execution eligibility after concurrency has already been explicitly requested, so prompt guidance alone does not resolve it.
No native patch has been built or deployed. If a supported mechanism already exists outside this inspected path, a pointer would be welcome.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/tools/src/tool_executor.rs, codex-rs/core/src/tools/handlers/dynamic.rs, protocol/src/dynamic_tools.rs, and core/src/tools/parallel.rs, then trace the nested paths in core/src/tools/code_mode/delegate.rs and mod.rs. Define the capability and compatibility behavior from the suggested contract, and verify done with direct and nested regression coverage for overlap, mixed serial workloads, result association, cancellation, and backward compatibility.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100