mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-07-10 01:29:17 +00:00
* feat(core): allow bounded nested sub-agent spawning via maxSubagentDepth Sub-agents may now spawn sub-agents up to a configurable maximum nesting depth (default 5; 1 reproduces the previous no-nesting behavior). Enforced in two layers sharing one predicate: prepareTools() hides the agent tool from leaf-depth sub-agents, and AgentTool.execute() rejects over-depth spawns as an authoritative backstop. Teammates, forks, and the workflow tool remain excluded from nesting. Launch depth is persisted in the agent meta sidecar and restored on resume (including deferred-approval continuations and in-process AgentInteractive frames) so a resumed nested agent cannot regain spawn capacity. See knowledge/qwen-code/design/nested-subagents.md. * fix(core): address review findings on nested sub-agent spawning - Deny the agent tool to workflow-spawned subagents: depth gating would otherwise re-admit it, letting a workflow leaf spawn outside the orchestrator's concurrency cap, agent accounting, and token budget. - Reject non-finite maxSubagentDepth values (JSON 1e309 parses to Infinity and would unbound the recursion cap; NaN would silently block all nesting) and cap the knob at 100 to catch typos. - Add a --max-subagent-depth CLI flag mirroring sibling budget flags, with loud validation for flag typos, and document the setting. - Log guard rejections (depth, fork containment) and silent fork-to-subagent downgrades through the agent debug logger. - Refresh stale comments (depthOverride resume pinning, depth-gated AgentTool exclusion) and drop references to a design doc that lives outside the repository. - Fill review-noted test gaps: nesting predicate primitives, fork-context prepareTools, persisted-depth restoration on background resume, nested AgentInteractive depth pinning, nested fork fallback, and the blocked-spawn returnDisplay shape. * fix(cli): add maxSubagentDepth to the CliArgs test literal The exhaustive CliArgs mock in gemini.test.tsx missed the new field, failing CI's clean tsc build (the local incremental build skipped the test file). * fix(core): add a teammate backstop to the agent spawn guards execute() backstopped depth and fork containment but not the teammate exclusion, so its guards covered less than prepareTools() gates. A teammate spawn call that slipped past schema-hiding would have nested. Block it symmetrically with the fork guard, log the rejection, and pin the behavior in a test. * fix(core): normalize persisted maxSubagentDepth on resume The resume path trusted the raw sidecar value, bypassing the Config clamp — a tampered or malformed sidecar (1e309 parses to Infinity; JSON.stringify turns Infinity into null) would remove the nesting cap for resumed agents. Extract the clamp into a shared normalizeMaxSubagentDepth used by both the Config constructor and the flag-restore path, and refresh the stale settings schema description (clamp range, non-finite fallback, workflow-agent wording). * test(core): pin null-to-default normalization of resumed maxSubagentDepth JSON.stringify(Infinity) === 'null', so a sidecar can legitimately carry null; widen the persisted flag type to admit it and parameterize the resume test over both the clamp (5000 -> 100) and the null fallback (null -> 5). * fix(core): harden nesting depth edges from final review pass - Normalize persisted meta.depth on resume: the sidecar is untrusted JSON, and a tampered negative depth (or -1e309 → -Infinity) would pin the resumed frame below zero and pass canSpawnNestedAgent for every cap. Invalid values fail closed to the depth ceiling — the agent keeps running but cannot spawn. - Register monitor notification routing for in-process interactive agents: framing runLoop() made their monitors agent-owned, and owned dispatch has no session fallback, so notifications were silently dropped. InProcessBackend now routes them into the agent's message queue and tears the routing down on release. - Downgrade background spawn requests from nested launchers to awaited foreground runs: a nested launcher cannot honor the background completion contract (send_message/task_stop excluded, notifications session-scoped), which orphaned the child's results. - Extract spawnBlockReason() as the single spawn-exclusion policy shared by prepareTools() and execute(), replacing two hand-kept copies of the depth/teammate/fork rules. - Share DEFAULT_MAX_SUBAGENT_DEPTH / MAX_SUBAGENT_DEPTH_LIMIT across the core normalizer, the CLI flag validator, and the settings schema. - Log dropped teammate names from nested spawns; revert the impossible |null persisted-flag widening to an honest tampered-sidecar framing; document the constructor-time depth capture invariant. * test(cli): add DEFAULT_MAX_SUBAGENT_DEPTH to core package mocks settingsSchema.ts now imports the shared constant, so CLI tests that mock @qwen-code/qwen-code-core with an explicit export list need the new export. * feat(cli): display nested sub-agents as a tree in the TUI (#6191) * feat(core): allow bounded nested sub-agent spawning via maxSubagentDepth Sub-agents may now spawn sub-agents up to a configurable maximum nesting depth (default 5; 1 reproduces the previous no-nesting behavior). Enforced in two layers sharing one predicate: prepareTools() hides the agent tool from leaf-depth sub-agents, and AgentTool.execute() rejects over-depth spawns as an authoritative backstop. Teammates, forks, and the workflow tool remain excluded from nesting. Launch depth is persisted in the agent meta sidecar and restored on resume (including deferred-approval continuations and in-process AgentInteractive frames) so a resumed nested agent cannot regain spawn capacity. See knowledge/qwen-code/design/nested-subagents.md. * feat(cli): display nested sub-agents as a tree in the TUI Render nested agents depth-first with indent + dim '↳' in the live agent panel and background tasks view; promote orphaned children to root with a '· from <parent>' annotation. Detail view gains a level badge, Parent breadcrumb, and Sub-agents section. The [blocking] tag and two-step cancel confirm now apply only to provably user-blocking foreground chains. Parent completion summaries carry a '· N sub-agents' tail (guard-rejected spawns now record as failed tool calls so the count stays honest). Also fixes the live-panel Enter-for-detail order mismatch by sharing one display order between the panel render and the composer keyboard mapping. * fix(core): address round-1 review on nested sub-agent spawning - Derive launch metadata (hooks, spans, task rows, meta sidecar) from the resolved subagent config instead of the raw requested type, so a fork request that falls back to the awaitable path no longer reports "fork". - Pin the blocked-spawn failure contract in tests: error is set and returnDisplay.status is 'failed' for both the depth and fork guards; also document the failure-path routing at buildSpawnBlockedResult. - Drop source-comment references to private knowledge/ design docs that do not exist in this repository. * test: address round-2 review on sub-agent counting and fork fallback - Exercise the legacy 'task' alias in the scrollback sub-agent count so the migration-aware name set is covered, not just the canonical name. - Pin the nested-fork downgrade: a sub-agent requesting a fork falls back to the awaitable general-purpose subagent even in interactive mode. - Drop a duplicated 'nesting depth guard' describe block left behind by the automated base-branch merge (kept the copy with the failure-shape assertions). * fix(core): keep actionable guidance in blocked-spawn error messages The scheduler's failure path sends only error.message to the model and the scrollback, discarding llmContent. With the terse terminateReason as the message, a blocked spawn lost its "do the task yourself instead" instruction, inviting retry loops. Carry the full guidance text in error.message and keep terminateReason for the display card. * test(cli): pin the tree indent clamp at depth beyond TREE_INDENT_MAX_LEVELS Maintainer mutation-testing on the PR found that removing the clamp in treeRowPrefix survived the suite. Assert a depth-4 row indents 3 levels (12 spaces), plus the base marker/indent behavior. --------- Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> --------- Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| configuration | ||
| extension | ||
| features | ||
| ide-integration | ||
| reference | ||
| support | ||
| _meta.ts | ||
| common-workflow.md | ||
| integration-github-action.md | ||
| integration-jetbrains.md | ||
| integration-vscode.md | ||
| integration-zed.md | ||
| overview.md | ||
| quickstart.md | ||
| qwen-serve-deploy-local.md | ||
| qwen-serve.md | ||