Uh oh!
There was an error while loading. Please reload this page.
feat(ai): rework tool-call budgets as middleware hooks - #972
Conversation
🚀 Changeset Version Preview16 package(s) bumped directly, 34 bumped as dependents. 🟥 Major bumps
🟨 Minor bumps
🟩 Patch bumps
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
💤 Files with no reviewable changes (4)
🚧 Files skipped from review as they are similar to previous changes (8)
📝 WalkthroughWalkthroughThe chat engine removes built-in tool-call budgets and adds middleware-driven continuation control. Tool-call accounting remains available through ChangesTool-call budgeting middleware
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant TextEngine
participant AgentLoopStrategy
participant MiddlewareRunner
participant ToolExecution
TextEngine->>ToolExecution: record deduplicated tool calls
TextEngine->>AgentLoopStrategy: evaluate loop state
TextEngine->>MiddlewareRunner: runOnShouldContinue(ctx, state)
MiddlewareRunner-->>TextEngine: continue or stop
TextEngine->>ToolExecution: execute executable tool calls
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 0c52b42
☁️ Nx Cloud last updated this comment at |
@tanstack/ai@tanstack/ai-acp@tanstack/ai-angular@tanstack/ai-anthropic@tanstack/ai-bedrock@tanstack/ai-claude-code@tanstack/ai-client@tanstack/ai-code-mode@tanstack/ai-code-mode-skills@tanstack/ai-codex@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-node@tanstack/ai-isolate-quickjs@tanstack/ai-mcp@tanstack/ai-memory@tanstack/ai-mistral@tanstack/ai-ollama@tanstack/ai-openai@tanstack/ai-opencode@tanstack/ai-openrouter@tanstack/ai-persistence@tanstack/ai-preact@tanstack/ai-react@tanstack/ai-react-ui@tanstack/ai-sandbox@tanstack/ai-sandbox-cloudflare@tanstack/ai-sandbox-daytona@tanstack/ai-sandbox-docker@tanstack/ai-sandbox-local-process@tanstack/ai-sandbox-sprites@tanstack/ai-sandbox-vercel@tanstack/ai-solid@tanstack/ai-solid-ui@tanstack/ai-svelte@tanstack/ai-utils@tanstack/ai-vue@tanstack/ai-vue-ui@tanstack/openai-base@tanstack/preact-ai-devtools@tanstack/react-ai-devtools@tanstack/solid-ai-devtoolscommit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
testing/e2e/src/routes/api.max-tool-calls-wire.ts (1)
8-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMove type-only import to the existing
import typeblock.To resolve the static analysis linting warning and maintain a consistent top-level type import style, consider moving
ChatMiddlewareto the existing type-only import statement.♻️ Proposed refactor
- type ChatMiddleware, } from '`@tanstack/ai`' import { z } from 'zod' -import type { AnyTextAdapter, StreamChunk } from '`@tanstack/ai`'+import type { AnyTextAdapter, ChatMiddleware, StreamChunk } from '`@tanstack/ai`'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@testing/e2e/src/routes/api.max-tool-calls-wire.ts` around lines 8 - 11, Move ChatMiddleware from the regular `@tanstack/ai` import into the existing import type declaration alongside AnyTextAdapter and StreamChunk, leaving the runtime zod import unchanged.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ai/src/activities/chat/index.ts`:
- Around line 1964-1994: Update shouldContinue so loopStrategy(state) and
middlewareRunner.runOnShouldContinue(this.middlewareCtx, state) are both
evaluated on every non-executeToolCalls check, including when the strategy
returns false. Combine their boolean results afterward with the existing
toolPhase === 'continue' condition, preserving the executeToolCalls early
return.
---
Nitpick comments:
In `@testing/e2e/src/routes/api.max-tool-calls-wire.ts`:
- Around line 8-11: Move ChatMiddleware from the regular `@tanstack/ai` import
into the existing import type declaration alongside AnyTextAdapter and
StreamChunk, leaving the runtime zod import unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4df1b917-28b5-4bea-9899-f4105b50345f
📒 Files selected for processing (24)
.changeset/max-tool-calls-middleware.mddocs/advanced/built-in-middleware.mddocs/advanced/middleware.mddocs/api/ai.mddocs/chat/agentic-cycle.mddocs/config.jsondocs/reference/functions/combineStrategies.mddocs/reference/functions/maxIterations.mddocs/reference/functions/maxToolCalls.mddocs/reference/index.mddocs/reference/interfaces/AgentLoopState.mddocs/reference/interfaces/TextOptions.mdpackages/ai/skills/ai-core/middleware/SKILL.mdpackages/ai/skills/ai-core/tool-calling/SKILL.mdpackages/ai/src/activities/chat/agent-loop-strategies.tspackages/ai/src/activities/chat/index.tspackages/ai/src/activities/chat/middleware/compose.tspackages/ai/src/activities/chat/middleware/types.tspackages/ai/src/index.tspackages/ai/src/types.tspackages/ai/tests/agent-loop-strategies.test.tspackages/ai/tests/chat.test.tstesting/e2e/src/routes/api.max-tool-calls-wire.tstesting/e2e/tests/max-tool-calls.spec.ts
💤 Files with no reviewable changes (6)
- docs/reference/functions/maxToolCalls.md
- docs/reference/interfaces/TextOptions.md
- docs/reference/index.md
- docs/reference/functions/combineStrategies.md
- packages/ai/tests/agent-loop-strategies.test.ts
- packages/ai/src/index.ts
Uh oh!
There was an error while loading. Please reload this page.
abf5532 to
18f47a4CompareReplace the unreleased maxToolCalls strategy and chat({ maxToolCallsPerTurn })
with an onShouldContinue middleware hook so apps can stop further agent turns
without aborting. Keep toolCallCount / lastTurnToolCallCount on AgentLoopState
for strategies and middleware. Document an app-owned tool-budget recipe
instead of shipping a built-in maxToolCallsMiddleware.Evaluate agentLoopStrategy and middleware onShouldContinue together so middleware still observes the final state when the strategy is what stops the loop. Also use a type-only import for ChatMiddleware in the E2E wire route.
18f47a4 to
0c52b42CompareUh oh!
There was an error while loading. Please reload this page.
Summary
maxToolCalls()strategy andchat({ maxToolCallsPerTurn })onShouldContinuemiddleware hook so policies can stop further agent-loop turns without hard-abortingAgentLoopState.toolCallCount/lastTurnToolCallCountfor custom strategies and middlewareonBeforeToolCallskip +onShouldContinue) in agentic-cycle docs — not a built-in library exportThis addresses maintainer feedback that tool-call budgeting belongs in middleware extensibility rather than first-class loop strategy + chat options (unreleased, so safe to rework).
Test plan
testing/e2e/tests/max-tool-calls.spec.ts(updated to inline budget middleware)docs/chat/agentic-cycle.md§ Tool-call budgetsSummary by CodeRabbit
onShouldContinuechat middleware hook to control whether the agent starts another model turn (supports async; middleware uses AND-style stopping on explicitfalse).maxToolCallsagent-loop strategy.maxToolCallsPerTurnchat option.