Skip to content

Latest commit

 

History

History
844 lines (545 loc) · 45.7 KB

File metadata and controls

844 lines (545 loc) · 45.7 KB

@tanstack/ai-client

0.18.1

Patch Changes

0.18.0

Minor Changes

  • #624 8fa6cc5 - generateImage() and generateVideo() now accept a multimodal prompt: 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 a metadata.role hint ('reference' | 'mask' | 'control' | 'start_frame' | 'end_frame' | 'character') that adapters use to route to the provider-specific field, plus an informational metadata.tag label 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-mini to images.edit() (up to 16 source images plus optional mask); dall-e-2 routes to images.edit() with one source image; dall-e-3 rejects 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 multimodal contents, 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; video role: '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 with pnpm generate:fal-image-fields (a unit test fails when it goes stale). In FalImageProviderOptions / 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 via modelOptions.
    • Grok — New grok-imagine-image / grok-imagine-image-quality models. Prompts with image parts route to xAI's JSON /v1/images/edits endpoint (up to 3 source images, addressed by xAI in request order; the prompt is sent verbatim). role: 'mask' / 'control' throw. Their size uses an aspectRatio_resolution template ('16:9_2k', suffix optional) mirroring Gemini's native image models. grok-2-image-1212 remains text-to-image only.
    • OpenRouter — Prompt parts map 1:1 onto multimodal text / image_url chat 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); data sources 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.prompt and VideoGenerateInput.prompt (@tanstack/ai-client, and the useGenerateImage / useGenerateVideo hooks built on them) are widened from string to the same MediaPrompt shape, so prompt parts can be sent from the browser through your server route to generateImage() / generateVideo().

    Closes #618.

Patch Changes

  • Updated dependencies [8fa6cc5, 8fa6cc5]:
    • @tanstack/ai@0.32.0
    • @tanstack/ai-event-client@0.6.3

0.17.3

Patch Changes

  • Updated dependencies [07aaf8b]:
    • @tanstack/ai@0.31.0
    • @tanstack/ai-event-client@0.6.2

0.17.2

Patch Changes

  • #752 4d5141c - Fix ChatClient throwing TypeError: this.devtoolsBridge.mountWithTools is not a function on the first sendMessage() (and on updateOptions({ tools })) when no devtools bridge factory is supplied. The default NoOpChatDevtoolsBridge was missing the mountWithTools, notifyToolsChanged, and recordStreamId methods 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.

0.17.1

Patch Changes

  • #769 1d1bb52 - Add repository metadata (homepage, bugs, funding), fix repository.directory to point at each package, and include an MIT LICENSE file in every published package.

  • Updated dependencies [7103348, 1d1bb52]:

    • @tanstack/ai@0.30.0
    • @tanstack/ai-event-client@0.6.1

0.17.0

Minor Changes

  • #727 7d44569 - Add an 'error' terminal to ToolCallState. When a tool execution produces an output error, the StreamProcessor now transitions the tool-call part to state: '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's state could not distinguish "still executing" from "failed" without reverse-engineering the error-shaped output or the sibling tool-result part. The new terminal makes the tool-call state machine self-describing and symmetric with ToolResultState (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 an output-error result arrives before TOOL_CALL_END.

Patch Changes

0.16.3

Patch Changes

0.16.2

Patch Changes

  • Updated dependencies [6df32b5]:
    • @tanstack/ai@0.27.0
    • @tanstack/ai-event-client@0.5.3

0.16.1

Patch Changes

  • Updated dependencies [7adff0f]:
    • @tanstack/ai-event-client@0.5.2
    • @tanstack/ai@0.26.1

0.16.0

Minor Changes

  • #661 755e995 - Add persistence support for chat messages.

0.15.2

Patch Changes

  • Updated dependencies [5d6cd28]:
    • @tanstack/ai@0.26.0
    • @tanstack/ai-event-client@0.5.1

0.15.1

