Repository navigation
feat(ai-ui-message-stream): client tools, structured output and reconnect for AI SDK routes - #1891
Conversation
…nect for AI SDK routes TanStack useChat gets more from an AI SDK route: - fromChatTransport sends the client's tool declarations in the request body. clientToolsFromAISDKBody(body, serverTools) turns them into AI SDK tools without execute on the route, so client and WebMCP tools need no copy there. Server tools win a name clash. - With outputSchema, an Output.object answer becomes a typed structured-output part with partial objects and a checked final value. - A dropped stream reconnects with createReconnectTracker, the backoff of the TanStack HTTP connections, set with the reconnect option. @tanstack/ai-client now exports createReconnectTracker. Tests prove client persistence, the message queue, devtools and loading saved AI SDK chats over the bridge.
🦋 Changeset detectedLatest commit: a576436 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 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 Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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 a576436
☁️ Nx Cloud last updated this comment at |
Coverage✅ Coverage held across 10 compared package(s). Each package is measured twice in this job — on this PR and on its merge-base with
|
@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-computer-local
@tanstack/ai-computer-playwright
@tanstack/ai-computer-sandbox
@tanstack/ai-computer-use
@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-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-neon
@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-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-svelte
@tanstack/ai-typesafe
@tanstack/ai-ui-message-stream
@tanstack/ai-utils
@tanstack/ai-vercel-gateway
@tanstack/ai-vertex
@tanstack/ai-vue
@tanstack/ai-worldlabs
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
@tanstack/svelte-ai-devtools
commit: |
TanStack
useChatnow gets more from an AI SDK route than the AI SDK's own client: client tools that the route reads from the request, typed structured output, and reconnect backoff. Stacked on #1888.🎯 Changes
fromChatTransportsends the client's tool declarations in the request body asclientTools. On the AI SDK route,clientToolsFromAISDKBody(body, serverTools)turns them into AI SDK tools withoutexecute, sostreamTextstops at the call and the client runs it.clientToolsthrows.outputSchemaonfromChatTransport(the same schema asuseChat({ outputSchema })), anOutput.objectanswer becomes astructured-outputpart, with partial objects while it streams and a checked final value. A schema failure ends the run withRUN_ERROR.createReconnectTracker, the backoff and limits of the TanStack HTTP connections, set with the newreconnectoption.@tanstack/ai-clientexportscreateReconnectTrackerandReconnectTrackerfor this, and becomes a required peer of the bridge.initialMessages: fromAISDKMessages(saved)) all work.reconnect. The compatibility table, README and migration skill are updated.✅ 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
packages/ai-ui-message-stream:vitest run(48 passed),test:types,test:oxlint,knip.packages/ai-client:test:types,test:oxlint. The one lint warning is in existing code.kiira checkon the changed docs and skill, andpnpm test:docs.pnpm test:prand the E2E suite. CI runs them.Manual test
streamText({ tools: clientToolsFromAISDKBody(body, {}) }).useChat({ tools: [myClientTool], connection: fromChatTransport(new DefaultChatTransport({ api })) }).How this PR makes testing easy
tests/client-tools.test.tsruns a realChatClient,fromChatTransportand AI SDKstreamTextwith a mock model.tests/client-extras.test.tscovers structured output, the queue, devtools and saved chats.tests/reconnect.test.tscovers backoff and the no-progress limit.Risk / rollback
Low. Every option is new and off by default, except two changes:
@tanstack/ai-clientis now a required peer of@tanstack/ai-ui-message-stream.Revert the PR to undo both.
Public API change
Before: every client tool also had to be defined on the AI SDK route.
After