Repository navigation
feat(runtime)!: run BuiltInAgent on TanStack AI chat() with options typed by the model adapter - #8224
Open
AlemTuzlak wants to merge 36 commits into
Open
AlemTuzlak wants to merge 36 commits into
AlemTuzlak wants to merge 36 commits into
Conversation
@tanstack/ai 1.2.0 and the openai, anthropic, gemini, vertex and mcp adapters are dev dependencies and optional peers of the runtime. The BuiltInAgent will load them lazily, so apps that never use it do not install them. The lockfile was resolved with @tanstack/* exempt from the 24h minimum-release-age rule for this one install (1.2.0 shipped today); every other package still had to pass it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…i peer isDedicatedEntry matches a path segment against the peer's last name segment, which cannot tell "ai" from "@tanstack/ai". A small alias table keyed by the full package name maps ai to the ai-sdk segment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
loadOptionalPeer imports a package at call time and, when it is not installed, throws an error that names the package and the install command. Other errors pass through unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Agent An optional second argument adds a leading prompt, opt-out of forwarded system and developer messages, resume answers for interrupt tool calls, and tool results that keep inline media. With no options the output is unchanged, so the tanstack factory behaves as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The v2-migration codemod moves agent exports from the runtime root and /v2 to @copilotkit/runtime/agent, and the AI SDK helpers to @copilotkit/runtime/agent/ai-sdk. It adds TODOs for the removed sampling options, providerOptions, maxRetries, urlDownload, AI SDK models passed as model, and resolveModel calls that are not awaited. The bundled skill lists the TanStack packages to install. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ools BuiltInAgentLearnedSkills.tools is a read-only array of TanStack AI server tools, built as plain objects so no @tanstack/ai import runs. mergeMCPTools and assertNoSkillToolConflicts work on tool arrays and match by name, with the same prefixing and collision rules. BREAKING CHANGE: ctx.learnedSkills.tools is a TanStack AI tool array, not an AI SDK ToolSet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
resolveModel is async and loads the adapter package for the provider only when a model string needs it: @tanstack/ai-openai (Responses or Chat Completions by the same host rule), -anthropic, -gemini, -vertex, and the OpenAI-compatible adapter for MiniMax. An AI SDK model object throws an error that points to the aisdk factory. BREAKING CHANGE: resolveModel returns a Promise of a TanStack AI text adapter. ANTHROPIC_BASE_URL loses a trailing /v1, MiniMax uses Chat Completions and no longer falls back to OPENAI_API_KEY, and a missing API key throws when the model is resolved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The message and tool converters, createSafeUrlDownload, and a new toAISDKTools (TanStack AI tools, such as ctx.learnedSkills.tools, to an AI SDK ToolSet) live in src/agent/ai-sdk. It is the only agent module that imports ai, so only apps that use AI SDK load it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Classic mode resolves the model to a TanStack AI adapter, loads @tanstack/ai (and @tanstack/ai-mcp for mcpServers) only when a run starts, and streams chat() through convertTanStackStream. Server tools, interrupt tools, state tools, frontend tools, learned skills, MCP tools, overrides, abort, errors and usage keep their behavior. The AI SDK helpers and the URL download guard now live only in agent/ai-sdk. BREAKING CHANGE: model takes a model string or a TanStack AI adapter; an AI SDK model throws at construction (use a type: "aisdk" factory). maxOutputTokens, temperature, topP, topK, presencePenalty, frequencyPenalty, stopSequences, seed, maxRetries, providerOptions and urlDownload are removed; pass provider-native options in modelOptions. OverridableProperty is model, toolChoice, prompt or modelOptions. MCPClientProvider.tools() returns TanStack AI tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eaches validate-dts-imports flagged every optional peer named in a published declaration. A subpath export such as ./agent exists for the peers it names, so a consumer who imports it installs them. The check now walks the root export's declaration graph and keeps flagging optional peers there; files outside it may name them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The agent ships from two new entries: @copilotkit/runtime/agent and @copilotkit/runtime/agent/ai-sdk. The root entry no longer re-exports the agent, so apps that run other agents load no LLM SDK. ai and every @ai-sdk/* package leave dependencies; ai is an optional peer for the ai-sdk entry. The MCPClient and MCPTransport types now come from @tanstack/ai-mcp through /agent. BREAKING CHANGE: import BuiltInAgent and the other agent exports from @copilotkit/runtime/agent, and the AI SDK helpers from @copilotkit/runtime/agent/ai-sdk. Install @tanstack/ai and the adapter for your provider, or ai for AI SDK factories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The runtime root no longer reaches @ai-sdk/google-vertex, so the edge smoke stops stubbing it. The README notes that BuiltInAgent on Workers needs a factory or a TanStack AI adapter instance, because model strings load their adapter with a runtime import(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ack AI Classic cases drive a real chat() with the fake TanStack model; aisdk factory cases keep a real streamText and import helpers from agent/ai-sdk. Two test.fails pin gaps with @tanstack/ai 1.2.0: the RUN_FINISHED finish reason and model now sit under metadata.tanstack, and needsApproval tools pause through RUN_FINISHED.outcome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mcpServers run against real Streamable HTTP and SSE servers, and mcpClients use a real @tanstack/ai-mcp client. Clients are checked closed after success, error and abort from the server side. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
State tools, overrides, config tools, Zod/Valibot/ArkType schemas, nullable and A2UI schemas, tool errors and id handling now drive a real chat() with the fake TanStack model. Assertions about removed sampling options and AI SDK internals are replaced or dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every shell-docs sample that imports an agent export now uses the /agent entry, and BuiltInAgent install commands add @tanstack/ai with the OpenAI adapter. Prose that named AI SDK models or removed options now names TanStack AI adapters and modelOptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tanstack/ai 1.2.0 moves the model, finish reason and provider under RUN_FINISHED.metadata.tanstack, and reports needsApproval pauses only in RUN_FINISHED.outcome. convertTanStackStream now reads both, keeps the older top-level fields and CUSTOM approval chunk as fallbacks, and no longer forwards the internal tanstack metadata to AG-UI clients. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
verify-runtime-package installs the packed runtime in a consumer with no LLM package and checks that the root, /agent and /agent/ai-sdk load and that a model string asks for its adapter package. A second consumer installs @tanstack/ai with the OpenAI adapter and checks that /agent loads them at run time. The intelligence smoke builds its BuiltInAgent from /agent with a TanStack AI OpenAI adapter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Built-in Agent pages cover the /agent import, the TanStack AI packages to install for each provider, adapter instances, modelOptions, MCP with @tanstack/ai-mcp, and AI SDK through an aisdk factory with the /agent/ai-sdk helpers. The runtime 2.0 migration page gets a Built-in Agent section that the codemod's TODOs link to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…emas convertTanStackStream gave every text segment of a run one message id, so text after a tool call landed in the message before it. Each TEXT_MESSAGE_START now opens a message with a fresh id, and a tool call names the message before it as parent. The classic agent again rejects a frontend tool whose parameters are not a JSON Schema before calling the model, with the same RUN_ERROR as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its inferred return type named a private @ag-ui/core chunk (TS2742). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workspace examples move their agent imports to the /agent entry and add @tanstack/ai with the adapters they use. The demos that set providerOptions or maxOutputTokens now pass modelOptions, OpenRouter runs through the OpenAI-compatible TanStack adapter, and genui-eval runs its AI SDK models in an aisdk factory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model strings loaded adapter packages with a runtime import() that
bundlers, output tracing and Cloudflare Workers cannot follow. The
classic model is now an AnyTextAdapter instance, and /agent imports
@tanstack/ai statically.
BREAKING CHANGE: `model` no longer accepts strings such as
"openai/gpt-5"; pass `openaiText("gpt-5")` from @tanstack/ai-openai (or
another TanStack AI text adapter). The `apiKey` option is removed (the
adapter carries its own config). `mcpServers` and the MCP type
re-exports are removed; create clients with `createMCPClient` from
@tanstack/ai-mcp and pass them in `mcpClients`. The exported
`resolveModel`, `classifyModelSpec`, `BuiltInAgentModel` and
`ModelSpecifier` are removed. A forwarded model override now goes to
the new `resolveModel` config callback; without one the configured
adapter is kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pters
`model: "openai/gpt-5"` becomes `openaiText("gpt-5")` with its import
(anthropic, google/gemini and vertex likewise). Other models, apiKey,
mcpServers and imports of the removed resolveModel, classifyModelSpec,
BuiltInAgentModel, ModelSpecifier and MCP types get a TODO.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ads from CJS @tanstack/ai is ESM-only, so the CommonJS build of /agent could not require() it at module scope. The classic run now loads it with a literal import(), which works from both builds and stays traceable for bundlers. /agent therefore also loads without @tanstack/ai installed (factory-only apps). The TanStack adapter packages and @tanstack/ai-mcp are no longer peers: the app imports its adapter itself. Unused @ai-sdk/* devDependencies are dropped. The optional-peer validator treats ./agent as the entry for @tanstack/ai, and verify-runtime-package runs a classic agent through ESM and CJS. BREAKING CHANGE: @tanstack/ai-openai, -anthropic, -gemini, -vertex and @tanstack/ai-mcp are no longer declared peers of @copilotkit/runtime; install the adapter you pass as `model`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Samples pass an adapter instance (openaiText, anthropicText, geminiText, openaiCompatibleText) as `model` and use `mcpClients` for MCP. validate-doc-model-names now checks the model id in adapter calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model selection, configuration, quickstart and MCP pages pass a TanStack AI adapter as `model`, configure the provider on the adapter, show the `resolveModel` callback for frontend model switching, and connect MCP servers with createMCPClient + mcpClients. The runtime 2.0 migration guide covers what the codemod rewrites and what is left by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workspace examples build their model with openaiText / anthropicText / geminiText (createOpenaiChat on Workers, where the key comes from env). The express, hono and node-express servers become ES modules because the TanStack AI packages are ESM-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- slack and teams templates import BuiltInAgent from /agent; teams passes an openaiText adapter and lists the TanStack AI packages - compatibility-monitor builds its native consumer from /agent and /agent/ai-sdk and installs @tanstack/ai - docs snippet typecheck (kiira) resolves /agent, /agent/ai-sdk and the TanStack AI adapter, MCP and AI SDK provider packages; the 1.x "before" samples in the migration guide are not typechecked - showcase built-in-agent: factory setup page uses /agent and /agent/ai-sdk; agent-config route pins a shipped model - runtime drops the unused anthropic, gemini and vertex adapter devDependencies Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tanstack/ai ^1.2.0, ai-mcp ^1.1.0 and ai-openai ^1.1.1, matching the runtime's optional peer. chat() in 1.x needs the thread id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uiltin-ts The classic BuiltInAgent runs on TanStack AI, so a builtin-ts request now supplies exact ai, @tanstack/ai and zod versions, and the dispatcher records @tanstack/ai from the lockfile. The version probe finds ESM-only packages on disk, since require.resolve cannot see them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed by the model adapter
The classic BuiltInAgent config now takes the chat() options (modelOptions,
reasoning, systemPrompts, promptCache, retry, middleware, context,
agentLoopStrategy, repairToolInput, and more), typed by the adapter passed as
`model`. defineTool returns a TanStack ServerTool, so it mixes with provider
tools. MCP moves to a native `mcp` option (keep-alive by default) and
`mcpClients` is removed. resolveModel can return an adapter or
{ adapter, modelOptions, reasoning }.
The v2 codemod rewrites maxRetries to retry: { maxRetries } and points its MCP
note at `mcp`. The built-in agent docs and the migration guide cover the new
options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the default maxSteps of 1, the run stops after the model calls an MCP tool, so the model never answers with the result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-default Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The AG-UI state tools return Promise.resolve() instead of using an async function with no await. The other hits in the agent files come from rules that need strictNullChecks, which the runtime package does not enable, or from guarded casts, so they go in the baseline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review: 1
Please check the settings in the CodeRabbit UI or the
|
Contributor
Production Digest-Pinning AuditAll 43 services digest-pinned. Run 2026-11-05 10:33:24 PST — 0 finding(s). |
@copilotkit/a2ui-renderer
@copilotkit/agentcore-runner
@copilotkit/angular
@copilotkit/channels
@copilotkit/channels-core
@copilotkit/channels-discord
@copilotkit/channels-intelligence
@copilotkit/channels-slack
@copilotkit/channels-teams
@copilotkit/channels-ui
@copilotkit/channels-whatsapp
@copilotkit/core
@copilotkit/intelligence-langgraph
@copilotkit/intelligence-mastra
@copilotkit/learning
@copilotkit/markdown
@copilotkit/mcp-apps-renderer
@copilotkit/react-core
@copilotkit/react-native
@copilotkit/runtime
@copilotkit/sdk-js
@copilotkit/shared
@copilotkit/sqlite-runner
@copilotkit/voice
@copilotkit/vue
@copilotkit/web-components
@copilotkit/web-inspector
commit: |
Contributor
|
Size Change: 0 B Total Size: 2.42 MB ℹ️ View Unchanged
|
This branch has not been deployed
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.
BuiltInAgentnow runs on TanStack AIchat(). You pass a TanStack AI adapter asmodel, and the agent takes thechat()options, typed for that adapter. A wrong provider option, a reasoning level that the model does not have, or a provider tool that the model does not support is a compile error. The agent moves to@copilotkit/runtime/agent, and the codemod and the migration guide cover the move.What does this PR do?
For a user of the classic
BuiltInAgent:model: openaiText("gpt-5.2")(oranthropicText,geminiText, and more). The adapter holds the API key and the base URL.chat()options.modelOptions,reasoning,systemPrompts,promptCache,retry,middleware,context,agentLoopStrategy,repairToolInput, and more. The agent sets the keys that it owns (messages,threadId,stream,outputSchema), so the types reject them, and only an allowlist of options goes tochat()at run time.defineToolkeeps its arguments and returns a TanStack AI server tool.toolsalso takes TanStack AI tools and provider tools (for examplewebSearchTool).mcp: { clients, lazyTools, onDiscoveryError, connection }replacesmcpServers. Clients stay open between runs by default.resolveModel(name)returns an adapter, orcreateChatOptions({ adapter, modelOptions, reasoning }).Other parts:
type: "aisdk"factory. The helpers (convertMessagesToVercelAISDKMessages,toAISDKTools, and more) import from@copilotkit/runtime/agent/ai-sdk.@tanstack/aiandaiare optional peers./agentloads from ESM and CJS.v2-migrationcodemod moves the imports, changes model strings to adapters, changesmaxRetriestoretry: { maxRetries }, and adds a TODO for each decision that it cannot make.migrate/runtime-2.0.mdxhas a Built-in Agent section.BREAKING CHANGE:
BuiltInAgent,defineTool, and the other agent exports import from@copilotkit/runtime/agent.modeltakes a TanStack AI text adapter, not a string.apiKey, the sampling options,providerOptions,mcpServers, andmaxRetriesare removed: use the adapter,modelOptions,reasoning,mcp, andretry. To migrate, runnpx codemod @copilotkit/v2-migration, then do the steps in the Built-in Agent section ofmigrate/runtime-2.0.mdx.Related PRs and Issues
Checklist
!(for examplefeat(react-core)!: ...) and the description has aBREAKING CHANGE:line with migration steps. See VERSIONING.mdTesting
Commands run (all pass, on the branch after the merge of
origin/2.0.0):pnpm nx run-many -t test check-types build --projects=@copilotkit/runtime: 183 test files pass.pnpm nx run-many -t check-dts publint attw --projects=@copilotkit/runtime, andpnpm run verify:runtime-package: the packed runtime loads from ESM and CJS, with and without@tanstack/ai.pnpm run lint: the gate passes.pnpm nx run repo-scripts:check-docs-snippets: 1654 snippets pass.v2-migrationcodemod tests, the compatibility monitor (29 of 29), and the Workers and Vercel Edge smoke test.Skipped:
nx affectedhas 13 local failures. Each one needs a toolchain that this machine does not have (dotnet, go, ruby, Python), or also fails onorigin/2.0.0(showcase-angular-host,react-native-demo).Manual test (React demo, with
OPENAI_API_KEY):pnpm devinexamples/dev/by-frontend/react/demo, then openhttp://localhost:3000.reasoning: { level: "high", summary: true }.overridableProperties: ["model"]and aresolveModelto the agent insrc/app/api/copilotkit/[[...slug]]/route.ts. Passproperties={{ model }}toCopilotKitProvider. Each run then uses the model thatresolveModelreturns.createMCPClientfrom@tanstack/ai-mcp. Passmcp: { clients: [client] }andmaxSteps: 3. The model calls the MCP tool and answers with the result.I did steps 3 and 4 with temporary edits and a local MCP server, and then I removed the edits.
How this PR makes testing easy:
chat-options.test.tsuses the realchat()on a fake model.mcp-clients.test.tsuses a real@tanstack/ai-mcpclient.chat-options-types.test.tsandtype-fixtures/agent/consumer.tshold the compile errors for wrong provider options, wrong reasoning levels, unsupported provider tools, and agent-owned keys.codemods/v2-migration/tests/ts/built-in-agent-adapters.reasoning.Risk / rollback
BuiltInAgentmust migrate. The codemod does most of the move, and the guide covers the rest.type: "aisdk"factory, the tool JSON Schema is always sent. Tool argument errors now read "Invalid arguments for tool X".maxStepsis 1 by default. If the model must answer after a tool call, setmaxStepsto 2 or more. The MCP and server-tool docs show this.Rollback: revert the merge of this PR on
2.0.0.Public API change
Before
After
🤖 Generated with Claude Code