diff --git a/.changeset/code-mode-skills-worker-safe-root.md b/.changeset/code-mode-skills-worker-safe-root.md deleted file mode 100644 index 652b6baca..000000000 --- a/.changeset/code-mode-skills-worker-safe-root.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@tanstack/ai-code-mode-skills': minor ---- - -Make the `@tanstack/ai-code-mode-skills` root export Worker/browser-safe. - -The root entry previously re-exported `createFileSkillStorage` (via `export * from './storage'`), which eagerly pulled in `node:fs` / `node:path`. This broke Cloudflare Workers and browser bundlers even for consumers that only used non-storage helpers like `createSkillManagementTools` or `createSkillsSystemPrompt`. - -The Node-only file storage now lives **only** behind the `@tanstack/ai-code-mode-skills/storage` subpath. The root entry still re-exports the browser-safe `createMemorySkillStorage`. - -**Breaking:** import `createFileSkillStorage` from `@tanstack/ai-code-mode-skills/storage` instead of the package root. diff --git a/.changeset/structured-output-undo-null-widening.md b/.changeset/structured-output-undo-null-widening.md deleted file mode 100644 index 35f69fb12..000000000 --- a/.changeset/structured-output-undo-null-widening.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@tanstack/ai-utils': minor -'@tanstack/ai': minor -'@tanstack/openai-base': minor -'@tanstack/ai-openrouter': patch ---- - -Fix structured output validation rejecting `null` for optional fields, across both stream modes and every adapter. - -Strict-mode structured output widens optional fields to `required` + nullable, so the provider returns `null` for an absent optional. Validating that `null` against the original schema then failed, because `.optional()` means `T | undefined`, not `T | null` — surfacing as a `StandardSchemaValidationError` (e.g. `Invalid type: Expected string but received null`). - -The engine now undoes the widening as a single, schema-aware step the moment the structured output is captured, so the fix applies uniformly: - -- The strict-conversion pass records a `NullWideningMap` marking exactly the positions where it added `null`, so the response can be un-widened precisely — no re-deriving or guessing which nulls were synthetic. -- `@tanstack/ai-utils` adds `undoNullWidening(value, map)` — a counterpart to `transformNullsToUndefined` that strips only the nulls the widening pass synthesized, preserving the ones a `.nullable()`/`.nullish()` field genuinely allows. -- The engine applies this via a new `finalStructuredOutput.normalize` hook the instant the result is captured, so **both** the `Promise` result **and** the streaming `structured-output.complete` event carry the un-widened object. Previously only the `Promise` path was corrected, and only for adapters that preserved provider nulls. -- `@tanstack/openai-base` adapters (and the OpenAI/Grok/Groq adapters built on them) no longer blind-strip every `null` from structured output via `transformStructuredOutput` — that default is now a passthrough. The blind strip masked the validation bug but also destroyed genuine `.nullable()` nulls; precise un-widening in the engine fixes both. The `transformStructuredOutput` hook remains for provider-specific reshaping. - -Adapters that already preserve provider nulls (`@tanstack/ai-openrouter`, Anthropic, Gemini, Ollama) now get correct un-widening on their streaming structured output too, not just `Promise`. diff --git a/.changeset/tool-first-parent-message-id.md b/.changeset/tool-first-parent-message-id.md deleted file mode 100644 index 8569432d5..000000000 --- a/.changeset/tool-first-parent-message-id.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -'@tanstack/ai-anthropic': patch -'@tanstack/openai-base': patch -'@tanstack/ai-openrouter': patch -'@tanstack/ai-gemini': patch -'@tanstack/ai-ollama': patch ---- - -Bind tool calls to the assistant message in tool-first streams by setting AG-UI's -`parentMessageId` on `TOOL_CALL_START`. - -When a provider streams a tool call **before** any text, the `StreamProcessor` had no -active assistant message to attach it to, so it created one under a temporary local id. -The later `TEXT_MESSAGE_START` then carried the real provider message id, forcing a -mid-stream id change — which destabilizes `UIMessage.id` and can remount the message -subtree in `useChat` (React list keys, etc.). See #477. - -Every text adapter generates one stable assistant message id per stream and already uses -it for `TEXT_MESSAGE_START`; they now also emit it as `parentMessageId` on -`TOOL_CALL_START`. The processor reads `chunk.parentMessageId` (`?? active assistant id`) -so the message is created with the correct id immediately and the subsequent -`TEXT_MESSAGE_START` matches — no rename, no remount. - -Fixed across all adapters that emit `TOOL_CALL_START` (Anthropic, OpenAI Responses + -Chat Completions via `@tanstack/openai-base`, OpenRouter, Gemini including the -experimental text-interactions adapter, and Ollama). diff --git a/packages/ai-angular/CHANGELOG.md b/packages/ai-angular/CHANGELOG.md index d4587ed13..8ae38d912 100644 --- a/packages/ai-angular/CHANGELOG.md +++ b/packages/ai-angular/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-angular +## 0.1.6 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.1.5 ### Patch Changes diff --git a/packages/ai-angular/package.json b/packages/ai-angular/package.json index d864b4361..ac665a7f1 100644 --- a/packages/ai-angular/package.json +++ b/packages/ai-angular/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-angular", - "version": "0.1.5", + "version": "0.1.6", "description": "Angular signals integration for TanStack AI streaming chat, structured outputs, and media generation.", "author": "", "license": "MIT", diff --git a/packages/ai-anthropic/CHANGELOG.md b/packages/ai-anthropic/CHANGELOG.md index 6055c9077..0c34d9534 100644 --- a/packages/ai-anthropic/CHANGELOG.md +++ b/packages/ai-anthropic/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-anthropic +## 0.15.7 + +### Patch Changes + +- [#480](https://github.com/TanStack/ai/pull/480) [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e) - Bind tool calls to the assistant message in tool-first streams by setting AG-UI's + `parentMessageId` on `TOOL_CALL_START`. + + When a provider streams a tool call **before** any text, the `StreamProcessor` had no + active assistant message to attach it to, so it created one under a temporary local id. + The later `TEXT_MESSAGE_START` then carried the real provider message id, forcing a + mid-stream id change — which destabilizes `UIMessage.id` and can remount the message + subtree in `useChat` (React list keys, etc.). See [#477](https://github.com/TanStack/ai/issues/477). + + Every text adapter generates one stable assistant message id per stream and already uses + it for `TEXT_MESSAGE_START`; they now also emit it as `parentMessageId` on + `TOOL_CALL_START`. The processor reads `chunk.parentMessageId` (`?? active assistant id`) + so the message is created with the correct id immediately and the subsequent + `TEXT_MESSAGE_START` matches — no rename, no remount. + + Fixed across all adapters that emit `TOOL_CALL_START` (Anthropic, OpenAI Responses + + Chat Completions via `@tanstack/openai-base`, OpenRouter, Gemini including the + experimental text-interactions adapter, and Ollama). + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + ## 0.15.6 ### Patch Changes diff --git a/packages/ai-anthropic/package.json b/packages/ai-anthropic/package.json index c726ce1ae..11eadb684 100644 --- a/packages/ai-anthropic/package.json +++ b/packages/ai-anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-anthropic", - "version": "0.15.6", + "version": "0.15.7", "description": "Anthropic Claude adapter for TanStack AI chat, tool calling, thinking, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-client/CHANGELOG.md b/packages/ai-client/CHANGELOG.md index 0a0b09968..a079c0d21 100644 --- a/packages/ai-client/CHANGELOG.md +++ b/packages/ai-client/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-client +## 0.18.2 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-event-client@0.6.5 + ## 0.18.1 ### Patch Changes diff --git a/packages/ai-client/package.json b/packages/ai-client/package.json index 555c76516..f3ca8aadd 100644 --- a/packages/ai-client/package.json +++ b/packages/ai-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-client", - "version": "0.18.1", + "version": "0.18.2", "description": "Framework-agnostic headless client for TanStack AI chat, realtime sessions, streaming transports, and media generations.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-code-mode-skills/CHANGELOG.md b/packages/ai-code-mode-skills/CHANGELOG.md index b7fa1f564..590c76a06 100644 --- a/packages/ai-code-mode-skills/CHANGELOG.md +++ b/packages/ai-code-mode-skills/CHANGELOG.md @@ -1,5 +1,23 @@ # @tanstack/ai-code-mode-skills +## 0.3.0 + +### Minor Changes + +- [#736](https://github.com/TanStack/ai/pull/736) [`6caac6b`](https://github.com/TanStack/ai/commit/6caac6b52881b0d5a9f7dc741e3f70a00b7137a9) - Make the `@tanstack/ai-code-mode-skills` root export Worker/browser-safe. + + The root entry previously re-exported `createFileSkillStorage` (via `export * from './storage'`), which eagerly pulled in `node:fs` / `node:path`. This broke Cloudflare Workers and browser bundlers even for consumers that only used non-storage helpers like `createSkillManagementTools` or `createSkillsSystemPrompt`. + + The Node-only file storage now lives **only** behind the `@tanstack/ai-code-mode-skills/storage` subpath. The root entry still re-exports the browser-safe `createMemorySkillStorage`. + + **Breaking:** import `createFileSkillStorage` from `@tanstack/ai-code-mode-skills/storage` instead of the package root. + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-code-mode@0.2.11 + ## 0.2.10 ### Patch Changes diff --git a/packages/ai-code-mode-skills/package.json b/packages/ai-code-mode-skills/package.json index 6aa183a57..28678f88e 100644 --- a/packages/ai-code-mode-skills/package.json +++ b/packages/ai-code-mode-skills/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-code-mode-skills", - "version": "0.2.10", + "version": "0.3.0", "description": "Persistent runtime skill library for TanStack AI Code Mode agents and sandboxed tool orchestration.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-code-mode/CHANGELOG.md b/packages/ai-code-mode/CHANGELOG.md index a6c4f9496..c5dc0e1a9 100644 --- a/packages/ai-code-mode/CHANGELOG.md +++ b/packages/ai-code-mode/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-code-mode +## 0.2.11 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + ## 0.2.10 ### Patch Changes diff --git a/packages/ai-code-mode/package.json b/packages/ai-code-mode/package.json index 5aa101d64..7158025d3 100644 --- a/packages/ai-code-mode/package.json +++ b/packages/ai-code-mode/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-code-mode", - "version": "0.2.10", + "version": "0.2.11", "description": "Secure TypeScript Code Mode for TanStack AI agents to execute sandboxed tool orchestration programs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-devtools/CHANGELOG.md b/packages/ai-devtools/CHANGELOG.md index 23dd876f4..80187a717 100644 --- a/packages/ai-devtools/CHANGELOG.md +++ b/packages/ai-devtools/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-devtools-core +## 0.4.14 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-event-client@0.6.5 + ## 0.4.13 ### Patch Changes diff --git a/packages/ai-devtools/package.json b/packages/ai-devtools/package.json index 326945ae5..ff92441e6 100644 --- a/packages/ai-devtools/package.json +++ b/packages/ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-devtools-core", - "version": "0.4.13", + "version": "0.4.14", "description": "Core TanStack AI Devtools plugin for inspecting chat messages, tool calls, streams, and errors.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-elevenlabs/CHANGELOG.md b/packages/ai-elevenlabs/CHANGELOG.md index fc37340cb..4b3613287 100644 --- a/packages/ai-elevenlabs/CHANGELOG.md +++ b/packages/ai-elevenlabs/CHANGELOG.md @@ -1,5 +1,14 @@ # @tanstack/ai-elevenlabs +## 0.2.26 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.2.25 ### Patch Changes diff --git a/packages/ai-elevenlabs/package.json b/packages/ai-elevenlabs/package.json index fee350c75..a719bca1a 100644 --- a/packages/ai-elevenlabs/package.json +++ b/packages/ai-elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-elevenlabs", - "version": "0.2.25", + "version": "0.2.26", "description": "ElevenLabs adapter for TanStack AI realtime voice, text-to-speech, transcription, music, and sound effects.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-event-client/CHANGELOG.md b/packages/ai-event-client/CHANGELOG.md index d7a556ab4..6f332981d 100644 --- a/packages/ai-event-client/CHANGELOG.md +++ b/packages/ai-event-client/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-event-client +## 0.6.5 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + ## 0.6.4 ### Patch Changes diff --git a/packages/ai-event-client/package.json b/packages/ai-event-client/package.json index c0e216959..ec04ea530 100644 --- a/packages/ai-event-client/package.json +++ b/packages/ai-event-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-event-client", - "version": "0.6.4", + "version": "0.6.5", "description": "Typed event client for TanStack AI devtools, observability, and streamed runtime events.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-fal/CHANGELOG.md b/packages/ai-fal/CHANGELOG.md index 935fbbaa6..9bdd3f374 100644 --- a/packages/ai-fal/CHANGELOG.md +++ b/packages/ai-fal/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-fal +## 0.9.2 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + ## 0.9.1 ### Patch Changes diff --git a/packages/ai-fal/package.json b/packages/ai-fal/package.json index 17a41506a..aac3571f8 100644 --- a/packages/ai-fal/package.json +++ b/packages/ai-fal/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-fal", - "version": "0.9.1", + "version": "0.9.2", "description": "fal.ai adapter for TanStack AI image, video, audio, speech, and transcription generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-gemini/CHANGELOG.md b/packages/ai-gemini/CHANGELOG.md index 07428e4be..d50dbf0ad 100644 --- a/packages/ai-gemini/CHANGELOG.md +++ b/packages/ai-gemini/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-gemini +## 0.17.2 + +### Patch Changes + +- [#480](https://github.com/TanStack/ai/pull/480) [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e) - Bind tool calls to the assistant message in tool-first streams by setting AG-UI's + `parentMessageId` on `TOOL_CALL_START`. + + When a provider streams a tool call **before** any text, the `StreamProcessor` had no + active assistant message to attach it to, so it created one under a temporary local id. + The later `TEXT_MESSAGE_START` then carried the real provider message id, forcing a + mid-stream id change — which destabilizes `UIMessage.id` and can remount the message + subtree in `useChat` (React list keys, etc.). See [#477](https://github.com/TanStack/ai/issues/477). + + Every text adapter generates one stable assistant message id per stream and already uses + it for `TEXT_MESSAGE_START`; they now also emit it as `parentMessageId` on + `TOOL_CALL_START`. The processor reads `chunk.parentMessageId` (`?? active assistant id`) + so the message is created with the correct id immediately and the subsequent + `TEXT_MESSAGE_START` matches — no rename, no remount. + + Fixed across all adapters that emit `TOOL_CALL_START` (Anthropic, OpenAI Responses + + Chat Completions via `@tanstack/openai-base`, OpenRouter, Gemini including the + experimental text-interactions adapter, and Ollama). + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + ## 0.17.1 ### Patch Changes diff --git a/packages/ai-gemini/package.json b/packages/ai-gemini/package.json index ac71f1b71..b23744b59 100644 --- a/packages/ai-gemini/package.json +++ b/packages/ai-gemini/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-gemini", - "version": "0.17.1", + "version": "0.17.2", "description": "Google Gemini adapter for TanStack AI chat, images, speech, audio generation, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-grok/CHANGELOG.md b/packages/ai-grok/CHANGELOG.md index b8259eaed..f2ed5e4e4 100644 --- a/packages/ai-grok/CHANGELOG.md +++ b/packages/ai-grok/CHANGELOG.md @@ -1,5 +1,14 @@ # @tanstack/ai-grok +## 0.12.4 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a), [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + - @tanstack/openai-base@0.9.0 + ## 0.12.3 ### Patch Changes diff --git a/packages/ai-grok/package.json b/packages/ai-grok/package.json index 636b32337..bda07e144 100644 --- a/packages/ai-grok/package.json +++ b/packages/ai-grok/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-grok", - "version": "0.12.3", + "version": "0.12.4", "description": "xAI Grok adapter for TanStack AI chat, image generation, realtime, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-groq/CHANGELOG.md b/packages/ai-groq/CHANGELOG.md index 92e4d9977..aa602e31b 100644 --- a/packages/ai-groq/CHANGELOG.md +++ b/packages/ai-groq/CHANGELOG.md @@ -1,5 +1,14 @@ # @tanstack/ai-groq +## 0.4.10 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a), [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + - @tanstack/openai-base@0.9.0 + ## 0.4.9 ### Patch Changes diff --git a/packages/ai-groq/package.json b/packages/ai-groq/package.json index 2a1efa1c9..426444719 100644 --- a/packages/ai-groq/package.json +++ b/packages/ai-groq/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-groq", - "version": "0.4.9", + "version": "0.4.10", "description": "Groq adapter for TanStack AI low-latency chat, tool calling, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-isolate-cloudflare/CHANGELOG.md b/packages/ai-isolate-cloudflare/CHANGELOG.md index cf1d57cfd..051b9f8a3 100644 --- a/packages/ai-isolate-cloudflare/CHANGELOG.md +++ b/packages/ai-isolate-cloudflare/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-isolate-cloudflare +## 0.2.27 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-code-mode@0.2.11 + ## 0.2.26 ### Patch Changes diff --git a/packages/ai-isolate-cloudflare/package.json b/packages/ai-isolate-cloudflare/package.json index 7af0b3b4e..ff663f184 100644 --- a/packages/ai-isolate-cloudflare/package.json +++ b/packages/ai-isolate-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-cloudflare", - "version": "0.2.26", + "version": "0.2.27", "description": "Cloudflare Workers sandbox driver for TanStack AI Code Mode TypeScript execution at the edge.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-isolate-node/CHANGELOG.md b/packages/ai-isolate-node/CHANGELOG.md index bda65d49a..b0bee1ce4 100644 --- a/packages/ai-isolate-node/CHANGELOG.md +++ b/packages/ai-isolate-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-isolate-node +## 0.1.36 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-code-mode@0.2.11 + ## 0.1.35 ### Patch Changes diff --git a/packages/ai-isolate-node/package.json b/packages/ai-isolate-node/package.json index 5663ed032..419a32dc3 100644 --- a/packages/ai-isolate-node/package.json +++ b/packages/ai-isolate-node/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-node", - "version": "0.1.35", + "version": "0.1.36", "description": "Node.js isolated-vm sandbox driver for TanStack AI Code Mode TypeScript execution.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-isolate-quickjs/CHANGELOG.md b/packages/ai-isolate-quickjs/CHANGELOG.md index a703649e9..e94212937 100644 --- a/packages/ai-isolate-quickjs/CHANGELOG.md +++ b/packages/ai-isolate-quickjs/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-isolate-quickjs +## 0.1.36 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-code-mode@0.2.11 + ## 0.1.35 ### Patch Changes diff --git a/packages/ai-isolate-quickjs/package.json b/packages/ai-isolate-quickjs/package.json index efc4fd3aa..b255a58c4 100644 --- a/packages/ai-isolate-quickjs/package.json +++ b/packages/ai-isolate-quickjs/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-quickjs", - "version": "0.1.35", + "version": "0.1.36", "description": "QuickJS WASM sandbox driver for TanStack AI Code Mode TypeScript execution across runtimes.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-mcp/CHANGELOG.md b/packages/ai-mcp/CHANGELOG.md index d1b7ba013..f922189f0 100644 --- a/packages/ai-mcp/CHANGELOG.md +++ b/packages/ai-mcp/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-mcp +## 0.1.6 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + ## 0.1.5 ### Patch Changes diff --git a/packages/ai-mcp/package.json b/packages/ai-mcp/package.json index 109573d04..d3d26818e 100644 --- a/packages/ai-mcp/package.json +++ b/packages/ai-mcp/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-mcp", - "version": "0.1.5", + "version": "0.1.6", "description": "Host-side Model Context Protocol client for TanStack AI: discover and run MCP server tools, resources, and prompts in any adapter's chat() loop, with generated end-to-end types.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-ollama/CHANGELOG.md b/packages/ai-ollama/CHANGELOG.md index 5db641d7a..a38c1adc0 100644 --- a/packages/ai-ollama/CHANGELOG.md +++ b/packages/ai-ollama/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-ollama +## 0.8.7 + +### Patch Changes + +- [#480](https://github.com/TanStack/ai/pull/480) [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e) - Bind tool calls to the assistant message in tool-first streams by setting AG-UI's + `parentMessageId` on `TOOL_CALL_START`. + + When a provider streams a tool call **before** any text, the `StreamProcessor` had no + active assistant message to attach it to, so it created one under a temporary local id. + The later `TEXT_MESSAGE_START` then carried the real provider message id, forcing a + mid-stream id change — which destabilizes `UIMessage.id` and can remount the message + subtree in `useChat` (React list keys, etc.). See [#477](https://github.com/TanStack/ai/issues/477). + + Every text adapter generates one stable assistant message id per stream and already uses + it for `TEXT_MESSAGE_START`; they now also emit it as `parentMessageId` on + `TOOL_CALL_START`. The processor reads `chunk.parentMessageId` (`?? active assistant id`) + so the message is created with the correct id immediately and the subsequent + `TEXT_MESSAGE_START` matches — no rename, no remount. + + Fixed across all adapters that emit `TOOL_CALL_START` (Anthropic, OpenAI Responses + + Chat Completions via `@tanstack/openai-base`, OpenRouter, Gemini including the + experimental text-interactions adapter, and Ollama). + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + ## 0.8.6 ### Patch Changes diff --git a/packages/ai-ollama/package.json b/packages/ai-ollama/package.json index 925f53b00..321b12d06 100644 --- a/packages/ai-ollama/package.json +++ b/packages/ai-ollama/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-ollama", - "version": "0.8.6", + "version": "0.8.7", "description": "Ollama adapter for TanStack AI local LLM chat, tool calling, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-openai/CHANGELOG.md b/packages/ai-openai/CHANGELOG.md index 5098b811c..ab5560be9 100644 --- a/packages/ai-openai/CHANGELOG.md +++ b/packages/ai-openai/CHANGELOG.md @@ -1,5 +1,15 @@ # @tanstack/ai-openai +## 0.15.4 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a), [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + - @tanstack/openai-base@0.9.0 + - @tanstack/ai-client@0.18.2 + ## 0.15.3 ### Patch Changes diff --git a/packages/ai-openai/package.json b/packages/ai-openai/package.json index b366d7f40..7fc1ad892 100644 --- a/packages/ai-openai/package.json +++ b/packages/ai-openai/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-openai", - "version": "0.15.3", + "version": "0.15.4", "description": "OpenAI adapter for TanStack AI chat, tools, images, video, speech, transcription, realtime, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-openrouter/CHANGELOG.md b/packages/ai-openrouter/CHANGELOG.md index c7cb26dbb..5e0b51bcb 100644 --- a/packages/ai-openrouter/CHANGELOG.md +++ b/packages/ai-openrouter/CHANGELOG.md @@ -1,5 +1,44 @@ # @tanstack/ai-openrouter +## 0.14.2 + +### Patch Changes + +- [#732](https://github.com/TanStack/ai/pull/732) [`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a) - Fix structured output validation rejecting `null` for optional fields, across both stream modes and every adapter. + + Strict-mode structured output widens optional fields to `required` + nullable, so the provider returns `null` for an absent optional. Validating that `null` against the original schema then failed, because `.optional()` means `T | undefined`, not `T | null` — surfacing as a `StandardSchemaValidationError` (e.g. `Invalid type: Expected string but received null`). + + The engine now undoes the widening as a single, schema-aware step the moment the structured output is captured, so the fix applies uniformly: + - The strict-conversion pass records a `NullWideningMap` marking exactly the positions where it added `null`, so the response can be un-widened precisely — no re-deriving or guessing which nulls were synthetic. + - `@tanstack/ai-utils` adds `undoNullWidening(value, map)` — a counterpart to `transformNullsToUndefined` that strips only the nulls the widening pass synthesized, preserving the ones a `.nullable()`/`.nullish()` field genuinely allows. + - The engine applies this via a new `finalStructuredOutput.normalize` hook the instant the result is captured, so **both** the `Promise` result **and** the streaming `structured-output.complete` event carry the un-widened object. Previously only the `Promise` path was corrected, and only for adapters that preserved provider nulls. + - `@tanstack/openai-base` adapters (and the OpenAI/Grok/Groq adapters built on them) no longer blind-strip every `null` from structured output via `transformStructuredOutput` — that default is now a passthrough. The blind strip masked the validation bug but also destroyed genuine `.nullable()` nulls; precise un-widening in the engine fixes both. The `transformStructuredOutput` hook remains for provider-specific reshaping. + + Adapters that already preserve provider nulls (`@tanstack/ai-openrouter`, Anthropic, Gemini, Ollama) now get correct un-widening on their streaming structured output too, not just `Promise`. + +- [#480](https://github.com/TanStack/ai/pull/480) [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e) - Bind tool calls to the assistant message in tool-first streams by setting AG-UI's + `parentMessageId` on `TOOL_CALL_START`. + + When a provider streams a tool call **before** any text, the `StreamProcessor` had no + active assistant message to attach it to, so it created one under a temporary local id. + The later `TEXT_MESSAGE_START` then carried the real provider message id, forcing a + mid-stream id change — which destabilizes `UIMessage.id` and can remount the message + subtree in `useChat` (React list keys, etc.). See [#477](https://github.com/TanStack/ai/issues/477). + + Every text adapter generates one stable assistant message id per stream and already uses + it for `TEXT_MESSAGE_START`; they now also emit it as `parentMessageId` on + `TOOL_CALL_START`. The processor reads `chunk.parentMessageId` (`?? active assistant id`) + so the message is created with the correct id immediately and the subsequent + `TEXT_MESSAGE_START` matches — no rename, no remount. + + Fixed across all adapters that emit `TOOL_CALL_START` (Anthropic, OpenAI Responses + + Chat Completions via `@tanstack/openai-base`, OpenRouter, Gemini including the + experimental text-interactions adapter, and Ollama). + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + ## 0.14.1 ### Patch Changes diff --git a/packages/ai-openrouter/package.json b/packages/ai-openrouter/package.json index f129f958a..5f5002881 100644 --- a/packages/ai-openrouter/package.json +++ b/packages/ai-openrouter/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-openrouter", - "version": "0.14.1", + "version": "0.14.2", "description": "TanStack AI adapter for OpenRouter chat, provider tools, structured outputs, and access to hundreds of LLMs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-preact/CHANGELOG.md b/packages/ai-preact/CHANGELOG.md index 0d6604d12..95cd50549 100644 --- a/packages/ai-preact/CHANGELOG.md +++ b/packages/ai-preact/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-preact +## 0.9.11 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.9.10 ### Patch Changes diff --git a/packages/ai-preact/package.json b/packages/ai-preact/package.json index af7a5050a..873d65878 100644 --- a/packages/ai-preact/package.json +++ b/packages/ai-preact/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-preact", - "version": "0.9.10", + "version": "0.9.11", "description": "Preact hooks for TanStack AI streaming chat and typed messages.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-react/CHANGELOG.md b/packages/ai-react/CHANGELOG.md index bb85cacf0..bca5ce864 100644 --- a/packages/ai-react/CHANGELOG.md +++ b/packages/ai-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-react +## 0.15.11 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.15.10 ### Patch Changes diff --git a/packages/ai-react/package.json b/packages/ai-react/package.json index de218122a..ee2e32460 100644 --- a/packages/ai-react/package.json +++ b/packages/ai-react/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-react", - "version": "0.15.10", + "version": "0.15.11", "description": "React hooks for TanStack AI streaming chat, realtime voice, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-solid/CHANGELOG.md b/packages/ai-solid/CHANGELOG.md index d67799eb5..5cca9e78b 100644 --- a/packages/ai-solid/CHANGELOG.md +++ b/packages/ai-solid/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-solid +## 0.13.11 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.13.10 ### Patch Changes diff --git a/packages/ai-solid/package.json b/packages/ai-solid/package.json index ce8a74b8b..67e6b97a6 100644 --- a/packages/ai-solid/package.json +++ b/packages/ai-solid/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-solid", - "version": "0.13.10", + "version": "0.13.11", "description": "Solid hooks for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-svelte/CHANGELOG.md b/packages/ai-svelte/CHANGELOG.md index cee93a952..56146c833 100644 --- a/packages/ai-svelte/CHANGELOG.md +++ b/packages/ai-svelte/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-svelte +## 0.13.11 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.13.10 ### Patch Changes diff --git a/packages/ai-svelte/package.json b/packages/ai-svelte/package.json index dd8ee4a73..ca74e02d8 100644 --- a/packages/ai-svelte/package.json +++ b/packages/ai-svelte/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-svelte", - "version": "0.13.10", + "version": "0.13.11", "description": "Svelte 5 bindings for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-utils/CHANGELOG.md b/packages/ai-utils/CHANGELOG.md index 10fb96af3..84874f1e4 100644 --- a/packages/ai-utils/CHANGELOG.md +++ b/packages/ai-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @tanstack/ai-utils +## 0.3.0 + +### Minor Changes + +- [#732](https://github.com/TanStack/ai/pull/732) [`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a) - Fix structured output validation rejecting `null` for optional fields, across both stream modes and every adapter. + + Strict-mode structured output widens optional fields to `required` + nullable, so the provider returns `null` for an absent optional. Validating that `null` against the original schema then failed, because `.optional()` means `T | undefined`, not `T | null` — surfacing as a `StandardSchemaValidationError` (e.g. `Invalid type: Expected string but received null`). + + The engine now undoes the widening as a single, schema-aware step the moment the structured output is captured, so the fix applies uniformly: + - The strict-conversion pass records a `NullWideningMap` marking exactly the positions where it added `null`, so the response can be un-widened precisely — no re-deriving or guessing which nulls were synthetic. + - `@tanstack/ai-utils` adds `undoNullWidening(value, map)` — a counterpart to `transformNullsToUndefined` that strips only the nulls the widening pass synthesized, preserving the ones a `.nullable()`/`.nullish()` field genuinely allows. + - The engine applies this via a new `finalStructuredOutput.normalize` hook the instant the result is captured, so **both** the `Promise` result **and** the streaming `structured-output.complete` event carry the un-widened object. Previously only the `Promise` path was corrected, and only for adapters that preserved provider nulls. + - `@tanstack/openai-base` adapters (and the OpenAI/Grok/Groq adapters built on them) no longer blind-strip every `null` from structured output via `transformStructuredOutput` — that default is now a passthrough. The blind strip masked the validation bug but also destroyed genuine `.nullable()` nulls; precise un-widening in the engine fixes both. The `transformStructuredOutput` hook remains for provider-specific reshaping. + + Adapters that already preserve provider nulls (`@tanstack/ai-openrouter`, Anthropic, Gemini, Ollama) now get correct un-widening on their streaming structured output too, not just `Promise`. + ## 0.2.2 ### Patch Changes diff --git a/packages/ai-utils/package.json b/packages/ai-utils/package.json index a267d29f5..ec8f2a098 100644 --- a/packages/ai-utils/package.json +++ b/packages/ai-utils/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-utils", - "version": "0.2.2", + "version": "0.3.0", "description": "Shared TypeScript utilities for TanStack AI provider adapters and runtime packages.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-vue-ui/CHANGELOG.md b/packages/ai-vue-ui/CHANGELOG.md index 2f6e332c9..fd07c44dd 100644 --- a/packages/ai-vue-ui/CHANGELOG.md +++ b/packages/ai-vue-ui/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/ai-vue-ui +## 0.2.23 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-vue@0.13.11 + ## 0.2.22 ### Patch Changes diff --git a/packages/ai-vue-ui/package.json b/packages/ai-vue-ui/package.json index ca55c03a8..75daea92f 100644 --- a/packages/ai-vue-ui/package.json +++ b/packages/ai-vue-ui/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-vue-ui", - "version": "0.2.22", + "version": "0.2.23", "description": "Headless Vue components for building TanStack AI chat interfaces with streamed message parts.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-vue/CHANGELOG.md b/packages/ai-vue/CHANGELOG.md index fa85dbd43..9582a4e17 100644 --- a/packages/ai-vue/CHANGELOG.md +++ b/packages/ai-vue/CHANGELOG.md @@ -1,5 +1,13 @@ # @tanstack/ai-vue +## 0.13.11 + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai@0.34.0 + - @tanstack/ai-client@0.18.2 + ## 0.13.10 ### Patch Changes diff --git a/packages/ai-vue/package.json b/packages/ai-vue/package.json index 081b467d8..a0a002cc6 100644 --- a/packages/ai-vue/package.json +++ b/packages/ai-vue/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-vue", - "version": "0.13.10", + "version": "0.13.11", "description": "Vue composables for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 9e3e6a339..15bdd5c9f 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,27 @@ # @tanstack/ai +## 0.34.0 + +### Minor Changes + +- [#732](https://github.com/TanStack/ai/pull/732) [`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a) - Fix structured output validation rejecting `null` for optional fields, across both stream modes and every adapter. + + Strict-mode structured output widens optional fields to `required` + nullable, so the provider returns `null` for an absent optional. Validating that `null` against the original schema then failed, because `.optional()` means `T | undefined`, not `T | null` — surfacing as a `StandardSchemaValidationError` (e.g. `Invalid type: Expected string but received null`). + + The engine now undoes the widening as a single, schema-aware step the moment the structured output is captured, so the fix applies uniformly: + - The strict-conversion pass records a `NullWideningMap` marking exactly the positions where it added `null`, so the response can be un-widened precisely — no re-deriving or guessing which nulls were synthetic. + - `@tanstack/ai-utils` adds `undoNullWidening(value, map)` — a counterpart to `transformNullsToUndefined` that strips only the nulls the widening pass synthesized, preserving the ones a `.nullable()`/`.nullish()` field genuinely allows. + - The engine applies this via a new `finalStructuredOutput.normalize` hook the instant the result is captured, so **both** the `Promise` result **and** the streaming `structured-output.complete` event carry the un-widened object. Previously only the `Promise` path was corrected, and only for adapters that preserved provider nulls. + - `@tanstack/openai-base` adapters (and the OpenAI/Grok/Groq adapters built on them) no longer blind-strip every `null` from structured output via `transformStructuredOutput` — that default is now a passthrough. The blind strip masked the validation bug but also destroyed genuine `.nullable()` nulls; precise un-widening in the engine fixes both. The `transformStructuredOutput` hook remains for provider-specific reshaping. + + Adapters that already preserve provider nulls (`@tanstack/ai-openrouter`, Anthropic, Gemini, Ollama) now get correct un-widening on their streaming structured output too, not just `Promise`. + +### Patch Changes + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai-event-client@0.6.5 + ## 0.33.0 ### Minor Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index f0c26cea7..89003b427 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai", - "version": "0.33.0", + "version": "0.34.0", "description": "Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/openai-base/CHANGELOG.md b/packages/openai-base/CHANGELOG.md index f78ccf40a..cb404b741 100644 --- a/packages/openai-base/CHANGELOG.md +++ b/packages/openai-base/CHANGELOG.md @@ -1,5 +1,46 @@ # @tanstack/openai-base +## 0.9.0 + +### Minor Changes + +- [#732](https://github.com/TanStack/ai/pull/732) [`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a) - Fix structured output validation rejecting `null` for optional fields, across both stream modes and every adapter. + + Strict-mode structured output widens optional fields to `required` + nullable, so the provider returns `null` for an absent optional. Validating that `null` against the original schema then failed, because `.optional()` means `T | undefined`, not `T | null` — surfacing as a `StandardSchemaValidationError` (e.g. `Invalid type: Expected string but received null`). + + The engine now undoes the widening as a single, schema-aware step the moment the structured output is captured, so the fix applies uniformly: + - The strict-conversion pass records a `NullWideningMap` marking exactly the positions where it added `null`, so the response can be un-widened precisely — no re-deriving or guessing which nulls were synthetic. + - `@tanstack/ai-utils` adds `undoNullWidening(value, map)` — a counterpart to `transformNullsToUndefined` that strips only the nulls the widening pass synthesized, preserving the ones a `.nullable()`/`.nullish()` field genuinely allows. + - The engine applies this via a new `finalStructuredOutput.normalize` hook the instant the result is captured, so **both** the `Promise` result **and** the streaming `structured-output.complete` event carry the un-widened object. Previously only the `Promise` path was corrected, and only for adapters that preserved provider nulls. + - `@tanstack/openai-base` adapters (and the OpenAI/Grok/Groq adapters built on them) no longer blind-strip every `null` from structured output via `transformStructuredOutput` — that default is now a passthrough. The blind strip masked the validation bug but also destroyed genuine `.nullable()` nulls; precise un-widening in the engine fixes both. The `transformStructuredOutput` hook remains for provider-specific reshaping. + + Adapters that already preserve provider nulls (`@tanstack/ai-openrouter`, Anthropic, Gemini, Ollama) now get correct un-widening on their streaming structured output too, not just `Promise`. + +### Patch Changes + +- [#480](https://github.com/TanStack/ai/pull/480) [`eddfbbd`](https://github.com/TanStack/ai/commit/eddfbbdfd979cad7874f0fb33695c5c41331631e) - Bind tool calls to the assistant message in tool-first streams by setting AG-UI's + `parentMessageId` on `TOOL_CALL_START`. + + When a provider streams a tool call **before** any text, the `StreamProcessor` had no + active assistant message to attach it to, so it created one under a temporary local id. + The later `TEXT_MESSAGE_START` then carried the real provider message id, forcing a + mid-stream id change — which destabilizes `UIMessage.id` and can remount the message + subtree in `useChat` (React list keys, etc.). See [#477](https://github.com/TanStack/ai/issues/477). + + Every text adapter generates one stable assistant message id per stream and already uses + it for `TEXT_MESSAGE_START`; they now also emit it as `parentMessageId` on + `TOOL_CALL_START`. The processor reads `chunk.parentMessageId` (`?? active assistant id`) + so the message is created with the correct id immediately and the subsequent + `TEXT_MESSAGE_START` matches — no rename, no remount. + + Fixed across all adapters that emit `TOOL_CALL_START` (Anthropic, OpenAI Responses + + Chat Completions via `@tanstack/openai-base`, OpenRouter, Gemini including the + experimental text-interactions adapter, and Ollama). + +- Updated dependencies [[`31de22b`](https://github.com/TanStack/ai/commit/31de22b1ae780c53e3abbf9cf17e1db7b62de84a)]: + - @tanstack/ai-utils@0.3.0 + - @tanstack/ai@0.34.0 + ## 0.8.8 ### Patch Changes diff --git a/packages/openai-base/package.json b/packages/openai-base/package.json index 22f72ba06..453f901bc 100644 --- a/packages/openai-base/package.json +++ b/packages/openai-base/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/openai-base", - "version": "0.8.8", + "version": "0.9.0", "description": "Shared OpenAI SDK base adapters for TanStack AI providers using Chat Completions and Responses APIs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/preact-ai-devtools/CHANGELOG.md b/packages/preact-ai-devtools/CHANGELOG.md index 3b495f1c1..1d4bc49d7 100644 --- a/packages/preact-ai-devtools/CHANGELOG.md +++ b/packages/preact-ai-devtools/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/preact-ai-devtools +## 0.1.57 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-devtools-core@0.4.14 + ## 0.1.56 ### Patch Changes diff --git a/packages/preact-ai-devtools/package.json b/packages/preact-ai-devtools/package.json index 0139abe51..f71ea6a3c 100644 --- a/packages/preact-ai-devtools/package.json +++ b/packages/preact-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/preact-ai-devtools", - "version": "0.1.56", + "version": "0.1.57", "description": "Preact Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-ai-devtools/CHANGELOG.md b/packages/react-ai-devtools/CHANGELOG.md index ca593f355..dc0357126 100644 --- a/packages/react-ai-devtools/CHANGELOG.md +++ b/packages/react-ai-devtools/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/react-ai-devtools +## 0.2.57 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-devtools-core@0.4.14 + ## 0.2.56 ### Patch Changes diff --git a/packages/react-ai-devtools/package.json b/packages/react-ai-devtools/package.json index 0ca1cbdf3..ba725380c 100644 --- a/packages/react-ai-devtools/package.json +++ b/packages/react-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-ai-devtools", - "version": "0.2.56", + "version": "0.2.57", "description": "React Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/solid-ai-devtools/CHANGELOG.md b/packages/solid-ai-devtools/CHANGELOG.md index 7282bf862..c9f034460 100644 --- a/packages/solid-ai-devtools/CHANGELOG.md +++ b/packages/solid-ai-devtools/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/solid-ai-devtools +## 0.2.57 + +### Patch Changes + +- Updated dependencies []: + - @tanstack/ai-devtools-core@0.4.14 + ## 0.2.56 ### Patch Changes diff --git a/packages/solid-ai-devtools/package.json b/packages/solid-ai-devtools/package.json index 29ec828c7..1ac3ea427 100644 --- a/packages/solid-ai-devtools/package.json +++ b/packages/solid-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-ai-devtools", - "version": "0.2.56", + "version": "0.2.57", "description": "Solid Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "Tanner Linsley", "license": "MIT",