Patch Changes

  • Updated dependencies [c251038]:
    • @tanstack/ai@0.25.0
    • @tanstack/ai-event-client@0.5.0

0.15.0

Minor Changes

  • #666 c1ae8b9 - feat: support multimodal (image) tool results

    Tools 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 a JSON.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 ContentPart is 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_result content blocks, and functionResponse.parts respectively). 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.
  • #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 framework useChat / createChat hooks infer the merged requirement and type-check the context option 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.context protocol field.

    Untyped tools and middleware continue to receive unknown context and do not force a context option. Client tools receive client-local context via ChatClient / useChat; use forwardedProps to 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 undefined or null. Previously these values bypassed outputSchema validation entirely; now the schema decides whether they are valid, so a tool whose schema forbids undefined/null surfaces a validation error (output-error) instead of silently passing. Tools whose schema permits null/undefined (e.g. nullable or void outputs) are unaffected.

Patch Changes

0.14.1

Patch Changes

  • Updated dependencies [94bb9c0]:
    • @tanstack/ai@0.23.1
    • @tanstack/ai-event-client@0.4.2

0.14.0

Minor Changes

  • #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 fetcher option is now available on ChatClient and the framework chat hooks (useChat / createChat), mirroring the generation hooks. Pass either connection or fetcher -- the XOR is enforced at the type level via ChatTransport. Fetchers may return either a Response (parsed as SSE) or an AsyncIterable<StreamChunk> (yielded directly).

    The client-safe @tanstack/ai/client subpath is now public for framework packages and mobile bundles. stream(), fetchServerSentEvents, fetchHttpStream, rpcStream, xhrServerSentEvents, and xhrHttpStream are 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.

Patch Changes

  • Updated dependencies [980ff9b, d5645cf]:
    • @tanstack/ai@0.23.0
    • @tanstack/ai-event-client@0.4.1

0.13.0

Minor Changes

  • #632 5634f18 - Add hook-aware AI devtools registration, run tracking, state snapshots, and tool fixture replay.

Patch Changes

  • Updated dependencies [5634f18]:
    • @tanstack/ai-event-client@0.4.0
    • @tanstack/ai@0.22.1

0.12.0

