Repository navigation
feat(ai): subagent limits, ctx.keys, ctx.step, and ctx.agents - #1727
AlemTuzlak wants to merge 2 commits into
Conversation
subagents.limits caps depth, calls, concurrency, and time across the whole subagent tree with one shared SubagentBudget. Agents get ctx.keys (ProviderKeys) from the binding or the provider env names, plus ctx.step and ctx.agents that a host can bind.
🦋 Changeset detectedLatest commit: 43be520 The changes in this PR will be included in the next version bump. This PR includes changesets to release 51 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
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 configuration
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 43be520
☁️ 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-isolate-cloudflare
@tanstack/ai-isolate-daytona
@tanstack/ai-isolate-e2b
@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-ollaya
@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-railway
@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: |
Coverage✅ Coverage held across 66 compared package(s). Each package is measured twice in this job — on this PR and on its merge-base with
|
chat({ subagents: { limits } })now caps the whole subagent tree: depth, total calls, children at once, and time per child. Agent code also getsctx.keysto build akeyedAdapterwith a provider key, plusctx.stepandctx.agents, which a host can bind.This piece is split out of #1555. It is a prerequisite for the harness work there. It stacks on #1723 (
feat/agent-run-context).🎯 Changes
subagents.limits(SubagentLimits,SubagentBudget):maxDepth,maxConcurrent,maxCalls,timeoutMs. One budget per root chat, shared by every child throughctx.chat({ subagents }). A refused start, a timeout, or a parent with no time left reaches the model as a tool error (subagent limit reached (maxCalls 12),subagent timed out after 20 ms). A router-picked child does not count, but its own children do, one level deeper. Only the root chat'slimitsapply.ctx.keys(ProviderKeys:get,require,adapter). FromSubagentBinding.keys, else each provider'senvnames (envKey, whichgetByokKeynow uses too). A missing key throwsByokMissingErrorwith a message that names the env var. Nested children get the host keys unless the nested call sets its own.ctx.step.do(name, fn)(AgentStep): runsfneach time without a host. A host setsSubagentBinding.stepto keep step values.ctx.agents.start()(AgentStarter,AgentRunHandle): throws without a host. A host setsSubagentBinding.agents.createSyntheticSubagentToolsis now onerunChildfunction, which the budget wraps.Docs:
chat/subagents.md(Limit the tree, Run context for hosts),advanced/byok.md(Keys inside agents).✅ 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. After merging the
SubagentForwardfix from #1723, these passed locally:nx run-many -t test:types,test:lib,test:oxlint -p @tanstack/ai @tanstack/ai-persistence,pnpm --filter @tanstack/ai-react-native-smoke typecheck, andnx run @tanstack/ai-e2e:test:types. CI is green.Manual test.
pnpm --filter @tanstack/ai-e2e test:e2e --grep "subagents".subagents.limits refuses a call past maxCalls with a tool errorpasses. The parent model callsresearchertwice withmaxCalls: 1. One card finishes, and the second tool result issubagent limit reached (maxCalls 1).How this PR makes testing easy.
packages/ai/tests/subagent-limits.test.ts,agent-step.test.ts,agent-start.test.ts, and actx.keysblock inprovider-keys.test.ts.limitsscenario intesting/e2e/tests/subagents.spec.ts.ctx.stepandctx.agentsonly change behavior with a host, so unit tests cover them.Risk / rollback
Low. Every option is opt-in. Without
limits, the budget has no caps.getByokKeyreads env names through the newenvKey, with the same result whereprocessexists. Revert the PR to undo.Public API change
Before
After
🤖 Generated with Claude Code