Skip to content

Commit 1477a3f

Browse files
authored
fix(mods): exclude native waits from root execution budget (#14986)
* fix(mods): exclude native waits from root execution budget * fix(cli): preserve cancelled tool results in Ink history * fix(cli): keep cancelled tool finalization in its owning session --------- Co-authored-by: qqqys <266654365+qqqys@users.noreply.github.com>
1 parent 6c8d1e0 commit 1477a3f

12 files changed

Lines changed: 2030 additions & 271 deletions

File tree

‎docs/users/extension/mods.md‎

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,13 @@ In headless runs, additional attempts count against `--max-tool-calls`; catch re
203203
attempt. Interactive terminals retain their existing usage counters and do not add a run-budget setting. Sessions with tool middleware serialize tool calls, including parallel
204204
next calls, because rewritten arguments may introduce side effects. One root
205205
call permits at most 64 native attempts and 32 outstanding host operations.
206-
The 60-second root limit includes native execution and time spent waiting for
207-
approval. Returning before an outstanding next completes cancels that work and
208-
waits for it to settle.
206+
The tool root has a cumulative 60-second Mod budget. Native execution and
207+
approval waiting do not consume it while the host owns the active attempt and
208+
no guest work is running or awaiting without lending its budget. Guest checks,
209+
callbacks, continuations and log observers still consume the root budget, even
210+
while another native attempt is active. Starting another attempt never resets
211+
the remaining budget. Returning before an outstanding next completes cancels
212+
that work and waits for it to settle.
209213

210214
`tool.check` receives `{tool, input, tool_use_id}` after native validation and
211215
classic input rewrites. All fields are pinned. Its next returns a declarative
@@ -353,12 +357,21 @@ queued notifications before returning output.
353357
A normal plugin layer has 10 seconds of its own time, excluding time waiting for
354358
cross-plugin `next` or API calls. Pending void `ui.log` notifications do not pause
355359
the caller's budget. Catch recovery uses a one-second budget.
356-
Qwen additionally caps each root dispatch at 60 seconds and each
357-
uninterrupted guest execution slice at 10 seconds. All `session.end` work shares
358-
1.5 seconds. An outer handler that finishes early abandons pending downstream
359-
work; cancellation never starts a fallback operation. Retained next/API functions
360-
cannot perform work after their invocation ends. A worker that cannot acknowledge
361-
cancellation within 250 milliseconds is terminated; restart the CLI to reload Mods.
360+
Qwen additionally caps each root dispatch at 60 seconds of charged time and each
361+
uninterrupted guest execution slice at 10 seconds. Only tool roots exclude the
362+
trusted native waits described above; load and command roots retain continuous
363+
60-second limits. All `session.end` work shares 1.5 seconds. Native tool timeouts
364+
and permission decisions still apply. The scheduler's optional execution timeout
365+
defaults to disabled and does not impose an approval deadline; individual tools
366+
retain their own timeout policies.
367+
368+
An outer handler that finishes early abandons pending downstream work;
369+
cancellation never starts a fallback operation. Retained next/API functions cannot
370+
perform work after their invocation ends. Cancellation immediately revokes the
371+
current root, including during an excluded native wait. A worker that cannot
372+
acknowledge cancellation within 250 milliseconds is terminated; this watchdog
373+
continues independently of the Mod budget. Native process cleanup and task drain
374+
can take longer. Restart the CLI to reload a terminated Mod worker.
362375

363376
There are at most 32 Mod environments, 64 registered commands, 128 registrations
364377
per plugin, and 4,096 root/API event chains per root call. Passing through another

0 commit comments

Comments
 (0)