feat(ai): subagent tree limits; harness ctx.agents and harness children - #1520
AlemTuzlak wants to merge 5 commits into
Conversation
@tanstack/ai: subagents.limits (maxDepth, maxConcurrent, maxCalls,
timeoutMs) for the tree of children the model starts through tools. One
SubagentBudget per root run is shared by every child and passed on through
ctx.chat({ subagents }), so a child cannot reset it. A refused start reaches
the model as a tool error.
@tanstack/ai-harness: plugins get ctx.agents.run, start, and group (with
cancel-siblings or collect). harnessAgent(harness) turns a harness into a
child agent for subagents.agents, and defineHarness takes a description.
A harness applies default limits (depth 2, 3 at once, 12 per tree), and
agents started from code count against them.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository: TanStack/ai/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit c2e6fb3
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-byteplus
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-cloudflare
@tanstack/ai-code-mode
@tanstack/ai-code-mode-snippets
@tanstack/ai-codex
@tanstack/ai-cohere
@tanstack/ai-compaction
@tanstack/ai-devtools-core
@tanstack/ai-durable-stream
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-grok-build
@tanstack/ai-groq
@tanstack/ai-harness
@tanstack/ai-harness-cli
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-daytona
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-isolate-quickjs-bun
@tanstack/ai-llmgateway
@tanstack/ai-lovable
@tanstack/ai-mcp
@tanstack/ai-memory
@tanstack/ai-mistral
@tanstack/ai-octane
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@tanstack/ai-perplexity
@tanstack/ai-persistence
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-reactor
@tanstack/ai-remix
@tanstack/ai-sandbox
@tanstack/ai-sandbox-blaxel
@tanstack/ai-sandbox-boxd
@tanstack/ai-sandbox-cloudflare
@tanstack/ai-sandbox-daytona
@tanstack/ai-sandbox-docker
@tanstack/ai-sandbox-e2b
@tanstack/ai-sandbox-local-process
@tanstack/ai-sandbox-sprites
@tanstack/ai-sandbox-upstash-box
@tanstack/ai-sandbox-vercel
@tanstack/ai-skills
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-typesafe
@tanstack/ai-utils
@tanstack/ai-vercel-gateway
@tanstack/ai-vertex
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/ai-worldlabs
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
@tanstack/svelte-ai-devtools
commit: |
Subagent trees now have limits, and a harness can run agents from code and call other harnesses.
chat({ subagents: { limits } })caps depth, total calls, children at once, and time per child across the whole tree. Harness plugins getctx.agents.run / start / group, andharnessAgent(harness)makes a harness a child agent. This is Phase 4 of the harness stack.Stacked on #1519 (Phase 3) → #1518 → #1515 → #1513 → #1509. Merge those first.
🎯 Changes
subagents.limitsin@tanstack/ai(maxDepth,maxConcurrent,maxCalls,timeoutMs). OneSubagentBudgetper root run, shared by every child and passed on throughctx.chat({ subagents }). A refused start is a tool error likesubagent limit reached (maxCalls 12). No defaults in core, so current apps behave as before.ctx.agentsin harness plugins:run,start(wake), andgroup(onFailure: 'cancel-siblings' | 'collect', withgroup.runandgroup.runSettled). Every child settles beforegroupreturns.harnessAgent(harness)forsubagents.agents.defineHarnesstakesdescription.DEFAULT_SUBAGENT_LIMITS(depth 2, 3 at once, 12 per tree). Code-started agents count against the limits.docs/chat/subagents.md, newdocs/harness/subagents.md. Changeset: ai, harness (minor).✅ Checklist
pnpm run test:pr, or these tests do not apply to this pull request.docs/for this change, or this change is not user-facing.pnpm changeset), or this PR does not change a published package.🚀 Release Impact
Testing
Commands run (not the full
pnpm test:pr, see below):@tanstack/ai:vitest run(1923 passed, all files),tsc --noEmit,test:oxlint,build,test:build.@tanstack/ai-harness:vitest run(68 passed),tsc --noEmit,test:oxlint,build,test:build.@tanstack/ai-harness-cli(8 passed) and@tanstack/ai-acp(61 passed): tests, types, lint, build.testing/e2e:tsc --noEmit,playwright test tests/harness.spec.ts tests/harness-protocol.spec.ts tests/subagents.spec.ts(14 passed).pnpm test:docs,kiira checkon the changed pages,pnpm test:sherif,pnpm test:knip.pnpm test:prrun because it is slow on this machine. CI runs it.Manual test
pnpm --filter @tanstack/ai exec vitest run tests/subagent-limits.test.ts.pnpm --filter @tanstack/ai-e2e test:e2e -- tests/harness.spec.ts -g limits. The second child start is refused and the model answers with that.How this PR makes testing easy
packages/ai/tests/subagent-limits.test.ts: the budget math,maxCalls,maxDepththrough a nestedctx.chat,timeoutMs,maxConcurrent.packages/ai-harness/tests/subagents.test.ts: a harness as a child,ctx.agents.runandgroup(cancel and collect), default limits.limitsscenario intesting/e2e/tests/harness.spec.ts.Risk / rollback
Low. Core limits only apply when
subagents.limitsis set (all 1923 core tests pass unchanged). Harness sessions now apply default limits to their children. Revert the PR to undo.Public API change
Before
After
🤖 Generated with Claude Code
https://claude.ai/code/session_01APYv1qshKyjPPpkFyRZhfZ