Minor Changes

  • Add a fetcher option to ChatClient and the framework chat hooks (#512) (useChat / createChat), mirroring the fetcher option on the generation hooks. Pass either connection or fetcher — the XOR is enforced at the type level via ChatTransport.

    useChat({
      fetcher: ({ messages }, { signal }) =>
        chatFn({ data: { messages }, signal }),
    })

    The fetcher may return either a Response (parsed as SSE) or an AsyncIterable<StreamChunk> (yielded directly). stream(), fetchServerSentEvents, fetchHttpStream, and rpcStream are unchanged.

0.11.8

Patch Changes

  • Updated dependencies [02f7d04]:
    • @tanstack/ai@0.22.0
    • @tanstack/ai-event-client@0.3.11

0.11.7

Patch Changes

  • Populate server-executed tool results on the matching tool-call part and mark successful tool calls as complete. (#596)

  • Updated dependencies [e144a53]:

    • @tanstack/ai@0.21.3
    • @tanstack/ai-event-client@0.3.10

0.11.6

Patch Changes

  • 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

0.11.5

Patch Changes

  • Updated dependencies [573f12e]:
    • @tanstack/ai@0.21.1
    • @tanstack/ai-event-client@0.3.8

0.11.4

Patch Changes

  • Expose the connection adapter primitives needed to build custom (#597) transports from every framework hook package. @tanstack/ai-client now re-exports RunAgentInputContext at its entry point, and @tanstack/ai-react, @tanstack/ai-vue, @tanstack/ai-solid, @tanstack/ai-svelte, and @tanstack/ai-preact now re-export rpcStream, ConnectConnectionAdapter, SubscribeConnectionAdapter, and RunAgentInputContext alongside the existing stream, fetchServerSentEvents, and fetchHttpStream re-exports.

    Previously, authors of WebSocket / persistent or RPC-backed adapters had to import these symbols from @tanstack/ai-client even though they were already pulling useChat from a framework package. No runtime change.

  • Updated dependencies [ec1393d, 188fe11]:

    • @tanstack/ai@0.21.0
    • @tanstack/ai-event-client@0.3.7

0.11.3

Patch Changes

  • Updated dependencies [2ad137b]:
    • @tanstack/ai@0.20.1
    • @tanstack/ai-event-client@0.3.6

0.11.2

Patch Changes

  • Updated dependencies [496db9c]:
    • @tanstack/ai@0.20.0
    • @tanstack/ai-event-client@0.3.5

0.11.1

Patch Changes

  • Updated dependencies [617b5b5]:
    • @tanstack/ai@0.19.1
    • @tanstack/ai-event-client@0.3.4

0.11.0

Minor Changes

  • feat: structured-output as a typed MessagePart on each assistant UIMessage (#577)

    useChat({ outputSchema }) (React, Vue, Solid) and createChat({ outputSchema }) (Svelte) previously kept a single hook-level partial/final slot, 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 typed structured-output MessagePart on the UIMessage it belongs to. History walks messages and finds the typed part on each turn; the hook-level partial and final are 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/ai carries data: TData, partial: DeepPartial<TData>, raw: string, plus status: 'streaming' | 'complete' | 'error' and an optional errorMessage.
    • MessagePart<TTools, TData> and UIMessage<TTools, TData> in @tanstack/ai-client thread the generic through the message types.
    • Each framework hook's return (UseChatReturn<TTools, TSchema> for React / Vue / Solid, CreateChatReturn<TTools, TSchema> for Svelte) substitutes TData = InferSchemaType<TSchema> when a schema is supplied, so messages[i].parts.find(p => p.type === 'structured-output').data is typed by the schema with no cast required.

    Default TData = unknown keeps every existing consumer that doesn't pass a schema source-compatible.

    Server-side chat({ outputSchema, stream: true }) emits a new structured-output.start CUSTOM 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 terminal structured-output.complete event 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-chat in the ts-react-chat example.

    Breaking-shape note (minor, not major): When outputSchema is set, TEXT_MESSAGE_CONTENT deltas no longer create a TextPart on the assistant message — they accumulate into the StructuredOutputPart. Consumers that iterated message.parts and explicitly filtered out TextParts to hide raw JSON (the workaround documented prior to this change) can remove that filter; doing nothing is also safe because no TextPart is produced in the first place.

Patch Changes

  • Updated dependencies [2e0e2eb]:
    • @tanstack/ai@0.19.0
    • @tanstack/ai-event-client@0.3.3

0.10.0

Minor Changes

  • Breaking: AG-UI client-to-server compliance. (#511)

    @tanstack/ai-client now POSTs an AG-UI RunAgentInput request body and @tanstack/ai server endpoints must use the new chatParamsFromRequestBody + mergeAgentTools helpers. Upgrade both packages together.

    Highlights:

    • Wire format: {threadId, runId, state, messages, tools, context, forwardedProps} (per AG-UI 0.0.52 RunAgentInputSchema) instead of {messages, data}.
    • New server helpers exported from @tanstack/ai: chatParamsFromRequestBody, mergeAgentTools.
    • chat() accepts threadId, runId, parentRunId as optional fields for AG-UI run correlation.
    • ChatClient accepts threadId option; auto-generates and persists per session if omitted; fresh runId per send.
    • Client tools auto-advertised to the server via RunAgentInput.tools.
    • Foreign AG-UI clients can hit a TanStack server: developer collapses to system, reasoning/activity drop.

    See docs/migration/ag-ui-compliance.md for full migration steps.

Patch Changes

  • Updated dependencies [a9d1916, e810153]:
    • @tanstack/ai@0.18.0
    • @tanstack/ai-event-client@0.3.2

0.9.2

Patch Changes

  • Updated dependencies [98979f7, 02527c2]:
    • @tanstack/ai@0.17.0
    • @tanstack/ai-event-client@0.3.1

0.9.1

Patch Changes

  • Updated dependencies [87f305c]:
    • @tanstack/ai@0.16.0
    • @tanstack/ai-event-client@0.3.0

0.9.0

Minor Changes

  • 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 ThinkingPart on the UIMessage instead 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.onThinkingUpdate now receives (messageId, stepId, content) instead of (messageId, content). ChatClient has been updated to handle the new stepId argument internally, but consumers implementing StreamProcessorEvents directly need to add the new parameter.

    @tanstack/ai:

    • ThinkingPart gains optional stepId and signature fields.
    • ModelMessage gains an optional thinking?: Array<{ content; signature? }> field so prior thinking can be replayed in subsequent turns.
    • StepFinishedEvent gains an optional signature field for provider-supplied thinking signatures.
    • StreamProcessor tracks thinking per-step via stepId and keeps step ordering. getState().thinking / getResult().thinking concatenate step contents in order.
    • The onThinkingUpdate callback on StreamProcessorEvents now receives (messageId, stepId, content) — consumers implementing it directly must add the stepId parameter.
    • TextEngine accumulates 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_delta stream events and emits the final STEP_FINISHED with the signature on content_block_stop.
    • Includes thinking blocks with signatures in formatMessages for multi-turn history.
    • Passes betas: ['interleaved-thinking-2025-05-14'] to the beta.messages.create call site when a thinking budget is configured. The beta flag is scoped to the streaming path only, so structuredOutput (which uses the non-beta messages.create endpoint) is unaffected.

    @tanstack/ai-client:

    • ChatClient's internal onThinkingUpdate wiring is updated for the new stepId parameter.

Patch Changes

  • 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

0.8.0

Minor Changes

  • feat: add useGenerateAudio hook and streaming support for generateAudio() (#463)

    Closes the parity gap between audio generation and the other media activities (image, speech, video, transcription, summarize):

    • generateAudio() now accepts stream: true, returning an AsyncIterable<StreamChunk> that can be piped through toServerSentEventsResponse().
    • AudioGenerateInput type added to @tanstack/ai-client.
    • useGenerateAudio hook added to @tanstack/ai-react, @tanstack/ai-solid, and @tanstack/ai-vue; matching createGenerateAudio added to @tanstack/ai-svelte. All follow the same { generate, result, isLoading, error, status, stop, reset } shape as the existing media hooks and support both connection (SSE) and fetcher transports.

Patch Changes

  • fix(ai-client): prevent drainPostStreamActions re-entrancy stealing queued actions (#429)

    When multiple client tools complete in the same round, nested drainPostStreamActions() calls from streamResponse()'s finally block could steal queued actions, permanently stalling the conversation. Added a re-entrancy guard and a shouldAutoSend() 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

0.7.14

Patch Changes

  • Updated dependencies [c1fd96f]:
    • @tanstack/ai@0.13.0
    • @tanstack/ai-event-client@0.2.7

0.7.13

Patch Changes

  • Updated dependencies [e32583e]:
    • @tanstack/ai@0.12.0
    • @tanstack/ai-event-client@0.2.6

0.7.12

Patch Changes

  • Updated dependencies [633a3d9]:
    • @tanstack/ai@0.11.1
    • @tanstack/ai-event-client@0.2.5

0.7.11

Patch Changes

  • Thread @tanstack/ai's AG-UI-compliant event shapes through the headless chat client: handle flat RUN_ERROR payloads, consume REASONING_* events, and warn when receiving the deprecated [DONE] sentinel. (#474)

  • fix(ai-client): add @standard-schema/spec to devDependencies so the type references @tanstack/ai forwards through InferToolInput / InferToolOutput resolve at build time. Types-only dep with no runtime cost; prevents tool-definition input/output inference from silently collapsing to unknown for consumers of useChat / ChatClient. (#428)

  • Updated dependencies [12d43e5, 12d43e5]:

    • @tanstack/ai@0.11.0
    • @tanstack/ai-event-client@0.2.4

0.7.10

Patch Changes

  • Updated dependencies [c780bc1]:
    • @tanstack/ai@0.10.3
    • @tanstack/ai-event-client@0.2.3

0.7.9

Patch Changes

  • Updated dependencies [4445410]:
    • @tanstack/ai@0.10.2
    • @tanstack/ai-event-client@0.2.2

0.7.8

Patch Changes

  • Updated dependencies [1d1c58f]:
    • @tanstack/ai@0.10.1
    • @tanstack/ai-event-client@0.2.1

0.7.7

Patch Changes

  • 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

0.7.6

Patch Changes

  • 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.

0.7.5

Patch Changes

  • Updated dependencies [26d8243]:
    • @tanstack/ai@0.9.2
    • @tanstack/ai-event-client@0.1.4

0.7.4

Patch Changes

  • Updated dependencies [b8cc69e]:
    • @tanstack/ai@0.9.1
    • @tanstack/ai-event-client@0.1.3

0.7.3

Patch Changes

  • Updated dependencies [842e119]:
    • @tanstack/ai@0.9.0
    • @tanstack/ai-event-client@0.1.2

0.7.2

Patch Changes

  • Add an explicit subscription lifecycle to ChatClient with subscribe()/unsubscribe(), isSubscribed, connectionStatus, and sessionGenerating, 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 live mode plus reactive subscription/session state, and improve StreamProcessor handling for concurrent runs and reconnects so active sessions do not finalize early or duplicate resumed assistant messages.

  • Add durable subscribe()/send() transport support to ChatClient while preserving compatibility with existing connect() 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

0.7.1

Patch Changes

  • feat: add middleware system and content guard middleware (#367)

    • @tanstack/ai: New @tanstack/ai/middlewares subpath with composable chat middleware architecture. Includes contentGuardMiddleware (delta and buffered strategies) and toolCacheMiddleware. Middleware hooks: onStart, onIteration, onChunk, onToolPhaseComplete, onFinish.
    • @tanstack/ai-event-client: Initial release. Extracted devtoolsMiddleware from @tanstack/ai core 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.
  • Updated dependencies [f62eeb0]:

    • @tanstack/ai@0.8.0
    • @tanstack/ai-event-client@0.1.0

0.7.0

Minor Changes

  • 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 RealtimeClient class with connection lifecycle, audio I/O, message state management, tool execution, and RealtimeAdapter/RealtimeConnection interfaces
    • @tanstack/ai-openai: openaiRealtime() client adapter (WebRTC) and openaiRealtimeToken() server token adapter with support for semantic VAD, multiple voices, and all realtime models
    • @tanstack/ai-elevenlabs: elevenlabsRealtime() client adapter (WebSocket) and elevenlabsRealtimeToken() 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

Patch Changes

  • Updated dependencies [86be1c8]:
    • @tanstack/ai@0.7.0
    • @tanstack/ai-event-client@0.0.2

0.6.0

Minor Changes

  • feat: support server function Response streaming via fetcher (#327)

    Generation fetchers can now return a Response with an SSE body (e.g., from a TanStack Start server function using toServerSentEventsResponse()). When a Response is returned, GenerationClient and VideoGenerationClient automatically parse it as an SSE stream while preserving full type safety on the input.

Patch Changes

  • feat: pass abort signal to generation fetchers and extract GenerationFetcher utility type (#327)

    • Generation clients now forward an AbortSignal to fetcher functions via an optional options parameter, enabling cancellation support when stop() is called
    • Introduced GenerationFetcher<TInput, TResult> utility type in @tanstack/ai-client to centralize the fetcher function signature across all framework integrations
    • All framework hooks/composables (React, Solid, Vue, Svelte) now use the shared GenerationFetcher type instead of inline definitions
  • Updated dependencies [6dfffca]:

    • @tanstack/ai@0.6.3

0.5.3

Patch Changes

  • Updated dependencies [2ee0b33]:
    • @tanstack/ai@0.6.2

0.5.2

Patch Changes

  • Fix chained tool approval flows where a second approval arriving during an active continuation stream was silently dropped (#347)

0.5.1

Patch Changes

  • Updated dependencies [d8678e2]:
    • @tanstack/ai@0.6.1

0.5.0

Minor Changes

  • 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 as custom_event stream chunks and surfaced through the client chat hook's onCustomEvent callback. This enables tools to send progress updates, intermediate results, or any structured data back to the UI during long-running operations.

Patch Changes

  • Refactor CustomEvent property from 'data' to 'value' for AG-UI compliance (#307)

  • Updated dependencies [5aa6acc, 1f800aa]:

    • @tanstack/ai@0.6.0

0.4.5

Patch Changes

  • Updated dependencies [58702bc]:
    • @tanstack/ai@0.5.1

0.4.4

Patch Changes

  • fix(ai, ai-client, ai-anthropic, ai-gemini): fix multi-turn conversations failing after tool calls (#275)

    Core (@tanstack/ai):

    • Lazy assistant message creation: StreamProcessor now defers creating the assistant message until the first content-bearing chunk arrives (text, tool call, thinking, or error), eliminating empty parts: [] messages from appearing during auto-continuation when the model returns no content
    • Add prepareAssistantMessage() (lazy) alongside deprecated startAssistantMessage() (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-result part and a tool-call part with output, only one role: '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_result blocks with the same tool_use_id
    • Filter out empty assistant messages from conversation history
    • Suppress duplicate RUN_FINISHED event from message_stop when message_delta already emitted one
    • Fix TEXT_MESSAGE_END incorrectly emitting for tool_use content 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 functionResponse parts with the same name (tool call ID)
    • Filter out empty model messages from conversation history
  • Updated dependencies [5d98472, 5d98472]:

    • @tanstack/ai@0.5.0

0.4.3

Patch Changes

  • Updated dependencies [6f886e9]:
    • @tanstack/ai@0.4.2

0.4.2

Patch Changes

  • Updated dependencies [6e1bb50]:
    • @tanstack/ai@0.4.1

0.4.1

Patch Changes

  • add multiple modalities support to the client (#263)

  • Updated dependencies [0158d14]:

    • @tanstack/ai@0.4.0

0.4.0

Minor Changes

  • Added status property to useChat to track the generation lifecycle (ready, submitted, streaming, error) (#247)

Patch Changes

  • 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

0.3.0

Minor Changes

  • 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 events
    • TEXT_MESSAGE_START / TEXT_MESSAGE_CONTENT / TEXT_MESSAGE_END - Text message streaming
    • TOOL_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.

Patch Changes

  • Updated dependencies [e52135f]:
    • @tanstack/ai@0.3.0

0.2.2

Patch Changes

  • Updated dependencies [7573619]:
    • @tanstack/ai@0.2.2

0.2.1

Patch Changes

0.2.0

Minor Changes

  • Standard schema / standard json schema support for TanStack AI (#165)

Patch Changes

  • Updated dependencies [c5df33c]:
    • @tanstack/ai@0.2.0

0.1.0

Minor Changes

  • Split up adapters for better tree shaking into separate functionalities (#137)

Patch Changes

  • Updated dependencies [8d77614]:
    • @tanstack/ai@0.1.0

0.0.3

Patch Changes

  • Updated dependencies [52c3172]:
    • @tanstack/ai@0.0.3

0.0.2

Patch Changes

  • Made the fetch client used by the default connection adapters configurable. (#80)

  • Updated dependencies [64fda55]:

    • @tanstack/ai@0.0.2

0.0.1

Patch Changes

  • Initial release of TanStack AI (#72)

  • Updated dependencies [a9b54c2]:

    • @tanstack/ai@0.0.1