- Updated dependencies [
2cb0313,18e5f4d,21720dd,243b8fa]:- @tanstack/ai@0.33.0
- @tanstack/ai-event-client@0.6.4
-
#624
8fa6cc5-generateImage()andgenerateVideo()now accept a multimodalprompt: a plain string, or an ordered array of content parts (TextPart/ImagePart/VideoPart/AudioPart) for image-conditioned generation, image-to-image, multi-reference, image-to-video, and edit / inpaint flows. Part order is meaningful — "not like this (image), more like this (image)" — and each media part may carry ametadata.rolehint ('reference' | 'mask' | 'control' | 'start_frame' | 'end_frame' | 'character') that adapters use to route to the provider-specific field, plus an informationalmetadata.taglabel for your own bookkeeping. The accepted part types are narrowed per model at compile time via each adapter's input-modality map, so passing an image part to a text-only model is a type error (with a clear runtime throw as backstop).Prompt text is always sent verbatim — the SDK never injects or rewrites in-prompt referencing markers. To reference inputs from your prompt, write the provider's own convention (fal Kling / Seedance
@Image1, OpenAI / FLUX.2"image 1"prose, Gemini content descriptions); see the image-generation docs for the per-provider table.Provider behavior in this release:
- OpenAI image — Prompts with image parts route
gpt-image-2/gpt-image-1/gpt-image-1-minitoimages.edit()(up to 16 source images plus optional mask);dall-e-2routes toimages.edit()with one source image;dall-e-3rejects image parts at compile time and at runtime. - OpenAI video — Sora-2 / Sora-2-Pro accept a single image part as
input_reference; passing more than one throws. - Gemini image — Native models (
gemini-*-flash-image, "nano-banana") map prompt parts 1:1 onto multimodalcontents, preserving interleaved order. Imagen is text-only (compile-time + runtime rejection). - fal.ai — Field names resolve per endpoint from a map generated from the fal SDK's endpoint types (362 endpoints with nonstandard fields, e.g. nano-banana edit →
image_urls, Kling i2v start frame →image_url, Veo first-last-frame →first_frame_url/last_frame_url). Defaults for endpoints not in the map: single →image_url, multiple →image_urls;role: 'mask'→mask_url;role: 'control'→control_image_url;role: 'reference'/'character'→reference_image_urls; videorole: 'start_frame'/'end_frame'→start_image_url/end_image_url. Per-model prompt modalities are derived at the type level from the SDK's endpoint input types. Regenerate the map after a fal SDK bump withpnpm generate:fal-image-fields(a unit test fails when it goes stale). InFalImageProviderOptions/FalVideoProviderOptions, media-conditioning fields the mappers can populate (image_url,start_image_url,video_url,audio_url, …) are demoted from required to optional — supply them as prompt parts, or keep passing them explicitly viamodelOptions. - Grok — New
grok-imagine-image/grok-imagine-image-qualitymodels. Prompts with image parts route to xAI's JSON/v1/images/editsendpoint (up to 3 source images, addressed by xAI in request order; the prompt is sent verbatim).role: 'mask'/'control'throw. Theirsizeuses anaspectRatio_resolutiontemplate ('16:9_2k', suffix optional) mirroring Gemini's native image models.grok-2-image-1212remains text-to-image only. - OpenRouter — Prompt parts map 1:1 onto multimodal
text/image_urlchat content parts, preserving interleaved order, and are forwarded to the underlying image model. URL sources pass through verbatim (no fetching or re-encoding in your process);datasources become data URIs. - Anthropic — Unchanged (no image generation API).
A new
resolveMediaPrompt()utility (exported from@tanstack/ai) is the single downrev point from the canonical interleaved prompt shape to flattened text + per-modality part buckets, for adapter authors.On the client side,
ImageGenerateInput.promptandVideoGenerateInput.prompt(@tanstack/ai-client, and theuseGenerateImage/useGenerateVideohooks built on them) are widened fromstringto the sameMediaPromptshape, so prompt parts can be sent from the browser through your server route togenerateImage()/generateVideo().Closes #618.
- OpenAI image — Prompts with image parts route
- Updated dependencies [
07aaf8b]:- @tanstack/ai@0.31.0
- @tanstack/ai-event-client@0.6.2
- #752
4d5141c- FixChatClientthrowingTypeError: this.devtoolsBridge.mountWithTools is not a functionon the firstsendMessage()(and onupdateOptions({ tools })) when no devtools bridge factory is supplied. The defaultNoOpChatDevtoolsBridgewas missing themountWithTools,notifyToolsChanged, andrecordStreamIdmethods of the real bridge; the throw happened before the user message was appended, so the first message was silently lost. The compile-time parity check between the real and no-op bridges now fails the build when the surfaces drift.
-
#769
1d1bb52- Add repository metadata (homepage,bugs,funding), fixrepository.directoryto point at each package, and include an MITLICENSEfile in every published package. -
Updated dependencies [
7103348,1d1bb52]:- @tanstack/ai@0.30.0
- @tanstack/ai-event-client@0.6.1
-
#727
7d44569- Add an'error'terminal toToolCallState. When a tool execution produces an output error, the StreamProcessor now transitions thetool-callpart tostate: 'error'instead of parking it at'input-complete'.Previously an errored tool call left the tool-call part at
'input-complete'forever, so UIs that render lifecycle from the part'sstatecould not distinguish "still executing" from "failed" without reverse-engineering the error-shapedoutputor the siblingtool-resultpart. The new terminal makes the tool-call state machine self-describing and symmetric withToolResultState(which already has'error'):if (part.type === 'tool-call' && part.state === 'error') { // render failure — no more inferring from output shape }
The completion safety net (
RUN_FINISHED/ stream finalization) no longer downgrades a failed tool call back to'input-complete', including when anoutput-errorresult arrives beforeTOOL_CALL_END.
- Updated dependencies [
ff267a5,570c08a,ff267a5,22c9b42,215b6b4,7d44569]:- @tanstack/ai@0.29.0
- @tanstack/ai-event-client@0.6.0
- Updated dependencies [
496e814,c0af426,00e0c93,496e814]:- @tanstack/ai@0.28.0
- @tanstack/ai-event-client@0.5.4
- Updated dependencies [
6df32b5]:- @tanstack/ai@0.27.0
- @tanstack/ai-event-client@0.5.3
- Updated dependencies [
7adff0f]:- @tanstack/ai-event-client@0.5.2
- @tanstack/ai@0.26.1
- Updated dependencies [
5d6cd28]:- @tanstack/ai@0.26.0
- @tanstack/ai-event-client@0.5.1
- Updated dependencies [
c251038]:- @tanstack/ai@0.25.0
- @tanstack/ai-event-client@0.5.0
-
#666
c1ae8b9- feat: support multimodal (image) tool resultsTools may now return an
Array<ContentPart>(e.g. a text part plus an image part) and have it transmitted to the model as structured multimodal tool output instead of aJSON.stringify'd blob. This unblocks use cases like returning a screenshot from a tool so the model can see it (issue #363).- Detection is structural and opt-in by shape: a tool that returns a non-empty array whose every element is a valid
ContentPartis passed through unchanged; strings and all other return values are serialized exactly as before, so there are no breaking changes. - The OpenAI Responses, Anthropic, and Google Gemini adapters convert the content parts into their native multimodal tool-output formats (
function_call_output.output,tool_resultcontent blocks, andfunctionResponse.partsrespectively). Providers on the Chat Completions path (Groq, Ollama, Grok, OpenRouter chat) fall back to stringifying, which their APIs require. - AG-UI stream events (
TOOL_CALL_RESULT.content,TOOL_CALL_END.result) remain string-only per the spec; the multimodal array travels on the tool message itself.
- Detection is structural and opt-in by shape: a tool that returns a non-empty array whose every element is a valid
-
#628
8036b50- Add typed runtime context for tools and middleware.Tools and middleware can now declare the runtime context shape they require, and
chat(),ChatClient, and the frameworkuseChat/createChathooks infer the merged requirement and type-check thecontextoption you pass against it.type AppContext = { userId: string; db: Db } const listNotes = toolDefinition({ name: 'list_notes' /* ... */, }).server<AppContext>((_input, ctx) => ctx.context.db.notes.findMany({ userId: ctx.context.userId }), ) chat({ adapter, messages, tools: [listNotes], context: { userId, db }, // required and type-checked because listNotes declares AppContext })
Runtime context is request-local application state for tool and middleware implementations (authenticated users, database clients, tenancy, feature flags, loggers, browser services). It is never sent to the model and is distinct from the AG-UI
RunAgentInput.contextprotocol field.Untyped tools and middleware continue to receive
unknowncontext and do not force acontextoption. Client tools receive client-local context viaChatClient/useChat; useforwardedPropsto hand serializable client data to the server and map it into server context explicitly. See the new Runtime Context guide for details.Behavior change: tool output validation now also runs when a tool returns
undefinedornull. Previously these values bypassedoutputSchemavalidation entirely; now the schema decides whether they are valid, so a tool whose schema forbidsundefined/nullsurfaces a validation error (output-error) instead of silently passing. Tools whose schema permitsnull/undefined(e.g. nullable or void outputs) are unaffected.
- Updated dependencies [
c1ae8b9,a452ae8,8036b50]:- @tanstack/ai@0.24.0
- @tanstack/ai-event-client@0.4.3
- Updated dependencies [
94bb9c0]:- @tanstack/ai@0.23.1
- @tanstack/ai-event-client@0.4.2
-
#647
d5645cf- Add React Native support for chat clients and framework hooks, including client-safe streaming utilities and connection adapters that work in mobile environments.The
fetcheroption is now available onChatClientand the framework chat hooks (useChat/createChat), mirroring the generation hooks. Pass eitherconnectionorfetcher-- the XOR is enforced at the type level viaChatTransport. Fetchers may return either aResponse(parsed as SSE) or anAsyncIterable<StreamChunk>(yielded directly).The client-safe
@tanstack/ai/clientsubpath is now public for framework packages and mobile bundles.stream(),fetchServerSentEvents,fetchHttpStream,rpcStream,xhrServerSentEvents, andxhrHttpStreamare available from the client package and framework re-exports. React Native docs, an Expo chat example, and smoke tests are included for the supported mobile setup.
- #632
5634f18- Add hook-aware AI devtools registration, run tracking, state snapshots, and tool fixture replay.
- Updated dependencies [
5634f18]:- @tanstack/ai-event-client@0.4.0
- @tanstack/ai@0.22.1
-
Add a
fetcheroption toChatClientand the framework chat hooks (#512) (useChat/createChat), mirroring thefetcheroption on the generation hooks. Pass eitherconnectionorfetcher— the XOR is enforced at the type level viaChatTransport.useChat({ fetcher: ({ messages }, { signal }) => chatFn({ data: { messages }, signal }), })
The fetcher may return either a
Response(parsed as SSE) or anAsyncIterable<StreamChunk>(yielded directly).stream(),fetchServerSentEvents,fetchHttpStream, andrpcStreamare unchanged.
- Updated dependencies [
02f7d04]:- @tanstack/ai@0.22.0
- @tanstack/ai-event-client@0.3.11
-
Populate server-executed tool results on the matching
tool-callpart and mark successful tool calls ascomplete. (#596) -
Updated dependencies [
e144a53]:- @tanstack/ai@0.21.3
- @tanstack/ai-event-client@0.3.10
-
Refresh package README content and npm metadata for better discoverability. (#626)
-
Updated dependencies [
ebeb22e]:- @tanstack/ai@0.21.2
- @tanstack/ai-event-client@0.3.9
- Updated dependencies [
573f12e]:- @tanstack/ai@0.21.1
- @tanstack/ai-event-client@0.3.8
-
Expose the connection adapter primitives needed to build custom (#597) transports from every framework hook package.
@tanstack/ai-clientnow re-exportsRunAgentInputContextat its entry point, and@tanstack/ai-react,@tanstack/ai-vue,@tanstack/ai-solid,@tanstack/ai-svelte, and@tanstack/ai-preactnow re-exportrpcStream,ConnectConnectionAdapter,SubscribeConnectionAdapter, andRunAgentInputContextalongside the existingstream,fetchServerSentEvents, andfetchHttpStreamre-exports.Previously, authors of WebSocket / persistent or RPC-backed adapters had to import these symbols from
@tanstack/ai-clienteven though they were already pullinguseChatfrom a framework package. No runtime change. -
Updated dependencies [
ec1393d,188fe11]:- @tanstack/ai@0.21.0
- @tanstack/ai-event-client@0.3.7
- Updated dependencies [
2ad137b]:- @tanstack/ai@0.20.1
- @tanstack/ai-event-client@0.3.6
- Updated dependencies [
496db9c]:- @tanstack/ai@0.20.0
- @tanstack/ai-event-client@0.3.5
- Updated dependencies [
617b5b5]:- @tanstack/ai@0.19.1
- @tanstack/ai-event-client@0.3.4
-
feat: structured-output as a typed MessagePart on each assistant UIMessage (#577)
useChat({ outputSchema })(React, Vue, Solid) andcreateChat({ outputSchema })(Svelte) previously kept a single hook-levelpartial/finalslot, so multi-turn structured chats lost every prior turn's response as soon as a new one streamed in. Each assistant turn now carries its own typedstructured-outputMessagePart on the UIMessage it belongs to. History walksmessagesand finds the typed part on each turn; the hook-levelpartialandfinalare derived from the latest assistant message's part and continue to work as before. Applies to all four framework hook packages.The structured-output part type is generic over the schema's inferred data type:
StructuredOutputPart<TData = unknown>in@tanstack/aicarriesdata: TData,partial: DeepPartial<TData>,raw: string, plusstatus: 'streaming' | 'complete' | 'error'and an optionalerrorMessage.MessagePart<TTools, TData>andUIMessage<TTools, TData>in@tanstack/ai-clientthread the generic through the message types.- Each framework hook's return (
UseChatReturn<TTools, TSchema>for React / Vue / Solid,CreateChatReturn<TTools, TSchema>for Svelte) substitutesTData = InferSchemaType<TSchema>when a schema is supplied, somessages[i].parts.find(p => p.type === 'structured-output').datais typed by the schema with no cast required.
Default
TData = unknownkeeps every existing consumer that doesn't pass a schema source-compatible.Server-side
chat({ outputSchema, stream: true })emits a newstructured-output.startCUSTOM event before the JSON deltas so the client processor can route them into the StructuredOutputPart instead of building a TextPart. The wire converter serializes the part's raw JSON back as assistant content, so multi-turn structured chats stay coherent (the LLM sees its own prior structured responses on follow-up turns). For adapters without native JSON-schema streaming (Anthropic, Gemini, Ollama), the existing fallback path emits one terminalstructured-output.completeevent and the same per-turn typed part lands on the message — consumer code is identical.A new example route demonstrating the multi-turn pattern is at
/generations/structured-chatin thets-react-chatexample.Breaking-shape note (minor, not major): When
outputSchemais set,TEXT_MESSAGE_CONTENTdeltas no longer create aTextParton the assistant message — they accumulate into theStructuredOutputPart. Consumers that iteratedmessage.partsand explicitly filtered outTextParts to hide raw JSON (the workaround documented prior to this change) can remove that filter; doing nothing is also safe because noTextPartis produced in the first place.
- Updated dependencies [
2e0e2eb]:- @tanstack/ai@0.19.0
- @tanstack/ai-event-client@0.3.3
-
Breaking: AG-UI client-to-server compliance. (#511)
@tanstack/ai-clientnow POSTs an AG-UIRunAgentInputrequest body and@tanstack/aiserver endpoints must use the newchatParamsFromRequestBody+mergeAgentToolshelpers. Upgrade both packages together.Highlights:
- Wire format:
{threadId, runId, state, messages, tools, context, forwardedProps}(per AG-UI 0.0.52RunAgentInputSchema) instead of{messages, data}. - New server helpers exported from
@tanstack/ai:chatParamsFromRequestBody,mergeAgentTools. chat()acceptsthreadId,runId,parentRunIdas optional fields for AG-UI run correlation.ChatClientacceptsthreadIdoption; auto-generates and persists per session if omitted; freshrunIdper send.- Client tools auto-advertised to the server via
RunAgentInput.tools. - Foreign AG-UI clients can hit a TanStack server:
developercollapses tosystem,reasoning/activitydrop.
See
docs/migration/ag-ui-compliance.mdfor full migration steps. - Wire format:
- Updated dependencies [
87f305c]:- @tanstack/ai@0.16.0
- @tanstack/ai-event-client@0.3.0
-
Fix thinking blocks getting merged across steps and lost on turn 2+ of Anthropic tool loops. (#391)
Each thinking step emitted by the adapter now produces its own
ThinkingParton theUIMessageinstead of being merged into a single part, and thinking content + Anthropic signatures are preserved in server-side message history so multi-turn tool flows with extended thinking work correctly.This includes a public callback signature change:
StreamProcessorEvents.onThinkingUpdatenow receives(messageId, stepId, content)instead of(messageId, content).ChatClienthas been updated to handle the newstepIdargument internally, but consumers implementingStreamProcessorEventsdirectly need to add the new parameter.@tanstack/ai:ThinkingPartgains optionalstepIdandsignaturefields.ModelMessagegains an optionalthinking?: Array<{ content; signature? }>field so prior thinking can be replayed in subsequent turns.StepFinishedEventgains an optionalsignaturefield for provider-supplied thinking signatures.StreamProcessortracks thinking per-step viastepIdand keeps step ordering.getState().thinking/getResult().thinkingconcatenate step contents in order.- The
onThinkingUpdatecallback onStreamProcessorEventsnow receives(messageId, stepId, content)— consumers implementing it directly must add thestepIdparameter. TextEngineaccumulates thinking + signatures per iteration and includes them in assistant messages with tool calls so the next turn can replay them.
@tanstack/ai-anthropic:- Captures
signature_deltastream events and emits the finalSTEP_FINISHEDwith the signature oncontent_block_stop. - Includes thinking blocks with signatures in
formatMessagesfor multi-turn history. - Passes
betas: ['interleaved-thinking-2025-05-14']to thebeta.messages.createcall site when a thinking budget is configured. The beta flag is scoped to the streaming path only, sostructuredOutput(which uses the non-betamessages.createendpoint) is unaffected.
@tanstack/ai-client:ChatClient's internalonThinkingUpdatewiring is updated for the newstepIdparameter.
-
Fixes a race condition in ChatClient.streamResponse() where this.abortController.signal could reference a stale or null controller by the time it is passed to this.connection.connect() (#377)
-
Updated dependencies [
a4e2c55,82078bd,b2d3cc1]:- @tanstack/ai@0.15.0
- @tanstack/ai-event-client@0.2.9
-
feat: add
useGenerateAudiohook and streaming support forgenerateAudio()(#463)Closes the parity gap between audio generation and the other media activities (image, speech, video, transcription, summarize):
generateAudio()now acceptsstream: true, returning anAsyncIterable<StreamChunk>that can be piped throughtoServerSentEventsResponse().AudioGenerateInputtype added to@tanstack/ai-client.useGenerateAudiohook added to@tanstack/ai-react,@tanstack/ai-solid, and@tanstack/ai-vue; matchingcreateGenerateAudioadded to@tanstack/ai-svelte. All follow the same{ generate, result, isLoading, error, status, stop, reset }shape as the existing media hooks and support bothconnection(SSE) andfetchertransports.
-
fix(ai-client): prevent drainPostStreamActions re-entrancy stealing queued actions (#429)
When multiple client tools complete in the same round, nested
drainPostStreamActions()calls fromstreamResponse()'sfinallyblock could steal queued actions, permanently stalling the conversation. Added a re-entrancy guard and ashouldAutoSend()check requiring tool-call parts before triggering continuation. -
Updated dependencies [
54523f5,54523f5,af9eb7b,54523f5]:- @tanstack/ai@0.14.0
- @tanstack/ai-event-client@0.2.8
- Updated dependencies [
c1fd96f]:- @tanstack/ai@0.13.0
- @tanstack/ai-event-client@0.2.7
- Updated dependencies [
e32583e]:- @tanstack/ai@0.12.0
- @tanstack/ai-event-client@0.2.6
- Updated dependencies [
633a3d9]:- @tanstack/ai@0.11.1
- @tanstack/ai-event-client@0.2.5
-
Thread
@tanstack/ai's AG-UI-compliant event shapes through the headless chat client: handle flatRUN_ERRORpayloads, consumeREASONING_*events, and warn when receiving the deprecated[DONE]sentinel. (#474) -
fix(ai-client): add
@standard-schema/specto devDependencies so the type references@tanstack/aiforwards throughInferToolInput/InferToolOutputresolve at build time. Types-only dep with no runtime cost; prevents tool-definition input/output inference from silently collapsing tounknownfor consumers ofuseChat/ChatClient. (#428) -
Updated dependencies [
12d43e5,12d43e5]:- @tanstack/ai@0.11.0
- @tanstack/ai-event-client@0.2.4
- Updated dependencies [
c780bc1]:- @tanstack/ai@0.10.3
- @tanstack/ai-event-client@0.2.3
- Updated dependencies [
4445410]:- @tanstack/ai@0.10.2
- @tanstack/ai-event-client@0.2.2
- Updated dependencies [
1d1c58f]:- @tanstack/ai@0.10.1
- @tanstack/ai-event-client@0.2.1
-
Add code mode and isolate packages for secure AI code execution (#362)
Also includes fixes for Ollama tool call argument streaming and usage reporting, OpenAI realtime adapter handling of missing call_id/item_id, realtime client guards for missing toolCallId, and new DevtoolsChatMiddleware type export from ai-event-client.
-
Updated dependencies [
54abae0]:- @tanstack/ai@0.10.0
- @tanstack/ai-event-client@0.2.0
-
fix: prevent infinite tool call loop when server tool finishes with stop (#412)
When the server-side agent loop executes a tool and the model finishes with
finishReason: 'stop', the client no longer auto-sends another request. Previously this caused infinite loops with non-OpenAI providers that respond minimally after tool execution.
- Updated dependencies [
26d8243]:- @tanstack/ai@0.9.2
- @tanstack/ai-event-client@0.1.4
- Updated dependencies [
b8cc69e]:- @tanstack/ai@0.9.1
- @tanstack/ai-event-client@0.1.3
- Updated dependencies [
842e119]:- @tanstack/ai@0.9.0
- @tanstack/ai-event-client@0.1.2
-
Add an explicit subscription lifecycle to
ChatClientwithsubscribe()/unsubscribe(),isSubscribed,connectionStatus, andsessionGenerating, while keeping request lifecycle state separate from long-lived connection state for durable chat sessions. (#356)Update the React, Preact, Solid, Svelte, and Vue chat bindings with
livemode plus reactive subscription/session state, and improveStreamProcessorhandling for concurrent runs and reconnects so active sessions do not finalize early or duplicate resumed assistant messages. -
Add durable
subscribe()/send()transport support toChatClientwhile preserving compatibility with existingconnect()adapters. This also introduces shared generation clients for one-shot streaming tasks and updates the framework wrappers to use the new generation transport APIs. (#286)Improve core stream processing to better handle concurrent runs and resumed streams so shared sessions stay consistent during reconnects and overlapping generations.
-
Updated dependencies [
64b9cba,dc53e1b]:- @tanstack/ai@0.8.1
- @tanstack/ai-event-client@0.1.1
-
feat: add middleware system and content guard middleware (#367)
- @tanstack/ai: New
@tanstack/ai/middlewaressubpath with composable chat middleware architecture. IncludescontentGuardMiddleware(delta and buffered strategies) andtoolCacheMiddleware. Middleware hooks:onStart,onIteration,onChunk,onToolPhaseComplete,onFinish. - @tanstack/ai-event-client: Initial release. Extracted
devtoolsMiddlewarefrom@tanstack/aicore into a standalone package for tree-shaking. Emits all DevTools events as an observation-only middleware. - @tanstack/ai-client: Updated event types for middleware integration.
- @tanstack/ai-devtools: Updated iteration timeline and conversation UI for middleware-aware event handling.
- @tanstack/ai: New
-
Updated dependencies [
f62eeb0]:- @tanstack/ai@0.8.0
- @tanstack/ai-event-client@0.1.0
-
feat: add realtime voice chat with OpenAI and ElevenLabs adapters (#300)
Adds realtime voice/text chat capabilities:
- @tanstack/ai:
realtimeToken()function and shared realtime types (RealtimeToken,RealtimeMessage,RealtimeSessionConfig,RealtimeStatus,RealtimeMode,AudioVisualization, events, and error types) - @tanstack/ai-client: Framework-agnostic
RealtimeClientclass with connection lifecycle, audio I/O, message state management, tool execution, andRealtimeAdapter/RealtimeConnectioninterfaces - @tanstack/ai-openai:
openaiRealtime()client adapter (WebRTC) andopenaiRealtimeToken()server token adapter with support for semantic VAD, multiple voices, and all realtime models - @tanstack/ai-elevenlabs:
elevenlabsRealtime()client adapter (WebSocket) andelevenlabsRealtimeToken()server token adapter for ElevenLabs conversational AI agents - @tanstack/ai-react:
useRealtimeChat()hook with reactive state for status, mode, messages, pending transcripts, audio visualization levels, VAD control, text/image input, and interruptions - Docs: Realtime Voice Chat guide and full API reference for all realtime classes, interfaces, functions, and type aliases
- @tanstack/ai:
- Updated dependencies [
86be1c8]:- @tanstack/ai@0.7.0
- @tanstack/ai-event-client@0.0.2
-
feat: support server function Response streaming via fetcher (#327)
Generation fetchers can now return a
Responsewith an SSE body (e.g., from a TanStack Start server function usingtoServerSentEventsResponse()). When aResponseis returned,GenerationClientandVideoGenerationClientautomatically parse it as an SSE stream while preserving full type safety on the input.
-
feat: pass abort signal to generation fetchers and extract GenerationFetcher utility type (#327)
- Generation clients now forward an
AbortSignalto fetcher functions via an optionaloptionsparameter, enabling cancellation support whenstop()is called - Introduced
GenerationFetcher<TInput, TResult>utility type in@tanstack/ai-clientto centralize the fetcher function signature across all framework integrations - All framework hooks/composables (React, Solid, Vue, Svelte) now use the shared
GenerationFetchertype instead of inline definitions
- Generation clients now forward an
-
Updated dependencies [
6dfffca]:- @tanstack/ai@0.6.3
- Updated dependencies [
2ee0b33]:- @tanstack/ai@0.6.2
- Fix chained tool approval flows where a second approval arriving during an active continuation stream was silently dropped (#347)
- Updated dependencies [
d8678e2]:- @tanstack/ai@0.6.1
-
feat: add custom event dispatch support for tools (#293)
Tools can now emit custom events during execution via
dispatchEvent(). Custom events are streamed to clients ascustom_eventstream chunks and surfaced through the client chat hook'sonCustomEventcallback. This enables tools to send progress updates, intermediate results, or any structured data back to the UI during long-running operations.
-
Refactor CustomEvent property from 'data' to 'value' for AG-UI compliance (#307)
-
Updated dependencies [
5aa6acc,1f800aa]:- @tanstack/ai@0.6.0
- Updated dependencies [
58702bc]:- @tanstack/ai@0.5.1
-
fix(ai, ai-client, ai-anthropic, ai-gemini): fix multi-turn conversations failing after tool calls (#275)
Core (@tanstack/ai):
- Lazy assistant message creation:
StreamProcessornow defers creating the assistant message until the first content-bearing chunk arrives (text, tool call, thinking, or error), eliminating emptyparts: []messages from appearing during auto-continuation when the model returns no content - Add
prepareAssistantMessage()(lazy) alongside deprecatedstartAssistantMessage()(eager, backwards-compatible) - Add
getCurrentAssistantMessageId()to check if a message was created - Rewrite
uiMessageToModelMessages()to preserve part ordering: the function now walks parts sequentially instead of separating by type, producing correctly interleaved assistant/tool messages (text1 + toolCall1 → toolResult1 → text2 + toolCall2 → toolResult2) instead of concatenating all text and batching all tool calls. This fixes multi-round tool flows where the model would see garbled conversation history and re-call tools unnecessarily. - Deduplicate tool result messages: when a client tool has both a
tool-resultpart and atool-callpart withoutput, only onerole: 'tool'message is emitted per tool call ID
Client (@tanstack/ai-client):
- Update
ChatClient.processStream()to use lazy assistant message creation, preventing UI flicker from empty messages being created then removed
Anthropic:
- Fix consecutive user-role messages violating Anthropic's alternating role requirement by merging them in
formatMessages - Deduplicate
tool_resultblocks with the sametool_use_id - Filter out empty assistant messages from conversation history
- Suppress duplicate
RUN_FINISHEDevent frommessage_stopwhenmessage_deltaalready emitted one - Fix
TEXT_MESSAGE_ENDincorrectly emitting fortool_usecontent blocks - Add Claude Opus 4.6 model support with adaptive thinking and effort parameter
Gemini:
- Fix consecutive user-role messages violating Gemini's alternating role requirement by merging them in
formatMessages - Deduplicate
functionResponseparts with the same name (tool call ID) - Filter out empty model messages from conversation history
- Lazy assistant message creation:
-
Updated dependencies [
5d98472,5d98472]:- @tanstack/ai@0.5.0
- Updated dependencies [
6f886e9]:- @tanstack/ai@0.4.2
- Updated dependencies [
6e1bb50]:- @tanstack/ai@0.4.1
-
add multiple modalities support to the client (#263)
-
Updated dependencies [
0158d14]:- @tanstack/ai@0.4.0
- Added status property to useChat to track the generation lifecycle (ready, submitted, streaming, error) (#247)
-
fix: improve tool execution reliability and prevent race conditions (#258)
- Fix client tool execution race conditions by tracking pending tool executions
- Prevent duplicate continuation attempts with continuationPending flag
- Guard against concurrent stream processing in streamResponse
- Add approval info to ToolCall type for server-side decision tracking
- Include approval info in model message conversion for approval workflows
- Check ModelMessage format for approval info extraction in chat activity
This change improves the reliability of tool execution, especially for:
- Client tools with async execute functions
- Approval-based tool workflows
- Sequential tool execution scenarios
-
Updated dependencies [
230bab6]:- @tanstack/ai@0.3.1
-
feat: Add AG-UI protocol events to streaming system (#244)
All text adapters now emit AG-UI protocol events only:
RUN_STARTED/RUN_FINISHED- Run lifecycle eventsTEXT_MESSAGE_START/TEXT_MESSAGE_CONTENT/TEXT_MESSAGE_END- Text message streamingTOOL_CALL_START/TOOL_CALL_ARGS/TOOL_CALL_END- Tool call streaming
Only AG-UI event types are supported; previous legacy chunk formats (
content,tool_call,done, etc.) are no longer accepted.
- Updated dependencies [
e52135f]:- @tanstack/ai@0.3.0
- Updated dependencies [
7573619]:- @tanstack/ai@0.2.2
- Standard schema / standard json schema support for TanStack AI (#165)
- Updated dependencies [
c5df33c]:- @tanstack/ai@0.2.0
- Split up adapters for better tree shaking into separate functionalities (#137)
- Updated dependencies [
8d77614]:- @tanstack/ai@0.1.0
- Updated dependencies [
52c3172]:- @tanstack/ai@0.0.3