Skip to content

subagent: tell the child its iter budget, warn near the cap#493

Merged
esengine merged 1 commit into
mainfrom
feat/488-subagent-budget-telemetry
May 9, 2026
Merged

subagent: tell the child its iter budget, warn near the cap#493
esengine merged 1 commit into
mainfrom
feat/488-subagent-budget-telemetry

Conversation

@esengine

@esengine esengine commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

Subagents had no visibility into their own tool-iter budget. The parent's maxToolIters capped the loop from outside, but the child neither knew the cap nor its current iteration — so an explore run could burn all 20 iters mapping the territory, hit the cap mid-thought, and emit a partial summary the parent had to re-dispatch.

This PR closes the gap with prompt + telemetry:

  1. System-prompt budget linespawnSubagent appends a one-paragraph "Tool budget: you have N tool calls" notice with the resolved cap baked in, applied uniformly to default, typed (explore / verify), and caller-supplied system prompts.
  2. Run-time countdown via setResultAugmenter — a new final-stage post-hook on ToolRegistry.dispatch(). spawnSubagent installs one that counts dispatches and appends [budget: K of N tool calls left — wrap up soon] once the child is within 3 iters of the cap, escalating to [budget: 0 left — finalize NOW] on the last call.

Static prompt sets the expectation; dynamic countdown forces reckoning when the budget is actually tight.

Closes #488

Test plan

  • tests/subagent.test.ts — new case drives 5 tool calls under a maxToolIters: 5 budget and asserts the augmented tool-result content at each iteration (no warning on iter 1, then 3 / 2 / 1 / 0 left on iters 2–5).
  • Existing custom-system-prompt tests updated from .toBe to .toContain + a regex match for the budget line.
  • npm run verify (full suite, 2292 tests).

The child loop's tool-iter cap was enforced from the outside only;
the subagent's system prompt never said "you have N tool calls", and
the child had no way to know which iteration it was on. The visible
failure mode was an explore subagent burning all 20 iters mapping the
territory, then hitting the cap mid-thought and emitting a partial
summary the parent had to re-dispatch from.

Two pieces:

1. spawnSubagent now appends a one-paragraph budget notice to the
   child's system prompt — literal "Tool budget: you have N tool calls"
   with the resolved cap baked in. Applies to default, typed
   (explore/verify), and caller-supplied system prompts uniformly.

2. ToolRegistry gains setResultAugmenter(), a final-stage post-hook
   on dispatch. spawnSubagent installs one that counts dispatches and
   appends "[budget: K of N tool calls left — wrap up soon]" once the
   child is within 3 iters of the cap, escalating to "0 left —
   finalize NOW" on the last call.

Static prompt + dynamic countdown together: prompt sets expectation,
countdown forces reckoning when the budget is actually tight.

Closes #488
@esengine esengine merged commit c63239d into main May 9, 2026
3 checks passed
@esengine esengine deleted the feat/488-subagent-budget-telemetry branch May 9, 2026 04:50
@esengine esengine mentioned this pull request May 9, 2026
2 tasks
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…engine#493)

The child loop's tool-iter cap was enforced from the outside only;
the subagent's system prompt never said "you have N tool calls", and
the child had no way to know which iteration it was on. The visible
failure mode was an explore subagent burning all 20 iters mapping the
territory, then hitting the cap mid-thought and emitting a partial
summary the parent had to re-dispatch from.

Two pieces:

1. spawnSubagent now appends a one-paragraph budget notice to the
   child's system prompt — literal "Tool budget: you have N tool calls"
   with the resolved cap baked in. Applies to default, typed
   (explore/verify), and caller-supplied system prompts uniformly.

2. ToolRegistry gains setResultAugmenter(), a final-stage post-hook
   on dispatch. spawnSubagent installs one that counts dispatches and
   appends "[budget: K of N tool calls left — wrap up soon]" once the
   child is within 3 iters of the cap, escalating to "0 left —
   finalize NOW" on the last call.

Static prompt + dynamic countdown together: prompt sets expectation,
countdown forces reckoning when the budget is actually tight.

Closes esengine#488
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.

tools: subagent has no visibility into its own iter budget

1 participant