🤖 feat: improve plan tool to scale with complexity - #32
Merged
Merged
Conversation
Update plan tool description to encourage proportional planning: - Plans should always be used (mandatory in plan mode) - Plans should be 'complete but minimal' - Detail level scales with task complexity - Removes prescriptive requirements (alternatives, testing strategy, etc.) Changes: - Tool description: 'Propose a plan before taking action' (imperative) - Plan parameter: Provides scaling guidance for simple vs complex tasks - Emphasizes 'cover what's necessary, omit obvious details' This allows agents to produce concise plans for simple tasks while still providing detailed plans for complex work, improving review speed and reducing token usage without sacrificing completeness.
ammario
pushed a commit
that referenced
this pull request
May 28, 2026
## Summary `task_await` now accepts an optional `min_completed` integer (default **1**). It returns as soon as that many awaited tasks have completed — by default the **first** completion — instead of always blocking until every awaited task finishes. The parent can act on each result as it lands (e.g. integrate variant lane #45 while #32/#69 keep running) and re-await the remainder, rather than idling until the whole batch is done. ## Background When the parent spawns a grouped batch (`task` with `n` for best-of-N or `variants`), there was often useful dependent work available after just **one** child completed — most obviously for `variants`, where each lane is independent. But both the foreground `task` path and `task_await` used `Promise.all` and only returned once the **slowest** task settled, and the tool/prelude guidance framed the flow as "launch → await as a batch → synthesize all." Nothing let the parent begin work after the first child. ## Implementation - **Schema** (`toolDefinitions.ts`): new `min_completed: z.number().int().min(1).nullish()` on `TaskAwaitToolArgsSchema`; absent/`null` ⇒ `1`. - **Handler** (`task_await.ts`): the per-task await body is now `awaitOne(taskId, taskSignal)`. Each task gets its own `AbortController` chained to the tool-call signal. A small coordinator resolves once `min_completed` tasks have completed **or** every task has otherwise settled (so an unreachable threshold still returns promptly). Still-pending "losers" are then **aborted to detach their waiters** — which only removes the in-memory waiter / interrupts a bash poll; the child keeps running and its report stays cached and re-awaitable on a later call. Losers are reported with a live `running`/`queued` status snapshot rather than an error (a real tool-call interrupt is still distinguished and surfaced as `error: "Interrupted"`). - `timeout_secs: 0` stays a non-blocking snapshot of every task regardless of `min_completed`. - **Clamped** to the number of awaited tasks (over-large values behave like "wait for all"). - **Guidance**: `task`/`task_await` descriptions and the `<best-of-n>` / `<task-variants>` prelude blocks now steer independent lanes toward the first-completion loop, and tell best-of-N synthesis (which must compare every candidate) to pass `min_completed` equal to the batch size or use a foreground grouped spawn. Auto-generated docs (`system-prompt.mdx`, `hooks/tools.mdx`) and the built-in skill snapshot were regenerated via `make fmt`. The foreground `task` (`run_in_background: false`) path is intentionally **unchanged** — grouped spawns still return all reports, which remains the natural "give me every candidate" path. ## Validation - New `task_await` tests: default returns after first (rest `running`); `min_completed = total` waits for all; `min_completed = k` returns after the k-th; clamp; re-awaitable loser resolves on a follow-up call; unreachable threshold returns promptly; `timeout_secs:0` non-blocking with `min_completed`. The first-completion test also asserts the loser's per-task signal is aborted while the winner's is not. - `make static-check` passes (typecheck, eslint, formatting, docs-sync). ## Risks `min_completed` defaults to `1`, so this is a **behavior change** for `task_await`: an existing background-spawn-then-await flow that expected all reports now returns after the first completion. Mitigations: the all-settled fallback + clamp keep results well-formed, losers remain re-awaitable (no work lost, children not terminated), and guidance steers aggregation flows to pass the batch size. Affected area is limited to sub-agent orchestration. --- _Generated with `mux` • Model: `anthropic:claude-opus-4-8` • Thinking: `xhigh` • Cost: `$5.76`_ <!-- mux-attribution: model=anthropic:claude-opus-4-8 thinking=xhigh costs=5.76 -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Updates the plan tool description to encourage proportional planning that scales with task complexity, making plans more concise for simple tasks while still allowing detailed plans for complex work.
Problem
The current plan tool description prescribes a fixed, comprehensive structure regardless of task complexity:
Changes
Tool Description (before):
Tool Description (after):
Plan Parameter Description (before):
Plan Parameter Description (after):
Key Improvements
Expected Behavior
Simple task: "Add parameter X"
→ Brief plan (what/why/how)
Complex task: "Redesign auth system"
→ Detailed plan (architecture, phases, risks)
Uncertain task: "Not sure which approach"
→ Decision-focused plan (options with pros/cons)
Benefits
Generated with
cmux