From 12ac4c37ac94a563500fec885505480b16322458 Mon Sep 17 00:00:00 2001 From: Dylan Mozlowski Date: Wed, 2 Apr 2025 23:10:16 -0700 Subject: [PATCH 001/191] docs: fix typo (#5521) --- content/cookbook/05-node/51-call-tools-in-parallel.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/cookbook/05-node/51-call-tools-in-parallel.mdx b/content/cookbook/05-node/51-call-tools-in-parallel.mdx index 960884645d7c..e1b9cb8585ac 100644 --- a/content/cookbook/05-node/51-call-tools-in-parallel.mdx +++ b/content/cookbook/05-node/51-call-tools-in-parallel.mdx @@ -1,5 +1,5 @@ --- -title: Call Tools in Parallels +title: Call Tools in Parallel description: Learn how to call tools in parallel using the AI SDK and Node tags: ['node', 'tool use'] --- From fba2bd5aa57c5a5233575b785e65aef9c01f7d02 Mon Sep 17 00:00:00 2001 From: Amagi Date: Thu, 3 Apr 2025 14:10:31 +0800 Subject: [PATCH 002/191] docs: fix highlights in node.js guide (#5519) --- content/docs/02-getting-started/06-nodejs.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/docs/02-getting-started/06-nodejs.mdx b/content/docs/02-getting-started/06-nodejs.mdx index a6f0b945768c..f5ec7edce2de 100644 --- a/content/docs/02-getting-started/06-nodejs.mdx +++ b/content/docs/02-getting-started/06-nodejs.mdx @@ -149,7 +149,7 @@ Let's enhance your chatbot by adding a simple weather tool. Modify your `index.ts` file to include the new weather tool: -```ts filename="index.ts" highlight="2,4,25-36" +```ts filename="index.ts" highlight="2,4,25-38" import { openai } from '@ai-sdk/openai'; import { CoreMessage, streamText, tool } from 'ai'; import dotenv from 'dotenv'; @@ -289,7 +289,7 @@ To solve this, you can enable multi-step tool calls using `maxSteps`. This featu Modify your `index.ts` file to include the `maxSteps` option: -```ts filename="index.ts" highlight="37-40" +```ts filename="index.ts" highlight="39-42" import { openai } from '@ai-sdk/openai'; import { CoreMessage, streamText, tool } from 'ai'; import dotenv from 'dotenv'; @@ -362,7 +362,7 @@ By setting `maxSteps` to 5, you're allowing the model to use up to 5 "steps" for Update your `index.ts` file to add a new tool to convert the temperature from Celsius to Fahrenheit: -```ts filename="index.ts" highlight="36-45" +```ts filename="index.ts" highlight="38-49" import { openai } from '@ai-sdk/openai'; import { CoreMessage, streamText, tool } from 'ai'; import dotenv from 'dotenv'; From 1a027905eedf452ff880353d3470c27142eb3ab2 Mon Sep 17 00:00:00 2001 From: Philip Kiely - Baseten <98474633+philipkiely-baseten@users.noreply.github.com> Date: Thu, 3 Apr 2025 00:10:57 -0600 Subject: [PATCH 003/191] docs: update baseten community provider docs (#5517) --- .../40-baseten.mdx | 75 ++++++------------- examples/ai-core/src/stream-text/baseten.ts | 23 +----- 2 files changed, 24 insertions(+), 74 deletions(-) diff --git a/content/providers/02-openai-compatible-providers/40-baseten.mdx b/content/providers/02-openai-compatible-providers/40-baseten.mdx index 9d0b22e1030b..54ea3d5a12f6 100644 --- a/content/providers/02-openai-compatible-providers/40-baseten.mdx +++ b/content/providers/02-openai-compatible-providers/40-baseten.mdx @@ -32,38 +32,27 @@ To use Baseten, you can create a custom provider instance with the `createOpenAI ```ts import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; -const BASETEN_MODEL_ID = ''; -const BASETEN_DEPLOYMENT_ID = null; - -// see https://docs.baseten.co/api-reference/openai for more information -const basetenExtraPayload = { - model_id: BASETEN_MODEL_ID, - deployment_id: BASETEN_DEPLOYMENT_ID, -}; +const BASETEN_MODEL_ID = ''; // e.g. 5q3z8xcw +const BASETEN_MODEL_URL = `https://model-${BASETEN_MODEL_ID}.api.baseten.co/environments/production/sync/v1`; const baseten = createOpenAICompatible({ name: 'baseten', - apiKey: process.env.BASETEN_API_KEY, - baseURL: 'https://bridge.baseten.co/v1/direct', - fetch: async (url, request) => { - const bodyWithBasetenPayload = JSON.stringify({ - ...JSON.parse(request.body), - baseten: basetenExtraPayload, - }); - return await fetch(url, { ...request, body: bodyWithBasetenPayload }); + baseURL: BASETEN_MODEL_URL, + headers: { + Authorization: `Bearer ${process.env.BASETEN_API_KEY ?? ''}`, }, }); ``` -Be sure to have your `BASETEN_API_KEY` set in your environment and the model `deployment id` ready. The `deployment_id` will be given after you have deployed the model on Baseten. +Be sure to have your `BASETEN_API_KEY` set in your environment and the model `` ready. The `` will be given after you have deployed the model on Baseten. ## Language Models -You can create [Baseten models](https://baseten.co/models) using a provider instance. -The first argument is the served model name, e.g. `ultravox`. +You can create [Baseten models](https://www.baseten.co/library/) using a provider instance. +The first argument is the served model name, e.g. `llama`. ```ts -const model = baseten('ultravox'); +const model = baseten('llama'); ``` ### Example @@ -74,30 +63,19 @@ You can use Baseten language models to generate text with the `generateText` fun import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { generateText } from 'ai'; -const BASETEN_MODEL_ID = ''; -const BASETEN_DEPLOYMENT_ID = null; - -// see https://docs.baseten.co/api-reference/openai for more information -const basetenExtraPayload = { - model_id: BASETEN_MODEL_ID, - deployment_id: BASETEN_DEPLOYMENT_ID, -}; +const BASETEN_MODEL_ID = ''; // e.g. 5q3z8xcw +const BASETEN_MODEL_URL = `https://model-${BASETEN_MODEL_ID}.api.baseten.co/environments/production/sync/v1`; const baseten = createOpenAICompatible({ name: 'baseten', - apiKey: process.env.BASETEN_API_KEY, - baseURL: 'https://bridge.baseten.co/v1/direct', - fetch: async (url, request) => { - const bodyWithBasetenPayload = JSON.stringify({ - ...JSON.parse(request.body), - baseten: basetenExtraPayload, - }); - return await fetch(url, { ...request, body: bodyWithBasetenPayload }); + baseURL: BASETEN_MODEL_URL, + headers: { + Authorization: `Bearer ${process.env.BASETEN_API_KEY ?? ''}`, }, }); const { text } = await generateText({ - model: baseten('ultravox'), + model: baseten('llama'), prompt: 'Tell me about yourself in one sentence', }); @@ -110,30 +88,19 @@ Baseten language models are also able to generate text in a streaming fashion wi import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { streamText } from 'ai'; -const BASETEN_MODEL_ID = ''; -const BASETEN_DEPLOYMENT_ID = null; - -// see https://docs.baseten.co/api-reference/openai for more information -const basetenExtraPayload = { - model_id: BASETEN_MODEL_ID, - deployment_id: BASETEN_DEPLOYMENT_ID, -}; +const BASETEN_MODEL_ID = ''; // e.g. 5q3z8xcw +const BASETEN_MODEL_URL = `https://model-${BASETEN_MODEL_ID}.api.baseten.co/environments/production/sync/v1`; const baseten = createOpenAICompatible({ name: 'baseten', - apiKey: process.env.BASETEN_API_KEY, - baseURL: 'https://bridge.baseten.co/v1/direct', - fetch: async (url, request) => { - const bodyWithBasetenPayload = JSON.stringify({ - ...JSON.parse(request.body), - baseten: basetenExtraPayload, - }); - return await fetch(url, { ...request, body: bodyWithBasetenPayload }); + baseURL: BASETEN_MODEL_URL, + headers: { + Authorization: `Bearer ${process.env.BASETEN_API_KEY ?? ''}`, }, }); const result = streamText({ - model: baseten('ultravox'), + model: baseten('llama'), prompt: 'Tell me about yourself in one sentence', }); diff --git a/examples/ai-core/src/stream-text/baseten.ts b/examples/ai-core/src/stream-text/baseten.ts index b1d6995f4eb9..82d33a5b3406 100644 --- a/examples/ai-core/src/stream-text/baseten.ts +++ b/examples/ai-core/src/stream-text/baseten.ts @@ -1,32 +1,15 @@ import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { streamText } from 'ai'; -import 'dotenv/config'; -const BASETEN_MODEL_ID = ''; -const BASETEN_DEPLOYMENT_ID = null; - -// see https://docs.baseten.co/api-reference/openai for more information -const basetenExtraPayload = { - model_id: BASETEN_MODEL_ID, - deployment_id: BASETEN_DEPLOYMENT_ID, -}; +const BASETEN_MODEL_ID = ''; // e.g. 5q3z8xcw +const BASETEN_MODEL_URL = `https://model-${BASETEN_MODEL_ID}.api.baseten.co/environments/production/sync/v1`; const baseten = createOpenAICompatible({ name: 'baseten', + baseURL: BASETEN_MODEL_URL, headers: { Authorization: `Bearer ${process.env.BASETEN_API_KEY ?? ''}`, }, - baseURL: 'https://bridge.baseten.co/v1/direct', - fetch: async (url, request) => { - if (!request || !request.body) { - throw new Error('Request body is undefined'); - } - const bodyWithBasetenPayload = JSON.stringify({ - ...JSON.parse(String(request.body)), - baseten: basetenExtraPayload, - }); - return await fetch(url, { ...request, body: bodyWithBasetenPayload }); - }, }); async function main() { From 292f543cff6047c1611ec470be840393e6cd77fa Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Thu, 3 Apr 2025 00:37:14 -0700 Subject: [PATCH 004/191] fix (provider/google-vertex): fix anthropic support for image urls in messages (#5523) --- .changeset/silent-nails-taste.md | 6 ++++ .../google-vertex-anthropic-image-url.ts | 29 +++++++++++++++++++ .../google-vertex-anthropic-image.ts | 2 +- .../src/anthropic-messages-language-model.ts | 7 +++-- packages/anthropic/src/anthropic-provider.ts | 1 + .../google-vertex-anthropic-provider.ts | 1 + 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 .changeset/silent-nails-taste.md create mode 100644 examples/ai-core/src/stream-text/google-vertex-anthropic-image-url.ts diff --git a/.changeset/silent-nails-taste.md b/.changeset/silent-nails-taste.md new file mode 100644 index 000000000000..6f0965942318 --- /dev/null +++ b/.changeset/silent-nails-taste.md @@ -0,0 +1,6 @@ +--- +'@ai-sdk/google-vertex': patch +'@ai-sdk/anthropic': patch +--- + +fix (provider/google-vertex): fix anthropic support for image urls in messages diff --git a/examples/ai-core/src/stream-text/google-vertex-anthropic-image-url.ts b/examples/ai-core/src/stream-text/google-vertex-anthropic-image-url.ts new file mode 100644 index 000000000000..f35c2fa4c2d4 --- /dev/null +++ b/examples/ai-core/src/stream-text/google-vertex-anthropic-image-url.ts @@ -0,0 +1,29 @@ +import 'dotenv/config'; +import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; +import { streamText } from 'ai'; +import fs from 'node:fs'; + +async function main() { + const result = streamText({ + model: vertexAnthropic('claude-3-7-sonnet@20250219'), + messages: [ + { + role: 'user', + content: [ + { type: 'text', text: 'Describe the image in detail.' }, + { + type: 'image', + image: + 'https://github.com/vercel/ai/blob/main/examples/ai-core/data/comic-cat.png?raw=true', + }, + ], + }, + ], + }); + + for await (const textPart of result.textStream) { + process.stdout.write(textPart); + } +} + +main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/google-vertex-anthropic-image.ts b/examples/ai-core/src/stream-text/google-vertex-anthropic-image.ts index c6ec43c63211..0e3d8933773f 100644 --- a/examples/ai-core/src/stream-text/google-vertex-anthropic-image.ts +++ b/examples/ai-core/src/stream-text/google-vertex-anthropic-image.ts @@ -5,7 +5,7 @@ import fs from 'node:fs'; async function main() { const result = streamText({ - model: vertexAnthropic('claude-3-5-sonnet-v2@20241022'), + model: vertexAnthropic('claude-3-7-sonnet@20250219'), messages: [ { role: 'user', diff --git a/packages/anthropic/src/anthropic-messages-language-model.ts b/packages/anthropic/src/anthropic-messages-language-model.ts index ddc063a660dc..167a5a9b46af 100644 --- a/packages/anthropic/src/anthropic-messages-language-model.ts +++ b/packages/anthropic/src/anthropic-messages-language-model.ts @@ -1,5 +1,4 @@ import { - InvalidArgumentError, LanguageModelV1, LanguageModelV1CallWarning, LanguageModelV1FinishReason, @@ -33,6 +32,7 @@ type AnthropicMessagesConfig = { provider: string; baseURL: string; headers: Resolvable>; + supportsImageUrls: boolean; fetch?: FetchFunction; buildRequestUrl?: (baseURL: string, isStreaming: boolean) => string; transformRequestBody?: (args: Record) => Record; @@ -41,7 +41,6 @@ type AnthropicMessagesConfig = { export class AnthropicMessagesLanguageModel implements LanguageModelV1 { readonly specificationVersion = 'v1'; readonly defaultObjectGenerationMode = 'tool'; - readonly supportsImageUrls = true; readonly modelId: AnthropicMessagesModelId; readonly settings: AnthropicMessagesSettings; @@ -62,6 +61,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV1 { return this.config.provider; } + get supportsImageUrls(): boolean { + return this.config.supportsImageUrls; + } + private async getArgs({ mode, prompt, diff --git a/packages/anthropic/src/anthropic-provider.ts b/packages/anthropic/src/anthropic-provider.ts index 82440c29e347..7a598e834f22 100644 --- a/packages/anthropic/src/anthropic-provider.ts +++ b/packages/anthropic/src/anthropic-provider.ts @@ -109,6 +109,7 @@ export function createAnthropic( baseURL, headers: getHeaders, fetch: options.fetch, + supportsImageUrls: true, }); const provider = function ( diff --git a/packages/google-vertex/src/anthropic/google-vertex-anthropic-provider.ts b/packages/google-vertex/src/anthropic/google-vertex-anthropic-provider.ts index 1c14853eddc0..e80447d79852 100644 --- a/packages/google-vertex/src/anthropic/google-vertex-anthropic-provider.ts +++ b/packages/google-vertex/src/anthropic/google-vertex-anthropic-provider.ts @@ -100,6 +100,7 @@ export function createVertexAnthropic( baseURL, headers: options.headers ?? {}, fetch: options.fetch, + supportsImageUrls: false, buildRequestUrl: (baseURL, isStreaming) => `${baseURL}/${modelId}:${ isStreaming ? 'streamRawPredict' : 'rawPredict' From 8362d21ac03a49f9d0d77b65762aec56a12f79b1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 09:38:20 +0200 Subject: [PATCH 005/191] Version Packages (#5525) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/silent-nails-taste.md | 6 ------ examples/ai-core/package.json | 4 ++-- examples/next-google-vertex/package.json | 2 +- examples/next-openai/package.json | 4 ++-- packages/anthropic/CHANGELOG.md | 6 ++++++ packages/anthropic/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 8 ++++++++ packages/google-vertex/package.json | 4 ++-- pnpm-lock.yaml | 26 ++++++++++++------------ 9 files changed, 35 insertions(+), 27 deletions(-) delete mode 100644 .changeset/silent-nails-taste.md diff --git a/.changeset/silent-nails-taste.md b/.changeset/silent-nails-taste.md deleted file mode 100644 index 6f0965942318..000000000000 --- a/.changeset/silent-nails-taste.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@ai-sdk/google-vertex': patch -'@ai-sdk/anthropic': patch ---- - -fix (provider/google-vertex): fix anthropic support for image urls in messages diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 261e7ea931d7..d4ec016bb548 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/amazon-bedrock": "2.2.4", - "@ai-sdk/anthropic": "1.2.4", + "@ai-sdk/anthropic": "1.2.5", "@ai-sdk/azure": "1.3.6", "@ai-sdk/cerebras": "0.2.5", "@ai-sdk/cohere": "1.2.4", @@ -13,7 +13,7 @@ "@ai-sdk/fal": "0.1.4", "@ai-sdk/fireworks": "0.2.5", "@ai-sdk/google": "1.2.5", - "@ai-sdk/google-vertex": "2.2.7", + "@ai-sdk/google-vertex": "2.2.8", "@ai-sdk/groq": "1.2.3", "@ai-sdk/luma": "0.1.3", "@ai-sdk/mistral": "1.2.3", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index 6e3a9e99252a..a6e9e8c04c29 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.7", + "@ai-sdk/google-vertex": "2.2.8", "ai": "4.2.10", "geist": "^1.3.1", "next": "latest", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 03979804c95e..b9fe2071ac54 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -9,12 +9,12 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/anthropic": "1.2.4", + "@ai-sdk/anthropic": "1.2.5", "@ai-sdk/deepseek": "0.2.5", "@ai-sdk/fireworks": "0.2.5", "@ai-sdk/openai": "1.3.6", "@ai-sdk/google": "1.2.5", - "@ai-sdk/google-vertex": "2.2.7", + "@ai-sdk/google-vertex": "2.2.8", "@ai-sdk/perplexity": "1.1.3", "@ai-sdk/ui-utils": "1.2.4", "@ai-sdk/react": "1.2.5", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 689856753b14..75fb435b6bc5 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/anthropic +## 1.2.5 + +### Patch Changes + +- 292f543: fix (provider/google-vertex): fix anthropic support for image urls in messages + ## 1.2.4 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 1e2f2d5ad6da..42ccbeb06e0c 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "1.2.4", + "version": "1.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index ca17793d1136..ce842ef6271c 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/google-vertex +## 2.2.8 + +### Patch Changes + +- 292f543: fix (provider/google-vertex): fix anthropic support for image urls in messages +- Updated dependencies [292f543] + - @ai-sdk/anthropic@1.2.5 + ## 2.2.7 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 4d96920378f6..433ccc9cb442 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.7", + "version": "2.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -49,7 +49,7 @@ } }, "dependencies": { - "@ai-sdk/anthropic": "1.2.4", + "@ai-sdk/anthropic": "1.2.5", "@ai-sdk/google": "1.2.5", "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2df8ced9166f..07b9008e6e2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,7 +63,7 @@ importers: specifier: 2.2.4 version: link:../../packages/amazon-bedrock '@ai-sdk/anthropic': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/anthropic '@ai-sdk/azure': specifier: 1.3.6 @@ -90,7 +90,7 @@ importers: specifier: 1.2.5 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.7 + specifier: 2.2.8 version: link:../../packages/google-vertex '@ai-sdk/groq': specifier: 1.2.3 @@ -436,7 +436,7 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.7 + specifier: 2.2.8 version: link:../../packages/google-vertex ai: specifier: 4.2.10 @@ -534,7 +534,7 @@ importers: examples/next-openai: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/anthropic '@ai-sdk/deepseek': specifier: 0.2.5 @@ -546,7 +546,7 @@ importers: specifier: 1.2.5 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.7 + specifier: 2.2.8 version: link:../../packages/google-vertex '@ai-sdk/openai': specifier: 1.3.6 @@ -1536,7 +1536,7 @@ importers: packages/google-vertex: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../anthropic '@ai-sdk/google': specifier: 1.2.5 @@ -24107,7 +24107,7 @@ snapshots: eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.1) eslint-plugin-react: 7.35.0(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -24182,8 +24182,8 @@ snapshots: debug: 4.4.0(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -24222,7 +24222,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24255,7 +24255,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24304,7 +24304,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -24314,7 +24314,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.0 is-glob: 4.0.3 From c45d100a8ec20768c40336eac98a7ba997724b8a Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Thu, 3 Apr 2025 14:03:54 +0200 Subject: [PATCH 006/191] fix (core): send buffered text in smooth stream when stream parts change (#5531) Co-authored-by: Carl Brugger --- .changeset/smooth-mirrors-kneel.md | 5 + .../core/generate-text/smooth-stream.test.ts | 160 ++++++++++++++++++ .../ai/core/generate-text/smooth-stream.ts | 8 +- 3 files changed, 167 insertions(+), 6 deletions(-) create mode 100644 .changeset/smooth-mirrors-kneel.md diff --git a/.changeset/smooth-mirrors-kneel.md b/.changeset/smooth-mirrors-kneel.md new file mode 100644 index 000000000000..c90af6f5bd58 --- /dev/null +++ b/.changeset/smooth-mirrors-kneel.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix (core): send buffered text in smooth stream when stream parts change diff --git a/packages/ai/core/generate-text/smooth-stream.test.ts b/packages/ai/core/generate-text/smooth-stream.test.ts index 6b01f7565ab8..7d5bbd5db00d 100644 --- a/packages/ai/core/generate-text/smooth-stream.test.ts +++ b/packages/ai/core/generate-text/smooth-stream.test.ts @@ -173,6 +173,166 @@ describe('smoothStream', () => { }, ]); }); + + it('should send remaining text buffer before tool call starts', async () => { + const stream = convertArrayToReadableStream([ + { type: 'text-delta', textDelta: 'I will check the' }, + { type: 'text-delta', textDelta: ' weather in Lon' }, + { type: 'text-delta', textDelta: 'don.' }, + { type: 'tool-call', name: 'weather', args: { city: 'London' } }, + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ + delayInMs: 10, + _internal: { delay }, + })({ tools: {} }), + ); + + await consumeStream(stream); + + expect(events).toMatchInlineSnapshot(` + [ + "delay 10", + { + "textDelta": "I ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "will ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "check ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "the ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "weather ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "in ", + "type": "text-delta", + }, + { + "textDelta": "London.", + "type": "text-delta", + }, + { + "args": { + "city": "London", + }, + "name": "weather", + "type": "tool-call", + }, + { + "type": "step-finish", + }, + { + "type": "finish", + }, + ] + `); + }); + + it('should send remaining text buffer before tool call starts and tool call streaming is enabled', async () => { + const stream = convertArrayToReadableStream([ + { type: 'text-delta', textDelta: 'I will check the' }, + { type: 'text-delta', textDelta: ' weather in Lon' }, + { type: 'text-delta', textDelta: 'don.' }, + { + type: 'tool-call-streaming-start', + name: 'weather', + args: { city: 'London' }, + }, + { type: 'tool-call-delta', name: 'weather', args: { city: 'London' } }, + { type: 'tool-call', name: 'weather', args: { city: 'London' } }, + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ + delayInMs: 10, + _internal: { delay }, + })({ tools: {} }), + ); + + await consumeStream(stream); + + expect(events).toMatchInlineSnapshot(` + [ + "delay 10", + { + "textDelta": "I ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "will ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "check ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "the ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "weather ", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "in ", + "type": "text-delta", + }, + { + "textDelta": "London.", + "type": "text-delta", + }, + { + "args": { + "city": "London", + }, + "name": "weather", + "type": "tool-call-streaming-start", + }, + { + "args": { + "city": "London", + }, + "name": "weather", + "type": "tool-call-delta", + }, + { + "args": { + "city": "London", + }, + "name": "weather", + "type": "tool-call", + }, + { + "type": "step-finish", + }, + { + "type": "finish", + }, + ] + `); + }); }); describe('line chunking', () => { diff --git a/packages/ai/core/generate-text/smooth-stream.ts b/packages/ai/core/generate-text/smooth-stream.ts index 2f0ef085aee4..3cca81c15ee9 100644 --- a/packages/ai/core/generate-text/smooth-stream.ts +++ b/packages/ai/core/generate-text/smooth-stream.ts @@ -44,9 +44,10 @@ export function smoothStream({ return () => { let buffer = ''; + return new TransformStream, TextStreamPart>({ async transform(chunk, controller) { - if (chunk.type === 'step-finish') { + if (chunk.type !== 'text-delta') { if (buffer.length > 0) { controller.enqueue({ type: 'text-delta', textDelta: buffer }); buffer = ''; @@ -56,11 +57,6 @@ export function smoothStream({ return; } - if (chunk.type !== 'text-delta') { - controller.enqueue(chunk); - return; - } - buffer += chunk.textDelta; let match; From 4e28bbad4d323b36a97e4919114a29afe2162e3f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 14:07:54 +0200 Subject: [PATCH 007/191] Version Packages (#5532) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/smooth-mirrors-kneel.md | 5 -- examples/ai-core/package.json | 4 +- examples/express/package.json | 2 +- examples/fastify/package.json | 2 +- examples/hono/package.json | 2 +- examples/mcp/package.json | 2 +- examples/nest/package.json | 2 +- examples/next-fastapi/package.json | 2 +- examples/next-google-vertex/package.json | 2 +- examples/next-langchain/package.json | 2 +- .../package.json | 2 +- examples/next-openai-pages/package.json | 2 +- .../next-openai-telemetry-sentry/package.json | 2 +- examples/next-openai-telemetry/package.json | 2 +- .../package.json | 2 +- examples/next-openai/package.json | 2 +- examples/node-http-server/package.json | 2 +- examples/nuxt-openai/package.json | 2 +- examples/solidstart-openai/package.json | 2 +- examples/sveltekit-openai/package.json | 2 +- packages/ai/CHANGELOG.md | 6 ++ packages/ai/package.json | 2 +- .../ai/tests/e2e/next-server/CHANGELOG.md | 7 +++ packages/valibot/CHANGELOG.md | 7 +++ packages/valibot/package.json | 4 +- pnpm-lock.yaml | 56 +++++++++---------- 26 files changed, 71 insertions(+), 56 deletions(-) delete mode 100644 .changeset/smooth-mirrors-kneel.md diff --git a/.changeset/smooth-mirrors-kneel.md b/.changeset/smooth-mirrors-kneel.md deleted file mode 100644 index c90af6f5bd58..000000000000 --- a/.changeset/smooth-mirrors-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix (core): send buffered text in smooth stream when stream parts change diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index d4ec016bb548..927f05428015 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -24,12 +24,12 @@ "@ai-sdk/replicate": "0.2.3", "@ai-sdk/togetherai": "0.2.5", "@ai-sdk/xai": "1.2.6", - "@ai-sdk/valibot": "0.1.10", + "@ai-sdk/valibot": "0.1.11", "@google/generative-ai": "0.21.0", "@opentelemetry/auto-instrumentations-node": "0.54.0", "@opentelemetry/sdk-node": "0.54.2", "@opentelemetry/sdk-trace-node": "1.28.0", - "ai": "4.2.10", + "ai": "4.2.11", "dotenv": "16.4.5", "image-type": "^5.2.0", "mathjs": "14.0.0", diff --git a/examples/express/package.json b/examples/express/package.json index b4a92051eb38..9bd08aa576fc 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@ai-sdk/openai": "1.3.6", - "ai": "4.2.10", + "ai": "4.2.11", "dotenv": "16.4.5", "express": "5.0.1" }, diff --git a/examples/fastify/package.json b/examples/fastify/package.json index d22d2ec2b114..d9ecc12b8e0c 100644 --- a/examples/fastify/package.json +++ b/examples/fastify/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/openai": "1.3.6", - "ai": "4.2.10", + "ai": "4.2.11", "dotenv": "16.4.5", "fastify": "5.1.0" }, diff --git a/examples/hono/package.json b/examples/hono/package.json index bd21f6a1e2ab..0ee1269c5bf8 100644 --- a/examples/hono/package.json +++ b/examples/hono/package.json @@ -5,7 +5,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.6", "@hono/node-server": "1.13.7", - "ai": "4.2.10", + "ai": "4.2.11", "dotenv": "16.4.5", "hono": "4.6.9" }, diff --git a/examples/mcp/package.json b/examples/mcp/package.json index 2fe5216c4508..81272bec3b3d 100644 --- a/examples/mcp/package.json +++ b/examples/mcp/package.json @@ -14,7 +14,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.6", "@modelcontextprotocol/sdk": "^1.7.0", - "ai": "4.2.10", + "ai": "4.2.11", "dotenv": "16.4.5", "express": "5.0.1", "zod": "3.23.8" diff --git a/examples/nest/package.json b/examples/nest/package.json index 83527c26dc83..fbedae50258e 100644 --- a/examples/nest/package.json +++ b/examples/nest/package.json @@ -19,7 +19,7 @@ "@nestjs/common": "^10.4.15", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.4.9", - "ai": "4.2.10", + "ai": "4.2.11", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/examples/next-fastapi/package.json b/examples/next-fastapi/package.json index 23b28546a504..494463703a72 100644 --- a/examples/next-fastapi/package.json +++ b/examples/next-fastapi/package.json @@ -13,7 +13,7 @@ "dependencies": { "@ai-sdk/ui-utils": "1.2.4", "@ai-sdk/react": "1.2.5", - "ai": "4.2.10", + "ai": "4.2.11", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index a6e9e8c04c29..e4c5fc973ee6 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@ai-sdk/google-vertex": "2.2.8", - "ai": "4.2.10", + "ai": "4.2.11", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-langchain/package.json b/examples/next-langchain/package.json index 88976a1fda17..016be9174fee 100644 --- a/examples/next-langchain/package.json +++ b/examples/next-langchain/package.json @@ -12,7 +12,7 @@ "@ai-sdk/react": "1.2.5", "@langchain/openai": "0.0.28", "@langchain/core": "0.1.63", - "ai": "4.2.10", + "ai": "4.2.11", "langchain": "0.1.36", "next": "latest", "react": "^18", diff --git a/examples/next-openai-kasada-bot-protection/package.json b/examples/next-openai-kasada-bot-protection/package.json index 7b69e7a3bc2e..863339ddcce2 100644 --- a/examples/next-openai-kasada-bot-protection/package.json +++ b/examples/next-openai-kasada-bot-protection/package.json @@ -12,7 +12,7 @@ "@ai-sdk/openai": "1.3.6", "@ai-sdk/react": "1.2.5", "@vercel/functions": "latest", - "ai": "4.2.10", + "ai": "4.2.11", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai-pages/package.json b/examples/next-openai-pages/package.json index 4ca73016cdfa..0db62cacf433 100644 --- a/examples/next-openai-pages/package.json +++ b/examples/next-openai-pages/package.json @@ -11,7 +11,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.6", "@ai-sdk/react": "1.2.5", - "ai": "4.2.10", + "ai": "4.2.11", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry-sentry/package.json b/examples/next-openai-telemetry-sentry/package.json index b2bc9a0cbbe9..34f63b0efabb 100644 --- a/examples/next-openai-telemetry-sentry/package.json +++ b/examples/next-openai-telemetry-sentry/package.json @@ -17,7 +17,7 @@ "@sentry/nextjs": "^8.42.0", "@sentry/opentelemetry": "8.22.0", "@vercel/otel": "1.10.0", - "ai": "4.2.10", + "ai": "4.2.11", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry/package.json b/examples/next-openai-telemetry/package.json index bf409af4266f..4ce0597f7034 100644 --- a/examples/next-openai-telemetry/package.json +++ b/examples/next-openai-telemetry/package.json @@ -15,7 +15,7 @@ "@opentelemetry/sdk-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@vercel/otel": "1.10.0", - "ai": "4.2.10", + "ai": "4.2.11", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-upstash-rate-limits/package.json b/examples/next-openai-upstash-rate-limits/package.json index dfd8213067a5..e738dfec075b 100644 --- a/examples/next-openai-upstash-rate-limits/package.json +++ b/examples/next-openai-upstash-rate-limits/package.json @@ -13,7 +13,7 @@ "@ai-sdk/react": "1.2.5", "@upstash/ratelimit": "^0.4.3", "@vercel/kv": "^0.2.2", - "ai": "4.2.10", + "ai": "4.2.11", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index b9fe2071ac54..75e8936c5992 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -19,7 +19,7 @@ "@ai-sdk/ui-utils": "1.2.4", "@ai-sdk/react": "1.2.5", "@vercel/blob": "^0.26.0", - "ai": "4.2.10", + "ai": "4.2.11", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/node-http-server/package.json b/examples/node-http-server/package.json index 09ff6fecb6aa..172ecac2fcf9 100644 --- a/examples/node-http-server/package.json +++ b/examples/node-http-server/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/openai": "1.3.6", - "ai": "4.2.10", + "ai": "4.2.11", "dotenv": "16.4.5", "zod": "3.23.8", "zod-to-json-schema": "3.23.5" diff --git a/examples/nuxt-openai/package.json b/examples/nuxt-openai/package.json index 429177683a28..28b775e0173f 100644 --- a/examples/nuxt-openai/package.json +++ b/examples/nuxt-openai/package.json @@ -11,7 +11,7 @@ "dependencies": { "@ai-sdk/vue": "1.2.4", "@ai-sdk/openai": "1.3.6", - "ai": "4.2.10", + "ai": "4.2.11", "zod": "3.23.8" }, "devDependencies": { diff --git a/examples/solidstart-openai/package.json b/examples/solidstart-openai/package.json index f364905d9791..4d4d984cfeff 100644 --- a/examples/solidstart-openai/package.json +++ b/examples/solidstart-openai/package.json @@ -20,7 +20,7 @@ "@solidjs/meta": "0.29.4", "@solidjs/router": "^0.15.1", "@solidjs/start": "^1.0.10", - "ai": "4.2.10", + "ai": "4.2.11", "solid-js": "^1.9.3", "zod": "^3.23.8" }, diff --git a/examples/sveltekit-openai/package.json b/examples/sveltekit-openai/package.json index 71a50d46cd59..f429e3dc4f8c 100644 --- a/examples/sveltekit-openai/package.json +++ b/examples/sveltekit-openai/package.json @@ -25,7 +25,7 @@ "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", - "ai": "4.2.10", + "ai": "4.2.11", "autoprefixer": "^10.4.20", "bits-ui": "^1.3.9", "clsx": "^2.1.1", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index b5e5cdf62b93..2ef517d70a6a 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 4.2.11 + +### Patch Changes + +- c45d100: fix (core): send buffered text in smooth stream when stream parts change + ## 4.2.10 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 6bebdcff74fd..7cbab6dd105c 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "4.2.10", + "version": "4.2.11", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/ai/tests/e2e/next-server/CHANGELOG.md b/packages/ai/tests/e2e/next-server/CHANGELOG.md index d89e10b106c9..ca71f95f5384 100644 --- a/packages/ai/tests/e2e/next-server/CHANGELOG.md +++ b/packages/ai/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [c45d100] + - ai@4.2.11 + +## 0.0.1 + +### Patch Changes + - ai@4.2.10 ## 0.0.1 diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index d0b6a4c6e3f6..41eeb2900014 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 0.1.11 + +### Patch Changes + +- Updated dependencies [c45d100] + - ai@4.2.11 + ## 0.1.10 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index f92be48a0f3e..2ed01cd5a1d8 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "0.1.10", + "version": "0.1.11", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -27,7 +27,7 @@ } }, "dependencies": { - "ai": "4.2.10" + "ai": "4.2.11" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 07b9008e6e2f..9dde4882e268 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,7 +120,7 @@ importers: specifier: 0.2.5 version: link:../../packages/togetherai '@ai-sdk/valibot': - specifier: 0.1.10 + specifier: 0.1.11 version: link:../../packages/valibot '@ai-sdk/xai': specifier: 1.2.6 @@ -138,7 +138,7 @@ importers: specifier: 1.28.0 version: 1.28.0(@opentelemetry/api@1.9.0) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -181,7 +181,7 @@ importers: specifier: 1.3.6 version: link:../../packages/openai ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -209,7 +209,7 @@ importers: specifier: 1.3.6 version: link:../../packages/openai ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -237,7 +237,7 @@ importers: specifier: 1.13.7 version: 1.13.7(hono@4.6.9) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -265,7 +265,7 @@ importers: specifier: ^1.7.0 version: 1.7.0 ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -305,7 +305,7 @@ importers: specifier: ^10.4.9 version: 10.4.9(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai reflect-metadata: specifier: ^0.2.0 @@ -387,7 +387,7 @@ importers: specifier: 1.2.4 version: link:../../packages/ui-utils ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -439,7 +439,7 @@ importers: specifier: 2.2.8 version: link:../../packages/google-vertex ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -488,7 +488,7 @@ importers: specifier: 0.0.28 version: 0.0.28 ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai langchain: specifier: 0.1.36 @@ -564,7 +564,7 @@ importers: specifier: ^0.26.0 version: 0.26.0 ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai next: specifier: latest @@ -625,7 +625,7 @@ importers: specifier: latest version: 2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai next: specifier: latest @@ -677,7 +677,7 @@ importers: specifier: 1.2.5 version: link:../../packages/react ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai next: specifier: latest @@ -744,7 +744,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.29.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai next: specifier: latest @@ -817,7 +817,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai next: specifier: latest @@ -878,7 +878,7 @@ importers: specifier: ^0.2.2 version: 0.2.4 ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai next: specifier: latest @@ -927,7 +927,7 @@ importers: specifier: 1.3.6 version: link:../../packages/openai ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -958,7 +958,7 @@ importers: specifier: 1.2.4 version: link:../../packages/vue ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai zod: specifier: 3.23.8 @@ -1025,7 +1025,7 @@ importers: specifier: ^1.0.10 version: 1.0.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vinxi@0.4.3(@types/node@22.7.4)(@upstash/redis@1.34.3)(ioredis@5.4.1)(terser@5.31.3)(typescript@5.6.3))(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai solid-js: specifier: ^1.9.3 @@ -1077,7 +1077,7 @@ importers: specifier: ^5.0.0 version: 5.0.3(svelte@5.22.4)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../../packages/ai autoprefixer: specifier: ^10.4.20 @@ -2052,7 +2052,7 @@ importers: specifier: ^1.0.0-rc.0 || ^1.0.0 version: 1.0.0-rc.0(valibot@1.0.0-rc.0(typescript@5.6.3)) ai: - specifier: 4.2.10 + specifier: 4.2.11 version: link:../ai devDependencies: '@types/node': @@ -24107,7 +24107,7 @@ snapshots: eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.1) eslint-plugin-react: 7.35.0(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -24182,8 +24182,8 @@ snapshots: debug: 4.4.0(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -24222,7 +24222,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24255,7 +24255,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24304,7 +24304,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -24314,7 +24314,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.0 is-glob: 4.0.3 From 2c19b9acf7e8dabcf4a52757b01d70b34fbf1e93 Mon Sep 17 00:00:00 2001 From: Sam Denty Date: Thu, 3 Apr 2025 13:45:09 +0100 Subject: [PATCH 008/191] chore (ui/react,vue): update more tests to unified test server (#5509) --- .changeset/clean-numbers-cover.md | 5 + .../src/test/unified-test-server.ts | 4 + packages/react/src/use-object.ui.test.tsx | 348 ++++++------- packages/svelte/src/completion.svelte.test.ts | 289 +++++------ .../src/structured-object.svelte.test.ts | 459 ++++++++---------- 5 files changed, 513 insertions(+), 592 deletions(-) create mode 100644 .changeset/clean-numbers-cover.md diff --git a/.changeset/clean-numbers-cover.md b/.changeset/clean-numbers-cover.md new file mode 100644 index 000000000000..590b5df0eec2 --- /dev/null +++ b/.changeset/clean-numbers-cover.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/provider-utils': patch +--- + +feat(provider-utils): add TestServerCall#requestCredentials diff --git a/packages/provider-utils/src/test/unified-test-server.ts b/packages/provider-utils/src/test/unified-test-server.ts index 47b2688de3a6..b03798379c75 100644 --- a/packages/provider-utils/src/test/unified-test-server.ts +++ b/packages/provider-utils/src/test/unified-test-server.ts @@ -62,6 +62,10 @@ class TestServerCall { return this.request!.text().then(JSON.parse); } + get requestCredentials() { + return this.request!.credentials; + } + get requestHeaders() { const requestHeaders = this.request!.headers; diff --git a/packages/react/src/use-object.ui.test.tsx b/packages/react/src/use-object.ui.test.tsx index 275716079072..e77402d9cc37 100644 --- a/packages/react/src/use-object.ui.test.tsx +++ b/packages/react/src/use-object.ui.test.tsx @@ -1,6 +1,6 @@ import { - describeWithTestServer, - withTestServer, + createTestServer, + TestResponseController, } from '@ai-sdk/provider-utils/test'; import '@testing-library/jest-dom/vitest'; import { cleanup, render, screen, waitFor } from '@testing-library/react'; @@ -8,6 +8,10 @@ import userEvent from '@testing-library/user-event'; import { z } from 'zod'; import { experimental_useObject } from './use-object'; +const server = createTestServer({ + '/api/use-object': {}, +}); + describe('text stream', () => { let onErrorResult: Error | undefined; let onFinishCalls: Array<{ @@ -69,208 +73,178 @@ describe('text stream', () => { beforeEach(() => { render(); }); - describeWithTestServer( - "when the API returns 'Hello, world!'", - { - url: '/api/use-object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"'], - }, - ({ call }) => { - beforeEach(async () => { - await userEvent.click(screen.getByTestId('submit-button')); - }); - it('should render stream', async () => { - await screen.findByTestId('object'); - expect(screen.getByTestId('object')).toHaveTextContent( - JSON.stringify({ content: 'Hello, world!' }), - ); - }); + describe("when the API returns 'Hello, world!'", () => { + beforeEach(async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"'], + }; + await userEvent.click(screen.getByTestId('submit-button')); + }); - it("should send 'test' to the API", async () => { - expect(await call(0).getRequestBodyJson()).toBe('test-input'); - }); + it('should render stream', async () => { + await screen.findByTestId('object'); + expect(screen.getByTestId('object')).toHaveTextContent( + JSON.stringify({ content: 'Hello, world!' }), + ); + }); + + it("should send 'test' to the API", async () => { + expect(await server.calls[0].requestBody).toBe('test-input'); + }); + + it('should not have an error', async () => { + await screen.findByTestId('error'); + expect(screen.getByTestId('error')).toBeEmptyDOMElement(); + expect(onErrorResult).toBeUndefined(); + }); + }); + + describe('isLoading', () => { + it('should be true while loading', async () => { + const controller = new TestResponseController(); + server.urls['/api/use-object'].response = { + type: 'controlled-stream', + controller, + }; - it('should not have an error', async () => { - await screen.findByTestId('error'); - expect(screen.getByTestId('error')).toBeEmptyDOMElement(); - expect(onErrorResult).toBeUndefined(); + controller.write('{"content": '); + await userEvent.click(screen.getByTestId('submit-button')); + + // wait for element "loading" to have text content "true": + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('true'); }); - }, - ); - describe('isLoading', async () => { - it( - 'should be true while loading', - withTestServer( - { url: '/api/use-object', type: 'controlled-stream' }, - async ({ streamController }) => { - streamController.enqueue('{"content": '); - - await userEvent.click(screen.getByTestId('submit-button')); - - // wait for element "loading" to have text content "true": - await waitFor(() => { - expect(screen.getByTestId('loading')).toHaveTextContent('true'); - }); - - streamController.enqueue('"Hello, world!"}'); - streamController.close(); - - // wait for element "loading" to have text content "false": - await waitFor(() => { - expect(screen.getByTestId('loading')).toHaveTextContent('false'); - }); - }, - ), - ); + controller.write('"Hello, world!"}'); + controller.close(); + + // wait for element "loading" to have text content "false": + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('false'); + }); + }); }); - describe('stop', async () => { - it( - 'should abort the stream and not consume any more data', - withTestServer( - { url: '/api/use-object', type: 'controlled-stream' }, - async ({ streamController }) => { - streamController.enqueue('{"content": "h'); - - userEvent.click(screen.getByTestId('submit-button')); - - // wait for element "loading" and "object" to have text content: - await waitFor(() => { - expect(screen.getByTestId('loading')).toHaveTextContent('true'); - }); - await waitFor(() => { - expect(screen.getByTestId('object')).toHaveTextContent( - '{"content":"h"}', - ); - }); - - // click stop button: - await userEvent.click(screen.getByTestId('stop-button')); - - // wait for element "loading" to have text content "false": - await waitFor(() => { - expect(screen.getByTestId('loading')).toHaveTextContent('false'); - }); - - // this should not be consumed any more: - streamController.enqueue('ello, world!"}'); - streamController.close(); - - // should only show start of object: - expect(screen.getByTestId('object')).toHaveTextContent( - '{"content":"h"}', - ); - }, - ), - ); + it('should abort the stream and not consume any more data', async () => { + const controller = new TestResponseController(); + server.urls['/api/use-object'].response = { + type: 'controlled-stream', + controller, + }; + + controller.write('{"content": "h'); + await userEvent.click(screen.getByTestId('submit-button')); + + // wait for element "loading" and "object" to have text content: + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('true'); + }); + await waitFor(() => { + expect(screen.getByTestId('object')).toHaveTextContent( + '{"content":"h"}', + ); + }); + + // click stop button: + await userEvent.click(screen.getByTestId('stop-button')); + + // wait for element "loading" to have text content "false": + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('false'); + }); + + // this should not be consumed any more: + controller.write('ello, world!"}'); + controller.close(); + + // should only show start of object: + await waitFor(() => { + expect(screen.getByTestId('object')).toHaveTextContent( + '{"content":"h"}', + ); + }); }); describe('when the API returns a 404', () => { - it( - 'should render error', - withTestServer( - { - url: '/api/use-object', - type: 'error', - status: 404, - content: 'Not found', - }, - async () => { - await userEvent.click(screen.getByTestId('submit-button')); - - await screen.findByTestId('error'); - expect(screen.getByTestId('error')).toHaveTextContent('Not found'); - expect(onErrorResult).toBeInstanceOf(Error); - expect(screen.getByTestId('loading')).toHaveTextContent('false'); - }, - ), - ); + it('should render error', async () => { + server.urls['/api/use-object'].response = { + type: 'error', + status: 404, + body: 'Not found', + }; + + await userEvent.click(screen.getByTestId('submit-button')); + + await screen.findByTestId('error'); + expect(screen.getByTestId('error')).toHaveTextContent('Not found'); + expect(onErrorResult).toBeInstanceOf(Error); + expect(screen.getByTestId('loading')).toHaveTextContent('false'); + }); }); describe('onFinish', () => { - it( - 'should be called with an object when the stream finishes and the object matches the schema', - withTestServer( - { - url: '/api/use-object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], - }, - async () => { - await userEvent.click(screen.getByTestId('submit-button')); - - expect(onFinishCalls).toStrictEqual([ - { object: { content: 'Hello, world!' }, error: undefined }, - ]); - }, - ), - ); + it('should be called with an object when the stream finishes and the object matches the schema', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + await userEvent.click(screen.getByTestId('submit-button')); + + expect(onFinishCalls).toStrictEqual([ + { object: { content: 'Hello, world!' }, error: undefined }, + ]); + }); + + it('should be called with an error when the stream finishes and the object does not match the schema', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content-wrong": "Hello, ', 'world', '!"', '}'], + }; + + await userEvent.click(screen.getByTestId('submit-button')); + + expect(onFinishCalls).toStrictEqual([ + { object: undefined, error: expect.any(Error) }, + ]); + }); }); + }); - it( - 'should be called with an error when the stream finishes and the object does not match the schema', - withTestServer( - { - url: '/api/use-object', - type: 'stream-values', - content: ['{ ', '"content-wrong": "Hello, ', 'world', '!"', '}'], - }, - async () => { - await userEvent.click(screen.getByTestId('submit-button')); - - expect(onFinishCalls).toStrictEqual([ - { object: undefined, error: expect.any(Error) }, - ]); - }, - ), + it('should send custom headers', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + render( + , ); - }); - it( - 'should send custom headers', - withTestServer( - { - url: '/api/use-object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], - }, - async ({ call }) => { - render( - , - ); + await userEvent.click(screen.getByTestId('submit-button')); - await userEvent.click(screen.getByTestId('submit-button')); + expect(server.calls[0].requestHeaders).toStrictEqual({ + 'content-type': 'application/json', + authorization: 'Bearer TEST_TOKEN', + 'x-custom-header': 'CustomValue', + }); + }); - expect(call(0).getRequestHeaders()).toStrictEqual({ - 'content-type': 'application/json', - authorization: 'Bearer TEST_TOKEN', - 'x-custom-header': 'CustomValue', - }); - }, - ), - ); - - it( - 'should send custom credentials', - withTestServer( - { - url: '/api/use-object', - type: 'stream-values', - content: ['{ ', '"content": "Authenticated ', 'content', '!"', '}'], - }, - async ({ call }) => { - render(); - await userEvent.click(screen.getByTestId('submit-button')); - expect(call(0).getRequestCredentials()).toBe('include'); - }, - ), - ); + it('should send custom credentials', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Authenticated ', 'content', '!"', '}'], + }; + + render(); + await userEvent.click(screen.getByTestId('submit-button')); + expect(server.calls[0].requestCredentials).toBe('include'); + }); }); diff --git a/packages/svelte/src/completion.svelte.test.ts b/packages/svelte/src/completion.svelte.test.ts index 13f2a0fb0a86..2840ec8f8577 100644 --- a/packages/svelte/src/completion.svelte.test.ts +++ b/packages/svelte/src/completion.svelte.test.ts @@ -1,178 +1,151 @@ -import { withTestServer } from '@ai-sdk/provider-utils/test'; +import { + createTestServer, + TestResponseController, +} from '@ai-sdk/provider-utils/test'; import { Completion } from './completion.svelte.js'; import { render } from '@testing-library/svelte'; import CompletionSynchronization from './tests/completion-synchronization.svelte'; +const server = createTestServer({ + '/api/completion': {}, +}); + describe('Completion', () => { - it( - 'should render a data stream', - withTestServer( - { - type: 'stream-values', - url: '/api/completion', - content: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], - }, - async () => { - const completion = new Completion(); - await completion.complete('hi'); - expect(completion.completion).toBe('Hello, world.'); - }, - ), - ); + it('should render a data stream', async () => { + server.urls['/api/completion'].response = { + type: 'stream-chunks', + chunks: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], + }; - it( - 'should render a text stream', - withTestServer( - { - type: 'stream-values', - url: '/api/completion', - content: ['Hello', ',', ' world', '.'], - }, - async () => { - const completion = new Completion({ streamProtocol: 'text' }); - await completion.complete('hi'); - expect(completion.completion).toBe('Hello, world.'); - }, - ), - ); + const completion = new Completion(); + await completion.complete('hi'); + expect(completion.completion).toBe('Hello, world.'); + }); - it( - 'should call `onFinish` callback', - withTestServer( - { - type: 'stream-values', - url: '/api/completion', - content: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], - }, - async () => { - const onFinish = vi.fn(); - const completion = new Completion({ onFinish }); - await completion.complete('hi'); - expect(onFinish).toHaveBeenCalledExactlyOnceWith('hi', 'Hello, world.'); - }, - ), - ); - - it( - 'should show loading state', - withTestServer( - { url: '/api/completion', type: 'controlled-stream' }, - async ({ streamController }) => { - const completion = new Completion(); - const completionOperation = completion.complete('hi'); - streamController.enqueue('0:"Hello"\n'); - await vi.waitFor(() => expect(completion.loading).toBe(true)); - streamController.close(); - await completionOperation; - expect(completion.loading).toBe(false); - }, - ), - ); + it('should render a text stream', async () => { + server.urls['/api/completion'].response = { + type: 'stream-chunks', + chunks: ['Hello', ',', ' world', '.'], + }; + + const completion = new Completion({ streamProtocol: 'text' }); + await completion.complete('hi'); + expect(completion.completion).toBe('Hello, world.'); + }); + + it('should call `onFinish` callback', async () => { + server.urls['/api/completion'].response = { + type: 'stream-chunks', + chunks: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], + }; + + const onFinish = vi.fn(); + const completion = new Completion({ onFinish }); + await completion.complete('hi'); + expect(onFinish).toHaveBeenCalledExactlyOnceWith('hi', 'Hello, world.'); + }); + + it('should show loading state', async () => { + const controller = new TestResponseController(); + server.urls['/api/completion'].response = { + type: 'controlled-stream', + controller, + }; + + const completion = new Completion(); + const completionOperation = completion.complete('hi'); + controller.write('0:"Hello"\n'); + await vi.waitFor(() => expect(completion.loading).toBe(true)); + controller.close(); + await completionOperation; + expect(completion.loading).toBe(false); + }); + + it('should reset loading state on error', async () => { + server.urls['/api/completion'].response = { + type: 'error', + status: 404, + body: 'Not found', + }; - it( - 'should reset loading state on error', - withTestServer( + const completion = new Completion(); + await completion.complete('hi'); + expect(completion.error).toBeInstanceOf(Error); + expect(completion.loading).toBe(false); + }); + + it('should reset error state on subsequent completion', async () => { + server.urls['/api/completion'].response = [ { type: 'error', - url: '/api/completion', status: 404, - content: 'Not found', - }, - async () => { - const completion = new Completion(); - await completion.complete('hi'); - expect(completion.error).toBeInstanceOf(Error); - expect(completion.loading).toBe(false); + body: 'Not found', }, - ), - ); - - it( - 'should reset error state on subsequent completion', - withTestServer( - [ - { - type: 'error', - url: '/api/completion', - status: 404, - content: 'Not found', - }, - { - type: 'stream-values', - url: '/api/completion', - content: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], - }, - ], - async () => { - const completion = new Completion(); - await completion.complete('hi'); - expect(completion.error).toBeInstanceOf(Error); - expect(completion.loading).toBe(false); - await completion.complete('hi'); - expect(completion.error).toBe(undefined); - expect(completion.completion).toBe('Hello, world.'); + { + type: 'stream-chunks', + chunks: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], }, - ), - ); + ]; + + const completion = new Completion(); + await completion.complete('hi'); + expect(completion.error).toBeInstanceOf(Error); + expect(completion.loading).toBe(false); + await completion.complete('hi'); + expect(completion.error).toBe(undefined); + expect(completion.completion).toBe('Hello, world.'); + }); }); describe('synchronization', () => { - it( - 'correctly synchronizes content between hook instances', - withTestServer( - { - type: 'stream-values', - url: '/api/completion', - content: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], - }, - async () => { - const { - component: { completion1, completion2 }, - } = render(CompletionSynchronization, { id: crypto.randomUUID() }); + it('correctly synchronizes content between hook instances', async () => { + server.urls['/api/completion'].response = { + type: 'stream-chunks', + chunks: ['0:"Hello"\n', '0:","\n', '0:" world"\n', '0:"."\n'], + }; - await completion1.complete('hi'); + const { + component: { completion1, completion2 }, + } = render(CompletionSynchronization, { id: crypto.randomUUID() }); - expect(completion1.completion).toBe('Hello, world.'); - expect(completion2.completion).toBe('Hello, world.'); - }, - ), - ); + await completion1.complete('hi'); - it( - 'correctly synchronizes loading and error state between hook instances', - withTestServer( - { - type: 'controlled-stream', - url: '/api/completion', - }, - async ({ streamController }) => { - const { - component: { completion1, completion2 }, - } = render(CompletionSynchronization, { id: crypto.randomUUID() }); - - const completionOperation = completion1.complete('hi'); - - await vi.waitFor(() => { - expect(completion1.loading).toBe(true); - expect(completion2.loading).toBe(true); - }); - - streamController.enqueue('0:"Hello"\n'); - await vi.waitFor(() => { - expect(completion1.completion).toBe('Hello'); - expect(completion2.completion).toBe('Hello'); - }); - - streamController.error(new Error('Failed to be cool enough')); - await completionOperation; - - expect(completion1.loading).toBe(false); - expect(completion2.loading).toBe(false); - expect(completion1.error).toBeInstanceOf(Error); - expect(completion1.error?.message).toBe('Failed to be cool enough'); - expect(completion2.error).toBeInstanceOf(Error); - expect(completion2.error?.message).toBe('Failed to be cool enough'); - }, - ), - ); + expect(completion1.completion).toBe('Hello, world.'); + expect(completion2.completion).toBe('Hello, world.'); + }); + + it('correctly synchronizes loading and error state between hook instances', async () => { + const controller = new TestResponseController(); + server.urls['/api/completion'].response = { + type: 'controlled-stream', + controller, + }; + + const { + component: { completion1, completion2 }, + } = render(CompletionSynchronization, { id: crypto.randomUUID() }); + + const completionOperation = completion1.complete('hi'); + + await vi.waitFor(() => { + expect(completion1.loading).toBe(true); + expect(completion2.loading).toBe(true); + }); + + controller.write('0:"Hello"\n'); + await vi.waitFor(() => { + expect(completion1.completion).toBe('Hello'); + expect(completion2.completion).toBe('Hello'); + }); + + controller.error(new Error('Failed to be cool enough')); + await completionOperation; + + expect(completion1.loading).toBe(false); + expect(completion2.loading).toBe(false); + expect(completion1.error).toBeInstanceOf(Error); + expect(completion1.error?.message).toBe('Failed to be cool enough'); + expect(completion2.error).toBeInstanceOf(Error); + expect(completion2.error?.message).toBe('Failed to be cool enough'); + }); }); diff --git a/packages/svelte/src/structured-object.svelte.test.ts b/packages/svelte/src/structured-object.svelte.test.ts index 7922ea055daf..35204383aa6e 100644 --- a/packages/svelte/src/structured-object.svelte.test.ts +++ b/packages/svelte/src/structured-object.svelte.test.ts @@ -1,12 +1,16 @@ import { - describeWithTestServer, - withTestServer, + createTestServer, + TestResponseController, } from '@ai-sdk/provider-utils/test'; import { render } from '@testing-library/svelte'; import { z } from 'zod'; import { StructuredObject } from './structured-object.svelte.js'; import StructuredObjectSynchronization from './tests/structured-object-synchronization.svelte'; +const server = createTestServer({ + '/api/object': {}, +}); + describe('text stream', () => { let structuredObject: StructuredObject<{ content: string }>; @@ -17,281 +21,242 @@ describe('text stream', () => { }); }); - describeWithTestServer( - 'when the API returns "Hello, world!"', - { - url: 'api/object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"', ' }'], - }, - ({ call }) => { - beforeEach(async () => { - await structuredObject.submit('test-input'); - }); + describe('when the API returns "Hello, world!"', () => { + beforeEach(async () => { + server.urls['/api/object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', ' }'], + }; + await structuredObject.submit('test-input'); + }); - it('should render the stream', () => { - expect(structuredObject.object).toEqual({ content: 'Hello, world!' }); - }); + it('should render the stream', () => { + expect(structuredObject.object).toEqual({ content: 'Hello, world!' }); + }); - it('should send the correct input to the API', async () => { - expect(await call(0).getRequestBodyJson()).toBe('test-input'); - }); + it('should send the correct input to the API', async () => { + expect(await server.calls[0].requestBody).toBe('test-input'); + }); - it('should not have an error', () => { - expect(structuredObject.error).toBeUndefined(); - }); - }, - ); + it('should not have an error', () => { + expect(structuredObject.error).toBeUndefined(); + }); + }); describe('loading', () => { - it( - 'should be true while loading', - withTestServer( - { url: '/api/object', type: 'controlled-stream' }, - async ({ streamController }) => { - streamController.enqueue('{"content": '); - - const submitOperation = structuredObject.submit('test-input'); - - await vi.waitFor(() => { - expect(structuredObject.loading).toBe(true); - }); - - streamController.enqueue('"Hello, world!"}'); - streamController.close(); - await submitOperation; - - expect(structuredObject.loading).toBe(false); - }, - ), - ); + it('should be true while loading', async () => { + const controller = new TestResponseController(); + server.urls['/api/object'].response = { + type: 'controlled-stream', + controller, + }; + + controller.write('{"content": '); + const submitOperation = structuredObject.submit('test-input'); + + await vi.waitFor(() => { + expect(structuredObject.loading).toBe(true); + }); + + controller.write('"Hello, world!"}'); + controller.close(); + await submitOperation; + + expect(structuredObject.loading).toBe(false); + }); }); describe('stop', () => { - it( - 'should abort the stream and not consume any more data', - withTestServer( - { url: '/api/object', type: 'controlled-stream' }, - async ({ streamController }) => { - streamController.enqueue('{"content": "h'); - - const submitOperation = structuredObject.submit('test-input'); - - await vi.waitFor(() => { - expect(structuredObject.loading).toBe(true); - expect(structuredObject.object).toStrictEqual({ - content: 'h', - }); - }); - - structuredObject.stop(); - - await vi.waitFor(() => { - expect(structuredObject.loading).toBe(false); - }); - - streamController.enqueue('ello, world!"}'); - streamController.close(); - await submitOperation; - - expect(structuredObject.loading).toBe(false); - expect(structuredObject.object).toStrictEqual({ - content: 'h', - }); - }, - ), - ); + it('should abort the stream and not consume any more data', async () => { + const controller = new TestResponseController(); + server.urls['/api/object'].response = { + type: 'controlled-stream', + controller, + }; + + controller.write('{"content": "h'); + const submitOperation = structuredObject.submit('test-input'); + + await vi.waitFor(() => { + expect(structuredObject.loading).toBe(true); + expect(structuredObject.object).toStrictEqual({ + content: 'h', + }); + }); + + structuredObject.stop(); + + await vi.waitFor(() => { + expect(structuredObject.loading).toBe(false); + }); + + controller.write('ello, world!"}'); + controller.close(); + await submitOperation; + + expect(structuredObject.loading).toBe(false); + expect(structuredObject.object).toStrictEqual({ + content: 'h', + }); + }); }); describe('when the API returns a 404', () => { - it( - 'should produce the correct error state', - withTestServer( - { - url: '/api/object', - type: 'error', - status: 404, - content: 'Not found', - }, - async () => { - await structuredObject.submit('test-input'); - expect(structuredObject.error).toBeInstanceOf(Error); - expect(structuredObject.error?.message).toBe('Not found'); - expect(structuredObject.loading).toBe(false); - }, - ), - ); + it('should produce the correct error state', async () => { + server.urls['/api/object'].response = { + type: 'error', + status: 404, + body: 'Not found', + }; + + await structuredObject.submit('test-input'); + expect(structuredObject.error).toBeInstanceOf(Error); + expect(structuredObject.error?.message).toBe('Not found'); + expect(structuredObject.loading).toBe(false); + }); }); describe('onFinish', () => { - it( - 'should be called with an object when the stream finishes and the object matches the schema', - withTestServer( - { - url: '/api/object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], - }, - async () => { - const onFinish = vi.fn(); - const structuredObjectWithOnFinish = new StructuredObject({ - api: '/api/object', - schema: z.object({ content: z.string() }), - onFinish, - }); - await structuredObjectWithOnFinish.submit('test-input'); - - expect(onFinish).toHaveBeenCalledExactlyOnceWith({ - object: { content: 'Hello, world!' }, - error: undefined, - }); - }, - ), - ); - - it( - 'should be called with an error when the stream finishes and the object does not match the schema', - withTestServer( - { - url: '/api/object', - type: 'stream-values', - content: ['{ ', '"content-wrong": "Hello, ', 'world', '!"', '}'], - }, - async () => { - const onFinish = vi.fn(); - const structuredObjectWithOnFinish = new StructuredObject({ - api: '/api/object', - schema: z.object({ content: z.string() }), - onFinish, - }); - await structuredObjectWithOnFinish.submit('test-input'); - - expect(onFinish).toHaveBeenCalledExactlyOnceWith({ - object: undefined, - error: expect.any(Error), - }); - }, - ), - ); + it('should be called with an object when the stream finishes and the object matches the schema', async () => { + server.urls['/api/object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + const onFinish = vi.fn(); + const structuredObjectWithOnFinish = new StructuredObject({ + api: '/api/object', + schema: z.object({ content: z.string() }), + onFinish, + }); + await structuredObjectWithOnFinish.submit('test-input'); + + expect(onFinish).toHaveBeenCalledExactlyOnceWith({ + object: { content: 'Hello, world!' }, + error: undefined, + }); + }); + + it('should be called with an error when the stream finishes and the object does not match the schema', async () => { + server.urls['/api/object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content-wrong": "Hello, ', 'world', '!"', '}'], + }; + + const onFinish = vi.fn(); + const structuredObjectWithOnFinish = new StructuredObject({ + api: '/api/object', + schema: z.object({ content: z.string() }), + onFinish, + }); + await structuredObjectWithOnFinish.submit('test-input'); + + expect(onFinish).toHaveBeenCalledExactlyOnceWith({ + object: undefined, + error: expect.any(Error), + }); + }); }); - it( - 'should send custom headers', - withTestServer( - { - url: '/api/object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + it('should send custom headers', async () => { + server.urls['/api/object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + const structuredObjectWithCustomHeaders = new StructuredObject({ + api: '/api/object', + schema: z.object({ content: z.string() }), + headers: { + Authorization: 'Bearer TEST_TOKEN', + 'X-Custom-Header': 'CustomValue', }, - async ({ call }) => { - const structuredObjectWithCustomHeaders = new StructuredObject({ - api: '/api/object', - schema: z.object({ content: z.string() }), - headers: { - Authorization: 'Bearer TEST_TOKEN', - 'X-Custom-Header': 'CustomValue', - }, - }); + }); - await structuredObjectWithCustomHeaders.submit('test-input'); + await structuredObjectWithCustomHeaders.submit('test-input'); - expect(call(0).getRequestHeaders()).toStrictEqual({ - 'content-type': 'application/json', - authorization: 'Bearer TEST_TOKEN', - 'x-custom-header': 'CustomValue', - }); - }, - ), - ); - - it( - 'should send custom credentials', - withTestServer( - { - url: '/api/object', - type: 'stream-values', - content: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], - }, - async ({ call }) => { - const structuredObjectWithCustomCredentials = new StructuredObject({ - api: '/api/object', - schema: z.object({ content: z.string() }), - credentials: 'include', - }); + expect(server.calls[0].requestHeaders).toStrictEqual({ + 'content-type': 'application/json', + authorization: 'Bearer TEST_TOKEN', + 'x-custom-header': 'CustomValue', + }); + }); - await structuredObjectWithCustomCredentials.submit('test-input'); + it('should send custom credentials', async () => { + server.urls['/api/object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; - expect(call(0).getRequestCredentials()).toBe('include'); - }, - ), - ); + const structuredObjectWithCustomCredentials = new StructuredObject({ + api: '/api/object', + schema: z.object({ content: z.string() }), + credentials: 'include', + }); + + await structuredObjectWithCustomCredentials.submit('test-input'); + + expect(server.calls[0].requestCredentials).toBe('include'); + }); }); describe('synchronization', () => { - it( - 'correctly synchronizes content between hook instances', - withTestServer( - { - type: 'stream-values', - url: '/api/object', - content: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], - }, - async () => { - const { - component: { object1, object2 }, - } = render(StructuredObjectSynchronization, { - id: crypto.randomUUID(), - api: '/api/object', - schema: z.object({ content: z.string() }), - }); + it('correctly synchronizes content between hook instances', async () => { + server.urls['/api/object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + const { + component: { object1, object2 }, + } = render(StructuredObjectSynchronization, { + id: crypto.randomUUID(), + api: '/api/object', + schema: z.object({ content: z.string() }), + }); - await object1.submit('hi'); + await object1.submit('hi'); - expect(object1.object).toStrictEqual({ content: 'Hello, world!' }); - expect(object2.object).toStrictEqual(object1.object); - }, - ), - ); + expect(object1.object).toStrictEqual({ content: 'Hello, world!' }); + expect(object2.object).toStrictEqual(object1.object); + }); - it( - 'correctly synchronizes loading and error state between hook instances', - withTestServer( - { - type: 'controlled-stream', - url: '/api/object', - }, - async ({ streamController }) => { - const { - component: { object1, object2 }, - } = render(StructuredObjectSynchronization, { - id: crypto.randomUUID(), - api: '/api/object', - schema: z.object({ content: z.string() }), - }); + it('correctly synchronizes loading and error state between hook instances', async () => { + const controller = new TestResponseController(); + server.urls['/api/object'].response = { + type: 'controlled-stream', + controller, + }; + + const { + component: { object1, object2 }, + } = render(StructuredObjectSynchronization, { + id: crypto.randomUUID(), + api: '/api/object', + schema: z.object({ content: z.string() }), + }); - const submitOperation = object1.submit('hi'); + const submitOperation = object1.submit('hi'); - await vi.waitFor(() => { - expect(object1.loading).toBe(true); - expect(object2.loading).toBe(true); - }); + await vi.waitFor(() => { + expect(object1.loading).toBe(true); + expect(object2.loading).toBe(true); + }); - streamController.enqueue('{ "content": "Hello"'); - await vi.waitFor(() => { - expect(object1.object).toStrictEqual({ content: 'Hello' }); - expect(object2.object).toStrictEqual(object1.object); - }); + controller.write('{ "content": "Hello"'); + await vi.waitFor(() => { + expect(object1.object).toStrictEqual({ content: 'Hello' }); + expect(object2.object).toStrictEqual(object1.object); + }); - streamController.error(new Error('Failed to be cool enough')); - await submitOperation; + controller.error(new Error('Failed to be cool enough')); + await submitOperation; - expect(object1.loading).toBe(false); - expect(object2.loading).toBe(false); - expect(object1.error).toBeInstanceOf(Error); - expect(object1.error?.message).toBe('Failed to be cool enough'); - expect(object2.error).toBeInstanceOf(Error); - expect(object2.error?.message).toBe('Failed to be cool enough'); - }, - ), - ); + expect(object1.loading).toBe(false); + expect(object2.loading).toBe(false); + expect(object1.error).toBeInstanceOf(Error); + expect(object1.error?.message).toBe('Failed to be cool enough'); + expect(object2.error).toBeInstanceOf(Error); + expect(object2.error?.message).toBe('Failed to be cool enough'); + }); }); From 9cfaaf0a43bac2575e519db6a463bca4a5cc07bc Mon Sep 17 00:00:00 2001 From: Robert Soriano Date: Thu, 3 Apr 2025 07:17:49 -0700 Subject: [PATCH 009/191] docs: Use new `create-nuxt` tool when starting Nuxt projects (#5175) --- content/docs/02-getting-started/05-nuxt.mdx | 2 +- examples/nuxt-openai/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/docs/02-getting-started/05-nuxt.mdx b/content/docs/02-getting-started/05-nuxt.mdx index 72ac0e1b7475..4d1818782cfd 100644 --- a/content/docs/02-getting-started/05-nuxt.mdx +++ b/content/docs/02-getting-started/05-nuxt.mdx @@ -24,7 +24,7 @@ If you haven't obtained your OpenAI API key, you can do so by [signing up](https Start by creating a new Nuxt application. This command will create a new directory named `my-ai-app` and set up a basic Nuxt application inside it. - + Navigate to the newly created directory: diff --git a/examples/nuxt-openai/README.md b/examples/nuxt-openai/README.md index cbadb669da44..bb847c0d912f 100644 --- a/examples/nuxt-openai/README.md +++ b/examples/nuxt-openai/README.md @@ -10,10 +10,10 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu ## How to use -Execute `nuxi` to bootstrap the example: +Execute `create-nuxt` to bootstrap the example: ```bash -npx nuxi@latest init -t github:vercel/ai/examples/nuxt-openai nuxt-openai +npx create-nuxt -t github:vercel/ai/examples/nuxt-openai nuxt-openai ``` To run the example locally you need to: From bc4677783a49d97eadd5dc465ddacd67442ac55b Mon Sep 17 00:00:00 2001 From: colegottdank Date: Fri, 4 Apr 2025 00:01:59 -0700 Subject: [PATCH 010/191] feat (docs): Helicone observability (#5472) --- .../providers/05-observability/helicone.mdx | 223 ++++++++++++++++++ content/providers/05-observability/index.mdx | 1 + 2 files changed, 224 insertions(+) create mode 100644 content/providers/05-observability/helicone.mdx diff --git a/content/providers/05-observability/helicone.mdx b/content/providers/05-observability/helicone.mdx new file mode 100644 index 000000000000..cbf02779bfe0 --- /dev/null +++ b/content/providers/05-observability/helicone.mdx @@ -0,0 +1,223 @@ +--- +title: Helicone +description: Monitor and optimize your AI SDK applications with minimal configuration using Helicone +--- + +# Helicone Observability + +[Helicone](https://helicone.ai) is an open-source LLM observability platform that helps you monitor, analyze, and optimize your AI applications through a proxy-based approach, requiring minimal setup and zero additional dependencies. + +## Setup + +Setting up Helicone: + +1. Create a Helicone account at [helicone.ai](https://helicone.ai) +2. Set your API key as an environment variable: + ```bash filename=".env" + HELICONE_API_KEY=your-helicone-api-key + ``` +3. Update your model provider configuration to use Helicone's proxy: + + ```javascript + import { createOpenAI } from '@ai-sdk/openai'; + + const openai = createOpenAI({ + baseURL: 'https://oai.helicone.ai/v1', + headers: { + 'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`, + }, + }); + + // Use normally with AI SDK + const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: 'Hello world', + }); + ``` + +That's it! Your requests are now being logged and monitored through Helicone. + +[→ Learn more about getting started with Helicone on AI SDK](https://docs.helicone.ai/getting-started/integration-method/vercelai) + +## Integration Approach + +While other observability solutions require OpenTelemetry instrumentation, Helicone uses a simple proxy approach: + + + + ```javascript + const openai = createOpenAI({ + baseURL: "https://oai.helicone.ai/v1", + headers: { "Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}` }, + }); + ``` + + + + ```javascript + // Install multiple packages + // @vercel/otel, @opentelemetry/sdk-node, @opentelemetry/auto-instrumentations-node, etc. + + // Create exporter + const exporter = new OtherProviderExporter({ + projectApiKey: process.env.API_KEY + }); + + // Setup SDK + const sdk = new NodeSDK({ + traceExporter: exporter, + instrumentations: [getNodeAutoInstrumentations()], + resource: new Resource({...}), + }); + + // Start SDK + sdk.start(); + + // Enable telemetry on each request + const response = await generateText({ + model: openai("gpt-4o-mini"), + prompt: "Hello world", + experimental_telemetry: { isEnabled: true } + }); + + // Shutdown SDK to flush traces + await sdk.shutdown(); + ``` + + + +**Characteristics of Helicone's Proxy Approach:** + +- No additional packages required +- Compatible with JavaScript environments +- Minimal code changes to existing implementations +- Supports features such as caching and rate limiting + +[→ Learn more about Helicone's proxy approach](https://docs.helicone.ai/references/proxy-vs-async) + +## Core Features + +### User Tracking + +Monitor how individual users interact with your AI application: + +```javascript +const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: 'Hello world', + headers: { + 'Helicone-User-Id': 'user@example.com', + }, +}); +``` + +[→ Learn more about User Metrics](https://docs.helicone.ai/features/advanced-usage/user-metrics) + +### Custom Properties + +Add structured metadata to filter and analyze requests: + +```javascript +const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: 'Translate this text to French', + headers: { + 'Helicone-Property-Feature': 'translation', + 'Helicone-Property-Source': 'mobile-app', + 'Helicone-Property-Language': 'French', + }, +}); +``` + +[→ Learn more about Custom Properties](https://docs.helicone.ai/features/advanced-usage/custom-properties) + +### Session Tracking + +Group related requests into coherent conversations: + +```javascript +const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: 'Tell me more about that', + headers: { + 'Helicone-Session-Id': 'convo-123', + 'Helicone-Session-Name': 'Travel Planning', + 'Helicone-Session-Path': '/chats/travel', + }, +}); +``` + +[→ Learn more about Sessions](https://docs.helicone.ai/features/sessions) + +## Advanced Configuration + +### Request Caching + +Reduce costs by caching identical requests: + +```javascript +const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: 'What is the capital of France?', + headers: { + 'Helicone-Cache-Enabled': 'true', + }, +}); +``` + +[→ Learn more about Caching](https://docs.helicone.ai/features/advanced-usage/caching) + +### Rate Limiting + +Control usage by adding a rate limit policy: + +```javascript +const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: 'Generate creative content', + headers: { + // Allow 10,000 requests per hour + 'Helicone-RateLimit-Policy': '10000;w=3600', + + // Optional: limit by user + 'Helicone-User-Id': 'user@example.com', + }, +}); +``` + +Format: `[quota];w=[time_window];u=[unit];s=[segment]` where: + +- `quota`: Maximum requests allowed in the time window +- `w`: Time window in seconds (minimum 60s) +- `u`: Optional unit - "request" (default) or "cents" +- `s`: Optional segment - "user", custom property, or global (default) + +[→ Learn more about Rate Limiting](https://docs.helicone.ai/features/advanced-usage/custom-rate-limits) + +### LLM Security + +Protect against prompt injection, jailbreaking, and other LLM-specific threats: + +```javascript +const response = await generateText({ + model: openai('gpt-4o-mini'), + prompt: userInput, + headers: { + // Basic protection (Prompt Guard model) + 'Helicone-LLM-Security-Enabled': 'true', + + // Optional: Advanced protection (Llama Guard model) + 'Helicone-LLM-Security-Advanced': 'true', + }, +}); +``` + +Protects against multiple attack vectors in 8 languages with minimal latency. Advanced mode adds protection across 14 threat categories. + +[→ Learn more about LLM Security](https://docs.helicone.ai/features/advanced-usage/llm-security) + +## Resources + +- [Helicone Documentation](https://docs.helicone.ai) +- [GitHub Repository](https://github.com/Helicone/helicone) +- [Discord Community](https://discord.com/invite/2TkeWdXNPQ) diff --git a/content/providers/05-observability/index.mdx b/content/providers/05-observability/index.mdx index fa54df2979d7..2f846d3a748d 100644 --- a/content/providers/05-observability/index.mdx +++ b/content/providers/05-observability/index.mdx @@ -8,6 +8,7 @@ description: AI SDK Integration for monitoring and tracing LLM applications Several LLM observability providers offer integrations with the AI SDK telemetry data: - [Braintrust](/providers/observability/braintrust) +- [Helicone](/providers/observability/helicone) - [Traceloop](/providers/observability/traceloop) - [Langfuse](/providers/observability/langfuse) - [LangSmith](/providers/observability/langsmith) From 0ee98df1629d4d0833d5463872b26282083f6ac9 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:08:00 +0100 Subject: [PATCH 011/191] docs: add local caching middleware recipe (#5540) --- .../05-node/80-local-caching-middleware.mdx | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 content/cookbook/05-node/80-local-caching-middleware.mdx diff --git a/content/cookbook/05-node/80-local-caching-middleware.mdx b/content/cookbook/05-node/80-local-caching-middleware.mdx new file mode 100644 index 000000000000..e2a95a51287d --- /dev/null +++ b/content/cookbook/05-node/80-local-caching-middleware.mdx @@ -0,0 +1,242 @@ +--- +title: Local Caching Middleware +description: Learn how to create a caching middleware for local development. +tags: ['streaming', 'caching', 'middleware'] +--- + +# Local Caching Middleware + +When developing AI applications, you'll often find yourself repeatedly making the same API calls during development. This can lead to increased costs and slower development cycles. A caching middleware allows you to store responses locally and reuse them when the same inputs are provided. + +This approach is particularly useful in two scenarios: + +1. **Iterating on UI/UX** - When you're focused on styling and user experience, you don't want to regenerate AI responses for every code change. +2. **Working on evals** - When developing evals, you need to repeatedly test the same prompts, but don't need new generations each time. + +## Implementation + +In this implementation, you create a JSON file to store responses. When a request is made, you first check if you have already seen this exact request. If you have, you return the cached response immediately (as a one-off generation or chunks of tokens). If not, you trigger the generation, save the response, and return it. + + + Make sure to add the path of your local cache to your `.gitignore` so you do + not commit it. + + +### How it works + +For regular generations, you store and retrieve complete responses. Instead, the streaming implementation captures each token as it arrives, stores the full sequence, and on cache hits uses the SDK's `simulateReadableStream` utility to recreate the token-by-token streaming experience at a controlled speed (defaults to 10ms between chunks). + +This approach gives you the best of both worlds: + +- Instant responses for repeated queries +- Preserved streaming behavior for UI development + +The middleware handles all transformations needed to make cached responses indistinguishable from fresh ones, including normalizing tool calls and fixing timestamp formats. + +### Middleware + +```ts +import { + type LanguageModelV1, + type LanguageModelV1Middleware, + LanguageModelV1Prompt, + type LanguageModelV1StreamPart, + simulateReadableStream, + wrapLanguageModel, +} from 'ai'; +import 'dotenv/config'; +import fs from 'fs'; +import path from 'path'; + +const CACHE_FILE = path.join(process.cwd(), '.cache/ai-cache.json'); + +export const cached = (model: LanguageModelV1) => + wrapLanguageModel({ + middleware: cacheMiddleware, + model, + }); + +const ensureCacheFile = () => { + const cacheDir = path.dirname(CACHE_FILE); + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }); + } + if (!fs.existsSync(CACHE_FILE)) { + fs.writeFileSync(CACHE_FILE, '{}'); + } +}; + +const getCachedResult = (key: string | object) => { + ensureCacheFile(); + const cacheKey = typeof key === 'object' ? JSON.stringify(key) : key; + try { + const cacheContent = fs.readFileSync(CACHE_FILE, 'utf-8'); + + const cache = JSON.parse(cacheContent); + + const result = cache[cacheKey]; + + return result ?? null; + } catch (error) { + console.error('Cache error:', error); + return null; + } +}; + +const updateCache = (key: string, value: any) => { + ensureCacheFile(); + try { + const cache = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8')); + const updatedCache = { ...cache, [key]: value }; + fs.writeFileSync(CACHE_FILE, JSON.stringify(updatedCache, null, 2)); + console.log('Cache updated for key:', key); + } catch (error) { + console.error('Failed to update cache:', error); + } +}; +const cleanPrompt = (prompt: LanguageModelV1Prompt) => { + return prompt.map(m => { + if (m.role === 'assistant') { + return m.content.map(part => + part.type === 'tool-call' ? { ...part, toolCallId: 'cached' } : part, + ); + } + if (m.role === 'tool') { + return m.content.map(tc => ({ + ...tc, + toolCallId: 'cached', + result: {}, + })); + } + + return m; + }); +}; + +export const cacheMiddleware: LanguageModelV1Middleware = { + wrapGenerate: async ({ doGenerate, params }) => { + const cacheKey = JSON.stringify({ + ...cleanPrompt(params.prompt), + _function: 'generate', + }); + console.log('Cache Key:', cacheKey); + + const cached = getCachedResult(cacheKey) as Awaited< + ReturnType + > | null; + + if (cached && cached !== null) { + console.log('Cache Hit'); + return { + ...cached, + response: { + ...cached.response, + timestamp: cached?.response?.timestamp + ? new Date(cached?.response?.timestamp) + : undefined, + }, + }; + } + + console.log('Cache Miss'); + const result = await doGenerate(); + + updateCache(cacheKey, result); + + return result; + }, + wrapStream: async ({ doStream, params }) => { + const cacheKey = JSON.stringify({ + ...cleanPrompt(params.prompt), + _function: 'stream', + }); + console.log('Cache Key:', cacheKey); + + // Check if the result is in the cache + const cached = getCachedResult(cacheKey); + + // If cached, return a simulated ReadableStream that yields the cached result + if (cached && cached !== null) { + console.log('Cache Hit'); + // Format the timestamps in the cached response + const formattedChunks = (cached as LanguageModelV1StreamPart[]).map(p => { + if (p.type === 'response-metadata' && p.timestamp) { + return { ...p, timestamp: new Date(p.timestamp) }; + } else return p; + }); + return { + stream: simulateReadableStream({ + initialDelayInMs: 0, + chunkDelayInMs: 10, + chunks: formattedChunks, + }), + rawCall: { rawPrompt: null, rawSettings: {} }, + }; + } + + console.log('Cache Miss'); + // If not cached, proceed with streaming + const { stream, ...rest } = await doStream(); + + const fullResponse: LanguageModelV1StreamPart[] = []; + + const transformStream = new TransformStream< + LanguageModelV1StreamPart, + LanguageModelV1StreamPart + >({ + transform(chunk, controller) { + fullResponse.push(chunk); + controller.enqueue(chunk); + }, + flush() { + // Store the full response in the cache after streaming is complete + updateCache(cacheKey, fullResponse); + }, + }); + + return { + stream: stream.pipeThrough(transformStream), + ...rest, + }; + }, +}; +``` + +## Using the Middleware + +The middleware can be easily integrated into your existing AI SDK setup: + +```ts highlight="4,8" +import { openai } from '@ai-sdk/openai'; +import { streamText } from 'ai'; +import 'dotenv/config'; +import { cached } from '../middleware/your-cache-middleware'; + +async function main() { + const result = streamText({ + model: cached(openai('gpt-4o')), + maxTokens: 512, + temperature: 0.3, + maxRetries: 5, + prompt: 'Invent a new holiday and describe its traditions.', + }); + + for await (const textPart of result.textStream) { + process.stdout.write(textPart); + } + + console.log(); + console.log('Token usage:', await result.usage); + console.log('Finish reason:', await result.finishReason); +} + +main().catch(console.error); +``` + +## Considerations + +When using this caching middleware, keep these points in mind: + +1. **Development Only** - This approach is intended for local development, not production environments +2. **Cache Invalidation** - You'll need to clear the cache (delete the cache file) when you want fresh responses +3. **Multi-Step Flows** - When using `maxSteps`, be aware that caching occurs at the individual language model response level, not across the entire execution flow. This means that while the model's generation is cached, the tool call is not and will run on each generation. From 5952cfbe92ad7a80ee2238b663c60e2f8550c598 Mon Sep 17 00:00:00 2001 From: Gen Tamura Date: Fri, 4 Apr 2025 19:06:13 +0900 Subject: [PATCH 012/191] fix (docs): highlight (#5545) --- content/docs/02-getting-started/02-nextjs-app-router.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/02-getting-started/02-nextjs-app-router.mdx b/content/docs/02-getting-started/02-nextjs-app-router.mdx index 8a8bc840e606..1de3a89c7c82 100644 --- a/content/docs/02-getting-started/02-nextjs-app-router.mdx +++ b/content/docs/02-getting-started/02-nextjs-app-router.mdx @@ -244,7 +244,7 @@ Notice the blank response in the UI? This is because instead of generating a tex To display the tool invocations in your UI, update your `app/page.tsx` file: -```tsx filename="app/page.tsx" highlight="18-24" +```tsx filename="app/page.tsx" highlight="16-21" 'use client'; import { useChat } from '@ai-sdk/react'; From 772a2d71902220515e205d6deec260e9c48b398f Mon Sep 17 00:00:00 2001 From: BramMeerten Date: Fri, 4 Apr 2025 16:15:00 +0200 Subject: [PATCH 013/191] feat (core): Add finishReason field to NoObjectGeneratedError (#5541) Co-authored-by: Bram Meerten --- .changeset/flat-plums-bake.md | 5 +++++ .../ai-no-object-generated-error.mdx | 2 ++ .../ai/core/generate-object/generate-object.test.ts | 1 + packages/ai/core/generate-object/generate-object.ts | 4 ++++ packages/ai/core/generate-object/output-strategy.ts | 8 +++++++- .../ai/core/generate-object/stream-object.test.ts | 6 ++++++ packages/ai/core/generate-object/stream-object.ts | 1 + packages/ai/core/generate-text/generate-text.ts | 6 +++++- packages/ai/core/generate-text/output.test.ts | 4 ++++ packages/ai/core/generate-text/output.ts | 5 +++++ packages/ai/errors/no-object-generated-error.ts | 13 +++++++++++++ 11 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 .changeset/flat-plums-bake.md diff --git a/.changeset/flat-plums-bake.md b/.changeset/flat-plums-bake.md new file mode 100644 index 000000000000..d7092eca4757 --- /dev/null +++ b/.changeset/flat-plums-bake.md @@ -0,0 +1,5 @@ +--- +'ai': minor +--- + +feat (core): Add finishReason field to NoObjectGeneratedError diff --git a/content/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx b/content/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx index bac1c98474ff..ef98315a0d31 100644 --- a/content/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx +++ b/content/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx @@ -18,6 +18,7 @@ It can arise due to the following reasons: - `text`: The text that was generated by the model. This can be the raw text or the tool call text, depending on the object generation mode. - `response`: Metadata about the language model response, including response id, timestamp, and model. - `usage`: Request token usage. +- `finishReason`: Request finish reason. For example 'length' if model generated maximum number of tokens, this could result in a JSON parsing error. - `cause`: The cause of the error (e.g. a JSON parsing error). You can use this for more detailed error handling. ## Checking for this Error @@ -36,6 +37,7 @@ try { console.log('Text:', error.text); console.log('Response:', error.response); console.log('Usage:', error.usage); + console.log('Finish Reason:', error.finishReason); } } ``` diff --git a/packages/ai/core/generate-object/generate-object.test.ts b/packages/ai/core/generate-object/generate-object.test.ts index 0686c05c4494..80747e4f286c 100644 --- a/packages/ai/core/generate-object/generate-object.test.ts +++ b/packages/ai/core/generate-object/generate-object.test.ts @@ -801,6 +801,7 @@ describe('output = "object"', () => { promptTokens: 10, totalTokens: 30, }, + finishReason: 'stop', }); } diff --git a/packages/ai/core/generate-object/generate-object.ts b/packages/ai/core/generate-object/generate-object.ts index 6284a12d8262..1a2e279d3726 100644 --- a/packages/ai/core/generate-object/generate-object.ts +++ b/packages/ai/core/generate-object/generate-object.ts @@ -556,6 +556,7 @@ export async function generateObject({ 'No object generated: the model did not return a response.', response: responseData, usage: calculateLanguageModelUsage(result.usage), + finishReason: result.finishReason, }); } @@ -681,6 +682,7 @@ export async function generateObject({ message: 'No object generated: the tool was not called.', response: responseData, usage: calculateLanguageModelUsage(result.usage), + finishReason: result.finishReason, }); } @@ -751,6 +753,7 @@ export async function generateObject({ text: result, response, usage: calculateLanguageModelUsage(usage), + finishReason: finishReason, }); } @@ -770,6 +773,7 @@ export async function generateObject({ text: result, response, usage: calculateLanguageModelUsage(usage), + finishReason: finishReason, }); } diff --git a/packages/ai/core/generate-object/output-strategy.ts b/packages/ai/core/generate-object/output-strategy.ts index 07c9d70ecd38..6da624bd331c 100644 --- a/packages/ai/core/generate-object/output-strategy.ts +++ b/packages/ai/core/generate-object/output-strategy.ts @@ -16,7 +16,11 @@ import { createAsyncIterableStream, } from '../util/async-iterable-stream'; import { ObjectStreamPart } from './stream-object-result'; -import { LanguageModelResponseMetadata, LanguageModelUsage } from '../types'; +import { + FinishReason, + LanguageModelResponseMetadata, + LanguageModelUsage, +} from '../types'; export interface OutputStrategy { readonly type: 'object' | 'array' | 'enum' | 'no-schema'; @@ -64,6 +68,7 @@ const noSchemaOutputStrategy: OutputStrategy = { text: string; response: LanguageModelResponseMetadata; usage: LanguageModelUsage; + finishReason: FinishReason; }, ): ValidationResult { return value === undefined @@ -74,6 +79,7 @@ const noSchemaOutputStrategy: OutputStrategy = { text: context.text, response: context.response, usage: context.usage, + finishReason: context.finishReason, }), } : { success: true, value }; diff --git a/packages/ai/core/generate-object/stream-object.test.ts b/packages/ai/core/generate-object/stream-object.test.ts index a645b1943159..0414a6d26c29 100644 --- a/packages/ai/core/generate-object/stream-object.test.ts +++ b/packages/ai/core/generate-object/stream-object.test.ts @@ -1311,6 +1311,7 @@ describe('streamObject', () => { modelId: 'model-1', }, usage: { completionTokens: 10, promptTokens: 3, totalTokens: 13 }, + finishReason: 'stop', }); } }); @@ -1354,6 +1355,7 @@ describe('streamObject', () => { modelId: 'model-1', }, usage: { completionTokens: 10, promptTokens: 3, totalTokens: 13 }, + finishReason: 'stop', }); } }); @@ -1403,6 +1405,7 @@ describe('streamObject', () => { modelId: 'model-1', }, usage: { completionTokens: 10, promptTokens: 3, totalTokens: 13 }, + finishReason: 'stop', }); } }); @@ -1446,6 +1449,7 @@ describe('streamObject', () => { modelId: 'model-1', }, usage: { completionTokens: 10, promptTokens: 3, totalTokens: 13 }, + finishReason: 'stop', }); } }); @@ -1488,6 +1492,7 @@ describe('streamObject', () => { modelId: 'model-1', }, usage: { completionTokens: 10, promptTokens: 3, totalTokens: 13 }, + finishReason: 'stop', }); } }); @@ -1530,6 +1535,7 @@ describe('streamObject', () => { modelId: 'model-1', }, usage: { completionTokens: 10, promptTokens: 3, totalTokens: 13 }, + finishReason: 'stop', }); } }); diff --git a/packages/ai/core/generate-object/stream-object.ts b/packages/ai/core/generate-object/stream-object.ts index 0cc5607bcf59..9f79cd1c3184 100644 --- a/packages/ai/core/generate-object/stream-object.ts +++ b/packages/ai/core/generate-object/stream-object.ts @@ -898,6 +898,7 @@ class DefaultStreamObjectResult text: accumulatedText, response, usage, + finishReason: finishReason, }); self.objectPromise.reject(error); } diff --git a/packages/ai/core/generate-text/generate-text.ts b/packages/ai/core/generate-text/generate-text.ts index 58b82664b47b..3f4293114b3f 100644 --- a/packages/ai/core/generate-text/generate-text.ts +++ b/packages/ai/core/generate-text/generate-text.ts @@ -576,7 +576,11 @@ A function that attempts to repair a tool call that failed to parse. return output.parseOutput( { text }, - { response: currentModelResponse.response, usage }, + { + response: currentModelResponse.response, + usage, + finishReason: currentModelResponse.finishReason, + }, ); }, toolCalls: currentToolCalls, diff --git a/packages/ai/core/generate-text/output.test.ts b/packages/ai/core/generate-text/output.test.ts index adde6bb5b610..d0a839036008 100644 --- a/packages/ai/core/generate-text/output.test.ts +++ b/packages/ai/core/generate-text/output.test.ts @@ -2,6 +2,7 @@ import { fail } from 'assert'; import { z } from 'zod'; import { verifyNoObjectGeneratedError } from '../../errors/no-object-generated-error'; import { object } from './output'; +import { FinishReason } from '../types'; const context = { response: { @@ -14,6 +15,7 @@ const context = { completionTokens: 2, totalTokens: 3, }, + finishReason: 'length' as FinishReason, }; describe('Output.object', () => { @@ -37,6 +39,7 @@ describe('Output.object', () => { message: 'No object generated: could not parse the response.', response: context.response, usage: context.usage, + finishReason: context.finishReason, }); } }); @@ -50,6 +53,7 @@ describe('Output.object', () => { message: 'No object generated: response did not match schema.', response: context.response, usage: context.usage, + finishReason: context.finishReason, }); } }); diff --git a/packages/ai/core/generate-text/output.ts b/packages/ai/core/generate-text/output.ts index 7d54fccbbb11..faa632a6f7a2 100644 --- a/packages/ai/core/generate-text/output.ts +++ b/packages/ai/core/generate-text/output.ts @@ -9,6 +9,7 @@ import { z } from 'zod'; import { NoObjectGeneratedError } from '../../errors'; import { injectJsonInstruction } from '../generate-object/inject-json-instruction'; import { + FinishReason, LanguageModel, LanguageModelV1CallOptions, } from '../types/language-model'; @@ -33,6 +34,7 @@ export interface Output { context: { response: LanguageModelResponseMetadata; usage: LanguageModelUsage; + finishReason: FinishReason; }, ): OUTPUT; } @@ -108,6 +110,7 @@ export const object = ({ context: { response: LanguageModelResponseMetadata; usage: LanguageModelUsage; + finishReason: FinishReason; }, ) { const parseResult = safeParseJSON({ text }); @@ -119,6 +122,7 @@ export const object = ({ text, response: context.response, usage: context.usage, + finishReason: context.finishReason, }); } @@ -134,6 +138,7 @@ export const object = ({ text, response: context.response, usage: context.usage, + finishReason: context.finishReason, }); } diff --git a/packages/ai/errors/no-object-generated-error.ts b/packages/ai/errors/no-object-generated-error.ts index 77ec7f5f1d52..06b7c05846c9 100644 --- a/packages/ai/errors/no-object-generated-error.ts +++ b/packages/ai/errors/no-object-generated-error.ts @@ -1,6 +1,7 @@ import { AISDKError } from '@ai-sdk/provider'; import { LanguageModelResponseMetadata } from '../core/types/language-model-response-metadata'; import { LanguageModelUsage } from '../core/types/usage'; +import { FinishReason } from '../core'; const name = 'AI_NoObjectGeneratedError'; const marker = `vercel.ai.error.${name}`; @@ -35,24 +36,32 @@ export class NoObjectGeneratedError extends AISDKError { */ readonly usage: LanguageModelUsage | undefined; + /** + Reason why the model finished generating a response. + */ + readonly finishReason: FinishReason | undefined; + constructor({ message = 'No object generated.', cause, text, response, usage, + finishReason, }: { message?: string; cause?: Error; text?: string; response: LanguageModelResponseMetadata; usage: LanguageModelUsage; + finishReason: FinishReason; }) { super({ name, message, cause }); this.text = text; this.response = response; this.usage = usage; + this.finishReason = finishReason; } static isInstance(error: unknown): error is NoObjectGeneratedError { @@ -66,6 +75,7 @@ export function verifyNoObjectGeneratedError( message: string; response: LanguageModelResponseMetadata; usage: LanguageModelUsage; + finishReason: FinishReason; }, ) { expect(NoObjectGeneratedError.isInstance(error)).toBeTruthy(); @@ -73,4 +83,7 @@ export function verifyNoObjectGeneratedError( expect(noObjectGeneratedError.message).toStrictEqual(expected.message); expect(noObjectGeneratedError.response).toStrictEqual(expected.response); expect(noObjectGeneratedError.usage).toStrictEqual(expected.usage); + expect(noObjectGeneratedError.finishReason).toStrictEqual( + expected.finishReason, + ); } From ed79357de73b3165a07b4b41c960ffe7d8acc7fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:34:29 +0200 Subject: [PATCH 014/191] Version Packages (#5536) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/clean-numbers-cover.md | 5 - .changeset/flat-plums-bake.md | 5 - examples/ai-core/package.json | 44 ++-- examples/express/package.json | 4 +- examples/fastify/package.json | 4 +- examples/hono/package.json | 4 +- examples/mcp/package.json | 4 +- examples/nest/package.json | 4 +- examples/next-fastapi/package.json | 6 +- examples/next-google-vertex/package.json | 4 +- examples/next-langchain/package.json | 4 +- .../package.json | 6 +- examples/next-openai-pages/package.json | 6 +- .../next-openai-telemetry-sentry/package.json | 6 +- examples/next-openai-telemetry/package.json | 6 +- .../package.json | 6 +- examples/next-openai/package.json | 20 +- examples/node-http-server/package.json | 4 +- examples/nuxt-openai/package.json | 6 +- examples/solidstart-openai/package.json | 8 +- examples/sveltekit-openai/package.json | 10 +- packages/ai/CHANGELOG.md | 13 + packages/ai/package.json | 8 +- .../ai/tests/e2e/next-server/CHANGELOG.md | 7 + packages/amazon-bedrock/CHANGELOG.md | 7 + packages/amazon-bedrock/package.json | 4 +- packages/anthropic/CHANGELOG.md | 7 + packages/anthropic/package.json | 4 +- packages/azure/CHANGELOG.md | 8 + packages/azure/package.json | 6 +- packages/cerebras/CHANGELOG.md | 8 + packages/cerebras/package.json | 6 +- packages/cohere/CHANGELOG.md | 7 + packages/cohere/package.json | 4 +- packages/deepinfra/CHANGELOG.md | 8 + packages/deepinfra/package.json | 6 +- packages/deepseek/CHANGELOG.md | 8 + packages/deepseek/package.json | 6 +- packages/fal/CHANGELOG.md | 7 + packages/fal/package.json | 4 +- packages/fireworks/CHANGELOG.md | 8 + packages/fireworks/package.json | 6 +- packages/google-vertex/CHANGELOG.md | 9 + packages/google-vertex/package.json | 8 +- packages/google/CHANGELOG.md | 7 + packages/google/package.json | 4 +- packages/groq/CHANGELOG.md | 7 + packages/groq/package.json | 4 +- packages/luma/CHANGELOG.md | 7 + packages/luma/package.json | 4 +- packages/mistral/CHANGELOG.md | 7 + packages/mistral/package.json | 4 +- packages/openai-compatible/CHANGELOG.md | 7 + packages/openai-compatible/package.json | 4 +- packages/openai/CHANGELOG.md | 7 + packages/openai/package.json | 4 +- packages/perplexity/CHANGELOG.md | 7 + packages/perplexity/package.json | 4 +- packages/provider-utils/CHANGELOG.md | 6 + packages/provider-utils/package.json | 2 +- packages/react/CHANGELOG.md | 8 + packages/react/package.json | 6 +- packages/replicate/CHANGELOG.md | 7 + packages/replicate/package.json | 4 +- packages/solid/CHANGELOG.md | 8 + packages/solid/package.json | 6 +- packages/svelte/CHANGELOG.md | 8 + packages/svelte/package.json | 6 +- packages/togetherai/CHANGELOG.md | 8 + packages/togetherai/package.json | 6 +- packages/ui-utils/CHANGELOG.md | 7 + packages/ui-utils/package.json | 4 +- packages/valibot/CHANGELOG.md | 7 + packages/valibot/package.json | 4 +- packages/vue/CHANGELOG.md | 8 + packages/vue/package.json | 6 +- packages/xai/CHANGELOG.md | 8 + packages/xai/package.json | 6 +- pnpm-lock.yaml | 248 +++++++++--------- 79 files changed, 493 insertions(+), 282 deletions(-) delete mode 100644 .changeset/clean-numbers-cover.md delete mode 100644 .changeset/flat-plums-bake.md diff --git a/.changeset/clean-numbers-cover.md b/.changeset/clean-numbers-cover.md deleted file mode 100644 index 590b5df0eec2..000000000000 --- a/.changeset/clean-numbers-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/provider-utils': patch ---- - -feat(provider-utils): add TestServerCall#requestCredentials diff --git a/.changeset/flat-plums-bake.md b/.changeset/flat-plums-bake.md deleted file mode 100644 index d7092eca4757..000000000000 --- a/.changeset/flat-plums-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': minor ---- - -feat (core): Add finishReason field to NoObjectGeneratedError diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 927f05428015..b559952fdf95 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -3,33 +3,33 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/amazon-bedrock": "2.2.4", - "@ai-sdk/anthropic": "1.2.5", - "@ai-sdk/azure": "1.3.6", - "@ai-sdk/cerebras": "0.2.5", - "@ai-sdk/cohere": "1.2.4", - "@ai-sdk/deepinfra": "0.2.5", - "@ai-sdk/deepseek": "0.2.5", - "@ai-sdk/fal": "0.1.4", - "@ai-sdk/fireworks": "0.2.5", - "@ai-sdk/google": "1.2.5", - "@ai-sdk/google-vertex": "2.2.8", - "@ai-sdk/groq": "1.2.3", - "@ai-sdk/luma": "0.1.3", - "@ai-sdk/mistral": "1.2.3", - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/openai-compatible": "0.2.5", - "@ai-sdk/perplexity": "1.1.3", + "@ai-sdk/amazon-bedrock": "2.2.5", + "@ai-sdk/anthropic": "1.2.6", + "@ai-sdk/azure": "1.3.7", + "@ai-sdk/cerebras": "0.2.6", + "@ai-sdk/cohere": "1.2.5", + "@ai-sdk/deepinfra": "0.2.6", + "@ai-sdk/deepseek": "0.2.6", + "@ai-sdk/fal": "0.1.5", + "@ai-sdk/fireworks": "0.2.6", + "@ai-sdk/google": "1.2.6", + "@ai-sdk/google-vertex": "2.2.9", + "@ai-sdk/groq": "1.2.4", + "@ai-sdk/luma": "0.1.4", + "@ai-sdk/mistral": "1.2.4", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/openai-compatible": "0.2.6", + "@ai-sdk/perplexity": "1.1.4", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/replicate": "0.2.3", - "@ai-sdk/togetherai": "0.2.5", - "@ai-sdk/xai": "1.2.6", - "@ai-sdk/valibot": "0.1.11", + "@ai-sdk/replicate": "0.2.4", + "@ai-sdk/togetherai": "0.2.6", + "@ai-sdk/xai": "1.2.7", + "@ai-sdk/valibot": "0.1.12", "@google/generative-ai": "0.21.0", "@opentelemetry/auto-instrumentations-node": "0.54.0", "@opentelemetry/sdk-node": "0.54.2", "@opentelemetry/sdk-trace-node": "1.28.0", - "ai": "4.2.11", + "ai": "4.3.0", "dotenv": "16.4.5", "image-type": "^5.2.0", "mathjs": "14.0.0", diff --git a/examples/express/package.json b/examples/express/package.json index 9bd08aa576fc..c8733146c5fd 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -7,8 +7,8 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "ai": "4.2.11", + "@ai-sdk/openai": "1.3.7", + "ai": "4.3.0", "dotenv": "16.4.5", "express": "5.0.1" }, diff --git a/examples/fastify/package.json b/examples/fastify/package.json index d9ecc12b8e0c..8b0076c109b2 100644 --- a/examples/fastify/package.json +++ b/examples/fastify/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "ai": "4.2.11", + "@ai-sdk/openai": "1.3.7", + "ai": "4.3.0", "dotenv": "16.4.5", "fastify": "5.1.0" }, diff --git a/examples/hono/package.json b/examples/hono/package.json index 0ee1269c5bf8..3fda75474e35 100644 --- a/examples/hono/package.json +++ b/examples/hono/package.json @@ -3,9 +3,9 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.6", + "@ai-sdk/openai": "1.3.7", "@hono/node-server": "1.13.7", - "ai": "4.2.11", + "ai": "4.3.0", "dotenv": "16.4.5", "hono": "4.6.9" }, diff --git a/examples/mcp/package.json b/examples/mcp/package.json index 81272bec3b3d..db4c45fbc777 100644 --- a/examples/mcp/package.json +++ b/examples/mcp/package.json @@ -12,9 +12,9 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", + "@ai-sdk/openai": "1.3.7", "@modelcontextprotocol/sdk": "^1.7.0", - "ai": "4.2.11", + "ai": "4.3.0", "dotenv": "16.4.5", "express": "5.0.1", "zod": "3.23.8" diff --git a/examples/nest/package.json b/examples/nest/package.json index fbedae50258e..726f53327457 100644 --- a/examples/nest/package.json +++ b/examples/nest/package.json @@ -15,11 +15,11 @@ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", + "@ai-sdk/openai": "1.3.7", "@nestjs/common": "^10.4.15", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.4.9", - "ai": "4.2.11", + "ai": "4.3.0", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/examples/next-fastapi/package.json b/examples/next-fastapi/package.json index 494463703a72..3114aaa23ed1 100644 --- a/examples/next-fastapi/package.json +++ b/examples/next-fastapi/package.json @@ -11,9 +11,9 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/ui-utils": "1.2.4", - "@ai-sdk/react": "1.2.5", - "ai": "4.2.11", + "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/react": "1.2.6", + "ai": "4.3.0", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index e4c5fc973ee6..1efb38c29389 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,8 +9,8 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.8", - "ai": "4.2.11", + "@ai-sdk/google-vertex": "2.2.9", + "ai": "4.3.0", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-langchain/package.json b/examples/next-langchain/package.json index 016be9174fee..acfb5b04f037 100644 --- a/examples/next-langchain/package.json +++ b/examples/next-langchain/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/react": "1.2.5", + "@ai-sdk/react": "1.2.6", "@langchain/openai": "0.0.28", "@langchain/core": "0.1.63", - "ai": "4.2.11", + "ai": "4.3.0", "langchain": "0.1.36", "next": "latest", "react": "^18", diff --git a/examples/next-openai-kasada-bot-protection/package.json b/examples/next-openai-kasada-bot-protection/package.json index 863339ddcce2..5115f36f7fd1 100644 --- a/examples/next-openai-kasada-bot-protection/package.json +++ b/examples/next-openai-kasada-bot-protection/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/react": "1.2.5", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/react": "1.2.6", "@vercel/functions": "latest", - "ai": "4.2.11", + "ai": "4.3.0", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai-pages/package.json b/examples/next-openai-pages/package.json index 0db62cacf433..896c305e1705 100644 --- a/examples/next-openai-pages/package.json +++ b/examples/next-openai-pages/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/react": "1.2.5", - "ai": "4.2.11", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/react": "1.2.6", + "ai": "4.3.0", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry-sentry/package.json b/examples/next-openai-telemetry-sentry/package.json index 34f63b0efabb..872fa1fb46b4 100644 --- a/examples/next-openai-telemetry-sentry/package.json +++ b/examples/next-openai-telemetry-sentry/package.json @@ -9,15 +9,15 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/react": "1.2.5", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/react": "1.2.6", "@opentelemetry/api-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@opentelemetry/sdk-logs": "0.55.0", "@sentry/nextjs": "^8.42.0", "@sentry/opentelemetry": "8.22.0", "@vercel/otel": "1.10.0", - "ai": "4.2.11", + "ai": "4.3.0", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry/package.json b/examples/next-openai-telemetry/package.json index 4ce0597f7034..b5ac98405eb8 100644 --- a/examples/next-openai-telemetry/package.json +++ b/examples/next-openai-telemetry/package.json @@ -9,13 +9,13 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/react": "1.2.5", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/react": "1.2.6", "@opentelemetry/api-logs": "0.55.0", "@opentelemetry/sdk-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@vercel/otel": "1.10.0", - "ai": "4.2.11", + "ai": "4.3.0", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-upstash-rate-limits/package.json b/examples/next-openai-upstash-rate-limits/package.json index e738dfec075b..11ac194c2f60 100644 --- a/examples/next-openai-upstash-rate-limits/package.json +++ b/examples/next-openai-upstash-rate-limits/package.json @@ -9,11 +9,11 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/react": "1.2.5", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/react": "1.2.6", "@upstash/ratelimit": "^0.4.3", "@vercel/kv": "^0.2.2", - "ai": "4.2.11", + "ai": "4.3.0", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 75e8936c5992..5b0fd44a8e7b 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -9,17 +9,17 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/anthropic": "1.2.5", - "@ai-sdk/deepseek": "0.2.5", - "@ai-sdk/fireworks": "0.2.5", - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/google": "1.2.5", - "@ai-sdk/google-vertex": "2.2.8", - "@ai-sdk/perplexity": "1.1.3", - "@ai-sdk/ui-utils": "1.2.4", - "@ai-sdk/react": "1.2.5", + "@ai-sdk/anthropic": "1.2.6", + "@ai-sdk/deepseek": "0.2.6", + "@ai-sdk/fireworks": "0.2.6", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/google": "1.2.6", + "@ai-sdk/google-vertex": "2.2.9", + "@ai-sdk/perplexity": "1.1.4", + "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/react": "1.2.6", "@vercel/blob": "^0.26.0", - "ai": "4.2.11", + "ai": "4.3.0", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/node-http-server/package.json b/examples/node-http-server/package.json index 172ecac2fcf9..165a76c50bbf 100644 --- a/examples/node-http-server/package.json +++ b/examples/node-http-server/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "ai": "4.2.11", + "@ai-sdk/openai": "1.3.7", + "ai": "4.3.0", "dotenv": "16.4.5", "zod": "3.23.8", "zod-to-json-schema": "3.23.5" diff --git a/examples/nuxt-openai/package.json b/examples/nuxt-openai/package.json index 28b775e0173f..bf1aa10581ac 100644 --- a/examples/nuxt-openai/package.json +++ b/examples/nuxt-openai/package.json @@ -9,9 +9,9 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@ai-sdk/vue": "1.2.4", - "@ai-sdk/openai": "1.3.6", - "ai": "4.2.11", + "@ai-sdk/vue": "1.2.5", + "@ai-sdk/openai": "1.3.7", + "ai": "4.3.0", "zod": "3.23.8" }, "devDependencies": { diff --git a/examples/solidstart-openai/package.json b/examples/solidstart-openai/package.json index 4d4d984cfeff..62b41e740402 100644 --- a/examples/solidstart-openai/package.json +++ b/examples/solidstart-openai/package.json @@ -14,13 +14,13 @@ "vinxi": "^0.4.3" }, "dependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/solid": "1.2.6", - "@ai-sdk/ui-utils": "1.2.4", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/solid": "1.2.7", + "@ai-sdk/ui-utils": "1.2.5", "@solidjs/meta": "0.29.4", "@solidjs/router": "^0.15.1", "@solidjs/start": "^1.0.10", - "ai": "4.2.11", + "ai": "4.3.0", "solid-js": "^1.9.3", "zod": "^3.23.8" }, diff --git a/examples/sveltekit-openai/package.json b/examples/sveltekit-openai/package.json index f429e3dc4f8c..341d7e2a3002 100644 --- a/examples/sveltekit-openai/package.json +++ b/examples/sveltekit-openai/package.json @@ -16,16 +16,16 @@ }, "type": "module", "devDependencies": { - "@ai-sdk/openai": "1.3.6", - "@ai-sdk/provider-utils": "2.2.3", - "@ai-sdk/svelte": "2.1.5", - "@ai-sdk/ui-utils": "1.2.4", + "@ai-sdk/openai": "1.3.7", + "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/svelte": "2.1.6", + "@ai-sdk/ui-utils": "1.2.5", "@eslint/compat": "^1.2.5", "@eslint/js": "^9.18.0", "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", - "ai": "4.2.11", + "ai": "4.3.0", "autoprefixer": "^10.4.20", "bits-ui": "^1.3.9", "clsx": "^2.1.1", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 2ef517d70a6a..226b2903f684 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,18 @@ # ai +## 4.3.0 + +### Minor Changes + +- 772a2d7: feat (core): Add finishReason field to NoObjectGeneratedError + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/react@1.2.6 + - @ai-sdk/ui-utils@1.2.5 + ## 4.2.11 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 7cbab6dd105c..c996c3f96c76 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "4.2.11", + "version": "4.3.0", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, @@ -67,9 +67,9 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3", - "@ai-sdk/react": "1.2.5", - "@ai-sdk/ui-utils": "1.2.4", + "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/react": "1.2.6", + "@ai-sdk/ui-utils": "1.2.5", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, diff --git a/packages/ai/tests/e2e/next-server/CHANGELOG.md b/packages/ai/tests/e2e/next-server/CHANGELOG.md index ca71f95f5384..7867274816c1 100644 --- a/packages/ai/tests/e2e/next-server/CHANGELOG.md +++ b/packages/ai/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [772a2d7] + - ai@4.3.0 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [c45d100] - ai@4.2.11 diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index 277c8e2d10bc..edbfa4edebad 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/amazon-bedrock +## 2.2.5 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 2.2.4 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index be1ea856e756..2d3995352c5b 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "2.2.4", + "version": "2.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,7 +31,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3", + "@ai-sdk/provider-utils": "2.2.4", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 75fb435b6bc5..ca68882a10ad 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/anthropic +## 1.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.2.5 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 42ccbeb06e0c..14db52beccb5 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,7 +38,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index c2a5f87fff91..fce12af5bda0 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/azure +## 1.3.7 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai@1.3.7 + ## 1.3.6 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index ff2d92b8130f..535504680a12 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "1.3.6", + "version": "1.3.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,9 +31,9 @@ } }, "dependencies": { - "@ai-sdk/openai": "1.3.6", + "@ai-sdk/openai": "1.3.7", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 45fe1286eeb7..6b6e90c5f279 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/cerebras +## 0.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai-compatible@0.2.6 + ## 0.2.5 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index 870a0dbcea4b..d8f66b4d33dd 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.5", + "@ai-sdk/openai-compatible": "0.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index 1270637b8e16..a646ffa23614 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/cohere +## 1.2.5 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.2.4 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index 504eafbf1ca2..540ab691ec8b 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "1.2.4", + "version": "1.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -32,7 +32,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index 913480777e74..d1457658b7c9 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/deepinfra +## 0.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai-compatible@0.2.6 + ## 0.2.5 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 9fbb3b5d730b..077c4bd75ccb 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.5", + "@ai-sdk/openai-compatible": "0.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index e1fde2d52f9f..419edbd5f270 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/deepseek +## 0.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai-compatible@0.2.6 + ## 0.2.5 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index e07cfc9ccb50..7101f434b2c5 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.5", + "@ai-sdk/openai-compatible": "0.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index caf5b088c60b..265cf4119b55 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/fal +## 0.1.5 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 0.1.4 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index 092606a4d979..d20e74fb9780 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "0.1.4", + "version": "0.1.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,7 +31,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 2126488c81f1..ad64e056e073 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/fireworks +## 0.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai-compatible@0.2.6 + ## 0.2.5 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index a21951f0aa80..d3aa1833ddec 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.5", + "@ai-sdk/openai-compatible": "0.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index ce842ef6271c..38823bfee2f5 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/google-vertex +## 2.2.9 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/anthropic@1.2.6 + - @ai-sdk/google@1.2.6 + ## 2.2.8 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 433ccc9cb442..a92c49dfee67 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.8", + "version": "2.2.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -49,10 +49,10 @@ } }, "dependencies": { - "@ai-sdk/anthropic": "1.2.5", - "@ai-sdk/google": "1.2.5", + "@ai-sdk/anthropic": "1.2.6", + "@ai-sdk/google": "1.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3", + "@ai-sdk/provider-utils": "2.2.4", "google-auth-library": "^9.15.0" }, "devDependencies": { diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 44da41030ded..d9b1023d6ae3 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/google +## 1.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.2.5 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index 8ae46dd09ff0..102a74c9c8f6 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -39,7 +39,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index 104016e417dc..67a6c973c2c6 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/groq +## 1.2.4 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.2.3 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index c7875a77e49d..3d8031d1d26a 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "1.2.3", + "version": "1.2.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -32,7 +32,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index f9efba8cf43a..a6214f2b7559 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/luma +## 0.1.4 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 0.1.3 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index 71644bd83c33..f8d060d0e8d4 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "0.1.3", + "version": "0.1.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,7 +31,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index ab6df6bd1df0..331df847daa1 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/mistral +## 1.2.4 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.2.3 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 8186d77e0c6a..8d2c56c7580f 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "1.2.3", + "version": "1.2.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -32,7 +32,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index 864481d86a8b..ab2340f20e4e 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/openai-compatible +## 0.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 0.2.5 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index e6c197f2747a..973520935c9b 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -39,7 +39,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index ec4bb3a9da6a..c52910778734 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/openai +## 1.3.7 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.3.6 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index 66d1a887adf6..3a40b134b704 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "1.3.6", + "version": "1.3.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -39,7 +39,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index efc8102c433c..b5a785320f64 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/perplexity +## 1.1.4 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.1.3 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index b41c5c4ceedd..6fb6e30c48fd 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "1.1.3", + "version": "1.1.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,7 +31,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index f1db57e93808..b6a727c16719 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider-utils +## 2.2.4 + +### Patch Changes + +- 2c19b9a: feat(provider-utils): add TestServerCall#requestCredentials + ## 2.2.3 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index e42f89effcc0..f51cef7e9d4d 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "2.2.3", + "version": "2.2.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 1d02fe297ba0..2b5bee4e1e0a 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/react +## 1.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/ui-utils@1.2.5 + ## 1.2.5 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 778f112abe46..8c73bbef2b4a 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.3", - "@ai-sdk/ui-utils": "1.2.4", + "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/ui-utils": "1.2.5", "swr": "^2.2.5", "throttleit": "2.1.0" }, diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index e7d78cc88cf6..6006620b3a1a 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/replicate +## 0.2.4 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 0.2.3 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index d06c01f23ec4..239c73469084 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "0.2.3", + "version": "0.2.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,7 +31,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/solid/CHANGELOG.md b/packages/solid/CHANGELOG.md index 0e72353d950d..cdba658fef2a 100644 --- a/packages/solid/CHANGELOG.md +++ b/packages/solid/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/solid +## 1.2.7 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/ui-utils@1.2.5 + ## 1.2.6 ### Patch Changes diff --git a/packages/solid/package.json b/packages/solid/package.json index 166f376f324c..c2991a6f8ba4 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/solid", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.3", - "@ai-sdk/ui-utils": "1.2.4", + "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/ui-utils": "1.2.5", "@solid-primitives/trigger": "^1.1.0", "zod": "^3.23.8" }, diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index a76f7634c401..fe709bb917aa 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/svelte +## 2.1.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/ui-utils@1.2.5 + ## 2.1.5 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 5b9fb56c4176..c74f7e3952d7 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "2.1.5", + "version": "2.1.6", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", @@ -51,8 +51,8 @@ } }, "dependencies": { - "@ai-sdk/provider-utils": "2.2.3", - "@ai-sdk/ui-utils": "1.2.4" + "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/ui-utils": "1.2.5" }, "devDependencies": { "@eslint/compat": "^1.2.5", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index 7c36b548a285..f0ddcb0bb0eb 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/togetherai +## 0.2.6 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai-compatible@0.2.6 + ## 0.2.5 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index 592157dd4737..1eef028d4944 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.5", + "@ai-sdk/openai-compatible": "0.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/ui-utils/CHANGELOG.md b/packages/ui-utils/CHANGELOG.md index f721b1262a9b..187b4dbfe59c 100644 --- a/packages/ui-utils/CHANGELOG.md +++ b/packages/ui-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/ui-utils +## 1.2.5 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + ## 1.2.4 ### Patch Changes diff --git a/packages/ui-utils/package.json b/packages/ui-utils/package.json index 615899297fdd..9447da7631a8 100644 --- a/packages/ui-utils/package.json +++ b/packages/ui-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/ui-utils", - "version": "1.2.4", + "version": "1.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,7 +38,7 @@ }, "dependencies": { "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3", + "@ai-sdk/provider-utils": "2.2.4", "zod-to-json-schema": "^3.24.1" }, "devDependencies": { diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 41eeb2900014..2817dc3a9301 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 0.1.12 + +### Patch Changes + +- Updated dependencies [772a2d7] + - ai@4.3.0 + ## 0.1.11 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index 2ed01cd5a1d8..d777b573e3fc 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "0.1.11", + "version": "0.1.12", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -27,7 +27,7 @@ } }, "dependencies": { - "ai": "4.2.11" + "ai": "4.3.0" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index fed108ae7668..ba8cf4aed113 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/vue +## 1.2.5 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/ui-utils@1.2.5 + ## 1.2.4 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 358e390ac03e..88c61894a603 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "1.2.4", + "version": "1.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.3", - "@ai-sdk/ui-utils": "1.2.4", + "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/ui-utils": "1.2.5", "swrv": "^1.0.4" }, "devDependencies": { diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index fc2fc64a3d27..d530b70855a4 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/xai +## 1.2.7 + +### Patch Changes + +- Updated dependencies [2c19b9a] + - @ai-sdk/provider-utils@2.2.4 + - @ai-sdk/openai-compatible@0.2.6 + ## 1.2.6 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 7e339c17c07d..83e9cfdcd568 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.5", + "@ai-sdk/openai-compatible": "0.2.6", "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.3" + "@ai-sdk/provider-utils": "2.2.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9dde4882e268..e13681c0e0f0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,70 +60,70 @@ importers: examples/ai-core: dependencies: '@ai-sdk/amazon-bedrock': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../../packages/amazon-bedrock '@ai-sdk/anthropic': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/anthropic '@ai-sdk/azure': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/azure '@ai-sdk/cerebras': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/cerebras '@ai-sdk/cohere': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/cohere '@ai-sdk/deepinfra': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/deepinfra '@ai-sdk/deepseek': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/deepseek '@ai-sdk/fal': - specifier: 0.1.4 + specifier: 0.1.5 version: link:../../packages/fal '@ai-sdk/fireworks': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.8 + specifier: 2.2.9 version: link:../../packages/google-vertex '@ai-sdk/groq': - specifier: 1.2.3 + specifier: 1.2.4 version: link:../../packages/groq '@ai-sdk/luma': - specifier: 0.1.3 + specifier: 0.1.4 version: link:../../packages/luma '@ai-sdk/mistral': - specifier: 1.2.3 + specifier: 1.2.4 version: link:../../packages/mistral '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/openai-compatible '@ai-sdk/perplexity': - specifier: 1.1.3 + specifier: 1.1.4 version: link:../../packages/perplexity '@ai-sdk/provider': specifier: 1.1.0 version: link:../../packages/provider '@ai-sdk/replicate': - specifier: 0.2.3 + specifier: 0.2.4 version: link:../../packages/replicate '@ai-sdk/togetherai': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/togetherai '@ai-sdk/valibot': - specifier: 0.1.11 + specifier: 0.1.12 version: link:../../packages/valibot '@ai-sdk/xai': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/xai '@google/generative-ai': specifier: 0.21.0 @@ -138,7 +138,7 @@ importers: specifier: 1.28.0 version: 1.28.0(@opentelemetry/api@1.9.0) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -178,10 +178,10 @@ importers: examples/express: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -206,10 +206,10 @@ importers: examples/fastify: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -231,13 +231,13 @@ importers: examples/hono: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@hono/node-server': specifier: 1.13.7 version: 1.13.7(hono@4.6.9) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -259,13 +259,13 @@ importers: examples/mcp: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@modelcontextprotocol/sdk': specifier: ^1.7.0 version: 1.7.0 ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -293,7 +293,7 @@ importers: examples/nest: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@nestjs/common': specifier: ^10.4.15 @@ -305,7 +305,7 @@ importers: specifier: ^10.4.9 version: 10.4.9(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai reflect-metadata: specifier: ^0.2.0 @@ -381,13 +381,13 @@ importers: examples/next-fastapi: dependencies: '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/ui-utils ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -436,10 +436,10 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.8 + specifier: 2.2.9 version: link:../../packages/google-vertex ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -479,7 +479,7 @@ importers: examples/next-langchain: dependencies: '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@langchain/core': specifier: 0.1.63 @@ -488,7 +488,7 @@ importers: specifier: 0.0.28 version: 0.0.28 ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai langchain: specifier: 0.1.36 @@ -534,37 +534,37 @@ importers: examples/next-openai: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/anthropic '@ai-sdk/deepseek': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/deepseek '@ai-sdk/fireworks': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.8 + specifier: 2.2.9 version: link:../../packages/google-vertex '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/perplexity': - specifier: 1.1.3 + specifier: 1.1.4 version: link:../../packages/perplexity '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/ui-utils '@vercel/blob': specifier: ^0.26.0 version: 0.26.0 ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai next: specifier: latest @@ -616,16 +616,16 @@ importers: examples/next-openai-kasada-bot-protection: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@vercel/functions': specifier: latest version: 2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai next: specifier: latest @@ -671,13 +671,13 @@ importers: examples/next-openai-pages: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai next: specifier: latest @@ -726,10 +726,10 @@ importers: examples/next-openai-telemetry: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@opentelemetry/api-logs': specifier: 0.55.0 @@ -744,7 +744,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.29.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai next: specifier: latest @@ -793,10 +793,10 @@ importers: examples/next-openai-telemetry-sentry: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@opentelemetry/api-logs': specifier: 0.55.0 @@ -817,7 +817,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai next: specifier: latest @@ -866,10 +866,10 @@ importers: examples/next-openai-upstash-rate-limits: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/react '@upstash/ratelimit': specifier: ^0.4.3 @@ -878,7 +878,7 @@ importers: specifier: ^0.2.2 version: 0.2.4 ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai next: specifier: latest @@ -924,10 +924,10 @@ importers: examples/node-http-server: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -952,13 +952,13 @@ importers: examples/nuxt-openai: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/vue': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/vue ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai zod: specifier: 3.23.8 @@ -1007,13 +1007,13 @@ importers: examples/solidstart-openai: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/solid': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/solid '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/ui-utils '@solidjs/meta': specifier: 0.29.4 @@ -1025,7 +1025,7 @@ importers: specifier: ^1.0.10 version: 1.0.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vinxi@0.4.3(@types/node@22.7.4)(@upstash/redis@1.34.3)(ioredis@5.4.1)(terser@5.31.3)(typescript@5.6.3))(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai solid-js: specifier: ^1.9.3 @@ -1050,16 +1050,16 @@ importers: examples/sveltekit-openai: devDependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../../packages/openai '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../../packages/provider-utils '@ai-sdk/svelte': - specifier: 2.1.5 + specifier: 2.1.6 version: link:../../packages/svelte '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/ui-utils '@eslint/compat': specifier: ^1.2.5 @@ -1077,7 +1077,7 @@ importers: specifier: ^5.0.0 version: 5.0.3(svelte@5.22.4)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../../packages/ai autoprefixer: specifier: ^10.4.20 @@ -1137,13 +1137,13 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils '@ai-sdk/react': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../react '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../ui-utils '@opentelemetry/api': specifier: 1.9.0 @@ -1216,7 +1216,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils '@smithy/eventstream-codec': specifier: ^4.0.1 @@ -1250,7 +1250,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1272,13 +1272,13 @@ importers: packages/azure: dependencies: '@ai-sdk/openai': - specifier: 1.3.6 + specifier: 1.3.7 version: link:../openai '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1300,13 +1300,13 @@ importers: packages/cerebras: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../openai-compatible '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1380,7 +1380,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1402,13 +1402,13 @@ importers: packages/deepinfra: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../openai-compatible '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1430,13 +1430,13 @@ importers: packages/deepseek: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../openai-compatible '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1461,7 +1461,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1483,13 +1483,13 @@ importers: packages/fireworks: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../openai-compatible '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1514,7 +1514,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1536,16 +1536,16 @@ importers: packages/google-vertex: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../anthropic '@ai-sdk/google': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../google '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils google-auth-library: specifier: ^9.15.0 @@ -1573,7 +1573,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1598,7 +1598,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1623,7 +1623,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1648,7 +1648,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1673,7 +1673,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1698,7 +1698,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1773,10 +1773,10 @@ importers: packages/react: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../ui-utils react: specifier: ^18 || ^19 || ^19.0.0-rc @@ -1840,7 +1840,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -1862,10 +1862,10 @@ importers: packages/solid: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../ui-utils '@solid-primitives/trigger': specifier: ^1.1.0 @@ -1923,10 +1923,10 @@ importers: packages/svelte: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../ui-utils devDependencies: '@eslint/compat': @@ -1987,13 +1987,13 @@ importers: packages/togetherai: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../openai-compatible '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -2018,7 +2018,7 @@ importers: specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils zod-to-json-schema: specifier: ^3.24.1 @@ -2052,7 +2052,7 @@ importers: specifier: ^1.0.0-rc.0 || ^1.0.0 version: 1.0.0-rc.0(valibot@1.0.0-rc.0(typescript@5.6.3)) ai: - specifier: 4.2.11 + specifier: 4.3.0 version: link:../ai devDependencies: '@types/node': @@ -2074,10 +2074,10 @@ importers: packages/vue: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../ui-utils swrv: specifier: ^1.0.4 @@ -2129,13 +2129,13 @@ importers: packages/xai: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../openai-compatible '@ai-sdk/provider': specifier: 1.1.0 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.3 + specifier: 2.2.4 version: link:../provider-utils devDependencies: '@types/node': @@ -24182,7 +24182,7 @@ snapshots: debug: 4.4.0(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.2 @@ -24222,7 +24222,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24255,7 +24255,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24314,7 +24314,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.0 is-glob: 4.0.3 From 2abf7a659e1fb43083f96050474015bd8bd62274 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Fri, 4 Apr 2025 18:57:07 +0200 Subject: [PATCH 015/191] fix (docs): troubleshooting page description (#5551) --- .../09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx b/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx index 9ca39a8792af..d7e83986229f 100644 --- a/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx +++ b/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx @@ -1,6 +1,6 @@ --- title: "Jest: cannot find module 'ai/rsc'" -description: "Troubleshooting AI SDK errors related to the "Jest: cannot find module 'ai/rsc'" error". +description: "Troubleshooting AI SDK errors related to the Jest: cannot find module 'ai/rsc' error". --- # Jest: cannot find module 'ai/rsc' From 1789884487f11fb12206ebee1b7b0778d966e330 Mon Sep 17 00:00:00 2001 From: Grace Yun <74513600+iteratetograceness@users.noreply.github.com> Date: Fri, 4 Apr 2025 20:21:54 -0400 Subject: [PATCH 016/191] feat (provider/{google, google-vertex}): expose type for validating provider options (#5491) --- .changeset/pink-deers-switch.md | 6 ++ .../15-google-generative-ai.mdx | 25 ++++++- .../01-ai-sdk-providers/16-google-vertex.mdx | 35 ++++++++++ .../src/generate-image/google-vertex.ts | 10 +-- .../ai-core/src/generate-text/google-image.ts | 7 +- .../src/google-vertex-image-model.test.ts | 66 ++++++++++--------- .../src/google-vertex-image-model.ts | 29 +++++++- packages/google-vertex/src/index.ts | 1 + ...oogle-generative-ai-language-model.test.ts | 58 ++++++++++++++++ .../google-generative-ai-language-model.ts | 11 +++- packages/google/src/index.ts | 3 +- 11 files changed, 210 insertions(+), 41 deletions(-) create mode 100644 .changeset/pink-deers-switch.md diff --git a/.changeset/pink-deers-switch.md b/.changeset/pink-deers-switch.md new file mode 100644 index 000000000000..84d524aeb623 --- /dev/null +++ b/.changeset/pink-deers-switch.md @@ -0,0 +1,6 @@ +--- +'@ai-sdk/google-vertex': patch +'@ai-sdk/google': patch +--- + +feat: add provider option schemas for vertex imagegen and google genai diff --git a/content/providers/01-ai-sdk-providers/15-google-generative-ai.mdx b/content/providers/01-ai-sdk-providers/15-google-generative-ai.mdx index 980fb3ccdc4d..2fba02438350 100644 --- a/content/providers/01-ai-sdk-providers/15-google-generative-ai.mdx +++ b/content/providers/01-ai-sdk-providers/15-google-generative-ai.mdx @@ -80,7 +80,7 @@ const model = google('gemini-1.5-pro-latest'); e.g. `tunedModels/my-model`. -Google Generative AI models support also some model specific settings that are not part of the [standard call settings](/docs/ai-sdk-core/settings). +Google Generative AI also supports some model specific settings that are not part of the [standard call settings](/docs/ai-sdk-core/settings). You can pass them as an options argument: ```ts @@ -132,6 +132,29 @@ The following optional settings are available for Google Generative AI models: - `BLOCK_ONLY_HIGH` - `BLOCK_NONE` +Further configuration can be done using Google Generative AI provider options. You can validate the provider options using the `GoogleGenerativeAIProviderOptions` type. + +```ts +import { google } from '@ai-sdk/google'; +import { GoogleGenerativeAIProviderOptions } from '@ai-sdk/google'; +import { generateText } from 'ai'; + +const { text } = await generateText({ + model: google('gemini-1.5-pro-latest'), + providerOptions: { + google: { + responseModalities: ['TEXT', 'IMAGE'], + } satisfies GoogleGenerativeAIProviderOptions, + }, + // ... +}); +``` + +The following provider options are available: + +- **responseModalities** _string[]_ + The modalities to use for the response. The following modalities are supported: `TEXT`, `IMAGE`. When not defined or empty, the model defaults to returning only text. + You can use Google Generative AI language models to generate text with the `generateText` function: ```ts diff --git a/content/providers/01-ai-sdk-providers/16-google-vertex.mdx b/content/providers/01-ai-sdk-providers/16-google-vertex.mdx index b326449fd6fe..b65b0f6b0819 100644 --- a/content/providers/01-ai-sdk-providers/16-google-vertex.mdx +++ b/content/providers/01-ai-sdk-providers/16-google-vertex.mdx @@ -599,6 +599,41 @@ const { image } = await generateImage({ }); ``` +Further configuration can be done using Google Vertex provider options. You can validate the provider options using the `GoogleVertexImageProviderOptions` type. + +```ts +import { vertex } from '@ai-sdk/google-vertex'; +import { GoogleVertexImageProviderOptions } from '@ai-sdk/google-vertex'; +import { generateImage } from 'ai'; + +const { image } = await generateImage({ + model: vertex.image('imagen-3.0-generate-001'), + providerOptions: { + vertex: { + negativePrompt: 'pixelated, blurry, low-quality', + } satisfies GoogleVertexImageProviderOptions, + }, + // ... +}); +``` + +The following provider options are available: + +- **negativePrompt** _string_ + A description of what to discourage in the generated images. + +- **personGeneration** `allow_adult` | `allow_all` | `dont_allow` + Whether to allow person generation. Defaults to `allow_adult`. + +- **safetySetting** `block_low_and_above` | `block_medium_and_above` | `block_only_high` | `block_none` + Whether to block unsafe content. Defaults to `block_medium_and_above`. + +- **addWatermark** _boolean_ + Whether to add an invisible watermark to the generated images. Defaults to `true`. + +- **storageUri** _string_ + Cloud Storage URI to store the generated images. + Imagen models do not support the `size` parameter. Use the `aspectRatio` parameter instead. diff --git a/examples/ai-core/src/generate-image/google-vertex.ts b/examples/ai-core/src/generate-image/google-vertex.ts index 4635fcda81dd..d21043e1005b 100644 --- a/examples/ai-core/src/generate-image/google-vertex.ts +++ b/examples/ai-core/src/generate-image/google-vertex.ts @@ -1,7 +1,10 @@ -import { vertex } from '@ai-sdk/google-vertex'; +import { + GoogleVertexImageProviderOptions, + vertex, +} from '@ai-sdk/google-vertex'; import { experimental_generateImage as generateImage } from 'ai'; -import { presentImages } from '../lib/present-image'; import 'dotenv/config'; +import { presentImages } from '../lib/present-image'; async function main() { const { image } = await generateImage({ @@ -10,9 +13,8 @@ async function main() { aspectRatio: '1:1', providerOptions: { vertex: { - // https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#parameter_list addWatermark: false, - }, + } satisfies GoogleVertexImageProviderOptions, }, }); diff --git a/examples/ai-core/src/generate-text/google-image.ts b/examples/ai-core/src/generate-text/google-image.ts index d7c66219ecdf..f5f32d72134a 100644 --- a/examples/ai-core/src/generate-text/google-image.ts +++ b/examples/ai-core/src/generate-text/google-image.ts @@ -1,4 +1,4 @@ -import { google } from '@ai-sdk/google'; +import { google, GoogleGenerativeAIProviderOptions } from '@ai-sdk/google'; import { generateText } from 'ai'; import 'dotenv/config'; import fs from 'node:fs'; @@ -15,6 +15,11 @@ async function main() { ], }, ], + providerOptions: { + google: { + responseModalities: ['TEXT', 'IMAGE'], + } satisfies GoogleGenerativeAIProviderOptions, + }, }); console.log(result.text); diff --git a/packages/google-vertex/src/google-vertex-image-model.test.ts b/packages/google-vertex/src/google-vertex-image-model.test.ts index 0a7dab1c6fe9..c9be8cb4839a 100644 --- a/packages/google-vertex/src/google-vertex-image-model.test.ts +++ b/packages/google-vertex/src/google-vertex-image-model.test.ts @@ -38,27 +38,6 @@ describe('GoogleVertexImageModel', () => { }; } - it('should pass the correct parameters', async () => { - prepareJsonResponse(); - - await model.doGenerate({ - prompt, - n: 2, - size: undefined, - aspectRatio: undefined, - seed: undefined, - providerOptions: { vertex: { aspectRatio: '1:1' } }, - }); - - expect(await server.calls[0].requestBody).toStrictEqual({ - instances: [{ prompt }], - parameters: { - sampleCount: 2, - aspectRatio: '1:1', - }, - }); - }); - it('should pass headers', async () => { prepareJsonResponse(); @@ -143,13 +122,9 @@ describe('GoogleVertexImageModel', () => { prompt: 'test prompt', n: 1, size: undefined, - aspectRatio: undefined, + aspectRatio: '16:9', seed: undefined, - providerOptions: { - vertex: { - aspectRatio: '16:9', - }, - }, + providerOptions: {}, }); expect(await server.calls[0].requestBody).toStrictEqual({ @@ -214,7 +189,7 @@ describe('GoogleVertexImageModel', () => { seed: 42, providerOptions: { vertex: { - temperature: 0.8, + addWatermark: false, }, }, }); @@ -225,7 +200,7 @@ describe('GoogleVertexImageModel', () => { sampleCount: 1, aspectRatio: '1:1', seed: 42, - temperature: 0.8, + addWatermark: false, }, }); }); @@ -302,7 +277,7 @@ describe('GoogleVertexImageModel', () => { const result = await model.doGenerate({ prompt, - n: 1, + n: 2, size: undefined, aspectRatio: undefined, seed: undefined, @@ -319,5 +294,36 @@ describe('GoogleVertexImageModel', () => { ); expect(result.response.modelId).toBe('imagen-3.0-generate-001'); }); + + it('should only pass valid provider options', async () => { + prepareJsonResponse(); + + await model.doGenerate({ + prompt, + n: 2, + size: undefined, + aspectRatio: '16:9', + seed: undefined, + providerOptions: { + vertex: { + addWatermark: false, + negativePrompt: 'negative prompt', + personGeneration: 'allow_all', + foo: 'bar', + }, + }, + }); + + expect(await server.calls[0].requestBody).toStrictEqual({ + instances: [{ prompt }], + parameters: { + sampleCount: 2, + addWatermark: false, + negativePrompt: 'negative prompt', + personGeneration: 'allow_all', + aspectRatio: '16:9', + }, + }); + }); }); }); diff --git a/packages/google-vertex/src/google-vertex-image-model.ts b/packages/google-vertex/src/google-vertex-image-model.ts index c94d5ddc32d5..635b50df5445 100644 --- a/packages/google-vertex/src/google-vertex-image-model.ts +++ b/packages/google-vertex/src/google-vertex-image-model.ts @@ -3,6 +3,7 @@ import { Resolvable, combineHeaders, createJsonResponseHandler, + parseProviderOptions, postJsonToApi, resolve, } from '@ai-sdk/provider-utils'; @@ -65,13 +66,19 @@ export class GoogleVertexImageModel implements ImageModelV1 { }); } + const vertexImageOptions = parseProviderOptions({ + provider: 'vertex', + providerOptions, + schema: vertexImageProviderOptionsSchema, + }); + const body = { instances: [{ prompt }], parameters: { sampleCount: n, ...(aspectRatio != null ? { aspectRatio } : {}), ...(seed != null ? { seed } : {}), - ...(providerOptions.vertex ?? {}), + ...(vertexImageOptions ?? {}), }, }; @@ -108,3 +115,23 @@ export class GoogleVertexImageModel implements ImageModelV1 { const vertexImageResponseSchema = z.object({ predictions: z.array(z.object({ bytesBase64Encoded: z.string() })).nullish(), }); + +const vertexImageProviderOptionsSchema = z.object({ + negativePrompt: z.string().nullish(), + personGeneration: z + .enum(['dont_allow', 'allow_adult', 'allow_all']) + .nullish(), + safetySetting: z + .enum([ + 'block_low_and_above', + 'block_medium_and_above', + 'block_only_high', + 'block_none', + ]) + .nullish(), + addWatermark: z.boolean().nullish(), + storageUri: z.string().nullish(), +}); +export type GoogleVertexImageProviderOptions = z.infer< + typeof vertexImageProviderOptionsSchema +>; diff --git a/packages/google-vertex/src/index.ts b/packages/google-vertex/src/index.ts index bf1e0fad1033..e84f8e06d72f 100644 --- a/packages/google-vertex/src/index.ts +++ b/packages/google-vertex/src/index.ts @@ -1,3 +1,4 @@ +export type { GoogleVertexImageProviderOptions } from './google-vertex-image-model'; export { createVertex, vertex } from './google-vertex-provider-node'; export type { GoogleVertexProvider, diff --git a/packages/google/src/google-generative-ai-language-model.test.ts b/packages/google/src/google-generative-ai-language-model.test.ts index 4a10794a8c2a..a860afb73ad9 100644 --- a/packages/google/src/google-generative-ai-language-model.test.ts +++ b/packages/google/src/google-generative-ai-language-model.test.ts @@ -414,6 +414,39 @@ describe('doGenerate', () => { }); }); + it('should only pass valid provider options', async () => { + prepareJsonResponse({}); + + await model.doGenerate({ + inputFormat: 'prompt', + mode: { type: 'regular' }, + prompt: [ + { role: 'system', content: 'test system instruction' }, + { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, + ], + seed: 123, + temperature: 0.5, + providerMetadata: { + google: { foo: 'bar', responseModalities: ['TEXT', 'IMAGE'] }, + }, + }); + + expect(await server.calls[0].requestBody).toStrictEqual({ + contents: [ + { + role: 'user', + parts: [{ text: 'Hello' }], + }, + ], + systemInstruction: { parts: [{ text: 'test system instruction' }] }, + generationConfig: { + seed: 123, + temperature: 0.5, + responseModalities: ['TEXT', 'IMAGE'], + }, + }); + }); + it('should pass tools and toolChoice', async () => { prepareJsonResponse({}); @@ -1869,4 +1902,29 @@ describe('doStream', () => { 'tool-calls', ); }); + + it('should only pass valid provider options', async () => { + prepareStreamResponse({ content: [''] }); + + await model.doStream({ + inputFormat: 'prompt', + mode: { type: 'regular' }, + prompt: TEST_PROMPT, + providerMetadata: { + google: { foo: 'bar', responseModalities: ['TEXT', 'IMAGE'] }, + }, + }); + + expect(await server.calls[0].requestBody).toMatchObject({ + contents: [ + { + role: 'user', + parts: [{ text: 'Hello' }], + }, + ], + generationConfig: { + responseModalities: ['TEXT', 'IMAGE'], + }, + }); + }); }); diff --git a/packages/google/src/google-generative-ai-language-model.ts b/packages/google/src/google-generative-ai-language-model.ts index 8f2a9bf1c356..6482e97d64c9 100644 --- a/packages/google/src/google-generative-ai-language-model.ts +++ b/packages/google/src/google-generative-ai-language-model.ts @@ -88,9 +88,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV1 { const googleOptions = parseProviderOptions({ provider: 'google', providerOptions: providerMetadata, - schema: z.object({ - responseModalities: z.array(z.enum(['TEXT', 'IMAGE'])).nullish(), - }), + schema: googleGenerativeAIProviderOptionsSchema, }); const generationConfig = { @@ -623,3 +621,10 @@ const chunkSchema = z.object({ }) .nullish(), }); + +const googleGenerativeAIProviderOptionsSchema = z.object({ + responseModalities: z.array(z.enum(['TEXT', 'IMAGE'])).nullish(), +}); +export type GoogleGenerativeAIProviderOptions = z.infer< + typeof googleGenerativeAIProviderOptionsSchema +>; diff --git a/packages/google/src/index.ts b/packages/google/src/index.ts index bf9c08c46346..8220c6c80ba0 100644 --- a/packages/google/src/index.ts +++ b/packages/google/src/index.ts @@ -1,6 +1,7 @@ -export { createGoogleGenerativeAI, google } from './google-provider'; export type { GoogleErrorData } from './google-error'; +export type { GoogleGenerativeAIProviderOptions } from './google-generative-ai-language-model'; export type { GoogleGenerativeAIProviderMetadata } from './google-generative-ai-prompt'; +export { createGoogleGenerativeAI, google } from './google-provider'; export type { GoogleGenerativeAIProvider, GoogleGenerativeAIProviderSettings, From 5f6129681d41379d56b61e9392dc5081d0055531 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Fri, 4 Apr 2025 23:01:24 -0700 Subject: [PATCH 017/191] fix (docs): correct content outside description in jest docs (#5559) --- .../09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx b/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx index d7e83986229f..6626d31c1bf0 100644 --- a/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx +++ b/content/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx @@ -1,6 +1,6 @@ --- title: "Jest: cannot find module 'ai/rsc'" -description: "Troubleshooting AI SDK errors related to the Jest: cannot find module 'ai/rsc' error". +description: "Troubleshooting AI SDK errors related to the Jest: cannot find module 'ai/rsc' error" --- # Jest: cannot find module 'ai/rsc' From bd8b6691e5d156ec0b045a332d5b3553d7727e8f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 10:51:27 +0200 Subject: [PATCH 018/191] Version Packages (#5558) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/pink-deers-switch.md | 6 ------ examples/ai-core/package.json | 4 ++-- examples/next-google-vertex/package.json | 2 +- examples/next-openai/package.json | 4 ++-- packages/google-vertex/CHANGELOG.md | 8 ++++++++ packages/google-vertex/package.json | 4 ++-- packages/google/CHANGELOG.md | 6 ++++++ packages/google/package.json | 2 +- pnpm-lock.yaml | 18 +++++++++--------- 9 files changed, 31 insertions(+), 23 deletions(-) delete mode 100644 .changeset/pink-deers-switch.md diff --git a/.changeset/pink-deers-switch.md b/.changeset/pink-deers-switch.md deleted file mode 100644 index 84d524aeb623..000000000000 --- a/.changeset/pink-deers-switch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@ai-sdk/google-vertex': patch -'@ai-sdk/google': patch ---- - -feat: add provider option schemas for vertex imagegen and google genai diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index b559952fdf95..f3b2fff69f71 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -12,8 +12,8 @@ "@ai-sdk/deepseek": "0.2.6", "@ai-sdk/fal": "0.1.5", "@ai-sdk/fireworks": "0.2.6", - "@ai-sdk/google": "1.2.6", - "@ai-sdk/google-vertex": "2.2.9", + "@ai-sdk/google": "1.2.7", + "@ai-sdk/google-vertex": "2.2.10", "@ai-sdk/groq": "1.2.4", "@ai-sdk/luma": "0.1.4", "@ai-sdk/mistral": "1.2.4", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index 1efb38c29389..6b276cf9c36b 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.9", + "@ai-sdk/google-vertex": "2.2.10", "ai": "4.3.0", "geist": "^1.3.1", "next": "latest", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 5b0fd44a8e7b..1307008dca5b 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -13,8 +13,8 @@ "@ai-sdk/deepseek": "0.2.6", "@ai-sdk/fireworks": "0.2.6", "@ai-sdk/openai": "1.3.7", - "@ai-sdk/google": "1.2.6", - "@ai-sdk/google-vertex": "2.2.9", + "@ai-sdk/google": "1.2.7", + "@ai-sdk/google-vertex": "2.2.10", "@ai-sdk/perplexity": "1.1.4", "@ai-sdk/ui-utils": "1.2.5", "@ai-sdk/react": "1.2.6", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index 38823bfee2f5..f8bd47ac0cfa 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/google-vertex +## 2.2.10 + +### Patch Changes + +- 1789884: feat: add provider option schemas for vertex imagegen and google genai +- Updated dependencies [1789884] + - @ai-sdk/google@1.2.7 + ## 2.2.9 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index a92c49dfee67..c8d000b2d507 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.9", + "version": "2.2.10", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -50,7 +50,7 @@ }, "dependencies": { "@ai-sdk/anthropic": "1.2.6", - "@ai-sdk/google": "1.2.6", + "@ai-sdk/google": "1.2.7", "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.4", "google-auth-library": "^9.15.0" diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index d9b1023d6ae3..6d37286d43da 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/google +## 1.2.7 + +### Patch Changes + +- 1789884: feat: add provider option schemas for vertex imagegen and google genai + ## 1.2.6 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index 102a74c9c8f6..aa4be34120bf 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e13681c0e0f0..84dc816ffcff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,10 +87,10 @@ importers: specifier: 0.2.6 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.9 + specifier: 2.2.10 version: link:../../packages/google-vertex '@ai-sdk/groq': specifier: 1.2.4 @@ -436,7 +436,7 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.9 + specifier: 2.2.10 version: link:../../packages/google-vertex ai: specifier: 4.3.0 @@ -543,10 +543,10 @@ importers: specifier: 0.2.6 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.9 + specifier: 2.2.10 version: link:../../packages/google-vertex '@ai-sdk/openai': specifier: 1.3.7 @@ -1539,7 +1539,7 @@ importers: specifier: 1.2.6 version: link:../anthropic '@ai-sdk/google': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../google '@ai-sdk/provider': specifier: 1.1.0 @@ -24107,7 +24107,7 @@ snapshots: eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.1) eslint-plugin-react: 7.35.0(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -24183,7 +24183,7 @@ snapshots: enhanced-resolve: 5.17.1 eslint: 8.57.1 eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -24304,7 +24304,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 From 3d1bd38e037f03959cf6c964e3560af067203f77 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Sat, 5 Apr 2025 10:58:54 +0200 Subject: [PATCH 019/191] feat (core): add chunking functions support to smoothStream (#5548) Co-authored-by: Sam Denty Co-authored-by: Sam Denty --- .changeset/beige-ligers-kneel.md | 5 + .../22-smooth-stream-japanese.mdx | 19 ++ .../04-ai-sdk-ui/23-smooth-stream-chinese.mdx | 19 ++ .../01-ai-sdk-core/80-smooth-stream.mdx | 57 +++++- .../src/stream-text/smooth-stream-chinese.ts | 39 ++++ .../src/stream-text/smooth-stream-japanese.ts | 39 ++++ packages/ai/core/generate-text/index.ts | 2 +- .../core/generate-text/smooth-stream.test.ts | 169 ++++++++++++++++++ .../ai/core/generate-text/smooth-stream.ts | 73 ++++++-- 9 files changed, 404 insertions(+), 18 deletions(-) create mode 100644 .changeset/beige-ligers-kneel.md create mode 100644 content/docs/04-ai-sdk-ui/22-smooth-stream-japanese.mdx create mode 100644 content/docs/04-ai-sdk-ui/23-smooth-stream-chinese.mdx create mode 100644 examples/ai-core/src/stream-text/smooth-stream-chinese.ts create mode 100644 examples/ai-core/src/stream-text/smooth-stream-japanese.ts diff --git a/.changeset/beige-ligers-kneel.md b/.changeset/beige-ligers-kneel.md new file mode 100644 index 000000000000..fe3a654a5dc5 --- /dev/null +++ b/.changeset/beige-ligers-kneel.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +feat(smooth-stream): chunking callbacks diff --git a/content/docs/04-ai-sdk-ui/22-smooth-stream-japanese.mdx b/content/docs/04-ai-sdk-ui/22-smooth-stream-japanese.mdx new file mode 100644 index 000000000000..8faabe199b0c --- /dev/null +++ b/content/docs/04-ai-sdk-ui/22-smooth-stream-japanese.mdx @@ -0,0 +1,19 @@ +--- +title: Smooth streaming japanese text +description: Learn how to stream smooth stream japanese text +--- + +# Smooth streaming japanese text + +You can smooth stream japanese text by using the `smoothStream` function, and the following regex that splits either on words of japanese characters: + +```tsx filename="page.tsx" +import { smoothStream } from 'ai'; +import { useChat } from '@ai-sdk/react'; + +const { data } = useChat({ + experimental_transform: smoothStream({ + chunking: /[\u3040-\u309F\u30A0-\u30FF]|\S+\s+/, + }), +}); +``` diff --git a/content/docs/04-ai-sdk-ui/23-smooth-stream-chinese.mdx b/content/docs/04-ai-sdk-ui/23-smooth-stream-chinese.mdx new file mode 100644 index 000000000000..7f7533397f5c --- /dev/null +++ b/content/docs/04-ai-sdk-ui/23-smooth-stream-chinese.mdx @@ -0,0 +1,19 @@ +--- +title: Smooth streaming chinese text +description: Learn how to stream smooth stream chinese text +--- + +# Smooth streaming chinese text + +You can smooth stream chinese text by using the `smoothStream` function, and the following regex that splits either on words of chinese characters: + +```tsx filename="page.tsx" +import { smoothStream } from 'ai'; +import { useChat } from '@ai-sdk/react'; + +const { data } = useChat({ + experimental_transform: smoothStream({ + chunking: /[\u4E00-\u9FFF]|\S+\s+/, + }), +}); +``` diff --git a/content/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx b/content/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx index 5e644487a284..474ea5875e8c 100644 --- a/content/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx @@ -42,14 +42,67 @@ const result = streamText({ }, { name: 'chunking', - type: '"word" | "line" | RegExp', + type: '"word" | "line" | RegExp | (buffer: string) => string | undefined | null', isOptional: true, description: - 'Controls how the text is chunked for streaming. Use "word" to stream word by word (default), "line" to stream line by line, or provide a custom RegExp pattern for custom chunking.', + 'Controls how the text is chunked for streaming. Use "word" to stream word by word (default), "line" to stream line by line, or provide a custom callback or RegExp pattern for custom chunking.', }, ]} /> +#### Word chunking caveats with non-latin languages + + + The word based chunking **does not work well** with the following languages that do not delimit words with spaces: + + For these languages we recommend using a custom regex, like the following: + + - Chinese - `/[\u4E00-\u9FFF]|\S+\s+/` + - Japanese - `/[\u3040-\u309F\u30A0-\u30FF]|\S+\s+/` + + For these languages you could pass your own language aware chunking function: + + - Vietnamese + - Thai + - Javanese (Aksara Jawa) + + + +#### Regex based chunking + +To use regex based chunking, pass a `RegExp` to the `chunking` option. + +```ts +// To split on underscores: +smoothStream({ + chunking: /_+/, +}); + +// Also can do it like this, same behavior +smoothStream({ + chunking: /[^_]*_/, +}); +``` + +#### Custom callback chunking + +To use a custom callback for chunking, pass a function to the `chunking` option. + +```ts +smoothStream({ + chunking: text => { + const findString = 'some string'; + const index = text.indexOf(findString); + + if (index === -1) { + return null; + } + + return text.slice(0, index) + findString; + }, +}); +``` + ### Returns Returns a `TransformStream` that: diff --git a/examples/ai-core/src/stream-text/smooth-stream-chinese.ts b/examples/ai-core/src/stream-text/smooth-stream-chinese.ts new file mode 100644 index 000000000000..71b8d1e99cae --- /dev/null +++ b/examples/ai-core/src/stream-text/smooth-stream-chinese.ts @@ -0,0 +1,39 @@ +import { simulateReadableStream, smoothStream, streamText } from 'ai'; +import { MockLanguageModelV1 } from 'ai/test'; + +async function main() { + const result = streamText({ + model: new MockLanguageModelV1({ + doStream: async () => ({ + stream: simulateReadableStream({ + chunks: [ + { type: 'text-delta', textDelta: '你好你好你好你好你好' }, + { type: 'text-delta', textDelta: '你好你好你好你好你好' }, + { type: 'text-delta', textDelta: '你好你好你好你好你好' }, + { type: 'text-delta', textDelta: '你好你好你好你好你好' }, + { type: 'text-delta', textDelta: '你好你好你好你好你好' }, + { + type: 'finish', + finishReason: 'stop', + logprobs: undefined, + usage: { completionTokens: 10, promptTokens: 3 }, + }, + ], + chunkDelayInMs: 400, + }), + rawCall: { rawPrompt: null, rawSettings: {} }, + }), + }), + + prompt: 'Say hello in Chinese!', + experimental_transform: smoothStream({ + chunking: /[\u4E00-\u9FFF]|\S+\s+/, + }), + }); + + for await (const textPart of result.textStream) { + process.stdout.write(textPart); + } +} + +main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/smooth-stream-japanese.ts b/examples/ai-core/src/stream-text/smooth-stream-japanese.ts new file mode 100644 index 000000000000..5139d835be3b --- /dev/null +++ b/examples/ai-core/src/stream-text/smooth-stream-japanese.ts @@ -0,0 +1,39 @@ +import { simulateReadableStream, smoothStream, streamText } from 'ai'; +import { MockLanguageModelV1 } from 'ai/test'; + +async function main() { + const result = streamText({ + model: new MockLanguageModelV1({ + doStream: async () => ({ + stream: simulateReadableStream({ + chunks: [ + { type: 'text-delta', textDelta: 'こんにちは' }, + { type: 'text-delta', textDelta: 'こんにちは' }, + { type: 'text-delta', textDelta: 'こんにちは' }, + { type: 'text-delta', textDelta: 'こんにちは' }, + { type: 'text-delta', textDelta: 'こんにちは' }, + { + type: 'finish', + finishReason: 'stop', + logprobs: undefined, + usage: { completionTokens: 10, promptTokens: 3 }, + }, + ], + chunkDelayInMs: 400, + }), + rawCall: { rawPrompt: null, rawSettings: {} }, + }), + }), + + prompt: 'Say hello in Japanese!', + experimental_transform: smoothStream({ + chunking: /[\u3040-\u309F\u30A0-\u30FF]|\S+\s+/, + }), + }); + + for await (const textPart of result.textStream) { + process.stdout.write(textPart); + } +} + +main().catch(console.error); diff --git a/packages/ai/core/generate-text/index.ts b/packages/ai/core/generate-text/index.ts index 8ca67561e4c9..ab53b626fc47 100644 --- a/packages/ai/core/generate-text/index.ts +++ b/packages/ai/core/generate-text/index.ts @@ -6,7 +6,7 @@ export type { GeneratedFile, } from './generated-file'; export * as Output from './output'; -export { smoothStream } from './smooth-stream'; +export { smoothStream, type ChunkDetector } from './smooth-stream'; export type { StepResult } from './step-result'; export { streamText } from './stream-text'; export type { diff --git a/packages/ai/core/generate-text/smooth-stream.test.ts b/packages/ai/core/generate-text/smooth-stream.test.ts index 7d5bbd5db00d..b2bc8257fe2a 100644 --- a/packages/ai/core/generate-text/smooth-stream.test.ts +++ b/packages/ai/core/generate-text/smooth-stream.test.ts @@ -23,6 +23,24 @@ describe('smoothStream', () => { return Promise.resolve(); } + describe('throws error if chunking option is invalid', async () => { + it('throws error if chunking strategy is invalid', async () => { + expect(() => { + smoothStream({ + chunking: 'foo' as any, + }); + }).toThrowError(); + }); + + it('throws error if chunking option is null', async () => { + expect(() => { + smoothStream({ + chunking: null as any, + }); + }).toThrowError(); + }); + }); + describe('word chunking', () => { it('should combine partial words', async () => { const stream = convertArrayToReadableStream([ @@ -333,6 +351,40 @@ describe('smoothStream', () => { ] `); }); + + it(`doesn't return chunks with just spaces`, async () => { + const stream = convertArrayToReadableStream([ + { type: 'text-delta', textDelta: ' ' }, + { type: 'text-delta', textDelta: ' ' }, + { type: 'text-delta', textDelta: ' ' }, + { type: 'text-delta', textDelta: 'foo' }, + + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ + delayInMs: 10, + _internal: { delay }, + })({ tools: {} }), + ); + + await consumeStream(stream); + + expect(events).toMatchInlineSnapshot(` + [ + { + "textDelta": " foo", + "type": "text-delta", + }, + { + "type": "step-finish", + }, + { + "type": "finish", + }, + ] + `); + }); }); describe('line chunking', () => { @@ -423,6 +475,42 @@ describe('smoothStream', () => { }); describe('custom chunking', () => { + it(`should return correct result for regexes that don't match from the exact start onwards`, async () => { + const stream = convertArrayToReadableStream([ + { textDelta: 'Hello_, world!', type: 'text-delta' }, + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ + chunking: /_/, + delayInMs: 10, + _internal: { delay }, + })({ tools: {} }), + ); + + await consumeStream(stream); + + expect(events).toMatchInlineSnapshot(` + [ + "delay 10", + { + "textDelta": "Hello_", + "type": "text-delta", + }, + { + "textDelta": ", world!", + "type": "text-delta", + }, + { + "type": "step-finish", + }, + { + "type": "finish", + }, + ] + `); + }); + it('should support custom chunking regexps (character-level)', async () => { const stream = convertArrayToReadableStream([ { textDelta: 'Hello, world!', type: 'text-delta' }, @@ -471,6 +559,87 @@ describe('smoothStream', () => { }); }); + describe('custom callback chunking', () => { + it('should support custom chunking callback', async () => { + const stream = convertArrayToReadableStream([ + { textDelta: 'He_llo, ', type: 'text-delta' }, + { textDelta: 'w_orld!', type: 'text-delta' }, + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ + chunking: buffer => /[^_]*_/.exec(buffer)?.[0], + _internal: { delay }, + })({ tools: {} }), + ); + + await consumeStream(stream); + + expect(events).toMatchInlineSnapshot(` + [ + "delay 10", + { + "textDelta": "He_", + "type": "text-delta", + }, + "delay 10", + { + "textDelta": "llo, w_", + "type": "text-delta", + }, + { + "textDelta": "orld!", + "type": "text-delta", + }, + { + "type": "step-finish", + }, + { + "type": "finish", + }, + ] + `); + }); + + describe('throws errors if the chunking function invalid matches', async () => { + it('throws empty match error', async () => { + const stream = convertArrayToReadableStream([ + { textDelta: 'Hello, world!', type: 'text-delta' }, + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ chunking: () => '', _internal: { delay } })({ + tools: {}, + }), + ); + + await expect( + consumeStream(stream), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: Chunking function must return a non-empty string.]`, + ); + }); + + it('throws match prefix error', async () => { + const stream = convertArrayToReadableStream([ + { textDelta: 'Hello, world!', type: 'text-delta' }, + { type: 'step-finish' }, + { type: 'finish' }, + ]).pipeThrough( + smoothStream({ chunking: () => 'world', _internal: { delay } })({ + tools: {}, + }), + ); + + await expect( + consumeStream(stream), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: Chunking function must return a match that is a prefix of the buffer. Received: "world" expected to start with "Hello, world!"]`, + ); + }); + }); + }); + describe('delay', () => { it('should default to 10ms', async () => { const stream = convertArrayToReadableStream([ diff --git a/packages/ai/core/generate-text/smooth-stream.ts b/packages/ai/core/generate-text/smooth-stream.ts index 3cca81c15ee9..86be60ca70ca 100644 --- a/packages/ai/core/generate-text/smooth-stream.ts +++ b/packages/ai/core/generate-text/smooth-stream.ts @@ -1,13 +1,22 @@ -import { InvalidArgumentError } from '@ai-sdk/provider'; import { delay as originalDelay } from '@ai-sdk/provider-utils'; import { TextStreamPart } from './stream-text-result'; import { ToolSet } from './tool-set'; +import { InvalidArgumentError } from '@ai-sdk/provider'; const CHUNKING_REGEXPS = { - word: /\s*\S+\s+/m, - line: /[^\n]*\n/m, + word: /\S+\s+/m, + line: /\n+/m, }; +/** + * Detects the first chunk in a buffer. + * + * @param buffer - The buffer to detect the first chunk in. + * + * @returns The first detected chunk, or `undefined` if no chunk was detected. + */ +export type ChunkDetector = (buffer: string) => string | undefined | null; + /** * Smooths text streaming output. * @@ -22,7 +31,7 @@ export function smoothStream({ _internal: { delay = originalDelay } = {}, }: { delayInMs?: number | null; - chunking?: 'word' | 'line' | RegExp; + chunking?: 'word' | 'line' | RegExp | ChunkDetector; /** * Internal. For test use only. May change without notice. */ @@ -32,14 +41,48 @@ export function smoothStream({ } = {}): (options: { tools: TOOLS; }) => TransformStream, TextStreamPart> { - const chunkingRegexp = - typeof chunking === 'string' ? CHUNKING_REGEXPS[chunking] : chunking; + let detectChunk: ChunkDetector; - if (chunkingRegexp == null) { - throw new InvalidArgumentError({ - argument: 'chunking', - message: `Chunking must be "word" or "line" or a RegExp. Received: ${chunking}`, - }); + if (typeof chunking === 'function') { + detectChunk = buffer => { + const match = chunking(buffer); + + if (match == null) { + return null; + } + + if (!match.length) { + throw new Error(`Chunking function must return a non-empty string.`); + } + + if (!buffer.startsWith(match)) { + throw new Error( + `Chunking function must return a match that is a prefix of the buffer. Received: "${match}" expected to start with "${buffer}"`, + ); + } + + return match; + }; + } else { + const chunkingRegex = + typeof chunking === 'string' ? CHUNKING_REGEXPS[chunking] : chunking; + + if (chunkingRegex == null) { + throw new InvalidArgumentError({ + argument: 'chunking', + message: `Chunking must be "word" or "line" or a RegExp. Received: ${chunking}`, + }); + } + + detectChunk = buffer => { + const match = chunkingRegex.exec(buffer); + + if (!match) { + return null; + } + + return buffer.slice(0, match.index) + match?.[0]; + }; } return () => { @@ -60,10 +103,10 @@ export function smoothStream({ buffer += chunk.textDelta; let match; - while ((match = chunkingRegexp.exec(buffer)) != null) { - const chunk = match[0]; - controller.enqueue({ type: 'text-delta', textDelta: chunk }); - buffer = buffer.slice(chunk.length); + + while ((match = detectChunk(buffer)) != null) { + controller.enqueue({ type: 'text-delta', textDelta: match }); + buffer = buffer.slice(match.length); await delay(delayInMs); } From 5c47bbd7d2990213365a61bbb2a1d4bdc8849931 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 11:00:31 +0200 Subject: [PATCH 020/191] Version Packages (#5561) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/beige-ligers-kneel.md | 5 --- examples/ai-core/package.json | 4 +- examples/express/package.json | 2 +- examples/fastify/package.json | 2 +- examples/hono/package.json | 2 +- examples/mcp/package.json | 2 +- examples/nest/package.json | 2 +- examples/next-fastapi/package.json | 2 +- examples/next-google-vertex/package.json | 2 +- examples/next-langchain/package.json | 2 +- .../package.json | 2 +- examples/next-openai-pages/package.json | 2 +- .../next-openai-telemetry-sentry/package.json | 2 +- examples/next-openai-telemetry/package.json | 2 +- .../package.json | 2 +- examples/next-openai/package.json | 2 +- examples/node-http-server/package.json | 2 +- examples/nuxt-openai/package.json | 2 +- examples/solidstart-openai/package.json | 2 +- examples/sveltekit-openai/package.json | 2 +- packages/ai/CHANGELOG.md | 6 +++ packages/ai/package.json | 2 +- .../ai/tests/e2e/next-server/CHANGELOG.md | 7 ++++ packages/valibot/CHANGELOG.md | 7 ++++ packages/valibot/package.json | 4 +- pnpm-lock.yaml | 42 +++++++++---------- 26 files changed, 64 insertions(+), 49 deletions(-) delete mode 100644 .changeset/beige-ligers-kneel.md diff --git a/.changeset/beige-ligers-kneel.md b/.changeset/beige-ligers-kneel.md deleted file mode 100644 index fe3a654a5dc5..000000000000 --- a/.changeset/beige-ligers-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -feat(smooth-stream): chunking callbacks diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index f3b2fff69f71..e9842a243adf 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -24,12 +24,12 @@ "@ai-sdk/replicate": "0.2.4", "@ai-sdk/togetherai": "0.2.6", "@ai-sdk/xai": "1.2.7", - "@ai-sdk/valibot": "0.1.12", + "@ai-sdk/valibot": "0.1.13", "@google/generative-ai": "0.21.0", "@opentelemetry/auto-instrumentations-node": "0.54.0", "@opentelemetry/sdk-node": "0.54.2", "@opentelemetry/sdk-trace-node": "1.28.0", - "ai": "4.3.0", + "ai": "4.3.1", "dotenv": "16.4.5", "image-type": "^5.2.0", "mathjs": "14.0.0", diff --git a/examples/express/package.json b/examples/express/package.json index c8733146c5fd..66ab14341203 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@ai-sdk/openai": "1.3.7", - "ai": "4.3.0", + "ai": "4.3.1", "dotenv": "16.4.5", "express": "5.0.1" }, diff --git a/examples/fastify/package.json b/examples/fastify/package.json index 8b0076c109b2..08f5ab7821ca 100644 --- a/examples/fastify/package.json +++ b/examples/fastify/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/openai": "1.3.7", - "ai": "4.3.0", + "ai": "4.3.1", "dotenv": "16.4.5", "fastify": "5.1.0" }, diff --git a/examples/hono/package.json b/examples/hono/package.json index 3fda75474e35..7b40f3b42d9d 100644 --- a/examples/hono/package.json +++ b/examples/hono/package.json @@ -5,7 +5,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.7", "@hono/node-server": "1.13.7", - "ai": "4.3.0", + "ai": "4.3.1", "dotenv": "16.4.5", "hono": "4.6.9" }, diff --git a/examples/mcp/package.json b/examples/mcp/package.json index db4c45fbc777..20666c9288d8 100644 --- a/examples/mcp/package.json +++ b/examples/mcp/package.json @@ -14,7 +14,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.7", "@modelcontextprotocol/sdk": "^1.7.0", - "ai": "4.3.0", + "ai": "4.3.1", "dotenv": "16.4.5", "express": "5.0.1", "zod": "3.23.8" diff --git a/examples/nest/package.json b/examples/nest/package.json index 726f53327457..095336a2cda2 100644 --- a/examples/nest/package.json +++ b/examples/nest/package.json @@ -19,7 +19,7 @@ "@nestjs/common": "^10.4.15", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.4.9", - "ai": "4.3.0", + "ai": "4.3.1", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/examples/next-fastapi/package.json b/examples/next-fastapi/package.json index 3114aaa23ed1..1644281c2329 100644 --- a/examples/next-fastapi/package.json +++ b/examples/next-fastapi/package.json @@ -13,7 +13,7 @@ "dependencies": { "@ai-sdk/ui-utils": "1.2.5", "@ai-sdk/react": "1.2.6", - "ai": "4.3.0", + "ai": "4.3.1", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index 6b276cf9c36b..f18c524c930d 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@ai-sdk/google-vertex": "2.2.10", - "ai": "4.3.0", + "ai": "4.3.1", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-langchain/package.json b/examples/next-langchain/package.json index acfb5b04f037..90234e863fd3 100644 --- a/examples/next-langchain/package.json +++ b/examples/next-langchain/package.json @@ -12,7 +12,7 @@ "@ai-sdk/react": "1.2.6", "@langchain/openai": "0.0.28", "@langchain/core": "0.1.63", - "ai": "4.3.0", + "ai": "4.3.1", "langchain": "0.1.36", "next": "latest", "react": "^18", diff --git a/examples/next-openai-kasada-bot-protection/package.json b/examples/next-openai-kasada-bot-protection/package.json index 5115f36f7fd1..236b3269ab96 100644 --- a/examples/next-openai-kasada-bot-protection/package.json +++ b/examples/next-openai-kasada-bot-protection/package.json @@ -12,7 +12,7 @@ "@ai-sdk/openai": "1.3.7", "@ai-sdk/react": "1.2.6", "@vercel/functions": "latest", - "ai": "4.3.0", + "ai": "4.3.1", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai-pages/package.json b/examples/next-openai-pages/package.json index 896c305e1705..8b25256af033 100644 --- a/examples/next-openai-pages/package.json +++ b/examples/next-openai-pages/package.json @@ -11,7 +11,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.7", "@ai-sdk/react": "1.2.6", - "ai": "4.3.0", + "ai": "4.3.1", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry-sentry/package.json b/examples/next-openai-telemetry-sentry/package.json index 872fa1fb46b4..80c10e3ed4ab 100644 --- a/examples/next-openai-telemetry-sentry/package.json +++ b/examples/next-openai-telemetry-sentry/package.json @@ -17,7 +17,7 @@ "@sentry/nextjs": "^8.42.0", "@sentry/opentelemetry": "8.22.0", "@vercel/otel": "1.10.0", - "ai": "4.3.0", + "ai": "4.3.1", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry/package.json b/examples/next-openai-telemetry/package.json index b5ac98405eb8..021451dac2da 100644 --- a/examples/next-openai-telemetry/package.json +++ b/examples/next-openai-telemetry/package.json @@ -15,7 +15,7 @@ "@opentelemetry/sdk-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@vercel/otel": "1.10.0", - "ai": "4.3.0", + "ai": "4.3.1", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-upstash-rate-limits/package.json b/examples/next-openai-upstash-rate-limits/package.json index 11ac194c2f60..d9c32d60f29d 100644 --- a/examples/next-openai-upstash-rate-limits/package.json +++ b/examples/next-openai-upstash-rate-limits/package.json @@ -13,7 +13,7 @@ "@ai-sdk/react": "1.2.6", "@upstash/ratelimit": "^0.4.3", "@vercel/kv": "^0.2.2", - "ai": "4.3.0", + "ai": "4.3.1", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 1307008dca5b..5fba5201a376 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -19,7 +19,7 @@ "@ai-sdk/ui-utils": "1.2.5", "@ai-sdk/react": "1.2.6", "@vercel/blob": "^0.26.0", - "ai": "4.3.0", + "ai": "4.3.1", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/node-http-server/package.json b/examples/node-http-server/package.json index 165a76c50bbf..68f707606d7b 100644 --- a/examples/node-http-server/package.json +++ b/examples/node-http-server/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/openai": "1.3.7", - "ai": "4.3.0", + "ai": "4.3.1", "dotenv": "16.4.5", "zod": "3.23.8", "zod-to-json-schema": "3.23.5" diff --git a/examples/nuxt-openai/package.json b/examples/nuxt-openai/package.json index bf1aa10581ac..582e7732239e 100644 --- a/examples/nuxt-openai/package.json +++ b/examples/nuxt-openai/package.json @@ -11,7 +11,7 @@ "dependencies": { "@ai-sdk/vue": "1.2.5", "@ai-sdk/openai": "1.3.7", - "ai": "4.3.0", + "ai": "4.3.1", "zod": "3.23.8" }, "devDependencies": { diff --git a/examples/solidstart-openai/package.json b/examples/solidstart-openai/package.json index 62b41e740402..7f5c4350b409 100644 --- a/examples/solidstart-openai/package.json +++ b/examples/solidstart-openai/package.json @@ -20,7 +20,7 @@ "@solidjs/meta": "0.29.4", "@solidjs/router": "^0.15.1", "@solidjs/start": "^1.0.10", - "ai": "4.3.0", + "ai": "4.3.1", "solid-js": "^1.9.3", "zod": "^3.23.8" }, diff --git a/examples/sveltekit-openai/package.json b/examples/sveltekit-openai/package.json index 341d7e2a3002..48e4d2b28be1 100644 --- a/examples/sveltekit-openai/package.json +++ b/examples/sveltekit-openai/package.json @@ -25,7 +25,7 @@ "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", - "ai": "4.3.0", + "ai": "4.3.1", "autoprefixer": "^10.4.20", "bits-ui": "^1.3.9", "clsx": "^2.1.1", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 226b2903f684..c812567a785d 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 4.3.1 + +### Patch Changes + +- 3d1bd38: feat(smooth-stream): chunking callbacks + ## 4.3.0 ### Minor Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index c996c3f96c76..7fa79f215c96 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "4.3.0", + "version": "4.3.1", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/ai/tests/e2e/next-server/CHANGELOG.md b/packages/ai/tests/e2e/next-server/CHANGELOG.md index 7867274816c1..01f6f02dc933 100644 --- a/packages/ai/tests/e2e/next-server/CHANGELOG.md +++ b/packages/ai/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [3d1bd38] + - ai@4.3.1 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [772a2d7] - ai@4.3.0 diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 2817dc3a9301..802d35cadeb7 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 0.1.13 + +### Patch Changes + +- Updated dependencies [3d1bd38] + - ai@4.3.1 + ## 0.1.12 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index d777b573e3fc..c01bc3c4abb1 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "0.1.12", + "version": "0.1.13", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -27,7 +27,7 @@ } }, "dependencies": { - "ai": "4.3.0" + "ai": "4.3.1" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 84dc816ffcff..3fe6e0cf1ddf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,7 +120,7 @@ importers: specifier: 0.2.6 version: link:../../packages/togetherai '@ai-sdk/valibot': - specifier: 0.1.12 + specifier: 0.1.13 version: link:../../packages/valibot '@ai-sdk/xai': specifier: 1.2.7 @@ -138,7 +138,7 @@ importers: specifier: 1.28.0 version: 1.28.0(@opentelemetry/api@1.9.0) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -181,7 +181,7 @@ importers: specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -209,7 +209,7 @@ importers: specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -237,7 +237,7 @@ importers: specifier: 1.13.7 version: 1.13.7(hono@4.6.9) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -265,7 +265,7 @@ importers: specifier: ^1.7.0 version: 1.7.0 ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -305,7 +305,7 @@ importers: specifier: ^10.4.9 version: 10.4.9(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai reflect-metadata: specifier: ^0.2.0 @@ -387,7 +387,7 @@ importers: specifier: 1.2.5 version: link:../../packages/ui-utils ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -439,7 +439,7 @@ importers: specifier: 2.2.10 version: link:../../packages/google-vertex ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -488,7 +488,7 @@ importers: specifier: 0.0.28 version: 0.0.28 ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai langchain: specifier: 0.1.36 @@ -564,7 +564,7 @@ importers: specifier: ^0.26.0 version: 0.26.0 ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai next: specifier: latest @@ -625,7 +625,7 @@ importers: specifier: latest version: 2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai next: specifier: latest @@ -677,7 +677,7 @@ importers: specifier: 1.2.6 version: link:../../packages/react ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai next: specifier: latest @@ -744,7 +744,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.29.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai next: specifier: latest @@ -817,7 +817,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai next: specifier: latest @@ -878,7 +878,7 @@ importers: specifier: ^0.2.2 version: 0.2.4 ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai next: specifier: latest @@ -927,7 +927,7 @@ importers: specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -958,7 +958,7 @@ importers: specifier: 1.2.5 version: link:../../packages/vue ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai zod: specifier: 3.23.8 @@ -1025,7 +1025,7 @@ importers: specifier: ^1.0.10 version: 1.0.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vinxi@0.4.3(@types/node@22.7.4)(@upstash/redis@1.34.3)(ioredis@5.4.1)(terser@5.31.3)(typescript@5.6.3))(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai solid-js: specifier: ^1.9.3 @@ -1077,7 +1077,7 @@ importers: specifier: ^5.0.0 version: 5.0.3(svelte@5.22.4)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../../packages/ai autoprefixer: specifier: ^10.4.20 @@ -2052,7 +2052,7 @@ importers: specifier: ^1.0.0-rc.0 || ^1.0.0 version: 1.0.0-rc.0(valibot@1.0.0-rc.0(typescript@5.6.3)) ai: - specifier: 4.3.0 + specifier: 4.3.1 version: link:../ai devDependencies: '@types/node': From 665a5674c9655df85e0d09b66ae92992e682c558 Mon Sep 17 00:00:00 2001 From: Grace Yun <74513600+iteratetograceness@users.noreply.github.com> Date: Sat, 5 Apr 2025 15:43:17 -0400 Subject: [PATCH 021/191] fix (core): consume stream on abort (#5492) --- .changeset/thin-numbers-shave.md | 5 ++ .../01-ai-sdk-core/02-stream-text.mdx | 19 +++- .../use-chat-resilient-persistence/route.ts | 9 +- .../[id]/chat.tsx | 26 ++++-- .../core/generate-text/stream-text-result.ts | 8 +- .../ai/core/generate-text/stream-text.test.ts | 86 +++++++++++++++++++ packages/ai/core/generate-text/stream-text.ts | 14 ++- packages/ai/util/consume-stream.ts | 20 ++++- 8 files changed, 165 insertions(+), 22 deletions(-) create mode 100644 .changeset/thin-numbers-shave.md diff --git a/.changeset/thin-numbers-shave.md b/.changeset/thin-numbers-shave.md new file mode 100644 index 000000000000..e57732de3101 --- /dev/null +++ b/.changeset/thin-numbers-shave.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix (core): improve error handling in streamText's consumeStream method diff --git a/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx b/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx index 450f77c9e619..8b1215e5aba1 100644 --- a/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx @@ -2274,13 +2274,26 @@ To see `streamText` in action, check out [these examples](#examples). }, { name: 'consumeStream', - type: '() => Promise', + type: '(options?: ConsumeStreamOptions) => Promise', description: - 'Consumes the stream without processing the parts. This is useful to force the stream to finish.', + 'Consumes the stream without processing the parts. This is useful to force the stream to finish. If an error occurs, it is passed to the optional `onError` callback.', + properties: [ + { + type: 'ConsumeStreamOptions', + parameters: [ + { + name: 'onError', + type: '(error: unknown) => void', + isOptional: true, + description: 'The error callback.', + }, + ], + }, + ], }, { name: 'pipeDataStreamToResponse', - type: '(response: ServerResponse, options: PipeDataStreamToResponseOptions } => void', + type: '(response: ServerResponse, options: PipeDataStreamToResponseOptions) => void', description: 'Writes stream data output to a Node.js response-like object. It sets a `Content-Type` header to `text/plain; charset=utf-8` and writes each stream data part as a separate chunk.', properties: [ diff --git a/examples/next-openai/app/api/use-chat-resilient-persistence/route.ts b/examples/next-openai/app/api/use-chat-resilient-persistence/route.ts index 92a72e6fcaad..7665e5adbcce 100644 --- a/examples/next-openai/app/api/use-chat-resilient-persistence/route.ts +++ b/examples/next-openai/app/api/use-chat-resilient-persistence/route.ts @@ -1,6 +1,6 @@ import { openai } from '@ai-sdk/openai'; -import { appendResponseMessages, createIdGenerator, streamText } from 'ai'; import { saveChat } from '@util/chat-store'; +import { appendResponseMessages, createIdGenerator, streamText } from 'ai'; export async function POST(req: Request) { const { messages, id } = await req.json(); @@ -26,7 +26,12 @@ export async function POST(req: Request) { // consume the stream to ensure it runs to completion and triggers onFinish // even when the client response is aborted (e.g. when the browser tab is closed). - result.consumeStream(); // no await + // no await + result.consumeStream({ + onError: error => { + console.log('Error during background stream consumption: ', error); // optional error callback + }, + }); return result.toDataStreamResponse(); } diff --git a/examples/next-openai/app/use-chat-resilient-persistence/[id]/chat.tsx b/examples/next-openai/app/use-chat-resilient-persistence/[id]/chat.tsx index 90428815a508..c589443d864f 100644 --- a/examples/next-openai/app/use-chat-resilient-persistence/[id]/chat.tsx +++ b/examples/next-openai/app/use-chat-resilient-persistence/[id]/chat.tsx @@ -1,19 +1,20 @@ 'use client'; -import { createIdGenerator } from 'ai'; import { Message, useChat } from '@ai-sdk/react'; +import { createIdGenerator } from 'ai'; export default function Chat({ id, initialMessages, }: { id?: string | undefined; initialMessages?: Message[] } = {}) { - const { input, status, handleInputChange, handleSubmit, messages } = useChat({ - api: '/api/use-chat-resilient-persistence', - id, // use the provided chatId - initialMessages, // initial messages if provided - sendExtraMessageFields: true, // send id and createdAt for each message - generateId: createIdGenerator({ prefix: 'msgc', size: 16 }), // id format for client-side messages - }); + const { input, status, handleInputChange, handleSubmit, messages, stop } = + useChat({ + api: '/api/use-chat-resilient-persistence', + id, // use the provided chatId + initialMessages, // initial messages if provided + sendExtraMessageFields: true, // send id and createdAt for each message + generateId: createIdGenerator({ prefix: 'msgc', size: 16 }), // id format for client-side messages + }); return (
@@ -32,6 +33,15 @@ export default function Chat({ onChange={handleInputChange} disabled={status !== 'ready'} /> + {status === 'streaming' && ( + + )}
); diff --git a/packages/ai/core/generate-text/stream-text-result.ts b/packages/ai/core/generate-text/stream-text-result.ts index 3dde6d3b765e..181518dac5d2 100644 --- a/packages/ai/core/generate-text/stream-text-result.ts +++ b/packages/ai/core/generate-text/stream-text-result.ts @@ -61,6 +61,10 @@ export type DataStreamOptions = { experimental_sendStart?: boolean; }; +export type ConsumeStreamOptions = { + onError?: (error: unknown) => void; +}; + /** A result object for accessing different stream types and additional information. */ @@ -203,8 +207,10 @@ Consumes the stream without processing the parts. This is useful to force the stream to finish. It effectively removes the backpressure and allows the stream to finish, triggering the `onFinish` callback and the promise resolution. + +If an error occurs, it is passed to the optional `onError` callback. */ - consumeStream(): Promise; + consumeStream(options?: ConsumeStreamOptions): Promise; /** Converts the result to a data stream. diff --git a/packages/ai/core/generate-text/stream-text.test.ts b/packages/ai/core/generate-text/stream-text.test.ts index bc31157575d3..395be5d96fd1 100644 --- a/packages/ai/core/generate-text/stream-text.test.ts +++ b/packages/ai/core/generate-text/stream-text.test.ts @@ -1542,6 +1542,92 @@ describe('streamText', () => { }); }); + describe('result.consumeStream', () => { + it('should ignore AbortError during stream consumption', async () => { + const result = streamText({ + model: createTestModel({ + stream: new ReadableStream({ + start(controller) { + controller.enqueue({ type: 'text-delta', textDelta: 'Hello' }); + queueMicrotask(() => { + controller.error( + Object.assign(new Error('Stream aborted'), { + name: 'AbortError', + }), + ); + }); + }, + }), + }), + prompt: 'test-input', + }); + + await expect(result.consumeStream()).resolves.not.toThrow(); + }); + + it('should ignore ResponseAborted error during stream consumption', async () => { + const result = streamText({ + model: createTestModel({ + stream: new ReadableStream({ + start(controller) { + controller.enqueue({ type: 'text-delta', textDelta: 'Hello' }); + queueMicrotask(() => { + controller.error( + Object.assign(new Error('Response aborted'), { + name: 'ResponseAborted', + }), + ); + }); + }, + }), + }), + prompt: 'test-input', + }); + + await expect(result.consumeStream()).resolves.not.toThrow(); + }); + + it('should ignore any errors during stream consumption', async () => { + const result = streamText({ + model: createTestModel({ + stream: new ReadableStream({ + start(controller) { + controller.enqueue({ type: 'text-delta', textDelta: 'Hello' }); + queueMicrotask(() => { + controller.error(Object.assign(new Error('Some error'))); + }); + }, + }), + }), + prompt: 'test-input', + }); + + await expect(result.consumeStream()).resolves.not.toThrow(); + }); + + it('should call the onError callback with the error', async () => { + const onErrorCallback = vi.fn(); + const result = streamText({ + model: createTestModel({ + stream: new ReadableStream({ + start(controller) { + controller.enqueue({ type: 'text-delta', textDelta: 'Hello' }); + queueMicrotask(() => { + controller.error(Object.assign(new Error('Some error'))); + }); + }, + }), + }), + prompt: 'test-input', + }); + + await expect( + result.consumeStream({ onError: onErrorCallback }), + ).resolves.not.toThrow(); + expect(onErrorCallback).toHaveBeenCalledWith(new Error('Some error')); + }); + }); + describe('multiple stream consumption', () => { it('should support text stream, ai stream, full stream on single result object', async () => { const result = streamText({ diff --git a/packages/ai/core/generate-text/stream-text.ts b/packages/ai/core/generate-text/stream-text.ts index b7d5c3a54efb..202524907906 100644 --- a/packages/ai/core/generate-text/stream-text.ts +++ b/packages/ai/core/generate-text/stream-text.ts @@ -8,6 +8,7 @@ import { InvalidStreamPartError } from '../../errors/invalid-stream-part-error'; import { NoOutputSpecifiedError } from '../../errors/no-output-specified-error'; import { StreamData } from '../../streams/stream-data'; import { asArray } from '../../util/as-array'; +import { consumeStream } from '../../util/consume-stream'; import { DelayedPromise } from '../../util/delayed-promise'; import { DataStreamWriter } from '../data-stream/data-stream-writer'; import { CallSettings } from '../prompt/call-settings'; @@ -53,6 +54,7 @@ import { } from './run-tools-transformation'; import { ResponseMessage, StepResult } from './step-result'; import { + ConsumeStreamOptions, DataStreamOptions, StreamTextResult, TextStreamPart, @@ -1591,10 +1593,14 @@ However, the LLM results are expected to be small enough to not cause issues. ); } - async consumeStream(): Promise { - const stream = this.fullStream; - for await (const part of stream) { - // no op + async consumeStream(options?: ConsumeStreamOptions): Promise { + try { + await consumeStream({ + stream: this.fullStream, + onError: options?.onError, + }); + } catch (error) { + options?.onError?.(error); } } diff --git a/packages/ai/util/consume-stream.ts b/packages/ai/util/consume-stream.ts index b38ab2fbb16d..c540696d72e3 100644 --- a/packages/ai/util/consume-stream.ts +++ b/packages/ai/util/consume-stream.ts @@ -8,10 +8,22 @@ * @param {ReadableStream} stream - The ReadableStream to be consumed. * @returns {Promise} A promise that resolves when the stream is fully consumed. */ -export async function consumeStream(stream: ReadableStream): Promise { +export async function consumeStream({ + stream, + onError, +}: { + stream: ReadableStream; + onError?: (error: unknown) => void; +}): Promise { const reader = stream.getReader(); - while (true) { - const { done } = await reader.read(); - if (done) break; + try { + while (true) { + const { done } = await reader.read(); + if (done) break; + } + } catch (error) { + onError?.(error); + } finally { + reader.releaseLock(); } } From 8fdc8fe38d78df7edb03b8a4952942ba5fc28d1f Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Sat, 5 Apr 2025 13:59:12 -0700 Subject: [PATCH 022/191] feat (provider/groq): add llama 4 model (#5565) --- .changeset/tall-rice-flash.md | 5 ++ .../02-providers-and-models.mdx | 75 ++++++++++--------- .../providers/01-ai-sdk-providers/09-groq.mdx | 29 +++---- .../providers/01-ai-sdk-providers/index.mdx | 1 + packages/groq/src/groq-chat-settings.ts | 1 + 5 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 .changeset/tall-rice-flash.md diff --git a/.changeset/tall-rice-flash.md b/.changeset/tall-rice-flash.md new file mode 100644 index 000000000000..20c49b454ede --- /dev/null +++ b/.changeset/tall-rice-flash.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/groq': patch +--- + +feat (provider/groq): add llama 4 model diff --git a/content/docs/02-foundations/02-providers-and-models.mdx b/content/docs/02-foundations/02-providers-and-models.mdx index a1902d339608..fcafe7cf6a2f 100644 --- a/content/docs/02-foundations/02-providers-and-models.mdx +++ b/content/docs/02-foundations/02-providers-and-models.mdx @@ -79,43 +79,44 @@ Additionally, any self-hosted provider that supports the OpenAI specification ca The AI providers support different language models with various capabilities. Here are the capabilities of popular models: -| Provider | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | -| ------------------------------------------------------------------------ | ---------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-1212` | | | | | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-vision-1212` | | | | | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-beta` | | | | | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-vision-beta` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o-mini` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4-turbo` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o3-mini` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o1` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-mini` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-preview` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-7-sonnet-20250219` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20241022` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20240620` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-haiku-20241022` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-large-latest` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-large-latest` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-small-latest` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-12b-2409` | | | | | -| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-2.0-flash-exp` | | | | | -| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-flash` | | | | | -| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-pro` | | | | | -| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-2.0-flash-exp` | | | | | -| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-flash` | | | | | -| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-pro` | | | | | -| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-chat` | | | | | -| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-reasoner` | | | | | -| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-8b` | | | | | -| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-70b` | | | | | -| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.3-70b` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.3-70b-versatile` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.1-8b-instant` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `mixtral-8x7b-32768` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `gemma2-9b-it` | | | | | +| Provider | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | +| ------------------------------------------------------------------------ | ------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-1212` | | | | | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-vision-1212` | | | | | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-beta` | | | | | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-vision-beta` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o-mini` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4-turbo` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o3-mini` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o1` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-mini` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-preview` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-7-sonnet-20250219` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20241022` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20240620` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-haiku-20241022` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-large-latest` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-large-latest` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-small-latest` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-12b-2409` | | | | | +| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-2.0-flash-exp` | | | | | +| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-flash` | | | | | +| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-pro` | | | | | +| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-2.0-flash-exp` | | | | | +| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-flash` | | | | | +| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-pro` | | | | | +| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-chat` | | | | | +| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-reasoner` | | | | | +| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-8b` | | | | | +| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-70b` | | | | | +| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.3-70b` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `meta-llama/llama-4-scout-17b-16e-instruct` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.3-70b-versatile` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.1-8b-instant` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `mixtral-8x7b-32768` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `gemma2-9b-it` | | | | | This table is not exhaustive. Additional models can be found in the provider diff --git a/content/providers/01-ai-sdk-providers/09-groq.mdx b/content/providers/01-ai-sdk-providers/09-groq.mdx index 96049593f133..6c8cc1c0e75a 100644 --- a/content/providers/01-ai-sdk-providers/09-groq.mdx +++ b/content/providers/01-ai-sdk-providers/09-groq.mdx @@ -112,20 +112,21 @@ const { text } = await generateText({ ## Model Capabilities -| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | -| ------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `gemma2-9b-it` | | | | | -| `llama-3.3-70b-versatile` | | | | | -| `llama-3.1-8b-instant` | | | | | -| `llama-guard-3-8b` | | | | | -| `llama3-70b-8192` | | | | | -| `llama3-8b-8192` | | | | | -| `mixtral-8x7b-32768` | | | | | -| `qwen-qwq-32b` | | | | | -| `mistral-saba-24b` | | | | | -| `qwen-2.5-32b` | | | | | -| `deepseek-r1-distill-qwen-32b` | | | | | -| `deepseek-r1-distill-llama-70b` | | | | | +| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | +| ------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `meta-llama/llama-4-scout-17b-16e-instruct` | | | | | +| `gemma2-9b-it` | | | | | +| `llama-3.3-70b-versatile` | | | | | +| `llama-3.1-8b-instant` | | | | | +| `llama-guard-3-8b` | | | | | +| `llama3-70b-8192` | | | | | +| `llama3-8b-8192` | | | | | +| `mixtral-8x7b-32768` | | | | | +| `qwen-qwq-32b` | | | | | +| `mistral-saba-24b` | | | | | +| `qwen-2.5-32b` | | | | | +| `deepseek-r1-distill-qwen-32b` | | | | | +| `deepseek-r1-distill-llama-70b` | | | | | The table above lists popular models. Please see the [Groq diff --git a/content/providers/01-ai-sdk-providers/index.mdx b/content/providers/01-ai-sdk-providers/index.mdx index 0aa13c6b99d7..503a3119e3de 100644 --- a/content/providers/01-ai-sdk-providers/index.mdx +++ b/content/providers/01-ai-sdk-providers/index.mdx @@ -34,6 +34,7 @@ Not all providers support all AI SDK features. Here's a quick comparison of the | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20241022` | | | | | | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20240620` | | | | | | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-haiku-20241022` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `meta-llama/llama-4-scout-17b-16e-instruct` | | | | | | [Groq](/providers/ai-sdk-providers/groq) | `deepseek-r1-distill-llama-70b` | | | | | | [Groq](/providers/ai-sdk-providers/groq) | `llama-3.3-70b-versatile` | | | | | | [Groq](/providers/ai-sdk-providers/groq) | `llama-3.1-8b-instant` | | | | | diff --git a/packages/groq/src/groq-chat-settings.ts b/packages/groq/src/groq-chat-settings.ts index ed70c1ec7527..2d8104d52cdc 100644 --- a/packages/groq/src/groq-chat-settings.ts +++ b/packages/groq/src/groq-chat-settings.ts @@ -9,6 +9,7 @@ export type GroqChatModelId = | 'llama3-8b-8192' | 'mixtral-8x7b-32768' // preview models (selection) + | 'meta-llama/llama-4-scout-17b-16e-instruct' | 'qwen-qwq-32b' | 'mistral-saba-24b' | 'qwen-2.5-32b' From 64f37ac055b5786b9706712ff4eb5bfeba3fc529 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 14:28:00 -0700 Subject: [PATCH 023/191] Version Packages (#5564) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/tall-rice-flash.md | 5 --- .changeset/thin-numbers-shave.md | 5 --- examples/ai-core/package.json | 6 +-- examples/express/package.json | 2 +- examples/fastify/package.json | 2 +- examples/hono/package.json | 2 +- examples/mcp/package.json | 2 +- examples/nest/package.json | 2 +- examples/next-fastapi/package.json | 2 +- examples/next-google-vertex/package.json | 2 +- examples/next-langchain/package.json | 2 +- .../package.json | 2 +- examples/next-openai-pages/package.json | 2 +- .../next-openai-telemetry-sentry/package.json | 2 +- examples/next-openai-telemetry/package.json | 2 +- .../package.json | 2 +- examples/next-openai/package.json | 2 +- examples/node-http-server/package.json | 2 +- examples/nuxt-openai/package.json | 2 +- examples/solidstart-openai/package.json | 2 +- examples/sveltekit-openai/package.json | 2 +- packages/ai/CHANGELOG.md | 6 +++ packages/ai/package.json | 2 +- .../ai/tests/e2e/next-server/CHANGELOG.md | 7 +++ packages/groq/CHANGELOG.md | 6 +++ packages/groq/package.json | 2 +- packages/valibot/CHANGELOG.md | 7 +++ packages/valibot/package.json | 4 +- pnpm-lock.yaml | 44 +++++++++---------- 29 files changed, 73 insertions(+), 57 deletions(-) delete mode 100644 .changeset/tall-rice-flash.md delete mode 100644 .changeset/thin-numbers-shave.md diff --git a/.changeset/tall-rice-flash.md b/.changeset/tall-rice-flash.md deleted file mode 100644 index 20c49b454ede..000000000000 --- a/.changeset/tall-rice-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/groq': patch ---- - -feat (provider/groq): add llama 4 model diff --git a/.changeset/thin-numbers-shave.md b/.changeset/thin-numbers-shave.md deleted file mode 100644 index e57732de3101..000000000000 --- a/.changeset/thin-numbers-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix (core): improve error handling in streamText's consumeStream method diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index e9842a243adf..12e90aa32f51 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -14,7 +14,7 @@ "@ai-sdk/fireworks": "0.2.6", "@ai-sdk/google": "1.2.7", "@ai-sdk/google-vertex": "2.2.10", - "@ai-sdk/groq": "1.2.4", + "@ai-sdk/groq": "1.2.5", "@ai-sdk/luma": "0.1.4", "@ai-sdk/mistral": "1.2.4", "@ai-sdk/openai": "1.3.7", @@ -24,12 +24,12 @@ "@ai-sdk/replicate": "0.2.4", "@ai-sdk/togetherai": "0.2.6", "@ai-sdk/xai": "1.2.7", - "@ai-sdk/valibot": "0.1.13", + "@ai-sdk/valibot": "0.1.14", "@google/generative-ai": "0.21.0", "@opentelemetry/auto-instrumentations-node": "0.54.0", "@opentelemetry/sdk-node": "0.54.2", "@opentelemetry/sdk-trace-node": "1.28.0", - "ai": "4.3.1", + "ai": "4.3.2", "dotenv": "16.4.5", "image-type": "^5.2.0", "mathjs": "14.0.0", diff --git a/examples/express/package.json b/examples/express/package.json index 66ab14341203..c427cfb9fa8b 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@ai-sdk/openai": "1.3.7", - "ai": "4.3.1", + "ai": "4.3.2", "dotenv": "16.4.5", "express": "5.0.1" }, diff --git a/examples/fastify/package.json b/examples/fastify/package.json index 08f5ab7821ca..26ffb3a76101 100644 --- a/examples/fastify/package.json +++ b/examples/fastify/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/openai": "1.3.7", - "ai": "4.3.1", + "ai": "4.3.2", "dotenv": "16.4.5", "fastify": "5.1.0" }, diff --git a/examples/hono/package.json b/examples/hono/package.json index 7b40f3b42d9d..1566490ef551 100644 --- a/examples/hono/package.json +++ b/examples/hono/package.json @@ -5,7 +5,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.7", "@hono/node-server": "1.13.7", - "ai": "4.3.1", + "ai": "4.3.2", "dotenv": "16.4.5", "hono": "4.6.9" }, diff --git a/examples/mcp/package.json b/examples/mcp/package.json index 20666c9288d8..141d22fb54f6 100644 --- a/examples/mcp/package.json +++ b/examples/mcp/package.json @@ -14,7 +14,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.7", "@modelcontextprotocol/sdk": "^1.7.0", - "ai": "4.3.1", + "ai": "4.3.2", "dotenv": "16.4.5", "express": "5.0.1", "zod": "3.23.8" diff --git a/examples/nest/package.json b/examples/nest/package.json index 095336a2cda2..8effe9dc76df 100644 --- a/examples/nest/package.json +++ b/examples/nest/package.json @@ -19,7 +19,7 @@ "@nestjs/common": "^10.4.15", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.4.9", - "ai": "4.3.1", + "ai": "4.3.2", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/examples/next-fastapi/package.json b/examples/next-fastapi/package.json index 1644281c2329..ab8324aebfe4 100644 --- a/examples/next-fastapi/package.json +++ b/examples/next-fastapi/package.json @@ -13,7 +13,7 @@ "dependencies": { "@ai-sdk/ui-utils": "1.2.5", "@ai-sdk/react": "1.2.6", - "ai": "4.3.1", + "ai": "4.3.2", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index f18c524c930d..4d0c0c7e22e7 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@ai-sdk/google-vertex": "2.2.10", - "ai": "4.3.1", + "ai": "4.3.2", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-langchain/package.json b/examples/next-langchain/package.json index 90234e863fd3..2bda536aa802 100644 --- a/examples/next-langchain/package.json +++ b/examples/next-langchain/package.json @@ -12,7 +12,7 @@ "@ai-sdk/react": "1.2.6", "@langchain/openai": "0.0.28", "@langchain/core": "0.1.63", - "ai": "4.3.1", + "ai": "4.3.2", "langchain": "0.1.36", "next": "latest", "react": "^18", diff --git a/examples/next-openai-kasada-bot-protection/package.json b/examples/next-openai-kasada-bot-protection/package.json index 236b3269ab96..1181ab92df89 100644 --- a/examples/next-openai-kasada-bot-protection/package.json +++ b/examples/next-openai-kasada-bot-protection/package.json @@ -12,7 +12,7 @@ "@ai-sdk/openai": "1.3.7", "@ai-sdk/react": "1.2.6", "@vercel/functions": "latest", - "ai": "4.3.1", + "ai": "4.3.2", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai-pages/package.json b/examples/next-openai-pages/package.json index 8b25256af033..d17fb4e370c0 100644 --- a/examples/next-openai-pages/package.json +++ b/examples/next-openai-pages/package.json @@ -11,7 +11,7 @@ "dependencies": { "@ai-sdk/openai": "1.3.7", "@ai-sdk/react": "1.2.6", - "ai": "4.3.1", + "ai": "4.3.2", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry-sentry/package.json b/examples/next-openai-telemetry-sentry/package.json index 80c10e3ed4ab..5fc0f2fa5335 100644 --- a/examples/next-openai-telemetry-sentry/package.json +++ b/examples/next-openai-telemetry-sentry/package.json @@ -17,7 +17,7 @@ "@sentry/nextjs": "^8.42.0", "@sentry/opentelemetry": "8.22.0", "@vercel/otel": "1.10.0", - "ai": "4.3.1", + "ai": "4.3.2", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry/package.json b/examples/next-openai-telemetry/package.json index 021451dac2da..bab1a1fb5a68 100644 --- a/examples/next-openai-telemetry/package.json +++ b/examples/next-openai-telemetry/package.json @@ -15,7 +15,7 @@ "@opentelemetry/sdk-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@vercel/otel": "1.10.0", - "ai": "4.3.1", + "ai": "4.3.2", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-upstash-rate-limits/package.json b/examples/next-openai-upstash-rate-limits/package.json index d9c32d60f29d..c234fa23da80 100644 --- a/examples/next-openai-upstash-rate-limits/package.json +++ b/examples/next-openai-upstash-rate-limits/package.json @@ -13,7 +13,7 @@ "@ai-sdk/react": "1.2.6", "@upstash/ratelimit": "^0.4.3", "@vercel/kv": "^0.2.2", - "ai": "4.3.1", + "ai": "4.3.2", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 5fba5201a376..ccf022ce7efd 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -19,7 +19,7 @@ "@ai-sdk/ui-utils": "1.2.5", "@ai-sdk/react": "1.2.6", "@vercel/blob": "^0.26.0", - "ai": "4.3.1", + "ai": "4.3.2", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/node-http-server/package.json b/examples/node-http-server/package.json index 68f707606d7b..77fd231461fb 100644 --- a/examples/node-http-server/package.json +++ b/examples/node-http-server/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/openai": "1.3.7", - "ai": "4.3.1", + "ai": "4.3.2", "dotenv": "16.4.5", "zod": "3.23.8", "zod-to-json-schema": "3.23.5" diff --git a/examples/nuxt-openai/package.json b/examples/nuxt-openai/package.json index 582e7732239e..2d544dc7091c 100644 --- a/examples/nuxt-openai/package.json +++ b/examples/nuxt-openai/package.json @@ -11,7 +11,7 @@ "dependencies": { "@ai-sdk/vue": "1.2.5", "@ai-sdk/openai": "1.3.7", - "ai": "4.3.1", + "ai": "4.3.2", "zod": "3.23.8" }, "devDependencies": { diff --git a/examples/solidstart-openai/package.json b/examples/solidstart-openai/package.json index 7f5c4350b409..8506c420a6b6 100644 --- a/examples/solidstart-openai/package.json +++ b/examples/solidstart-openai/package.json @@ -20,7 +20,7 @@ "@solidjs/meta": "0.29.4", "@solidjs/router": "^0.15.1", "@solidjs/start": "^1.0.10", - "ai": "4.3.1", + "ai": "4.3.2", "solid-js": "^1.9.3", "zod": "^3.23.8" }, diff --git a/examples/sveltekit-openai/package.json b/examples/sveltekit-openai/package.json index 48e4d2b28be1..3ca39062ea28 100644 --- a/examples/sveltekit-openai/package.json +++ b/examples/sveltekit-openai/package.json @@ -25,7 +25,7 @@ "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", - "ai": "4.3.1", + "ai": "4.3.2", "autoprefixer": "^10.4.20", "bits-ui": "^1.3.9", "clsx": "^2.1.1", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index c812567a785d..804a06bef4dc 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 4.3.2 + +### Patch Changes + +- 665a567: fix (core): improve error handling in streamText's consumeStream method + ## 4.3.1 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 7fa79f215c96..127efd261485 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "4.3.1", + "version": "4.3.2", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/ai/tests/e2e/next-server/CHANGELOG.md b/packages/ai/tests/e2e/next-server/CHANGELOG.md index 01f6f02dc933..5db88ca560ee 100644 --- a/packages/ai/tests/e2e/next-server/CHANGELOG.md +++ b/packages/ai/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [665a567] + - ai@4.3.2 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [3d1bd38] - ai@4.3.1 diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index 67a6c973c2c6..dfebef8742ed 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/groq +## 1.2.5 + +### Patch Changes + +- 8fdc8fe: feat (provider/groq): add llama 4 model + ## 1.2.4 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index 3d8031d1d26a..af39aaa1e140 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "1.2.4", + "version": "1.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 802d35cadeb7..6d73cd8d83bf 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 0.1.14 + +### Patch Changes + +- Updated dependencies [665a567] + - ai@4.3.2 + ## 0.1.13 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index c01bc3c4abb1..5cfbdd5fb478 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "0.1.13", + "version": "0.1.14", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -27,7 +27,7 @@ } }, "dependencies": { - "ai": "4.3.1" + "ai": "4.3.2" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fe6e0cf1ddf..96f61f4b2a17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,7 +93,7 @@ importers: specifier: 2.2.10 version: link:../../packages/google-vertex '@ai-sdk/groq': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/groq '@ai-sdk/luma': specifier: 0.1.4 @@ -120,7 +120,7 @@ importers: specifier: 0.2.6 version: link:../../packages/togetherai '@ai-sdk/valibot': - specifier: 0.1.13 + specifier: 0.1.14 version: link:../../packages/valibot '@ai-sdk/xai': specifier: 1.2.7 @@ -138,7 +138,7 @@ importers: specifier: 1.28.0 version: 1.28.0(@opentelemetry/api@1.9.0) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -181,7 +181,7 @@ importers: specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -209,7 +209,7 @@ importers: specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -237,7 +237,7 @@ importers: specifier: 1.13.7 version: 1.13.7(hono@4.6.9) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -265,7 +265,7 @@ importers: specifier: ^1.7.0 version: 1.7.0 ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -305,7 +305,7 @@ importers: specifier: ^10.4.9 version: 10.4.9(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai reflect-metadata: specifier: ^0.2.0 @@ -387,7 +387,7 @@ importers: specifier: 1.2.5 version: link:../../packages/ui-utils ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -439,7 +439,7 @@ importers: specifier: 2.2.10 version: link:../../packages/google-vertex ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -488,7 +488,7 @@ importers: specifier: 0.0.28 version: 0.0.28 ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai langchain: specifier: 0.1.36 @@ -564,7 +564,7 @@ importers: specifier: ^0.26.0 version: 0.26.0 ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai next: specifier: latest @@ -625,7 +625,7 @@ importers: specifier: latest version: 2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai next: specifier: latest @@ -677,7 +677,7 @@ importers: specifier: 1.2.6 version: link:../../packages/react ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai next: specifier: latest @@ -744,7 +744,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.29.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai next: specifier: latest @@ -817,7 +817,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai next: specifier: latest @@ -878,7 +878,7 @@ importers: specifier: ^0.2.2 version: 0.2.4 ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai next: specifier: latest @@ -927,7 +927,7 @@ importers: specifier: 1.3.7 version: link:../../packages/openai ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -958,7 +958,7 @@ importers: specifier: 1.2.5 version: link:../../packages/vue ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai zod: specifier: 3.23.8 @@ -1025,7 +1025,7 @@ importers: specifier: ^1.0.10 version: 1.0.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vinxi@0.4.3(@types/node@22.7.4)(@upstash/redis@1.34.3)(ioredis@5.4.1)(terser@5.31.3)(typescript@5.6.3))(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai solid-js: specifier: ^1.9.3 @@ -1077,7 +1077,7 @@ importers: specifier: ^5.0.0 version: 5.0.3(svelte@5.22.4)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../../packages/ai autoprefixer: specifier: ^10.4.20 @@ -2052,7 +2052,7 @@ importers: specifier: ^1.0.0-rc.0 || ^1.0.0 version: 1.0.0-rc.0(valibot@1.0.0-rc.0(typescript@5.6.3)) ai: - specifier: 4.3.1 + specifier: 4.3.2 version: link:../ai devDependencies: '@types/node': From 1e8e66d29788b2d3720b02a48d4a78743f96cb43 Mon Sep 17 00:00:00 2001 From: Kevin Ang <51168758+kvnang@users.noreply.github.com> Date: Sun, 6 Apr 2025 04:08:48 -0400 Subject: [PATCH 024/191] fix (provider/google): allow "OFF" for Google HarmBlockThreshold (#5550) --- .changeset/huge-cloths-burn.md | 5 +++++ packages/google/src/google-generative-ai-settings.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/huge-cloths-burn.md diff --git a/.changeset/huge-cloths-burn.md b/.changeset/huge-cloths-burn.md new file mode 100644 index 000000000000..bdb13e564d46 --- /dev/null +++ b/.changeset/huge-cloths-burn.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/google': patch +--- + +fix (provider/google): allow "OFF" for Google HarmBlockThreshold diff --git a/packages/google/src/google-generative-ai-settings.ts b/packages/google/src/google-generative-ai-settings.ts index 02f57d68e797..a2c8f32f6982 100644 --- a/packages/google/src/google-generative-ai-settings.ts +++ b/packages/google/src/google-generative-ai-settings.ts @@ -72,7 +72,8 @@ Optional. A list of unique safety settings for blocking unsafe content. | 'BLOCK_LOW_AND_ABOVE' | 'BLOCK_MEDIUM_AND_ABOVE' | 'BLOCK_ONLY_HIGH' - | 'BLOCK_NONE'; + | 'BLOCK_NONE' + | 'OFF'; }>; /** * Optional. Enables timestamp understanding for audio-only files. From e82024e087bce8d3c9225e1bd172d9fc4dfd5c8f Mon Sep 17 00:00:00 2001 From: ANKIT VARSHNEY <132201033+AVtheking@users.noreply.github.com> Date: Sun, 6 Apr 2025 13:51:01 +0530 Subject: [PATCH 025/191] feat (provider/azure): add OpenAI responses API support (#5461) --- .changeset/angry-poems-learn.md | 5 + .../01-ai-sdk-providers/03-azure.mdx | 140 ++++++++++++++++++ .../src/generate-text/azure-responses.ts | 22 +++ .../azure/src/azure-openai-provider.test.ts | 120 +++++++++++++-- packages/azure/src/azure-openai-provider.ts | 30 +++- 5 files changed, 304 insertions(+), 13 deletions(-) create mode 100644 .changeset/angry-poems-learn.md create mode 100644 examples/ai-core/src/generate-text/azure-responses.ts diff --git a/.changeset/angry-poems-learn.md b/.changeset/angry-poems-learn.md new file mode 100644 index 000000000000..22456f013a8d --- /dev/null +++ b/.changeset/angry-poems-learn.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/azure': patch +--- + +feat (provider/azure): add OpenAI responses API support diff --git a/content/providers/01-ai-sdk-providers/03-azure.mdx b/content/providers/01-ai-sdk-providers/03-azure.mdx index cbd23429c853..46e03042a833 100644 --- a/content/providers/01-ai-sdk-providers/03-azure.mdx +++ b/content/providers/01-ai-sdk-providers/03-azure.mdx @@ -223,6 +223,146 @@ The following optional settings are available for OpenAI chat models: A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Learn more. +### Responses Models + +You can use the Azure OpenAI responses API with the `azure.responses(deploymentName)` factory method. + +```ts +const model = azure.responses('your-deployment-name'); +``` + +Further configuration can be done using OpenAI provider options. +You can validate the provider options using the `OpenAIResponsesProviderOptions` type. + +```ts +import { azure, OpenAIResponsesProviderOptions } from '@ai-sdk/azure'; +import { generateText } from 'ai'; + +const result = await generateText({ + model: azure.responses('your-deployment-name'), + providerOptions: { + openai: { + parallelToolCalls: false, + store: false, + user: 'user_123', + // ... + } satisfies OpenAIResponsesProviderOptions, + }, + // ... +}); +``` + +The following provider options are available: + +- **parallelToolCalls** _boolean_ + Whether to use parallel tool calls. Defaults to `true`. + +- **store** _boolean_ + Whether to store the generation. Defaults to `true`. + +- **metadata** _Record<string, string>_ + Additional metadata to store with the generation. + +- **previousResponseId** _string_ + The ID of the previous response. You can use it to continue a conversation. Defaults to `undefined`. + +- **instructions** _string_ + Instructions for the model. + They can be used to change the system or developer message when continuing a conversation using the `previousResponseId` option. + Defaults to `undefined`. + +- **user** _string_ + A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Defaults to `undefined`. + +- **reasoningEffort** _'low' | 'medium' | 'high'_ + Reasoning effort for reasoning models. Defaults to `medium`. If you use `providerOptions` to set the `reasoningEffort` option, this model setting will be ignored. + +- **strictSchemas** _boolean_ + Whether to use strict JSON schemas in tools and when generating JSON outputs. Defaults to `true`. + +The Azure OpenAI responses provider also returns provider-specific metadata: + +```ts +const { providerMetadata } = await generateText({ + model: azure.responses('your-deployment-name'), +}); + +const openaiMetadata = providerMetadata?.openai; +``` + +The following OpenAI-specific metadata is returned: + +- **responseId** _string_ + The ID of the response. Can be used to continue a conversation. + +- **cachedPromptTokens** _number_ + The number of prompt tokens that were a cache hit. + +- **reasoningTokens** _number_ + The number of reasoning tokens that the model generated. + +#### Web Search + +The Azure OpenAI responses provider supports web search through the `azure.tools.webSearchPreview` tool. + +You can force the use of the web search tool by setting the `toolChoice` parameter to `{ type: 'tool', toolName: 'web_search_preview' }`. + +```ts +const result = await generateText({ + model: azure.responses('your-deployment-name'), + prompt: 'What happened in San Francisco last week?', + tools: { + web_search_preview: azure.tools.webSearchPreview({ + // optional configuration: + searchContextSize: 'high', + userLocation: { + type: 'approximate', + city: 'San Francisco', + region: 'California', + }, + }), + }, + // Force web search tool: + toolChoice: { type: 'tool', toolName: 'web_search_preview' }, +}); + +// URL sources +const sources = result.sources; +``` + +#### PDF support + +The Azure OpenAI Responses API supports reading PDF files. +You can pass PDF files as part of the message content using the `file` type: + +```ts +const result = await generateText({ + model: azure.responses('your-deployment-name'), + messages: [ + { + role: 'user', + content: [ + { + type: 'text', + text: 'What is an embedding model?', + }, + { + type: 'file', + data: fs.readFileSync('./data/ai.pdf'), + mimeType: 'application/pdf', + filename: 'ai.pdf', // optional + }, + ], + }, + ], +}); +``` + +The model will have access to the contents of the PDF file and +respond to questions about it. +The PDF file should be passed using the `data` field, +and the `mimeType` should be set to `'application/pdf'`. + ### Completion Models You can create models that call the completions API using the `.completion()` factory method. diff --git a/examples/ai-core/src/generate-text/azure-responses.ts b/examples/ai-core/src/generate-text/azure-responses.ts new file mode 100644 index 000000000000..9f7a587b99ae --- /dev/null +++ b/examples/ai-core/src/generate-text/azure-responses.ts @@ -0,0 +1,22 @@ +import { createAzure } from '@ai-sdk/azure'; +import { generateText } from 'ai'; +import 'dotenv/config'; + +// Initialize Azure OpenAI provider +const azure = createAzure({ + apiKey: process.env.AZURE_API_KEY, + baseURL: process.env.AZURE_BASE_URL, +}); + +async function main() { + // Basic text generation + const basicResult = await generateText({ + model: azure.responses('gpt-4o-mini'), + prompt: 'What is quantum computing?', + }); + + console.log('\n=== Basic Text Generation ==='); + console.log(basicResult.text); +} + +main().catch(console.error); diff --git a/packages/azure/src/azure-openai-provider.test.ts b/packages/azure/src/azure-openai-provider.test.ts index 4958b07d5981..7c926e551bcc 100644 --- a/packages/azure/src/azure-openai-provider.test.ts +++ b/packages/azure/src/azure-openai-provider.test.ts @@ -29,6 +29,7 @@ const server = createTestServer({ {}, 'https://test-resource.openai.azure.com/openai/deployments/dalle-deployment/images/generations': {}, + 'https://test-resource.openai.azure.com/openai/responses': {}, }); describe('chat', () => { @@ -74,7 +75,7 @@ describe('chat', () => { expect( server.calls[0].requestUrlSearchParams.get('api-version'), - ).toStrictEqual('2024-10-01-preview'); + ).toStrictEqual('2025-03-01-preview'); }); it('should set the correct modified api version', async () => { @@ -132,9 +133,8 @@ describe('chat', () => { mode: { type: 'regular' }, prompt: TEST_PROMPT, }); - expect(server.calls[0].requestUrl).toStrictEqual( - 'https://test-resource.openai.azure.com/openai/deployments/test-deployment/chat/completions?api-version=2024-10-01-preview', + 'https://test-resource.openai.azure.com/openai/deployments/test-deployment/chat/completions?api-version=2025-03-01-preview', ); }); }); @@ -195,10 +195,9 @@ describe('completion', () => { mode: { type: 'regular' }, prompt: TEST_PROMPT, }); - expect( server.calls[0].requestUrlSearchParams.get('api-version'), - ).toStrictEqual('2024-10-01-preview'); + ).toStrictEqual('2025-03-01-preview'); }); it('should pass headers', async () => { @@ -269,10 +268,9 @@ describe('embedding', () => { await model.doEmbed({ values: testValues, }); - expect( server.calls[0].requestUrlSearchParams.get('api-version'), - ).toStrictEqual('2024-10-01-preview'); + ).toStrictEqual('2025-03-01-preview'); }); it('should pass headers', async () => { @@ -342,7 +340,7 @@ describe('image', () => { expect( server.calls[0].requestUrlSearchParams.get('api-version'), - ).toStrictEqual('2024-10-01-preview'); + ).toStrictEqual('2025-03-01-preview'); }); it('should set the correct modified api version', async () => { @@ -413,7 +411,7 @@ describe('image', () => { }); expect(server.calls[0].requestUrl).toStrictEqual( - 'https://test-resource.openai.azure.com/openai/deployments/dalle-deployment/images/generations?api-version=2024-10-01-preview', + 'https://test-resource.openai.azure.com/openai/deployments/dalle-deployment/images/generations?api-version=2025-03-01-preview', ); }); @@ -465,3 +463,107 @@ describe('image', () => { }); }); }); + +describe('responses', () => { + describe('doGenerate', () => { + function prepareJsonResponse({ + content = '', + usage = { + input_tokens: 4, + output_tokens: 30, + total_tokens: 34, + }, + } = {}) { + server.urls[ + 'https://test-resource.openai.azure.com/openai/responses' + ].response = { + type: 'json-value', + body: { + id: 'resp_67c97c0203188190a025beb4a75242bc', + object: 'response', + created_at: 1741257730, + status: 'completed', + model: 'test-deployment', + output: [ + { + id: 'msg_67c97c02656c81908e080dfdf4a03cd1', + type: 'message', + status: 'completed', + role: 'assistant', + content: [ + { + type: 'output_text', + text: content, + annotations: [], + }, + ], + }, + ], + usage, + incomplete_details: null, + }, + }; + } + + it('should set the correct api version', async () => { + prepareJsonResponse(); + + await provider.responses('test-deployment').doGenerate({ + inputFormat: 'prompt', + mode: { type: 'regular' }, + prompt: TEST_PROMPT, + }); + + expect( + server.calls[0].requestUrlSearchParams.get('api-version'), + ).toStrictEqual('2025-03-01-preview'); + }); + + it('should pass headers', async () => { + prepareJsonResponse(); + + const provider = createAzure({ + resourceName: 'test-resource', + apiKey: 'test-api-key', + headers: { + 'Custom-Provider-Header': 'provider-header-value', + }, + }); + + await provider.responses('test-deployment').doGenerate({ + inputFormat: 'prompt', + mode: { type: 'regular' }, + prompt: TEST_PROMPT, + headers: { + 'Custom-Request-Header': 'request-header-value', + }, + }); + + expect(server.calls[0].requestHeaders).toStrictEqual({ + 'api-key': 'test-api-key', + 'content-type': 'application/json', + 'custom-provider-header': 'provider-header-value', + 'custom-request-header': 'request-header-value', + }); + }); + + it('should use the baseURL correctly', async () => { + prepareJsonResponse(); + + const provider = createAzure({ + baseURL: 'https://test-resource.openai.azure.com/openai', + apiKey: 'test-api-key', + }); + + await provider.responses('test-deployment').doGenerate({ + inputFormat: 'prompt', + mode: { type: 'regular' }, + prompt: TEST_PROMPT, + }); + + expect(server.calls[0].requestUrl).toStrictEqual( + 'https://test-resource.openai.azure.com/openai/responses?api-version=2025-03-01-preview', + ); + }); + }); +}); diff --git a/packages/azure/src/azure-openai-provider.ts b/packages/azure/src/azure-openai-provider.ts index 8d51750f0727..c4f2416e8625 100644 --- a/packages/azure/src/azure-openai-provider.ts +++ b/packages/azure/src/azure-openai-provider.ts @@ -7,6 +7,7 @@ import { OpenAIEmbeddingSettings, OpenAIImageModel, OpenAIImageSettings, + OpenAIResponsesLanguageModel, } from '@ai-sdk/openai/internal'; import { EmbeddingModelV1, @@ -32,6 +33,11 @@ Creates an Azure OpenAI chat model for text generation. */ chat(deploymentId: string, settings?: OpenAIChatSettings): LanguageModelV1; + /** +Creates an Azure OpenAI responses API model for text generation. + */ + responses(deploymentId: string): LanguageModelV1; + /** Creates an Azure OpenAI completion model for text generation. */ @@ -140,11 +146,19 @@ export function createAzure( description: 'Azure OpenAI resource name', }); - const apiVersion = options.apiVersion ?? '2024-10-01-preview'; - const url = ({ path, modelId }: { path: string; modelId: string }) => - options.baseURL + const apiVersion = options.apiVersion ?? '2025-03-01-preview'; + const url = ({ path, modelId }: { path: string; modelId: string }) => { + if (path === '/responses') { + return options.baseURL + ? `${options.baseURL}${path}?api-version=${apiVersion}` + : `https://${getResourceName()}.openai.azure.com/openai/responses?api-version=${apiVersion}`; + } + + // Default URL format for other endpoints + return options.baseURL ? `${options.baseURL}/${modelId}${path}?api-version=${apiVersion}` : `https://${getResourceName()}.openai.azure.com/openai/deployments/${modelId}${path}?api-version=${apiVersion}`; + }; const createChatModel = ( deploymentName: string, @@ -181,6 +195,14 @@ export function createAzure( fetch: options.fetch, }); + const createResponsesModel = (modelId: string) => + new OpenAIResponsesLanguageModel(modelId, { + provider: 'azure-openai.responses', + url, + headers: getHeaders, + fetch: options.fetch, + }); + const createImageModel = ( modelId: string, settings: OpenAIImageSettings = {}, @@ -213,7 +235,7 @@ export function createAzure( provider.imageModel = createImageModel; provider.textEmbedding = createEmbeddingModel; provider.textEmbeddingModel = createEmbeddingModel; - + provider.responses = createResponsesModel; return provider; } From 4b97ea9d9caca598e772fa021480e7bb8a10077a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 6 Apr 2025 10:22:37 +0200 Subject: [PATCH 026/191] Version Packages (#5570) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/angry-poems-learn.md | 5 ----- .changeset/huge-cloths-burn.md | 5 ----- examples/ai-core/package.json | 6 +++--- examples/next-google-vertex/package.json | 2 +- examples/next-openai/package.json | 4 ++-- packages/azure/CHANGELOG.md | 6 ++++++ packages/azure/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 7 +++++++ packages/google-vertex/package.json | 4 ++-- packages/google/CHANGELOG.md | 6 ++++++ packages/google/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 12 files changed, 36 insertions(+), 27 deletions(-) delete mode 100644 .changeset/angry-poems-learn.md delete mode 100644 .changeset/huge-cloths-burn.md diff --git a/.changeset/angry-poems-learn.md b/.changeset/angry-poems-learn.md deleted file mode 100644 index 22456f013a8d..000000000000 --- a/.changeset/angry-poems-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/azure': patch ---- - -feat (provider/azure): add OpenAI responses API support diff --git a/.changeset/huge-cloths-burn.md b/.changeset/huge-cloths-burn.md deleted file mode 100644 index bdb13e564d46..000000000000 --- a/.changeset/huge-cloths-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/google': patch ---- - -fix (provider/google): allow "OFF" for Google HarmBlockThreshold diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 12e90aa32f51..45c17418bdb9 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -5,15 +5,15 @@ "dependencies": { "@ai-sdk/amazon-bedrock": "2.2.5", "@ai-sdk/anthropic": "1.2.6", - "@ai-sdk/azure": "1.3.7", + "@ai-sdk/azure": "1.3.8", "@ai-sdk/cerebras": "0.2.6", "@ai-sdk/cohere": "1.2.5", "@ai-sdk/deepinfra": "0.2.6", "@ai-sdk/deepseek": "0.2.6", "@ai-sdk/fal": "0.1.5", "@ai-sdk/fireworks": "0.2.6", - "@ai-sdk/google": "1.2.7", - "@ai-sdk/google-vertex": "2.2.10", + "@ai-sdk/google": "1.2.8", + "@ai-sdk/google-vertex": "2.2.11", "@ai-sdk/groq": "1.2.5", "@ai-sdk/luma": "0.1.4", "@ai-sdk/mistral": "1.2.4", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index 4d0c0c7e22e7..ef7eed9bcf35 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.10", + "@ai-sdk/google-vertex": "2.2.11", "ai": "4.3.2", "geist": "^1.3.1", "next": "latest", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index ccf022ce7efd..50d0a844ebb7 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -13,8 +13,8 @@ "@ai-sdk/deepseek": "0.2.6", "@ai-sdk/fireworks": "0.2.6", "@ai-sdk/openai": "1.3.7", - "@ai-sdk/google": "1.2.7", - "@ai-sdk/google-vertex": "2.2.10", + "@ai-sdk/google": "1.2.8", + "@ai-sdk/google-vertex": "2.2.11", "@ai-sdk/perplexity": "1.1.4", "@ai-sdk/ui-utils": "1.2.5", "@ai-sdk/react": "1.2.6", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index fce12af5bda0..4f3b3a25637b 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/azure +## 1.3.8 + +### Patch Changes + +- e82024e: feat (provider/azure): add OpenAI responses API support + ## 1.3.7 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 535504680a12..4b9a93edac5d 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "1.3.7", + "version": "1.3.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index f8bd47ac0cfa..29099e94d540 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/google-vertex +## 2.2.11 + +### Patch Changes + +- Updated dependencies [1e8e66d] + - @ai-sdk/google@1.2.8 + ## 2.2.10 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index c8d000b2d507..527178a401ce 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.10", + "version": "2.2.11", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -50,7 +50,7 @@ }, "dependencies": { "@ai-sdk/anthropic": "1.2.6", - "@ai-sdk/google": "1.2.7", + "@ai-sdk/google": "1.2.8", "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.4", "google-auth-library": "^9.15.0" diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 6d37286d43da..191585ab92ad 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/google +## 1.2.8 + +### Patch Changes + +- 1e8e66d: fix (provider/google): allow "OFF" for Google HarmBlockThreshold + ## 1.2.7 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index aa4be34120bf..d4ee7ce4f4bd 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "1.2.7", + "version": "1.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96f61f4b2a17..8a35ce888bc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,7 +66,7 @@ importers: specifier: 1.2.6 version: link:../../packages/anthropic '@ai-sdk/azure': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/azure '@ai-sdk/cerebras': specifier: 0.2.6 @@ -87,10 +87,10 @@ importers: specifier: 0.2.6 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.10 + specifier: 2.2.11 version: link:../../packages/google-vertex '@ai-sdk/groq': specifier: 1.2.5 @@ -436,7 +436,7 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.10 + specifier: 2.2.11 version: link:../../packages/google-vertex ai: specifier: 4.3.2 @@ -543,10 +543,10 @@ importers: specifier: 0.2.6 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.10 + specifier: 2.2.11 version: link:../../packages/google-vertex '@ai-sdk/openai': specifier: 1.3.7 @@ -1539,7 +1539,7 @@ importers: specifier: 1.2.6 version: link:../anthropic '@ai-sdk/google': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../google '@ai-sdk/provider': specifier: 1.1.0 From 264b1e04d20f6867c9c86e9f4c014d0bf636a961 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Sun, 6 Apr 2025 10:19:06 -0700 Subject: [PATCH 027/191] feat (providers/deepinfra): add llama 4 models (#5572) --- .changeset/beige-penguins-greet.md | 5 + .../01-ai-sdk-providers/11-deepinfra.mdx | 50 +++++----- .../providers/01-ai-sdk-providers/index.mdx | 92 ++++++++++--------- examples/ai-core/src/e2e/deepinfra.test.ts | 2 + .../deepinfra/src/deepinfra-chat-settings.ts | 2 + 5 files changed, 82 insertions(+), 69 deletions(-) create mode 100644 .changeset/beige-penguins-greet.md diff --git a/.changeset/beige-penguins-greet.md b/.changeset/beige-penguins-greet.md new file mode 100644 index 000000000000..22e6868c97d1 --- /dev/null +++ b/.changeset/beige-penguins-greet.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/deepinfra': patch +--- + +feat (providers/deepinfra): add llama 4 models diff --git a/content/providers/01-ai-sdk-providers/11-deepinfra.mdx b/content/providers/01-ai-sdk-providers/11-deepinfra.mdx index b451445fd84c..23296f0e2b2e 100644 --- a/content/providers/01-ai-sdk-providers/11-deepinfra.mdx +++ b/content/providers/01-ai-sdk-providers/11-deepinfra.mdx @@ -82,30 +82,32 @@ DeepInfra language models can also be used in the `streamText` function (see [AI ## Model Capabilities -| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | -| ---------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `meta-llama/Llama-3.3-70B-Instruct-Turbo` | | | | | -| `meta-llama/Llama-3.3-70B-Instruct` | | | | | -| `meta-llama/Meta-Llama-3.1-405B-Instruct` | | | | | -| `meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo` | | | | | -| `meta-llama/Meta-Llama-3.1-70B-Instruct` | | | | | -| `meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo` | | | | | -| `meta-llama/Meta-Llama-3.1-8B-Instruct` | | | | | -| `meta-llama/Llama-3.2-11B-Vision-Instruct` | | | | | -| `meta-llama/Llama-3.2-90B-Vision-Instruct` | | | | | -| `mistralai/Mixtral-8x7B-Instruct-v0.1` | | | | | -| `deepseek-ai/DeepSeek-V3` | | | | | -| `deepseek-ai/DeepSeek-R1` | | | | | -| `deepseek-ai/DeepSeek-R1-Distill-Llama-70B` | | | | | -| `deepseek-ai/DeepSeek-R1-Turbo` | | | | | -| `nvidia/Llama-3.1-Nemotron-70B-Instruct` | | | | | -| `Qwen/Qwen2-7B-Instruct` | | | | | -| `Qwen/Qwen2.5-72B-Instruct` | | | | | -| `Qwen/Qwen2.5-Coder-32B-Instruct` | | | | | -| `Qwen/QwQ-32B-Preview` | | | | | -| `google/codegemma-7b-it` | | | | | -| `google/gemma-2-9b-it` | | | | | -| `microsoft/WizardLM-2-8x22B` | | | | | +| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | +| --------------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8` | | | | | +| `meta-llama/Llama-4-Scout-17B-16E-Instruct` | | | | | +| `meta-llama/Llama-3.3-70B-Instruct-Turbo` | | | | | +| `meta-llama/Llama-3.3-70B-Instruct` | | | | | +| `meta-llama/Meta-Llama-3.1-405B-Instruct` | | | | | +| `meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo` | | | | | +| `meta-llama/Meta-Llama-3.1-70B-Instruct` | | | | | +| `meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo` | | | | | +| `meta-llama/Meta-Llama-3.1-8B-Instruct` | | | | | +| `meta-llama/Llama-3.2-11B-Vision-Instruct` | | | | | +| `meta-llama/Llama-3.2-90B-Vision-Instruct` | | | | | +| `mistralai/Mixtral-8x7B-Instruct-v0.1` | | | | | +| `deepseek-ai/DeepSeek-V3` | | | | | +| `deepseek-ai/DeepSeek-R1` | | | | | +| `deepseek-ai/DeepSeek-R1-Distill-Llama-70B` | | | | | +| `deepseek-ai/DeepSeek-R1-Turbo` | | | | | +| `nvidia/Llama-3.1-Nemotron-70B-Instruct` | | | | | +| `Qwen/Qwen2-7B-Instruct` | | | | | +| `Qwen/Qwen2.5-72B-Instruct` | | | | | +| `Qwen/Qwen2.5-Coder-32B-Instruct` | | | | | +| `Qwen/QwQ-32B-Preview` | | | | | +| `google/codegemma-7b-it` | | | | | +| `google/gemma-2-9b-it` | | | | | +| `microsoft/WizardLM-2-8x22B` | | | | | The table above lists popular models. Please see the [DeepInfra diff --git a/content/providers/01-ai-sdk-providers/index.mdx b/content/providers/01-ai-sdk-providers/index.mdx index 503a3119e3de..dd0b183414b0 100644 --- a/content/providers/01-ai-sdk-providers/index.mdx +++ b/content/providers/01-ai-sdk-providers/index.mdx @@ -17,51 +17,53 @@ There are also [community providers](./community-providers) that have been creat Not all providers support all AI SDK features. Here's a quick comparison of the capabilities of popular models: -| Provider | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | -| ------------------------------------------------------------------------ | --------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-1212` | | | | | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-vision-1212` | | | | | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-beta` | | | | | -| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-vision-beta` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o-mini` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4-turbo` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o1` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-mini` | | | | | -| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-preview` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-7-sonnet-20250219` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20241022` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20240620` | | | | | -| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-haiku-20241022` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `meta-llama/llama-4-scout-17b-16e-instruct` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `deepseek-r1-distill-llama-70b` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.3-70b-versatile` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.1-8b-instant` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `mistral-saba-24b` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `qwen-qwq-32b` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `mixtral-8x7b-32768` | | | | | -| [Groq](/providers/ai-sdk-providers/groq) | `gemma2-9b-it` | | | | | -| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo` | | | | | -| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `meta-llama/Llama-3.3-70B-Instruct` | | | | | -| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-V3` | | | | | -| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-R1` | | | | | -| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-R1-Distill-Llama-70B` | | | | | -| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-R1-Turbo` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-large-latest` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-large-latest` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-small-latest` | | | | | -| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-12b-2409` | | | | | -| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-2.0-flash-exp` | | | | | -| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-flash` | | | | | -| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-pro` | | | | | -| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-2.0-flash-exp` | | | | | -| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-flash` | | | | | -| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-pro` | | | | | -| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-chat` | | | | | -| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-reasoner` | | | | | -| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-8b` | | | | | -| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.3-70b` | | | | | +| Provider | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | +| ------------------------------------------------------------------------ | --------------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-1212` | | | | | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-2-vision-1212` | | | | | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-beta` | | | | | +| [xAI Grok](/providers/ai-sdk-providers/xai) | `grok-vision-beta` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4o-mini` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4-turbo` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-4` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o1` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-mini` | | | | | +| [OpenAI](/providers/ai-sdk-providers/openai) | `o1-preview` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-7-sonnet-20250219` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20241022` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-sonnet-20240620` | | | | | +| [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-3-5-haiku-20241022` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `meta-llama/llama-4-scout-17b-16e-instruct` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `deepseek-r1-distill-llama-70b` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.3-70b-versatile` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `llama-3.1-8b-instant` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `mistral-saba-24b` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `qwen-qwq-32b` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `mixtral-8x7b-32768` | | | | | +| [Groq](/providers/ai-sdk-providers/groq) | `gemma2-9b-it` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `meta-llama/Llama-4-Scout-17B-16E-Instruct` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `meta-llama/Llama-3.3-70B-Instruct` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-V3` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-R1` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-R1-Distill-Llama-70B` | | | | | +| [DeepInfra](/providers/ai-sdk-providers/deepinfra) | `deepseek-ai/DeepSeek-R1-Turbo` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-large-latest` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-large-latest` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `mistral-small-latest` | | | | | +| [Mistral](/providers/ai-sdk-providers/mistral) | `pixtral-12b-2409` | | | | | +| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-2.0-flash-exp` | | | | | +| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-flash` | | | | | +| [Google Generative AI](/providers/ai-sdk-providers/google-generative-ai) | `gemini-1.5-pro` | | | | | +| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-2.0-flash-exp` | | | | | +| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-flash` | | | | | +| [Google Vertex](/providers/ai-sdk-providers/google-vertex) | `gemini-1.5-pro` | | | | | +| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-chat` | | | | | +| [DeepSeek](/providers/ai-sdk-providers/deepseek) | `deepseek-reasoner` | | | | | +| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-8b` | | | | | +| [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.3-70b` | | | | | This table is not exhaustive. Additional models can be found in the provider diff --git a/examples/ai-core/src/e2e/deepinfra.test.ts b/examples/ai-core/src/e2e/deepinfra.test.ts index fc549841dcc3..bc1943a7d61e 100644 --- a/examples/ai-core/src/e2e/deepinfra.test.ts +++ b/examples/ai-core/src/e2e/deepinfra.test.ts @@ -13,6 +13,8 @@ createFeatureTestSuite({ name: 'DeepInfra', models: { languageModels: [ + createChatModel('meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8'), + createChatModel('meta-llama/Llama-4-Scout-17B-16E-Instruct'), createChatModel('deepseek-ai/DeepSeek-V3'), createChatModel('deepseek-ai/DeepSeek-R1'), createChatModel('deepseek-ai/DeepSeek-R1-Distill-Llama-70B'), diff --git a/packages/deepinfra/src/deepinfra-chat-settings.ts b/packages/deepinfra/src/deepinfra-chat-settings.ts index 8694d195e1e3..6c45c9f7dd0d 100644 --- a/packages/deepinfra/src/deepinfra-chat-settings.ts +++ b/packages/deepinfra/src/deepinfra-chat-settings.ts @@ -2,6 +2,8 @@ import { OpenAICompatibleChatSettings } from '@ai-sdk/openai-compatible'; // https://deepinfra.com/models/text-generation export type DeepInfraChatModelId = + | 'meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8' + | 'meta-llama/Llama-4-Scout-17B-16E-Instruct' | 'meta-llama/Llama-3.3-70B-Instruct' | 'meta-llama/Llama-3.3-70B-Instruct-Turbo' | 'meta-llama/Meta-Llama-3.1-70B-Instruct' From e5f6a50d0e166b6937989ee3d76be2df1093a438 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 6 Apr 2025 10:24:11 -0700 Subject: [PATCH 028/191] Version Packages (#5573) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/beige-penguins-greet.md | 5 ----- examples/ai-core/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 6 ++++++ packages/deepinfra/package.json | 2 +- pnpm-lock.yaml | 16 ++++++++-------- 5 files changed, 16 insertions(+), 15 deletions(-) delete mode 100644 .changeset/beige-penguins-greet.md diff --git a/.changeset/beige-penguins-greet.md b/.changeset/beige-penguins-greet.md deleted file mode 100644 index 22e6868c97d1..000000000000 --- a/.changeset/beige-penguins-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/deepinfra': patch ---- - -feat (providers/deepinfra): add llama 4 models diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 45c17418bdb9..43af23a0e595 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -8,7 +8,7 @@ "@ai-sdk/azure": "1.3.8", "@ai-sdk/cerebras": "0.2.6", "@ai-sdk/cohere": "1.2.5", - "@ai-sdk/deepinfra": "0.2.6", + "@ai-sdk/deepinfra": "0.2.7", "@ai-sdk/deepseek": "0.2.6", "@ai-sdk/fal": "0.1.5", "@ai-sdk/fireworks": "0.2.6", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index d1457658b7c9..d6114b21b08f 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/deepinfra +## 0.2.7 + +### Patch Changes + +- 264b1e0: feat (providers/deepinfra): add llama 4 models + ## 0.2.6 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 077c4bd75ccb..63ad97c2cf11 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a35ce888bc0..4bc32549c63e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,7 +75,7 @@ importers: specifier: 1.2.5 version: link:../../packages/cohere '@ai-sdk/deepinfra': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/deepinfra '@ai-sdk/deepseek': specifier: 0.2.6 @@ -24107,7 +24107,7 @@ snapshots: eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.1) eslint-plugin-react: 7.35.0(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -24182,8 +24182,8 @@ snapshots: debug: 4.4.0(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -24222,7 +24222,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24255,7 +24255,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24304,7 +24304,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -24314,7 +24314,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.0 is-glob: 4.0.3 From 3e88f4d21e1d4e3dd8b8b6658bc6a35e2bb0ed23 Mon Sep 17 00:00:00 2001 From: choi sung keun <86150470+cgoinglove@users.noreply.github.com> Date: Tue, 8 Apr 2025 02:04:41 +0900 Subject: [PATCH 029/191] fix (ai/mcp): prevent mutation of customEnv (#5583) --- .changeset/fix-env-mutation.md | 5 +++++ packages/ai/mcp-stdio/get-environment.test.ts | 13 +++++++++++++ packages/ai/mcp-stdio/get-environment.ts | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-env-mutation.md create mode 100644 packages/ai/mcp-stdio/get-environment.test.ts diff --git a/.changeset/fix-env-mutation.md b/.changeset/fix-env-mutation.md new file mode 100644 index 000000000000..92454ae660df --- /dev/null +++ b/.changeset/fix-env-mutation.md @@ -0,0 +1,5 @@ +--- +'@ai/core': patch +--- + +fix (ai/mcp): prevent mutation of customEnv diff --git a/packages/ai/mcp-stdio/get-environment.test.ts b/packages/ai/mcp-stdio/get-environment.test.ts new file mode 100644 index 000000000000..1ea0bb900766 --- /dev/null +++ b/packages/ai/mcp-stdio/get-environment.test.ts @@ -0,0 +1,13 @@ +import { describe, it, expect } from 'vitest'; +import { getEnvironment } from './get-environment'; + +describe('getEnvironment', () => { + it('should not mutate the original custom environment object', () => { + const customEnv = { CUSTOM_VAR: 'custom_value' }; + + const result = getEnvironment(customEnv); + + expect(customEnv).toStrictEqual({ CUSTOM_VAR: 'custom_value' }); + expect(result).not.toBe(customEnv); + }); +}); diff --git a/packages/ai/mcp-stdio/get-environment.ts b/packages/ai/mcp-stdio/get-environment.ts index 843d7edb41e9..d22b7f854caf 100644 --- a/packages/ai/mcp-stdio/get-environment.ts +++ b/packages/ai/mcp-stdio/get-environment.ts @@ -24,7 +24,7 @@ export function getEnvironment( ] : ['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER']; - const env: Record = customEnv ?? {}; + const env: Record = customEnv ? { ...customEnv } : {}; for (const key of DEFAULT_INHERITED_ENV_VARS) { const value = globalThis.process.env[key]; From b8e7fb7e1f410a237b326d8898ea23b5d090172e Mon Sep 17 00:00:00 2001 From: Matt <77928207+mattzcarey@users.noreply.github.com> Date: Mon, 7 Apr 2025 18:55:32 +0100 Subject: [PATCH 030/191] docs: add stackone toolset (#5585) --- content/docs/02-foundations/04-tools.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/content/docs/02-foundations/04-tools.mdx b/content/docs/02-foundations/04-tools.mdx index ac8a2acf3338..e56ef4745d5a 100644 --- a/content/docs/02-foundations/04-tools.mdx +++ b/content/docs/02-foundations/04-tools.mdx @@ -94,6 +94,7 @@ There are several providers that offer pre-built tools as **toolkits** that you - **[agentic](https://github.com/transitive-bullshit/agentic)** - A collection of 20+ tools. Most tools connect to access external APIs such as [Exa](https://exa.ai/) or [E2B](https://e2b.dev/). - **[browserbase](https://docs.browserbase.com/integrations/vercel-ai/introduction)** - Browser tool that runs a headless browser - **[Stripe agent tools](https://docs.stripe.com/agents)** - Tools for interacting with Stripe. +- **[StackOne ToolSet](https://docs.stackone.com/agents)** - Agentic integrations for hundreds of [enterprise SaaS](https://www.stackone.com/integrations) - **[Toolhouse](https://docs.toolhouse.ai/toolhouse/using-vercel-ai)** - AI function-calling in 3 lines of code for over 25 different actions. - **[Agent Tools](https://ai-sdk-agents.vercel.app/?item=introduction)** - A collection of tools for agents. - **[AI Tool Maker](https://github.com/nihaocami/ai-tool-maker)** - A CLI utility to generate AI SDK tools from OpenAPI specs. From 7bff5e29dc41af2dcf76b3463463e818ce31b6ed Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Tue, 8 Apr 2025 07:33:59 +0200 Subject: [PATCH 031/191] fix: changeset --- .changeset/fix-env-mutation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fix-env-mutation.md b/.changeset/fix-env-mutation.md index 92454ae660df..86cd47b5e2d3 100644 --- a/.changeset/fix-env-mutation.md +++ b/.changeset/fix-env-mutation.md @@ -1,5 +1,5 @@ --- -'@ai/core': patch +'ai': patch --- fix (ai/mcp): prevent mutation of customEnv From ddf0454300649320fded60a3c9e03451a3ac0a04 Mon Sep 17 00:00:00 2001 From: faiz-gear <70053309+faiz-gear@users.noreply.github.com> Date: Tue, 8 Apr 2025 14:37:58 +0800 Subject: [PATCH 032/191] fix(docs): correct Completions API example by using openai() instead of openai.responses() (#5589) --- content/docs/02-guides/19-openai-responses.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/02-guides/19-openai-responses.mdx b/content/docs/02-guides/19-openai-responses.mdx index f53fdfe71e2e..928fc2ded153 100644 --- a/content/docs/02-guides/19-openai-responses.mdx +++ b/content/docs/02-guides/19-openai-responses.mdx @@ -180,7 +180,7 @@ import { openai } from '@ai-sdk/openai'; // Completions API const { text } = await generateText({ - model: openai.responses('gpt-4o', { parallelToolCalls: false }), + model: openai('gpt-4o', { parallelToolCalls: false }), prompt: 'Explain the concept of quantum entanglement.', }); From c21fa6d669dfa5bd1f338d8ed54bdd1a773064b9 Mon Sep 17 00:00:00 2001 From: Hayden Bleasel Date: Mon, 7 Apr 2025 23:51:39 -0700 Subject: [PATCH 033/191] feat: add transcription with `experimental_transcribe` (#5496) Co-authored-by: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> --- .changeset/happy-kangaroos-roll.md | 8 + .../docs/03-ai-sdk-core/36-transcription.mdx | 153 +++++++ content/docs/03-ai-sdk-core/index.mdx | 5 + .../01-ai-sdk-core/11-transcribe.mdx | 138 ++++++ .../07-reference/01-ai-sdk-core/index.mdx | 5 + .../01-ai-sdk-providers/02-openai.mdx | 64 +++ .../ai-core/src/transcribe/openai-string.ts | 23 + examples/ai-core/src/transcribe/openai-url.ts | 23 + examples/ai-core/src/transcribe/openai.ts | 21 + .../ai/core/generate-image/generate-image.ts | 11 +- packages/ai/core/index.ts | 1 + .../convert-to-language-model-prompt.ts | 11 +- .../core/test/mock-transcription-model-v1.ts | 24 ++ packages/ai/core/transcribe/index.ts | 2 + .../ai/core/transcribe/transcribe-result.ts | 60 +++ .../ai/core/transcribe/transcribe.test.ts | 229 ++++++++++ packages/ai/core/transcribe/transcribe.ts | 150 +++++++ .../transcription-model-response-metadata.ts | 16 + packages/ai/core/types/transcription-model.ts | 15 + .../core/util/detect-image-mimetype.test.ts | 138 ------ .../ai/core/util/detect-image-mimetype.ts | 68 --- packages/ai/core/util/detect-mimetype.test.ts | 400 ++++++++++++++++++ packages/ai/core/util/detect-mimetype.ts | 105 +++++ .../errors/no-transcript-generated-error.ts | 20 + packages/openai/src/internal/index.ts | 2 + packages/openai/src/openai-provider.ts | 19 + .../src/openai-transcription-model.test.ts | 182 ++++++++ .../openai/src/openai-transcription-model.ts | 259 ++++++++++++ .../src/openai-transcription-settings.ts | 34 ++ packages/openai/src/transcript-test.mp3 | Bin 0 -> 40169 bytes packages/provider-utils/src/post-to-api.ts | 30 ++ .../src/test/unified-test-server.ts | 15 + packages/provider/src/index.ts | 1 + .../provider/src/provider/v1/provider-v1.ts | 12 +- .../provider/src/transcription-model/index.ts | 1 + .../src/transcription-model/v1/index.ts | 3 + .../v1/transcription-model-v1-call-options.ts | 46 ++ .../v1/transcription-model-v1-call-warning.ts | 16 + .../v1/transcription-model-v1.ts | 116 +++++ 39 files changed, 2215 insertions(+), 211 deletions(-) create mode 100644 .changeset/happy-kangaroos-roll.md create mode 100644 content/docs/03-ai-sdk-core/36-transcription.mdx create mode 100644 content/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx create mode 100644 examples/ai-core/src/transcribe/openai-string.ts create mode 100644 examples/ai-core/src/transcribe/openai-url.ts create mode 100644 examples/ai-core/src/transcribe/openai.ts create mode 100644 packages/ai/core/test/mock-transcription-model-v1.ts create mode 100644 packages/ai/core/transcribe/index.ts create mode 100644 packages/ai/core/transcribe/transcribe-result.ts create mode 100644 packages/ai/core/transcribe/transcribe.test.ts create mode 100644 packages/ai/core/transcribe/transcribe.ts create mode 100644 packages/ai/core/types/transcription-model-response-metadata.ts create mode 100644 packages/ai/core/types/transcription-model.ts delete mode 100644 packages/ai/core/util/detect-image-mimetype.test.ts delete mode 100644 packages/ai/core/util/detect-image-mimetype.ts create mode 100644 packages/ai/core/util/detect-mimetype.test.ts create mode 100644 packages/ai/core/util/detect-mimetype.ts create mode 100644 packages/ai/errors/no-transcript-generated-error.ts create mode 100644 packages/openai/src/openai-transcription-model.test.ts create mode 100644 packages/openai/src/openai-transcription-model.ts create mode 100644 packages/openai/src/openai-transcription-settings.ts create mode 100644 packages/openai/src/transcript-test.mp3 create mode 100644 packages/provider/src/transcription-model/index.ts create mode 100644 packages/provider/src/transcription-model/v1/index.ts create mode 100644 packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts create mode 100644 packages/provider/src/transcription-model/v1/transcription-model-v1-call-warning.ts create mode 100644 packages/provider/src/transcription-model/v1/transcription-model-v1.ts diff --git a/.changeset/happy-kangaroos-roll.md b/.changeset/happy-kangaroos-roll.md new file mode 100644 index 000000000000..8b0e54911d9c --- /dev/null +++ b/.changeset/happy-kangaroos-roll.md @@ -0,0 +1,8 @@ +--- +'@ai-sdk/provider-utils': patch +'@ai-sdk/provider': patch +'@ai-sdk/openai': patch +'ai': patch +--- + +feat: add transcription with experimental_transcribe diff --git a/content/docs/03-ai-sdk-core/36-transcription.mdx b/content/docs/03-ai-sdk-core/36-transcription.mdx new file mode 100644 index 000000000000..24d3dca4f1d1 --- /dev/null +++ b/content/docs/03-ai-sdk-core/36-transcription.mdx @@ -0,0 +1,153 @@ +--- +title: Transcription +description: Learn how to transcribe audio with the AI SDK. +--- + +# Transcription + +Transcription is an experimental feature. + +The AI SDK provides the [`transcribe`](/docs/reference/ai-sdk-core/transcribe) +function to transcribe audio using a transcription model. + +```ts +import { experimental_transcribe as transcribe } from 'ai'; +import { openai } from '@ai-sdk/openai'; +import { readFile } from 'fs/promises'; + +const transcript = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), +}); +``` + +The `audio` property can be a `Uint8Array`, `ArrayBuffer`, `Buffer`, `string` (base64 encoded audio data), or a `URL`. + +To access the generated transcript: + +```ts +const text = transcript.text; // transcript text e.g. "Hello, world!" +const segments = transcript.segments; // array of segments with start and end times, if available +const language = transcript.language; // language of the transcript e.g. "en", if available +const durationInSeconds = transcript.durationInSeconds; // duration of the transcript in seconds, if available +``` + +## Settings + +### Provider-Specific settings + +Transcription models often have provider or model-specific settings which you can set using the `providerOptions` parameter. + +```ts highlight={"9"} +import { experimental_transcribe as transcribe } from 'ai'; +import { openai } from '@ai-sdk/openai'; +import { readFile } from 'fs/promises'; + +const transcript = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), + providerOptions: { + openai: { + timestampGranularities: ['word'], + }, + }, +}); +``` + +### Abort Signals and Timeouts + +`transcribe` accepts an optional `abortSignal` parameter of +type [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) +that you can use to abort the transcription process or set a timeout. + +```ts highlight={"7"} +import { openai } from '@ai-sdk/openai'; +import { experimental_transcribe as transcribe } from 'ai'; +import { readFile } from 'fs/promises'; + +const transcript = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), + abortSignal: AbortSignal.timeout(1000), // Abort after 1 second +}); +``` + +### Custom Headers + +`transcribe` accepts an optional `headers` parameter of type `Record` +that you can use to add custom headers to the transcription request. + +```ts highlight={"7"} +import { openai } from '@ai-sdk/openai'; +import { experimental_transcribe as transcribe } from 'ai'; +import { readFile } from 'fs/promises'; + +const transcript = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), + headers: { 'X-Custom-Header': 'custom-value' }, +}); +``` + +### Warnings + +Warnings (e.g. unsupported parameters) are available on the `warnings` property. + +```ts +import { openai } from '@ai-sdk/openai'; +import { experimental_transcribe as transcribe } from 'ai'; +import { readFile } from 'fs/promises'; + +const transcript = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), +}); + +const warnings = transcript.warnings; +``` + +### Error Handling + +When `transcribe` cannot generate a valid transcript, it throws a [`AI_NoTranscriptGeneratedError`](/docs/reference/ai-sdk-errors/ai-no-transcript-generated-error). + +This error can arise for any the following reasons: + +- The model failed to generate a response +- The model generated a response that could not be parsed + +The error preserves the following information to help you log the issue: + +- `responses`: Metadata about the transcription model responses, including timestamp, model, and headers. +- `cause`: The cause of the error. You can use this for more detailed error handling. + +```ts +import { + experimental_transcribe as transcribe, + NoTranscriptGeneratedError, +} from 'ai'; +import { openai } from '@ai-sdk/openai'; +import { readFile } from 'fs/promises'; + +try { + await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), + }); +} catch (error) { + if (NoTranscriptGeneratedError.isInstance(error)) { + console.log('NoTranscriptGeneratedError'); + console.log('Cause:', error.cause); + console.log('Responses:', error.responses); + } +} +``` + +## Transcription Models + +| Provider | Model | +| ----------------------------------------------------------------- | ------------------------ | +| [OpenAI](/providers/ai-sdk-providers/openai#transcription-models) | `whisper-1` | +| [OpenAI](/providers/ai-sdk-providers/openai#transcription-models) | `gpt-4o-transcribe` | +| [OpenAI](/providers/ai-sdk-providers/openai#transcription-models) | `gpt-4o-mini-transcribe` | + +Above are a small subset of the transcription models supported by the AI SDK providers. For more, see the respective provider documentation. diff --git a/content/docs/03-ai-sdk-core/index.mdx b/content/docs/03-ai-sdk-core/index.mdx index 521994c46ec9..3a3c93a46f2a 100644 --- a/content/docs/03-ai-sdk-core/index.mdx +++ b/content/docs/03-ai-sdk-core/index.mdx @@ -49,6 +49,11 @@ description: Learn about AI SDK Core. description: 'Learn how to generate images with AI SDK Core.', href: '/docs/ai-sdk-core/image-generation', }, + { + title: 'Transcription', + description: 'Learn how to transcribe audio with AI SDK Core.', + href: '/docs/ai-sdk-core/transcription', + }, { title: 'Provider Management', description: 'Learn how to work with multiple providers.', diff --git a/content/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx b/content/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx new file mode 100644 index 000000000000..86f52973bda7 --- /dev/null +++ b/content/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx @@ -0,0 +1,138 @@ +--- +title: transcribe +description: API Reference for transcribe. +--- + +# `transcribe()` + +`transcribe` is an experimental feature. + +Generates a transcript from an audio file. + +```ts +import { experimental_transcribe as transcribe } from 'ai'; +import { openai } from '@ai-sdk/openai'; +import { readFile } from 'fs/promises'; + +const { transcript } = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('audio.mp3'), +}); + +console.log(transcript); +``` + +## Import + + + +## API Signature + +### Parameters + +>', + isOptional: true, + description: 'Additional provider-specific options.', + }, + { + name: 'maxRetries', + type: 'number', + isOptional: true, + description: 'Maximum number of retries. Default: 2.', + }, + { + name: 'abortSignal', + type: 'AbortSignal', + isOptional: true, + description: 'An optional abort signal to cancel the call.', + }, + { + name: 'headers', + type: 'Record', + isOptional: true, + description: 'Additional HTTP headers for the request.', + }, + ]} +/> + +### Returns + +', + description: + 'An array of transcript segments, each containing a portion of the transcribed text along with its start and end times in seconds.', + }, + { + name: 'language', + type: 'string | undefined', + description: + 'The language of the transcript in ISO-639-1 format e.g. "en" for English.', + }, + { + name: 'durationInSeconds', + type: 'number | undefined', + description: 'The duration of the transcript in seconds.', + }, + { + name: 'warnings', + type: 'TranscriptionWarning[]', + description: + 'Warnings from the model provider (e.g. unsupported settings).', + }, + { + name: 'responses', + type: 'Array', + description: + 'Response metadata from the provider. There may be multiple responses if we made multiple calls to the model.', + properties: [ + { + type: 'TranscriptionModelResponseMetadata', + parameters: [ + { + name: 'timestamp', + type: 'Date', + description: 'Timestamp for the start of the generated response.', + }, + { + name: 'modelId', + type: 'string', + description: + 'The ID of the response model that was used to generate the response.', + }, + { + name: 'headers', + type: 'Record', + isOptional: true, + description: 'Response headers.', + }, + ], + }, + ], + }, + ]} +/> diff --git a/content/docs/07-reference/01-ai-sdk-core/index.mdx b/content/docs/07-reference/01-ai-sdk-core/index.mdx index 509e7a78b516..78c347f522f9 100644 --- a/content/docs/07-reference/01-ai-sdk-core/index.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/index.mdx @@ -52,6 +52,11 @@ AI SDK Core contains the following main functions: 'Generate images based on a given prompt using an image model.', href: '/docs/reference/ai-sdk-core/generate-image', }, + { + title: 'transcribe()', + description: 'Generate a transcript from an audio file.', + href: '/docs/reference/ai-sdk-core/transcribe', + }, ]} /> diff --git a/content/providers/01-ai-sdk-providers/02-openai.mdx b/content/providers/01-ai-sdk-providers/02-openai.mdx index 1a008b049402..c86f18f0fc4c 100644 --- a/content/providers/01-ai-sdk-providers/02-openai.mdx +++ b/content/providers/01-ai-sdk-providers/02-openai.mdx @@ -804,3 +804,67 @@ const model = openai.image('dall-e-3'); | ---------- | ------------------------------- | | `dall-e-3` | 1024x1024, 1792x1024, 1024x1792 | | `dall-e-2` | 256x256, 512x512, 1024x1024 | + +## Transcription Models + +You can create models that call the [OpenAI transcription API](https://platform.openai.com/docs/api-reference/audio/transcribe) +using the `.transcription()` factory method. + +The first argument is the model id e.g. `whisper-1`. + +```ts +const model = openai.transcription('whisper-1'); +``` + +OpenAI transcription models support an `audio` argument which can be a `DataContent` (`string | Uint8Array | ArrayBuffer | Buffer`) or a `URL`. + +```ts +const model = openai.transcription('whisper-1', { + audio: new Uint8Array([1, 2, 3, 4]), +}); +``` + +You can also pass additional provider-specific options using the `providerOptions` argument. For example, supplying the input language in ISO-639-1 (e.g. `en`) format will improve accuracy and latency. + +```ts highlight="6" +import { experimental_transcribe as transcribe } from 'ai'; +import { openai } from '@ai-sdk/openai'; + +const result = await transcribe({ + model: openai.transcription('whisper-1'), + audio: new Uint8Array([1, 2, 3, 4]), + providerOptions: { openai: { language: 'en' } }, +}); +``` + +The following provider options are available: + +- **timestampGranularities** _string[]_ + The granularity of the timestamps in the transcription. + Defaults to `['segment']`. + Possible values are `['word']`, `['segment']`, and `['word', 'segment']`. + Note: There is no additional latency for segment timestamps, but generating word timestamps incurs additional latency. + +- **language** _string_ + The language of the input audio. Supplying the input language in ISO-639-1 format (e.g. 'en') will improve accuracy and latency. + Optional. + +- **prompt** _string_ + An optional text to guide the model's style or continue a previous audio segment. The prompt should match the audio language. + Optional. + +- **temperature** _number_ + The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit. + Defaults to 0. + Optional. + +- **include** _string[]_ + Additional information to include in the transcription response. + +### Model Capabilities + +| Model | Transcription | Duration | Segments | Language | +| ------------------------ | ------------------- | ------------------- | ------------------- | ------------------- | +| `whisper-1` | | | | | +| `gpt-4o-mini-transcribe` | | | | | +| `gpt-4o-transcribe` | | | | | diff --git a/examples/ai-core/src/transcribe/openai-string.ts b/examples/ai-core/src/transcribe/openai-string.ts new file mode 100644 index 000000000000..5376c79e799b --- /dev/null +++ b/examples/ai-core/src/transcribe/openai-string.ts @@ -0,0 +1,23 @@ +import { openai } from '@ai-sdk/openai'; +import { experimental_transcribe as transcribe } from 'ai'; +import 'dotenv/config'; +import { readFile } from 'fs/promises'; + +async function main() { + const result = await transcribe({ + model: openai.transcription('whisper-1'), + audio: Buffer.from( + await readFile('examples/ai-core/data/galileo.mp3'), + ).toString('base64'), + }); + + console.log('Text:', result.text); + console.log('Duration:', result.durationInSeconds); + console.log('Language:', result.language); + console.log('Segments:', result.segments); + console.log('Warnings:', result.warnings); + console.log('Responses:', result.responses); + console.log('Provider Metadata:', result.providerMetadata); +} + +main().catch(console.error); diff --git a/examples/ai-core/src/transcribe/openai-url.ts b/examples/ai-core/src/transcribe/openai-url.ts new file mode 100644 index 000000000000..7c64932cd102 --- /dev/null +++ b/examples/ai-core/src/transcribe/openai-url.ts @@ -0,0 +1,23 @@ +import { openai } from '@ai-sdk/openai'; +import { experimental_transcribe as transcribe } from 'ai'; +import 'dotenv/config'; + +async function main() { + const result = await transcribe({ + model: openai.transcription('whisper-1'), + audio: new URL( + '/vercel/ai/raw/refs/heads/main/examples/ai-core/data/galileo.mp3', + 'https://github.com', + ), + }); + + console.log('Text:', result.text); + console.log('Duration:', result.durationInSeconds); + console.log('Language:', result.language); + console.log('Segments:', result.segments); + console.log('Warnings:', result.warnings); + console.log('Responses:', result.responses); + console.log('Provider Metadata:', result.providerMetadata); +} + +main().catch(console.error); diff --git a/examples/ai-core/src/transcribe/openai.ts b/examples/ai-core/src/transcribe/openai.ts new file mode 100644 index 000000000000..fafa586c6498 --- /dev/null +++ b/examples/ai-core/src/transcribe/openai.ts @@ -0,0 +1,21 @@ +import { openai } from '@ai-sdk/openai'; +import { experimental_transcribe as transcribe } from 'ai'; +import 'dotenv/config'; +import { readFile } from 'fs/promises'; + +async function main() { + const result = await transcribe({ + model: openai.transcription('whisper-1'), + audio: await readFile('examples/ai-core/data/galileo.mp3'), + }); + + console.log('Text:', result.text); + console.log('Duration:', result.durationInSeconds); + console.log('Language:', result.language); + console.log('Segments:', result.segments); + console.log('Warnings:', result.warnings); + console.log('Responses:', result.responses); + console.log('Provider Metadata:', result.providerMetadata); +} + +main().catch(console.error); diff --git a/packages/ai/core/generate-image/generate-image.ts b/packages/ai/core/generate-image/generate-image.ts index cf06d8f7d498..ae0a79a550ec 100644 --- a/packages/ai/core/generate-image/generate-image.ts +++ b/packages/ai/core/generate-image/generate-image.ts @@ -8,7 +8,10 @@ import { prepareRetries } from '../prompt/prepare-retries'; import { ImageGenerationWarning } from '../types/image-model'; import { ImageModelResponseMetadata } from '../types/image-model-response-metadata'; import { GenerateImageResult } from './generate-image-result'; -import { detectImageMimeType } from '../util/detect-image-mimetype'; +import { + detectMimeType, + imageMimeTypeSignatures, +} from '../util/detect-mimetype'; /** Generates images using an image model. @@ -146,7 +149,11 @@ Only applicable for HTTP-based providers. image => new DefaultGeneratedFile({ data: image, - mimeType: detectImageMimeType(image) ?? 'image/png', + mimeType: + detectMimeType({ + data: image, + signatures: imageMimeTypeSignatures, + }) ?? 'image/png', }), ), ); diff --git a/packages/ai/core/index.ts b/packages/ai/core/index.ts index d23acab74658..47e8299e63ff 100644 --- a/packages/ai/core/index.ts +++ b/packages/ai/core/index.ts @@ -37,6 +37,7 @@ export * from './embed'; export * from './generate-image'; export * from './generate-object'; export * from './generate-text'; +export * from './transcribe'; export * from './middleware'; export * from './prompt'; export * from './registry'; diff --git a/packages/ai/core/prompt/convert-to-language-model-prompt.ts b/packages/ai/core/prompt/convert-to-language-model-prompt.ts index 61c9240362aa..e6dcf8000fef 100644 --- a/packages/ai/core/prompt/convert-to-language-model-prompt.ts +++ b/packages/ai/core/prompt/convert-to-language-model-prompt.ts @@ -7,7 +7,10 @@ import { } from '@ai-sdk/provider'; import { download } from '../../util/download'; import { CoreMessage } from '../prompt/message'; -import { detectImageMimeType } from '../util/detect-image-mimetype'; +import { + detectMimeType, + imageMimeTypeSignatures, +} from '../util/detect-mimetype'; import { FilePart, ImagePart, TextPart } from './content-part'; import { convertDataContentToBase64String, @@ -341,7 +344,11 @@ function convertPartToLanguageModelPart( // When detection fails, use provided mimetype. if (normalizedData instanceof Uint8Array) { - mimeType = detectImageMimeType(normalizedData) ?? mimeType; + mimeType = + detectMimeType({ + data: normalizedData, + signatures: imageMimeTypeSignatures, + }) ?? mimeType; } return { type: 'image', diff --git a/packages/ai/core/test/mock-transcription-model-v1.ts b/packages/ai/core/test/mock-transcription-model-v1.ts new file mode 100644 index 000000000000..87d6007793bc --- /dev/null +++ b/packages/ai/core/test/mock-transcription-model-v1.ts @@ -0,0 +1,24 @@ +import { TranscriptionModelV1 } from '@ai-sdk/provider'; +import { notImplemented } from './not-implemented'; + +export class MockTranscriptionModelV1 implements TranscriptionModelV1 { + readonly specificationVersion = 'v1'; + readonly provider: TranscriptionModelV1['provider']; + readonly modelId: TranscriptionModelV1['modelId']; + + doGenerate: TranscriptionModelV1['doGenerate']; + + constructor({ + provider = 'mock-provider', + modelId = 'mock-model-id', + doGenerate = notImplemented, + }: { + provider?: TranscriptionModelV1['provider']; + modelId?: TranscriptionModelV1['modelId']; + doGenerate?: TranscriptionModelV1['doGenerate']; + } = {}) { + this.provider = provider; + this.modelId = modelId; + this.doGenerate = doGenerate; + } +} diff --git a/packages/ai/core/transcribe/index.ts b/packages/ai/core/transcribe/index.ts new file mode 100644 index 000000000000..596a3d8b7af7 --- /dev/null +++ b/packages/ai/core/transcribe/index.ts @@ -0,0 +1,2 @@ +export { transcribe as experimental_transcribe } from './transcribe'; +export type { TranscriptionResult as Experimental_TranscriptionResult } from './transcribe-result'; diff --git a/packages/ai/core/transcribe/transcribe-result.ts b/packages/ai/core/transcribe/transcribe-result.ts new file mode 100644 index 000000000000..ed5a34d2289f --- /dev/null +++ b/packages/ai/core/transcribe/transcribe-result.ts @@ -0,0 +1,60 @@ +import { JSONValue } from '@ai-sdk/provider'; +import { TranscriptionWarning } from '../types/transcription-model'; +import { TranscriptionModelResponseMetadata } from '../types/transcription-model-response-metadata'; + +/** +The result of a `transcribe` call. +It contains the transcript and additional information. + */ +export interface TranscriptionResult { + /** + * The complete transcribed text from the audio. + */ + readonly text: string; + + /** + * Array of transcript segments with timing information. + * Each segment represents a portion of the transcribed text with start and end times. + */ + readonly segments: Array<{ + /** + * The text content of this segment. + */ + readonly text: string; + /** + * The start time of this segment in seconds. + */ + readonly startSecond: number; + /** + * The end time of this segment in seconds. + */ + readonly endSecond: number; + }>; + + /** + * The detected language of the audio content, as an ISO-639-1 code (e.g., 'en' for English). + * May be undefined if the language couldn't be detected. + */ + readonly language: string | undefined; + + /** + * The total duration of the audio file in seconds. + * May be undefined if the duration couldn't be determined. + */ + readonly durationInSeconds: number | undefined; + + /** + Warnings for the call, e.g. unsupported settings. + */ + readonly warnings: Array; + + /** + Response metadata from the provider. There may be multiple responses if we made multiple calls to the model. + */ + readonly responses: Array; + + /** + Provider metadata from the provider. + */ + readonly providerMetadata: Record>; +} diff --git a/packages/ai/core/transcribe/transcribe.test.ts b/packages/ai/core/transcribe/transcribe.test.ts new file mode 100644 index 000000000000..72a555783a78 --- /dev/null +++ b/packages/ai/core/transcribe/transcribe.test.ts @@ -0,0 +1,229 @@ +import { + JSONValue, + TranscriptionModelV1, + TranscriptionModelV1CallWarning, +} from '@ai-sdk/provider'; +import { MockTranscriptionModelV1 } from '../test/mock-transcription-model-v1'; +import { transcribe } from './transcribe'; + +const audioData = new Uint8Array([1, 2, 3, 4]); // Sample audio data +const testDate = new Date(2024, 0, 1); + +const sampleTranscript = { + text: 'This is a sample transcript.', + segments: [ + { + startSecond: 0, + endSecond: 2.5, + text: 'This is a', + }, + { + startSecond: 2.5, + endSecond: 4.0, + text: 'sample transcript.', + }, + ], + language: 'en', + durationInSeconds: 4.0, +}; + +const createMockResponse = (options: { + text: string; + segments: Array<{ + text: string; + startSecond: number; + endSecond: number; + }>; + language?: string; + durationInSeconds?: number; + warnings?: TranscriptionModelV1CallWarning[]; + timestamp?: Date; + modelId?: string; + headers?: Record; + providerMetadata?: Record>; +}) => ({ + text: options.text, + segments: options.segments, + language: options.language, + durationInSeconds: options.durationInSeconds, + warnings: options.warnings ?? [], + response: { + timestamp: options.timestamp ?? new Date(), + modelId: options.modelId ?? 'test-model-id', + headers: options.headers ?? {}, + }, + providerMetadata: options.providerMetadata ?? {}, +}); + +describe('transcribe', () => { + it('should send args to doGenerate', async () => { + const abortController = new AbortController(); + const abortSignal = abortController.signal; + + let capturedArgs!: Parameters[0]; + + await transcribe({ + model: new MockTranscriptionModelV1({ + doGenerate: async args => { + capturedArgs = args; + return createMockResponse({ + ...sampleTranscript, + }); + }, + }), + audio: audioData, + headers: { 'custom-request-header': 'request-header-value' }, + abortSignal, + }); + + expect(capturedArgs).toStrictEqual({ + audio: audioData, + mimeType: 'audio/wav', + headers: { 'custom-request-header': 'request-header-value' }, + abortSignal, + providerOptions: {}, + }); + }); + + it('should return warnings', async () => { + const result = await transcribe({ + model: new MockTranscriptionModelV1({ + doGenerate: async () => + createMockResponse({ + ...sampleTranscript, + warnings: [ + { + type: 'other', + message: 'Setting is not supported', + }, + ], + providerMetadata: { + 'test-provider': { + 'test-key': 'test-value', + }, + }, + }), + }), + audio: audioData, + }); + + expect(result.warnings).toStrictEqual([ + { + type: 'other', + message: 'Setting is not supported', + }, + ]); + }); + + it('should return the transcript', async () => { + const result = await transcribe({ + model: new MockTranscriptionModelV1({ + doGenerate: async () => + createMockResponse({ + ...sampleTranscript, + }), + }), + audio: audioData, + }); + + expect(result).toEqual({ + ...sampleTranscript, + warnings: [], + responses: [ + { + timestamp: expect.any(Date), + modelId: 'test-model-id', + headers: {}, + }, + ], + providerMetadata: {}, + }); + }); + + describe('error handling', () => { + it('should throw NoTranscriptGeneratedError when no transcript is returned', async () => { + await expect( + transcribe({ + model: new MockTranscriptionModelV1({ + doGenerate: async () => + createMockResponse({ + text: '', + segments: [], + language: 'en', + durationInSeconds: 0, + timestamp: testDate, + }), + }), + audio: audioData, + }), + ).rejects.toMatchObject({ + name: 'AI_NoTranscriptGeneratedError', + message: 'No transcript generated.', + responses: [ + { + timestamp: testDate, + modelId: expect.any(String), + }, + ], + }); + }); + + it('should include response headers in error when no transcript generated', async () => { + await expect( + transcribe({ + model: new MockTranscriptionModelV1({ + doGenerate: async () => + createMockResponse({ + text: '', + segments: [], + language: 'en', + durationInSeconds: 0, + timestamp: testDate, + headers: { + 'custom-response-header': 'response-header-value', + }, + }), + }), + audio: audioData, + }), + ).rejects.toMatchObject({ + name: 'AI_NoTranscriptGeneratedError', + message: 'No transcript generated.', + responses: [ + { + timestamp: testDate, + modelId: expect.any(String), + headers: { + 'custom-response-header': 'response-header-value', + }, + }, + ], + }); + }); + }); + + it('should return response metadata', async () => { + const testHeaders = { 'x-test': 'value' }; + + const result = await transcribe({ + model: new MockTranscriptionModelV1({ + doGenerate: async () => + createMockResponse({ + ...sampleTranscript, + timestamp: testDate, + modelId: 'test-model', + headers: testHeaders, + }), + }), + audio: audioData, + }); + + expect(result.responses).toStrictEqual([ + { + timestamp: testDate, + modelId: 'test-model', + headers: testHeaders, + }, + ]); + }); +}); diff --git a/packages/ai/core/transcribe/transcribe.ts b/packages/ai/core/transcribe/transcribe.ts new file mode 100644 index 000000000000..2114522845bc --- /dev/null +++ b/packages/ai/core/transcribe/transcribe.ts @@ -0,0 +1,150 @@ +import { TranscriptionModelV1, JSONValue } from '@ai-sdk/provider'; +import { NoTranscriptGeneratedError } from '../../errors/no-transcript-generated-error'; +import { prepareRetries } from '../prompt/prepare-retries'; +import { TranscriptionWarning } from '../types/transcription-model'; +import { TranscriptionModelResponseMetadata } from '../types/transcription-model-response-metadata'; +import { TranscriptionResult } from './transcribe-result'; +import { DataContent } from '../prompt'; +import { convertDataContentToUint8Array } from '../prompt/data-content'; +import { download } from '../../util/download'; +import { + audioMimeTypeSignatures, + detectMimeType, +} from '../util/detect-mimetype'; +import { ProviderOptions } from '../types/provider-metadata'; + +/** +Generates transcripts using a transcription model. + +@param model - The transcription model to use. +@param audio - The audio data to transcribe as DataContent (string | Uint8Array | ArrayBuffer | Buffer) or a URL. +@param providerOptions - Additional provider-specific options that are passed through to the provider +as body parameters. +@param maxRetries - Maximum number of retries. Set to 0 to disable retries. Default: 2. +@param abortSignal - An optional abort signal that can be used to cancel the call. +@param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers. + +@returns A result object that contains the generated transcript. + */ +export async function transcribe({ + model, + audio, + providerOptions = {}, + maxRetries: maxRetriesArg, + abortSignal, + headers, +}: { + /** +The transcription model to use. + */ + model: TranscriptionModelV1; + + /** +The audio data to transcribe. + */ + audio: DataContent | URL; + + /** +Additional provider-specific options that are passed through to the provider +as body parameters. + +The outer record is keyed by the provider name, and the inner +record is keyed by the provider-specific metadata key. +```ts +{ + "openai": { + "temperature": 0 + } +} +``` + */ + providerOptions?: ProviderOptions; + + /** +Maximum number of retries per transcript model call. Set to 0 to disable retries. + +@default 2 + */ + maxRetries?: number; + + /** +Abort signal. + */ + abortSignal?: AbortSignal; + + /** +Additional headers to include in the request. +Only applicable for HTTP-based providers. + */ + headers?: Record; +}): Promise { + const { retry } = prepareRetries({ maxRetries: maxRetriesArg }); + const audioData = + audio instanceof URL + ? new Uint8Array((await download({ url: audio })).data) + : convertDataContentToUint8Array(audio); + + const result = await retry(() => + model.doGenerate({ + audio: audioData, + abortSignal, + headers, + providerOptions, + mimeType: + detectMimeType({ + data: audioData, + signatures: audioMimeTypeSignatures, + }) ?? 'audio/wav', + }), + ); + + if (!result.text) { + throw new NoTranscriptGeneratedError({ responses: [result.response] }); + } + + return new DefaultTranscriptionResult({ + text: result.text, + segments: result.segments, + language: result.language, + durationInSeconds: result.durationInSeconds, + warnings: result.warnings, + responses: [result.response], + providerMetadata: result.providerMetadata, + }); +} + +class DefaultTranscriptionResult implements TranscriptionResult { + readonly text: string; + readonly segments: Array<{ + text: string; + startSecond: number; + endSecond: number; + }>; + readonly language: string | undefined; + readonly durationInSeconds: number | undefined; + readonly warnings: Array; + readonly responses: Array; + readonly providerMetadata: Record>; + + constructor(options: { + text: string; + segments: Array<{ + text: string; + startSecond: number; + endSecond: number; + }>; + language: string | undefined; + durationInSeconds: number | undefined; + warnings: Array; + responses: Array; + providerMetadata: Record> | undefined; + }) { + this.text = options.text; + this.segments = options.segments; + this.language = options.language; + this.durationInSeconds = options.durationInSeconds; + this.warnings = options.warnings; + this.responses = options.responses; + this.providerMetadata = options.providerMetadata ?? {}; + } +} diff --git a/packages/ai/core/types/transcription-model-response-metadata.ts b/packages/ai/core/types/transcription-model-response-metadata.ts new file mode 100644 index 000000000000..9fcf62f3fcd6 --- /dev/null +++ b/packages/ai/core/types/transcription-model-response-metadata.ts @@ -0,0 +1,16 @@ +export type TranscriptionModelResponseMetadata = { + /** +Timestamp for the start of the generated response. + */ + timestamp: Date; + + /** +The ID of the response model that was used to generate the response. + */ + modelId: string; + + /** +Response headers. + */ + headers?: Record; +}; diff --git a/packages/ai/core/types/transcription-model.ts b/packages/ai/core/types/transcription-model.ts new file mode 100644 index 000000000000..d2eba1244fd0 --- /dev/null +++ b/packages/ai/core/types/transcription-model.ts @@ -0,0 +1,15 @@ +import { + TranscriptionModelV1, + TranscriptionModelV1CallWarning, +} from '@ai-sdk/provider'; + +/** +Transcription model that is used by the AI SDK Core functions. + */ +export type TranscriptionModel = TranscriptionModelV1; + +/** +Warning from the model provider for this call. The call will proceed, but e.g. +some settings might not be supported, which can lead to suboptimal results. + */ +export type TranscriptionWarning = TranscriptionModelV1CallWarning; diff --git a/packages/ai/core/util/detect-image-mimetype.test.ts b/packages/ai/core/util/detect-image-mimetype.test.ts deleted file mode 100644 index cf5cfa61988e..000000000000 --- a/packages/ai/core/util/detect-image-mimetype.test.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { detectImageMimeType } from './detect-image-mimetype'; - -describe('detectImageMimeType', () => { - describe('GIF', () => { - it('should detect GIF from bytes', () => { - const gifBytes = new Uint8Array([0x47, 0x49, 0x46, 0xff, 0xff]); - expect(detectImageMimeType(gifBytes)).toBe('image/gif'); - }); - - it('should detect GIF from base64', () => { - const gifBase64 = 'R0lGabc123'; // Base64 string starting with GIF signature - expect(detectImageMimeType(gifBase64)).toBe('image/gif'); - }); - }); - - describe('PNG', () => { - it('should detect PNG from bytes', () => { - const pngBytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0xff, 0xff]); - expect(detectImageMimeType(pngBytes)).toBe('image/png'); - }); - - it('should detect PNG from base64', () => { - const pngBase64 = 'iVBORwabc123'; // Base64 string starting with PNG signature - expect(detectImageMimeType(pngBase64)).toBe('image/png'); - }); - }); - - describe('JPEG', () => { - it('should detect JPEG from bytes', () => { - const jpegBytes = new Uint8Array([0xff, 0xd8, 0xff, 0xff]); - expect(detectImageMimeType(jpegBytes)).toBe('image/jpeg'); - }); - - it('should detect JPEG from base64', () => { - const jpegBase64 = '/9j/abc123'; // Base64 string starting with JPEG signature - expect(detectImageMimeType(jpegBase64)).toBe('image/jpeg'); - }); - }); - - describe('WebP', () => { - it('should detect WebP from bytes', () => { - const webpBytes = new Uint8Array([0x52, 0x49, 0x46, 0x46, 0xff, 0xff]); - expect(detectImageMimeType(webpBytes)).toBe('image/webp'); - }); - - it('should detect WebP from base64', () => { - const webpBase64 = 'UklGRgabc123'; // Base64 string starting with WebP signature - expect(detectImageMimeType(webpBase64)).toBe('image/webp'); - }); - }); - - describe('BMP', () => { - it('should detect BMP from bytes', () => { - const bmpBytes = new Uint8Array([0x42, 0x4d, 0xff, 0xff]); - expect(detectImageMimeType(bmpBytes)).toBe('image/bmp'); - }); - - it('should detect BMP from base64', () => { - const bmpBase64 = 'Qkabc123'; // Base64 string starting with BMP signature - expect(detectImageMimeType(bmpBase64)).toBe('image/bmp'); - }); - }); - - describe('TIFF', () => { - it('should detect TIFF (little endian) from bytes', () => { - const tiffLEBytes = new Uint8Array([0x49, 0x49, 0x2a, 0x00, 0xff]); - expect(detectImageMimeType(tiffLEBytes)).toBe('image/tiff'); - }); - - it('should detect TIFF (little endian) from base64', () => { - const tiffLEBase64 = 'SUkqAAabc123'; // Base64 string starting with TIFF LE signature - expect(detectImageMimeType(tiffLEBase64)).toBe('image/tiff'); - }); - - it('should detect TIFF (big endian) from bytes', () => { - const tiffBEBytes = new Uint8Array([0x4d, 0x4d, 0x00, 0x2a, 0xff]); - expect(detectImageMimeType(tiffBEBytes)).toBe('image/tiff'); - }); - - it('should detect TIFF (big endian) from base64', () => { - const tiffBEBase64 = 'TU0AKgabc123'; // Base64 string starting with TIFF BE signature - expect(detectImageMimeType(tiffBEBase64)).toBe('image/tiff'); - }); - }); - - describe('AVIF', () => { - it('should detect AVIF from bytes', () => { - const avifBytes = new Uint8Array([ - 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, - 0xff, - ]); - expect(detectImageMimeType(avifBytes)).toBe('image/avif'); - }); - - it('should detect AVIF from base64', () => { - const avifBase64 = 'AAAAIGZ0eXBhdmlmabc123'; // Base64 string starting with AVIF signature - expect(detectImageMimeType(avifBase64)).toBe('image/avif'); - }); - }); - - describe('HEIC', () => { - it('should detect HEIC from bytes', () => { - const heicBytes = new Uint8Array([ - 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, - 0xff, - ]); - expect(detectImageMimeType(heicBytes)).toBe('image/heic'); - }); - - it('should detect HEIC from base64', () => { - const heicBase64 = 'AAAAIGZ0eXBoZWljabc123'; // Base64 string starting with HEIC signature - expect(detectImageMimeType(heicBase64)).toBe('image/heic'); - }); - }); - - describe('error cases', () => { - it('should return undefined for unknown image formats', () => { - const unknownBytes = new Uint8Array([0x00, 0x01, 0x02, 0x03]); - expect(detectImageMimeType(unknownBytes)).toBeUndefined(); - }); - - it('should return undefined for empty arrays', () => { - const emptyBytes = new Uint8Array([]); - expect(detectImageMimeType(emptyBytes)).toBeUndefined(); - }); - - it('should return undefined for arrays shorter than signature length', () => { - const shortBytes = new Uint8Array([0x89, 0x50]); // Incomplete PNG signature - expect(detectImageMimeType(shortBytes)).toBeUndefined(); - }); - - it('should return undefined for invalid base64 strings', () => { - const invalidBase64 = 'invalid123'; - expect(detectImageMimeType(invalidBase64)).toBeUndefined(); - }); - }); -}); diff --git a/packages/ai/core/util/detect-image-mimetype.ts b/packages/ai/core/util/detect-image-mimetype.ts deleted file mode 100644 index cbb708fb50eb..000000000000 --- a/packages/ai/core/util/detect-image-mimetype.ts +++ /dev/null @@ -1,68 +0,0 @@ -const mimeTypeSignatures = [ - { - mimeType: 'image/gif' as const, - bytesPrefix: [0x47, 0x49, 0x46], - base64Prefix: 'R0lG', - }, - { - mimeType: 'image/png' as const, - bytesPrefix: [0x89, 0x50, 0x4e, 0x47], - base64Prefix: 'iVBORw', - }, - { - mimeType: 'image/jpeg' as const, - bytesPrefix: [0xff, 0xd8], - base64Prefix: '/9j/', - }, - { - mimeType: 'image/webp' as const, - bytesPrefix: [0x52, 0x49, 0x46, 0x46], - base64Prefix: 'UklGRg', - }, - { - mimeType: 'image/bmp' as const, - bytesPrefix: [0x42, 0x4d], - base64Prefix: 'Qk', - }, - { - mimeType: 'image/tiff' as const, - bytesPrefix: [0x49, 0x49, 0x2a, 0x00], - base64Prefix: 'SUkqAA', - }, - { - mimeType: 'image/tiff' as const, - bytesPrefix: [0x4d, 0x4d, 0x00, 0x2a], - base64Prefix: 'TU0AKg', - }, - { - mimeType: 'image/avif' as const, - bytesPrefix: [ - 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, - ], - base64Prefix: 'AAAAIGZ0eXBhdmlm', - }, - { - mimeType: 'image/heic' as const, - bytesPrefix: [ - 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, - ], - base64Prefix: 'AAAAIGZ0eXBoZWlj', - }, -] as const; - -export function detectImageMimeType( - image: Uint8Array | string, -): (typeof mimeTypeSignatures)[number]['mimeType'] | undefined { - for (const signature of mimeTypeSignatures) { - if ( - typeof image === 'string' - ? image.startsWith(signature.base64Prefix) - : image.length >= signature.bytesPrefix.length && - signature.bytesPrefix.every((byte, index) => image[index] === byte) - ) { - return signature.mimeType; - } - } - - return undefined; -} diff --git a/packages/ai/core/util/detect-mimetype.test.ts b/packages/ai/core/util/detect-mimetype.test.ts new file mode 100644 index 000000000000..d965c712d359 --- /dev/null +++ b/packages/ai/core/util/detect-mimetype.test.ts @@ -0,0 +1,400 @@ +import { describe, it, expect } from 'vitest'; +import { + detectMimeType, + imageMimeTypeSignatures, + audioMimeTypeSignatures, +} from './detect-mimetype'; + +describe('detectMimeType', () => { + describe('GIF', () => { + it('should detect GIF from bytes', () => { + const gifBytes = new Uint8Array([0x47, 0x49, 0x46, 0xff, 0xff]); + expect( + detectMimeType({ data: gifBytes, signatures: imageMimeTypeSignatures }), + ).toBe('image/gif'); + }); + + it('should detect GIF from base64', () => { + const gifBase64 = 'R0lGabc123'; // Base64 string starting with GIF signature + expect( + detectMimeType({ + data: gifBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/gif'); + }); + }); + + describe('PNG', () => { + it('should detect PNG from bytes', () => { + const pngBytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0xff, 0xff]); + expect( + detectMimeType({ data: pngBytes, signatures: imageMimeTypeSignatures }), + ).toBe('image/png'); + }); + + it('should detect PNG from base64', () => { + const pngBase64 = 'iVBORwabc123'; // Base64 string starting with PNG signature + expect( + detectMimeType({ + data: pngBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/png'); + }); + }); + + describe('JPEG', () => { + it('should detect JPEG from bytes', () => { + const jpegBytes = new Uint8Array([0xff, 0xd8, 0xff, 0xff]); + expect( + detectMimeType({ + data: jpegBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/jpeg'); + }); + + it('should detect JPEG from base64', () => { + const jpegBase64 = '/9j/abc123'; // Base64 string starting with JPEG signature + expect( + detectMimeType({ + data: jpegBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/jpeg'); + }); + }); + + describe('WebP', () => { + it('should detect WebP from bytes', () => { + const webpBytes = new Uint8Array([0x52, 0x49, 0x46, 0x46, 0xff, 0xff]); + expect( + detectMimeType({ + data: webpBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/webp'); + }); + + it('should detect WebP from base64', () => { + const webpBase64 = 'UklGRgabc123'; // Base64 string starting with WebP signature + expect( + detectMimeType({ + data: webpBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/webp'); + }); + }); + + describe('BMP', () => { + it('should detect BMP from bytes', () => { + const bmpBytes = new Uint8Array([0x42, 0x4d, 0xff, 0xff]); + expect( + detectMimeType({ data: bmpBytes, signatures: imageMimeTypeSignatures }), + ).toBe('image/bmp'); + }); + + it('should detect BMP from base64', () => { + const bmpBase64 = 'Qkabc123'; // Base64 string starting with BMP signature + expect( + detectMimeType({ + data: bmpBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/bmp'); + }); + }); + + describe('TIFF', () => { + it('should detect TIFF (little endian) from bytes', () => { + const tiffLEBytes = new Uint8Array([0x49, 0x49, 0x2a, 0x00, 0xff]); + expect( + detectMimeType({ + data: tiffLEBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/tiff'); + }); + + it('should detect TIFF (little endian) from base64', () => { + const tiffLEBase64 = 'SUkqAAabc123'; // Base64 string starting with TIFF LE signature + expect( + detectMimeType({ + data: tiffLEBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/tiff'); + }); + + it('should detect TIFF (big endian) from bytes', () => { + const tiffBEBytes = new Uint8Array([0x4d, 0x4d, 0x00, 0x2a, 0xff]); + expect( + detectMimeType({ + data: tiffBEBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/tiff'); + }); + + it('should detect TIFF (big endian) from base64', () => { + const tiffBEBase64 = 'TU0AKgabc123'; // Base64 string starting with TIFF BE signature + expect( + detectMimeType({ + data: tiffBEBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/tiff'); + }); + }); + + describe('AVIF', () => { + it('should detect AVIF from bytes', () => { + const avifBytes = new Uint8Array([ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, + 0xff, + ]); + expect( + detectMimeType({ + data: avifBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/avif'); + }); + + it('should detect AVIF from base64', () => { + const avifBase64 = 'AAAAIGZ0eXBhdmlmabc123'; // Base64 string starting with AVIF signature + expect( + detectMimeType({ + data: avifBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/avif'); + }); + }); + + describe('HEIC', () => { + it('should detect HEIC from bytes', () => { + const heicBytes = new Uint8Array([ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, + 0xff, + ]); + expect( + detectMimeType({ + data: heicBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/heic'); + }); + + it('should detect HEIC from base64', () => { + const heicBase64 = 'AAAAIGZ0eXBoZWljabc123'; // Base64 string starting with HEIC signature + expect( + detectMimeType({ + data: heicBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBe('image/heic'); + }); + }); + + describe('MP3', () => { + it('should detect MP3 from bytes', () => { + const mp3Bytes = new Uint8Array([0xff, 0xfb]); + expect( + detectMimeType({ data: mp3Bytes, signatures: audioMimeTypeSignatures }), + ).toBe('audio/mpeg'); + }); + + it('should detect MP3 from base64', () => { + const mp3Base64 = '//s='; // Base64 string starting with MP3 signature + expect( + detectMimeType({ + data: mp3Base64, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/mpeg'); + }); + }); + + describe('WAV', () => { + it('should detect WAV from bytes', () => { + const wavBytes = new Uint8Array([0x52, 0x49, 0x46, 0x46]); + expect( + detectMimeType({ data: wavBytes, signatures: audioMimeTypeSignatures }), + ).toBe('audio/wav'); + }); + + it('should detect WAV from base64', () => { + const wavBase64 = 'UklGRiQ='; // Base64 string starting with WAV signature + expect( + detectMimeType({ + data: wavBase64, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/wav'); + }); + }); + + describe('OGG', () => { + it('should detect OGG from bytes', () => { + const oggBytes = new Uint8Array([0x4f, 0x67, 0x67, 0x53]); + expect( + detectMimeType({ data: oggBytes, signatures: audioMimeTypeSignatures }), + ).toBe('audio/ogg'); + }); + + it('should detect OGG from base64', () => { + const oggBase64 = 'T2dnUw'; // Base64 string starting with OGG signature + expect( + detectMimeType({ + data: oggBase64, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/ogg'); + }); + }); + + describe('FLAC', () => { + it('should detect FLAC from bytes', () => { + const flacBytes = new Uint8Array([0x66, 0x4c, 0x61, 0x43]); + expect( + detectMimeType({ + data: flacBytes, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/flac'); + }); + + it('should detect FLAC from base64', () => { + const flacBase64 = 'ZkxhQw'; // Base64 string starting with FLAC signature + expect( + detectMimeType({ + data: flacBase64, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/flac'); + }); + }); + + describe('AAC', () => { + it('should detect AAC from bytes', () => { + const aacBytes = new Uint8Array([0x40, 0x15, 0x00, 0x00]); + expect( + detectMimeType({ data: aacBytes, signatures: audioMimeTypeSignatures }), + ).toBe('audio/aac'); + }); + + it('should detect AAC from base64', () => { + const aacBase64 = 'QBUA'; // Base64 string starting with AAC signature + expect( + detectMimeType({ + data: aacBase64, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/aac'); + }); + }); + + describe('MP4', () => { + it('should detect MP4 from bytes', () => { + const mp4Bytes = new Uint8Array([0x66, 0x74, 0x79, 0x70]); + expect( + detectMimeType({ data: mp4Bytes, signatures: audioMimeTypeSignatures }), + ).toBe('audio/mp4'); + }); + + it('should detect MP4 from base64', () => { + const mp4Base64 = 'ZnR5cA'; // Base64 string starting with MP4 signature + expect( + detectMimeType({ + data: mp4Base64, + signatures: audioMimeTypeSignatures, + }), + ).toBe('audio/mp4'); + }); + }); + + describe('error cases', () => { + it('should return undefined for unknown image formats', () => { + const unknownBytes = new Uint8Array([0x00, 0x01, 0x02, 0x03]); + expect( + detectMimeType({ + data: unknownBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for unknown audio formats', () => { + const unknownBytes = new Uint8Array([0x00, 0x01, 0x02, 0x03]); + expect( + detectMimeType({ + data: unknownBytes, + signatures: audioMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for empty arrays for image', () => { + const emptyBytes = new Uint8Array([]); + expect( + detectMimeType({ + data: emptyBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for empty arrays for audio', () => { + const emptyBytes = new Uint8Array([]); + expect( + detectMimeType({ + data: emptyBytes, + signatures: audioMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for arrays shorter than signature length for image', () => { + const shortBytes = new Uint8Array([0x89, 0x50]); // Incomplete PNG signature + expect( + detectMimeType({ + data: shortBytes, + signatures: imageMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for arrays shorter than signature length for audio', () => { + const shortBytes = new Uint8Array([0x4f, 0x67]); // Incomplete OGG signature + expect( + detectMimeType({ + data: shortBytes, + signatures: audioMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for invalid base64 strings for image', () => { + const invalidBase64 = 'invalid123'; + expect( + detectMimeType({ + data: invalidBase64, + signatures: imageMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + + it('should return undefined for invalid base64 strings for audio', () => { + const invalidBase64 = 'invalid123'; + expect( + detectMimeType({ + data: invalidBase64, + signatures: audioMimeTypeSignatures, + }), + ).toBeUndefined(); + }); + }); +}); diff --git a/packages/ai/core/util/detect-mimetype.ts b/packages/ai/core/util/detect-mimetype.ts new file mode 100644 index 000000000000..1851e3217a03 --- /dev/null +++ b/packages/ai/core/util/detect-mimetype.ts @@ -0,0 +1,105 @@ +export const imageMimeTypeSignatures = [ + { + mimeType: 'image/gif' as const, + bytesPrefix: [0x47, 0x49, 0x46], + base64Prefix: 'R0lG', + }, + { + mimeType: 'image/png' as const, + bytesPrefix: [0x89, 0x50, 0x4e, 0x47], + base64Prefix: 'iVBORw', + }, + { + mimeType: 'image/jpeg' as const, + bytesPrefix: [0xff, 0xd8], + base64Prefix: '/9j/', + }, + { + mimeType: 'image/webp' as const, + bytesPrefix: [0x52, 0x49, 0x46, 0x46], + base64Prefix: 'UklGRg', + }, + { + mimeType: 'image/bmp' as const, + bytesPrefix: [0x42, 0x4d], + base64Prefix: 'Qk', + }, + { + mimeType: 'image/tiff' as const, + bytesPrefix: [0x49, 0x49, 0x2a, 0x00], + base64Prefix: 'SUkqAA', + }, + { + mimeType: 'image/tiff' as const, + bytesPrefix: [0x4d, 0x4d, 0x00, 0x2a], + base64Prefix: 'TU0AKg', + }, + { + mimeType: 'image/avif' as const, + bytesPrefix: [ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, + ], + base64Prefix: 'AAAAIGZ0eXBhdmlm', + }, + { + mimeType: 'image/heic' as const, + bytesPrefix: [ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, + ], + base64Prefix: 'AAAAIGZ0eXBoZWlj', + }, +] as const; + +export const audioMimeTypeSignatures = [ + { + mimeType: 'audio/mpeg' as const, + bytesPrefix: [0xff, 0xfb], + base64Prefix: '//s=', + }, + { + mimeType: 'audio/wav' as const, + bytesPrefix: [0x52, 0x49, 0x46, 0x46], + base64Prefix: 'UklGR', + }, + { + mimeType: 'audio/ogg' as const, + bytesPrefix: [0x4f, 0x67, 0x67, 0x53], + base64Prefix: 'T2dnUw', + }, + { + mimeType: 'audio/flac' as const, + bytesPrefix: [0x66, 0x4c, 0x61, 0x43], + base64Prefix: 'ZkxhQw', + }, + { + mimeType: 'audio/aac' as const, + bytesPrefix: [0x40, 0x15, 0x00, 0x00], + base64Prefix: 'QBUA', + }, + { + mimeType: 'audio/mp4' as const, + bytesPrefix: [0x66, 0x74, 0x79, 0x70], + base64Prefix: 'ZnR5cA', + }, +] as const; + +export function detectMimeType({ + data, + signatures, +}: { + data: Uint8Array | string; + signatures: typeof audioMimeTypeSignatures | typeof imageMimeTypeSignatures; +}): (typeof signatures)[number]['mimeType'] | undefined { + for (const signature of signatures) { + if ( + typeof data === 'string' + ? data.startsWith(signature.base64Prefix) + : data.length >= signature.bytesPrefix.length && + signature.bytesPrefix.every((byte, index) => data[index] === byte) + ) { + return signature.mimeType; + } + } + + return undefined; +} diff --git a/packages/ai/errors/no-transcript-generated-error.ts b/packages/ai/errors/no-transcript-generated-error.ts new file mode 100644 index 000000000000..9ed11aa1eeb7 --- /dev/null +++ b/packages/ai/errors/no-transcript-generated-error.ts @@ -0,0 +1,20 @@ +import { AISDKError } from '@ai-sdk/provider'; +import { TranscriptionModelResponseMetadata } from '../core/types/transcription-model-response-metadata'; + +/** +Error that is thrown when no transcript was generated. + */ +export class NoTranscriptGeneratedError extends AISDKError { + readonly responses: Array; + + constructor(options: { + responses: Array; + }) { + super({ + name: 'AI_NoTranscriptGeneratedError', + message: 'No transcript generated.', + }); + + this.responses = options.responses; + } +} diff --git a/packages/openai/src/internal/index.ts b/packages/openai/src/internal/index.ts index b2fca011ffb8..c14303526866 100644 --- a/packages/openai/src/internal/index.ts +++ b/packages/openai/src/internal/index.ts @@ -6,4 +6,6 @@ export * from '../openai-embedding-model'; export * from '../openai-embedding-settings'; export * from '../openai-image-model'; export * from '../openai-image-settings'; +export * from '../openai-transcription-model'; +export * from '../openai-transcription-settings'; export * from '../responses/openai-responses-language-model'; diff --git a/packages/openai/src/openai-provider.ts b/packages/openai/src/openai-provider.ts index 8b403073d94a..9304f218975d 100644 --- a/packages/openai/src/openai-provider.ts +++ b/packages/openai/src/openai-provider.ts @@ -1,6 +1,7 @@ import { EmbeddingModelV1, ImageModelV1, + TranscriptionModelV1, LanguageModelV1, ProviderV1, } from '@ai-sdk/provider'; @@ -26,6 +27,8 @@ import { OpenAIImageModelId, OpenAIImageSettings, } from './openai-image-settings'; +import { OpenAITranscriptionModel } from './openai-transcription-model'; +import { OpenAITranscriptionModelId } from './openai-transcription-settings'; import { OpenAIResponsesLanguageModel } from './responses/openai-responses-language-model'; import { OpenAIResponsesModelId } from './responses/openai-responses-settings'; import { openaiTools } from './openai-tools'; @@ -112,6 +115,11 @@ Creates a model for image generation. settings?: OpenAIImageSettings, ): ImageModelV1; + /** +Creates a model for transcription. + */ + transcription(modelId: OpenAITranscriptionModelId): TranscriptionModelV1; + /** OpenAI-specific tools. */ @@ -234,6 +242,14 @@ export function createOpenAI( fetch: options.fetch, }); + const createTranscriptionModel = (modelId: OpenAITranscriptionModelId) => + new OpenAITranscriptionModel(modelId, { + provider: `${providerName}.transcription`, + url: ({ path }) => `${baseURL}${path}`, + headers: getHeaders, + fetch: options.fetch, + }); + const createLanguageModel = ( modelId: OpenAIChatModelId | OpenAICompletionModelId, settings?: OpenAIChatSettings | OpenAICompletionSettings, @@ -281,6 +297,9 @@ export function createOpenAI( provider.image = createImageModel; provider.imageModel = createImageModel; + provider.transcription = createTranscriptionModel; + provider.transcriptionModel = createTranscriptionModel; + provider.tools = openaiTools; return provider as OpenAIProvider; diff --git a/packages/openai/src/openai-transcription-model.test.ts b/packages/openai/src/openai-transcription-model.test.ts new file mode 100644 index 000000000000..cee508de293a --- /dev/null +++ b/packages/openai/src/openai-transcription-model.test.ts @@ -0,0 +1,182 @@ +import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { OpenAITranscriptionModel } from './openai-transcription-model'; +import { createOpenAI } from './openai-provider'; +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; + +const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); +const provider = createOpenAI({ apiKey: 'test-api-key' }); +const model = provider.transcription('whisper-1'); + +const server = createTestServer({ + 'https://api.openai.com/v1/audio/transcriptions': {}, +}); + +describe('doGenerate', () => { + function prepareJsonResponse({ + headers, + }: { + headers?: Record; + } = {}) { + server.urls['https://api.openai.com/v1/audio/transcriptions'].response = { + type: 'json-value', + headers, + body: { + task: 'transcribe', + text: 'Hello from the Vercel AI SDK!', + words: [ + { + word: 'Hello', + start: 0, + end: 5, + }, + { + word: 'from', + start: 5, + end: 10, + }, + { + word: 'the', + start: 10, + end: 15, + }, + { + word: 'Vercel', + start: 15, + end: 20, + }, + { + word: 'AI', + start: 20, + end: 25, + }, + { + word: 'SDK', + start: 25, + end: 30, + }, + { + word: '!', + start: 30, + end: 35, + }, + ], + durationInSeconds: 35, + language: 'en', + _request_id: 'req_1234', + }, + }; + } + + it('should pass the model', async () => { + prepareJsonResponse(); + + await model.doGenerate({ + audio: audioData, + mimeType: 'audio/wav', + }); + + expect(await server.calls[0].requestBodyMultipart).toMatchObject({ + model: 'whisper-1', + }); + }); + + it('should pass headers', async () => { + prepareJsonResponse(); + + const provider = createOpenAI({ + apiKey: 'test-api-key', + organization: 'test-organization', + project: 'test-project', + headers: { + 'Custom-Provider-Header': 'provider-header-value', + }, + }); + + await provider.transcription('whisper-1').doGenerate({ + audio: audioData, + mimeType: 'audio/wav', + headers: { + 'Custom-Request-Header': 'request-header-value', + }, + }); + + expect(server.calls[0].requestHeaders).toMatchObject({ + authorization: 'Bearer test-api-key', + 'content-type': expect.stringMatching( + /^multipart\/form-data; boundary=----formdata-undici-\d+$/, + ), + 'custom-provider-header': 'provider-header-value', + 'custom-request-header': 'request-header-value', + 'openai-organization': 'test-organization', + 'openai-project': 'test-project', + }); + }); + + it('should extract the transcription text', async () => { + prepareJsonResponse(); + + const result = await model.doGenerate({ + audio: audioData, + mimeType: 'audio/wav', + }); + + expect(result.text).toBe('Hello from the Vercel AI SDK!'); + }); + + it('should include response data with timestamp, modelId and headers', async () => { + prepareJsonResponse({ + headers: { + 'x-request-id': 'test-request-id', + 'x-ratelimit-remaining': '123', + }, + }); + + const testDate = new Date(0); + const customModel = new OpenAITranscriptionModel('whisper-1', { + provider: 'test-provider', + url: () => 'https://api.openai.com/v1/audio/transcriptions', + headers: () => ({}), + _internal: { + currentDate: () => testDate, + }, + }); + + const result = await customModel.doGenerate({ + audio: audioData, + mimeType: 'audio/wav', + }); + + expect(result.response).toMatchObject({ + timestamp: testDate, + modelId: 'whisper-1', + headers: { + 'content-type': 'application/json', + 'x-request-id': 'test-request-id', + 'x-ratelimit-remaining': '123', + }, + }); + }); + + it('should use real date when no custom date provider is specified', async () => { + prepareJsonResponse(); + + const testDate = new Date(0); + const customModel = new OpenAITranscriptionModel('whisper-1', { + provider: 'test-provider', + url: () => 'https://api.openai.com/v1/audio/transcriptions', + headers: () => ({}), + _internal: { + currentDate: () => testDate, + }, + }); + + const result = await customModel.doGenerate({ + audio: audioData, + mimeType: 'audio/wav', + }); + + expect(result.response.timestamp.getTime()).toEqual(testDate.getTime()); + expect(result.response.modelId).toBe('whisper-1'); + }); +}); diff --git a/packages/openai/src/openai-transcription-model.ts b/packages/openai/src/openai-transcription-model.ts new file mode 100644 index 000000000000..5720b4932081 --- /dev/null +++ b/packages/openai/src/openai-transcription-model.ts @@ -0,0 +1,259 @@ +import { + TranscriptionModelV1, + TranscriptionModelV1CallOptions, + TranscriptionModelV1CallWarning, +} from '@ai-sdk/provider'; +import { + combineHeaders, + convertBase64ToUint8Array, + createJsonResponseHandler, + parseProviderOptions, + postFormDataToApi, +} from '@ai-sdk/provider-utils'; +import { z } from 'zod'; +import { OpenAIConfig } from './openai-config'; +import { openaiFailedResponseHandler } from './openai-error'; +import { + OpenAITranscriptionModelId, + OpenAITranscriptionModelOptions, +} from './openai-transcription-settings'; + +// https://platform.openai.com/docs/api-reference/audio/createTranscription +const OpenAIProviderOptionsSchema = z.object({ + include: z + .array(z.string()) + .optional() + .describe( + 'Additional information to include in the transcription response.', + ), + language: z + .string() + .optional() + .describe('The language of the input audio in ISO-639-1 format.'), + prompt: z + .string() + .optional() + .describe( + "An optional text to guide the model's style or continue a previous audio segment.", + ), + temperature: z + .number() + .min(0) + .max(1) + .optional() + .default(0) + .describe('The sampling temperature, between 0 and 1.'), + timestampGranularities: z + .array(z.enum(['word', 'segment'])) + .optional() + .default(['segment']) + .describe( + 'The timestamp granularities to populate for this transcription.', + ), +}); + +export type OpenAITranscriptionCallOptions = Omit< + TranscriptionModelV1CallOptions, + 'providerOptions' +> & { + providerOptions?: { + openai?: z.infer; + }; +}; + +interface OpenAITranscriptionModelConfig extends OpenAIConfig { + _internal?: { + currentDate?: () => Date; + }; +} + +// https://platform.openai.com/docs/guides/speech-to-text#supported-languages +const languageMap = { + afrikaans: 'af', + arabic: 'ar', + armenian: 'hy', + azerbaijani: 'az', + belarusian: 'be', + bosnian: 'bs', + bulgarian: 'bg', + catalan: 'ca', + chinese: 'zh', + croatian: 'hr', + czech: 'cs', + danish: 'da', + dutch: 'nl', + english: 'en', + estonian: 'et', + finnish: 'fi', + french: 'fr', + galician: 'gl', + german: 'de', + greek: 'el', + hebrew: 'he', + hindi: 'hi', + hungarian: 'hu', + icelandic: 'is', + indonesian: 'id', + italian: 'it', + japanese: 'ja', + kannada: 'kn', + kazakh: 'kk', + korean: 'ko', + latvian: 'lv', + lithuanian: 'lt', + macedonian: 'mk', + malay: 'ms', + marathi: 'mr', + maori: 'mi', + nepali: 'ne', + norwegian: 'no', + persian: 'fa', + polish: 'pl', + portuguese: 'pt', + romanian: 'ro', + russian: 'ru', + serbian: 'sr', + slovak: 'sk', + slovenian: 'sl', + spanish: 'es', + swahili: 'sw', + swedish: 'sv', + tagalog: 'tl', + tamil: 'ta', + thai: 'th', + turkish: 'tr', + ukrainian: 'uk', + urdu: 'ur', + vietnamese: 'vi', + welsh: 'cy', +}; + +export class OpenAITranscriptionModel implements TranscriptionModelV1 { + readonly specificationVersion = 'v1'; + + get provider(): string { + return this.config.provider; + } + + constructor( + readonly modelId: OpenAITranscriptionModelId, + private readonly config: OpenAITranscriptionModelConfig, + ) {} + + private getArgs({ + audio, + mimeType, + providerOptions, + }: OpenAITranscriptionCallOptions) { + const warnings: TranscriptionModelV1CallWarning[] = []; + + // Parse provider options + const openAIOptions = parseProviderOptions({ + provider: 'openai', + providerOptions, + schema: OpenAIProviderOptionsSchema, + }); + + // Create form data with base fields + const formData = new FormData(); + const blob = + audio instanceof Uint8Array + ? new Blob([audio]) + : new Blob([convertBase64ToUint8Array(audio)]); + + formData.append('model', this.modelId); + formData.append('file', new File([blob], 'audio', { type: mimeType })); + + // Add provider-specific options + if (openAIOptions) { + const transcriptionModelOptions: OpenAITranscriptionModelOptions = { + include: openAIOptions.include, + language: openAIOptions.language, + prompt: openAIOptions.prompt, + temperature: openAIOptions.temperature, + timestamp_granularities: openAIOptions.timestampGranularities, + }; + + for (const key in transcriptionModelOptions) { + const value = + transcriptionModelOptions[ + key as keyof OpenAITranscriptionModelOptions + ]; + if (value !== undefined) { + formData.append(key, value as string); + } + } + } + + return { + formData, + warnings, + }; + } + + async doGenerate( + options: OpenAITranscriptionCallOptions, + ): Promise>> { + const currentDate = this.config._internal?.currentDate?.() ?? new Date(); + const { formData, warnings } = this.getArgs(options); + + const { value: response, responseHeaders } = await postFormDataToApi({ + url: this.config.url({ + path: '/audio/transcriptions', + modelId: this.modelId, + }), + headers: combineHeaders(this.config.headers(), options.headers), + formData, + failedResponseHandler: openaiFailedResponseHandler, + successfulResponseHandler: createJsonResponseHandler( + openaiTranscriptionResponseSchema, + ), + abortSignal: options.abortSignal, + fetch: this.config.fetch, + }); + + let language: string | undefined; + + if (response.language && response.language in languageMap) { + language = languageMap[response.language as keyof typeof languageMap]; + } + + return { + text: response.text, + segments: response.words.map(word => ({ + text: word.word, + startSecond: word.start, + endSecond: word.end, + })), + language, + durationInSeconds: response.duration, + warnings, + response: { + timestamp: currentDate, + modelId: this.modelId, + headers: responseHeaders, + body: response, + }, + + // When using format `verbose_json` on `whisper-1`, OpenAI includes the things like `task` and enhanced `segments` information. + providerMetadata: { + openai: { + transcript: response, + }, + }, + }; + } +} + +const openaiTranscriptionResponseSchema = z.object({ + text: z.string(), + language: z.string().optional(), + duration: z.number().optional(), + words: z.array( + z.object({ + word: z.string(), + start: z.number(), + end: z.number(), + }), + ), +}); diff --git a/packages/openai/src/openai-transcription-settings.ts b/packages/openai/src/openai-transcription-settings.ts new file mode 100644 index 000000000000..f289b603bc08 --- /dev/null +++ b/packages/openai/src/openai-transcription-settings.ts @@ -0,0 +1,34 @@ +export type OpenAITranscriptionModelId = + | 'whisper-1' + | 'gpt-4o-mini-transcribe' + | 'gpt-4o-transcribe' + | (string & {}); + +export type OpenAITranscriptionModelOptions = { + /** + * Additional information to include in the transcription response. + */ + include?: string[]; + + /** + * The language of the input audio in ISO-639-1 format. + */ + language?: string; + + /** + * An optional text to guide the model's style or continue a previous audio segment. + */ + prompt?: string; + + /** + * The sampling temperature, between 0 and 1. + * @default 0 + */ + temperature?: number; + + /** + * The timestamp granularities to populate for this transcription. + * @default ['segment'] + */ + timestamp_granularities?: Array<'word' | 'segment'>; +}; diff --git a/packages/openai/src/transcript-test.mp3 b/packages/openai/src/transcript-test.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6a4cf7b67483c076cebf897b5456f64d0372df90 GIT binary patch literal 40169 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 VY0mcaZ;SOm=>PwZ{$EGnzW{t`1;GFS literal 0 HcmV?d00001 diff --git a/packages/provider-utils/src/post-to-api.ts b/packages/provider-utils/src/post-to-api.ts index 0be7b65e27cd..bafc711eadfe 100644 --- a/packages/provider-utils/src/post-to-api.ts +++ b/packages/provider-utils/src/post-to-api.ts @@ -41,6 +41,36 @@ export const postJsonToApi = async ({ fetch, }); +export const postFormDataToApi = async ({ + url, + headers, + formData, + failedResponseHandler, + successfulResponseHandler, + abortSignal, + fetch, +}: { + url: string; + headers?: Record; + formData: FormData; + failedResponseHandler: ResponseHandler; + successfulResponseHandler: ResponseHandler; + abortSignal?: AbortSignal; + fetch?: FetchFunction; +}) => + postToApi({ + url, + headers, + body: { + content: formData, + values: Object.fromEntries((formData as any).entries()), + }, + failedResponseHandler, + successfulResponseHandler, + abortSignal, + fetch, + }); + export const postToApi = async ({ url, headers = {}, diff --git a/packages/provider-utils/src/test/unified-test-server.ts b/packages/provider-utils/src/test/unified-test-server.ts index b03798379c75..4d48c3de462b 100644 --- a/packages/provider-utils/src/test/unified-test-server.ts +++ b/packages/provider-utils/src/test/unified-test-server.ts @@ -62,6 +62,21 @@ class TestServerCall { return this.request!.text().then(JSON.parse); } + get requestBodyMultipart() { + return this.request!.headers.get('content-type')?.startsWith( + 'multipart/form-data', + ) + ? // For multipart/form-data, return the form data entries as an object + this.request!.formData().then(formData => { + const entries: Record = {}; + formData.forEach((value, key) => { + entries[key] = value; + }); + return entries; + }) + : null; + } + get requestCredentials() { return this.request!.credentials; } diff --git a/packages/provider/src/index.ts b/packages/provider/src/index.ts index 1e258cf9baa8..3de87e64e606 100644 --- a/packages/provider/src/index.ts +++ b/packages/provider/src/index.ts @@ -4,5 +4,6 @@ export * from './image-model/index'; export * from './json-value/index'; export * from './language-model/index'; export * from './provider/index'; +export * from './transcription-model/index'; export type { JSONSchema7, JSONSchema7Definition } from 'json-schema'; diff --git a/packages/provider/src/provider/v1/provider-v1.ts b/packages/provider/src/provider/v1/provider-v1.ts index 1e813d25497a..bf3383e1db33 100644 --- a/packages/provider/src/provider/v1/provider-v1.ts +++ b/packages/provider/src/provider/v1/provider-v1.ts @@ -1,7 +1,7 @@ import { EmbeddingModelV1 } from '../../embedding-model/v1/embedding-model-v1'; import { ImageModelV1 } from '../../image-model/v1/image-model-v1'; import { LanguageModelV1 } from '../../language-model/v1/language-model-v1'; - +import { TranscriptionModelV1 } from '../../transcription-model/v1/transcription-model-v1'; /** * Provider for language, text embedding, and image generation models. */ @@ -39,4 +39,14 @@ The model id is then passed to the provider function to get the model. @returns {ImageModel} The image model associated with the id */ readonly imageModel?: (modelId: string) => ImageModelV1; + + /** +Returns the transcription model with the given id. +The model id is then passed to the provider function to get the model. + +@param {string} modelId - The id of the model to return. + +@returns {TranscriptionModel} The transcription model associated with the id +*/ + readonly transcriptionModel?: (modelId: string) => TranscriptionModelV1; } diff --git a/packages/provider/src/transcription-model/index.ts b/packages/provider/src/transcription-model/index.ts new file mode 100644 index 000000000000..e69fb44d6835 --- /dev/null +++ b/packages/provider/src/transcription-model/index.ts @@ -0,0 +1 @@ +export * from './v1/index'; diff --git a/packages/provider/src/transcription-model/v1/index.ts b/packages/provider/src/transcription-model/v1/index.ts new file mode 100644 index 000000000000..ac8635de6935 --- /dev/null +++ b/packages/provider/src/transcription-model/v1/index.ts @@ -0,0 +1,3 @@ +export type { TranscriptionModelV1 } from './transcription-model-v1'; +export type { TranscriptionModelV1CallOptions } from './transcription-model-v1-call-options'; +export type { TranscriptionModelV1CallWarning } from './transcription-model-v1-call-warning'; diff --git a/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts b/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts new file mode 100644 index 000000000000..a2164a14bba6 --- /dev/null +++ b/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts @@ -0,0 +1,46 @@ +import { JSONValue } from '../../json-value/json-value'; + +type TranscriptionModelV1ProviderOptions = Record< + string, + Record +>; + +export type TranscriptionModelV1CallOptions = { + /** +Audio data to transcribe. +Accepts a `Uint8Array` or `string`, where `string` is a base64 encoded audio file. + */ + audio: Uint8Array | string; + + /** + The MIME type of the audio data. + */ + mimeType: string; + + /** +Additional provider-specific options that are passed through to the provider +as body parameters. + +The outer record is keyed by the provider name, and the inner +record is keyed by the provider-specific metadata key. +```ts +{ +"openai": { +"timestampGranularities": ["word"] +} +} +``` + */ + providerOptions?: TranscriptionModelV1ProviderOptions; + + /** +Abort signal for cancelling the operation. + */ + abortSignal?: AbortSignal; + + /** +Additional HTTP headers to be sent with the request. +Only applicable for HTTP-based providers. + */ + headers?: Record; +}; diff --git a/packages/provider/src/transcription-model/v1/transcription-model-v1-call-warning.ts b/packages/provider/src/transcription-model/v1/transcription-model-v1-call-warning.ts new file mode 100644 index 000000000000..4c4797309c25 --- /dev/null +++ b/packages/provider/src/transcription-model/v1/transcription-model-v1-call-warning.ts @@ -0,0 +1,16 @@ +import { TranscriptionModelV1CallOptions } from './transcription-model-v1-call-options'; + +/** +Warning from the model provider for this call. The call will proceed, but e.g. +some settings might not be supported, which can lead to suboptimal results. + */ +export type TranscriptionModelV1CallWarning = + | { + type: 'unsupported-setting'; + setting: keyof TranscriptionModelV1CallOptions; + details?: string; + } + | { + type: 'other'; + message: string; + }; diff --git a/packages/provider/src/transcription-model/v1/transcription-model-v1.ts b/packages/provider/src/transcription-model/v1/transcription-model-v1.ts new file mode 100644 index 000000000000..73f7811c24e4 --- /dev/null +++ b/packages/provider/src/transcription-model/v1/transcription-model-v1.ts @@ -0,0 +1,116 @@ +import { JSONValue } from '../../json-value'; +import { TranscriptionModelV1CallOptions } from './transcription-model-v1-call-options'; +import { TranscriptionModelV1CallWarning } from './transcription-model-v1-call-warning'; + +/** +Transcription model specification version 1. + */ +export type TranscriptionModelV1 = { + /** +The transcription model must specify which transcription model interface +version it implements. This will allow us to evolve the transcription +model interface and retain backwards compatibility. The different +implementation versions can be handled as a discriminated union +on our side. + */ + readonly specificationVersion: 'v1'; + + /** +Name of the provider for logging purposes. + */ + readonly provider: string; + + /** +Provider-specific model ID for logging purposes. + */ + readonly modelId: string; + + /** +Generates a transcript. + */ + doGenerate(options: TranscriptionModelV1CallOptions): PromiseLike<{ + /** + * The complete transcribed text from the audio. + */ + text: string; + + /** + * Array of transcript segments with timing information. + * Each segment represents a portion of the transcribed text with start and end times. + */ + segments: Array<{ + /** + * The text content of this segment. + */ + text: string; + /** + * The start time of this segment in seconds. + */ + startSecond: number; + /** + * The end time of this segment in seconds. + */ + endSecond: number; + }>; + + /** + * The detected language of the audio content, as an ISO-639-1 code (e.g., 'en' for English). + * May be undefined if the language couldn't be detected. + */ + language: string | undefined; + + /** + * The total duration of the audio file in seconds. + * May be undefined if the duration couldn't be determined. + */ + durationInSeconds: number | undefined; + + /** +Warnings for the call, e.g. unsupported settings. + */ + warnings: Array; + + /** +Optional request information for telemetry and debugging purposes. + */ + request?: { + /** +Raw request HTTP body that was sent to the provider API as a string (JSON should be stringified). +Non-HTTP(s) providers should not set this. + */ + body?: string; + }; + + /** +Response information for telemetry and debugging purposes. + */ + response: { + /** +Timestamp for the start of the generated response. + */ + timestamp: Date; + + /** +The ID of the response model that was used to generate the response. + */ + modelId: string; + + /** +Response headers. + */ + headers: Record | undefined; + + /** +Response body. + */ + body?: unknown; + }; + + /** +Additional provider-specific metadata. They are passed through +from the provider to the AI SDK and enable provider-specific +results that can be fully encapsulated in the provider. + */ + providerMetadata?: Record>; + }>; +}; From c96e093113e2fe0f957cd4699e2eed38239de2d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:57:26 +0200 Subject: [PATCH 034/191] Version Packages (#5590) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/fix-env-mutation.md | 5 - .changeset/happy-kangaroos-roll.md | 8 - examples/ai-core/package.json | 46 +-- examples/express/package.json | 4 +- examples/fastify/package.json | 4 +- examples/hono/package.json | 4 +- examples/mcp/package.json | 4 +- examples/nest/package.json | 4 +- examples/next-fastapi/package.json | 6 +- examples/next-google-vertex/package.json | 4 +- examples/next-langchain/package.json | 4 +- .../package.json | 6 +- examples/next-openai-pages/package.json | 6 +- .../next-openai-telemetry-sentry/package.json | 6 +- examples/next-openai-telemetry/package.json | 6 +- .../package.json | 6 +- examples/next-openai/package.json | 20 +- examples/node-http-server/package.json | 4 +- examples/nuxt-openai/package.json | 6 +- examples/solidstart-openai/package.json | 8 +- examples/sveltekit-openai/package.json | 10 +- packages/ai/CHANGELOG.md | 12 + packages/ai/package.json | 10 +- .../ai/tests/e2e/next-server/CHANGELOG.md | 8 + packages/amazon-bedrock/CHANGELOG.md | 8 + packages/amazon-bedrock/package.json | 6 +- packages/anthropic/CHANGELOG.md | 8 + packages/anthropic/package.json | 6 +- packages/azure/CHANGELOG.md | 9 + packages/azure/package.json | 8 +- packages/cerebras/CHANGELOG.md | 9 + packages/cerebras/package.json | 8 +- packages/cohere/CHANGELOG.md | 8 + packages/cohere/package.json | 6 +- packages/deepinfra/CHANGELOG.md | 9 + packages/deepinfra/package.json | 8 +- packages/deepseek/CHANGELOG.md | 9 + packages/deepseek/package.json | 8 +- packages/fal/CHANGELOG.md | 8 + packages/fal/package.json | 6 +- packages/fireworks/CHANGELOG.md | 9 + packages/fireworks/package.json | 8 +- packages/google-vertex/CHANGELOG.md | 10 + packages/google-vertex/package.json | 10 +- packages/google/CHANGELOG.md | 8 + packages/google/package.json | 6 +- packages/groq/CHANGELOG.md | 8 + packages/groq/package.json | 6 +- packages/luma/CHANGELOG.md | 8 + packages/luma/package.json | 6 +- packages/mistral/CHANGELOG.md | 8 + packages/mistral/package.json | 6 +- packages/openai-compatible/CHANGELOG.md | 8 + packages/openai-compatible/package.json | 6 +- packages/openai/CHANGELOG.md | 9 + packages/openai/package.json | 6 +- packages/perplexity/CHANGELOG.md | 8 + packages/perplexity/package.json | 6 +- packages/provider-utils/CHANGELOG.md | 8 + packages/provider-utils/package.json | 4 +- packages/provider/CHANGELOG.md | 6 + packages/provider/package.json | 2 +- packages/react/CHANGELOG.md | 8 + packages/react/package.json | 6 +- packages/replicate/CHANGELOG.md | 8 + packages/replicate/package.json | 6 +- packages/solid/CHANGELOG.md | 8 + packages/solid/package.json | 6 +- packages/svelte/CHANGELOG.md | 8 + packages/svelte/package.json | 6 +- packages/togetherai/CHANGELOG.md | 9 + packages/togetherai/package.json | 8 +- packages/ui-utils/CHANGELOG.md | 8 + packages/ui-utils/package.json | 6 +- packages/valibot/CHANGELOG.md | 8 + packages/valibot/package.json | 4 +- packages/vue/CHANGELOG.md | 8 + packages/vue/package.json | 6 +- packages/xai/CHANGELOG.md | 9 + packages/xai/package.json | 8 +- pnpm-lock.yaml | 302 +++++++++--------- 81 files changed, 576 insertions(+), 337 deletions(-) delete mode 100644 .changeset/fix-env-mutation.md delete mode 100644 .changeset/happy-kangaroos-roll.md diff --git a/.changeset/fix-env-mutation.md b/.changeset/fix-env-mutation.md deleted file mode 100644 index 86cd47b5e2d3..000000000000 --- a/.changeset/fix-env-mutation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix (ai/mcp): prevent mutation of customEnv diff --git a/.changeset/happy-kangaroos-roll.md b/.changeset/happy-kangaroos-roll.md deleted file mode 100644 index 8b0e54911d9c..000000000000 --- a/.changeset/happy-kangaroos-roll.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@ai-sdk/provider-utils': patch -'@ai-sdk/provider': patch -'@ai-sdk/openai': patch -'ai': patch ---- - -feat: add transcription with experimental_transcribe diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 43af23a0e595..4e3aad460543 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -3,33 +3,33 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/amazon-bedrock": "2.2.5", - "@ai-sdk/anthropic": "1.2.6", - "@ai-sdk/azure": "1.3.8", - "@ai-sdk/cerebras": "0.2.6", - "@ai-sdk/cohere": "1.2.5", - "@ai-sdk/deepinfra": "0.2.7", - "@ai-sdk/deepseek": "0.2.6", - "@ai-sdk/fal": "0.1.5", - "@ai-sdk/fireworks": "0.2.6", - "@ai-sdk/google": "1.2.8", - "@ai-sdk/google-vertex": "2.2.11", - "@ai-sdk/groq": "1.2.5", - "@ai-sdk/luma": "0.1.4", - "@ai-sdk/mistral": "1.2.4", - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/perplexity": "1.1.4", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/replicate": "0.2.4", - "@ai-sdk/togetherai": "0.2.6", - "@ai-sdk/xai": "1.2.7", - "@ai-sdk/valibot": "0.1.14", + "@ai-sdk/amazon-bedrock": "2.2.6", + "@ai-sdk/anthropic": "1.2.7", + "@ai-sdk/azure": "1.3.9", + "@ai-sdk/cerebras": "0.2.7", + "@ai-sdk/cohere": "1.2.6", + "@ai-sdk/deepinfra": "0.2.8", + "@ai-sdk/deepseek": "0.2.7", + "@ai-sdk/fal": "0.1.6", + "@ai-sdk/fireworks": "0.2.7", + "@ai-sdk/google": "1.2.9", + "@ai-sdk/google-vertex": "2.2.12", + "@ai-sdk/groq": "1.2.6", + "@ai-sdk/luma": "0.1.5", + "@ai-sdk/mistral": "1.2.5", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/perplexity": "1.1.5", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/replicate": "0.2.5", + "@ai-sdk/togetherai": "0.2.7", + "@ai-sdk/xai": "1.2.8", + "@ai-sdk/valibot": "0.1.15", "@google/generative-ai": "0.21.0", "@opentelemetry/auto-instrumentations-node": "0.54.0", "@opentelemetry/sdk-node": "0.54.2", "@opentelemetry/sdk-trace-node": "1.28.0", - "ai": "4.3.2", + "ai": "4.3.3", "dotenv": "16.4.5", "image-type": "^5.2.0", "mathjs": "14.0.0", diff --git a/examples/express/package.json b/examples/express/package.json index c427cfb9fa8b..bc1789a9d4f7 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -7,8 +7,8 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "ai": "4.3.2", + "@ai-sdk/openai": "1.3.8", + "ai": "4.3.3", "dotenv": "16.4.5", "express": "5.0.1" }, diff --git a/examples/fastify/package.json b/examples/fastify/package.json index 26ffb3a76101..e69f76841f49 100644 --- a/examples/fastify/package.json +++ b/examples/fastify/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "ai": "4.3.2", + "@ai-sdk/openai": "1.3.8", + "ai": "4.3.3", "dotenv": "16.4.5", "fastify": "5.1.0" }, diff --git a/examples/hono/package.json b/examples/hono/package.json index 1566490ef551..068fb1ccbe0d 100644 --- a/examples/hono/package.json +++ b/examples/hono/package.json @@ -3,9 +3,9 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.7", + "@ai-sdk/openai": "1.3.8", "@hono/node-server": "1.13.7", - "ai": "4.3.2", + "ai": "4.3.3", "dotenv": "16.4.5", "hono": "4.6.9" }, diff --git a/examples/mcp/package.json b/examples/mcp/package.json index 141d22fb54f6..21f3e23b9b75 100644 --- a/examples/mcp/package.json +++ b/examples/mcp/package.json @@ -12,9 +12,9 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", + "@ai-sdk/openai": "1.3.8", "@modelcontextprotocol/sdk": "^1.7.0", - "ai": "4.3.2", + "ai": "4.3.3", "dotenv": "16.4.5", "express": "5.0.1", "zod": "3.23.8" diff --git a/examples/nest/package.json b/examples/nest/package.json index 8effe9dc76df..f849b8ff0dd1 100644 --- a/examples/nest/package.json +++ b/examples/nest/package.json @@ -15,11 +15,11 @@ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", + "@ai-sdk/openai": "1.3.8", "@nestjs/common": "^10.4.15", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.4.9", - "ai": "4.3.2", + "ai": "4.3.3", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/examples/next-fastapi/package.json b/examples/next-fastapi/package.json index ab8324aebfe4..d8f0fa6be8d0 100644 --- a/examples/next-fastapi/package.json +++ b/examples/next-fastapi/package.json @@ -11,9 +11,9 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/ui-utils": "1.2.5", - "@ai-sdk/react": "1.2.6", - "ai": "4.3.2", + "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/react": "1.2.7", + "ai": "4.3.3", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index ef7eed9bcf35..a78e6ec21b3b 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,8 +9,8 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.11", - "ai": "4.3.2", + "@ai-sdk/google-vertex": "2.2.12", + "ai": "4.3.3", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-langchain/package.json b/examples/next-langchain/package.json index 2bda536aa802..8650065f099d 100644 --- a/examples/next-langchain/package.json +++ b/examples/next-langchain/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/react": "1.2.6", + "@ai-sdk/react": "1.2.7", "@langchain/openai": "0.0.28", "@langchain/core": "0.1.63", - "ai": "4.3.2", + "ai": "4.3.3", "langchain": "0.1.36", "next": "latest", "react": "^18", diff --git a/examples/next-openai-kasada-bot-protection/package.json b/examples/next-openai-kasada-bot-protection/package.json index 1181ab92df89..11ff64ab6318 100644 --- a/examples/next-openai-kasada-bot-protection/package.json +++ b/examples/next-openai-kasada-bot-protection/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/react": "1.2.6", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/react": "1.2.7", "@vercel/functions": "latest", - "ai": "4.3.2", + "ai": "4.3.3", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai-pages/package.json b/examples/next-openai-pages/package.json index d17fb4e370c0..592c45c4a5d4 100644 --- a/examples/next-openai-pages/package.json +++ b/examples/next-openai-pages/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/react": "1.2.6", - "ai": "4.3.2", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/react": "1.2.7", + "ai": "4.3.3", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry-sentry/package.json b/examples/next-openai-telemetry-sentry/package.json index 5fc0f2fa5335..67a56f4f526b 100644 --- a/examples/next-openai-telemetry-sentry/package.json +++ b/examples/next-openai-telemetry-sentry/package.json @@ -9,15 +9,15 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/react": "1.2.6", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/react": "1.2.7", "@opentelemetry/api-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@opentelemetry/sdk-logs": "0.55.0", "@sentry/nextjs": "^8.42.0", "@sentry/opentelemetry": "8.22.0", "@vercel/otel": "1.10.0", - "ai": "4.3.2", + "ai": "4.3.3", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry/package.json b/examples/next-openai-telemetry/package.json index bab1a1fb5a68..d3b4f4c36be3 100644 --- a/examples/next-openai-telemetry/package.json +++ b/examples/next-openai-telemetry/package.json @@ -9,13 +9,13 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/react": "1.2.6", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/react": "1.2.7", "@opentelemetry/api-logs": "0.55.0", "@opentelemetry/sdk-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@vercel/otel": "1.10.0", - "ai": "4.3.2", + "ai": "4.3.3", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-upstash-rate-limits/package.json b/examples/next-openai-upstash-rate-limits/package.json index c234fa23da80..8f4ddff50de4 100644 --- a/examples/next-openai-upstash-rate-limits/package.json +++ b/examples/next-openai-upstash-rate-limits/package.json @@ -9,11 +9,11 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/react": "1.2.6", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/react": "1.2.7", "@upstash/ratelimit": "^0.4.3", "@vercel/kv": "^0.2.2", - "ai": "4.3.2", + "ai": "4.3.3", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 50d0a844ebb7..575cba73c73d 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -9,17 +9,17 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/anthropic": "1.2.6", - "@ai-sdk/deepseek": "0.2.6", - "@ai-sdk/fireworks": "0.2.6", - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/google": "1.2.8", - "@ai-sdk/google-vertex": "2.2.11", - "@ai-sdk/perplexity": "1.1.4", - "@ai-sdk/ui-utils": "1.2.5", - "@ai-sdk/react": "1.2.6", + "@ai-sdk/anthropic": "1.2.7", + "@ai-sdk/deepseek": "0.2.7", + "@ai-sdk/fireworks": "0.2.7", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/google": "1.2.9", + "@ai-sdk/google-vertex": "2.2.12", + "@ai-sdk/perplexity": "1.1.5", + "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/react": "1.2.7", "@vercel/blob": "^0.26.0", - "ai": "4.3.2", + "ai": "4.3.3", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/node-http-server/package.json b/examples/node-http-server/package.json index 77fd231461fb..18fe0887bc35 100644 --- a/examples/node-http-server/package.json +++ b/examples/node-http-server/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "ai": "4.3.2", + "@ai-sdk/openai": "1.3.8", + "ai": "4.3.3", "dotenv": "16.4.5", "zod": "3.23.8", "zod-to-json-schema": "3.23.5" diff --git a/examples/nuxt-openai/package.json b/examples/nuxt-openai/package.json index 2d544dc7091c..b79a87664dbd 100644 --- a/examples/nuxt-openai/package.json +++ b/examples/nuxt-openai/package.json @@ -9,9 +9,9 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@ai-sdk/vue": "1.2.5", - "@ai-sdk/openai": "1.3.7", - "ai": "4.3.2", + "@ai-sdk/vue": "1.2.6", + "@ai-sdk/openai": "1.3.8", + "ai": "4.3.3", "zod": "3.23.8" }, "devDependencies": { diff --git a/examples/solidstart-openai/package.json b/examples/solidstart-openai/package.json index 8506c420a6b6..9bbb6d0e707b 100644 --- a/examples/solidstart-openai/package.json +++ b/examples/solidstart-openai/package.json @@ -14,13 +14,13 @@ "vinxi": "^0.4.3" }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/solid": "1.2.7", - "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/solid": "1.2.8", + "@ai-sdk/ui-utils": "1.2.6", "@solidjs/meta": "0.29.4", "@solidjs/router": "^0.15.1", "@solidjs/start": "^1.0.10", - "ai": "4.3.2", + "ai": "4.3.3", "solid-js": "^1.9.3", "zod": "^3.23.8" }, diff --git a/examples/sveltekit-openai/package.json b/examples/sveltekit-openai/package.json index 3ca39062ea28..da6c8ee0564b 100644 --- a/examples/sveltekit-openai/package.json +++ b/examples/sveltekit-openai/package.json @@ -16,16 +16,16 @@ }, "type": "module", "devDependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/provider-utils": "2.2.4", - "@ai-sdk/svelte": "2.1.6", - "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/svelte": "2.1.7", + "@ai-sdk/ui-utils": "1.2.6", "@eslint/compat": "^1.2.5", "@eslint/js": "^9.18.0", "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", - "ai": "4.3.2", + "ai": "4.3.3", "autoprefixer": "^10.4.20", "bits-ui": "^1.3.9", "clsx": "^2.1.1", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 804a06bef4dc..d74cf3e26ba1 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,17 @@ # ai +## 4.3.3 + +### Patch Changes + +- 3e88f4d: fix (ai/mcp): prevent mutation of customEnv +- c21fa6d: feat: add transcription with experimental_transcribe +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/react@1.2.7 + - @ai-sdk/ui-utils@1.2.6 + ## 4.3.2 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 127efd261485..24248eee8dfd 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "4.3.2", + "version": "4.3.3", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, @@ -66,10 +66,10 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4", - "@ai-sdk/react": "1.2.6", - "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/react": "1.2.7", + "@ai-sdk/ui-utils": "1.2.6", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, diff --git a/packages/ai/tests/e2e/next-server/CHANGELOG.md b/packages/ai/tests/e2e/next-server/CHANGELOG.md index 5db88ca560ee..f6f2a2901b1d 100644 --- a/packages/ai/tests/e2e/next-server/CHANGELOG.md +++ b/packages/ai/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,14 @@ ### Patch Changes +- Updated dependencies [3e88f4d] +- Updated dependencies [c21fa6d] + - ai@4.3.3 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [665a567] - ai@4.3.2 diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index edbfa4edebad..adb6f44877a4 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/amazon-bedrock +## 2.2.6 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 2.2.5 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 2d3995352c5b..94eecd8218c2 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "2.2.5", + "version": "2.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index ca68882a10ad..34c9988cf6e9 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/anthropic +## 1.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.2.6 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 14db52beccb5..72e839254b11 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -37,8 +37,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index 4f3b3a25637b..6708bc5cf8e2 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/azure +## 1.3.9 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai@1.3.8 + ## 1.3.8 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 4b9a93edac5d..24cd070cd812 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "1.3.8", + "version": "1.3.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,9 +31,9 @@ } }, "dependencies": { - "@ai-sdk/openai": "1.3.7", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai": "1.3.8", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 6b6e90c5f279..0aaf17cc1b8e 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/cerebras +## 0.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai-compatible@0.2.7 + ## 0.2.6 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index d8f66b4d33dd..af760f7b705f 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index a646ffa23614..769f2b927a31 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/cohere +## 1.2.6 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.2.5 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index 540ab691ec8b..f96e12735f57 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,8 +31,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index d6114b21b08f..3c90f86a9c09 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/deepinfra +## 0.2.8 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai-compatible@0.2.7 + ## 0.2.7 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 63ad97c2cf11..0f62d27fd9d5 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "0.2.7", + "version": "0.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 419edbd5f270..f65decc316f3 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/deepseek +## 0.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai-compatible@0.2.7 + ## 0.2.6 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index 7101f434b2c5..924ec6c20f13 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index 265cf4119b55..8013b6febe15 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/fal +## 0.1.6 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 0.1.5 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index d20e74fb9780..50746fa0ae59 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "0.1.5", + "version": "0.1.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index ad64e056e073..f25a1757145e 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/fireworks +## 0.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai-compatible@0.2.7 + ## 0.2.6 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index d3aa1833ddec..41b09501754f 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index 29099e94d540..e1c28ab4de2f 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/google-vertex +## 2.2.12 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/anthropic@1.2.7 + - @ai-sdk/google@1.2.9 + ## 2.2.11 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 527178a401ce..a1f42a44f02f 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.11", + "version": "2.2.12", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -49,10 +49,10 @@ } }, "dependencies": { - "@ai-sdk/anthropic": "1.2.6", - "@ai-sdk/google": "1.2.8", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/anthropic": "1.2.7", + "@ai-sdk/google": "1.2.9", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5", "google-auth-library": "^9.15.0" }, "devDependencies": { diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 191585ab92ad..02320cf753f3 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/google +## 1.2.9 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.2.8 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index d4ee7ce4f4bd..59f2222e6bd1 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "1.2.8", + "version": "1.2.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,8 +38,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index dfebef8742ed..35a6070ee870 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/groq +## 1.2.6 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.2.5 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index af39aaa1e140..755d737f1d70 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,8 +31,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index a6214f2b7559..e73a74c7abd0 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/luma +## 0.1.5 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 0.1.4 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index f8d060d0e8d4..cdf0343fc369 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "0.1.4", + "version": "0.1.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index 331df847daa1..e3489dfe9023 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/mistral +## 1.2.5 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.2.4 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 8d2c56c7580f..ce1ae0cac08b 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "1.2.4", + "version": "1.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,8 +31,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index ab2340f20e4e..cf9d8f540276 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/openai-compatible +## 0.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 0.2.6 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index 973520935c9b..e577c1b64c81 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,8 +38,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index c52910778734..b930955c2ebc 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/openai +## 1.3.8 + +### Patch Changes + +- c21fa6d: feat: add transcription with experimental_transcribe +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.3.7 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index 3a40b134b704..8e2f264f73fd 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "1.3.7", + "version": "1.3.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,8 +38,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index b5a785320f64..df4343c742be 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/perplexity +## 1.1.5 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.1.4 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index 6fb6e30c48fd..5d20339afa47 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "1.1.4", + "version": "1.1.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index b6a727c16719..8552ce5ddbbc 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/provider-utils +## 2.2.5 + +### Patch Changes + +- c21fa6d: feat: add transcription with experimental_transcribe +- Updated dependencies [c21fa6d] + - @ai-sdk/provider@1.1.1 + ## 2.2.4 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index f51cef7e9d4d..05c542cc6cf3 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "2.2.4", + "version": "2.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", + "@ai-sdk/provider": "1.1.1", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, diff --git a/packages/provider/CHANGELOG.md b/packages/provider/CHANGELOG.md index f57f90edb9bc..fac9d79ae646 100644 --- a/packages/provider/CHANGELOG.md +++ b/packages/provider/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider +## 1.1.1 + +### Patch Changes + +- c21fa6d: feat: add transcription with experimental_transcribe + ## 1.1.0 ### Minor Changes diff --git a/packages/provider/package.json b/packages/provider/package.json index 4f340332f119..4c8a5215e825 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider", - "version": "1.1.0", + "version": "1.1.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 2b5bee4e1e0a..4ad7efda55dd 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/react +## 1.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/ui-utils@1.2.6 + ## 1.2.6 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 8c73bbef2b4a..47684a388161 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.4", - "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/ui-utils": "1.2.6", "swr": "^2.2.5", "throttleit": "2.1.0" }, diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index 6006620b3a1a..b07860b852e4 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/replicate +## 0.2.5 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 0.2.4 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index 239c73469084..df5c6a66a6fc 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "0.2.4", + "version": "0.2.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/solid/CHANGELOG.md b/packages/solid/CHANGELOG.md index cdba658fef2a..36e4a79f4672 100644 --- a/packages/solid/CHANGELOG.md +++ b/packages/solid/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/solid +## 1.2.8 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/ui-utils@1.2.6 + ## 1.2.7 ### Patch Changes diff --git a/packages/solid/package.json b/packages/solid/package.json index c2991a6f8ba4..fee6623c9480 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/solid", - "version": "1.2.7", + "version": "1.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.4", - "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/ui-utils": "1.2.6", "@solid-primitives/trigger": "^1.1.0", "zod": "^3.23.8" }, diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index fe709bb917aa..affc4adf16b4 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/svelte +## 2.1.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/ui-utils@1.2.6 + ## 2.1.6 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index c74f7e3952d7..fad45dce6ffd 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "2.1.6", + "version": "2.1.7", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", @@ -51,8 +51,8 @@ } }, "dependencies": { - "@ai-sdk/provider-utils": "2.2.4", - "@ai-sdk/ui-utils": "1.2.5" + "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/ui-utils": "1.2.6" }, "devDependencies": { "@eslint/compat": "^1.2.5", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index f0ddcb0bb0eb..11b664732b0f 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/togetherai +## 0.2.7 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai-compatible@0.2.7 + ## 0.2.6 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index 1eef028d4944..a78f13eb0497 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/ui-utils/CHANGELOG.md b/packages/ui-utils/CHANGELOG.md index 187b4dbfe59c..bc03ef8c7422 100644 --- a/packages/ui-utils/CHANGELOG.md +++ b/packages/ui-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/ui-utils +## 1.2.6 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + ## 1.2.5 ### Patch Changes diff --git a/packages/ui-utils/package.json b/packages/ui-utils/package.json index 9447da7631a8..c71d3952930b 100644 --- a/packages/ui-utils/package.json +++ b/packages/ui-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/ui-utils", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -37,8 +37,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5", "zod-to-json-schema": "^3.24.1" }, "devDependencies": { diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 6d73cd8d83bf..60e8bf050468 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/valibot +## 0.1.15 + +### Patch Changes + +- Updated dependencies [3e88f4d] +- Updated dependencies [c21fa6d] + - ai@4.3.3 + ## 0.1.14 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index 5cfbdd5fb478..25a4ce654839 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "0.1.14", + "version": "0.1.15", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -27,7 +27,7 @@ } }, "dependencies": { - "ai": "4.3.2" + "ai": "4.3.3" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index ba8cf4aed113..06239a5ad5ea 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/vue +## 1.2.6 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/ui-utils@1.2.6 + ## 1.2.5 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 88c61894a603..9a51c4ed9ca4 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.4", - "@ai-sdk/ui-utils": "1.2.5", + "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/ui-utils": "1.2.6", "swrv": "^1.0.4" }, "devDependencies": { diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index d530b70855a4..1656ead3a428 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/xai +## 1.2.8 + +### Patch Changes + +- Updated dependencies [c21fa6d] + - @ai-sdk/provider-utils@2.2.5 + - @ai-sdk/provider@1.1.1 + - @ai-sdk/openai-compatible@0.2.7 + ## 1.2.7 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 83e9cfdcd568..82c6667e12b1 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "1.2.7", + "version": "1.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.6", - "@ai-sdk/provider": "1.1.0", - "@ai-sdk/provider-utils": "2.2.4" + "@ai-sdk/openai-compatible": "0.2.7", + "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider-utils": "2.2.5" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4bc32549c63e..d5e968f89f56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,70 +60,70 @@ importers: examples/ai-core: dependencies: '@ai-sdk/amazon-bedrock': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../../packages/amazon-bedrock '@ai-sdk/anthropic': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/anthropic '@ai-sdk/azure': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/azure '@ai-sdk/cerebras': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/cerebras '@ai-sdk/cohere': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/cohere '@ai-sdk/deepinfra': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/deepinfra '@ai-sdk/deepseek': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/deepseek '@ai-sdk/fal': - specifier: 0.1.5 + specifier: 0.1.6 version: link:../../packages/fal '@ai-sdk/fireworks': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.11 + specifier: 2.2.12 version: link:../../packages/google-vertex '@ai-sdk/groq': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/groq '@ai-sdk/luma': - specifier: 0.1.4 + specifier: 0.1.5 version: link:../../packages/luma '@ai-sdk/mistral': - specifier: 1.2.4 + specifier: 1.2.5 version: link:../../packages/mistral '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/openai-compatible '@ai-sdk/perplexity': - specifier: 1.1.4 + specifier: 1.1.5 version: link:../../packages/perplexity '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../../packages/provider '@ai-sdk/replicate': - specifier: 0.2.4 + specifier: 0.2.5 version: link:../../packages/replicate '@ai-sdk/togetherai': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/togetherai '@ai-sdk/valibot': - specifier: 0.1.14 + specifier: 0.1.15 version: link:../../packages/valibot '@ai-sdk/xai': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/xai '@google/generative-ai': specifier: 0.21.0 @@ -138,7 +138,7 @@ importers: specifier: 1.28.0 version: 1.28.0(@opentelemetry/api@1.9.0) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -178,10 +178,10 @@ importers: examples/express: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -206,10 +206,10 @@ importers: examples/fastify: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -231,13 +231,13 @@ importers: examples/hono: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@hono/node-server': specifier: 1.13.7 version: 1.13.7(hono@4.6.9) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -259,13 +259,13 @@ importers: examples/mcp: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@modelcontextprotocol/sdk': specifier: ^1.7.0 version: 1.7.0 ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -293,7 +293,7 @@ importers: examples/nest: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@nestjs/common': specifier: ^10.4.15 @@ -305,7 +305,7 @@ importers: specifier: ^10.4.9 version: 10.4.9(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai reflect-metadata: specifier: ^0.2.0 @@ -381,13 +381,13 @@ importers: examples/next-fastapi: dependencies: '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/ui-utils ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -436,10 +436,10 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.11 + specifier: 2.2.12 version: link:../../packages/google-vertex ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -479,7 +479,7 @@ importers: examples/next-langchain: dependencies: '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@langchain/core': specifier: 0.1.63 @@ -488,7 +488,7 @@ importers: specifier: 0.0.28 version: 0.0.28 ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai langchain: specifier: 0.1.36 @@ -534,37 +534,37 @@ importers: examples/next-openai: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/anthropic '@ai-sdk/deepseek': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/deepseek '@ai-sdk/fireworks': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.11 + specifier: 2.2.12 version: link:../../packages/google-vertex '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/perplexity': - specifier: 1.1.4 + specifier: 1.1.5 version: link:../../packages/perplexity '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/ui-utils '@vercel/blob': specifier: ^0.26.0 version: 0.26.0 ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai next: specifier: latest @@ -616,16 +616,16 @@ importers: examples/next-openai-kasada-bot-protection: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@vercel/functions': specifier: latest version: 2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai next: specifier: latest @@ -671,13 +671,13 @@ importers: examples/next-openai-pages: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai next: specifier: latest @@ -726,10 +726,10 @@ importers: examples/next-openai-telemetry: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@opentelemetry/api-logs': specifier: 0.55.0 @@ -744,7 +744,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.29.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai next: specifier: latest @@ -793,10 +793,10 @@ importers: examples/next-openai-telemetry-sentry: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@opentelemetry/api-logs': specifier: 0.55.0 @@ -817,7 +817,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai next: specifier: latest @@ -866,10 +866,10 @@ importers: examples/next-openai-upstash-rate-limits: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/react '@upstash/ratelimit': specifier: ^0.4.3 @@ -878,7 +878,7 @@ importers: specifier: ^0.2.2 version: 0.2.4 ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai next: specifier: latest @@ -924,10 +924,10 @@ importers: examples/node-http-server: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -952,13 +952,13 @@ importers: examples/nuxt-openai: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/vue': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/vue ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai zod: specifier: 3.23.8 @@ -1007,13 +1007,13 @@ importers: examples/solidstart-openai: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/solid': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/solid '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/ui-utils '@solidjs/meta': specifier: 0.29.4 @@ -1025,7 +1025,7 @@ importers: specifier: ^1.0.10 version: 1.0.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vinxi@0.4.3(@types/node@22.7.4)(@upstash/redis@1.34.3)(ioredis@5.4.1)(terser@5.31.3)(typescript@5.6.3))(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai solid-js: specifier: ^1.9.3 @@ -1050,16 +1050,16 @@ importers: examples/sveltekit-openai: devDependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../../packages/openai '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../../packages/provider-utils '@ai-sdk/svelte': - specifier: 2.1.6 + specifier: 2.1.7 version: link:../../packages/svelte '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/ui-utils '@eslint/compat': specifier: ^1.2.5 @@ -1077,7 +1077,7 @@ importers: specifier: ^5.0.0 version: 5.0.3(svelte@5.22.4)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../../packages/ai autoprefixer: specifier: ^10.4.20 @@ -1134,16 +1134,16 @@ importers: packages/ai: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils '@ai-sdk/react': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../react '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../ui-utils '@opentelemetry/api': specifier: 1.9.0 @@ -1213,10 +1213,10 @@ importers: packages/amazon-bedrock: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils '@smithy/eventstream-codec': specifier: ^4.0.1 @@ -1247,10 +1247,10 @@ importers: packages/anthropic: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1272,13 +1272,13 @@ importers: packages/azure: dependencies: '@ai-sdk/openai': - specifier: 1.3.7 + specifier: 1.3.8 version: link:../openai '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1300,13 +1300,13 @@ importers: packages/cerebras: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1377,10 +1377,10 @@ importers: packages/cohere: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1402,13 +1402,13 @@ importers: packages/deepinfra: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1430,13 +1430,13 @@ importers: packages/deepseek: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1458,10 +1458,10 @@ importers: packages/fal: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1483,13 +1483,13 @@ importers: packages/fireworks: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1511,10 +1511,10 @@ importers: packages/google: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1536,16 +1536,16 @@ importers: packages/google-vertex: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../anthropic '@ai-sdk/google': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../google '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils google-auth-library: specifier: ^9.15.0 @@ -1570,10 +1570,10 @@ importers: packages/groq: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1595,10 +1595,10 @@ importers: packages/luma: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1620,10 +1620,10 @@ importers: packages/mistral: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1645,10 +1645,10 @@ importers: packages/openai: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1670,10 +1670,10 @@ importers: packages/openai-compatible: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1695,10 +1695,10 @@ importers: packages/perplexity: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1742,7 +1742,7 @@ importers: packages/provider-utils: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider nanoid: specifier: ^3.3.8 @@ -1773,10 +1773,10 @@ importers: packages/react: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../ui-utils react: specifier: ^18 || ^19 || ^19.0.0-rc @@ -1837,10 +1837,10 @@ importers: packages/replicate: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -1862,10 +1862,10 @@ importers: packages/solid: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../ui-utils '@solid-primitives/trigger': specifier: ^1.1.0 @@ -1923,10 +1923,10 @@ importers: packages/svelte: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../ui-utils devDependencies: '@eslint/compat': @@ -1987,13 +1987,13 @@ importers: packages/togetherai: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -2015,10 +2015,10 @@ importers: packages/ui-utils: dependencies: '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils zod-to-json-schema: specifier: ^3.24.1 @@ -2052,7 +2052,7 @@ importers: specifier: ^1.0.0-rc.0 || ^1.0.0 version: 1.0.0-rc.0(valibot@1.0.0-rc.0(typescript@5.6.3)) ai: - specifier: 4.3.2 + specifier: 4.3.3 version: link:../ai devDependencies: '@types/node': @@ -2074,10 +2074,10 @@ importers: packages/vue: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../ui-utils swrv: specifier: ^1.0.4 @@ -2129,13 +2129,13 @@ importers: packages/xai: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.6 + specifier: 0.2.7 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.0 + specifier: 1.1.1 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.4 + specifier: 2.2.5 version: link:../provider-utils devDependencies: '@types/node': @@ -24107,7 +24107,7 @@ snapshots: eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.1) eslint-plugin-react: 7.35.0(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -24182,8 +24182,8 @@ snapshots: debug: 4.4.0(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -24222,7 +24222,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24255,7 +24255,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -24304,7 +24304,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -24314,7 +24314,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.0 is-glob: 4.0.3 From 013faa8f00043cdd481573cd931ea2ac833d0ae6 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Tue, 8 Apr 2025 12:44:14 +0200 Subject: [PATCH 035/191] fix (provider/openai): increase transcription model resilience (#5600) --- .changeset/nasty-spiders-sparkle.md | 7 +++ .changeset/tender-buses-glow.md | 5 ++ .../ai-core/src/transcribe/openai-string.ts | 4 +- examples/ai-core/src/transcribe/openai-url.ts | 3 +- examples/ai-core/src/transcribe/openai.ts | 2 +- .../ai/core/transcribe/transcribe.test.ts | 2 +- packages/ai/core/transcribe/transcribe.ts | 16 ++--- .../src/openai-transcription-model.test.ts | 59 ++++++++++++++++-- .../openai/src/openai-transcription-model.ts | 61 +++++++++---------- .../v1/transcription-model-v1-call-options.ts | 6 +- 10 files changed, 112 insertions(+), 53 deletions(-) create mode 100644 .changeset/nasty-spiders-sparkle.md create mode 100644 .changeset/tender-buses-glow.md diff --git a/.changeset/nasty-spiders-sparkle.md b/.changeset/nasty-spiders-sparkle.md new file mode 100644 index 000000000000..7245e14bdfbf --- /dev/null +++ b/.changeset/nasty-spiders-sparkle.md @@ -0,0 +1,7 @@ +--- +'@ai-sdk/provider': patch +'@ai-sdk/openai': patch +'ai': patch +--- + +core (ai): change transcription model mimeType to mediaType diff --git a/.changeset/tender-buses-glow.md b/.changeset/tender-buses-glow.md new file mode 100644 index 000000000000..adea7e261eac --- /dev/null +++ b/.changeset/tender-buses-glow.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +fix (provider/openai): increase transcription model resilience diff --git a/examples/ai-core/src/transcribe/openai-string.ts b/examples/ai-core/src/transcribe/openai-string.ts index 5376c79e799b..5c1f1ea2b72d 100644 --- a/examples/ai-core/src/transcribe/openai-string.ts +++ b/examples/ai-core/src/transcribe/openai-string.ts @@ -6,9 +6,7 @@ import { readFile } from 'fs/promises'; async function main() { const result = await transcribe({ model: openai.transcription('whisper-1'), - audio: Buffer.from( - await readFile('examples/ai-core/data/galileo.mp3'), - ).toString('base64'), + audio: Buffer.from(await readFile('./data/galileo.mp3')).toString('base64'), }); console.log('Text:', result.text); diff --git a/examples/ai-core/src/transcribe/openai-url.ts b/examples/ai-core/src/transcribe/openai-url.ts index 7c64932cd102..d8d7a5830d85 100644 --- a/examples/ai-core/src/transcribe/openai-url.ts +++ b/examples/ai-core/src/transcribe/openai-url.ts @@ -6,8 +6,7 @@ async function main() { const result = await transcribe({ model: openai.transcription('whisper-1'), audio: new URL( - '/vercel/ai/raw/refs/heads/main/examples/ai-core/data/galileo.mp3', - 'https://github.com', + 'https://github.com/vercel/ai/raw/refs/heads/main/examples/ai-core/data/galileo.mp3', ), }); diff --git a/examples/ai-core/src/transcribe/openai.ts b/examples/ai-core/src/transcribe/openai.ts index fafa586c6498..56ccca73330f 100644 --- a/examples/ai-core/src/transcribe/openai.ts +++ b/examples/ai-core/src/transcribe/openai.ts @@ -6,7 +6,7 @@ import { readFile } from 'fs/promises'; async function main() { const result = await transcribe({ model: openai.transcription('whisper-1'), - audio: await readFile('examples/ai-core/data/galileo.mp3'), + audio: await readFile('data/galileo.mp3'), }); console.log('Text:', result.text); diff --git a/packages/ai/core/transcribe/transcribe.test.ts b/packages/ai/core/transcribe/transcribe.test.ts index 72a555783a78..91d843178031 100644 --- a/packages/ai/core/transcribe/transcribe.test.ts +++ b/packages/ai/core/transcribe/transcribe.test.ts @@ -78,7 +78,7 @@ describe('transcribe', () => { expect(capturedArgs).toStrictEqual({ audio: audioData, - mimeType: 'audio/wav', + mediaType: 'audio/wav', headers: { 'custom-request-header': 'request-header-value' }, abortSignal, providerOptions: {}, diff --git a/packages/ai/core/transcribe/transcribe.ts b/packages/ai/core/transcribe/transcribe.ts index 2114522845bc..1c7029102fc2 100644 --- a/packages/ai/core/transcribe/transcribe.ts +++ b/packages/ai/core/transcribe/transcribe.ts @@ -1,17 +1,17 @@ -import { TranscriptionModelV1, JSONValue } from '@ai-sdk/provider'; +import { JSONValue, TranscriptionModelV1 } from '@ai-sdk/provider'; import { NoTranscriptGeneratedError } from '../../errors/no-transcript-generated-error'; +import { download } from '../../util/download'; +import { DataContent } from '../prompt'; +import { convertDataContentToUint8Array } from '../prompt/data-content'; import { prepareRetries } from '../prompt/prepare-retries'; +import { ProviderOptions } from '../types/provider-metadata'; import { TranscriptionWarning } from '../types/transcription-model'; import { TranscriptionModelResponseMetadata } from '../types/transcription-model-response-metadata'; -import { TranscriptionResult } from './transcribe-result'; -import { DataContent } from '../prompt'; -import { convertDataContentToUint8Array } from '../prompt/data-content'; -import { download } from '../../util/download'; import { audioMimeTypeSignatures, detectMimeType, } from '../util/detect-mimetype'; -import { ProviderOptions } from '../types/provider-metadata'; +import { TranscriptionResult } from './transcribe-result'; /** Generates transcripts using a transcription model. @@ -81,7 +81,7 @@ Only applicable for HTTP-based providers. const { retry } = prepareRetries({ maxRetries: maxRetriesArg }); const audioData = audio instanceof URL - ? new Uint8Array((await download({ url: audio })).data) + ? (await download({ url: audio })).data : convertDataContentToUint8Array(audio); const result = await retry(() => @@ -90,7 +90,7 @@ Only applicable for HTTP-based providers. abortSignal, headers, providerOptions, - mimeType: + mediaType: detectMimeType({ data: audioData, signatures: audioMimeTypeSignatures, diff --git a/packages/openai/src/openai-transcription-model.test.ts b/packages/openai/src/openai-transcription-model.test.ts index cee508de293a..61c2be77adb0 100644 --- a/packages/openai/src/openai-transcription-model.test.ts +++ b/packages/openai/src/openai-transcription-model.test.ts @@ -73,7 +73,7 @@ describe('doGenerate', () => { await model.doGenerate({ audio: audioData, - mimeType: 'audio/wav', + mediaType: 'audio/wav', }); expect(await server.calls[0].requestBodyMultipart).toMatchObject({ @@ -95,7 +95,7 @@ describe('doGenerate', () => { await provider.transcription('whisper-1').doGenerate({ audio: audioData, - mimeType: 'audio/wav', + mediaType: 'audio/wav', headers: { 'Custom-Request-Header': 'request-header-value', }, @@ -118,7 +118,7 @@ describe('doGenerate', () => { const result = await model.doGenerate({ audio: audioData, - mimeType: 'audio/wav', + mediaType: 'audio/wav', }); expect(result.text).toBe('Hello from the Vercel AI SDK!'); @@ -144,7 +144,7 @@ describe('doGenerate', () => { const result = await customModel.doGenerate({ audio: audioData, - mimeType: 'audio/wav', + mediaType: 'audio/wav', }); expect(result.response).toMatchObject({ @@ -173,10 +173,59 @@ describe('doGenerate', () => { const result = await customModel.doGenerate({ audio: audioData, - mimeType: 'audio/wav', + mediaType: 'audio/wav', }); expect(result.response.timestamp.getTime()).toEqual(testDate.getTime()); expect(result.response.modelId).toBe('whisper-1'); }); + + it('should work when no words, language, or duration are returned', async () => { + server.urls['https://api.openai.com/v1/audio/transcriptions'].response = { + type: 'json-value', + body: { + task: 'transcribe', + text: 'Hello from the Vercel AI SDK!', + _request_id: 'req_1234', + }, + }; + + const testDate = new Date(0); + const customModel = new OpenAITranscriptionModel('whisper-1', { + provider: 'test-provider', + url: () => 'https://api.openai.com/v1/audio/transcriptions', + headers: () => ({}), + _internal: { + currentDate: () => testDate, + }, + }); + + const result = await customModel.doGenerate({ + audio: audioData, + mediaType: 'audio/wav', + }); + + expect(result).toMatchInlineSnapshot(` + { + "durationInSeconds": undefined, + "language": undefined, + "response": { + "body": { + "_request_id": "req_1234", + "task": "transcribe", + "text": "Hello from the Vercel AI SDK!", + }, + "headers": { + "content-length": "85", + "content-type": "application/json", + }, + "modelId": "whisper-1", + "timestamp": 1970-01-01T00:00:00.000Z, + }, + "segments": [], + "text": "Hello from the Vercel AI SDK!", + "warnings": [], + } + `); + }); }); diff --git a/packages/openai/src/openai-transcription-model.ts b/packages/openai/src/openai-transcription-model.ts index 5720b4932081..8a1a91caf77e 100644 --- a/packages/openai/src/openai-transcription-model.ts +++ b/packages/openai/src/openai-transcription-model.ts @@ -142,7 +142,7 @@ export class OpenAITranscriptionModel implements TranscriptionModelV1 { private getArgs({ audio, - mimeType, + mediaType, providerOptions, }: OpenAITranscriptionCallOptions) { const warnings: TranscriptionModelV1CallWarning[] = []; @@ -162,7 +162,7 @@ export class OpenAITranscriptionModel implements TranscriptionModelV1 { : new Blob([convertBase64ToUint8Array(audio)]); formData.append('model', this.modelId); - formData.append('file', new File([blob], 'audio', { type: mimeType })); + formData.append('file', new File([blob], 'audio', { type: mediaType })); // Add provider-specific options if (openAIOptions) { @@ -197,7 +197,11 @@ export class OpenAITranscriptionModel implements TranscriptionModelV1 { const currentDate = this.config._internal?.currentDate?.() ?? new Date(); const { formData, warnings } = this.getArgs(options); - const { value: response, responseHeaders } = await postFormDataToApi({ + const { + value: response, + responseHeaders, + rawValue: rawResponse, + } = await postFormDataToApi({ url: this.config.url({ path: '/audio/transcriptions', modelId: this.modelId, @@ -212,34 +216,27 @@ export class OpenAITranscriptionModel implements TranscriptionModelV1 { fetch: this.config.fetch, }); - let language: string | undefined; - - if (response.language && response.language in languageMap) { - language = languageMap[response.language as keyof typeof languageMap]; - } + const language = + response.language != null && response.language in languageMap + ? languageMap[response.language as keyof typeof languageMap] + : undefined; return { text: response.text, - segments: response.words.map(word => ({ - text: word.word, - startSecond: word.start, - endSecond: word.end, - })), + segments: + response.words?.map(word => ({ + text: word.word, + startSecond: word.start, + endSecond: word.end, + })) ?? [], language, - durationInSeconds: response.duration, + durationInSeconds: response.duration ?? undefined, warnings, response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders, - body: response, - }, - - // When using format `verbose_json` on `whisper-1`, OpenAI includes the things like `task` and enhanced `segments` information. - providerMetadata: { - openai: { - transcript: response, - }, + body: rawResponse, }, }; } @@ -247,13 +244,15 @@ export class OpenAITranscriptionModel implements TranscriptionModelV1 { const openaiTranscriptionResponseSchema = z.object({ text: z.string(), - language: z.string().optional(), - duration: z.number().optional(), - words: z.array( - z.object({ - word: z.string(), - start: z.number(), - end: z.number(), - }), - ), + language: z.string().nullish(), + duration: z.number().nullish(), + words: z + .array( + z.object({ + word: z.string(), + start: z.number(), + end: z.number(), + }), + ) + .nullish(), }); diff --git a/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts b/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts index a2164a14bba6..cd0e94b668c1 100644 --- a/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts +++ b/packages/provider/src/transcription-model/v1/transcription-model-v1-call-options.ts @@ -13,9 +13,11 @@ Accepts a `Uint8Array` or `string`, where `string` is a base64 encoded audio fil audio: Uint8Array | string; /** - The MIME type of the audio data. +The IANA media type of the audio data. + +@see https://www.iana.org/assignments/media-types/media-types.xhtml */ - mimeType: string; + mediaType: string; /** Additional provider-specific options that are passed through to the provider From 45010ddb63edfa8551be7b848c5b1f6c1eced305 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 12:45:31 +0200 Subject: [PATCH 036/191] Version Packages (#5601) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/nasty-spiders-sparkle.md | 7 - .changeset/tender-buses-glow.md | 5 - examples/ai-core/package.json | 46 +-- examples/express/package.json | 4 +- examples/fastify/package.json | 4 +- examples/hono/package.json | 4 +- examples/mcp/package.json | 4 +- examples/nest/package.json | 4 +- examples/next-fastapi/package.json | 6 +- examples/next-google-vertex/package.json | 4 +- examples/next-langchain/package.json | 4 +- .../package.json | 6 +- examples/next-openai-pages/package.json | 6 +- .../next-openai-telemetry-sentry/package.json | 6 +- examples/next-openai-telemetry/package.json | 6 +- .../package.json | 6 +- examples/next-openai/package.json | 20 +- examples/node-http-server/package.json | 4 +- examples/nuxt-openai/package.json | 6 +- examples/solidstart-openai/package.json | 8 +- examples/sveltekit-openai/package.json | 10 +- packages/ai/CHANGELOG.md | 11 + packages/ai/package.json | 10 +- .../ai/tests/e2e/next-server/CHANGELOG.md | 7 + packages/amazon-bedrock/CHANGELOG.md | 8 + packages/amazon-bedrock/package.json | 6 +- packages/anthropic/CHANGELOG.md | 8 + packages/anthropic/package.json | 6 +- packages/azure/CHANGELOG.md | 10 + packages/azure/package.json | 8 +- packages/cerebras/CHANGELOG.md | 9 + packages/cerebras/package.json | 8 +- packages/cohere/CHANGELOG.md | 8 + packages/cohere/package.json | 6 +- packages/deepinfra/CHANGELOG.md | 9 + packages/deepinfra/package.json | 8 +- packages/deepseek/CHANGELOG.md | 9 + packages/deepseek/package.json | 8 +- packages/fal/CHANGELOG.md | 8 + packages/fal/package.json | 6 +- packages/fireworks/CHANGELOG.md | 9 + packages/fireworks/package.json | 8 +- packages/google-vertex/CHANGELOG.md | 10 + packages/google-vertex/package.json | 10 +- packages/google/CHANGELOG.md | 8 + packages/google/package.json | 6 +- packages/groq/CHANGELOG.md | 8 + packages/groq/package.json | 6 +- packages/luma/CHANGELOG.md | 8 + packages/luma/package.json | 6 +- packages/mistral/CHANGELOG.md | 8 + packages/mistral/package.json | 6 +- packages/openai-compatible/CHANGELOG.md | 8 + packages/openai-compatible/package.json | 6 +- packages/openai/CHANGELOG.md | 10 + packages/openai/package.json | 6 +- packages/perplexity/CHANGELOG.md | 8 + packages/perplexity/package.json | 6 +- packages/provider-utils/CHANGELOG.md | 7 + packages/provider-utils/package.json | 4 +- packages/provider/CHANGELOG.md | 6 + packages/provider/package.json | 2 +- packages/react/CHANGELOG.md | 7 + packages/react/package.json | 6 +- packages/replicate/CHANGELOG.md | 8 + packages/replicate/package.json | 6 +- packages/solid/CHANGELOG.md | 7 + packages/solid/package.json | 6 +- packages/svelte/CHANGELOG.md | 7 + packages/svelte/package.json | 6 +- packages/togetherai/CHANGELOG.md | 9 + packages/togetherai/package.json | 8 +- packages/ui-utils/CHANGELOG.md | 8 + packages/ui-utils/package.json | 6 +- packages/valibot/CHANGELOG.md | 7 + packages/valibot/package.json | 4 +- packages/vue/CHANGELOG.md | 7 + packages/vue/package.json | 6 +- packages/xai/CHANGELOG.md | 9 + packages/xai/package.json | 8 +- pnpm-lock.yaml | 288 +++++++++--------- 81 files changed, 563 insertions(+), 329 deletions(-) delete mode 100644 .changeset/nasty-spiders-sparkle.md delete mode 100644 .changeset/tender-buses-glow.md diff --git a/.changeset/nasty-spiders-sparkle.md b/.changeset/nasty-spiders-sparkle.md deleted file mode 100644 index 7245e14bdfbf..000000000000 --- a/.changeset/nasty-spiders-sparkle.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@ai-sdk/provider': patch -'@ai-sdk/openai': patch -'ai': patch ---- - -core (ai): change transcription model mimeType to mediaType diff --git a/.changeset/tender-buses-glow.md b/.changeset/tender-buses-glow.md deleted file mode 100644 index adea7e261eac..000000000000 --- a/.changeset/tender-buses-glow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -fix (provider/openai): increase transcription model resilience diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 4e3aad460543..43a47af9bb90 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -3,33 +3,33 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/amazon-bedrock": "2.2.6", - "@ai-sdk/anthropic": "1.2.7", - "@ai-sdk/azure": "1.3.9", - "@ai-sdk/cerebras": "0.2.7", - "@ai-sdk/cohere": "1.2.6", - "@ai-sdk/deepinfra": "0.2.8", - "@ai-sdk/deepseek": "0.2.7", - "@ai-sdk/fal": "0.1.6", - "@ai-sdk/fireworks": "0.2.7", - "@ai-sdk/google": "1.2.9", - "@ai-sdk/google-vertex": "2.2.12", - "@ai-sdk/groq": "1.2.6", - "@ai-sdk/luma": "0.1.5", - "@ai-sdk/mistral": "1.2.5", - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/perplexity": "1.1.5", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/replicate": "0.2.5", - "@ai-sdk/togetherai": "0.2.7", - "@ai-sdk/xai": "1.2.8", - "@ai-sdk/valibot": "0.1.15", + "@ai-sdk/amazon-bedrock": "2.2.7", + "@ai-sdk/anthropic": "1.2.8", + "@ai-sdk/azure": "1.3.10", + "@ai-sdk/cerebras": "0.2.8", + "@ai-sdk/cohere": "1.2.7", + "@ai-sdk/deepinfra": "0.2.9", + "@ai-sdk/deepseek": "0.2.8", + "@ai-sdk/fal": "0.1.7", + "@ai-sdk/fireworks": "0.2.8", + "@ai-sdk/google": "1.2.10", + "@ai-sdk/google-vertex": "2.2.13", + "@ai-sdk/groq": "1.2.7", + "@ai-sdk/luma": "0.1.6", + "@ai-sdk/mistral": "1.2.6", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/perplexity": "1.1.6", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/replicate": "0.2.6", + "@ai-sdk/togetherai": "0.2.8", + "@ai-sdk/xai": "1.2.9", + "@ai-sdk/valibot": "0.1.16", "@google/generative-ai": "0.21.0", "@opentelemetry/auto-instrumentations-node": "0.54.0", "@opentelemetry/sdk-node": "0.54.2", "@opentelemetry/sdk-trace-node": "1.28.0", - "ai": "4.3.3", + "ai": "4.3.4", "dotenv": "16.4.5", "image-type": "^5.2.0", "mathjs": "14.0.0", diff --git a/examples/express/package.json b/examples/express/package.json index bc1789a9d4f7..5273c315a58b 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -7,8 +7,8 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "ai": "4.3.3", + "@ai-sdk/openai": "1.3.9", + "ai": "4.3.4", "dotenv": "16.4.5", "express": "5.0.1" }, diff --git a/examples/fastify/package.json b/examples/fastify/package.json index e69f76841f49..56fee1c6f448 100644 --- a/examples/fastify/package.json +++ b/examples/fastify/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "ai": "4.3.3", + "@ai-sdk/openai": "1.3.9", + "ai": "4.3.4", "dotenv": "16.4.5", "fastify": "5.1.0" }, diff --git a/examples/hono/package.json b/examples/hono/package.json index 068fb1ccbe0d..ac40b65ab03a 100644 --- a/examples/hono/package.json +++ b/examples/hono/package.json @@ -3,9 +3,9 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.8", + "@ai-sdk/openai": "1.3.9", "@hono/node-server": "1.13.7", - "ai": "4.3.3", + "ai": "4.3.4", "dotenv": "16.4.5", "hono": "4.6.9" }, diff --git a/examples/mcp/package.json b/examples/mcp/package.json index 21f3e23b9b75..1d80f1169c4e 100644 --- a/examples/mcp/package.json +++ b/examples/mcp/package.json @@ -12,9 +12,9 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", + "@ai-sdk/openai": "1.3.9", "@modelcontextprotocol/sdk": "^1.7.0", - "ai": "4.3.3", + "ai": "4.3.4", "dotenv": "16.4.5", "express": "5.0.1", "zod": "3.23.8" diff --git a/examples/nest/package.json b/examples/nest/package.json index f849b8ff0dd1..32944bdf8bcc 100644 --- a/examples/nest/package.json +++ b/examples/nest/package.json @@ -15,11 +15,11 @@ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", + "@ai-sdk/openai": "1.3.9", "@nestjs/common": "^10.4.15", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.4.9", - "ai": "4.3.3", + "ai": "4.3.4", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/examples/next-fastapi/package.json b/examples/next-fastapi/package.json index d8f0fa6be8d0..59a3eb9bd381 100644 --- a/examples/next-fastapi/package.json +++ b/examples/next-fastapi/package.json @@ -11,9 +11,9 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/ui-utils": "1.2.6", - "@ai-sdk/react": "1.2.7", - "ai": "4.3.3", + "@ai-sdk/ui-utils": "1.2.7", + "@ai-sdk/react": "1.2.8", + "ai": "4.3.4", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index a78e6ec21b3b..80771f6fa8c2 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,8 +9,8 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.12", - "ai": "4.3.3", + "@ai-sdk/google-vertex": "2.2.13", + "ai": "4.3.4", "geist": "^1.3.1", "next": "latest", "react": "^18", diff --git a/examples/next-langchain/package.json b/examples/next-langchain/package.json index 8650065f099d..42f8d3d8dd59 100644 --- a/examples/next-langchain/package.json +++ b/examples/next-langchain/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/react": "1.2.7", + "@ai-sdk/react": "1.2.8", "@langchain/openai": "0.0.28", "@langchain/core": "0.1.63", - "ai": "4.3.3", + "ai": "4.3.4", "langchain": "0.1.36", "next": "latest", "react": "^18", diff --git a/examples/next-openai-kasada-bot-protection/package.json b/examples/next-openai-kasada-bot-protection/package.json index 11ff64ab6318..3bfa55ebcf3b 100644 --- a/examples/next-openai-kasada-bot-protection/package.json +++ b/examples/next-openai-kasada-bot-protection/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/react": "1.2.7", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/react": "1.2.8", "@vercel/functions": "latest", - "ai": "4.3.3", + "ai": "4.3.4", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai-pages/package.json b/examples/next-openai-pages/package.json index 592c45c4a5d4..f2013e99ee4f 100644 --- a/examples/next-openai-pages/package.json +++ b/examples/next-openai-pages/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/react": "1.2.7", - "ai": "4.3.3", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/react": "1.2.8", + "ai": "4.3.4", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry-sentry/package.json b/examples/next-openai-telemetry-sentry/package.json index 67a56f4f526b..760601260a22 100644 --- a/examples/next-openai-telemetry-sentry/package.json +++ b/examples/next-openai-telemetry-sentry/package.json @@ -9,15 +9,15 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/react": "1.2.7", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/react": "1.2.8", "@opentelemetry/api-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@opentelemetry/sdk-logs": "0.55.0", "@sentry/nextjs": "^8.42.0", "@sentry/opentelemetry": "8.22.0", "@vercel/otel": "1.10.0", - "ai": "4.3.3", + "ai": "4.3.4", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-telemetry/package.json b/examples/next-openai-telemetry/package.json index d3b4f4c36be3..2718de6a7baa 100644 --- a/examples/next-openai-telemetry/package.json +++ b/examples/next-openai-telemetry/package.json @@ -9,13 +9,13 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/react": "1.2.7", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/react": "1.2.8", "@opentelemetry/api-logs": "0.55.0", "@opentelemetry/sdk-logs": "0.55.0", "@opentelemetry/instrumentation": "0.52.1", "@vercel/otel": "1.10.0", - "ai": "4.3.3", + "ai": "4.3.4", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/next-openai-upstash-rate-limits/package.json b/examples/next-openai-upstash-rate-limits/package.json index 8f4ddff50de4..3002e9e9a735 100644 --- a/examples/next-openai-upstash-rate-limits/package.json +++ b/examples/next-openai-upstash-rate-limits/package.json @@ -9,11 +9,11 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/react": "1.2.7", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/react": "1.2.8", "@upstash/ratelimit": "^0.4.3", "@vercel/kv": "^0.2.2", - "ai": "4.3.3", + "ai": "4.3.4", "next": "latest", "react": "^18", "react-dom": "^18", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 575cba73c73d..8ac1ac06f3ba 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -9,17 +9,17 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/anthropic": "1.2.7", - "@ai-sdk/deepseek": "0.2.7", - "@ai-sdk/fireworks": "0.2.7", - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/google": "1.2.9", - "@ai-sdk/google-vertex": "2.2.12", - "@ai-sdk/perplexity": "1.1.5", - "@ai-sdk/ui-utils": "1.2.6", - "@ai-sdk/react": "1.2.7", + "@ai-sdk/anthropic": "1.2.8", + "@ai-sdk/deepseek": "0.2.8", + "@ai-sdk/fireworks": "0.2.8", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/google": "1.2.10", + "@ai-sdk/google-vertex": "2.2.13", + "@ai-sdk/perplexity": "1.1.6", + "@ai-sdk/ui-utils": "1.2.7", + "@ai-sdk/react": "1.2.8", "@vercel/blob": "^0.26.0", - "ai": "4.3.3", + "ai": "4.3.4", "next": "latest", "openai": "4.52.6", "react": "^18", diff --git a/examples/node-http-server/package.json b/examples/node-http-server/package.json index 18fe0887bc35..40c8b6d3d932 100644 --- a/examples/node-http-server/package.json +++ b/examples/node-http-server/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "ai": "4.3.3", + "@ai-sdk/openai": "1.3.9", + "ai": "4.3.4", "dotenv": "16.4.5", "zod": "3.23.8", "zod-to-json-schema": "3.23.5" diff --git a/examples/nuxt-openai/package.json b/examples/nuxt-openai/package.json index b79a87664dbd..2ab3b5ebd196 100644 --- a/examples/nuxt-openai/package.json +++ b/examples/nuxt-openai/package.json @@ -9,9 +9,9 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@ai-sdk/vue": "1.2.6", - "@ai-sdk/openai": "1.3.8", - "ai": "4.3.3", + "@ai-sdk/vue": "1.2.7", + "@ai-sdk/openai": "1.3.9", + "ai": "4.3.4", "zod": "3.23.8" }, "devDependencies": { diff --git a/examples/solidstart-openai/package.json b/examples/solidstart-openai/package.json index 9bbb6d0e707b..8cafeb89562b 100644 --- a/examples/solidstart-openai/package.json +++ b/examples/solidstart-openai/package.json @@ -14,13 +14,13 @@ "vinxi": "^0.4.3" }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/solid": "1.2.8", - "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/solid": "1.2.9", + "@ai-sdk/ui-utils": "1.2.7", "@solidjs/meta": "0.29.4", "@solidjs/router": "^0.15.1", "@solidjs/start": "^1.0.10", - "ai": "4.3.3", + "ai": "4.3.4", "solid-js": "^1.9.3", "zod": "^3.23.8" }, diff --git a/examples/sveltekit-openai/package.json b/examples/sveltekit-openai/package.json index da6c8ee0564b..31a123dfabdd 100644 --- a/examples/sveltekit-openai/package.json +++ b/examples/sveltekit-openai/package.json @@ -16,16 +16,16 @@ }, "type": "module", "devDependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/provider-utils": "2.2.5", - "@ai-sdk/svelte": "2.1.7", - "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/provider-utils": "2.2.6", + "@ai-sdk/svelte": "2.1.8", + "@ai-sdk/ui-utils": "1.2.7", "@eslint/compat": "^1.2.5", "@eslint/js": "^9.18.0", "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", - "ai": "4.3.3", + "ai": "4.3.4", "autoprefixer": "^10.4.20", "bits-ui": "^1.3.9", "clsx": "^2.1.1", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index d74cf3e26ba1..e58fbc14ed68 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,16 @@ # ai +## 4.3.4 + +### Patch Changes + +- 013faa8: core (ai): change transcription model mimeType to mediaType +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + - @ai-sdk/ui-utils@1.2.7 + - @ai-sdk/react@1.2.8 + ## 4.3.3 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 24248eee8dfd..c87dc33fa9b3 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "4.3.3", + "version": "4.3.4", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, @@ -66,10 +66,10 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5", - "@ai-sdk/react": "1.2.7", - "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6", + "@ai-sdk/react": "1.2.8", + "@ai-sdk/ui-utils": "1.2.7", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, diff --git a/packages/ai/tests/e2e/next-server/CHANGELOG.md b/packages/ai/tests/e2e/next-server/CHANGELOG.md index f6f2a2901b1d..0813f0dd1fdc 100644 --- a/packages/ai/tests/e2e/next-server/CHANGELOG.md +++ b/packages/ai/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [013faa8] + - ai@4.3.4 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [3e88f4d] - Updated dependencies [c21fa6d] - ai@4.3.3 diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index adb6f44877a4..570fe212a057 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/amazon-bedrock +## 2.2.7 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 2.2.6 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 94eecd8218c2..af0208ec8b3b 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "2.2.6", + "version": "2.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 34c9988cf6e9..08e5e8f9261e 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/anthropic +## 1.2.8 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.7 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 72e839254b11..0291a4256b8a 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "1.2.7", + "version": "1.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -37,8 +37,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index 6708bc5cf8e2..2e06b55fd206 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/azure +## 1.3.10 + +### Patch Changes + +- Updated dependencies [013faa8] +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai@1.3.9 + - @ai-sdk/provider-utils@2.2.6 + ## 1.3.9 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 24cd070cd812..d19e180d67c5 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "1.3.9", + "version": "1.3.10", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,9 +31,9 @@ } }, "dependencies": { - "@ai-sdk/openai": "1.3.8", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai": "1.3.9", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 0aaf17cc1b8e..a40567a00b85 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/cerebras +## 0.2.8 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai-compatible@0.2.8 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.7 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index af760f7b705f..e7b376788b21 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "0.2.7", + "version": "0.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index 769f2b927a31..3d6bb8580cb8 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/cohere +## 1.2.7 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.6 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index f96e12735f57..a651b064f352 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,8 +31,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index 3c90f86a9c09..b4bd9380872a 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/deepinfra +## 0.2.9 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai-compatible@0.2.8 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.8 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 0f62d27fd9d5..49a43c1b4cad 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "0.2.8", + "version": "0.2.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index f65decc316f3..82470584068c 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/deepseek +## 0.2.8 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai-compatible@0.2.8 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.7 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index 924ec6c20f13..2f1a31732024 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "0.2.7", + "version": "0.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index 8013b6febe15..2ecffb5b2526 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/fal +## 0.1.7 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 0.1.6 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index 50746fa0ae59..a26772d04494 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "0.1.6", + "version": "0.1.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index f25a1757145e..a0e3ab974e36 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/fireworks +## 0.2.8 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai-compatible@0.2.8 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.7 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index 41b09501754f..4173d8988f4a 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "0.2.7", + "version": "0.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index e1c28ab4de2f..377fd65ed302 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/google-vertex +## 2.2.13 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/anthropic@1.2.8 + - @ai-sdk/google@1.2.10 + - @ai-sdk/provider-utils@2.2.6 + ## 2.2.12 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index a1f42a44f02f..7042c8176120 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.12", + "version": "2.2.13", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -49,10 +49,10 @@ } }, "dependencies": { - "@ai-sdk/anthropic": "1.2.7", - "@ai-sdk/google": "1.2.9", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/anthropic": "1.2.8", + "@ai-sdk/google": "1.2.10", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6", "google-auth-library": "^9.15.0" }, "devDependencies": { diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 02320cf753f3..421f032a776f 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/google +## 1.2.10 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.9 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index 59f2222e6bd1..5f8def1e7f62 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "1.2.9", + "version": "1.2.10", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,8 +38,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index 35a6070ee870..e467455374cf 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/groq +## 1.2.7 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.6 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index 755d737f1d70..e43252243dfd 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,8 +31,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index e73a74c7abd0..44c5d001ae50 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/luma +## 0.1.6 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 0.1.5 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index cdf0343fc369..ad2bbb80b345 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "0.1.5", + "version": "0.1.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index e3489dfe9023..5bd157d9d40c 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/mistral +## 1.2.6 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.5 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index ce1ae0cac08b..6bf3693bfd0b 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "1.2.5", + "version": "1.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -31,8 +31,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index cf9d8f540276..0bc5626e3f05 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/openai-compatible +## 0.2.8 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.7 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index e577c1b64c81..055638597685 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "0.2.7", + "version": "0.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,8 +38,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index b930955c2ebc..48bf322be7a7 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/openai +## 1.3.9 + +### Patch Changes + +- 013faa8: core (ai): change transcription model mimeType to mediaType +- 013faa8: fix (provider/openai): increase transcription model resilience +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.3.8 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index 8e2f264f73fd..25d37fbbd32e 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "1.3.8", + "version": "1.3.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -38,8 +38,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index df4343c742be..dc3534252bca 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/perplexity +## 1.1.6 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.1.5 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index 5d20339afa47..ecb1683e4951 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "1.1.5", + "version": "1.1.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index 8552ce5ddbbc..8ece2a771fbe 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/provider-utils +## 2.2.6 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + ## 2.2.5 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index 05c542cc6cf3..552b72dbb348 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "2.2.5", + "version": "2.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", + "@ai-sdk/provider": "1.1.2", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, diff --git a/packages/provider/CHANGELOG.md b/packages/provider/CHANGELOG.md index fac9d79ae646..4d2e911c53d3 100644 --- a/packages/provider/CHANGELOG.md +++ b/packages/provider/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider +## 1.1.2 + +### Patch Changes + +- 013faa8: core (ai): change transcription model mimeType to mediaType + ## 1.1.1 ### Patch Changes diff --git a/packages/provider/package.json b/packages/provider/package.json index 4c8a5215e825..f3fc8c1a8599 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider", - "version": "1.1.1", + "version": "1.1.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 4ad7efda55dd..a5f5978949ad 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/react +## 1.2.8 + +### Patch Changes + +- @ai-sdk/provider-utils@2.2.6 +- @ai-sdk/ui-utils@1.2.7 + ## 1.2.7 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 47684a388161..51a3bcf5504a 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "1.2.7", + "version": "1.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.5", - "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/provider-utils": "2.2.6", + "@ai-sdk/ui-utils": "1.2.7", "swr": "^2.2.5", "throttleit": "2.1.0" }, diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index b07860b852e4..236617cce8b1 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/replicate +## 0.2.6 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.5 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index df5c6a66a6fc..d45745d03874 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "0.2.5", + "version": "0.2.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,8 +30,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/solid/CHANGELOG.md b/packages/solid/CHANGELOG.md index 36e4a79f4672..1a339d82cd5b 100644 --- a/packages/solid/CHANGELOG.md +++ b/packages/solid/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/solid +## 1.2.9 + +### Patch Changes + +- @ai-sdk/provider-utils@2.2.6 +- @ai-sdk/ui-utils@1.2.7 + ## 1.2.8 ### Patch Changes diff --git a/packages/solid/package.json b/packages/solid/package.json index fee6623c9480..a166fd336b07 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/solid", - "version": "1.2.8", + "version": "1.2.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.5", - "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/provider-utils": "2.2.6", + "@ai-sdk/ui-utils": "1.2.7", "@solid-primitives/trigger": "^1.1.0", "zod": "^3.23.8" }, diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index affc4adf16b4..2eab47c7ce68 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/svelte +## 2.1.8 + +### Patch Changes + +- @ai-sdk/provider-utils@2.2.6 +- @ai-sdk/ui-utils@1.2.7 + ## 2.1.7 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index fad45dce6ffd..87b088512cf1 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "2.1.7", + "version": "2.1.8", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", @@ -51,8 +51,8 @@ } }, "dependencies": { - "@ai-sdk/provider-utils": "2.2.5", - "@ai-sdk/ui-utils": "1.2.6" + "@ai-sdk/provider-utils": "2.2.6", + "@ai-sdk/ui-utils": "1.2.7" }, "devDependencies": { "@eslint/compat": "^1.2.5", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index 11b664732b0f..01a1dbde7166 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/togetherai +## 0.2.8 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai-compatible@0.2.8 + - @ai-sdk/provider-utils@2.2.6 + ## 0.2.7 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index a78f13eb0497..c76fc396edcd 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "0.2.7", + "version": "0.2.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/ui-utils/CHANGELOG.md b/packages/ui-utils/CHANGELOG.md index bc03ef8c7422..168ace2a6b31 100644 --- a/packages/ui-utils/CHANGELOG.md +++ b/packages/ui-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/ui-utils +## 1.2.7 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.6 ### Patch Changes diff --git a/packages/ui-utils/package.json b/packages/ui-utils/package.json index c71d3952930b..811ef22957cc 100644 --- a/packages/ui-utils/package.json +++ b/packages/ui-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/ui-utils", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -37,8 +37,8 @@ } }, "dependencies": { - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6", "zod-to-json-schema": "^3.24.1" }, "devDependencies": { diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 60e8bf050468..62471356c367 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 0.1.16 + +### Patch Changes + +- Updated dependencies [013faa8] + - ai@4.3.4 + ## 0.1.15 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index 25a4ce654839..fa8285ad1eac 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "0.1.15", + "version": "0.1.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -27,7 +27,7 @@ } }, "dependencies": { - "ai": "4.3.3" + "ai": "4.3.4" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 06239a5ad5ea..698116170d3f 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 1.2.7 + +### Patch Changes + +- @ai-sdk/provider-utils@2.2.6 +- @ai-sdk/ui-utils@1.2.7 + ## 1.2.6 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 9a51c4ed9ca4..ea014d1e8414 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "1.2.6", + "version": "1.2.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -29,8 +29,8 @@ "CHANGELOG.md" ], "dependencies": { - "@ai-sdk/provider-utils": "2.2.5", - "@ai-sdk/ui-utils": "1.2.6", + "@ai-sdk/provider-utils": "2.2.6", + "@ai-sdk/ui-utils": "1.2.7", "swrv": "^1.0.4" }, "devDependencies": { diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 1656ead3a428..73a14915d07b 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/xai +## 1.2.9 + +### Patch Changes + +- Updated dependencies [013faa8] + - @ai-sdk/provider@1.1.2 + - @ai-sdk/openai-compatible@0.2.8 + - @ai-sdk/provider-utils@2.2.6 + ## 1.2.8 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 82c6667e12b1..7eec4db96fa4 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "1.2.8", + "version": "1.2.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -30,9 +30,9 @@ } }, "dependencies": { - "@ai-sdk/openai-compatible": "0.2.7", - "@ai-sdk/provider": "1.1.1", - "@ai-sdk/provider-utils": "2.2.5" + "@ai-sdk/openai-compatible": "0.2.8", + "@ai-sdk/provider": "1.1.2", + "@ai-sdk/provider-utils": "2.2.6" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d5e968f89f56..5c5124c64449 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,70 +60,70 @@ importers: examples/ai-core: dependencies: '@ai-sdk/amazon-bedrock': - specifier: 2.2.6 + specifier: 2.2.7 version: link:../../packages/amazon-bedrock '@ai-sdk/anthropic': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/anthropic '@ai-sdk/azure': - specifier: 1.3.9 + specifier: 1.3.10 version: link:../../packages/azure '@ai-sdk/cerebras': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/cerebras '@ai-sdk/cohere': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/cohere '@ai-sdk/deepinfra': - specifier: 0.2.8 + specifier: 0.2.9 version: link:../../packages/deepinfra '@ai-sdk/deepseek': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/deepseek '@ai-sdk/fal': - specifier: 0.1.6 + specifier: 0.1.7 version: link:../../packages/fal '@ai-sdk/fireworks': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.9 + specifier: 1.2.10 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.12 + specifier: 2.2.13 version: link:../../packages/google-vertex '@ai-sdk/groq': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/groq '@ai-sdk/luma': - specifier: 0.1.5 + specifier: 0.1.6 version: link:../../packages/luma '@ai-sdk/mistral': - specifier: 1.2.5 + specifier: 1.2.6 version: link:../../packages/mistral '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/openai-compatible '@ai-sdk/perplexity': - specifier: 1.1.5 + specifier: 1.1.6 version: link:../../packages/perplexity '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../../packages/provider '@ai-sdk/replicate': - specifier: 0.2.5 + specifier: 0.2.6 version: link:../../packages/replicate '@ai-sdk/togetherai': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/togetherai '@ai-sdk/valibot': - specifier: 0.1.15 + specifier: 0.1.16 version: link:../../packages/valibot '@ai-sdk/xai': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../../packages/xai '@google/generative-ai': specifier: 0.21.0 @@ -138,7 +138,7 @@ importers: specifier: 1.28.0 version: 1.28.0(@opentelemetry/api@1.9.0) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -178,10 +178,10 @@ importers: examples/express: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -206,10 +206,10 @@ importers: examples/fastify: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -231,13 +231,13 @@ importers: examples/hono: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@hono/node-server': specifier: 1.13.7 version: 1.13.7(hono@4.6.9) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -259,13 +259,13 @@ importers: examples/mcp: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@modelcontextprotocol/sdk': specifier: ^1.7.0 version: 1.7.0 ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -293,7 +293,7 @@ importers: examples/nest: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@nestjs/common': specifier: ^10.4.15 @@ -305,7 +305,7 @@ importers: specifier: ^10.4.9 version: 10.4.9(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai reflect-metadata: specifier: ^0.2.0 @@ -381,13 +381,13 @@ importers: examples/next-fastapi: dependencies: '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/ui-utils ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -436,10 +436,10 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.12 + specifier: 2.2.13 version: link:../../packages/google-vertex ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai geist: specifier: ^1.3.1 @@ -479,7 +479,7 @@ importers: examples/next-langchain: dependencies: '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@langchain/core': specifier: 0.1.63 @@ -488,7 +488,7 @@ importers: specifier: 0.0.28 version: 0.0.28 ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai langchain: specifier: 0.1.36 @@ -534,37 +534,37 @@ importers: examples/next-openai: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/anthropic '@ai-sdk/deepseek': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/deepseek '@ai-sdk/fireworks': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../../packages/fireworks '@ai-sdk/google': - specifier: 1.2.9 + specifier: 1.2.10 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.12 + specifier: 2.2.13 version: link:../../packages/google-vertex '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/perplexity': - specifier: 1.1.5 + specifier: 1.1.6 version: link:../../packages/perplexity '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/ui-utils '@vercel/blob': specifier: ^0.26.0 version: 0.26.0 ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai next: specifier: latest @@ -616,16 +616,16 @@ importers: examples/next-openai-kasada-bot-protection: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@vercel/functions': specifier: latest version: 2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai next: specifier: latest @@ -671,13 +671,13 @@ importers: examples/next-openai-pages: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai next: specifier: latest @@ -726,10 +726,10 @@ importers: examples/next-openai-telemetry: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@opentelemetry/api-logs': specifier: 0.55.0 @@ -744,7 +744,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.29.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai next: specifier: latest @@ -793,10 +793,10 @@ importers: examples/next-openai-telemetry-sentry: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@opentelemetry/api-logs': specifier: 0.55.0 @@ -817,7 +817,7 @@ importers: specifier: 1.10.0 version: 1.10.0(@opentelemetry/api-logs@0.55.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.55.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.29.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0)) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai next: specifier: latest @@ -866,10 +866,10 @@ importers: examples/next-openai-upstash-rate-limits: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../../packages/react '@upstash/ratelimit': specifier: ^0.4.3 @@ -878,7 +878,7 @@ importers: specifier: ^0.2.2 version: 0.2.4 ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai next: specifier: latest @@ -924,10 +924,10 @@ importers: examples/node-http-server: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai dotenv: specifier: 16.4.5 @@ -952,13 +952,13 @@ importers: examples/nuxt-openai: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/vue': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/vue ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai zod: specifier: 3.23.8 @@ -1007,13 +1007,13 @@ importers: examples/solidstart-openai: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/solid': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../../packages/solid '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/ui-utils '@solidjs/meta': specifier: 0.29.4 @@ -1025,7 +1025,7 @@ importers: specifier: ^1.0.10 version: 1.0.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vinxi@0.4.3(@types/node@22.7.4)(@upstash/redis@1.34.3)(ioredis@5.4.1)(terser@5.31.3)(typescript@5.6.3))(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai solid-js: specifier: ^1.9.3 @@ -1050,16 +1050,16 @@ importers: examples/sveltekit-openai: devDependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../../packages/openai '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../../packages/provider-utils '@ai-sdk/svelte': - specifier: 2.1.7 + specifier: 2.1.8 version: link:../../packages/svelte '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../../packages/ui-utils '@eslint/compat': specifier: ^1.2.5 @@ -1077,7 +1077,7 @@ importers: specifier: ^5.0.0 version: 5.0.3(svelte@5.22.4)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(terser@5.31.3)(tsx@4.19.2)(yaml@2.7.0)) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../../packages/ai autoprefixer: specifier: ^10.4.20 @@ -1134,16 +1134,16 @@ importers: packages/ai: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils '@ai-sdk/react': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../react '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../ui-utils '@opentelemetry/api': specifier: 1.9.0 @@ -1213,10 +1213,10 @@ importers: packages/amazon-bedrock: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils '@smithy/eventstream-codec': specifier: ^4.0.1 @@ -1247,10 +1247,10 @@ importers: packages/anthropic: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1272,13 +1272,13 @@ importers: packages/azure: dependencies: '@ai-sdk/openai': - specifier: 1.3.8 + specifier: 1.3.9 version: link:../openai '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1300,13 +1300,13 @@ importers: packages/cerebras: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1377,10 +1377,10 @@ importers: packages/cohere: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1402,13 +1402,13 @@ importers: packages/deepinfra: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1430,13 +1430,13 @@ importers: packages/deepseek: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1458,10 +1458,10 @@ importers: packages/fal: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1483,13 +1483,13 @@ importers: packages/fireworks: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1511,10 +1511,10 @@ importers: packages/google: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1536,16 +1536,16 @@ importers: packages/google-vertex: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.7 + specifier: 1.2.8 version: link:../anthropic '@ai-sdk/google': - specifier: 1.2.9 + specifier: 1.2.10 version: link:../google '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils google-auth-library: specifier: ^9.15.0 @@ -1570,10 +1570,10 @@ importers: packages/groq: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1595,10 +1595,10 @@ importers: packages/luma: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1620,10 +1620,10 @@ importers: packages/mistral: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1645,10 +1645,10 @@ importers: packages/openai: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1670,10 +1670,10 @@ importers: packages/openai-compatible: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1695,10 +1695,10 @@ importers: packages/perplexity: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1742,7 +1742,7 @@ importers: packages/provider-utils: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider nanoid: specifier: ^3.3.8 @@ -1773,10 +1773,10 @@ importers: packages/react: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../ui-utils react: specifier: ^18 || ^19 || ^19.0.0-rc @@ -1837,10 +1837,10 @@ importers: packages/replicate: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -1862,10 +1862,10 @@ importers: packages/solid: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../ui-utils '@solid-primitives/trigger': specifier: ^1.1.0 @@ -1923,10 +1923,10 @@ importers: packages/svelte: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../ui-utils devDependencies: '@eslint/compat': @@ -1987,13 +1987,13 @@ importers: packages/togetherai: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': @@ -2015,10 +2015,10 @@ importers: packages/ui-utils: dependencies: '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils zod-to-json-schema: specifier: ^3.24.1 @@ -2052,7 +2052,7 @@ importers: specifier: ^1.0.0-rc.0 || ^1.0.0 version: 1.0.0-rc.0(valibot@1.0.0-rc.0(typescript@5.6.3)) ai: - specifier: 4.3.3 + specifier: 4.3.4 version: link:../ai devDependencies: '@types/node': @@ -2074,10 +2074,10 @@ importers: packages/vue: dependencies: '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils '@ai-sdk/ui-utils': - specifier: 1.2.6 + specifier: 1.2.7 version: link:../ui-utils swrv: specifier: ^1.0.4 @@ -2129,13 +2129,13 @@ importers: packages/xai: dependencies: '@ai-sdk/openai-compatible': - specifier: 0.2.7 + specifier: 0.2.8 version: link:../openai-compatible '@ai-sdk/provider': - specifier: 1.1.1 + specifier: 1.1.2 version: link:../provider '@ai-sdk/provider-utils': - specifier: 2.2.5 + specifier: 2.2.6 version: link:../provider-utils devDependencies: '@types/node': From 2669f00b8e9acf8352bd07d930fbd181e5219500 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Tue, 8 Apr 2025 15:13:03 +0100 Subject: [PATCH 037/191] docs: update transcription highlights (#5603) --- .../docs/03-ai-sdk-core/36-transcription.mdx | 6 ++--- .../ai-no-transcript-generated-error.mdx | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 content/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx diff --git a/content/docs/03-ai-sdk-core/36-transcription.mdx b/content/docs/03-ai-sdk-core/36-transcription.mdx index 24d3dca4f1d1..8cfcdd47087b 100644 --- a/content/docs/03-ai-sdk-core/36-transcription.mdx +++ b/content/docs/03-ai-sdk-core/36-transcription.mdx @@ -38,7 +38,7 @@ const durationInSeconds = transcript.durationInSeconds; // duration of the trans Transcription models often have provider or model-specific settings which you can set using the `providerOptions` parameter. -```ts highlight={"9"} +```ts highlight="8-12" import { experimental_transcribe as transcribe } from 'ai'; import { openai } from '@ai-sdk/openai'; import { readFile } from 'fs/promises'; @@ -60,7 +60,7 @@ const transcript = await transcribe({ type [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that you can use to abort the transcription process or set a timeout. -```ts highlight={"7"} +```ts highlight="8" import { openai } from '@ai-sdk/openai'; import { experimental_transcribe as transcribe } from 'ai'; import { readFile } from 'fs/promises'; @@ -77,7 +77,7 @@ const transcript = await transcribe({ `transcribe` accepts an optional `headers` parameter of type `Record` that you can use to add custom headers to the transcription request. -```ts highlight={"7"} +```ts highlight="8" import { openai } from '@ai-sdk/openai'; import { experimental_transcribe as transcribe } from 'ai'; import { readFile } from 'fs/promises'; diff --git a/content/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx b/content/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx new file mode 100644 index 000000000000..c9124974439c --- /dev/null +++ b/content/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx @@ -0,0 +1,25 @@ +--- +title: AI_NoTranscriptGeneratedError +description: Learn how to fix AI_NoTranscriptGeneratedError +--- + +# AI_NoTranscriptGeneratedError + +This error occurs when no transcript could be generated from the input. + +## Properties + +- `responses`: Array of responses +- `message`: The error message + +## Checking for this Error + +You can check if an error is an instance of `AI_NoTranscriptGeneratedError` using: + +```typescript +import { NoTranscriptGeneratedError } from 'ai'; + +if (NoTranscriptGeneratedError.isInstance(error)) { + // Handle the error +} +``` From aeba38eb490390dadb67a2c79665afbe5cc28d50 Mon Sep 17 00:00:00 2001 From: Anish K Srinivasan Date: Wed, 9 Apr 2025 13:56:55 +0530 Subject: [PATCH 038/191] feat (provider/anthropic): Add URL-based PDF support (#5470) --- .changeset/smart-swans-drive.md | 5 +++ .../01-ai-sdk-providers/05-anthropic.mdx | 28 +++++++++++++ .../src/generate-text/anthropic-pdf-url.ts | 31 ++++++++++++++ packages/anthropic/src/anthropic-api-types.ts | 28 ++++++------- .../src/anthropic-messages-language-model.ts | 4 ++ ...nvert-to-anthropic-messages-prompt.test.ts | 42 ++++++++++++++++++- .../convert-to-anthropic-messages-prompt.ts | 23 +++++----- 7 files changed, 133 insertions(+), 28 deletions(-) create mode 100644 .changeset/smart-swans-drive.md create mode 100644 examples/ai-core/src/generate-text/anthropic-pdf-url.ts diff --git a/.changeset/smart-swans-drive.md b/.changeset/smart-swans-drive.md new file mode 100644 index 000000000000..ec8649ef9131 --- /dev/null +++ b/.changeset/smart-swans-drive.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/anthropic': patch +--- + +Add support for URL-based PDF documents in the Anthropic provider diff --git a/content/providers/01-ai-sdk-providers/05-anthropic.mdx b/content/providers/01-ai-sdk-providers/05-anthropic.mdx index 3f48eed03923..21a82c5e7e9f 100644 --- a/content/providers/01-ai-sdk-providers/05-anthropic.mdx +++ b/content/providers/01-ai-sdk-providers/05-anthropic.mdx @@ -344,6 +344,34 @@ These tools can be used in conjunction with the `sonnet-3-5-sonnet-20240620` mod Anthropic Sonnet `claude-3-5-sonnet-20241022` supports reading PDF files. You can pass PDF files as part of the message content using the `file` type: +Option 1: URL-based PDF document + +```ts +const result = await generateText({ + model: anthropic('claude-3-5-sonnet-20241022'), + messages: [ + { + role: 'user', + content: [ + { + type: 'text', + text: 'What is an embedding model according to this document?', + }, + { + type: 'file', + data: new URL( + 'https://github.com/vercel/ai/blob/main/examples/ai-core/data/ai.pdf?raw=true', + ), + mimeType: 'application/pdf', + }, + ], + }, + ], +}); +``` + +Option 2: Base64-encoded PDF document + ```ts const result = await generateText({ model: anthropic('claude-3-5-sonnet-20241022'), diff --git a/examples/ai-core/src/generate-text/anthropic-pdf-url.ts b/examples/ai-core/src/generate-text/anthropic-pdf-url.ts new file mode 100644 index 000000000000..3a19cad64f21 --- /dev/null +++ b/examples/ai-core/src/generate-text/anthropic-pdf-url.ts @@ -0,0 +1,31 @@ +import { anthropic } from '@ai-sdk/anthropic'; +import { generateText } from 'ai'; +import 'dotenv/config'; + +async function main() { + const result = await generateText({ + model: anthropic('claude-3-5-sonnet-20241022'), + messages: [ + { + role: 'user', + content: [ + { + type: 'text', + text: 'What is an embedding model according to this document?', + }, + { + type: 'file', + data: new URL( + 'https://github.com/vercel/ai/blob/main/examples/ai-core/data/ai.pdf?raw=true', + ), + mimeType: 'application/pdf', + }, + ], + }, + ], + }); + + console.log(result.text); +} + +main().catch(console.error); diff --git a/packages/anthropic/src/anthropic-api-types.ts b/packages/anthropic/src/anthropic-api-types.ts index 205df3859b1c..0e2e0c67ac5c 100644 --- a/packages/anthropic/src/anthropic-api-types.ts +++ b/packages/anthropic/src/anthropic-api-types.ts @@ -48,28 +48,26 @@ export interface AnthropicRedactedThinkingContent { cache_control: AnthropicCacheControl | undefined; } +type AnthropicContentSource = + | { + type: 'base64'; + media_type: string; + data: string; + } + | { + type: 'url'; + url: string; + }; + export interface AnthropicImageContent { type: 'image'; - source: - | { - type: 'base64'; - media_type: string; - data: string; - } - | { - type: 'url'; - url: string; - }; + source: AnthropicContentSource; cache_control: AnthropicCacheControl | undefined; } export interface AnthropicDocumentContent { type: 'document'; - source: { - type: 'base64'; - media_type: 'application/pdf'; - data: string; - }; + source: AnthropicContentSource; cache_control: AnthropicCacheControl | undefined; } diff --git a/packages/anthropic/src/anthropic-messages-language-model.ts b/packages/anthropic/src/anthropic-messages-language-model.ts index 167a5a9b46af..bf91030414d5 100644 --- a/packages/anthropic/src/anthropic-messages-language-model.ts +++ b/packages/anthropic/src/anthropic-messages-language-model.ts @@ -57,6 +57,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV1 { this.config = config; } + supportsUrl(url: URL): boolean { + return url.protocol === 'https:'; + } + get provider(): string { return this.config.provider; } diff --git a/packages/anthropic/src/convert-to-anthropic-messages-prompt.test.ts b/packages/anthropic/src/convert-to-anthropic-messages-prompt.test.ts index a0faf40e49e7..42fad0e4c3f9 100644 --- a/packages/anthropic/src/convert-to-anthropic-messages-prompt.test.ts +++ b/packages/anthropic/src/convert-to-anthropic-messages-prompt.test.ts @@ -123,7 +123,7 @@ describe('user messages', () => { }); }); - it('should add PDF file parts', async () => { + it('should add PDF file parts for base64 PDFs', async () => { const result = convertToAnthropicMessagesPrompt({ prompt: [ { @@ -164,6 +164,46 @@ describe('user messages', () => { }); }); + it('should add PDF file parts for URL PDFs', async () => { + const result = convertToAnthropicMessagesPrompt({ + prompt: [ + { + role: 'user', + content: [ + { + type: 'file', + data: new URL('https://example.com/document.pdf'), + mimeType: 'application/pdf', + }, + ], + }, + ], + sendReasoning: true, + warnings: [], + }); + + expect(result).toEqual({ + prompt: { + messages: [ + { + role: 'user', + content: [ + { + type: 'document', + source: { + type: 'url', + url: 'https://example.com/document.pdf', + }, + }, + ], + }, + ], + system: undefined, + }, + betas: new Set(['pdfs-2024-09-25']), + }); + }); + it('should throw error for non-PDF file types', async () => { expect(() => convertToAnthropicMessagesPrompt({ diff --git a/packages/anthropic/src/convert-to-anthropic-messages-prompt.ts b/packages/anthropic/src/convert-to-anthropic-messages-prompt.ts index 731ad6478f1b..3a839f273387 100644 --- a/packages/anthropic/src/convert-to-anthropic-messages-prompt.ts +++ b/packages/anthropic/src/convert-to-anthropic-messages-prompt.ts @@ -121,13 +121,6 @@ export function convertToAnthropicMessagesPrompt({ } case 'file': { - if (part.data instanceof URL) { - // The AI SDK automatically downloads files for user file parts with URLs - throw new UnsupportedFunctionalityError({ - functionality: 'Image URLs in user messages', - }); - } - if (part.mimeType !== 'application/pdf') { throw new UnsupportedFunctionalityError({ functionality: 'Non-PDF files in user messages', @@ -138,11 +131,17 @@ export function convertToAnthropicMessagesPrompt({ anthropicContent.push({ type: 'document', - source: { - type: 'base64', - media_type: 'application/pdf', - data: part.data, - }, + source: + part.data instanceof URL + ? { + type: 'url', + url: part.data.toString(), + } + : { + type: 'base64', + media_type: 'application/pdf', + data: part.data, + }, cache_control: cacheControl, }); From b35e490ad828d7f1dfdd97930a89892761a4811e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:29:34 +0200 Subject: [PATCH 039/191] Version Packages (#5617) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/smart-swans-drive.md | 5 ----- examples/ai-core/package.json | 4 ++-- examples/next-google-vertex/package.json | 2 +- examples/next-openai/package.json | 4 ++-- packages/anthropic/CHANGELOG.md | 6 ++++++ packages/anthropic/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 7 +++++++ packages/google-vertex/package.json | 4 ++-- pnpm-lock.yaml | 12 ++++++------ 9 files changed, 27 insertions(+), 19 deletions(-) delete mode 100644 .changeset/smart-swans-drive.md diff --git a/.changeset/smart-swans-drive.md b/.changeset/smart-swans-drive.md deleted file mode 100644 index ec8649ef9131..000000000000 --- a/.changeset/smart-swans-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/anthropic': patch ---- - -Add support for URL-based PDF documents in the Anthropic provider diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 43a47af9bb90..21c4a42a0333 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@ai-sdk/amazon-bedrock": "2.2.7", - "@ai-sdk/anthropic": "1.2.8", + "@ai-sdk/anthropic": "1.2.9", "@ai-sdk/azure": "1.3.10", "@ai-sdk/cerebras": "0.2.8", "@ai-sdk/cohere": "1.2.7", @@ -13,7 +13,7 @@ "@ai-sdk/fal": "0.1.7", "@ai-sdk/fireworks": "0.2.8", "@ai-sdk/google": "1.2.10", - "@ai-sdk/google-vertex": "2.2.13", + "@ai-sdk/google-vertex": "2.2.14", "@ai-sdk/groq": "1.2.7", "@ai-sdk/luma": "0.1.6", "@ai-sdk/mistral": "1.2.6", diff --git a/examples/next-google-vertex/package.json b/examples/next-google-vertex/package.json index 80771f6fa8c2..230f2bfc2a26 100644 --- a/examples/next-google-vertex/package.json +++ b/examples/next-google-vertex/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/google-vertex": "2.2.13", + "@ai-sdk/google-vertex": "2.2.14", "ai": "4.3.4", "geist": "^1.3.1", "next": "latest", diff --git a/examples/next-openai/package.json b/examples/next-openai/package.json index 8ac1ac06f3ba..ac081dfc8904 100644 --- a/examples/next-openai/package.json +++ b/examples/next-openai/package.json @@ -9,12 +9,12 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/anthropic": "1.2.8", + "@ai-sdk/anthropic": "1.2.9", "@ai-sdk/deepseek": "0.2.8", "@ai-sdk/fireworks": "0.2.8", "@ai-sdk/openai": "1.3.9", "@ai-sdk/google": "1.2.10", - "@ai-sdk/google-vertex": "2.2.13", + "@ai-sdk/google-vertex": "2.2.14", "@ai-sdk/perplexity": "1.1.6", "@ai-sdk/ui-utils": "1.2.7", "@ai-sdk/react": "1.2.8", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 08e5e8f9261e..7394be461217 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/anthropic +## 1.2.9 + +### Patch Changes + +- aeba38e: Add support for URL-based PDF documents in the Anthropic provider + ## 1.2.8 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 0291a4256b8a..e40dc7ff5b24 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "1.2.8", + "version": "1.2.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index 377fd65ed302..5d0f56cb336e 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/google-vertex +## 2.2.14 + +### Patch Changes + +- Updated dependencies [aeba38e] + - @ai-sdk/anthropic@1.2.9 + ## 2.2.13 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 7042c8176120..2c77feae26ae 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "2.2.13", + "version": "2.2.14", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -49,7 +49,7 @@ } }, "dependencies": { - "@ai-sdk/anthropic": "1.2.8", + "@ai-sdk/anthropic": "1.2.9", "@ai-sdk/google": "1.2.10", "@ai-sdk/provider": "1.1.2", "@ai-sdk/provider-utils": "2.2.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c5124c64449..b7d4cb44fdb4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,7 +63,7 @@ importers: specifier: 2.2.7 version: link:../../packages/amazon-bedrock '@ai-sdk/anthropic': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../../packages/anthropic '@ai-sdk/azure': specifier: 1.3.10 @@ -90,7 +90,7 @@ importers: specifier: 1.2.10 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.13 + specifier: 2.2.14 version: link:../../packages/google-vertex '@ai-sdk/groq': specifier: 1.2.7 @@ -436,7 +436,7 @@ importers: examples/next-google-vertex: dependencies: '@ai-sdk/google-vertex': - specifier: 2.2.13 + specifier: 2.2.14 version: link:../../packages/google-vertex ai: specifier: 4.3.4 @@ -534,7 +534,7 @@ importers: examples/next-openai: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../../packages/anthropic '@ai-sdk/deepseek': specifier: 0.2.8 @@ -546,7 +546,7 @@ importers: specifier: 1.2.10 version: link:../../packages/google '@ai-sdk/google-vertex': - specifier: 2.2.13 + specifier: 2.2.14 version: link:../../packages/google-vertex '@ai-sdk/openai': specifier: 1.3.9 @@ -1536,7 +1536,7 @@ importers: packages/google-vertex: dependencies: '@ai-sdk/anthropic': - specifier: 1.2.8 + specifier: 1.2.9 version: link:../anthropic '@ai-sdk/google': specifier: 1.2.10 From 158ddc45ef15ea8a51c246116a62a342c27c7832 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:17:02 +0100 Subject: [PATCH 040/191] docs: update llms txt header and remove outdated troubleshooting pages (#5621) Co-authored-by: Nico Albanese --- content/docs/01-introduction/index.mdx | 2 +- ...ing-not-working-on-vercel-pages-router.mdx | 43 ------------------- .../06-streaming-not-working-on-vercel.mdx | 40 ----------------- 3 files changed, 1 insertion(+), 84 deletions(-) delete mode 100644 content/docs/09-troubleshooting/06-streaming-not-working-on-vercel-pages-router.mdx delete mode 100644 content/docs/09-troubleshooting/06-streaming-not-working-on-vercel.mdx diff --git a/content/docs/01-introduction/index.mdx b/content/docs/01-introduction/index.mdx index b53909739d58..952fb2260ffa 100644 --- a/content/docs/01-introduction/index.mdx +++ b/content/docs/01-introduction/index.mdx @@ -48,7 +48,7 @@ We've built some [templates](https://vercel.com/templates?type=ai) that include If you have questions about anything related to the AI SDK, you're always welcome to ask our community on [GitHub Discussions](https://github.com/vercel/ai/discussions). -## `llms.txt` +## `llms.txt` (for Cursor, Windsurf, Copilot, Claude etc.) You can access the entire AI SDK documentation in Markdown format at [sdk.vercel.ai/llms.txt](/llms.txt). This can be used to ask any LLM (assuming it has a big enough context window) questions about the AI SDK based on the most up-to-date documentation. diff --git a/content/docs/09-troubleshooting/06-streaming-not-working-on-vercel-pages-router.mdx b/content/docs/09-troubleshooting/06-streaming-not-working-on-vercel-pages-router.mdx deleted file mode 100644 index 5425aae848c7..000000000000 --- a/content/docs/09-troubleshooting/06-streaming-not-working-on-vercel-pages-router.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Streaming Not Working When Deploying on Vercel (Next.js Pages Router) -description: Troubleshooting streaming issues when deploying to Vercel with the Next.js Pages Router. ---- - -# Streaming Not Working When Deploying on Vercel (Next.js Pages Router) - -## Issue - -I'm using the Next.js Pages Router. Streaming with the AI SDK works in my local development environment. -However, when deploying to Vercel, streaming does not work in the deployed app. -Instead of streaming, only the full response is returned after a while. - -## Cause - -The Next.js Pages Router currently does not support streaming with its own routes. - -## Solution - -With Next.js 13+, you can mix and match App Router and Pages Router routes in the same project. -You need to use App Router routes for streaming with the AI SDK. - -Example App Router route: - -```tsx filename="app/api/chat/route.ts" -import { openai } from '@ai-sdk/openai'; -import { StreamingTextResponse, streamText } from 'ai'; - -// Force the route to be dynamic and allow streaming responses up to 30 seconds -export const dynamic = 'force-dynamic'; -export const maxDuration = 30; - -export async function POST(req: Request) { - const { messages } = await req.json(); - - const result = streamText({ - model: openai('gpt-4-turbo'), - messages, - }); - - return result.toDataStreamResponse(); -} -``` diff --git a/content/docs/09-troubleshooting/06-streaming-not-working-on-vercel.mdx b/content/docs/09-troubleshooting/06-streaming-not-working-on-vercel.mdx deleted file mode 100644 index 28ca0f9888a8..000000000000 --- a/content/docs/09-troubleshooting/06-streaming-not-working-on-vercel.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Streaming Not Working When Deploying on Vercel (Next.js App Router) -description: Troubleshooting streaming issues when deploying to Vercel with the Next.js App Router. ---- - -# Streaming Not Working When Deploying on Vercel (Next.js App Router) - -## Issue - -I'm using the Next.js App Router. Streaming with the AI SDK works in my local development environment. -However, when deploying to Vercel, streaming does not work in the deployed app. -Instead of streaming, only the full response is returned after a while. - -## Cause - -The route was inferred as a static route and has been compiled as such. - -## Solution - -You need to explicitly enforce dynamic behavior for the route. - -Add the following to your route file: - -```tsx -export const dynamic = 'force-dynamic'; -``` - -This will enforce dynamic behavior, which is required for streaming. - -> **Note:** When deploying on Vercel you may also need the following workaround: - -```tsx -import { unstable_noStore as noStore } from 'next/cache'; - -export default async function Component() { - noStore(); - const result = await generateText({...}) - ... -} -``` From f35277b0f5224445744a12ab305a2cdcab757d8d Mon Sep 17 00:00:00 2001 From: Sam Denty Date: Wed, 9 Apr 2025 13:00:53 +0100 Subject: [PATCH 041/191] chore: improve contributing guide & add PR template checklist (#5627) --- .github/pull_request_template.md | 27 +++++++++++++++++++++++++++ CONTRIBUTING.md | 19 +++++++++++++++---- 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000000..604d3faf54d8 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,27 @@ + + +## Background + + + +## Summary + + + +## Tasks + + + +- [ ] Tests for the changes have been added (for bug fixes / features) +- [ ] Docs have been added / updated (for bug fixes / features) +- [ ] You've followed the [PR contributing guidelines](https://github.com/vercel/ai/blob/main/CONTRIBUTING.md#submitting-pull-requests) for adding a _patch_ changeset to version packages and fixing prettier issues + +## Future Work + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9644053c4a2..6ed072f3e44e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,10 +70,21 @@ Some packages like `ai` also have more details tests and watch mode, see their ` We greatly appreciate your pull requests. Here are the steps to submit them: 1. **Create a New Branch**: Initiate your changes in a fresh branch. It's recommended to name the branch in a manner that signifies the changes you're implementing. -2. **Commit Your Changes**: Ensure your commits are succinct and clear, detailing what modifications have been made and the reasons behind them. -3. **Push the Changes to Your GitHub Repository**: After committing your changes, push them to your GitHub repository. -4. **Open a Pull Request**: Propose your changes for review. Furnish a lucid title and description of your contributions. Make sure to link any relevant issues your PR resolves. -5. **Respond to Feedback**: Stay receptive to and address any feedback or alteration requests from the project maintainers. +2. **Add a patch changeset**: If you're updating any packages and want to ensure they're released, add a **patch** changeset to your branch by running `pnpm changeset` in the workspace root. + + - **Please do not use minor or major changesets**, we'll let you know when you need to use a different changeset type than patch. + - You don't need to select any of the `examples/*` packages, as they are not released. + +3. **Commit Your Changes**: Ensure your commits are succinct and clear, detailing what modifications have been made and the reasons behind them. We don't require a specific commit message format, but please be descriptive. +4. **Fix prettier issues**: Run `pnpm prettier-fix` to fix any formatting issues in your code. +5. **Push the Changes to Your GitHub Repository**: After committing your changes, push them to your GitHub repository. +6. **Open a Pull Request**: Propose your changes for review. Furnish a lucid title and description of your contributions. Make sure to link any relevant issues your PR resolves. We use the following PR title format: + + - `fix(package-name): description` or + - `feat(package-name): description` or + - `chore(package-name): description` etc. + +7. **Respond to Feedback**: Stay receptive to and address any feedback or alteration requests from the project maintainers. ### Fixing Prettier Issues From 632cf2739bd9507cec8aeff2936fa82285bce341 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Wed, 9 Apr 2025 15:44:48 +0100 Subject: [PATCH 042/191] docs: update svelte kit guide to use parts (#5630) --- content/docs/02-getting-started/04-svelte.mdx | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/content/docs/02-getting-started/04-svelte.mdx b/content/docs/02-getting-started/04-svelte.mdx index 36bd75871702..d92ed86ee731 100644 --- a/content/docs/02-getting-started/04-svelte.mdx +++ b/content/docs/02-getting-started/04-svelte.mdx @@ -139,8 +139,17 @@ Update your root page (`src/routes/+page.svelte`) with the following code to sho
    - {#each chat.messages as message} -
  • {message.role}: {message.content}
  • + {#each chat.messages as message, messageIndex (messageIndex)} +
  • +
    {message.role}
    +
    + {#each message.parts as part, partIndex (partIndex)} + {#if part.type === 'text'} +
    {part.text}
    + {/if} + {/each} +
    +
  • {/each}
@@ -152,10 +161,12 @@ Update your root page (`src/routes/+page.svelte`) with the following code to sho This page utilizes the `Chat` class, which will, by default, use the `POST` route handler you created earlier. The hook provides functions and state for handling user input and form submission. The `Chat` class provides multiple utility functions and state variables: -- `messages` - the current chat messages (an array of objects with `id`, `role`, and `content` properties). +- `messages` - the current chat messages (an array of objects with `id`, `role`, and `parts` properties). - `input` - the current value of the user's input field. - `handleSubmit` - function to handle form submission. +The LLM's response is accessed through the message `parts` array. Each message contains an ordered array of `parts` that represents everything the model generated in its response. These parts can include plain text, reasoning tokens, and more that you will see later. The `parts` array preserves the sequence of the model's outputs, allowing you to display or process each component in the order it was generated. + ## Running Your Application With that, you have built everything you need for your chatbot! To start your application, use the command: @@ -244,14 +255,18 @@ To display the tool invocations in your UI, update your `src/routes/+page.svelte
    - {#each chat.messages as message} + {#each chat.messages as message, messageIndex (messageIndex)}
  • - {message.role}: - {#if message.toolInvocations} -
    {JSON.stringify(message.toolInvocations, null, 2)}
    - {:else} - {message.content} - {/if} +
    {message.role}
    +
    + {#each message.parts as part, partIndex (partIndex)} + {#if part.type === 'text'} +
    {part.text}
    + {:else if part.type === 'tool-invocation'} +
    {JSON.stringify(part.toolInvocation, null, 2)}
    + {/if} + {/each} +
  • {/each}
@@ -262,7 +277,7 @@ To display the tool invocations in your UI, update your `src/routes/+page.svelte
``` -With this change, you check each message for any tool calls (`toolInvocations`). These tool calls will be displayed as stringified JSON. Otherwise, you show the message content as before. +With this change, you're updating the UI to handle different message parts. For text parts, you display the text content as before. For tool invocations, you display a JSON representation of the tool call and its result. Now, when you ask about the weather, you'll see the tool invocation and its result displayed in your chat interface. From c0fa382a054858eb158ae9d1cfea998098a4fdd7 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Wed, 9 Apr 2025 15:45:01 +0100 Subject: [PATCH 043/191] docs: remove broken link from vc deployment guide (#5631) --- content/docs/06-advanced/10-vercel-deployment-guide.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/content/docs/06-advanced/10-vercel-deployment-guide.mdx b/content/docs/06-advanced/10-vercel-deployment-guide.mdx index fbe05e7ed3e4..99d157f9b5e6 100644 --- a/content/docs/06-advanced/10-vercel-deployment-guide.mdx +++ b/content/docs/06-advanced/10-vercel-deployment-guide.mdx @@ -113,6 +113,5 @@ A firewall helps protect your applications and websites from DDoS attacks and u ## Troubleshooting -- Streaming not working ([App Router](/docs/troubleshooting/streaming-not-working-on-vercel) / [Pages Router](/docs/troubleshooting/streaming-not-working-on-vercel-pages-router)) - Streaming not working when [proxied](/docs/troubleshooting/streaming-not-working-when-proxied) - Experiencing [Timeouts](/docs/troubleshooting/timeout-on-vercel) From 0089ef5de5982c128bc3d2cee768c90a792ddcf9 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Wed, 9 Apr 2025 15:45:12 +0100 Subject: [PATCH 044/191] docs: update nuxt guide parts (#5632) --- .../02-nextjs-app-router.mdx | 4 +- content/docs/02-getting-started/04-svelte.mdx | 4 +- content/docs/02-getting-started/05-nuxt.mdx | 44 +++++++++++-------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/content/docs/02-getting-started/02-nextjs-app-router.mdx b/content/docs/02-getting-started/02-nextjs-app-router.mdx index 1de3a89c7c82..95451e468dc2 100644 --- a/content/docs/02-getting-started/02-nextjs-app-router.mdx +++ b/content/docs/02-getting-started/02-nextjs-app-router.mdx @@ -234,11 +234,11 @@ In this updated code: - Defines parameters using a Zod schema, specifying that it requires a `location` string to execute this tool. The model will attempt to extract this parameter from the context of the conversation. If it can't, it will ask the user for the missing information. - Defines an `execute` function that simulates getting weather data (in this case, it returns a random temperature). This is an asynchronous function running on the server so you can fetch real data from an external API. - Now your chatbot can "fetch" weather information for any location the user asks about. When the model determines it needs to use the weather tool, it will generate a tool call with the necessary parameters. The `execute` function will then be automatically run, and you can access the results via `toolInvocations` that is available on the message object. +Now your chatbot can "fetch" weather information for any location the user asks about. When the model determines it needs to use the weather tool, it will generate a tool call with the necessary parameters. The `execute` function will then be automatically run, and you can access the results via `tool-invocations` part that is available on the `message.parts` array. Try asking something like "What's the weather in New York?" and see how the model uses the new tool. -Notice the blank response in the UI? This is because instead of generating a text response, the model generated a tool call. You can access the tool call and subsequent tool result in the `toolInvocations` key of the message object. +Notice the blank response in the UI? This is because instead of generating a text response, the model generated a tool call. You can access the tool call and subsequent tool result via the `tool-invocation` part of the `message.parts` array. ### Update the UI diff --git a/content/docs/02-getting-started/04-svelte.mdx b/content/docs/02-getting-started/04-svelte.mdx index d92ed86ee731..6de2e30f49c4 100644 --- a/content/docs/02-getting-started/04-svelte.mdx +++ b/content/docs/02-getting-started/04-svelte.mdx @@ -236,11 +236,11 @@ In this updated code: - Defines parameters using a Zod schema, specifying that it requires a `location` string to execute this tool. The model will attempt to extract this parameter from the context of the conversation. If it can't, it will ask the user for the missing information. - Defines an `execute` function that simulates getting weather data (in this case, it returns a random temperature). This is an asynchronous function running on the server so you can fetch real data from an external API. -Now your chatbot can "fetch" weather information for any location the user asks about. When the model determines it needs to use the weather tool, it will generate a tool call with the necessary parameters. The `execute` function will then be automatically run, and you can access the results via `toolInvocations` that is available on the message object. +Now your chatbot can "fetch" weather information for any location the user asks about. When the model determines it needs to use the weather tool, it will generate a tool call with the necessary parameters. The `execute` function will then be automatically run, and you can access the results via `tool-invocations` part that is available on the `message.parts` array. Try asking something like "What's the weather in New York?" and see how the model uses the new tool. -Notice the blank response in the UI? This is because instead of generating a text response, the model generated a tool call. You can access the tool call and subsequent tool result in the `toolInvocations` key of the message object. +Notice the blank response in the UI? This is because instead of generating a text response, the model generated a tool call. You can access the tool call and subsequent tool result via the `tool-invocation` part of the `message.parts` array. ### Update the UI diff --git a/content/docs/02-getting-started/05-nuxt.mdx b/content/docs/02-getting-started/05-nuxt.mdx index 4d1818782cfd..ed58a7f22d04 100644 --- a/content/docs/02-getting-started/05-nuxt.mdx +++ b/content/docs/02-getting-started/05-nuxt.mdx @@ -137,15 +137,19 @@ const { messages, input, handleSubmit } = useChat();