From 4c2bb77ffb35223a79ebba864e5c5e43e9563762 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 10 Sep 2025 17:01:14 +0200 Subject: [PATCH 001/121] fix (provider/openai): send sources action as include (#8559) ## Background `web_search_call.action.sources` was not sent to the OpenAI API. ## Summary * check if tool is `web_search` or `web_search_preview` and use correct name in tool calls and results * automatically add `web_search_call.action.sources` include when either web search tool is present * remove redundant tests ## Manual Verification - [x] run `examples/ai-core/src/generate-text/openai-web-search-tool.ts` ## Tasks - [x] add include flag automatically - [x] investigate why there are no tool calls / results in the generate case - [x] update generate test (outputs, check flag) - [x] add easy way to record raw chunks and use them in tests - [x] investigate why stream does not send sources - [x] update stream test (outputs, check flag) - [x] update examples - [x] changeset ## Related Issues Closes #8528 --- .changeset/eighty-buses-raise.md | 5 + .../generate-text/openai-web-search-tool.ts | 20 +- examples/ai-core/src/lib/save-raw-chunks.ts | 22 + .../src/stream-text/openai-web-search-tool.ts | 43 +- .../responses/openai-responses-api-types.ts | 13 + .../openai-responses-language-model.test.ts | 1463 +++++++++-------- .../openai-responses-language-model.ts | 53 +- .../openai-web-search-tool.chunks.txt | 56 + 8 files changed, 924 insertions(+), 751 deletions(-) create mode 100644 .changeset/eighty-buses-raise.md create mode 100644 examples/ai-core/src/lib/save-raw-chunks.ts create mode 100644 packages/openai/src/responses/test-fixtures/openai-web-search-tool.chunks.txt diff --git a/.changeset/eighty-buses-raise.md b/.changeset/eighty-buses-raise.md new file mode 100644 index 000000000000..9f650ebe942a --- /dev/null +++ b/.changeset/eighty-buses-raise.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +fix (provider/openai): send sources action as include diff --git a/examples/ai-core/src/generate-text/openai-web-search-tool.ts b/examples/ai-core/src/generate-text/openai-web-search-tool.ts index 7703e4bb6ad5..fd063e7c97a9 100644 --- a/examples/ai-core/src/generate-text/openai-web-search-tool.ts +++ b/examples/ai-core/src/generate-text/openai-web-search-tool.ts @@ -1,10 +1,10 @@ import { openai } from '@ai-sdk/openai'; import { generateText } from 'ai'; -import 'dotenv/config'; +import { run } from '../lib/run'; -async function main() { +run(async () => { const result = await generateText({ - model: openai.responses('gpt-5'), + model: openai.responses('gpt-5-mini'), prompt: 'What happened in tech news today?', tools: { web_search: openai.tools.webSearch({ @@ -13,13 +13,9 @@ async function main() { }, }); - for (const toolCall of result.toolCalls) { - if (toolCall.toolName === 'web_search') { - console.log('Search query:', toolCall.input); - } - } - + console.dir(result.response.body, { depth: Infinity }); + console.dir(result.toolCalls, { depth: Infinity }); + console.dir(result.toolResults, { depth: Infinity }); + console.dir(result.sources, { depth: Infinity }); console.log(result.text); -} - -main().catch(console.error); +}); diff --git a/examples/ai-core/src/lib/save-raw-chunks.ts b/examples/ai-core/src/lib/save-raw-chunks.ts new file mode 100644 index 000000000000..520454692c5b --- /dev/null +++ b/examples/ai-core/src/lib/save-raw-chunks.ts @@ -0,0 +1,22 @@ +import { StreamTextResult } from 'ai'; +import fs from 'fs'; + +export async function saveRawChunks({ + result, + filename, +}: { + result: StreamTextResult; + filename: string; +}) { + const rawChunks: unknown[] = []; + for await (const chunk of result.fullStream) { + if (chunk.type === 'raw') { + rawChunks.push(chunk.rawValue); + } + } + + fs.writeFileSync( + filename, + rawChunks.map(chunk => JSON.stringify(chunk)).join('\n'), + ); +} diff --git a/examples/ai-core/src/stream-text/openai-web-search-tool.ts b/examples/ai-core/src/stream-text/openai-web-search-tool.ts index 5a13c25b90f7..ecaa82c908d3 100644 --- a/examples/ai-core/src/stream-text/openai-web-search-tool.ts +++ b/examples/ai-core/src/stream-text/openai-web-search-tool.ts @@ -1,17 +1,16 @@ import { openai } from '@ai-sdk/openai'; -import { stepCountIs, streamText } from 'ai'; -import 'dotenv/config'; +import { streamText } from 'ai'; +import { run } from '../lib/run'; -async function main() { +run(async () => { const result = streamText({ - model: openai.responses('gpt-4o-mini'), + model: openai.responses('gpt-5-mini'), + prompt: 'What happened in tech news today?', tools: { web_search: openai.tools.webSearch({ - searchContextSize: 'high', + searchContextSize: 'medium', }), }, - prompt: 'Look up the company that owns Sonny Angel', - stopWhen: stepCountIs(5), // note: should stop after a single step }); for await (const chunk of result.fullStream) { @@ -22,36 +21,30 @@ async function main() { } case 'tool-call': { - console.log('Tool call:', JSON.stringify(chunk, null, 2)); + console.log( + `\x1b[32m\x1b[1mTool call:\x1b[22m ${JSON.stringify(chunk, null, 2)}\x1b[0m`, + ); break; } case 'tool-result': { - console.log('Tool result:', JSON.stringify(chunk, null, 2)); + console.log( + `\x1b[32m\x1b[1mTool result:\x1b[22m ${JSON.stringify(chunk, null, 2)}\x1b[0m`, + ); break; } case 'source': { if (chunk.sourceType === 'url') { - process.stdout.write(`\n\n Source: ${chunk.title} (${chunk.url})`); - } else { - process.stdout.write(`\n\n Document: ${chunk.title}`); + process.stdout.write( + `\n\n\x1b[36mSource: ${chunk.title} (${chunk.url})\x1b[0m\n\n`, + ); } break; } - case 'finish-step': { - console.log(); - console.log(); - console.log('STEP FINISH'); - console.log('Finish reason:', chunk.finishReason); - console.log('Usage:', chunk.usage); - console.log(); - break; - } - case 'finish': { - console.log('FINISH'); + console.log('\n\nFINISH'); console.log('Finish reason:', chunk.finishReason); console.log('Total Usage:', chunk.totalUsage); break; @@ -62,6 +55,4 @@ async function main() { break; } } -} - -main().catch(console.error); +}); diff --git a/packages/openai/src/responses/openai-responses-api-types.ts b/packages/openai/src/responses/openai-responses-api-types.ts index d1a9cea559f5..049ccb1d5da3 100644 --- a/packages/openai/src/responses/openai-responses-api-types.ts +++ b/packages/openai/src/responses/openai-responses-api-types.ts @@ -13,6 +13,19 @@ export type OpenAIResponsesMessage = | OpenAIFileSearchCall | OpenAIResponsesReasoning; +export type OpenAIResponsesIncludeOptions = + | Array< + | 'web_search_call.action.sources' + | 'code_interpreter_call.outputs' + | 'computer_call_output.output.image_url' + | 'file_search_call.results' + | 'message.input_image.image_url' + | 'message.output_text.logprobs' + | 'reasoning.encrypted_content' + > + | undefined + | null; + export type OpenAIResponsesSystemMessage = { role: 'system' | 'developer'; content: string; diff --git a/packages/openai/src/responses/openai-responses-language-model.test.ts b/packages/openai/src/responses/openai-responses-language-model.test.ts index 22dd1d93ff64..80793fe1da9d 100644 --- a/packages/openai/src/responses/openai-responses-language-model.test.ts +++ b/packages/openai/src/responses/openai-responses-language-model.test.ts @@ -7,12 +7,13 @@ import { createTestServer, mockId, } from '@ai-sdk/provider-utils/test'; +import fs from 'node:fs'; +import { beforeEach, describe, expect, it } from 'vitest'; import { OpenAIResponsesLanguageModel } from './openai-responses-language-model'; import { openaiResponsesModelIds, openaiResponsesReasoningModelIds, } from './openai-responses-settings'; -import { beforeEach, describe, expect, it } from 'vitest'; const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -41,6 +42,15 @@ const TEST_TOOLS: Array = [ }, ]; +function loadOpenAIChunks(filename: string) { + const lines = fs + .readFileSync(filename, 'utf8') + .split('\n') + .map(line => `data: ${line}\n\n`); + lines.push('data: [DONE]\n\n'); + return lines; +} + const nonReasoningModelIds = openaiResponsesModelIds.filter( modelId => !openaiResponsesReasoningModelIds.includes( @@ -929,83 +939,6 @@ describe('OpenAIResponsesLanguageModel', () => { expect(warnings).toStrictEqual([]); }); - it('should send web_search tool', async () => { - const { warnings } = await createModel('gpt-4o').doGenerate({ - tools: [ - { - type: 'provider-defined', - id: 'openai.web_search_preview', - name: 'web_search_preview', - args: { - searchContextSize: 'high', - userLocation: { - type: 'approximate', - city: 'San Francisco', - }, - }, - }, - ], - prompt: TEST_PROMPT, - }); - - expect(await server.calls[0].requestBodyJson).toStrictEqual({ - model: 'gpt-4o', - tools: [ - { - type: 'web_search_preview', - search_context_size: 'high', - user_location: { type: 'approximate', city: 'San Francisco' }, - }, - ], - input: [ - { role: 'user', content: [{ type: 'input_text', text: 'Hello' }] }, - ], - }); - - expect(warnings).toStrictEqual([]); - }); - - it('should send web_search tool as tool_choice', async () => { - const { warnings } = await createModel('gpt-4o').doGenerate({ - toolChoice: { - type: 'tool', - toolName: 'web_search_preview', - }, - tools: [ - { - type: 'provider-defined', - id: 'openai.web_search_preview', - name: 'web_search_preview', - args: { - searchContextSize: 'high', - userLocation: { - type: 'approximate', - city: 'San Francisco', - }, - }, - }, - ], - prompt: TEST_PROMPT, - }); - - expect(await server.calls[0].requestBodyJson).toStrictEqual({ - model: 'gpt-4o', - tool_choice: { type: 'web_search_preview' }, - tools: [ - { - type: 'web_search_preview', - search_context_size: 'high', - user_location: { type: 'approximate', city: 'San Francisco' }, - }, - ], - input: [ - { role: 'user', content: [{ type: 'input_text', text: 'Hello' }] }, - ], - }); - - expect(warnings).toStrictEqual([]); - }); - it('should send file_search tool', async () => { const { warnings } = await createModel('gpt-4o').doGenerate({ tools: [ @@ -2369,8 +2302,6 @@ describe('OpenAIResponsesLanguageModel', () => { }); describe('web search', () => { - const outputText = `Last week in San Francisco, several notable events and developments took place:\n\n**Bruce Lee Statue in Chinatown**\n\nThe Chinese Historical Society of America Museum announced plans to install a Bruce Lee statue in Chinatown. This initiative, supported by the Rose Pak Community Fund, the Bruce Lee Foundation, and Stand With Asians, aims to honor Lee's contributions to film and martial arts. Artist Arnie Kim has been commissioned for the project, with a fundraising goal of $150,000. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/07/bruce-lee-statue-sf-chinatown?utm_source=chatgpt.com))\n\n**Office Leasing Revival**\n\nThe Bay Area experienced a resurgence in office leasing, securing 11 of the largest U.S. office leases in 2024. This trend, driven by the tech industry's growth and advancements in generative AI, suggests a potential boost to downtown recovery through increased foot traffic. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/bay-area-office-leasing-activity?utm_source=chatgpt.com))\n\n**Spring Blooms in the Bay Area**\n\nWith the arrival of spring, several locations in the Bay Area are showcasing vibrant blooms. Notable spots include the Conservatory of Flowers, Japanese Tea Garden, Queen Wilhelmina Tulip Garden, and the San Francisco Botanical Garden, each offering unique floral displays. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/where-to-see-spring-blooms-bay-area?utm_source=chatgpt.com))\n\n**Oceanfront Great Highway Park**\n\nSan Francisco's long-awaited Oceanfront Great Highway park is set to open on April 12. This 43-acre, car-free park will span a two-mile stretch of the Great Highway from Lincoln Way to Sloat Boulevard, marking the largest pedestrianization project in California's history. The park follows voter approval of Proposition K, which permanently bans cars on part of the highway. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/great-highway-park-opening-april-recall-campaign?utm_source=chatgpt.com))\n\n**Warmer Spring Seasons**\n\nAn analysis by Climate Central revealed that San Francisco, along with most U.S. cities, is experiencing increasingly warmer spring seasons. Over a 55-year period from 1970 to 2024, the national average temperature during March through May rose by 2.4°F. This warming trend poses various risks, including early snowmelt and increased wildfire threats. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/climate-weather-spring-temperatures-warmer-sf?utm_source=chatgpt.com))\n\n\n# Key San Francisco Developments Last Week:\n- [Bruce Lee statue to be installed in SF Chinatown](https://www.axios.com/local/san-francisco/2025/03/07/bruce-lee-statue-sf-chinatown?utm_source=chatgpt.com)\n- [The Bay Area is set to make an office leasing comeback](https://www.axios.com/local/san-francisco/2025/03/03/bay-area-office-leasing-activity?utm_source=chatgpt.com)\n- [Oceanfront Great Highway park set to open in April](https://www.axios.com/local/san-francisco/2025/03/03/great-highway-park-opening-april-recall-campaign?utm_source=chatgpt.com)`; - beforeEach(() => { server.urls['https://api.openai.com/v1/responses'].response = { type: 'json-value', @@ -2411,7 +2342,7 @@ describe('OpenAIResponsesLanguageModel', () => { content: [ { type: 'output_text', - text: outputText, + text: `Last week in San Francisco, several notable events and developments took place:\n\n**Bruce Lee Statue in Chinatown**\n\nThe Chinese Historical Society of America Museum announced plans to install a Bruce Lee statue in Chinatown. This initiative, supported by the Rose Pak Community Fund, the Bruce Lee Foundation, and Stand With Asians, aims to honor Lee's contributions to film and martial arts. Artist Arnie Kim has been commissioned for the project, with a fundraising goal of $150,000. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/07/bruce-lee-statue-sf-chinatown?utm_source=chatgpt.com))\n\n**Office Leasing Revival**\n\nThe Bay Area experienced a resurgence in office leasing, securing 11 of the largest U.S. office leases in 2024. This trend, driven by the tech industry's growth and advancements in generative AI, suggests a potential boost to downtown recovery through increased foot traffic. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/bay-area-office-leasing-activity?utm_source=chatgpt.com))\n\n**Spring Blooms in the Bay Area**\n\nWith the arrival of spring, several locations in the Bay Area are showcasing vibrant blooms. Notable spots include the Conservatory of Flowers, Japanese Tea Garden, Queen Wilhelmina Tulip Garden, and the San Francisco Botanical Garden, each offering unique floral displays. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/where-to-see-spring-blooms-bay-area?utm_source=chatgpt.com))\n\n**Oceanfront Great Highway Park**\n\nSan Francisco's long-awaited Oceanfront Great Highway park is set to open on April 12. This 43-acre, car-free park will span a two-mile stretch of the Great Highway from Lincoln Way to Sloat Boulevard, marking the largest pedestrianization project in California's history. The park follows voter approval of Proposition K, which permanently bans cars on part of the highway. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/great-highway-park-opening-april-recall-campaign?utm_source=chatgpt.com))\n\n**Warmer Spring Seasons**\n\nAn analysis by Climate Central revealed that San Francisco, along with most U.S. cities, is experiencing increasingly warmer spring seasons. Over a 55-year period from 1970 to 2024, the national average temperature during March through May rose by 2.4°F. This warming trend poses various risks, including early snowmelt and increased wildfire threats. ([axios.com](https://www.axios.com/local/san-francisco/2025/03/03/climate-weather-spring-temperatures-warmer-sf?utm_source=chatgpt.com))\n\n\n# Key San Francisco Developments Last Week:\n- [Bruce Lee statue to be installed in SF Chinatown](https://www.axios.com/local/san-francisco/2025/03/07/bruce-lee-statue-sf-chinatown?utm_source=chatgpt.com)\n- [The Bay Area is set to make an office leasing comeback](https://www.axios.com/local/san-francisco/2025/03/03/bay-area-office-leasing-activity?utm_source=chatgpt.com)\n- [Oceanfront Great Highway park set to open in April](https://www.axios.com/local/san-francisco/2025/03/03/great-highway-park-opening-april-recall-campaign?utm_source=chatgpt.com)`, annotations: [ { type: 'url_citation', @@ -2473,7 +2404,7 @@ describe('OpenAIResponsesLanguageModel', () => { tool_choice: 'auto', tools: [ { - type: 'web_search_preview', + type: 'web_search', search_context_size: 'medium', user_location: { type: 'approximate', @@ -2503,7 +2434,118 @@ describe('OpenAIResponsesLanguageModel', () => { }; }); - it('should generate text and sources', async () => { + it('should send web_search tool', async () => { + const { warnings } = await createModel('gpt-4o').doGenerate({ + tools: [ + { + type: 'provider-defined', + id: 'openai.web_search', + name: 'web_search', + args: { + searchContextSize: 'high', + userLocation: { + type: 'approximate', + city: 'San Francisco', + }, + }, + }, + ], + prompt: TEST_PROMPT, + }); + + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "include": [ + "web_search_call.action.sources", + ], + "input": [ + { + "content": [ + { + "text": "Hello", + "type": "input_text", + }, + ], + "role": "user", + }, + ], + "model": "gpt-4o", + "tools": [ + { + "search_context_size": "high", + "type": "web_search", + "user_location": { + "city": "San Francisco", + "type": "approximate", + }, + }, + ], + } + `); + + expect(warnings).toStrictEqual([]); + }); + + it('should send web_search tool as tool_choice', async () => { + const { warnings } = await createModel('gpt-4o').doGenerate({ + toolChoice: { + type: 'tool', + toolName: 'web_search', + }, + tools: [ + { + type: 'provider-defined', + id: 'openai.web_search', + name: 'web_search', + args: { + searchContextSize: 'high', + userLocation: { + type: 'approximate', + city: 'San Francisco', + }, + }, + }, + ], + prompt: TEST_PROMPT, + }); + + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "include": [ + "web_search_call.action.sources", + ], + "input": [ + { + "content": [ + { + "text": "Hello", + "type": "input_text", + }, + ], + "role": "user", + }, + ], + "model": "gpt-4o", + "tool_choice": { + "type": "web_search", + }, + "tools": [ + { + "search_context_size": "high", + "type": "web_search", + "user_location": { + "city": "San Francisco", + "type": "approximate", + }, + }, + ], + } + `); + + expect(warnings).toStrictEqual([]); + }); + + it('should generate content', async () => { const result = await createModel('gpt-4o').doGenerate({ prompt: TEST_PROMPT, }); @@ -2514,7 +2556,7 @@ describe('OpenAIResponsesLanguageModel', () => { "input": "{"action":{"type":"search","query":"Vercel AI SDK next version features"}}", "providerExecuted": true, "toolCallId": "ws_67cf2b3051e88190b006770db6fdb13d", - "toolName": "web_search_preview", + "toolName": "web_search", "type": "tool-call", }, { @@ -2523,14 +2565,14 @@ describe('OpenAIResponsesLanguageModel', () => { "status": "completed", }, "toolCallId": "ws_67cf2b3051e88190b006770db6fdb13d", - "toolName": "web_search_preview", + "toolName": "web_search", "type": "tool-result", }, { "input": "{"action":{"type":"search"}}", "providerExecuted": true, "toolCallId": "ws_67cf2b3051e88190b006234456fdb13d", - "toolName": "web_search_preview", + "toolName": "web_search", "type": "tool-call", }, { @@ -2539,7 +2581,7 @@ describe('OpenAIResponsesLanguageModel', () => { "status": "completed", }, "toolCallId": "ws_67cf2b3051e88190b006234456fdb13d", - "toolName": "web_search_preview", + "toolName": "web_search", "type": "tool-result", }, { @@ -2615,233 +2657,231 @@ describe('OpenAIResponsesLanguageModel', () => { ] `); }); + }); - it('should handle file_search tool calls in generate', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'json-value', - body: { - id: 'resp_67cf3390786881908b27489d7e8cfb6b', - object: 'response', - created_at: 1741632400, - status: 'completed', - error: null, - incomplete_details: null, - input: [], - instructions: null, - max_output_tokens: null, - model: 'gpt-4o-mini-2024-07-18', - output: [ - { - type: 'file_search_call', - id: 'fs_67cf3390e9608190869b5d45698a7067', - status: 'completed', - queries: ['AI information'], - results: [ - { - attributes: { - file_id: 'file-123', - filename: 'ai_guide.pdf', - score: 0.95, - text: 'AI is a field of computer science', - }, - }, - ], - }, - { - id: 'msg_67cf33924ea88190b8c12bf68c1f6416', - type: 'message', - status: 'completed', - role: 'assistant', - content: [ - { - type: 'output_text', - text: 'Based on the search results, here is the information you requested.', - annotations: [], + it('should handle file_search tool calls in generate', async () => { + server.urls['https://api.openai.com/v1/responses'].response = { + type: 'json-value', + body: { + id: 'resp_67cf3390786881908b27489d7e8cfb6b', + object: 'response', + created_at: 1741632400, + status: 'completed', + error: null, + incomplete_details: null, + input: [], + instructions: null, + max_output_tokens: null, + model: 'gpt-4o-mini-2024-07-18', + output: [ + { + type: 'file_search_call', + id: 'fs_67cf3390e9608190869b5d45698a7067', + status: 'completed', + queries: ['AI information'], + results: [ + { + attributes: { + file_id: 'file-123', + filename: 'ai_guide.pdf', + score: 0.95, + text: 'AI is a field of computer science', }, - ], - }, - ], - parallel_tool_calls: true, - previous_response_id: null, - reasoning: { - effort: null, - summary: null, + }, + ], }, - store: true, - temperature: 0, - text: { - format: { - type: 'text', - }, + { + id: 'msg_67cf33924ea88190b8c12bf68c1f6416', + type: 'message', + status: 'completed', + role: 'assistant', + content: [ + { + type: 'output_text', + text: 'Based on the search results, here is the information you requested.', + annotations: [], + }, + ], }, - tool_choice: 'auto', - tools: [ - { - type: 'file_search', - }, - ], - top_p: 1, - truncation: 'disabled', - usage: { - input_tokens: 327, - input_tokens_details: { - cached_tokens: 0, - }, - output_tokens: 834, - output_tokens_details: { - reasoning_tokens: 0, - }, - total_tokens: 1161, + ], + parallel_tool_calls: true, + previous_response_id: null, + reasoning: { + effort: null, + summary: null, + }, + store: true, + temperature: 0, + text: { + format: { + type: 'text', }, - user: null, - metadata: {}, }, - }; - - const result = await createModel('gpt-4o-mini').doGenerate({ - prompt: TEST_PROMPT, - }); - - expect(result.content).toMatchInlineSnapshot(` - [ + tool_choice: 'auto', + tools: [ { - "input": "", - "providerExecuted": true, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-call", + type: 'file_search', }, - { - "providerExecuted": true, - "result": { - "queries": [ - "AI information", - ], - "results": [ - { - "attributes": { - "file_id": "file-123", - "filename": "ai_guide.pdf", - "score": 0.95, - "text": "AI is a field of computer science", - }, - }, - ], - "status": "completed", - "type": "file_search_tool_result", - }, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-result", + ], + top_p: 1, + truncation: 'disabled', + usage: { + input_tokens: 327, + input_tokens_details: { + cached_tokens: 0, }, - { - "providerMetadata": { - "openai": { - "itemId": "msg_67cf33924ea88190b8c12bf68c1f6416", + output_tokens: 834, + output_tokens_details: { + reasoning_tokens: 0, + }, + total_tokens: 1161, + }, + user: null, + metadata: {}, + }, + }; + + const result = await createModel('gpt-4o-mini').doGenerate({ + prompt: TEST_PROMPT, + }); + + expect(result.content).toMatchInlineSnapshot(` + [ + { + "input": "", + "providerExecuted": true, + "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", + "toolName": "file_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "queries": [ + "AI information", + ], + "results": [ + { + "attributes": { + "file_id": "file-123", + "filename": "ai_guide.pdf", + "score": 0.95, + "text": "AI is a field of computer science", + }, }, + ], + "status": "completed", + "type": "file_search_tool_result", + }, + "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", + "toolName": "file_search", + "type": "tool-result", + }, + { + "providerMetadata": { + "openai": { + "itemId": "msg_67cf33924ea88190b8c12bf68c1f6416", }, - "text": "Based on the search results, here is the information you requested.", - "type": "text", }, - ] - `); - }); + "text": "Based on the search results, here is the information you requested.", + "type": "text", + }, + ] + `); + }); - it('should handle web search with action query field', async () => { + it('should handle computer use tool calls', async () => { + function prepareJsonResponse(body: any) { server.urls['https://api.openai.com/v1/responses'].response = { type: 'json-value', - body: { - id: 'resp_test', - object: 'response', - created_at: 1741630255, + body, + }; + } + prepareJsonResponse({ + id: 'resp_computer_test', + object: 'response', + created_at: 1741630255, + status: 'completed', + error: null, + incomplete_details: null, + instructions: null, + max_output_tokens: null, + model: 'gpt-4o-mini', + output: [ + { + type: 'computer_call', + id: 'computer_67cf2b3051e88190b006770db6fdb13d', status: 'completed', - error: null, - incomplete_details: null, - instructions: null, - max_output_tokens: null, - model: 'o3-2025-04-16', - output: [ + }, + { + type: 'message', + id: 'msg_computer_test', + status: 'completed', + role: 'assistant', + content: [ { - type: 'web_search_call', - id: 'ws_test', - status: 'completed', - action: { - type: 'search', - query: 'Vercel AI SDK next version features', - }, + type: 'output_text', + text: "I've completed the computer task.", + annotations: [], }, + ], + }, + ], + usage: { input_tokens: 100, output_tokens: 50 }, + }); + + const result = await createModel('gpt-4o-mini').doGenerate({ + prompt: [ + { + role: 'user' as const, + content: [ { - type: 'message', - id: 'msg_test', - status: 'completed', - role: 'assistant', - content: [ - { - type: 'output_text', - text: 'Based on the search results, here are the upcoming features.', - annotations: [], - }, - ], + type: 'text' as const, + text: 'Use the computer to complete a task.', }, ], - parallel_tool_calls: true, - previous_response_id: null, - reasoning: { effort: null, summary: null }, - store: true, - temperature: 0, - text: { format: { type: 'text' } }, - tool_choice: 'auto', - tools: [ - { type: 'web_search_preview', search_context_size: 'medium' }, - ], - top_p: 1, - truncation: 'disabled', - usage: { - input_tokens: 50, - input_tokens_details: { cached_tokens: 0 }, - output_tokens: 25, - output_tokens_details: { reasoning_tokens: 0 }, - total_tokens: 75, - }, - user: null, - metadata: {}, }, - }; - - const result = await createModel('o3-2025-04-16').doGenerate({ - prompt: TEST_PROMPT, - }); + ], + tools: [ + { + type: 'provider-defined', + id: 'openai.computer_use', + name: 'computer_use', + args: {}, + }, + ], + }); - expect(result.content).toMatchInlineSnapshot(` + expect(result.content).toMatchInlineSnapshot(` [ { - "input": "{"action":{"type":"search","query":"Vercel AI SDK next version features"}}", + "input": "", "providerExecuted": true, - "toolCallId": "ws_test", - "toolName": "web_search_preview", + "toolCallId": "computer_67cf2b3051e88190b006770db6fdb13d", + "toolName": "computer_use", "type": "tool-call", }, { "providerExecuted": true, "result": { "status": "completed", + "type": "computer_use_tool_result", }, - "toolCallId": "ws_test", - "toolName": "web_search_preview", + "toolCallId": "computer_67cf2b3051e88190b006770db6fdb13d", + "toolName": "computer_use", "type": "tool-result", }, { "providerMetadata": { "openai": { - "itemId": "msg_test", + "itemId": "msg_computer_test", }, }, - "text": "Based on the search results, here are the upcoming features.", + "text": "I've completed the computer task.", "type": "text", }, ] `); - }); }); describe('errors', () => { @@ -3259,108 +3299,6 @@ describe('OpenAIResponsesLanguageModel', () => { `); }); - it('should handle streaming web search with action query field', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'stream-chunks', - chunks: [ - `data:{"type":"response.created","response":{"id":"resp_test","object":"response","created_at":1741630255,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"o3-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":"medium","summary":"auto"},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search_preview","search_context_size":"medium"}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, - `data:{"type":"response.output_item.added","output_index":0,"item":{"type":"web_search_call","id":"ws_test","status":"in_progress","action":{"type":"search","query":"Vercel AI SDK next version features"}}}\n\n`, - `data:{"type":"response.web_search_call.in_progress","output_index":0,"item_id":"ws_test"}\n\n`, - `data:{"type":"response.web_search_call.searching","output_index":0,"item_id":"ws_test"}\n\n`, - `data:{"type":"response.web_search_call.completed","output_index":0,"item_id":"ws_test"}\n\n`, - `data:{"type":"response.output_item.done","output_index":0,"item":{"type":"web_search_call","id":"ws_test","status":"completed","action":{"type":"search","query":"Vercel AI SDK next version features"}}}\n\n`, - `data:{"type":"response.output_item.added","output_index":1,"item":{"type":"message","id":"msg_test","status":"in_progress","role":"assistant","content":[]}}\n\n`, - `data:{"type":"response.content_part.added","item_id":"msg_test","output_index":1,"content_index":0,"part":{"type":"output_text","text":"","annotations":[]}}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_test","output_index":1,"content_index":0,"delta":"Based on the search results, here are the upcoming features."}\n\n`, - `data:{"type":"response.output_text.done","item_id":"msg_test","output_index":1,"content_index":0,"text":"Based on the search results, here are the upcoming features."}\n\n`, - `data:{"type":"response.content_part.done","item_id":"msg_test","output_index":1,"content_index":0,"part":{"type":"output_text","text":"Based on the search results, here are the upcoming features.","annotations":[]}}\n\n`, - `data:{"type":"response.output_item.done","output_index":1,"item":{"type":"message","id":"msg_test","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here are the upcoming features.","annotations":[]}]}}\n\n`, - `data:{"type":"response.completed","response":{"id":"resp_test","object":"response","created_at":1741630255,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"o3-2025-04-16","output":[{"type":"web_search_call","id":"ws_test","status":"completed","action":{"type":"search","query":"Vercel AI SDK next version features"}},{"type":"message","id":"msg_test","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here are the upcoming features.","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":"medium","summary":"auto"},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search_preview","search_context_size":"medium"}],"top_p":1,"truncation":"disabled","usage":{"input_tokens":50,"input_tokens_details":{"cached_tokens":0},"output_tokens":25,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":75},"user":null,"metadata":{}}}\n\n`, - 'data: [DONE]\n\n', - ], - }; - - const { stream } = await createModel('o3-2025-04-16').doStream({ - prompt: TEST_PROMPT, - includeRawChunks: false, - }); - - const result = await convertReadableStreamToArray(stream); - expect(result).toMatchInlineSnapshot(` - [ - { - "type": "stream-start", - "warnings": [], - }, - { - "id": "resp_test", - "modelId": "o3-2025-04-16", - "timestamp": 2025-03-10T18:10:55.000Z, - "type": "response-metadata", - }, - { - "id": "ws_test", - "toolName": "web_search_preview", - "type": "tool-input-start", - }, - { - "id": "ws_test", - "type": "tool-input-end", - }, - { - "input": "{"action":{"type":"search","query":"Vercel AI SDK next version features"}}", - "providerExecuted": true, - "toolCallId": "ws_test", - "toolName": "web_search", - "type": "tool-call", - }, - { - "providerExecuted": true, - "result": { - "status": "completed", - }, - "toolCallId": "ws_test", - "toolName": "web_search", - "type": "tool-result", - }, - { - "id": "msg_test", - "providerMetadata": { - "openai": { - "itemId": "msg_test", - }, - }, - "type": "text-start", - }, - { - "delta": "Based on the search results, here are the upcoming features.", - "id": "msg_test", - "type": "text-delta", - }, - { - "id": "msg_test", - "type": "text-end", - }, - { - "finishReason": "stop", - "providerMetadata": { - "openai": { - "responseId": "resp_test", - }, - }, - "type": "finish", - "usage": { - "cachedInputTokens": 0, - "inputTokens": 50, - "outputTokens": 25, - "reasoningTokens": 0, - "totalTokens": 75, - }, - }, - ] - `); - }); - it('should send finish reason for incomplete response', async () => { server.urls['https://api.openai.com/v1/responses'].response = { type: 'stream-chunks', @@ -3766,63 +3704,58 @@ describe('OpenAIResponsesLanguageModel', () => { `); }); - it('should stream sources', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'stream-chunks', - chunks: [ - `data:{"type":"response.created","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search_preview","search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, - `data:{"type":"response.in_progress","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search_preview","search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, - `data:{"type":"response.output_item.added","output_index":0,"item":{"type":"web_search_call","id":"ws_67cf3390e9608190869b5d45698a7067","status":"in_progress"}}\n\n`, - `data:{"type":"response.web_search_call.in_progress","output_index":0,"item_id":"ws_67cf3390e9608190869b5d45698a7067"}\n\n`, - `data:{"type":"response.web_search_call.searching","output_index":0,"item_id":"ws_67cf3390e9608190869b5d45698a7067"}\n\n`, - `data:{"type":"response.web_search_call.completed","output_index":0,"item_id":"ws_67cf3390e9608190869b5d45698a7067"}\n\n`, - `data:{"type":"response.output_item.done","output_index":0,"item":{"type":"web_search_call","id":"ws_67cf3390e9608190869b5d45698a7067","status":"completed"}}\n\n`, - `data:{"type":"response.output_item.added","output_index":1,"item":{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"in_progress","role":"assistant","content":[]}}\n\n`, - `data:{"type":"response.content_part.added","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"part":{"type":"output_text","text":"","annotations":[]}}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":"Last week"}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":" in San Francisco"}\n\n`, - `data:{"type":"response.output_text.annotation.added","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"annotation_index":0,"annotation":{"type":"url_citation","start_index":383,"end_index":493,"url":"https://www.sftourismtips.com/san-francisco-events-in-march.html?utm_source=chatgpt.com","title":"San Francisco Events in March 2025: Festivals, Theater & Easter"}}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":" a themed party"}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":"([axios.com](https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com))"}\n\n`, - `data:{"type":"response.output_text.annotation.added","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"annotation_index":1,"annotation":{"type":"url_citation","start_index":630,"end_index":762,"url":"https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com","title":"SF weekend events: Giants FanFest, crab crawl and more"}}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":"."}\n\n`, - `data:{"type":"response.output_text.done","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"text":"Last week in San Francisco a themed..."}\n\n`, - `data:{"type":"response.content_part.done","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"part":{"type":"output_text","text":"Last week in San Francisco a themed party...","annotations":[{"type":"url_citation","start_index":383,"end_index":493,"url":"https://www.sftourismtips.com/san-francisco-events-in-march.html?utm_source=chatgpt.com","title":"San Francisco Events in March 2025: Festivals, Theater & Easter"},{"type":"url_citation","start_index":630,"end_index":762,"url":"https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com","title":"SF weekend events: Giants FanFest, crab crawl and more"}]}}\n\n`, - `data:{"type":"response.output_item.done","output_index":1,"item":{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Last week in San Francisco a themed party...","annotations":[{"type":"url_citation","start_index":383,"end_index":493,"url":"https://www.sftourismtips.com/san-francisco-events-in-march.html?utm_source=chatgpt.com","title":"San Francisco Events in March 2025: Festivals, Theater & Easter"},{"type":"url_citation","start_index":630,"end_index":762,"url":"https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com","title":"SF weekend events: Giants FanFest, crab crawl and more"}]}]}}\n\n`, - `data:{"type":"response.completed","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[{"type":"web_search_call","id":"ws_67cf3390e9608190869b5d45698a7067","status":"completed"},{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Last week in San Francisco a themed party...","annotations":[{"type":"url_citation","start_index":383,"end_index":493,"url":"https://www.sftourismtips.com/san-francisco-events-in-march.html?utm_source=chatgpt.com","title":"San Francisco Events in March 2025: Festivals, Theater & Easter"},{"type":"url_citation","start_index":630,"end_index":762,"url":"https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com","title":"SF weekend events: Giants FanFest, crab crawl and more"}]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search_preview","search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_p":1,"truncation":"disabled","usage":{"input_tokens":327,"input_tokens_details":{"cached_tokens":0},"output_tokens":834,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":1161},"user":null,"metadata":{}}}\n\n`, - ], - }; + describe('web search tool', () => { + it('should handle streaming web search with action query field', async () => { + server.urls['https://api.openai.com/v1/responses'].response = { + type: 'stream-chunks', + chunks: [ + `data:{"type":"response.created","response":{"id":"resp_test","object":"response","created_at":1741630255,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"o3-2025-04-16","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":"medium","summary":"auto"},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search","search_context_size":"medium"}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, + `data:{"type":"response.output_item.added","output_index":0,"item":{"type":"web_search_call","id":"ws_test","status":"in_progress","action":{"type":"search","query":"Vercel AI SDK next version features"}}}\n\n`, + `data:{"type":"response.web_search_call.in_progress","output_index":0,"item_id":"ws_test"}\n\n`, + `data:{"type":"response.web_search_call.searching","output_index":0,"item_id":"ws_test"}\n\n`, + `data:{"type":"response.web_search_call.completed","output_index":0,"item_id":"ws_test"}\n\n`, + `data:{"type":"response.output_item.done","output_index":0,"item":{"type":"web_search_call","id":"ws_test","status":"completed","action":{"type":"search","query":"Vercel AI SDK next version features"}}}\n\n`, + `data:{"type":"response.output_item.added","output_index":1,"item":{"type":"message","id":"msg_test","status":"in_progress","role":"assistant","content":[]}}\n\n`, + `data:{"type":"response.content_part.added","item_id":"msg_test","output_index":1,"content_index":0,"part":{"type":"output_text","text":"","annotations":[]}}\n\n`, + `data:{"type":"response.output_text.delta","item_id":"msg_test","output_index":1,"content_index":0,"delta":"Based on the search results, here are the upcoming features."}\n\n`, + `data:{"type":"response.output_text.done","item_id":"msg_test","output_index":1,"content_index":0,"text":"Based on the search results, here are the upcoming features."}\n\n`, + `data:{"type":"response.content_part.done","item_id":"msg_test","output_index":1,"content_index":0,"part":{"type":"output_text","text":"Based on the search results, here are the upcoming features.","annotations":[]}}\n\n`, + `data:{"type":"response.output_item.done","output_index":1,"item":{"type":"message","id":"msg_test","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here are the upcoming features.","annotations":[]}]}}\n\n`, + `data:{"type":"response.completed","response":{"id":"resp_test","object":"response","created_at":1741630255,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"o3-2025-04-16","output":[{"type":"web_search_call","id":"ws_test","status":"completed","action":{"type":"search","query":"Vercel AI SDK next version features"}},{"type":"message","id":"msg_test","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here are the upcoming features.","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":"medium","summary":"auto"},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search","search_context_size":"medium"}],"top_p":1,"truncation":"disabled","usage":{"input_tokens":50,"input_tokens_details":{"cached_tokens":0},"output_tokens":25,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":75},"user":null,"metadata":{}}}\n\n`, + 'data: [DONE]\n\n', + ], + }; - const { stream } = await createModel('gpt-4o-mini').doStream({ - prompt: TEST_PROMPT, - includeRawChunks: false, - }); + const { stream } = await createModel('o3-2025-04-16').doStream({ + prompt: TEST_PROMPT, + }); - expect(await convertReadableStreamToArray(stream)).toMatchInlineSnapshot(` + const result = await convertReadableStreamToArray(stream); + expect(result).toMatchInlineSnapshot(` [ { "type": "stream-start", "warnings": [], }, { - "id": "resp_67cf3390786881908b27489d7e8cfb6b", - "modelId": "gpt-4o-mini-2024-07-18", - "timestamp": 2025-03-10T18:46:40.000Z, + "id": "resp_test", + "modelId": "o3-2025-04-16", + "timestamp": 2025-03-10T18:10:55.000Z, "type": "response-metadata", }, { - "id": "ws_67cf3390e9608190869b5d45698a7067", - "toolName": "web_search_preview", + "id": "ws_test", + "toolName": "web_search", "type": "tool-input-start", }, { - "id": "ws_67cf3390e9608190869b5d45698a7067", + "id": "ws_test", "type": "tool-input-end", }, { - "input": "{}", + "input": "{"action":{"type":"search","query":"Vercel AI SDK next version features"}}", "providerExecuted": true, - "toolCallId": "ws_67cf3390e9608190869b5d45698a7067", + "toolCallId": "ws_test", "toolName": "web_search", "type": "tool-call", }, @@ -3831,80 +3764,430 @@ describe('OpenAIResponsesLanguageModel', () => { "result": { "status": "completed", }, - "toolCallId": "ws_67cf3390e9608190869b5d45698a7067", + "toolCallId": "ws_test", "toolName": "web_search", "type": "tool-result", }, { - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", + "id": "msg_test", "providerMetadata": { "openai": { - "itemId": "msg_67cf33924ea88190b8c12bf68c1f6416", + "itemId": "msg_test", + }, + }, + "type": "text-start", + }, + { + "delta": "Based on the search results, here are the upcoming features.", + "id": "msg_test", + "type": "text-delta", + }, + { + "id": "msg_test", + "type": "text-end", + }, + { + "finishReason": "stop", + "providerMetadata": { + "openai": { + "responseId": "resp_test", + }, + }, + "type": "finish", + "usage": { + "cachedInputTokens": 0, + "inputTokens": 50, + "outputTokens": 25, + "reasoningTokens": 0, + "totalTokens": 75, + }, + }, + ] + `); + }); + + it('should stream web search results (sources, tool calls, tool results)', async () => { + server.urls['https://api.openai.com/v1/responses'].response = { + type: 'stream-chunks', + chunks: loadOpenAIChunks( + 'src/responses/test-fixtures/openai-web-search-tool.chunks.txt', + ), + }; + + const { stream } = await createModel('gpt-5-nano').doStream({ + tools: [ + { + type: 'provider-defined', + id: 'openai.web_search', + name: 'web_search', + args: {}, + }, + ], + prompt: TEST_PROMPT, + }); + + expect(await convertReadableStreamToArray(stream)) + .toMatchInlineSnapshot(` + [ + { + "type": "stream-start", + "warnings": [], + }, + { + "id": "resp_68c187cc09508192aa225af9734e2ed905ca09a4773fcd25", + "modelId": "gpt-5-nano-2025-08-07", + "timestamp": 2025-09-10T14:14:36.000Z, + "type": "response-metadata", + }, + { + "id": "rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-input-start", + }, + { + "id": "ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25", + "type": "tool-input-end", + }, + { + "input": "{"action":{"type":"search","query":"Berlin news today"}}", + "providerExecuted": true, + "toolCallId": "ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "status": "completed", + }, + "toolCallId": "ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-result", + }, + { + "id": "rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-input-start", + }, + { + "id": "ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25", + "type": "tool-input-end", + }, + { + "input": "{"action":{"type":"search"}}", + "providerExecuted": true, + "toolCallId": "ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "status": "completed", + }, + "toolCallId": "ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-result", + }, + { + "id": "rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-input-start", + }, + { + "id": "ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25", + "type": "tool-input-end", + }, + { + "input": "{"action":{"type":"search"}}", + "providerExecuted": true, + "toolCallId": "ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "status": "completed", + }, + "toolCallId": "ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-result", + }, + { + "id": "rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-input-start", + }, + { + "id": "ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25", + "type": "tool-input-end", + }, + { + "input": "{"action":{"type":"search"}}", + "providerExecuted": true, + "toolCallId": "ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "status": "completed", + }, + "toolCallId": "ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25", + "toolName": "web_search", + "type": "tool-result", + }, + { + "id": "rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "providerMetadata": { + "openai": { + "itemId": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + }, + }, + "type": "text-start", + }, + { + "delta": "Here’s what’s notable in Berlin today (September 10, 2025), based on three quick web searches: + + - Berlin Art Week 2025 kicks off today and runs through September 14. The city’s autumn art season opens with more than 100 venues, featuring exhibitions from Patti Smith, Mark Leckey, Katharina Grosse, Carrie Mae Weems, and more. ([wallpaper.com](https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025)) + + - The city is highlighting its 200-year Museum Island anniversary this year, with ongoing events and exhibitions around Berlin’s historic center. This is part of Berlin’s big year of cultural highlights. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events)) + + - 49h ICC: Open House is scheduled for September 11–14, offering guided tours and design talks at the former ICC Berlin. It’s one of the major architecture/design events associated with Berlin 2025. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events)) + + - Open Monument Day is coming up on September 13–14, when many", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "id": "id-0", + "sourceType": "url", + "title": "What to see at Berlin Art Week 2025 | Wallpaper*", + "type": "source", + "url": "https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025", + }, + { + "id": "id-1", + "sourceType": "url", + "title": "Berlin 2025 – the main events | visitBerlin.de", + "type": "source", + "url": "https://www.visitberlin.de/en/berlin-2025-the-main-events", + }, + { + "id": "id-2", + "sourceType": "url", + "title": "Berlin 2025 – the main events | visitBerlin.de", + "type": "source", + "url": "https://www.visitberlin.de/en/berlin-2025-the-main-events", + }, + { + "delta": " historic sites around Berlin open to the public with special programs. If you’re in town this weekend, it’s a good chance to explore landmarks that aren’t usually accessible.", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": " ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events)) + + - If you’re a sports fan, Berlin will host NFL games", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "id": "id-3", + "sourceType": "url", + "title": "Berlin 2025 – the main events | visitBerlin.de", + "type": "source", + "url": "https://www.visitberlin.de/en/berlin-2025-the-main-events", + }, + { + "delta": " in November 2025 (three regular-season games in the Olympic Stadium, with the Indianapolis Colts among", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": " the teams). It’s part of Berlin’s ongoing slate of major events this year", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": ". ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events)) + + - For some broader", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", }, - }, - "type": "text-start", - }, - { - "delta": "Last week", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "delta": " in San Francisco", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "id": "id-0", - "sourceType": "url", - "title": "San Francisco Events in March 2025: Festivals, Theater & Easter", - "type": "source", - "url": "https://www.sftourismtips.com/san-francisco-events-in-march.html?utm_source=chatgpt.com", - }, - { - "delta": " a themed party", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "delta": "([axios.com](https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com))", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "id": "id-1", - "sourceType": "url", - "title": "SF weekend events: Giants FanFest, crab crawl and more", - "type": "source", - "url": "https://www.axios.com/local/san-francisco/2025/03/06/sf-events-march-what-to-do-giants-fanfest?utm_source=chatgpt.com", - }, - { - "delta": ".", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-end", - }, - { - "finishReason": "stop", - "providerMetadata": { - "openai": { - "responseId": "resp_67cf3390786881908b27489d7e8cfb6b", + { + "id": "id-4", + "sourceType": "url", + "title": "Berlin 2025 – the main events | visitBerlin.de", + "type": "source", + "url": "https://www.visitberlin.de/en/berlin-2025-the-main-events", }, - }, - "type": "finish", - "usage": { - "cachedInputTokens": 0, - "inputTokens": 327, - "outputTokens": 834, - "reasoningTokens": 0, - "totalTokens": 1161, - }, - }, - ] - `); + { + "delta": " context, Berlin has been discussing its role in postwar security arrangements for Ukraine, with", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": " German officials signaling readiness to increase support but delaying a formal deployment decision until broader conditions are", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": " clearer. This", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": " was reported for early September 2025. ([reuters.com](https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/))", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "id": "id-5", + "sourceType": "url", + "title": "Berlin holds off decision on participation in postwar Ukraine force | Reuters", + "type": "source", + "url": "https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/", + }, + { + "delta": " + + Would you like me to pull live updates or focus on a specific topic (arts,", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "delta": " politics, sports) from today?", + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-delta", + }, + { + "id": "msg_68c187e279048192be3775da689aa25105ca09a4773fcd25", + "type": "text-end", + }, + { + "finishReason": "stop", + "providerMetadata": { + "openai": { + "responseId": "resp_68c187cc09508192aa225af9734e2ed905ca09a4773fcd25", + "serviceTier": "default", + }, + }, + "type": "finish", + "usage": { + "cachedInputTokens": 34560, + "inputTokens": 60093, + "outputTokens": 4080, + "reasoningTokens": 3648, + "totalTokens": 64173, + }, + }, + ] + `); + }); }); describe('errors', () => { @@ -3912,7 +4195,7 @@ describe('OpenAIResponsesLanguageModel', () => { server.urls['https://api.openai.com/v1/responses'].response = { type: 'stream-chunks', chunks: [ - `data:{"type":"response.created","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search_preview","search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, + `data:{"type":"response.created","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"web_search","search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, `data:{"type":"error","code":"ERR_SOMETHING","message":"Something went wrong","param":null,"sequence_number":1}\n\n`, ], }; @@ -5020,230 +5303,6 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); }); - - describe('server-side tools', () => { - const TEST_PROMPT = [ - { - role: 'user' as const, - content: [ - { - type: 'text' as const, - text: 'Search for recent news about San Francisco tech events, then check the status of our server-side tool implementation.', - }, - ], - }, - ]; - - function prepareJsonResponse(body: any) { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'json-value', - body, - }; - } - - it('should enable server-side web search when using openai.tools.webSearchPreview', async () => { - prepareJsonResponse({ - id: 'resp_67cf2b2f6bd081909be2c8054ddef0eb', - object: 'response', - created_at: 1741630255, - status: 'completed', - error: null, - incomplete_details: null, - instructions: null, - max_output_tokens: null, - model: 'gpt-4o-mini', - output: [ - { - type: 'web_search_call', - id: 'ws_67cf2b3051e88190b006770db6fdb13d', - status: 'completed', - }, - { - type: 'message', - id: 'msg_67cf2b35467481908f24412e4fd40d66', - status: 'completed', - role: 'assistant', - content: [ - { - type: 'output_text', - text: "As of June 23, 2025, here are some recent developments in San Francisco's tech scene:", - annotations: [ - { - type: 'url_citation', - start_index: 0, - end_index: 50, - url: 'https://www.eventbrite.sg/d/ca--san-francisco/tech-events/?utm_source=openai', - title: - 'Discover Tech Events & Activities in San Francisco, CA | Eventbrite', - }, - { - type: 'url_citation', - start_index: 51, - end_index: 100, - url: 'https://www.axios.com/2024/12/10/ai-sf-summit-2024-roundup?utm_source=openai', - title: 'AI+ SF Summit: AI agents are the next big thing', - }, - ], - }, - ], - }, - ], - usage: { input_tokens: 1359, output_tokens: 624 }, - }); - - const result = await createModel('gpt-4o-mini').doGenerate({ - prompt: TEST_PROMPT, - tools: [ - { - type: 'provider-defined', - id: 'openai.web_search_preview', - name: 'web_search_preview', - args: { - searchContextSize: 'high', - userLocation: { - type: 'approximate', - city: 'San Francisco', - region: 'California', - country: 'US', - }, - }, - }, - ], - }); - - expect(result.content).toMatchInlineSnapshot(` - [ - { - "input": "{}", - "providerExecuted": true, - "toolCallId": "ws_67cf2b3051e88190b006770db6fdb13d", - "toolName": "web_search_preview", - "type": "tool-call", - }, - { - "providerExecuted": true, - "result": { - "status": "completed", - }, - "toolCallId": "ws_67cf2b3051e88190b006770db6fdb13d", - "toolName": "web_search_preview", - "type": "tool-result", - }, - { - "providerMetadata": { - "openai": { - "itemId": "msg_67cf2b35467481908f24412e4fd40d66", - }, - }, - "text": "As of June 23, 2025, here are some recent developments in San Francisco's tech scene:", - "type": "text", - }, - { - "id": "id-0", - "sourceType": "url", - "title": "Discover Tech Events & Activities in San Francisco, CA | Eventbrite", - "type": "source", - "url": "https://www.eventbrite.sg/d/ca--san-francisco/tech-events/?utm_source=openai", - }, - { - "id": "id-1", - "sourceType": "url", - "title": "AI+ SF Summit: AI agents are the next big thing", - "type": "source", - "url": "https://www.axios.com/2024/12/10/ai-sf-summit-2024-roundup?utm_source=openai", - }, - ] - `); - }); - - it('should handle computer use tool calls', async () => { - prepareJsonResponse({ - id: 'resp_computer_test', - object: 'response', - created_at: 1741630255, - status: 'completed', - error: null, - incomplete_details: null, - instructions: null, - max_output_tokens: null, - model: 'gpt-4o-mini', - output: [ - { - type: 'computer_call', - id: 'computer_67cf2b3051e88190b006770db6fdb13d', - status: 'completed', - }, - { - type: 'message', - id: 'msg_computer_test', - status: 'completed', - role: 'assistant', - content: [ - { - type: 'output_text', - text: "I've completed the computer task.", - annotations: [], - }, - ], - }, - ], - usage: { input_tokens: 100, output_tokens: 50 }, - }); - - const result = await createModel('gpt-4o-mini').doGenerate({ - prompt: [ - { - role: 'user' as const, - content: [ - { - type: 'text' as const, - text: 'Use the computer to complete a task.', - }, - ], - }, - ], - tools: [ - { - type: 'provider-defined', - id: 'openai.computer_use', - name: 'computer_use', - args: {}, - }, - ], - }); - - expect(result.content).toMatchInlineSnapshot(` - [ - { - "input": "", - "providerExecuted": true, - "toolCallId": "computer_67cf2b3051e88190b006770db6fdb13d", - "toolName": "computer_use", - "type": "tool-call", - }, - { - "providerExecuted": true, - "result": { - "status": "completed", - "type": "computer_use_tool_result", - }, - "toolCallId": "computer_67cf2b3051e88190b006770db6fdb13d", - "toolName": "computer_use", - "type": "tool-result", - }, - { - "providerMetadata": { - "openai": { - "itemId": "msg_computer_test", - }, - }, - "text": "I've completed the computer task.", - "type": "text", - }, - ] - `); - }); - }); }); describe('fileIdPrefixes configuration', () => { diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index e997ba57d9ba..45d07014817d 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -4,6 +4,7 @@ import { LanguageModelV2CallWarning, LanguageModelV2Content, LanguageModelV2FinishReason, + LanguageModelV2ProviderDefinedTool, LanguageModelV2StreamPart, LanguageModelV2Usage, SharedV2ProviderMetadata, @@ -24,6 +25,7 @@ import { convertToOpenAIResponsesMessages } from './convert-to-openai-responses- import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason'; import { prepareResponsesTools } from './openai-responses-prepare-tools'; import { OpenAIResponsesModelId } from './openai-responses-settings'; +import { OpenAIResponsesIncludeOptions } from './openai-responses-api-types'; const webSearchCallItem = z.object({ type: z.literal('web_search_call'), @@ -152,17 +154,37 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { const strictJsonSchema = openaiOptions?.strictJsonSchema ?? false; + let include: OpenAIResponsesIncludeOptions = openaiOptions?.include; + + // when logprobs are requested, automatically include them: const topLogprobs = typeof openaiOptions?.logprobs === 'number' ? openaiOptions?.logprobs : openaiOptions?.logprobs === true ? TOP_LOGPROBS_MAX : undefined; - const openaiOptionsInclude = topLogprobs - ? Array.isArray(openaiOptions?.include) - ? [...openaiOptions?.include, 'message.output_text.logprobs'] + + include = topLogprobs + ? Array.isArray(include) + ? [...include, 'message.output_text.logprobs'] : ['message.output_text.logprobs'] - : openaiOptions?.include; + : include; + + // when a web search tool is present, automatically include the sources: + const webSearchToolName = ( + tools?.find( + tool => + tool.type === 'provider-defined' && + (tool.id === 'openai.web_search' || + tool.id === 'openai.web_search_preview'), + ) as LanguageModelV2ProviderDefinedTool | undefined + )?.name; + + include = webSearchToolName + ? Array.isArray(include) + ? [...include, 'web_search_call.action.sources'] + : ['web_search_call.action.sources'] + : include; const baseArgs = { model: this.modelId, @@ -199,7 +221,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { user: openaiOptions?.user, instructions: openaiOptions?.instructions, service_tier: openaiOptions?.serviceTier, - include: openaiOptionsInclude, + include, prompt_cache_key: openaiOptions?.promptCacheKey, safety_identifier: openaiOptions?.safetyIdentifier, top_logprobs: topLogprobs, @@ -301,6 +323,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }); return { + webSearchToolName, args: { ...baseArgs, tools: openaiTools, @@ -313,7 +336,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { async doGenerate( options: Parameters[0], ): Promise>> { - const { args: body, warnings } = await this.getArgs(options); + const { + args: body, + warnings, + webSearchToolName, + } = await this.getArgs(options); const url = this.config.url({ path: '/responses', modelId: this.modelId, @@ -539,7 +566,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { content.push({ type: 'tool-call', toolCallId: part.id, - toolName: 'web_search_preview', + toolName: webSearchToolName ?? 'web_search', input: JSON.stringify({ action: part.action }), providerExecuted: true, }); @@ -547,7 +574,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { content.push({ type: 'tool-result', toolCallId: part.id, - toolName: 'web_search_preview', + toolName: webSearchToolName ?? 'web_search', result: { status: part.status }, providerExecuted: true, }); @@ -645,7 +672,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { async doStream( options: Parameters[0], ): Promise>> { - const { args: body, warnings } = await this.getArgs(options); + const { + args: body, + warnings, + webSearchToolName, + } = await this.getArgs(options); const { responseHeaders, value: response } = await postJsonToApi({ url: this.config.url({ @@ -731,14 +762,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }); } else if (value.item.type === 'web_search_call') { ongoingToolCalls[value.output_index] = { - toolName: 'web_search_preview', + toolName: webSearchToolName ?? 'web_search', toolCallId: value.item.id, }; controller.enqueue({ type: 'tool-input-start', id: value.item.id, - toolName: 'web_search_preview', + toolName: webSearchToolName ?? 'web_search', }); } else if (value.item.type === 'computer_call') { ongoingToolCalls[value.output_index] = { diff --git a/packages/openai/src/responses/test-fixtures/openai-web-search-tool.chunks.txt b/packages/openai/src/responses/test-fixtures/openai-web-search-tool.chunks.txt new file mode 100644 index 000000000000..5c7868d99060 --- /dev/null +++ b/packages/openai/src/responses/test-fixtures/openai-web-search-tool.chunks.txt @@ -0,0 +1,56 @@ +{"type":"response.created","sequence_number":0,"response":{"id":"resp_68c187cc09508192aa225af9734e2ed905ca09a4773fcd25","object":"response","created_at":1757513676,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-nano-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"web_search","filters":null,"search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68c187cc09508192aa225af9734e2ed905ca09a4773fcd25","object":"response","created_at":1757513676,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-nano-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"web_search","filters":null,"search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25","type":"web_search_call","status":"in_progress"}} +{"type":"response.web_search_call.in_progress","sequence_number":5,"output_index":1,"item_id":"ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25"} +{"type":"response.web_search_call.searching","sequence_number":6,"output_index":1,"item_id":"ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25"} +{"type":"response.web_search_call.completed","sequence_number":7,"output_index":1,"item_id":"ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25"} +{"type":"response.output_item.done","sequence_number":8,"output_index":1,"item":{"id":"ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","query":"Berlin news today","sources":[{"type":"url","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"},{"type":"url","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"},{"type":"url","url":"https://en.wikipedia.org/wiki/75th_Berlin_International_Film_Festival"},{"type":"url","url":"https://apnews.com/article/ecf774eea5cdc7cbf88adf3887102d9b"},{"type":"url","url":"https://apnews.com/article/1710be90a0e733d016e32db4d8353e1c"},{"type":"url","url":"https://en.wikipedia.org/wiki/Rave_The_Planet_Parade"},{"type":"url","url":"https://en.wikipedia.org/wiki/2025_DFB-Pokal_final"},{"type":"url","url":"https://en.wikipedia.org/wiki/2025_Berlin_Tennis_Open"},{"type":"url","url":"https://en.wikipedia.org/wiki/Parkb%C3%BChne_Wuhlheide"},{"type":"url","url":"https://en.wikipedia.org/wiki/2025_Berlin_Tennis_Open_%E2%80%93_Singles"},{"type":"url","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url","url":"https://helloberl.in/berlin-events-feb-27-march-2nd-2025/"}]}}} +{"type":"response.output_item.added","sequence_number":9,"output_index":2,"item":{"id":"rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":10,"output_index":2,"item":{"id":"rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":11,"output_index":3,"item":{"id":"ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25","type":"web_search_call","status":"in_progress"}} +{"type":"response.web_search_call.in_progress","sequence_number":12,"output_index":3,"item_id":"ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25"} +{"type":"response.web_search_call.searching","sequence_number":13,"output_index":3,"item_id":"ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25"} +{"type":"response.web_search_call.completed","sequence_number":14,"output_index":3,"item_id":"ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25"} +{"type":"response.output_item.done","sequence_number":15,"output_index":3,"item":{"id":"ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","sources":[{"type":"url","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"}]}}} +{"type":"response.output_item.added","sequence_number":16,"output_index":4,"item":{"id":"rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":17,"output_index":4,"item":{"id":"rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":18,"output_index":5,"item":{"id":"ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25","type":"web_search_call","status":"in_progress"}} +{"type":"response.web_search_call.in_progress","sequence_number":19,"output_index":5,"item_id":"ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25"} +{"type":"response.web_search_call.searching","sequence_number":20,"output_index":5,"item_id":"ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25"} +{"type":"response.web_search_call.completed","sequence_number":21,"output_index":5,"item_id":"ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25"} +{"type":"response.output_item.done","sequence_number":22,"output_index":5,"item":{"id":"ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","sources":[{"type":"url","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"}]}}} +{"type":"response.output_item.added","sequence_number":23,"output_index":6,"item":{"id":"rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":24,"output_index":6,"item":{"id":"rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":25,"output_index":7,"item":{"id":"ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25","type":"web_search_call","status":"in_progress"}} +{"type":"response.web_search_call.in_progress","sequence_number":26,"output_index":7,"item_id":"ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25"} +{"type":"response.web_search_call.searching","sequence_number":27,"output_index":7,"item_id":"ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25"} +{"type":"response.web_search_call.completed","sequence_number":28,"output_index":7,"item_id":"ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25"} +{"type":"response.output_item.done","sequence_number":29,"output_index":7,"item":{"id":"ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","sources":[{"type":"url","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"}]}}} +{"type":"response.output_item.added","sequence_number":30,"output_index":8,"item":{"id":"rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":31,"output_index":8,"item":{"id":"rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":32,"output_index":9,"item":{"id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","type":"message","status":"in_progress","content":[],"role":"assistant"}} +{"type":"response.content_part.added","sequence_number":33,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} +{"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":"Here’s what’s notable in Berlin today (September 10, 2025), based on three quick web searches:\n\n- Berlin Art Week 2025 kicks off today and runs through September 14. The city’s autumn art season opens with more than 100 venues, featuring exhibitions from Patti Smith, Mark Leckey, Katharina Grosse, Carrie Mae Weems, and more. ([wallpaper.com](https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025))\n\n- The city is highlighting its 200-year Museum Island anniversary this year, with ongoing events and exhibitions around Berlin’s historic center. This is part of Berlin’s big year of cultural highlights. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- 49h ICC: Open House is scheduled for September 11–14, offering guided tours and design talks at the former ICC Berlin. It’s one of the major architecture/design events associated with Berlin 2025. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- Open Monument Day is coming up on September 13–14, when many","logprobs":[],"obfuscation":"Y"} +{"type":"response.output_text.annotation.added","sequence_number":35,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"annotation_index":0,"annotation":{"type":"url_citation","end_index":414,"start_index":327,"title":"What to see at Berlin Art Week 2025 | Wallpaper*","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"}} +{"type":"response.output_text.annotation.added","sequence_number":36,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"annotation_index":1,"annotation":{"type":"url_citation","end_index":697,"start_index":620,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"}} +{"type":"response.output_text.annotation.added","sequence_number":37,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"annotation_index":2,"annotation":{"type":"url_citation","end_index":975,"start_index":898,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"}} +{"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" historic sites around Berlin open to the public with special programs. If you’re in town this weekend, it’s a good chance to explore landmarks that aren’t usually accessible.","logprobs":[],"obfuscation":"M"} +{"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- If you’re a sports fan, Berlin will host NFL games","logprobs":[],"obfuscation":"IGQbTBYQU3o5"} +{"type":"response.output_text.annotation.added","sequence_number":40,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"annotation_index":3,"annotation":{"type":"url_citation","end_index":1292,"start_index":1215,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"}} +{"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" in November 2025 (three regular-season games in the Olympic Stadium, with the Indianapolis Colts among","logprobs":[],"obfuscation":"obbirOyig"} +{"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" the teams). It’s part of Berlin’s ongoing slate of major events this year","logprobs":[],"obfuscation":"y4HnJl"} +{"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":". ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- For some broader","logprobs":[],"obfuscation":"TmpmuVqo23O5Q"} +{"type":"response.output_text.annotation.added","sequence_number":44,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"annotation_index":4,"annotation":{"type":"url_citation","end_index":1602,"start_index":1525,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"}} +{"type":"response.output_text.delta","sequence_number":45,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" context, Berlin has been discussing its role in postwar security arrangements for Ukraine, with","logprobs":[],"obfuscation":""} +{"type":"response.output_text.delta","sequence_number":46,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" German officials signaling readiness to increase support but delaying a formal deployment decision until broader conditions are","logprobs":[],"obfuscation":""} +{"type":"response.output_text.delta","sequence_number":47,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" clearer. This","logprobs":[],"obfuscation":"k6"} +{"type":"response.output_text.delta","sequence_number":48,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" was reported for early September 2025. ([reuters.com](https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/))","logprobs":[],"obfuscation":"sFsCwiO"} +{"type":"response.output_text.annotation.added","sequence_number":49,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"annotation_index":5,"annotation":{"type":"url_citation","end_index":2029,"start_index":1900,"title":"Berlin holds off decision on participation in postwar Ukraine force | Reuters","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"}} +{"type":"response.output_text.delta","sequence_number":50,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":"\n\nWould you like me to pull live updates or focus on a specific topic (arts,","logprobs":[],"obfuscation":"0Jl6"} +{"type":"response.output_text.delta","sequence_number":51,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"delta":" politics, sports) from today?","logprobs":[],"obfuscation":"67"} +{"type":"response.output_text.done","sequence_number":52,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"text":"Here’s what’s notable in Berlin today (September 10, 2025), based on three quick web searches:\n\n- Berlin Art Week 2025 kicks off today and runs through September 14. The city’s autumn art season opens with more than 100 venues, featuring exhibitions from Patti Smith, Mark Leckey, Katharina Grosse, Carrie Mae Weems, and more. ([wallpaper.com](https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025))\n\n- The city is highlighting its 200-year Museum Island anniversary this year, with ongoing events and exhibitions around Berlin’s historic center. This is part of Berlin’s big year of cultural highlights. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- 49h ICC: Open House is scheduled for September 11–14, offering guided tours and design talks at the former ICC Berlin. It’s one of the major architecture/design events associated with Berlin 2025. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- Open Monument Day is coming up on September 13–14, when many historic sites around Berlin open to the public with special programs. If you’re in town this weekend, it’s a good chance to explore landmarks that aren’t usually accessible. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- If you’re a sports fan, Berlin will host NFL games in November 2025 (three regular-season games in the Olympic Stadium, with the Indianapolis Colts among the teams). It’s part of Berlin’s ongoing slate of major events this year. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- For some broader context, Berlin has been discussing its role in postwar security arrangements for Ukraine, with German officials signaling readiness to increase support but delaying a formal deployment decision until broader conditions are clearer. This was reported for early September 2025. ([reuters.com](https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/))\n\nWould you like me to pull live updates or focus on a specific topic (arts, politics, sports) from today?","logprobs":[]} +{"type":"response.content_part.done","sequence_number":53,"item_id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","output_index":9,"content_index":0,"part":{"type":"output_text","annotations":[{"type":"url_citation","end_index":414,"start_index":327,"title":"What to see at Berlin Art Week 2025 | Wallpaper*","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"},{"type":"url_citation","end_index":697,"start_index":620,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":975,"start_index":898,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":1292,"start_index":1215,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":1602,"start_index":1525,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":2029,"start_index":1900,"title":"Berlin holds off decision on participation in postwar Ukraine force | Reuters","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"}],"logprobs":[],"text":"Here’s what’s notable in Berlin today (September 10, 2025), based on three quick web searches:\n\n- Berlin Art Week 2025 kicks off today and runs through September 14. The city’s autumn art season opens with more than 100 venues, featuring exhibitions from Patti Smith, Mark Leckey, Katharina Grosse, Carrie Mae Weems, and more. ([wallpaper.com](https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025))\n\n- The city is highlighting its 200-year Museum Island anniversary this year, with ongoing events and exhibitions around Berlin’s historic center. This is part of Berlin’s big year of cultural highlights. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- 49h ICC: Open House is scheduled for September 11–14, offering guided tours and design talks at the former ICC Berlin. It’s one of the major architecture/design events associated with Berlin 2025. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- Open Monument Day is coming up on September 13–14, when many historic sites around Berlin open to the public with special programs. If you’re in town this weekend, it’s a good chance to explore landmarks that aren’t usually accessible. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- If you’re a sports fan, Berlin will host NFL games in November 2025 (three regular-season games in the Olympic Stadium, with the Indianapolis Colts among the teams). It’s part of Berlin’s ongoing slate of major events this year. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- For some broader context, Berlin has been discussing its role in postwar security arrangements for Ukraine, with German officials signaling readiness to increase support but delaying a formal deployment decision until broader conditions are clearer. This was reported for early September 2025. ([reuters.com](https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/))\n\nWould you like me to pull live updates or focus on a specific topic (arts, politics, sports) from today?"}} +{"type":"response.output_item.done","sequence_number":54,"output_index":9,"item":{"id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"url_citation","end_index":414,"start_index":327,"title":"What to see at Berlin Art Week 2025 | Wallpaper*","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"},{"type":"url_citation","end_index":697,"start_index":620,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":975,"start_index":898,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":1292,"start_index":1215,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":1602,"start_index":1525,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":2029,"start_index":1900,"title":"Berlin holds off decision on participation in postwar Ukraine force | Reuters","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"}],"logprobs":[],"text":"Here’s what’s notable in Berlin today (September 10, 2025), based on three quick web searches:\n\n- Berlin Art Week 2025 kicks off today and runs through September 14. The city’s autumn art season opens with more than 100 venues, featuring exhibitions from Patti Smith, Mark Leckey, Katharina Grosse, Carrie Mae Weems, and more. ([wallpaper.com](https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025))\n\n- The city is highlighting its 200-year Museum Island anniversary this year, with ongoing events and exhibitions around Berlin’s historic center. This is part of Berlin’s big year of cultural highlights. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- 49h ICC: Open House is scheduled for September 11–14, offering guided tours and design talks at the former ICC Berlin. It’s one of the major architecture/design events associated with Berlin 2025. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- Open Monument Day is coming up on September 13–14, when many historic sites around Berlin open to the public with special programs. If you’re in town this weekend, it’s a good chance to explore landmarks that aren’t usually accessible. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- If you’re a sports fan, Berlin will host NFL games in November 2025 (three regular-season games in the Olympic Stadium, with the Indianapolis Colts among the teams). It’s part of Berlin’s ongoing slate of major events this year. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- For some broader context, Berlin has been discussing its role in postwar security arrangements for Ukraine, with German officials signaling readiness to increase support but delaying a formal deployment decision until broader conditions are clearer. This was reported for early September 2025. ([reuters.com](https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/))\n\nWould you like me to pull live updates or focus on a specific topic (arts, politics, sports) from today?"}],"role":"assistant"}} +{"type":"response.completed","sequence_number":55,"response":{"id":"resp_68c187cc09508192aa225af9734e2ed905ca09a4773fcd25","object":"response","created_at":1757513676,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-nano-2025-08-07","output":[{"id":"rs_68c187cc87a88192b58352081364836c05ca09a4773fcd25","type":"reasoning","summary":[]},{"id":"ws_68c187d0973881928c78c79e50ae028805ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","query":"Berlin news today","sources":[{"type":"url","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"},{"type":"url","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"},{"type":"url","url":"https://en.wikipedia.org/wiki/75th_Berlin_International_Film_Festival"},{"type":"url","url":"https://apnews.com/article/ecf774eea5cdc7cbf88adf3887102d9b"},{"type":"url","url":"https://apnews.com/article/1710be90a0e733d016e32db4d8353e1c"},{"type":"url","url":"https://en.wikipedia.org/wiki/Rave_The_Planet_Parade"},{"type":"url","url":"https://en.wikipedia.org/wiki/2025_DFB-Pokal_final"},{"type":"url","url":"https://en.wikipedia.org/wiki/2025_Berlin_Tennis_Open"},{"type":"url","url":"https://en.wikipedia.org/wiki/Parkb%C3%BChne_Wuhlheide"},{"type":"url","url":"https://en.wikipedia.org/wiki/2025_Berlin_Tennis_Open_%E2%80%93_Singles"},{"type":"url","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url","url":"https://helloberl.in/berlin-events-feb-27-march-2nd-2025/"}]}},{"id":"rs_68c187d2484881929a3908a9ad4e745f05ca09a4773fcd25","type":"reasoning","summary":[]},{"id":"ws_68c187d3954881929c1d6d96c46e4fef05ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","sources":[{"type":"url","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"}]}},{"id":"rs_68c187d42c0481929f8e156e064bd0a105ca09a4773fcd25","type":"reasoning","summary":[]},{"id":"ws_68c187d4dd548192ab8473f8c95a4d8d05ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","sources":[{"type":"url","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"}]}},{"id":"rs_68c187d592f481929b10ff6121241b1d05ca09a4773fcd25","type":"reasoning","summary":[]},{"id":"ws_68c187d70ba88192aad48510cff1b4c905ca09a4773fcd25","type":"web_search_call","status":"completed","action":{"type":"search","sources":[{"type":"url","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"}]}},{"id":"rs_68c187d87fb481929fc9d6593d88c3dd05ca09a4773fcd25","type":"reasoning","summary":[]},{"id":"msg_68c187e279048192be3775da689aa25105ca09a4773fcd25","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"url_citation","end_index":414,"start_index":327,"title":"What to see at Berlin Art Week 2025 | Wallpaper*","url":"https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025"},{"type":"url_citation","end_index":697,"start_index":620,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":975,"start_index":898,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":1292,"start_index":1215,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":1602,"start_index":1525,"title":"Berlin 2025 – the main events | visitBerlin.de","url":"https://www.visitberlin.de/en/berlin-2025-the-main-events"},{"type":"url_citation","end_index":2029,"start_index":1900,"title":"Berlin holds off decision on participation in postwar Ukraine force | Reuters","url":"https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/"}],"logprobs":[],"text":"Here’s what’s notable in Berlin today (September 10, 2025), based on three quick web searches:\n\n- Berlin Art Week 2025 kicks off today and runs through September 14. The city’s autumn art season opens with more than 100 venues, featuring exhibitions from Patti Smith, Mark Leckey, Katharina Grosse, Carrie Mae Weems, and more. ([wallpaper.com](https://www.wallpaper.com/art/exhibitions-shows/berlin-art-week-2025))\n\n- The city is highlighting its 200-year Museum Island anniversary this year, with ongoing events and exhibitions around Berlin’s historic center. This is part of Berlin’s big year of cultural highlights. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- 49h ICC: Open House is scheduled for September 11–14, offering guided tours and design talks at the former ICC Berlin. It’s one of the major architecture/design events associated with Berlin 2025. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- Open Monument Day is coming up on September 13–14, when many historic sites around Berlin open to the public with special programs. If you’re in town this weekend, it’s a good chance to explore landmarks that aren’t usually accessible. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- If you’re a sports fan, Berlin will host NFL games in November 2025 (three regular-season games in the Olympic Stadium, with the Indianapolis Colts among the teams). It’s part of Berlin’s ongoing slate of major events this year. ([visitberlin.de](https://www.visitberlin.de/en/berlin-2025-the-main-events))\n\n- For some broader context, Berlin has been discussing its role in postwar security arrangements for Ukraine, with German officials signaling readiness to increase support but delaying a formal deployment decision until broader conditions are clearer. This was reported for early September 2025. ([reuters.com](https://www.reuters.com/world/europe/berlin-postpones-decision-military-engagement-regarding-ukraine-2025-09-04/))\n\nWould you like me to pull live updates or focus on a specific topic (arts, politics, sports) from today?"}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"web_search","filters":null,"search_context_size":"medium","user_location":{"type":"approximate","city":null,"country":"US","region":null,"timezone":null}}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":{"input_tokens":60093,"input_tokens_details":{"cached_tokens":34560},"output_tokens":4080,"output_tokens_details":{"reasoning_tokens":3648},"total_tokens":64173},"user":null,"metadata":{}}} \ No newline at end of file From 970163a7a5844e465d89d6662da7f74a04e18a0a Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 17:45:21 +0200 Subject: [PATCH 002/121] Version Packages (#8557) # Releases ## @ai-sdk/azure@2.0.28 ### Patch Changes - Updated dependencies [4c2bb77] - Updated dependencies [561e8b0] - @ai-sdk/openai@2.0.28 ## @ai-sdk/openai@2.0.28 ### Patch Changes - 4c2bb77: fix (provider/openai): send sources action as include - 561e8b0: fix (provider/openai): fix code interpreter tool in doGenerate Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/eighty-buses-raise.md | 5 ----- .changeset/violet-cameras-yell.md | 5 ----- packages/azure/CHANGELOG.md | 8 ++++++++ packages/azure/package.json | 2 +- packages/openai/CHANGELOG.md | 7 +++++++ packages/openai/package.json | 2 +- 6 files changed, 17 insertions(+), 12 deletions(-) delete mode 100644 .changeset/eighty-buses-raise.md delete mode 100644 .changeset/violet-cameras-yell.md diff --git a/.changeset/eighty-buses-raise.md b/.changeset/eighty-buses-raise.md deleted file mode 100644 index 9f650ebe942a..000000000000 --- a/.changeset/eighty-buses-raise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -fix (provider/openai): send sources action as include diff --git a/.changeset/violet-cameras-yell.md b/.changeset/violet-cameras-yell.md deleted file mode 100644 index 679379ce091f..000000000000 --- a/.changeset/violet-cameras-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -fix (provider/openai): fix code interpreter tool in doGenerate diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index ec0490aca5b9..a10850ad1909 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/azure +## 2.0.28 + +### Patch Changes + +- Updated dependencies [4c2bb77] +- Updated dependencies [561e8b0] + - @ai-sdk/openai@2.0.28 + ## 2.0.27 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index b131f096ad5c..24420c24472b 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.0.27", + "version": "2.0.28", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index d0f6a8711451..913fbd0e1b87 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/openai +## 2.0.28 + +### Patch Changes + +- 4c2bb77: fix (provider/openai): send sources action as include +- 561e8b0: fix (provider/openai): fix code interpreter tool in doGenerate + ## 2.0.27 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index b4e8ca1dcd0d..ad4459e75cd9 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.0.27", + "version": "2.0.28", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 4ee371916719e98304203a9871d35deeec5f8cd0 Mon Sep 17 00:00:00 2001 From: Rohan Taneja <47066511+R-Taneja@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:56:16 -0400 Subject: [PATCH 003/121] feat(provider/gateway): Add Meituan LongCat Flash Chat to autocomplete (#8547) ## Background Meituan released a new model - LongCat Flash Chat ## Summary Adds model to the autocomplete list for Gateway ## Manual Verification Autocomplete works ## Tasks - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) --- .changeset/tender-masks-grow.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/tender-masks-grow.md diff --git a/.changeset/tender-masks-grow.md b/.changeset/tender-masks-grow.md new file mode 100644 index 000000000000..ae671f5b28ee --- /dev/null +++ b/.changeset/tender-masks-grow.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat(provider/gateway): Add Meituan LongCat Flash Chat to autocomplete diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index 230213e8d75c..7eaf96e297bf 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -33,6 +33,7 @@ export type GatewayModelId = | 'google/gemini-2.5-pro' | 'google/gemma-2-9b' | 'inception/mercury-coder-small' + | 'meituan/longcat-flash-chat' | 'meta/llama-3-70b' | 'meta/llama-3-8b' | 'meta/llama-3.1-70b' From b75beb06b569861f1db5fab9dd3f16887f223d9e Mon Sep 17 00:00:00 2001 From: Tom Auger <31711089+tom-auger@users.noreply.github.com> Date: Thu, 11 Sep 2025 07:46:02 +0400 Subject: [PATCH 004/121] feat(vue): add useObject support for Vue (#8493) ## Summary * Added experimental_useObject to the Vue package, following the same pattern as the React version. * Added unit tests similar to the corresponding React tests. * Added example page to the nuxt-openai example project * Updated the docs. ## Manual Verification Added an example page `use-object` to the `nuxt-openai` example project to run and verify streaming objects works as expected. ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues Fixes #2903 --- .changeset/rude-readers-hope.md | 5 + .../04-ai-sdk-ui/08-object-generation.mdx | 5 +- .../02-ai-sdk-ui/03-use-object.mdx | 3 +- .../nuxt-openai/pages/use-object/index.vue | 69 +++++ examples/nuxt-openai/server/api/use-object.ts | 22 ++ .../nuxt-openai/shared/notification-schema.ts | 11 + packages/vue/package.json | 6 +- packages/vue/src/TestUseObjectComponent.vue | 45 ++++ .../TestUseObjectCustomTransportComponent.vue | 35 +++ packages/vue/src/index.ts | 1 + packages/vue/src/use-object.ts | 234 ++++++++++++++++ packages/vue/src/use-object.ui.test.tsx | 250 ++++++++++++++++++ pnpm-lock.yaml | 21 +- 13 files changed, 695 insertions(+), 12 deletions(-) create mode 100644 .changeset/rude-readers-hope.md create mode 100644 examples/nuxt-openai/pages/use-object/index.vue create mode 100644 examples/nuxt-openai/server/api/use-object.ts create mode 100644 examples/nuxt-openai/shared/notification-schema.ts create mode 100644 packages/vue/src/TestUseObjectComponent.vue create mode 100644 packages/vue/src/TestUseObjectCustomTransportComponent.vue create mode 100644 packages/vue/src/use-object.ts create mode 100644 packages/vue/src/use-object.ui.test.tsx diff --git a/.changeset/rude-readers-hope.md b/.changeset/rude-readers-hope.md new file mode 100644 index 000000000000..3824443dd731 --- /dev/null +++ b/.changeset/rude-readers-hope.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/vue': patch +--- + +Add useObject support to Vue diff --git a/content/docs/04-ai-sdk-ui/08-object-generation.mdx b/content/docs/04-ai-sdk-ui/08-object-generation.mdx index b5258db889c9..1413906c16ae 100644 --- a/content/docs/04-ai-sdk-ui/08-object-generation.mdx +++ b/content/docs/04-ai-sdk-ui/08-object-generation.mdx @@ -5,7 +5,10 @@ description: Learn how to use the useObject hook. # Object Generation -`useObject` is an experimental feature and only available in React. + + `useObject` is an experimental feature and only available in React, Svelte, + and Vue. + The [`useObject`](/docs/reference/ai-sdk-ui/use-object) hook allows you to create interfaces that represent a structured JSON object that is being streamed. diff --git a/content/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx b/content/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx index c020866cec49..fff8793ca9f0 100644 --- a/content/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx +++ b/content/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx @@ -6,7 +6,8 @@ description: API reference for the useObject hook. # `experimental_useObject()` - `useObject` is an experimental feature and only available in React and Svelte. + `useObject` is an experimental feature and only available in React, Svelte, + and Vue. Allows you to consume text streams that represent a JSON object and parse them into a complete object based on a schema. diff --git a/examples/nuxt-openai/pages/use-object/index.vue b/examples/nuxt-openai/pages/use-object/index.vue new file mode 100644 index 000000000000..737b01067ee2 --- /dev/null +++ b/examples/nuxt-openai/pages/use-object/index.vue @@ -0,0 +1,69 @@ + + + diff --git a/examples/nuxt-openai/server/api/use-object.ts b/examples/nuxt-openai/server/api/use-object.ts new file mode 100644 index 000000000000..4e7a59deb3e3 --- /dev/null +++ b/examples/nuxt-openai/server/api/use-object.ts @@ -0,0 +1,22 @@ +import { createOpenAI } from '@ai-sdk/openai'; +import { streamObject } from 'ai'; +import { notificationSchema } from '~/shared/notification-schema'; + +export default defineLazyEventHandler(async () => { + const apiKey = useRuntimeConfig().openaiApiKey; + if (!apiKey) throw new Error('Missing OpenAI API key'); + const openai = createOpenAI({ apiKey }); + + return defineEventHandler(async (event: any) => { + const context = await readBody(event); + + // Stream generated notifications as objects + const result = streamObject({ + model: openai('gpt-4.1'), + prompt: `Generate 5 notifications for a messages app in this context: ${context}`, + schema: notificationSchema, + }); + + return result.toTextStreamResponse(); + }); +}); diff --git a/examples/nuxt-openai/shared/notification-schema.ts b/examples/nuxt-openai/shared/notification-schema.ts new file mode 100644 index 000000000000..86f3e751fcd7 --- /dev/null +++ b/examples/nuxt-openai/shared/notification-schema.ts @@ -0,0 +1,11 @@ +import { z } from 'zod/v4'; + +export const notificationSchema = z.object({ + notifications: z.array( + z.object({ + name: z.string().describe('Name of a fictional person.'), + message: z.string().describe('Message. Do not use emojis or links.'), + minutesAgo: z.number(), + }), + ), +}); diff --git a/packages/vue/package.json b/packages/vue/package.json index 52af8c47426d..da830d689d01 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -50,11 +50,15 @@ "vitest": "2.1.4" }, "peerDependencies": { - "vue": "^3.3.4" + "vue": "^3.3.4", + "zod": "^3.25.76 || ^4" }, "peerDependenciesMeta": { "vue": { "optional": true + }, + "zod": { + "optional": true } }, "engines": { diff --git a/packages/vue/src/TestUseObjectComponent.vue b/packages/vue/src/TestUseObjectComponent.vue new file mode 100644 index 000000000000..c1e1f793ae00 --- /dev/null +++ b/packages/vue/src/TestUseObjectComponent.vue @@ -0,0 +1,45 @@ + + + diff --git a/packages/vue/src/TestUseObjectCustomTransportComponent.vue b/packages/vue/src/TestUseObjectCustomTransportComponent.vue new file mode 100644 index 000000000000..ad03c4d2e2e1 --- /dev/null +++ b/packages/vue/src/TestUseObjectCustomTransportComponent.vue @@ -0,0 +1,35 @@ + + + diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 2722bb568750..5e9d33a48d9d 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -1,2 +1,3 @@ export * from './use-completion'; export { Chat } from './chat.vue'; +export * from './use-object'; diff --git a/packages/vue/src/use-object.ts b/packages/vue/src/use-object.ts new file mode 100644 index 000000000000..6aeaf7d29b0a --- /dev/null +++ b/packages/vue/src/use-object.ts @@ -0,0 +1,234 @@ +import { ref, type Ref } from 'vue'; +import swrv from 'swrv'; +import { + isAbortError, + safeValidateTypes, + type FetchFunction, + type InferSchema, +} from '@ai-sdk/provider-utils'; +import { + asSchema, + type DeepPartial, + isDeepEqualData, + parsePartialJson, + type Schema, +} from 'ai'; +import * as z3 from 'zod/v3'; +import * as z4 from 'zod/v4'; + +// use function to allow for mocking in tests +const getOriginalFetch = () => fetch; + +export type Experimental_UseObjectOptions< + SCHEMA extends z4.core.$ZodType | z3.Schema | Schema, + RESULT, +> = { + /** API endpoint that streams JSON chunks matching the schema */ + api: string; + + /** Zod or AI schema that defines the final object shape */ + schema: SCHEMA; + + /** Shared state key. If omitted a random one is generated */ + id?: string; + + /** Initial partial value */ + initialValue?: DeepPartial; + + /** Optional custom fetch implementation */ + fetch?: FetchFunction; + + /** Called when stream ends */ + onFinish?: (event: { + object: RESULT | undefined; + error: Error | undefined; + }) => Promise | void; + + /** Called on error */ + onError?: (error: Error) => void; + + /** Extra request headers */ + headers?: Record | Headers; + + /** Request credentials mode. Defaults to 'same-origin' if omitted */ + credentials?: RequestCredentials; +}; + +export type Experimental_UseObjectHelpers = { + /** POST the input and start streaming */ + submit: (input: INPUT) => void; + + /** Current partial object, updated as chunks arrive */ + object: Ref | undefined>; + + /** Latest error if any */ + error: Ref; + + /** Loading flag for the in-flight request */ + isLoading: Ref; + + /** Abort the current request. Keeps current partial object. */ + stop: () => void; + + /** Abort and clear all state */ + clear: () => void; +}; + +let uniqueId = 0; + +// @ts-expect-error - some issues with the default export of useSWRV +const useSWRV = (swrv.default as (typeof import('swrv'))['default']) || swrv; +const store: Record = {}; + +export const experimental_useObject = function useObject< + SCHEMA extends z4.core.$ZodType | z3.Schema | Schema, + RESULT = InferSchema, + INPUT = any, +>({ + api, + id, + schema, + initialValue, + fetch, + onError, + onFinish, + headers, + credentials, +}: Experimental_UseObjectOptions< + SCHEMA, + RESULT +>): Experimental_UseObjectHelpers { + // Generate an unique id for the object if not provided. + const completionId = id || `completion-${uniqueId++}`; + + const key = `${api}|${completionId}`; + const { data, mutate: originalMutate } = useSWRV< + DeepPartial | undefined + >(key, () => (key in store ? store[key] : initialValue)); + + const { data: isLoading, mutate: mutateLoading } = useSWRV( + `${completionId}-loading`, + null, + ); + + isLoading.value ??= false; + data.value ||= initialValue as DeepPartial | undefined; + + const mutateObject = (value: DeepPartial | undefined) => { + store[key] = value; + return originalMutate(); + }; + + const error = ref(undefined); + let abortController: AbortController | null = null; + + const stop = async () => { + if (abortController) { + try { + abortController.abort(); + } catch { + // ignore + } finally { + abortController = null; + } + } + await mutateLoading(() => false); + }; + + const clearObject = async () => { + error.value = undefined; + await mutateLoading(() => false); + await mutateObject(undefined); + // Need to explicitly set the value to undefined to trigger a re-render + data.value = undefined; + }; + + const clear = async () => { + await stop(); + await clearObject(); + }; + + const submit = async (input: INPUT) => { + try { + await clearObject(); + await mutateLoading(() => true); + + abortController = new AbortController(); + + const actualFetch = fetch ?? getOriginalFetch(); + const response = await actualFetch(api, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(headers as any), + }, + credentials: credentials ?? 'same-origin', + signal: abortController.signal, + body: JSON.stringify(input), + }); + + if (!response.ok) { + throw new Error( + (await response.text()) || 'Failed to fetch the response.', + ); + } + + if (!response.body) { + throw new Error('The response body is empty.'); + } + + let accumulatedText = ''; + let latestObject: DeepPartial | undefined = undefined; + + await response.body.pipeThrough(new TextDecoderStream()).pipeTo( + new WritableStream({ + async write(chunk) { + accumulatedText += chunk; + const { value } = await parsePartialJson(accumulatedText); + const currentObject = value as DeepPartial; + if (!isDeepEqualData(latestObject, currentObject)) { + latestObject = currentObject; + await mutateObject(currentObject); + } + }, + async close() { + await mutateLoading(() => false); + abortController = null; + + if (onFinish) { + const validationResult = await safeValidateTypes({ + value: latestObject, + schema: asSchema(schema), + }); + + onFinish( + validationResult.success + ? { + object: validationResult.value as RESULT, + error: undefined, + } + : { object: undefined, error: validationResult.error }, + ); + } + }, + }), + ); + } catch (err: unknown) { + if (isAbortError(err)) return; + + if (onError && err instanceof Error) onError(err); + + await mutateLoading(() => false); + error.value = err instanceof Error ? err : new Error(String(err)); + } + }; + + return { + submit, + object: data, + error, + isLoading, + stop, + clear, + }; +}; diff --git a/packages/vue/src/use-object.ui.test.tsx b/packages/vue/src/use-object.ui.test.tsx new file mode 100644 index 000000000000..fdc05efd5196 --- /dev/null +++ b/packages/vue/src/use-object.ui.test.tsx @@ -0,0 +1,250 @@ +import { + createTestServer, + TestResponseController, +} from '@ai-sdk/provider-utils/test'; +import '@testing-library/jest-dom/vitest'; +import { cleanup, screen, waitFor } from '@testing-library/vue'; +import userEvent from '@testing-library/user-event'; +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { setupTestComponent } from './setup-test-component'; +import TestUseObjectComponent from './TestUseObjectComponent.vue'; +import TestUseObjectCustomTransportComponent from './TestUseObjectCustomTransportComponent.vue'; + +const server = createTestServer({ + '/api/use-object': {}, +}); + +describe('text stream', () => { + afterEach(() => { + vi.restoreAllMocks(); + cleanup(); + }); + + describe('basic component', () => { + setupTestComponent(TestUseObjectComponent); + + 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 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].requestBodyJson).toBe('test-input'); + }); + + it('should not have an error', async () => { + await screen.findByTestId('error'); + expect(screen.getByTestId('error')).toBeEmptyDOMElement(); + expect(screen.getByTestId('on-error-result')).toBeEmptyDOMElement(); + }); + }); + + describe('isLoading', () => { + it('should be true while loading', async () => { + const controller = new TestResponseController(); + server.urls['/api/use-object'].response = { + type: 'controlled-stream', + controller, + }; + + 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'); + }); + + controller.write('"Hello, world!"}'); + controller.close(); + + // wait for element "loading" to have text content "false": + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('false'); + }); + }); + }); + + 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: + await expect(controller.write('ello, world!"}')).rejects.toThrow(); + await expect(controller.close()).rejects.toThrow(); + + // should only show start of object: + await waitFor(() => { + expect(screen.getByTestId('object')).toHaveTextContent( + '{"content":"h"}', + ); + }); + }); + + it('should stop and clear the object state after a call to submit then clear', 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')); + + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('true'); + }); + await waitFor(() => { + expect(screen.getByTestId('object')).toHaveTextContent( + '{"content":"h"}', + ); + }); + + await userEvent.click(screen.getByTestId('clear-button')); + + await expect(controller.write('ello, world!"}')).rejects.toThrow(); + await expect(controller.close()).rejects.toThrow(); + + await waitFor(() => { + expect(screen.getByTestId('loading')).toHaveTextContent('false'); + expect(screen.getByTestId('error')).toBeEmptyDOMElement(); + expect(screen.getByTestId('object')).toBeEmptyDOMElement(); + }); + }); + + describe('when the API returns a 404', () => { + 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(screen.getByTestId('on-error-result')).toHaveTextContent( + 'Not found', + ); + 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', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + await userEvent.click(screen.getByTestId('submit-button')); + + expect(screen.getByTestId('on-finish-calls')).toHaveTextContent( + JSON.stringify([ + { 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(screen.getByTestId('on-finish-calls')).toHaveTextContent( + 'ZodError', + ); + }); + }); + + it('should clear the object state after a call to clear', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + await userEvent.click(screen.getByTestId('submit-button')); + + await screen.findByTestId('object'); + expect(screen.getByTestId('object')).toHaveTextContent( + JSON.stringify({ content: 'Hello, world!' }), + ); + + await userEvent.click(screen.getByTestId('clear-button')); + + await waitFor(() => { + expect(screen.getByTestId('object')).toBeEmptyDOMElement(); + expect(screen.getByTestId('error')).toBeEmptyDOMElement(); + expect(screen.getByTestId('loading')).toHaveTextContent('false'); + }); + }); + }); + + describe('custom transport', () => { + setupTestComponent(TestUseObjectCustomTransportComponent); + + it('should send custom headers', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Hello, ', 'world', '!"', '}'], + }; + + 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', + }); + }); + + it('should send custom credentials', async () => { + server.urls['/api/use-object'].response = { + type: 'stream-chunks', + chunks: ['{ ', '"content": "Authenticated ', 'content', '!"', '}'], + }; + + await userEvent.click(screen.getByTestId('submit-button')); + expect(server.calls[0].requestCredentials).toBe('include'); + }); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7788608fb65..e9fbdd9a317c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2608,6 +2608,9 @@ importers: vue: specifier: ^3.3.4 version: 3.3.8(typescript@5.8.3) + zod: + specifier: ^3.25.76 || ^4 + version: 3.25.76 devDependencies: '@testing-library/jest-dom': specifier: ^6.6.3 @@ -29315,8 +29318,8 @@ snapshots: '@typescript-eslint/parser': 7.2.0(eslint@8.57.1)(typescript@5.8.3) 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.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.34.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -29399,13 +29402,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 4.4.1 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.3))(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.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.3 get-tsconfig: 4.8.1 is-core-module: 2.16.1 @@ -29455,14 +29458,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.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: '@typescript-eslint/parser': 7.2.0(eslint@8.57.1)(typescript@5.8.3) 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.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -29531,7 +29534,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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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 @@ -29541,7 +29544,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.8.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.8.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.8.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.16.1 is-glob: 4.0.3 From 1c1f6caec0903f88a34de9c55530ee3ed680b86f Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 10:15:13 +0200 Subject: [PATCH 005/121] Version Packages (#8565) # Releases ## ai@5.0.40 ### Patch Changes - Updated dependencies [4ee3719] - @ai-sdk/gateway@1.0.21 ## @ai-sdk/angular@1.0.40 ### Patch Changes - ai@5.0.40 ## @ai-sdk/gateway@1.0.21 ### Patch Changes - 4ee3719: feat(provider/gateway): Add Meituan LongCat Flash Chat to autocomplete ## @ai-sdk/langchain@1.0.40 ### Patch Changes - ai@5.0.40 ## @ai-sdk/llamaindex@1.0.40 ### Patch Changes - ai@5.0.40 ## @ai-sdk/react@2.0.40 ### Patch Changes - ai@5.0.40 ## @ai-sdk/rsc@1.0.40 ### Patch Changes - ai@5.0.40 ## @ai-sdk/svelte@3.0.40 ### Patch Changes - ai@5.0.40 ## @ai-sdk/vue@2.0.40 ### Patch Changes - b75beb0: Add useObject support to Vue - ai@5.0.40 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/rude-readers-hope.md | 5 ----- .changeset/tender-masks-grow.md | 5 ----- packages/ai/CHANGELOG.md | 7 +++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 6 ++++++ packages/angular/package.json | 2 +- packages/gateway/CHANGELOG.md | 6 ++++++ packages/gateway/package.json | 2 +- packages/langchain/CHANGELOG.md | 6 ++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 6 ++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 6 ++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 6 ++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 6 ++++++ packages/svelte/CHANGELOG.md | 6 ++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 7 +++++++ packages/vue/package.json | 2 +- 21 files changed, 71 insertions(+), 19 deletions(-) delete mode 100644 .changeset/rude-readers-hope.md delete mode 100644 .changeset/tender-masks-grow.md diff --git a/.changeset/rude-readers-hope.md b/.changeset/rude-readers-hope.md deleted file mode 100644 index 3824443dd731..000000000000 --- a/.changeset/rude-readers-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/vue': patch ---- - -Add useObject support to Vue diff --git a/.changeset/tender-masks-grow.md b/.changeset/tender-masks-grow.md deleted file mode 100644 index ae671f5b28ee..000000000000 --- a/.changeset/tender-masks-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/gateway': patch ---- - -feat(provider/gateway): Add Meituan LongCat Flash Chat to autocomplete diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 7318ca092ec9..7803f81ba64b 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,12 @@ # ai +## 5.0.40 + +### Patch Changes + +- Updated dependencies [4ee3719] + - @ai-sdk/gateway@1.0.21 + ## 5.0.39 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 1857be2eb7ce..91a558d2494a 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.39", + "version": "5.0.40", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 50f3d718bd99..dc9e46fc77a8 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/angular +## 1.0.40 + +### Patch Changes + +- ai@5.0.40 + ## 1.0.39 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 4d7a3a2fff9f..99d364bfc89d 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.39", + "version": "1.0.40", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index e1aaba60072d..a966b2c7c968 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/gateway +## 1.0.21 + +### Patch Changes + +- 4ee3719: feat(provider/gateway): Add Meituan LongCat Flash Chat to autocomplete + ## 1.0.20 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index bf917a184103..45fa04d777d7 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.0.20", + "version": "1.0.21", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index a0d0bd844189..98030e2fbdaf 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/langchain +## 1.0.40 + +### Patch Changes + +- ai@5.0.40 + ## 1.0.39 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 44b0138bd357..1fa876d1ed60 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.39", + "version": "1.0.40", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 66a22184c952..cff40ff31fbf 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/llamaindex +## 1.0.40 + +### Patch Changes + +- ai@5.0.40 + ## 1.0.39 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index e12f9bd8d2bb..ce5242ef62af 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.39", + "version": "1.0.40", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 94cf65791680..9ae6d1f0771b 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/react +## 2.0.40 + +### Patch Changes + +- ai@5.0.40 + ## 2.0.39 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 26e9c254fdbb..3b5868a2660b 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.39", + "version": "2.0.40", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 02f76d4090ac..bb597dc9818d 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/rsc +## 1.0.40 + +### Patch Changes + +- ai@5.0.40 + ## 1.0.39 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index c7ac35434e36..6aae7ce82fd2 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.39", + "version": "1.0.40", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 301c5517a42e..15b0e730f435 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,12 @@ ### Patch Changes +- ai@5.0.40 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [a0a725f] - ai@5.0.39 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 0310a780f1ea..746c6cdb4e0a 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/svelte +## 3.0.40 + +### Patch Changes + +- ai@5.0.40 + ## 3.0.39 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index a113e5eeff97..cd581d43df9c 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.39", + "version": "3.0.40", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 22a125f2991c..9165c037d677 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 2.0.40 + +### Patch Changes + +- b75beb0: Add useObject support to Vue + - ai@5.0.40 + ## 2.0.39 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index da830d689d01..b20badd6141b 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.39", + "version": "2.0.40", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 4f11fffc10827c3b7b5a02accebc6f3f8bfc5751 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Thu, 11 Sep 2025 13:09:02 +0100 Subject: [PATCH 006/121] docs: update typescript performance troubleshooting recommendation (#8580) ## Background Typescript issues have been identified as likely resulting from `"moduleResolution": "node"` ## Summary Updated recommendation. ## Tasks - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [ ] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [ ] I have reviewed this pull request (self-review) ## Future Work ## Related Issues --- .../26-migration-guide-5-0.mdx | 24 +++++++++----- .../12-typescript-performance-zod.mdx | 31 ++++++++++++++----- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/content/docs/08-migration-guides/26-migration-guide-5-0.mdx b/content/docs/08-migration-guides/26-migration-guide-5-0.mdx index af3b2f398352..aec3ec99ebaf 100644 --- a/content/docs/08-migration-guides/26-migration-guide-5-0.mdx +++ b/content/docs/08-migration-guides/26-migration-guide-5-0.mdx @@ -34,6 +34,13 @@ An example upgrade command would be: npm install ai @ai-sdk/react @ai-sdk/openai zod@3.25.0 ``` + + If you encounter TypeScript performance issues after upgrading, update your + `tsconfig.json` to use `moduleResolution: "nodenext"`. See the [TypeScript + performance troubleshooting + guide](/docs/troubleshooting/typescript-performance-zod) for more details. + + ## Codemods The AI SDK provides Codemod transformations to help upgrade your codebase when a @@ -3094,17 +3101,18 @@ import { ### TypeScript Performance Issues with Zod -If you experience TypeScript server crashes, slow type checking, or errors like "Type instantiation is excessively deep and possibly infinite" when using Zod with AI SDK 5.0, you need to use the Zod v3 import path: - -```typescript -// ❌ Avoid: Standard import causes TypeScript issues -import { z } from 'zod'; +If you experience TypeScript server crashes, slow type checking, or errors like "Type instantiation is excessively deep and possibly infinite" when using Zod with AI SDK 5.0, update your `tsconfig.json` to use `moduleResolution: "nodenext"`: -// ✅ Use: v3-specific import for AI SDK 5.0 compatibility -import { z } from 'zod/v3'; +```json +{ + "compilerOptions": { + "moduleResolution": "nodenext" + // ... other options + } +} ``` -This is particularly important when using `generateObject`, `tool`, or other AI SDK functions with Zod schemas. For detailed troubleshooting steps, see [TypeScript performance issues with Zod](/docs/troubleshooting/typescript-performance-zod). +This resolves the TypeScript performance issues while allowing you to continue using the standard Zod import. If this doesn't resolve the issue, you can try using a version-specific import path as an alternative solution. For detailed troubleshooting steps, see [TypeScript performance issues with Zod](/docs/troubleshooting/typescript-performance-zod). ## Codemod Table diff --git a/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx b/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx index 39d7814db1ff..70c098132d32 100644 --- a/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx +++ b/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx @@ -20,18 +20,33 @@ The AI SDK 5 has specific compatibility requirements with Zod versions. When imp ## Solution -### Use the Zod Version-Specific Import Path +### Update TypeScript Configuration -The recommended solution is to import Zod using a version-specific import path: +The recommended solution is to update your `tsconfig.json` to use `moduleResolution: "nodenext"`: + +```json +{ + "compilerOptions": { + "moduleResolution": "nodenext" + // ... other options + } +} +``` + +This resolves the TypeScript performance issues while allowing you to continue using the standard Zod import: ```typescript -// ❌ Avoid: Standard import causes TypeScript issues +import { z } from 'zod'; // Works correctly with nodenext module resolution +``` + +### Alternative: Use the Zod Version-Specific Import Path + +If the above solution doesn't resolve the issue, you can try importing Zod using a version-specific import path: + +```typescript +// ❌ Potentially problematic: Standard import may cause TypeScript issues import { z } from 'zod'; -// ✅ Use: version-specific import for AI SDK 5 compatibility -import { z } from 'zod/v3'; -// or +// ✅ Alternative: version-specific import that may help with compatibility import { z } from 'zod/v4'; ``` - -After making this change, restart your TypeScript server (in VS Code: `Cmd/Ctrl + Shift + P` → "TypeScript: Restart TS Server"). From d52f0aee82f2314cecf21cf9a2a4c5204d2ffb7f Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Thu, 11 Sep 2025 15:44:02 +0100 Subject: [PATCH 007/121] docs/examples: add guide/example for gemini image editing (#8582) Lots of interest in generating and editing images with Gemini 2.5 Flash Image. - Added guide - Added example that shows how to pass url for image editing --- .../20-google-gemini-image-generation.mdx | 107 ++++++++++++++++++ .../google-gemini-editing-url.ts | 44 +++++++ 2 files changed, 151 insertions(+) create mode 100644 content/cookbook/00-guides/20-google-gemini-image-generation.mdx create mode 100644 examples/ai-core/src/generate-image/google-gemini-editing-url.ts diff --git a/content/cookbook/00-guides/20-google-gemini-image-generation.mdx b/content/cookbook/00-guides/20-google-gemini-image-generation.mdx new file mode 100644 index 000000000000..69aa80e4ac9b --- /dev/null +++ b/content/cookbook/00-guides/20-google-gemini-image-generation.mdx @@ -0,0 +1,107 @@ +--- +title: Google Gemini Image Generation +description: Generate and edit images with Google Gemini 2.5 Flash Image using the AI SDK. +tags: ['image-generation', 'google', 'gemini'] +--- + +# Generate and Edit Images with Google Gemini 2.5 Flash + +This guide will show you how to generate and edit images with the AI SDK and Google's latest multimodal language model Gemini 2.5 Flash Image. + +## Generating Images + +As Gemini 2.5 Flash Image is a language model with multimodal capabilities, you can use the `generateText` or `streamText` functions (not `generateImage`) to create images. The model determines which modality to respond in based on your prompt and configuration. Here's how to create your first image: + +```ts +import { google } from '@ai-sdk/google'; +import { generateText } from 'ai'; +import fs from 'node:fs'; +import 'dotenv/config'; + +async function generateImage() { + const result = await generateText({ + model: google('gemini-2.5-flash-image-preview'), + prompt: + 'Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme', + }); + + // Save generated images + for (const file of result.files) { + if (file.mediaType.startsWith('image/')) { + const timestamp = Date.now(); + const fileName = `generated-${timestamp}.png`; + + fs.mkdirSync('output', { recursive: true }); + await fs.promises.writeFile(`output/${fileName}`, file.uint8Array); + + console.log(`Generated and saved image: output/${fileName}`); + } + } +} + +generateImage().catch(console.error); +``` + +Here are some key points to remember: + +- Generated images are returned in the `result.files` array +- Images are returned as `Uint8Array` data +- The model leverages Gemini's world knowledge, so detailed prompts yield better results + +## Editing Images + +Gemini 2.5 Flash Image excels at editing existing images with natural language instructions. You can add elements, modify styles, or transform images while maintaining their core characteristics: + +```ts +import { google } from '@ai-sdk/google'; +import { generateText } from 'ai'; +import fs from 'node:fs'; +import 'dotenv/config'; + +async function editImage() { + const editResult = await generateText({ + model: google('gemini-2.5-flash-image-preview'), + prompt: [ + { + role: 'user', + content: [ + { + type: 'text', + text: 'Add a small wizard hat to this cat. Keep everything else the same.', + }, + { + type: 'image', + // image: DataContent (string | Uint8Array | ArrayBuffer | Buffer) or URL + image: new URL( + 'https://raw.githubusercontent.com/vercel/ai/refs/heads/main/examples/ai-core/data/comic-cat.png', + ), + mediaType: 'image/jpeg', + }, + ], + }, + ], + }); + + // Save the edited image + const timestamp = Date.now(); + fs.mkdirSync('output', { recursive: true }); + + for (const file of editResult.files) { + if (file.mediaType.startsWith('image/')) { + await fs.promises.writeFile( + `output/edited-${timestamp}.png`, + file.uint8Array, + ); + console.log(`Saved edited image: output/edited-${timestamp}.png`); + } + } +} + +editImage().catch(console.error); +``` + +## What's Next? + +You've learned how to generate new images from text prompts and edit existing images using natural language instructions with Google's Gemini 2.5 Flash Image model. + +For more advanced techniques, integration patterns, and practical examples, check out our [Cookbook](/cookbook) where you'll find comprehensive guides for building sophisticated AI-powered applications. diff --git a/examples/ai-core/src/generate-image/google-gemini-editing-url.ts b/examples/ai-core/src/generate-image/google-gemini-editing-url.ts new file mode 100644 index 000000000000..9248316d63c6 --- /dev/null +++ b/examples/ai-core/src/generate-image/google-gemini-editing-url.ts @@ -0,0 +1,44 @@ +import { google } from '@ai-sdk/google'; +import { generateText } from 'ai'; +import fs from 'node:fs'; +import 'dotenv/config'; + +async function editImage() { + const editResult = await generateText({ + model: google('gemini-2.5-flash-image-preview'), + prompt: [ + { + role: 'user', + content: [ + { + type: 'text', + text: 'Add a small wizard hat to this cat. Keep everything else the same.', + }, + { + type: 'image', + image: new URL( + 'https://raw.githubusercontent.com/vercel/ai/refs/heads/main/examples/ai-core/data/comic-cat.png', + ), + mediaType: 'image/jpeg', + }, + ], + }, + ], + }); + + // Save the edited image + const timestamp = Date.now(); + fs.mkdirSync('output', { recursive: true }); + + for (const file of editResult.files) { + if (file.mediaType.startsWith('image/')) { + await fs.promises.writeFile( + `output/edited-${timestamp}.png`, + file.uint8Array, + ); + console.log(`Saved edited image: output/edited-${timestamp}.png`); + } + } +} + +editImage().catch(console.error); From becaed0404882729056b67d2a13e75242dee40a3 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Thu, 11 Sep 2025 15:58:56 +0100 Subject: [PATCH 008/121] chore: remove versioned zod import from examples and docs (#8581) Related to #8580. Fixing stray imports. --- content/docs/03-ai-sdk-core/10-generating-structured-data.mdx | 2 +- content/providers/01-ai-sdk-providers/20-mistral.mdx | 4 ++-- examples/ai-core/src/agent/openai-stream-tools.ts | 2 +- .../src/complex/math-agent/agent-required-tool-choice.ts | 2 +- examples/ai-core/src/complex/math-agent/agent.ts | 2 +- examples/ai-core/src/e2e/feature-test-suite.ts | 2 +- examples/ai-core/src/generate-object/amazon-bedrock.ts | 2 +- examples/ai-core/src/generate-object/anthropic.ts | 2 +- examples/ai-core/src/generate-object/azure.ts | 2 +- examples/ai-core/src/generate-object/cohere.ts | 2 +- examples/ai-core/src/generate-object/fireworks.ts | 2 +- examples/ai-core/src/generate-object/gateway.ts | 2 +- examples/ai-core/src/generate-object/google-complex-1.ts | 2 +- examples/ai-core/src/generate-object/google-complex-2.ts | 2 +- examples/ai-core/src/generate-object/google-gemini-files.ts | 2 +- .../src/generate-object/google-no-structured-output.ts | 2 +- examples/ai-core/src/generate-object/google-pdf-url.ts | 2 +- .../ai-core/src/generate-object/google-vertex-anthropic.ts | 2 +- examples/ai-core/src/generate-object/google-vertex.ts | 2 +- examples/ai-core/src/generate-object/google.ts | 2 +- examples/ai-core/src/generate-object/groq.ts | 2 +- examples/ai-core/src/generate-object/mistral.ts | 2 +- examples/ai-core/src/generate-object/mock-error.ts | 2 +- examples/ai-core/src/generate-object/mock-repair-add-close.ts | 2 +- examples/ai-core/src/generate-object/mock.ts | 2 +- examples/ai-core/src/generate-object/nim.ts | 2 +- examples/ai-core/src/generate-object/openai-5-reasoning.ts | 2 +- examples/ai-core/src/generate-object/openai-array.ts | 2 +- .../src/generate-object/openai-compatible-togetherai.ts | 2 +- examples/ai-core/src/generate-object/openai-date-parsing.ts | 2 +- examples/ai-core/src/generate-object/openai-full-result.ts | 2 +- examples/ai-core/src/generate-object/openai-multimodal.ts | 2 +- examples/ai-core/src/generate-object/openai-reasoning.ts | 2 +- examples/ai-core/src/generate-object/openai-request-body.ts | 2 +- examples/ai-core/src/generate-object/openai-responses.ts | 2 +- .../ai-core/src/generate-object/openai-store-generation.ts | 2 +- .../openai-structured-outputs-name-description.ts | 2 +- examples/ai-core/src/generate-object/openai.ts | 2 +- examples/ai-core/src/generate-object/perplexity.ts | 2 +- examples/ai-core/src/generate-object/togetherai.ts | 2 +- examples/ai-core/src/generate-object/vercel.ts | 2 +- .../xai-structured-outputs-name-description.ts | 2 +- examples/ai-core/src/generate-object/xai.ts | 2 +- .../src/generate-text/amazon-bedrock-cache-point-tool-call.ts | 2 +- .../src/generate-text/amazon-bedrock-nova-tool-call.ts | 2 +- .../generate-text/amazon-bedrock-tool-call-image-result.ts | 2 +- .../ai-core/src/generate-text/amazon-bedrock-tool-call.ts | 2 +- .../ai-core/src/generate-text/amazon-bedrock-tool-choice.ts | 2 +- .../ai-core/src/generate-text/anthropic-tool-call-cache.ts | 2 +- examples/ai-core/src/generate-text/anthropic-tool-call.ts | 2 +- examples/ai-core/src/generate-text/anthropic-tool-choice.ts | 2 +- examples/ai-core/src/generate-text/cerebras-tool-call.ts | 2 +- .../src/generate-text/cohere-tool-call-empty-params.ts | 2 +- examples/ai-core/src/generate-text/cohere-tool-call.ts | 2 +- examples/ai-core/src/generate-text/deepinfra-tool-call.ts | 2 +- examples/ai-core/src/generate-text/gateway-tool-call.ts | 2 +- .../ai-core/src/generate-text/google-image-tool-results.ts | 2 +- examples/ai-core/src/generate-text/google-multi-step.ts | 2 +- examples/ai-core/src/generate-text/google-output-object.ts | 2 +- examples/ai-core/src/generate-text/google-tool-call.ts | 2 +- examples/ai-core/src/generate-text/google-tool-choice.ts | 2 +- .../src/generate-text/google-vertex-anthropic-tool-call.ts | 2 +- .../src/generate-text/google-vertex-anthropic-tool-choice.ts | 2 +- .../ai-core/src/generate-text/google-vertex-multi-step.ts | 2 +- .../ai-core/src/generate-text/google-vertex-output-object.ts | 2 +- examples/ai-core/src/generate-text/google-vertex-tool-call.ts | 2 +- examples/ai-core/src/generate-text/mistral-tool-call.ts | 2 +- examples/ai-core/src/generate-text/mistral-tool-choice.ts | 2 +- examples/ai-core/src/generate-text/mock-invalid-tool-call.ts | 2 +- .../src/generate-text/mock-tool-call-repair-change-tool.ts | 2 +- .../ai-core/src/generate-text/mock-tool-call-repair-reask.ts | 2 +- .../generate-text/mock-tool-call-repair-structured-model.ts | 2 +- examples/ai-core/src/generate-text/openai-active-tools.ts | 2 +- .../generate-text/openai-compatible-togetherai-tool-call.ts | 2 +- .../ai-core/src/generate-text/openai-dynamic-tool-call.ts | 2 +- examples/ai-core/src/generate-text/openai-multi-step.ts | 2 +- examples/ai-core/src/generate-text/openai-output-object.ts | 2 +- examples/ai-core/src/generate-text/openai-reasoning-tools.ts | 2 +- .../src/generate-text/openai-responses-output-object.ts | 2 +- .../openai-responses-roundtrip-server-side-tools.ts | 2 +- .../ai-core/src/generate-text/openai-responses-tool-call.ts | 2 +- .../src/generate-text/openai-tool-call-with-context.ts | 2 +- examples/ai-core/src/generate-text/openai-tool-call.ts | 2 +- examples/ai-core/src/generate-text/openai-tool-choice.ts | 2 +- .../ai-core/src/generate-text/openai-tool-execution-error.ts | 2 +- examples/ai-core/src/generate-text/togetherai-tool-call.ts | 2 +- examples/ai-core/src/generate-text/xai-structured-output.ts | 2 +- examples/ai-core/src/generate-text/xai-tool-call.ts | 2 +- examples/ai-core/src/stream-object/amazon-bedrock.ts | 2 +- examples/ai-core/src/stream-object/anthropic.ts | 2 +- examples/ai-core/src/stream-object/azure.ts | 2 +- examples/ai-core/src/stream-object/fireworks.ts | 2 +- examples/ai-core/src/stream-object/gateway.ts | 2 +- examples/ai-core/src/stream-object/google-vertex-anthropic.ts | 2 +- examples/ai-core/src/stream-object/google-vertex.ts | 2 +- examples/ai-core/src/stream-object/google.ts | 2 +- examples/ai-core/src/stream-object/groq.ts | 2 +- examples/ai-core/src/stream-object/mistral.ts | 2 +- examples/ai-core/src/stream-object/mock.ts | 2 +- examples/ai-core/src/stream-object/nim.ts | 2 +- examples/ai-core/src/stream-object/openai-5-reasoning.ts | 2 +- examples/ai-core/src/stream-object/openai-array.ts | 2 +- .../ai-core/src/stream-object/openai-compatible-togetherai.ts | 2 +- examples/ai-core/src/stream-object/openai-fullstream.ts | 2 +- examples/ai-core/src/stream-object/openai-object.ts | 2 +- examples/ai-core/src/stream-object/openai-on-finish.ts | 2 +- examples/ai-core/src/stream-object/openai-reasoning.ts | 2 +- examples/ai-core/src/stream-object/openai-request-body.ts | 2 +- examples/ai-core/src/stream-object/openai-responses.ts | 2 +- examples/ai-core/src/stream-object/openai-store-generation.ts | 2 +- .../stream-object/openai-stream-object-name-description.ts | 2 +- examples/ai-core/src/stream-object/openai-stream-object.ts | 2 +- examples/ai-core/src/stream-object/openai-token-usage.ts | 2 +- .../ai-core/src/stream-object/openai-unstructured-output.ts | 2 +- examples/ai-core/src/stream-object/openai.ts | 2 +- examples/ai-core/src/stream-object/togetherai.ts | 2 +- examples/ai-core/src/stream-object/vercel.ts | 2 +- .../stream-object/xai-structured-outputs-name-description.ts | 2 +- examples/ai-core/src/stream-object/xai.ts | 2 +- .../src/stream-text/amazon-bedrock-cache-point-tool-call.ts | 2 +- examples/ai-core/src/stream-text/amazon-bedrock-chatbot.ts | 2 +- examples/ai-core/src/stream-text/amazon-bedrock-fullstream.ts | 2 +- .../src/stream-text/amazon-bedrock-reasoning-chatbot.ts | 2 +- examples/ai-core/src/stream-text/anthropic-chatbot.ts | 2 +- examples/ai-core/src/stream-text/anthropic-fullstream.ts | 2 +- .../ai-core/src/stream-text/anthropic-reasoning-chatbot.ts | 2 +- examples/ai-core/src/stream-text/azure-fullstream.ts | 2 +- examples/ai-core/src/stream-text/cohere-chatbot.ts | 2 +- .../ai-core/src/stream-text/cohere-tool-call-empty-params.ts | 2 +- examples/ai-core/src/stream-text/google-chatbot.ts | 2 +- examples/ai-core/src/stream-text/google-fullstream.ts | 2 +- .../src/stream-text/google-vertex-anthropic-chatbot.ts | 2 +- .../src/stream-text/google-vertex-anthropic-fullstream.ts | 2 +- examples/ai-core/src/stream-text/google-vertex-fullstream.ts | 2 +- examples/ai-core/src/stream-text/groq-chatbot.ts | 2 +- examples/ai-core/src/stream-text/mistral-chatbot.ts | 2 +- examples/ai-core/src/stream-text/mistral-fullstream.ts | 2 +- .../src/stream-text/mock-tool-call-repair-change-tool.ts | 2 +- examples/ai-core/src/stream-text/openai-5-reasoning.ts | 2 +- examples/ai-core/src/stream-text/openai-chatbot.ts | 2 +- examples/ai-core/src/stream-text/openai-dynamic-tool-call.ts | 2 +- examples/ai-core/src/stream-text/openai-fullstream.ts | 2 +- examples/ai-core/src/stream-text/openai-multi-step.ts | 2 +- .../src/stream-text/openai-on-chunk-tool-call-streaming.ts | 2 +- .../src/stream-text/openai-on-finish-response-messages.ts | 2 +- examples/ai-core/src/stream-text/openai-on-finish-steps.ts | 2 +- examples/ai-core/src/stream-text/openai-on-step-finish.ts | 2 +- examples/ai-core/src/stream-text/openai-output-object.ts | 2 +- examples/ai-core/src/stream-text/openai-prepare-step.ts | 2 +- .../ai-core/src/stream-text/openai-read-ui-message-stream.ts | 2 +- examples/ai-core/src/stream-text/openai-responses-chatbot.ts | 2 +- .../src/stream-text/openai-responses-reasoning-chatbot.ts | 2 +- .../src/stream-text/openai-responses-reasoning-tool-call.ts | 2 +- .../ai-core/src/stream-text/openai-responses-tool-call.ts | 2 +- examples/ai-core/src/stream-text/openai-swarm.ts | 2 +- examples/ai-core/src/stream-text/openai-tool-abort.ts | 2 +- examples/ai-core/src/stream-text/openai-tool-call.ts | 2 +- examples/ai-core/src/stream-text/openai-tool-output-stream.ts | 2 +- examples/ai-core/src/stream-text/xai-chatbot.ts | 2 +- examples/ai-core/src/telemetry/generate-object.ts | 2 +- examples/ai-core/src/telemetry/generate-text-tool-call.ts | 2 +- examples/ai-core/src/telemetry/stream-object.ts | 2 +- examples/ai-core/src/tools/weather-tool.ts | 2 +- examples/ai-core/src/types/tool-set.ts | 2 +- examples/mcp/src/stdio/client.ts | 2 +- examples/next-agent/tool/weather-tool.ts | 2 +- examples/next-openai-pages/app/api/call-tool/route.ts | 2 +- examples/next-openai-pages/app/api/generate-object/route.ts | 2 +- examples/next-openai-pages/app/api/stream-object/route.ts | 2 +- examples/next-openai/app/api/dynamic-tools/route.ts | 2 +- examples/next-openai/app/api/test-invalid-tool-call/route.ts | 2 +- examples/next-openai/app/api/use-chat-data-ui-parts/route.ts | 2 +- .../api/use-chat-message-metadata/example-metadata-schema.ts | 2 +- .../app/api/use-chat-streaming-tool-calls/route.ts | 2 +- examples/next-openai/app/api/use-chat-tools/route.ts | 2 +- .../app/api/use-completion-server-side-multi-step/route.ts | 2 +- .../next-openai/app/api/use-object-expense-tracker/schema.ts | 2 +- examples/next-openai/app/api/use-object/schema.ts | 2 +- examples/next-openai/app/stream-object/schema.ts | 2 +- examples/next/util/chat-schema.ts | 2 +- examples/nuxt-openai/server/api/use-chat-tools.ts | 2 +- examples/nuxt-openai/shared/notification-schema.ts | 2 +- examples/sveltekit-openai/src/routes/api/chat/+server.ts | 2 +- .../sveltekit-openai/src/routes/structured-object/schema.ts | 2 +- 184 files changed, 185 insertions(+), 185 deletions(-) diff --git a/content/docs/03-ai-sdk-core/10-generating-structured-data.mdx b/content/docs/03-ai-sdk-core/10-generating-structured-data.mdx index f83761ef7025..1a3a22fa428b 100644 --- a/content/docs/03-ai-sdk-core/10-generating-structured-data.mdx +++ b/content/docs/03-ai-sdk-core/10-generating-structured-data.mdx @@ -214,7 +214,7 @@ You can access the reasoning used by the language model to generate the object v ```ts import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { generateObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const result = await generateObject({ model: openai('gpt-5'), diff --git a/content/providers/01-ai-sdk-providers/20-mistral.mdx b/content/providers/01-ai-sdk-providers/20-mistral.mdx index 686b913e03b7..e8d16e44c1d6 100644 --- a/content/providers/01-ai-sdk-providers/20-mistral.mdx +++ b/content/providers/01-ai-sdk-providers/20-mistral.mdx @@ -221,7 +221,7 @@ with Zod, Valibot, or raw JSON Schema. The SDK sends your schema via Mistral's ` ```ts import { mistral } from '@ai-sdk/mistral'; import { generateObject } from 'ai'; -import { z } from 'zod/v3'; +import { z } from 'zod'; const result = await generateObject({ model: mistral('mistral-large-latest'), @@ -243,7 +243,7 @@ You can enable strict JSON Schema validation using a provider option: ```ts highlight="7-11" import { mistral } from '@ai-sdk/mistral'; import { generateObject } from 'ai'; -import { z } from 'zod/v3'; +import { z } from 'zod'; const result = await generateObject({ model: mistral('mistral-large-latest'), diff --git a/examples/ai-core/src/agent/openai-stream-tools.ts b/examples/ai-core/src/agent/openai-stream-tools.ts index ffdfdda67cc4..b044128e0659 100644 --- a/examples/ai-core/src/agent/openai-stream-tools.ts +++ b/examples/ai-core/src/agent/openai-stream-tools.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { Experimental_Agent as Agent, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const agent = new Agent({ diff --git a/examples/ai-core/src/complex/math-agent/agent-required-tool-choice.ts b/examples/ai-core/src/complex/math-agent/agent-required-tool-choice.ts index 4b5b38e519af..d2d3a4109c5d 100644 --- a/examples/ai-core/src/complex/math-agent/agent-required-tool-choice.ts +++ b/examples/ai-core/src/complex/math-agent/agent-required-tool-choice.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; import * as mathjs from 'mathjs'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { toolCalls } = await generateText({ diff --git a/examples/ai-core/src/complex/math-agent/agent.ts b/examples/ai-core/src/complex/math-agent/agent.ts index 582a3986cae6..3a945d7aff8c 100644 --- a/examples/ai-core/src/complex/math-agent/agent.ts +++ b/examples/ai-core/src/complex/math-agent/agent.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; import * as mathjs from 'mathjs'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { text: answer } = await generateText({ diff --git a/examples/ai-core/src/e2e/feature-test-suite.ts b/examples/ai-core/src/e2e/feature-test-suite.ts index 3cb313391fd6..d4a27801bb5b 100644 --- a/examples/ai-core/src/e2e/feature-test-suite.ts +++ b/examples/ai-core/src/e2e/feature-test-suite.ts @@ -17,7 +17,7 @@ import { } from 'ai'; import fs from 'fs'; import { describe, expect, it, vi } from 'vitest'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export type Capability = | 'audioInput' diff --git a/examples/ai-core/src/generate-object/amazon-bedrock.ts b/examples/ai-core/src/generate-object/amazon-bedrock.ts index 3da48ae2f2be..5b120dd092bd 100644 --- a/examples/ai-core/src/generate-object/amazon-bedrock.ts +++ b/examples/ai-core/src/generate-object/amazon-bedrock.ts @@ -1,7 +1,7 @@ import { bedrock } from '@ai-sdk/amazon-bedrock'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/anthropic.ts b/examples/ai-core/src/generate-object/anthropic.ts index 33a77eb9f664..1c9756f612f2 100644 --- a/examples/ai-core/src/generate-object/anthropic.ts +++ b/examples/ai-core/src/generate-object/anthropic.ts @@ -1,7 +1,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/azure.ts b/examples/ai-core/src/generate-object/azure.ts index b9b73c6f4263..59324627d027 100644 --- a/examples/ai-core/src/generate-object/azure.ts +++ b/examples/ai-core/src/generate-object/azure.ts @@ -1,7 +1,7 @@ import { azure } from '@ai-sdk/azure'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/cohere.ts b/examples/ai-core/src/generate-object/cohere.ts index ea5e60a5219a..daaef72de5f7 100644 --- a/examples/ai-core/src/generate-object/cohere.ts +++ b/examples/ai-core/src/generate-object/cohere.ts @@ -1,7 +1,7 @@ import { cohere } from '@ai-sdk/cohere'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/fireworks.ts b/examples/ai-core/src/generate-object/fireworks.ts index 4cd14b7a9487..73f64413cb78 100644 --- a/examples/ai-core/src/generate-object/fireworks.ts +++ b/examples/ai-core/src/generate-object/fireworks.ts @@ -1,7 +1,7 @@ import { fireworks } from '@ai-sdk/fireworks'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/gateway.ts b/examples/ai-core/src/generate-object/gateway.ts index 84945393d3be..e6e37821a760 100644 --- a/examples/ai-core/src/generate-object/gateway.ts +++ b/examples/ai-core/src/generate-object/gateway.ts @@ -1,6 +1,6 @@ import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/google-complex-1.ts b/examples/ai-core/src/generate-object/google-complex-1.ts index 17907cf08961..5895d7f094bc 100644 --- a/examples/ai-core/src/generate-object/google-complex-1.ts +++ b/examples/ai-core/src/generate-object/google-complex-1.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { // split schema support: diff --git a/examples/ai-core/src/generate-object/google-complex-2.ts b/examples/ai-core/src/generate-object/google-complex-2.ts index 2be33324159a..00d16fd7e8c8 100644 --- a/examples/ai-core/src/generate-object/google-complex-2.ts +++ b/examples/ai-core/src/generate-object/google-complex-2.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { // enum support: diff --git a/examples/ai-core/src/generate-object/google-gemini-files.ts b/examples/ai-core/src/generate-object/google-gemini-files.ts index 18cd10ef6799..04163bb357c5 100644 --- a/examples/ai-core/src/generate-object/google-gemini-files.ts +++ b/examples/ai-core/src/generate-object/google-gemini-files.ts @@ -3,7 +3,7 @@ import { google } from '@ai-sdk/google'; import { generateObject } from 'ai'; import path from 'path'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const fileManager = new GoogleAIFileManager( diff --git a/examples/ai-core/src/generate-object/google-no-structured-output.ts b/examples/ai-core/src/generate-object/google-no-structured-output.ts index 5f355c39d9ff..2c01e0b9ee46 100644 --- a/examples/ai-core/src/generate-object/google-no-structured-output.ts +++ b/examples/ai-core/src/generate-object/google-no-structured-output.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/google-pdf-url.ts b/examples/ai-core/src/generate-object/google-pdf-url.ts index 9318bea1cfef..3d44ad8b1262 100644 --- a/examples/ai-core/src/generate-object/google-pdf-url.ts +++ b/examples/ai-core/src/generate-object/google-pdf-url.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { object: summary } = await generateObject({ diff --git a/examples/ai-core/src/generate-object/google-vertex-anthropic.ts b/examples/ai-core/src/generate-object/google-vertex-anthropic.ts index b9bb9e56df9b..c61f983fa97d 100644 --- a/examples/ai-core/src/generate-object/google-vertex-anthropic.ts +++ b/examples/ai-core/src/generate-object/google-vertex-anthropic.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; import { generateObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/google-vertex.ts b/examples/ai-core/src/generate-object/google-vertex.ts index 0d2484a850e5..70fac65124fc 100644 --- a/examples/ai-core/src/generate-object/google-vertex.ts +++ b/examples/ai-core/src/generate-object/google-vertex.ts @@ -1,7 +1,7 @@ import { vertex } from '@ai-sdk/google-vertex'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/google.ts b/examples/ai-core/src/generate-object/google.ts index 359c090f7278..06149bd45bf6 100644 --- a/examples/ai-core/src/generate-object/google.ts +++ b/examples/ai-core/src/generate-object/google.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/groq.ts b/examples/ai-core/src/generate-object/groq.ts index 70abd4685e52..8466665dc273 100644 --- a/examples/ai-core/src/generate-object/groq.ts +++ b/examples/ai-core/src/generate-object/groq.ts @@ -1,7 +1,7 @@ import { groq } from '@ai-sdk/groq'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/mistral.ts b/examples/ai-core/src/generate-object/mistral.ts index 5dbf095fc1ad..69136230d18a 100644 --- a/examples/ai-core/src/generate-object/mistral.ts +++ b/examples/ai-core/src/generate-object/mistral.ts @@ -1,7 +1,7 @@ import { mistral } from '@ai-sdk/mistral'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/mock-error.ts b/examples/ai-core/src/generate-object/mock-error.ts index 8812b7afe73b..d2c8fee769cb 100644 --- a/examples/ai-core/src/generate-object/mock-error.ts +++ b/examples/ai-core/src/generate-object/mock-error.ts @@ -1,7 +1,7 @@ import { generateObject, NoObjectGeneratedError } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { try { diff --git a/examples/ai-core/src/generate-object/mock-repair-add-close.ts b/examples/ai-core/src/generate-object/mock-repair-add-close.ts index d00accf9133f..bd9a8cebe8c9 100644 --- a/examples/ai-core/src/generate-object/mock-repair-add-close.ts +++ b/examples/ai-core/src/generate-object/mock-repair-add-close.ts @@ -1,7 +1,7 @@ import { generateObject, JSONParseError } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/mock.ts b/examples/ai-core/src/generate-object/mock.ts index 5da3d7ce921c..61f2bed65c7b 100644 --- a/examples/ai-core/src/generate-object/mock.ts +++ b/examples/ai-core/src/generate-object/mock.ts @@ -1,7 +1,7 @@ import { generateObject } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { object, usage } = await generateObject({ diff --git a/examples/ai-core/src/generate-object/nim.ts b/examples/ai-core/src/generate-object/nim.ts index e2eed9137829..a0b53a37d764 100644 --- a/examples/ai-core/src/generate-object/nim.ts +++ b/examples/ai-core/src/generate-object/nim.ts @@ -1,6 +1,6 @@ import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { generateObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import 'dotenv/config'; async function main() { diff --git a/examples/ai-core/src/generate-object/openai-5-reasoning.ts b/examples/ai-core/src/generate-object/openai-5-reasoning.ts index d1db7d1bf7d7..f3a3b467c159 100644 --- a/examples/ai-core/src/generate-object/openai-5-reasoning.ts +++ b/examples/ai-core/src/generate-object/openai-5-reasoning.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-array.ts b/examples/ai-core/src/generate-object/openai-array.ts index 74f42bda5bc4..9392bf40d657 100644 --- a/examples/ai-core/src/generate-object/openai-array.ts +++ b/examples/ai-core/src/generate-object/openai-array.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts b/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts index e2d5064eeb0d..a8dcfba81fa8 100644 --- a/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts +++ b/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { generateObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const togetherai = createOpenAICompatible({ diff --git a/examples/ai-core/src/generate-object/openai-date-parsing.ts b/examples/ai-core/src/generate-object/openai-date-parsing.ts index b7eaff1b6fa4..b80416dedee8 100644 --- a/examples/ai-core/src/generate-object/openai-date-parsing.ts +++ b/examples/ai-core/src/generate-object/openai-date-parsing.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { diff --git a/examples/ai-core/src/generate-object/openai-full-result.ts b/examples/ai-core/src/generate-object/openai-full-result.ts index 0f34a1e61d07..f47c2323f311 100644 --- a/examples/ai-core/src/generate-object/openai-full-result.ts +++ b/examples/ai-core/src/generate-object/openai-full-result.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-multimodal.ts b/examples/ai-core/src/generate-object/openai-multimodal.ts index 342faaf62445..1f3a1ec2da6e 100644 --- a/examples/ai-core/src/generate-object/openai-multimodal.ts +++ b/examples/ai-core/src/generate-object/openai-multimodal.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; import fs from 'node:fs'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { object } = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-reasoning.ts b/examples/ai-core/src/generate-object/openai-reasoning.ts index bdc4209dea4b..d93468b1dcd3 100644 --- a/examples/ai-core/src/generate-object/openai-reasoning.ts +++ b/examples/ai-core/src/generate-object/openai-reasoning.ts @@ -1,7 +1,7 @@ import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-request-body.ts b/examples/ai-core/src/generate-object/openai-request-body.ts index 14d4516cfe5e..88d609253fed 100644 --- a/examples/ai-core/src/generate-object/openai-request-body.ts +++ b/examples/ai-core/src/generate-object/openai-request-body.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { request } = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-responses.ts b/examples/ai-core/src/generate-object/openai-responses.ts index 3d8fdcd5c6f1..a1643c8ca983 100644 --- a/examples/ai-core/src/generate-object/openai-responses.ts +++ b/examples/ai-core/src/generate-object/openai-responses.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-store-generation.ts b/examples/ai-core/src/generate-object/openai-store-generation.ts index eea2671a0812..2e5b5e9ebdca 100644 --- a/examples/ai-core/src/generate-object/openai-store-generation.ts +++ b/examples/ai-core/src/generate-object/openai-store-generation.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai-structured-outputs-name-description.ts b/examples/ai-core/src/generate-object/openai-structured-outputs-name-description.ts index 3bf56da6257c..83d8681902f6 100644 --- a/examples/ai-core/src/generate-object/openai-structured-outputs-name-description.ts +++ b/examples/ai-core/src/generate-object/openai-structured-outputs-name-description.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/openai.ts b/examples/ai-core/src/generate-object/openai.ts index 96b77d7be669..813a23afdef5 100644 --- a/examples/ai-core/src/generate-object/openai.ts +++ b/examples/ai-core/src/generate-object/openai.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/perplexity.ts b/examples/ai-core/src/generate-object/perplexity.ts index 6ed2b29d9767..84ccb1e246c9 100644 --- a/examples/ai-core/src/generate-object/perplexity.ts +++ b/examples/ai-core/src/generate-object/perplexity.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { perplexity } from '@ai-sdk/perplexity'; import { generateObject, generateText } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/togetherai.ts b/examples/ai-core/src/generate-object/togetherai.ts index 37c77f7c68b4..6eae7344ca56 100644 --- a/examples/ai-core/src/generate-object/togetherai.ts +++ b/examples/ai-core/src/generate-object/togetherai.ts @@ -1,7 +1,7 @@ import { togetherai } from '@ai-sdk/togetherai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/vercel.ts b/examples/ai-core/src/generate-object/vercel.ts index d34ac3d254ad..d50fa4992dc2 100644 --- a/examples/ai-core/src/generate-object/vercel.ts +++ b/examples/ai-core/src/generate-object/vercel.ts @@ -1,7 +1,7 @@ import { vercel } from '@ai-sdk/vercel'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/xai-structured-outputs-name-description.ts b/examples/ai-core/src/generate-object/xai-structured-outputs-name-description.ts index a9ec93fc11dc..417cd065e74d 100644 --- a/examples/ai-core/src/generate-object/xai-structured-outputs-name-description.ts +++ b/examples/ai-core/src/generate-object/xai-structured-outputs-name-description.ts @@ -1,7 +1,7 @@ import { xai } from '@ai-sdk/xai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-object/xai.ts b/examples/ai-core/src/generate-object/xai.ts index e069b246f13c..fbed1c987ed7 100644 --- a/examples/ai-core/src/generate-object/xai.ts +++ b/examples/ai-core/src/generate-object/xai.ts @@ -1,7 +1,7 @@ import { xai } from '@ai-sdk/xai'; import { generateObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateObject({ diff --git a/examples/ai-core/src/generate-text/amazon-bedrock-cache-point-tool-call.ts b/examples/ai-core/src/generate-text/amazon-bedrock-cache-point-tool-call.ts index 9a4c70be57d5..476e32a9dced 100644 --- a/examples/ai-core/src/generate-text/amazon-bedrock-cache-point-tool-call.ts +++ b/examples/ai-core/src/generate-text/amazon-bedrock-cache-point-tool-call.ts @@ -1,6 +1,6 @@ import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { bedrock } from '@ai-sdk/amazon-bedrock'; const weatherTool = tool({ diff --git a/examples/ai-core/src/generate-text/amazon-bedrock-nova-tool-call.ts b/examples/ai-core/src/generate-text/amazon-bedrock-nova-tool-call.ts index e4017b41243c..1a237c2e0159 100644 --- a/examples/ai-core/src/generate-text/amazon-bedrock-nova-tool-call.ts +++ b/examples/ai-core/src/generate-text/amazon-bedrock-nova-tool-call.ts @@ -1,6 +1,6 @@ import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; import { bedrock } from '@ai-sdk/amazon-bedrock'; diff --git a/examples/ai-core/src/generate-text/amazon-bedrock-tool-call-image-result.ts b/examples/ai-core/src/generate-text/amazon-bedrock-tool-call-image-result.ts index a2a775c61a06..3cd34e7649fe 100644 --- a/examples/ai-core/src/generate-text/amazon-bedrock-tool-call-image-result.ts +++ b/examples/ai-core/src/generate-text/amazon-bedrock-tool-call-image-result.ts @@ -1,7 +1,7 @@ import { bedrock } from '@ai-sdk/amazon-bedrock'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/amazon-bedrock-tool-call.ts b/examples/ai-core/src/generate-text/amazon-bedrock-tool-call.ts index 4b34135e194e..0f8a29c8c8b9 100644 --- a/examples/ai-core/src/generate-text/amazon-bedrock-tool-call.ts +++ b/examples/ai-core/src/generate-text/amazon-bedrock-tool-call.ts @@ -1,6 +1,6 @@ import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; import { bedrock } from '@ai-sdk/amazon-bedrock'; diff --git a/examples/ai-core/src/generate-text/amazon-bedrock-tool-choice.ts b/examples/ai-core/src/generate-text/amazon-bedrock-tool-choice.ts index 15e16d388cf0..ddd6c29847d3 100644 --- a/examples/ai-core/src/generate-text/amazon-bedrock-tool-choice.ts +++ b/examples/ai-core/src/generate-text/amazon-bedrock-tool-choice.ts @@ -1,6 +1,6 @@ import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; import { bedrock } from '@ai-sdk/amazon-bedrock'; diff --git a/examples/ai-core/src/generate-text/anthropic-tool-call-cache.ts b/examples/ai-core/src/generate-text/anthropic-tool-call-cache.ts index ea7cb9884401..c2fdc3772d3f 100644 --- a/examples/ai-core/src/generate-text/anthropic-tool-call-cache.ts +++ b/examples/ai-core/src/generate-text/anthropic-tool-call-cache.ts @@ -1,7 +1,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/anthropic-tool-call.ts b/examples/ai-core/src/generate-text/anthropic-tool-call.ts index 3b5a7058c080..0319d4f35478 100644 --- a/examples/ai-core/src/generate-text/anthropic-tool-call.ts +++ b/examples/ai-core/src/generate-text/anthropic-tool-call.ts @@ -1,7 +1,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/anthropic-tool-choice.ts b/examples/ai-core/src/generate-text/anthropic-tool-choice.ts index ce5ebd50e3cb..b56375dffe70 100644 --- a/examples/ai-core/src/generate-text/anthropic-tool-choice.ts +++ b/examples/ai-core/src/generate-text/anthropic-tool-choice.ts @@ -1,7 +1,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/cerebras-tool-call.ts b/examples/ai-core/src/generate-text/cerebras-tool-call.ts index 65da88a1eb2a..65267e8654e5 100644 --- a/examples/ai-core/src/generate-text/cerebras-tool-call.ts +++ b/examples/ai-core/src/generate-text/cerebras-tool-call.ts @@ -1,7 +1,7 @@ import { cerebras } from '@ai-sdk/cerebras'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/cohere-tool-call-empty-params.ts b/examples/ai-core/src/generate-text/cohere-tool-call-empty-params.ts index 1826eb26d916..9666c40c702d 100644 --- a/examples/ai-core/src/generate-text/cohere-tool-call-empty-params.ts +++ b/examples/ai-core/src/generate-text/cohere-tool-call-empty-params.ts @@ -1,7 +1,7 @@ import { cohere } from '@ai-sdk/cohere'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/cohere-tool-call.ts b/examples/ai-core/src/generate-text/cohere-tool-call.ts index 476a5d9d4ff4..c54d24f7a109 100644 --- a/examples/ai-core/src/generate-text/cohere-tool-call.ts +++ b/examples/ai-core/src/generate-text/cohere-tool-call.ts @@ -1,7 +1,7 @@ import { cohere } from '@ai-sdk/cohere'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/deepinfra-tool-call.ts b/examples/ai-core/src/generate-text/deepinfra-tool-call.ts index f6f140485f2f..8aaeb09f2abc 100644 --- a/examples/ai-core/src/generate-text/deepinfra-tool-call.ts +++ b/examples/ai-core/src/generate-text/deepinfra-tool-call.ts @@ -1,7 +1,7 @@ import { deepinfra } from '@ai-sdk/deepinfra'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/gateway-tool-call.ts b/examples/ai-core/src/generate-text/gateway-tool-call.ts index 3d32ae8f5a07..76e4ead4e1af 100644 --- a/examples/ai-core/src/generate-text/gateway-tool-call.ts +++ b/examples/ai-core/src/generate-text/gateway-tool-call.ts @@ -1,6 +1,6 @@ import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/google-image-tool-results.ts b/examples/ai-core/src/generate-text/google-image-tool-results.ts index 31e14625aa46..9b2b3636ebdf 100644 --- a/examples/ai-core/src/generate-text/google-image-tool-results.ts +++ b/examples/ai-core/src/generate-text/google-image-tool-results.ts @@ -1,6 +1,6 @@ import { google } from '@ai-sdk/google'; import { generateText, stepCountIs, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import 'dotenv/config'; import * as fs from 'fs'; import * as path from 'path'; diff --git a/examples/ai-core/src/generate-text/google-multi-step.ts b/examples/ai-core/src/generate-text/google-multi-step.ts index aa41ac80e370..321511117a05 100644 --- a/examples/ai-core/src/generate-text/google-multi-step.ts +++ b/examples/ai-core/src/generate-text/google-multi-step.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { text } = await generateText({ diff --git a/examples/ai-core/src/generate-text/google-output-object.ts b/examples/ai-core/src/generate-text/google-output-object.ts index 392be92fa367..a39c320a32a7 100644 --- a/examples/ai-core/src/generate-text/google-output-object.ts +++ b/examples/ai-core/src/generate-text/google-output-object.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateText, Output } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { experimental_output } = await generateText({ diff --git a/examples/ai-core/src/generate-text/google-tool-call.ts b/examples/ai-core/src/generate-text/google-tool-call.ts index 2c6971c18a27..e9ec40630c14 100644 --- a/examples/ai-core/src/generate-text/google-tool-call.ts +++ b/examples/ai-core/src/generate-text/google-tool-call.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/google-tool-choice.ts b/examples/ai-core/src/generate-text/google-tool-choice.ts index 90c325edd1b2..fe4670c055a9 100644 --- a/examples/ai-core/src/generate-text/google-tool-choice.ts +++ b/examples/ai-core/src/generate-text/google-tool-choice.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-call.ts b/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-call.ts index 07f53f74d308..451ab78bd458 100644 --- a/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-call.ts +++ b/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-call.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; import { generateText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-choice.ts b/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-choice.ts index d5d55449f75c..524c2178f78d 100644 --- a/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-choice.ts +++ b/examples/ai-core/src/generate-text/google-vertex-anthropic-tool-choice.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; import { generateText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/google-vertex-multi-step.ts b/examples/ai-core/src/generate-text/google-vertex-multi-step.ts index e56432774c6b..7ab1b2431784 100644 --- a/examples/ai-core/src/generate-text/google-vertex-multi-step.ts +++ b/examples/ai-core/src/generate-text/google-vertex-multi-step.ts @@ -1,7 +1,7 @@ import { vertex } from '@ai-sdk/google-vertex'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { text } = await generateText({ diff --git a/examples/ai-core/src/generate-text/google-vertex-output-object.ts b/examples/ai-core/src/generate-text/google-vertex-output-object.ts index 702e2f6556de..403911c915dc 100644 --- a/examples/ai-core/src/generate-text/google-vertex-output-object.ts +++ b/examples/ai-core/src/generate-text/google-vertex-output-object.ts @@ -1,7 +1,7 @@ import { vertex } from '@ai-sdk/google-vertex'; import { generateText, Output } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { experimental_output } = await generateText({ diff --git a/examples/ai-core/src/generate-text/google-vertex-tool-call.ts b/examples/ai-core/src/generate-text/google-vertex-tool-call.ts index 68bf13865493..f9140b6f745a 100644 --- a/examples/ai-core/src/generate-text/google-vertex-tool-call.ts +++ b/examples/ai-core/src/generate-text/google-vertex-tool-call.ts @@ -1,7 +1,7 @@ import { vertex } from '@ai-sdk/google-vertex'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { text } = await generateText({ diff --git a/examples/ai-core/src/generate-text/mistral-tool-call.ts b/examples/ai-core/src/generate-text/mistral-tool-call.ts index 952dc5df24d4..7e2fea71967c 100644 --- a/examples/ai-core/src/generate-text/mistral-tool-call.ts +++ b/examples/ai-core/src/generate-text/mistral-tool-call.ts @@ -1,7 +1,7 @@ import { mistral } from '@ai-sdk/mistral'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/mistral-tool-choice.ts b/examples/ai-core/src/generate-text/mistral-tool-choice.ts index d96f9199e60d..53725b38b974 100644 --- a/examples/ai-core/src/generate-text/mistral-tool-choice.ts +++ b/examples/ai-core/src/generate-text/mistral-tool-choice.ts @@ -1,7 +1,7 @@ import { mistral } from '@ai-sdk/mistral'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/mock-invalid-tool-call.ts b/examples/ai-core/src/generate-text/mock-invalid-tool-call.ts index aec4a1b7c7e9..ece8183bbb7a 100644 --- a/examples/ai-core/src/generate-text/mock-invalid-tool-call.ts +++ b/examples/ai-core/src/generate-text/mock-invalid-tool-call.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, tool } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/mock-tool-call-repair-change-tool.ts b/examples/ai-core/src/generate-text/mock-tool-call-repair-change-tool.ts index 508455a697d1..bc3ada555002 100644 --- a/examples/ai-core/src/generate-text/mock-tool-call-repair-change-tool.ts +++ b/examples/ai-core/src/generate-text/mock-tool-call-repair-change-tool.ts @@ -1,7 +1,7 @@ import { generateText, tool } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/mock-tool-call-repair-reask.ts b/examples/ai-core/src/generate-text/mock-tool-call-repair-reask.ts index 04faf0bd7164..cecbb0426225 100644 --- a/examples/ai-core/src/generate-text/mock-tool-call-repair-reask.ts +++ b/examples/ai-core/src/generate-text/mock-tool-call-repair-reask.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/mock-tool-call-repair-structured-model.ts b/examples/ai-core/src/generate-text/mock-tool-call-repair-structured-model.ts index 9f0555c5f583..9cf55ba61570 100644 --- a/examples/ai-core/src/generate-text/mock-tool-call-repair-structured-model.ts +++ b/examples/ai-core/src/generate-text/mock-tool-call-repair-structured-model.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { generateObject, generateText, NoSuchToolError, tool } from 'ai'; import { MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/openai-active-tools.ts b/examples/ai-core/src/generate-text/openai-active-tools.ts index 914c59e8a92f..3fea36ea5a0e 100644 --- a/examples/ai-core/src/generate-text/openai-active-tools.ts +++ b/examples/ai-core/src/generate-text/openai-active-tools.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/openai-compatible-togetherai-tool-call.ts b/examples/ai-core/src/generate-text/openai-compatible-togetherai-tool-call.ts index 8f63077ebbda..7c5c76514e54 100644 --- a/examples/ai-core/src/generate-text/openai-compatible-togetherai-tool-call.ts +++ b/examples/ai-core/src/generate-text/openai-compatible-togetherai-tool-call.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { generateText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/openai-dynamic-tool-call.ts b/examples/ai-core/src/generate-text/openai-dynamic-tool-call.ts index eeea02305033..34349e444266 100644 --- a/examples/ai-core/src/generate-text/openai-dynamic-tool-call.ts +++ b/examples/ai-core/src/generate-text/openai-dynamic-tool-call.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { dynamicTool, generateText, stepCountIs, ToolSet } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; function dynamicTools(): ToolSet { diff --git a/examples/ai-core/src/generate-text/openai-multi-step.ts b/examples/ai-core/src/generate-text/openai-multi-step.ts index 2ebd1ae99298..e63e67a1099b 100644 --- a/examples/ai-core/src/generate-text/openai-multi-step.ts +++ b/examples/ai-core/src/generate-text/openai-multi-step.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { text, usage } = await generateText({ diff --git a/examples/ai-core/src/generate-text/openai-output-object.ts b/examples/ai-core/src/generate-text/openai-output-object.ts index 71137177e5b4..ef271dd95c35 100644 --- a/examples/ai-core/src/generate-text/openai-output-object.ts +++ b/examples/ai-core/src/generate-text/openai-output-object.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, Output, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { experimental_output } = await generateText({ diff --git a/examples/ai-core/src/generate-text/openai-reasoning-tools.ts b/examples/ai-core/src/generate-text/openai-reasoning-tools.ts index bc51d5463c03..372a22b8d7eb 100644 --- a/examples/ai-core/src/generate-text/openai-reasoning-tools.ts +++ b/examples/ai-core/src/generate-text/openai-reasoning-tools.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/openai-responses-output-object.ts b/examples/ai-core/src/generate-text/openai-responses-output-object.ts index c887ecb8ea1c..d3e6a85d60c8 100644 --- a/examples/ai-core/src/generate-text/openai-responses-output-object.ts +++ b/examples/ai-core/src/generate-text/openai-responses-output-object.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, stepCountIs, Output, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { experimental_output } = await generateText({ diff --git a/examples/ai-core/src/generate-text/openai-responses-roundtrip-server-side-tools.ts b/examples/ai-core/src/generate-text/openai-responses-roundtrip-server-side-tools.ts index fcf1b8766257..3f56ddffa834 100644 --- a/examples/ai-core/src/generate-text/openai-responses-roundtrip-server-side-tools.ts +++ b/examples/ai-core/src/generate-text/openai-responses-roundtrip-server-side-tools.ts @@ -1,7 +1,7 @@ import { createOpenAI } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const openai = createOpenAI({ // Console log the API request body for debugging diff --git a/examples/ai-core/src/generate-text/openai-responses-tool-call.ts b/examples/ai-core/src/generate-text/openai-responses-tool-call.ts index d53b8c2e9579..9c087f1cfbf4 100644 --- a/examples/ai-core/src/generate-text/openai-responses-tool-call.ts +++ b/examples/ai-core/src/generate-text/openai-responses-tool-call.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/openai-tool-call-with-context.ts b/examples/ai-core/src/generate-text/openai-tool-call-with-context.ts index 08f1e07e3c95..b250a2b6be3a 100644 --- a/examples/ai-core/src/generate-text/openai-tool-call-with-context.ts +++ b/examples/ai-core/src/generate-text/openai-tool-call-with-context.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/openai-tool-call.ts b/examples/ai-core/src/generate-text/openai-tool-call.ts index f3d575a70336..a9879fb8da8d 100644 --- a/examples/ai-core/src/generate-text/openai-tool-call.ts +++ b/examples/ai-core/src/generate-text/openai-tool-call.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/openai-tool-choice.ts b/examples/ai-core/src/generate-text/openai-tool-choice.ts index e78f616d1b09..2c0ec526d841 100644 --- a/examples/ai-core/src/generate-text/openai-tool-choice.ts +++ b/examples/ai-core/src/generate-text/openai-tool-choice.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/openai-tool-execution-error.ts b/examples/ai-core/src/generate-text/openai-tool-execution-error.ts index f211f4bdf0f9..69e4563c066f 100644 --- a/examples/ai-core/src/generate-text/openai-tool-execution-error.ts +++ b/examples/ai-core/src/generate-text/openai-tool-execution-error.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = await generateText({ diff --git a/examples/ai-core/src/generate-text/togetherai-tool-call.ts b/examples/ai-core/src/generate-text/togetherai-tool-call.ts index 67480e1a6038..75ad3bfe5648 100644 --- a/examples/ai-core/src/generate-text/togetherai-tool-call.ts +++ b/examples/ai-core/src/generate-text/togetherai-tool-call.ts @@ -1,7 +1,7 @@ import { togetherai } from '@ai-sdk/togetherai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/generate-text/xai-structured-output.ts b/examples/ai-core/src/generate-text/xai-structured-output.ts index a420f0d68fd1..d4b91778260c 100644 --- a/examples/ai-core/src/generate-text/xai-structured-output.ts +++ b/examples/ai-core/src/generate-text/xai-structured-output.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { generateText, Output } from 'ai'; import { xai } from '@ai-sdk/xai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { experimental_output } = await generateText({ diff --git a/examples/ai-core/src/generate-text/xai-tool-call.ts b/examples/ai-core/src/generate-text/xai-tool-call.ts index 5f4de2999d48..8be6818745d0 100644 --- a/examples/ai-core/src/generate-text/xai-tool-call.ts +++ b/examples/ai-core/src/generate-text/xai-tool-call.ts @@ -1,7 +1,7 @@ import { xai } from '@ai-sdk/xai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-object/amazon-bedrock.ts b/examples/ai-core/src/stream-object/amazon-bedrock.ts index aaee002700ff..9f8466ed52d5 100644 --- a/examples/ai-core/src/stream-object/amazon-bedrock.ts +++ b/examples/ai-core/src/stream-object/amazon-bedrock.ts @@ -1,7 +1,7 @@ import { bedrock } from '@ai-sdk/amazon-bedrock'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/anthropic.ts b/examples/ai-core/src/stream-object/anthropic.ts index 126031f13026..bc8b8cf93d84 100644 --- a/examples/ai-core/src/stream-object/anthropic.ts +++ b/examples/ai-core/src/stream-object/anthropic.ts @@ -1,7 +1,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/azure.ts b/examples/ai-core/src/stream-object/azure.ts index 95c6e69dfb64..2fd3335d9daa 100644 --- a/examples/ai-core/src/stream-object/azure.ts +++ b/examples/ai-core/src/stream-object/azure.ts @@ -1,7 +1,7 @@ import { azure } from '@ai-sdk/azure'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/fireworks.ts b/examples/ai-core/src/stream-object/fireworks.ts index 720e352b4d02..7e3e9a523e3b 100644 --- a/examples/ai-core/src/stream-object/fireworks.ts +++ b/examples/ai-core/src/stream-object/fireworks.ts @@ -1,7 +1,7 @@ import { fireworks } from '@ai-sdk/fireworks'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/gateway.ts b/examples/ai-core/src/stream-object/gateway.ts index 6a5c047b9c20..2fff05a89f3b 100644 --- a/examples/ai-core/src/stream-object/gateway.ts +++ b/examples/ai-core/src/stream-object/gateway.ts @@ -1,6 +1,6 @@ import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/google-vertex-anthropic.ts b/examples/ai-core/src/stream-object/google-vertex-anthropic.ts index 0ebbe7cf6ccd..27519f80e12e 100644 --- a/examples/ai-core/src/stream-object/google-vertex-anthropic.ts +++ b/examples/ai-core/src/stream-object/google-vertex-anthropic.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; import { streamObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/google-vertex.ts b/examples/ai-core/src/stream-object/google-vertex.ts index 92eab5aab3cd..026c71cb585f 100644 --- a/examples/ai-core/src/stream-object/google-vertex.ts +++ b/examples/ai-core/src/stream-object/google-vertex.ts @@ -1,7 +1,7 @@ import { vertex } from '@ai-sdk/google-vertex'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/google.ts b/examples/ai-core/src/stream-object/google.ts index 10ca1c19bd40..6b42457d562a 100644 --- a/examples/ai-core/src/stream-object/google.ts +++ b/examples/ai-core/src/stream-object/google.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/groq.ts b/examples/ai-core/src/stream-object/groq.ts index fd211a3d24c9..e777aa57632b 100644 --- a/examples/ai-core/src/stream-object/groq.ts +++ b/examples/ai-core/src/stream-object/groq.ts @@ -1,7 +1,7 @@ import { groq } from '@ai-sdk/groq'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/mistral.ts b/examples/ai-core/src/stream-object/mistral.ts index 417e98956591..996b59a88147 100644 --- a/examples/ai-core/src/stream-object/mistral.ts +++ b/examples/ai-core/src/stream-object/mistral.ts @@ -1,7 +1,7 @@ import { mistral } from '@ai-sdk/mistral'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/mock.ts b/examples/ai-core/src/stream-object/mock.ts index 47d71f34ec2f..c5449223d4fa 100644 --- a/examples/ai-core/src/stream-object/mock.ts +++ b/examples/ai-core/src/stream-object/mock.ts @@ -1,7 +1,7 @@ import { streamObject } from 'ai'; import { convertArrayToReadableStream, MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/nim.ts b/examples/ai-core/src/stream-object/nim.ts index 96b91f112588..a4dfaa778803 100644 --- a/examples/ai-core/src/stream-object/nim.ts +++ b/examples/ai-core/src/stream-object/nim.ts @@ -1,6 +1,6 @@ import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { streamObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import 'dotenv/config'; async function main() { diff --git a/examples/ai-core/src/stream-object/openai-5-reasoning.ts b/examples/ai-core/src/stream-object/openai-5-reasoning.ts index dc6ed0c3ed12..134ea1762f01 100644 --- a/examples/ai-core/src/stream-object/openai-5-reasoning.ts +++ b/examples/ai-core/src/stream-object/openai-5-reasoning.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-array.ts b/examples/ai-core/src/stream-object/openai-array.ts index fa71304d1835..5010e17a663d 100644 --- a/examples/ai-core/src/stream-object/openai-array.ts +++ b/examples/ai-core/src/stream-object/openai-array.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { elementStream: destinations } = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-compatible-togetherai.ts b/examples/ai-core/src/stream-object/openai-compatible-togetherai.ts index 07878e70ad3d..9fa464ba7bf7 100644 --- a/examples/ai-core/src/stream-object/openai-compatible-togetherai.ts +++ b/examples/ai-core/src/stream-object/openai-compatible-togetherai.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { streamObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const togetherai = createOpenAICompatible({ diff --git a/examples/ai-core/src/stream-object/openai-fullstream.ts b/examples/ai-core/src/stream-object/openai-fullstream.ts index 6216abbbe849..f7d33257f228 100644 --- a/examples/ai-core/src/stream-object/openai-fullstream.ts +++ b/examples/ai-core/src/stream-object/openai-fullstream.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-object.ts b/examples/ai-core/src/stream-object/openai-object.ts index 8959b2df3012..7ae7d8fb7a19 100644 --- a/examples/ai-core/src/stream-object/openai-object.ts +++ b/examples/ai-core/src/stream-object/openai-object.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-on-finish.ts b/examples/ai-core/src/stream-object/openai-on-finish.ts index 603dd7ce8b78..4047d2e1a7c3 100644 --- a/examples/ai-core/src/stream-object/openai-on-finish.ts +++ b/examples/ai-core/src/stream-object/openai-on-finish.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-reasoning.ts b/examples/ai-core/src/stream-object/openai-reasoning.ts index de77d440af1b..2046f0327081 100644 --- a/examples/ai-core/src/stream-object/openai-reasoning.ts +++ b/examples/ai-core/src/stream-object/openai-reasoning.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-request-body.ts b/examples/ai-core/src/stream-object/openai-request-body.ts index 058e1e509723..4db0c51266b5 100644 --- a/examples/ai-core/src/stream-object/openai-request-body.ts +++ b/examples/ai-core/src/stream-object/openai-request-body.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-responses.ts b/examples/ai-core/src/stream-object/openai-responses.ts index 131e1a6957ad..37e41e07b751 100644 --- a/examples/ai-core/src/stream-object/openai-responses.ts +++ b/examples/ai-core/src/stream-object/openai-responses.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-store-generation.ts b/examples/ai-core/src/stream-object/openai-store-generation.ts index 9a0c9750f73a..650a6612e370 100644 --- a/examples/ai-core/src/stream-object/openai-store-generation.ts +++ b/examples/ai-core/src/stream-object/openai-store-generation.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-stream-object-name-description.ts b/examples/ai-core/src/stream-object/openai-stream-object-name-description.ts index 33f1a72c44c4..f66e8e13e2fa 100644 --- a/examples/ai-core/src/stream-object/openai-stream-object-name-description.ts +++ b/examples/ai-core/src/stream-object/openai-stream-object-name-description.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-stream-object.ts b/examples/ai-core/src/stream-object/openai-stream-object.ts index df1a4d9df383..21667049c493 100644 --- a/examples/ai-core/src/stream-object/openai-stream-object.ts +++ b/examples/ai-core/src/stream-object/openai-stream-object.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-token-usage.ts b/examples/ai-core/src/stream-object/openai-token-usage.ts index 1b9622f670a0..a10e1ced652a 100644 --- a/examples/ai-core/src/stream-object/openai-token-usage.ts +++ b/examples/ai-core/src/stream-object/openai-token-usage.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject, LanguageModelUsage } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai-unstructured-output.ts b/examples/ai-core/src/stream-object/openai-unstructured-output.ts index 8672059e0809..4c011d0cb6cb 100644 --- a/examples/ai-core/src/stream-object/openai-unstructured-output.ts +++ b/examples/ai-core/src/stream-object/openai-unstructured-output.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/openai.ts b/examples/ai-core/src/stream-object/openai.ts index caf3ae46e8cc..2a8b8f5fb1d6 100644 --- a/examples/ai-core/src/stream-object/openai.ts +++ b/examples/ai-core/src/stream-object/openai.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v3'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/togetherai.ts b/examples/ai-core/src/stream-object/togetherai.ts index 536319ddd3f7..8cfb6b557379 100644 --- a/examples/ai-core/src/stream-object/togetherai.ts +++ b/examples/ai-core/src/stream-object/togetherai.ts @@ -1,7 +1,7 @@ import { togetherai } from '@ai-sdk/togetherai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/vercel.ts b/examples/ai-core/src/stream-object/vercel.ts index 94251c54eda9..ed55b743f853 100644 --- a/examples/ai-core/src/stream-object/vercel.ts +++ b/examples/ai-core/src/stream-object/vercel.ts @@ -1,7 +1,7 @@ import { vercel } from '@ai-sdk/vercel'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/xai-structured-outputs-name-description.ts b/examples/ai-core/src/stream-object/xai-structured-outputs-name-description.ts index cc3e53579b07..b74efa67e81a 100644 --- a/examples/ai-core/src/stream-object/xai-structured-outputs-name-description.ts +++ b/examples/ai-core/src/stream-object/xai-structured-outputs-name-description.ts @@ -1,7 +1,7 @@ import { xai } from '@ai-sdk/xai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-object/xai.ts b/examples/ai-core/src/stream-object/xai.ts index 5169ab298e4e..0504fbb6fa7c 100644 --- a/examples/ai-core/src/stream-object/xai.ts +++ b/examples/ai-core/src/stream-object/xai.ts @@ -1,7 +1,7 @@ import { xai } from '@ai-sdk/xai'; import { streamObject } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamObject({ diff --git a/examples/ai-core/src/stream-text/amazon-bedrock-cache-point-tool-call.ts b/examples/ai-core/src/stream-text/amazon-bedrock-cache-point-tool-call.ts index 0c53cb50f243..8232f6283acc 100644 --- a/examples/ai-core/src/stream-text/amazon-bedrock-cache-point-tool-call.ts +++ b/examples/ai-core/src/stream-text/amazon-bedrock-cache-point-tool-call.ts @@ -1,7 +1,7 @@ import { bedrock } from '@ai-sdk/amazon-bedrock'; import { streamText, tool, ModelMessage } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const messages: ModelMessage[] = []; diff --git a/examples/ai-core/src/stream-text/amazon-bedrock-chatbot.ts b/examples/ai-core/src/stream-text/amazon-bedrock-chatbot.ts index 3b3cb579498b..ec9cf5021b3e 100644 --- a/examples/ai-core/src/stream-text/amazon-bedrock-chatbot.ts +++ b/examples/ai-core/src/stream-text/amazon-bedrock-chatbot.ts @@ -2,7 +2,7 @@ import { bedrock } from '@ai-sdk/amazon-bedrock'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/amazon-bedrock-fullstream.ts b/examples/ai-core/src/stream-text/amazon-bedrock-fullstream.ts index f4f6ad1955e4..f582f47aab0e 100644 --- a/examples/ai-core/src/stream-text/amazon-bedrock-fullstream.ts +++ b/examples/ai-core/src/stream-text/amazon-bedrock-fullstream.ts @@ -1,7 +1,7 @@ import { bedrock } from '@ai-sdk/amazon-bedrock'; import { stepCountIs, streamText, ToolCallPart, ToolResultPart } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/amazon-bedrock-reasoning-chatbot.ts b/examples/ai-core/src/stream-text/amazon-bedrock-reasoning-chatbot.ts index 5f4bd8a9ca07..4a7a152d57e6 100644 --- a/examples/ai-core/src/stream-text/amazon-bedrock-reasoning-chatbot.ts +++ b/examples/ai-core/src/stream-text/amazon-bedrock-reasoning-chatbot.ts @@ -2,7 +2,7 @@ import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const bedrock = createAmazonBedrock({ // example fetch wrapper that logs the input to the API call: diff --git a/examples/ai-core/src/stream-text/anthropic-chatbot.ts b/examples/ai-core/src/stream-text/anthropic-chatbot.ts index cbeea13db127..3ba55d204abe 100644 --- a/examples/ai-core/src/stream-text/anthropic-chatbot.ts +++ b/examples/ai-core/src/stream-text/anthropic-chatbot.ts @@ -2,7 +2,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/anthropic-fullstream.ts b/examples/ai-core/src/stream-text/anthropic-fullstream.ts index 48aad985ede5..0736bf864d50 100644 --- a/examples/ai-core/src/stream-text/anthropic-fullstream.ts +++ b/examples/ai-core/src/stream-text/anthropic-fullstream.ts @@ -1,7 +1,7 @@ import { anthropic } from '@ai-sdk/anthropic'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/anthropic-reasoning-chatbot.ts b/examples/ai-core/src/stream-text/anthropic-reasoning-chatbot.ts index 731bee6b322b..eddeffdd5ca9 100644 --- a/examples/ai-core/src/stream-text/anthropic-reasoning-chatbot.ts +++ b/examples/ai-core/src/stream-text/anthropic-reasoning-chatbot.ts @@ -2,7 +2,7 @@ import { AnthropicProviderOptions, createAnthropic } from '@ai-sdk/anthropic'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const anthropic = createAnthropic({ // example fetch wrapper that logs the input to the API call: diff --git a/examples/ai-core/src/stream-text/azure-fullstream.ts b/examples/ai-core/src/stream-text/azure-fullstream.ts index f3e3a70e7e97..09603ea288a8 100644 --- a/examples/ai-core/src/stream-text/azure-fullstream.ts +++ b/examples/ai-core/src/stream-text/azure-fullstream.ts @@ -1,7 +1,7 @@ import { azure } from '@ai-sdk/azure'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/cohere-chatbot.ts b/examples/ai-core/src/stream-text/cohere-chatbot.ts index 17fff2b43b50..c20471aee0fa 100644 --- a/examples/ai-core/src/stream-text/cohere-chatbot.ts +++ b/examples/ai-core/src/stream-text/cohere-chatbot.ts @@ -2,7 +2,7 @@ import { cohere } from '@ai-sdk/cohere'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/cohere-tool-call-empty-params.ts b/examples/ai-core/src/stream-text/cohere-tool-call-empty-params.ts index f74b99a8447e..20de2baa87ed 100644 --- a/examples/ai-core/src/stream-text/cohere-tool-call-empty-params.ts +++ b/examples/ai-core/src/stream-text/cohere-tool-call-empty-params.ts @@ -7,7 +7,7 @@ import { tool, } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const messages: ModelMessage[] = []; diff --git a/examples/ai-core/src/stream-text/google-chatbot.ts b/examples/ai-core/src/stream-text/google-chatbot.ts index 3e667f7ecfe7..491c318c66d0 100644 --- a/examples/ai-core/src/stream-text/google-chatbot.ts +++ b/examples/ai-core/src/stream-text/google-chatbot.ts @@ -2,7 +2,7 @@ import { google } from '@ai-sdk/google'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/google-fullstream.ts b/examples/ai-core/src/stream-text/google-fullstream.ts index e7e87992dce0..2019b50b2b46 100644 --- a/examples/ai-core/src/stream-text/google-fullstream.ts +++ b/examples/ai-core/src/stream-text/google-fullstream.ts @@ -1,7 +1,7 @@ import { google } from '@ai-sdk/google'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/google-vertex-anthropic-chatbot.ts b/examples/ai-core/src/stream-text/google-vertex-anthropic-chatbot.ts index 16e9e7717f17..49126fd4d221 100644 --- a/examples/ai-core/src/stream-text/google-vertex-anthropic-chatbot.ts +++ b/examples/ai-core/src/stream-text/google-vertex-anthropic-chatbot.ts @@ -2,7 +2,7 @@ import 'dotenv/config'; import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/google-vertex-anthropic-fullstream.ts b/examples/ai-core/src/stream-text/google-vertex-anthropic-fullstream.ts index 74035bbf9e5c..016cc18a4da4 100644 --- a/examples/ai-core/src/stream-text/google-vertex-anthropic-fullstream.ts +++ b/examples/ai-core/src/stream-text/google-vertex-anthropic-fullstream.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic'; import { streamText } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/google-vertex-fullstream.ts b/examples/ai-core/src/stream-text/google-vertex-fullstream.ts index 7ad45bfe4c25..c4e7d4561336 100644 --- a/examples/ai-core/src/stream-text/google-vertex-fullstream.ts +++ b/examples/ai-core/src/stream-text/google-vertex-fullstream.ts @@ -1,7 +1,7 @@ import { vertex } from '@ai-sdk/google-vertex'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/groq-chatbot.ts b/examples/ai-core/src/stream-text/groq-chatbot.ts index f4583ee8e3f0..12901cea40b2 100644 --- a/examples/ai-core/src/stream-text/groq-chatbot.ts +++ b/examples/ai-core/src/stream-text/groq-chatbot.ts @@ -2,7 +2,7 @@ import { groq } from '@ai-sdk/groq'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/mistral-chatbot.ts b/examples/ai-core/src/stream-text/mistral-chatbot.ts index 419ab466b6d5..b6a9126aed18 100644 --- a/examples/ai-core/src/stream-text/mistral-chatbot.ts +++ b/examples/ai-core/src/stream-text/mistral-chatbot.ts @@ -2,7 +2,7 @@ import { mistral } from '@ai-sdk/mistral'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/mistral-fullstream.ts b/examples/ai-core/src/stream-text/mistral-fullstream.ts index 5ad619548310..d17d6be05e14 100644 --- a/examples/ai-core/src/stream-text/mistral-fullstream.ts +++ b/examples/ai-core/src/stream-text/mistral-fullstream.ts @@ -1,7 +1,7 @@ import { mistral } from '@ai-sdk/mistral'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/mock-tool-call-repair-change-tool.ts b/examples/ai-core/src/stream-text/mock-tool-call-repair-change-tool.ts index 8b74462a8f13..2ede4ea92b4f 100644 --- a/examples/ai-core/src/stream-text/mock-tool-call-repair-change-tool.ts +++ b/examples/ai-core/src/stream-text/mock-tool-call-repair-change-tool.ts @@ -1,7 +1,7 @@ import { streamText, tool } from 'ai'; import { convertArrayToReadableStream, MockLanguageModelV2 } from 'ai/test'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-5-reasoning.ts b/examples/ai-core/src/stream-text/openai-5-reasoning.ts index 066760773546..edd5e7ea12d5 100644 --- a/examples/ai-core/src/stream-text/openai-5-reasoning.ts +++ b/examples/ai-core/src/stream-text/openai-5-reasoning.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/openai-chatbot.ts b/examples/ai-core/src/stream-text/openai-chatbot.ts index f40675776da6..e603acbaa0da 100644 --- a/examples/ai-core/src/stream-text/openai-chatbot.ts +++ b/examples/ai-core/src/stream-text/openai-chatbot.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/openai-dynamic-tool-call.ts b/examples/ai-core/src/stream-text/openai-dynamic-tool-call.ts index 4664a2bc90a9..b265e1194ded 100644 --- a/examples/ai-core/src/stream-text/openai-dynamic-tool-call.ts +++ b/examples/ai-core/src/stream-text/openai-dynamic-tool-call.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import 'dotenv/config'; import { weatherTool } from '../tools/weather-tool'; import { stepCountIs, streamText, dynamicTool, ToolSet } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; function dynamicTools(): ToolSet { return { diff --git a/examples/ai-core/src/stream-text/openai-fullstream.ts b/examples/ai-core/src/stream-text/openai-fullstream.ts index ed7aa9c9baa8..a97c7c9f6945 100644 --- a/examples/ai-core/src/stream-text/openai-fullstream.ts +++ b/examples/ai-core/src/stream-text/openai-fullstream.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/openai-multi-step.ts b/examples/ai-core/src/stream-text/openai-multi-step.ts index d44977e842ad..0e0d7af5f260 100644 --- a/examples/ai-core/src/stream-text/openai-multi-step.ts +++ b/examples/ai-core/src/stream-text/openai-multi-step.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-on-chunk-tool-call-streaming.ts b/examples/ai-core/src/stream-text/openai-on-chunk-tool-call-streaming.ts index 7c53467fb8d2..336471eb7b8b 100644 --- a/examples/ai-core/src/stream-text/openai-on-chunk-tool-call-streaming.ts +++ b/examples/ai-core/src/stream-text/openai-on-chunk-tool-call-streaming.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { streamText } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; async function main() { diff --git a/examples/ai-core/src/stream-text/openai-on-finish-response-messages.ts b/examples/ai-core/src/stream-text/openai-on-finish-response-messages.ts index b5498c718f21..14b2825f096f 100644 --- a/examples/ai-core/src/stream-text/openai-on-finish-response-messages.ts +++ b/examples/ai-core/src/stream-text/openai-on-finish-response-messages.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-on-finish-steps.ts b/examples/ai-core/src/stream-text/openai-on-finish-steps.ts index c3da4d22ea3f..c786ea755a79 100644 --- a/examples/ai-core/src/stream-text/openai-on-finish-steps.ts +++ b/examples/ai-core/src/stream-text/openai-on-finish-steps.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-on-step-finish.ts b/examples/ai-core/src/stream-text/openai-on-step-finish.ts index d950ac2f9c9f..96e448d03f99 100644 --- a/examples/ai-core/src/stream-text/openai-on-step-finish.ts +++ b/examples/ai-core/src/stream-text/openai-on-step-finish.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-output-object.ts b/examples/ai-core/src/stream-text/openai-output-object.ts index 52ec32cafe13..afcf6cdefcbd 100644 --- a/examples/ai-core/src/stream-text/openai-output-object.ts +++ b/examples/ai-core/src/stream-text/openai-output-object.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, Output, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const { experimental_partialOutputStream: partialOutputStream } = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-prepare-step.ts b/examples/ai-core/src/stream-text/openai-prepare-step.ts index fb21005ef2f3..bfb532d440b2 100644 --- a/examples/ai-core/src/stream-text/openai-prepare-step.ts +++ b/examples/ai-core/src/stream-text/openai-prepare-step.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const retrieveInformation = tool({ description: 'Retrieve information from the database', diff --git a/examples/ai-core/src/stream-text/openai-read-ui-message-stream.ts b/examples/ai-core/src/stream-text/openai-read-ui-message-stream.ts index 8e77a68cff7d..5319ddaa819d 100644 --- a/examples/ai-core/src/stream-text/openai-read-ui-message-stream.ts +++ b/examples/ai-core/src/stream-text/openai-read-ui-message-stream.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { readUIMessageStream, stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-responses-chatbot.ts b/examples/ai-core/src/stream-text/openai-responses-chatbot.ts index 4e5e8552e76f..0f1f049b8606 100644 --- a/examples/ai-core/src/stream-text/openai-responses-chatbot.ts +++ b/examples/ai-core/src/stream-text/openai-responses-chatbot.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/openai-responses-reasoning-chatbot.ts b/examples/ai-core/src/stream-text/openai-responses-reasoning-chatbot.ts index 6a0894a9605f..6724a3c2a25c 100644 --- a/examples/ai-core/src/stream-text/openai-responses-reasoning-chatbot.ts +++ b/examples/ai-core/src/stream-text/openai-responses-reasoning-chatbot.ts @@ -2,7 +2,7 @@ import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { stepCountIs, ModelMessage, streamText, tool, APICallError } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/stream-text/openai-responses-reasoning-tool-call.ts b/examples/ai-core/src/stream-text/openai-responses-reasoning-tool-call.ts index 5c91bcc32777..42f09fa37782 100644 --- a/examples/ai-core/src/stream-text/openai-responses-reasoning-tool-call.ts +++ b/examples/ai-core/src/stream-text/openai-responses-reasoning-tool-call.ts @@ -1,7 +1,7 @@ import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-responses-tool-call.ts b/examples/ai-core/src/stream-text/openai-responses-tool-call.ts index 3132e0ac513d..35072b5198a9 100644 --- a/examples/ai-core/src/stream-text/openai-responses-tool-call.ts +++ b/examples/ai-core/src/stream-text/openai-responses-tool-call.ts @@ -2,7 +2,7 @@ import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import 'dotenv/config'; import { weatherTool } from '../tools/weather-tool'; import { stepCountIs, streamText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-swarm.ts b/examples/ai-core/src/stream-text/openai-swarm.ts index 1e83cf550cca..37fd2b9d4a71 100644 --- a/examples/ai-core/src/stream-text/openai-swarm.ts +++ b/examples/ai-core/src/stream-text/openai-swarm.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/openai-tool-abort.ts b/examples/ai-core/src/stream-text/openai-tool-abort.ts index c2aadacfca58..ff940e42fe44 100644 --- a/examples/ai-core/src/stream-text/openai-tool-abort.ts +++ b/examples/ai-core/src/stream-text/openai-tool-abort.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const abortController = new AbortController(); diff --git a/examples/ai-core/src/stream-text/openai-tool-call.ts b/examples/ai-core/src/stream-text/openai-tool-call.ts index 398e24019222..e74f866926f2 100644 --- a/examples/ai-core/src/stream-text/openai-tool-call.ts +++ b/examples/ai-core/src/stream-text/openai-tool-call.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import 'dotenv/config'; import { weatherTool } from '../tools/weather-tool'; import { stepCountIs, streamText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/openai-tool-output-stream.ts b/examples/ai-core/src/stream-text/openai-tool-output-stream.ts index b9b05729bc31..f5ec079c1199 100644 --- a/examples/ai-core/src/stream-text/openai-tool-output-stream.ts +++ b/examples/ai-core/src/stream-text/openai-tool-output-stream.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import 'dotenv/config'; import { stepCountIs, streamText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { const result = streamText({ diff --git a/examples/ai-core/src/stream-text/xai-chatbot.ts b/examples/ai-core/src/stream-text/xai-chatbot.ts index 4bc7467b0307..fdce2962177e 100644 --- a/examples/ai-core/src/stream-text/xai-chatbot.ts +++ b/examples/ai-core/src/stream-text/xai-chatbot.ts @@ -2,7 +2,7 @@ import { xai } from '@ai-sdk/xai'; import { stepCountIs, ModelMessage, streamText, tool } from 'ai'; import 'dotenv/config'; import * as readline from 'node:readline/promises'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const terminal = readline.createInterface({ input: process.stdin, diff --git a/examples/ai-core/src/telemetry/generate-object.ts b/examples/ai-core/src/telemetry/generate-object.ts index 1c793ee2cd81..dfa5214e1437 100644 --- a/examples/ai-core/src/telemetry/generate-object.ts +++ b/examples/ai-core/src/telemetry/generate-object.ts @@ -5,7 +5,7 @@ import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentation import { NodeSDK } from '@opentelemetry/sdk-node'; import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node'; import { generateObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter(), diff --git a/examples/ai-core/src/telemetry/generate-text-tool-call.ts b/examples/ai-core/src/telemetry/generate-text-tool-call.ts index 705419bcf20c..c26e221b35da 100644 --- a/examples/ai-core/src/telemetry/generate-text-tool-call.ts +++ b/examples/ai-core/src/telemetry/generate-text-tool-call.ts @@ -1,7 +1,7 @@ import { openai } from '@ai-sdk/openai'; import { generateText, tool } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; import { weatherTool } from '../tools/weather-tool'; import { NodeSDK } from '@opentelemetry/sdk-node'; diff --git a/examples/ai-core/src/telemetry/stream-object.ts b/examples/ai-core/src/telemetry/stream-object.ts index 1b5eb480007e..12ab6af6bbee 100644 --- a/examples/ai-core/src/telemetry/stream-object.ts +++ b/examples/ai-core/src/telemetry/stream-object.ts @@ -5,7 +5,7 @@ import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentation import { NodeSDK } from '@opentelemetry/sdk-node'; import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node'; import { streamObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter(), diff --git a/examples/ai-core/src/tools/weather-tool.ts b/examples/ai-core/src/tools/weather-tool.ts index a4588a9adbe7..83fceab490d1 100644 --- a/examples/ai-core/src/tools/weather-tool.ts +++ b/examples/ai-core/src/tools/weather-tool.ts @@ -1,5 +1,5 @@ import { tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export const weatherTool = tool({ description: 'Get the weather in a location', diff --git a/examples/ai-core/src/types/tool-set.ts b/examples/ai-core/src/types/tool-set.ts index b9a2dee6ec71..c4c49490990c 100644 --- a/examples/ai-core/src/types/tool-set.ts +++ b/examples/ai-core/src/types/tool-set.ts @@ -1,6 +1,6 @@ import { openai } from '@ai-sdk/openai'; import { StaticToolCall, StaticToolResult, generateText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const myToolSet = { firstTool: tool({ diff --git a/examples/mcp/src/stdio/client.ts b/examples/mcp/src/stdio/client.ts index e0f83cdf0075..b3f5e137e27a 100644 --- a/examples/mcp/src/stdio/client.ts +++ b/examples/mcp/src/stdio/client.ts @@ -2,7 +2,7 @@ import { openai } from '@ai-sdk/openai'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { experimental_createMCPClient, generateText, stepCountIs } from 'ai'; import 'dotenv/config'; -import { z } from 'zod/v4'; +import { z } from 'zod'; async function main() { let mcpClient; diff --git a/examples/next-agent/tool/weather-tool.ts b/examples/next-agent/tool/weather-tool.ts index 14350de8c14c..05b2491476cb 100644 --- a/examples/next-agent/tool/weather-tool.ts +++ b/examples/next-agent/tool/weather-tool.ts @@ -1,5 +1,5 @@ import { UIToolInvocation, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export const weatherTool = tool({ description: 'Get the weather in a location', diff --git a/examples/next-openai-pages/app/api/call-tool/route.ts b/examples/next-openai-pages/app/api/call-tool/route.ts index e7bb0c046c0d..a406610d06f7 100644 --- a/examples/next-openai-pages/app/api/call-tool/route.ts +++ b/examples/next-openai-pages/app/api/call-tool/route.ts @@ -1,6 +1,6 @@ import { convertToModelMessages, streamText, UIMessage } from 'ai'; import { openai } from '@ai-sdk/openai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); diff --git a/examples/next-openai-pages/app/api/generate-object/route.ts b/examples/next-openai-pages/app/api/generate-object/route.ts index 3a3a5e6d677f..cabff4128d87 100644 --- a/examples/next-openai-pages/app/api/generate-object/route.ts +++ b/examples/next-openai-pages/app/api/generate-object/route.ts @@ -1,6 +1,6 @@ import { generateObject } from 'ai'; import { openai } from '@ai-sdk/openai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export async function POST(req: Request) { const { prompt }: { prompt: string } = await req.json(); diff --git a/examples/next-openai-pages/app/api/stream-object/route.ts b/examples/next-openai-pages/app/api/stream-object/route.ts index 2bc0b6e8662f..e8570b33b9a3 100644 --- a/examples/next-openai-pages/app/api/stream-object/route.ts +++ b/examples/next-openai-pages/app/api/stream-object/route.ts @@ -1,6 +1,6 @@ import { openai } from '@ai-sdk/openai'; import { streamObject } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export const maxDuration = 30; diff --git a/examples/next-openai/app/api/dynamic-tools/route.ts b/examples/next-openai/app/api/dynamic-tools/route.ts index c5a4a2c06538..93cb898401db 100644 --- a/examples/next-openai/app/api/dynamic-tools/route.ts +++ b/examples/next-openai/app/api/dynamic-tools/route.ts @@ -10,7 +10,7 @@ import { UIDataTypes, UIMessage, } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // Allow streaming responses up to 30 seconds export const maxDuration = 30; diff --git a/examples/next-openai/app/api/test-invalid-tool-call/route.ts b/examples/next-openai/app/api/test-invalid-tool-call/route.ts index bd7d3deb4e31..3ae474401271 100644 --- a/examples/next-openai/app/api/test-invalid-tool-call/route.ts +++ b/examples/next-openai/app/api/test-invalid-tool-call/route.ts @@ -9,7 +9,7 @@ import { UIMessage, } from 'ai'; import { convertArrayToReadableStream, MockLanguageModelV2 } from 'ai/test'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // Allow streaming responses up to 30 seconds export const maxDuration = 30; diff --git a/examples/next-openai/app/api/use-chat-data-ui-parts/route.ts b/examples/next-openai/app/api/use-chat-data-ui-parts/route.ts index c2799f32fecd..4a148f53c63d 100644 --- a/examples/next-openai/app/api/use-chat-data-ui-parts/route.ts +++ b/examples/next-openai/app/api/use-chat-data-ui-parts/route.ts @@ -7,7 +7,7 @@ import { stepCountIs, streamText, } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export async function POST(req: Request) { const { messages } = await req.json(); diff --git a/examples/next-openai/app/api/use-chat-message-metadata/example-metadata-schema.ts b/examples/next-openai/app/api/use-chat-message-metadata/example-metadata-schema.ts index aa2be9ecb2f1..9821f9e2083d 100644 --- a/examples/next-openai/app/api/use-chat-message-metadata/example-metadata-schema.ts +++ b/examples/next-openai/app/api/use-chat-message-metadata/example-metadata-schema.ts @@ -1,4 +1,4 @@ -import { z } from 'zod/v4'; +import { z } from 'zod'; export const exampleMetadataSchema = z.object({ createdAt: z.number().optional(), diff --git a/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts b/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts index 2144c3038ddb..bd66360eca2f 100644 --- a/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts +++ b/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts @@ -1,6 +1,6 @@ import { openai } from '@ai-sdk/openai'; import { convertToModelMessages, streamText, UIDataTypes, UIMessage } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // Allow streaming responses up to 30 seconds export const maxDuration = 30; diff --git a/examples/next-openai/app/api/use-chat-tools/route.ts b/examples/next-openai/app/api/use-chat-tools/route.ts index 56392ba54446..b584fed7b569 100644 --- a/examples/next-openai/app/api/use-chat-tools/route.ts +++ b/examples/next-openai/app/api/use-chat-tools/route.ts @@ -9,7 +9,7 @@ import { UIMessage, validateUIMessages, } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // Allow streaming responses up to 30 seconds export const maxDuration = 30; diff --git a/examples/next-openai/app/api/use-completion-server-side-multi-step/route.ts b/examples/next-openai/app/api/use-completion-server-side-multi-step/route.ts index 82466c4a5c52..3b6aad2473d2 100644 --- a/examples/next-openai/app/api/use-completion-server-side-multi-step/route.ts +++ b/examples/next-openai/app/api/use-completion-server-side-multi-step/route.ts @@ -1,6 +1,6 @@ import { openai } from '@ai-sdk/openai'; import { stepCountIs, streamText, tool } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // Allow streaming responses up to 60 seconds export const maxDuration = 60; diff --git a/examples/next-openai/app/api/use-object-expense-tracker/schema.ts b/examples/next-openai/app/api/use-object-expense-tracker/schema.ts index aeb533e06478..9f7ebd952fd4 100644 --- a/examples/next-openai/app/api/use-object-expense-tracker/schema.ts +++ b/examples/next-openai/app/api/use-object-expense-tracker/schema.ts @@ -1,5 +1,5 @@ import { DeepPartial } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export const expenseSchema = z.object({ expense: z.object({ diff --git a/examples/next-openai/app/api/use-object/schema.ts b/examples/next-openai/app/api/use-object/schema.ts index 37fd5ca61f44..e63dc963f8cf 100644 --- a/examples/next-openai/app/api/use-object/schema.ts +++ b/examples/next-openai/app/api/use-object/schema.ts @@ -1,5 +1,5 @@ import { DeepPartial } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // define a schema for the notifications export const notificationSchema = z.object({ diff --git a/examples/next-openai/app/stream-object/schema.ts b/examples/next-openai/app/stream-object/schema.ts index 37fd5ca61f44..e63dc963f8cf 100644 --- a/examples/next-openai/app/stream-object/schema.ts +++ b/examples/next-openai/app/stream-object/schema.ts @@ -1,5 +1,5 @@ import { DeepPartial } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; // define a schema for the notifications export const notificationSchema = z.object({ diff --git a/examples/next/util/chat-schema.ts b/examples/next/util/chat-schema.ts index 8c49a52f5fce..ff6e30930578 100644 --- a/examples/next/util/chat-schema.ts +++ b/examples/next/util/chat-schema.ts @@ -1,5 +1,5 @@ import { UIDataTypes, UIMessage } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export const myMessageMetadataSchema = z.object({ createdAt: z.number(), diff --git a/examples/nuxt-openai/server/api/use-chat-tools.ts b/examples/nuxt-openai/server/api/use-chat-tools.ts index 71c4d1f3dfb0..d4d0c32fc436 100644 --- a/examples/nuxt-openai/server/api/use-chat-tools.ts +++ b/examples/nuxt-openai/server/api/use-chat-tools.ts @@ -1,6 +1,6 @@ import { createOpenAI } from '@ai-sdk/openai'; import { convertToModelMessages, stepCountIs, streamText } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; export default defineLazyEventHandler(async () => { const openai = createOpenAI({ diff --git a/examples/nuxt-openai/shared/notification-schema.ts b/examples/nuxt-openai/shared/notification-schema.ts index 86f3e751fcd7..932f6eb3de7f 100644 --- a/examples/nuxt-openai/shared/notification-schema.ts +++ b/examples/nuxt-openai/shared/notification-schema.ts @@ -1,4 +1,4 @@ -import { z } from 'zod/v4'; +import { z } from 'zod'; export const notificationSchema = z.object({ notifications: z.array( diff --git a/examples/sveltekit-openai/src/routes/api/chat/+server.ts b/examples/sveltekit-openai/src/routes/api/chat/+server.ts index c191f3a45716..1446b9e0fe5a 100644 --- a/examples/sveltekit-openai/src/routes/api/chat/+server.ts +++ b/examples/sveltekit-openai/src/routes/api/chat/+server.ts @@ -1,7 +1,7 @@ import { env } from '$env/dynamic/private'; import { createOpenAI } from '@ai-sdk/openai'; import { convertToModelMessages, streamText, stepCountIs } from 'ai'; -import { z } from 'zod/v4'; +import { z } from 'zod'; const openai = createOpenAI({ apiKey: env?.OPENAI_API_KEY, diff --git a/examples/sveltekit-openai/src/routes/structured-object/schema.ts b/examples/sveltekit-openai/src/routes/structured-object/schema.ts index 539f51299117..72104f1e8b25 100644 --- a/examples/sveltekit-openai/src/routes/structured-object/schema.ts +++ b/examples/sveltekit-openai/src/routes/structured-object/schema.ts @@ -1,4 +1,4 @@ -import { z } from 'zod/v4'; +import { z } from 'zod'; // define a schema for the notifications export const notificationSchema = z.object({ From db6051bf93c7e9b26680cd86b3aeb7c01b6e1220 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Thu, 11 Sep 2025 15:59:25 +0100 Subject: [PATCH 009/121] chore: remove response modalities from gemini flash image examples and docs (#8584) Passing response modalities in provider options is no longer required with gemini flash image. --- content/docs/03-ai-sdk-core/35-image-generation.mdx | 7 ++----- content/docs/04-ai-sdk-ui/02-chatbot.mdx | 2 +- .../01-ai-sdk-providers/15-google-generative-ai.mdx | 5 ----- .../ai-core/src/generate-image/google-gemini-editing.ts | 6 ------ examples/ai-core/src/generate-image/google-gemini-image.ts | 3 --- .../ai-core/src/generate-image/google-gemini-minimal.ts | 3 --- examples/ai-core/src/generate-text/google-image-output.ts | 3 --- examples/ai-core/src/generate-text/google-image.ts | 7 +------ .../ai-core/src/stream-text/google-chatbot-image-output.ts | 3 --- .../google-gemini-2.5-flash-image-preview-chatbot.ts | 3 --- examples/ai-core/src/stream-text/google-image-output.ts | 3 --- .../vertex-gemini-2.5-flash-image-preview-chatbot.ts | 3 --- .../next-openai/app/api/use-chat-image-output/route.ts | 3 --- 13 files changed, 4 insertions(+), 47 deletions(-) diff --git a/content/docs/03-ai-sdk-core/35-image-generation.mdx b/content/docs/03-ai-sdk-core/35-image-generation.mdx index aa2afdff494b..0d39b409913a 100644 --- a/content/docs/03-ai-sdk-core/35-image-generation.mdx +++ b/content/docs/03-ai-sdk-core/35-image-generation.mdx @@ -231,7 +231,7 @@ try { ## Generating Images with Language Models -Some language models such as Google `gemini-2.0-flash-exp` support multi-modal outputs including images. +Some language models such as Google `gemini-2.5-flash-image-preview` support multi-modal outputs including images. With such models, you can access the generated images using the `files` property of the response. ```ts @@ -239,10 +239,7 @@ import { google } from '@ai-sdk/google'; import { generateText } from 'ai'; const result = await generateText({ - model: google('gemini-2.0-flash-exp'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, + model: google('gemini-2.5-flash-image-preview'), prompt: 'Generate an image of a comic cat', }); diff --git a/content/docs/04-ai-sdk-ui/02-chatbot.mdx b/content/docs/04-ai-sdk-ui/02-chatbot.mdx index c83bb61302fe..86e3e8dc228d 100644 --- a/content/docs/04-ai-sdk-ui/02-chatbot.mdx +++ b/content/docs/04-ai-sdk-ui/02-chatbot.mdx @@ -960,7 +960,7 @@ messages.map(message => ( ## Image Generation -Some models such as Google `gemini-2.0-flash-exp` support image generation. +Some models such as Google `gemini-2.5-flash-image-preview` support image generation. When images are generated, they are exposed as files to the client. On the client side, you can access file parts of the message object and render them as images. 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 80223208fe2b..9e15432e11fd 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 @@ -110,7 +110,6 @@ await generateText({ threshold: 'BLOCK_LOW_AND_ABOVE', }, ], - responseModalities: ['TEXT', 'IMAGE'], }, }, }); @@ -582,7 +581,6 @@ const urlContextMetadata = metadata?.urlContextMetadata; ### Image Outputs Gemini models with image generation capabilities (`gemini-2.5-flash-image-preview`) support image generation. Images are exposed as files in the response. -You need to enable image output in the provider options using the `responseModalities` option. ```ts import { google } from '@ai-sdk/google'; @@ -590,9 +588,6 @@ import { generateText } from 'ai'; const result = await generateText({ model: google('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, prompt: 'Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme', }); diff --git a/examples/ai-core/src/generate-image/google-gemini-editing.ts b/examples/ai-core/src/generate-image/google-gemini-editing.ts index c4fe667d95ef..e15bf572c80b 100644 --- a/examples/ai-core/src/generate-image/google-gemini-editing.ts +++ b/examples/ai-core/src/generate-image/google-gemini-editing.ts @@ -7,9 +7,6 @@ async function main() { console.log('Generating base cat image...'); const baseResult = await generateText({ model: google('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, prompt: 'A photorealistic picture of a fluffy ginger cat sitting on a wooden table', }); @@ -38,9 +35,6 @@ async function main() { console.log('Adding wizard hat...'); const editResult = await generateText({ model: google('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, prompt: [ { role: 'user', diff --git a/examples/ai-core/src/generate-image/google-gemini-image.ts b/examples/ai-core/src/generate-image/google-gemini-image.ts index a28382131ad0..53163f9fee65 100644 --- a/examples/ai-core/src/generate-image/google-gemini-image.ts +++ b/examples/ai-core/src/generate-image/google-gemini-image.ts @@ -6,9 +6,6 @@ import 'dotenv/config'; async function main() { const result = await generateText({ model: google('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, prompt: 'Create a picture of a nano banana dish in a fancy restaurant with a Gemini theme', }); diff --git a/examples/ai-core/src/generate-image/google-gemini-minimal.ts b/examples/ai-core/src/generate-image/google-gemini-minimal.ts index 310e4ffd269d..aeeb8586e5bd 100644 --- a/examples/ai-core/src/generate-image/google-gemini-minimal.ts +++ b/examples/ai-core/src/generate-image/google-gemini-minimal.ts @@ -5,9 +5,6 @@ import 'dotenv/config'; async function main() { const { files } = await generateText({ model: google('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, prompt: 'A nano banana in a fancy restaurant', }); diff --git a/examples/ai-core/src/generate-text/google-image-output.ts b/examples/ai-core/src/generate-text/google-image-output.ts index d2d52e19da62..f26b2ac92711 100644 --- a/examples/ai-core/src/generate-text/google-image-output.ts +++ b/examples/ai-core/src/generate-text/google-image-output.ts @@ -7,9 +7,6 @@ async function main() { const result = await generateText({ model: google('gemini-2.0-flash-exp'), prompt: 'Generate an image of a comic cat', - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, }); console.log(result.text); diff --git a/examples/ai-core/src/generate-text/google-image.ts b/examples/ai-core/src/generate-text/google-image.ts index 9092b0639944..1cf1e328e69b 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, GoogleGenerativeAIProviderOptions } from '@ai-sdk/google'; +import { google } from '@ai-sdk/google'; import { generateText } from 'ai'; import 'dotenv/config'; import fs from 'node:fs'; @@ -15,11 +15,6 @@ async function main() { ], }, ], - providerOptions: { - google: { - responseModalities: ['TEXT', 'IMAGE'], - } satisfies GoogleGenerativeAIProviderOptions, - }, }); console.log(result.content); diff --git a/examples/ai-core/src/stream-text/google-chatbot-image-output.ts b/examples/ai-core/src/stream-text/google-chatbot-image-output.ts index 158f5a2f8d16..e264b2bb7a8a 100644 --- a/examples/ai-core/src/stream-text/google-chatbot-image-output.ts +++ b/examples/ai-core/src/stream-text/google-chatbot-image-output.ts @@ -17,9 +17,6 @@ async function main() { const result = streamText({ model: google('gemini-2.0-flash-exp'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, messages, }); diff --git a/examples/ai-core/src/stream-text/google-gemini-2.5-flash-image-preview-chatbot.ts b/examples/ai-core/src/stream-text/google-gemini-2.5-flash-image-preview-chatbot.ts index 9a0eb5c4f65c..15394a00aed7 100644 --- a/examples/ai-core/src/stream-text/google-gemini-2.5-flash-image-preview-chatbot.ts +++ b/examples/ai-core/src/stream-text/google-gemini-2.5-flash-image-preview-chatbot.ts @@ -17,9 +17,6 @@ async function main() { const result = streamText({ model: google('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, messages, }); diff --git a/examples/ai-core/src/stream-text/google-image-output.ts b/examples/ai-core/src/stream-text/google-image-output.ts index 17650996a8e1..f86914958b91 100644 --- a/examples/ai-core/src/stream-text/google-image-output.ts +++ b/examples/ai-core/src/stream-text/google-image-output.ts @@ -7,9 +7,6 @@ async function main() { const result = streamText({ model: google('gemini-2.0-flash-exp'), prompt: 'Generate an image of a comic cat', - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, }); for await (const part of result.fullStream) { diff --git a/examples/ai-core/src/stream-text/vertex-gemini-2.5-flash-image-preview-chatbot.ts b/examples/ai-core/src/stream-text/vertex-gemini-2.5-flash-image-preview-chatbot.ts index c8a95f0c09c6..ba484aeb1f9c 100644 --- a/examples/ai-core/src/stream-text/vertex-gemini-2.5-flash-image-preview-chatbot.ts +++ b/examples/ai-core/src/stream-text/vertex-gemini-2.5-flash-image-preview-chatbot.ts @@ -17,9 +17,6 @@ async function main() { const result = streamText({ model: vertex('gemini-2.5-flash-image-preview'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, messages, }); diff --git a/examples/next-openai/app/api/use-chat-image-output/route.ts b/examples/next-openai/app/api/use-chat-image-output/route.ts index c7e1b442a084..c1b7b979a163 100644 --- a/examples/next-openai/app/api/use-chat-image-output/route.ts +++ b/examples/next-openai/app/api/use-chat-image-output/route.ts @@ -8,9 +8,6 @@ export async function POST(req: Request) { const result = streamText({ model: google('gemini-2.0-flash-exp'), - providerOptions: { - google: { responseModalities: ['TEXT', 'IMAGE'] }, - }, messages: convertToModelMessages(messages), }); From cd91e4b80d4d1a22ccc4a046979b4679b654fa0b Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Fri, 12 Sep 2025 00:17:36 +0200 Subject: [PATCH 010/121] fix(ai): use correct type for reasoning outputs (#8590) ## Background The types for the reasoning output are wrong, we used reasoning input types (see #8589 ) ## Summary * introduce `ReasoningOutput` type and update streamText/generateText result types. ## Manual Verification * [x] verified in example that `providerMetadata` is used on reasoning parts of generateText result ## Future Work Move to explicit `*Output` types for outputs. ## Related Issues Fixes #8589 --- .changeset/tricky-penguins-carry.md | 5 +++++ .../01-ai-sdk-core/01-generate-text.mdx | 10 ++++++++-- .../01-ai-sdk-core/02-stream-text.mdx | 12 ++++++++--- packages/ai/src/generate-text/content-part.ts | 3 ++- .../src/generate-text/generate-text-result.ts | 4 ++-- packages/ai/src/generate-text/index.ts | 1 + .../ai/src/generate-text/reasoning-output.ts | 20 +++++++++++++++++++ .../src/generate-text/stream-text-result.ts | 15 +++++++------- 8 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 .changeset/tricky-penguins-carry.md create mode 100644 packages/ai/src/generate-text/reasoning-output.ts diff --git a/.changeset/tricky-penguins-carry.md b/.changeset/tricky-penguins-carry.md new file mode 100644 index 000000000000..4d2f379167c6 --- /dev/null +++ b/.changeset/tricky-penguins-carry.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): use correct type for reasoning outputs diff --git a/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx b/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx index 9b925b4f07a3..a0b204ff6880 100644 --- a/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx @@ -847,12 +847,12 @@ To see `generateText` in action, check out [these examples](#examples). }, { name: 'reasoning', - type: 'Array', + type: 'Array', description: 'The full reasoning that the model has generated in the last step.', properties: [ { - type: 'ReasoningPart', + type: 'ReasoningOutput', parameters: [ { name: 'type', @@ -864,6 +864,12 @@ To see `generateText` in action, check out [these examples](#examples). type: 'string', description: 'The reasoning text.', }, + { + name: 'providerMetadata', + type: 'SharedV2ProviderMetadata', + isOptional: true, + description: 'Additional provider metadata for the source.', + }, ], }, ], 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 66974257d55b..0ebbd5af89d5 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 @@ -1540,23 +1540,29 @@ To see `streamText` in action, check out [these examples](#examples). }, { name: 'reasoning', - type: 'Promise>', + type: 'Promise>', description: 'The full reasoning that the model has generated in the last step. Automatically consumes the stream.', properties: [ { - type: 'ReasoningPart', + type: 'ReasoningOutput', parameters: [ { name: 'type', type: "'reasoning'", - description: 'The type of the reasoning part.', + description: 'The type of the message part.', }, { name: 'text', type: 'string', description: 'The reasoning text.', }, + { + name: 'providerMetadata', + type: 'SharedV2ProviderMetadata', + isOptional: true, + description: 'Additional provider metadata for the source.', + }, ], }, ], diff --git a/packages/ai/src/generate-text/content-part.ts b/packages/ai/src/generate-text/content-part.ts index 81509a200dc7..e1cfb5d14290 100644 --- a/packages/ai/src/generate-text/content-part.ts +++ b/packages/ai/src/generate-text/content-part.ts @@ -1,6 +1,7 @@ import { ProviderMetadata } from '../types'; import { Source } from '../types/language-model'; import { GeneratedFile } from './generated-file'; +import { ReasoningOutput } from './reasoning-output'; import { TypedToolCall } from './tool-call'; import { TypedToolError } from './tool-error'; import { TypedToolResult } from './tool-result'; @@ -8,7 +9,7 @@ import { ToolSet } from './tool-set'; export type ContentPart = | { type: 'text'; text: string; providerMetadata?: ProviderMetadata } - | { type: 'reasoning'; text: string; providerMetadata?: ProviderMetadata } + | ReasoningOutput | ({ type: 'source' } & Source) | { type: 'file'; file: GeneratedFile; providerMetadata?: ProviderMetadata } // different because of GeneratedFile object | ({ type: 'tool-call' } & TypedToolCall & { diff --git a/packages/ai/src/generate-text/generate-text-result.ts b/packages/ai/src/generate-text/generate-text-result.ts index c9bac1a6c4ff..61ef021bf50f 100644 --- a/packages/ai/src/generate-text/generate-text-result.ts +++ b/packages/ai/src/generate-text/generate-text-result.ts @@ -1,4 +1,3 @@ -import { ReasoningPart } from '@ai-sdk/provider-utils'; import { CallWarning, FinishReason, ProviderMetadata } from '../types'; import { Source } from '../types/language-model'; import { LanguageModelRequestMetadata } from '../types/language-model-request-metadata'; @@ -6,6 +5,7 @@ import { LanguageModelResponseMetadata } from '../types/language-model-response- import { LanguageModelUsage } from '../types/usage'; import { ContentPart } from './content-part'; import { GeneratedFile } from './generated-file'; +import { ReasoningOutput } from './reasoning-output'; import { ResponseMessage } from './response-message'; import { StepResult } from './step-result'; import { DynamicToolCall, StaticToolCall, TypedToolCall } from './tool-call'; @@ -34,7 +34,7 @@ The text that was generated in the last step. /** The full reasoning that the model has generated in the last step. */ - readonly reasoning: Array; + readonly reasoning: Array; /** The reasoning text that the model has generated in the last step. Can be undefined if the model diff --git a/packages/ai/src/generate-text/index.ts b/packages/ai/src/generate-text/index.ts index 5f36dd698cd2..ba890f16d76d 100644 --- a/packages/ai/src/generate-text/index.ts +++ b/packages/ai/src/generate-text/index.ts @@ -7,6 +7,7 @@ export type { } from './generated-file'; export * as Output from './output'; export type { PrepareStepFunction, PrepareStepResult } from './prepare-step'; +export type { ReasoningOutput } from './reasoning-output'; export { smoothStream, type ChunkDetector } from './smooth-stream'; export type { StepResult } from './step-result'; export { hasToolCall, stepCountIs, type StopCondition } from './stop-condition'; diff --git a/packages/ai/src/generate-text/reasoning-output.ts b/packages/ai/src/generate-text/reasoning-output.ts new file mode 100644 index 000000000000..85c03103bc34 --- /dev/null +++ b/packages/ai/src/generate-text/reasoning-output.ts @@ -0,0 +1,20 @@ +import { ProviderMetadata } from '../types/provider-metadata'; + +/** + * Reasoning output of a text generation. It contains a reasoning. + */ +export interface ReasoningOutput { + type: 'reasoning'; + + /** + * The reasoning text. + */ + text: string; + + /** + * Additional provider-specific metadata. They are passed through + * to the provider from the AI SDK and enable provider-specific + * functionality that can be fully encapsulated in the provider. + */ + providerMetadata?: ProviderMetadata; +} diff --git a/packages/ai/src/generate-text/stream-text-result.ts b/packages/ai/src/generate-text/stream-text-result.ts index 6080a9e42510..236d0e5cb422 100644 --- a/packages/ai/src/generate-text/stream-text-result.ts +++ b/packages/ai/src/generate-text/stream-text-result.ts @@ -1,10 +1,5 @@ -import { IdGenerator, ReasoningPart } from '@ai-sdk/provider-utils'; +import { IdGenerator } from '@ai-sdk/provider-utils'; import { ServerResponse } from 'node:http'; -import { InferUIMessageChunk } from '../ui-message-stream/ui-message-chunks'; -import { UIMessageStreamResponseInit } from '../ui-message-stream/ui-message-stream-response-init'; -import { InferUIMessageMetadata, UIMessage } from '../ui/ui-messages'; -import { AsyncIterableStream } from '../util/async-iterable-stream'; -import { ErrorHandler } from '../util/error-handler'; import { CallWarning, FinishReason, @@ -14,9 +9,15 @@ import { import { Source } from '../types/language-model'; import { LanguageModelResponseMetadata } from '../types/language-model-response-metadata'; import { LanguageModelUsage } from '../types/usage'; +import { InferUIMessageChunk } from '../ui-message-stream/ui-message-chunks'; import { UIMessageStreamOnFinishCallback } from '../ui-message-stream/ui-message-stream-on-finish-callback'; +import { UIMessageStreamResponseInit } from '../ui-message-stream/ui-message-stream-response-init'; +import { InferUIMessageMetadata, UIMessage } from '../ui/ui-messages'; +import { AsyncIterableStream } from '../util/async-iterable-stream'; +import { ErrorHandler } from '../util/error-handler'; import { ContentPart } from './content-part'; import { GeneratedFile } from './generated-file'; +import { ReasoningOutput } from './reasoning-output'; import { ResponseMessage } from './response-message'; import { StepResult } from './step-result'; import { DynamicToolCall, StaticToolCall, TypedToolCall } from './tool-call'; @@ -117,7 +118,7 @@ The full reasoning that the model has generated. Automatically consumes the stream. */ - readonly reasoning: Promise>; + readonly reasoning: Promise>; /** The reasoning that has been generated by the last step. From e676acdf0e83717308c43f21405edb68508175df Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 15:58:45 -0700 Subject: [PATCH 011/121] Version Packages (#8594) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## ai@5.0.41 ### Patch Changes - cd91e4b: fix(ai): use correct type for reasoning outputs ## @ai-sdk/angular@1.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 ## @ai-sdk/langchain@1.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 ## @ai-sdk/llamaindex@1.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 ## @ai-sdk/react@2.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 ## @ai-sdk/rsc@1.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 ## @ai-sdk/svelte@3.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 ## @ai-sdk/vue@2.0.41 ### Patch Changes - Updated dependencies [cd91e4b] - ai@5.0.41 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/tricky-penguins-carry.md | 5 ----- packages/ai/CHANGELOG.md | 6 ++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 7 +++++++ packages/angular/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 7 +++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 7 +++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 7 +++++++ packages/vue/package.json | 2 +- 18 files changed, 70 insertions(+), 13 deletions(-) delete mode 100644 .changeset/tricky-penguins-carry.md diff --git a/.changeset/tricky-penguins-carry.md b/.changeset/tricky-penguins-carry.md deleted file mode 100644 index 4d2f379167c6..000000000000 --- a/.changeset/tricky-penguins-carry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix(ai): use correct type for reasoning outputs diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 7803f81ba64b..af77d98a611f 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 5.0.41 + +### Patch Changes + +- cd91e4b: fix(ai): use correct type for reasoning outputs + ## 5.0.40 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 91a558d2494a..94cdf7ce6699 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.40", + "version": "5.0.41", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index dc9e46fc77a8..6d6f0e3885f8 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/angular +## 1.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 1.0.40 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 99d364bfc89d..5a48a707852a 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.40", + "version": "1.0.41", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 98030e2fbdaf..a7b25c7026c5 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 1.0.40 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 1fa876d1ed60..653d425fc518 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.40", + "version": "1.0.41", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index cff40ff31fbf..3bfbc5cce55e 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 1.0.40 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index ce5242ef62af..cacb83b2e32f 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.40", + "version": "1.0.41", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 9ae6d1f0771b..5762d6fba9f0 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/react +## 2.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 2.0.40 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 3b5868a2660b..e724ebb1e8fa 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.40", + "version": "2.0.41", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index bb597dc9818d..28bea36fed13 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/rsc +## 1.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 1.0.40 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 6aae7ce82fd2..f92b8fefee47 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.40", + "version": "1.0.41", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 15b0e730f435..8342a8fbd8b4 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [cd91e4b] + - ai@5.0.41 + +## 0.0.1 + +### Patch Changes + - ai@5.0.40 ## 0.0.1 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 746c6cdb4e0a..0dda004b7234 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/svelte +## 3.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 3.0.40 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index cd581d43df9c..668a20cc8fa5 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.40", + "version": "3.0.41", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 9165c037d677..4f6d2176a59a 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 2.0.41 + +### Patch Changes + +- Updated dependencies [cd91e4b] + - ai@5.0.41 + ## 2.0.40 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index b20badd6141b..7a49765e7dad 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.40", + "version": "2.0.41", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 22ef25dcf0cb8dbf24a4fc9ffd83911509942695 Mon Sep 17 00:00:00 2001 From: Tristan Sinclair <67209026+tristansinclair@users.noreply.github.com> Date: Thu, 11 Sep 2025 16:28:16 -0700 Subject: [PATCH 012/121] docs: correct broken langchain-stream link to langchain-adapter (#8576) ## Summary - Fixed broken documentation link from `/docs/reference/stream-helpers/langchain-stream` to `/docs/reference/stream-helpers/langchain-adapter` - The actual documentation file is `16-langchain-adapter.mdx`, not `langchain-stream` ## Details The link in the stream helpers index page was pointing to a non-existent path. This PR corrects it to match the actual file name and working URL path. ### Changes - Updated `content/docs/07-reference/04-stream-helpers/index.mdx` line 82 - Changed `href: '/docs/reference/stream-helpers/langchain-stream'` to `href: '/docs/reference/stream-helpers/langchain-adapter'` ### Verification - Broken link: https://ai-sdk.dev/docs/reference/stream-helpers/langchain-stream (404) - Working link: https://ai-sdk.dev/docs/reference/stream-helpers/langchain-adapter (exists) --- content/docs/07-reference/04-stream-helpers/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/07-reference/04-stream-helpers/index.mdx b/content/docs/07-reference/04-stream-helpers/index.mdx index 63b303303061..74b9f027c85d 100644 --- a/content/docs/07-reference/04-stream-helpers/index.mdx +++ b/content/docs/07-reference/04-stream-helpers/index.mdx @@ -79,7 +79,7 @@ collapsed: true title: 'LangChainStream', description: "Transforms the response from LangChain's language models into a readable stream.", - href: '/docs/reference/stream-helpers/langchain-stream', + href: '/docs/reference/stream-helpers/langchain-adapter', }, { title: 'MistralStream', From 56224dba7be3cc61e0ada8f4887ba881d3aa07c0 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Fri, 12 Sep 2025 09:48:15 +0100 Subject: [PATCH 013/121] docs: update zod typescript issue troubleshooting with new version (#8600) [New version of zod solves zod issues.](https://x.com/colinhacks/status/1966261915115782654). Updated troubleshooting. --- .../26-migration-guide-5-0.mdx | 19 +++++++---- .../12-typescript-performance-zod.mdx | 32 ++++++++----------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/content/docs/08-migration-guides/26-migration-guide-5-0.mdx b/content/docs/08-migration-guides/26-migration-guide-5-0.mdx index aec3ec99ebaf..6ad413016365 100644 --- a/content/docs/08-migration-guides/26-migration-guide-5-0.mdx +++ b/content/docs/08-migration-guides/26-migration-guide-5-0.mdx @@ -26,19 +26,20 @@ You need to update the following packages to the following versions in your `pac Additionally, you need to update the following peer dependencies: -- `zod` package: `3.25.0` or later +- `zod` package: `4.1.8` or later (recommended to avoid TypeScript performance issues) An example upgrade command would be: ``` -npm install ai @ai-sdk/react @ai-sdk/openai zod@3.25.0 +npm install ai @ai-sdk/react @ai-sdk/openai zod@^4.1.8 ``` - If you encounter TypeScript performance issues after upgrading, update your - `tsconfig.json` to use `moduleResolution: "nodenext"`. See the [TypeScript - performance troubleshooting - guide](/docs/troubleshooting/typescript-performance-zod) for more details. + If you encounter TypeScript performance issues after upgrading, ensure you're + using Zod 4.1.8 or later. If the issue persists, update your `tsconfig.json` + to use `moduleResolution: "nodenext"`. See the [TypeScript performance + troubleshooting guide](/docs/troubleshooting/typescript-performance-zod) for + more details. ## Codemods @@ -3101,7 +3102,11 @@ import { ### TypeScript Performance Issues with Zod -If you experience TypeScript server crashes, slow type checking, or errors like "Type instantiation is excessively deep and possibly infinite" when using Zod with AI SDK 5.0, update your `tsconfig.json` to use `moduleResolution: "nodenext"`: +If you experience TypeScript server crashes, slow type checking, or errors like "Type instantiation is excessively deep and possibly infinite" when using Zod with AI SDK 5.0: + +1. **First, ensure you're using Zod 4.1.8 or later** - this version includes a fix for module resolution issues that cause TypeScript performance problems. + +2. If the issue persists, update your `tsconfig.json` to use `moduleResolution: "nodenext"`: ```json { diff --git a/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx b/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx index 70c098132d32..6cbc3fc027e2 100644 --- a/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx +++ b/content/docs/09-troubleshooting/12-typescript-performance-zod.mdx @@ -20,9 +20,19 @@ The AI SDK 5 has specific compatibility requirements with Zod versions. When imp ## Solution -### Update TypeScript Configuration +### Upgrade Zod to 4.1.8 or Later -The recommended solution is to update your `tsconfig.json` to use `moduleResolution: "nodenext"`: +The primary solution is to upgrade to Zod version 4.1.8 or later, which includes a fix for this module resolution issue: + +```bash +pnpm add zod@^4.1.8 +``` + +This version resolves the underlying problem where different module resolution settings were causing TypeScript to load the same Zod declarations twice, leading to expensive structural comparisons. + +### Alternative: Update TypeScript Configuration + +If upgrading Zod isn't possible, you can update your `tsconfig.json` to use `moduleResolution: "nodenext"`: ```json { @@ -33,20 +43,4 @@ The recommended solution is to update your `tsconfig.json` to use `moduleResolut } ``` -This resolves the TypeScript performance issues while allowing you to continue using the standard Zod import: - -```typescript -import { z } from 'zod'; // Works correctly with nodenext module resolution -``` - -### Alternative: Use the Zod Version-Specific Import Path - -If the above solution doesn't resolve the issue, you can try importing Zod using a version-specific import path: - -```typescript -// ❌ Potentially problematic: Standard import may cause TypeScript issues -import { z } from 'zod'; - -// ✅ Alternative: version-specific import that may help with compatibility -import { z } from 'zod/v4'; -``` +This resolves the TypeScript performance issues while allowing you to continue using the standard Zod import. From 4235eb37e8cae25a83e51aace2f92acbcb277173 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Fri, 12 Sep 2025 12:54:34 +0200 Subject: [PATCH 014/121] feat(provider/openai): code interpreter tool calls and results (#8556) ## Background The [OpenAI code interpreter tool](https://platform.openai.com/docs/guides/tools-code-interpreter) does not add tool call / tool results. ## Summary * add input and output schema to code interpreter tool * send tool call and tool result for code interpreter tool * add `code_interpreter_call.outputs` include when code interpreter tool is present ## Manual Verification - [x] run `examples/ai-core/src/generate-text/openai-code-interpreter-tool.ts` - [x] run `examples/ai-core/src/stream-text/openai-code-interpreter-tool.ts` - [x] run UI example ## Tasks - [x] specify tool result type - [x] add doGenerate functionality - [x] automatically set include for code interpreter outputs - [x] test include in request body - [x] update generate tests for code interpreter tool (updated / extracted fixture) - [x] container_id support - [x] add doStream functionality - [x] update stream tests for code interpreter tool (updated / extracted fixture) - [x] add ui example - [x] review and update documentation - [x] add changeset ## Future Work * preliminary output support for provider-defined tools * code interpreter code input streaming and earlier tool call * send code interpreter outputs back to openai api ## Related Issues Follow up from #7952 and #8505 --- .changeset/unlucky-clouds-agree.md | 5 + .../openai-code-interpreter-tool.ts | 2 +- examples/ai-core/src/lib/save-raw-chunks.ts | 2 +- .../openai-code-interpreter-tool.ts | 14 +- .../api/chat-openai-code-interpreter/route.ts | 33 + .../app/test-openai-code-interpreter/page.tsx | 38 + .../openai-code-interpreter-view.tsx | 52 + .../openai-code-interpreter-tool.1.chunks.txt | 393 +++++ .../openai-code-interpreter-tool.1.json | 112 ++ .../openai-web-search-tool.chunks.txt | 0 ...enai-responses-language-model.test.ts.snap | 1365 +++++++++++++++++ .../openai-responses-language-model.test.ts | 300 ++-- .../openai-responses-language-model.ts | 86 +- packages/openai/src/tool/code-interpreter.ts | 88 +- 14 files changed, 2246 insertions(+), 244 deletions(-) create mode 100644 .changeset/unlucky-clouds-agree.md create mode 100644 examples/next-openai/app/api/chat-openai-code-interpreter/route.ts create mode 100644 examples/next-openai/app/test-openai-code-interpreter/page.tsx create mode 100644 examples/next-openai/component/openai-code-interpreter-view.tsx create mode 100644 packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.chunks.txt create mode 100644 packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.json rename packages/openai/src/responses/{test-fixtures => __fixtures__}/openai-web-search-tool.chunks.txt (100%) create mode 100644 packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap diff --git a/.changeset/unlucky-clouds-agree.md b/.changeset/unlucky-clouds-agree.md new file mode 100644 index 000000000000..58788d2cf3a4 --- /dev/null +++ b/.changeset/unlucky-clouds-agree.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +feat(provider/openai): code interpreter tool calls and results diff --git a/examples/ai-core/src/generate-text/openai-code-interpreter-tool.ts b/examples/ai-core/src/generate-text/openai-code-interpreter-tool.ts index 096e111c1d8d..6c42f782eaca 100644 --- a/examples/ai-core/src/generate-text/openai-code-interpreter-tool.ts +++ b/examples/ai-core/src/generate-text/openai-code-interpreter-tool.ts @@ -12,5 +12,5 @@ run(async () => { 'Simulate rolling two dice 10000 times and and return the sum all the results.', }); - console.log(result.text); + console.dir(result.content, { depth: Infinity }); }); diff --git a/examples/ai-core/src/lib/save-raw-chunks.ts b/examples/ai-core/src/lib/save-raw-chunks.ts index 520454692c5b..2bb0a0f8662f 100644 --- a/examples/ai-core/src/lib/save-raw-chunks.ts +++ b/examples/ai-core/src/lib/save-raw-chunks.ts @@ -16,7 +16,7 @@ export async function saveRawChunks({ } fs.writeFileSync( - filename, + `output/${filename}.chunks.txt`, rawChunks.map(chunk => JSON.stringify(chunk)).join('\n'), ); } diff --git a/examples/ai-core/src/stream-text/openai-code-interpreter-tool.ts b/examples/ai-core/src/stream-text/openai-code-interpreter-tool.ts index bad0a0d73af3..8c664a4bc266 100644 --- a/examples/ai-core/src/stream-text/openai-code-interpreter-tool.ts +++ b/examples/ai-core/src/stream-text/openai-code-interpreter-tool.ts @@ -1,8 +1,8 @@ import { openai } from '@ai-sdk/openai'; import { streamText } from 'ai'; -import 'dotenv/config'; +import { run } from '../lib/run'; -async function main() { +run(async () => { const result = streamText({ model: openai.responses('gpt-5-nano'), tools: { @@ -10,16 +10,10 @@ async function main() { }, prompt: 'Simulate rolling two dice 10000 times and and return the sum all the results.', - // includeRawChunks: true, }); for await (const chunk of result.fullStream) { switch (chunk.type) { - case 'raw': { - console.log('Raw chunk:', JSON.stringify(chunk.rawValue)); - break; - } - case 'text-delta': { process.stdout.write(chunk.text); break; @@ -40,6 +34,4 @@ async function main() { break; } } -} - -main().catch(console.error); +}); diff --git a/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts b/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts new file mode 100644 index 000000000000..58b3040033ed --- /dev/null +++ b/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts @@ -0,0 +1,33 @@ +import { openai } from '@ai-sdk/openai'; +import { + convertToModelMessages, + InferUITools, + streamText, + ToolSet, + UIDataTypes, + UIMessage, + validateUIMessages, +} from 'ai'; + +const tools = { + code_interpreter: openai.tools.codeInterpreter(), +} satisfies ToolSet; + +export type OpenAICodeInterpreterMessage = UIMessage< + never, + UIDataTypes, + InferUITools +>; + +export async function POST(req: Request) { + const { messages } = await req.json(); + const uiMessages = await validateUIMessages({ messages }); + + const result = streamText({ + model: openai.responses('gpt-5-nano'), + tools, + messages: convertToModelMessages(uiMessages), + }); + + return result.toUIMessageStreamResponse(); +} diff --git a/examples/next-openai/app/test-openai-code-interpreter/page.tsx b/examples/next-openai/app/test-openai-code-interpreter/page.tsx new file mode 100644 index 000000000000..00bc1ee84819 --- /dev/null +++ b/examples/next-openai/app/test-openai-code-interpreter/page.tsx @@ -0,0 +1,38 @@ +'use client'; + +import { useChat } from '@ai-sdk/react'; +import { DefaultChatTransport } from 'ai'; +import ChatInput from '@/component/chat-input'; +import { OpenAICodeInterpreterMessage } from '@/app/api/chat-openai-code-interpreter/route'; +import CodeInterpreterView from '@/component/openai-code-interpreter-view'; + +export default function TestOpenAIWebSearch() { + const { status, sendMessage, messages } = + useChat({ + transport: new DefaultChatTransport({ + api: '/api/chat-openai-code-interpreter', + }), + }); + + return ( +
+

OpenAI Code Interpreter Test

+ + {messages.map(message => ( +
+ {message.role === 'user' ? 'User: ' : 'AI: '} + {message.parts.map((part, index) => { + switch (part.type) { + case 'text': + return
{part.text}
; + case 'tool-code_interpreter': + return ; + } + })} +
+ ))} + + sendMessage({ text })} /> +
+ ); +} diff --git a/examples/next-openai/component/openai-code-interpreter-view.tsx b/examples/next-openai/component/openai-code-interpreter-view.tsx new file mode 100644 index 000000000000..6289f5e3a639 --- /dev/null +++ b/examples/next-openai/component/openai-code-interpreter-view.tsx @@ -0,0 +1,52 @@ +import { openai } from '@ai-sdk/openai'; +import { UIToolInvocation } from 'ai'; + +export default function CodeInterpreterView({ + invocation, +}: { + invocation: UIToolInvocation>; +}) { + switch (invocation.state) { + case 'output-available': + return ( +
+
+
+ {invocation.input.containerId} +
+
+ +
+
+
+ Code: +
+
+                {invocation.input.code}
+              
+
+ +
+
+ Output: +
+
+ {invocation.output.outputs?.map((output, index) => ( +
+ {output.type === 'logs' && ( +
+ + {output.logs} + +
+ )} + {output.type === 'image' && } +
+ ))} +
+
+
+
+ ); + } +} diff --git a/packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.chunks.txt b/packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.chunks.txt new file mode 100644 index 000000000000..526e654d1d84 --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.chunks.txt @@ -0,0 +1,393 @@ +{"type":"response.created","sequence_number":0,"response":{"id":"resp_68c2e6efa238819383d5f52a2c2a3baa02d3a5742c7ddae9","object":"response","created_at":1757603567,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-nano-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"code_interpreter","container":{"type":"auto"}}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_68c2e6efa238819383d5f52a2c2a3baa02d3a5742c7ddae9","object":"response","created_at":1757603567,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-nano-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"code_interpreter","container":{"type":"auto"}}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","type":"code_interpreter_call","status":"in_progress","code":"","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[]}} +{"type":"response.code_interpreter_call.in_progress","sequence_number":5,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":6,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"import","obfuscation":"OIvaVX38kd"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":7,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" random","obfuscation":"BehxQZQ2d"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":8,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":",","obfuscation":"9CZBTAhqNL39rvm"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":9,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" math","obfuscation":"gJGstQCbmBz"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":10,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"\n","obfuscation":"NDJnE8FanAc30He"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":11,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"N","obfuscation":"EzKVUcA2jjv2vlZ"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":12,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"=","obfuscation":"7ZY0446GwpTQvtm"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":13,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"100","obfuscation":"NsI6sDvcnIzse"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":14,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"00","obfuscation":"9X1Ho4jfEV0RS9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":15,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"\n","obfuscation":"H8Y1P6g9UEtJwk2"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":16,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"s","obfuscation":"9QCH6CJ1iI6n2qX"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":17,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"ums","obfuscation":"TUy2OEScLJqyu"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":18,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"=[]\n","obfuscation":"mY5A7Xd6WQaB"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":19,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"s","obfuscation":"jd0bnnJ6KLIOb0Z"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":20,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"=","obfuscation":"QxbN5tWnCnhiujx"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":21,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"0","obfuscation":"ybsZK3KxG5hAA62"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":22,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"\n","obfuscation":"pGerylB9mkV7M9y"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":23,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"for","obfuscation":"bugXXbayxnyEn"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":24,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" _","obfuscation":"swCViNFMEreQOE"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":25,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" in","obfuscation":"aOzFRkHvGQaOf"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":26,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" range","obfuscation":"rOq4cK4Xkb"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":27,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(N","obfuscation":"kQC1XGCTtAyXut"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":28,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"):\n","obfuscation":"UBYG2mZnN0Kn6"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":29,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" ","obfuscation":"cwVPkTduQyDRH"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":30,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" a","obfuscation":"jkL2ggSaHCoQZE"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":31,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"=random","obfuscation":"CeILD3TgG"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":32,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":".randint","obfuscation":"H6ej8bzj"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":33,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(","obfuscation":"A6wLj2RbRElPaYh"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":34,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"1","obfuscation":"20oH9KzqbEgwf2E"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":35,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":",","obfuscation":"VQovrtpRVURakU4"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":36,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"6","obfuscation":"OaLX7hoG9MVNB78"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":37,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":")\n","obfuscation":"b5t7NMWofCIeb4"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":38,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" ","obfuscation":"mUnVcQCuBKrRb"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":39,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" b","obfuscation":"ou8Xxmmv5u59HZ"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":40,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"=random","obfuscation":"IkxH8gSk3"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":41,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":".randint","obfuscation":"ZFMdoKnr"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":42,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(","obfuscation":"matJkyirCs8fEkT"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":43,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"1","obfuscation":"6392sm7p643sNwQ"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":44,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":",","obfuscation":"CylXXp45gG2YpfU"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":45,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"6","obfuscation":"jR4lmAu43NGVN5w"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":46,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":")\n","obfuscation":"d551m56KVrZvkP"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":47,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" ","obfuscation":"E4jdWpuII0V6Q"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":48,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" sm","obfuscation":"9PCqkf9B9HQ03"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":49,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"=a","obfuscation":"VX03wzsXAo9Gj8"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":50,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"+b","obfuscation":"aQz4e6tOKSv5Xv"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":51,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"\n","obfuscation":"MgxWQt0jjfjoh40"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":52,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" ","obfuscation":"AxB3ZJpztCNHO"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":53,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" sums","obfuscation":"ZT4QjPPzgfa"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":54,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":".append","obfuscation":"jIgGSr7nx"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":55,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(sm","obfuscation":"6lOALP9UAcwli"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":56,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":")\n","obfuscation":"FDmptnYJsF06tf"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":57,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" ","obfuscation":"VTrrsRPIFwGLr"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":58,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" s","obfuscation":"C7Ld7ZOT0NIfH4"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":59,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"+=","obfuscation":"h0QkRsiSMS3ST5"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":60,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"sm","obfuscation":"w67YRJSYiImgMw"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":61,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"\n","obfuscation":"nyadeNRxjzKhah9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":62,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"min","obfuscation":"L1FOw2uMN41wr"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":63,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(s","obfuscation":"x9G1pMe4HPtWRc"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":64,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"ums","obfuscation":"bRhDo2uoDbzDU"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":65,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"),","obfuscation":"7ir1OOQ8PRXepf"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":66,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" max","obfuscation":"MY4uXjzfiJYC"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":67,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(s","obfuscation":"KUMVY4a2EuTlUB"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":68,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"ums","obfuscation":"HabMLvTvv9Xpb"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":69,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"),","obfuscation":"k5Z4QViGpCalFV"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":70,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" sum","obfuscation":"gHPfwElMRQ7X"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":71,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(s","obfuscation":"OQqKGcI6yD3hCv"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":72,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"ums","obfuscation":"eleO2Cy8G36IN"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":73,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"),","obfuscation":"KH87OaX6qL9EoE"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":74,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":" sum","obfuscation":"6jtxAwH8MlID"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":75,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"(s","obfuscation":"BQMUi7ayzyAobI"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":76,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"ums","obfuscation":"jfYB6TdANxirQ"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":77,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":")/","obfuscation":"82XAQdKQv3ocdA"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":78,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"N","obfuscation":"1BmZgJs1MxSt7BP"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":79,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","delta":"\n","obfuscation":"paA5Kh4ppB56TM7"} +{"type":"response.code_interpreter_call_code.done","sequence_number":80,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","code":"import random, math\nN=10000\nsums=[]\ns=0\nfor _ in range(N):\n a=random.randint(1,6)\n b=random.randint(1,6)\n sm=a+b\n sums.append(sm)\n s+=sm\nmin(sums), max(sums), sum(sums), sum(sums)/N\n"} +{"type":"response.code_interpreter_call.interpreting","sequence_number":81,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9"} +{"type":"response.code_interpreter_call.completed","sequence_number":82,"output_index":1,"item_id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9"} +{"type":"response.output_item.done","sequence_number":83,"output_index":1,"item":{"id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","type":"code_interpreter_call","status":"completed","code":"import random, math\nN=10000\nsums=[]\ns=0\nfor _ in range(N):\n a=random.randint(1,6)\n b=random.randint(1,6)\n sm=a+b\n sums.append(sm)\n s+=sm\nmin(sums), max(sums), sum(sums), sum(sums)/N\n","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[{"type":"logs","logs":"(2, 12, 69868, 6.9868)"}]}} +{"type":"response.output_item.added","sequence_number":84,"output_index":2,"item":{"id":"rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":85,"output_index":2,"item":{"id":"rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":86,"output_index":3,"item":{"id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","type":"code_interpreter_call","status":"in_progress","code":"","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[]}} +{"type":"response.code_interpreter_call.in_progress","sequence_number":87,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":88,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"import","obfuscation":"Q5Vt5nbYav"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":89,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" csv","obfuscation":"kWZINj0xnmCN"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":90,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":",","obfuscation":"yuD5SWIiH0mZy9p"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":91,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" pathlib","obfuscation":"LVw3IcA3"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":92,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"\n","obfuscation":"Nr92hIGSaSrOCop"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":93,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"path","obfuscation":"tYmBas4T1VlZ"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":94,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" =","obfuscation":"Y4MuYj1jZHCwlU"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":95,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" pathlib","obfuscation":"zmW7YzNY"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":96,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":".Path","obfuscation":"YW0SRfsvBPX"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":97,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"('/","obfuscation":"cDwpVqOjfQdMz"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":98,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"mnt","obfuscation":"vzMBtn7n4vmqu"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":99,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"/data","obfuscation":"BDpBczqzb03"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":100,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"/","obfuscation":"iMOcC2sfCeqvPWt"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":101,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"roll","obfuscation":"e06sua0vHSZI"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":102,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"2","obfuscation":"EkQb6y3vxcY8akF"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":103,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"dice","obfuscation":"rIrGtWmbqnaL"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":104,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"_s","obfuscation":"5V89xn1ccGFLCX"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":105,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"ums","obfuscation":"dJtfaB4Z1mjbp"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":106,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"_","obfuscation":"2JOwD91dVMndxUt"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":107,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"100","obfuscation":"gYu9oFkUcX2U0"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":108,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"00","obfuscation":"LSMwodFP8vB6Vk"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":109,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":".csv","obfuscation":"lBH2cU2HiAJl"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":110,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"')\n","obfuscation":"VLuOi5ItXC12s"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":111,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"with","obfuscation":"HGPo22WbgQQx"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":112,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" open","obfuscation":"Y63mv40IMcX"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":113,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"(path","obfuscation":"99cn0n4KKeC"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":114,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":",","obfuscation":"GrmejhFdMKkcnfo"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":115,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" '","obfuscation":"az3yVeZK1rhy3s"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":116,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"w","obfuscation":"uu8LMJNvzUSz9U9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":117,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"',","obfuscation":"AiYFdBpnV7hzDd"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":118,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" newline","obfuscation":"O3nB1Q3L"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":119,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"='","obfuscation":"yFJ3FwOeIEShoN"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":120,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"')","obfuscation":"ZoSctx5RbMFuvv"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":121,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" as","obfuscation":"YxkRPQDKS0rcn"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":122,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" f","obfuscation":"0X8tGkLUnAsHHq"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":123,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":":\n","obfuscation":"2ZiXc6z84Fx7n2"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":124,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" ","obfuscation":"XL7r4TwA1JNmn"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":125,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" writer","obfuscation":"wam8ZK8pj"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":126,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" =","obfuscation":"fURGlZd9iB14Ta"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":127,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" csv","obfuscation":"DFciDuEyx2iM"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":128,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":".writer","obfuscation":"oHAcHpp7k"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":129,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"(f","obfuscation":"c7FyIJS5Tz6UyO"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":130,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":")\n","obfuscation":"d2bqVnyYwlHKC7"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":131,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" ","obfuscation":"RVJgqZtsODA6K"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":132,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" writer","obfuscation":"FIDF831k1"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":133,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":".writerow","obfuscation":"Lcn10d9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":134,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"(['","obfuscation":"RxqMcQOqjouZ8"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":135,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"sum","obfuscation":"3ltJUghFzhYrR"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":136,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"'])\n","obfuscation":"qdEyqJq5J6Ju"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":137,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" ","obfuscation":"kqIZFGi458Szj"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":138,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" for","obfuscation":"qvWBlahiKoTK"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":139,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" val","obfuscation":"QMq3J5caChq3"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":140,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" in","obfuscation":"v2nA64jkmmBeN"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":141,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" sums","obfuscation":"Q5iqkWm1jol"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":142,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":":\n","obfuscation":"CK3ULGAJcvFAJe"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":143,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" ","obfuscation":"GMvgyT2Rv"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":144,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" writer","obfuscation":"ihT43CIeC"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":145,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":".writerow","obfuscation":"AY0Mmyl"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":146,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"([","obfuscation":"FQGJsMr18gcWuK"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":147,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"val","obfuscation":"TtXREk8S4EdYL"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":148,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"])\n","obfuscation":"uYp4Eex0ELRfK"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":149,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"path","obfuscation":"4dybh126gQHx"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":150,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":",","obfuscation":"t8OFnbdkUrs6Uno"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":151,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" path","obfuscation":"jzkGOtvXcB7"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":152,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":".exists","obfuscation":"OTPZHwIxr"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":153,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"(),","obfuscation":"vR0eajccRRVMX"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":154,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":" len","obfuscation":"EXhzSHusL3cL"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":155,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"(s","obfuscation":"XsAd0nPHtCaIST"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":156,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":"ums","obfuscation":"SlF1CGCVNiTj3"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":157,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","delta":")\n","obfuscation":"rMHq84Q57a55mS"} +{"type":"response.code_interpreter_call_code.done","sequence_number":158,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","code":"import csv, pathlib\npath = pathlib.Path('/mnt/data/roll2dice_sums_10000.csv')\nwith open(path, 'w', newline='') as f:\n writer = csv.writer(f)\n writer.writerow(['sum'])\n for val in sums:\n writer.writerow([val])\npath, path.exists(), len(sums)\n"} +{"type":"response.code_interpreter_call.interpreting","sequence_number":159,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9"} +{"type":"response.code_interpreter_call.completed","sequence_number":160,"output_index":3,"item_id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9"} +{"type":"response.output_item.done","sequence_number":161,"output_index":3,"item":{"id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","type":"code_interpreter_call","status":"completed","code":"import csv, pathlib\npath = pathlib.Path('/mnt/data/roll2dice_sums_10000.csv')\nwith open(path, 'w', newline='') as f:\n writer = csv.writer(f)\n writer.writerow(['sum'])\n for val in sums:\n writer.writerow([val])\npath, path.exists(), len(sums)\n","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[{"type":"logs","logs":"(PosixPath('/mnt/data/roll2dice_sums_10000.csv'), True, 10000)"}]}} +{"type":"response.output_item.added","sequence_number":162,"output_index":4,"item":{"id":"rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":163,"output_index":4,"item":{"id":"rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":164,"output_index":5,"item":{"id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","type":"code_interpreter_call","status":"in_progress","code":"","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[]}} +{"type":"response.code_interpreter_call.in_progress","sequence_number":165,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":166,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","delta":"s","obfuscation":"K7FMMOT7d8kYYva"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":167,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","delta":"ums","obfuscation":"wfKSZgnAloo8W"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":168,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","delta":"[:","obfuscation":"G5XMdLaW2r0wBo"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":169,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","delta":"20","obfuscation":"VnqDLZheFrqn5b"} +{"type":"response.code_interpreter_call_code.delta","sequence_number":170,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","delta":"]\n","obfuscation":"5BBjQbjI1SbB5q"} +{"type":"response.code_interpreter_call_code.done","sequence_number":171,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","code":"sums[:20]\n"} +{"type":"response.code_interpreter_call.interpreting","sequence_number":172,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9"} +{"type":"response.code_interpreter_call.completed","sequence_number":173,"output_index":5,"item_id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9"} +{"type":"response.output_item.done","sequence_number":174,"output_index":5,"item":{"id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","type":"code_interpreter_call","status":"completed","code":"sums[:20]\n","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[{"type":"logs","logs":"[6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7]"}]}} +{"type":"response.output_item.added","sequence_number":175,"output_index":6,"item":{"id":"rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":176,"output_index":6,"item":{"id":"rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":177,"output_index":7,"item":{"id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","type":"message","status":"in_progress","content":[],"role":"assistant"}} +{"type":"response.content_part.added","sequence_number":178,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} +{"type":"response.output_text.delta","sequence_number":179,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"Here","logprobs":[],"obfuscation":"cWtiKXaGjem2"} +{"type":"response.output_text.delta","sequence_number":180,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"’s","logprobs":[],"obfuscation":"tCu4gPjumNTFmD"} +{"type":"response.output_text.delta","sequence_number":181,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"JnPxZem2fRHtAY"} +{"type":"response.output_text.delta","sequence_number":182,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" simulation","logprobs":[],"obfuscation":"wwKNf"} +{"type":"response.output_text.delta","sequence_number":183,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"iaryaBgPsdz34"} +{"type":"response.output_text.delta","sequence_number":184,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" rolling","logprobs":[],"obfuscation":"oyUpOVUY"} +{"type":"response.output_text.delta","sequence_number":185,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" two","logprobs":[],"obfuscation":"uUEDqEO4Zw33"} +{"type":"response.output_text.delta","sequence_number":186,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" fair","logprobs":[],"obfuscation":"0BdgPF0tVha"} +{"type":"response.output_text.delta","sequence_number":187,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" six","logprobs":[],"obfuscation":"RJNXKa4QfiPn"} +{"type":"response.output_text.delta","sequence_number":188,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-sided","logprobs":[],"obfuscation":"J2wIUlUlDK"} +{"type":"response.output_text.delta","sequence_number":189,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" dice","logprobs":[],"obfuscation":"uQ01CzXfntg"} +{"type":"response.output_text.delta","sequence_number":190,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"kaSJw7hDfrziOu0"} +{"type":"response.output_text.delta","sequence_number":191,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"eOVSUlhAVZKn91"} +{"type":"response.output_text.delta","sequence_number":192,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"7N197ClBTCK1JOQ"} +{"type":"response.output_text.delta","sequence_number":193,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"000","logprobs":[],"obfuscation":"VjnhfcA30nIGG"} +{"type":"response.output_text.delta","sequence_number":194,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" times","logprobs":[],"obfuscation":"Z8Q7sWHzsq"} +{"type":"response.output_text.delta","sequence_number":195,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":".","logprobs":[],"obfuscation":"IN62T6mCu6fYl7Z"} +{"type":"response.output_text.delta","sequence_number":196,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Each","logprobs":[],"obfuscation":"2MZMAmlsfNc"} +{"type":"response.output_text.delta","sequence_number":197,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" trial","logprobs":[],"obfuscation":"oizOX5EXr5"} +{"type":"response.output_text.delta","sequence_number":198,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sums","logprobs":[],"obfuscation":"5ObkKIGcTkQ"} +{"type":"response.output_text.delta","sequence_number":199,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"asb6TrkUh1Cm"} +{"type":"response.output_text.delta","sequence_number":200,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" two","logprobs":[],"obfuscation":"DiIKkiBtzYOB"} +{"type":"response.output_text.delta","sequence_number":201,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" dice","logprobs":[],"obfuscation":"dSmCBiYzgkA"} +{"type":"response.output_text.delta","sequence_number":202,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":".\n\n","logprobs":[],"obfuscation":"B4RRfgIWurZhM"} +{"type":"response.output_text.delta","sequence_number":203,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"Results","logprobs":[],"obfuscation":"I8hspPPYn"} +{"type":"response.output_text.delta","sequence_number":204,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"k9ZUdNPKl9MokYL"} +{"type":"response.output_text.delta","sequence_number":205,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"f6MR2xtEU5uYHlp"} +{"type":"response.output_text.delta","sequence_number":206,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Total","logprobs":[],"obfuscation":"3ISIUjGjnU"} +{"type":"response.output_text.delta","sequence_number":207,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sum","logprobs":[],"obfuscation":"ODYO2Simfox4"} +{"type":"response.output_text.delta","sequence_number":208,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"3Y3Ptvu0BqapM"} +{"type":"response.output_text.delta","sequence_number":209,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" all","logprobs":[],"obfuscation":"AszqcOsVr72y"} +{"type":"response.output_text.delta","sequence_number":210,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"Jy7ALXZ6mlpMekP"} +{"type":"response.output_text.delta","sequence_number":211,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"kc4mRtEUhUdtSX"} +{"type":"response.output_text.delta","sequence_number":212,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"cDQGVbxXjI7yLV9"} +{"type":"response.output_text.delta","sequence_number":213,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"000","logprobs":[],"obfuscation":"PQ9Rbi6B1pDGv"} +{"type":"response.output_text.delta","sequence_number":214,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" trials","logprobs":[],"obfuscation":"3Hy0lSObp"} +{"type":"response.output_text.delta","sequence_number":215,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":","logprobs":[],"obfuscation":"gl1nkwnjIeRW0uj"} +{"type":"response.output_text.delta","sequence_number":216,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"MIDLjmmIoCEi9em"} +{"type":"response.output_text.delta","sequence_number":217,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"69","logprobs":[],"obfuscation":"PbzKsAbJaBcHJC"} +{"type":"response.output_text.delta","sequence_number":218,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"vZ7xqtdD8EJTicP"} +{"type":"response.output_text.delta","sequence_number":219,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"868","logprobs":[],"obfuscation":"bJpXgNh7BsJcq"} +{"type":"response.output_text.delta","sequence_number":220,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"JNDFGdujdYg21ES"} +{"type":"response.output_text.delta","sequence_number":221,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"QXSorNvhTzeaXh8"} +{"type":"response.output_text.delta","sequence_number":222,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Average","logprobs":[],"obfuscation":"D0CVJd3J"} +{"type":"response.output_text.delta","sequence_number":223,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sum","logprobs":[],"obfuscation":"k4SZuQjxkPG2"} +{"type":"response.output_text.delta","sequence_number":224,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" per","logprobs":[],"obfuscation":"NNFtPpEGRDaq"} +{"type":"response.output_text.delta","sequence_number":225,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" trial","logprobs":[],"obfuscation":"p1OMEEEgdy"} +{"type":"response.output_text.delta","sequence_number":226,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":","logprobs":[],"obfuscation":"dzqJ1rG9L8JlybS"} +{"type":"response.output_text.delta","sequence_number":227,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"S3pApfeofpkiGR2"} +{"type":"response.output_text.delta","sequence_number":228,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"6","logprobs":[],"obfuscation":"vamf1TIG5wk7vR7"} +{"type":"response.output_text.delta","sequence_number":229,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":".","logprobs":[],"obfuscation":"hi8WfRh2huRV2av"} +{"type":"response.output_text.delta","sequence_number":230,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"986","logprobs":[],"obfuscation":"eQl8O30dpxC1D"} +{"type":"response.output_text.delta","sequence_number":231,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"8","logprobs":[],"obfuscation":"pWiLsTRf53gtR5k"} +{"type":"response.output_text.delta","sequence_number":232,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"iJJ0EbjegjFMJIU"} +{"type":"response.output_text.delta","sequence_number":233,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"N0bGXFvSI8S79P9"} +{"type":"response.output_text.delta","sequence_number":234,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Minimum","logprobs":[],"obfuscation":"Dw0jHUib"} +{"type":"response.output_text.delta","sequence_number":235,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sum","logprobs":[],"obfuscation":"vEVnMQIaSbKv"} +{"type":"response.output_text.delta","sequence_number":236,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" observed","logprobs":[],"obfuscation":"NtvpKxj"} +{"type":"response.output_text.delta","sequence_number":237,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":","logprobs":[],"obfuscation":"aCDwp3IWLjpZYXN"} +{"type":"response.output_text.delta","sequence_number":238,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"LMKMpUEYzeSLVzM"} +{"type":"response.output_text.delta","sequence_number":239,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"ClYZjsEoHgeyyx5"} +{"type":"response.output_text.delta","sequence_number":240,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"eWgBfrp3etb1PXW"} +{"type":"response.output_text.delta","sequence_number":241,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"quVcOZuR0EQJRLU"} +{"type":"response.output_text.delta","sequence_number":242,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Maximum","logprobs":[],"obfuscation":"MSYZTyax"} +{"type":"response.output_text.delta","sequence_number":243,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sum","logprobs":[],"obfuscation":"skeWftDXCy0f"} +{"type":"response.output_text.delta","sequence_number":244,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" observed","logprobs":[],"obfuscation":"Es7GIxV"} +{"type":"response.output_text.delta","sequence_number":245,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":","logprobs":[],"obfuscation":"L1yobSjDDHdJj2Q"} +{"type":"response.output_text.delta","sequence_number":246,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"rKximwRLUxT1oE8"} +{"type":"response.output_text.delta","sequence_number":247,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"12","logprobs":[],"obfuscation":"vxCOZriMlGIBr5"} +{"type":"response.output_text.delta","sequence_number":248,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"93iYynmGyvaDROv"} +{"type":"response.output_text.delta","sequence_number":249,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"vYWCVytchr887ft"} +{"type":"response.output_text.delta","sequence_number":250,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Sample","logprobs":[],"obfuscation":"oTY4DvhLU"} +{"type":"response.output_text.delta","sequence_number":251,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"uab8JVOfMHCBy"} +{"type":"response.output_text.delta","sequence_number":252,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"Px636omVZ9eT"} +{"type":"response.output_text.delta","sequence_number":253,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" first","logprobs":[],"obfuscation":"8kXFpfluR6"} +{"type":"response.output_text.delta","sequence_number":254,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"2P4bZfiZns17SjY"} +{"type":"response.output_text.delta","sequence_number":255,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"20","logprobs":[],"obfuscation":"juXtPm1WNuxXsu"} +{"type":"response.output_text.delta","sequence_number":256,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" trial","logprobs":[],"obfuscation":"s3rXjHd8HT"} +{"type":"response.output_text.delta","sequence_number":257,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sums","logprobs":[],"obfuscation":"Z8LVrQHamR5"} +{"type":"response.output_text.delta","sequence_number":258,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":","logprobs":[],"obfuscation":"nncCGQgd7S6dugK"} +{"type":"response.output_text.delta","sequence_number":259,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"jwxRD0GfBSMl3n3"} +{"type":"response.output_text.delta","sequence_number":260,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"6","logprobs":[],"obfuscation":"e2LguwC6eWkDYJL"} +{"type":"response.output_text.delta","sequence_number":261,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"GWh6hS60wuKC5vg"} +{"type":"response.output_text.delta","sequence_number":262,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"HRjkZOGFA6ABf7e"} +{"type":"response.output_text.delta","sequence_number":263,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"7","logprobs":[],"obfuscation":"NV7T3fVKnZjaoh7"} +{"type":"response.output_text.delta","sequence_number":264,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"0hQqXftC4Hm1DZU"} +{"type":"response.output_text.delta","sequence_number":265,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"myz0bO87K5wuzKx"} +{"type":"response.output_text.delta","sequence_number":266,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"3UQjA7MPiSu4wft"} +{"type":"response.output_text.delta","sequence_number":267,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"e2DmWcn2QSCqO8T"} +{"type":"response.output_text.delta","sequence_number":268,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"4PgVLhowFQInu8j"} +{"type":"response.output_text.delta","sequence_number":269,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"Je43jmILGxAHVLX"} +{"type":"response.output_text.delta","sequence_number":270,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"xLRCC2wPENo8kjM"} +{"type":"response.output_text.delta","sequence_number":271,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"aHJ31Fc1Q4Wkhtf"} +{"type":"response.output_text.delta","sequence_number":272,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"qIUWrJBtGqzfUYv"} +{"type":"response.output_text.delta","sequence_number":273,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"iUjdWK214dw3gyE"} +{"type":"response.output_text.delta","sequence_number":274,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"XELnI6FE9VyDspQ"} +{"type":"response.output_text.delta","sequence_number":275,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"11","logprobs":[],"obfuscation":"S0yhClyBH6fxe0"} +{"type":"response.output_text.delta","sequence_number":276,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"5QncHOPIDC6HBOh"} +{"type":"response.output_text.delta","sequence_number":277,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"0ZJ4iQpb5FXwlV5"} +{"type":"response.output_text.delta","sequence_number":278,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"4","logprobs":[],"obfuscation":"e1ky3dAFjWbfdiJ"} +{"type":"response.output_text.delta","sequence_number":279,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"DOKodHuxCEFe2DP"} +{"type":"response.output_text.delta","sequence_number":280,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"9OrQn0kuad7Lz6a"} +{"type":"response.output_text.delta","sequence_number":281,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"8","logprobs":[],"obfuscation":"vPhqvXeSkulQg2a"} +{"type":"response.output_text.delta","sequence_number":282,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"ALNYVvL8vMucMLT"} +{"type":"response.output_text.delta","sequence_number":283,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"MndsWcUDU3nHNNz"} +{"type":"response.output_text.delta","sequence_number":284,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"TgTAh8ufRUWzNE"} +{"type":"response.output_text.delta","sequence_number":285,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"dnnmqq7hIOEC4JZ"} +{"type":"response.output_text.delta","sequence_number":286,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"nRUxu3QaMtgNmWT"} +{"type":"response.output_text.delta","sequence_number":287,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"7","logprobs":[],"obfuscation":"8tbbRihVBi306eS"} +{"type":"response.output_text.delta","sequence_number":288,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"gZhLtTYHoldGVWK"} +{"type":"response.output_text.delta","sequence_number":289,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"iVBTTaAfcxERh2P"} +{"type":"response.output_text.delta","sequence_number":290,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"QIIR6BkPzw6APPl"} +{"type":"response.output_text.delta","sequence_number":291,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"ebTTUkU9r9HVszz"} +{"type":"response.output_text.delta","sequence_number":292,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"9XK2wBq8udw3eFr"} +{"type":"response.output_text.delta","sequence_number":293,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"8","logprobs":[],"obfuscation":"rMSAFNcC5g9p9DN"} +{"type":"response.output_text.delta","sequence_number":294,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"QLqJqJkFAjXPI2Y"} +{"type":"response.output_text.delta","sequence_number":295,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"5KCGtHjEH61OZhc"} +{"type":"response.output_text.delta","sequence_number":296,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"8","logprobs":[],"obfuscation":"IUJJnpfdkyLeccq"} +{"type":"response.output_text.delta","sequence_number":297,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"OpfU3QYrayPiMOm"} +{"type":"response.output_text.delta","sequence_number":298,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"AliFIu1VX7Dz74r"} +{"type":"response.output_text.delta","sequence_number":299,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"7","logprobs":[],"obfuscation":"mPJ8kR8OSPDzPQl"} +{"type":"response.output_text.delta","sequence_number":300,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"b7M6KuSQYsnFVZg"} +{"type":"response.output_text.delta","sequence_number":301,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"JTgFDVXH3kWQcYx"} +{"type":"response.output_text.delta","sequence_number":302,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"KxVELZQq9yCVUQ"} +{"type":"response.output_text.delta","sequence_number":303,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"1gA2ZtMvi7G8mFZ"} +{"type":"response.output_text.delta","sequence_number":304,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"CuStWf7xXL0G00v"} +{"type":"response.output_text.delta","sequence_number":305,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"8","logprobs":[],"obfuscation":"OAHgvv8Cngs8xFn"} +{"type":"response.output_text.delta","sequence_number":306,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"alKHq8tUmAFUrZu"} +{"type":"response.output_text.delta","sequence_number":307,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"5vAFerkS24LZAOD"} +{"type":"response.output_text.delta","sequence_number":308,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"9","logprobs":[],"obfuscation":"u6pAUP1AFWosM0l"} +{"type":"response.output_text.delta","sequence_number":309,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"ruCFwr6QtNzHgWh"} +{"type":"response.output_text.delta","sequence_number":310,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"B8uJnFA5fqLzMUn"} +{"type":"response.output_text.delta","sequence_number":311,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"5","logprobs":[],"obfuscation":"IemN0l0cJ3M7p7W"} +{"type":"response.output_text.delta","sequence_number":312,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"cM8qo7LcbhjVnLP"} +{"type":"response.output_text.delta","sequence_number":313,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"I4U0eaDMax4NFVx"} +{"type":"response.output_text.delta","sequence_number":314,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"4","logprobs":[],"obfuscation":"0jDd1xIFZGsym4c"} +{"type":"response.output_text.delta","sequence_number":315,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"SIairBPzlvUVHnV"} +{"type":"response.output_text.delta","sequence_number":316,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"gfD5s5fdJA7jdNa"} +{"type":"response.output_text.delta","sequence_number":317,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"7","logprobs":[],"obfuscation":"6Uehs9yaaYLxqgk"} +{"type":"response.output_text.delta","sequence_number":318,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n\n","logprobs":[],"obfuscation":"7T2NHwJTG86sNN"} +{"type":"response.output_text.delta","sequence_number":319,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"Full","logprobs":[],"obfuscation":"5y4T5HBe50r7"} +{"type":"response.output_text.delta","sequence_number":320,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" data","logprobs":[],"obfuscation":"vXpsCx5y3Sp"} +{"type":"response.output_text.delta","sequence_number":321,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"\n","logprobs":[],"obfuscation":"PrQvID5NzVyCJcC"} +{"type":"response.output_text.delta","sequence_number":322,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"-","logprobs":[],"obfuscation":"2GE1CtejTAi96YO"} +{"type":"response.output_text.delta","sequence_number":323,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" You","logprobs":[],"obfuscation":"r3foZ9yVkATc"} +{"type":"response.output_text.delta","sequence_number":324,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" can","logprobs":[],"obfuscation":"fh1PiubrLQeS"} +{"type":"response.output_text.delta","sequence_number":325,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" download","logprobs":[],"obfuscation":"pBopd1w"} +{"type":"response.output_text.delta","sequence_number":326,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" all","logprobs":[],"obfuscation":"aPdfZwfpQuEl"} +{"type":"response.output_text.delta","sequence_number":327,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"xG3frwmAq5zanxi"} +{"type":"response.output_text.delta","sequence_number":328,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"10","logprobs":[],"obfuscation":"85Zhu6ZApSSv49"} +{"type":"response.output_text.delta","sequence_number":329,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"90KtoHbick8dVbm"} +{"type":"response.output_text.delta","sequence_number":330,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"000","logprobs":[],"obfuscation":"MPVfxNDAGjNTL"} +{"type":"response.output_text.delta","sequence_number":331,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sums","logprobs":[],"obfuscation":"TLHgl1UKQ7G"} +{"type":"response.output_text.delta","sequence_number":332,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" as","logprobs":[],"obfuscation":"pkzFVYXfopfRb"} +{"type":"response.output_text.delta","sequence_number":333,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"kX0QfcY8nY4FQg"} +{"type":"response.output_text.delta","sequence_number":334,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" CSV","logprobs":[],"obfuscation":"1yyQP1VWHMmh"} +{"type":"response.output_text.delta","sequence_number":335,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" file","logprobs":[],"obfuscation":"XVH1wugfb3W"} +{"type":"response.output_text.delta","sequence_number":336,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" here","logprobs":[],"obfuscation":"LYk6z7SShk3"} +{"type":"response.output_text.delta","sequence_number":337,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":","logprobs":[],"obfuscation":"EHznVM6qV3dUz5q"} +{"type":"response.output_text.delta","sequence_number":338,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" [","logprobs":[],"obfuscation":"yC0E2HbfZJfr58"} +{"type":"response.output_text.delta","sequence_number":339,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"Download","logprobs":[],"obfuscation":"zBVk2U1X"} +{"type":"response.output_text.delta","sequence_number":340,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"YukWgk3NVFTf"} +{"type":"response.output_text.delta","sequence_number":341,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" sums","logprobs":[],"obfuscation":"Ff4UB1pYLEw"} +{"type":"response.output_text.delta","sequence_number":342,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" CSV","logprobs":[],"obfuscation":"7qg90SXOrR64"} +{"type":"response.output_text.delta","sequence_number":343,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"](","logprobs":[],"obfuscation":"uad1fLm2LyJFXp"} +{"type":"response.output_text.delta","sequence_number":344,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"sandbox","logprobs":[],"obfuscation":"Gzvqa3eWs"} +{"type":"response.output_text.delta","sequence_number":345,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":":/","logprobs":[],"obfuscation":"3G1JcCwqSZ3E07"} +{"type":"response.output_text.delta","sequence_number":346,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"mnt","logprobs":[],"obfuscation":"qNM4XBDC5E47U"} +{"type":"response.output_text.delta","sequence_number":347,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"/data","logprobs":[],"obfuscation":"eQPcHBXTp1O"} +{"type":"response.output_text.delta","sequence_number":348,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"/","logprobs":[],"obfuscation":"PRXarZXoQfBHUYr"} +{"type":"response.output_text.delta","sequence_number":349,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"roll","logprobs":[],"obfuscation":"8gyrwnLDVb1u"} +{"type":"response.output_text.delta","sequence_number":350,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"2","logprobs":[],"obfuscation":"AnANPoowjy7CFPM"} +{"type":"response.output_text.delta","sequence_number":351,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"dice","logprobs":[],"obfuscation":"a2J0djksVmXT"} +{"type":"response.output_text.delta","sequence_number":352,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"_s","logprobs":[],"obfuscation":"SNdtEN2TqFvJwn"} +{"type":"response.output_text.delta","sequence_number":353,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"ums","logprobs":[],"obfuscation":"cC7vj3HQvDsKT"} +{"type":"response.output_text.delta","sequence_number":354,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"_","logprobs":[],"obfuscation":"aqwtHC8bIEmSlaH"} +{"type":"response.output_text.delta","sequence_number":355,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"100","logprobs":[],"obfuscation":"Zl5mTHeqBQC7f"} +{"type":"response.output_text.delta","sequence_number":356,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"00","logprobs":[],"obfuscation":"wzcbOFqdd6Bq6l"} +{"type":"response.output_text.delta","sequence_number":357,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":".csv","logprobs":[],"obfuscation":"nFiPj3YSH1wI"} +{"type":"response.output_text.delta","sequence_number":358,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":")\n\n","logprobs":[],"obfuscation":"c63JCElW1sxgE"} +{"type":"response.output_text.delta","sequence_number":359,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"If","logprobs":[],"obfuscation":"hmuiqROMBAtN3v"} +{"type":"response.output_text.delta","sequence_number":360,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" you","logprobs":[],"obfuscation":"LGTlBp5C2814"} +{"type":"response.output_text.delta","sequence_number":361,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"’d","logprobs":[],"obfuscation":"MWryEKNYHOb89i"} +{"type":"response.output_text.delta","sequence_number":362,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" like","logprobs":[],"obfuscation":"6MF1XQrHKG4"} +{"type":"response.output_text.delta","sequence_number":363,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"a9wF93x9t4wgffs"} +{"type":"response.output_text.delta","sequence_number":364,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" I","logprobs":[],"obfuscation":"0z50QafGlya07v"} +{"type":"response.output_text.delta","sequence_number":365,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" can","logprobs":[],"obfuscation":"1PLHvN4if6gl"} +{"type":"response.output_text.delta","sequence_number":366,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" also","logprobs":[],"obfuscation":"acmi80RliNw"} +{"type":"response.output_text.delta","sequence_number":367,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" provide","logprobs":[],"obfuscation":"L8up9l6A"} +{"type":"response.output_text.delta","sequence_number":368,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"rGTbPB0pm5uufW"} +{"type":"response.output_text.delta","sequence_number":369,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" frequency","logprobs":[],"obfuscation":"K8fKda"} +{"type":"response.output_text.delta","sequence_number":370,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" distribution","logprobs":[],"obfuscation":"aqu"} +{"type":"response.output_text.delta","sequence_number":371,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"QRmWuvGSe0XSma2"} +{"type":"response.output_text.delta","sequence_number":372,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" histogram","logprobs":[],"obfuscation":"y17GhG"} +{"type":"response.output_text.delta","sequence_number":373,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"N5afzRDEPIOge85"} +{"type":"response.output_text.delta","sequence_number":374,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"4o1w6HFm362pQ"} +{"type":"response.output_text.delta","sequence_number":375,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" export","logprobs":[],"obfuscation":"X4Puseb6P"} +{"type":"response.output_text.delta","sequence_number":376,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"zdlHqrMrs2x2"} +{"type":"response.output_text.delta","sequence_number":377,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" data","logprobs":[],"obfuscation":"Do99yawuoct"} +{"type":"response.output_text.delta","sequence_number":378,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" in","logprobs":[],"obfuscation":"HWSZIK8AMkR9k"} +{"type":"response.output_text.delta","sequence_number":379,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" another","logprobs":[],"obfuscation":"eOrsXpaC"} +{"type":"response.output_text.delta","sequence_number":380,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" format","logprobs":[],"obfuscation":"KcsARIA8Q"} +{"type":"response.output_text.delta","sequence_number":381,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"JDIAi2tJwZYfxH"} +{"type":"response.output_text.delta","sequence_number":382,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":"JSON","logprobs":[],"obfuscation":"FiK1wrEbetDq"} +{"type":"response.output_text.delta","sequence_number":383,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"Fdy5HG1UlwZ7vrh"} +{"type":"response.output_text.delta","sequence_number":384,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" Excel","logprobs":[],"obfuscation":"DZltKnNygj"} +{"type":"response.output_text.delta","sequence_number":385,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":",","logprobs":[],"obfuscation":"YYKStBfj7zeBNm6"} +{"type":"response.output_text.delta","sequence_number":386,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":" etc","logprobs":[],"obfuscation":"4NZz1Y5LYAJx"} +{"type":"response.output_text.delta","sequence_number":387,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"delta":".).","logprobs":[],"obfuscation":"9cCnvOYtIf9pW"} +{"type":"response.output_text.annotation.added","sequence_number":388,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"annotation_index":0,"annotation":{"type":"container_file_citation","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","end_index":465,"file_id":"cfile_68c2e7084ab48191a67824aa1f4c90f1","filename":"roll2dice_sums_10000.csv","start_index":423}} +{"type":"response.output_text.done","sequence_number":389,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"text":"Here’s a simulation of rolling two fair six-sided dice 10,000 times. Each trial sums the two dice.\n\nResults\n- Total sum of all 10,000 trials: 69,868\n- Average sum per trial: 6.9868\n- Minimum sum observed: 2\n- Maximum sum observed: 12\n- Sample of the first 20 trial sums: 6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7\n\nFull data\n- You can download all 10,000 sums as a CSV file here: [Download the sums CSV](sandbox:/mnt/data/roll2dice_sums_10000.csv)\n\nIf you’d like, I can also provide a frequency distribution, histogram, or export the data in another format (JSON, Excel, etc.).","logprobs":[]} +{"type":"response.content_part.done","sequence_number":390,"item_id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","output_index":7,"content_index":0,"part":{"type":"output_text","annotations":[{"type":"container_file_citation","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","end_index":465,"file_id":"cfile_68c2e7084ab48191a67824aa1f4c90f1","filename":"roll2dice_sums_10000.csv","start_index":423}],"logprobs":[],"text":"Here’s a simulation of rolling two fair six-sided dice 10,000 times. Each trial sums the two dice.\n\nResults\n- Total sum of all 10,000 trials: 69,868\n- Average sum per trial: 6.9868\n- Minimum sum observed: 2\n- Maximum sum observed: 12\n- Sample of the first 20 trial sums: 6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7\n\nFull data\n- You can download all 10,000 sums as a CSV file here: [Download the sums CSV](sandbox:/mnt/data/roll2dice_sums_10000.csv)\n\nIf you’d like, I can also provide a frequency distribution, histogram, or export the data in another format (JSON, Excel, etc.)."}} +{"type":"response.output_item.done","sequence_number":391,"output_index":7,"item":{"id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"container_file_citation","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","end_index":465,"file_id":"cfile_68c2e7084ab48191a67824aa1f4c90f1","filename":"roll2dice_sums_10000.csv","start_index":423}],"logprobs":[],"text":"Here’s a simulation of rolling two fair six-sided dice 10,000 times. Each trial sums the two dice.\n\nResults\n- Total sum of all 10,000 trials: 69,868\n- Average sum per trial: 6.9868\n- Minimum sum observed: 2\n- Maximum sum observed: 12\n- Sample of the first 20 trial sums: 6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7\n\nFull data\n- You can download all 10,000 sums as a CSV file here: [Download the sums CSV](sandbox:/mnt/data/roll2dice_sums_10000.csv)\n\nIf you’d like, I can also provide a frequency distribution, histogram, or export the data in another format (JSON, Excel, etc.)."}],"role":"assistant"}} +{"type":"response.completed","sequence_number":392,"response":{"id":"resp_68c2e6efa238819383d5f52a2c2a3baa02d3a5742c7ddae9","object":"response","created_at":1757603567,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-nano-2025-08-07","output":[{"id":"rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9","type":"reasoning","summary":[]},{"id":"ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9","type":"code_interpreter_call","status":"completed","code":"import random, math\nN=10000\nsums=[]\ns=0\nfor _ in range(N):\n a=random.randint(1,6)\n b=random.randint(1,6)\n sm=a+b\n sums.append(sm)\n s+=sm\nmin(sums), max(sums), sum(sums), sum(sums)/N\n","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[{"type":"logs","logs":"(2, 12, 69868, 6.9868)"}]},{"id":"rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9","type":"reasoning","summary":[]},{"id":"ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9","type":"code_interpreter_call","status":"completed","code":"import csv, pathlib\npath = pathlib.Path('/mnt/data/roll2dice_sums_10000.csv')\nwith open(path, 'w', newline='') as f:\n writer = csv.writer(f)\n writer.writerow(['sum'])\n for val in sums:\n writer.writerow([val])\npath, path.exists(), len(sums)\n","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[{"type":"logs","logs":"(PosixPath('/mnt/data/roll2dice_sums_10000.csv'), True, 10000)"}]},{"id":"rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9","type":"reasoning","summary":[]},{"id":"ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9","type":"code_interpreter_call","status":"completed","code":"sums[:20]\n","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","outputs":[{"type":"logs","logs":"[6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7]"}]},{"id":"rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9","type":"reasoning","summary":[]},{"id":"msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"container_file_citation","container_id":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9","end_index":465,"file_id":"cfile_68c2e7084ab48191a67824aa1f4c90f1","filename":"roll2dice_sums_10000.csv","start_index":423}],"logprobs":[],"text":"Here’s a simulation of rolling two fair six-sided dice 10,000 times. Each trial sums the two dice.\n\nResults\n- Total sum of all 10,000 trials: 69,868\n- Average sum per trial: 6.9868\n- Minimum sum observed: 2\n- Maximum sum observed: 12\n- Sample of the first 20 trial sums: 6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7\n\nFull data\n- You can download all 10,000 sums as a CSV file here: [Download the sums CSV](sandbox:/mnt/data/roll2dice_sums_10000.csv)\n\nIf you’d like, I can also provide a frequency distribution, histogram, or export the data in another format (JSON, Excel, etc.)."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"code_interpreter","container":{"type":"auto"}}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":{"input_tokens":6047,"input_tokens_details":{"cached_tokens":2944},"output_tokens":1623,"output_tokens_details":{"reasoning_tokens":1408},"total_tokens":7670},"user":null,"metadata":{}}} \ No newline at end of file diff --git a/packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.json b/packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.json new file mode 100644 index 000000000000..b495cfb5e14e --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-code-interpreter-tool.1.json @@ -0,0 +1,112 @@ +{ + "id": "resp_68c2e2c6f7208190b9a439ac98147eb40b24aae9c6c01e4f", + "object": "response", + "created_at": 1757602503, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-5-nano-2025-08-07", + "output": [ + { + "id": "rs_68c2e2cbc0a08190bc754d734af0940f0b24aae9c6c01e4f", + "type": "reasoning", + "summary": [] + }, + { + "id": "ci_68c2e2cf522c81908f3e2c1bccd1493b0b24aae9c6c01e4f", + "type": "code_interpreter_call", + "status": "completed", + "code": "import random\nrandom.seed() # system time\nn=10000\nsums=[(random.randint(1,6)+random.randint(1,6)) for _ in range(n)]\ntotal=sum(sums)\nmean=total/n\nfrom collections import Counter\ncounts=Counter(sums)\ncounts_sorted=[(sum_val, counts[sum_val]) for sum_val in range(2,13)]\ntotal, mean, counts_sorted[:5], counts_sorted[-5:]", + "container_id": "cntr_68c2e2caf50c8193b4069276f4c75ef301e63bd5fd6a4d4d", + "outputs": [ + { + "type": "logs", + "logs": "(70141,\n 7.0141,\n [(2, 269), (3, 511), (4, 865), (5, 1130), (6, 1353)],\n [(8, 1387), (9, 1110), (10, 828), (11, 538), (12, 299)])" + } + ] + }, + { + "id": "rs_68c2e2d67f60819097167827b0e29b4f0b24aae9c6c01e4f", + "type": "reasoning", + "summary": [] + }, + { + "id": "ci_68c2e2d75fe08190b27c6e44213143010b24aae9c6c01e4f", + "type": "code_interpreter_call", + "status": "completed", + "code": "counts_sorted_full = [(s,c) for s,c in sorted(counts.items())]\ncounts_sorted_full", + "container_id": "cntr_68c2e2caf50c8193b4069276f4c75ef301e63bd5fd6a4d4d", + "outputs": [ + { + "type": "logs", + "logs": "[(2, 269),\n (3, 511),\n (4, 865),\n (5, 1130),\n (6, 1353),\n (7, 1710),\n (8, 1387),\n (9, 1110),\n (10, 828),\n (11, 538),\n (12, 299)]" + } + ] + }, + { + "id": "rs_68c2e2dab6508190987f0d3db143b0580b24aae9c6c01e4f", + "type": "reasoning", + "summary": [] + }, + { + "id": "msg_68c2e2e513c88190a72cefb37140d19a0b24aae9c6c01e4f", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "Here’s a quick result from simulating 10,000 rolls of two fair six-sided dice (sum per trial, then total across all trials):\n\n- Total sum of all 10,000 trial sums: 70141\n- Average sum per trial: 7.0141\n\nDistribution of the per-trial sums (2–12):\n- 2: 269 (2.69%)\n- 3: 511 (5.11%)\n- 4: 865 (8.65%)\n- 5: 1130 (11.30%)\n- 6: 1353 (13.53%)\n- 7: 1710 (17.10%)\n- 8: 1387 (13.87%)\n- 9: 1110 (11.10%)\n- 10: 828 (8.28%)\n- 11: 538 (5.38%)\n- 12: 299 (2.99%)\n\nNotes:\n- The total is around 7,0000 since the expected sum per trial is 7, so 10,000 trials ≈ 70000. Your exact total will vary with each run unless you fix a random seed.\n- If you’d like, I can provide the per-trial sums as a CSV file or share a reproducible run with a fixed seed." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": "medium", + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "code_interpreter", + "container": { + "type": "auto" + } + } + ], + "top_logprobs": 0, + "top_p": 1, + "truncation": "disabled", + "usage": { + "input_tokens": 4071, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 2456, + "output_tokens_details": { + "reasoning_tokens": 2176 + }, + "total_tokens": 6527 + }, + "user": null, + "metadata": {} +} diff --git a/packages/openai/src/responses/test-fixtures/openai-web-search-tool.chunks.txt b/packages/openai/src/responses/__fixtures__/openai-web-search-tool.chunks.txt similarity index 100% rename from packages/openai/src/responses/test-fixtures/openai-web-search-tool.chunks.txt rename to packages/openai/src/responses/__fixtures__/openai-web-search-tool.chunks.txt diff --git a/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap b/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap new file mode 100644 index 000000000000..3229f8a27393 --- /dev/null +++ b/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap @@ -0,0 +1,1365 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`OpenAIResponsesLanguageModel > doGenerate > code interpreter tool > should include code interpreter tool call and result in content 1`] = ` +[ + { + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e2cbc0a08190bc754d734af0940f0b24aae9c6c01e4f", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "input": "{"code":"import random\\nrandom.seed() # system time\\nn=10000\\nsums=[(random.randint(1,6)+random.randint(1,6)) for _ in range(n)]\\ntotal=sum(sums)\\nmean=total/n\\nfrom collections import Counter\\ncounts=Counter(sums)\\ncounts_sorted=[(sum_val, counts[sum_val]) for sum_val in range(2,13)]\\ntotal, mean, counts_sorted[:5], counts_sorted[-5:]","containerId":"cntr_68c2e2caf50c8193b4069276f4c75ef301e63bd5fd6a4d4d"}", + "providerExecuted": true, + "toolCallId": "ci_68c2e2cf522c81908f3e2c1bccd1493b0b24aae9c6c01e4f", + "toolName": "code_interpreter", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "outputs": [ + { + "logs": "(70141, + 7.0141, + [(2, 269), (3, 511), (4, 865), (5, 1130), (6, 1353)], + [(8, 1387), (9, 1110), (10, 828), (11, 538), (12, 299)])", + "type": "logs", + }, + ], + }, + "toolCallId": "ci_68c2e2cf522c81908f3e2c1bccd1493b0b24aae9c6c01e4f", + "toolName": "code_interpreter", + "type": "tool-result", + }, + { + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e2d67f60819097167827b0e29b4f0b24aae9c6c01e4f", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "input": "{"code":"counts_sorted_full = [(s,c) for s,c in sorted(counts.items())]\\ncounts_sorted_full","containerId":"cntr_68c2e2caf50c8193b4069276f4c75ef301e63bd5fd6a4d4d"}", + "providerExecuted": true, + "toolCallId": "ci_68c2e2d75fe08190b27c6e44213143010b24aae9c6c01e4f", + "toolName": "code_interpreter", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "outputs": [ + { + "logs": "[(2, 269), + (3, 511), + (4, 865), + (5, 1130), + (6, 1353), + (7, 1710), + (8, 1387), + (9, 1110), + (10, 828), + (11, 538), + (12, 299)]", + "type": "logs", + }, + ], + }, + "toolCallId": "ci_68c2e2d75fe08190b27c6e44213143010b24aae9c6c01e4f", + "toolName": "code_interpreter", + "type": "tool-result", + }, + { + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e2dab6508190987f0d3db143b0580b24aae9c6c01e4f", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "providerMetadata": { + "openai": { + "itemId": "msg_68c2e2e513c88190a72cefb37140d19a0b24aae9c6c01e4f", + }, + }, + "text": "Here’s a quick result from simulating 10,000 rolls of two fair six-sided dice (sum per trial, then total across all trials): + +- Total sum of all 10,000 trial sums: 70141 +- Average sum per trial: 7.0141 + +Distribution of the per-trial sums (2–12): +- 2: 269 (2.69%) +- 3: 511 (5.11%) +- 4: 865 (8.65%) +- 5: 1130 (11.30%) +- 6: 1353 (13.53%) +- 7: 1710 (17.10%) +- 8: 1387 (13.87%) +- 9: 1110 (11.10%) +- 10: 828 (8.28%) +- 11: 538 (5.38%) +- 12: 299 (2.99%) + +Notes: +- The total is around 7,0000 since the expected sum per trial is 7, so 10,000 trials ≈ 70000. Your exact total will vary with each run unless you fix a random seed. +- If you’d like, I can provide the per-trial sums as a CSV file or share a reproducible run with a fixed seed.", + "type": "text", + }, +] +`; + +exports[`OpenAIResponsesLanguageModel > doStream > code interpreter tool > should stream code interpreter results 1`] = ` +[ + { + "type": "stream-start", + "warnings": [], + }, + { + "id": "resp_68c2e6efa238819383d5f52a2c2a3baa02d3a5742c7ddae9", + "modelId": "gpt-5-nano-2025-08-07", + "timestamp": 2025-09-11T15:12:47.000Z, + "type": "response-metadata", + }, + { + "id": "rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e6f40ba48193a1c27abf31130e7e02d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "input": "{"code":"import random, math\\nN=10000\\nsums=[]\\ns=0\\nfor _ in range(N):\\n a=random.randint(1,6)\\n b=random.randint(1,6)\\n sm=a+b\\n sums.append(sm)\\n s+=sm\\nmin(sums), max(sums), sum(sums), sum(sums)/N\\n","containerId":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9"}", + "providerExecuted": true, + "toolCallId": "ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9", + "toolName": "code_interpreter", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "outputs": [ + { + "logs": "(2, 12, 69868, 6.9868)", + "type": "logs", + }, + ], + }, + "toolCallId": "ci_68c2e6f7b72c8193ba1f552552c8dc9202d3a5742c7ddae9", + "toolName": "code_interpreter", + "type": "tool-result", + }, + { + "id": "rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e6fcb52881938f21c45741216ac002d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "input": "{"code":"import csv, pathlib\\npath = pathlib.Path('/mnt/data/roll2dice_sums_10000.csv')\\nwith open(path, 'w', newline='') as f:\\n writer = csv.writer(f)\\n writer.writerow(['sum'])\\n for val in sums:\\n writer.writerow([val])\\npath, path.exists(), len(sums)\\n","containerId":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9"}", + "providerExecuted": true, + "toolCallId": "ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9", + "toolName": "code_interpreter", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "outputs": [ + { + "logs": "(PosixPath('/mnt/data/roll2dice_sums_10000.csv'), True, 10000)", + "type": "logs", + }, + ], + }, + "toolCallId": "ci_68c2e6fd57948193aa93df6bdb00a86d02d3a5742c7ddae9", + "toolName": "code_interpreter", + "type": "tool-result", + }, + { + "id": "rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e6fff1808193a78d43410a1feb4802d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "input": "{"code":"sums[:20]\\n","containerId":"cntr_68c2e6f380d881908a57a82d394434ff02f484f5344062e9"}", + "providerExecuted": true, + "toolCallId": "ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9", + "toolName": "code_interpreter", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "outputs": [ + { + "logs": "[6, 7, 2, 5, 5, 11, 4, 8, 10, 7, 5, 8, 8, 7, 10, 8, 9, 5, 4, 7]", + "type": "logs", + }, + ], + }, + "toolCallId": "ci_68c2e701a23081939c93b6fb5bb952d302d3a5742c7ddae9", + "toolName": "code_interpreter", + "type": "tool-result", + }, + { + "id": "rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_68c2e703d114819383c5da260649c7ce02d3a5742c7ddae9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "providerMetadata": { + "openai": { + "itemId": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + }, + }, + "type": "text-start", + }, + { + "delta": "Here", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "’s", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " simulation", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " of", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " rolling", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " two", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " fair", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " six", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-sided", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " dice", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "10", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "000", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " times", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ".", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Each", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " trial", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sums", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " the", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " two", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " dice", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ". + +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "Results", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Total", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sum", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " of", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " all", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "10", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "000", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " trials", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "69", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "868", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Average", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sum", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " per", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " trial", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "6", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ".", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "986", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "8", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Minimum", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sum", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " observed", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "2", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Maximum", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sum", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " observed", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "12", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Sample", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " of", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " the", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " first", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "20", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " trial", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sums", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "6", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "7", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "2", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "5", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "5", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "11", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "4", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "8", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "10", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "7", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "5", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "8", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "8", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "7", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "10", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "8", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "9", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "5", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "4", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "7", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " + +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "Full", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " data", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "-", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " You", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " can", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " download", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " all", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "10", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "000", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sums", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " as", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " CSV", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " file", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " here", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " [", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "Download", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " the", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " sums", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " CSV", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "](", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "sandbox", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ":/", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "mnt", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "/data", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "/", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "roll", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "2", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "dice", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "_s", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "ums", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "_", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "100", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "00", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ".csv", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ") + +", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "If", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " you", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "’d", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " like", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " I", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " can", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " also", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " provide", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " frequency", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " distribution", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " histogram", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " export", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " the", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " data", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " in", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " another", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " format", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " (", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": "JSON", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " Excel", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": " etc", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "delta": ".).", + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-delta", + }, + { + "id": "msg_68c2e7054ae481938354ab3e4e77abad02d3a5742c7ddae9", + "type": "text-end", + }, + { + "finishReason": "stop", + "providerMetadata": { + "openai": { + "responseId": "resp_68c2e6efa238819383d5f52a2c2a3baa02d3a5742c7ddae9", + "serviceTier": "default", + }, + }, + "type": "finish", + "usage": { + "cachedInputTokens": 2944, + "inputTokens": 6047, + "outputTokens": 1623, + "reasoningTokens": 1408, + "totalTokens": 7670, + }, + }, +] +`; diff --git a/packages/openai/src/responses/openai-responses-language-model.test.ts b/packages/openai/src/responses/openai-responses-language-model.test.ts index 80793fe1da9d..98b7a87021d3 100644 --- a/packages/openai/src/responses/openai-responses-language-model.test.ts +++ b/packages/openai/src/responses/openai-responses-language-model.test.ts @@ -1,4 +1,5 @@ import { + LanguageModelV2, LanguageModelV2FunctionTool, LanguageModelV2Prompt, } from '@ai-sdk/provider'; @@ -42,15 +43,6 @@ const TEST_TOOLS: Array = [ }, ]; -function loadOpenAIChunks(filename: string) { - const lines = fs - .readFileSync(filename, 'utf8') - .split('\n') - .map(line => `data: ${line}\n\n`); - lines.push('data: [DONE]\n\n'); - return lines; -} - const nonReasoningModelIds = openaiResponsesModelIds.filter( modelId => !openaiResponsesReasoningModelIds.includes( @@ -73,6 +65,29 @@ describe('OpenAIResponsesLanguageModel', () => { 'https://api.openai.com/v1/responses': {}, }); + function prepareJsonFixtureResponse(filename: string) { + server.urls['https://api.openai.com/v1/responses'].response = { + type: 'json-value', + body: JSON.parse( + fs.readFileSync(`src/responses/__fixtures__/${filename}.json`, 'utf8'), + ), + }; + return; + } + + function prepareChunksFixtureResponse(filename: string) { + const chunks = fs + .readFileSync(`src/responses/__fixtures__/${filename}.chunks.txt`, 'utf8') + .split('\n') + .map(line => `data: ${line}\n\n`); + chunks.push('data: [DONE]\n\n'); + + server.urls['https://api.openai.com/v1/responses'].response = { + type: 'stream-chunks', + chunks, + }; + } + describe('doGenerate', () => { function prepareJsonResponse(body: any) { server.urls['https://api.openai.com/v1/responses'].response = { @@ -2091,213 +2106,57 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); - describe('code interpreter', () => { - beforeEach(() => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'json-value', - body: { - id: 'resp_68c12b837ca881a0a062ebb60494ae7700553426a98f13ca', - object: 'response', - created_at: 1757490051, - status: 'completed', - background: false, - error: null, - incomplete_details: null, - instructions: null, - max_output_tokens: null, - max_tool_calls: null, - model: 'gpt-5-nano-2025-08-07', - output: [ - { - id: 'rs_68c12b868cd081a09ec2d83759a43b9e00553426a98f13ca', - type: 'reasoning', - summary: [], - }, - { - id: 'ci_68c12b8a4e6481a0bd969d4488e6809700553426a98f13ca', - type: 'code_interpreter_call', - status: 'completed', - code: 'import random\nrandom.seed(0)\nn = 10000\nsums = []\nfor _ in range(n):\n a = random.randint(1,6)\n b = random.randint(1,6)\n sums.append(a+b)\ntotal = sum(sums)\nmean = total / n\nfrom collections import Counter\ncounts = Counter(sums)\ndist = {s: counts.get(s,0) for s in range(2,13)}\ntotal, mean, dist, sums[:20]', - container_id: - 'cntr_68c12b85cd34819190332dbb00ec850c0f117a6c6bf754ed', - outputs: null, - }, - { - id: 'rs_68c12b8cf96081a08764e212603bb16600553426a98f13ca', - type: 'reasoning', - summary: [], - }, - { - id: 'ci_68c12b8dfa3881a084c474e6fbd0220500553426a98f13ca', - type: 'code_interpreter_call', - status: 'completed', - code: "# Write sums to CSV\nimport csv\nwith open('/mnt/data/dice_sums_10000.csv','w', newline='') as f:\n writer = csv.writer(f)\n writer.writerow(['sum'])\n for s in sums:\n writer.writerow([s])\n# Write summary\nsummary = {\n 'n_trials': n,\n 'total_sum': total,\n 'mean_sum_per_trial': mean,\n 'distribution': {str(k): v for k,v in dist.items()}\n}\nimport json\nwith open('/mnt/data/dice_sums_summary.json','w') as f:\n json.dump(summary, f, indent=2)\n('/mnt/data/dice_sums_10000.csv', '/mnt/data/dice_sums_summary.json')", - container_id: - 'cntr_68c12b85cd34819190332dbb00ec850c0f117a6c6bf754ed', - outputs: null, - }, - { - id: 'rs_68c12b90775c81a0bdcb8c306da10e7700553426a98f13ca', - type: 'reasoning', - summary: [], - }, + describe('code interpreter tool', () => { + let result: Awaited>; + + beforeEach(async () => { + prepareJsonFixtureResponse('openai-code-interpreter-tool.1'); + + result = await createModel('gpt-5-nano').doGenerate({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.code_interpreter', + name: 'code_interpreter', + args: {}, + }, + ], + }); + }); + + it('should send request body with include and tool', async () => { + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "include": [ + "code_interpreter_call.outputs", + ], + "input": [ { - id: 'msg_68c12b93d98481a0b8696d68b6c5968100553426a98f13ca', - type: 'message', - status: 'completed', - content: [ + "content": [ { - type: 'output_text', - annotations: [ - { - type: 'container_file_citation', - container_id: - 'cntr_68c12b85cd34819190332dbb00ec850c0f117a6c6bf754ed', - end_index: 744, - file_id: 'cfile_68c12b969ca881919d2ad197c7790751', - filename: 'dice_sums_10000.csv', - start_index: 707, - }, - { - type: 'container_file_citation', - container_id: - 'cntr_68c12b85cd34819190332dbb00ec850c0f117a6c6bf754ed', - end_index: 818, - file_id: 'cfile_68c12b969cc88191846a76aa26a47fe8', - filename: 'dice_sums_summary.json', - start_index: 778, - }, - ], - logprobs: [], - text: 'I ran a simulation of rolling two fair dice 10,000 times and computed the sums for each trial.\n\nKey results\n- Total sum of all 10,000 trial sums: 69953\n- Average sum per trial: 6.9953\n- Distribution of sums (counts for sums 2 through 12):\n - 2: 285\n - 3: 552\n - 4: 818\n - 5: 1134\n - 6: 1359\n - 7: 1721\n - 8: 1378\n - 9: 1108\n - 10: 797\n - 11: 558\n - 12: 290\n\nSample of the first 20 trial sums\n[8, 4, 9, 7, 7, 7, 7, 5, 6, 8, 11, 5, 7, 7, 7, 6, 7, 8, 8, 9]\n\nFiles created\n- dice_sums_10000.csv: each row contains the sum of a trial (one column: "sum")\n- dice_sums_summary.json: a summary with n_trials, total_sum, mean_sum_per_trial, and the distribution\n\nDownload links\n- [Download the sums (CSV)](sandbox:/mnt/data/dice_sums_10000.csv)\n- [Download the summary (JSON)](sandbox:/mnt/data/dice_sums_summary.json)\n\nIf you want me to run again with a different seed, or to provide a fuller distribution table or a plotted histogram, tell me how you\u2019d like the results formatted.', + "text": "Hello", + "type": "input_text", }, ], - role: 'assistant', + "role": "user", }, ], - parallel_tool_calls: true, - previous_response_id: null, - prompt_cache_key: null, - reasoning: { - effort: 'medium', - summary: null, - }, - safety_identifier: null, - service_tier: 'default', - store: true, - temperature: 1.0, - text: { - format: { - type: 'text', - }, - verbosity: 'medium', - }, - tool_choice: 'auto', - tools: [ + "model": "gpt-5-nano", + "tools": [ { - type: 'code_interpreter', - container: { - type: 'auto', + "container": { + "type": "auto", }, + "type": "code_interpreter", }, ], - top_logprobs: 0, - top_p: 1.0, - truncation: 'disabled', - usage: { - input_tokens: 4621, - input_tokens_details: { - cached_tokens: 3584, - }, - output_tokens: 2094, - output_tokens_details: { - reasoning_tokens: 1728, - }, - total_tokens: 6715, - }, - user: null, - metadata: {}, - }, - }; + } + `); }); - it('should generate text response', async () => { - const result = await createModel('gpt-5-nano').doGenerate({ - prompt: TEST_PROMPT, - }); - - expect(result.content).toMatchInlineSnapshot(` - [ - { - "providerMetadata": { - "openai": { - "itemId": "rs_68c12b868cd081a09ec2d83759a43b9e00553426a98f13ca", - "reasoningEncryptedContent": null, - }, - }, - "text": "", - "type": "reasoning", - }, - { - "providerMetadata": { - "openai": { - "itemId": "rs_68c12b8cf96081a08764e212603bb16600553426a98f13ca", - "reasoningEncryptedContent": null, - }, - }, - "text": "", - "type": "reasoning", - }, - { - "providerMetadata": { - "openai": { - "itemId": "rs_68c12b90775c81a0bdcb8c306da10e7700553426a98f13ca", - "reasoningEncryptedContent": null, - }, - }, - "text": "", - "type": "reasoning", - }, - { - "providerMetadata": { - "openai": { - "itemId": "msg_68c12b93d98481a0b8696d68b6c5968100553426a98f13ca", - }, - }, - "text": "I ran a simulation of rolling two fair dice 10,000 times and computed the sums for each trial. - - Key results - - Total sum of all 10,000 trial sums: 69953 - - Average sum per trial: 6.9953 - - Distribution of sums (counts for sums 2 through 12): - - 2: 285 - - 3: 552 - - 4: 818 - - 5: 1134 - - 6: 1359 - - 7: 1721 - - 8: 1378 - - 9: 1108 - - 10: 797 - - 11: 558 - - 12: 290 - - Sample of the first 20 trial sums - [8, 4, 9, 7, 7, 7, 7, 5, 6, 8, 11, 5, 7, 7, 7, 6, 7, 8, 8, 9] - - Files created - - dice_sums_10000.csv: each row contains the sum of a trial (one column: "sum") - - dice_sums_summary.json: a summary with n_trials, total_sum, mean_sum_per_trial, and the distribution - - Download links - - [Download the sums (CSV)](sandbox:/mnt/data/dice_sums_10000.csv) - - [Download the summary (JSON)](sandbox:/mnt/data/dice_sums_summary.json) - - If you want me to run again with a different seed, or to provide a fuller distribution table or a plotted histogram, tell me how you’d like the results formatted.", - "type": "text", - }, - ] - `); + it('should include code interpreter tool call and result in content', async () => { + expect(result.content).toMatchSnapshot(); }); }); @@ -3807,12 +3666,7 @@ describe('OpenAIResponsesLanguageModel', () => { }); it('should stream web search results (sources, tool calls, tool results)', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'stream-chunks', - chunks: loadOpenAIChunks( - 'src/responses/test-fixtures/openai-web-search-tool.chunks.txt', - ), - }; + prepareChunksFixtureResponse('openai-web-search-tool'); const { stream } = await createModel('gpt-5-nano').doStream({ tools: [ @@ -4190,6 +4044,32 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); + describe('code interpreter tool', () => { + let result: Awaited>; + + beforeEach(async () => { + prepareChunksFixtureResponse('openai-code-interpreter-tool.1'); + + result = await createModel('gpt-5-nano').doStream({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.code_interpreter', + name: 'code_interpreter', + args: {}, + }, + ], + }); + }); + + it('should stream code interpreter results', async () => { + expect( + await convertReadableStreamToArray(result.stream), + ).toMatchSnapshot(); + }); + }); + describe('errors', () => { it('should stream error parts', async () => { server.urls['https://api.openai.com/v1/responses'].response = { diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index 45d07014817d..62a86d1f8ad9 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -21,11 +21,15 @@ import { import { z } from 'zod/v4'; import { OpenAIConfig } from '../openai-config'; import { openaiFailedResponseHandler } from '../openai-error'; +import { + codeInterpreterInputSchema, + codeInterpreterOutputSchema, +} from '../tool/code-interpreter'; import { convertToOpenAIResponsesMessages } from './convert-to-openai-responses-messages'; import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason'; +import { OpenAIResponsesIncludeOptions } from './openai-responses-api-types'; import { prepareResponsesTools } from './openai-responses-prepare-tools'; import { OpenAIResponsesModelId } from './openai-responses-settings'; -import { OpenAIResponsesIncludeOptions } from './openai-responses-api-types'; const webSearchCallItem = z.object({ type: z.literal('web_search_call'), @@ -50,6 +54,21 @@ const webSearchCallItem = z.object({ .nullish(), }); +const codeInterpreterCallItem = z.object({ + type: z.literal('code_interpreter_call'), + id: z.string(), + code: z.string().nullable(), + container_id: z.string(), + outputs: z + .array( + z.discriminatedUnion('type', [ + z.object({ type: z.literal('logs'), logs: z.string() }), + z.object({ type: z.literal('image'), url: z.string() }), + ]), + ) + .nullable(), +}); + /** * `top_logprobs` request body argument can be set to an integer between * 0 and 20 specifying the number of most likely tokens to return at each @@ -186,6 +205,21 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { : ['web_search_call.action.sources'] : include; + // when a code interpreter tool is present, automatically include the outputs: + const codeInterpreterToolName = ( + tools?.find( + tool => + tool.type === 'provider-defined' && + tool.id === 'openai.code_interpreter', + ) as LanguageModelV2ProviderDefinedTool | undefined + )?.name; + + include = codeInterpreterToolName + ? Array.isArray(include) + ? [...include, 'code_interpreter_call.outputs'] + : ['code_interpreter_call.outputs'] + : include; + const baseArgs = { model: this.modelId, input: messages, @@ -403,9 +437,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }), ), }), - z.object({ - type: z.literal('code_interpreter_call'), - }), + codeInterpreterCallItem, z.object({ type: z.literal('function_call'), call_id: z.string(), @@ -626,6 +658,30 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }); break; } + + case 'code_interpreter_call': { + content.push({ + type: 'tool-call', + toolCallId: part.id, + toolName: 'code_interpreter', + input: JSON.stringify({ + code: part.code, + containerId: part.container_id, + } satisfies z.infer), + providerExecuted: true, + }); + + content.push({ + type: 'tool-result', + toolCallId: part.id, + toolName: 'code_interpreter', + result: { + outputs: part.outputs, + } satisfies z.infer, + providerExecuted: true, + }); + break; + } } } @@ -919,6 +975,27 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }, providerExecuted: true, }); + } else if (value.item.type === 'code_interpreter_call') { + controller.enqueue({ + type: 'tool-call', + toolCallId: value.item.id, + toolName: 'code_interpreter', + input: JSON.stringify({ + code: value.item.code, + containerId: value.item.container_id, + } satisfies z.infer), + providerExecuted: true, + }); + + controller.enqueue({ + type: 'tool-result', + toolCallId: value.item.id, + toolName: 'code_interpreter', + result: { + outputs: value.item.outputs, + } satisfies z.infer, + providerExecuted: true, + }); } else if (value.item.type === 'message') { controller.enqueue({ type: 'text-end', @@ -1202,6 +1279,7 @@ const responseOutputItemDoneSchema = z.object({ arguments: z.string(), status: z.literal('completed'), }), + codeInterpreterCallItem, webSearchCallItem, z.object({ type: z.literal('computer_call'), diff --git a/packages/openai/src/tool/code-interpreter.ts b/packages/openai/src/tool/code-interpreter.ts index 90fbf570eb44..3962cef80ac8 100644 --- a/packages/openai/src/tool/code-interpreter.ts +++ b/packages/openai/src/tool/code-interpreter.ts @@ -1,6 +1,22 @@ -import { createProviderDefinedToolFactory } from '@ai-sdk/provider-utils'; +import { createProviderDefinedToolFactoryWithOutputSchema } from '@ai-sdk/provider-utils'; import { z } from 'zod/v4'; +export const codeInterpreterInputSchema = z.object({ + code: z.string().nullish(), + containerId: z.string(), +}); + +export const codeInterpreterOutputSchema = z.object({ + outputs: z + .array( + z.discriminatedUnion('type', [ + z.object({ type: z.literal('logs'), logs: z.string() }), + z.object({ type: z.literal('image'), url: z.string() }), + ]), + ) + .nullish(), +}); + export const codeInterpreterArgsSchema = z.object({ container: z .union([ @@ -12,24 +28,62 @@ export const codeInterpreterArgsSchema = z.object({ .optional(), }); -export const codeInterpreterToolFactory = createProviderDefinedToolFactory< - {}, - { - /** - * The code interpreter container. - * Can be a container ID - * or an object that specifies uploaded file IDs to make available to your code. - */ - container?: string | { fileIds?: string[] }; - } ->({ - id: 'openai.code_interpreter', - name: 'code_interpreter', - inputSchema: z.object({}), -}); +type CodeInterpreterArgs = { + /** + * The code interpreter container. + * Can be a container ID + * or an object that specifies uploaded file IDs to make available to your code. + */ + container?: string | { fileIds?: string[] }; +}; + +export const codeInterpreterToolFactory = + createProviderDefinedToolFactoryWithOutputSchema< + { + /** + * The code to run, or null if not available. + */ + code?: string | null; + + /** + * The ID of the container used to run the code. + */ + containerId: string; + }, + { + /** + * The outputs generated by the code interpreter, such as logs or images. + * Can be null if no outputs are available. + */ + outputs?: Array< + | { + type: 'logs'; + + /** + * The logs output from the code interpreter. + */ + logs: string; + } + | { + type: 'image'; + + /** + * The URL of the image output from the code interpreter. + */ + url: string; + } + > | null; + }, + CodeInterpreterArgs + >({ + id: 'openai.code_interpreter', + name: 'code_interpreter', + inputSchema: codeInterpreterInputSchema, + outputSchema: codeInterpreterOutputSchema, + }); export const codeInterpreter = ( - args: Parameters[0] = {}, // default + args: CodeInterpreterArgs = {}, // default ) => { return codeInterpreterToolFactory(args); }; From de5c066f206067c55e43550f4b0e8c76281c55f8 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Fri, 12 Sep 2025 15:16:12 +0200 Subject: [PATCH 015/121] fix(ai): forward providerExecuted flag in validateUIMessages (#8607) ## Background When validating UI messages, the provided executed flag was dropped because it was missing in the zod schema. ## Summary Add `providerExecuted` flag to zod schema definitions in `validateUIMessages`. ## Manual Verification Validated as part of #8604 ## Related Issues Discovered during #8604 --- .changeset/brown-vans-complain.md | 5 ++ .../ai/src/ui/validate-ui-messages.test.ts | 49 +++++++++++++------ packages/ai/src/ui/validate-ui-messages.ts | 4 ++ 3 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 .changeset/brown-vans-complain.md diff --git a/.changeset/brown-vans-complain.md b/.changeset/brown-vans-complain.md new file mode 100644 index 000000000000..3dedfd64e7b1 --- /dev/null +++ b/.changeset/brown-vans-complain.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): forwarded providerExecuted flag in validateUIMessages diff --git a/packages/ai/src/ui/validate-ui-messages.test.ts b/packages/ai/src/ui/validate-ui-messages.test.ts index c413768bf93c..0b6316cbd0c1 100644 --- a/packages/ai/src/ui/validate-ui-messages.test.ts +++ b/packages/ai/src/ui/validate-ui-messages.test.ts @@ -678,6 +678,7 @@ describe('validateUIMessages', () => { toolCallId: '1', state: 'input-streaming', input: { foo: 'bar' }, + providerExecuted: true, }, ], }, @@ -695,6 +696,7 @@ describe('validateUIMessages', () => { "input": { "foo": "bar", }, + "providerExecuted": true, "state": "input-streaming", "toolCallId": "1", "type": "tool-foo", @@ -718,6 +720,7 @@ describe('validateUIMessages', () => { toolCallId: '1', state: 'input-available', input: { foo: 'bar' }, + providerExecuted: true, }, ], }, @@ -735,6 +738,7 @@ describe('validateUIMessages', () => { "input": { "foo": "bar", }, + "providerExecuted": true, "state": "input-available", "toolCallId": "1", "type": "tool-foo", @@ -759,6 +763,7 @@ describe('validateUIMessages', () => { state: 'output-available', input: { foo: 'bar' }, output: { result: 'success' }, + providerExecuted: true, }, ], }, @@ -779,6 +784,7 @@ describe('validateUIMessages', () => { "output": { "result": "success", }, + "providerExecuted": true, "state": "output-available", "toolCallId": "1", "type": "tool-foo", @@ -803,6 +809,7 @@ describe('validateUIMessages', () => { state: 'output-error', input: { foo: 'bar' }, errorText: 'Tool execution failed', + providerExecuted: true, }, ], }, @@ -821,6 +828,7 @@ describe('validateUIMessages', () => { "input": { "foo": "bar", }, + "providerExecuted": true, "state": "output-error", "toolCallId": "1", "type": "tool-foo", @@ -844,6 +852,7 @@ describe('validateUIMessages', () => { toolCallId: '1', state: 'input-available', input: { foo: 'bar' }, + providerExecuted: true, }, ], }, @@ -855,23 +864,24 @@ describe('validateUIMessages', () => { expectTypeOf(messages).toEqualTypeOf>(); expect(messages).toMatchInlineSnapshot(` - [ - { - "id": "1", - "parts": [ - { - "input": { - "foo": "bar", + [ + { + "id": "1", + "parts": [ + { + "input": { + "foo": "bar", + }, + "providerExecuted": true, + "state": "input-available", + "toolCallId": "1", + "type": "tool-foo", }, - "state": "input-available", - "toolCallId": "1", - "type": "tool-foo", - }, - ], - "role": "assistant", - }, - ] - `); + ], + "role": "assistant", + }, + ] + `); }); it('should validate tool input and output when state is output-available', async () => { @@ -933,6 +943,7 @@ describe('validateUIMessages', () => { state: 'output-error', input: { foo: 'bar' }, errorText: 'Tool execution failed', + providerExecuted: true, }, ], }, @@ -953,6 +964,7 @@ describe('validateUIMessages', () => { "input": { "foo": "bar", }, + "providerExecuted": true, "state": "output-error", "toolCallId": "1", "type": "tool-foo", @@ -977,6 +989,7 @@ describe('validateUIMessages', () => { toolCallId: '1', state: 'input-available', input: { foo: 'bar' }, + providerExecuted: true, }, ], }, @@ -1004,6 +1017,7 @@ describe('validateUIMessages', () => { toolCallId: '1', state: 'input-available', input: { foo: 123 }, // wrong type + providerExecuted: true, }, ], }, @@ -1030,6 +1044,7 @@ describe('validateUIMessages', () => { type: 'tool-foo', toolCallId: '1', state: 'output-available', + providerExecuted: true, input: { foo: 'bar' }, output: { result: 123 }, // wrong type }, @@ -1058,6 +1073,7 @@ describe('validateUIMessages', () => { toolCallId: '1', state: 'input-streaming', input: { foo: 123 }, // wrong type but should not be validated + providerExecuted: true, }, ], }, @@ -1077,6 +1093,7 @@ describe('validateUIMessages', () => { "input": { "foo": 123, }, + "providerExecuted": true, "state": "input-streaming", "toolCallId": "1", "type": "tool-foo", diff --git a/packages/ai/src/ui/validate-ui-messages.ts b/packages/ai/src/ui/validate-ui-messages.ts index 131d4e9d43b2..3c18de8f5945 100644 --- a/packages/ai/src/ui/validate-ui-messages.ts +++ b/packages/ai/src/ui/validate-ui-messages.ts @@ -113,6 +113,7 @@ const toolUIPartSchemas = [ type: z.string().startsWith('tool-'), toolCallId: z.string(), state: z.literal('input-streaming'), + providerExecuted: z.boolean().optional(), input: z.unknown().optional(), output: z.never().optional(), errorText: z.never().optional(), @@ -121,6 +122,7 @@ const toolUIPartSchemas = [ type: z.string().startsWith('tool-'), toolCallId: z.string(), state: z.literal('input-available'), + providerExecuted: z.boolean().optional(), input: z.unknown(), output: z.never().optional(), errorText: z.never().optional(), @@ -130,6 +132,7 @@ const toolUIPartSchemas = [ type: z.string().startsWith('tool-'), toolCallId: z.string(), state: z.literal('output-available'), + providerExecuted: z.boolean().optional(), input: z.unknown(), output: z.unknown(), errorText: z.never().optional(), @@ -140,6 +143,7 @@ const toolUIPartSchemas = [ type: z.string().startsWith('tool-'), toolCallId: z.string(), state: z.literal('output-error'), + providerExecuted: z.boolean().optional(), input: z.unknown(), output: z.never().optional(), errorText: z.string(), From db495205f532adfbc63b747329760b51bda78502 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:30:50 +0200 Subject: [PATCH 016/121] Version Packages (#8603) # Releases ## ai@5.0.42 ### Patch Changes - de5c066: fix(ai): forwarded providerExecuted flag in validateUIMessages ## @ai-sdk/angular@1.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 ## @ai-sdk/azure@2.0.29 ### Patch Changes - Updated dependencies [4235eb3] - @ai-sdk/openai@2.0.29 ## @ai-sdk/langchain@1.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 ## @ai-sdk/llamaindex@1.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 ## @ai-sdk/openai@2.0.29 ### Patch Changes - 4235eb3: feat(provider/openai): code interpreter tool calls and results ## @ai-sdk/react@2.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 ## @ai-sdk/rsc@1.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 ## @ai-sdk/svelte@3.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 ## @ai-sdk/vue@2.0.42 ### Patch Changes - Updated dependencies [de5c066] - ai@5.0.42 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/brown-vans-complain.md | 5 ----- .changeset/unlucky-clouds-agree.md | 5 ----- packages/ai/CHANGELOG.md | 6 ++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 7 +++++++ packages/angular/package.json | 2 +- packages/azure/CHANGELOG.md | 7 +++++++ packages/azure/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/openai/CHANGELOG.md | 6 ++++++ packages/openai/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 7 +++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 7 +++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 7 +++++++ packages/vue/package.json | 2 +- 23 files changed, 85 insertions(+), 20 deletions(-) delete mode 100644 .changeset/brown-vans-complain.md delete mode 100644 .changeset/unlucky-clouds-agree.md diff --git a/.changeset/brown-vans-complain.md b/.changeset/brown-vans-complain.md deleted file mode 100644 index 3dedfd64e7b1..000000000000 --- a/.changeset/brown-vans-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix(ai): forwarded providerExecuted flag in validateUIMessages diff --git a/.changeset/unlucky-clouds-agree.md b/.changeset/unlucky-clouds-agree.md deleted file mode 100644 index 58788d2cf3a4..000000000000 --- a/.changeset/unlucky-clouds-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -feat(provider/openai): code interpreter tool calls and results diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index af77d98a611f..28f7a4020529 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 5.0.42 + +### Patch Changes + +- de5c066: fix(ai): forwarded providerExecuted flag in validateUIMessages + ## 5.0.41 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 94cdf7ce6699..a1faf99166ca 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.41", + "version": "5.0.42", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 6d6f0e3885f8..105eae3e4f3e 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/angular +## 1.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 1.0.41 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 5a48a707852a..14116d295beb 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.41", + "version": "1.0.42", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index a10850ad1909..cb76e4f6de58 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/azure +## 2.0.29 + +### Patch Changes + +- Updated dependencies [4235eb3] + - @ai-sdk/openai@2.0.29 + ## 2.0.28 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 24420c24472b..53b1379281aa 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.0.28", + "version": "2.0.29", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index a7b25c7026c5..1d296c3cf57f 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 1.0.41 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 653d425fc518..ef2b9b3755bb 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.41", + "version": "1.0.42", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 3bfbc5cce55e..782db1950d23 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 1.0.41 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index cacb83b2e32f..eb1cf5db90a9 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.41", + "version": "1.0.42", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 913fbd0e1b87..b0982aa1ae69 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/openai +## 2.0.29 + +### Patch Changes + +- 4235eb3: feat(provider/openai): code interpreter tool calls and results + ## 2.0.28 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index ad4459e75cd9..95c30fe3d1b8 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.0.28", + "version": "2.0.29", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 5762d6fba9f0..16467ba7c21e 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/react +## 2.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 2.0.41 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index e724ebb1e8fa..a4e2a876db83 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.41", + "version": "2.0.42", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 28bea36fed13..f822344f37bc 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/rsc +## 1.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 1.0.41 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index f92b8fefee47..754fca373291 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.41", + "version": "1.0.42", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 8342a8fbd8b4..405103b71b3a 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [de5c066] + - ai@5.0.42 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [cd91e4b] - ai@5.0.41 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 0dda004b7234..557ac02ade75 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/svelte +## 3.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 3.0.41 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 668a20cc8fa5..cd86f34b81e1 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.41", + "version": "3.0.42", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 4f6d2176a59a..86b05b784fd7 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 2.0.42 + +### Patch Changes + +- Updated dependencies [de5c066] + - ai@5.0.42 + ## 2.0.41 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 7a49765e7dad..00b5e57e9655 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.41", + "version": "2.0.42", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 90b13f8376a9ddaa8b17f11864f317b3ee22330b Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Fri, 12 Sep 2025 16:06:38 +0200 Subject: [PATCH 017/121] refactoring(provider/openai): rename responses conversion to input (#8608) ## Background The OpenAI responses API calls the inputs `input`. We should align our API terminology to avoid confusion. ## Summary * rename input conversion to `convertToOpenAIResponsesInput` * rename API types accordingly ## Related Issues Discovered during #8604 --- ...convert-to-openai-responses-input.test.ts} | 170 +++++++++--------- ...s => convert-to-openai-responses-input.ts} | 35 ++-- .../responses/openai-responses-api-types.ts | 36 ++-- .../openai-responses-language-model.ts | 10 +- 4 files changed, 132 insertions(+), 119 deletions(-) rename packages/openai/src/responses/{convert-to-openai-responses-messages.test.ts => convert-to-openai-responses-input.test.ts} (90%) rename packages/openai/src/responses/{convert-to-openai-responses-messages.ts => convert-to-openai-responses-input.ts} (90%) diff --git a/packages/openai/src/responses/convert-to-openai-responses-messages.test.ts b/packages/openai/src/responses/convert-to-openai-responses-input.test.ts similarity index 90% rename from packages/openai/src/responses/convert-to-openai-responses-messages.test.ts rename to packages/openai/src/responses/convert-to-openai-responses-input.test.ts index 65133229f32f..50285d216ae3 100644 --- a/packages/openai/src/responses/convert-to-openai-responses-messages.test.ts +++ b/packages/openai/src/responses/convert-to-openai-responses-input.test.ts @@ -1,41 +1,39 @@ -import { convertToOpenAIResponsesMessages } from './convert-to-openai-responses-messages'; +import { convertToOpenAIResponsesInput } from './convert-to-openai-responses-input'; import { describe, it, expect } from 'vitest'; -describe('convertToOpenAIResponsesMessages', () => { +describe('convertToOpenAIResponsesInput', () => { describe('system messages', () => { it('should convert system messages to system role', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [{ role: 'system', content: 'Hello' }], systemMessageMode: 'system', }); - expect(result.messages).toEqual([{ role: 'system', content: 'Hello' }]); + expect(result.input).toEqual([{ role: 'system', content: 'Hello' }]); }); it('should convert system messages to developer role', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [{ role: 'system', content: 'Hello' }], systemMessageMode: 'developer', }); - expect(result.messages).toEqual([ - { role: 'developer', content: 'Hello' }, - ]); + expect(result.input).toEqual([{ role: 'developer', content: 'Hello' }]); }); it('should remove system messages', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [{ role: 'system', content: 'Hello' }], systemMessageMode: 'remove', }); - expect(result.messages).toEqual([]); + expect(result.input).toEqual([]); }); }); describe('user messages', () => { it('should convert messages with only a text part to a string content', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -45,13 +43,13 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [{ type: 'input_text', text: 'Hello' }] }, ]); }); it('should convert messages with image parts using URL', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -68,7 +66,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -83,7 +81,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert messages with image parts using binary data', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -99,7 +97,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -113,7 +111,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert messages with image parts using Uint8Array', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -129,7 +127,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -143,7 +141,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert messages with image parts using file_id', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -160,7 +158,7 @@ describe('convertToOpenAIResponsesMessages', () => { fileIdPrefixes: ['file-'], }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -174,7 +172,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should use default mime type for binary images', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -190,7 +188,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -204,7 +202,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should add image detail when specified through extension', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -225,7 +223,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -242,7 +240,7 @@ describe('convertToOpenAIResponsesMessages', () => { it('should convert messages with PDF file parts', async () => { const base64Data = 'AQIDBAU='; // Base64 encoding of pdfData - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -259,7 +257,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -274,7 +272,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert messages with PDF file parts using file_id', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -291,7 +289,7 @@ describe('convertToOpenAIResponsesMessages', () => { fileIdPrefixes: ['file-'], }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -307,7 +305,7 @@ describe('convertToOpenAIResponsesMessages', () => { it('should use default filename for PDF file parts when not provided', async () => { const base64Data = 'AQIDBAU='; - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -323,7 +321,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -341,7 +339,7 @@ describe('convertToOpenAIResponsesMessages', () => { const base64Data = 'AQIDBAU='; await expect( - convertToOpenAIResponsesMessages({ + convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -360,7 +358,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert PDF file parts with URL to input_file with file_url', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -376,7 +374,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -391,7 +389,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('Azure OpenAI file ID support', () => { it('should convert image parts with assistant- prefix', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -408,7 +406,7 @@ describe('convertToOpenAIResponsesMessages', () => { fileIdPrefixes: ['assistant-'], }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -422,7 +420,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert PDF parts with assistant- prefix', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -439,7 +437,7 @@ describe('convertToOpenAIResponsesMessages', () => { fileIdPrefixes: ['assistant-'], }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -453,7 +451,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should support multiple file ID prefixes', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -475,7 +473,7 @@ describe('convertToOpenAIResponsesMessages', () => { fileIdPrefixes: ['assistant-', 'file-'], }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -495,7 +493,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('fileIdPrefixes undefined behavior', () => { it('should treat all file data as base64 when fileIdPrefixes is undefined', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -518,7 +516,7 @@ describe('convertToOpenAIResponsesMessages', () => { // fileIdPrefixes intentionally omitted }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -537,7 +535,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should handle empty fileIdPrefixes array', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -554,7 +552,7 @@ describe('convertToOpenAIResponsesMessages', () => { fileIdPrefixes: [], // Empty array should disable file ID detection }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [ @@ -571,14 +569,14 @@ describe('convertToOpenAIResponsesMessages', () => { describe('assistant messages', () => { it('should convert messages with only a text part to a string content', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', content: [{ type: 'text', text: 'Hello' }] }, ], systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'assistant', content: [{ type: 'output_text', text: 'Hello' }], @@ -587,7 +585,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert messages with tool call parts', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -605,7 +603,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'assistant', content: [ @@ -625,7 +623,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert messages with tool call parts that have ids', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -656,7 +654,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toMatchInlineSnapshot(` + expect(result.input).toMatchInlineSnapshot(` [ { "content": [ @@ -680,7 +678,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert multiple tool call parts in a single message', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -703,7 +701,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'function_call', call_id: 'call_123', @@ -722,7 +720,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('reasoning messages', () => { describe('basic conversion', () => { it('should convert single reasoning part with text', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -742,7 +740,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -760,7 +758,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert single reasoning part with encrypted content', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -781,7 +779,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -799,7 +797,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert single reasoning part with null encrypted content', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -820,7 +818,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -840,7 +838,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('empty text handling', () => { it('should create empty summary for initial empty text', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -860,7 +858,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -873,7 +871,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should create empty summary for initial empty text with encrypted content', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -894,7 +892,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -907,7 +905,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should warn when appending empty text to existing sequence', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -936,7 +934,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -963,7 +961,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('merging and sequencing', () => { it('should merge consecutive parts with same reasoning ID', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -992,7 +990,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -1014,7 +1012,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should create separate messages for different reasoning IDs', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -1043,7 +1041,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'reasoning', id: 'reasoning_001', @@ -1072,7 +1070,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should handle reasoning across multiple assistant messages', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'user', @@ -1125,7 +1123,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { role: 'user', content: [{ type: 'input_text', text: 'First user question' }], @@ -1174,7 +1172,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should handle complex reasoning sequences with tool interactions', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -1296,7 +1294,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ // First reasoning block (2 parts merged) { type: 'reasoning', @@ -1377,7 +1375,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('error handling', () => { it('should warn when reasoning part has no provider options', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -1392,7 +1390,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toHaveLength(0); + expect(result.input).toHaveLength(0); expect(result.warnings).toMatchInlineSnapshot(` [ @@ -1405,7 +1403,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should warn when reasoning part lacks OpenAI-specific reasoning ID provider options', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -1427,7 +1425,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toHaveLength(0); + expect(result.input).toHaveLength(0); expect(result.warnings).toMatchInlineSnapshot(` [ @@ -1444,7 +1442,7 @@ describe('convertToOpenAIResponsesMessages', () => { describe('tool messages', () => { it('should convert tool result parts', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'tool', @@ -1464,7 +1462,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'function_call_output', call_id: 'call_123', @@ -1474,7 +1472,7 @@ describe('convertToOpenAIResponsesMessages', () => { }); it('should convert multiple tool result parts in a single message', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'tool', @@ -1500,7 +1498,7 @@ describe('convertToOpenAIResponsesMessages', () => { systemMessageMode: 'system', }); - expect(result.messages).toEqual([ + expect(result.input).toEqual([ { type: 'function_call_output', call_id: 'call_123', @@ -1515,9 +1513,9 @@ describe('convertToOpenAIResponsesMessages', () => { }); }); - describe('provider-executed tool calls', () => { - it('should exclude provider-executed tool calls and results from prompt', async () => { - const result = await convertToOpenAIResponsesMessages({ + describe('web search tool', () => { + it('should exclude web search tool calls and results from prompt', async () => { + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -1560,7 +1558,7 @@ describe('convertToOpenAIResponsesMessages', () => { expect(result).toMatchInlineSnapshot(` { - "messages": [ + "input": [ { "content": [ { @@ -1591,9 +1589,11 @@ describe('convertToOpenAIResponsesMessages', () => { } `); }); + }); + describe('function tools', () => { it('should include client-side tool calls in prompt', async () => { - const result = await convertToOpenAIResponsesMessages({ + const result = await convertToOpenAIResponsesInput({ prompt: [ { role: 'assistant', @@ -1613,7 +1613,7 @@ describe('convertToOpenAIResponsesMessages', () => { expect(result).toMatchInlineSnapshot(` { - "messages": [ + "input": [ { "arguments": "{"a":1,"b":2}", "call_id": "call-1", diff --git a/packages/openai/src/responses/convert-to-openai-responses-messages.ts b/packages/openai/src/responses/convert-to-openai-responses-input.ts similarity index 90% rename from packages/openai/src/responses/convert-to-openai-responses-messages.ts rename to packages/openai/src/responses/convert-to-openai-responses-input.ts index 12dc8eb957f2..44226658e134 100644 --- a/packages/openai/src/responses/convert-to-openai-responses-messages.ts +++ b/packages/openai/src/responses/convert-to-openai-responses-input.ts @@ -1,15 +1,19 @@ import { LanguageModelV2CallWarning, LanguageModelV2Prompt, + LanguageModelV2ToolCallPart, UnsupportedFunctionalityError, } from '@ai-sdk/provider'; -import { parseProviderOptions } from '@ai-sdk/provider-utils'; +import { convertToBase64, parseProviderOptions } from '@ai-sdk/provider-utils'; import { z } from 'zod/v4'; import { - OpenAIResponsesPrompt, + OpenAIResponsesInput, OpenAIResponsesReasoning, } from './openai-responses-api-types'; -import { convertToBase64 } from '@ai-sdk/provider-utils'; +import { + codeInterpreterInputSchema, + codeInterpreterOutputSchema, +} from '../tool/code-interpreter'; /** * Check if a string is a file ID based on the given prefixes @@ -20,7 +24,7 @@ function isFileId(data: string, prefixes?: readonly string[]): boolean { return prefixes.some(prefix => data.startsWith(prefix)); } -export async function convertToOpenAIResponsesMessages({ +export async function convertToOpenAIResponsesInput({ prompt, systemMessageMode, fileIdPrefixes, @@ -29,10 +33,10 @@ export async function convertToOpenAIResponsesMessages({ systemMessageMode: 'system' | 'developer' | 'remove'; fileIdPrefixes?: readonly string[]; }): Promise<{ - messages: OpenAIResponsesPrompt; + input: OpenAIResponsesInput; warnings: Array; }> { - const messages: OpenAIResponsesPrompt = []; + const input: OpenAIResponsesInput = []; const warnings: Array = []; for (const { role, content } of prompt) { @@ -40,11 +44,11 @@ export async function convertToOpenAIResponsesMessages({ case 'system': { switch (systemMessageMode) { case 'system': { - messages.push({ role: 'system', content }); + input.push({ role: 'system', content }); break; } case 'developer': { - messages.push({ role: 'developer', content }); + input.push({ role: 'developer', content }); break; } case 'remove': { @@ -65,7 +69,7 @@ export async function convertToOpenAIResponsesMessages({ } case 'user': { - messages.push({ + input.push({ role: 'user', content: content.map((part, index) => { switch (part.type) { @@ -123,11 +127,12 @@ export async function convertToOpenAIResponsesMessages({ case 'assistant': { const reasoningMessages: Record = {}; + const toolCallParts: Record = {}; for (const part of content) { switch (part.type) { case 'text': { - messages.push({ + input.push({ role: 'assistant', content: [{ type: 'output_text', text: part.text }], id: @@ -136,11 +141,13 @@ export async function convertToOpenAIResponsesMessages({ break; } case 'tool-call': { + toolCallParts[part.toolCallId] = part; + if (part.providerExecuted) { break; } - messages.push({ + input.push({ type: 'function_call', call_id: part.toolCallId, name: part.toolName, @@ -193,7 +200,7 @@ export async function convertToOpenAIResponsesMessages({ providerOptions?.reasoningEncryptedContent, summary: summaryParts, }; - messages.push(reasoningMessages[reasoningId]); + input.push(reasoningMessages[reasoningId]); } else { existingReasoningMessage.summary.push(...summaryParts); } @@ -228,7 +235,7 @@ export async function convertToOpenAIResponsesMessages({ break; } - messages.push({ + input.push({ type: 'function_call_output', call_id: part.toolCallId, output: contentValue, @@ -245,7 +252,7 @@ export async function convertToOpenAIResponsesMessages({ } } - return { messages, warnings }; + return { input, warnings }; } const openaiResponsesReasoningProviderOptionsSchema = z.object({ diff --git a/packages/openai/src/responses/openai-responses-api-types.ts b/packages/openai/src/responses/openai-responses-api-types.ts index 049ccb1d5da3..57182979d029 100644 --- a/packages/openai/src/responses/openai-responses-api-types.ts +++ b/packages/openai/src/responses/openai-responses-api-types.ts @@ -1,17 +1,18 @@ import { JSONSchema7 } from '@ai-sdk/provider'; -export type OpenAIResponsesPrompt = Array; +export type OpenAIResponsesInput = Array; -export type OpenAIResponsesMessage = +export type OpenAIResponsesInputItem = | OpenAIResponsesSystemMessage | OpenAIResponsesUserMessage | OpenAIResponsesAssistantMessage | OpenAIResponsesFunctionCall | OpenAIResponsesFunctionCallOutput - | OpenAIWebSearchCall - | OpenAIComputerCall - | OpenAIFileSearchCall - | OpenAIResponsesReasoning; + | OpenAIResponsesWebSearchCall + | OpenAIResponsesComputerCall + | OpenAIResponsesFileSearchCall + | OpenAIResponsesReasoning + | OpenAIResponsesCodeInterpreterCall; export type OpenAIResponsesIncludeOptions = | Array< @@ -45,12 +46,7 @@ export type OpenAIResponsesUserMessage = { export type OpenAIResponsesAssistantMessage = { role: 'assistant'; - content: Array< - | { type: 'output_text'; text: string } - | OpenAIWebSearchCall - | OpenAIComputerCall - | OpenAIFileSearchCall - >; + content: Array<{ type: 'output_text'; text: string }>; id?: string; }; @@ -68,19 +64,29 @@ export type OpenAIResponsesFunctionCallOutput = { output: string; }; -export type OpenAIWebSearchCall = { +export type OpenAIResponsesWebSearchCall = { type: 'web_search_call'; id: string; status?: string; }; -export type OpenAIComputerCall = { +export type OpenAIResponsesComputerCall = { type: 'computer_call'; id: string; status?: string; }; -export type OpenAIFileSearchCall = { +export type OpenAIResponsesCodeInterpreterCall = { + type: 'code_interpreter_call'; + container_id: string; + id: string; + code: string | null; + outputs: Array< + { type: 'logs'; logs: string } | { type: 'image'; url: string } + > | null; +}; + +export type OpenAIResponsesFileSearchCall = { type: 'file_search_call'; id: string; status?: string; diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index 62a86d1f8ad9..e3d730c8db79 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -25,7 +25,7 @@ import { codeInterpreterInputSchema, codeInterpreterOutputSchema, } from '../tool/code-interpreter'; -import { convertToOpenAIResponsesMessages } from './convert-to-openai-responses-messages'; +import { convertToOpenAIResponsesInput } from './convert-to-openai-responses-input'; import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason'; import { OpenAIResponsesIncludeOptions } from './openai-responses-api-types'; import { prepareResponsesTools } from './openai-responses-prepare-tools'; @@ -156,14 +156,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { warnings.push({ type: 'unsupported-setting', setting: 'stopSequences' }); } - const { messages, warnings: messageWarnings } = - await convertToOpenAIResponsesMessages({ + const { input, warnings: inputWarnings } = + await convertToOpenAIResponsesInput({ prompt, systemMessageMode: modelConfig.systemMessageMode, fileIdPrefixes: this.config.fileIdPrefixes, }); - warnings.push(...messageWarnings); + warnings.push(...inputWarnings); const openaiOptions = await parseProviderOptions({ provider: 'openai', @@ -222,7 +222,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { const baseArgs = { model: this.modelId, - input: messages, + input, temperature, top_p: topP, max_output_tokens: maxOutputTokens, From 0294b585b04daa3136fcd9a0f341578528bf67de Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 12 Sep 2025 12:52:29 -0700 Subject: [PATCH 018/121] feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header (#8530) ## Background Setting a custom user agent is considered best practice and would help debug problems in case any occur. As suggested by @gr2m, `ai` is not setting a custom user agent right now. This is an alternative approach to #8472. ## Summary - export new `createUserAgentFetch()` and `withUserAgentSuffix()` helper methods - add `__PACKAGE_VERSION__` to each core package and inject it at build time - pass current `ai/x.y.z` version through the headers argument in all methods exported by `ai` - updated test files, with updated snapshots - expected behavior after this change is: - `user-agent` in the `Headers` with the syntax: `ai/ @ai-sdk/provider/ @ai-sdk/provider-utils/ ` ## Manual Verification Running `examples/ai-core/fetch-user-agent/user-agent.ts` simulates a mock call being made to an echo server with our new `createUserAgentFetch()` method. Output shows a user-agent header with the correct versions being set. ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Future work - https://github.com/vercel/ai/issues/8595 ## Related Issues closes #8419 closes #8472 --------- Co-authored-by: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> --- .changeset/seven-zoos-suffer.md | 6 + .../generate-object/openai-request-headers.ts | 39 +++++ .../__snapshots__/embed-many.test.ts.snap | 7 + .../embed/__snapshots__/embed.test.ts.snap | 4 + packages/ai/src/embed/embed-many.test.ts | 15 +- packages/ai/src/embed/embed-many.ts | 14 +- packages/ai/src/embed/embed.test.ts | 13 +- packages/ai/src/embed/embed.ts | 12 +- .../src/generate-image/generate-image.test.ts | 52 +++++- .../ai/src/generate-image/generate-image.ts | 10 +- .../generate-object.test.ts.snap | 4 + .../generate-object/generate-object.test.ts | 19 +- .../ai/src/generate-object/generate-object.ts | 11 +- .../generate-speech/generate-speech.test.ts | 27 ++- .../ai/src/generate-speech/generate-speech.ts | 11 +- .../__snapshots__/generate-text.test.ts.snap | 4 + .../src/generate-text/generate-text.test.ts | 165 ++++++++++-------- .../ai/src/generate-text/generate-text.ts | 11 +- packages/ai/src/transcribe/transcribe.test.ts | 27 ++- packages/ai/src/transcribe/transcribe.ts | 11 +- packages/ai/src/version.ts | 5 + packages/ai/tsup.config.ts | 24 +++ packages/ai/vitest.edge.config.js | 8 + packages/ai/vitest.node.config.js | 8 + .../provider-utils/src/get-from-api.test.ts | 24 ++- packages/provider-utils/src/get-from-api.ts | 10 +- ...get-runtime-environment-user-agent.test.ts | 47 +++++ .../src/get-runtime-environment-user-agent.ts | 24 +++ packages/provider-utils/src/index.ts | 5 + packages/provider-utils/src/post-to-api.ts | 10 +- .../provider-utils/src/test/test-server.ts | 1 + packages/provider-utils/src/version.ts | 6 + .../src/with-user-agent-suffix.test.ts | 58 ++++++ .../src/with-user-agent-suffix.ts | 30 ++++ packages/provider-utils/tsup.config.ts | 12 ++ pnpm-lock.yaml | 12 +- 36 files changed, 618 insertions(+), 128 deletions(-) create mode 100644 .changeset/seven-zoos-suffer.md create mode 100644 examples/ai-core/src/generate-object/openai-request-headers.ts create mode 100644 packages/ai/src/version.ts create mode 100644 packages/provider-utils/src/get-runtime-environment-user-agent.test.ts create mode 100644 packages/provider-utils/src/get-runtime-environment-user-agent.ts create mode 100644 packages/provider-utils/src/version.ts create mode 100644 packages/provider-utils/src/with-user-agent-suffix.test.ts create mode 100644 packages/provider-utils/src/with-user-agent-suffix.ts diff --git a/.changeset/seven-zoos-suffer.md b/.changeset/seven-zoos-suffer.md new file mode 100644 index 000000000000..2f4e6051a83b --- /dev/null +++ b/.changeset/seven-zoos-suffer.md @@ -0,0 +1,6 @@ +--- +'@ai-sdk/provider-utils': patch +'ai': patch +--- + +feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header diff --git a/examples/ai-core/src/generate-object/openai-request-headers.ts b/examples/ai-core/src/generate-object/openai-request-headers.ts new file mode 100644 index 000000000000..81f02ff1ab04 --- /dev/null +++ b/examples/ai-core/src/generate-object/openai-request-headers.ts @@ -0,0 +1,39 @@ +import { createOpenAI } from '@ai-sdk/openai'; +import { generateObject } from 'ai'; +import 'dotenv/config'; +import { z } from 'zod'; + +async function main() { + let headers; + const openai = createOpenAI({ + fetch: (url, init) => { + headers = { + ...init?.headers, + authorization: 'REDACTED', + }; + return fetch(url, init); + }, + }); + const options = { + model: openai('gpt-4o-mini'), + schema: z.object({ + recipe: z.object({ + name: z.string(), + ingredients: z.array( + z.object({ + name: z.string(), + amount: z.string(), + }), + ), + steps: z.array(z.string()), + }), + }), + prompt: 'Generate a lasagna recipe.', + }; + await generateObject(options); + + console.log('REQUEST HEADERS'); + console.log(headers); +} + +main().catch(console.error); diff --git a/packages/ai/src/embed/__snapshots__/embed-many.test.ts.snap b/packages/ai/src/embed/__snapshots__/embed-many.test.ts.snap index 449bc194042b..e028b64865ec 100644 --- a/packages/ai/src/embed/__snapshots__/embed-many.test.ts.snap +++ b/packages/ai/src/embed/__snapshots__/embed-many.test.ts.snap @@ -27,6 +27,7 @@ exports[`telemetry > should not record telemetry inputs / outputs when disabled "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.usage.tokens": 10, "operation.name": "ai.embedMany", @@ -39,6 +40,7 @@ exports[`telemetry > should not record telemetry inputs / outputs when disabled "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany.doEmbed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.usage.tokens": 10, "operation.name": "ai.embedMany.doEmbed", @@ -61,6 +63,7 @@ exports[`telemetry > should record telemetry data when enabled (multiple calls p "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", @@ -86,6 +89,7 @@ exports[`telemetry > should record telemetry data when enabled (multiple calls p "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany.doEmbed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", @@ -109,6 +113,7 @@ exports[`telemetry > should record telemetry data when enabled (multiple calls p "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany.doEmbed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", @@ -138,6 +143,7 @@ exports[`telemetry > should record telemetry data when enabled (single call path "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", @@ -164,6 +170,7 @@ exports[`telemetry > should record telemetry data when enabled (single call path "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embedMany.doEmbed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", diff --git a/packages/ai/src/embed/__snapshots__/embed.test.ts.snap b/packages/ai/src/embed/__snapshots__/embed.test.ts.snap index cb41f8f95dba..eb32140c247c 100644 --- a/packages/ai/src/embed/__snapshots__/embed.test.ts.snap +++ b/packages/ai/src/embed/__snapshots__/embed.test.ts.snap @@ -9,6 +9,7 @@ exports[`telemetry > should not record telemetry inputs / outputs when disabled "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.usage.tokens": 10, "operation.name": "ai.embed", @@ -21,6 +22,7 @@ exports[`telemetry > should not record telemetry inputs / outputs when disabled "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embed.doEmbed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.usage.tokens": 10, "operation.name": "ai.embed.doEmbed", @@ -39,6 +41,7 @@ exports[`telemetry > should record telemetry data when enabled 1`] = ` "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", @@ -59,6 +62,7 @@ exports[`telemetry > should record telemetry data when enabled 1`] = ` "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.embed.doEmbed", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.settings.maxRetries": 2, "ai.telemetry.functionId": "test-function-id", "ai.telemetry.metadata.test1": "value1", diff --git a/packages/ai/src/embed/embed-many.test.ts b/packages/ai/src/embed/embed-many.test.ts index 4acc73d736e4..e72d2c288cfb 100644 --- a/packages/ai/src/embed/embed-many.test.ts +++ b/packages/ai/src/embed/embed-many.test.ts @@ -7,6 +7,12 @@ import { Embedding, EmbeddingModelUsage } from '../types'; import { createResolvablePromise } from '../util/create-resolvable-promise'; import { embedMany } from './embed-many'; +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + const dummyEmbeddings = [ [0.1, 0.2, 0.3], [0.4, 0.5, 0.6], @@ -303,13 +309,16 @@ describe('options.headers', () => { doEmbed: async ({ headers }) => { assert.deepStrictEqual(headers, { 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', }); return { embeddings: dummyEmbeddings }; }, }), values: testValues, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, }); assert.deepStrictEqual(result.embeddings, dummyEmbeddings); @@ -336,7 +345,9 @@ describe('options.providerOptions', () => { expect(model.doEmbed).toHaveBeenCalledWith({ abortSignal: undefined, - headers: undefined, + headers: { + 'user-agent': 'ai/0.0.0-test', + }, providerOptions: { aProvider: { someKey: 'someValue' }, }, diff --git a/packages/ai/src/embed/embed-many.ts b/packages/ai/src/embed/embed-many.ts index 98cd420a63da..1fbe717a880e 100644 --- a/packages/ai/src/embed/embed-many.ts +++ b/packages/ai/src/embed/embed-many.ts @@ -1,4 +1,4 @@ -import { ProviderOptions } from '@ai-sdk/provider-utils'; +import { ProviderOptions, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { prepareRetries } from '../util/prepare-retries'; import { splitArray } from '../util/split-array'; import { UnsupportedModelVersionError } from '../error/unsupported-model-version-error'; @@ -11,6 +11,7 @@ import { TelemetrySettings } from '../telemetry/telemetry-settings'; import { Embedding, EmbeddingModel, ProviderMetadata } from '../types'; import { resolveEmbeddingModel } from '../model/resolve-model'; import { EmbedManyResult } from './embed-many-result'; +import { VERSION } from '../version'; /** Embed several values using an embedding model. The type of the value is defined @@ -92,10 +93,15 @@ Only applicable for HTTP-based providers. abortSignal, }); + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const baseTelemetryAttributes = getBaseTelemetryAttributes({ model, telemetry, - headers, + headers: headersWithUserAgent, settings: { maxRetries }, }); @@ -148,7 +154,7 @@ Only applicable for HTTP-based providers. const modelResponse = await model.doEmbed({ values, abortSignal, - headers, + headers: headersWithUserAgent, providerOptions, }); @@ -249,7 +255,7 @@ Only applicable for HTTP-based providers. const modelResponse = await model.doEmbed({ values: chunk, abortSignal, - headers, + headers: headersWithUserAgent, providerOptions, }); diff --git a/packages/ai/src/embed/embed.test.ts b/packages/ai/src/embed/embed.test.ts index 1138acb82f93..9fd478c68af6 100644 --- a/packages/ai/src/embed/embed.test.ts +++ b/packages/ai/src/embed/embed.test.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV2 } from '@ai-sdk/provider'; import assert from 'node:assert'; -import { beforeEach, describe, expect, it } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; import { MockTracer } from '../test/mock-tracer'; import { Embedding, EmbeddingModelUsage } from '../types'; @@ -9,6 +9,12 @@ import { embed } from './embed'; const dummyEmbedding = [0.1, 0.2, 0.3]; const testValue = 'sunny day at the beach'; +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + describe('result.embedding', () => { it('should generate embedding', async () => { const result = await embed({ @@ -110,13 +116,16 @@ describe('options.headers', () => { doEmbed: async ({ headers }) => { assert.deepStrictEqual(headers, { 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', }); return { embeddings: [dummyEmbedding] }; }, }), value: testValue, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, }); assert.deepStrictEqual(result.embedding, dummyEmbedding); diff --git a/packages/ai/src/embed/embed.ts b/packages/ai/src/embed/embed.ts index 7d547540475c..6c3027ad1d03 100644 --- a/packages/ai/src/embed/embed.ts +++ b/packages/ai/src/embed/embed.ts @@ -1,4 +1,4 @@ -import { ProviderOptions } from '@ai-sdk/provider-utils'; +import { ProviderOptions, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { resolveEmbeddingModel } from '../model/resolve-model'; import { assembleOperationName } from '../telemetry/assemble-operation-name'; import { getBaseTelemetryAttributes } from '../telemetry/get-base-telemetry-attributes'; @@ -9,6 +9,7 @@ import { TelemetrySettings } from '../telemetry/telemetry-settings'; import { EmbeddingModel } from '../types'; import { prepareRetries } from '../util/prepare-retries'; import { EmbedResult } from './embed-result'; +import { VERSION } from '../version'; /** Embed a value using an embedding model. The type of the value is defined by the embedding model. @@ -78,10 +79,15 @@ Only applicable for HTTP-based providers. abortSignal, }); + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const baseTelemetryAttributes = getBaseTelemetryAttributes({ model: model, telemetry, - headers, + headers: headersWithUserAgent, settings: { maxRetries }, }); @@ -120,7 +126,7 @@ Only applicable for HTTP-based providers. const modelResponse = await model.doEmbed({ values: [value], abortSignal, - headers, + headers: headersWithUserAgent, providerOptions, }); diff --git a/packages/ai/src/generate-image/generate-image.test.ts b/packages/ai/src/generate-image/generate-image.test.ts index a08683a65483..c5f99b082f5d 100644 --- a/packages/ai/src/generate-image/generate-image.test.ts +++ b/packages/ai/src/generate-image/generate-image.test.ts @@ -14,6 +14,7 @@ import { expect, it, test, + vi, vitest, } from 'vitest'; import * as logWarningsModule from '../logger/log-warnings'; @@ -29,6 +30,12 @@ const jpegBase64 = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABmX/9k='; // 1x1 black JPEG const gifBase64 = 'R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='; // 1x1 transparent GIF +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + const createMockResponse = (options: { images: string[] | Uint8Array[]; warnings?: ImageModelV2CallWarning[]; @@ -88,7 +95,9 @@ describe('generateImage', () => { style: 'vivid', }, }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, abortSignal, }); @@ -99,7 +108,10 @@ describe('generateImage', () => { aspectRatio: '16:9', seed: 12345, providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal, }); }); @@ -325,7 +337,10 @@ describe('generateImage', () => { providerOptions: { 'mock-provider': { style: 'vivid' }, }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal: undefined, }); return createMockResponse({ @@ -339,7 +354,10 @@ describe('generateImage', () => { size: '1024x1024', aspectRatio: '16:9', providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal: undefined, }); return createMockResponse({ @@ -356,7 +374,9 @@ describe('generateImage', () => { aspectRatio: '16:9', seed: 12345, providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, }); expect(result.images.map(image => image.base64)).toStrictEqual( @@ -382,7 +402,10 @@ describe('generateImage', () => { size: '1024x1024', aspectRatio: '16:9', providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal: undefined, }); return createMockResponse({ @@ -397,7 +420,10 @@ describe('generateImage', () => { size: '1024x1024', aspectRatio: '16:9', providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal: undefined, }); return createMockResponse({ @@ -415,7 +441,9 @@ describe('generateImage', () => { aspectRatio: '16:9', seed: 12345, providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, }); expect(result.warnings).toStrictEqual([ @@ -452,6 +480,7 @@ describe('generateImage', () => { }, headers: { 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', }, abortSignal: undefined, }); @@ -468,6 +497,7 @@ describe('generateImage', () => { providerOptions: { 'mock-provider': { style: 'vivid' } }, headers: { 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', }, abortSignal: undefined, }); @@ -485,7 +515,9 @@ describe('generateImage', () => { aspectRatio: '16:9', seed: 12345, providerOptions: { 'mock-provider': { style: 'vivid' } }, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, }); expect(result.images.map(image => image.base64)).toStrictEqual( @@ -534,6 +566,7 @@ describe('generateImage', () => { timestamp: testDate, headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, }), }), @@ -548,6 +581,7 @@ describe('generateImage', () => { modelId: expect.any(String), headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, }, ], diff --git a/packages/ai/src/generate-image/generate-image.ts b/packages/ai/src/generate-image/generate-image.ts index 8f938b9b0e00..262032c90039 100644 --- a/packages/ai/src/generate-image/generate-image.ts +++ b/packages/ai/src/generate-image/generate-image.ts @@ -1,5 +1,5 @@ import { ImageModelV2, ImageModelV2ProviderMetadata } from '@ai-sdk/provider'; -import { ProviderOptions } from '@ai-sdk/provider-utils'; +import { ProviderOptions, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { NoImageGeneratedError } from '../error/no-image-generated-error'; import { detectMediaType, @@ -15,6 +15,7 @@ import { ImageGenerationWarning } from '../types/image-model'; import { ImageModelResponseMetadata } from '../types/image-model-response-metadata'; import { GenerateImageResult } from './generate-image-result'; import { logWarnings } from '../logger/log-warnings'; +import { VERSION } from '../version'; /** Generates images using an image model. @@ -123,6 +124,11 @@ Only applicable for HTTP-based providers. }); } + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const { retry } = prepareRetries({ maxRetries: maxRetriesArg, abortSignal, @@ -151,7 +157,7 @@ Only applicable for HTTP-based providers. prompt, n: callImageCount, abortSignal, - headers, + headers: headersWithUserAgent, size, aspectRatio, seed, diff --git a/packages/ai/src/generate-object/__snapshots__/generate-object.test.ts.snap b/packages/ai/src/generate-object/__snapshots__/generate-object.test.ts.snap index e5d90ec7e305..dcd7676a2e73 100644 --- a/packages/ai/src/generate-object/__snapshots__/generate-object.test.ts.snap +++ b/packages/ai/src/generate-object/__snapshots__/generate-object.test.ts.snap @@ -7,6 +7,7 @@ exports[`generateObject > telemetry > should not record telemetry inputs / outpu "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.generateObject", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.settings.maxRetries": 2, "ai.settings.output": "object", @@ -22,6 +23,7 @@ exports[`generateObject > telemetry > should not record telemetry inputs / outpu "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.generateObject.doGenerate", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.id": "test-id-from-model", "ai.response.model": "test-response-model-id", @@ -56,6 +58,7 @@ exports[`generateObject > telemetry > should record telemetry data when enabled "ai.prompt": "{"prompt":"prompt"}", "ai.request.headers.header1": "value1", "ai.request.headers.header2": "value2", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.object": "{"content":"Hello, world!"}", "ai.response.providerMetadata": "{"testProvider":{"testKey":"testValue"}}", @@ -88,6 +91,7 @@ exports[`generateObject > telemetry > should record telemetry data when enabled "ai.prompt.messages": "[{"role":"user","content":[{"type":"text","text":"prompt"}]}]", "ai.request.headers.header1": "value1", "ai.request.headers.header2": "value2", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.id": "test-id-from-model", "ai.response.model": "test-response-model-id", diff --git a/packages/ai/src/generate-object/generate-object.test.ts b/packages/ai/src/generate-object/generate-object.test.ts index 4481fa566f9c..f995d76d0e6c 100644 --- a/packages/ai/src/generate-object/generate-object.test.ts +++ b/packages/ai/src/generate-object/generate-object.test.ts @@ -6,7 +6,15 @@ import { import { jsonSchema } from '@ai-sdk/provider-utils'; import { convertReadableStreamToArray } from '@ai-sdk/provider-utils/test'; import assert, { fail } from 'node:assert'; -import { afterEach, beforeEach, describe, expect, it, vitest } from 'vitest'; +import { + afterEach, + beforeEach, + describe, + expect, + it, + vitest, + vi, +} from 'vitest'; import { z } from 'zod/v4'; import { verifyNoObjectGeneratedError as originalVerifyNoObjectGeneratedError } from '../error/verify-no-object-generated-error'; import * as logWarningsModule from '../logger/log-warnings'; @@ -14,6 +22,12 @@ import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { MockTracer } from '../test/mock-tracer'; import { generateObject } from './generate-object'; +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + const dummyResponseValues = { finishReason: 'stop' as const, usage: { @@ -250,6 +264,7 @@ describe('generateObject', () => { modelId: 'test-response-model-id', headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, body: 'test body', }, @@ -265,6 +280,7 @@ describe('generateObject', () => { modelId: 'test-response-model-id', headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, body: 'test body', }); @@ -523,6 +539,7 @@ describe('generateObject', () => { doGenerate: async ({ headers }) => { expect(headers).toStrictEqual({ 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', }); return { diff --git a/packages/ai/src/generate-object/generate-object.ts b/packages/ai/src/generate-object/generate-object.ts index 9a1e6925f5c2..4fc552aa0156 100644 --- a/packages/ai/src/generate-object/generate-object.ts +++ b/packages/ai/src/generate-object/generate-object.ts @@ -4,6 +4,7 @@ import { InferSchema, ProviderOptions, Schema, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import * as z3 from 'zod/v3'; import * as z4 from 'zod/v4'; @@ -42,6 +43,7 @@ import { getOutputStrategy } from './output-strategy'; import { parseAndValidateObjectResultWithRepair } from './parse-and-validate-object-result'; import { RepairTextFunction } from './repair-text'; import { validateObjectGenerationInput } from './validate-object-generation-input'; +import { VERSION } from '../version'; const originalGenerateId = createIdGenerator({ prefix: 'aiobj', size: 24 }); @@ -262,10 +264,15 @@ Default and recommended: 'auto' (best mode for the model). const callSettings = prepareCallSettings(settings); + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const baseTelemetryAttributes = getBaseTelemetryAttributes({ model, telemetry, - headers, + headers: headersWithUserAgent, settings: { ...callSettings, maxRetries }, }); @@ -358,7 +365,7 @@ Default and recommended: 'auto' (best mode for the model). prompt: promptMessages, providerOptions, abortSignal, - headers, + headers: headersWithUserAgent, }); const responseData = { diff --git a/packages/ai/src/generate-speech/generate-speech.test.ts b/packages/ai/src/generate-speech/generate-speech.test.ts index bf781d25eeee..66812fb5db7c 100644 --- a/packages/ai/src/generate-speech/generate-speech.test.ts +++ b/packages/ai/src/generate-speech/generate-speech.test.ts @@ -3,7 +3,15 @@ import { SpeechModelV2, SpeechModelV2CallWarning, } from '@ai-sdk/provider'; -import { afterEach, beforeEach, describe, expect, it, vitest } from 'vitest'; +import { + afterEach, + beforeEach, + describe, + expect, + it, + vitest, + vi, +} from 'vitest'; import * as logWarningsModule from '../logger/log-warnings'; import { MockSpeechModelV2 } from '../test/mock-speech-model-v2'; import { generateSpeech } from './generate-speech'; @@ -21,6 +29,12 @@ const mockFile = new DefaultGeneratedAudioFile({ const sampleText = 'This is a sample text to convert to speech.'; +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + const createMockResponse = (options: { audio: GeneratedAudioFile; warnings?: SpeechModelV2CallWarning[]; @@ -69,14 +83,19 @@ describe('generateSpeech', () => { }), text: sampleText, voice: 'test-voice', - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, abortSignal, }); expect(capturedArgs).toStrictEqual({ text: sampleText, voice: 'test-voice', - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal, providerOptions: {}, outputFormat: undefined, @@ -226,6 +245,7 @@ describe('generateSpeech', () => { timestamp: testDate, headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, }), }), @@ -240,6 +260,7 @@ describe('generateSpeech', () => { modelId: expect.any(String), headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, }, ], diff --git a/packages/ai/src/generate-speech/generate-speech.ts b/packages/ai/src/generate-speech/generate-speech.ts index e65067ce21ac..ddcfbaaabc5b 100644 --- a/packages/ai/src/generate-speech/generate-speech.ts +++ b/packages/ai/src/generate-speech/generate-speech.ts @@ -1,5 +1,5 @@ import { JSONValue, SpeechModelV2 } from '@ai-sdk/provider'; -import { ProviderOptions } from '@ai-sdk/provider-utils'; +import { ProviderOptions, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { NoSpeechGeneratedError } from '../error/no-speech-generated-error'; import { UnsupportedModelVersionError } from '../error/unsupported-model-version-error'; import { logWarnings } from '../logger/log-warnings'; @@ -15,7 +15,7 @@ import { DefaultGeneratedAudioFile, GeneratedAudioFile, } from './generated-audio-file'; - +import { VERSION } from '../version'; /** Generates speech audio using a speech model. @@ -122,6 +122,11 @@ Only applicable for HTTP-based providers. }); } + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const { retry } = prepareRetries({ maxRetries: maxRetriesArg, abortSignal, @@ -136,7 +141,7 @@ Only applicable for HTTP-based providers. speed, language, abortSignal, - headers, + headers: headersWithUserAgent, providerOptions, }), ); diff --git a/packages/ai/src/generate-text/__snapshots__/generate-text.test.ts.snap b/packages/ai/src/generate-text/__snapshots__/generate-text.test.ts.snap index bc5598da45d0..6bcedcbfd064 100644 --- a/packages/ai/src/generate-text/__snapshots__/generate-text.test.ts.snap +++ b/packages/ai/src/generate-text/__snapshots__/generate-text.test.ts.snap @@ -1091,6 +1091,7 @@ exports[`generateText > telemetry > should not record telemetry inputs / outputs "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.generateText", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.settings.maxRetries": 2, "ai.usage.completionTokens": 10, @@ -1105,6 +1106,7 @@ exports[`generateText > telemetry > should not record telemetry inputs / outputs "ai.model.id": "mock-model-id", "ai.model.provider": "mock-provider", "ai.operationId": "ai.generateText.doGenerate", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.id": "test-id", "ai.response.model": "mock-model-id", @@ -1149,6 +1151,7 @@ exports[`generateText > telemetry > should record telemetry data when enabled 1` "ai.prompt": "{"prompt":"prompt"}", "ai.request.headers.header1": "value1", "ai.request.headers.header2": "value2", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.providerMetadata": "{"testProvider":{"testKey":"testValue"}}", "ai.response.text": "Hello, world!", @@ -1180,6 +1183,7 @@ exports[`generateText > telemetry > should record telemetry data when enabled 1` "ai.prompt.messages": "[{"role":"user","content":[{"type":"text","text":"prompt"}]}]", "ai.request.headers.header1": "value1", "ai.request.headers.header2": "value2", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.id": "test-id-from-model", "ai.response.model": "test-response-model-id", diff --git a/packages/ai/src/generate-text/generate-text.test.ts b/packages/ai/src/generate-text/generate-text.test.ts index 502cb088e1ee..4baef067f0e7 100644 --- a/packages/ai/src/generate-text/generate-text.test.ts +++ b/packages/ai/src/generate-text/generate-text.test.ts @@ -31,6 +31,12 @@ import { GenerateTextResult } from './generate-text-result'; import { StepResult } from './step-result'; import { stepCountIs } from './stop-condition'; +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + const dummyResponseValues = { finishReason: 'stop' as const, usage: { @@ -1677,9 +1683,10 @@ describe('generateText', () => { const result = await generateText({ model: new MockLanguageModelV2({ doGenerate: async ({ headers }) => { - assert.deepStrictEqual(headers, { - 'custom-request-header': 'request-header-value', - }); + assert.equal( + headers?.['custom-request-header'], + 'request-header-value', + ); return { ...dummyResponseValues, @@ -1930,6 +1937,7 @@ describe('generateText', () => { "ai.model.provider": "mock-provider", "ai.operationId": "ai.generateText", "ai.prompt": "{"prompt":"test-input"}", + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.toolCalls": "[{"toolCallId":"call-1","toolName":"tool1","input":"{ \\"value\\": \\"value\\" }"}]", "ai.settings.maxRetries": 2, @@ -1950,6 +1958,7 @@ describe('generateText', () => { "ai.prompt.tools": [ "{"type":"function","name":"tool1","inputSchema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"value":{"type":"string"}},"required":["value"],"additionalProperties":false}}", ], + "ai.request.headers.user-agent": "ai/0.0.0-test", "ai.response.finishReason": "stop", "ai.response.id": "test-id", "ai.response.model": "mock-model-id", @@ -2470,37 +2479,39 @@ describe('generateText', () => { }); expect(callOptions!).toMatchInlineSnapshot(` - { - "abortSignal": undefined, - "frequencyPenalty": undefined, - "headers": undefined, - "maxOutputTokens": undefined, - "presencePenalty": undefined, - "prompt": [ - { - "content": [ - { - "text": "prompt", - "type": "text", - }, - ], - "providerOptions": undefined, - "role": "user", - }, - ], - "providerOptions": undefined, - "responseFormat": { - "type": "text", - }, - "seed": undefined, - "stopSequences": undefined, - "temperature": undefined, - "toolChoice": undefined, - "tools": undefined, - "topK": undefined, - "topP": undefined, - } - `); + { + "abortSignal": undefined, + "frequencyPenalty": undefined, + "headers": { + "user-agent": "ai/0.0.0-test", + }, + "maxOutputTokens": undefined, + "presencePenalty": undefined, + "prompt": [ + { + "content": [ + { + "text": "prompt", + "type": "text", + }, + ], + "providerOptions": undefined, + "role": "user", + }, + ], + "providerOptions": undefined, + "responseFormat": { + "type": "text", + }, + "seed": undefined, + "stopSequences": undefined, + "temperature": undefined, + "toolChoice": undefined, + "tools": undefined, + "topK": undefined, + "topP": undefined, + } + `); }); }); @@ -2542,50 +2553,52 @@ describe('generateText', () => { }); expect(callOptions!).toMatchInlineSnapshot(` - { - "abortSignal": undefined, - "frequencyPenalty": undefined, - "headers": undefined, - "maxOutputTokens": undefined, - "presencePenalty": undefined, - "prompt": [ - { - "content": [ - { - "text": "prompt", - "type": "text", - }, - ], - "providerOptions": undefined, - "role": "user", - }, - ], - "providerOptions": undefined, - "responseFormat": { - "schema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "value": { - "type": "string", + { + "abortSignal": undefined, + "frequencyPenalty": undefined, + "headers": { + "user-agent": "ai/0.0.0-test", + }, + "maxOutputTokens": undefined, + "presencePenalty": undefined, + "prompt": [ + { + "content": [ + { + "text": "prompt", + "type": "text", + }, + ], + "providerOptions": undefined, + "role": "user", + }, + ], + "providerOptions": undefined, + "responseFormat": { + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "value": { + "type": "string", + }, }, + "required": [ + "value", + ], + "type": "object", }, - "required": [ - "value", - ], - "type": "object", - }, - "type": "json", - }, - "seed": undefined, - "stopSequences": undefined, - "temperature": undefined, - "toolChoice": undefined, - "tools": undefined, - "topK": undefined, - "topP": undefined, - } - `); + "type": "json", + }, + "seed": undefined, + "stopSequences": undefined, + "temperature": undefined, + "toolChoice": undefined, + "tools": undefined, + "topK": undefined, + "topP": undefined, + } + `); }); }); }); diff --git a/packages/ai/src/generate-text/generate-text.ts b/packages/ai/src/generate-text/generate-text.ts index ebfbb3c944b5..94a87ce382ca 100644 --- a/packages/ai/src/generate-text/generate-text.ts +++ b/packages/ai/src/generate-text/generate-text.ts @@ -9,6 +9,7 @@ import { getErrorMessage, IdGenerator, ProviderOptions, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { Tracer } from '@opentelemetry/api'; import { NoOutputSpecifiedError } from '../error/no-output-specified-error'; @@ -55,6 +56,7 @@ import { TypedToolError } from './tool-error'; import { ToolOutput } from './tool-output'; import { TypedToolResult } from './tool-result'; import { ToolSet } from './tool-set'; +import { VERSION } from '../version'; const originalGenerateId = createIdGenerator({ prefix: 'aitxt', @@ -255,10 +257,15 @@ A function that attempts to repair a tool call that failed to parse. const callSettings = prepareCallSettings(settings); + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const baseTelemetryAttributes = getBaseTelemetryAttributes({ model, telemetry, - headers, + headers: headersWithUserAgent, settings: { ...callSettings, maxRetries }, }); @@ -387,7 +394,7 @@ A function that attempts to repair a tool call that failed to parse. prompt: promptMessages, providerOptions, abortSignal, - headers, + headers: headersWithUserAgent, }); // Fill in default values: diff --git a/packages/ai/src/transcribe/transcribe.test.ts b/packages/ai/src/transcribe/transcribe.test.ts index 9be4f6ee6db1..9160da6bb7f0 100644 --- a/packages/ai/src/transcribe/transcribe.test.ts +++ b/packages/ai/src/transcribe/transcribe.test.ts @@ -3,11 +3,25 @@ import { TranscriptionModelV2, TranscriptionModelV2CallWarning, } from '@ai-sdk/provider'; -import { afterEach, beforeEach, describe, expect, it, vitest } from 'vitest'; +import { + afterEach, + beforeEach, + describe, + expect, + it, + vitest, + vi, +} from 'vitest'; import * as logWarningsModule from '../logger/log-warnings'; import { MockTranscriptionModelV2 } from '../test/mock-transcription-model-v2'; import { transcribe } from './transcribe'; +vi.mock('../version', () => { + return { + VERSION: '0.0.0-test', + }; +}); + const audioData = new Uint8Array([1, 2, 3, 4]); // Sample audio data const testDate = new Date(2024, 0, 1); @@ -86,14 +100,19 @@ describe('transcribe', () => { }, }), audio: audioData, - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + }, abortSignal, }); expect(capturedArgs).toStrictEqual({ audio: audioData, mediaType: 'audio/wav', - headers: { 'custom-request-header': 'request-header-value' }, + headers: { + 'custom-request-header': 'request-header-value', + 'user-agent': 'ai/0.0.0-test', + }, abortSignal, providerOptions: {}, }); @@ -239,6 +258,7 @@ describe('transcribe', () => { timestamp: testDate, headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, }), }), @@ -253,6 +273,7 @@ describe('transcribe', () => { modelId: expect.any(String), headers: { 'custom-response-header': 'response-header-value', + 'user-agent': 'ai/0.0.0-test', }, }, ], diff --git a/packages/ai/src/transcribe/transcribe.ts b/packages/ai/src/transcribe/transcribe.ts index 7e36d8e4e13c..bbf19b89eb4d 100644 --- a/packages/ai/src/transcribe/transcribe.ts +++ b/packages/ai/src/transcribe/transcribe.ts @@ -1,5 +1,5 @@ import { JSONValue, TranscriptionModelV2 } from '@ai-sdk/provider'; -import { ProviderOptions } from '@ai-sdk/provider-utils'; +import { ProviderOptions, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { NoTranscriptGeneratedError } from '../error/no-transcript-generated-error'; import { UnsupportedModelVersionError } from '../error/unsupported-model-version-error'; import { logWarnings } from '../logger/log-warnings'; @@ -14,7 +14,7 @@ import { import { download } from '../util/download/download'; import { prepareRetries } from '../util/prepare-retries'; import { TranscriptionResult } from './transcribe-result'; - +import { VERSION } from '../version'; /** Generates transcripts using a transcription model. @@ -93,6 +93,11 @@ Only applicable for HTTP-based providers. abortSignal, }); + const headersWithUserAgent = withUserAgentSuffix( + headers ?? {}, + `ai/${VERSION}`, + ); + const audioData = audio instanceof URL ? (await download({ url: audio })).data @@ -102,7 +107,7 @@ Only applicable for HTTP-based providers. model.doGenerate({ audio: audioData, abortSignal, - headers, + headers: headersWithUserAgent, providerOptions, mediaType: detectMediaType({ diff --git a/packages/ai/src/version.ts b/packages/ai/src/version.ts new file mode 100644 index 000000000000..8fda877d6d33 --- /dev/null +++ b/packages/ai/src/version.ts @@ -0,0 +1,5 @@ +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/ai/tsup.config.ts b/packages/ai/tsup.config.ts index 6efc434cff45..40b286074930 100644 --- a/packages/ai/tsup.config.ts +++ b/packages/ai/tsup.config.ts @@ -10,6 +10,12 @@ export default defineConfig([ sourcemap: true, target: 'es2018', platform: 'node', + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, // Internal APIs { @@ -21,6 +27,12 @@ export default defineConfig([ sourcemap: true, target: 'es2018', platform: 'node', + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, // Test utilities { @@ -43,6 +55,12 @@ export default defineConfig([ // Allow BigInt in tests target: 'es2020', platform: 'node', + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, // MCP stdio { @@ -54,5 +72,11 @@ export default defineConfig([ sourcemap: true, target: 'es2018', platform: 'node', + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/ai/vitest.edge.config.js b/packages/ai/vitest.edge.config.js index 32fbed1c6dae..ab1a7969f6a8 100644 --- a/packages/ai/vitest.edge.config.js +++ b/packages/ai/vitest.edge.config.js @@ -1,7 +1,15 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'edge-runtime', include: ['**/*.test.ts{,x}'], diff --git a/packages/ai/vitest.node.config.js b/packages/ai/vitest.node.config.js index 2518577b8137..091e0fbe8374 100644 --- a/packages/ai/vitest.node.config.js +++ b/packages/ai/vitest.node.config.js @@ -1,7 +1,15 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'node', include: ['**/*.test.ts{,x}'], diff --git a/packages/provider-utils/src/get-from-api.test.ts b/packages/provider-utils/src/get-from-api.test.ts index 8bb5788e56a3..868891efbd31 100644 --- a/packages/provider-utils/src/get-from-api.test.ts +++ b/packages/provider-utils/src/get-from-api.test.ts @@ -6,6 +6,16 @@ import { createStatusCodeErrorResponseHandler, } from './response-handler'; import { z } from 'zod/v4'; +import { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-agent'; +import { withUserAgentSuffix } from './with-user-agent-suffix'; + +vi.mock('./get-runtime-environment-user-agent', async () => { + const actual = await vi.importActual('./get-runtime-environment-user-agent'); + return { + ...actual, + getRuntimeEnvironmentUserAgent: () => 'runtime/test-env', + }; +}); describe('getFromApi', () => { const mockSuccessResponse = { @@ -21,13 +31,17 @@ describe('getFromApi', () => { const mockHeaders = { 'Content-Type': 'application/json', Authorization: 'Bearer test', + 'user-agent': 'runtime/test-env', }; it('should successfully fetch and parse data', async () => { const mockFetch = vi.fn().mockResolvedValue( new Response(JSON.stringify(mockSuccessResponse), { status: 200, - headers: mockHeaders, + headers: withUserAgentSuffix( + mockHeaders, + getRuntimeEnvironmentUserAgent(), + ), }), ); @@ -44,7 +58,10 @@ describe('getFromApi', () => { 'https://api.test.com/data', expect.objectContaining({ method: 'GET', - headers: { Authorization: 'Bearer test' }, + headers: { + authorization: 'Bearer test', + 'user-agent': 'ai-sdk/provider-utils/0.0.0-test runtime/test-env', + }, }), ); }); @@ -130,7 +147,8 @@ describe('getFromApi', () => { 'https://api.test.com/data', expect.objectContaining({ headers: { - Authorization: 'Bearer test', + authorization: 'Bearer test', + 'user-agent': 'ai-sdk/provider-utils/0.0.0-test runtime/test-env', }, }), ); diff --git a/packages/provider-utils/src/get-from-api.ts b/packages/provider-utils/src/get-from-api.ts index 58178c7c701a..0a786dd069e6 100644 --- a/packages/provider-utils/src/get-from-api.ts +++ b/packages/provider-utils/src/get-from-api.ts @@ -3,8 +3,10 @@ import { extractResponseHeaders } from './extract-response-headers'; import { FetchFunction } from './fetch-function'; import { handleFetchError } from './handle-fetch-error'; import { isAbortError } from './is-abort-error'; -import { removeUndefinedEntries } from './remove-undefined-entries'; import { ResponseHandler } from './response-handler'; +import { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-agent'; +import { withUserAgentSuffix } from './with-user-agent-suffix'; +import { VERSION } from './version'; // use function to allow for mocking in tests: const getOriginalFetch = () => globalThis.fetch; @@ -27,7 +29,11 @@ export const getFromApi = async ({ try { const response = await fetch(url, { method: 'GET', - headers: removeUndefinedEntries(headers), + headers: withUserAgentSuffix( + headers, + `ai-sdk/provider-utils/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), signal: abortSignal, }); diff --git a/packages/provider-utils/src/get-runtime-environment-user-agent.test.ts b/packages/provider-utils/src/get-runtime-environment-user-agent.test.ts new file mode 100644 index 000000000000..e8bb86423d8d --- /dev/null +++ b/packages/provider-utils/src/get-runtime-environment-user-agent.test.ts @@ -0,0 +1,47 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + +// Stabilize provider utils version used inside UA string construction +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + +import { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-agent'; + +describe('getRuntimeEnvironmentUserAgent', () => { + it('should return the correct user agent for browsers', () => { + expect( + getRuntimeEnvironmentUserAgent({ + window: true, + }), + ).toBe('runtime/browser'); + }); + + it('should return the correct user agent for test', () => { + expect( + getRuntimeEnvironmentUserAgent({ + navigator: { + userAgent: 'test', + }, + }), + ).toBe('runtime/test'); + }); + + it('should return the correct user agent for Edge Runtime', () => { + expect( + getRuntimeEnvironmentUserAgent({ + EdgeRuntime: true, + }), + ).toBe('runtime/vercel-edge'); + }); + + it('should return the correct user agent for Node.js', () => { + expect( + getRuntimeEnvironmentUserAgent({ + process: { + versions: { node: 'test' }, + version: 'test', + }, + }), + ).toBe('runtime/node.js/test'); + }); +}); diff --git a/packages/provider-utils/src/get-runtime-environment-user-agent.ts b/packages/provider-utils/src/get-runtime-environment-user-agent.ts new file mode 100644 index 000000000000..f553f735320b --- /dev/null +++ b/packages/provider-utils/src/get-runtime-environment-user-agent.ts @@ -0,0 +1,24 @@ +export function getRuntimeEnvironmentUserAgent( + globalThisAny: any = globalThis as any, +): string { + // Browsers + if (globalThisAny.window) { + return `runtime/browser`; + } + + // Cloudflare Workers / Deno / Bun / Node.js >= 21.1 + if (globalThisAny.navigator?.userAgent) { + return `runtime/${globalThisAny.navigator.userAgent.toLowerCase()}`; + } + + // Nodes.js < 21.1 + if (globalThisAny.process?.versions?.node) { + return `runtime/node.js/${globalThisAny.process.version.substring(0)}`; + } + + if (globalThisAny.EdgeRuntime) { + return `runtime/vercel-edge`; + } + + return 'runtime/unknown'; +} diff --git a/packages/provider-utils/src/index.ts b/packages/provider-utils/src/index.ts index 9b57dca02f36..ba02f6705d17 100644 --- a/packages/provider-utils/src/index.ts +++ b/packages/provider-utils/src/index.ts @@ -3,6 +3,8 @@ export { convertAsyncIteratorToReadableStream } from './convert-async-iterator-t export * from './delay'; export * from './extract-response-headers'; export * from './fetch-function'; +export { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-agent'; +export { withUserAgentSuffix } from './with-user-agent-suffix'; export { createIdGenerator, generateId, type IdGenerator } from './generate-id'; export * from './get-error-message'; export * from './get-from-api'; @@ -48,3 +50,6 @@ export { EventSourceParserStream, type EventSourceMessage, } from 'eventsource-parser/stream'; + +// user-agent exports +export { VERSION } from './version'; diff --git a/packages/provider-utils/src/post-to-api.ts b/packages/provider-utils/src/post-to-api.ts index 6595a56e014b..6e387dda3913 100644 --- a/packages/provider-utils/src/post-to-api.ts +++ b/packages/provider-utils/src/post-to-api.ts @@ -3,8 +3,10 @@ import { extractResponseHeaders } from './extract-response-headers'; import { FetchFunction } from './fetch-function'; import { handleFetchError } from './handle-fetch-error'; import { isAbortError } from './is-abort-error'; -import { removeUndefinedEntries } from './remove-undefined-entries'; import { ResponseHandler } from './response-handler'; +import { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-agent'; +import { withUserAgentSuffix } from './with-user-agent-suffix'; +import { VERSION } from './version'; // use function to allow for mocking in tests: const getOriginalFetch = () => globalThis.fetch; @@ -95,7 +97,11 @@ export const postToApi = async ({ try { const response = await fetch(url, { method: 'POST', - headers: removeUndefinedEntries(headers), + headers: withUserAgentSuffix( + headers, + `ai-sdk/provider-utils/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), body: body.content, signal: abortSignal, }); diff --git a/packages/provider-utils/src/test/test-server.ts b/packages/provider-utils/src/test/test-server.ts index c5d0301a7862..826a68222be8 100644 --- a/packages/provider-utils/src/test/test-server.ts +++ b/packages/provider-utils/src/test/test-server.ts @@ -88,6 +88,7 @@ class TestServerCall { // convert headers to object for easier comparison const headersObject: Record = {}; requestHeaders.forEach((value, key) => { + if (key.toLowerCase() === 'user-agent') return; headersObject[key] = value; }); diff --git a/packages/provider-utils/src/version.ts b/packages/provider-utils/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/provider-utils/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/provider-utils/src/with-user-agent-suffix.test.ts b/packages/provider-utils/src/with-user-agent-suffix.test.ts new file mode 100644 index 000000000000..0c0a1ff8713c --- /dev/null +++ b/packages/provider-utils/src/with-user-agent-suffix.test.ts @@ -0,0 +1,58 @@ +import { describe, it, expect } from 'vitest'; + +import { withUserAgentSuffix } from './with-user-agent-suffix'; + +describe('withUserAgentSuffix', () => { + it('should create a new user-agent header when no existing user-agent exists', () => { + const headers = { + 'content-type': 'application/json', + authorization: 'Bearer token123', + }; + + const result = withUserAgentSuffix( + headers, + 'ai-sdk/0.0.0-test', + 'provider/test-openai', + ); + + expect(result['user-agent']).toBe('ai-sdk/0.0.0-test provider/test-openai'); + expect(result['content-type']).toBe('application/json'); + expect(result['authorization']).toBe('Bearer token123'); + }); + + it('should append suffix parts to existing user-agent header', () => { + const headers = { + 'user-agent': 'TestApp/0.0.0-test', + accept: 'application/json', + }; + + const result = withUserAgentSuffix( + headers, + 'ai-sdk/0.0.0-test', + 'provider/test-anthropic', + ); + + expect(result['user-agent']).toBe( + 'TestApp/0.0.0-test ai-sdk/0.0.0-test provider/test-anthropic', + ); + expect(result['accept']).toBe('application/json'); + }); + + it('should automatically remove undefined entries from headers', () => { + const headers = { + 'content-type': 'application/json', + authorization: undefined, + 'user-agent': 'TestApp/0.0.0-test', + accept: 'application/json', + 'cache-control': null, + }; + + const result = withUserAgentSuffix(headers as any, 'ai-sdk/0.0.0-test'); + + expect(result['user-agent']).toBe('TestApp/0.0.0-test ai-sdk/0.0.0-test'); + expect(result['content-type']).toBe('application/json'); + expect(result['accept']).toBe('application/json'); + expect(result['authorization']).toBeUndefined(); + expect(result['cache-control']).toBeUndefined(); + }); +}); diff --git a/packages/provider-utils/src/with-user-agent-suffix.ts b/packages/provider-utils/src/with-user-agent-suffix.ts new file mode 100644 index 000000000000..65bd8c898fe1 --- /dev/null +++ b/packages/provider-utils/src/with-user-agent-suffix.ts @@ -0,0 +1,30 @@ +import { removeUndefinedEntries } from './remove-undefined-entries'; + +/** + * Appends suffix parts to the `user-agent` header. + * If a `user-agent` header already exists, the suffix parts are appended to it. + * If no `user-agent` header exists, a new one is created with the suffix parts. + * Automatically removes undefined entries from the headers. + * + * @param headers - The original headers. + * @param userAgentSuffixParts - The parts to append to the `user-agent` header. + * @returns The new headers with the `user-agent` header set or updated. + */ +export function withUserAgentSuffix( + headers: HeadersInit | Record | undefined, + ...userAgentSuffixParts: string[] +): Record { + const cleanedHeaders = removeUndefinedEntries( + (headers as Record) ?? {}, + ); + const normalizedHeaders = new Headers(cleanedHeaders); + + const currentUserAgentHeader = normalizedHeaders.get('user-agent') || ''; + + normalizedHeaders.set( + 'user-agent', + [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(' '), + ); + + return Object.fromEntries(normalizedHeaders); +} diff --git a/packages/provider-utils/tsup.config.ts b/packages/provider-utils/tsup.config.ts index bd4682744e9c..499e424b8c21 100644 --- a/packages/provider-utils/tsup.config.ts +++ b/packages/provider-utils/tsup.config.ts @@ -9,6 +9,12 @@ export default defineConfig([ // Keep library target conservative for wide compatibility target: 'es2018', platform: 'node', + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, { entry: ['src/test/index.ts'], @@ -31,5 +37,11 @@ export default defineConfig([ 'vitest/dist/node/*', 'vitest/dist/node/chunks/*', ], + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9fbdd9a317c..136e8c0d0cf5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29319,7 +29319,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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.34.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -29407,8 +29407,8 @@ snapshots: debug: 4.4.1 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.3 get-tsconfig: 4.8.1 is-core-module: 2.16.1 @@ -29458,7 +29458,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.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: @@ -29534,7 +29534,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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -29544,7 +29544,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.8.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.8.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.8.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.16.1 is-glob: 4.0.3 From 3aed04cfac049c314d7bfd709d9bef1ac66092b3 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Fri, 12 Sep 2025 16:40:42 -0400 Subject: [PATCH 019/121] feat(provider/openai-compatible): set `user-agent` header for `createOpenAICompatible` (#8616) ## Background As added for other providers/provider-utils/`ai`, we're setting user-agent property for `openai-compatible` ## Summary - added a `version.ts` file to extract that package's version - inject that version number to the user-agent string when we build and test this package - modified the `getHeaders()` function so that we append this package's string to existing user-agent header (if any) ## Manual Verification updated test file `openai-compatible-provider.test.ts` to ensure the package version is being attached to the header ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Related Issues Fixes #8612 --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/soft-moons-tie.md | 5 +++ packages/openai-compatible/src/index.ts | 1 + .../src/openai-compatible-provider.test.ts | 36 ++++++++++++------- .../src/openai-compatible-provider.ts | 15 ++++++-- packages/openai-compatible/src/version.ts | 5 +++ packages/openai-compatible/tsup.config.ts | 12 +++++++ .../openai-compatible/vitest.edge.config.js | 8 +++++ .../openai-compatible/vitest.node.config.js | 8 +++++ pnpm-lock.yaml | 6 ++-- 9 files changed, 77 insertions(+), 19 deletions(-) create mode 100644 .changeset/soft-moons-tie.md create mode 100644 packages/openai-compatible/src/version.ts diff --git a/.changeset/soft-moons-tie.md b/.changeset/soft-moons-tie.md new file mode 100644 index 000000000000..e7e789f39597 --- /dev/null +++ b/.changeset/soft-moons-tie.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai-compatible': patch +--- + +feat(provider/openai-compatible): set `user-agent` header for `createOpenAICompatible` diff --git a/packages/openai-compatible/src/index.ts b/packages/openai-compatible/src/index.ts index f781eddba2d2..75da5c767ba1 100644 --- a/packages/openai-compatible/src/index.ts +++ b/packages/openai-compatible/src/index.ts @@ -24,3 +24,4 @@ export type { OpenAICompatibleProvider, OpenAICompatibleProviderSettings, } from './openai-compatible-provider'; +export { VERSION } from './version'; diff --git a/packages/openai-compatible/src/openai-compatible-provider.test.ts b/packages/openai-compatible/src/openai-compatible-provider.test.ts index 261adb542a75..35f001a966d1 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.test.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.test.ts @@ -4,6 +4,11 @@ import { OpenAICompatibleCompletionLanguageModel } from './completion/openai-com import { OpenAICompatibleEmbeddingModel } from './embedding/openai-compatible-embedding-model'; import { vi, describe, beforeEach, it, expect } from 'vitest'; +// Mock version +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + const OpenAICompatibleChatLanguageModelMock = vi.mocked( OpenAICompatibleChatLanguageModel, ); @@ -37,7 +42,7 @@ describe('OpenAICompatibleProvider', () => { baseURL: 'https://api.example.com', name: 'test-provider', apiKey: 'test-api-key', - headers: { 'Custom-Header': 'value' }, + headers: { 'custom-header': 'value' }, queryParams: { 'Custom-Param': 'value' }, }; @@ -50,8 +55,9 @@ describe('OpenAICompatibleProvider', () => { const headers = config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer test-api-key', - 'Custom-Header': 'value', + authorization: 'Bearer test-api-key', + 'custom-header': 'value', + 'user-agent': 'ai-sdk/openai-compatible/0.0.0-test', }); expect(config.provider).toBe('test-provider.chat'); expect(config.url({ modelId: 'model-id', path: '/v1/chat' })).toBe( @@ -59,11 +65,11 @@ describe('OpenAICompatibleProvider', () => { ); }); - it('should create headers without Authorization when no apiKey provided', () => { + it('should create headers without authorization when no apiKey provided', () => { const options = { baseURL: 'https://api.example.com', name: 'test-provider', - headers: { 'Custom-Header': 'value' }, + headers: { 'custom-header': 'value' }, }; const provider = createOpenAICompatible(options); @@ -75,7 +81,8 @@ describe('OpenAICompatibleProvider', () => { const headers = config.headers(); expect(headers).toEqual({ - 'Custom-Header': 'value', + 'custom-header': 'value', + 'user-agent': 'ai-sdk/openai-compatible/0.0.0-test', }); }); }); @@ -85,7 +92,7 @@ describe('OpenAICompatibleProvider', () => { baseURL: 'https://api.example.com', name: 'test-provider', apiKey: 'test-api-key', - headers: { 'Custom-Header': 'value' }, + headers: { 'custom-header': 'value' }, queryParams: { 'Custom-Param': 'value' }, }; @@ -100,8 +107,9 @@ describe('OpenAICompatibleProvider', () => { const headers = config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer test-api-key', - 'Custom-Header': 'value', + authorization: 'Bearer test-api-key', + 'custom-header': 'value', + 'user-agent': 'ai-sdk/openai-compatible/0.0.0-test', }); expect(config.provider).toBe('test-provider.chat'); expect(config.url({ modelId: 'model-id', path: '/v1/chat' })).toBe( @@ -120,8 +128,9 @@ describe('OpenAICompatibleProvider', () => { const headers = config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer test-api-key', - 'Custom-Header': 'value', + authorization: 'Bearer test-api-key', + 'custom-header': 'value', + 'user-agent': 'ai-sdk/openai-compatible/0.0.0-test', }); expect(config.provider).toBe('test-provider.completion'); expect( @@ -139,8 +148,9 @@ describe('OpenAICompatibleProvider', () => { const headers = config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer test-api-key', - 'Custom-Header': 'value', + authorization: 'Bearer test-api-key', + 'custom-header': 'value', + 'user-agent': 'ai-sdk/openai-compatible/0.0.0-test', }); expect(config.provider).toBe('test-provider.embedding'); expect( diff --git a/packages/openai-compatible/src/openai-compatible-provider.ts b/packages/openai-compatible/src/openai-compatible-provider.ts index d222283327c3..f34a8cb220cc 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.ts @@ -4,11 +4,17 @@ import { LanguageModelV2, ProviderV2, } from '@ai-sdk/provider'; -import { FetchFunction, withoutTrailingSlash } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + withoutTrailingSlash, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; import { OpenAICompatibleChatLanguageModel } from './chat/openai-compatible-chat-language-model'; import { OpenAICompatibleCompletionLanguageModel } from './completion/openai-compatible-completion-language-model'; import { OpenAICompatibleEmbeddingModel } from './embedding/openai-compatible-embedding-model'; import { OpenAICompatibleImageModel } from './image/openai-compatible-image-model'; +import { VERSION } from './version'; export interface OpenAICompatibleProvider< CHAT_MODEL_IDS extends string = string, @@ -96,10 +102,13 @@ export function createOpenAICompatible< fetch?: FetchFunction; } - const getHeaders = () => ({ + const headers = { ...(options.apiKey && { Authorization: `Bearer ${options.apiKey}` }), ...options.headers, - }); + }; + + const getHeaders = () => + withUserAgentSuffix(headers, `ai-sdk/openai-compatible/${VERSION}`); const getCommonModelConfig = (modelType: string): CommonModelConfig => ({ provider: `${providerName}.${modelType}`, diff --git a/packages/openai-compatible/src/version.ts b/packages/openai-compatible/src/version.ts new file mode 100644 index 000000000000..8fda877d6d33 --- /dev/null +++ b/packages/openai-compatible/src/version.ts @@ -0,0 +1,5 @@ +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/openai-compatible/tsup.config.ts b/packages/openai-compatible/tsup.config.ts index 87efcf0d5720..d0b56a7122cd 100644 --- a/packages/openai-compatible/tsup.config.ts +++ b/packages/openai-compatible/tsup.config.ts @@ -6,6 +6,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, { entry: ['src/internal/index.ts'], @@ -13,5 +19,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/openai-compatible/vitest.edge.config.js b/packages/openai-compatible/vitest.edge.config.js index 3dc49ba29774..02b9e8c6cf92 100644 --- a/packages/openai-compatible/vitest.edge.config.js +++ b/packages/openai-compatible/vitest.edge.config.js @@ -1,7 +1,15 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], diff --git a/packages/openai-compatible/vitest.node.config.js b/packages/openai-compatible/vitest.node.config.js index b7e4a9cabd48..5b86131f58c6 100644 --- a/packages/openai-compatible/vitest.node.config.js +++ b/packages/openai-compatible/vitest.node.config.js @@ -1,7 +1,15 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 136e8c0d0cf5..ed8b29bea144 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29407,7 +29407,7 @@ snapshots: debug: 4.4.1 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.3 get-tsconfig: 4.8.1 @@ -29458,7 +29458,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.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: @@ -29544,7 +29544,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.8.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.8.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.8.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.16.1 is-glob: 4.0.3 From 80fb3dc6f6b4cef66f897d41491c6679aeaa3e1d Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 13:41:06 -0700 Subject: [PATCH 020/121] Version Packages (#8619) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## ai@5.0.43 ### Patch Changes - 0294b58: feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/gateway@1.0.22 ## @ai-sdk/amazon-bedrock@3.0.20 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/anthropic@2.0.16 ## @ai-sdk/angular@1.0.43 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - ai@5.0.43 ## @ai-sdk/anthropic@2.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/assemblyai@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/azure@2.0.30 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai@2.0.30 ## @ai-sdk/cerebras@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 ## @ai-sdk/cohere@2.0.10 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/deepgram@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/deepinfra@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 ## @ai-sdk/deepseek@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 ## @ai-sdk/elevenlabs@1.0.10 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/fal@1.0.13 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/fireworks@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 ## @ai-sdk/gateway@1.0.22 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/gladia@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/google@2.0.14 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/google-vertex@3.0.26 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/anthropic@2.0.16 - @ai-sdk/google@2.0.14 ## @ai-sdk/groq@2.0.19 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/hume@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/langchain@1.0.43 ### Patch Changes - Updated dependencies [0294b58] - ai@5.0.43 ## @ai-sdk/llamaindex@1.0.43 ### Patch Changes - Updated dependencies [0294b58] - ai@5.0.43 ## @ai-sdk/lmnt@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/luma@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/mistral@2.0.14 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/openai@2.0.30 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/openai-compatible@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/perplexity@2.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/provider-utils@3.0.9 ### Patch Changes - 0294b58: feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header ## @ai-sdk/react@2.0.43 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - ai@5.0.43 ## @ai-sdk/replicate@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/revai@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/rsc@1.0.43 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - ai@5.0.43 ## @ai-sdk/svelte@3.0.43 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - ai@5.0.43 ## @ai-sdk/togetherai@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 ## @ai-sdk/valibot@1.0.9 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 ## @ai-sdk/vercel@1.0.16 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 ## @ai-sdk/vue@2.0.43 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - ai@5.0.43 ## @ai-sdk/xai@2.0.17 ### Patch Changes - Updated dependencies [0294b58] - @ai-sdk/provider-utils@3.0.9 - @ai-sdk/openai-compatible@1.0.16 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/seven-zoos-suffer.md | 6 ------ packages/ai/CHANGELOG.md | 9 +++++++++ packages/ai/package.json | 2 +- packages/amazon-bedrock/CHANGELOG.md | 8 ++++++++ packages/amazon-bedrock/package.json | 2 +- packages/angular/CHANGELOG.md | 8 ++++++++ packages/angular/package.json | 2 +- packages/anthropic/CHANGELOG.md | 7 +++++++ packages/anthropic/package.json | 2 +- packages/assemblyai/CHANGELOG.md | 7 +++++++ packages/assemblyai/package.json | 2 +- packages/azure/CHANGELOG.md | 8 ++++++++ packages/azure/package.json | 2 +- packages/cerebras/CHANGELOG.md | 8 ++++++++ packages/cerebras/package.json | 2 +- packages/cohere/CHANGELOG.md | 7 +++++++ packages/cohere/package.json | 2 +- packages/deepgram/CHANGELOG.md | 7 +++++++ packages/deepgram/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 8 ++++++++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 8 ++++++++ packages/deepseek/package.json | 2 +- packages/elevenlabs/CHANGELOG.md | 7 +++++++ packages/elevenlabs/package.json | 2 +- packages/fal/CHANGELOG.md | 7 +++++++ packages/fal/package.json | 2 +- packages/fireworks/CHANGELOG.md | 8 ++++++++ packages/fireworks/package.json | 2 +- packages/gateway/CHANGELOG.md | 7 +++++++ packages/gateway/package.json | 2 +- packages/gladia/CHANGELOG.md | 7 +++++++ packages/gladia/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 9 +++++++++ packages/google-vertex/package.json | 2 +- packages/google/CHANGELOG.md | 7 +++++++ packages/google/package.json | 2 +- packages/groq/CHANGELOG.md | 7 +++++++ packages/groq/package.json | 2 +- packages/hume/CHANGELOG.md | 7 +++++++ packages/hume/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/lmnt/CHANGELOG.md | 7 +++++++ packages/lmnt/package.json | 2 +- packages/luma/CHANGELOG.md | 7 +++++++ packages/luma/package.json | 2 +- packages/mistral/CHANGELOG.md | 7 +++++++ packages/mistral/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 7 +++++++ packages/openai-compatible/package.json | 2 +- packages/openai/CHANGELOG.md | 7 +++++++ packages/openai/package.json | 2 +- packages/perplexity/CHANGELOG.md | 7 +++++++ packages/perplexity/package.json | 2 +- packages/provider-utils/CHANGELOG.md | 6 ++++++ packages/provider-utils/package.json | 2 +- packages/react/CHANGELOG.md | 8 ++++++++ packages/react/package.json | 2 +- packages/replicate/CHANGELOG.md | 7 +++++++ packages/replicate/package.json | 2 +- packages/revai/CHANGELOG.md | 7 +++++++ packages/revai/package.json | 2 +- packages/rsc/CHANGELOG.md | 8 ++++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 8 ++++++++ packages/svelte/package.json | 2 +- packages/togetherai/CHANGELOG.md | 8 ++++++++ packages/togetherai/package.json | 2 +- packages/valibot/CHANGELOG.md | 7 +++++++ packages/valibot/package.json | 2 +- packages/vercel/CHANGELOG.md | 8 ++++++++ packages/vercel/package.json | 2 +- packages/vue/CHANGELOG.md | 8 ++++++++ packages/vue/package.json | 2 +- packages/xai/CHANGELOG.md | 8 ++++++++ packages/xai/package.json | 2 +- 80 files changed, 336 insertions(+), 45 deletions(-) delete mode 100644 .changeset/seven-zoos-suffer.md diff --git a/.changeset/seven-zoos-suffer.md b/.changeset/seven-zoos-suffer.md deleted file mode 100644 index 2f4e6051a83b..000000000000 --- a/.changeset/seven-zoos-suffer.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@ai-sdk/provider-utils': patch -'ai': patch ---- - -feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 28f7a4020529..547d3ba3cdab 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,14 @@ # ai +## 5.0.43 + +### Patch Changes + +- 0294b58: feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/gateway@1.0.22 + ## 5.0.42 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index a1faf99166ca..e4555582bcd4 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.42", + "version": "5.0.43", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index 8ebb51169aed..d7ef95907fc3 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/amazon-bedrock +## 3.0.20 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/anthropic@2.0.16 + ## 3.0.19 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 16f6603a7546..794d6d2f4c69 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.0.19", + "version": "3.0.20", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 105eae3e4f3e..95a7803e0c5f 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/angular +## 1.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - ai@5.0.43 + ## 1.0.42 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 14116d295beb..646e741a7adf 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.42", + "version": "1.0.43", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 5c8197960cfc..9bec596056e3 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/anthropic +## 2.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.15 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 11f72a482f88..395aaeceee7c 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "2.0.15", + "version": "2.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/assemblyai/CHANGELOG.md b/packages/assemblyai/CHANGELOG.md index 2e25b8fcff35..e67eaa1df456 100644 --- a/packages/assemblyai/CHANGELOG.md +++ b/packages/assemblyai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/assemblyai +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index 0754317b7f8f..08dd16b2e828 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/assemblyai", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index cb76e4f6de58..febda9ec5fa8 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/azure +## 2.0.30 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai@2.0.30 + ## 2.0.29 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 53b1379281aa..f528d9a60566 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.0.29", + "version": "2.0.30", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index a8801f10a302..7c4046dc2cce 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/cerebras +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 1.0.15 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index 49ff6c819a62..b46a84b95065 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index 52f70baf45d7..90d7d99a2c4c 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/cohere +## 2.0.10 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.9 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index 29546abcd843..e47effde26e5 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "2.0.9", + "version": "2.0.10", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepgram/CHANGELOG.md b/packages/deepgram/CHANGELOG.md index abfcbe822479..bacf08287086 100644 --- a/packages/deepgram/CHANGELOG.md +++ b/packages/deepgram/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/deepgram +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index 86ad7196945d..3d7c5be84ec6 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepgram", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index c9110ed6f24c..407bd705e499 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/deepinfra +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 1.0.15 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index b40b5f6dbbbc..f0fb16820a4a 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 38c0f4f53b16..205b8bbdd601 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/deepseek +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 1.0.15 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index dd8b4f92d6a8..e40a1a8d305b 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/elevenlabs/CHANGELOG.md b/packages/elevenlabs/CHANGELOG.md index 9c788e700561..abf4899095d3 100644 --- a/packages/elevenlabs/CHANGELOG.md +++ b/packages/elevenlabs/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/elevenlabs +## 1.0.10 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.9 ### Patch Changes diff --git a/packages/elevenlabs/package.json b/packages/elevenlabs/package.json index e32de1126dd5..29d23a6ce1c3 100644 --- a/packages/elevenlabs/package.json +++ b/packages/elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/elevenlabs", - "version": "1.0.9", + "version": "1.0.10", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index c6777622c82e..b3e7ad432234 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/fal +## 1.0.13 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.12 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index 16f68b575bc2..9fbc5b6d1d04 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "1.0.12", + "version": "1.0.13", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 2e3416375373..9c19621d6035 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/fireworks +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 1.0.15 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index d490c8baea91..1c50db1dde6e 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index a966b2c7c968..c00d009e8c7d 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/gateway +## 1.0.22 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.21 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 45fa04d777d7..18c1de3430db 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.0.21", + "version": "1.0.22", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gladia/CHANGELOG.md b/packages/gladia/CHANGELOG.md index dc08ab72f672..993480ec5a26 100644 --- a/packages/gladia/CHANGELOG.md +++ b/packages/gladia/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/gladia +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/gladia/package.json b/packages/gladia/package.json index e268740a7cb9..b3bd2b5ab47b 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/gladia", - "version": "1.0.8", + "version": "1.0.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 c6206a2320c7..c95b63fbaf1d 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/google-vertex +## 3.0.26 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/anthropic@2.0.16 + - @ai-sdk/google@2.0.14 + ## 3.0.25 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index cabdba33506a..c37d99749bc1 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.0.25", + "version": "3.0.26", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 74116f473935..56987a069c77 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/google +## 2.0.14 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.13 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index c608da9b602c..b93da9db3fa1 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "2.0.13", + "version": "2.0.14", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index ff7a4dfe28e2..f1744566b7d9 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/groq +## 2.0.19 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.18 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index 2bf2ff32a594..c35450f91c52 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "2.0.18", + "version": "2.0.19", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/hume/CHANGELOG.md b/packages/hume/CHANGELOG.md index efdb1086900f..448575ac03e5 100644 --- a/packages/hume/CHANGELOG.md +++ b/packages/hume/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/hume +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/hume/package.json b/packages/hume/package.json index c7d01d8d7512..983d991e52c5 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/hume", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 1d296c3cf57f..2d7f5b5caa02 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - ai@5.0.43 + ## 1.0.42 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index ef2b9b3755bb..27a07f40d100 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.42", + "version": "1.0.43", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 782db1950d23..88a0c927344a 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - ai@5.0.43 + ## 1.0.42 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index eb1cf5db90a9..43a2927a5040 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.42", + "version": "1.0.43", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/lmnt/CHANGELOG.md b/packages/lmnt/CHANGELOG.md index bfcd1ab3f5c5..07bbf36e222b 100644 --- a/packages/lmnt/CHANGELOG.md +++ b/packages/lmnt/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/lmnt +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index f3d0455a8a3e..f5cd3405f3a4 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/lmnt", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index f770d14dfeb8..159acffe2480 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/luma +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index 07796f488366..cfe619c3752b 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index 219db001b48a..2cdc3e6b4428 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/mistral +## 2.0.14 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.13 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 113e614a9fe9..fb171be92685 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "2.0.13", + "version": "2.0.14", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index 3bc2e3586aa7..3452d9b57ac5 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/openai-compatible +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.15 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index 360ba8f2d097..1be5ce29a34d 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index b0982aa1ae69..22f6d939f33f 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/openai +## 2.0.30 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.29 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index 95c30fe3d1b8..27f0b97249c3 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.0.29", + "version": "2.0.30", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index 6a7be555813f..f04a49dde43d 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/perplexity +## 2.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 2.0.8 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index 53a76460fa59..b72fc745c7cd 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "2.0.8", + "version": "2.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index 5b912367cd42..14f8873ee08f 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider-utils +## 3.0.9 + +### Patch Changes + +- 0294b58: feat(ai): set `ai`, `@ai-sdk/provider-utils`, and runtime in `user-agent` header + ## 3.0.8 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index 91049ff97194..5886081acaf2 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "3.0.8", + "version": "3.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 16467ba7c21e..3ec4879c4b1a 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/react +## 2.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - ai@5.0.43 + ## 2.0.42 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index a4e2a876db83..e0841a8b0d38 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.42", + "version": "2.0.43", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index 7f9c0aff8ea2..bf69a829dfa4 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/replicate +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index 180f578308f9..3e945bdfc183 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/revai/CHANGELOG.md b/packages/revai/CHANGELOG.md index c23eb164e11f..498e4c60a068 100644 --- a/packages/revai/CHANGELOG.md +++ b/packages/revai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/revai +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/revai/package.json b/packages/revai/package.json index 309b825deb76..49b8e5bb9b33 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/revai", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index f822344f37bc..216a44d91686 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/rsc +## 1.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - ai@5.0.43 + ## 1.0.42 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 754fca373291..4ae57a0f58a5 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.42", + "version": "1.0.43", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 405103b71b3a..f34ff97aff6a 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [0294b58] + - ai@5.0.43 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [de5c066] - ai@5.0.42 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 557ac02ade75..1bbe1f7de6e1 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/svelte +## 3.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - ai@5.0.43 + ## 3.0.42 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index cd86f34b81e1..1d6dda4de392 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.42", + "version": "3.0.43", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index e6b54b074305..241c0ae0fad6 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/togetherai +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 1.0.15 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index f13862d78736..1ff16cb5b52c 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 976c04f4ca60..c84fac29da22 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 1.0.9 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + ## 1.0.8 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index fb1cd93b8a85..712740e5b2b4 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "1.0.8", + "version": "1.0.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index 8a5e825526a5..33da227da246 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/vercel +## 1.0.16 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 1.0.15 ### Patch Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index 36da99106c95..22d4ecf24bdf 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.0.15", + "version": "1.0.16", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 86b05b784fd7..1f3a9308d2fb 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/vue +## 2.0.43 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - ai@5.0.43 + ## 2.0.42 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 00b5e57e9655..1372eba99658 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.42", + "version": "2.0.43", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 21601d2977e2..c6e3194f67dc 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/xai +## 2.0.17 + +### Patch Changes + +- Updated dependencies [0294b58] + - @ai-sdk/provider-utils@3.0.9 + - @ai-sdk/openai-compatible@1.0.16 + ## 2.0.16 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index b12e488fc025..0c2464cba1d5 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.0.16", + "version": "2.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From b024298c3f75fd6d9166869bb56395d6708532e9 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 13:47:35 -0700 Subject: [PATCH 021/121] Version Packages (#8620) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @ai-sdk/cerebras@1.0.17 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 ## @ai-sdk/deepinfra@1.0.17 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 ## @ai-sdk/deepseek@1.0.17 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 ## @ai-sdk/fireworks@1.0.17 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 ## @ai-sdk/openai-compatible@1.0.17 ### Patch Changes - 3aed04c: feat(provider/openai-compatible): set `user-agent` header for `createOpenAICompatible` ## @ai-sdk/togetherai@1.0.17 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 ## @ai-sdk/vercel@1.0.17 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 ## @ai-sdk/xai@2.0.18 ### Patch Changes - Updated dependencies [3aed04c] - @ai-sdk/openai-compatible@1.0.17 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/soft-moons-tie.md | 5 ----- packages/cerebras/CHANGELOG.md | 7 +++++++ packages/cerebras/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 7 +++++++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 7 +++++++ packages/deepseek/package.json | 2 +- packages/fireworks/CHANGELOG.md | 7 +++++++ packages/fireworks/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 6 ++++++ packages/openai-compatible/package.json | 2 +- packages/togetherai/CHANGELOG.md | 7 +++++++ packages/togetherai/package.json | 2 +- packages/vercel/CHANGELOG.md | 7 +++++++ packages/vercel/package.json | 2 +- packages/xai/CHANGELOG.md | 7 +++++++ packages/xai/package.json | 2 +- 17 files changed, 63 insertions(+), 13 deletions(-) delete mode 100644 .changeset/soft-moons-tie.md diff --git a/.changeset/soft-moons-tie.md b/.changeset/soft-moons-tie.md deleted file mode 100644 index e7e789f39597..000000000000 --- a/.changeset/soft-moons-tie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai-compatible': patch ---- - -feat(provider/openai-compatible): set `user-agent` header for `createOpenAICompatible` diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 7c4046dc2cce..43dca328182c 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/cerebras +## 1.0.17 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 1.0.16 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index b46a84b95065..55ca6a563b18 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index 407bd705e499..4741f467d4ab 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/deepinfra +## 1.0.17 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 1.0.16 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index f0fb16820a4a..9254eba21f5e 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 205b8bbdd601..884bca1fe4ba 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/deepseek +## 1.0.17 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 1.0.16 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index e40a1a8d305b..bdc066f09864 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 9c19621d6035..421006a33cdd 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/fireworks +## 1.0.17 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 1.0.16 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index 1c50db1dde6e..ffd156991999 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index 3452d9b57ac5..c4a12d390609 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/openai-compatible +## 1.0.17 + +### Patch Changes + +- 3aed04c: feat(provider/openai-compatible): set `user-agent` header for `createOpenAICompatible` + ## 1.0.16 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index 1be5ce29a34d..d863b32e9830 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index 241c0ae0fad6..366adfc57c0e 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/togetherai +## 1.0.17 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 1.0.16 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index 1ff16cb5b52c..b8ae47dad3f1 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index 33da227da246..7b386e9450e5 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vercel +## 1.0.17 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 1.0.16 ### Patch Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index 22d4ecf24bdf..52bd72466e94 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.0.16", + "version": "1.0.17", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index c6e3194f67dc..3f0f768acc27 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/xai +## 2.0.18 + +### Patch Changes + +- Updated dependencies [3aed04c] + - @ai-sdk/openai-compatible@1.0.17 + ## 2.0.17 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 0c2464cba1d5..e0118f4fc45c 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.0.17", + "version": "2.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From f49f92459527123b690904f3f647aa4263a6634f Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Fri, 12 Sep 2025 21:15:57 -0700 Subject: [PATCH 022/121] feat (provider/gateway): add qwen3 next model ids (#8627) ## Background Qwen3 Next new models have been added to the AI Gateway model library. --- .changeset/funny-rats-greet.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/funny-rats-greet.md diff --git a/.changeset/funny-rats-greet.md b/.changeset/funny-rats-greet.md new file mode 100644 index 000000000000..7d2f85359d47 --- /dev/null +++ b/.changeset/funny-rats-greet.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat (provider/gateway): add qwen3 next model ids diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index 7eaf96e297bf..60755738bec7 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -5,6 +5,8 @@ export type GatewayModelId = | 'alibaba/qwen-3-32b' | 'alibaba/qwen3-coder' | 'alibaba/qwen3-max' + | 'alibaba/qwen3-next-80b-a3b-instruct' + | 'alibaba/qwen3-next-80b-a3b-thinking' | 'amazon/nova-lite' | 'amazon/nova-micro' | 'amazon/nova-pro' From 048a585dd3f29001f5d65c979c92e84563e69ea6 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 21:26:47 -0700 Subject: [PATCH 023/121] Version Packages (#8628) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## ai@5.0.44 ### Patch Changes - Updated dependencies [f49f924] - @ai-sdk/gateway@1.0.23 ## @ai-sdk/angular@1.0.44 ### Patch Changes - ai@5.0.44 ## @ai-sdk/gateway@1.0.23 ### Patch Changes - f49f924: feat (provider/gateway): add qwen3 next model ids ## @ai-sdk/langchain@1.0.44 ### Patch Changes - ai@5.0.44 ## @ai-sdk/llamaindex@1.0.44 ### Patch Changes - ai@5.0.44 ## @ai-sdk/react@2.0.44 ### Patch Changes - ai@5.0.44 ## @ai-sdk/rsc@1.0.44 ### Patch Changes - ai@5.0.44 ## @ai-sdk/svelte@3.0.44 ### Patch Changes - ai@5.0.44 ## @ai-sdk/vue@2.0.44 ### Patch Changes - ai@5.0.44 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/funny-rats-greet.md | 5 ----- packages/ai/CHANGELOG.md | 7 +++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 6 ++++++ packages/angular/package.json | 2 +- packages/gateway/CHANGELOG.md | 6 ++++++ packages/gateway/package.json | 2 +- packages/langchain/CHANGELOG.md | 6 ++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 6 ++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 6 ++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 6 ++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 6 ++++++ packages/svelte/CHANGELOG.md | 6 ++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 6 ++++++ packages/vue/package.json | 2 +- 20 files changed, 70 insertions(+), 14 deletions(-) delete mode 100644 .changeset/funny-rats-greet.md diff --git a/.changeset/funny-rats-greet.md b/.changeset/funny-rats-greet.md deleted file mode 100644 index 7d2f85359d47..000000000000 --- a/.changeset/funny-rats-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/gateway': patch ---- - -feat (provider/gateway): add qwen3 next model ids diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 547d3ba3cdab..54e6fcf10373 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,12 @@ # ai +## 5.0.44 + +### Patch Changes + +- Updated dependencies [f49f924] + - @ai-sdk/gateway@1.0.23 + ## 5.0.43 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index e4555582bcd4..c0b67b7562fe 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.43", + "version": "5.0.44", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 95a7803e0c5f..5e5bfdd3d1c5 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/angular +## 1.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 1.0.43 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 646e741a7adf..f1bf827163a9 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.43", + "version": "1.0.44", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index c00d009e8c7d..c7c172d52322 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/gateway +## 1.0.23 + +### Patch Changes + +- f49f924: feat (provider/gateway): add qwen3 next model ids + ## 1.0.22 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 18c1de3430db..b2bc3edb2a60 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.0.22", + "version": "1.0.23", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 2d7f5b5caa02..2b7eb663eb0b 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/langchain +## 1.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 1.0.43 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 27a07f40d100..f27c0fb83322 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.43", + "version": "1.0.44", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 88a0c927344a..b2c1fbcb7b8b 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/llamaindex +## 1.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 1.0.43 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 43a2927a5040..a3f49d0a7d05 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.43", + "version": "1.0.44", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 3ec4879c4b1a..8e3b93d4caa2 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/react +## 2.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 2.0.43 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index e0841a8b0d38..868720439a41 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.43", + "version": "2.0.44", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 216a44d91686..9b54c44e86b1 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/rsc +## 1.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 1.0.43 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 4ae57a0f58a5..091a7bc01652 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.43", + "version": "1.0.44", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index f34ff97aff6a..9d115b423f51 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,12 @@ ### Patch Changes +- ai@5.0.44 + +## 0.0.1 + +### Patch Changes + - Updated dependencies [0294b58] - ai@5.0.43 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 1bbe1f7de6e1..22ae8b05c3b9 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/svelte +## 3.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 3.0.43 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 1d6dda4de392..36d4ce4a0d00 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.43", + "version": "3.0.44", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 1f3a9308d2fb..08ef384726ec 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/vue +## 2.0.44 + +### Patch Changes + +- ai@5.0.44 + ## 2.0.43 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 1372eba99658..1fa450638807 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.43", + "version": "2.0.44", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From da921328ed2cc89da03c68b1a94b4073f747d296 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Sat, 13 Sep 2025 00:42:18 -0700 Subject: [PATCH 024/121] fix(provider/anthorpic): add `cacheControl` to `AnthropicProviderOptions` (#8623) ## Background Follow up to #7526 which I think aimed at implementing support for the `cache_control` input argument, but didn't fix it correctly ## Summary This was already implemented and tested, but we lacked the type for `AnthropicProviderOptions` ## Manual Verification `examples/ai-core/src/generate-text/anthropic-cache-control-beta-1h.ts` ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [ ] n/a ~~Documentation has been added / updated (for bug fixes / features)~~ - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues #7526 --- .changeset/gorgeous-pets-tie.md | 5 +++++ .../providers/01-ai-sdk-providers/05-anthropic.mdx | 7 +------ .../generate-text/anthropic-cache-control-beta-1h.ts | 4 ++-- .../src/anthropic-messages-language-model.test.ts | 10 ++-------- packages/anthropic/src/anthropic-messages-options.ts | 11 +++++++++++ 5 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 .changeset/gorgeous-pets-tie.md diff --git a/.changeset/gorgeous-pets-tie.md b/.changeset/gorgeous-pets-tie.md new file mode 100644 index 000000000000..4f62eb892ec0 --- /dev/null +++ b/.changeset/gorgeous-pets-tie.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/anthropic': patch +--- + +fix(provider/anthorpic): add cacheControl to AnthropicProviderOptions diff --git a/content/providers/01-ai-sdk-providers/05-anthropic.mdx b/content/providers/01-ai-sdk-providers/05-anthropic.mdx index d221f10e06d6..30c9302a8310 100644 --- a/content/providers/01-ai-sdk-providers/05-anthropic.mdx +++ b/content/providers/01-ai-sdk-providers/05-anthropic.mdx @@ -234,18 +234,13 @@ const result = await generateText({ #### Longer cache TTL -Anthropic also supports a longer 1-hour cache duration. At time of writing, -[this is currently in beta](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#1-hour-cache-duration), -so you must pass a `'anthropic-beta'` header set to `'extended-cache-ttl-2025-04-11'`. +Anthropic also supports a longer 1-hour cache duration. Here's an example: ```ts const result = await generateText({ model: anthropic('claude-3-5-haiku-latest'), - headers: { - 'anthropic-beta': 'extended-cache-ttl-2025-04-11', - }, messages: [ { role: 'user', diff --git a/examples/ai-core/src/generate-text/anthropic-cache-control-beta-1h.ts b/examples/ai-core/src/generate-text/anthropic-cache-control-beta-1h.ts index f166f116912b..6abab3162ddc 100644 --- a/examples/ai-core/src/generate-text/anthropic-cache-control-beta-1h.ts +++ b/examples/ai-core/src/generate-text/anthropic-cache-control-beta-1h.ts @@ -1,4 +1,4 @@ -import { anthropic } from '@ai-sdk/anthropic'; +import { anthropic, AnthropicProviderOptions } from '@ai-sdk/anthropic'; import { generateText } from 'ai'; import 'dotenv/config'; import fs from 'node:fs'; @@ -27,7 +27,7 @@ async function main() { providerOptions: { anthropic: { cacheControl: { type: 'ephemeral', ttl: '1h' }, - }, + } satisfies AnthropicProviderOptions, }, }, { diff --git a/packages/anthropic/src/anthropic-messages-language-model.test.ts b/packages/anthropic/src/anthropic-messages-language-model.test.ts index 42921806531c..62c38cf41f81 100644 --- a/packages/anthropic/src/anthropic-messages-language-model.test.ts +++ b/packages/anthropic/src/anthropic-messages-language-model.test.ts @@ -553,7 +553,7 @@ describe('AnthropicMessagesLanguageModel', () => { providerOptions: { anthropic: { cacheControl: { type: 'ephemeral' }, - }, + } satisfies AnthropicProviderOptions, }, }, ], @@ -679,9 +679,6 @@ describe('AnthropicMessagesLanguageModel', () => { const model = provider('claude-3-haiku-20240307'); const result = await model.doGenerate({ - headers: { - 'anthropic-beta': 'extended-cache-ttl-2025-04-11', - }, prompt: [ { role: 'user', @@ -689,7 +686,7 @@ describe('AnthropicMessagesLanguageModel', () => { providerOptions: { anthropic: { cacheControl: { type: 'ephemeral', ttl: '1h' }, - }, + } satisfies AnthropicProviderOptions, }, }, ], @@ -2534,9 +2531,6 @@ describe('AnthropicMessagesLanguageModel', () => { const { stream } = await model.doStream({ prompt: TEST_PROMPT, - headers: { - 'anthropic-beta': 'extended-cache-ttl-2025-04-11', - }, }); expect(await convertReadableStreamToArray(stream)).toMatchInlineSnapshot(` diff --git a/packages/anthropic/src/anthropic-messages-options.ts b/packages/anthropic/src/anthropic-messages-options.ts index f702eed6a893..746dd39f7f2a 100644 --- a/packages/anthropic/src/anthropic-messages-options.ts +++ b/packages/anthropic/src/anthropic-messages-options.ts @@ -67,6 +67,17 @@ export const anthropicProviderOptions = z.object({ * When set to true, Claude will use at most one tool per response. */ disableParallelToolUse: z.boolean().optional(), + + /** + * Cache control settings for this message. + * See https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching + */ + cacheControl: z + .object({ + type: z.literal('ephemeral'), + ttl: z.union([z.literal('5m'), z.literal('1h')]).optional(), + }) + .optional(), }); export type AnthropicProviderOptions = z.infer; From 8a658220f3d9c3c6c183aa2d00cb342b0ca4c64e Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:26:29 -0700 Subject: [PATCH 025/121] Version Packages (#8632) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @ai-sdk/amazon-bedrock@3.0.21 ### Patch Changes - Updated dependencies [da92132] - @ai-sdk/anthropic@2.0.17 ## @ai-sdk/anthropic@2.0.17 ### Patch Changes - da92132: fix(provider/anthorpic): add cacheControl to AnthropicProviderOptions ## @ai-sdk/google-vertex@3.0.27 ### Patch Changes - Updated dependencies [da92132] - @ai-sdk/anthropic@2.0.17 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/gorgeous-pets-tie.md | 5 ----- packages/amazon-bedrock/CHANGELOG.md | 7 +++++++ packages/amazon-bedrock/package.json | 2 +- packages/anthropic/CHANGELOG.md | 6 ++++++ packages/anthropic/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 7 +++++++ packages/google-vertex/package.json | 2 +- 7 files changed, 23 insertions(+), 8 deletions(-) delete mode 100644 .changeset/gorgeous-pets-tie.md diff --git a/.changeset/gorgeous-pets-tie.md b/.changeset/gorgeous-pets-tie.md deleted file mode 100644 index 4f62eb892ec0..000000000000 --- a/.changeset/gorgeous-pets-tie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/anthropic': patch ---- - -fix(provider/anthorpic): add cacheControl to AnthropicProviderOptions diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index d7ef95907fc3..a4fdee36ba7d 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/amazon-bedrock +## 3.0.21 + +### Patch Changes + +- Updated dependencies [da92132] + - @ai-sdk/anthropic@2.0.17 + ## 3.0.20 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 794d6d2f4c69..7ea753402bfb 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.0.20", + "version": "3.0.21", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 9bec596056e3..2192ea928998 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/anthropic +## 2.0.17 + +### Patch Changes + +- da92132: fix(provider/anthorpic): add cacheControl to AnthropicProviderOptions + ## 2.0.16 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 395aaeceee7c..bbccc9cfa1e8 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "2.0.16", + "version": "2.0.17", "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 c95b63fbaf1d..94b915e65644 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/google-vertex +## 3.0.27 + +### Patch Changes + +- Updated dependencies [da92132] + - @ai-sdk/anthropic@2.0.17 + ## 3.0.26 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index c37d99749bc1..5ef580912531 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.0.26", + "version": "3.0.27", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 0f30528731a3b9f85cfb36b7ea40fe344994f9ef Mon Sep 17 00:00:00 2001 From: Parbez Date: Mon, 15 Sep 2025 02:31:30 +0530 Subject: [PATCH 026/121] ci(publis): do not run in forks (#8640) --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0ecedf873e48..e7d9673d3bc6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,8 @@ jobs: name: Release runs-on: ubuntu-latest timeout-minutes: 10 + # do not attempt running in forks + if: github.repository_owner == 'vercel' steps: - name: Create access token for GitHub App uses: actions/create-github-app-token@v2 From 6bfd007ae0817a517cce02b78b1a872415312381 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:52:38 +0100 Subject: [PATCH 027/121] docs: update mcp and move into separate page (#8652) ## Background Given MCP popularity, we should make the documentation more discoverable. ## Summary Created dedicated page for MCP. Added a table for feature comparison between AI SDK Tools and MCP. ## Tasks - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [ ] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [ ] I have reviewed this pull request (self-review) ## Future Work ## Related Issues --- .../15-tools-and-tool-calling.mdx | 191 ++---------------- content/docs/03-ai-sdk-core/16-mcp-tools.mdx | 184 +++++++++++++++++ 2 files changed, 198 insertions(+), 177 deletions(-) create mode 100644 content/docs/03-ai-sdk-core/16-mcp-tools.mdx diff --git a/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx b/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx index 872f6403f8b1..0c7374576fd0 100644 --- a/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +++ b/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx @@ -827,187 +827,24 @@ export const weatherTool = tool({ ## MCP Tools - - The MCP tools feature is experimental and may change in the future. - - -The AI SDK supports connecting to [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers to access their tools. -This enables your AI applications to discover and use tools across various services through a standardized interface. - -### Initializing an MCP Client - -Create an MCP client using either: - -- `SSE` (Server-Sent Events): Uses HTTP-based real-time communication, better suited for remote servers that need to send data over the network -- `stdio`: Uses standard input and output streams for communication, ideal for local tool servers running on the same machine (like CLI tools or local services) -- Custom transport: Bring your own transport by implementing the `MCPTransport` interface, ideal when implementing transports from MCP's official Typescript SDK (e.g. `StreamableHTTPClientTransport`) - -#### SSE Transport - -The SSE can be configured using a simple object with a `type` and `url` property: - -```typescript -import { experimental_createMCPClient as createMCPClient } from 'ai'; - -const mcpClient = await createMCPClient({ - transport: { - type: 'sse', - url: 'https://my-server.com/sse', - - // optional: configure HTTP headers, e.g. for authentication - headers: { - Authorization: 'Bearer my-api-key', - }, - }, -}); -``` - -#### Stdio Transport - -The Stdio transport requires importing the `StdioMCPTransport` class from the `ai/mcp-stdio` package: - -```typescript -import { experimental_createMCPClient as createMCPClient } from 'ai'; -import { Experimental_StdioMCPTransport as StdioMCPTransport } from 'ai/mcp-stdio'; - -const mcpClient = await createMCPClient({ - transport: new StdioMCPTransport({ - command: 'node', - args: ['src/stdio/dist/server.js'], - }), -}); -``` - -#### Custom Transport - -You can also bring your own transport, as long as it implements the `MCPTransport` interface. Below is an example of using the new `StreamableHTTPClientTransport` from MCP's official Typescript SDK: - -```typescript -import { - MCPTransport, - experimental_createMCPClient as createMCPClient, -} from 'ai'; -import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp'; - -const url = new URL('http://localhost:3000/mcp'); -const mcpClient = await createMCPClient({ - transport: new StreamableHTTPClientTransport(url, { - sessionId: 'session_123', - }), -}); -``` - - - The client returned by the `experimental_createMCPClient` function is a - lightweight client intended for use in tool conversion. It currently does not - support all features of the full MCP client, such as: authorization, session - management, resumable streams, and receiving notifications. - - -#### Closing the MCP Client - -After initialization, you should close the MCP client based on your usage pattern: - -- For short-lived usage (e.g., single requests), close the client when the response is finished -- For long-running clients (e.g., command line apps), keep the client open but ensure it's closed when the application terminates - -When streaming responses, you can close the client when the LLM response has finished. For example, when using `streamText`, you should use the `onFinish` callback: - -```typescript -const mcpClient = await experimental_createMCPClient({ - // ... -}); - -const tools = await mcpClient.tools(); - -const result = await streamText({ - model: openai('gpt-4.1'), - tools, - prompt: 'What is the weather in Brooklyn, New York?', - onFinish: async () => { - await mcpClient.close(); - }, -}); -``` - -When generating responses without streaming, you can use try/finally or cleanup functions in your framework: - -```typescript -let mcpClient: MCPClient | undefined; - -try { - mcpClient = await experimental_createMCPClient({ - // ... - }); -} finally { - await mcpClient?.close(); -} -``` - -### Using MCP Tools - -The client's `tools` method acts as an adapter between MCP tools and AI SDK tools. It supports two approaches for working with tool schemas: - -#### Schema Discovery - -The simplest approach where all tools offered by the server are listed, and input parameter types are inferred based the schemas provided by the server: - -```typescript -const tools = await mcpClient.tools(); -``` - -**Pros:** - -- Simpler to implement -- Automatically stays in sync with server changes - -**Cons:** - -- No TypeScript type safety during development -- No IDE autocompletion for tool parameters -- Errors only surface at runtime -- Loads all tools from the server - -#### Schema Definition - -You can also define the tools and their input schemas explicitly in your client code: - -```typescript -import { z } from 'zod'; - -const tools = await mcpClient.tools({ - schemas: { - 'get-data': { - inputSchema: z.object({ - query: z.string().describe('The data query'), - format: z.enum(['json', 'text']).optional(), - }), - }, - // For tools with zero inputs, you should use an empty object: - 'tool-with-no-args': { - inputSchema: z.object({}), - }, - }, -}); -``` - -**Pros:** - -- Control over which tools are loaded -- Full TypeScript type safety -- Better IDE support with autocompletion -- Catch parameter mismatches during development +The AI SDK supports connecting to Model Context Protocol (MCP) servers to access their tools. +MCP enables your AI applications to discover and use tools across various services through a standardized interface. -**Cons:** +For detailed information about MCP tools, including initialization, transport options, and usage patterns, see the [MCP Tools documentation](/docs/ai-sdk-core/mcp-tools). -- Need to manually keep schemas in sync with server -- More code to maintain +### AI SDK Tools vs MCP Tools -When you define `schemas`, the client will only pull the explicitly defined tools, even if the server offers additional tools. This can be beneficial for: +In most cases, you should define your own AI SDK tools for production applications. They provide full control, type safety, and optimal performance. MCP tools are best suited for rapid development iteration and scenarios where users bring their own tools. -- Keeping your application focused on the tools it needs -- Reducing unnecessary tool loading -- Making your tool dependencies explicit +| Aspect | AI SDK Tools | MCP Tools | +| ---------------------- | --------------------------------------------------------- | ----------------------------------------------------- | +| **Type Safety** | Full static typing end-to-end | Dynamic discovery at runtime | +| **Execution** | Same process as your request (low latency) | Separate server (network overhead) | +| **Prompt Control** | Full control over descriptions and schemas | Controlled by MCP server owner | +| **Schema Control** | You define and optimize for your model | Controlled by MCP server owner | +| **Version Management** | Full visibility over updates | Can update independently (version skew risk) | +| **Authentication** | Same process, no additional auth required | Separate server introduces additional auth complexity | +| **Best For** | Production applications requiring control and performance | Development iteration, user-provided tools | ## Examples diff --git a/content/docs/03-ai-sdk-core/16-mcp-tools.mdx b/content/docs/03-ai-sdk-core/16-mcp-tools.mdx new file mode 100644 index 000000000000..05d40b9a7910 --- /dev/null +++ b/content/docs/03-ai-sdk-core/16-mcp-tools.mdx @@ -0,0 +1,184 @@ +--- +title: Model Context Protocol (MCP) Tools +description: Learn how to connect to Model Context Protocol (MCP) servers and use their tools with AI SDK Core. +--- + +# Model Context Protocol (MCP) Tools + + + The MCP tools feature is experimental and may change in the future. + + +The AI SDK supports connecting to [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers to access their tools. +This enables your AI applications to discover and use tools across various services through a standardized interface. + +## Initializing an MCP Client + +We recommend using HTTP transport (like `StreamableHTTPClientTransport`) for production deployments. The stdio transport should only be used for connecting to local servers as it cannot be deployed to production environments. + +Create an MCP client using one of the following transport options: + +- **HTTP transport (Recommended)**: Use transports from MCP's official TypeScript SDK like `StreamableHTTPClientTransport` for production deployments +- SSE (Server-Sent Events): An alternative HTTP-based transport +- `stdio`: For local development only. Uses standard input/output streams for local MCP servers + +### HTTP Transport (Recommended) + +For production deployments, we recommend using HTTP transports like `StreamableHTTPClientTransport` from MCP's official TypeScript SDK: + +```typescript +import { experimental_createMCPClient as createMCPClient } from 'ai'; +import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; + +const url = new URL('https://your-server.com/mcp'); +const mcpClient = await createMCPClient({ + transport: new StreamableHTTPClientTransport(url, { + sessionId: 'session_123', + }), +}); +``` + +### SSE Transport + +SSE provides an alternative HTTP-based transport option. Configure it with a `type` and `url` property: + +```typescript +import { experimental_createMCPClient as createMCPClient } from 'ai'; + +const mcpClient = await createMCPClient({ + transport: { + type: 'sse', + url: 'https://my-server.com/sse', + + // optional: configure HTTP headers, e.g. for authentication + headers: { + Authorization: 'Bearer my-api-key', + }, + }, +}); +``` + +### Stdio Transport (Local Servers) + + + The stdio transport should only be used for local servers. + + +The Stdio transport can be imported from either the MCP SDK or the AI SDK: + +```typescript +import { experimental_createMCPClient as createMCPClient } from 'ai'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; +// Or use the AI SDK's stdio transport: +// import { Experimental_StdioMCPTransport as StdioClientTransport } from 'ai/mcp-stdio'; + +const mcpClient = await createMCPClient({ + transport: new StdioClientTransport({ + command: 'node', + args: ['src/stdio/dist/server.js'], + }), +}); +``` + +### Custom Transport + +You can also bring your own transport by implementing the `MCPTransport` interface for specific requirements not covered by the standard transports. + + + The client returned by the `experimental_createMCPClient` function is a + lightweight client intended for use in tool conversion. It currently does not + support all features of the full MCP client, such as: authorization, session + management, resumable streams, and receiving notifications. + + +### Closing the MCP Client + +After initialization, you should close the MCP client based on your usage pattern: + +- For short-lived usage (e.g., single requests), close the client when the response is finished +- For long-running clients (e.g., command line apps), keep the client open but ensure it's closed when the application terminates + +When streaming responses, you can close the client when the LLM response has finished. For example, when using `streamText`, you should use the `onFinish` callback: + +```typescript +const mcpClient = await experimental_createMCPClient({ + // ... +}); + +const tools = await mcpClient.tools(); + +const result = await streamText({ + model: 'openai/gpt-4.1', + tools, + prompt: 'What is the weather in Brooklyn, New York?', + onFinish: async () => { + await mcpClient.close(); + }, +}); +``` + +When generating responses without streaming, you can use try/finally or cleanup functions in your framework: + +```typescript +let mcpClient: MCPClient | undefined; + +try { + mcpClient = await experimental_createMCPClient({ + // ... + }); +} finally { + await mcpClient?.close(); +} +``` + +## Using MCP Tools + +The client's `tools` method acts as an adapter between MCP tools and AI SDK tools. It supports two approaches for working with tool schemas: + +### Schema Discovery + +With schema discovery, all tools offered by the server are automatically listed, and input parameter types are inferred based on the schemas provided by the server: + +```typescript +const tools = await mcpClient.tools(); +``` + +This approach is simpler to implement and automatically stays in sync with server changes. However, you won't have TypeScript type safety during development, and all tools from the server will be loaded + +### Schema Definition + +For better type safety and control, you can define the tools and their input schemas explicitly in your client code: + +```typescript +import { z } from 'zod'; + +const tools = await mcpClient.tools({ + schemas: { + 'get-data': { + inputSchema: z.object({ + query: z.string().describe('The data query'), + format: z.enum(['json', 'text']).optional(), + }), + }, + // For tools with zero inputs, you should use an empty object: + 'tool-with-no-args': { + inputSchema: z.object({}), + }, + }, +}); +``` + +This approach provides full TypeScript type safety and IDE autocompletion, letting you catch parameter mismatches during development. When you define `schemas`, the client only pulls the explicitly defined tools, keeping your application focused on the tools it needs + +## Examples + +You can see MCP tools in action in the following example: + + From 28363da81e17369f0f02a70dff9a7ec0240fb0dc Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Mon, 15 Sep 2025 09:28:32 -0700 Subject: [PATCH 028/121] feat(openai-compatible): add `supportsStructuredOutputs` to provider settings (#8546) ## Background Alternative implementation to #5262 which doesn't introduce a 2nd argument for a model constructor, which would break our provider registry feature related: - https://github.com/vercel/ai/issues/8475#issuecomment-3264158527 - https://github.com/vercel/ai/pull/8428 - https://github.com/vercel/ai/issues/8427 ## Summary Introduce a new `supportsStructuredOutputs` option to `createOpenAICompatible()` that gets passed to `provider.languageModel` and `provider.chatModel` ## Manual Verification ```ts import 'dotenv/config'; import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { generateObject } from 'ai'; import { z } from 'zod/v4'; async function main() { const togetherai = createOpenAICompatible({ baseURL: 'https://api.together.xyz/v1', name: 'togetherai', headers: { Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`, }, supportsStructuredOutputs: true, }); const model = togetherai.chatModel('mistralai/Mistral-7B-Instruct-v0.1'); const result = await generateObject({ model, schema: z.object({ recipe: z.object({ name: z.string(), ingredients: z.array( z.object({ name: z.string(), amount: z.string(), }), ), steps: z.array(z.string()), }), }), prompt: 'Generate a lasagna recipe.', }); console.log(JSON.stringify(result.object.recipe, null, 2)); console.log(); console.log('Token usage:', result.usage); console.log('Finish reason:', result.finishReason); } main().catch(console.error); ``` ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Future work Since the `createOpenAICompatible` option is only relevant to some of the model types, we might consider adding sub configuration for each model type if more of these type of options get added ## Related Issues closes #5262 closes #8427 closes #8428 --- .changeset/yellow-jeans-know.md | 5 ++ .../02-openai-compatible-providers/index.mdx | 4 ++ .../openai-compatible-togetherai.ts | 1 + .../src/openai-compatible-provider.test.ts | 60 +++++++++++++++++++ .../src/openai-compatible-provider.ts | 16 ++++- 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 .changeset/yellow-jeans-know.md diff --git a/.changeset/yellow-jeans-know.md b/.changeset/yellow-jeans-know.md new file mode 100644 index 000000000000..e4886b20af96 --- /dev/null +++ b/.changeset/yellow-jeans-know.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai-compatible': patch +--- + +feat(openai-compatible): add `supportsStructuredOutputs` to provider settings diff --git a/content/providers/02-openai-compatible-providers/index.mdx b/content/providers/02-openai-compatible-providers/index.mdx index 678e87e531d1..28c3b1653ac4 100644 --- a/content/providers/02-openai-compatible-providers/index.mdx +++ b/content/providers/02-openai-compatible-providers/index.mdx @@ -85,6 +85,10 @@ You can use the following optional settings to customize the provider instance: Include usage information in streaming responses. When enabled, usage data will be included in the response metadata for streaming requests. Defaults to `undefined` (`false`). +- **supportsStructuredOutputs** _boolean_ + + Set to true if the provider supports structured outputs. Only relevant for `provider()`, `provider.chatModel()`, and `provider.languageModel()`. + ## Language Models You can create provider models using a provider instance. diff --git a/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts b/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts index a8dcfba81fa8..bb37f6a5db20 100644 --- a/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts +++ b/examples/ai-core/src/generate-object/openai-compatible-togetherai.ts @@ -10,6 +10,7 @@ async function main() { headers: { Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`, }, + supportsStructuredOutputs: true, }); const model = togetherai.chatModel('mistralai/Mistral-7B-Instruct-v0.1'); const result = await generateObject({ diff --git a/packages/openai-compatible/src/openai-compatible-provider.test.ts b/packages/openai-compatible/src/openai-compatible-provider.test.ts index 35f001a966d1..3fbeb3e0ca77 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.test.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.test.ts @@ -2,6 +2,7 @@ import { createOpenAICompatible } from './openai-compatible-provider'; import { OpenAICompatibleChatLanguageModel } from './chat/openai-compatible-chat-language-model'; import { OpenAICompatibleCompletionLanguageModel } from './completion/openai-compatible-completion-language-model'; import { OpenAICompatibleEmbeddingModel } from './embedding/openai-compatible-embedding-model'; +import { OpenAICompatibleImageModel } from './image/openai-compatible-image-model'; import { vi, describe, beforeEach, it, expect } from 'vitest'; // Mock version @@ -19,10 +20,16 @@ const OpenAICompatibleEmbeddingModelMock = vi.mocked( OpenAICompatibleEmbeddingModel, ); +const OpenAICompatibleImageModelMock = vi.mocked(OpenAICompatibleImageModel); + vi.mock('./chat/openai-compatible-chat-language-model', () => ({ OpenAICompatibleChatLanguageModel: vi.fn(), })); +vi.mock('./image/openai-compatible-image-model', () => ({ + OpenAICompatibleImageModel: vi.fn(), +})); + vi.mock('./completion/openai-compatible-completion-language-model', () => ({ OpenAICompatibleCompletionLanguageModel: vi.fn(), })); @@ -266,4 +273,57 @@ describe('OpenAICompatibleProvider', () => { ).toBeUndefined(); }); }); + + describe('supportsStructuredOutputs setting', () => { + it('should pass supportsStructuredOutputs to to .chatModel() and .languageModel() only', () => { + const options = { + baseURL: 'https://api.example.com', + name: 'test-provider', + supportsStructuredOutputs: true, + }; + const provider = createOpenAICompatible(options); + + provider('model-id'); + expect( + OpenAICompatibleChatLanguageModelMock.mock.calls[0][1] + .supportsStructuredOutputs, + ).toBe(true); + + provider.chatModel('chat-model'); + expect( + OpenAICompatibleChatLanguageModelMock.mock.calls[1][1] + .supportsStructuredOutputs, + ).toBe(true); + + provider.languageModel('completion-model'); + expect( + OpenAICompatibleChatLanguageModelMock.mock.calls[2][1] + .supportsStructuredOutputs, + ).toBe(true); + + provider.completionModel('completion-model'); + const completionModelConfigArg = + OpenAICompatibleCompletionLanguageModelMock.mock.calls[0][1]; + expect( + // @ts-expect-error - testing + completionModelConfigArg.supportsStructuredOutputs, + ).toBe(undefined); + + provider.textEmbeddingModel('embedding-model'); + const embeddingModelConfigArg = + OpenAICompatibleEmbeddingModelMock.mock.calls[0][1]; + expect( + // @ts-expect-error - testing + embeddingModelConfigArg.supportsStructuredOutputs, + ).toBe(undefined); + + provider.imageModel('image-model'); + const imageModelConfigArg = + OpenAICompatibleImageModelMock.mock.calls[0][1]; + expect( + // @ts-expect-error - testing + imageModelConfigArg.supportsStructuredOutputs, + ).toBe(undefined); + }); + }); }); diff --git a/packages/openai-compatible/src/openai-compatible-provider.ts b/packages/openai-compatible/src/openai-compatible-provider.ts index f34a8cb220cc..58a1ba71d57f 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.ts @@ -10,7 +10,10 @@ import { withUserAgentSuffix, getRuntimeEnvironmentUserAgent, } from '@ai-sdk/provider-utils'; -import { OpenAICompatibleChatLanguageModel } from './chat/openai-compatible-chat-language-model'; +import { + OpenAICompatibleChatConfig, + OpenAICompatibleChatLanguageModel, +} from './chat/openai-compatible-chat-language-model'; import { OpenAICompatibleCompletionLanguageModel } from './completion/openai-compatible-completion-language-model'; import { OpenAICompatibleEmbeddingModel } from './embedding/openai-compatible-embedding-model'; import { OpenAICompatibleImageModel } from './image/openai-compatible-image-model'; @@ -24,7 +27,10 @@ export interface OpenAICompatibleProvider< > extends Omit { (modelId: CHAT_MODEL_IDS): LanguageModelV2; - languageModel(modelId: CHAT_MODEL_IDS): LanguageModelV2; + languageModel( + modelId: CHAT_MODEL_IDS, + config?: Partial, + ): LanguageModelV2; chatModel(modelId: CHAT_MODEL_IDS): LanguageModelV2; @@ -74,6 +80,11 @@ or to provide a custom fetch implementation for e.g. testing. Include usage information in streaming responses. */ includeUsage?: boolean; + + /** + * Whether the provider supports structured outputs in chat models. + */ + supportsStructuredOutputs?: boolean; } /** @@ -130,6 +141,7 @@ export function createOpenAICompatible< new OpenAICompatibleChatLanguageModel(modelId, { ...getCommonModelConfig('chat'), includeUsage: options.includeUsage, + supportsStructuredOutputs: options.supportsStructuredOutputs, }); const createCompletionModel = (modelId: COMPLETION_MODEL_IDS) => From 474a0eddfc8c046fbc2c29b7d4bc3f900cdc683c Mon Sep 17 00:00:00 2001 From: Francisco Veiras <74626997+fveiraswww@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:56:28 -0300 Subject: [PATCH 029/121] docs(examples): switch next example to use AI Gateway provider (#8654) ## Background the Next.js example was using the OpenAI provider directly, which requires users to have an OpenAI API key and limits them to only OpenAI models. By switching to AI Gateway, users can access multiple AI providers ## Summary - Replaced `@ai-sdk/openai` provider with a direct model string - Updated the Next.js example to use the cheaper `gpt-5-mini` model --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- examples/next/app/api/chat/route.ts | 3 +-- examples/next/package.json | 1 - pnpm-lock.yaml | 9 +++------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/next/app/api/chat/route.ts b/examples/next/app/api/chat/route.ts index 54b5b11e46c6..1ec9ee37f75c 100644 --- a/examples/next/app/api/chat/route.ts +++ b/examples/next/app/api/chat/route.ts @@ -1,5 +1,4 @@ import type { MyUIMessage } from '@/util/chat-schema'; -import { openai } from '@ai-sdk/openai'; import { readChat, saveChat } from '@util/chat-store'; import { convertToModelMessages, generateId, streamText } from 'ai'; import { after } from 'next/server'; @@ -57,7 +56,7 @@ export async function POST(req: Request) { saveChat({ id, messages, activeStreamId: null }); const result = streamText({ - model: openai('gpt-4o-mini'), + model: 'openai/gpt-5-mini', messages: convertToModelMessages(messages), abortSignal: req.signal, }); diff --git a/examples/next/package.json b/examples/next/package.json index b8d07801f9c7..1a336b3a68d7 100644 --- a/examples/next/package.json +++ b/examples/next/package.json @@ -9,7 +9,6 @@ "lint": "next lint" }, "dependencies": { - "@ai-sdk/openai": "workspace:*", "@ai-sdk/react": "workspace:*", "@vercel/blob": "^0.26.0", "ai": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed8b29bea144..3c7f4964fd3f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -504,9 +504,6 @@ importers: examples/next: dependencies: - '@ai-sdk/openai': - specifier: workspace:* - version: link:../../packages/openai '@ai-sdk/react': specifier: workspace:* version: link:../../packages/react @@ -29319,7 +29316,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.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.34.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -29408,7 +29405,7 @@ snapshots: enhanced-resolve: 5.17.1 eslint: 8.57.1 eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.3 get-tsconfig: 4.8.1 is-core-module: 2.16.1 @@ -29534,7 +29531,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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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 32f3cef5f0c8d9cb6e98f6eed859eb416e0d7486 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:06:29 -0400 Subject: [PATCH 030/121] feat: adding user-agent to all packages that use global fetch directly (#8622) ## Background All the packages that use global fetch directly have to be updated so that user-agent header is set properly ## Summary - updated tests to reflect the new user-agent header - package version is updated during build and test phases - exports added to use the `__PACKAGE_VERSION__` ## Manual Verification updated tests to reflect the new user-agent header ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Future Work - [x] amazon-bedrock - [x] google-vertex ## Related Issues fixes #8617 --- .changeset/dry-cheetahs-eat.md | 5 ++ .../ai/src/tool/mcp/mcp-sse-transport.test.ts | 2 + packages/ai/src/tool/mcp/mcp-sse-transport.ts | 27 ++++++++-- packages/ai/src/ui/call-completion-api.ts | 20 ++++++-- .../ai/src/ui/http-chat-transport.test.ts | 2 + packages/ai/src/ui/http-chat-transport.ts | 27 +++++++--- .../ai/src/util/download/download.test.ts | 3 ++ packages/ai/src/util/download/download.ts | 13 ++++- .../src/bedrock-sigv4-fetch.test.ts | 44 +++++++++++++++-- .../amazon-bedrock/src/bedrock-sigv4-fetch.ts | 42 +++++++++++----- packages/amazon-bedrock/src/index.ts | 1 + .../src/inject-fetch-headers.test.ts | 49 ++++++++++++++----- .../src/inject-fetch-headers.ts | 25 +++++++--- packages/amazon-bedrock/src/version.ts | 6 +++ packages/amazon-bedrock/tsup.config.ts | 6 +++ packages/amazon-bedrock/vitest.edge.config.js | 4 ++ packages/amazon-bedrock/vitest.node.config.js | 4 ++ .../src/edge/google-vertex-auth-edge.test.ts | 33 +++++++++++++ .../src/edge/google-vertex-auth-edge.ts | 14 +++++- packages/google-vertex/src/version.ts | 6 +++ packages/google-vertex/tsup.config.ts | 24 +++++++++ packages/google-vertex/vitest.edge.config.js | 4 ++ packages/google-vertex/vitest.node.config.js | 4 ++ .../provider-utils/src/test/test-server.ts | 4 ++ 24 files changed, 316 insertions(+), 53 deletions(-) create mode 100644 .changeset/dry-cheetahs-eat.md create mode 100644 packages/amazon-bedrock/src/version.ts create mode 100644 packages/google-vertex/src/version.ts diff --git a/.changeset/dry-cheetahs-eat.md b/.changeset/dry-cheetahs-eat.md new file mode 100644 index 000000000000..dff576498639 --- /dev/null +++ b/.changeset/dry-cheetahs-eat.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/amazon-bedrock': patch +--- + +feat: adding user-agent to all packages that use global fetch directly diff --git a/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts b/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts index c6470b5eb59d..94b24e79d6f1 100644 --- a/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts +++ b/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts @@ -269,12 +269,14 @@ describe('SseMCPTransport', () => { accept: 'text/event-stream', ...customHeaders, }); + expect(server.calls[0].requestUserAgent).toContain('ai-sdk/'); // Verify POST request headers expect(server.calls[1].requestHeaders).toEqual({ 'content-type': 'application/json', ...customHeaders, }); + expect(server.calls[1].requestUserAgent).toContain('ai-sdk/'); await transport.close(); }); diff --git a/packages/ai/src/tool/mcp/mcp-sse-transport.ts b/packages/ai/src/tool/mcp/mcp-sse-transport.ts index 1fd2ddc7ff14..5ca2be0b93f4 100644 --- a/packages/ai/src/tool/mcp/mcp-sse-transport.ts +++ b/packages/ai/src/tool/mcp/mcp-sse-transport.ts @@ -1,7 +1,12 @@ -import { EventSourceParserStream } from '@ai-sdk/provider-utils'; +import { + EventSourceParserStream, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; import { MCPClientError } from '../../error/mcp-client-error'; import { JSONRPCMessage, JSONRPCMessageSchema } from './json-rpc-message'; import { MCPTransport } from './mcp-transport'; +import { VERSION } from '../../version'; export class SseMCPTransport implements MCPTransport { private endpoint?: URL; @@ -38,8 +43,14 @@ export class SseMCPTransport implements MCPTransport { const establishConnection = async () => { try { - const headers = new Headers(this.headers); - headers.set('Accept', 'text/event-stream'); + const headers = withUserAgentSuffix( + { + ...this.headers, + Accept: 'text/event-stream', + }, + `ai-sdk/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ); const response = await fetch(this.url.href, { headers, signal: this.abortController?.signal, @@ -149,8 +160,14 @@ export class SseMCPTransport implements MCPTransport { } try { - const headers = new Headers(this.headers); - headers.set('Content-Type', 'application/json'); + const headers = withUserAgentSuffix( + { + ...this.headers, + 'Content-Type': 'application/json', + }, + `ai-sdk/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ); const init = { method: 'POST', headers, diff --git a/packages/ai/src/ui/call-completion-api.ts b/packages/ai/src/ui/call-completion-api.ts index 2af1196e1df9..8174dac67ac2 100644 --- a/packages/ai/src/ui/call-completion-api.ts +++ b/packages/ai/src/ui/call-completion-api.ts @@ -1,10 +1,16 @@ -import { parseJsonEventStream, ParseResult } from '@ai-sdk/provider-utils'; +import { + parseJsonEventStream, + ParseResult, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; import { UIMessageChunk, uiMessageChunkSchema, } from '../ui-message-stream/ui-message-chunks'; import { consumeStream } from '../util/consume-stream'; import { processTextStream } from './process-text-stream'; +import { VERSION } from '../version'; // use function to allow for mocking in tests: const getOriginalFetch = () => fetch; @@ -55,10 +61,14 @@ export async function callCompletionApi({ ...body, }), credentials, - headers: { - 'Content-Type': 'application/json', - ...headers, - }, + headers: withUserAgentSuffix( + { + 'Content-Type': 'application/json', + ...headers, + }, + `ai-sdk/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), signal: abortController.signal, }).catch(err => { throw err; diff --git a/packages/ai/src/ui/http-chat-transport.test.ts b/packages/ai/src/ui/http-chat-transport.test.ts index 031f537baff9..f032e9d7e43c 100644 --- a/packages/ai/src/ui/http-chat-transport.test.ts +++ b/packages/ai/src/ui/http-chat-transport.test.ts @@ -148,6 +148,7 @@ describe('HttpChatTransport', () => { expect(server.calls[0].requestHeaders['x-test-header']).toBe( 'test-value', ); + expect(server.calls[0].requestUserAgent).toContain('ai-sdk/'); }); it('should include headers in the request when a function is provided', async () => { @@ -178,6 +179,7 @@ describe('HttpChatTransport', () => { expect(server.calls[0].requestHeaders['x-test-header']).toBe( 'test-value-fn', ); + expect(server.calls[0].requestUserAgent).toContain('ai-sdk/'); }); }); }); diff --git a/packages/ai/src/ui/http-chat-transport.ts b/packages/ai/src/ui/http-chat-transport.ts index b0ed429eb5c6..d304e4f794cf 100644 --- a/packages/ai/src/ui/http-chat-transport.ts +++ b/packages/ai/src/ui/http-chat-transport.ts @@ -1,7 +1,14 @@ -import { FetchFunction, Resolvable, resolve } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + Resolvable, + resolve, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; import { UIMessageChunk } from '../ui-message-stream/ui-message-chunks'; import { ChatTransport } from './chat-transport'; import { UIMessage } from './ui-messages'; +import { VERSION } from '../version'; export type PrepareSendMessagesRequest = ( options: { @@ -188,10 +195,14 @@ export abstract class HttpChatTransport const response = await fetch(api, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - ...headers, - }, + headers: withUserAgentSuffix( + { + 'Content-Type': 'application/json', + ...headers, + }, + `ai-sdk/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), body: JSON.stringify(body), credentials, signal: abortSignal, @@ -238,7 +249,11 @@ export abstract class HttpChatTransport const response = await fetch(api, { method: 'GET', - headers, + headers: withUserAgentSuffix( + headers, + `ai-sdk/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), credentials, }); diff --git a/packages/ai/src/util/download/download.test.ts b/packages/ai/src/util/download/download.test.ts index 8f483ed88e79..5f2c3b240e04 100644 --- a/packages/ai/src/util/download/download.test.ts +++ b/packages/ai/src/util/download/download.test.ts @@ -26,6 +26,9 @@ describe('download', () => { expect(result).not.toBeNull(); expect(result!.data).toEqual(expectedBytes); expect(result!.mediaType).toBe('application/octet-stream'); + + // UA header assertion + expect(server.calls[0].requestUserAgent).toContain('ai-sdk/'); }); it('should throw DownloadError when response is not ok', async () => { diff --git a/packages/ai/src/util/download/download.ts b/packages/ai/src/util/download/download.ts index 84ae6d6db0de..57b3ca2bcd7b 100644 --- a/packages/ai/src/util/download/download.ts +++ b/packages/ai/src/util/download/download.ts @@ -1,4 +1,9 @@ import { DownloadError } from './download-error'; +import { + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; +import { VERSION } from '../../version'; /** * Download a file from a URL. @@ -11,7 +16,13 @@ import { DownloadError } from './download-error'; export const download = async ({ url }: { url: URL }) => { const urlText = url.toString(); try { - const response = await fetch(urlText); + const response = await fetch(urlText, { + headers: withUserAgentSuffix( + {}, + `ai-sdk/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), + }); if (!response.ok) { throw new DownloadError({ diff --git a/packages/amazon-bedrock/src/bedrock-sigv4-fetch.test.ts b/packages/amazon-bedrock/src/bedrock-sigv4-fetch.test.ts index b832d06109ac..b7ee239352bd 100644 --- a/packages/amazon-bedrock/src/bedrock-sigv4-fetch.test.ts +++ b/packages/amazon-bedrock/src/bedrock-sigv4-fetch.test.ts @@ -4,6 +4,20 @@ import { } from './bedrock-sigv4-fetch'; import { vi, describe, it, expect, afterEach } from 'vitest'; +// Mock the version module +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + +// Mock provider-utils to control runtime environment detection +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + getRuntimeEnvironmentUserAgent: vi.fn(() => 'runtime/testenv'), + }; +}); + // Mock AwsV4Signer so that no real crypto calls are made. vi.mock('aws4fetch', () => { class MockAwsV4Signer { @@ -48,6 +62,9 @@ describe('createSigV4FetchFunction', () => { const response = await fetchFn('http://example.com', { method: 'GET' }); expect(dummyFetch).toHaveBeenCalledWith('http://example.com', { method: 'GET', + headers: { + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }, }); expect(response).toBe(dummyResponse); }); @@ -60,11 +77,14 @@ describe('createSigV4FetchFunction', () => { const response = await fetchFn('http://example.com', { method: 'POST' }); expect(dummyFetch).toHaveBeenCalledWith('http://example.com', { method: 'POST', + headers: { + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }, }); expect(response).toBe(dummyResponse); }); - it('should handle a POST request with a string body and merge signed headers', async () => { + it('should handle a POST request with a string body and merge signed headers including user-agent', async () => { const dummyResponse = new Response('Signed', { status: 200 }); const dummyFetch = vi.fn().mockResolvedValue(dummyResponse); @@ -103,6 +123,9 @@ describe('createSigV4FetchFunction', () => { 'AWS4-HMAC-SHA256 Credential=test', ); expect(headers['x-amz-security-token']).toEqual('test-session-token'); + expect(headers['user-agent']).toEqual( + 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + ); // Body is left unmodified for a string body. expect(calledInit.body).toEqual('{"test": "data"}'); }); @@ -222,7 +245,11 @@ describe('createSigV4FetchFunction', () => { const fetchFn = createFetchFunction(dummyFetch); const response = await fetchFn('http://example.com'); - expect(dummyFetch).toHaveBeenCalledWith('http://example.com', undefined); + expect(dummyFetch).toHaveBeenCalledWith('http://example.com', { + headers: { + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }, + }); expect(response).toBe(dummyResponse); }); @@ -297,7 +324,7 @@ describe('createApiKeyFetchFunction', () => { vi.restoreAllMocks(); }); - it('should add Authorization header with Bearer token', async () => { + it('should add Authorization header with Bearer token and user-agent', async () => { const dummyResponse = new Response('OK', { status: 200 }); const dummyFetch = vi.fn().mockResolvedValue(dummyResponse); const apiKey = 'test-api-key-123'; @@ -318,6 +345,7 @@ describe('createApiKeyFetchFunction', () => { headers: { 'content-type': 'application/json', Authorization: 'Bearer test-api-key-123', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); expect(response).toBe(dummyResponse); @@ -348,6 +376,7 @@ describe('createApiKeyFetchFunction', () => { 'custom-header': 'custom-value', 'x-request-id': 'req-123', Authorization: 'Bearer test-api-key-456', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -376,6 +405,7 @@ describe('createApiKeyFetchFunction', () => { 'content-type': 'application/json', 'x-custom': 'value', Authorization: 'Bearer test-api-key-789', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -405,6 +435,7 @@ describe('createApiKeyFetchFunction', () => { 'content-type': 'application/json', 'x-array-header': 'array-value', Authorization: 'Bearer test-api-key-array', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -428,6 +459,7 @@ describe('createApiKeyFetchFunction', () => { headers: { accept: 'application/json', Authorization: 'Bearer test-api-key-get', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -449,6 +481,7 @@ describe('createApiKeyFetchFunction', () => { body: '{"test": "data"}', headers: { Authorization: 'Bearer test-api-key-no-headers', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -465,6 +498,7 @@ describe('createApiKeyFetchFunction', () => { expect(dummyFetch).toHaveBeenCalledWith('http://example.com', { headers: { Authorization: 'Bearer test-api-key-undefined', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -492,6 +526,7 @@ describe('createApiKeyFetchFunction', () => { 'content-type': 'application/json', Authorization: 'Bearer test-api-key-override', authorization: 'Bearer old-token', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -515,6 +550,7 @@ describe('createApiKeyFetchFunction', () => { body: '{"test": "data"}', headers: { Authorization: 'Bearer test-api-key-default', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); } finally { @@ -539,6 +575,7 @@ describe('createApiKeyFetchFunction', () => { body: '{"test": "data"}', headers: { Authorization: 'Bearer ', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, }); }); @@ -567,6 +604,7 @@ describe('createApiKeyFetchFunction', () => { headers: { 'content-type': 'application/json', Authorization: 'Bearer test-api-key-preserve', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', }, credentials: 'include', cache: 'no-cache', diff --git a/packages/amazon-bedrock/src/bedrock-sigv4-fetch.ts b/packages/amazon-bedrock/src/bedrock-sigv4-fetch.ts index 9398345c96be..5e6ddfdd34ce 100644 --- a/packages/amazon-bedrock/src/bedrock-sigv4-fetch.ts +++ b/packages/amazon-bedrock/src/bedrock-sigv4-fetch.ts @@ -2,9 +2,11 @@ import { convertHeadersToRecord, extractHeaders } from './headers-utils'; import { FetchFunction, combineHeaders, - removeUndefinedEntries, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, } from '@ai-sdk/provider-utils'; import { AwsV4Signer } from 'aws4fetch'; +import { VERSION } from './version'; export interface BedrockCredentials { region: string; @@ -28,8 +30,18 @@ export function createSigV4FetchFunction( input: RequestInfo | URL, init?: RequestInit, ): Promise => { + const originalHeaders = extractHeaders(init?.headers); + const headersWithUserAgent = withUserAgentSuffix( + originalHeaders, + `ai-sdk/amazon-bedrock/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ); + if (init?.method?.toUpperCase() !== 'POST' || !init?.body) { - return fetch(input, init); + return fetch(input, { + ...init, + headers: headersWithUserAgent as HeadersInit, + }); } const url = @@ -39,13 +51,12 @@ export function createSigV4FetchFunction( ? input.href : input.url; - const originalHeaders = extractHeaders(init.headers); const body = prepareBodyString(init.body); const credentials = await getCredentials(); const signer = new AwsV4Signer({ url, method: 'POST', - headers: Object.entries(removeUndefinedEntries(originalHeaders)), + headers: Object.entries(headersWithUserAgent), body, region: credentials.region, accessKeyId: credentials.accessKeyId, @@ -56,12 +67,14 @@ export function createSigV4FetchFunction( const signingResult = await signer.sign(); const signedHeaders = convertHeadersToRecord(signingResult.headers); + + // Use the combined headers directly as HeadersInit + const combinedHeaders = combineHeaders(headersWithUserAgent, signedHeaders); + return fetch(input, { ...init, body, - headers: removeUndefinedEntries( - combineHeaders(originalHeaders, signedHeaders), - ), + headers: combinedHeaders as HeadersInit, }); }; } @@ -94,14 +107,19 @@ export function createApiKeyFetchFunction( init?: RequestInit, ): Promise => { const originalHeaders = extractHeaders(init?.headers); + const headersWithUserAgent = withUserAgentSuffix( + originalHeaders, + `ai-sdk/amazon-bedrock/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ); + + const finalHeaders = combineHeaders(headersWithUserAgent, { + Authorization: `Bearer ${apiKey}`, + }); return fetch(input, { ...init, - headers: removeUndefinedEntries( - combineHeaders(originalHeaders, { - Authorization: `Bearer ${apiKey}`, - }), - ), + headers: finalHeaders as HeadersInit, }); }; } diff --git a/packages/amazon-bedrock/src/index.ts b/packages/amazon-bedrock/src/index.ts index 2fda4e2a9e85..9e1fc9bbfcd5 100644 --- a/packages/amazon-bedrock/src/index.ts +++ b/packages/amazon-bedrock/src/index.ts @@ -4,3 +4,4 @@ export type { AmazonBedrockProviderSettings, } from './bedrock-provider'; export type { BedrockProviderOptions } from './bedrock-chat-options'; +export { VERSION } from './version'; diff --git a/packages/amazon-bedrock/src/inject-fetch-headers.test.ts b/packages/amazon-bedrock/src/inject-fetch-headers.test.ts index bd5294699e9d..72b79d1cb40c 100644 --- a/packages/amazon-bedrock/src/inject-fetch-headers.test.ts +++ b/packages/amazon-bedrock/src/inject-fetch-headers.test.ts @@ -1,6 +1,20 @@ import { injectFetchHeaders } from './inject-fetch-headers'; import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +// Mock the version module +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + +// // Mock provider-utils to control runtime environment detection +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + getRuntimeEnvironmentUserAgent: vi.fn(() => 'runtime/testenv'), + }; +}); + describe('injectFetchHeaders', () => { const originalFetch = globalThis.fetch; @@ -18,8 +32,8 @@ describe('injectFetchHeaders', () => { globalThis.fetch = mockFetch; const customHeaders = { - 'X-Custom-Header': 'custom-value', - Authorization: 'Bearer token', + 'x-custom-header': 'custom-value', + authorization: 'Bearer token', }; const enhancedFetch = injectFetchHeaders(customHeaders); @@ -28,7 +42,11 @@ describe('injectFetchHeaders', () => { expect(mockFetch).toHaveBeenCalledWith( 'https://api.example.com', expect.objectContaining({ - headers: customHeaders, + headers: expect.objectContaining({ + 'x-custom-header': 'custom-value', + authorization: 'Bearer token', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }), }), ); }); @@ -38,7 +56,7 @@ describe('injectFetchHeaders', () => { globalThis.fetch = mockFetch; const customHeaders = { - 'X-Custom-Header': 'custom-value', + 'x-custom-header': 'custom-value', }; const existingHeaders = { @@ -53,10 +71,11 @@ describe('injectFetchHeaders', () => { expect(mockFetch).toHaveBeenCalledWith( 'https://api.example.com', expect.objectContaining({ - headers: { + headers: expect.objectContaining({ 'content-type': 'application/json', - 'X-Custom-Header': 'custom-value', - }, + 'x-custom-header': 'custom-value', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }), }), ); }); @@ -66,7 +85,7 @@ describe('injectFetchHeaders', () => { globalThis.fetch = mockFetch; const customHeaders = { - 'X-Custom-Header': 'custom-value', + 'x-custom-header': 'custom-value', }; const enhancedFetch = injectFetchHeaders(customHeaders); @@ -77,7 +96,10 @@ describe('injectFetchHeaders', () => { expect(mockFetch).toHaveBeenCalledWith( 'https://api.example.com', expect.objectContaining({ - headers: customHeaders, + headers: expect.objectContaining({ + 'x-custom-header': 'custom-value', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }), }), ); }); @@ -87,7 +109,7 @@ describe('injectFetchHeaders', () => { globalThis.fetch = mockFetch; const customHeaders = { - 'X-Custom-Header': 'custom-value', + 'x-custom-header': 'custom-value', }; const existingHeaders = new Headers({ @@ -102,10 +124,11 @@ describe('injectFetchHeaders', () => { expect(mockFetch).toHaveBeenCalledWith( 'https://api.example.com', expect.objectContaining({ - headers: { + headers: expect.objectContaining({ 'content-type': 'application/json', - 'X-Custom-Header': 'custom-value', - }, + 'x-custom-header': 'custom-value', + 'user-agent': 'ai-sdk/amazon-bedrock/0.0.0-test runtime/testenv', + }), }), ); }); diff --git a/packages/amazon-bedrock/src/inject-fetch-headers.ts b/packages/amazon-bedrock/src/inject-fetch-headers.ts index 9f0edcf72fd8..91310ea4accb 100644 --- a/packages/amazon-bedrock/src/inject-fetch-headers.ts +++ b/packages/amazon-bedrock/src/inject-fetch-headers.ts @@ -1,5 +1,11 @@ import { extractHeaders } from './headers-utils'; -import { FetchFunction, removeUndefinedEntries } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + removeUndefinedEntries, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; /** * Test helper to inject custom headers into a fetch request. @@ -9,12 +15,19 @@ import { FetchFunction, removeUndefinedEntries } from '@ai-sdk/provider-utils'; export function injectFetchHeaders( customHeaders: Record, ): FetchFunction { - return async (input, init = {}) => - await globalThis.fetch(input, { - ...init, - headers: removeUndefinedEntries({ + return async (input, init = {}) => { + const headers = withUserAgentSuffix( + { ...extractHeaders(init.headers), ...customHeaders, - }), + }, + `ai-sdk/amazon-bedrock/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ); + + return await globalThis.fetch(input, { + ...init, + headers: removeUndefinedEntries(headers), }); + }; } diff --git a/packages/amazon-bedrock/src/version.ts b/packages/amazon-bedrock/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/amazon-bedrock/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/amazon-bedrock/tsup.config.ts b/packages/amazon-bedrock/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/amazon-bedrock/tsup.config.ts +++ b/packages/amazon-bedrock/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/amazon-bedrock/vitest.edge.config.js b/packages/amazon-bedrock/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/amazon-bedrock/vitest.edge.config.js +++ b/packages/amazon-bedrock/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/amazon-bedrock/vitest.node.config.js b/packages/amazon-bedrock/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/amazon-bedrock/vitest.node.config.js +++ b/packages/amazon-bedrock/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/google-vertex/src/edge/google-vertex-auth-edge.test.ts b/packages/google-vertex/src/edge/google-vertex-auth-edge.test.ts index 13621ea9c71b..dd7ce347e8f8 100644 --- a/packages/google-vertex/src/edge/google-vertex-auth-edge.test.ts +++ b/packages/google-vertex/src/edge/google-vertex-auth-edge.test.ts @@ -4,6 +4,20 @@ import { } from './google-vertex-auth-edge'; import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest'; +// Mock provider-utils to control runtime environment detection +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + getRuntimeEnvironmentUserAgent: vi.fn(() => 'runtime/testenv'), + withUserAgentSuffix: actual.withUserAgentSuffix, + }; +}); + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); + describe('Google Vertex Edge Auth', () => { const mockCredentials: GoogleCredentials = { clientEmail: 'test@test.iam.gserviceaccount.com', @@ -272,4 +286,23 @@ describe('Google Vertex Edge Auth', () => { const header = JSON.parse(atob(parts[0])); expect(header).not.toHaveProperty('kid'); }); + + it('should include correct user-agent header', async () => { + const mockFetch = vi.fn().mockResolvedValue({ + ok: true, + json: () => Promise.resolve({ access_token: 'mock.jwt.token' }), + }); + global.fetch = mockFetch; + + await generateAuthToken(mockCredentials); + + expect(mockFetch).toHaveBeenCalledWith( + 'https://oauth2.googleapis.com/token', + expect.objectContaining({ + headers: expect.objectContaining({ + 'user-agent': 'ai-sdk/google-vertex/0.0.0-test runtime/testenv', + }), + }), + ); + }); }); diff --git a/packages/google-vertex/src/edge/google-vertex-auth-edge.ts b/packages/google-vertex/src/edge/google-vertex-auth-edge.ts index 5e8814b3455b..378887713842 100644 --- a/packages/google-vertex/src/edge/google-vertex-auth-edge.ts +++ b/packages/google-vertex/src/edge/google-vertex-auth-edge.ts @@ -1,4 +1,10 @@ -import { loadOptionalSetting, loadSetting } from '@ai-sdk/provider-utils'; +import { + loadOptionalSetting, + loadSetting, + withUserAgentSuffix, + getRuntimeEnvironmentUserAgent, +} from '@ai-sdk/provider-utils'; +import { VERSION } from '../version'; export interface GoogleCredentials { /** @@ -132,7 +138,11 @@ export async function generateAuthToken(credentials?: GoogleCredentials) { const response = await fetch('https://oauth2.googleapis.com/token', { method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + headers: withUserAgentSuffix( + { 'Content-Type': 'application/x-www-form-urlencoded' }, + `ai-sdk/google-vertex/${VERSION}`, + getRuntimeEnvironmentUserAgent(), + ), body: new URLSearchParams({ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: jwt, diff --git a/packages/google-vertex/src/version.ts b/packages/google-vertex/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/google-vertex/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/google-vertex/tsup.config.ts b/packages/google-vertex/tsup.config.ts index 9842250fc08f..46ec8c78dd1c 100644 --- a/packages/google-vertex/tsup.config.ts +++ b/packages/google-vertex/tsup.config.ts @@ -6,6 +6,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, outDir: 'dist', }, { @@ -13,6 +19,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, outDir: 'dist/edge', }, { @@ -20,6 +32,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, outDir: 'dist/anthropic', }, { @@ -27,6 +45,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, outDir: 'dist/anthropic/edge', }, ]); diff --git a/packages/google-vertex/vitest.edge.config.js b/packages/google-vertex/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/google-vertex/vitest.edge.config.js +++ b/packages/google-vertex/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/google-vertex/vitest.node.config.js b/packages/google-vertex/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/google-vertex/vitest.node.config.js +++ b/packages/google-vertex/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/provider-utils/src/test/test-server.ts b/packages/provider-utils/src/test/test-server.ts index 826a68222be8..94b066b01353 100644 --- a/packages/provider-utils/src/test/test-server.ts +++ b/packages/provider-utils/src/test/test-server.ts @@ -95,6 +95,10 @@ class TestServerCall { return headersObject; } + get requestUserAgent(): string | undefined { + return this.request!.headers.get('user-agent') ?? undefined; + } + get requestUrlSearchParams() { return new URL(this.request!.url).searchParams; } From 24161b123a451086f6d1467da186d840d770df17 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:20:14 -0700 Subject: [PATCH 031/121] Version Packages (#8657) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @ai-sdk/amazon-bedrock@3.0.22 ### Patch Changes - 32f3cef: feat: adding user-agent to all packages that use global fetch directly ## @ai-sdk/cerebras@1.0.18 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 ## @ai-sdk/deepinfra@1.0.18 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 ## @ai-sdk/deepseek@1.0.18 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 ## @ai-sdk/fireworks@1.0.18 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 ## @ai-sdk/openai-compatible@1.0.18 ### Patch Changes - 28363da: feat(openai-compatible): add `supportsStructuredOutputs` to provider settings ## @ai-sdk/togetherai@1.0.18 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 ## @ai-sdk/vercel@1.0.18 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 ## @ai-sdk/xai@2.0.19 ### Patch Changes - Updated dependencies [28363da] - @ai-sdk/openai-compatible@1.0.18 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/dry-cheetahs-eat.md | 5 ----- .changeset/yellow-jeans-know.md | 5 ----- packages/amazon-bedrock/CHANGELOG.md | 6 ++++++ packages/amazon-bedrock/package.json | 2 +- packages/cerebras/CHANGELOG.md | 7 +++++++ packages/cerebras/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 7 +++++++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 7 +++++++ packages/deepseek/package.json | 2 +- packages/fireworks/CHANGELOG.md | 7 +++++++ packages/fireworks/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 6 ++++++ packages/openai-compatible/package.json | 2 +- packages/togetherai/CHANGELOG.md | 7 +++++++ packages/togetherai/package.json | 2 +- packages/vercel/CHANGELOG.md | 7 +++++++ packages/vercel/package.json | 2 +- packages/xai/CHANGELOG.md | 7 +++++++ packages/xai/package.json | 2 +- 20 files changed, 70 insertions(+), 19 deletions(-) delete mode 100644 .changeset/dry-cheetahs-eat.md delete mode 100644 .changeset/yellow-jeans-know.md diff --git a/.changeset/dry-cheetahs-eat.md b/.changeset/dry-cheetahs-eat.md deleted file mode 100644 index dff576498639..000000000000 --- a/.changeset/dry-cheetahs-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/amazon-bedrock': patch ---- - -feat: adding user-agent to all packages that use global fetch directly diff --git a/.changeset/yellow-jeans-know.md b/.changeset/yellow-jeans-know.md deleted file mode 100644 index e4886b20af96..000000000000 --- a/.changeset/yellow-jeans-know.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai-compatible': patch ---- - -feat(openai-compatible): add `supportsStructuredOutputs` to provider settings diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index a4fdee36ba7d..5f0b50d9fcb6 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/amazon-bedrock +## 3.0.22 + +### Patch Changes + +- 32f3cef: feat: adding user-agent to all packages that use global fetch directly + ## 3.0.21 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 7ea753402bfb..3c1957855079 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.0.21", + "version": "3.0.22", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 43dca328182c..6f3737ac1b9a 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/cerebras +## 1.0.18 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 1.0.17 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index 55ca6a563b18..22d9ada70268 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index 4741f467d4ab..7cf2dad362a6 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/deepinfra +## 1.0.18 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 1.0.17 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 9254eba21f5e..be7dcad18ee4 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 884bca1fe4ba..e685d2193897 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/deepseek +## 1.0.18 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 1.0.17 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index bdc066f09864..4279aab2ae2d 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 421006a33cdd..eac85847164d 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/fireworks +## 1.0.18 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 1.0.17 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index ffd156991999..4a7ea8b1ee3a 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index c4a12d390609..47664a46f325 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/openai-compatible +## 1.0.18 + +### Patch Changes + +- 28363da: feat(openai-compatible): add `supportsStructuredOutputs` to provider settings + ## 1.0.17 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index d863b32e9830..eb8e109b65ff 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index 366adfc57c0e..811fbbc17f24 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/togetherai +## 1.0.18 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 1.0.17 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index b8ae47dad3f1..e03f25c3726a 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index 7b386e9450e5..06c11940fe87 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vercel +## 1.0.18 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 1.0.17 ### Patch Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index 52bd72466e94..e10166cb819e 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.0.17", + "version": "1.0.18", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 3f0f768acc27..42299a69e70b 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/xai +## 2.0.19 + +### Patch Changes + +- Updated dependencies [28363da] + - @ai-sdk/openai-compatible@1.0.18 + ## 2.0.18 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index e0118f4fc45c..31bf489553c3 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.0.18", + "version": "2.0.19", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 3a10095ad1f6d33ed88e359891897abc2c070add Mon Sep 17 00:00:00 2001 From: Parbez Date: Tue, 16 Sep 2025 02:26:49 +0530 Subject: [PATCH 032/121] feat(xai): add new additional fields for x search in xai (#8553) ## Background xAi added some new fields for x live search, this pr implements them https://docs.x.ai/docs/guides/live-search#overview-of-data-sources-and-supported-parameters ## Summary Added new fields and deprecated old field ## Manual Verification @gr2m verified the change by testing the example --- .changeset/bright-keys-exercise.md | 6 ++++++ .../providers/01-ai-sdk-providers/01-xai.mdx | 12 ++++++++--- .../ai-core/src/stream-text/xai-search.ts | 2 +- .../xai/src/xai-chat-language-model.test.ts | 20 +++++++++++++++---- packages/xai/src/xai-chat-language-model.ts | 5 ++++- packages/xai/src/xai-chat-options.ts | 7 +++++++ 6 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 .changeset/bright-keys-exercise.md diff --git a/.changeset/bright-keys-exercise.md b/.changeset/bright-keys-exercise.md new file mode 100644 index 000000000000..42a976331b34 --- /dev/null +++ b/.changeset/bright-keys-exercise.md @@ -0,0 +1,6 @@ +--- +'@example/ai-core': patch +'@ai-sdk/xai': patch +--- + +added new xai x live search fields diff --git a/content/providers/01-ai-sdk-providers/01-xai.mdx b/content/providers/01-ai-sdk-providers/01-xai.mdx index 584f74ff8fce..fa4c12683df5 100644 --- a/content/providers/01-ai-sdk-providers/01-xai.mdx +++ b/content/providers/01-ai-sdk-providers/01-xai.mdx @@ -230,7 +230,10 @@ const result = await generateText({ sources: [ { type: 'x', - xHandles: ['grok', 'xai'], + includedXHandles: ['grok', 'xai'], + excludedXHandles: ['openai'], + postFavoriteCount: 10, + postViewCount: 100, }, ], }, @@ -241,7 +244,10 @@ const result = await generateText({ #### X source parameters -- **xHandles** _string[]_: Array of X handles to search (without @ symbol) +- **includedXHandles** _string[]_: Array of X handles to search (without @ symbol) +- **excludedXHandles** _string[]_: Array of X handles to exclude from search (without @ symbol) +- **postFavoriteCount** _number_: Minimum favorite count of the X posts to consider. +- **postViewCount** _number_: Minimum view count of the X posts to consider. #### News Search @@ -324,7 +330,7 @@ const result = await generateText({ }, { type: 'x', - xHandles: ['openai', 'deepmind'], + includedXHandles: ['openai', 'deepmind'], }, ], }, diff --git a/examples/ai-core/src/stream-text/xai-search.ts b/examples/ai-core/src/stream-text/xai-search.ts index 45d3510a92c5..c18c17fa20bc 100644 --- a/examples/ai-core/src/stream-text/xai-search.ts +++ b/examples/ai-core/src/stream-text/xai-search.ts @@ -16,7 +16,7 @@ async function main() { sources: [ { type: 'x', - xHandles: ['nishimiya'], + includedXHandles: ['nishimiya'], }, ], }, diff --git a/packages/xai/src/xai-chat-language-model.test.ts b/packages/xai/src/xai-chat-language-model.test.ts index 2bdd7e2d1895..4829a5c6f5be 100644 --- a/packages/xai/src/xai-chat-language-model.test.ts +++ b/packages/xai/src/xai-chat-language-model.test.ts @@ -409,7 +409,10 @@ describe('XaiChatLanguageModel', () => { }, { type: 'x', - xHandles: ['grok'], + includedXHandles: ['grok'], + excludedXHandles: ['openai'], + postFavoriteCount: 5, + postViewCount: 50, }, { type: 'news', @@ -439,7 +442,10 @@ describe('XaiChatLanguageModel', () => { }, { type: 'x', - x_handles: ['grok'], + included_x_handles: ['grok'], + excluded_x_handles: ['openai'], + post_favorite_count: 5, + post_view_count: 50, }, { type: 'news', @@ -581,7 +587,10 @@ describe('XaiChatLanguageModel', () => { }, { type: 'x', - xHandles: ['openai', 'deepmind'], + includedXHandles: ['openai', 'deepmind'], + excludedXHandles: ['grok'], + postFavoriteCount: 10, + postViewCount: 100, }, ], }, @@ -612,7 +621,10 @@ describe('XaiChatLanguageModel', () => { }, { type: 'x', - x_handles: ['openai', 'deepmind'], + included_x_handles: ['openai', 'deepmind'], + excluded_x_handles: ['grok'], + post_favorite_count: 10, + post_view_count: 100, }, ], }, diff --git a/packages/xai/src/xai-chat-language-model.ts b/packages/xai/src/xai-chat-language-model.ts index c3990c0215f3..efc469f4aae1 100644 --- a/packages/xai/src/xai-chat-language-model.ts +++ b/packages/xai/src/xai-chat-language-model.ts @@ -176,7 +176,10 @@ export class XaiChatLanguageModel implements LanguageModelV2 { safe_search: source.safeSearch, }), ...(source.type === 'x' && { - x_handles: source.xHandles, + excluded_x_handles: source.excludedXHandles, + included_x_handles: source.includedXHandles ?? source.xHandles, + post_favorite_count: source.postFavoriteCount, + post_view_count: source.postViewCount, }), ...(source.type === 'news' && { country: source.country, diff --git a/packages/xai/src/xai-chat-options.ts b/packages/xai/src/xai-chat-options.ts index 4b7035d1602b..b8a25ae6029a 100644 --- a/packages/xai/src/xai-chat-options.ts +++ b/packages/xai/src/xai-chat-options.ts @@ -38,6 +38,13 @@ const webSourceSchema = z.object({ const xSourceSchema = z.object({ type: z.literal('x'), + excludedXHandles: z.array(z.string()).optional(), + includedXHandles: z.array(z.string()).optional(), + postFavoriteCount: z.number().int().optional(), + postViewCount: z.number().int().optional(), + /** + * @deprecated use `includedXHandles` instead + */ xHandles: z.array(z.string()).optional(), }); From ecb0152addb44a6d2786359f87710e1cf8814caf Mon Sep 17 00:00:00 2001 From: Aron Carroll Date: Wed, 10 Sep 2025 12:15:33 +0100 Subject: [PATCH 033/121] fix(ai): consider `output-error` in tool call helper This commit updates the `lastAssistantMessageIsCompleteWithToolCalls` helper function to also consider tool parts with a state of `output-error` a completed tool call. Co-Authored-By: Lars Grammel --- ...essage-is-complete-with-tool-calls.test.ts | 36 +++++++++++++++++-- ...ant-message-is-complete-with-tool-calls.ts | 7 ++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.test.ts b/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.test.ts index 526ab4172664..cf9b759099d3 100644 --- a/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.test.ts +++ b/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.test.ts @@ -2,7 +2,7 @@ import { lastAssistantMessageIsCompleteWithToolCalls } from './last-assistant-me import { describe, it, expect } from 'vitest'; describe('lastAssistantMessageIsCompleteWithToolCalls', () => { - it('should return false if the last step of a multi-step sequency only has text', () => { + it('should return false if the last step of a multi-step sequence only has text', () => { expect( lastAssistantMessageIsCompleteWithToolCalls({ messages: [ @@ -61,6 +61,36 @@ describe('lastAssistantMessageIsCompleteWithToolCalls', () => { ).toBe(true); }); + it('should return true when the tool has a output-error state', () => { + expect( + lastAssistantMessageIsCompleteWithToolCalls({ + messages: [ + { + id: '1', + role: 'assistant', + parts: [ + { type: 'step-start' }, + { + type: 'tool-getWeatherInformation', + toolCallId: 'call_6iy0GxZ9R4VDI5MKohXxV48y', + state: 'output-error', + input: { + city: 'New York', + }, + errorText: 'Unable to get weather information', + }, + { + type: 'text', + text: 'The current weather in New York is windy.', + state: 'done', + }, + ], + }, + ], + }), + ).toBe(true); + }); + it('should return true when dynamic tool call is complete', () => { expect( lastAssistantMessageIsCompleteWithToolCalls({ @@ -137,7 +167,7 @@ describe('lastAssistantMessageIsCompleteWithToolCalls', () => { ).toBe(false); }); - it('should return false when dynamic tool call has an error', () => { + it('should return true when dynamic tool call has an error', () => { expect( lastAssistantMessageIsCompleteWithToolCalls({ messages: [ @@ -160,7 +190,7 @@ describe('lastAssistantMessageIsCompleteWithToolCalls', () => { }, ], }), - ).toBe(false); + ).toBe(true); }); it('should return true when mixing regular and dynamic tool calls and all are complete', () => { diff --git a/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.ts b/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.ts index da7b2c386a2f..613430ac1a20 100644 --- a/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +++ b/packages/ai/src/ui/last-assistant-message-is-complete-with-tool-calls.ts @@ -1,4 +1,4 @@ -import { isToolOrDynamicToolUIPart, UIMessage } from './ui-messages'; +import { isToolOrDynamicToolUIPart, type UIMessage } from './ui-messages'; /** Check if the message is an assistant message with completed tool calls. @@ -30,6 +30,9 @@ export function lastAssistantMessageIsCompleteWithToolCalls({ return ( lastStepToolInvocations.length > 0 && - lastStepToolInvocations.every(part => part.state === 'output-available') + lastStepToolInvocations.every( + part => + part.state === 'output-available' || part.state === 'output-error', + ) ); } From 30e982af9566237399c9f7dca4bfcecd73c2c743 Mon Sep 17 00:00:00 2001 From: Aron Carroll Date: Wed, 10 Sep 2025 12:16:39 +0100 Subject: [PATCH 034/121] feat(ai): extend addToolResult to support error results This commit extends the `addToolResult` method on the `AbstractChat` class to optionally take an `output-error` result. This allows clients to report both successful and failed tool calls using the same mechanism. addToolResult({ state: "output-error", errorText: "Failed" }); For backwards compatibility the existing method interface is still supported and will default to a state of `output-available`. Co-Authored-By: Lars Grammel --- packages/ai/src/ui/chat.test.ts | 144 ++++++++++++++++++++++++++++++++ packages/ai/src/ui/chat.ts | 33 +++++--- 2 files changed, 167 insertions(+), 10 deletions(-) diff --git a/packages/ai/src/ui/chat.test.ts b/packages/ai/src/ui/chat.test.ts index 6d95f9c7134e..87b35f89dc6a 100644 --- a/packages/ai/src/ui/chat.test.ts +++ b/packages/ai/src/ui/chat.test.ts @@ -1742,6 +1742,149 @@ describe('Chat', () => { `); }); + it('should send message when a tool error result is submitted', async () => { + server.urls['http://localhost:3000/api/chat'].response = [ + { + type: 'stream-chunks', + chunks: [ + formatChunk({ type: 'start' }), + formatChunk({ type: 'start-step' }), + formatChunk({ + type: 'tool-input-available', + toolCallId: 'tool-call-0', + toolName: 'test-tool', + input: { testArg: 'test-value' }, + }), + formatChunk({ type: 'finish-step' }), + formatChunk({ type: 'finish' }), + ], + }, + { + type: 'stream-chunks', + chunks: [ + formatChunk({ type: 'start' }), + formatChunk({ type: 'start-step' }), + formatChunk({ type: 'finish-step' }), + formatChunk({ type: 'finish' }), + ], + }, + ]; + + let callCount = 0; + const onFinishPromise = createResolvablePromise(); + + const chat = new TestChat({ + id: '123', + generateId: mockId(), + transport: new DefaultChatTransport({ + api: 'http://localhost:3000/api/chat', + }), + sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls, + onFinish: () => { + callCount++; + if (callCount === 2) { + onFinishPromise.resolve(); + } + }, + }); + + await chat.sendMessage({ + text: 'Hello, world!', + }); + + // user submits the tool result + await chat.addToolResult({ + state: 'output-error', + tool: 'test-tool', + toolCallId: 'tool-call-0', + errorText: 'test-error', + }); + + // UI should show the tool result + expect(chat.messages).toMatchInlineSnapshot(` + [ + { + "id": "id-0", + "metadata": undefined, + "parts": [ + { + "text": "Hello, world!", + "type": "text", + }, + ], + "role": "user", + }, + { + "id": "id-1", + "metadata": undefined, + "parts": [ + { + "type": "step-start", + }, + { + "errorText": "test-error", + "input": { + "testArg": "test-value", + }, + "output": undefined, + "preliminary": undefined, + "providerExecuted": undefined, + "rawInput": undefined, + "state": "output-error", + "toolCallId": "tool-call-0", + "type": "tool-test-tool", + }, + ], + "role": "assistant", + }, + ] + `); + + await onFinishPromise.promise; + + // 2nd call should happen after the stream is finished + expect(server.calls.length).toBe(2); + + // check details of the 2nd call + expect(await server.calls[1].requestBodyJson).toMatchInlineSnapshot(` + { + "id": "123", + "messageId": "id-1", + "messages": [ + { + "id": "id-0", + "parts": [ + { + "text": "Hello, world!", + "type": "text", + }, + ], + "role": "user", + }, + { + "id": "id-1", + "parts": [ + { + "type": "step-start", + }, + { + "errorText": "test-error", + "input": { + "testArg": "test-value", + }, + "state": "output-error", + "toolCallId": "tool-call-0", + "type": "tool-test-tool", + }, + ], + "role": "assistant", + }, + ], + "trigger": "submit-message", + } + `); + }); + it('should send message when a dynamic tool result is submitted', async () => { server.urls['http://localhost:3000/api/chat'].response = [ { @@ -1795,6 +1938,7 @@ describe('Chat', () => { // user submits the tool result await chat.addToolResult({ + state: 'output-available', tool: 'test-tool', toolCallId: 'tool-call-0', output: 'test-result', diff --git a/packages/ai/src/ui/chat.ts b/packages/ai/src/ui/chat.ts index f1f94192211d..65831e407219 100644 --- a/packages/ai/src/ui/chat.ts +++ b/packages/ai/src/ui/chat.ts @@ -18,6 +18,7 @@ import { import { InferUIMessageToolCall, isToolOrDynamicToolUIPart, + ToolUIPart, type DataUIPart, type FileUIPart, type InferUIMessageData, @@ -414,14 +415,26 @@ export abstract class AbstractChat { }; addToolResult = async >({ + state = 'output-available', tool, toolCallId, output, - }: { - tool: TOOL; - toolCallId: string; - output: InferUIMessageTools[TOOL]['output']; - }) => + errorText, + }: + | { + state?: 'output-available'; + tool: TOOL; + toolCallId: string; + output: InferUIMessageTools[TOOL]['output']; + errorText?: never; + } + | { + state: 'output-error'; + tool: TOOL; + toolCallId: string; + output?: never; + errorText: string; + }) => this.jobExecutor.run(async () => { const messages = this.state.messages; const lastMessage = messages[messages.length - 1]; @@ -430,7 +443,7 @@ export abstract class AbstractChat { ...lastMessage, parts: lastMessage.parts.map(part => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId - ? { ...part, state: 'output-available', output } + ? { ...part, state, output, errorText } : part, ), }); @@ -440,12 +453,12 @@ export abstract class AbstractChat { this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(part => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId - ? { + ? ({ ...part, - state: 'output-available', + state, output, - errorText: undefined, - } + errorText, + } as ToolUIPart>) : part, ); } From 0d0b8e911fc0d025db489cf6c731658d34e733ed Mon Sep 17 00:00:00 2001 From: Aron Carroll Date: Wed, 10 Sep 2025 12:47:10 +0100 Subject: [PATCH 035/121] chore(ai): document the new addToolResult interface Co-authored-by: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> --- .../04-ai-sdk-ui/03-chatbot-tool-usage.mdx | 53 +++++++++++++++++++ .../07-reference/02-ai-sdk-ui/01-use-chat.mdx | 2 +- .../05-tool-invocation-missing-result.mdx | 26 ++++++--- 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx b/content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx index aa6f5a85cf5f..d6f0d766a109 100644 --- a/content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +++ b/content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx @@ -296,6 +296,59 @@ export default function Chat() { } ``` +### Error handling + +Sometimes an error may occur during client-side tool execution. Use the `addToolResult` method with a `state` of `output-error` and `errorText` value instead of `output` record the error. + +```tsx filename='app/page.tsx' highlight="19,36-41" +'use client'; + +import { useChat } from '@ai-sdk/react'; +import { + DefaultChatTransport, + lastAssistantMessageIsCompleteWithToolCalls, +} from 'ai'; +import { useState } from 'react'; + +export default function Chat() { + const { messages, sendMessage, addToolResult } = useChat({ + transport: new DefaultChatTransport({ + api: '/api/chat', + }), + + sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls, + + // run client-side tools that are automatically executed: + async onToolCall({ toolCall }) { + // Check if it's a dynamic tool first for proper type narrowing + if (toolCall.dynamic) { + return; + } + + if (toolCall.toolName === 'getWeatherInformation') { + try { + const weather = await getWeatherInformation(toolCall.input); + + // No await - avoids potential deadlocks + addToolResult({ + tool: 'getWeatherInformation', + toolCallId: toolCall.toolCallId, + output: weather, + }); + } catch (err) { + addToolResult({ + tool: 'getWeatherInformation', + toolCallId: toolCall.toolCallId, + state: 'output-error', + errorText: 'Unable to get the weather information', + }); + } + } + }, + }); +} +``` + ## Dynamic Tools When using dynamic tools (tools with unknown types at compile time), the UI parts use a generic `dynamic-tool` type instead of specific tool types: diff --git a/content/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx b/content/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx index a1772855b0d8..794ac8a2599a 100644 --- a/content/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +++ b/content/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx @@ -419,7 +419,7 @@ Allows you to easily create a conversational user interface for your chatbot app }, { name: 'addToolResult', - type: '(options: { tool: string; toolCallId: string; output: unknown }) => void', + type: '(options: { tool: string; toolCallId: string; output: unknown } | { tool: string; toolCallId: string; state: "output-error", errorText: string }) => void', description: 'Function to add a tool result to the chat. This will update the chat messages with the tool result. If sendAutomaticallyWhen is configured, it may trigger an automatic submission.', }, diff --git a/content/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx b/content/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx index 825a1b6e680a..bdf115542188 100644 --- a/content/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +++ b/content/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx @@ -54,14 +54,24 @@ const { messages, sendMessage, addToolResult } = useChat({ // Handle tool calls in onToolCall onToolCall: async ({ toolCall }) => { if (toolCall.toolName === 'getLocation') { - const result = await getLocationData(); - - // Important: Don't await inside onToolCall to avoid deadlocks - addToolResult({ - tool: 'getLocation', - toolCallId: toolCall.toolCallId, - output: result, - }); + try { + const result = await getLocationData(); + + // Important: Don't await inside onToolCall to avoid deadlocks + addToolResult({ + tool: 'getLocation', + toolCallId: toolCall.toolCallId, + output: result, + }); + } catch (err) { + // Important: Don't await inside onToolCall to avoid deadlocks + addToolResult({ + tool: 'getLocation', + toolCallId: toolCall.toolCallId, + state: 'output-error', + errorText: 'Failed to get location', + }); + } } }, }); From 065731ebf8f73d2c0cf5078cc964336d5f1481fc Mon Sep 17 00:00:00 2001 From: Aron Carroll Date: Wed, 10 Sep 2025 12:49:24 +0100 Subject: [PATCH 036/121] chore(ai): add changeset for addToolResult --- .changeset/long-dodos-lay.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/long-dodos-lay.md diff --git a/.changeset/long-dodos-lay.md b/.changeset/long-dodos-lay.md new file mode 100644 index 000000000000..9d5661f0605f --- /dev/null +++ b/.changeset/long-dodos-lay.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +Extend addToolResult to support error results From 4a2b70e03bbb552e7d130cec7f8cbfcb96bdc03f Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Tue, 16 Sep 2025 14:30:54 +0200 Subject: [PATCH 037/121] feat(provider/openai): send item references for provider-executed tool results (#8604) ## Background When sending messages back to the OpenAI responses API, tool calls and results for OpenAI provider-executed tools are ignored (see #8556 future work). ## Summary - when `store: true`, send item references back to the OpenAI API - when `store: false`, create warnings ## Manual Verification - [x] run `examples/next-openai/app/test-openai-code-interpreter` with `store: false` and follow-up messages - [x] run `examples/next-openai/app/test-openai-code-interpreter` with `store: true` and follow-up messages - [x] run `examples/next-openai/app/test-openai-web-search` with `store: false` and follow-up messages - [x] run `examples/next-openai/app/test-openai-web-search` with `store: true` and follow-up messages ## Future Work * explore using item references for reasoning and assistant messages to reduce prompt sizes ## Related Issues Discovered during #8556 --- .changeset/cyan-zebras-live.md | 5 + .../api/chat-openai-code-interpreter/route.ts | 13 ++- .../app/api/chat-openai-web-search/route.ts | 47 ++++++---- .../convert-to-openai-responses-input.test.ts | 93 ++++++++++++++++++- .../convert-to-openai-responses-input.ts | 17 +++- .../responses/openai-responses-api-types.ts | 25 +---- .../openai-responses-language-model.ts | 13 +-- 7 files changed, 155 insertions(+), 58 deletions(-) create mode 100644 .changeset/cyan-zebras-live.md diff --git a/.changeset/cyan-zebras-live.md b/.changeset/cyan-zebras-live.md new file mode 100644 index 000000000000..22e5e2822f72 --- /dev/null +++ b/.changeset/cyan-zebras-live.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +feat(provider/openai): send item references for provider-executed tool results diff --git a/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts b/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts index 58b3040033ed..5e863f2f5e96 100644 --- a/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts +++ b/examples/next-openai/app/api/chat-openai-code-interpreter/route.ts @@ -1,4 +1,4 @@ -import { openai } from '@ai-sdk/openai'; +import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { convertToModelMessages, InferUITools, @@ -24,9 +24,18 @@ export async function POST(req: Request) { const uiMessages = await validateUIMessages({ messages }); const result = streamText({ - model: openai.responses('gpt-5-nano'), + model: openai('gpt-5-nano'), tools, messages: convertToModelMessages(uiMessages), + onStepFinish: ({ request }) => { + console.log(JSON.stringify(request.body, null, 2)); + }, + providerOptions: { + openai: { + store: false, + include: ['reasoning.encrypted_content'], + } satisfies OpenAIResponsesProviderOptions, + }, }); return result.toUIMessageStreamResponse(); diff --git a/examples/next-openai/app/api/chat-openai-web-search/route.ts b/examples/next-openai/app/api/chat-openai-web-search/route.ts index dcecffbff058..f859869715fa 100644 --- a/examples/next-openai/app/api/chat-openai-web-search/route.ts +++ b/examples/next-openai/app/api/chat-openai-web-search/route.ts @@ -1,40 +1,49 @@ -import { openai } from '@ai-sdk/openai'; +import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { convertToModelMessages, - InferUITool, + InferUITools, streamText, + ToolSet, UIDataTypes, UIMessage, + validateUIMessages, } from 'ai'; -// Allow streaming responses up to 30 seconds -export const maxDuration = 30; +const tools = { + web_search: openai.tools.webSearch({ + searchContextSize: 'low', + userLocation: { + type: 'approximate', + city: 'San Francisco', + region: 'California', + country: 'US', + }, + }), +} satisfies ToolSet; export type OpenAIWebSearchMessage = UIMessage< never, UIDataTypes, - { - web_search: InferUITool>; - } + InferUITools >; export async function POST(req: Request) { const { messages } = await req.json(); + const uiMessages = await validateUIMessages({ messages }); const result = streamText({ - model: openai.responses('gpt-4o-mini'), - tools: { - web_search: openai.tools.webSearch({ - searchContextSize: 'high', - userLocation: { - type: 'approximate', - city: 'San Francisco', - region: 'California', - country: 'US', - }, - }), + model: openai('gpt-5-nano'), + tools, + messages: convertToModelMessages(uiMessages), + onStepFinish: ({ request }) => { + console.log(JSON.stringify(request.body, null, 2)); + }, + providerOptions: { + openai: { + store: false, + include: ['reasoning.encrypted_content'], + } satisfies OpenAIResponsesProviderOptions, }, - messages: convertToModelMessages(messages), }); return result.toUIMessageStreamResponse({ diff --git a/packages/openai/src/responses/convert-to-openai-responses-input.test.ts b/packages/openai/src/responses/convert-to-openai-responses-input.test.ts index 50285d216ae3..442fedf420a3 100644 --- a/packages/openai/src/responses/convert-to-openai-responses-input.test.ts +++ b/packages/openai/src/responses/convert-to-openai-responses-input.test.ts @@ -7,6 +7,7 @@ describe('convertToOpenAIResponsesInput', () => { const result = await convertToOpenAIResponsesInput({ prompt: [{ role: 'system', content: 'Hello' }], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([{ role: 'system', content: 'Hello' }]); @@ -16,6 +17,7 @@ describe('convertToOpenAIResponsesInput', () => { const result = await convertToOpenAIResponsesInput({ prompt: [{ role: 'system', content: 'Hello' }], systemMessageMode: 'developer', + store: true, }); expect(result.input).toEqual([{ role: 'developer', content: 'Hello' }]); @@ -25,6 +27,7 @@ describe('convertToOpenAIResponsesInput', () => { const result = await convertToOpenAIResponsesInput({ prompt: [{ role: 'system', content: 'Hello' }], systemMessageMode: 'remove', + store: true, }); expect(result.input).toEqual([]); @@ -41,6 +44,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -64,6 +68,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -95,6 +100,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -125,6 +131,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -156,6 +163,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', fileIdPrefixes: ['file-'], + store: true, }); expect(result.input).toEqual([ @@ -186,6 +194,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -221,6 +230,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -255,6 +265,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -287,6 +298,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', fileIdPrefixes: ['file-'], + store: true, }); expect(result.input).toEqual([ @@ -319,6 +331,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -353,6 +366,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }), ).rejects.toThrow('file part media type text/plain'); }); @@ -372,6 +386,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -404,6 +419,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', fileIdPrefixes: ['assistant-'], + store: true, }); expect(result.input).toEqual([ @@ -435,6 +451,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', fileIdPrefixes: ['assistant-'], + store: true, }); expect(result.input).toEqual([ @@ -471,6 +488,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', fileIdPrefixes: ['assistant-', 'file-'], + store: true, }); expect(result.input).toEqual([ @@ -514,6 +532,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', // fileIdPrefixes intentionally omitted + store: true, }); expect(result.input).toEqual([ @@ -550,6 +569,7 @@ describe('convertToOpenAIResponsesInput', () => { ], systemMessageMode: 'system', fileIdPrefixes: [], // Empty array should disable file ID detection + store: true, }); expect(result.input).toEqual([ @@ -574,6 +594,7 @@ describe('convertToOpenAIResponsesInput', () => { { role: 'assistant', content: [{ type: 'text', text: 'Hello' }] }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -601,6 +622,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -652,6 +674,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toMatchInlineSnapshot(` @@ -699,6 +722,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -738,6 +762,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -777,6 +802,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -816,6 +842,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -856,6 +883,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -890,6 +918,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -932,6 +961,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -988,6 +1018,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -1039,6 +1070,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -1121,6 +1153,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -1292,6 +1325,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -1388,6 +1422,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toHaveLength(0); @@ -1423,6 +1458,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toHaveLength(0); @@ -1460,6 +1496,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -1496,6 +1533,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result.input).toEqual([ @@ -1513,8 +1551,51 @@ describe('convertToOpenAIResponsesInput', () => { }); }); - describe('web search tool', () => { - it('should exclude web search tool calls and results from prompt', async () => { + describe('provider-executed tools', () => { + it('should convert single provider-executed tool call and result into item reference with store: true', async () => { + const result = await convertToOpenAIResponsesInput({ + prompt: [ + { + role: 'assistant', + content: [ + { + input: { code: 'example code', containerId: 'container_123' }, + providerExecuted: true, + toolCallId: + 'ci_68c2e2cf522c81908f3e2c1bccd1493b0b24aae9c6c01e4f', + toolName: 'code_interpreter', + type: 'tool-call', + }, + { + output: { + type: 'json', + value: { + outputs: [{ type: 'logs', logs: 'example logs' }], + }, + }, + toolCallId: + 'ci_68c2e2cf522c81908f3e2c1bccd1493b0b24aae9c6c01e4f', + toolName: 'code_interpreter', + type: 'tool-result', + }, + ], + }, + ], + systemMessageMode: 'system', + store: true, + }); + + expect(result.input).toMatchInlineSnapshot(` + [ + { + "id": "ci_68c2e2cf522c81908f3e2c1bccd1493b0b24aae9c6c01e4f", + "type": "item_reference", + }, + ] + `); + }); + + it('should exclude provider-executed tool calls and results from prompt with store: false', async () => { const result = await convertToOpenAIResponsesInput({ prompt: [ { @@ -1527,7 +1608,7 @@ describe('convertToOpenAIResponsesInput', () => { { type: 'tool-call', toolCallId: 'ws_67cf2b3051e88190b006770db6fdb13d', - toolName: 'web_search_preview', + toolName: 'web_search', input: { query: 'San Francisco major news events June 22 2025', }, @@ -1536,7 +1617,7 @@ describe('convertToOpenAIResponsesInput', () => { { type: 'tool-result', toolCallId: 'ws_67cf2b3051e88190b006770db6fdb13d', - toolName: 'web_search_preview', + toolName: 'web_search', output: { type: 'json', value: [ @@ -1554,6 +1635,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: false, }); expect(result).toMatchInlineSnapshot(` @@ -1582,7 +1664,7 @@ describe('convertToOpenAIResponsesInput', () => { ], "warnings": [ { - "message": "tool result parts in assistant messages are not supported for OpenAI responses", + "message": "Results for OpenAI tool web_search are not sent to the API when store is false", "type": "other", }, ], @@ -1609,6 +1691,7 @@ describe('convertToOpenAIResponsesInput', () => { }, ], systemMessageMode: 'system', + store: true, }); expect(result).toMatchInlineSnapshot(` diff --git a/packages/openai/src/responses/convert-to-openai-responses-input.ts b/packages/openai/src/responses/convert-to-openai-responses-input.ts index 44226658e134..e560eacb76d6 100644 --- a/packages/openai/src/responses/convert-to-openai-responses-input.ts +++ b/packages/openai/src/responses/convert-to-openai-responses-input.ts @@ -28,10 +28,12 @@ export async function convertToOpenAIResponsesInput({ prompt, systemMessageMode, fileIdPrefixes, + store, }: { prompt: LanguageModelV2Prompt; systemMessageMode: 'system' | 'developer' | 'remove'; fileIdPrefixes?: readonly string[]; + store: boolean; }): Promise<{ input: OpenAIResponsesInput; warnings: Array; @@ -158,11 +160,18 @@ export async function convertToOpenAIResponsesInput({ break; } + // assistant tool result parts are from provider-executed tools: case 'tool-result': { - warnings.push({ - type: 'other', - message: `tool result parts in assistant messages are not supported for OpenAI responses`, - }); + if (store) { + // use item references to refer to tool results from built-in tools + input.push({ type: 'item_reference', id: part.toolCallId }); + } else { + warnings.push({ + type: 'other', + message: `Results for OpenAI tool ${part.toolName} are not sent to the API when store is false`, + }); + } + break; } diff --git a/packages/openai/src/responses/openai-responses-api-types.ts b/packages/openai/src/responses/openai-responses-api-types.ts index 57182979d029..0fd889240762 100644 --- a/packages/openai/src/responses/openai-responses-api-types.ts +++ b/packages/openai/src/responses/openai-responses-api-types.ts @@ -8,11 +8,9 @@ export type OpenAIResponsesInputItem = | OpenAIResponsesAssistantMessage | OpenAIResponsesFunctionCall | OpenAIResponsesFunctionCallOutput - | OpenAIResponsesWebSearchCall | OpenAIResponsesComputerCall - | OpenAIResponsesFileSearchCall | OpenAIResponsesReasoning - | OpenAIResponsesCodeInterpreterCall; + | OpenAIResponsesItemReference; export type OpenAIResponsesIncludeOptions = | Array< @@ -64,32 +62,15 @@ export type OpenAIResponsesFunctionCallOutput = { output: string; }; -export type OpenAIResponsesWebSearchCall = { - type: 'web_search_call'; - id: string; - status?: string; -}; - export type OpenAIResponsesComputerCall = { type: 'computer_call'; id: string; status?: string; }; -export type OpenAIResponsesCodeInterpreterCall = { - type: 'code_interpreter_call'; - container_id: string; +export type OpenAIResponsesItemReference = { + type: 'item_reference'; id: string; - code: string | null; - outputs: Array< - { type: 'logs'; logs: string } | { type: 'image'; url: string } - > | null; -}; - -export type OpenAIResponsesFileSearchCall = { - type: 'file_search_call'; - id: string; - status?: string; }; export type OpenAIResponsesTool = diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index e3d730c8db79..577eab0321dd 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -156,21 +156,22 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { warnings.push({ type: 'unsupported-setting', setting: 'stopSequences' }); } + const openaiOptions = await parseProviderOptions({ + provider: 'openai', + providerOptions, + schema: openaiResponsesProviderOptionsSchema, + }); + const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({ prompt, systemMessageMode: modelConfig.systemMessageMode, fileIdPrefixes: this.config.fileIdPrefixes, + store: openaiOptions?.store ?? true, }); warnings.push(...inputWarnings); - const openaiOptions = await parseProviderOptions({ - provider: 'openai', - providerOptions, - schema: openaiResponsesProviderOptionsSchema, - }); - const strictJsonSchema = openaiOptions?.strictJsonSchema ?? false; let include: OpenAIResponsesIncludeOptions = openaiOptions?.include; From dbc09757e1c17661acf82a8ec19b8ebcd5b83f75 Mon Sep 17 00:00:00 2001 From: Christopher Ehrlich Date: Wed, 17 Sep 2025 10:39:27 +0200 Subject: [PATCH 038/121] docs: add Axiom to Observability Integrations (#8647) ## Summary - Adds page for setting up AI SDK o11y with Axiom - Adds Axiom to the list of observability integrations - Reorders the list to match the sidebar (which is alphabetical) ## Tasks - [ ] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [ ] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [ ] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> Co-authored-by: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> --- content/providers/05-observability/axiom.mdx | 178 +++++++++++++++++++ content/providers/05-observability/index.mdx | 5 +- 2 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 content/providers/05-observability/axiom.mdx diff --git a/content/providers/05-observability/axiom.mdx b/content/providers/05-observability/axiom.mdx new file mode 100644 index 000000000000..d0373794f8a6 --- /dev/null +++ b/content/providers/05-observability/axiom.mdx @@ -0,0 +1,178 @@ +--- +title: Axiom +description: Measure, observe, and improve your AI SDK application with Axiom +--- + +# Axiom Observability + +**Axiom** is a data platform with specialized features for **AI engineering workflows**, helping you build sophisticated AI systems with confidence. + +Axiom’s integration with the AI SDK uses a model wrapper to automatically capture detailed traces for every LLM call, giving you immediate visibility into your application's performance, cost, and behavior. + +## Setup + +### 1. Configure Axiom + +First, you'll need an Axiom organization, a dataset to send traces to, and an API token. + +- [Create an Axiom organization](https://app.axiom.co/register). +- [Create a new dataset](https://app.axiom.co/datasets) (e.g., `my-ai-app`). +- [Create an API token](https://app.axiom.co/settings/api-tokens) with ingest permissions for your dataset. + +### 2. Install the Axiom SDK + +Install the Axiom package in your project: + + + + + + + + + + + + + + + + + +### 3. Set Environment Variables + +Configure your environment variables in a `.env` file. This uses the standard OpenTelemetry configuration to send traces directly to your Axiom dataset. + +```bash filename=".env" +# Axiom Configuration +AXIOM_TOKEN="YOUR_AXIOM_API_TOKEN" +AXIOM_DATASET="your-axiom-dataset-name" + +# Vercel and OpenTelemetry Configuration +OTEL_SERVICE_NAME="my-ai-app" +OTEL_EXPORTER_OTLP_ENDPOINT="https://api.axiom.co/v1/traces" +OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer YOUR_AXIOM_API_TOKEN,X-Axiom-Dataset=your-axiom-dataset-name" + +# Your AI Provider Key +OPENAI_API_KEY="YOUR_OPENAI_API_KEY" +``` + +Replace the placeholder values with your actual Axiom token and dataset name. + +### 4. Set Up Instrumentation + +To send data to Axiom, configure a tracer. For example, use a dedicated instrumentation file and load it before the rest of your app. An example configuration for a Node.js environment: + +1. Install dependencies: + + + + + + + + + + + + + + + + +2. Create instrumentation file: + +```typescript filename="src/instrumentation.ts" +import { trace } from '@opentelemetry/api'; +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; +import type { Resource } from '@opentelemetry/resources'; +import { resourceFromAttributes } from '@opentelemetry/resources'; +import { NodeSDK } from '@opentelemetry/sdk-node'; +import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node'; +import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; +import { initAxiomAI, RedactionPolicy } from 'axiom/ai'; + +const tracer = trace.getTracer('my-tracer'); + +const sdk = new NodeSDK({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: 'my-ai-app', + }) as Resource, + spanProcessor: new SimpleSpanProcessor( + new OTLPTraceExporter({ + url: `https://api.axiom.co/v1/traces`, + headers: { + Authorization: `Bearer ${process.env.AXIOM_TOKEN}`, + 'X-Axiom-Dataset': process.env.AXIOM_DATASET, + }, + }), + ), +}); + +sdk.start(); + +initAxiomAI({ tracer, redactionPolicy: RedactionPolicy.AxiomDefault }); +``` + +### 5. Wrap and Use the AI Model + +In your application code, import `wrapAISDKModel` from Axiom and use it to wrap your existing AI SDK model client. + +```typescript +import { createOpenAI } from '@ai-sdk/openai'; +import { generateText } from 'ai'; +import { wrapAISDKModel } from 'axiom/ai'; + +// 1. Create your standard AI model provider +const openaiProvider = createOpenAI({ + apiKey: process.env.OPENAI_API_KEY, +}); + +// 2. Wrap the model to enable automatic tracing +const tracedGpt4o = wrapAISDKModel(openaiProvider('gpt-4o')); + +// 3. Use the wrapped model as you normally would +const { text } = await generateText({ + model: tracedGpt4o, + prompt: 'What is the capital of Spain?', +}); + +console.log(text); +``` + +Any calls made using the `tracedGpt4o` model will now automatically send detailed traces to your Axiom dataset. + +## What You'll See in Axiom + +Once integrated, your Axiom dataset will include: + +- **AI Trace Waterfall:** A dedicated view to visualize single and multi-step LLM workflows. +- **Gen AI Dashboard:** A pre-built dashboard to monitor cost, latency, token usage, and error rates. +- **Detailed Spans:** Rich telemetry for every call, including the full prompt and completion, token counts, and model information. + +## Advanced Usage + +Axiom’s AI SDK offers more advanced instrumentation for deeper visibility: + +- **Business Context:** Use the `withSpan` function to group LLM calls under a specific business capability (e.g., `customer_support_agent`). +- **Tool Tracing:** Use the `wrapTool` helper to automatically trace the execution of tools your AI model calls. + +To learn more about these features, see the [Axiom AI SDK Instrumentation guide](https://axiom.co/docs/ai-engineering/observe/axiom-ai-sdk-instrumentation). + +## Additional Resources + +- [Axiom AI Engineering Documentation](https://axiom.co/docs/ai-engineering/overview) +- [Axiom AI SDK on GitHub](https://github.com/axiomhq/ai) +- [Full Quickstart Guide](https://axiom.co/docs/ai-engineering/quickstart) diff --git a/content/providers/05-observability/index.mdx b/content/providers/05-observability/index.mdx index 85b76221843b..5341c22b2686 100644 --- a/content/providers/05-observability/index.mdx +++ b/content/providers/05-observability/index.mdx @@ -7,10 +7,9 @@ description: AI SDK Integration for monitoring and tracing LLM applications Several LLM observability providers offer integrations with the AI SDK telemetry data: +- [Axiom](/providers/observability/axiom) - [Braintrust](/providers/observability/braintrust) - [Helicone](/providers/observability/helicone) -- [Traceloop](/providers/observability/traceloop) -- [Weave](/providers/observability/weave) - [Langfuse](/providers/observability/langfuse) - [LangSmith](/providers/observability/langsmith) - [Laminar](/providers/observability/laminar) @@ -19,6 +18,8 @@ Several LLM observability providers offer integrations with the AI SDK telemetry - [HoneyHive](https://docs.honeyhive.ai/integrations/vercel) - [Scorecard](/providers/observability/scorecard) - [SigNoz](/providers/observability/signoz) +- [Traceloop](/providers/observability/traceloop) +- [Weave](/providers/observability/weave) There are also providers that provide monitoring and tracing for the AI SDK through model wrappers: From d8eb31f7af5446a0779bb2171dd307efb6441cf4 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 10:41:29 +0200 Subject: [PATCH 039/121] fix(ai): fix wav audio and webp image detection (#8685) ## Background The webp image detection did not correctly detect all webp images. Further investigation revealed both false positives and false negatives. ## Summary * precise checks for `wav` and `webp` types * rewrite detection algorithm to only use byte comparison ## Future Work * investigate performance issue with mp3 stripping (uint8 conversion) ## Related Issues Discovered during #8324 --- .changeset/small-ladybugs-check.md | 5 + .../ai/src/util/detect-media-type.test.ts | 171 ++++++++++++++++-- packages/ai/src/util/detect-media-type.ts | 75 ++++---- 3 files changed, 208 insertions(+), 43 deletions(-) create mode 100644 .changeset/small-ladybugs-check.md diff --git a/.changeset/small-ladybugs-check.md b/.changeset/small-ladybugs-check.md new file mode 100644 index 000000000000..29b0bcfd8faf --- /dev/null +++ b/.changeset/small-ladybugs-check.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): fix webp image detection from base64 diff --git a/packages/ai/src/util/detect-media-type.test.ts b/packages/ai/src/util/detect-media-type.test.ts index f127ea819e89..0962f08aa47a 100644 --- a/packages/ai/src/util/detect-media-type.test.ts +++ b/packages/ai/src/util/detect-media-type.test.ts @@ -74,8 +74,26 @@ describe('detectMediaType', () => { }); describe('WebP', () => { - it('should detect WebP from bytes', () => { - const webpBytes = new Uint8Array([0x52, 0x49, 0x46, 0x46, 0xff, 0xff]); + it('should detect WebP from bytes (positive webp image uint8)', () => { + // WebP format: RIFF + 4 bytes file size + WEBP + const webpBytes = new Uint8Array([ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + 0x24, + 0x00, + 0x00, + 0x00, // file size (example: 36 bytes) + 0x57, + 0x45, + 0x42, + 0x50, // "WEBP" + 0x56, + 0x50, + 0x38, + 0x20, // VP8 chunk (additional WebP data) + ]); expect( detectMediaType({ data: webpBytes, @@ -84,8 +102,27 @@ describe('detectMediaType', () => { ).toBe('image/webp'); }); - it('should detect WebP from base64', () => { - const webpBase64 = 'UklGRgabc123'; // Base64 string starting with WebP signature + it('should detect WebP from base64 (positive webp image base64)', () => { + // WebP: RIFF + file size + WEBP encoded to base64 + const webpBytes = new Uint8Array([ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + 0x24, + 0x00, + 0x00, + 0x00, // file size + 0x57, + 0x45, + 0x42, + 0x50, // "WEBP" + 0x56, + 0x50, + 0x38, + 0x20, // VP8 chunk + ]); + const webpBase64 = convertUint8ArrayToBase64(webpBytes); expect( detectMediaType({ data: webpBase64, @@ -93,6 +130,63 @@ describe('detectMediaType', () => { }), ).toBe('image/webp'); }); + + it('should NOT detect RIFF audio as WebP from bytes (negative riff audio uint8)', () => { + // WAV format: RIFF + file size + WAVE (not WEBP) + const wavBytes = new Uint8Array([ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + 0x24, + 0x00, + 0x00, + 0x00, // file size + 0x57, + 0x41, + 0x56, + 0x45, // "WAVE" (not "WEBP") + 0x66, + 0x6d, + 0x74, + 0x20, // fmt chunk + ]); + expect( + detectMediaType({ + data: wavBytes, + signatures: imageMediaTypeSignatures, + }), + ).toBeUndefined(); // Should not detect as WebP + }); + + it('should NOT detect RIFF audio as WebP from base64 (negative riff audio base64)', () => { + // WAV format encoded to base64 + const wavBytes = new Uint8Array([ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + 0x24, + 0x00, + 0x00, + 0x00, // file size + 0x57, + 0x41, + 0x56, + 0x45, // "WAVE" (not "WEBP") + 0x66, + 0x6d, + 0x74, + 0x20, // fmt chunk + ]); + const wavBase64 = convertUint8ArrayToBase64(wavBytes); + expect( + detectMediaType({ + data: wavBase64, + signatures: imageMediaTypeSignatures, + }), + ).toBeUndefined(); // Should not detect as WebP + }); }); describe('BMP', () => { @@ -107,10 +201,10 @@ describe('detectMediaType', () => { }); it('should detect BMP from base64', () => { - const bmpBase64 = 'Qkabc123'; // Base64 string starting with BMP signature + const bmpBytes = new Uint8Array([0x42, 0x4d, 0xff, 0xff]); expect( detectMediaType({ - data: bmpBase64, + data: convertUint8ArrayToBase64(bmpBytes), signatures: imageMediaTypeSignatures, }), ).toBe('image/bmp'); @@ -306,8 +400,46 @@ describe('detectMediaType', () => { }); describe('WAV', () => { + // WebP format: RIFF + 4 bytes file size + WEBP + const webpBytes = new Uint8Array([ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + 0x24, + 0x00, + 0x00, + 0x00, // file size (example: 36 bytes) + 0x57, + 0x45, + 0x42, + 0x50, // "WEBP" + 0x56, + 0x50, + 0x38, + 0x20, // VP8 chunk (additional WebP data) + ]); + + const wavBytes = new Uint8Array([ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + 0x24, + 0x00, + 0x00, + 0x00, // file size (example: 36 bytes) + 0x57, + 0x41, + 0x56, + 0x45, // "WAVE" (not "WEBP") + 0x66, + 0x6d, + 0x74, + 0x20, // fmt chunk + ]); + it('should detect WAV from bytes', () => { - const wavBytes = new Uint8Array([0x52, 0x49, 0x46, 0x46]); expect( detectMediaType({ data: wavBytes, @@ -317,14 +449,31 @@ describe('detectMediaType', () => { }); it('should detect WAV from base64', () => { - const wavBase64 = 'UklGRiQ='; // Base64 string starting with WAV signature expect( detectMediaType({ - data: wavBase64, + data: convertUint8ArrayToBase64(wavBytes), signatures: audioMediaTypeSignatures, }), ).toBe('audio/wav'); }); + + it('should NOT detect WebP as WAV from bytes (negative webp image uint8)', () => { + expect( + detectMediaType({ + data: webpBytes, + signatures: audioMediaTypeSignatures, + }), + ).toBeUndefined(); // Should not detect as WAV + }); + + it('should NOT detect WebP as WAV from base64 (negative webp image base64)', () => { + expect( + detectMediaType({ + data: convertUint8ArrayToBase64(webpBytes), + signatures: audioMediaTypeSignatures, + }), + ).toBeUndefined(); // Should not detect as WAV + }); }); describe('OGG', () => { @@ -383,10 +532,10 @@ describe('detectMediaType', () => { }); it('should detect AAC from base64', () => { - const aacBase64 = 'QBUA'; // Base64 string starting with AAC signature + const aacBytes = new Uint8Array([0x40, 0x15, 0x00, 0x00]); expect( detectMediaType({ - data: aacBase64, + data: convertUint8ArrayToBase64(aacBytes), signatures: audioMediaTypeSignatures, }), ).toBe('audio/aac'); diff --git a/packages/ai/src/util/detect-media-type.ts b/packages/ai/src/util/detect-media-type.ts index d36b2393411f..49a3ed237f4a 100644 --- a/packages/ai/src/util/detect-media-type.ts +++ b/packages/ai/src/util/detect-media-type.ts @@ -3,52 +3,56 @@ import { convertBase64ToUint8Array } from '@ai-sdk/provider-utils'; export const imageMediaTypeSignatures = [ { mediaType: 'image/gif' as const, - bytesPrefix: [0x47, 0x49, 0x46], - base64Prefix: 'R0lG', + bytesPrefix: [0x47, 0x49, 0x46], // GIF }, { mediaType: 'image/png' as const, - bytesPrefix: [0x89, 0x50, 0x4e, 0x47], - base64Prefix: 'iVBORw', + bytesPrefix: [0x89, 0x50, 0x4e, 0x47], // PNG }, { mediaType: 'image/jpeg' as const, - bytesPrefix: [0xff, 0xd8], - base64Prefix: '/9j/', + bytesPrefix: [0xff, 0xd8], // JPEG }, { mediaType: 'image/webp' as const, - bytesPrefix: [0x52, 0x49, 0x46, 0x46], - base64Prefix: 'UklGRg', + bytesPrefix: [ + 0x52, + 0x49, + 0x46, + 0x46, // "RIFF" + null, + null, + null, + null, // file size (variable) + 0x57, + 0x45, + 0x42, + 0x50, // "WEBP" + ], }, { mediaType: 'image/bmp' as const, bytesPrefix: [0x42, 0x4d], - base64Prefix: 'Qk', }, { mediaType: 'image/tiff' as const, bytesPrefix: [0x49, 0x49, 0x2a, 0x00], - base64Prefix: 'SUkqAA', }, { mediaType: 'image/tiff' as const, bytesPrefix: [0x4d, 0x4d, 0x00, 0x2a], - base64Prefix: 'TU0AKg', }, { mediaType: 'image/avif' as const, bytesPrefix: [ 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, ], - base64Prefix: 'AAAAIGZ0eXBhdmlm', }, { mediaType: 'image/heic' as const, bytesPrefix: [ 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, ], - base64Prefix: 'AAAAIGZ0eXBoZWlj', }, ] as const; @@ -56,62 +60,63 @@ export const audioMediaTypeSignatures = [ { mediaType: 'audio/mpeg' as const, bytesPrefix: [0xff, 0xfb], - base64Prefix: '//s=', }, { mediaType: 'audio/mpeg' as const, bytesPrefix: [0xff, 0xfa], - base64Prefix: '//o=', }, { mediaType: 'audio/mpeg' as const, bytesPrefix: [0xff, 0xf3], - base64Prefix: '//M=', }, { mediaType: 'audio/mpeg' as const, bytesPrefix: [0xff, 0xf2], - base64Prefix: '//I=', }, { mediaType: 'audio/mpeg' as const, bytesPrefix: [0xff, 0xe3], - base64Prefix: '/+M=', }, { mediaType: 'audio/mpeg' as const, bytesPrefix: [0xff, 0xe2], - base64Prefix: '/+I=', }, { mediaType: 'audio/wav' as const, - bytesPrefix: [0x52, 0x49, 0x46, 0x46], - base64Prefix: 'UklGR', + bytesPrefix: [ + 0x52, // R + 0x49, // I + 0x46, // F + 0x46, // F + null, + null, + null, + null, + 0x57, // W + 0x41, // A + 0x56, // V + 0x45, // E + ], }, { mediaType: 'audio/ogg' as const, bytesPrefix: [0x4f, 0x67, 0x67, 0x53], - base64Prefix: 'T2dnUw', }, { mediaType: 'audio/flac' as const, bytesPrefix: [0x66, 0x4c, 0x61, 0x43], - base64Prefix: 'ZkxhQw', }, { mediaType: 'audio/aac' as const, bytesPrefix: [0x40, 0x15, 0x00, 0x00], - base64Prefix: 'QBUA', }, { mediaType: 'audio/mp4' as const, bytesPrefix: [0x66, 0x74, 0x79, 0x70], - base64Prefix: 'ZnR5cA', }, { mediaType: 'audio/webm', bytesPrefix: [0x1a, 0x45, 0xdf, 0xa3], - base64Prefix: 'GkXf', }, ] as const; @@ -156,14 +161,20 @@ export function detectMediaType({ }): (typeof signatures)[number]['mediaType'] | undefined { const processedData = stripID3TagsIfPresent(data); + // Convert the first ~18 bytes (24 base64 chars) for consistent detection logic: + const bytes = + typeof processedData === 'string' + ? convertBase64ToUint8Array( + processedData.substring(0, Math.min(processedData.length, 24)), + ) + : processedData; + for (const signature of signatures) { if ( - typeof processedData === 'string' - ? processedData.startsWith(signature.base64Prefix) - : processedData.length >= signature.bytesPrefix.length && - signature.bytesPrefix.every( - (byte, index) => processedData[index] === byte, - ) + bytes.length >= signature.bytesPrefix.length && + signature.bytesPrefix.every( + (byte, index) => byte === null || bytes[index] === byte, + ) ) { return signature.mediaType; } From 93d8b602bb6e298e5fc97ad0cbc5ad255d9e7586 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 10:42:34 +0200 Subject: [PATCH 040/121] fix(ai): do not filter zero-length text parts that have provider options (#8686) ## Background Filtering out empty message parts from the OpenAI responses API can lead to `Item 'rs_...' was provided without its required following item` issues (see #8321 ). ## Summary Limit filtering of empty message parts to cases where there are no provider options. ## Manual Verification Verified during #8324 ## Related Issues Discovered during #8324 Fixes one cause of #8321 --- .changeset/silly-buses-thank.md | 5 ++ .../convert-to-language-model-prompt.test.ts | 54 ++++++++++++++++++- .../convert-to-language-model-prompt.ts | 7 ++- 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 .changeset/silly-buses-thank.md diff --git a/.changeset/silly-buses-thank.md b/.changeset/silly-buses-thank.md new file mode 100644 index 000000000000..dbba49378698 --- /dev/null +++ b/.changeset/silly-buses-thank.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): do not filter zero-length text parts that have provider options diff --git a/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts b/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts index 80b1ce7608ff..867d6cb9d5a4 100644 --- a/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts +++ b/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts @@ -899,7 +899,7 @@ describe('convertToLanguageModelMessage', () => { describe('assistant message', () => { describe('text parts', () => { - it('should ignore empty text parts', async () => { + it('should ignore empty text parts when there are no provider options', async () => { const result = convertToLanguageModelMessage({ message: { role: 'assistant', @@ -931,6 +931,58 @@ describe('convertToLanguageModelMessage', () => { ], }); }); + + it('should include empty text parts when there are provider options', async () => { + const result = convertToLanguageModelMessage({ + message: { + role: 'assistant', + content: [ + { + type: 'text', + text: '', + providerOptions: { + 'test-provider': { + 'key-a': 'test-value-1', + }, + }, + }, + { + type: 'tool-call', + toolName: 'toolName', + toolCallId: 'toolCallId', + input: {}, + }, + ], + }, + downloadedAssets: {}, + }); + + expect(result).toMatchInlineSnapshot(` + { + "content": [ + { + "providerOptions": { + "test-provider": { + "key-a": "test-value-1", + }, + }, + "text": "", + "type": "text", + }, + { + "input": {}, + "providerExecuted": undefined, + "providerOptions": undefined, + "toolCallId": "toolCallId", + "toolName": "toolName", + "type": "tool-call", + }, + ], + "providerOptions": undefined, + "role": "assistant", + } + `); + }); }); describe('reasoning parts', () => { diff --git a/packages/ai/src/prompt/convert-to-language-model-prompt.ts b/packages/ai/src/prompt/convert-to-language-model-prompt.ts index f08152a4c3d4..0a9736edd757 100644 --- a/packages/ai/src/prompt/convert-to-language-model-prompt.ts +++ b/packages/ai/src/prompt/convert-to-language-model-prompt.ts @@ -108,8 +108,11 @@ export function convertToLanguageModelMessage({ role: 'assistant', content: message.content .filter( - // remove empty text parts: - part => part.type !== 'text' || part.text !== '', + // remove empty text parts (no text, and no provider options): + part => + part.type !== 'text' || + part.text !== '' || + part.providerOptions != null, ) .map(part => { const providerOptions = part.providerOptions; From 76024fc38854e25220a27012dce45684e48e2cfc Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 10:42:56 +0200 Subject: [PATCH 041/121] fix(ai): fix static tool call and result detection when dynamic is undefined (#8687) ## Background Provider-executed tools (e.g. OpenAI image generation) were not included in the list of static tools. ## Summary Fix behavior for `dynamic: undefined`. ## Related Issues Discovered during #8324 --- .changeset/funny-needles-return.md | 5 ++ .../src/generate-text/generate-text.test.ts | 47 +++++++++++++++- packages/ai/src/generate-text/step-result.ts | 4 +- .../ai/src/generate-text/stream-text.test.ts | 54 +++++++++++++++++-- 4 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 .changeset/funny-needles-return.md diff --git a/.changeset/funny-needles-return.md b/.changeset/funny-needles-return.md new file mode 100644 index 000000000000..145db74b35a0 --- /dev/null +++ b/.changeset/funny-needles-return.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): fix static tool call and result detection when dynamic is undefined diff --git a/packages/ai/src/generate-text/generate-text.test.ts b/packages/ai/src/generate-text/generate-text.test.ts index 4baef067f0e7..e0c6402da3b0 100644 --- a/packages/ai/src/generate-text/generate-text.test.ts +++ b/packages/ai/src/generate-text/generate-text.test.ts @@ -2275,7 +2275,7 @@ describe('generateText', () => { }); describe('provider-executed tools', () => { - describe('single provider-executed tool call and result', () => { + describe('two provider-executed tool calls and results', () => { let result: GenerateTextResult; beforeEach(async () => { @@ -2379,6 +2379,51 @@ describe('generateText', () => { `); }); + it('should include provider-executed tool calls in staticToolCalls', async () => { + expect(result.staticToolCalls).toMatchInlineSnapshot(` + [ + { + "input": { + "value": "value", + }, + "providerExecuted": true, + "providerMetadata": undefined, + "toolCallId": "call-1", + "toolName": "web_search", + "type": "tool-call", + }, + { + "input": { + "value": "value", + }, + "providerExecuted": true, + "providerMetadata": undefined, + "toolCallId": "call-2", + "toolName": "web_search", + "type": "tool-call", + }, + ] + `); + }); + + it('should include provider-executed results in staticToolResults (errors excluded)', async () => { + expect(result.staticToolResults).toMatchInlineSnapshot(` + [ + { + "dynamic": undefined, + "input": { + "value": "value", + }, + "output": "{ "value": "result1" }", + "providerExecuted": true, + "toolCallId": "call-1", + "toolName": "web_search", + "type": "tool-result", + }, + ] + `); + }); + it('should only execute a single step', async () => { expect(result.steps.length).toBe(1); }); diff --git a/packages/ai/src/generate-text/step-result.ts b/packages/ai/src/generate-text/step-result.ts index 6ea9f4c688f4..5c5ec1004263 100644 --- a/packages/ai/src/generate-text/step-result.ts +++ b/packages/ai/src/generate-text/step-result.ts @@ -199,7 +199,7 @@ export class DefaultStepResult get staticToolCalls() { return this.toolCalls.filter( (toolCall): toolCall is StaticToolCall => - toolCall.dynamic === false, + toolCall.dynamic !== true, ); } @@ -216,7 +216,7 @@ export class DefaultStepResult get staticToolResults() { return this.toolResults.filter( (toolResult): toolResult is StaticToolResult => - toolResult.dynamic === false, + toolResult.dynamic !== true, ); } diff --git a/packages/ai/src/generate-text/stream-text.test.ts b/packages/ai/src/generate-text/stream-text.test.ts index 24b562f82efc..ccb3b3091209 100644 --- a/packages/ai/src/generate-text/stream-text.test.ts +++ b/packages/ai/src/generate-text/stream-text.test.ts @@ -4824,8 +4824,31 @@ describe('streamText', () => { "timestamp": 1970-01-01T00:00:00.000Z, }, "sources": [], - "staticToolCalls": [], - "staticToolResults": [], + "staticToolCalls": [ + { + "input": { + "value": "value", + }, + "providerExecuted": undefined, + "providerMetadata": undefined, + "toolCallId": "call-1", + "toolName": "tool1", + "type": "tool-call", + }, + ], + "staticToolResults": [ + { + "input": { + "value": "value", + }, + "output": "value-result", + "providerExecuted": undefined, + "providerMetadata": undefined, + "toolCallId": "call-1", + "toolName": "tool1", + "type": "tool-result", + }, + ], "steps": [ DefaultStepResult { "content": [ @@ -10623,8 +10646,31 @@ describe('streamText', () => { "timestamp": 1970-01-01T00:00:00.000Z, }, "sources": [], - "staticToolCalls": [], - "staticToolResults": [], + "staticToolCalls": [ + { + "input": { + "value": "VALUE", + }, + "providerExecuted": undefined, + "providerMetadata": undefined, + "toolCallId": "call-1", + "toolName": "tool1", + "type": "tool-call", + }, + ], + "staticToolResults": [ + { + "input": { + "value": "VALUE", + }, + "output": "VALUE-RESULT", + "providerExecuted": undefined, + "providerMetadata": undefined, + "toolCallId": "call-1", + "toolName": "tool1", + "type": "tool-result", + }, + ], "steps": [ DefaultStepResult { "content": [ From 643711d678940d6dae9c1f849f8f89564910cd1b Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 11:21:25 +0200 Subject: [PATCH 042/121] feat (provider/openai): provider defined image generation tool support (#8324) ## Background OpenAI offers [image generation](https://platform.openai.com/docs/guides/tools-image-generation) for some of their language models. GPT-5 model launch includes the latest version of this feature. Users would like to be able to use these models to generate images (see #6425 ). ## Summary * add OpenAI built-in `image-generation` tool ## Manual Verification - [x] run `examples/ai-core/src/generate-text/openai-image-generation-tool.ts` - [x] run `examples/ai-core/src/stream-text/openai-image-generation-tool.ts` - [x] ui test with store: true and multi-turn interactions - [x] ui test with store: false and multi-turn interactions ## Future Work * support partial images for image streaming via prelimary results for provider-executed tools ## Related Issues Builds on #7977 Closes #6425 --------- Co-authored-by: Walter Korman Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> Co-authored-by: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> --- .changeset/nice-wombats-move.md | 5 + .../01-ai-sdk-providers/03-openai.mdx | 124 ++++++++++++----- .../openai-image-generation-tool.ts | 31 +++++ .../src/lib/convertBase64ToUint8Array.ts | 5 + .../openai-image-generation-tool.ts | 31 +++++ .../api/chat-openai-image-generation/route.ts | 42 ++++++ .../app/test-openai-image-generation/page.tsx | 38 +++++ .../openai-image-generation-view.tsx | 23 +++ packages/openai/src/openai-tools.ts | 16 +++ .../openai-image-generation-tool.1.chunks.txt | 16 +++ .../openai-image-generation-tool.1.json | 96 +++++++++++++ ...enai-responses-language-model.test.ts.snap | 131 ++++++++++++++++++ .../convert-to-openai-responses-input.ts | 4 - .../responses/openai-responses-api-types.ts | 38 +++-- .../openai-responses-language-model.test.ts | 83 ++++++++++- .../openai-responses-language-model.ts | 54 ++++++++ .../openai-responses-prepare-tools.test.ts | 59 ++++++++ .../openai-responses-prepare-tools.ts | 26 +++- packages/openai/src/tool/image-generation.ts | 110 +++++++++++++++ 19 files changed, 882 insertions(+), 50 deletions(-) create mode 100644 .changeset/nice-wombats-move.md create mode 100644 examples/ai-core/src/generate-text/openai-image-generation-tool.ts create mode 100644 examples/ai-core/src/lib/convertBase64ToUint8Array.ts create mode 100644 examples/ai-core/src/stream-text/openai-image-generation-tool.ts create mode 100644 examples/next-openai/app/api/chat-openai-image-generation/route.ts create mode 100644 examples/next-openai/app/test-openai-image-generation/page.tsx create mode 100644 examples/next-openai/component/openai-image-generation-view.tsx create mode 100644 packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.chunks.txt create mode 100644 packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.json create mode 100644 packages/openai/src/tool/image-generation.ts diff --git a/.changeset/nice-wombats-move.md b/.changeset/nice-wombats-move.md new file mode 100644 index 000000000000..03fed26dc000 --- /dev/null +++ b/.changeset/nice-wombats-move.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +feat (provider/openai): provider defined image generation tool support diff --git a/content/providers/01-ai-sdk-providers/03-openai.mdx b/content/providers/01-ai-sdk-providers/03-openai.mdx index 94d7325dcc3f..99f01c3e29fd 100644 --- a/content/providers/01-ai-sdk-providers/03-openai.mdx +++ b/content/providers/01-ai-sdk-providers/03-openai.mdx @@ -234,33 +234,6 @@ The following OpenAI-specific metadata is returned: - **reasoningTokens** _number_ The number of reasoning tokens that the model generated. -#### Web Search - -The OpenAI responses API supports web search through the `openai.tools.webSearch` tool. - -```ts -const result = await generateText({ - model: openai('gpt-5'), - prompt: 'What happened in San Francisco last week?', - tools: { - web_search: openai.tools.webSearch({ - // optional configuration: - searchContextSize: 'high', - userLocation: { - type: 'approximate', - city: 'San Francisco', - region: 'California', - }, - }), - }, - // Force web search tool (optional): - toolChoice: { type: 'tool', toolName: 'web_search' }, -}); - -// URL sources -const sources = result.sources; -``` - #### Reasoning Output For reasoning models like `gpt-5`, you can enable reasoning summaries to see the model's thought process. Different models support different summarizers—for example, `o4-mini` supports detailed summaries. Set `reasoningSummary: "auto"` to automatically receive the richest level available. @@ -333,7 +306,34 @@ The `textVerbosity` parameter scales output length without changing the underlyi - `'medium'`: Balanced detail (default) - `'high'`: Verbose responses with comprehensive detail -#### File Search +#### Web Search Tool + +The OpenAI responses API supports web search through the `openai.tools.webSearch` tool. + +```ts +const result = await generateText({ + model: openai('gpt-5'), + prompt: 'What happened in San Francisco last week?', + tools: { + web_search: openai.tools.webSearch({ + // optional configuration: + searchContextSize: 'high', + userLocation: { + type: 'approximate', + city: 'San Francisco', + region: 'California', + }, + }), + }, + // Force web search tool (optional): + toolChoice: { type: 'tool', toolName: 'web_search' }, +}); + +// URL sources +const sources = result.sources; +``` + +#### File Search Tool The OpenAI responses API supports file search through the `openai.tools.fileSearch` tool. @@ -371,7 +371,69 @@ const result = await generateText({ be customized. -#### Code Interpreter +#### Image Generation Tool + +OpenAI's Responses API supports multi-modal image generation as a provider-defined tool. +Availability is restricted to specific models (for example, `gpt-5` variants). + +You can use the image tool with either `generateText` or `streamText`: + +```ts +import { openai } from '@ai-sdk/openai'; +import { generateText } from 'ai'; + +const result = await generateText({ + model: openai('gpt-5'), + prompt: + 'Generate an image of an echidna swimming across the Mozambique channel.', + tools: { + image_generation: openai.tools.imageGeneration({ outputFormat: 'webp' }), + }, +}); + +for (const toolResult of result.staticToolResults) { + if (toolResult.toolName === 'image_generation') { + const base64Image = toolResult.output.result; + } +} +``` + +```ts +import { openai } from '@ai-sdk/openai'; +import { streamText } from 'ai'; + +const result = streamText({ + model: openai('gpt-5'), + prompt: + 'Generate an image of an echidna swimming across the Mozambique channel.', + tools: { + image_generation: openai.tools.imageGeneration({ + outputFormat: 'webp', + quality: 'low', + }), + }, +}); + +for await (const part of result.fullStream) { + if (part.type == 'tool-result' && !part.dynamic) { + const base64Image = part.output.result; + } +} +``` + + + When you set `store: false`, then previously generated images will not be + accessible by the model. We recommend using the image generation tool without + setting `store: false`. + + +For complete details on model availability, image quality controls, supported sizes, and tool-specific parameters, +refer to the OpenAI documentation: + +- Image generation overview and models: [OpenAI Image Generation](https://platform.openai.com/docs/guides/image-generation) +- Image generation tool parameters (background, size, quality, format, etc.): [Image Generation Tool Options](https://platform.openai.com/docs/guides/tools-image-generation#tool-options) + +#### Code Interpreter Tool The OpenAI responses API supports the code interpreter tool through the `openai.tools.codeInterpreter` tool. This allows models to write and execute Python code. @@ -403,7 +465,7 @@ The code interpreter tool can be configured with: be customized. -#### Image Support +#### Image Inputs The OpenAI Responses API supports Image inputs for appropriate models. You can pass Image files as part of the message content using the 'image' type: @@ -450,7 +512,7 @@ You can also pass the URL of an image. } ``` -#### PDF support +#### PDF Inputs The OpenAI Responses API supports reading PDF files. You can pass PDF files as part of the message content using the `file` type: diff --git a/examples/ai-core/src/generate-text/openai-image-generation-tool.ts b/examples/ai-core/src/generate-text/openai-image-generation-tool.ts new file mode 100644 index 000000000000..28b86016d10a --- /dev/null +++ b/examples/ai-core/src/generate-text/openai-image-generation-tool.ts @@ -0,0 +1,31 @@ +import { openai } from '@ai-sdk/openai'; +import { generateText } from 'ai'; +import { presentImages } from '../lib/present-image'; +import { run } from '../lib/run'; +import { convertBase64ToUint8Array } from '../lib/convertBase64ToUint8Array'; + +run(async () => { + const result = await generateText({ + model: openai('gpt-5-nano'), + prompt: 'Generate an image of a cat.', + tools: { + image_generation: openai.tools.imageGeneration({ + outputFormat: 'webp', + quality: 'low', + size: '1024x1024', + }), + }, + }); + + for (const toolResult of result.staticToolResults) { + if (toolResult.toolName === 'image_generation') { + await presentImages([ + { + mediaType: 'image/webp', + base64: toolResult.output.result, + uint8Array: convertBase64ToUint8Array(toolResult.output.result), + }, + ]); + } + } +}); diff --git a/examples/ai-core/src/lib/convertBase64ToUint8Array.ts b/examples/ai-core/src/lib/convertBase64ToUint8Array.ts new file mode 100644 index 000000000000..c4aba3375be3 --- /dev/null +++ b/examples/ai-core/src/lib/convertBase64ToUint8Array.ts @@ -0,0 +1,5 @@ +export function convertBase64ToUint8Array(base64String: string) { + const base64Url = base64String.replace(/-/g, '+').replace(/_/g, '/'); + const latin1string = atob(base64Url); + return Uint8Array.from(latin1string, byte => byte.codePointAt(0)!); +} diff --git a/examples/ai-core/src/stream-text/openai-image-generation-tool.ts b/examples/ai-core/src/stream-text/openai-image-generation-tool.ts new file mode 100644 index 000000000000..d4570a41c675 --- /dev/null +++ b/examples/ai-core/src/stream-text/openai-image-generation-tool.ts @@ -0,0 +1,31 @@ +import { openai } from '@ai-sdk/openai'; +import { streamText } from 'ai'; +import { convertBase64ToUint8Array } from '../lib/convertBase64ToUint8Array'; +import { presentImages } from '../lib/present-image'; +import { run } from '../lib/run'; + +run(async () => { + const result = streamText({ + model: openai('gpt-5'), + prompt: + 'Generate an image of an echidna swimming across the Mozambique channel.', + tools: { + image_generation: openai.tools.imageGeneration({ + outputFormat: 'webp', + quality: 'low', + }), + }, + }); + + for await (const part of result.fullStream) { + if (part.type == 'tool-result' && !part.dynamic) { + await presentImages([ + { + mediaType: 'image/webp', + base64: part.output.result, + uint8Array: convertBase64ToUint8Array(part.output.result), + }, + ]); + } + } +}); diff --git a/examples/next-openai/app/api/chat-openai-image-generation/route.ts b/examples/next-openai/app/api/chat-openai-image-generation/route.ts new file mode 100644 index 000000000000..4c5e63eb1d77 --- /dev/null +++ b/examples/next-openai/app/api/chat-openai-image-generation/route.ts @@ -0,0 +1,42 @@ +import { openai } from '@ai-sdk/openai'; +import { + convertToModelMessages, + InferUITools, + streamText, + ToolSet, + UIDataTypes, + UIMessage, + validateUIMessages, +} from 'ai'; + +const tools = { + image_generation: openai.tools.imageGeneration(), +} satisfies ToolSet; + +export type OpenAIImageGenerationMessage = UIMessage< + never, + UIDataTypes, + InferUITools +>; + +export async function POST(req: Request) { + const { messages } = await req.json(); + const uiMessages = await validateUIMessages({ messages }); + + const result = streamText({ + model: openai('gpt-5-nano'), + tools, + messages: convertToModelMessages(uiMessages), + onStepFinish: ({ request }) => { + console.log(JSON.stringify(request.body, null, 2)); + }, + providerOptions: { + // openai: { + // store: false, + // include: ['reasoning.encrypted_content'], + // } satisfies OpenAIResponsesProviderOptions, + }, + }); + + return result.toUIMessageStreamResponse(); +} diff --git a/examples/next-openai/app/test-openai-image-generation/page.tsx b/examples/next-openai/app/test-openai-image-generation/page.tsx new file mode 100644 index 000000000000..76f5f707551e --- /dev/null +++ b/examples/next-openai/app/test-openai-image-generation/page.tsx @@ -0,0 +1,38 @@ +'use client'; + +import { OpenAIImageGenerationMessage } from '@/app/api/chat-openai-image-generation/route'; +import ChatInput from '@/component/chat-input'; +import ImageGenerationView from '@/component/openai-image-generation-view'; +import { useChat } from '@ai-sdk/react'; +import { DefaultChatTransport } from 'ai'; + +export default function TestOpenAIWebSearch() { + const { status, sendMessage, messages } = + useChat({ + transport: new DefaultChatTransport({ + api: '/api/chat-openai-image-generation', + }), + }); + + return ( +
+

OpenAI Image Generation Test

+ + {messages.map(message => ( +
+ {message.role === 'user' ? 'User: ' : 'AI: '} + {message.parts.map((part, index) => { + switch (part.type) { + case 'text': + return
{part.text}
; + case 'tool-image_generation': + return ; + } + })} +
+ ))} + + sendMessage({ text })} /> +
+ ); +} diff --git a/examples/next-openai/component/openai-image-generation-view.tsx b/examples/next-openai/component/openai-image-generation-view.tsx new file mode 100644 index 000000000000..f4c4b1e8ced4 --- /dev/null +++ b/examples/next-openai/component/openai-image-generation-view.tsx @@ -0,0 +1,23 @@ +import { openai } from '@ai-sdk/openai'; +import { UIToolInvocation } from 'ai'; + +export default function ImageGenerationView({ + invocation, +}: { + invocation: UIToolInvocation>; +}) { + switch (invocation.state) { + case 'input-available': + return ( +
+ Generating image... +
+ ); + case 'output-available': + return ( +
+ +
+ ); + } +} diff --git a/packages/openai/src/openai-tools.ts b/packages/openai/src/openai-tools.ts index c3a9ff92d89e..b3c4e4390be1 100644 --- a/packages/openai/src/openai-tools.ts +++ b/packages/openai/src/openai-tools.ts @@ -1,5 +1,6 @@ import { codeInterpreter } from './tool/code-interpreter'; import { fileSearch } from './tool/file-search'; +import { imageGeneration } from './tool/image-generation'; import { webSearch } from './tool/web-search'; import { webSearchPreview } from './tool/web-search-preview'; @@ -29,6 +30,21 @@ export const openaiTools = { */ fileSearch, + /** + * The image generation tool allows you to generate images using a text prompt, + * and optionally image inputs. It leverages the GPT Image model, + * and automatically optimizes text inputs for improved performance. + * + * Must have name `image_generation`. + * + * @param size - Image dimensions (e.g., 1024x1024, 1024x1536) + * @param quality - Rendering quality (e.g. low, medium, high) + * @param format - File output format + * @param compression - Compression level (0-100%) for JPEG and WebP formats + * @param background - Transparent or opaque + */ + imageGeneration, + /** * Web search allows models to access up-to-date information from the internet * and provide answers with sourced citations. diff --git a/packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.chunks.txt b/packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.chunks.txt new file mode 100644 index 000000000000..0d587cf50a19 --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.chunks.txt @@ -0,0 +1,16 @@ +{"type":"response.created","sequence_number":0,"response":{"id":"resp_0df93c0bb83a72f20068c979db26ac819e8b5a444fad3f0d7f","object":"response","created_at":1758034395,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"image_generation","background":"auto","moderation":"auto","n":1,"output_compression":100,"output_format":"webp","quality":"low","size":"auto"}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0df93c0bb83a72f20068c979db26ac819e8b5a444fad3f0d7f","object":"response","created_at":1758034395,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"image_generation","background":"auto","moderation":"auto","n":1,"output_compression":100,"output_format":"webp","quality":"low","size":"auto"}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8","type":"image_generation_call","status":"in_progress"}} +{"type":"response.image_generation_call.in_progress","sequence_number":5,"output_index":1,"item_id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8"} +{"type":"response.image_generation_call.generating","sequence_number":6,"output_index":1,"item_id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8"} +{"type":"response.image_generation_call.partial_image","sequence_number":7,"output_index":1,"item_id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8","partial_image_index":0,"partial_image_b64":"UklGRuIWGQBXRUJQVlA4TKAwGAAv/8X/ABlJbiNJkgRDwkID67D/P9gjl9nuEf2fgPyZzj1Jyu97SlIDX5iPbDv2F3U/+UU+JIlr+wVtEwKO7xiJ7dh26zu3NgZIasDGMcSYOIltx8MpJGFWJAaDE8g4AzhJzCAkCedAeJ17KsRCTxd5r4c1SfLsHwzwZ/2/f67rukb7R1yzavfWH3mdtqpvK4HU00+v2a1qb/...AAAPZYQFuWuM6Be+taQrxy8eMnvFntuAhnHLJbzoq1L9GGMdWs/9hArxYpBl4GS+zJ3eoEsBEkmxChF9k+m5HNgnA2uzI=","size":"1536x1024","quality":"low","background":"opaque","output_format":"webp"} +{"type":"response.image_generation_call.completed","sequence_number":8,"output_index":1,"item_id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8"} +{"type":"response.output_item.done","sequence_number":9,"output_index":1,"item":{"id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8","type":"image_generation_call","status":"completed","background":"opaque","output_format":"webp","quality":"low","result":"UklGRuIWGQBXRUJQVlA4TKAwGAAv/8X/ABlJbiNJkgRDwkID67D/P9gjl9nuEf2fgPyZzj1Jyu97SlIDX5iPbDv2F3U/+UU+JIlr+wVtEwKO7xiJ7dh26zu3NgZIasDGMcSYOIltx8MpJGFWJAaDE8g4AzhJzCAkCedAeJ17KsRCTxd5r4c1SfLsHwzwZ/2/f67rukb7R1yzavfWH3mdtqpvK4HU00+v2a1qb/...AAAPZYQFuWuM6Be+taQrxy8eMnvFntuAhnHLJbzoq1L9GGMdWs/9hArxYpBl4GS+zJ3eoEsBEkmxChF9k+m5HNgnA2uzI=","revised_prompt":"Create a high-resolution, hyperrealistic illustration of an echidna swimming across the Mozambique Channel. Composition: wide, cinematic aerial perspective over the Indian Ocean with Mozambique’s coastline faintly visible to the left and Madagascar’s coastline faintly visible to the right, both softened by atmospheric haze and no text labels. In the midground, feature a short-beaked echidna partially submerged: spines slick and glistening with seawater, small snout just above the surface, front limbs paddling and creating delicate ripples and a subtle V-shaped wake. Water: deep cobalt transitioning to turquoise, with gentle swells, current lines, and sparkling sun reflections. Lighting: warm golden-hour late afternoon, long highlights on wave crests and soft shadows. Add a few distant seabirds and soft cumulus clouds for scale and atmosphere. Style: richly detailed, natural colors, crisp yet painterly rendering, shallow depth of field emphasizing the echidna, 16:9 aspect ratio, 4K resolution.","size":"1536x1024"}} +{"type":"response.output_item.added","sequence_number":10,"output_index":2,"item":{"id":"msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2","type":"message","status":"in_progress","content":[],"role":"assistant"}} +{"type":"response.content_part.added","sequence_number":11,"item_id":"msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2","output_index":2,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} +{"type":"response.output_text.done","sequence_number":12,"item_id":"msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2","output_index":2,"content_index":0,"text":"","logprobs":[]} +{"type":"response.content_part.done","sequence_number":13,"item_id":"msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2","output_index":2,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} +{"type":"response.output_item.done","sequence_number":14,"output_index":2,"item":{"id":"msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":""}],"role":"assistant"}} +{"type":"response.completed","sequence_number":15,"response":{"id":"resp_0df93c0bb83a72f20068c979db26ac819e8b5a444fad3f0d7f","object":"response","created_at":1758034395,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-2025-08-07","output":[{"id":"rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6","type":"reasoning","summary":[]},{"id":"ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8","type":"image_generation_call","status":"completed","background":"opaque","output_format":"webp","quality":"low","result":"UklGRuIWGQBXRUJQVlA4TKAwGAAv/8X/ABlJbiNJkgRDwkID67D/P9gjl9nuEf2fgPyZzj1Jyu97SlIDX5iPbDv2F3U/+UU+JIlr+wVtEwKO7xiJ7dh26zu3NgZIasDGMcSYOIltx8MpJGFWJAaDE8g4AzhJzCAkCedAeJ17KsRCTxd5r4c1SfLsHwzwZ/2/f67rukb7R1yzavfWH3mdtqpvK4HU00+v2a1qb/...AAAPZYQFuWuM6Be+taQrxy8eMnvFntuAhnHLJbzoq1L9GGMdWs/9hArxYpBl4GS+zJ3eoEsBEkmxChF9k+m5HNgnA2uzI=","revised_prompt":"Create a high-resolution, hyperrealistic illustration of an echidna swimming across the Mozambique Channel. Composition: wide, cinematic aerial perspective over the Indian Ocean with Mozambique’s coastline faintly visible to the left and Madagascar’s coastline faintly visible to the right, both softened by atmospheric haze and no text labels. In the midground, feature a short-beaked echidna partially submerged: spines slick and glistening with seawater, small snout just above the surface, front limbs paddling and creating delicate ripples and a subtle V-shaped wake. Water: deep cobalt transitioning to turquoise, with gentle swells, current lines, and sparkling sun reflections. Lighting: warm golden-hour late afternoon, long highlights on wave crests and soft shadows. Add a few distant seabirds and soft cumulus clouds for scale and atmosphere. Style: richly detailed, natural colors, crisp yet painterly rendering, shallow depth of field emphasizing the echidna, 16:9 aspect ratio, 4K resolution.","size":"1536x1024"},{"id":"msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":""}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"image_generation","background":"auto","moderation":"auto","n":1,"output_compression":100,"output_format":"webp","quality":"low","size":"auto"}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":{"input_tokens":2941,"input_tokens_details":{"cached_tokens":1920},"output_tokens":1249,"output_tokens_details":{"reasoning_tokens":1024},"total_tokens":4190},"user":null,"metadata":{}}} \ No newline at end of file diff --git a/packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.json b/packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.json new file mode 100644 index 000000000000..52e9ff9f7a90 --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-image-generation-tool.1.json @@ -0,0 +1,96 @@ +{ + "id": "resp_0a33d15155cb126d0068c96c54970481958484dea31f07926d", + "object": "response", + "created_at": 1758030932, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-5-nano-2025-08-07", + "output": [ + { + "id": "rs_0a33d15155cb126d0068c96c5527808195a933b468ccb5dfd9", + "type": "reasoning", + "summary": [] + }, + { + "id": "ig_0a33d15155cb126d0068c96c59bc14819599154c9988b82996", + "type": "image_generation_call", + "status": "completed", + "background": "opaque", + "output_format": "webp", + "quality": "low", + "result": "UklGRoitEQBXRUJQVlA4TEGzEAAv/8P/AM1AbNtGkITZhU4fH9J/wTOT+xIi+j8BuT4kABkCibNAZrlwIPyQ7W/bH5L2RHMzMBKgXmfZeYi9tLtrrQkZvN1yXHLLgG71gPkpDxmI/gc03YFulQR...AA9lhA0Y9rVdqQs/W4w/MOxeRW5+R1/UXmmNVi9yQ7x/vG0q2VRk01seZIuj5OmRYhD+yY82dZqMH1BCueTeOcNfGKxQ==", + "revised_prompt": "A cute fluffy cat sitting on a sunlit windowsill, warm sunlight, soft fur, expressive eyes, photorealistic style.", + "size": "1024x1024" + }, + { + "id": "rs_0a33d15155cb126d0068c96c6c0ef48195bc73e30faf832ba3", + "type": "reasoning", + "summary": [] + }, + { + "id": "msg_0a33d15155cb126d0068c96c723ed88195b1405bc370bb8a65", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [], + "logprobs": [], + "text": "" + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": "medium", + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "image_generation", + "background": "auto", + "moderation": "auto", + "n": 1, + "output_compression": 100, + "output_format": "webp", + "quality": "low", + "size": "1024x1024" + } + ], + "top_logprobs": 0, + "top_p": 1, + "truncation": "disabled", + "usage": { + "input_tokens": 3151, + "input_tokens_details": { + "cached_tokens": 0 + }, + "output_tokens": 1970, + "output_tokens_details": { + "reasoning_tokens": 1920 + }, + "total_tokens": 5121 + }, + "user": null, + "metadata": {} +} diff --git a/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap b/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap index 3229f8a27393..2ba41e8c4c62 100644 --- a/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap +++ b/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap @@ -119,6 +119,56 @@ Notes: ] `; +exports[`OpenAIResponsesLanguageModel > doGenerate > image generation tool > should include generate image tool call and result in content 1`] = ` +[ + { + "providerMetadata": { + "openai": { + "itemId": "rs_0a33d15155cb126d0068c96c5527808195a933b468ccb5dfd9", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "input": "{}", + "providerExecuted": true, + "toolCallId": "ig_0a33d15155cb126d0068c96c59bc14819599154c9988b82996", + "toolName": "image_generation", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "result": "UklGRoitEQBXRUJQVlA4TEGzEAAv/8P/AM1AbNtGkITZhU4fH9J/wTOT+xIi+j8BuT4kABkCibNAZrlwIPyQ7W/bH5L2RHMzMBKgXmfZeYi9tLtrrQkZvN1yXHLLgG71gPkpDxmI/gc03YFulQR...AA9lhA0Y9rVdqQs/W4w/MOxeRW5+R1/UXmmNVi9yQ7x/vG0q2VRk01seZIuj5OmRYhD+yY82dZqMH1BCueTeOcNfGKxQ==", + }, + "toolCallId": "ig_0a33d15155cb126d0068c96c59bc14819599154c9988b82996", + "toolName": "image_generation", + "type": "tool-result", + }, + { + "providerMetadata": { + "openai": { + "itemId": "rs_0a33d15155cb126d0068c96c6c0ef48195bc73e30faf832ba3", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "providerMetadata": { + "openai": { + "itemId": "msg_0a33d15155cb126d0068c96c723ed88195b1405bc370bb8a65", + }, + }, + "text": "", + "type": "text", + }, +] +`; + exports[`OpenAIResponsesLanguageModel > doStream > code interpreter tool > should stream code interpreter results 1`] = ` [ { @@ -1363,3 +1413,84 @@ exports[`OpenAIResponsesLanguageModel > doStream > code interpreter tool > shoul }, ] `; + +exports[`OpenAIResponsesLanguageModel > doStream > image generation tool > should stream code image generation results 1`] = ` +[ + { + "type": "stream-start", + "warnings": [], + }, + { + "id": "resp_0df93c0bb83a72f20068c979db26ac819e8b5a444fad3f0d7f", + "modelId": "gpt-5-2025-08-07", + "timestamp": 2025-09-16T14:53:15.000Z, + "type": "response-metadata", + }, + { + "id": "rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6:0", + "providerMetadata": { + "openai": { + "itemId": "rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6:0", + "providerMetadata": { + "openai": { + "itemId": "rs_0df93c0bb83a72f20068c979db90b4819e94cedbfda2d49af6", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "input": "{}", + "providerExecuted": true, + "toolCallId": "ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8", + "toolName": "image_generation", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "result": "UklGRuIWGQBXRUJQVlA4TKAwGAAv/8X/ABlJbiNJkgRDwkID67D/P9gjl9nuEf2fgPyZzj1Jyu97SlIDX5iPbDv2F3U/+UU+JIlr+wVtEwKO7xiJ7dh26zu3NgZIasDGMcSYOIltx8MpJGFWJAaDE8g4AzhJzCAkCedAeJ17KsRCTxd5r4c1SfLsHwzwZ/2/f67rukb7R1yzavfWH3mdtqpvK4HU00+v2a1qb/...AAAPZYQFuWuM6Be+taQrxy8eMnvFntuAhnHLJbzoq1L9GGMdWs/9hArxYpBl4GS+zJ3eoEsBEkmxChF9k+m5HNgnA2uzI=", + }, + "toolCallId": "ig_0df93c0bb83a72f20068c979f589c0819e9f0fc2d1a27aa1b8", + "toolName": "image_generation", + "type": "tool-result", + }, + { + "id": "msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2", + "providerMetadata": { + "openai": { + "itemId": "msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2", + }, + }, + "type": "text-start", + }, + { + "id": "msg_0df93c0bb83a72f20068c97a0b36f4819ea5906451007f95e2", + "type": "text-end", + }, + { + "finishReason": "stop", + "providerMetadata": { + "openai": { + "responseId": "resp_0df93c0bb83a72f20068c979db26ac819e8b5a444fad3f0d7f", + "serviceTier": "default", + }, + }, + "type": "finish", + "usage": { + "cachedInputTokens": 1920, + "inputTokens": 2941, + "outputTokens": 1249, + "reasoningTokens": 1024, + "totalTokens": 4190, + }, + }, +] +`; diff --git a/packages/openai/src/responses/convert-to-openai-responses-input.ts b/packages/openai/src/responses/convert-to-openai-responses-input.ts index e560eacb76d6..64b18cd8577b 100644 --- a/packages/openai/src/responses/convert-to-openai-responses-input.ts +++ b/packages/openai/src/responses/convert-to-openai-responses-input.ts @@ -10,10 +10,6 @@ import { OpenAIResponsesInput, OpenAIResponsesReasoning, } from './openai-responses-api-types'; -import { - codeInterpreterInputSchema, - codeInterpreterOutputSchema, -} from '../tool/code-interpreter'; /** * Check if a string is a file ID based on the given prefixes diff --git a/packages/openai/src/responses/openai-responses-api-types.ts b/packages/openai/src/responses/openai-responses-api-types.ts index 0fd889240762..9c83a9d805f8 100644 --- a/packages/openai/src/responses/openai-responses-api-types.ts +++ b/packages/openai/src/responses/openai-responses-api-types.ts @@ -79,13 +79,11 @@ export type OpenAIResponsesTool = name: string; description: string | undefined; parameters: JSONSchema7; - strict?: boolean; + strict: boolean | undefined; } | { type: 'web_search'; - filters?: { - allowed_domains?: string[]; - }; + filters: { allowed_domains: string[] | undefined } | undefined; search_context_size: 'low' | 'medium' | 'high' | undefined; user_location: | { @@ -116,12 +114,12 @@ export type OpenAIResponsesTool = } | { type: 'file_search'; - vector_store_ids?: string[]; - max_num_results?: number; - ranking_options?: { - ranker?: 'auto' | 'default-2024-08-21'; - }; - filters?: + vector_store_ids: string[] | undefined; + max_num_results: number | undefined; + ranking_options: + | { ranker: 'auto' | 'default-2024-08-21' | undefined } + | undefined; + filters: | { key: string; type: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte'; @@ -130,7 +128,25 @@ export type OpenAIResponsesTool = | { type: 'and' | 'or'; filters: any[]; - }; + } + | undefined; + } + | { + type: 'image_generation'; + background: 'auto' | 'opaque' | 'transparent' | undefined; + input_fidelity: 'low' | 'high' | undefined; + input_image_mask: + | { + file_id: string | undefined; + image_url: string | undefined; + } + | undefined; + model: string | undefined; + moderation: 'auto' | undefined; + output_compression: number | undefined; + output_format: 'png' | 'jpeg' | 'webp' | undefined; + quality: 'auto' | 'low' | 'medium' | 'high' | undefined; + size: 'auto' | '1024x1024' | '1024x1536' | '1536x1024' | undefined; }; export type OpenAIResponsesReasoning = { diff --git a/packages/openai/src/responses/openai-responses-language-model.test.ts b/packages/openai/src/responses/openai-responses-language-model.test.ts index 98b7a87021d3..98b3225e07c8 100644 --- a/packages/openai/src/responses/openai-responses-language-model.test.ts +++ b/packages/openai/src/responses/openai-responses-language-model.test.ts @@ -2160,7 +2160,62 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); - describe('web search', () => { + describe('image generation tool', () => { + let result: Awaited>; + + beforeEach(async () => { + prepareJsonFixtureResponse('openai-image-generation-tool.1'); + + result = await createModel('gpt-5-nano').doGenerate({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.image_generation', + name: 'image_generation', + args: { + outputFormat: 'webp', + quality: 'low', + size: '1024x1024', + }, + }, + ], + }); + }); + + it('should send request body with include and tool', async () => { + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "input": [ + { + "content": [ + { + "text": "Hello", + "type": "input_text", + }, + ], + "role": "user", + }, + ], + "model": "gpt-5-nano", + "tools": [ + { + "output_format": "webp", + "quality": "low", + "size": "1024x1024", + "type": "image_generation", + }, + ], + } + `); + }); + + it('should include generate image tool call and result in content', async () => { + expect(result.content).toMatchSnapshot(); + }); + }); + + describe('web search tool', () => { beforeEach(() => { server.urls['https://api.openai.com/v1/responses'].response = { type: 'json-value', @@ -4070,6 +4125,32 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); + describe('image generation tool', () => { + let result: Awaited>; + + beforeEach(async () => { + prepareChunksFixtureResponse('openai-image-generation-tool.1'); + + result = await createModel('gpt-5-nano').doStream({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.image_generation', + name: 'image_generation', + args: {}, + }, + ], + }); + }); + + it('should stream code image generation results', async () => { + expect( + await convertReadableStreamToArray(result.stream), + ).toMatchSnapshot(); + }); + }); + describe('errors', () => { it('should stream error parts', async () => { server.urls['https://api.openai.com/v1/responses'].response = { diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index 577eab0321dd..07c253b14bb7 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -30,6 +30,7 @@ import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-rea import { OpenAIResponsesIncludeOptions } from './openai-responses-api-types'; import { prepareResponsesTools } from './openai-responses-prepare-tools'; import { OpenAIResponsesModelId } from './openai-responses-settings'; +import { imageGenerationOutputSchema } from '../tool/image-generation'; const webSearchCallItem = z.object({ type: z.literal('web_search_call'), @@ -69,6 +70,12 @@ const codeInterpreterCallItem = z.object({ .nullable(), }); +const imageGenerationCallItem = z.object({ + type: z.literal('image_generation_call'), + id: z.string(), + result: z.string(), +}); + /** * `top_logprobs` request body argument can be set to an integer between * 0 and 20 specifying the number of most likely tokens to return at each @@ -439,6 +446,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { ), }), codeInterpreterCallItem, + imageGenerationCallItem, z.object({ type: z.literal('function_call'), call_id: z.string(), @@ -534,6 +542,28 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { break; } + case 'image_generation_call': { + content.push({ + type: 'tool-call', + toolCallId: part.id, + toolName: 'image_generation', + input: '{}', + providerExecuted: true, + }); + + content.push({ + type: 'tool-result', + toolCallId: part.id, + toolName: 'image_generation', + result: { + result: part.result, + } satisfies z.infer, + providerExecuted: true, + }); + + break; + } + case 'message': { for (const contentPart of part.content) { if ( @@ -611,6 +641,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { result: { status: part.status }, providerExecuted: true, }); + break; } @@ -850,6 +881,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { id: value.item.id, toolName: 'file_search', }); + } else if (value.item.type === 'image_generation_call') { + controller.enqueue({ + type: 'tool-call', + toolCallId: value.item.id, + toolName: 'image_generation', + input: '{}', + providerExecuted: true, + }); } else if (value.item.type === 'message') { controller.enqueue({ type: 'text-start', @@ -997,6 +1036,16 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { } satisfies z.infer, providerExecuted: true, }); + } else if (value.item.type === 'image_generation_call') { + controller.enqueue({ + type: 'tool-result', + toolCallId: value.item.id, + toolName: 'image_generation', + result: { + result: value.item.result, + } satisfies z.infer, + providerExecuted: true, + }); } else if (value.item.type === 'message') { controller.enqueue({ type: 'text-end', @@ -1256,6 +1305,10 @@ const responseOutputItemAddedSchema = z.object({ ) .optional(), }), + z.object({ + type: z.literal('image_generation_call'), + id: z.string(), + }), ]), }); @@ -1281,6 +1334,7 @@ const responseOutputItemDoneSchema = z.object({ status: z.literal('completed'), }), codeInterpreterCallItem, + imageGenerationCallItem, webSearchCallItem, z.object({ type: z.literal('computer_call'), diff --git a/packages/openai/src/responses/openai-responses-prepare-tools.test.ts b/packages/openai/src/responses/openai-responses-prepare-tools.test.ts index b8aa8e8ce1ce..1c90e1b9adb0 100644 --- a/packages/openai/src/responses/openai-responses-prepare-tools.test.ts +++ b/packages/openai/src/responses/openai-responses-prepare-tools.test.ts @@ -203,4 +203,63 @@ describe('prepareResponsesTools', () => { expect(result.toolWarnings).toEqual([]); }); }); + + describe('image generation', () => { + it('should prepare image_generation tool with all options', () => { + const result = prepareResponsesTools({ + tools: [ + { + type: 'provider-defined', + id: 'openai.image_generation', + name: 'image_generation', + args: { + background: 'opaque', + size: '1536x1024', + quality: 'high', + moderation: 'auto', + outputFormat: 'png', + outputCompression: 100, + }, + }, + ], + strictJsonSchema: false, + }); + + expect(result.tools).toEqual([ + { + type: 'image_generation', + background: 'opaque', + size: '1536x1024', + quality: 'high', + moderation: 'auto', + output_format: 'png', + output_compression: 100, + }, + ]); + expect(result.toolWarnings).toEqual([]); + }); + + it('should support tool choice selection for image_generation', () => { + const result = prepareResponsesTools({ + tools: [ + { + type: 'provider-defined', + id: 'openai.image_generation', + name: 'image_generation', + args: {}, + }, + ], + toolChoice: { type: 'tool', toolName: 'image_generation' }, + strictJsonSchema: false, + }); + + expect(result.tools).toEqual([ + { + type: 'image_generation', + }, + ]); + expect(result.toolChoice).toEqual({ type: 'image_generation' }); + expect(result.toolWarnings).toEqual([]); + }); + }); }); diff --git a/packages/openai/src/responses/openai-responses-prepare-tools.ts b/packages/openai/src/responses/openai-responses-prepare-tools.ts index b70930931191..b5971807ea36 100644 --- a/packages/openai/src/responses/openai-responses-prepare-tools.ts +++ b/packages/openai/src/responses/openai-responses-prepare-tools.ts @@ -7,6 +7,7 @@ import { codeInterpreterArgsSchema } from '../tool/code-interpreter'; import { fileSearchArgsSchema } from '../tool/file-search'; import { webSearchArgsSchema } from '../tool/web-search'; import { webSearchPreviewArgsSchema } from '../tool/web-search-preview'; +import { imageGenerationArgsSchema } from '../tool/image-generation'; import { OpenAIResponsesTool } from './openai-responses-api-types'; export function prepareResponsesTools({ @@ -27,7 +28,8 @@ export function prepareResponsesTools({ | { type: 'web_search_preview' } | { type: 'web_search' } | { type: 'function'; name: string } - | { type: 'code_interpreter' }; + | { type: 'code_interpreter' } + | { type: 'image_generation' }; toolWarnings: LanguageModelV2CallWarning[]; } { // when the tools array is empty, change it to undefined to prevent errors: @@ -102,8 +104,25 @@ export function prepareResponsesTools({ }); break; } - default: { - toolWarnings.push({ type: 'unsupported-tool', tool }); + case 'openai.image_generation': { + const args = imageGenerationArgsSchema.parse(tool.args); + openaiTools.push({ + type: 'image_generation', + background: args.background, + input_fidelity: args.inputFidelity, + input_image_mask: args.inputImageMask + ? { + file_id: args.inputImageMask.fileId, + image_url: args.inputImageMask.imageUrl, + } + : undefined, + model: args.model, + size: args.size, + quality: args.quality, + moderation: args.moderation, + output_format: args.outputFormat, + output_compression: args.outputCompression, + }); break; } } @@ -132,6 +151,7 @@ export function prepareResponsesTools({ toolChoice: toolChoice.toolName === 'code_interpreter' || toolChoice.toolName === 'file_search' || + toolChoice.toolName === 'image_generation' || toolChoice.toolName === 'web_search_preview' || toolChoice.toolName === 'web_search' ? { type: toolChoice.toolName } diff --git a/packages/openai/src/tool/image-generation.ts b/packages/openai/src/tool/image-generation.ts new file mode 100644 index 000000000000..f3c7c3ff56bd --- /dev/null +++ b/packages/openai/src/tool/image-generation.ts @@ -0,0 +1,110 @@ +import { createProviderDefinedToolFactoryWithOutputSchema } from '@ai-sdk/provider-utils'; +import { z } from 'zod/v4'; + +export const imageGenerationArgsSchema = z + .object({ + background: z.enum(['auto', 'opaque', 'transparent']).optional(), + inputFidelity: z.enum(['low', 'high']).optional(), + inputImageMask: z + .object({ + fileId: z.string().optional(), + imageUrl: z.string().optional(), + }) + .optional(), + model: z.string().optional(), + moderation: z.enum(['auto']).optional(), + outputCompression: z.number().int().min(0).max(100).optional(), + outputFormat: z.enum(['png', 'jpeg', 'webp']).optional(), + quality: z.enum(['auto', 'low', 'medium', 'high']).optional(), + size: z.enum(['1024x1024', '1024x1536', '1536x1024', 'auto']).optional(), + }) + .strict(); + +export const imageGenerationOutputSchema = z.object({ + result: z.string(), +}); + +type ImageGenerationArgs = { + /** + * Background type for the generated image. Default is 'auto'. + */ + background?: 'auto' | 'opaque' | 'transparent'; + + /** + * Input fidelity for the generated image. Default is 'low'. + */ + inputFidelity?: 'low' | 'high'; + + /** + * Optional mask for inpainting. + * Contains image_url (string, optional) and file_id (string, optional). + */ + inputImageMask?: { + /** + * File ID for the mask image. + */ + fileId?: string; + + /** + * Base64-encoded mask image. + */ + imageUrl?: string; + }; + + /** + * The image generation model to use. Default: gpt-image-1. + */ + model?: string; + + /** + * Moderation level for the generated image. Default: auto. + */ + moderation?: 'auto'; + + /** + * Compression level for the output image. Default: 100. + */ + outputCompression?: number; + + /** + * The output format of the generated image. One of png, webp, or jpeg. + * Default: png + */ + outputFormat?: 'png' | 'jpeg' | 'webp'; + + /** + * The quality of the generated image. + * One of low, medium, high, or auto. Default: auto. + */ + quality?: 'auto' | 'low' | 'medium' | 'high'; + + /** + * The size of the generated image. + * One of 1024x1024, 1024x1536, 1536x1024, or auto. + * Default: auto. + */ + size?: 'auto' | '1024x1024' | '1024x1536' | '1536x1024'; +}; + +const imageGenerationToolFactory = + createProviderDefinedToolFactoryWithOutputSchema< + {}, + { + /** + * The generated image encoded in base64. + */ + result: string; + }, + ImageGenerationArgs + >({ + id: 'openai.image_generation', + name: 'image_generation', + inputSchema: z.object({}), + outputSchema: imageGenerationOutputSchema, + }); + +export const imageGeneration = ( + args: ImageGenerationArgs = {}, // default +) => { + return imageGenerationToolFactory(args); +}; From bb94467b0019cf6293c858f3a6f81f4252dac5fe Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 11:29:33 +0200 Subject: [PATCH 043/121] feat(provider/openai): add maxToolCalls provider option (#8690) ## Background OpenAI has introduced a `max_tool_calls` parameter in the responses API: https://platform.openai.com/docs/api-reference/responses/create#responses-create-max_tool_calls ## Summary Add support via a `maxToolCalls` provider option. --- .changeset/big-walls-care.md | 5 +++ .../01-ai-sdk-providers/03-openai.mdx | 5 +++ .../openai-responses-language-model.test.ts | 37 ++++++++++++++----- .../openai-responses-language-model.ts | 35 +++++++++++------- 4 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 .changeset/big-walls-care.md diff --git a/.changeset/big-walls-care.md b/.changeset/big-walls-care.md new file mode 100644 index 000000000000..1e3092b3bc83 --- /dev/null +++ b/.changeset/big-walls-care.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +feat(provider/openai): add maxToolCalls provider option diff --git a/content/providers/01-ai-sdk-providers/03-openai.mdx b/content/providers/01-ai-sdk-providers/03-openai.mdx index 99f01c3e29fd..61ede827efd8 100644 --- a/content/providers/01-ai-sdk-providers/03-openai.mdx +++ b/content/providers/01-ai-sdk-providers/03-openai.mdx @@ -168,6 +168,11 @@ The following provider options are available: include `['reasoning.encrypted_content']` in the `include` option to ensure reasoning content is available across conversation steps. +- **maxToolCalls** _integer_ + The maximum number of total calls to built-in tools that can be processed in a response. + This maximum number applies across all built-in tool calls, not per individual tool. + Any further attempts to call a tool by the model will be ignored. + - **metadata** _Record<string, string>_ Additional metadata to store with the generation. diff --git a/packages/openai/src/responses/openai-responses-language-model.test.ts b/packages/openai/src/responses/openai-responses-language-model.test.ts index 98b3225e07c8..a936f2418bbb 100644 --- a/packages/openai/src/responses/openai-responses-language-model.test.ts +++ b/packages/openai/src/responses/openai-responses-language-model.test.ts @@ -213,17 +213,36 @@ describe('OpenAIResponsesLanguageModel', () => { ], temperature: 0.5, topP: 0.3, + providerOptions: { + openai: { + maxToolCalls: 10, + }, + }, }); - expect(await server.calls[0].requestBodyJson).toStrictEqual({ - model: 'gpt-4o', - temperature: 0.5, - top_p: 0.3, - input: [ - { role: 'system', content: 'You are a helpful assistant.' }, - { role: 'user', content: [{ type: 'input_text', text: 'Hello' }] }, - ], - }); + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "input": [ + { + "content": "You are a helpful assistant.", + "role": "system", + }, + { + "content": [ + { + "text": "Hello", + "type": "input_text", + }, + ], + "role": "user", + }, + ], + "max_tool_calls": 10, + "model": "gpt-4o", + "temperature": 0.5, + "top_p": 0.3, + } + `); expect(warnings).toStrictEqual([]); }); diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index 07c253b14bb7..190c25171ddc 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -256,6 +256,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }), // provider options: + max_tool_calls: openaiOptions?.maxToolCalls, metadata: openaiOptions?.metadata, parallel_tool_calls: openaiOptions?.parallelToolCalls, previous_response_id: openaiOptions?.previousResponseId, @@ -1576,16 +1577,6 @@ function getResponsesModelConfig(modelId: string): ResponsesModelConfig { // TODO AI SDK 6: use optional here instead of nullish const openaiResponsesProviderOptionsSchema = z.object({ - metadata: z.any().nullish(), - parallelToolCalls: z.boolean().nullish(), - previousResponseId: z.string().nullish(), - store: z.boolean().nullish(), - user: z.string().nullish(), - reasoningEffort: z.string().nullish(), - strictJsonSchema: z.boolean().nullish(), - instructions: z.string().nullish(), - reasoningSummary: z.string().nullish(), - serviceTier: z.enum(['auto', 'flex', 'priority']).nullish(), include: z .array( z.enum([ @@ -1595,9 +1586,7 @@ const openaiResponsesProviderOptionsSchema = z.object({ ]), ) .nullish(), - textVerbosity: z.enum(['low', 'medium', 'high']).nullish(), - promptCacheKey: z.string().nullish(), - safetyIdentifier: z.string().nullish(), + instructions: z.string().nullish(), /** * Return the log probabilities of the tokens. @@ -1614,6 +1603,26 @@ const openaiResponsesProviderOptionsSchema = z.object({ logprobs: z .union([z.boolean(), z.number().min(1).max(TOP_LOGPROBS_MAX)]) .optional(), + + /** + * The maximum number of total calls to built-in tools that can be processed in a response. + * This maximum number applies across all built-in tool calls, not per individual tool. + * Any further attempts to call a tool by the model will be ignored. + */ + maxToolCalls: z.number().nullish(), + + metadata: z.any().nullish(), + parallelToolCalls: z.boolean().nullish(), + previousResponseId: z.string().nullish(), + promptCacheKey: z.string().nullish(), + reasoningEffort: z.string().nullish(), + reasoningSummary: z.string().nullish(), + safetyIdentifier: z.string().nullish(), + serviceTier: z.enum(['auto', 'flex', 'priority']).nullish(), + store: z.boolean().nullish(), + strictJsonSchema: z.boolean().nullish(), + textVerbosity: z.enum(['low', 'medium', 'high']).nullish(), + user: z.string().nullish(), }); export type OpenAIResponsesProviderOptions = z.infer< From f3a638de9b0fd2cf66172054e1b0cb70fe7d2c1a Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:34:01 +0200 Subject: [PATCH 044/121] Version Packages (#8664) # Releases ## ai@5.0.45 ### Patch Changes - 76024fc: fix(ai): fix static tool call and result detection when dynamic is undefined - 93d8b60: fix(ai): do not filter zero-length text parts that have provider options - d8eb31f: fix(ai): fix webp image detection from base64 ## @ai-sdk/angular@1.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/azure@2.0.31 ### Patch Changes - Updated dependencies [bb94467] - Updated dependencies [4a2b70e] - Updated dependencies [643711d] - @ai-sdk/openai@2.0.31 ## @ai-sdk/langchain@1.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/llamaindex@1.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/openai@2.0.31 ### Patch Changes - bb94467: feat(provider/openai): add maxToolCalls provider option - 4a2b70e: feat(provider/openai): send item references for provider-executed tool results - 643711d: feat (provider/openai): provider defined image generation tool support ## @ai-sdk/react@2.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/rsc@1.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/svelte@3.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/vue@2.0.45 ### Patch Changes - Updated dependencies [76024fc] - Updated dependencies [93d8b60] - Updated dependencies [d8eb31f] - ai@5.0.45 ## @ai-sdk/xai@2.0.20 ### Patch Changes - 3a10095: added new xai x live search fields Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/big-walls-care.md | 5 ----- .changeset/bright-keys-exercise.md | 6 ------ .changeset/cyan-zebras-live.md | 5 ----- .changeset/funny-needles-return.md | 5 ----- .changeset/nice-wombats-move.md | 5 ----- .changeset/silly-buses-thank.md | 5 ----- .changeset/small-ladybugs-check.md | 5 ----- packages/ai/CHANGELOG.md | 8 ++++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 9 +++++++++ packages/angular/package.json | 2 +- packages/azure/CHANGELOG.md | 9 +++++++++ packages/azure/package.json | 2 +- packages/langchain/CHANGELOG.md | 9 +++++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 9 +++++++++ packages/llamaindex/package.json | 2 +- packages/openai/CHANGELOG.md | 8 ++++++++ packages/openai/package.json | 2 +- packages/react/CHANGELOG.md | 9 +++++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 9 +++++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 9 +++++++++ packages/svelte/CHANGELOG.md | 9 +++++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 9 +++++++++ packages/vue/package.json | 2 +- packages/xai/CHANGELOG.md | 6 ++++++ packages/xai/package.json | 2 +- 30 files changed, 114 insertions(+), 47 deletions(-) delete mode 100644 .changeset/big-walls-care.md delete mode 100644 .changeset/bright-keys-exercise.md delete mode 100644 .changeset/cyan-zebras-live.md delete mode 100644 .changeset/funny-needles-return.md delete mode 100644 .changeset/nice-wombats-move.md delete mode 100644 .changeset/silly-buses-thank.md delete mode 100644 .changeset/small-ladybugs-check.md diff --git a/.changeset/big-walls-care.md b/.changeset/big-walls-care.md deleted file mode 100644 index 1e3092b3bc83..000000000000 --- a/.changeset/big-walls-care.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -feat(provider/openai): add maxToolCalls provider option diff --git a/.changeset/bright-keys-exercise.md b/.changeset/bright-keys-exercise.md deleted file mode 100644 index 42a976331b34..000000000000 --- a/.changeset/bright-keys-exercise.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@example/ai-core': patch -'@ai-sdk/xai': patch ---- - -added new xai x live search fields diff --git a/.changeset/cyan-zebras-live.md b/.changeset/cyan-zebras-live.md deleted file mode 100644 index 22e5e2822f72..000000000000 --- a/.changeset/cyan-zebras-live.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -feat(provider/openai): send item references for provider-executed tool results diff --git a/.changeset/funny-needles-return.md b/.changeset/funny-needles-return.md deleted file mode 100644 index 145db74b35a0..000000000000 --- a/.changeset/funny-needles-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix(ai): fix static tool call and result detection when dynamic is undefined diff --git a/.changeset/nice-wombats-move.md b/.changeset/nice-wombats-move.md deleted file mode 100644 index 03fed26dc000..000000000000 --- a/.changeset/nice-wombats-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -feat (provider/openai): provider defined image generation tool support diff --git a/.changeset/silly-buses-thank.md b/.changeset/silly-buses-thank.md deleted file mode 100644 index dbba49378698..000000000000 --- a/.changeset/silly-buses-thank.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix(ai): do not filter zero-length text parts that have provider options diff --git a/.changeset/small-ladybugs-check.md b/.changeset/small-ladybugs-check.md deleted file mode 100644 index 29b0bcfd8faf..000000000000 --- a/.changeset/small-ladybugs-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'ai': patch ---- - -fix(ai): fix webp image detection from base64 diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 54e6fcf10373..0b4a4573b696 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,13 @@ # ai +## 5.0.45 + +### Patch Changes + +- 76024fc: fix(ai): fix static tool call and result detection when dynamic is undefined +- 93d8b60: fix(ai): do not filter zero-length text parts that have provider options +- d8eb31f: fix(ai): fix webp image detection from base64 + ## 5.0.44 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index c0b67b7562fe..e68042045892 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.44", + "version": "5.0.45", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 5e5bfdd3d1c5..08967329d5a3 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/angular +## 1.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 1.0.44 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index f1bf827163a9..a6f1035b2bab 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.44", + "version": "1.0.45", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index febda9ec5fa8..de5ab180550b 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/azure +## 2.0.31 + +### Patch Changes + +- Updated dependencies [bb94467] +- Updated dependencies [4a2b70e] +- Updated dependencies [643711d] + - @ai-sdk/openai@2.0.31 + ## 2.0.30 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index f528d9a60566..2878adf251f0 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.0.30", + "version": "2.0.31", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 2b7eb663eb0b..965255e463e7 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/langchain +## 1.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 1.0.44 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index f27c0fb83322..8c16122e9205 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.44", + "version": "1.0.45", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index b2c1fbcb7b8b..26c1eb28cd10 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/llamaindex +## 1.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 1.0.44 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index a3f49d0a7d05..c82f1417718e 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.44", + "version": "1.0.45", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 22f6d939f33f..2e76842ce0d4 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/openai +## 2.0.31 + +### Patch Changes + +- bb94467: feat(provider/openai): add maxToolCalls provider option +- 4a2b70e: feat(provider/openai): send item references for provider-executed tool results +- 643711d: feat (provider/openai): provider defined image generation tool support + ## 2.0.30 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index 27f0b97249c3..d5b85844f9cf 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.0.30", + "version": "2.0.31", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 8e3b93d4caa2..2b2aa81df4d1 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/react +## 2.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 2.0.44 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 868720439a41..85df74152a44 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.44", + "version": "2.0.45", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 9b54c44e86b1..c60b5dd6f6eb 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/rsc +## 1.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 1.0.44 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 091a7bc01652..81e48a37d4e9 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.44", + "version": "1.0.45", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 9d115b423f51..276f4a9ba59a 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,15 @@ ### Patch Changes +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + +## 0.0.1 + +### Patch Changes + - ai@5.0.44 ## 0.0.1 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 22ae8b05c3b9..b7ad1adfeca4 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/svelte +## 3.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 3.0.44 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 36d4ce4a0d00..c81ab6e72c83 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.44", + "version": "3.0.45", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 08ef384726ec..b69d676c9ee2 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/vue +## 2.0.45 + +### Patch Changes + +- Updated dependencies [76024fc] +- Updated dependencies [93d8b60] +- Updated dependencies [d8eb31f] + - ai@5.0.45 + ## 2.0.44 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 1fa450638807..62798eab2f68 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.44", + "version": "2.0.45", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 42299a69e70b..3346eb487c8b 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/xai +## 2.0.20 + +### Patch Changes + +- 3a10095: added new xai x live search fields + ## 2.0.19 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 31bf489553c3..fa1064acde21 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.0.19", + "version": "2.0.20", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 1cf857d505ad4c4740d596d03c386561c085de32 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 14:36:35 +0200 Subject: [PATCH 045/121] fix(provider/openai): remove provider-executed tools from chat completions model (#8694) ## Background Discovered during #8691 that provider-execution tools were never supported by the OpenAI chat completions API. ## Summary Remove related code. ## Manual Verification Checked examples to verify that functionality is not supported by OpenAI chat completions. ## Related Issues Discovered during #8691 --- .changeset/famous-walls-tell.md | 5 + .../openai-provider-defined-tools.ts | 39 ------ .../chat/openai-chat-prepare-tools.test.ts | 126 ------------------ .../src/chat/openai-chat-prepare-tools.ts | 40 +----- packages/openai/src/chat/openai-chat-types.ts | 75 +---------- 5 files changed, 12 insertions(+), 273 deletions(-) create mode 100644 .changeset/famous-walls-tell.md delete mode 100644 examples/ai-core/src/generate-text/openai-provider-defined-tools.ts diff --git a/.changeset/famous-walls-tell.md b/.changeset/famous-walls-tell.md new file mode 100644 index 000000000000..0b1a3f08f661 --- /dev/null +++ b/.changeset/famous-walls-tell.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +fix(provider/openai): remove provider-executed tools from chat completions model diff --git a/examples/ai-core/src/generate-text/openai-provider-defined-tools.ts b/examples/ai-core/src/generate-text/openai-provider-defined-tools.ts deleted file mode 100644 index 932e7cdeac86..000000000000 --- a/examples/ai-core/src/generate-text/openai-provider-defined-tools.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { generateText } from 'ai'; -import { openai } from '@ai-sdk/openai'; -import 'dotenv/config'; - -async function main() { - const result = await generateText({ - model: openai('gpt-4o-mini'), - prompt: 'Search for information about TypeScript best practices', - tools: { - web_search: openai.tools.webSearch({ - searchContextSize: 'medium', - userLocation: { - type: 'approximate', - city: 'San Francisco', - region: 'California', - country: 'US', - }, - }), - - file_search: openai.tools.fileSearch({ - maxNumResults: 5, - ranking: { - ranker: 'auto', - }, - }), - }, - }); - - console.log('Result:', result.text); - console.log('Tool calls made:', result.toolCalls.length); - - for (const toolCall of result.toolCalls) { - console.log(`\nTool Call:`); - console.log(`- Tool: ${toolCall.toolName}`); - console.log(`- Input:`, JSON.stringify(toolCall.input, null, 2)); - } -} - -main().catch(console.error); diff --git a/packages/openai/src/chat/openai-chat-prepare-tools.test.ts b/packages/openai/src/chat/openai-chat-prepare-tools.test.ts index ac2b02f6ea38..7ba4d1262890 100644 --- a/packages/openai/src/chat/openai-chat-prepare-tools.test.ts +++ b/packages/openai/src/chat/openai-chat-prepare-tools.test.ts @@ -58,103 +58,6 @@ it('should correctly prepare function tools', () => { expect(result.toolWarnings).toEqual([]); }); -it('should correctly prepare provider-defined-server tools', () => { - const result = prepareChatTools({ - tools: [ - { - type: 'provider-defined', - id: 'openai.file_search', - name: 'file_search', - args: { - vectorStoreIds: ['vs_123'], - maxNumResults: 10, - ranking: { - ranker: 'auto', - }, - }, - }, - { - type: 'provider-defined', - id: 'openai.web_search_preview', - name: 'web_search_preview', - args: { - searchContextSize: 'high', - userLocation: { - type: 'approximate', - city: 'San Francisco', - region: 'CA', - }, - }, - }, - ], - structuredOutputs: false, - strictJsonSchema: false, - }); - - expect(result.tools).toEqual([ - { - type: 'file_search', - vector_store_ids: ['vs_123'], - max_num_results: 10, - ranking_options: { - ranker: 'auto', - }, - }, - { - type: 'web_search_preview', - search_context_size: 'high', - user_location: { - type: 'approximate', - city: 'San Francisco', - region: 'CA', - }, - }, - ]); - expect(result.toolChoice).toBeUndefined(); - expect(result.toolWarnings).toEqual([]); -}); - -it('should correctly prepare file_search with filters', () => { - const result = prepareChatTools({ - tools: [ - { - type: 'provider-defined', - id: 'openai.file_search', - name: 'file_search', - args: { - vectorStoreIds: ['vs_123'], - maxNumResults: 5, - filters: { - type: 'and', - filters: [ - { key: 'author', type: 'eq', value: 'John Doe' }, - { key: 'date', type: 'gte', value: '2023-01-01' }, - ], - }, - }, - }, - ], - structuredOutputs: false, - strictJsonSchema: false, - }); - - expect(result.tools).toEqual([ - { - type: 'file_search', - vector_store_ids: ['vs_123'], - max_num_results: 5, - ranking_options: undefined, - filters: { - type: 'and', - filters: [ - { key: 'author', type: 'eq', value: 'John Doe' }, - { key: 'date', type: 'gte', value: '2023-01-01' }, - ], - }, - }, - ]); -}); - it('should add warnings for unsupported tools', () => { const result = prepareChatTools({ tools: [ @@ -186,35 +89,6 @@ it('should add warnings for unsupported tools', () => { `); }); -it('should add warnings for unsupported provider-defined tools', () => { - const result = prepareChatTools({ - tools: [ - { - type: 'provider-defined', - id: 'some.client_tool', - name: 'clientTool', - args: {}, - } as any, - ], - structuredOutputs: false, - strictJsonSchema: false, - }); - - expect(result.tools).toEqual([]); - expect(result.toolChoice).toBeUndefined(); - expect(result.toolWarnings).toEqual([ - { - type: 'unsupported-tool', - tool: { - type: 'provider-defined', - id: 'some.client_tool', - name: 'clientTool', - args: {}, - }, - }, - ]); -}); - it('should handle tool choice "auto"', () => { const result = prepareChatTools({ tools: [ diff --git a/packages/openai/src/chat/openai-chat-prepare-tools.ts b/packages/openai/src/chat/openai-chat-prepare-tools.ts index 38c630da46c5..e7bd2be7fe95 100644 --- a/packages/openai/src/chat/openai-chat-prepare-tools.ts +++ b/packages/openai/src/chat/openai-chat-prepare-tools.ts @@ -3,9 +3,10 @@ import { LanguageModelV2CallWarning, UnsupportedFunctionalityError, } from '@ai-sdk/provider'; -import { fileSearchArgsSchema } from '../tool/file-search'; -import { webSearchPreviewArgsSchema } from '../tool/web-search-preview'; -import { OpenAIChatToolChoice, OpenAIChatTools } from './openai-chat-types'; +import { + OpenAIChatToolChoice, + OpenAIChatFunctionTool, +} from './openai-chat-types'; export function prepareChatTools({ tools, @@ -18,7 +19,7 @@ export function prepareChatTools({ structuredOutputs: boolean; strictJsonSchema: boolean; }): { - tools?: OpenAIChatTools; + tools?: OpenAIChatFunctionTool[]; toolChoice?: OpenAIChatToolChoice; toolWarnings: Array; } { @@ -31,7 +32,7 @@ export function prepareChatTools({ return { tools: undefined, toolChoice: undefined, toolWarnings }; } - const openaiTools: OpenAIChatTools = []; + const openaiTools: OpenAIChatFunctionTool[] = []; for (const tool of tools) { switch (tool.type) { @@ -46,35 +47,6 @@ export function prepareChatTools({ }, }); break; - case 'provider-defined': - switch (tool.id) { - case 'openai.file_search': { - const args = fileSearchArgsSchema.parse(tool.args); - openaiTools.push({ - type: 'file_search', - vector_store_ids: args.vectorStoreIds, - max_num_results: args.maxNumResults, - ranking_options: args.ranking - ? { ranker: args.ranking.ranker } - : undefined, - filters: args.filters, - }); - break; - } - case 'openai.web_search_preview': { - const args = webSearchPreviewArgsSchema.parse(tool.args); - openaiTools.push({ - type: 'web_search_preview', - search_context_size: args.searchContextSize, - user_location: args.userLocation, - }); - break; - } - default: - toolWarnings.push({ type: 'unsupported-tool', tool }); - break; - } - break; default: toolWarnings.push({ type: 'unsupported-tool', tool }); break; diff --git a/packages/openai/src/chat/openai-chat-types.ts b/packages/openai/src/chat/openai-chat-types.ts index 42c235d4b2bd..896dbda8709a 100644 --- a/packages/openai/src/chat/openai-chat-types.ts +++ b/packages/openai/src/chat/openai-chat-types.ts @@ -1,9 +1,6 @@ import { JSONSchema7 } from '@ai-sdk/provider'; -/** - * OpenAI function tool definition - */ -interface OpenAIChatFunctionTool { +export interface OpenAIChatFunctionTool { type: 'function'; function: { name: string; @@ -13,78 +10,8 @@ interface OpenAIChatFunctionTool { }; } -/** - * OpenAI file search tool definition - */ -interface OpenAIChatFileSearchTool { - type: 'file_search'; - vector_store_ids?: string[]; - max_num_results?: number; - ranking_options?: { - ranker?: 'auto' | 'default-2024-08-21'; - }; - filters?: - | { - key: string; - type: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte'; - value: string | number | boolean; - } - | { - type: 'and' | 'or'; - filters: any[]; - }; -} - -/** - * User location for web search - */ -interface OpenAIChatWebSearchUserLocation { - type?: 'approximate'; - city?: string; - region?: string; - country?: string; - timezone?: string; -} - -/** - * OpenAI web search preview tool definition - */ -interface OpenAIChatWebSearchPreviewTool { - type: 'web_search_preview'; - search_context_size?: 'low' | 'medium' | 'high'; - user_location?: OpenAIChatWebSearchUserLocation; -} - -/** - * OpenAI code interpreter tool definition - */ -interface OpenAIChatCodeInterpreterTool { - type: 'code_interpreter'; - container: { - type: 'auto'; - file_ids: string[]; - }; -} - -/** - * Union type for all OpenAI tools - */ -export type OpenAIChatTool = - | OpenAIChatFunctionTool - | OpenAIChatFileSearchTool - | OpenAIChatWebSearchPreviewTool - | OpenAIChatCodeInterpreterTool; - -/** - * OpenAI tool choice options - */ export type OpenAIChatToolChoice = | 'auto' | 'none' | 'required' | { type: 'function'; function: { name: string } }; - -/** - * OpenAI tools array type - */ -export type OpenAIChatTools = Array; From 94e5c00fa994eef80d7b334fb484631c5e3d61ad Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:47:52 +0100 Subject: [PATCH 046/121] docs: introduce new agents section (#8693) ## Summary This PR introduces a new top level section covering agents. This also documents the new Agent class. ## Tasks - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [ ] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [ ] I have reviewed this pull request (self-review) ## Future Work Reference documentation for Agent class. --- content/docs/03-agents/01-overview.mdx | 216 ++++++++++++ content/docs/03-agents/02-workflows.mdx | 365 +++++++++++++++++++++ content/docs/03-agents/03-agent-class.mdx | 359 ++++++++++++++++++++ content/docs/03-agents/04-loop-control.mdx | 271 +++++++++++++++ content/docs/03-agents/index.mdx | 34 ++ 5 files changed, 1245 insertions(+) create mode 100644 content/docs/03-agents/01-overview.mdx create mode 100644 content/docs/03-agents/02-workflows.mdx create mode 100644 content/docs/03-agents/03-agent-class.mdx create mode 100644 content/docs/03-agents/04-loop-control.mdx create mode 100644 content/docs/03-agents/index.mdx diff --git a/content/docs/03-agents/01-overview.mdx b/content/docs/03-agents/01-overview.mdx new file mode 100644 index 000000000000..d5dc16313c55 --- /dev/null +++ b/content/docs/03-agents/01-overview.mdx @@ -0,0 +1,216 @@ +--- +title: Agents +description: Learn how to build agents with the AI SDK. +--- + +# Agents + +Agents are **large language models (LLMs)** using **tools** in a **loop** to accomplish tasks. + +Each component plays a distinct role: + +- **LLMs** process input (text) and decide what action to take next +- **Tools** extend what the model can do beyond text generation (e.g. reading files, calling APIs, writing to databases) +- **Loop** orchestrates execution through: + - **Context management** - Maintaining conversation history and deciding what the model sees (input) at each step + - **Stopping conditions** - Determining when the loop (task) is complete + +## Building Blocks + +You combine these fundamental components to create increasingly sophisticated systems: + +### Single-Step Generation + +One call to an LLM to get a response. Use this for straightforward tasks like classification or text generation. + +```ts +import { generateText } from 'ai'; + +const result = await generateText({ + model: 'openai/gpt-4o', + prompt: 'Classify this sentiment: "I love this product!"', +}); +``` + +### Tool Usage + +Enhance LLM capabilities through tools that provide access to external systems. Tools can read data to augment context (like fetching files or querying databases) or write data to take actions (like sending emails or updating records). + +```ts +import { generateText, tool } from 'ai'; +import { z } from 'zod'; + +const result = await generateText({ + model: 'openai/gpt-4o', + prompt: 'What is the weather in San Francisco?', + tools: { + weather: tool({ + description: 'Get the weather in a location', + parameters: z.object({ + location: z.string().describe('The location to get the weather for'), + }), + execute: async ({ location }) => ({ + location, + temperature: 72 + Math.floor(Math.random() * 21) - 10, + }), + }), + }, +}); + +console.log(result.toolResults); +``` + +### Multi-Step Tool Usage (Agents) + +For complex problems, an LLM can make multiple tool calls across multiple steps. The model decides the order and number of tool calls based on the task. + +```ts +import { generateText, stepCountIs, tool } from 'ai'; +import { z } from 'zod'; + +const result = await generateText({ + model: 'openai/gpt-4o', + prompt: 'What is the weather in San Francisco in celsius?', + tools: { + weather: tool({ + description: 'Get the weather in a location (in Fahrenheit)', + parameters: z.object({ + location: z.string().describe('The location to get the weather for'), + }), + execute: async ({ location }) => ({ + location, + temperature: 72 + Math.floor(Math.random() * 21) - 10, + }), + }), + convertFahrenheitToCelsius: tool({ + description: 'Convert temperature from Fahrenheit to Celsius', + parameters: z.object({ + temperature: z.number().describe('Temperature in Fahrenheit'), + }), + execute: async ({ temperature }) => { + const celsius = Math.round((temperature - 32) * (5 / 9)); + return { celsius }; + }, + }), + }, + stopWhen: stepCountIs(10), // Stop after maximum 10 steps +}); + +console.log(result.text); // Output: The weather in San Francisco is currently _°C. +``` + +The LLM might: + +1. Call the `weather` tool to get the temperature in Fahrenheit +2. Call the `convertFahrenheitToCelsius` tool to convert it +3. Generate a text response with the converted temperature + +This behavior is flexible - the LLM determines the approach based on its understanding of the task. + +## Implementation Approaches + +The AI SDK provides two approaches to build agents: + +### Agent Class + +Object-oriented abstraction that handles the loop for you. Best when you want to: + +- Reuse agent configurations +- Minimize boilerplate code +- Build consistent agent behaviors + +```ts +import { Experimental_Agent as Agent } from 'ai'; + +const myAgent = new Agent({ + model: 'openai/gpt-4o', + tools: { + // your tools here + }, + stopWhen: stepCountIs(10), // Continue for up to 10 steps +}); + +const result = await myAgent.generate({ + prompt: 'Analyze the latest sales data and create a summary report', +}); + +console.log(result.text); +``` + +[Learn more about the Agent class](/docs/agents/agent-class). + +### Core Functions + +Use `generateText` or `streamText` with tools. Choose between: + +**Built-in Loop** - Let the SDK manage the execution cycle: + +```ts +import { generateText, stepCountIs } from 'ai'; + +const result = await generateText({ + model: 'openai/gpt-4o', + prompt: 'Research machine learning trends and provide key insights', + tools: { + // your tools here + }, + stopWhen: stepCountIs(10), + prepareStep: ({ stepNumber }) => { + // Modify settings between steps + }, + onStepFinish: step => { + // Monitor or save progress + }, +}); +``` + +[Learn more about loop control](/docs/agents/loop-control). + +**Manual Loop** - Full control over execution: + +```ts +import { generateText, ModelMessage } from 'ai'; + +const messages: ModelMessage[] = [{ role: 'user', content: '...' }]; + +let step = 0; +const maxSteps = 10; + +while (step < maxSteps) { + const result = await generateText({ + model: 'openai/gpt-4o', + messages, + tools: { + // your tools here + }, + }); + + messages.push(...result.response.messages); + + if (result.text) { + break; // Stop when model generates text + } + + step++; +} +``` + +## When You Need More Control + +Agents are powerful but non-deterministic. When you need reliable, repeatable outcomes, combine tool calling with standard programming patterns: + +- Conditional statements for explicit branching +- Functions for reusable logic +- Error handling for robustness +- Explicit control flow for predictability + +This approach gives you the benefits of AI while maintaining control over critical paths. + +[Explore workflow patterns](/docs/agents/workflows). + +## Next Steps + +- **[Agent Class](/docs/agents/agent-class)** - Build reusable agents with the object-oriented API +- **[Loop Control](/docs/agents/loop-control)** - Control agent execution with stopWhen and prepareStep +- **[Workflow Patterns](/docs/agents/workflows)** - Build reliable multi-agent systems +- **[Manual Loop Example](/cookbook/node/manual-agent-loop)** - See a complete example of custom loop management diff --git a/content/docs/03-agents/02-workflows.mdx b/content/docs/03-agents/02-workflows.mdx new file mode 100644 index 000000000000..9d8134b54818 --- /dev/null +++ b/content/docs/03-agents/02-workflows.mdx @@ -0,0 +1,365 @@ +--- +title: Workflow Patterns +description: Learn workflow patterns for building reliable agents with the AI SDK. +--- + +# Workflow Patterns + +Combine the building blocks from the [overview](/docs/agents/overview) with these patterns to add structure and reliability to your agents: + +- [Sequential Processing](#sequential-processing-chains) - Steps executed in order +- [Parallel Processing](#parallel-processing) - Independent tasks run simultaneously +- [Evaluation/Feedback Loops](#evaluator-optimizer) - Results checked and improved iteratively +- [Orchestration](#orchestrator-worker) - Coordinating multiple components +- [Routing](#routing) - Directing work based on context + +## Choose Your Approach + +Consider these key factors: + +- **Flexibility vs Control** - How much freedom does the LLM need vs how tightly you must constrain its actions? +- **Error Tolerance** - What are the consequences of mistakes in your use case? +- **Cost Considerations** - More complex systems typically mean more LLM calls and higher costs +- **Maintenance** - Simpler architectures are easier to debug and modify + +**Start with the simplest approach that meets your needs**. Add complexity only when required by: + +1. Breaking down tasks into clear steps +2. Adding tools for specific capabilities +3. Implementing feedback loops for quality control +4. Introducing multiple agents for complex workflows + +Let's look at examples of these patterns in action. + +## Patterns with Examples + +These patterns, adapted from [Anthropic's guide on building effective agents](https://www.anthropic.com/research/building-effective-agents), serve as building blocks you can combine to create comprehensive workflows. Each pattern addresses specific aspects of task execution. Combine them thoughtfully to build reliable solutions for complex problems. + +## Sequential Processing (Chains) + +The simplest workflow pattern executes steps in a predefined order. Each step's output becomes input for the next step, creating a clear chain of operations. Use this pattern for tasks with well-defined sequences, like content generation pipelines or data transformation processes. + +```ts +import { generateText, generateObject } from 'ai'; +import { z } from 'zod'; + +async function generateMarketingCopy(input: string) { + const model = 'openai/gpt-4o'; + + // First step: Generate marketing copy + const { text: copy } = await generateText({ + model, + prompt: `Write persuasive marketing copy for: ${input}. Focus on benefits and emotional appeal.`, + }); + + // Perform quality check on copy + const { object: qualityMetrics } = await generateObject({ + model, + schema: z.object({ + hasCallToAction: z.boolean(), + emotionalAppeal: z.number().min(1).max(10), + clarity: z.number().min(1).max(10), + }), + prompt: `Evaluate this marketing copy for: + 1. Presence of call to action (true/false) + 2. Emotional appeal (1-10) + 3. Clarity (1-10) + + Copy to evaluate: ${copy}`, + }); + + // If quality check fails, regenerate with more specific instructions + if ( + !qualityMetrics.hasCallToAction || + qualityMetrics.emotionalAppeal < 7 || + qualityMetrics.clarity < 7 + ) { + const { text: improvedCopy } = await generateText({ + model, + prompt: `Rewrite this marketing copy with: + ${!qualityMetrics.hasCallToAction ? '- A clear call to action' : ''} + ${qualityMetrics.emotionalAppeal < 7 ? '- Stronger emotional appeal' : ''} + ${qualityMetrics.clarity < 7 ? '- Improved clarity and directness' : ''} + + Original copy: ${copy}`, + }); + return { copy: improvedCopy, qualityMetrics }; + } + + return { copy, qualityMetrics }; +} +``` + +## Routing + +This pattern lets the model decide which path to take through a workflow based on context and intermediate results. The model acts as an intelligent router, directing the flow of execution between different branches of your workflow. Use this when handling varied inputs that require different processing approaches. In the example below, the first LLM call's results determine the second call's model size and system prompt. + +```ts +import { generateObject, generateText } from 'ai'; +import { z } from 'zod'; + +async function handleCustomerQuery(query: string) { + const model = 'openai/gpt-4o'; + + // First step: Classify the query type + const { object: classification } = await generateObject({ + model, + schema: z.object({ + reasoning: z.string(), + type: z.enum(['general', 'refund', 'technical']), + complexity: z.enum(['simple', 'complex']), + }), + prompt: `Classify this customer query: + ${query} + + Determine: + 1. Query type (general, refund, or technical) + 2. Complexity (simple or complex) + 3. Brief reasoning for classification`, + }); + + // Route based on classification + // Set model and system prompt based on query type and complexity + const { text: response } = await generateText({ + model: + classification.complexity === 'simple' + ? 'openai/gpt-4o-mini' + : 'openai/o4-mini', + system: { + general: + 'You are an expert customer service agent handling general inquiries.', + refund: + 'You are a customer service agent specializing in refund requests. Follow company policy and collect necessary information.', + technical: + 'You are a technical support specialist with deep product knowledge. Focus on clear step-by-step troubleshooting.', + }[classification.type], + prompt: query, + }); + + return { response, classification }; +} +``` + +## Parallel Processing + +Break down tasks into independent subtasks that execute simultaneously. This pattern uses parallel execution to improve efficiency while maintaining the benefits of structured workflows. For example, analyze multiple documents or process different aspects of a single input concurrently (like code review). + +```ts +import { generateText, generateObject } from 'ai'; +import { z } from 'zod'; + +// Example: Parallel code review with multiple specialized reviewers +async function parallelCodeReview(code: string) { + const model = 'openai/gpt-4o'; + + // Run parallel reviews + const [securityReview, performanceReview, maintainabilityReview] = + await Promise.all([ + generateObject({ + model, + system: + 'You are an expert in code security. Focus on identifying security vulnerabilities, injection risks, and authentication issues.', + schema: z.object({ + vulnerabilities: z.array(z.string()), + riskLevel: z.enum(['low', 'medium', 'high']), + suggestions: z.array(z.string()), + }), + prompt: `Review this code: + ${code}`, + }), + + generateObject({ + model, + system: + 'You are an expert in code performance. Focus on identifying performance bottlenecks, memory leaks, and optimization opportunities.', + schema: z.object({ + issues: z.array(z.string()), + impact: z.enum(['low', 'medium', 'high']), + optimizations: z.array(z.string()), + }), + prompt: `Review this code: + ${code}`, + }), + + generateObject({ + model, + system: + 'You are an expert in code quality. Focus on code structure, readability, and adherence to best practices.', + schema: z.object({ + concerns: z.array(z.string()), + qualityScore: z.number().min(1).max(10), + recommendations: z.array(z.string()), + }), + prompt: `Review this code: + ${code}`, + }), + ]); + + const reviews = [ + { ...securityReview.object, type: 'security' }, + { ...performanceReview.object, type: 'performance' }, + { ...maintainabilityReview.object, type: 'maintainability' }, + ]; + + // Aggregate results using another model instance + const { text: summary } = await generateText({ + model, + system: 'You are a technical lead summarizing multiple code reviews.', + prompt: `Synthesize these code review results into a concise summary with key actions: + ${JSON.stringify(reviews, null, 2)}`, + }); + + return { reviews, summary }; +} +``` + +## Orchestrator-Worker + +A primary model (orchestrator) coordinates the execution of specialized workers. Each worker optimizes for a specific subtask, while the orchestrator maintains overall context and ensures coherent results. This pattern excels at complex tasks requiring different types of expertise or processing. + +```ts +import { generateObject } from 'ai'; +import { z } from 'zod'; + +async function implementFeature(featureRequest: string) { + // Orchestrator: Plan the implementation + const { object: implementationPlan } = await generateObject({ + model: 'openai/o4-mini', + schema: z.object({ + files: z.array( + z.object({ + purpose: z.string(), + filePath: z.string(), + changeType: z.enum(['create', 'modify', 'delete']), + }), + ), + estimatedComplexity: z.enum(['low', 'medium', 'high']), + }), + system: + 'You are a senior software architect planning feature implementations.', + prompt: `Analyze this feature request and create an implementation plan: + ${featureRequest}`, + }); + + // Workers: Execute the planned changes + const fileChanges = await Promise.all( + implementationPlan.files.map(async file => { + // Each worker is specialized for the type of change + const workerSystemPrompt = { + create: + 'You are an expert at implementing new files following best practices and project patterns.', + modify: + 'You are an expert at modifying existing code while maintaining consistency and avoiding regressions.', + delete: + 'You are an expert at safely removing code while ensuring no breaking changes.', + }[file.changeType]; + + const { object: change } = await generateObject({ + model: 'openai/gpt-4o', + schema: z.object({ + explanation: z.string(), + code: z.string(), + }), + system: workerSystemPrompt, + prompt: `Implement the changes for ${file.filePath} to support: + ${file.purpose} + + Consider the overall feature context: + ${featureRequest}`, + }); + + return { + file, + implementation: change, + }; + }), + ); + + return { + plan: implementationPlan, + changes: fileChanges, + }; +} +``` + +## Evaluator-Optimizer + +Add quality control to workflows with dedicated evaluation steps that assess intermediate results. Based on the evaluation, the workflow proceeds, retries with adjusted parameters, or takes corrective action. This creates robust workflows capable of self-improvement and error recovery. + +```ts +import { generateText, generateObject } from 'ai'; +import { z } from 'zod'; + +async function translateWithFeedback(text: string, targetLanguage: string) { + let currentTranslation = ''; + let iterations = 0; + const MAX_ITERATIONS = 3; + + // Initial translation + const { text: translation } = await generateText({ + model: 'openai/gpt-4o-mini', // use small model for first attempt + system: 'You are an expert literary translator.', + prompt: `Translate this text to ${targetLanguage}, preserving tone and cultural nuances: + ${text}`, + }); + + currentTranslation = translation; + + // Evaluation-optimization loop + while (iterations < MAX_ITERATIONS) { + // Evaluate current translation + const { object: evaluation } = await generateObject({ + model: 'openai/gpt-4o', // use a larger model to evaluate + schema: z.object({ + qualityScore: z.number().min(1).max(10), + preservesTone: z.boolean(), + preservesNuance: z.boolean(), + culturallyAccurate: z.boolean(), + specificIssues: z.array(z.string()), + improvementSuggestions: z.array(z.string()), + }), + system: 'You are an expert in evaluating literary translations.', + prompt: `Evaluate this translation: + + Original: ${text} + Translation: ${currentTranslation} + + Consider: + 1. Overall quality + 2. Preservation of tone + 3. Preservation of nuance + 4. Cultural accuracy`, + }); + + // Check if quality meets threshold + if ( + evaluation.qualityScore >= 8 && + evaluation.preservesTone && + evaluation.preservesNuance && + evaluation.culturallyAccurate + ) { + break; + } + + // Generate improved translation based on feedback + const { text: improvedTranslation } = await generateText({ + model: 'openai/gpt-4o', // use a larger model + system: 'You are an expert literary translator.', + prompt: `Improve this translation based on the following feedback: + ${evaluation.specificIssues.join('\n')} + ${evaluation.improvementSuggestions.join('\n')} + + Original: ${text} + Current Translation: ${currentTranslation}`, + }); + + currentTranslation = improvedTranslation; + iterations++; + } + + return { + finalTranslation: currentTranslation, + iterationsRequired: iterations, + }; +} +``` diff --git a/content/docs/03-agents/03-agent-class.mdx b/content/docs/03-agents/03-agent-class.mdx new file mode 100644 index 000000000000..cbe67bd66a3a --- /dev/null +++ b/content/docs/03-agents/03-agent-class.mdx @@ -0,0 +1,359 @@ +--- +title: Agent Class +description: Learn how to build agents with the Agent class. +--- + +# Agent Class + +The Agent class provides a structured way to encapsulate LLM configuration, tools, and behavior into reusable components. It handles the agent loop for you, allowing the LLM to call tools multiple times in sequence to accomplish complex tasks. Define agents once and use them across your application. + +## Why Use the Agent Class? + +When building AI applications, you often need to: + +- **Reuse configurations** - Same model settings, tools, and prompts across different parts of your application +- **Maintain consistency** - Ensure the same behavior and capabilities throughout your codebase +- **Simplify API routes** - Reduce boilerplate in your endpoints +- **Type safety** - Get full TypeScript support for your agent's tools and outputs + +The Agent class provides a single place to define your agent's behavior. + +## Creating an Agent + +Define an agent by instantiating the Agent class with your desired configuration: + +```ts +import { Experimental_Agent as Agent } from 'ai'; + +const myAgent = new Agent({ + model: 'openai/gpt-4o', + system: 'You are a helpful assistant.', + tools: { + // Your tools here + }, +}); +``` + +## Configuration Options + +The Agent class accepts all the same settings as `generateText` and `streamText`. Configure: + +### Model and System Prompt + +```ts +import { Experimental_Agent as Agent } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + system: 'You are an expert software engineer.', +}); +``` + +### Tools + +Provide tools that the agent can use to accomplish tasks: + +```ts +import { Experimental_Agent as Agent, tool } from 'ai'; +import { z } from 'zod'; + +const codeAgent = new Agent({ + model: 'openai/gpt-4o', + tools: { + runCode: tool({ + description: 'Execute Python code', + inputSchema: z.object({ + code: z.string(), + }), + execute: async ({ code }) => { + // Execute code and return result + return { output: 'Code executed successfully' }; + }, + }), + }, +}); +``` + +### Loop Control + +By default, agents run for only one step. In each step, the model either generates text or calls a tool. If it generates text, the agent completes. If it calls a tool, the AI SDK executes that tool. + +To let agents call multiple tools in sequence, configure `stopWhen` to allow more steps. After each tool execution, the agent triggers a new generation where the model can call another tool or generate text: + +```ts +import { Experimental_Agent as Agent, stepCountIs } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + stopWhen: stepCountIs(10), // Allow up to 10 steps +}); +``` + +Each step represents one generation (which results in either text or a tool call). The loop continues until: + +- The model generates text instead of calling a tool, or +- A stop condition is met + +You can combine multiple conditions: + +```ts +import { Experimental_Agent as Agent, stepCountIs } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + stopWhen: [ + stepCountIs(10), // Maximum 10 steps + yourCustomCondition(), // Custom logic for when to stop + ], +}); +``` + +Learn more about [loop control and stop conditions](/docs/agents/loop-control). + +### Tool Choice + +Control how the agent uses tools: + +```ts +import { Experimental_Agent as Agent } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + tools: { + // your tools here + }, + toolChoice: 'required', // Force tool use + // or toolChoice: 'none' to disable tools + // or toolChoice: 'auto' (default) to let the model decide +}); +``` + +You can also force the use of a specific tool: + +```ts +import { Experimental_Agent as Agent } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + tools: { + weather: weatherTool, + cityAttractions: attractionsTool, + }, + toolChoice: { + type: 'tool', + toolName: 'weather', // Force the weather tool to be used + }, +}); +``` + +### Structured Output + +Define structured output schemas: + +```ts +import { Experimental_Agent as Agent, Output, stepCountIs } from 'ai'; +import { z } from 'zod'; + +const analysisAgent = new Agent({ + model: 'openai/gpt-4o', + experimental_output: Output.object({ + schema: z.object({ + sentiment: z.enum(['positive', 'neutral', 'negative']), + summary: z.string(), + keyPoints: z.array(z.string()), + }), + }), + stopWhen: stepCountIs(10), +}); + +const { experimental_output: output } = await analysisAgent.generate({ + prompt: 'Analyze customer feedback from the last quarter', +}); +``` + +## Define Agent Behavior with System Prompts + +System prompts define your agent's behavior, personality, and constraints. They set the context for all interactions and guide how the agent responds to user queries and uses tools. + +### Basic System Prompts + +Set the agent's role and expertise: + +```ts +const agent = new Agent({ + model: 'openai/gpt-4o', + system: + 'You are an expert data analyst. You provide clear insights from complex data.', +}); +``` + +### Detailed Behavioral Instructions + +Provide specific guidelines for agent behavior: + +```ts +const codeReviewAgent = new Agent({ + model: 'openai/gpt-4o', + system: `You are a senior software engineer conducting code reviews. + + Your approach: + - Focus on security vulnerabilities first + - Identify performance bottlenecks + - Suggest improvements for readability and maintainability + - Be constructive and educational in your feedback + - Always explain why something is an issue and how to fix it`, +}); +``` + +### Constrain Agent Behavior + +Set boundaries and ensure consistent behavior: + +```ts +const customerSupportAgent = new Agent({ + model: 'openai/gpt-4o', + system: `You are a customer support specialist for an e-commerce platform. + + Rules: + - Never make promises about refunds without checking the policy + - Always be empathetic and professional + - If you don't know something, say so and offer to escalate + - Keep responses concise and actionable + - Never share internal company information`, + tools: { + checkOrderStatus, + lookupPolicy, + createTicket, + }, +}); +``` + +### Tool Usage Instructions + +Guide how the agent should use available tools: + +```ts +const researchAgent = new Agent({ + model: 'openai/gpt-4o', + system: `You are a research assistant with access to search and document tools. + + When researching: + 1. Always start with a broad search to understand the topic + 2. Use document analysis for detailed information + 3. Cross-reference multiple sources before drawing conclusions + 4. Cite your sources when presenting information + 5. If information conflicts, present both viewpoints`, + tools: { + webSearch, + analyzeDocument, + extractQuotes, + }, +}); +``` + +### Format and Style Instructions + +Control the output format and communication style: + +```ts +const technicalWriterAgent = new Agent({ + model: 'openai/gpt-4o', + system: `You are a technical documentation writer. + + Writing style: + - Use clear, simple language + - Avoid jargon unless necessary + - Structure information with headers and bullet points + - Include code examples where relevant + - Write in second person ("you" instead of "the user") + + Always format responses in Markdown.`, +}); +``` + +## Using an Agent + +Once defined, you can use your agent in three ways: + +### Generate Text + +Use `generate()` for one-time text generation: + +```ts +const result = await myAgent.generate({ + prompt: 'What is the weather like?', +}); + +console.log(result.text); +``` + +### Stream Text + +Use `stream()` for streaming responses: + +```ts +const stream = myAgent.stream({ + prompt: 'Tell me a story', +}); + +for await (const chunk of stream.textStream) { + console.log(chunk); +} +``` + +### Respond to UI Messages + +Use `respond()` to create API responses for client applications: + +```ts +// In your API route (e.g., app/api/chat/route.ts) +import { validateUIMessages } from 'ai'; + +export async function POST(request: Request) { + const { messages } = await request.json(); + + return myAgent.respond({ + messages: await validateUIMessages({ messages }), + }); +} +``` + +## End-to-end Type Safety + +You can infer types for your Agent's `UIMessage`s: + +```ts +import { + Experimental_Agent as Agent, + Experimental_InferAgentUIMessage as InferAgentUIMessage, +} from 'ai'; + +const myAgent = new Agent({ + // ... configuration +}); + +// Infer the UIMessage type for UI components or persistence +export type MyAgentUIMessage = InferAgentUIMessage; +``` + +Use this type in your client components with `useChat`: + +```tsx filename="components/chat.tsx" +'use client'; + +import { useChat } from '@ai-sdk/react'; +import type { MyAgentUIMessage } from '@/agent/my-agent'; + +export function Chat() { + const { messages } = useChat(); + // Full type safety for your messages and tools +} +``` + +## Next Steps + +Now that you understand the Agent class, you can: + +- Explore [tool patterns](/docs/agents/tools) to add capabilities to your agents +- Learn about [workflow patterns](/docs/agents/workflows) for complex multi-agent systems +- Understand [building agentic systems](/docs/agents/building-agentic-systems) for architectural guidance diff --git a/content/docs/03-agents/04-loop-control.mdx b/content/docs/03-agents/04-loop-control.mdx new file mode 100644 index 000000000000..b1fc99eb74e5 --- /dev/null +++ b/content/docs/03-agents/04-loop-control.mdx @@ -0,0 +1,271 @@ +--- +title: Loop Control +description: Control agent execution with built-in loop management using stopWhen and prepareStep +--- + +# Loop Control + +When building agents with the AI SDK, you can control both the execution flow and the settings at each step of the agent loop. The AI SDK provides built-in loop control through two parameters: `stopWhen` for defining stopping conditions and `prepareStep` for modifying settings (model, tools, messages, and more) between steps. + +Both parameters work with: + +- `generateText` and `streamText` functions from AI SDK Core +- The `Agent` class for object-oriented agent implementations + +## Stop Conditions + +The `stopWhen` parameter controls when to stop the generation when there are tool results in the last step. By default, the stopping condition is `stepCountIs(1)`, which allows only a single step. + +When you provide `stopWhen`, the AI SDK continues generating responses after tool calls until a stopping condition is met. When the condition is an array, the generation stops when any of the conditions are met. + +### Use Built-in Conditions + +The AI SDK provides several built-in stopping conditions: + +```ts +import { generateText, stepCountIs } from 'ai'; + +const result = await generateText({ + model: 'openai/gpt-4o', + tools: { + // your tools + }, + stopWhen: stepCountIs(10), // Stop after 10 steps maximum + prompt: 'Analyze this dataset and create a summary report', +}); +``` + +### Combine Multiple Conditions + +Combine multiple stopping conditions. The loop stops when it meets any condition: + +```ts +import { generateText, stepCountIs, hasToolCall } from 'ai'; + +const result = await generateText({ + model: 'openai/gpt-4o', + tools: { + // your tools + }, + stopWhen: [ + stepCountIs(10), // Maximum 10 steps + hasToolCall('someTool'), // Stop after calling 'someTool' + ], + prompt: 'Research and analyze the topic', +}); +``` + +### Create Custom Conditions + +Build custom stopping conditions for specific requirements: + +```ts +import { generateText, StopCondition, ToolSet } from 'ai'; + +const tools = { + // your tools +} satisfies ToolSet; + +const hasAnswer: StopCondition = ({ steps }) => { + // Stop when the model generates text containing "ANSWER:" + return steps.some(step => step.text?.includes('ANSWER:')) ?? false; +}; + +const result = await generateText({ + model: 'openai/gpt-4o', + tools, + stopWhen: hasAnswer, + prompt: 'Find the answer and respond with "ANSWER: [your answer]"', +}); +``` + +Custom conditions receive step information across all steps: + +```ts +const budgetExceeded: StopCondition = ({ steps }) => { + const totalUsage = steps.reduce( + (acc, step) => ({ + inputTokens: acc.inputTokens + (step.usage?.inputTokens ?? 0), + outputTokens: acc.outputTokens + (step.usage?.outputTokens ?? 0), + }), + { inputTokens: 0, outputTokens: 0 }, + ); + + const costEstimate = + (totalUsage.inputTokens * 0.01 + totalUsage.outputTokens * 0.03) / 1000; + return costEstimate > 0.5; // Stop if cost exceeds $0.50 +}; +``` + +## Prepare Step + +The `prepareStep` callback runs before each step in the loop and defaults to the initial settings if you don't return any changes. Use it to modify settings, manage context, or implement dynamic behavior based on execution history. + +### Dynamic Model Selection + +Switch models based on step requirements: + +```ts +import { generateText } from 'ai'; + +const result = await generateText({ + model: 'openai/gpt-4o-mini', // Default model + tools: { + // your tools + }, + prepareStep: async ({ stepNumber, messages }) => { + // Use a stronger model for complex reasoning after initial steps + if (stepNumber > 2 && messages.length > 10) { + return { + model: 'openai/gpt-4o', + }; + } + // Continue with default settings + return {}; + }, +}); +``` + +### Context Management + +Manage growing conversation history in long-running loops: + +```ts +const result = await generateText({ + model: 'openai/gpt-4o', + tools: { + // your tools + }, + prepareStep: async ({ messages }) => { + // Keep only recent messages to stay within context limits + if (messages.length > 20) { + return { + messages: [ + messages[0], // Keep system message + ...messages.slice(-10), // Keep last 10 messages + ], + }; + } + return {}; + }, +}); +``` + +### Tool Selection + +Control which tools are available at each step: + +```ts +const result = await generateText({ + model: 'openai/gpt-4o', + tools: { + search: searchTool, + analyze: analyzeTool, + summarize: summarizeTool, + }, + prepareStep: async ({ stepNumber, steps }) => { + // Search phase (steps 0-2) + if (stepNumber <= 2) { + return { + activeTools: ['search'], + toolChoice: 'required', + }; + } + + // Analysis phase (steps 3-5) + if (stepNumber <= 5) { + return { + activeTools: ['analyze'], + }; + } + + // Summary phase (step 6+) + return { + activeTools: ['summarize'], + toolChoice: 'required', + }; + }, +}); +``` + +You can also force a specific tool to be used: + +```ts +prepareStep: async ({ stepNumber }) => { + if (stepNumber === 0) { + // Force the search tool to be used first + return { + toolChoice: { type: 'tool', toolName: 'search' }, + }; + } + + if (stepNumber === 5) { + // Force the summarize tool after analysis + return { + toolChoice: { type: 'tool', toolName: 'summarize' }, + }; + } + + return {}; +}; +``` + +### Message Modification + +Transform messages before sending them to the model: + +```ts +const result = await generateText({ + model: 'openai/gpt-4o', + messages, + tools: { + // your tools + }, + prepareStep: async ({ messages, stepNumber }) => { + // Summarize tool results to reduce token usage + const processedMessages = messages.map(msg => { + if (msg.role === 'tool' && msg.content.length > 1000) { + return { + ...msg, + content: summarizeToolResult(msg.content), + }; + } + return msg; + }); + + return { messages: processedMessages }; + }, +}); +``` + +## Access Step Information + +Both `stopWhen` and `prepareStep` receive detailed information about the current execution: + +```ts +prepareStep: async ({ + model, // Current model configuration + stepNumber, // Current step number (0-indexed) + steps, // All previous steps with their results + messages, // Messages to be sent to the model +}) => { + // Access previous tool calls and results + const previousToolCalls = steps.flatMap(step => step.toolCalls); + const previousResults = steps.flatMap(step => step.toolResults); + + // Make decisions based on execution history + if (previousToolCalls.some(call => call.toolName === 'dataAnalysis')) { + return { + toolChoice: { type: 'tool', toolName: 'reportGenerator' }, + }; + } + + return {}; +}, +``` + +## Manual Loop Control + +For scenarios requiring complete control over the agent loop, implement your own loop management instead of using `stopWhen` and `prepareStep`. This approach provides maximum flexibility for complex workflows. + +[Learn more about manual agent loops in the cookbook](/cookbook/node/manual-agent-loop). diff --git a/content/docs/03-agents/index.mdx b/content/docs/03-agents/index.mdx new file mode 100644 index 000000000000..9f33625efc2b --- /dev/null +++ b/content/docs/03-agents/index.mdx @@ -0,0 +1,34 @@ +--- +title: Agents +description: An overview of building agents with the AI SDK. +--- + +# Agents + +The following section show you how to build agents with the AI SDK - systems where large language models (LLMs) use tools in a loop to accomplish tasks. + + From 01de47f61bb05b0042f115806c24b83d30952067 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 18:41:28 +0200 Subject: [PATCH 047/121] feat(provider/openai): rework file search tool (#8691) ## Background The file search tool does not send tool call or result parts. Tests do not use fixtures. The file search tool definition is wrong. ## Summary * update file search tool definition to match args from OpenAI docs * update file search tool inputs and outputs ## Manual Verification - [x] run `examples/ai-core/src/generate-text/openai-file-search-tool.ts` with include - [x] run `examples/ai-core/src/generate-text/openai-file-search-tool.ts` without include - [x] run `examples/ai-core/src/stream-text/openai-file-search-tool.ts` with include - [x] run `examples/ai-core/src/stream-text/openai-file-search-tool.ts` without include - [x] ui tests (incl. `store: false`) ## Related Issues Extracted #8694 Closes #8542 Fixes #7636 Fixes #7740 Fixes #8479 --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- .changeset/good-trees-join.md | 5 + .../01-ai-sdk-providers/03-openai.mdx | 27 +- .../generate-text/openai-file-search-tool.ts | 26 + .../provider-defined-tools-working.ts | 72 - .../stream-text/openai-file-search-tool.ts | 54 + .../src/stream-text/openai-web-search-tool.ts | 9 +- .../app/api/chat-openai-file-search/route.ts | 38 +- .../app/test-openai-file-search/page.tsx | 110 +- .../component/openai-file-search-view.tsx | 42 + .../openai-file-search-tool.1.chunks.txt | 94 ++ .../openai-file-search-tool.1.json | 89 ++ .../openai-file-search-tool.2.chunks.txt | 93 ++ .../openai-file-search-tool.2.json | 112 ++ ...enai-responses-language-model.test.ts.snap | 1206 +++++++++++++++++ .../responses/openai-responses-api-types.ts | 72 +- .../openai-responses-language-model.test.ts | 743 +++------- .../openai-responses-language-model.ts | 179 +-- .../openai-responses-prepare-tools.ts | 7 +- packages/openai/src/tool/file-search.ts | 105 +- 19 files changed, 2187 insertions(+), 896 deletions(-) create mode 100644 .changeset/good-trees-join.md create mode 100644 examples/ai-core/src/generate-text/openai-file-search-tool.ts delete mode 100644 examples/ai-core/src/generate-text/provider-defined-tools-working.ts create mode 100644 examples/ai-core/src/stream-text/openai-file-search-tool.ts create mode 100644 examples/next-openai/component/openai-file-search-view.tsx create mode 100644 packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.chunks.txt create mode 100644 packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.json create mode 100644 packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.chunks.txt create mode 100644 packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.json diff --git a/.changeset/good-trees-join.md b/.changeset/good-trees-join.md new file mode 100644 index 000000000000..bf54a271d1f4 --- /dev/null +++ b/.changeset/good-trees-join.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +feat(provider/openai): rework file search tool diff --git a/content/providers/01-ai-sdk-providers/03-openai.mdx b/content/providers/01-ai-sdk-providers/03-openai.mdx index 61ede827efd8..7a4f7c65b8be 100644 --- a/content/providers/01-ai-sdk-providers/03-openai.mdx +++ b/content/providers/01-ai-sdk-providers/03-openai.mdx @@ -350,23 +350,26 @@ const result = await generateText({ prompt: 'What does the document say about user authentication?', tools: { file_search: openai.tools.fileSearch({ - // optional configuration: - vectorStoreIds: ['vs_123', 'vs_456'], - maxNumResults: 10, + vectorStoreIds: ['vs_123'], + // configuration below is optional: + maxNumResults: 5, + filters: { + key: 'author', + type: 'eq', + value: 'Jane Smith', + }, ranking: { ranker: 'auto', - }, - filters: { - type: 'and', - filters: [ - { key: 'author', type: 'eq', value: 'John Doe' }, - { key: 'date', type: 'gte', value: '2023-01-01' }, - ], + scoreThreshold: 0.5, }, }), }, - // Force file search tool: - toolChoice: { type: 'tool', toolName: 'file_search' }, + providerOptions: { + openai: { + // optional: include results + include: ['file_search_call.results'], + } satisfies OpenAIResponsesProviderOptions, + }, }); ``` diff --git a/examples/ai-core/src/generate-text/openai-file-search-tool.ts b/examples/ai-core/src/generate-text/openai-file-search-tool.ts new file mode 100644 index 000000000000..30151491c7b9 --- /dev/null +++ b/examples/ai-core/src/generate-text/openai-file-search-tool.ts @@ -0,0 +1,26 @@ +import { openai } from '@ai-sdk/openai'; +import { generateText } from 'ai'; +import { run } from '../lib/run'; + +run(async () => { + const result = await generateText({ + model: openai('gpt-5-mini'), + prompt: 'What is an embedding model according to this document?', + tools: { + file_search: openai.tools.fileSearch({ + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + }), + }, + providerOptions: { + openai: { + include: ['file_search_call.results'], + }, + }, + }); + + console.log(JSON.stringify(result.response.body, null, 2)); + console.dir(result.toolCalls, { depth: Infinity }); + console.dir(result.toolResults, { depth: Infinity }); + console.dir(result.sources, { depth: Infinity }); + console.log(result.text); +}); diff --git a/examples/ai-core/src/generate-text/provider-defined-tools-working.ts b/examples/ai-core/src/generate-text/provider-defined-tools-working.ts deleted file mode 100644 index 96ca0b0b6502..000000000000 --- a/examples/ai-core/src/generate-text/provider-defined-tools-working.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { generateText } from 'ai'; -import { anthropic } from '@ai-sdk/anthropic'; -import { openai } from '@ai-sdk/openai'; -import 'dotenv/config'; - -async function main() { - console.log('=== Demonstrating Refactored Provider-Defined Tools ===\n'); - - console.log('1. OpenAI Provider-Defined Tools (Successfully Refactored):'); - const openaiWebSearch = openai.tools.webSearch({ - searchContextSize: 'medium', - userLocation: { - type: 'approximate', - city: 'San Francisco', - region: 'California', - country: 'US', - }, - }); - - const openaiFileSearch = openai.tools.fileSearch({ - maxNumResults: 5, - ranking: { - ranker: 'auto', - }, - }); - - console.log('OpenAI Web Search Tool created successfully'); - console.log('OpenAI File Search Tool created successfully'); - - console.log('\n2. Anthropic Provider-Defined Tools (Working Example):'); - const result = await generateText({ - model: anthropic('claude-3-5-sonnet-20241022'), - prompt: 'Search for current weather in Tokyo', - tools: { - web_search: anthropic.tools.webSearch_20250305({ - maxUses: 2, - allowedDomains: ['weather.com', 'accuweather.com'], - userLocation: { - type: 'approximate', - city: 'Tokyo', - region: 'Tokyo', - country: 'JP', - }, - }), - }, - }); - - console.log('Anthropic Web Search Tool executed successfully'); - console.log('Tool calls made:', result.toolCalls.length); - - for (const toolCall of result.toolCalls) { - console.log(`\nTool Call:`); - console.log(`- Tool: ${toolCall.toolName}`); - console.log(`- Input:`, JSON.stringify(toolCall.input, null, 2)); - } - - console.log('\n=== Refactoring Summary ==='); - console.log( - 'OpenAI tools refactored to use createProviderDefinedToolFactory', - ); - console.log( - 'Anthropic tools refactored to use createProviderDefinedToolFactory', - ); - console.log( - 'All tools now follow consistent pattern like computer_20250124.ts', - ); - console.log('Type safety improved with better TypeScript inference'); - console.log('Anthropic tools working in production'); - console.log('Factory pattern provides cleaner, more maintainable API'); -} - -main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/openai-file-search-tool.ts b/examples/ai-core/src/stream-text/openai-file-search-tool.ts new file mode 100644 index 000000000000..587015f93ef5 --- /dev/null +++ b/examples/ai-core/src/stream-text/openai-file-search-tool.ts @@ -0,0 +1,54 @@ +import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; +import { streamText } from 'ai'; +import { run } from '../lib/run'; + +run(async () => { + const result = streamText({ + model: openai('gpt-5-mini'), + prompt: 'What is an embedding model according to this document?', + tools: { + file_search: openai.tools.fileSearch({ + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + }), + }, + providerOptions: { + openai: { + include: ['file_search_call.results'], + } satisfies OpenAIResponsesProviderOptions, + }, + }); + + for await (const chunk of result.fullStream) { + switch (chunk.type) { + case 'text-delta': { + process.stdout.write(chunk.text); + break; + } + + case 'tool-call': { + console.log( + `\x1b[32m\x1b[1mTool call:\x1b[22m ${JSON.stringify(chunk, null, 2)}\x1b[0m`, + ); + break; + } + + case 'tool-result': { + console.log( + `\x1b[32m\x1b[1mTool result:\x1b[22m ${JSON.stringify(chunk, null, 2)}\x1b[0m`, + ); + break; + } + + case 'source': { + process.stdout.write( + `\n\n\x1b[36mSource: ${chunk.title} (${JSON.stringify(chunk)})\x1b[0m\n\n`, + ); + break; + } + + case 'error': + console.error('Error:', chunk.error); + break; + } + } +}); diff --git a/examples/ai-core/src/stream-text/openai-web-search-tool.ts b/examples/ai-core/src/stream-text/openai-web-search-tool.ts index ecaa82c908d3..0133626b17c9 100644 --- a/examples/ai-core/src/stream-text/openai-web-search-tool.ts +++ b/examples/ai-core/src/stream-text/openai-web-search-tool.ts @@ -4,7 +4,7 @@ import { run } from '../lib/run'; run(async () => { const result = streamText({ - model: openai.responses('gpt-5-mini'), + model: openai('gpt-5-mini'), prompt: 'What happened in tech news today?', tools: { web_search: openai.tools.webSearch({ @@ -43,13 +43,6 @@ run(async () => { break; } - case 'finish': { - console.log('\n\nFINISH'); - console.log('Finish reason:', chunk.finishReason); - console.log('Total Usage:', chunk.totalUsage); - break; - } - case 'error': console.error('Error:', chunk.error); break; diff --git a/examples/next-openai/app/api/chat-openai-file-search/route.ts b/examples/next-openai/app/api/chat-openai-file-search/route.ts index 5fe5d3f2c5f0..23dd1c5ea9db 100644 --- a/examples/next-openai/app/api/chat-openai-file-search/route.ts +++ b/examples/next-openai/app/api/chat-openai-file-search/route.ts @@ -1,38 +1,44 @@ -import { openai } from '@ai-sdk/openai'; +import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; import { convertToModelMessages, - InferUITool, + InferUITools, streamText, + ToolSet, UIDataTypes, UIMessage, + validateUIMessages, } from 'ai'; export const maxDuration = 30; +const tools = { + file_search: openai.tools.fileSearch({ + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + }), +} satisfies ToolSet; + export type OpenAIFileSearchMessage = UIMessage< never, UIDataTypes, - { - file_search: InferUITool>; - } + InferUITools >; export async function POST(req: Request) { const { messages } = await req.json(); + const uiMessages = await validateUIMessages({ messages }); const result = streamText({ - model: openai.responses('gpt-4o-mini'), - tools: { - file_search: openai.tools.fileSearch({ - maxNumResults: 10, - ranking: { - ranker: 'auto', - }, - // vectorStoreIds: ['vs_123'], // optional: specify vector store IDs - // filters: { key: 'category', type: 'eq', value: 'technical' }, // optional: filter results - }), + model: openai('gpt-5-nano'), + tools, + messages: convertToModelMessages(uiMessages), + onStepFinish: ({ request }) => { + console.log(JSON.stringify(request.body, null, 2)); + }, + providerOptions: { + openai: { + include: ['file_search_call.results'], + } satisfies OpenAIResponsesProviderOptions, }, - messages: convertToModelMessages(messages), }); return result.toUIMessageStreamResponse({ diff --git a/examples/next-openai/app/test-openai-file-search/page.tsx b/examples/next-openai/app/test-openai-file-search/page.tsx index 266deec05497..777b67d1f28d 100644 --- a/examples/next-openai/app/test-openai-file-search/page.tsx +++ b/examples/next-openai/app/test-openai-file-search/page.tsx @@ -1,116 +1,36 @@ 'use client'; +import ChatInput from '@/component/chat-input'; +import FileSearchView from '@/component/openai-file-search-view'; import { useChat } from '@ai-sdk/react'; import { DefaultChatTransport } from 'ai'; -import ChatInput from '@/component/chat-input'; -import { OpenAIFileSearchMessage } from '@/app/api/chat-openai-file-search/route'; +import { OpenAIFileSearchMessage } from '../api/chat-openai-file-search/route'; export default function TestOpenAIFileSearch() { - const { error, status, sendMessage, messages, regenerate, stop } = - useChat({ - transport: new DefaultChatTransport({ - api: '/api/chat-openai-file-search', - }), - }); + const { status, sendMessage, messages } = useChat({ + transport: new DefaultChatTransport({ + api: '/api/chat-openai-file-search', + }), + }); return ( -
-

- OpenAI File Search Block-Based Streaming Test -

+
+

OpenAI File Search Test

{messages.map(message => (
{message.role === 'user' ? 'User: ' : 'AI: '} {message.parts.map((part, index) => { - if (part.type === 'text') { - return
{part.text}
; - } - - if (part.type === 'tool-file_search') { - if (part.state === 'input-available') { - return ( -
-                    {JSON.stringify(part.input, null, 2)}
-                  
- ); - } - if (part.state === 'output-available') { - return ( -
-                    {JSON.stringify(part.input, null, 2)}
-                    {`\n\nDONE - File search completed`}
-                  
- ); - } + switch (part.type) { + case 'text': + return
{part.text}
; + case 'tool-file_search': + return ; } - - if (part.type === 'source-document') { - return ( - - [ - - {part.title || part.filename || 'Document'} - - ] - - ); - } - - if (part.type === 'source-url') { - return ( - - [ - - {part.title ?? new URL(part.url).hostname} - - ] - - ); - } - - return null; })}
))} - {(status === 'submitted' || status === 'streaming') && ( -
- {status === 'submitted' &&
Loading...
} - -
- )} - - {error && ( -
-
An error occurred.
- -
- )} - sendMessage({ text })} />
); diff --git a/examples/next-openai/component/openai-file-search-view.tsx b/examples/next-openai/component/openai-file-search-view.tsx new file mode 100644 index 000000000000..b27e34c5d0f9 --- /dev/null +++ b/examples/next-openai/component/openai-file-search-view.tsx @@ -0,0 +1,42 @@ +import { openai } from '@ai-sdk/openai'; +import { UIToolInvocation } from 'ai'; + +export default function FileSearchView({ + invocation, +}: { + invocation: UIToolInvocation>; +}) { + switch (invocation.state) { + case 'input-available': + return ( +
+ Searching... +
+ ); + case 'output-available': + return ( +
+
+ Queries: +
    + {invocation.output.queries.map((query, index) => ( +
  • - {query}
  • + ))} +
+
+
+ Results: +
+ {invocation.output.results?.map((result, index) => ( +
+
+                    {JSON.stringify(result, null, 2)}
+                  
+
+ ))} +
+
+
+ ); + } +} diff --git a/packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.chunks.txt b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.chunks.txt new file mode 100644 index 000000000000..914a434eb071 --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.chunks.txt @@ -0,0 +1,94 @@ +{"type":"response.created","sequence_number":0,"response":{"id":"resp_0459517ad68504ad0068cabfba22b88192836339640e9a765a","object":"response","created_at":1758117818,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"file_search","filters":null,"max_num_results":20,"ranking_options":{"ranker":"auto","score_threshold":0},"vector_store_ids":["vs_68caad8bd5d88191ab766cf043d89a18"]}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0459517ad68504ad0068cabfba22b88192836339640e9a765a","object":"response","created_at":1758117818,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"file_search","filters":null,"max_num_results":20,"ranking_options":{"ranker":"auto","score_threshold":0},"vector_store_ids":["vs_68caad8bd5d88191ab766cf043d89a18"]}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_0459517ad68504ad0068cabfba951881929654a05214361b35","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_0459517ad68504ad0068cabfba951881929654a05214361b35","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a","type":"file_search_call","status":"in_progress","queries":[],"results":null}} +{"type":"response.file_search_call.in_progress","sequence_number":5,"output_index":1,"item_id":"fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a"} +{"type":"response.file_search_call.searching","sequence_number":6,"output_index":1,"item_id":"fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a"} +{"type":"response.file_search_call.completed","sequence_number":7,"output_index":1,"item_id":"fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a"} +{"type":"response.output_item.done","sequence_number":8,"output_index":1,"item":{"id":"fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a","type":"file_search_call","status":"completed","queries":["What is an embedding model according to this document?","What is an embedding model defined as in the document?","definition of embedding model"],"results":null}} +{"type":"response.output_item.added","sequence_number":9,"output_index":2,"item":{"id":"rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":10,"output_index":2,"item":{"id":"rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":11,"output_index":3,"item":{"id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","type":"message","status":"in_progress","content":[],"role":"assistant"}} +{"type":"response.content_part.added","sequence_number":12,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} +{"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":"According","logprobs":[],"obfuscation":"liJu2gE"} +{"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" to","logprobs":[],"obfuscation":"5HNu0x2oBP4DS"} +{"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" the","logprobs":[],"obfuscation":"oMCnjSTGpdPE"} +{"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" document","logprobs":[],"obfuscation":"NiZmPdD"} +{"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":",","logprobs":[],"obfuscation":"vlgD14WDda5lNTa"} +{"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" an","logprobs":[],"obfuscation":"ubOMhz6bqdOfs"} +{"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" embedding","logprobs":[],"obfuscation":"6OHQBe"} +{"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" model","logprobs":[],"obfuscation":"wE2FfjpXAl"} +{"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" converts","logprobs":[],"obfuscation":"cdIHT2o"} +{"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" complex","logprobs":[],"obfuscation":"0LIh8ijL"} +{"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" data","logprobs":[],"obfuscation":"XDDB8MMj7dQ"} +{"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"xrOoDo1pxe8Sih"} +{"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":"e","logprobs":[],"obfuscation":"YrjNY3GNWvBvvtA"} +{"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":".g","logprobs":[],"obfuscation":"FfWwJ3WQRyPMOI"} +{"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":".,","logprobs":[],"obfuscation":"52FV9X2Y5LfzVW"} +{"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" words","logprobs":[],"obfuscation":"Qu3QkUBEwy"} +{"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"Lb2zYunjo6tJp"} +{"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" images","logprobs":[],"obfuscation":"T0I6C2Ji0"} +{"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":")","logprobs":[],"obfuscation":"hLXFmqQJOpK7lmV"} +{"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" into","logprobs":[],"obfuscation":"shSSEWk9ZhS"} +{"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"aBFr0xTdklDdiA"} +{"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" dense","logprobs":[],"obfuscation":"YfRRLmWPET"} +{"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" vector","logprobs":[],"obfuscation":"FvaquGcUw"} +{"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" —","logprobs":[],"obfuscation":"8PuGQrs29oeDLj"} +{"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"gJpFvi1LcxcOtE"} +{"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" list","logprobs":[],"obfuscation":"xwPT69uDxS2"} +{"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"vEKNu3upEN6T6"} +{"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" numbers","logprobs":[],"obfuscation":"YY7mOFEn"} +{"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" —","logprobs":[],"obfuscation":"4UBtB3i3LbiWrJ"} +{"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" called","logprobs":[],"obfuscation":"cnjAeV2A0"} +{"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" an","logprobs":[],"obfuscation":"COksnLu2vES9P"} +{"type":"response.output_text.delta","sequence_number":44,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" embedding","logprobs":[],"obfuscation":"w96Cn5"} +{"type":"response.output_text.delta","sequence_number":45,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"1UseJlZiemBSPAg"} +{"type":"response.output_text.annotation.added","sequence_number":46,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"annotation_index":0,"annotation":{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":154}} +{"type":"response.output_text.delta","sequence_number":47,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":".","logprobs":[],"obfuscation":"8aFRlmffIqtlfCt"} +{"type":"response.output_text.delta","sequence_number":48,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" Unlike","logprobs":[],"obfuscation":"xUqTw4yKa"} +{"type":"response.output_text.delta","sequence_number":49,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" gener","logprobs":[],"obfuscation":"NsFTmfGbff"} +{"type":"response.output_text.delta","sequence_number":50,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":"ative","logprobs":[],"obfuscation":"qBiTdJa2gyP"} +{"type":"response.output_text.delta","sequence_number":51,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" models","logprobs":[],"obfuscation":"PSKt3fxkM"} +{"type":"response.output_text.delta","sequence_number":52,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":",","logprobs":[],"obfuscation":"8e8Za1VVyteB4ds"} +{"type":"response.output_text.delta","sequence_number":53,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" embedding","logprobs":[],"obfuscation":"Gs3cTl"} +{"type":"response.output_text.delta","sequence_number":54,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" models","logprobs":[],"obfuscation":"xrC7jkFgt"} +{"type":"response.output_text.delta","sequence_number":55,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" do","logprobs":[],"obfuscation":"R7RQOJ17j1cpc"} +{"type":"response.output_text.delta","sequence_number":56,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" not","logprobs":[],"obfuscation":"HLUy8me4lqhJ"} +{"type":"response.output_text.delta","sequence_number":57,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" generate","logprobs":[],"obfuscation":"nVQusCL"} +{"type":"response.output_text.delta","sequence_number":58,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" new","logprobs":[],"obfuscation":"8p6C49tSUygH"} +{"type":"response.output_text.delta","sequence_number":59,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" text","logprobs":[],"obfuscation":"NAiFjEoDpi3"} +{"type":"response.output_text.delta","sequence_number":60,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"exp5SVQ1bWj35"} +{"type":"response.output_text.delta","sequence_number":61,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" data","logprobs":[],"obfuscation":"mpWYgcEeCJG"} +{"type":"response.output_text.delta","sequence_number":62,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":";","logprobs":[],"obfuscation":"ugjrVmPsBQ0sBVM"} +{"type":"response.output_text.delta","sequence_number":63,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" instead","logprobs":[],"obfuscation":"5TuCbJBY"} +{"type":"response.output_text.delta","sequence_number":64,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" they","logprobs":[],"obfuscation":"7GfAc92ZRM0"} +{"type":"response.output_text.delta","sequence_number":65,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" produce","logprobs":[],"obfuscation":"LW1cSi08"} +{"type":"response.output_text.delta","sequence_number":66,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" vector","logprobs":[],"obfuscation":"vQvkU1Q0g"} +{"type":"response.output_text.delta","sequence_number":67,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" representations","logprobs":[],"obfuscation":""} +{"type":"response.output_text.delta","sequence_number":68,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" that","logprobs":[],"obfuscation":"H6ufQbaSbhr"} +{"type":"response.output_text.delta","sequence_number":69,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" capture","logprobs":[],"obfuscation":"G9rJM2Kb"} +{"type":"response.output_text.delta","sequence_number":70,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" semantic","logprobs":[],"obfuscation":"0C6xQkm"} +{"type":"response.output_text.delta","sequence_number":71,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"gob8I5gbSO5U"} +{"type":"response.output_text.delta","sequence_number":72,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" synt","logprobs":[],"obfuscation":"U3SbSG7fMxc"} +{"type":"response.output_text.delta","sequence_number":73,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":"actic","logprobs":[],"obfuscation":"W4sXaF0Eyf7"} +{"type":"response.output_text.delta","sequence_number":74,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" relationships","logprobs":[],"obfuscation":"1g"} +{"type":"response.output_text.delta","sequence_number":75,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"T8VvgtUNIhwm"} +{"type":"response.output_text.delta","sequence_number":76,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" can","logprobs":[],"obfuscation":"YlEDrBvI3rGk"} +{"type":"response.output_text.delta","sequence_number":77,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" be","logprobs":[],"obfuscation":"d2YAlk8o41VBn"} +{"type":"response.output_text.delta","sequence_number":78,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" used","logprobs":[],"obfuscation":"h4uUBaMut0Y"} +{"type":"response.output_text.delta","sequence_number":79,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" as","logprobs":[],"obfuscation":"Cu4PJZ54whk2T"} +{"type":"response.output_text.delta","sequence_number":80,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" input","logprobs":[],"obfuscation":"D2Py3Lykxm"} +{"type":"response.output_text.delta","sequence_number":81,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" for","logprobs":[],"obfuscation":"db4mrk4WThq1"} +{"type":"response.output_text.delta","sequence_number":82,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" other","logprobs":[],"obfuscation":"Yq7VkDPJKu"} +{"type":"response.output_text.delta","sequence_number":83,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" models","logprobs":[],"obfuscation":"yhKaHEHFm"} +{"type":"response.output_text.delta","sequence_number":84,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"JXNpZ1gnAGSeJ"} +{"type":"response.output_text.delta","sequence_number":85,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" NLP","logprobs":[],"obfuscation":"XH6YlZrmr3mA"} +{"type":"response.output_text.delta","sequence_number":86,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" tasks","logprobs":[],"obfuscation":"Jotz6jyyyq"} +{"type":"response.output_text.delta","sequence_number":87,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"PbwW8c892lezp7M"} +{"type":"response.output_text.annotation.added","sequence_number":88,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"annotation_index":1,"annotation":{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":382}} +{"type":"response.output_text.delta","sequence_number":89,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"delta":".","logprobs":[],"obfuscation":"brJFUhKp1ov7xs6"} +{"type":"response.output_text.done","sequence_number":90,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"text":"According to the document, an embedding model converts complex data (e.g., words or images) into a dense vector — a list of numbers — called an embedding . Unlike generative models, embedding models do not generate new text or data; instead they produce vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks .","logprobs":[]} +{"type":"response.content_part.done","sequence_number":91,"item_id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","output_index":3,"content_index":0,"part":{"type":"output_text","annotations":[{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":154},{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":382}],"logprobs":[],"text":"According to the document, an embedding model converts complex data (e.g., words or images) into a dense vector — a list of numbers — called an embedding . Unlike generative models, embedding models do not generate new text or data; instead they produce vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks ."}} +{"type":"response.output_item.done","sequence_number":92,"output_index":3,"item":{"id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":154},{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":382}],"logprobs":[],"text":"According to the document, an embedding model converts complex data (e.g., words or images) into a dense vector — a list of numbers — called an embedding . Unlike generative models, embedding models do not generate new text or data; instead they produce vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks ."}],"role":"assistant"}} +{"type":"response.completed","sequence_number":93,"response":{"id":"resp_0459517ad68504ad0068cabfba22b88192836339640e9a765a","object":"response","created_at":1758117818,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini-2025-08-07","output":[{"id":"rs_0459517ad68504ad0068cabfba951881929654a05214361b35","type":"reasoning","summary":[]},{"id":"fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a","type":"file_search_call","status":"completed","queries":["What is an embedding model according to this document?","What is an embedding model defined as in the document?","definition of embedding model"],"results":null},{"id":"rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9","type":"reasoning","summary":[]},{"id":"msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":154},{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":382}],"logprobs":[],"text":"According to the document, an embedding model converts complex data (e.g., words or images) into a dense vector — a list of numbers — called an embedding . Unlike generative models, embedding models do not generate new text or data; instead they produce vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks ."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"file_search","filters":null,"max_num_results":20,"ranking_options":{"ranker":"auto","score_threshold":0},"vector_store_ids":["vs_68caad8bd5d88191ab766cf043d89a18"]}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":{"input_tokens":3737,"input_tokens_details":{"cached_tokens":2304},"output_tokens":621,"output_tokens_details":{"reasoning_tokens":512},"total_tokens":4358},"user":null,"metadata":{}}} \ No newline at end of file diff --git a/packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.json b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.json new file mode 100644 index 000000000000..26d4b7addb1e --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.1.json @@ -0,0 +1,89 @@ +{ + "id": "resp_0a098396a8feca410068caae39e7648196b346e99fa8ec494c", + "object": "response", + "created_at": 1758113338, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-5-mini-2025-08-07", + "output": [ + { + "id": "rs_0a098396a8feca410068caae3b47208196957fe59419daad70", + "type": "reasoning", + "summary": [] + }, + { + "id": "fs_0a098396a8feca410068caae3cab5c8196a54fd00498464e62", + "type": "file_search_call", + "status": "completed", + "queries": [ + "What is an embedding model according to this document?", + "What is an embedding model?", + "definition of embedding model in the document", + "embedding model description" + ], + "results": null + }, + { + "id": "rs_0a098396a8feca410068caae3e21a081968e7ac588401c4a6a", + "type": "reasoning", + "summary": [] + }, + { + "id": "msg_0a098396a8feca410068caae457c508196b2fcd079d1d3ec74", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [ + { + "type": "file_citation", + "file_id": "file-Ebzhf8H4DPGPr9pUhr7n7v", + "filename": "ai.pdf", + "index": 438 + } + ], + "logprobs": [], + "text": "According to the document, an embedding model is used to convert complex data (like words or images) into a dense vector (a list of numbers) representation called an embedding, which captures semantic and syntactic relationships. Unlike generative models, embedding models do not generate new text or data; instead, they provide these vector representations to be used as input for other models or other natural language processing tasks ." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { "effort": "medium", "summary": null }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1, + "text": { "format": { "type": "text" }, "verbosity": "medium" }, + "tool_choice": "auto", + "tools": [ + { + "type": "file_search", + "filters": null, + "max_num_results": 20, + "ranking_options": { "ranker": "auto", "score_threshold": 0 }, + "vector_store_ids": ["vs_68caad8bd5d88191ab766cf043d89a18"] + } + ], + "top_logprobs": 0, + "top_p": 1, + "truncation": "disabled", + "usage": { + "input_tokens": 3700, + "input_tokens_details": { "cached_tokens": 2560 }, + "output_tokens": 741, + "output_tokens_details": { "reasoning_tokens": 640 }, + "total_tokens": 4441 + }, + "user": null, + "metadata": {} +} diff --git a/packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.chunks.txt b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.chunks.txt new file mode 100644 index 000000000000..0d5c1ab4f3c4 --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.chunks.txt @@ -0,0 +1,93 @@ +{"type":"response.created","sequence_number":0,"response":{"id":"resp_06456cb9918b63780068cacd710b0881a1b00b5fca56e7100b","object":"response","created_at":1758121329,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"file_search","filters":null,"max_num_results":20,"ranking_options":{"ranker":"auto","score_threshold":0},"vector_store_ids":["vs_68caad8bd5d88191ab766cf043d89a18"]}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_06456cb9918b63780068cacd710b0881a1b00b5fca56e7100b","object":"response","created_at":1758121329,"status":"in_progress","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini-2025-08-07","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"file_search","filters":null,"max_num_results":20,"ranking_options":{"ranker":"auto","score_threshold":0},"vector_store_ids":["vs_68caad8bd5d88191ab766cf043d89a18"]}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} +{"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"id":"rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"id":"rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":4,"output_index":1,"item":{"id":"fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6","type":"file_search_call","status":"in_progress","queries":[],"results":null}} +{"type":"response.file_search_call.in_progress","sequence_number":5,"output_index":1,"item_id":"fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6"} +{"type":"response.file_search_call.searching","sequence_number":6,"output_index":1,"item_id":"fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6"} +{"type":"response.file_search_call.completed","sequence_number":7,"output_index":1,"item_id":"fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6"} +{"type":"response.output_item.done","sequence_number":8,"output_index":1,"item":{"id":"fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6","type":"file_search_call","status":"completed","queries":["What is an embedding model according to this document?","What is an embedding model definition in this document?","How does the document define an embedding model?"],"results":[{"attributes":{},"file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","score":0.9312,"text":"AI 1\n\nAI\nGenerative artificial intelligence refers to models that predict and generate \nvarious types of outputs (such as text, images, or audio) based on whatʼs \nstatistically likely, pulling from patterns theyʼve learned from their training data. \nFor example:\n\nGiven a photo, a generative model can generate a caption.\n\nGiven an audio file, a generative model can generate a transcription.\n\nGiven a text description, a generative model can generate an image.\n\nA large language model LLM is a subset of generative models focused \nprimarily on text. An LLM takes a sequence of words as input and aims to \npredict the most likely sequence to follow. It assigns probabilities to potential \nnext sequences and then selects one. The model continues to generate \nsequences until it meets a specified stopping criterion.\n\nLLMs learn by training on massive collections of written text, which means they \nwill be better suited to some use cases than others. For example, a model \ntrained on GitHub data would understand the probabilities of sequences in \nsource code particularly well.\n\nHowever, it's crucial to understand LLMs' limitations. When asked about less \nknown or absent information, like the birthday of a personal relative, LLMs \nmight \"hallucinate\" or make up information. It's essential to consider how well-\nrepresented the information you need is in the model.\n\nAn embedding model is used to convert complex data (like words or images) \ninto a dense vector (a list of numbers) representation, known as an embedding. \nUnlike generative models, embedding models do not generate new text or data. \nInstead, they provide representations of semantic and synactic relationships \nbetween entities that can be used as input for other models or other natural \nlanguage processing tasks.\n\nIn the next section, you will learn about the difference between models \nproviders and models, and which ones are available in the AI SDK."}]}} +{"type":"response.output_item.added","sequence_number":9,"output_index":2,"item":{"id":"rs_06456cb9918b63780068cacd7663c481a191dd84333d842728","type":"reasoning","summary":[]}} +{"type":"response.output_item.done","sequence_number":10,"output_index":2,"item":{"id":"rs_06456cb9918b63780068cacd7663c481a191dd84333d842728","type":"reasoning","summary":[]}} +{"type":"response.output_item.added","sequence_number":11,"output_index":3,"item":{"id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","type":"message","status":"in_progress","content":[],"role":"assistant"}} +{"type":"response.content_part.added","sequence_number":12,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"part":{"type":"output_text","annotations":[],"logprobs":[],"text":""}} +{"type":"response.output_text.delta","sequence_number":13,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":"The","logprobs":[],"obfuscation":"yXJ7d69Qa0Xhg"} +{"type":"response.output_text.delta","sequence_number":14,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" document","logprobs":[],"obfuscation":"uRM0Xte"} +{"type":"response.output_text.delta","sequence_number":15,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" defines","logprobs":[],"obfuscation":"gqfYU8Gk"} +{"type":"response.output_text.delta","sequence_number":16,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" an","logprobs":[],"obfuscation":"sIOtpEg2ePgh9"} +{"type":"response.output_text.delta","sequence_number":17,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" embedding","logprobs":[],"obfuscation":"BL6ayz"} +{"type":"response.output_text.delta","sequence_number":18,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" model","logprobs":[],"obfuscation":"cOZxeAdcof"} +{"type":"response.output_text.delta","sequence_number":19,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" as","logprobs":[],"obfuscation":"33u4lzP2RCmBA"} +{"type":"response.output_text.delta","sequence_number":20,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"tAdbvxKxU9Jt34"} +{"type":"response.output_text.delta","sequence_number":21,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" tool","logprobs":[],"obfuscation":"ToTXHZ3M1lZ"} +{"type":"response.output_text.delta","sequence_number":22,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" that","logprobs":[],"obfuscation":"yO9zzzFiEnB"} +{"type":"response.output_text.delta","sequence_number":23,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" converts","logprobs":[],"obfuscation":"NIS0KqN"} +{"type":"response.output_text.delta","sequence_number":24,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" complex","logprobs":[],"obfuscation":"8eyFBFah"} +{"type":"response.output_text.delta","sequence_number":25,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" data","logprobs":[],"obfuscation":"MXLSAE7Hciw"} +{"type":"response.output_text.delta","sequence_number":26,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"KujSuxv3mVdafv"} +{"type":"response.output_text.delta","sequence_number":27,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":"e","logprobs":[],"obfuscation":"WQiFog0AB5WgHEX"} +{"type":"response.output_text.delta","sequence_number":28,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":".g","logprobs":[],"obfuscation":"EcWbFs0sP9xTCK"} +{"type":"response.output_text.delta","sequence_number":29,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":".,","logprobs":[],"obfuscation":"hyYzGk2OvxhNnC"} +{"type":"response.output_text.delta","sequence_number":30,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" words","logprobs":[],"obfuscation":"wMKwLlAkhz"} +{"type":"response.output_text.delta","sequence_number":31,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"YCetLlQLYpljF"} +{"type":"response.output_text.delta","sequence_number":32,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" images","logprobs":[],"obfuscation":"iGIypDuiQ"} +{"type":"response.output_text.delta","sequence_number":33,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":")","logprobs":[],"obfuscation":"rlDCo94jSRrQ0Ku"} +{"type":"response.output_text.delta","sequence_number":34,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" into","logprobs":[],"obfuscation":"hqKnAHBodav"} +{"type":"response.output_text.delta","sequence_number":35,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" a","logprobs":[],"obfuscation":"l7Se5SpBVh2BpH"} +{"type":"response.output_text.delta","sequence_number":36,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" dense","logprobs":[],"obfuscation":"xfttmfQBKD"} +{"type":"response.output_text.delta","sequence_number":37,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" vector","logprobs":[],"obfuscation":"wPnUfyNXf"} +{"type":"response.output_text.delta","sequence_number":38,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" (","logprobs":[],"obfuscation":"5qP6M3c0mgjVkN"} +{"type":"response.output_text.delta","sequence_number":39,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":"a","logprobs":[],"obfuscation":"QaUxc9fnyinuNQ6"} +{"type":"response.output_text.delta","sequence_number":40,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" list","logprobs":[],"obfuscation":"DeEdqnfe944"} +{"type":"response.output_text.delta","sequence_number":41,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" of","logprobs":[],"obfuscation":"Bm7EpLyUCn2AN"} +{"type":"response.output_text.delta","sequence_number":42,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" numbers","logprobs":[],"obfuscation":"IKqcNUbi"} +{"type":"response.output_text.delta","sequence_number":43,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":")","logprobs":[],"obfuscation":"UQTvFE7bChKyFp5"} +{"type":"response.output_text.delta","sequence_number":44,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" called","logprobs":[],"obfuscation":"WTwiUhbHS"} +{"type":"response.output_text.delta","sequence_number":45,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" an","logprobs":[],"obfuscation":"kttPbHSNqmX0y"} +{"type":"response.output_text.delta","sequence_number":46,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" embedding","logprobs":[],"obfuscation":"Moo0yX"} +{"type":"response.output_text.delta","sequence_number":47,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":".","logprobs":[],"obfuscation":"EmvnJ4uA6NZ5ceE"} +{"type":"response.output_text.delta","sequence_number":48,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" Unlike","logprobs":[],"obfuscation":"TIMqttB6l"} +{"type":"response.output_text.delta","sequence_number":49,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" gener","logprobs":[],"obfuscation":"CWGu8UmkPE"} +{"type":"response.output_text.delta","sequence_number":50,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":"ative","logprobs":[],"obfuscation":"fZYGNftnexv"} +{"type":"response.output_text.delta","sequence_number":51,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" models","logprobs":[],"obfuscation":"NhiGZhiO1"} +{"type":"response.output_text.delta","sequence_number":52,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":",","logprobs":[],"obfuscation":"oct7t3SuU2oyXa8"} +{"type":"response.output_text.delta","sequence_number":53,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" embedding","logprobs":[],"obfuscation":"fhrQQu"} +{"type":"response.output_text.delta","sequence_number":54,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" models","logprobs":[],"obfuscation":"newAISHsy"} +{"type":"response.output_text.delta","sequence_number":55,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" don","logprobs":[],"obfuscation":"wgLqz59u8sBH"} +{"type":"response.output_text.delta","sequence_number":56,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":"’t","logprobs":[],"obfuscation":"3apfijLo4kchSy"} +{"type":"response.output_text.delta","sequence_number":57,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" generate","logprobs":[],"obfuscation":"NOB6Rt5"} +{"type":"response.output_text.delta","sequence_number":58,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" new","logprobs":[],"obfuscation":"7PhHJxzKxHAh"} +{"type":"response.output_text.delta","sequence_number":59,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" text","logprobs":[],"obfuscation":"XHE9N4Pci7r"} +{"type":"response.output_text.delta","sequence_number":60,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"EdN3SzRu0FHE1"} +{"type":"response.output_text.delta","sequence_number":61,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" data","logprobs":[],"obfuscation":"F8WJ5dJC1le"} +{"type":"response.output_text.delta","sequence_number":62,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":";","logprobs":[],"obfuscation":"VO2swkknSS59gpy"} +{"type":"response.output_text.delta","sequence_number":63,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" they","logprobs":[],"obfuscation":"0dS8z4W1nya"} +{"type":"response.output_text.delta","sequence_number":64,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" provide","logprobs":[],"obfuscation":"zvMkHWTz"} +{"type":"response.output_text.delta","sequence_number":65,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" vector","logprobs":[],"obfuscation":"eLO2EBfHb"} +{"type":"response.output_text.delta","sequence_number":66,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" representations","logprobs":[],"obfuscation":""} +{"type":"response.output_text.delta","sequence_number":67,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" that","logprobs":[],"obfuscation":"U1OjtYxSGzH"} +{"type":"response.output_text.delta","sequence_number":68,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" capture","logprobs":[],"obfuscation":"1WNFLSPy"} +{"type":"response.output_text.delta","sequence_number":69,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" semantic","logprobs":[],"obfuscation":"W94qMwH"} +{"type":"response.output_text.delta","sequence_number":70,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"yHXnkXLRkRiJ"} +{"type":"response.output_text.delta","sequence_number":71,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" synt","logprobs":[],"obfuscation":"yba7aRbW35i"} +{"type":"response.output_text.delta","sequence_number":72,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":"actic","logprobs":[],"obfuscation":"fBctDzgyXwp"} +{"type":"response.output_text.delta","sequence_number":73,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" relationships","logprobs":[],"obfuscation":"ij"} +{"type":"response.output_text.delta","sequence_number":74,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" and","logprobs":[],"obfuscation":"IkjQHX8UZAqw"} +{"type":"response.output_text.delta","sequence_number":75,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" can","logprobs":[],"obfuscation":"KeWSf6GIB255"} +{"type":"response.output_text.delta","sequence_number":76,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" be","logprobs":[],"obfuscation":"S9FqWtZQIVLyk"} +{"type":"response.output_text.delta","sequence_number":77,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" used","logprobs":[],"obfuscation":"LCbNtpBZ0e9"} +{"type":"response.output_text.delta","sequence_number":78,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" as","logprobs":[],"obfuscation":"wuOZSH4cQ3noT"} +{"type":"response.output_text.delta","sequence_number":79,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" input","logprobs":[],"obfuscation":"1T7tFOMhrM"} +{"type":"response.output_text.delta","sequence_number":80,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" for","logprobs":[],"obfuscation":"BdCcok8fktXY"} +{"type":"response.output_text.delta","sequence_number":81,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" other","logprobs":[],"obfuscation":"0wdxG2uVZP"} +{"type":"response.output_text.delta","sequence_number":82,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" models","logprobs":[],"obfuscation":"RAUycCDJu"} +{"type":"response.output_text.delta","sequence_number":83,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" or","logprobs":[],"obfuscation":"6iPHFYBL95P3E"} +{"type":"response.output_text.delta","sequence_number":84,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" NLP","logprobs":[],"obfuscation":"GBY2kZCP5O8j"} +{"type":"response.output_text.delta","sequence_number":85,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" tasks","logprobs":[],"obfuscation":"gf7oRS9CDZ"} +{"type":"response.output_text.delta","sequence_number":86,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":" ","logprobs":[],"obfuscation":"TojvmgJPmRBgDD4"} +{"type":"response.output_text.annotation.added","sequence_number":87,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"annotation_index":0,"annotation":{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":379}} +{"type":"response.output_text.delta","sequence_number":88,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"delta":".","logprobs":[],"obfuscation":"UccCBPjfZeqM25q"} +{"type":"response.output_text.done","sequence_number":89,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"text":"The document defines an embedding model as a tool that converts complex data (e.g., words or images) into a dense vector (a list of numbers) called an embedding. Unlike generative models, embedding models don’t generate new text or data; they provide vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks .","logprobs":[]} +{"type":"response.content_part.done","sequence_number":90,"item_id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","output_index":3,"content_index":0,"part":{"type":"output_text","annotations":[{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":379}],"logprobs":[],"text":"The document defines an embedding model as a tool that converts complex data (e.g., words or images) into a dense vector (a list of numbers) called an embedding. Unlike generative models, embedding models don’t generate new text or data; they provide vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks ."}} +{"type":"response.output_item.done","sequence_number":91,"output_index":3,"item":{"id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":379}],"logprobs":[],"text":"The document defines an embedding model as a tool that converts complex data (e.g., words or images) into a dense vector (a list of numbers) called an embedding. Unlike generative models, embedding models don’t generate new text or data; they provide vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks ."}],"role":"assistant"}} +{"type":"response.completed","sequence_number":92,"response":{"id":"resp_06456cb9918b63780068cacd710b0881a1b00b5fca56e7100b","object":"response","created_at":1758121329,"status":"completed","background":false,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"gpt-5-mini-2025-08-07","output":[{"id":"rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41","type":"reasoning","summary":[]},{"id":"fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6","type":"file_search_call","status":"completed","queries":["What is an embedding model according to this document?","What is an embedding model definition in this document?","How does the document define an embedding model?"],"results":[{"attributes":{},"file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","score":0.9312,"text":"AI 1\n\nAI\nGenerative artificial intelligence refers to models that predict and generate \nvarious types of outputs (such as text, images, or audio) based on whatʼs \nstatistically likely, pulling from patterns theyʼve learned from their training data. \nFor example:\n\nGiven a photo, a generative model can generate a caption.\n\nGiven an audio file, a generative model can generate a transcription.\n\nGiven a text description, a generative model can generate an image.\n\nA large language model LLM is a subset of generative models focused \nprimarily on text. An LLM takes a sequence of words as input and aims to \npredict the most likely sequence to follow. It assigns probabilities to potential \nnext sequences and then selects one. The model continues to generate \nsequences until it meets a specified stopping criterion.\n\nLLMs learn by training on massive collections of written text, which means they \nwill be better suited to some use cases than others. For example, a model \ntrained on GitHub data would understand the probabilities of sequences in \nsource code particularly well.\n\nHowever, it's crucial to understand LLMs' limitations. When asked about less \nknown or absent information, like the birthday of a personal relative, LLMs \nmight \"hallucinate\" or make up information. It's essential to consider how well-\nrepresented the information you need is in the model.\n\nAn embedding model is used to convert complex data (like words or images) \ninto a dense vector (a list of numbers) representation, known as an embedding. \nUnlike generative models, embedding models do not generate new text or data. \nInstead, they provide representations of semantic and synactic relationships \nbetween entities that can be used as input for other models or other natural \nlanguage processing tasks.\n\nIn the next section, you will learn about the difference between models \nproviders and models, and which ones are available in the AI SDK."}]},{"id":"rs_06456cb9918b63780068cacd7663c481a191dd84333d842728","type":"reasoning","summary":[]},{"id":"msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f","type":"message","status":"completed","content":[{"type":"output_text","annotations":[{"type":"file_citation","file_id":"file-Ebzhf8H4DPGPr9pUhr7n7v","filename":"ai.pdf","index":379}],"logprobs":[],"text":"The document defines an embedding model as a tool that converts complex data (e.g., words or images) into a dense vector (a list of numbers) called an embedding. Unlike generative models, embedding models don’t generate new text or data; they provide vector representations that capture semantic and syntactic relationships and can be used as input for other models or NLP tasks ."}],"role":"assistant"}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","summary":null},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":"auto","tools":[{"type":"file_search","filters":null,"max_num_results":20,"ranking_options":{"ranker":"auto","score_threshold":0},"vector_store_ids":["vs_68caad8bd5d88191ab766cf043d89a18"]}],"top_logprobs":0,"top_p":1,"truncation":"disabled","usage":{"input_tokens":3748,"input_tokens_details":{"cached_tokens":2304},"output_tokens":543,"output_tokens_details":{"reasoning_tokens":448},"total_tokens":4291},"user":null,"metadata":{}}} \ No newline at end of file diff --git a/packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.json b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.json new file mode 100644 index 000000000000..3a28b1fc87be --- /dev/null +++ b/packages/openai/src/responses/__fixtures__/openai-file-search-tool.2.json @@ -0,0 +1,112 @@ +{ + "id": "resp_0365d26c32c64c650068cabb02fea4819495862c2bc58440ad", + "object": "response", + "created_at": 1758116611, + "status": "completed", + "background": false, + "error": null, + "incomplete_details": null, + "instructions": null, + "max_output_tokens": null, + "max_tool_calls": null, + "model": "gpt-5-mini-2025-08-07", + "output": [ + { + "id": "rs_0365d26c32c64c650068cabb03bcc48194bfbd973152bca8f6", + "type": "reasoning", + "summary": [] + }, + { + "id": "fs_0365d26c32c64c650068cabb04aa388194b53c59de50a3951e", + "type": "file_search_call", + "status": "completed", + "queries": [ + "What is an embedding model according to this document?", + "What is an embedding model in the document?", + "definition of embedding model", + "embedding model explanation 'embedding model'" + ], + "results": [ + { + "attributes": {}, + "file_id": "file-Ebzhf8H4DPGPr9pUhr7n7v", + "filename": "ai.pdf", + "score": 0.9311, + "text": "AI 1\n\nAI\nGenerative artificial intelligence refers to models that predict and generate \nvarious types of outputs (such as text, images, or audio) based on whatʼs \nstatistically likely, pulling from patterns theyʼve learned from their training data. \nFor example:\n\nGiven a photo, a generative model can generate a caption.\n\nGiven an audio file, a generative model can generate a transcription.\n\nGiven a text description, a generative model can generate an image.\n\nA large language model LLM is a subset of generative models focused \nprimarily on text. An LLM takes a sequence of words as input and aims to \npredict the most likely sequence to follow. It assigns probabilities to potential \nnext sequences and then selects one. The model continues to generate \nsequences until it meets a specified stopping criterion.\n\nLLMs learn by training on massive collections of written text, which means they \nwill be better suited to some use cases than others. For example, a model \ntrained on GitHub data would understand the probabilities of sequences in \nsource code particularly well.\n\nHowever, it's crucial to understand LLMs' limitations. When asked about less \nknown or absent information, like the birthday of a personal relative, LLMs \nmight \"hallucinate\" or make up information. It's essential to consider how well-\nrepresented the information you need is in the model.\n\nAn embedding model is used to convert complex data (like words or images) \ninto a dense vector (a list of numbers) representation, known as an embedding. \nUnlike generative models, embedding models do not generate new text or data. \nInstead, they provide representations of semantic and synactic relationships \nbetween entities that can be used as input for other models or other natural \nlanguage processing tasks.\n\nIn the next section, you will learn about the difference between models \nproviders and models, and which ones are available in the AI SDK." + } + ] + }, + { + "id": "rs_0365d26c32c64c650068cabb061740819491324d349d0f07ca", + "type": "reasoning", + "summary": [] + }, + { + "id": "msg_0365d26c32c64c650068cabb0e66b081949f66f61dacef39f3", + "type": "message", + "status": "completed", + "content": [ + { + "type": "output_text", + "annotations": [ + { + "type": "file_citation", + "file_id": "file-Ebzhf8H4DPGPr9pUhr7n7v", + "filename": "ai.pdf", + "index": 350 + } + ], + "logprobs": [], + "text": "According to the document, an embedding model converts complex data (like words or images) into a dense vector — a list of numbers — called an embedding. It does not generate new text or data; instead it encodes semantic and syntactic relationships between entities so those vector representations can be used as inputs for other models or NLP tasks ." + } + ], + "role": "assistant" + } + ], + "parallel_tool_calls": true, + "previous_response_id": null, + "prompt_cache_key": null, + "reasoning": { + "effort": "medium", + "summary": null + }, + "safety_identifier": null, + "service_tier": "default", + "store": true, + "temperature": 1, + "text": { + "format": { + "type": "text" + }, + "verbosity": "medium" + }, + "tool_choice": "auto", + "tools": [ + { + "type": "file_search", + "filters": null, + "max_num_results": 20, + "ranking_options": { + "ranker": "auto", + "score_threshold": 0 + }, + "vector_store_ids": ["vs_68caad8bd5d88191ab766cf043d89a18"] + } + ], + "top_logprobs": 0, + "top_p": 1, + "truncation": "disabled", + "usage": { + "input_tokens": 3678, + "input_tokens_details": { + "cached_tokens": 2304 + }, + "output_tokens": 536, + "output_tokens_details": { + "reasoning_tokens": 448 + }, + "total_tokens": 4214 + }, + "user": null, + "metadata": {} +} diff --git a/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap b/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap index 2ba41e8c4c62..3e0ffa0df6b1 100644 --- a/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap +++ b/packages/openai/src/responses/__snapshots__/openai-responses-language-model.test.ts.snap @@ -119,6 +119,180 @@ Notes: ] `; +exports[`OpenAIResponsesLanguageModel > doGenerate > file search tool > with results include > should include file search tool call and result in content 1`] = ` +[ + { + "providerMetadata": { + "openai": { + "itemId": "rs_0365d26c32c64c650068cabb03bcc48194bfbd973152bca8f6", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "input": "{}", + "providerExecuted": true, + "toolCallId": "fs_0365d26c32c64c650068cabb04aa388194b53c59de50a3951e", + "toolName": "file_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "queries": [ + "What is an embedding model according to this document?", + "What is an embedding model in the document?", + "definition of embedding model", + "embedding model explanation 'embedding model'", + ], + "results": [ + { + "attributes": {}, + "fileId": "file-Ebzhf8H4DPGPr9pUhr7n7v", + "filename": "ai.pdf", + "score": 0.9311, + "text": "AI 1 + +AI +Generative artificial intelligence refers to models that predict and generate +various types of outputs (such as text, images, or audio) based on whatʼs +statistically likely, pulling from patterns theyʼve learned from their training data. +For example: + +Given a photo, a generative model can generate a caption. + +Given an audio file, a generative model can generate a transcription. + +Given a text description, a generative model can generate an image. + +A large language model LLM is a subset of generative models focused +primarily on text. An LLM takes a sequence of words as input and aims to +predict the most likely sequence to follow. It assigns probabilities to potential +next sequences and then selects one. The model continues to generate +sequences until it meets a specified stopping criterion. + +LLMs learn by training on massive collections of written text, which means they +will be better suited to some use cases than others. For example, a model +trained on GitHub data would understand the probabilities of sequences in +source code particularly well. + +However, it's crucial to understand LLMs' limitations. When asked about less +known or absent information, like the birthday of a personal relative, LLMs +might "hallucinate" or make up information. It's essential to consider how well- +represented the information you need is in the model. + +An embedding model is used to convert complex data (like words or images) +into a dense vector (a list of numbers) representation, known as an embedding. +Unlike generative models, embedding models do not generate new text or data. +Instead, they provide representations of semantic and synactic relationships +between entities that can be used as input for other models or other natural +language processing tasks. + +In the next section, you will learn about the difference between models +providers and models, and which ones are available in the AI SDK.", + }, + ], + }, + "toolCallId": "fs_0365d26c32c64c650068cabb04aa388194b53c59de50a3951e", + "toolName": "file_search", + "type": "tool-result", + }, + { + "providerMetadata": { + "openai": { + "itemId": "rs_0365d26c32c64c650068cabb061740819491324d349d0f07ca", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "providerMetadata": { + "openai": { + "itemId": "msg_0365d26c32c64c650068cabb0e66b081949f66f61dacef39f3", + }, + }, + "text": "According to the document, an embedding model converts complex data (like words or images) into a dense vector — a list of numbers — called an embedding. It does not generate new text or data; instead it encodes semantic and syntactic relationships between entities so those vector representations can be used as inputs for other models or NLP tasks .", + "type": "text", + }, + { + "filename": "ai.pdf", + "id": "id-0", + "mediaType": "text/plain", + "sourceType": "document", + "title": "ai.pdf", + "type": "source", + }, +] +`; + +exports[`OpenAIResponsesLanguageModel > doGenerate > file search tool > without results include > should include file search tool call and result in content 1`] = ` +[ + { + "providerMetadata": { + "openai": { + "itemId": "rs_0a098396a8feca410068caae3b47208196957fe59419daad70", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "input": "{}", + "providerExecuted": true, + "toolCallId": "fs_0a098396a8feca410068caae3cab5c8196a54fd00498464e62", + "toolName": "file_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "queries": [ + "What is an embedding model according to this document?", + "What is an embedding model?", + "definition of embedding model in the document", + "embedding model description", + ], + "results": null, + }, + "toolCallId": "fs_0a098396a8feca410068caae3cab5c8196a54fd00498464e62", + "toolName": "file_search", + "type": "tool-result", + }, + { + "providerMetadata": { + "openai": { + "itemId": "rs_0a098396a8feca410068caae3e21a081968e7ac588401c4a6a", + "reasoningEncryptedContent": null, + }, + }, + "text": "", + "type": "reasoning", + }, + { + "providerMetadata": { + "openai": { + "itemId": "msg_0a098396a8feca410068caae457c508196b2fcd079d1d3ec74", + }, + }, + "text": "According to the document, an embedding model is used to convert complex data (like words or images) into a dense vector (a list of numbers) representation called an embedding, which captures semantic and syntactic relationships. Unlike generative models, embedding models do not generate new text or data; instead, they provide these vector representations to be used as input for other models or other natural language processing tasks .", + "type": "text", + }, + { + "filename": "ai.pdf", + "id": "id-0", + "mediaType": "text/plain", + "sourceType": "document", + "title": "ai.pdf", + "type": "source", + }, +] +`; + exports[`OpenAIResponsesLanguageModel > doGenerate > image generation tool > should include generate image tool call and result in content 1`] = ` [ { @@ -1414,6 +1588,1038 @@ exports[`OpenAIResponsesLanguageModel > doStream > code interpreter tool > shoul ] `; +exports[`OpenAIResponsesLanguageModel > doStream > file search tool > with results include > should stream file search results 1`] = ` +[ + { + "type": "stream-start", + "warnings": [], + }, + { + "id": "resp_06456cb9918b63780068cacd710b0881a1b00b5fca56e7100b", + "modelId": "gpt-5-mini-2025-08-07", + "timestamp": 2025-09-17T15:02:09.000Z, + "type": "response-metadata", + }, + { + "id": "rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41:0", + "providerMetadata": { + "openai": { + "itemId": "rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41:0", + "providerMetadata": { + "openai": { + "itemId": "rs_06456cb9918b63780068cacd717c3481a1b8c7094da5770b41", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "input": "{}", + "providerExecuted": true, + "toolCallId": "fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6", + "toolName": "file_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "queries": [ + "What is an embedding model according to this document?", + "What is an embedding model definition in this document?", + "How does the document define an embedding model?", + ], + "results": [ + { + "attributes": {}, + "fileId": "file-Ebzhf8H4DPGPr9pUhr7n7v", + "filename": "ai.pdf", + "score": 0.9312, + "text": "AI 1 + +AI +Generative artificial intelligence refers to models that predict and generate +various types of outputs (such as text, images, or audio) based on whatʼs +statistically likely, pulling from patterns theyʼve learned from their training data. +For example: + +Given a photo, a generative model can generate a caption. + +Given an audio file, a generative model can generate a transcription. + +Given a text description, a generative model can generate an image. + +A large language model LLM is a subset of generative models focused +primarily on text. An LLM takes a sequence of words as input and aims to +predict the most likely sequence to follow. It assigns probabilities to potential +next sequences and then selects one. The model continues to generate +sequences until it meets a specified stopping criterion. + +LLMs learn by training on massive collections of written text, which means they +will be better suited to some use cases than others. For example, a model +trained on GitHub data would understand the probabilities of sequences in +source code particularly well. + +However, it's crucial to understand LLMs' limitations. When asked about less +known or absent information, like the birthday of a personal relative, LLMs +might "hallucinate" or make up information. It's essential to consider how well- +represented the information you need is in the model. + +An embedding model is used to convert complex data (like words or images) +into a dense vector (a list of numbers) representation, known as an embedding. +Unlike generative models, embedding models do not generate new text or data. +Instead, they provide representations of semantic and synactic relationships +between entities that can be used as input for other models or other natural +language processing tasks. + +In the next section, you will learn about the difference between models +providers and models, and which ones are available in the AI SDK.", + }, + ], + }, + "toolCallId": "fs_06456cb9918b63780068cacd74a1dc81a1bf68dd57f140b4b6", + "toolName": "file_search", + "type": "tool-result", + }, + { + "id": "rs_06456cb9918b63780068cacd7663c481a191dd84333d842728:0", + "providerMetadata": { + "openai": { + "itemId": "rs_06456cb9918b63780068cacd7663c481a191dd84333d842728", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_06456cb9918b63780068cacd7663c481a191dd84333d842728:0", + "providerMetadata": { + "openai": { + "itemId": "rs_06456cb9918b63780068cacd7663c481a191dd84333d842728", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "providerMetadata": { + "openai": { + "itemId": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + }, + }, + "type": "text-start", + }, + { + "delta": "The", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " document", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " defines", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " an", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " embedding", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " model", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " as", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " tool", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " that", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " converts", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " complex", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " data", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " (", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": "e", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ".g", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ".,", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " words", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " images", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ")", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " into", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " dense", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " vector", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " (", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": "a", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " list", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " of", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " numbers", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ")", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " called", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " an", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " embedding", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ".", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " Unlike", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " gener", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": "ative", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " models", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " embedding", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " models", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " don", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": "’t", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " generate", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " new", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " text", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " data", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": ";", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " they", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " provide", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " vector", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " representations", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " that", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " capture", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " semantic", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " and", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " synt", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": "actic", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " relationships", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " and", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " can", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " be", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " used", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " as", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " input", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " for", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " other", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " models", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " NLP", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " tasks", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "filename": "ai.pdf", + "id": "id-0", + "mediaType": "text/plain", + "sourceType": "document", + "title": "ai.pdf", + "type": "source", + }, + { + "delta": ".", + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-delta", + }, + { + "id": "msg_06456cb9918b63780068cacd7c922081a1ae15f2672a51980f", + "type": "text-end", + }, + { + "finishReason": "stop", + "providerMetadata": { + "openai": { + "responseId": "resp_06456cb9918b63780068cacd710b0881a1b00b5fca56e7100b", + "serviceTier": "default", + }, + }, + "type": "finish", + "usage": { + "cachedInputTokens": 2304, + "inputTokens": 3748, + "outputTokens": 543, + "reasoningTokens": 448, + "totalTokens": 4291, + }, + }, +] +`; + +exports[`OpenAIResponsesLanguageModel > doStream > file search tool > without results include > should stream file search results 1`] = ` +[ + { + "type": "stream-start", + "warnings": [], + }, + { + "id": "resp_0459517ad68504ad0068cabfba22b88192836339640e9a765a", + "modelId": "gpt-5-mini-2025-08-07", + "timestamp": 2025-09-17T14:03:38.000Z, + "type": "response-metadata", + }, + { + "id": "rs_0459517ad68504ad0068cabfba951881929654a05214361b35:0", + "providerMetadata": { + "openai": { + "itemId": "rs_0459517ad68504ad0068cabfba951881929654a05214361b35", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_0459517ad68504ad0068cabfba951881929654a05214361b35:0", + "providerMetadata": { + "openai": { + "itemId": "rs_0459517ad68504ad0068cabfba951881929654a05214361b35", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "input": "{}", + "providerExecuted": true, + "toolCallId": "fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a", + "toolName": "file_search", + "type": "tool-call", + }, + { + "providerExecuted": true, + "result": { + "queries": [ + "What is an embedding model according to this document?", + "What is an embedding model defined as in the document?", + "definition of embedding model", + ], + "results": null, + }, + "toolCallId": "fs_0459517ad68504ad0068cabfbd76888192a5dc4475fadabf8a", + "toolName": "file_search", + "type": "tool-result", + }, + { + "id": "rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-start", + }, + { + "id": "rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9:0", + "providerMetadata": { + "openai": { + "itemId": "rs_0459517ad68504ad0068cabfbf337881929cf5266be7a008a9", + "reasoningEncryptedContent": null, + }, + }, + "type": "reasoning-end", + }, + { + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "providerMetadata": { + "openai": { + "itemId": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + }, + }, + "type": "text-start", + }, + { + "delta": "According", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " to", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " the", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " document", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " an", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " embedding", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " model", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " converts", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " complex", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " data", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " (", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": "e", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": ".g", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": ".,", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " words", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " images", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": ")", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " into", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " dense", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " vector", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " —", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " a", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " list", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " of", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " numbers", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " —", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " called", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " an", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " embedding", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "filename": "ai.pdf", + "id": "id-0", + "mediaType": "text/plain", + "sourceType": "document", + "title": "ai.pdf", + "type": "source", + }, + { + "delta": ".", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " Unlike", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " gener", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": "ative", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " models", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": ",", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " embedding", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " models", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " do", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " not", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " generate", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " new", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " text", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " data", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": ";", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " instead", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " they", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " produce", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " vector", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " representations", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " that", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " capture", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " semantic", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " and", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " synt", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": "actic", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " relationships", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " and", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " can", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " be", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " used", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " as", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " input", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " for", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " other", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " models", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " or", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " NLP", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " tasks", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "delta": " ", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "filename": "ai.pdf", + "id": "id-1", + "mediaType": "text/plain", + "sourceType": "document", + "title": "ai.pdf", + "type": "source", + }, + { + "delta": ".", + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-delta", + }, + { + "id": "msg_0459517ad68504ad0068cabfc6b5c48192a15ac773668537f1", + "type": "text-end", + }, + { + "finishReason": "stop", + "providerMetadata": { + "openai": { + "responseId": "resp_0459517ad68504ad0068cabfba22b88192836339640e9a765a", + "serviceTier": "default", + }, + }, + "type": "finish", + "usage": { + "cachedInputTokens": 2304, + "inputTokens": 3737, + "outputTokens": 621, + "reasoningTokens": 512, + "totalTokens": 4358, + }, + }, +] +`; + exports[`OpenAIResponsesLanguageModel > doStream > image generation tool > should stream code image generation results 1`] = ` [ { diff --git a/packages/openai/src/responses/openai-responses-api-types.ts b/packages/openai/src/responses/openai-responses-api-types.ts index 9c83a9d805f8..a9094bd21e68 100644 --- a/packages/openai/src/responses/openai-responses-api-types.ts +++ b/packages/openai/src/responses/openai-responses-api-types.ts @@ -12,16 +12,17 @@ export type OpenAIResponsesInputItem = | OpenAIResponsesReasoning | OpenAIResponsesItemReference; +export type OpenAIResponsesIncludeValue = + | 'web_search_call.action.sources' + | 'code_interpreter_call.outputs' + | 'computer_call_output.output.image_url' + | 'file_search_call.results' + | 'message.input_image.image_url' + | 'message.output_text.logprobs' + | 'reasoning.encrypted_content'; + export type OpenAIResponsesIncludeOptions = - | Array< - | 'web_search_call.action.sources' - | 'code_interpreter_call.outputs' - | 'computer_call_output.output.image_url' - | 'file_search_call.results' - | 'message.input_image.image_url' - | 'message.output_text.logprobs' - | 'reasoning.encrypted_content' - > + | Array | undefined | null; @@ -73,6 +74,44 @@ export type OpenAIResponsesItemReference = { id: string; }; +/** + * A filter used to compare a specified attribute key to a given value using a defined comparison operation. + */ +export type OpenAIResponsesFileSearchToolComparisonFilter = { + /** + * The key to compare against the value. + */ + key: string; + + /** + * Specifies the comparison operator: eq, ne, gt, gte, lt, lte. + */ + type: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte'; + + /** + * The value to compare against the attribute key; supports string, number, or boolean types. + */ + value: string | number | boolean; +}; + +/** + * Combine multiple filters using and or or. + */ +export type OpenAIResponsesFileSearchToolCompoundFilter = { + /** + * Type of operation: and or or. + */ + type: 'and' | 'or'; + + /** + * Array of filters to combine. Items can be ComparisonFilter or CompoundFilter. + */ + filters: Array< + | OpenAIResponsesFileSearchToolComparisonFilter + | OpenAIResponsesFileSearchToolCompoundFilter + >; +}; + export type OpenAIResponsesTool = | { type: 'function'; @@ -114,21 +153,14 @@ export type OpenAIResponsesTool = } | { type: 'file_search'; - vector_store_ids: string[] | undefined; + vector_store_ids: string[]; max_num_results: number | undefined; ranking_options: - | { ranker: 'auto' | 'default-2024-08-21' | undefined } + | { ranker?: string; score_threshold?: number } | undefined; filters: - | { - key: string; - type: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte'; - value: string | number | boolean; - } - | { - type: 'and' | 'or'; - filters: any[]; - } + | OpenAIResponsesFileSearchToolComparisonFilter + | OpenAIResponsesFileSearchToolCompoundFilter | undefined; } | { diff --git a/packages/openai/src/responses/openai-responses-language-model.test.ts b/packages/openai/src/responses/openai-responses-language-model.test.ts index a936f2418bbb..f5b5e75fd7d3 100644 --- a/packages/openai/src/responses/openai-responses-language-model.test.ts +++ b/packages/openai/src/responses/openai-responses-language-model.test.ts @@ -640,27 +640,6 @@ describe('OpenAIResponsesLanguageModel', () => { expect(warnings).toStrictEqual([]); }); - it('should send include provider option for file search results', async () => { - const { warnings } = await createModel('gpt-4o-mini').doGenerate({ - prompt: TEST_PROMPT, - providerOptions: { - openai: { - include: ['file_search_call.results'], - }, - }, - }); - - expect(await server.calls[0].requestBodyJson).toStrictEqual({ - model: 'gpt-4o-mini', - input: [ - { role: 'user', content: [{ type: 'input_text', text: 'Hello' }] }, - ], - include: ['file_search_call.results'], - }); - - expect(warnings).toStrictEqual([]); - }); - it('should send include provider option with multiple values', async () => { const { warnings } = await createModel('o3-mini').doGenerate({ prompt: TEST_PROMPT, @@ -973,203 +952,6 @@ describe('OpenAIResponsesLanguageModel', () => { expect(warnings).toStrictEqual([]); }); - it('should send file_search tool', async () => { - const { warnings } = await createModel('gpt-4o').doGenerate({ - tools: [ - { - type: 'provider-defined', - id: 'openai.file_search', - name: 'file_search', - args: { - vectorStoreIds: ['vs_123', 'vs_456'], - maxNumResults: 10, - ranking: { - ranker: 'auto', - }, - }, - }, - ], - prompt: TEST_PROMPT, - }); - - expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` - { - "input": [ - { - "content": [ - { - "text": "Hello", - "type": "input_text", - }, - ], - "role": "user", - }, - ], - "model": "gpt-4o", - "tools": [ - { - "max_num_results": 10, - "ranking_options": { - "ranker": "auto", - }, - "type": "file_search", - "vector_store_ids": [ - "vs_123", - "vs_456", - ], - }, - ], - } - `); - - expect(warnings).toStrictEqual([]); - }); - - it('should send file_search tool as tool_choice', async () => { - const { warnings } = await createModel('gpt-4o').doGenerate({ - toolChoice: { - type: 'tool', - toolName: 'file_search', - }, - tools: [ - { - type: 'provider-defined', - id: 'openai.file_search', - name: 'file_search', - args: { - vectorStoreIds: ['vs_789'], - maxNumResults: 5, - }, - }, - ], - prompt: TEST_PROMPT, - }); - - expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` - { - "input": [ - { - "content": [ - { - "text": "Hello", - "type": "input_text", - }, - ], - "role": "user", - }, - ], - "model": "gpt-4o", - "tool_choice": { - "type": "file_search", - }, - "tools": [ - { - "max_num_results": 5, - "type": "file_search", - "vector_store_ids": [ - "vs_789", - ], - }, - ], - } - `); - - expect(warnings).toStrictEqual([]); - }); - - it('should send file_search tool with filters', async () => { - const { warnings } = await createModel('gpt-4o').doGenerate({ - tools: [ - { - type: 'provider-defined', - id: 'openai.file_search', - name: 'file_search', - args: { - vectorStoreIds: ['vs_123'], - maxNumResults: 5, - filters: { - key: 'author', - type: 'eq', - value: 'Jane Smith', - }, - }, - }, - ], - prompt: TEST_PROMPT, - }); - - expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` - { - "input": [ - { - "content": [ - { - "text": "Hello", - "type": "input_text", - }, - ], - "role": "user", - }, - ], - "model": "gpt-4o", - "tools": [ - { - "filters": { - "key": "author", - "type": "eq", - "value": "Jane Smith", - }, - "max_num_results": 5, - "type": "file_search", - "vector_store_ids": [ - "vs_123", - ], - }, - ], - } - `); - - expect(warnings).toStrictEqual([]); - }); - - it('should send file_search tool with minimal args', async () => { - const { warnings } = await createModel('gpt-4o').doGenerate({ - tools: [ - { - type: 'provider-defined', - id: 'openai.file_search', - name: 'file_search', - args: {}, - }, - ], - prompt: TEST_PROMPT, - }); - - expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` - { - "input": [ - { - "content": [ - { - "text": "Hello", - "type": "input_text", - }, - ], - "role": "user", - }, - ], - "model": "gpt-4o", - "tools": [ - { - "type": "file_search", - }, - ], - } - `); - - expect(warnings).toStrictEqual([]); - }); - it('should warn about unsupported settings', async () => { const { warnings } = await createModel('gpt-4o').doGenerate({ prompt: TEST_PROMPT, @@ -2592,135 +2374,158 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); - it('should handle file_search tool calls in generate', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'json-value', - body: { - id: 'resp_67cf3390786881908b27489d7e8cfb6b', - object: 'response', - created_at: 1741632400, - status: 'completed', - error: null, - incomplete_details: null, - input: [], - instructions: null, - max_output_tokens: null, - model: 'gpt-4o-mini-2024-07-18', - output: [ - { - type: 'file_search_call', - id: 'fs_67cf3390e9608190869b5d45698a7067', - status: 'completed', - queries: ['AI information'], - results: [ - { - attributes: { - file_id: 'file-123', - filename: 'ai_guide.pdf', - score: 0.95, - text: 'AI is a field of computer science', + describe('file search tool', () => { + let result: Awaited>; + + describe('without results include', () => { + beforeEach(async () => { + prepareJsonFixtureResponse('openai-file-search-tool.1'); + + result = await createModel('gpt-5-nano').doGenerate({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.file_search', + name: 'file_search', + args: { + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + maxNumResults: 5, + filters: { + key: 'author', + type: 'eq', + value: 'Jane Smith', + }, + ranking: { + ranker: 'auto', + scoreThreshold: 0.5, }, }, - ], - }, - { - id: 'msg_67cf33924ea88190b8c12bf68c1f6416', - type: 'message', - status: 'completed', - role: 'assistant', - content: [ - { - type: 'output_text', - text: 'Based on the search results, here is the information you requested.', - annotations: [], + }, + ], + }); + }); + + it('should send request body with tool', async () => { + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "input": [ + { + "content": [ + { + "text": "Hello", + "type": "input_text", + }, + ], + "role": "user", + }, + ], + "model": "gpt-5-nano", + "tools": [ + { + "filters": { + "key": "author", + "type": "eq", + "value": "Jane Smith", }, - ], - }, - ], - parallel_tool_calls: true, - previous_response_id: null, - reasoning: { - effort: null, - summary: null, - }, - store: true, - temperature: 0, - text: { - format: { - type: 'text', - }, - }, - tool_choice: 'auto', - tools: [ - { - type: 'file_search', - }, - ], - top_p: 1, - truncation: 'disabled', - usage: { - input_tokens: 327, - input_tokens_details: { - cached_tokens: 0, - }, - output_tokens: 834, - output_tokens_details: { - reasoning_tokens: 0, - }, - total_tokens: 1161, - }, - user: null, - metadata: {}, - }, - }; + "max_num_results": 5, + "ranking_options": { + "ranker": "auto", + "score_threshold": 0.5, + }, + "type": "file_search", + "vector_store_ids": [ + "vs_68caad8bd5d88191ab766cf043d89a18", + ], + }, + ], + } + `); + }); - const result = await createModel('gpt-4o-mini').doGenerate({ - prompt: TEST_PROMPT, + it('should include file search tool call and result in content', async () => { + expect(result.content).toMatchSnapshot(); + }); }); - expect(result.content).toMatchInlineSnapshot(` - [ - { - "input": "", - "providerExecuted": true, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-call", - }, - { - "providerExecuted": true, - "result": { - "queries": [ - "AI information", + describe('with results include', () => { + beforeEach(async () => { + prepareJsonFixtureResponse('openai-file-search-tool.2'); + + result = await createModel('gpt-5-nano').doGenerate({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.file_search', + name: 'file_search', + args: { + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + maxNumResults: 5, + filters: { + key: 'author', + type: 'eq', + value: 'Jane Smith', + }, + ranking: { + ranker: 'auto', + scoreThreshold: 0.5, + }, + }, + }, + ], + providerOptions: { + openai: { + include: ['file_search_call.results'], + }, + }, + }); + }); + + it('should send request body with tool', async () => { + expect(await server.calls[0].requestBodyJson).toMatchInlineSnapshot(` + { + "include": [ + "file_search_call.results", + ], + "input": [ + { + "content": [ + { + "text": "Hello", + "type": "input_text", + }, + ], + "role": "user", + }, ], - "results": [ + "model": "gpt-5-nano", + "tools": [ { - "attributes": { - "file_id": "file-123", - "filename": "ai_guide.pdf", - "score": 0.95, - "text": "AI is a field of computer science", + "filters": { + "key": "author", + "type": "eq", + "value": "Jane Smith", + }, + "max_num_results": 5, + "ranking_options": { + "ranker": "auto", + "score_threshold": 0.5, }, + "type": "file_search", + "vector_store_ids": [ + "vs_68caad8bd5d88191ab766cf043d89a18", + ], }, ], - "status": "completed", - "type": "file_search_tool_result", - }, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-result", - }, - { - "providerMetadata": { - "openai": { - "itemId": "msg_67cf33924ea88190b8c12bf68c1f6416", - }, - }, - "text": "Based on the search results, here is the information you requested.", - "type": "text", - }, - ] - `); + } + `); + }); + + it('should include file search tool call and result in content', async () => { + expect(result.content).toMatchSnapshot(); + }); + }); }); it('should handle computer use tool calls', async () => { @@ -4118,6 +3923,67 @@ describe('OpenAIResponsesLanguageModel', () => { }); }); + describe('file search tool', () => { + let result: Awaited>; + + describe('without results include', () => { + beforeEach(async () => { + prepareChunksFixtureResponse('openai-file-search-tool.1'); + + result = await createModel('gpt-5-nano').doStream({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.file_search', + name: 'file_search', + args: { + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + }, + }, + ], + }); + }); + + it('should stream file search results', async () => { + expect( + await convertReadableStreamToArray(result.stream), + ).toMatchSnapshot(); + }); + }); + + describe('with results include', () => { + beforeEach(async () => { + prepareChunksFixtureResponse('openai-file-search-tool.2'); + + result = await createModel('gpt-5-nano').doStream({ + prompt: TEST_PROMPT, + tools: [ + { + type: 'provider-defined', + id: 'openai.file_search', + name: 'file_search', + args: { + vectorStoreIds: ['vs_68caad8bd5d88191ab766cf043d89a18'], + }, + }, + ], + providerOptions: { + openai: { + include: ['file_search_call.results'], + }, + }, + }); + }); + + it('should stream file search results', async () => { + expect( + await convertReadableStreamToArray(result.stream), + ).toMatchSnapshot(); + }); + }); + }); + describe('code interpreter tool', () => { let result: Awaited>; @@ -4225,211 +4091,6 @@ describe('OpenAIResponsesLanguageModel', () => { ] `); }); - - it('should handle file_search tool calls', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'stream-chunks', - chunks: [ - `data:{"type":"response.created","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"file_search"}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, - `data:{"type":"response.output_item.added","output_index":0,"item":{"type":"file_search_call","id":"fs_67cf3390e9608190869b5d45698a7067","status":"in_progress"}}\n\n`, - `data:{"type":"response.output_item.done","output_index":0,"item":{"type":"file_search_call","id":"fs_67cf3390e9608190869b5d45698a7067","status":"completed"}}\n\n`, - `data:{"type":"response.output_item.added","output_index":1,"item":{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"in_progress","role":"assistant","content":[]}}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":"Based on the search results, here is the information you requested."}\n\n`, - `data:{"type":"response.output_item.done","output_index":1,"item":{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here is the information you requested.","annotations":[]}]}}\n\n`, - `data:{"type":"response.completed","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[{"type":"file_search_call","id":"fs_67cf3390e9608190869b5d45698a7067","status":"completed"},{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here is the information you requested.","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"file_search"}],"top_p":1,"truncation":"disabled","usage":{"input_tokens":327,"input_tokens_details":{"cached_tokens":0},"output_tokens":834,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":1161},"user":null,"metadata":{}}}\n\n`, - ], - }; - - const { stream } = await createModel('gpt-4o-mini').doStream({ - prompt: TEST_PROMPT, - includeRawChunks: false, - }); - - expect(await convertReadableStreamToArray(stream)) - .toMatchInlineSnapshot(` - [ - { - "type": "stream-start", - "warnings": [], - }, - { - "id": "resp_67cf3390786881908b27489d7e8cfb6b", - "modelId": "gpt-4o-mini-2024-07-18", - "timestamp": 2025-03-10T18:46:40.000Z, - "type": "response-metadata", - }, - { - "id": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-input-start", - }, - { - "id": "fs_67cf3390e9608190869b5d45698a7067", - "type": "tool-input-end", - }, - { - "input": "", - "providerExecuted": true, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-call", - }, - { - "providerExecuted": true, - "result": { - "status": "completed", - "type": "file_search_tool_result", - }, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-result", - }, - { - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "providerMetadata": { - "openai": { - "itemId": "msg_67cf33924ea88190b8c12bf68c1f6416", - }, - }, - "type": "text-start", - }, - { - "delta": "Based on the search results, here is the information you requested.", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-end", - }, - { - "finishReason": "stop", - "providerMetadata": { - "openai": { - "responseId": "resp_67cf3390786881908b27489d7e8cfb6b", - }, - }, - "type": "finish", - "usage": { - "cachedInputTokens": 0, - "inputTokens": 327, - "outputTokens": 834, - "reasoningTokens": 0, - "totalTokens": 1161, - }, - }, - ] - `); - }); - - it('should handle file_search tool calls with results', async () => { - server.urls['https://api.openai.com/v1/responses'].response = { - type: 'stream-chunks', - chunks: [ - `data:{"type":"response.created","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"file_search"}],"top_p":1,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}\n\n`, - `data:{"type":"response.output_item.added","output_index":0,"item":{"type":"file_search_call","id":"fs_67cf3390e9608190869b5d45698a7067","status":"in_progress"}}\n\n`, - `data:{"type":"response.output_item.done","output_index":0,"item":{"type":"file_search_call","id":"fs_67cf3390e9608190869b5d45698a7067","status":"completed","queries":["AI information"],"results":[{"attributes":{"file_id":"file-123","filename":"ai_guide.pdf","score":0.95,"text":"AI is a field of computer science"}}]}}\n\n`, - `data:{"type":"response.output_item.added","output_index":1,"item":{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"in_progress","role":"assistant","content":[]}}\n\n`, - `data:{"type":"response.output_text.delta","item_id":"msg_67cf33924ea88190b8c12bf68c1f6416","output_index":1,"content_index":0,"delta":"Based on the search results, here is the information you requested."}\n\n`, - `data:{"type":"response.output_item.done","output_index":1,"item":{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here is the information you requested.","annotations":[]}]}}\n\n`, - `data:{"type":"response.completed","response":{"id":"resp_67cf3390786881908b27489d7e8cfb6b","object":"response","created_at":1741632400,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-mini-2024-07-18","output":[{"type":"file_search_call","id":"fs_67cf3390e9608190869b5d45698a7067","status":"completed","queries":["AI information"],"results":[{"attributes":{"file_id":"file-123","filename":"ai_guide.pdf","score":0.95,"text":"AI is a field of computer science"}}]},{"type":"message","id":"msg_67cf33924ea88190b8c12bf68c1f6416","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Based on the search results, here is the information you requested.","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[{"type":"file_search"}],"top_p":1,"truncation":"disabled","usage":{"input_tokens":327,"input_tokens_details":{"cached_tokens":0},"output_tokens":834,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":1161},"user":null,"metadata":{}}}\n\n`, - ], - }; - - const { stream } = await createModel('gpt-4o-mini').doStream({ - prompt: TEST_PROMPT, - includeRawChunks: false, - }); - - expect(await convertReadableStreamToArray(stream)) - .toMatchInlineSnapshot(` - [ - { - "type": "stream-start", - "warnings": [], - }, - { - "id": "resp_67cf3390786881908b27489d7e8cfb6b", - "modelId": "gpt-4o-mini-2024-07-18", - "timestamp": 2025-03-10T18:46:40.000Z, - "type": "response-metadata", - }, - { - "id": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-input-start", - }, - { - "id": "fs_67cf3390e9608190869b5d45698a7067", - "type": "tool-input-end", - }, - { - "input": "", - "providerExecuted": true, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-call", - }, - { - "providerExecuted": true, - "result": { - "queries": [ - "AI information", - ], - "results": [ - { - "attributes": { - "file_id": "file-123", - "filename": "ai_guide.pdf", - "score": 0.95, - "text": "AI is a field of computer science", - }, - }, - ], - "status": "completed", - "type": "file_search_tool_result", - }, - "toolCallId": "fs_67cf3390e9608190869b5d45698a7067", - "toolName": "file_search", - "type": "tool-result", - }, - { - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "providerMetadata": { - "openai": { - "itemId": "msg_67cf33924ea88190b8c12bf68c1f6416", - }, - }, - "type": "text-start", - }, - { - "delta": "Based on the search results, here is the information you requested.", - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-delta", - }, - { - "id": "msg_67cf33924ea88190b8c12bf68c1f6416", - "type": "text-end", - }, - { - "finishReason": "stop", - "providerMetadata": { - "openai": { - "responseId": "resp_67cf3390786881908b27489d7e8cfb6b", - }, - }, - "type": "finish", - "usage": { - "cachedInputTokens": 0, - "inputTokens": 327, - "outputTokens": 834, - "reasoningTokens": 0, - "totalTokens": 1161, - }, - }, - ] - `); - }); }); describe('reasoning', () => { diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index 190c25171ddc..cd1a4811dd3f 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -25,12 +25,16 @@ import { codeInterpreterInputSchema, codeInterpreterOutputSchema, } from '../tool/code-interpreter'; +import { fileSearchOutputSchema } from '../tool/file-search'; +import { imageGenerationOutputSchema } from '../tool/image-generation'; import { convertToOpenAIResponsesInput } from './convert-to-openai-responses-input'; import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason'; -import { OpenAIResponsesIncludeOptions } from './openai-responses-api-types'; +import { + OpenAIResponsesIncludeOptions, + OpenAIResponsesIncludeValue, +} from './openai-responses-api-types'; import { prepareResponsesTools } from './openai-responses-prepare-tools'; import { OpenAIResponsesModelId } from './openai-responses-settings'; -import { imageGenerationOutputSchema } from '../tool/image-generation'; const webSearchCallItem = z.object({ type: z.literal('web_search_call'), @@ -55,6 +59,23 @@ const webSearchCallItem = z.object({ .nullish(), }); +const fileSearchCallItem = z.object({ + type: z.literal('file_search_call'), + id: z.string(), + queries: z.array(z.string()), + results: z + .array( + z.object({ + attributes: z.record(z.string(), z.unknown()), + file_id: z.string(), + filename: z.string(), + score: z.number(), + text: z.string(), + }), + ) + .nullish(), +}); + const codeInterpreterCallItem = z.object({ type: z.literal('code_interpreter_call'), id: z.string(), @@ -183,6 +204,18 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { let include: OpenAIResponsesIncludeOptions = openaiOptions?.include; + function addInclude(key: OpenAIResponsesIncludeValue) { + include = include != null ? [...include, key] : [key]; + } + + function hasOpenAITool(id: string) { + return ( + tools?.find( + tool => tool.type === 'provider-defined' && tool.id === id, + ) != null + ); + } + // when logprobs are requested, automatically include them: const topLogprobs = typeof openaiOptions?.logprobs === 'number' @@ -191,11 +224,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { ? TOP_LOGPROBS_MAX : undefined; - include = topLogprobs - ? Array.isArray(include) - ? [...include, 'message.output_text.logprobs'] - : ['message.output_text.logprobs'] - : include; + if (topLogprobs) { + addInclude('message.output_text.logprobs'); + } // when a web search tool is present, automatically include the sources: const webSearchToolName = ( @@ -207,26 +238,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { ) as LanguageModelV2ProviderDefinedTool | undefined )?.name; - include = webSearchToolName - ? Array.isArray(include) - ? [...include, 'web_search_call.action.sources'] - : ['web_search_call.action.sources'] - : include; + if (webSearchToolName) { + addInclude('web_search_call.action.sources'); + } // when a code interpreter tool is present, automatically include the outputs: - const codeInterpreterToolName = ( - tools?.find( - tool => - tool.type === 'provider-defined' && - tool.id === 'openai.code_interpreter', - ) as LanguageModelV2ProviderDefinedTool | undefined - )?.name; - - include = codeInterpreterToolName - ? Array.isArray(include) - ? [...include, 'code_interpreter_call.outputs'] - : ['code_interpreter_call.outputs'] - : include; + if (hasOpenAITool('openai.code_interpreter')) { + addInclude('code_interpreter_call.outputs'); + } const baseArgs = { model: this.modelId, @@ -446,6 +465,8 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { }), ), }), + webSearchCallItem, + fileSearchCallItem, codeInterpreterCallItem, imageGenerationCallItem, z.object({ @@ -455,30 +476,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { arguments: z.string(), id: z.string(), }), - webSearchCallItem, z.object({ type: z.literal('computer_call'), id: z.string(), status: z.string().optional(), }), - z.object({ - type: z.literal('file_search_call'), - id: z.string(), - status: z.string().optional(), - queries: z.array(z.string()).nullish(), - results: z - .array( - z.object({ - attributes: z.object({ - file_id: z.string(), - filename: z.string(), - score: z.number(), - text: z.string(), - }), - }), - ) - .nullish(), - }), z.object({ type: z.literal('reasoning'), id: z.string(), @@ -673,7 +675,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { type: 'tool-call', toolCallId: part.id, toolName: 'file_search', - input: '', + input: '{}', providerExecuted: true, }); @@ -682,11 +684,16 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { toolCallId: part.id, toolName: 'file_search', result: { - type: 'file_search_tool_result', - status: part.status || 'completed', - ...(part.queries && { queries: part.queries }), - ...(part.results && { results: part.results }), - }, + queries: part.queries, + results: + part.results?.map(result => ({ + attributes: result.attributes, + fileId: result.file_id, + filename: result.filename, + score: result.score, + text: result.text, + })) ?? null, + } satisfies z.infer, providerExecuted: true, }); break; @@ -872,15 +879,12 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { toolName: 'computer_use', }); } else if (value.item.type === 'file_search_call') { - ongoingToolCalls[value.output_index] = { - toolName: 'file_search', - toolCallId: value.item.id, - }; - controller.enqueue({ - type: 'tool-input-start', - id: value.item.id, + type: 'tool-call', + toolCallId: value.item.id, toolName: 'file_search', + input: '{}', + providerExecuted: true, }); } else if (value.item.type === 'image_generation_call') { controller.enqueue({ @@ -991,29 +995,21 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { } else if (value.item.type === 'file_search_call') { ongoingToolCalls[value.output_index] = undefined; - controller.enqueue({ - type: 'tool-input-end', - id: value.item.id, - }); - - controller.enqueue({ - type: 'tool-call', - toolCallId: value.item.id, - toolName: 'file_search', - input: '', - providerExecuted: true, - }); - controller.enqueue({ type: 'tool-result', toolCallId: value.item.id, toolName: 'file_search', result: { - type: 'file_search_tool_result', - status: value.item.status || 'completed', - ...(value.item.queries && { queries: value.item.queries }), - ...(value.item.results && { results: value.item.results }), - }, + queries: value.item.queries, + results: + value.item.results?.map(result => ({ + attributes: result.attributes, + fileId: result.file_id, + filename: result.filename, + score: result.score, + text: result.text, + })) ?? null, + } satisfies z.infer, providerExecuted: true, }); } else if (value.item.type === 'code_interpreter_call') { @@ -1291,20 +1287,6 @@ const responseOutputItemAddedSchema = z.object({ z.object({ type: z.literal('file_search_call'), id: z.string(), - status: z.string(), - queries: z.array(z.string()).nullish(), - results: z - .array( - z.object({ - attributes: z.object({ - file_id: z.string(), - filename: z.string(), - score: z.number(), - text: z.string(), - }), - }), - ) - .optional(), }), z.object({ type: z.literal('image_generation_call'), @@ -1337,29 +1319,12 @@ const responseOutputItemDoneSchema = z.object({ codeInterpreterCallItem, imageGenerationCallItem, webSearchCallItem, + fileSearchCallItem, z.object({ type: z.literal('computer_call'), id: z.string(), status: z.literal('completed'), }), - z.object({ - type: z.literal('file_search_call'), - id: z.string(), - status: z.literal('completed'), - queries: z.array(z.string()).nullish(), - results: z - .array( - z.object({ - attributes: z.object({ - file_id: z.string(), - filename: z.string(), - score: z.number(), - text: z.string(), - }), - }), - ) - .nullish(), - }), ]), }); diff --git a/packages/openai/src/responses/openai-responses-prepare-tools.ts b/packages/openai/src/responses/openai-responses-prepare-tools.ts index b5971807ea36..3ed69181ea82 100644 --- a/packages/openai/src/responses/openai-responses-prepare-tools.ts +++ b/packages/openai/src/responses/openai-responses-prepare-tools.ts @@ -58,15 +58,20 @@ export function prepareResponsesTools({ switch (tool.id) { case 'openai.file_search': { const args = fileSearchArgsSchema.parse(tool.args); + openaiTools.push({ type: 'file_search', vector_store_ids: args.vectorStoreIds, max_num_results: args.maxNumResults, ranking_options: args.ranking - ? { ranker: args.ranking.ranker } + ? { + ranker: args.ranking.ranker, + score_threshold: args.ranking.scoreThreshold, + } : undefined, filters: args.filters, }); + break; } case 'openai.web_search_preview': { diff --git a/packages/openai/src/tool/file-search.ts b/packages/openai/src/tool/file-search.ts index af508aad897e..01829caade24 100644 --- a/packages/openai/src/tool/file-search.ts +++ b/packages/openai/src/tool/file-search.ts @@ -1,4 +1,8 @@ -import { createProviderDefinedToolFactory } from '@ai-sdk/provider-utils'; +import { createProviderDefinedToolFactoryWithOutputSchema } from '@ai-sdk/provider-utils'; +import { + OpenAIResponsesFileSearchToolComparisonFilter, + OpenAIResponsesFileSearchToolCompoundFilter, +} from '../responses/openai-responses-api-types'; import { z } from 'zod/v4'; const comparisonFilterSchema = z.object({ @@ -14,31 +18,82 @@ const compoundFilterSchema: z.ZodType = z.object({ ), }); -const filtersSchema = z.union([comparisonFilterSchema, compoundFilterSchema]); - export const fileSearchArgsSchema = z.object({ - vectorStoreIds: z.array(z.string()).optional(), + vectorStoreIds: z.array(z.string()), maxNumResults: z.number().optional(), ranking: z .object({ - ranker: z.enum(['auto', 'default-2024-08-21']).optional(), + ranker: z.string().optional(), + scoreThreshold: z.number().optional(), }) .optional(), - filters: filtersSchema.optional(), + filters: z.union([comparisonFilterSchema, compoundFilterSchema]).optional(), +}); + +export const fileSearchOutputSchema = z.object({ + queries: z.array(z.string()), + results: z + .array( + z.object({ + attributes: z.record(z.string(), z.unknown()), + fileId: z.string(), + filename: z.string(), + score: z.number(), + text: z.string(), + }), + ) + .nullable(), }); -export const fileSearch = createProviderDefinedToolFactory< +export const fileSearch = createProviderDefinedToolFactoryWithOutputSchema< + {}, { /** * The search query to execute. */ - query: string; + queries: string[]; + + /** + * The results of the file search tool call. + */ + results: + | null + | { + /** + * Set of 16 key-value pairs that can be attached to an object. + * This can be useful for storing additional information about the object + * in a structured format, and querying for objects via API or the dashboard. + * Keys are strings with a maximum length of 64 characters. + * Values are strings with a maximum length of 512 characters, booleans, or numbers. + */ + attributes: Record; + + /** + * The unique ID of the file. + */ + fileId: string; + + /** + * The name of the file. + */ + filename: string; + + /** + * The relevance score of the file - a value between 0 and 1. + */ + score: number; + + /** + * The text that was retrieved from the file. + */ + text: string; + }[]; }, { /** - * List of vector store IDs to search through. If not provided, searches all available vector stores. + * List of vector store IDs to search through. */ - vectorStoreIds?: string[]; + vectorStoreIds: string[]; /** * Maximum number of search results to return. Defaults to 10. @@ -49,27 +104,29 @@ export const fileSearch = createProviderDefinedToolFactory< * Ranking options for the search. */ ranking?: { - ranker?: 'auto' | 'default-2024-08-21'; + /** + * The ranker to use for the file search. + */ + ranker?: string; + + /** + * The score threshold for the file search, a number between 0 and 1. + * Numbers closer to 1 will attempt to return only the most relevant results, + * but may return fewer results. + */ + scoreThreshold?: number; }; /** - * A filter to apply based on file attributes. + * A filter to apply. */ filters?: - | { - key: string; - type: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte'; - value: string | number | boolean; - } - | { - type: 'and' | 'or'; - filters: any[]; - }; + | OpenAIResponsesFileSearchToolComparisonFilter + | OpenAIResponsesFileSearchToolCompoundFilter; } >({ id: 'openai.file_search', name: 'file_search', - inputSchema: z.object({ - query: z.string(), - }), + inputSchema: z.object({}), + outputSchema: fileSearchOutputSchema, }); From 5c5fab361b8a8392c4d9b6083be67019fff9ec09 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 09:54:36 -0700 Subject: [PATCH 048/121] Version Packages (#8695) This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @ai-sdk/azure@2.0.32 ### Patch Changes - Updated dependencies [1cf857d] - Updated dependencies [01de47f] - @ai-sdk/openai@2.0.32 ## @ai-sdk/openai@2.0.32 ### Patch Changes - 1cf857d: fix(provider/openai): remove provider-executed tools from chat completions model - 01de47f: feat(provider/openai): rework file search tool Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/famous-walls-tell.md | 5 ----- .changeset/good-trees-join.md | 5 ----- packages/azure/CHANGELOG.md | 8 ++++++++ packages/azure/package.json | 2 +- packages/openai/CHANGELOG.md | 7 +++++++ packages/openai/package.json | 2 +- 6 files changed, 17 insertions(+), 12 deletions(-) delete mode 100644 .changeset/famous-walls-tell.md delete mode 100644 .changeset/good-trees-join.md diff --git a/.changeset/famous-walls-tell.md b/.changeset/famous-walls-tell.md deleted file mode 100644 index 0b1a3f08f661..000000000000 --- a/.changeset/famous-walls-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -fix(provider/openai): remove provider-executed tools from chat completions model diff --git a/.changeset/good-trees-join.md b/.changeset/good-trees-join.md deleted file mode 100644 index bf54a271d1f4..000000000000 --- a/.changeset/good-trees-join.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ai-sdk/openai': patch ---- - -feat(provider/openai): rework file search tool diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index de5ab180550b..63251ca0784f 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/azure +## 2.0.32 + +### Patch Changes + +- Updated dependencies [1cf857d] +- Updated dependencies [01de47f] + - @ai-sdk/openai@2.0.32 + ## 2.0.31 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 2878adf251f0..23436d02962b 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.0.31", + "version": "2.0.32", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 2e76842ce0d4..298a643a774e 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/openai +## 2.0.32 + +### Patch Changes + +- 1cf857d: fix(provider/openai): remove provider-executed tools from chat completions model +- 01de47f: feat(provider/openai): rework file search tool + ## 2.0.31 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index d5b85844f9cf..e827c7aaa89a 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.0.31", + "version": "2.0.32", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From db39635ff383d725702a1af1d8e2d0e18206ad12 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 19:57:04 +0200 Subject: [PATCH 049/121] ci(release): remove v5 branch targets from github actions (#8709) ## Summary remove v5 branch targets from github actions --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89c274e80b81..87b1e931d06b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [main, v5] + branches: [main] pull_request: - branches: [main, v5] + branches: [main] jobs: build-examples: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e7d9673d3bc6..82a74e3b62f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,6 @@ on: push: branches: - main - - v5 paths: - '.changeset/**' - '.github/workflows/release.yml' From 78928cb390e53646813f551f537cd5950373cce6 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 17 Sep 2025 20:01:30 +0200 Subject: [PATCH 050/121] release: start 5.1 beta (#8710) ## Background 5.0 branch was cut and we are starting 5.1 beta work on `main` ## Summary 5.1 beta prerelease mode and changeset. --- .changeset/curly-glasses-count.md | 45 +++++++++++++++++++ .changeset/pre.json | 74 +++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 .changeset/curly-glasses-count.md create mode 100644 .changeset/pre.json diff --git a/.changeset/curly-glasses-count.md b/.changeset/curly-glasses-count.md new file mode 100644 index 000000000000..ce538e65bf5c --- /dev/null +++ b/.changeset/curly-glasses-count.md @@ -0,0 +1,45 @@ +--- +'ai': minor +'@ai-sdk/amazon-bedrock': minor +'@ai-sdk/angular': minor +'@ai-sdk/anthropic': minor +'@ai-sdk/assemblyai': minor +'@ai-sdk/azure': minor +'@ai-sdk/cerebras': minor +'@ai-sdk/codemod': minor +'@ai-sdk/cohere': minor +'@ai-sdk/deepgram': minor +'@ai-sdk/deepinfra': minor +'@ai-sdk/deepseek': minor +'@ai-sdk/elevenlabs': minor +'@ai-sdk/fal': minor +'@ai-sdk/fireworks': minor +'@ai-sdk/gateway': minor +'@ai-sdk/gladia': minor +'@ai-sdk/google': minor +'@ai-sdk/google-vertex': minor +'@ai-sdk/groq': minor +'@ai-sdk/hume': minor +'@ai-sdk/langchain': minor +'@ai-sdk/llamaindex': minor +'@ai-sdk/lmnt': minor +'@ai-sdk/luma': minor +'@ai-sdk/mistral': minor +'@ai-sdk/openai': minor +'@ai-sdk/openai-compatible': minor +'@ai-sdk/perplexity': minor +'@ai-sdk/provider': minor +'@ai-sdk/provider-utils': minor +'@ai-sdk/react': minor +'@ai-sdk/replicate': minor +'@ai-sdk/revai': minor +'@ai-sdk/rsc': minor +'@ai-sdk/svelte': minor +'@ai-sdk/togetherai': minor +'@ai-sdk/valibot': minor +'@ai-sdk/vercel': minor +'@ai-sdk/vue': minor +'@ai-sdk/xai': minor +--- + +release: start 5.1 beta diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000000..1e5eb2bc2192 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,74 @@ +{ + "mode": "pre", + "tag": "beta", + "initialVersions": { + "@example/ai-core": "0.0.0", + "@example/angular": "0.0.0", + "@example/express": "0.0.0", + "@example/fastify": "0.0.0", + "@example/hono": "0.0.0", + "@example/mcp": "0.0.0", + "@example/nest": "0.0.0", + "@example/next": "0.0.0", + "@example/next-agent": "0.0.0", + "@example/next-fastapi": "0.0.0", + "@example/next-google-vertex": "0.0.0", + "@example/next-langchain": "0.0.0", + "@example/next-openai": "0.0.0", + "@example/next-openai-kasada-bot-protection": "0.0.0", + "@example/next-openai-pages": "0.0.0", + "@example/next-openai-telemetry": "0.0.0", + "@example/next-openai-telemetry-sentry": "0.0.0", + "@example/next-openai-rate-limits": "0.0.0", + "@example/node-http-server": "0.0.0", + "@example/nuxt-openai": "0.0.0", + "@example/sveltekit-openai": "0.0.0", + "ai": "5.0.45", + "@ai-sdk/amazon-bedrock": "3.0.22", + "@ai-sdk/angular": "1.0.45", + "@ai-sdk/anthropic": "2.0.17", + "@ai-sdk/assemblyai": "1.0.9", + "@ai-sdk/azure": "2.0.32", + "@ai-sdk/cerebras": "1.0.18", + "@ai-sdk/codemod": "2.0.10", + "@ai-sdk/cohere": "2.0.10", + "@ai-sdk/deepgram": "1.0.9", + "@ai-sdk/deepinfra": "1.0.18", + "@ai-sdk/deepseek": "1.0.18", + "@ai-sdk/elevenlabs": "1.0.10", + "@ai-sdk/fal": "1.0.13", + "@ai-sdk/fireworks": "1.0.18", + "@ai-sdk/gateway": "1.0.23", + "@ai-sdk/gladia": "1.0.9", + "@ai-sdk/google": "2.0.14", + "@ai-sdk/google-vertex": "3.0.27", + "@ai-sdk/groq": "2.0.19", + "@ai-sdk/hume": "1.0.9", + "@ai-sdk/langchain": "1.0.45", + "@ai-sdk/llamaindex": "1.0.45", + "@ai-sdk/lmnt": "1.0.9", + "@ai-sdk/luma": "1.0.9", + "@ai-sdk/mistral": "2.0.14", + "@ai-sdk/openai": "2.0.32", + "@ai-sdk/openai-compatible": "1.0.18", + "@ai-sdk/perplexity": "2.0.9", + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.9", + "@ai-sdk/react": "2.0.45", + "@ai-sdk/replicate": "1.0.9", + "@ai-sdk/revai": "1.0.9", + "@ai-sdk/rsc": "1.0.45", + "ai-core-e2e-next-server": "0.0.0", + "@ai-sdk/svelte": "3.0.45", + "@ai-sdk/togetherai": "1.0.18", + "@ai-sdk/valibot": "1.0.9", + "@ai-sdk/vercel": "1.0.18", + "@ai-sdk/vue": "2.0.45", + "@ai-sdk/xai": "2.0.20", + "analyze-downloads": "0.0.0", + "eslint-config-vercel-ai": "0.0.0", + "generate-llms-txt": "0.0.0", + "@vercel/ai-tsconfig": "0.0.0" + }, + "changesets": [] +} From 49bec97a8d1d9772b93cd84f569eb6a05dedfe92 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:13:44 +0000 Subject: [PATCH 051/121] Version Packages (beta) (#8711) # Releases ## ai@5.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/gateway@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/amazon-bedrock@3.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/anthropic@2.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/angular@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/anthropic@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/assemblyai@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/azure@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai@2.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/cerebras@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/codemod@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ## @ai-sdk/cohere@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/deepgram@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/deepinfra@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/deepseek@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/elevenlabs@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/fal@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/fireworks@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/gateway@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/gladia@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/google@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/google-vertex@3.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/anthropic@2.1.0-beta.0 - @ai-sdk/google@2.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/groq@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/hume@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/langchain@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 ## @ai-sdk/llamaindex@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 ## @ai-sdk/lmnt@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/luma@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/mistral@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/openai@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/openai-compatible@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/perplexity@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/provider@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ## @ai-sdk/provider-utils@3.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 ## @ai-sdk/react@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/replicate@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/revai@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/rsc@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/svelte@3.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/togetherai@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/valibot@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/vercel@1.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/vue@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - ai@5.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 ## @ai-sdk/xai@2.1.0-beta.0 ### Minor Changes - 78928cb: release: start 5.1 beta ### Patch Changes - Updated dependencies [78928cb] - @ai-sdk/openai-compatible@1.1.0-beta.0 - @ai-sdk/provider@2.1.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.0 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 4 +++- packages/ai/CHANGELOG.md | 13 +++++++++++++ packages/ai/package.json | 2 +- packages/amazon-bedrock/CHANGELOG.md | 13 +++++++++++++ packages/amazon-bedrock/package.json | 2 +- packages/angular/CHANGELOG.md | 12 ++++++++++++ packages/angular/package.json | 2 +- packages/anthropic/CHANGELOG.md | 12 ++++++++++++ packages/anthropic/package.json | 2 +- packages/assemblyai/CHANGELOG.md | 12 ++++++++++++ packages/assemblyai/package.json | 2 +- packages/azure/CHANGELOG.md | 13 +++++++++++++ packages/azure/package.json | 2 +- packages/cerebras/CHANGELOG.md | 13 +++++++++++++ packages/cerebras/package.json | 2 +- packages/codemod/CHANGELOG.md | 6 ++++++ packages/codemod/package.json | 2 +- packages/cohere/CHANGELOG.md | 12 ++++++++++++ packages/cohere/package.json | 2 +- packages/deepgram/CHANGELOG.md | 12 ++++++++++++ packages/deepgram/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 13 +++++++++++++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 13 +++++++++++++ packages/deepseek/package.json | 2 +- packages/elevenlabs/CHANGELOG.md | 12 ++++++++++++ packages/elevenlabs/package.json | 2 +- packages/fal/CHANGELOG.md | 12 ++++++++++++ packages/fal/package.json | 2 +- packages/fireworks/CHANGELOG.md | 13 +++++++++++++ packages/fireworks/package.json | 2 +- packages/gateway/CHANGELOG.md | 12 ++++++++++++ packages/gateway/package.json | 2 +- packages/gladia/CHANGELOG.md | 12 ++++++++++++ packages/gladia/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 14 ++++++++++++++ packages/google-vertex/package.json | 2 +- packages/google/CHANGELOG.md | 12 ++++++++++++ packages/google/package.json | 2 +- packages/groq/CHANGELOG.md | 12 ++++++++++++ packages/groq/package.json | 2 +- packages/hume/CHANGELOG.md | 12 ++++++++++++ packages/hume/package.json | 2 +- packages/langchain/CHANGELOG.md | 11 +++++++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 11 +++++++++++ packages/llamaindex/package.json | 2 +- packages/lmnt/CHANGELOG.md | 12 ++++++++++++ packages/lmnt/package.json | 2 +- packages/luma/CHANGELOG.md | 12 ++++++++++++ packages/luma/package.json | 2 +- packages/mistral/CHANGELOG.md | 12 ++++++++++++ packages/mistral/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 12 ++++++++++++ packages/openai-compatible/package.json | 2 +- packages/openai/CHANGELOG.md | 12 ++++++++++++ packages/openai/package.json | 2 +- packages/perplexity/CHANGELOG.md | 12 ++++++++++++ packages/perplexity/package.json | 2 +- packages/provider-utils/CHANGELOG.md | 11 +++++++++++ packages/provider-utils/package.json | 2 +- packages/provider/CHANGELOG.md | 6 ++++++ packages/provider/package.json | 2 +- packages/react/CHANGELOG.md | 12 ++++++++++++ packages/react/package.json | 2 +- packages/replicate/CHANGELOG.md | 12 ++++++++++++ packages/replicate/package.json | 2 +- packages/revai/CHANGELOG.md | 12 ++++++++++++ packages/revai/package.json | 2 +- packages/rsc/CHANGELOG.md | 13 +++++++++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 12 ++++++++++++ packages/svelte/package.json | 2 +- packages/togetherai/CHANGELOG.md | 13 +++++++++++++ packages/togetherai/package.json | 2 +- packages/valibot/CHANGELOG.md | 11 +++++++++++ packages/valibot/package.json | 2 +- packages/vercel/CHANGELOG.md | 13 +++++++++++++ packages/vercel/package.json | 2 +- packages/vue/CHANGELOG.md | 12 ++++++++++++ packages/vue/package.json | 2 +- packages/xai/CHANGELOG.md | 13 +++++++++++++ packages/xai/package.json | 2 +- 84 files changed, 540 insertions(+), 42 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 1e5eb2bc2192..546c51643f48 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -70,5 +70,7 @@ "generate-llms-txt": "0.0.0", "@vercel/ai-tsconfig": "0.0.0" }, - "changesets": [] + "changesets": [ + "curly-glasses-count" + ] } diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 0b4a4573b696..a840365dcfba 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,18 @@ # ai +## 5.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/gateway@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 5.0.45 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index e68042045892..ae8cbd8df0ee 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.0.45", + "version": "5.1.0-beta.0", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index 5f0b50d9fcb6..b7ee1a67b6e3 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/amazon-bedrock +## 3.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/anthropic@2.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 3.0.22 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 3c1957855079..0e4dae86c383 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.0.22", + "version": "3.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 08967329d5a3..6664b352ab65 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/angular +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.45 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index a6f1035b2bab..99b9ac7f4e44 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.0.45", + "version": "1.1.0-beta.0", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 2192ea928998..9b5064fc2626 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/anthropic +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.17 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index bbccc9cfa1e8..97c1fc03cdba 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "2.0.17", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/assemblyai/CHANGELOG.md b/packages/assemblyai/CHANGELOG.md index e67eaa1df456..d0c4bc2a4a2e 100644 --- a/packages/assemblyai/CHANGELOG.md +++ b/packages/assemblyai/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/assemblyai +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index 08dd16b2e828..2d40afd22570 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/assemblyai", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index 63251ca0784f..d8884226f045 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/azure +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai@2.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.32 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 23436d02962b..a1b8dcc86f26 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.0.32", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 6f3737ac1b9a..96dcffdc481b 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/cerebras +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index 22d9ada70268..1acd5442ed9e 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/codemod/CHANGELOG.md b/packages/codemod/CHANGELOG.md index 8e0147060fcf..05dabda4013b 100644 --- a/packages/codemod/CHANGELOG.md +++ b/packages/codemod/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/codemod +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + ## 2.0.10 ### Patch Changes diff --git a/packages/codemod/package.json b/packages/codemod/package.json index 653ad92cd2df..363cc796ae09 100644 --- a/packages/codemod/package.json +++ b/packages/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/codemod", - "version": "2.0.10", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "files": [ diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index 90d7d99a2c4c..04c9ddab18f3 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/cohere +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.10 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index e47effde26e5..e3e8e9f147d7 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "2.0.10", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepgram/CHANGELOG.md b/packages/deepgram/CHANGELOG.md index bacf08287086..98b8a43f00d5 100644 --- a/packages/deepgram/CHANGELOG.md +++ b/packages/deepgram/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/deepgram +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index 3d7c5be84ec6..b0d52c5fe629 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepgram", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index 7cf2dad362a6..9375e8505237 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/deepinfra +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index be7dcad18ee4..092e6b4d0e4a 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index e685d2193897..4538703c60a3 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/deepseek +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index 4279aab2ae2d..00073f350d54 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/elevenlabs/CHANGELOG.md b/packages/elevenlabs/CHANGELOG.md index abf4899095d3..f76ffaccd158 100644 --- a/packages/elevenlabs/CHANGELOG.md +++ b/packages/elevenlabs/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/elevenlabs +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.10 ### Patch Changes diff --git a/packages/elevenlabs/package.json b/packages/elevenlabs/package.json index 29d23a6ce1c3..93f65ef34e8e 100644 --- a/packages/elevenlabs/package.json +++ b/packages/elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/elevenlabs", - "version": "1.0.10", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index b3e7ad432234..765418c49d5d 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/fal +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.13 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index 9fbc5b6d1d04..a23cc392ce44 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "1.0.13", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index eac85847164d..59b6151ae22c 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/fireworks +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index 4a7ea8b1ee3a..58535e382a43 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index c7c172d52322..dad882cc9a1f 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/gateway +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.23 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index b2bc3edb2a60..e58f343ff7c8 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.0.23", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gladia/CHANGELOG.md b/packages/gladia/CHANGELOG.md index 993480ec5a26..cd40c09f2dd0 100644 --- a/packages/gladia/CHANGELOG.md +++ b/packages/gladia/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/gladia +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/gladia/package.json b/packages/gladia/package.json index b3bd2b5ab47b..46d0175ba985 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/gladia", - "version": "1.0.9", + "version": "1.1.0-beta.0", "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 94b915e65644..00e21f68a7ad 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,19 @@ # @ai-sdk/google-vertex +## 3.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/anthropic@2.1.0-beta.0 + - @ai-sdk/google@2.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 3.0.27 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 5ef580912531..1da5f3cb6ca0 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.0.27", + "version": "3.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 56987a069c77..b71b8e64f32f 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/google +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.14 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index b93da9db3fa1..3d3760a092f6 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "2.0.14", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index f1744566b7d9..eac486ff3896 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/groq +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.19 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index c35450f91c52..be0b3f3c3090 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "2.0.19", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/hume/CHANGELOG.md b/packages/hume/CHANGELOG.md index 448575ac03e5..a79a5053efe0 100644 --- a/packages/hume/CHANGELOG.md +++ b/packages/hume/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/hume +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/hume/package.json b/packages/hume/package.json index 983d991e52c5..4d6358eb2126 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/hume", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 965255e463e7..8b205a2edfec 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/langchain +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + ## 1.0.45 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 8c16122e9205..b70913ac8719 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.0.45", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 26c1eb28cd10..924df9923ee6 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + ## 1.0.45 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index c82f1417718e..b152e0931f7d 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.0.45", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/lmnt/CHANGELOG.md b/packages/lmnt/CHANGELOG.md index 07bbf36e222b..d0c6301ac0e2 100644 --- a/packages/lmnt/CHANGELOG.md +++ b/packages/lmnt/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/lmnt +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index f5cd3405f3a4..569a794f6446 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/lmnt", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index 159acffe2480..52539b2afc2a 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/luma +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index cfe619c3752b..cc7038777a4d 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index 2cdc3e6b4428..de1ebacdb928 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/mistral +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.14 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index fb171be92685..8a48cb7b595e 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "2.0.14", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index 47664a46f325..d39a178681f5 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/openai-compatible +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index eb8e109b65ff..bcfd522818f2 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 298a643a774e..6b99dadc070f 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/openai +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.32 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index e827c7aaa89a..31434007c833 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.0.32", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index f04a49dde43d..ac0b927b8b1e 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/perplexity +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.9 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index b72fc745c7cd..0e599a6afde0 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "2.0.9", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index 14f8873ee08f..b8ae8c3d8cc4 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/provider-utils +## 3.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + ## 3.0.9 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index 5886081acaf2..3181451601f4 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "3.0.9", + "version": "3.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider/CHANGELOG.md b/packages/provider/CHANGELOG.md index 9e3609f86e9e..13cc5bcbdcaf 100644 --- a/packages/provider/CHANGELOG.md +++ b/packages/provider/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + ## 2.0.0 ### Major Changes diff --git a/packages/provider/package.json b/packages/provider/package.json index 892e979a6e81..365b78b07d70 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider", - "version": "2.0.0", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 2b2aa81df4d1..cb55b7af73ed 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/react +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.45 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 85df74152a44..46fcfb7e0e74 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.0.45", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index bf69a829dfa4..4b87e403f286 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/replicate +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index 3e945bdfc183..28ab8aa82f21 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/revai/CHANGELOG.md b/packages/revai/CHANGELOG.md index 498e4c60a068..ac0216930e60 100644 --- a/packages/revai/CHANGELOG.md +++ b/packages/revai/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/revai +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/revai/package.json b/packages/revai/package.json index 49b8e5bb9b33..33e08f058468 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/revai", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index c60b5dd6f6eb..4698150575ac 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/rsc +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.45 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 81e48a37d4e9..9cc6c93e49ed 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.0.45", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 276f4a9ba59a..f30798b9386e 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -1,5 +1,12 @@ # ai-core-e2e-next-server +## 0.0.1-beta.0 + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + ## 0.0.1 ### Patch Changes diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index b7ad1adfeca4..918addb57ba2 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/svelte +## 3.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 3.0.45 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index c81ab6e72c83..e5349fdb120b 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.0.45", + "version": "3.1.0-beta.0", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index 811fbbc17f24..511a9a3ff34e 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/togetherai +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index e03f25c3726a..f9002706459d 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index c84fac29da22..57628c06ed5d 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/valibot +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.9 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index 712740e5b2b4..ff781fdc544a 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "1.0.9", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index 06c11940fe87..779b2b7e4e3a 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/vercel +## 1.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 1.0.18 ### Patch Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index e10166cb819e..c816b7dfe03b 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.0.18", + "version": "1.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index b69d676c9ee2..1ffc30e6b005 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/vue +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - ai@5.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.45 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 62798eab2f68..efce362c329b 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.0.45", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 3346eb487c8b..1459a34c7cac 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/xai +## 2.1.0-beta.0 + +### Minor Changes + +- 78928cb: release: start 5.1 beta + +### Patch Changes + +- Updated dependencies [78928cb] + - @ai-sdk/openai-compatible@1.1.0-beta.0 + - @ai-sdk/provider@2.1.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.0 + ## 2.0.20 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index fa1064acde21..c79b1752008f 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.0.20", + "version": "2.1.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 53d393fba024897438e1fa45fe0f354f8dc0399d Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:47:35 +0100 Subject: [PATCH 052/121] chore: remove agents page from foundations section (#8702) Related to #8693 which brings new section dedicated to agents. --- content/docs/02-foundations/06-agents.mdx | 535 ---------------------- content/docs/03-agents/01-overview.mdx | 2 +- 2 files changed, 1 insertion(+), 536 deletions(-) delete mode 100644 content/docs/02-foundations/06-agents.mdx diff --git a/content/docs/02-foundations/06-agents.mdx b/content/docs/02-foundations/06-agents.mdx deleted file mode 100644 index 95dc2b470935..000000000000 --- a/content/docs/02-foundations/06-agents.mdx +++ /dev/null @@ -1,535 +0,0 @@ ---- -title: Agents -description: Learn how to build agents with AI SDK Core. ---- - -# Agents - -When building AI applications, you often need **systems that can understand context and take meaningful actions**. When building these systems, the key consideration is finding the right balance between flexibility and control. Let's explore different approaches and patterns for building these systems, with a focus on helping you match capabilities to your needs. - -## Building Blocks - -When building AI systems, you can combine these fundamental components: - -### Single-Step LLM Generation - -The basic building block - one call to an LLM to get a response. Useful for straightforward tasks like classification or text generation. - -### Tool Usage - -Enhanced capabilities through tools (like calculators, APIs, or databases) that the LLM can use to accomplish tasks. Tools provide a controlled way to extend what the LLM can do. - -When solving complex problems, **an LLM can make multiple tool calls across multiple steps without you explicitly specifying the order** - for example, looking up information in a database, using that to make calculations, and then storing results. The AI SDK makes this [multi-step tool usage](#multi-step-tool-usage) straightforward through the `stopWhen` parameter. - -### Multi-Agent Systems - -Multiple LLMs working together, each specialized for different aspects of a complex task. This enables sophisticated behaviors while keeping individual components focused. - -## Patterns - -These building blocks can be combined with workflow patterns that help manage complexity: - -- [Sequential Processing](#sequential-processing-chains) - Steps executed in order -- [Parallel Processing](#parallel-processing) - Independent tasks run simultaneously -- [Evaluation/Feedback Loops](#evaluator-optimizer) - Results checked and improved iteratively -- [Orchestration](#orchestrator-worker) - Coordinating multiple components -- [Routing](#routing) - Directing work based on context - -## Choosing Your Approach - -The key factors to consider: - -- **Flexibility vs Control** - How much freedom does the LLM need vs how tightly must you constrain its actions? -- **Error Tolerance** - What are the consequences of mistakes in your use case? -- **Cost Considerations** - More complex systems typically mean more LLM calls and higher costs -- **Maintenance** - Simpler architectures are easier to debug and modify - -**Start with the simplest approach that meets your needs**. Add complexity only when required by: - -1. Breaking down tasks into clear steps -2. Adding tools for specific capabilities -3. Implementing feedback loops for quality control -4. Introducing multiple agents for complex workflows - -Let's look at examples of these patterns in action. - -## Patterns with Examples - -The following patterns, adapted from [Anthropic's guide on building effective agents](https://www.anthropic.com/research/building-effective-agents), serve as building blocks that can be combined to create comprehensive workflows. Each pattern addresses specific aspects of task execution, and by combining them thoughtfully, you can build reliable solutions for complex problems. - -### Sequential Processing (Chains) - -The simplest workflow pattern executes steps in a predefined order. Each step's output becomes input for the next step, creating a clear chain of operations. This pattern is ideal for tasks with well-defined sequences, like content generation pipelines or data transformation processes. - -```ts -import { openai } from '@ai-sdk/openai'; -import { generateText, generateObject } from 'ai'; -import { z } from 'zod'; - -async function generateMarketingCopy(input: string) { - const model = openai('gpt-4o'); - - // First step: Generate marketing copy - const { text: copy } = await generateText({ - model, - prompt: `Write persuasive marketing copy for: ${input}. Focus on benefits and emotional appeal.`, - }); - - // Perform quality check on copy - const { object: qualityMetrics } = await generateObject({ - model, - schema: z.object({ - hasCallToAction: z.boolean(), - emotionalAppeal: z.number().min(1).max(10), - clarity: z.number().min(1).max(10), - }), - prompt: `Evaluate this marketing copy for: - 1. Presence of call to action (true/false) - 2. Emotional appeal (1-10) - 3. Clarity (1-10) - - Copy to evaluate: ${copy}`, - }); - - // If quality check fails, regenerate with more specific instructions - if ( - !qualityMetrics.hasCallToAction || - qualityMetrics.emotionalAppeal < 7 || - qualityMetrics.clarity < 7 - ) { - const { text: improvedCopy } = await generateText({ - model, - prompt: `Rewrite this marketing copy with: - ${!qualityMetrics.hasCallToAction ? '- A clear call to action' : ''} - ${qualityMetrics.emotionalAppeal < 7 ? '- Stronger emotional appeal' : ''} - ${qualityMetrics.clarity < 7 ? '- Improved clarity and directness' : ''} - - Original copy: ${copy}`, - }); - return { copy: improvedCopy, qualityMetrics }; - } - - return { copy, qualityMetrics }; -} -``` - -### Routing - -This pattern allows the model to make decisions about which path to take through a workflow based on context and intermediate results. The model acts as an intelligent router, directing the flow of execution between different branches of your workflow. This is particularly useful when handling varied inputs that require different processing approaches. In the example below, the results of the first LLM call change the properties of the second LLM call like model size and system prompt. - -```ts -import { openai } from '@ai-sdk/openai'; -import { generateObject, generateText } from 'ai'; -import { z } from 'zod'; - -async function handleCustomerQuery(query: string) { - const model = openai('gpt-4o'); - - // First step: Classify the query type - const { object: classification } = await generateObject({ - model, - schema: z.object({ - reasoning: z.string(), - type: z.enum(['general', 'refund', 'technical']), - complexity: z.enum(['simple', 'complex']), - }), - prompt: `Classify this customer query: - ${query} - - Determine: - 1. Query type (general, refund, or technical) - 2. Complexity (simple or complex) - 3. Brief reasoning for classification`, - }); - - // Route based on classification - // Set model and system prompt based on query type and complexity - const { text: response } = await generateText({ - model: - classification.complexity === 'simple' - ? openai('gpt-4o-mini') - : openai('o3-mini'), - system: { - general: - 'You are an expert customer service agent handling general inquiries.', - refund: - 'You are a customer service agent specializing in refund requests. Follow company policy and collect necessary information.', - technical: - 'You are a technical support specialist with deep product knowledge. Focus on clear step-by-step troubleshooting.', - }[classification.type], - prompt: query, - }); - - return { response, classification }; -} -``` - -### Parallel Processing - -Some tasks can be broken down into independent subtasks that can be executed simultaneously. This pattern takes advantage of parallel execution to improve efficiency while maintaining the benefits of structured workflows. For example, analyzing multiple documents or processing different aspects of a single input concurrently (like code review). - -```ts -import { openai } from '@ai-sdk/openai'; -import { generateText, generateObject } from 'ai'; -import { z } from 'zod'; - -// Example: Parallel code review with multiple specialized reviewers -async function parallelCodeReview(code: string) { - const model = openai('gpt-4o'); - - // Run parallel reviews - const [securityReview, performanceReview, maintainabilityReview] = - await Promise.all([ - generateObject({ - model, - system: - 'You are an expert in code security. Focus on identifying security vulnerabilities, injection risks, and authentication issues.', - schema: z.object({ - vulnerabilities: z.array(z.string()), - riskLevel: z.enum(['low', 'medium', 'high']), - suggestions: z.array(z.string()), - }), - prompt: `Review this code: - ${code}`, - }), - - generateObject({ - model, - system: - 'You are an expert in code performance. Focus on identifying performance bottlenecks, memory leaks, and optimization opportunities.', - schema: z.object({ - issues: z.array(z.string()), - impact: z.enum(['low', 'medium', 'high']), - optimizations: z.array(z.string()), - }), - prompt: `Review this code: - ${code}`, - }), - - generateObject({ - model, - system: - 'You are an expert in code quality. Focus on code structure, readability, and adherence to best practices.', - schema: z.object({ - concerns: z.array(z.string()), - qualityScore: z.number().min(1).max(10), - recommendations: z.array(z.string()), - }), - prompt: `Review this code: - ${code}`, - }), - ]); - - const reviews = [ - { ...securityReview.object, type: 'security' }, - { ...performanceReview.object, type: 'performance' }, - { ...maintainabilityReview.object, type: 'maintainability' }, - ]; - - // Aggregate results using another model instance - const { text: summary } = await generateText({ - model, - system: 'You are a technical lead summarizing multiple code reviews.', - prompt: `Synthesize these code review results into a concise summary with key actions: - ${JSON.stringify(reviews, null, 2)}`, - }); - - return { reviews, summary }; -} -``` - -### Orchestrator-Worker - -In this pattern, a primary model (orchestrator) coordinates the execution of specialized workers. Each worker is optimized for a specific subtask, while the orchestrator maintains overall context and ensures coherent results. This pattern excels at complex tasks requiring different types of expertise or processing. - -```ts -import { openai } from '@ai-sdk/openai'; -import { generateObject } from 'ai'; -import { z } from 'zod'; - -async function implementFeature(featureRequest: string) { - // Orchestrator: Plan the implementation - const { object: implementationPlan } = await generateObject({ - model: openai('o3-mini'), - schema: z.object({ - files: z.array( - z.object({ - purpose: z.string(), - filePath: z.string(), - changeType: z.enum(['create', 'modify', 'delete']), - }), - ), - estimatedComplexity: z.enum(['low', 'medium', 'high']), - }), - system: - 'You are a senior software architect planning feature implementations.', - prompt: `Analyze this feature request and create an implementation plan: - ${featureRequest}`, - }); - - // Workers: Execute the planned changes - const fileChanges = await Promise.all( - implementationPlan.files.map(async file => { - // Each worker is specialized for the type of change - const workerSystemPrompt = { - create: - 'You are an expert at implementing new files following best practices and project patterns.', - modify: - 'You are an expert at modifying existing code while maintaining consistency and avoiding regressions.', - delete: - 'You are an expert at safely removing code while ensuring no breaking changes.', - }[file.changeType]; - - const { object: change } = await generateObject({ - model: openai('gpt-4o'), - schema: z.object({ - explanation: z.string(), - code: z.string(), - }), - system: workerSystemPrompt, - prompt: `Implement the changes for ${file.filePath} to support: - ${file.purpose} - - Consider the overall feature context: - ${featureRequest}`, - }); - - return { - file, - implementation: change, - }; - }), - ); - - return { - plan: implementationPlan, - changes: fileChanges, - }; -} -``` - -### Evaluator-Optimizer - -This pattern introduces quality control into workflows by having dedicated evaluation steps that assess intermediate results. Based on the evaluation, the workflow can either proceed, retry with adjusted parameters, or take corrective action. This creates more robust workflows capable of self-improvement and error recovery. - -```ts -import { openai } from '@ai-sdk/openai'; -import { generateText, generateObject } from 'ai'; -import { z } from 'zod'; - -async function translateWithFeedback(text: string, targetLanguage: string) { - let currentTranslation = ''; - let iterations = 0; - const MAX_ITERATIONS = 3; - - // Initial translation - const { text: translation } = await generateText({ - model: openai('gpt-4o-mini'), // use small model for first attempt - system: 'You are an expert literary translator.', - prompt: `Translate this text to ${targetLanguage}, preserving tone and cultural nuances: - ${text}`, - }); - - currentTranslation = translation; - - // Evaluation-optimization loop - while (iterations < MAX_ITERATIONS) { - // Evaluate current translation - const { object: evaluation } = await generateObject({ - model: openai('gpt-4o'), // use a larger model to evaluate - schema: z.object({ - qualityScore: z.number().min(1).max(10), - preservesTone: z.boolean(), - preservesNuance: z.boolean(), - culturallyAccurate: z.boolean(), - specificIssues: z.array(z.string()), - improvementSuggestions: z.array(z.string()), - }), - system: 'You are an expert in evaluating literary translations.', - prompt: `Evaluate this translation: - - Original: ${text} - Translation: ${currentTranslation} - - Consider: - 1. Overall quality - 2. Preservation of tone - 3. Preservation of nuance - 4. Cultural accuracy`, - }); - - // Check if quality meets threshold - if ( - evaluation.qualityScore >= 8 && - evaluation.preservesTone && - evaluation.preservesNuance && - evaluation.culturallyAccurate - ) { - break; - } - - // Generate improved translation based on feedback - const { text: improvedTranslation } = await generateText({ - model: openai('gpt-4o'), // use a larger model - system: 'You are an expert literary translator.', - prompt: `Improve this translation based on the following feedback: - ${evaluation.specificIssues.join('\n')} - ${evaluation.improvementSuggestions.join('\n')} - - Original: ${text} - Current Translation: ${currentTranslation}`, - }); - - currentTranslation = improvedTranslation; - iterations++; - } - - return { - finalTranslation: currentTranslation, - iterationsRequired: iterations, - }; -} -``` - -## Multi-Step Tool Usage - -If your use case involves solving problems where the solution path is poorly defined or too complex to map out as a workflow in advance, you may want to provide the LLM with a set of lower-level tools and allow it to break down the task into small pieces that it can solve on its own iteratively, without discrete instructions. To implement this kind of agentic pattern, you need to call an LLM in a loop until a task is complete. The AI SDK makes this simple with the `stopWhen` parameter. - -The AI SDK gives you control over the stopping conditions, enabling you to keep the LLM running until one of the conditions are met. The SDK automatically triggers an additional request to the model after every tool result (each request is considered a "step"), continuing until the model does not generate a tool call or other stopping conditions (e.g. `stepCountIs`) you define are satisfied. - -`stopWhen` can be used with both `generateText` and `streamText` - -### Using `stopWhen` - -This example demonstrates how to create an agent that solves math problems. -It has a calculator tool (using [math.js](https://mathjs.org/)) that it can call to evaluate mathematical expressions. - -```ts file='main.ts' -import { openai } from '@ai-sdk/openai'; -import { generateText, tool, stepCountIs } from 'ai'; -import * as mathjs from 'mathjs'; -import { z } from 'zod'; - -const { text: answer } = await generateText({ - model: openai('gpt-4o-2024-08-06'), - tools: { - calculate: tool({ - description: - 'A tool for evaluating mathematical expressions. ' + - 'Example expressions: ' + - "'1.2 * (2 + 4.5)', '12.7 cm to inch', 'sin(45 deg) ^ 2'.", - inputSchema: z.object({ expression: z.string() }), - execute: async ({ expression }) => mathjs.evaluate(expression), - }), - }, - stopWhen: stepCountIs(10), - system: - 'You are solving math problems. ' + - 'Reason step by step. ' + - 'Use the calculator when necessary. ' + - 'When you give the final answer, ' + - 'provide an explanation for how you arrived at it.', - prompt: - 'A taxi driver earns $9461 per 1-hour of work. ' + - 'If he works 12 hours a day and in 1 hour ' + - 'he uses 12 liters of petrol with a price of $134 for 1 liter. ' + - 'How much money does he earn in one day?', -}); - -console.log(`ANSWER: ${answer}`); -``` - -### Structured Answers - -When building an agent for tasks like mathematical analysis or report generation, it's often useful to have the agent's final output structured in a consistent format that your application can process. You can use an **answer tool** and the `toolChoice: 'required'` setting to force the LLM to answer with a structured output that matches the schema of the answer tool. The answer tool has no `execute` function, so invoking it will terminate the agent. - -```ts highlight="6,16-29,31,45" -import { openai } from '@ai-sdk/openai'; -import { generateText, tool, stepCountIs } from 'ai'; -import 'dotenv/config'; -import { z } from 'zod'; - -const { toolCalls } = await generateText({ - model: openai('gpt-4o-2024-08-06'), - tools: { - calculate: tool({ - description: - 'A tool for evaluating mathematical expressions. Example expressions: ' + - "'1.2 * (2 + 4.5)', '12.7 cm to inch', 'sin(45 deg) ^ 2'.", - inputSchema: z.object({ expression: z.string() }), - execute: async ({ expression }) => mathjs.evaluate(expression), - }), - // answer tool: the LLM will provide a structured answer - answer: tool({ - description: 'A tool for providing the final answer.', - inputSchema: z.object({ - steps: z.array( - z.object({ - calculation: z.string(), - reasoning: z.string(), - }), - ), - answer: z.string(), - }), - // no execute function - invoking it will terminate the agent - }), - }, - toolChoice: 'required', - stopWhen: stepCountIs(10), - system: - 'You are solving math problems. ' + - 'Reason step by step. ' + - 'Use the calculator when necessary. ' + - 'The calculator can only do simple additions, subtractions, multiplications, and divisions. ' + - 'When you give the final answer, provide an explanation for how you got it.', - prompt: - 'A taxi driver earns $9461 per 1-hour work. ' + - 'If he works 12 hours a day and in 1 hour he uses 14-liters petrol with price $134 for 1-liter. ' + - 'How much money does he earn in one day?', -}); - -console.log(`FINAL TOOL CALLS: ${JSON.stringify(toolCalls, null, 2)}`); -``` - - - You can also use the - [`experimental_output`](/docs/ai-sdk-core/generating-structured-data#structured-output-with-generatetext) - setting for `generateText` to generate structured outputs. - - -### Accessing all steps - -Calling `generateText` with `stopWhen` can result in several calls to the LLM (steps). -You can access information from all steps by using the `steps` property of the response. - -```ts highlight="3,9-10" -import { generateText, stepCountIs } from 'ai'; - -const { steps } = await generateText({ - model: openai('gpt-4o'), - stopWhen: stepCountIs(10), - // ... -}); - -// extract all tool calls from the steps: -const allToolCalls = steps.flatMap(step => step.toolCalls); -``` - -### Getting notified on each completed step - -You can use the `onStepFinish` callback to get notified on each completed step. -It is triggered when a step is finished, -i.e. all text deltas, tool calls, and tool results for the step are available. - -```tsx highlight="6-8" -import { generateText, stepCountIs } from 'ai'; - -const result = await generateText({ - model: 'openai/gpt-4.1', - stopWhen: stepCountIs(10), - onStepFinish({ text, toolCalls, toolResults, finishReason, usage }) { - // your own logic, e.g. for saving the chat history or recording usage - }, - // ... -}); -``` diff --git a/content/docs/03-agents/01-overview.mdx b/content/docs/03-agents/01-overview.mdx index d5dc16313c55..4e65df2f64d4 100644 --- a/content/docs/03-agents/01-overview.mdx +++ b/content/docs/03-agents/01-overview.mdx @@ -1,5 +1,5 @@ --- -title: Agents +title: Overview description: Learn how to build agents with the AI SDK. --- From 6cc9cd0e44035e40b1dab7971e673b8703f75758 Mon Sep 17 00:00:00 2001 From: Alex Ker Date: Wed, 17 Sep 2025 18:22:46 -0400 Subject: [PATCH 053/121] feat(baseten): Add Baseten as a Provider to AI SDK providers (#8136) ## Summary This change adds Baseten to the AI SDK providers list. The provider supports: - **Model APIs**: OpenAI-compatible chat models via default inference endpoints - **Custom Deployments**: Dedicated model deployments with /sync/v1 endpoints - **High-Performance Embeddings**: 12x faster embedding generation via Baseten's Performance Client Users can import `@ai-sdk/baseten` and access all Baseten capabilities through a consistent interface. ## Manual Verification - 24/24 unit tests passing (mocked API responses) - 12/12 integration tests passing (real API calls with embeddings + chat) - Tested both /sync and /sync/v1 endpoint formats - Verified Performance Client integration for embeddings - Internal review by Baseten engineering team ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) --------- Co-authored-by: Lars Grammel Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> Co-authored-by: AlexKer --- .changeset/quiet-pens-suffer.md | 5 + .../01-ai-sdk-providers/170-baseten.mdx | 242 ++++++++++ examples/ai-core/package.json | 1 + examples/ai-core/src/embed-many/baseten.ts | 31 ++ examples/ai-core/src/embed/baseten.ts | 25 ++ .../src/generate-text/baseten-custom-url.ts | 24 + examples/ai-core/src/generate-text/baseten.ts | 17 + packages/baseten/.prettierignore | 4 + packages/baseten/README.md | 35 ++ packages/baseten/package.json | 67 +++ packages/baseten/src/baseten-chat-options.ts | 13 + .../baseten/src/baseten-embedding-options.ts | 12 + packages/baseten/src/baseten-provider.ts | 234 ++++++++++ .../baseten/src/baseten-provider.unit.test.ts | 415 ++++++++++++++++++ packages/baseten/src/index.ts | 7 + packages/baseten/tsconfig.build.json | 7 + packages/baseten/tsconfig.json | 23 + packages/baseten/tsup.config.ts | 10 + packages/baseten/turbo.json | 8 + packages/baseten/vitest.edge.config.js | 10 + packages/baseten/vitest.node.config.js | 10 + pnpm-lock.yaml | 171 ++++++++ tsconfig.json | 1 + 23 files changed, 1372 insertions(+) create mode 100644 .changeset/quiet-pens-suffer.md create mode 100644 content/providers/01-ai-sdk-providers/170-baseten.mdx create mode 100644 examples/ai-core/src/embed-many/baseten.ts create mode 100644 examples/ai-core/src/embed/baseten.ts create mode 100644 examples/ai-core/src/generate-text/baseten-custom-url.ts create mode 100644 examples/ai-core/src/generate-text/baseten.ts create mode 100644 packages/baseten/.prettierignore create mode 100644 packages/baseten/README.md create mode 100644 packages/baseten/package.json create mode 100644 packages/baseten/src/baseten-chat-options.ts create mode 100644 packages/baseten/src/baseten-embedding-options.ts create mode 100644 packages/baseten/src/baseten-provider.ts create mode 100644 packages/baseten/src/baseten-provider.unit.test.ts create mode 100644 packages/baseten/src/index.ts create mode 100644 packages/baseten/tsconfig.build.json create mode 100644 packages/baseten/tsconfig.json create mode 100644 packages/baseten/tsup.config.ts create mode 100644 packages/baseten/turbo.json create mode 100644 packages/baseten/vitest.edge.config.js create mode 100644 packages/baseten/vitest.node.config.js diff --git a/.changeset/quiet-pens-suffer.md b/.changeset/quiet-pens-suffer.md new file mode 100644 index 000000000000..6cb27771fc32 --- /dev/null +++ b/.changeset/quiet-pens-suffer.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/baseten': major +--- + +Added Baseten as a Provider for AI SDK diff --git a/content/providers/01-ai-sdk-providers/170-baseten.mdx b/content/providers/01-ai-sdk-providers/170-baseten.mdx new file mode 100644 index 000000000000..e20a7567b290 --- /dev/null +++ b/content/providers/01-ai-sdk-providers/170-baseten.mdx @@ -0,0 +1,242 @@ +--- +title: Baseten +description: Learn how to use Baseten models with the AI SDK. +--- + +# Baseten Provider + +[Baseten](https://baseten.co/) is an inference platform for serving frontier, enterprise-grade open source AI models[API](https://docs.baseten.co/overview). + +## Setup + +The Baseten provider is available via the `@ai-sdk/baseten` module. You can install it with + + + + + + + + + + + + + +## Provider Instance + +You can import the default provider instance `baseten` from `@ai-sdk/baseten`: + +```ts +import { baseten } from '@ai-sdk/baseten'; +``` + +If you need a customized setup, you can import `createBaseten` from `@ai-sdk/baseten` +and create a provider instance with your settings: + +```ts +import { createBaseten } from '@ai-sdk/baseten'; + +const baseten = createBaseten({ + apiKey: process.env.BASETEN_API_KEY ?? '', +}); +``` + +You can use the following optional settings to customize the Baseten provider instance: + +- **baseURL** _string_ + + Use a different URL prefix for API calls, e.g. to use proxy servers. + The default prefix is `https://inference.baseten.co/v1`. + +- **apiKey** _string_ + + API key that is being sent using the `Authorization` header. It defaults to + the `BASETEN_API_KEY` environment variable. It is recommended you set the environment variable using `export` so you do not need to include the field everytime. + You can grab your Baseten API Key [here](https://app.baseten.co/settings/api_keys) + +- **modelURL** _string_ + + Custom model URL for specific models (chat or embeddings). If not provided, + the default Models API will be used. + +- **headers** _Record<string,string>_ + + Custom headers to include in the requests. + +- **fetch** _(input: RequestInfo, init?: RequestInit) => Promise<Response>_ + + Custom [fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) implementation. + +## Models API + +You can select [Baseten models](https://www.baseten.co/products/model-apis/) using a provider instance. +The first argument is the model id, e.g. `'deepseek-ai/DeepSeek-V3-0324'`: The complete supported models under models API can be found [here](https://docs.baseten.co/development/model-apis/overview#supported-models). + +```ts +const model = baseten('deepseek-ai/Deepseek-V3-0324'); +``` + +### Example + +You can use Baseten language models to generate text with the `generateText` function: + +```ts +import { baseten } from '@ai-sdk/baseten'; +import { generateText } from 'ai'; + +const { text } = await generateText({ + model: baseten('deepseek-ai/Deepseek-V3-0324'), + prompt: 'What is the meaning of life? Answer in one sentence.', +}); +``` + +Baseten language models can also be used in the `streamText` function +(see [AI SDK Core](/docs/ai-sdk-core)). + +## Dedicated Models + +Baseten supports dedicated model URLs for both chat and embedding models. You have to specify a `modelURL` when creating the provider: + +### OpenAI-Compatible Endpoints (`/sync/v1`) + +For models deployed with Baseten's OpenAI-compatible endpoints: + +```ts +import { createBaseten } from '@ai-sdk/baseten'; + +const baseten = createBaseten({ + modelURL: 'https://model-{MODEL_ID}.api.baseten.co/sync/v1', +}); +// No modelId is needed because we specified modelURL +const model = baseten(); +const { text } = await generateText({ + model: customChatModel as any, + prompt: 'Say hello from the OpenAI-compatible chat model!', +}); +``` + +### `/predict` Endpoints + +`/predict` endpoints are currently NOT supported for chat models. You must use `/sync/v1` endpoints for chat functionality. + +## Embedding Models + +You can create models that call the Baseten embeddings API using the `.textEmbeddingModel()` factory method. The Baseten provider uses the high-performance `@basetenlabs/performance-client` for optimal embedding performance. + +```ts +import { createBaseten } from '@ai-sdk/baseten'; +import { embed, embedMany } from 'ai'; + +const baseten = createBaseten({ + modelURL: 'https://model-{MODEL_ID}.api.baseten.co/sync', +}); + +const embeddingModel = baseten.textEmbeddingModel(); + +// Single embedding +const { embedding } = await embed({ + model: embeddingModel, + value: 'sunny day at the beach', +}); + +// Batch embeddings +const { embeddings } = await embedMany({ + model: embeddingModel, + values: [ + 'sunny day at the beach', + 'rainy afternoon in the city', + 'snowy mountain peak', + ], +}); +``` + +### Endpoint Support for Embeddings + +**Supported:** + +- `/sync` endpoints (Performance Client automatically adds `/v1/embeddings`) +- `/sync/v1` endpoints (automatically strips `/v1` before passing to Performance Client) + +**Not Supported:** + +- `/predict` endpoints (not compatible with Performance Client) + +### Performance Features + +The embedding implementation includes: + +- **High-performance client**: Uses `@basetenlabs/performance-client` for optimal performance +- **Automatic batching**: Efficiently handles multiple texts in a single request +- **Connection reuse**: Performance Client is created once and reused for all requests +- **Built-in retries**: Automatic retry logic for failed requests + +## Error Handling + +The Baseten provider includes built-in error handling for common API errors: + +```ts +import { baseten } from '@ai-sdk/baseten'; +import { generateText } from 'ai'; + +try { + const { text } = await generateText({ + model: baseten('deepseek-ai/DeepSeek-V3-0324'), + prompt: 'Hello, world!', + }); +} catch (error) { + console.error('Baseten API error:', error.message); +} +``` + +### Common Error Scenarios + +```ts +// Embeddings require a modelURL +try { + baseten.textEmbeddingModel(); +} catch (error) { + // Error: "No model URL provided for embeddings. Please set modelURL option for embeddings." +} + +// /predict endpoints are not supported for chat models +try { + const baseten = createBaseten({ + modelURL: + 'https://model-{MODEL_ID}.api.baseten.co/environments/production/predict', + }); + baseten(); // This will throw an error +} catch (error) { + // Error: "Not supported. You must use a /sync/v1 endpoint for chat models." +} + +// /sync/v1 endpoints are now supported for embeddings +const baseten = createBaseten({ + modelURL: + 'https://model-{MODEL_ID}.api.baseten.co/environments/production/sync/v1', +}); +const embeddingModel = baseten.textEmbeddingModel(); // This works fine! + +// /predict endpoints are not supported for embeddings +try { + const baseten = createBaseten({ + modelURL: + 'https://model-{MODEL_ID}.api.baseten.co/environments/production/predict', + }); + baseten.textEmbeddingModel(); // This will throw an error +} catch (error) { + // Error: "Not supported. You must use a /sync or /sync/v1 endpoint for embeddings." +} + +// Image models are not supported +try { + baseten.imageModel('test-model'); +} catch (error) { + // Error: NoSuchModelError for imageModel +} +``` + + + For more information about Baseten models and deployment options, see the + [Baseten documentation](https://docs.baseten.co/). + diff --git a/examples/ai-core/package.json b/examples/ai-core/package.json index 3c94cc4f3f75..5d30a9118bb3 100644 --- a/examples/ai-core/package.json +++ b/examples/ai-core/package.json @@ -7,6 +7,7 @@ "@ai-sdk/anthropic": "workspace:*", "@ai-sdk/assemblyai": "workspace:*", "@ai-sdk/azure": "workspace:*", + "@ai-sdk/baseten": "workspace:*", "@ai-sdk/cerebras": "workspace:*", "@ai-sdk/cohere": "workspace:*", "@ai-sdk/deepgram": "workspace:*", diff --git a/examples/ai-core/src/embed-many/baseten.ts b/examples/ai-core/src/embed-many/baseten.ts new file mode 100644 index 000000000000..af2147d3a9c2 --- /dev/null +++ b/examples/ai-core/src/embed-many/baseten.ts @@ -0,0 +1,31 @@ +import { createBaseten } from '@ai-sdk/baseten'; +import { embedMany } from 'ai'; +import 'dotenv/config'; + +async function main() { + // Using Performance Client with custom model URL for batch embeddings + // Performance Client automatically handles batching and parallel processing + const EMBEDDING_MODEL_ID = ''; // e.g. 03y7n6e3 + const EMBEDDING_MODEL_URL = `https://model-${EMBEDDING_MODEL_ID}.api.baseten.co/environments/production/sync`; + + const baseten = createBaseten({ + modelURL: EMBEDDING_MODEL_URL, + }); + + const { embeddings, usage } = await embedMany({ + model: baseten.textEmbeddingModel(), + values: [ + 'sunny day at the beach', + 'rainy afternoon in the city', + 'snowy mountain peak', + 'foggy morning in the forest', + ], + }); + + console.log('Number of embeddings:', embeddings.length); + console.log('Embedding dimension:', embeddings[0].length); + console.log('First embedding (first 5 values):', embeddings[0].slice(0, 5)); + console.log('Usage:', usage); +} + +main().catch(console.error); diff --git a/examples/ai-core/src/embed/baseten.ts b/examples/ai-core/src/embed/baseten.ts new file mode 100644 index 000000000000..9732bc719e9a --- /dev/null +++ b/examples/ai-core/src/embed/baseten.ts @@ -0,0 +1,25 @@ +import { createBaseten } from '@ai-sdk/baseten'; +import { embed } from 'ai'; +import 'dotenv/config'; + +async function main() { + // Using Performance Client with custom model URL for embeddings + // Performance Client requires /sync endpoints and handles batching automatically + const EMBEDDING_MODEL_ID = ''; // e.g. 03y7n6e3 + const EMBEDDING_MODEL_URL = `https://model-${EMBEDDING_MODEL_ID}.api.baseten.co/environments/production/sync`; + + const baseten = createBaseten({ + modelURL: EMBEDDING_MODEL_URL, + }); + + const { embedding, usage } = await embed({ + model: baseten.textEmbeddingModel(), + value: 'sunny day at the beach', + }); + + console.log('Embedding dimension:', embedding.length); + console.log('First 5 values:', embedding.slice(0, 5)); + console.log('Usage:', usage); +} + +main().catch(console.error); diff --git a/examples/ai-core/src/generate-text/baseten-custom-url.ts b/examples/ai-core/src/generate-text/baseten-custom-url.ts new file mode 100644 index 000000000000..eb28de86ae9f --- /dev/null +++ b/examples/ai-core/src/generate-text/baseten-custom-url.ts @@ -0,0 +1,24 @@ +import { createBaseten } from '@ai-sdk/baseten'; +import { generateText } from 'ai'; +import 'dotenv/config'; + +async function main() { + // Using custom model URL for chat/text generation + const CHAT_MODEL_ID = ''; // e.g. 6wg17egw + const CHAT_MODEL_URL = `https://model-${CHAT_MODEL_ID}.api.baseten.co/environments/production/sync/v1`; + + const baseten = createBaseten({ + modelURL: CHAT_MODEL_URL, + }); + + const { text, usage } = await generateText({ + model: baseten.languageModel(), + prompt: 'Explain quantum computing in simple terms.', + }); + + console.log(text); + console.log(); + console.log('Usage:', usage); +} + +main().catch(console.error); diff --git a/examples/ai-core/src/generate-text/baseten.ts b/examples/ai-core/src/generate-text/baseten.ts new file mode 100644 index 000000000000..c9426301fb9a --- /dev/null +++ b/examples/ai-core/src/generate-text/baseten.ts @@ -0,0 +1,17 @@ +import { baseten } from '@ai-sdk/baseten'; +import { generateText } from 'ai'; +import 'dotenv/config'; + +async function main() { + // Using default Model APIs - works with hosted models on Baseten + const { text, usage } = await generateText({ + model: baseten('deepseek-ai/DeepSeek-V3-0324'), + prompt: 'What is the meaning of life? Answer in one sentence.', + }); + + console.log(text); + console.log(); + console.log('Usage:', usage); +} + +main().catch(console.error); diff --git a/packages/baseten/.prettierignore b/packages/baseten/.prettierignore new file mode 100644 index 000000000000..5e9e46f88301 --- /dev/null +++ b/packages/baseten/.prettierignore @@ -0,0 +1,4 @@ +dist/ +node_modules/ +*.tsbuildinfo +.turbo/ \ No newline at end of file diff --git a/packages/baseten/README.md b/packages/baseten/README.md new file mode 100644 index 000000000000..4de7a5d97110 --- /dev/null +++ b/packages/baseten/README.md @@ -0,0 +1,35 @@ +# AI SDK - Baseten Provider + +The **[Baseten provider](https://ai-sdk.dev/providers/ai-sdk-providers/baseten)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model and embedding model support for the [Baseten](https://baseten.co) platform. + +## Setup + +The Baseten provider is available in the `@ai-sdk/baseten` module. You can install it with + +```bash +npm i @ai-sdk/baseten +``` + +## Provider Instance + +You can import the default provider instance `baseten` from `@ai-sdk/baseten`: + +```ts +import { baseten } from '@ai-sdk/baseten'; +``` + +## Language Model Example (Model APIs) + +```ts +import { baseten } from '@ai-sdk/baseten'; +import { generateText } from 'ai'; + +const { text } = await generateText({ + model: baseten('deepseek-ai/DeepSeek-V3-0324'), + prompt: 'What is the meaning of life?', +}); +``` + +## Documentation + +Please check out the **[Baseten provider](https://ai-sdk.dev/providers/ai-sdk-providers/baseten)** for more information. diff --git a/packages/baseten/package.json b/packages/baseten/package.json new file mode 100644 index 000000000000..1d74580d814e --- /dev/null +++ b/packages/baseten/package.json @@ -0,0 +1,67 @@ +{ + "name": "@ai-sdk/baseten", + "version": "0.0.0", + "license": "Apache-2.0", + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist/**/*", + "CHANGELOG.md" + ], + "scripts": { + "build": "pnpm clean && tsup --tsconfig tsconfig.build.json", + "build:watch": "pnpm clean && tsup --watch", + "clean": "rm -rf dist *.tsbuildinfo", + "lint": "eslint \"./**/*.ts*\"", + "type-check": "tsc --build", + "prettier-check": "prettier --check \"./**/*.ts*\"", + "test": "pnpm test:node && pnpm test:edge", + "test:update": "pnpm test:node -u", + "test:watch": "vitest --config vitest.node.config.js", + "test:edge": "vitest --config vitest.edge.config.js --run", + "test:node": "vitest --config vitest.node.config.js --run" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + } + }, + "dependencies": { + "@ai-sdk/openai-compatible": "workspace:*", + "@ai-sdk/provider": "workspace:*", + "@ai-sdk/provider-utils": "workspace:*", + "@basetenlabs/performance-client": "^0.0.8" + }, + "devDependencies": { + "@types/node": "20.17.24", + "@vercel/ai-tsconfig": "workspace:*", + "tsup": "^8", + "typescript": "5.8.3", + "zod": "3.25.76" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4" + }, + "engines": { + "node": ">=18" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://ai-sdk.dev/docs", + "repository": { + "type": "git", + "url": "git+https://github.com/vercel/ai.git" + }, + "bugs": { + "url": "https://github.com/vercel/ai/issues" + }, + "keywords": [ + "ai" + ] +} diff --git a/packages/baseten/src/baseten-chat-options.ts b/packages/baseten/src/baseten-chat-options.ts new file mode 100644 index 000000000000..7fd66c228bd7 --- /dev/null +++ b/packages/baseten/src/baseten-chat-options.ts @@ -0,0 +1,13 @@ +// https://docs.baseten.co/development/model-apis/overview#supported-models +// Below is the current list of models supported by Baseten model APIs. +// Ohter dedicated models are also supported, but not listed here. +export type BasetenChatModelId = + | 'deepseek-ai/DeepSeek-R1-0528' + | 'deepseek-ai/DeepSeek-V3-0324' + | 'meta-llama/Llama-4-Maverick-17B-128E-Instruct' + | 'meta-llama/Llama-4-Scout-17B-16E-Instruct' + | 'moonshotai/Kimi-K2-Instruct' + | 'Qwen/Qwen3-235B-A22B-Instruct-2507' + | 'Qwen/Qwen3-Coder-480B-A35B-Instruct' + | 'openai/gpt-oss-120b' + | (string & {}); diff --git a/packages/baseten/src/baseten-embedding-options.ts b/packages/baseten/src/baseten-embedding-options.ts new file mode 100644 index 000000000000..d88e036ce51c --- /dev/null +++ b/packages/baseten/src/baseten-embedding-options.ts @@ -0,0 +1,12 @@ +import { z } from 'zod/v4'; + +// https://www.baseten.co/library/tag/embedding/ +// Pass in the model URL directly, we won't be using the model ID + +export type BasetenEmbeddingModelId = string & {}; + +export const basetenEmbeddingProviderOptions = z.object({}); + +export type BasetenEmbeddingProviderOptions = z.infer< + typeof basetenEmbeddingProviderOptions +>; diff --git a/packages/baseten/src/baseten-provider.ts b/packages/baseten/src/baseten-provider.ts new file mode 100644 index 000000000000..2b1aa54ee949 --- /dev/null +++ b/packages/baseten/src/baseten-provider.ts @@ -0,0 +1,234 @@ +import { + OpenAICompatibleChatLanguageModel, + OpenAICompatibleEmbeddingModel, + ProviderErrorStructure, +} from '@ai-sdk/openai-compatible'; +import { + EmbeddingModelV2, + LanguageModelV2, + NoSuchModelError, + ProviderV2, +} from '@ai-sdk/provider'; +import { + FetchFunction, + loadApiKey, + withoutTrailingSlash, +} from '@ai-sdk/provider-utils'; +import { z } from 'zod/v4'; +import { BasetenChatModelId } from './baseten-chat-options'; +import { BasetenEmbeddingModelId } from './baseten-embedding-options'; +import { PerformanceClient } from '@basetenlabs/performance-client'; + +export type BasetenErrorData = z.infer; + +const basetenErrorSchema = z.object({ + error: z.string(), +}); + +const basetenErrorStructure: ProviderErrorStructure = { + errorSchema: basetenErrorSchema, + errorToMessage: data => data.error, +}; + +export interface BasetenProviderSettings { + /** + * Baseten API key. Default value is taken from the `BASETEN_API_KEY` + * environment variable. + */ + apiKey?: string; + + /** + * Base URL for the Model APIs. Default: 'https://inference.baseten.co/v1' + */ + baseURL?: string; + + /** + * Model URL for custom models (chat or embeddings). + * If not supplied, the default Model APIs will be used. + */ + modelURL?: string; + /** + * Custom headers to include in the requests. + */ + headers?: Record; + + /** + * Custom fetch implementation. You can use it as a middleware to intercept requests, + * or to provide a custom fetch implementation for e.g. testing. + */ + fetch?: FetchFunction; +} + +export interface BasetenProvider extends ProviderV2 { + /** +Creates a chat model for text generation. +*/ + (modelId?: BasetenChatModelId): LanguageModelV2; + + /** +Creates a chat model for text generation. +*/ + chatModel(modelId?: BasetenChatModelId): LanguageModelV2; + + /** +Creates a language model for text generation. Alias for chatModel. +*/ + languageModel(modelId?: BasetenChatModelId): LanguageModelV2; + + /** +Creates a text embedding model for text generation. +*/ + textEmbeddingModel( + modelId?: BasetenEmbeddingModelId, + ): EmbeddingModelV2; +} + +// by default, we use the Model APIs +const defaultBaseURL = 'https://inference.baseten.co/v1'; + +export function createBaseten( + options: BasetenProviderSettings = {}, +): BasetenProvider { + const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL); + const getHeaders = () => ({ + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'BASETEN_API_KEY', + description: 'Baseten API key', + })}`, + ...options.headers, + }); + + interface CommonModelConfig { + provider: string; + url: ({ path }: { path: string }) => string; + headers: () => Record; + fetch?: FetchFunction; + } + + const getCommonModelConfig = ( + modelType: string, + customURL?: string, + ): CommonModelConfig => ({ + provider: `baseten.${modelType}`, + url: ({ path }) => { + // For embeddings with /sync URLs (but not /sync/v1), we need to add /v1 + if ( + modelType === 'embedding' && + customURL?.includes('/sync') && + !customURL?.includes('/sync/v1') + ) { + return `${customURL}/v1${path}`; + } + return `${customURL || baseURL}${path}`; + }, + headers: getHeaders, + fetch: options.fetch, + }); + + const createChatModel = (modelId?: BasetenChatModelId) => { + // Use modelURL if provided, otherwise use default Model APIs + const customURL = options.modelURL; + + if (customURL) { + // Check if this is a /sync/v1 endpoint (OpenAI-compatible) or /predict endpoint (custom) + const isOpenAICompatible = customURL.includes('/sync/v1'); + + if (isOpenAICompatible) { + // For /sync/v1 endpoints, use standard OpenAI-compatible format + return new OpenAICompatibleChatLanguageModel(modelId ?? 'placeholder', { + ...getCommonModelConfig('chat', customURL), + errorStructure: basetenErrorStructure, + }); + } else if (customURL.includes('/predict')) { + throw new Error( + 'Not supported. You must use a /sync/v1 endpoint for chat models.', + ); + } + } + + // Use default OpenAI-compatible format for Model APIs + return new OpenAICompatibleChatLanguageModel(modelId ?? 'chat', { + ...getCommonModelConfig('chat'), + errorStructure: basetenErrorStructure, + }); + }; + + const createTextEmbeddingModel = (modelId?: BasetenEmbeddingModelId) => { + // Use modelURL if provided + const customURL = options.modelURL; + if (!customURL) { + throw new Error( + 'No model URL provided for embeddings. Please set modelURL option for embeddings.', + ); + } + + // Check if this is a /sync or /sync/v1 endpoint (OpenAI-compatible) + // We support both /sync and /sync/v1, stripping /v1 before passing to Performance Client, as Performance Client adds /v1 itself + const isOpenAICompatible = customURL.includes('/sync'); + + if (isOpenAICompatible) { + // Create the model using OpenAICompatibleEmbeddingModel and override doEmbed + const model = new OpenAICompatibleEmbeddingModel( + modelId ?? 'embeddings', + { + ...getCommonModelConfig('embedding', customURL), + errorStructure: basetenErrorStructure, + }, + ); + + // Strip /v1 from URL if present before passing to Performance Client to avoid double /v1 + const performanceClientURL = customURL.replace('/sync/v1', '/sync'); + + // Initialize the B10 Performance Client once for reuse + const performanceClient = new PerformanceClient( + performanceClientURL, + loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'BASETEN_API_KEY', + description: 'Baseten API key', + }), + ); + + // Override the doEmbed method to use the pre-created Performance Client + model.doEmbed = async params => { + if (!params.values || !Array.isArray(params.values)) { + throw new Error('params.values must be an array of strings'); + } + + // Performance Client handles batching internally, so we don't need to limit in 128 here + const response = await performanceClient.embed( + params.values, + modelId ?? 'embeddings', // model_id is for Model APIs, we don't use it here for dedicated + ); + // Transform the response to match the expected format + const embeddings = response.data.map((item: any) => item.embedding); + + return { + embeddings: embeddings, + usage: response.usage + ? { tokens: response.usage.total_tokens } + : undefined, + response: { headers: {}, body: response }, + }; + }; + + return model; + } else { + throw new Error( + 'Not supported. You must use a /sync or /sync/v1 endpoint for embeddings.', + ); + } + }; + + const provider = (modelId?: BasetenChatModelId) => createChatModel(modelId); + provider.chatModel = createChatModel; + provider.languageModel = createChatModel; + provider.imageModel = (modelId: string) => { + throw new NoSuchModelError({ modelId, modelType: 'imageModel' }); + }; + provider.textEmbeddingModel = createTextEmbeddingModel; + return provider; +} + +export const baseten = createBaseten(); diff --git a/packages/baseten/src/baseten-provider.unit.test.ts b/packages/baseten/src/baseten-provider.unit.test.ts new file mode 100644 index 000000000000..1cee0f14c5a0 --- /dev/null +++ b/packages/baseten/src/baseten-provider.unit.test.ts @@ -0,0 +1,415 @@ +import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; +import { createBaseten } from './baseten-provider'; +import { + LanguageModelV2, + EmbeddingModelV2, + NoSuchModelError, +} from '@ai-sdk/provider'; +import { loadApiKey } from '@ai-sdk/provider-utils'; +import { + OpenAICompatibleChatLanguageModel, + OpenAICompatibleEmbeddingModel, +} from '@ai-sdk/openai-compatible'; + +// Mock the OpenAI-compatible classes +const OpenAICompatibleChatLanguageModelMock = + OpenAICompatibleChatLanguageModel as unknown as Mock; +const OpenAICompatibleEmbeddingModelMock = + OpenAICompatibleEmbeddingModel as unknown as Mock; + +vi.mock('@ai-sdk/openai-compatible', () => { + const createMockConstructor = (providerName: string) => { + const mockConstructor = vi.fn().mockImplementation(function ( + this: any, + modelId: string, + settings: any, + ) { + this.provider = providerName; + this.modelId = modelId; + this.settings = settings; + this.doGenerate = vi.fn(); + this.doEmbed = vi.fn(); + }); + return mockConstructor; + }; + + return { + OpenAICompatibleChatLanguageModel: createMockConstructor('baseten.chat'), + OpenAICompatibleEmbeddingModel: createMockConstructor('baseten.embedding'), + }; +}); + +vi.mock('@ai-sdk/provider-utils', () => ({ + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), +})); + +vi.mock('@basetenlabs/performance-client', () => ({ + PerformanceClient: vi.fn().mockImplementation(() => ({ + embed: vi.fn(), + embedBatch: vi.fn(), + })), +})); + +describe('BasetenProvider', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe('createBaseten', () => { + it('should create a BasetenProvider instance with default options', () => { + const provider = createBaseten(); + const model = provider.chatModel('deepseek-ai/DeepSeek-V3-0324'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + expect(loadApiKey).toHaveBeenCalledWith({ + apiKey: undefined, + environmentVariableName: 'BASETEN_API_KEY', + description: 'Baseten API key', + }); + expect(headers.Authorization).toBe('Bearer mock-api-key'); + expect(config.provider).toBe('baseten.chat'); + }); + + it('should create a BasetenProvider instance with custom options', () => { + const options = { + apiKey: 'custom-key', + baseURL: 'https://custom.url', + headers: { 'Custom-Header': 'value' }, + }; + const provider = createBaseten(options); + const model = provider.chatModel('deepseek-ai/DeepSeek-V3-0324'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + expect(loadApiKey).toHaveBeenCalledWith({ + apiKey: 'custom-key', + environmentVariableName: 'BASETEN_API_KEY', + description: 'Baseten API key', + }); + expect(headers['Custom-Header']).toBe('value'); + }); + + it('should support optional modelId parameter', () => { + const provider = createBaseten(); + + // Should work without modelId + const model1 = provider(); + expect(model1).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + + // Should work with modelId + const model2 = provider('deepseek-ai/DeepSeek-V3-0324'); + expect(model2).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + }); + }); + + describe('chatModel', () => { + it('should construct a chat model with correct configuration for default Model APIs', () => { + const provider = createBaseten(); + const modelId = 'deepseek-ai/DeepSeek-V3-0324'; + + const model = provider.chatModel(modelId); + + expect(model).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + expect(OpenAICompatibleChatLanguageModelMock).toHaveBeenCalledWith( + modelId, + expect.objectContaining({ + provider: 'baseten.chat', + errorStructure: expect.any(Object), + }), + ); + }); + + it('should construct a chat model with optional modelId', () => { + const provider = createBaseten(); + + // Should work without modelId + const model1 = provider.chatModel(); + expect(model1).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + expect(OpenAICompatibleChatLanguageModelMock).toHaveBeenCalledWith( + 'chat', + expect.any(Object), + ); + + // Should work with modelId + const model2 = provider.chatModel('deepseek-ai/DeepSeek-V3-0324'); + expect(model2).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + }); + + it('should handle /sync/v1 endpoints correctly', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/sync/v1', + }); + + const model = provider.chatModel(); + + expect(model).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + expect(OpenAICompatibleChatLanguageModelMock).toHaveBeenCalledWith( + 'placeholder', + expect.objectContaining({ + provider: 'baseten.chat', + url: expect.any(Function), + errorStructure: expect.any(Object), + }), + ); + + // Test URL construction + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const url = config.url({ path: '/chat/completions' }); + expect(url).toBe( + 'https://model-123.api.baseten.co/environments/production/sync/v1/chat/completions', + ); + }); + + it('should throw error for /predict endpoints with chat models', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/predict', + }); + + expect(() => { + provider.chatModel(); + }).toThrow( + 'Not supported. You must use a /sync/v1 endpoint for chat models.', + ); + }); + }); + + describe('languageModel', () => { + it('should be an alias for chatModel', () => { + const provider = createBaseten(); + const modelId = 'deepseek-ai/DeepSeek-V3-0324'; + + const chatModel = provider.chatModel(modelId); + const languageModel = provider.languageModel(modelId); + + expect(chatModel).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + expect(languageModel).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + }); + + it('should support optional modelId parameter', () => { + const provider = createBaseten(); + + const model1 = provider.languageModel(); + expect(model1).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + + const model2 = provider.languageModel('deepseek-ai/DeepSeek-V3-0324'); + expect(model2).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + }); + }); + + describe('textEmbeddingModel', () => { + it('should throw error when no modelURL is provided', () => { + const provider = createBaseten(); + + expect(() => { + provider.textEmbeddingModel(); + }).toThrow( + 'No model URL provided for embeddings. Please set modelURL option for embeddings.', + ); + }); + + it('should construct embedding model for /sync endpoints', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/sync', + }); + + const model = provider.textEmbeddingModel(); + + expect(model).toBeInstanceOf(OpenAICompatibleEmbeddingModel); + expect(OpenAICompatibleEmbeddingModelMock).toHaveBeenCalledWith( + 'embeddings', + expect.objectContaining({ + provider: 'baseten.embedding', + url: expect.any(Function), + errorStructure: expect.any(Object), + }), + ); + + // Test URL construction for embeddings (Performance Client adds /v1/embeddings) + const constructorCall = OpenAICompatibleEmbeddingModelMock.mock.calls[0]; + const config = constructorCall[1]; + const url = config.url({ path: '/embeddings' }); + expect(url).toBe( + 'https://model-123.api.baseten.co/environments/production/sync/v1/embeddings', + ); + }); + + it('should throw error for /predict endpoints (not supported with Performance Client)', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/predict', + }); + + expect(() => { + provider.textEmbeddingModel(); + }).toThrow( + 'Not supported. You must use a /sync or /sync/v1 endpoint for embeddings.', + ); + }); + + it('should support /sync/v1 endpoints (strips /v1 before passing to Performance Client)', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/sync/v1', + }); + + const model = provider.textEmbeddingModel(); + + expect(model).toBeInstanceOf(OpenAICompatibleEmbeddingModel); + expect(OpenAICompatibleEmbeddingModelMock).toHaveBeenCalledWith( + 'embeddings', + expect.any(Object), + ); + }); + + it('should support custom modelId for embeddings', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/sync', + }); + + const model = provider.textEmbeddingModel(); + + expect(model).toBeInstanceOf(OpenAICompatibleEmbeddingModel); + expect(OpenAICompatibleEmbeddingModelMock).toHaveBeenCalledWith( + 'embeddings', + expect.any(Object), + ); + }); + }); + + describe('imageModel', () => { + it('should throw NoSuchModelError for unsupported image models', () => { + const provider = createBaseten(); + + expect(() => { + provider.imageModel('test-model'); + }).toThrow(NoSuchModelError); + }); + }); + + describe('URL construction', () => { + it('should use default baseURL when no modelURL is provided', () => { + const provider = createBaseten(); + const model = provider.chatModel('test-model'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const url = config.url({ path: '/chat/completions' }); + expect(url).toBe('https://inference.baseten.co/v1/chat/completions'); + }); + + it('should use custom baseURL when provided', () => { + const provider = createBaseten({ + baseURL: 'https://custom.baseten.co/v1', + }); + const model = provider.chatModel('test-model'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const url = config.url({ path: '/chat/completions' }); + expect(url).toBe('https://custom.baseten.co/v1/chat/completions'); + }); + + it('should use modelURL for custom endpoints', () => { + const provider = createBaseten({ + modelURL: + 'https://model-123.api.baseten.co/environments/production/sync/v1', + }); + const model = provider.chatModel(); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const url = config.url({ path: '/chat/completions' }); + expect(url).toBe( + 'https://model-123.api.baseten.co/environments/production/sync/v1/chat/completions', + ); + }); + }); + + describe('Headers', () => { + it('should include Authorization header with API key', () => { + const provider = createBaseten(); + const model = provider.chatModel('test-model'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + expect(headers.Authorization).toBe('Bearer mock-api-key'); + }); + + it('should include custom headers when provided', () => { + const provider = createBaseten({ + headers: { 'Custom-Header': 'custom-value' }, + }); + const model = provider.chatModel('test-model'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + expect(headers.Authorization).toBe('Bearer mock-api-key'); + expect(headers['Custom-Header']).toBe('custom-value'); + }); + }); + + describe('Error handling', () => { + it('should handle missing modelURL for embeddings gracefully', () => { + const provider = createBaseten(); + + expect(() => { + provider.textEmbeddingModel(); + }).toThrow( + 'No model URL provided for embeddings. Please set modelURL option for embeddings.', + ); + }); + + it('should handle unsupported image models', () => { + const provider = createBaseten(); + + expect(() => { + provider.imageModel('unsupported-model'); + }).toThrow(NoSuchModelError); + }); + }); + + describe('Provider interface', () => { + it('should implement all required provider methods', () => { + const provider = createBaseten(); + + expect(typeof provider).toBe('function'); + expect(typeof provider.chatModel).toBe('function'); + expect(typeof provider.languageModel).toBe('function'); + expect(typeof provider.textEmbeddingModel).toBe('function'); + expect(typeof provider.imageModel).toBe('function'); + }); + + it('should allow calling provider as function', () => { + const provider = createBaseten(); + + const model1 = provider(); + expect(model1).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + + const model2 = provider('test-model'); + expect(model2).toBeInstanceOf(OpenAICompatibleChatLanguageModel); + }); + }); +}); diff --git a/packages/baseten/src/index.ts b/packages/baseten/src/index.ts new file mode 100644 index 000000000000..5eec4c4f4727 --- /dev/null +++ b/packages/baseten/src/index.ts @@ -0,0 +1,7 @@ +export type { BasetenChatModelId } from './baseten-chat-options'; +export { baseten, createBaseten } from './baseten-provider'; +export type { + BasetenProvider, + BasetenProviderSettings, + BasetenErrorData, +} from './baseten-provider'; diff --git a/packages/baseten/tsconfig.build.json b/packages/baseten/tsconfig.build.json new file mode 100644 index 000000000000..8181e407dd6d --- /dev/null +++ b/packages/baseten/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + // Disable project configuration for tsup builds + "composite": false + } +} diff --git a/packages/baseten/tsconfig.json b/packages/baseten/tsconfig.json new file mode 100644 index 000000000000..6c6ee8ebe46a --- /dev/null +++ b/packages/baseten/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "./node_modules/@vercel/ai-tsconfig/ts-library.json", + "compilerOptions": { + "composite": true, + "rootDir": "src", + "outDir": "dist" + }, + "exclude": ["dist", "build", "node_modules", "tsup.config.ts"], + "references": [ + { + "path": "../openai-compatible" + }, + { + "path": "../provider" + }, + { + "path": "../provider-utils" + }, + { + "path": "../ai" + } + ] +} diff --git a/packages/baseten/tsup.config.ts b/packages/baseten/tsup.config.ts new file mode 100644 index 000000000000..3f92041b987c --- /dev/null +++ b/packages/baseten/tsup.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig([ + { + entry: ['src/index.ts'], + format: ['cjs', 'esm'], + dts: true, + sourcemap: true, + }, +]); diff --git a/packages/baseten/turbo.json b/packages/baseten/turbo.json new file mode 100644 index 000000000000..3e50dc890ace --- /dev/null +++ b/packages/baseten/turbo.json @@ -0,0 +1,8 @@ +{ + "extends": ["//"], + "tasks": { + "build": { + "outputs": ["**/dist/**"] + } + } +} diff --git a/packages/baseten/vitest.edge.config.js b/packages/baseten/vitest.edge.config.js new file mode 100644 index 000000000000..700660e913f5 --- /dev/null +++ b/packages/baseten/vitest.edge.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + test: { + environment: 'edge-runtime', + globals: true, + include: ['**/*.test.ts', '**/*.test.tsx'], + }, +}); diff --git a/packages/baseten/vitest.node.config.js b/packages/baseten/vitest.node.config.js new file mode 100644 index 000000000000..b1d14b21fc11 --- /dev/null +++ b/packages/baseten/vitest.node.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + test: { + environment: 'node', + globals: true, + include: ['**/*.test.ts', '**/*.test.tsx'], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c7f4964fd3f..439a24a532a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,6 +74,9 @@ importers: '@ai-sdk/azure': specifier: workspace:* version: link:../../packages/azure + '@ai-sdk/baseten': + specifier: workspace:* + version: link:../../packages/baseten '@ai-sdk/cerebras': specifier: workspace:* version: link:../../packages/cerebras @@ -1577,6 +1580,37 @@ importers: specifier: 3.25.76 version: 3.25.76 + packages/baseten: + dependencies: + '@ai-sdk/openai-compatible': + specifier: workspace:* + version: link:../openai-compatible + '@ai-sdk/provider': + specifier: workspace:* + version: link:../provider + '@ai-sdk/provider-utils': + specifier: workspace:* + version: link:../provider-utils + '@basetenlabs/performance-client': + specifier: ^0.0.8 + version: 0.0.8 + devDependencies: + '@types/node': + specifier: 20.17.24 + version: 20.17.24 + '@vercel/ai-tsconfig': + specifier: workspace:* + version: link:../../tools/tsconfig + tsup: + specifier: ^8 + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) + typescript: + specifier: 5.8.3 + version: 5.8.3 + zod: + specifier: 3.25.76 + version: 3.25.76 + packages/cerebras: dependencies: '@ai-sdk/openai-compatible': @@ -3869,6 +3903,88 @@ packages: resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} engines: {node: '>=6.9.0'} + '@basetenlabs/performance-client-android-arm-eabi@0.0.8': + resolution: {integrity: sha512-Ej6UO02/QNQdFfjWJ/9jVrr0ThF24Bq4BL4fnljNcvfzbJGtsJFlkIUzT+waj+ORyUuZePQU5bB0+gA0IpUvfg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@basetenlabs/performance-client-android-arm64@0.0.8': + resolution: {integrity: sha512-yKKzSkK2+ktrZoZmObojURAJtY8JNILLC4RsNy07Cdp/fCzh9OTkknFoiOVXTspdILgBbvIkFbiJOkFZf9fiPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@basetenlabs/performance-client-darwin-arm64@0.0.8': + resolution: {integrity: sha512-6HVXSYtPrBmWP1Icmkn4ccuEUPJqXPUQyBiGzF6dn3RIF2YtRYYqfpIPeBmwDXfBs/AaOOM81MjNDVGlp5gNRw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@basetenlabs/performance-client-darwin-x64@0.0.8': + resolution: {integrity: sha512-A+YBOMR2DdSH6BCV/8xIDwu2KoxQGiVkwwrQygXNCTXuWC+KJNoQ2UoOUsXpWZyI0JB6nm6UuOMSfV3bFOe6EQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@basetenlabs/performance-client-linux-arm-gnueabihf@0.0.8': + resolution: {integrity: sha512-P4QNm7YiYitSvd2gbfbvSabdLQLrKCTU9lam+4JgcHNf19hd9HZLjfDiqmEZ9apAxuOcd+3xYnM2ukNRJwP4qQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@basetenlabs/performance-client-linux-arm-musleabihf@0.0.8': + resolution: {integrity: sha512-PFv2SH/sfN8my9lZs+TVKOAyNGmQNx9NRjmXAAyXbrz3/DEp5y87MSuAKtK9jklUyrlzFJPkKJLbpQnBvCg79g==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@basetenlabs/performance-client-linux-arm64-gnu@0.0.8': + resolution: {integrity: sha512-4srDdNhaTIPBTjfwNhlD2bIF4MEIDxtyGK1umOxFZOBR2Yr9LaOP5ZVrYhkKiSHTdd4MsaL8+hlNL26L54WxXQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@basetenlabs/performance-client-linux-riscv64-gnu@0.0.8': + resolution: {integrity: sha512-MRgQg07l0hN+lzbcKAcJc0D0hZDxhH+WrRDig/U4TlpsWBweHKhk//IFpIn/nzmMrp3hAVZLsM4nbQZ6SWxnKw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@basetenlabs/performance-client-linux-x64-gnu@0.0.8': + resolution: {integrity: sha512-msLwWKcPkJJdjGocn5YtSm+kAVcSeSH6VjwidmM9FeHi0YcNZuXHWoBf8gkfP4muXDek5Ml4PVWfgvz7zFA2zw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@basetenlabs/performance-client-linux-x64-musl@0.0.8': + resolution: {integrity: sha512-tI9UMpl+35nwSPeCib/b0ao/bV11ZtLYrJeHaI3GERnCYZDOUje1qrLac1gYdikIuJycKtvucfkMRjc6dGNy/w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@basetenlabs/performance-client-win32-arm64-msvc@0.0.8': + resolution: {integrity: sha512-IH76vdeRyouecsLLIHs07XsXs+GWf1GaGVqT3HtkmwF0DRKTeLAWgdhyBjQc1+cC1fE+cO8N9OHjsbD0u8/5yg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@basetenlabs/performance-client-win32-ia32-msvc@0.0.8': + resolution: {integrity: sha512-oIS68FvHqwLfIHmZ5FHxveVpg83nln8VFm9ED9+xvElqhrFcP58yqkg5YLbXyqmCKno0e6QbpIK0LqKGdRaI8g==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@basetenlabs/performance-client-win32-x64-msvc@0.0.8': + resolution: {integrity: sha512-HWkuf+E7Hdj7iPfIs9ibTJC2kMvuNfB9hfloJccCuA2LffpkMcqZ4wOamEwbFSCe6bQ5Dxik3RsBFIUbQsbL9Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@basetenlabs/performance-client@0.0.8': + resolution: {integrity: sha512-D6BbLwJCldgAhxMdNTO/HTZpyvxFtR6lUv9Ht3UPHPg06lrofoKryRWL1oZmeJw1z4yP34Lj4KpKqa+bpUB9HA==} + engines: {node: '>= 10'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -20548,6 +20664,61 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@basetenlabs/performance-client-android-arm-eabi@0.0.8': + optional: true + + '@basetenlabs/performance-client-android-arm64@0.0.8': + optional: true + + '@basetenlabs/performance-client-darwin-arm64@0.0.8': + optional: true + + '@basetenlabs/performance-client-darwin-x64@0.0.8': + optional: true + + '@basetenlabs/performance-client-linux-arm-gnueabihf@0.0.8': + optional: true + + '@basetenlabs/performance-client-linux-arm-musleabihf@0.0.8': + optional: true + + '@basetenlabs/performance-client-linux-arm64-gnu@0.0.8': + optional: true + + '@basetenlabs/performance-client-linux-riscv64-gnu@0.0.8': + optional: true + + '@basetenlabs/performance-client-linux-x64-gnu@0.0.8': + optional: true + + '@basetenlabs/performance-client-linux-x64-musl@0.0.8': + optional: true + + '@basetenlabs/performance-client-win32-arm64-msvc@0.0.8': + optional: true + + '@basetenlabs/performance-client-win32-ia32-msvc@0.0.8': + optional: true + + '@basetenlabs/performance-client-win32-x64-msvc@0.0.8': + optional: true + + '@basetenlabs/performance-client@0.0.8': + optionalDependencies: + '@basetenlabs/performance-client-android-arm-eabi': 0.0.8 + '@basetenlabs/performance-client-android-arm64': 0.0.8 + '@basetenlabs/performance-client-darwin-arm64': 0.0.8 + '@basetenlabs/performance-client-darwin-x64': 0.0.8 + '@basetenlabs/performance-client-linux-arm-gnueabihf': 0.0.8 + '@basetenlabs/performance-client-linux-arm-musleabihf': 0.0.8 + '@basetenlabs/performance-client-linux-arm64-gnu': 0.0.8 + '@basetenlabs/performance-client-linux-riscv64-gnu': 0.0.8 + '@basetenlabs/performance-client-linux-x64-gnu': 0.0.8 + '@basetenlabs/performance-client-linux-x64-musl': 0.0.8 + '@basetenlabs/performance-client-win32-arm64-msvc': 0.0.8 + '@basetenlabs/performance-client-win32-ia32-msvc': 0.0.8 + '@basetenlabs/performance-client-win32-x64-msvc': 0.0.8 + '@bcoe/v8-coverage@0.2.3': {} '@bundled-es-modules/cookie@2.0.1': diff --git a/tsconfig.json b/tsconfig.json index 806af97491e2..4d6270b0bb4d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ { "path": "packages/anthropic" }, { "path": "packages/assemblyai" }, { "path": "packages/azure" }, + { "path": "packages/baseten" }, { "path": "packages/cerebras" }, { "path": "packages/codemod" }, { "path": "packages/cohere" }, From 1fe4bd4144bff927f5319d9d206e782a73979ccb Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 15:35:22 -0700 Subject: [PATCH 054/121] Version Packages (beta) (#8715) # Releases ## @ai-sdk/baseten@1.0.0-beta.0 ### Major Changes - 6cc9cd0: Added Baseten as a Provider for AI SDK Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 6 ++++-- packages/baseten/CHANGELOG.md | 7 +++++++ packages/baseten/package.json | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 packages/baseten/CHANGELOG.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 546c51643f48..659637727691 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -68,9 +68,11 @@ "analyze-downloads": "0.0.0", "eslint-config-vercel-ai": "0.0.0", "generate-llms-txt": "0.0.0", - "@vercel/ai-tsconfig": "0.0.0" + "@vercel/ai-tsconfig": "0.0.0", + "@ai-sdk/baseten": "0.0.0" }, "changesets": [ - "curly-glasses-count" + "curly-glasses-count", + "quiet-pens-suffer" ] } diff --git a/packages/baseten/CHANGELOG.md b/packages/baseten/CHANGELOG.md new file mode 100644 index 000000000000..09e1e8f9aaa1 --- /dev/null +++ b/packages/baseten/CHANGELOG.md @@ -0,0 +1,7 @@ +# @ai-sdk/baseten + +## 1.0.0-beta.0 + +### Major Changes + +- 6cc9cd0: Added Baseten as a Provider for AI SDK diff --git a/packages/baseten/package.json b/packages/baseten/package.json index 1d74580d814e..6d67bb5771df 100644 --- a/packages/baseten/package.json +++ b/packages/baseten/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/baseten", - "version": "0.0.0", + "version": "1.0.0-beta.0", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 47c88b04e0d5e8e7174e0554cda1085d31ac3deb Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:23:07 +0100 Subject: [PATCH 055/121] docs: add reference docs for agent class (#8733) ## Background Follow on from #8693. ## Summary This PR adds a reference page for the `Agent` class. ## Tasks - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [ ] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [ ] I have reviewed this pull request (self-review) --- .../07-reference/01-ai-sdk-core/05-agent.mdx | 429 ++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 content/docs/07-reference/01-ai-sdk-core/05-agent.mdx diff --git a/content/docs/07-reference/01-ai-sdk-core/05-agent.mdx b/content/docs/07-reference/01-ai-sdk-core/05-agent.mdx new file mode 100644 index 000000000000..d85ac0c14be0 --- /dev/null +++ b/content/docs/07-reference/01-ai-sdk-core/05-agent.mdx @@ -0,0 +1,429 @@ +--- +title: Agent +description: API Reference for the Agent class. +--- + +# `Agent` + +Creates a reusable AI agent that can generate text, stream responses, and use tools across multiple steps. + +It is ideal for building autonomous AI systems that need to perform complex, multi-step tasks with tool calling capabilities. Unlike single-step functions like `generateText`, agents can iteratively call tools and make decisions based on intermediate results. + +```ts +import { Experimental_Agent as Agent } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + system: 'You are a helpful assistant.', + tools: { + weather: weatherTool, + calculator: calculatorTool, + }, +}); + +const { text } = await agent.generate({ + prompt: 'What is the weather in NYC?', +}); + +console.log(text); +``` + +To see `Agent` in action, check out [these examples](#examples). + +## Import + + + +## Constructor + +### Parameters + +', + description: + 'The tools that the model can call. The model needs to support calling tools.', + }, + { + name: 'toolChoice', + type: 'ToolChoice', + description: + "The tool choice strategy. Options: 'auto' | 'none' | 'required' | { type: 'tool', toolName: string }. Default: 'auto'", + }, + { + name: 'stopWhen', + type: 'StopCondition | StopCondition[]', + description: + 'Condition for stopping the generation when there are tool results in the last step. Default: stepCountIs(1)', + }, + { + name: 'activeTools', + type: 'Array', + description: + 'Limits the tools that are available for the model to call without changing the tool call and result types.', + }, + { + name: 'experimental_output', + type: 'Output', + description: + 'Optional specification for parsing structured outputs from the LLM response.', + }, + { + name: 'prepareStep', + type: 'PrepareStepFunction', + description: + 'Optional function that you can use to provide different settings for a step.', + }, + { + name: 'experimental_repairToolCall', + type: 'ToolCallRepairFunction', + description: + 'A function that attempts to repair a tool call that failed to parse.', + }, + { + name: 'onStepFinish', + type: 'GenerateTextOnStepFinishCallback', + description: + 'Callback that is called when each step (LLM call) is finished, including intermediate steps.', + }, + { + name: 'experimental_context', + type: 'unknown', + description: + 'Context that is passed into tool calls. Experimental (can break in patch releases).', + }, + { + name: 'experimental_telemetry', + type: 'TelemetrySettings', + description: 'Optional telemetry configuration (experimental).', + }, + { + name: 'maxOutputTokens', + type: 'number', + description: 'Maximum number of tokens to generate.', + }, + { + name: 'temperature', + type: 'number', + description: + 'Temperature setting. The value is passed through to the provider. The range depends on the provider and model.', + }, + { + name: 'topP', + type: 'number', + description: + 'Top-p sampling setting. The value is passed through to the provider. The range depends on the provider and model.', + }, + { + name: 'topK', + type: 'number', + description: + 'Top-k sampling setting. The value is passed through to the provider. The range depends on the provider and model.', + }, + { + name: 'presencePenalty', + type: 'number', + description: + 'Presence penalty setting. The value is passed through to the provider. The range depends on the provider and model.', + }, + { + name: 'frequencyPenalty', + type: 'number', + description: + 'Frequency penalty setting. The value is passed through to the provider. The range depends on the provider and model.', + }, + { + name: 'stopSequences', + type: 'string[]', + description: + 'Stop sequences to use. The value is passed through to the provider.', + }, + { + name: 'seed', + type: 'number', + description: + 'Seed for random number generation. The value is passed through to the provider.', + }, + { + name: 'maxRetries', + type: 'number', + description: 'Maximum number of retries. Default: 2.', + }, + { + name: 'abortSignal', + type: 'AbortSignal', + description: + 'An optional abort signal that can be used to cancel the call.', + }, + ]} +/> + +## Methods + +### `generate()` + +Generates text and calls tools for a given prompt. Returns a promise that resolves to a `GenerateTextResult`. + +```ts +const result = await agent.generate({ + prompt: 'What is the weather like?', +}); +``` + +', + description: 'A text prompt.', + }, + { + name: 'messages', + type: 'Array', + description: 'A list of messages that represent a conversation.', + }, + { + name: 'providerMetadata', + type: 'ProviderMetadata', + isOptional: true, + description: + '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.', + }, + { + name: 'providerOptions', + type: 'ProviderOptions', + isOptional: true, + description: + 'Additional provider-specific metadata. They are passed through to the provider from the AI SDK and enable provider-specific functionality that can be fully encapsulated in the provider.', + }, + { + name: 'system', + type: 'string', + isOptional: true, + description: + 'The system prompt to use that specifies the behavior of the model.', + }, + ]} +/> + +#### Returns + +The `generate()` method returns a `GenerateTextResult` object with the same properties as [`generateText`](/docs/reference/ai-sdk-core/generate-text#returns). + +### `stream()` + +Streams text and calls tools for a given prompt. Returns a `StreamTextResult` that can be used to iterate over the stream. + +```ts +const stream = agent.stream({ + prompt: 'Tell me a story about a robot.', +}); + +for await (const chunk of stream.textStream) { + console.log(chunk); +} +``` + +', + description: 'A text prompt.', + }, + { + name: 'messages', + type: 'Array', + description: 'A list of messages that represent a conversation.', + }, + { + name: 'providerMetadata', + type: 'ProviderMetadata', + isOptional: true, + description: + '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.', + }, + { + name: 'providerOptions', + type: 'ProviderOptions', + isOptional: true, + description: + 'Additional provider-specific metadata. They are passed through to the provider from the AI SDK and enable provider-specific functionality that can be fully encapsulated in the provider.', + }, + { + name: 'system', + type: 'string', + isOptional: true, + description: + 'The system prompt to use that specifies the behavior of the model.', + }, + ]} +/> + +#### Returns + +The `stream()` method returns a `StreamTextResult` object with the same properties as [`streamText`](/docs/reference/ai-sdk-core/stream-text#returns). + +### `respond()` + +Creates a Response object that streams UI messages to the client. This method is particularly useful for building chat interfaces in web applications. + +```ts +export async function POST(request: Request) { + const { messages } = await request.json(); + + return agent.respond({ + messages, + }); +} +``` + + + +#### Returns + +Returns a `Response` object that streams UI messages to the client in the format expected by the `useChat` hook and other UI integrations. + +## Types + +### `InferAgentUIMessage` + +Infers the UI message type of an agent, useful for type-safe message handling in TypeScript applications. + +```ts +import { + Experimental_Agent as Agent, + Experimental_InferAgentUIMessage as InferAgentUIMessage, +} from 'ai'; + +const weatherAgent = new Agent({ + model: 'openai/gpt-4o', + tools: { weather: weatherTool }, +}); + +type WeatherAgentUIMessage = InferAgentUIMessage; +``` + +## Examples + +### Basic Agent with Tools + +Create an agent that can use multiple tools to answer questions: + +```ts +import { Experimental_Agent as Agent, stepCountIs } from 'ai'; +import { weatherTool, calculatorTool } from './tools'; + +const assistant = new Agent({ + model: 'openai/gpt-4o', + system: 'You are a helpful assistant.', + tools: { + weather: weatherTool, + calculator: calculatorTool, + }, + stopWhen: stepCountIs(3), +}); + +// Generate a response +const result = await assistant.generate({ + prompt: 'What is the weather in NYC and what is 100 * 25?', +}); + +console.log(result.text); +console.log(result.steps); // Array of all steps taken +``` + +### Streaming Agent Response + +Stream responses for real-time interaction: + +```ts +const agent = new Agent({ + model: 'openai/gpt-4o', + system: 'You are a creative storyteller.', +}); + +const stream = agent.stream({ + prompt: 'Tell me a short story about a time traveler.', +}); + +for await (const chunk of stream.textStream) { + process.stdout.write(chunk); +} +``` + +### Agent with Output Parsing + +Parse structured output from agent responses: + +```ts +import { z } from 'zod'; + +const analysisAgent = new Agent({ + model: 'openai/gpt-4o', + experimental_output: { + schema: z.object({ + sentiment: z.enum(['positive', 'negative', 'neutral']), + score: z.number(), + summary: z.string(), + }), + }, +}); + +const result = await analysisAgent.generate({ + prompt: 'Analyze this review: "The product exceeded my expectations!"', +}); + +console.log(result.experimental_output); // Typed as { sentiment: 'positive' | 'negative' | 'neutral', score: number, summary: string } +``` + +### Next.js Route Handler + +Use an agent in a Next.js API route: + +```ts +// app/api/chat/route.ts +import { Experimental_Agent as Agent } from 'ai'; + +const agent = new Agent({ + model: 'openai/gpt-4o', + system: 'You are a helpful assistant.', + tools: { + // your tools here + }, +}); + +export async function POST(request: Request) { + const { messages } = await request.json(); + + return agent.respond({ + messages, + }); +} +``` From ece283cd7bc8258a19e1294df6c36488edb3a803 Mon Sep 17 00:00:00 2001 From: Nico Albanese <49612682+nicoalbanese@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:38:02 +0100 Subject: [PATCH 056/121] docs(contributing): add contributing section for documentation (#8735) Adds contributing section for documentation (website). --- contributing/documentation.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 contributing/documentation.md diff --git a/contributing/documentation.md b/contributing/documentation.md new file mode 100644 index 000000000000..3e110778840f --- /dev/null +++ b/contributing/documentation.md @@ -0,0 +1,17 @@ +# Documentation + +## Making Changes + +To make changes to the documentation website (https://ai-sdk.dev), modify files in the `/content` directory. Please follow conventions of similar files. + +Note: There is currently no way to preview documentation changes locally before submitting. + +## Pull Request Guidelines + +All documentation PRs should be prefixed with `docs:` in the title. + +Run `npm run prettier-fix` to solve formatting issues. + +## Update Schedule + +Documentation is sourced and updated every 3 hours on the live site. From 2a72308eb008fccc9508be86774b1ce40d7fbd16 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Saini <40729749+rockingrohit9639@users.noreply.github.com> Date: Thu, 18 Sep 2025 18:56:37 +0200 Subject: [PATCH 057/121] docs: change provider options from azure to openai (#8684) ## Background The `@ai-sdk/azure` package's documentation for the embed function was misleading. It instructed users to pass provider-specific options using the azure key within the providerOptions object (e.g., `providerOptions: { azure: { dimensions: 512 } })`. However, the implementation only recognized the openai key, which is the standard for the underlying API. This inconsistency caused confusion and wasted time for users attempting to configure Azure embeddings. ## Summary This pull request updates the documentation for the `@ai-sdk/azure` package to correctly reflect how provider-specific options for the embed function should be passed. The documentation now explicitly states that the `providerOptions` key should be openai, aligning with the existing code implementation. ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues Fixes #8679 --- content/providers/01-ai-sdk-providers/04-azure.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/providers/01-ai-sdk-providers/04-azure.mdx b/content/providers/01-ai-sdk-providers/04-azure.mdx index 2d193a92be9d..100297abb9aa 100644 --- a/content/providers/01-ai-sdk-providers/04-azure.mdx +++ b/content/providers/01-ai-sdk-providers/04-azure.mdx @@ -198,7 +198,7 @@ const result = await generateText({ model: azure('your-deployment-name'), prompt: 'Write a short story about a robot.', providerOptions: { - azure: { + openai: { logitBias: { // optional likelihood for specific tokens '50256': -100, @@ -378,7 +378,7 @@ const result = await generateText({ model: azure.completion('your-gpt-35-turbo-instruct-deployment'), prompt: 'Write a haiku about coding.', providerOptions: { - azure: { + openai: { echo: true, // optional, echo the prompt in addition to the completion logitBias: { // optional likelihood for specific tokens @@ -453,7 +453,7 @@ const { embedding } = await embed({ model: azure.textEmbedding('your-embedding-deployment'), value: 'sunny day at the beach', providerOptions: { - azure: { + openai: { dimensions: 512, // optional, number of dimensions for the embedding user: 'test-user', // optional unique user identifier }, @@ -481,7 +481,7 @@ You can create models that call the Azure OpenAI image generation API (DALL-E) u const model = azure.image('your-dalle-deployment-name'); ``` -Azure OpenAI image models support several additional settings. You can pass them as `providerOptions.azure` when generating the image: +Azure OpenAI image models support several additional settings. You can pass them as `providerOptions.openai` when generating the image: ```ts await generateImage({ @@ -489,7 +489,7 @@ await generateImage({ prompt: 'A photorealistic image of a cat astronaut floating in space', size: '1024x1024', // '1024x1024', '1792x1024', or '1024x1792' for DALL-E 3 providerOptions: { - azure: { + openai: { user: 'test-user', // optional unique user identifier responseFormat: 'url', // 'url' or 'b64_json', defaults to 'url' }, @@ -567,7 +567,7 @@ import { readFile } from 'fs/promises'; const result = await transcribe({ model: azure.transcription('whisper-1'), audio: await readFile('audio.mp3'), - providerOptions: { azure: { language: 'en' } }, + providerOptions: { openai: { language: 'en' } }, }); ``` From 8d2bd8daa9116b5eef9c34737f6ea1e4d833e1a1 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:13:13 -0700 Subject: [PATCH 058/121] ci(backport): original version (#8736) --- .github/workflows/backport.yml | 106 +++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 000000000000..8f01b756cb74 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,106 @@ +name: Backport + +on: + pull_request: + types: [closed, labeled] + +concurrency: ${{ github.workflow }}-${{ github.event.pull_request.number }} + +jobs: + backport: + name: Backport to v5.0 + runs-on: ubuntu-latest + timeout-minutes: 10 + # Only run on merged PRs with backport label in the main repository + if: | + github.repository_owner == 'vercel' && + github.event.pull_request.merged == true && + contains(github.event.pull_request.labels.*.name, 'backport') && + github.event.pull_request.base.ref == 'main' + + steps: + - name: Create access token for GitHub App + uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ vars.VERCEL_AI_SDK_GITHUB_APP_CLIENT_ID }} + private-key: ${{ secrets.VERCEL_AI_SDK_GITHUB_APP_PRIVATE_KEY_PKCS8 }} + + - name: Get GitHub App User ID + id: app-user-id + run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + + - name: Configure git user for GitHub App + run: | + git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]' + git config --global user.email '${{ steps.app-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' + + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} + + - name: Create backport branch + run: | + # Create a new branch from v5.0 for the backport + git checkout -b backport-pr-${{ github.event.pull_request.number }}-to-v5.0 origin/v5.0 + + - name: Cherry-pick commits + run: | + # Get the merge commit hash + MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}" + + # Cherry-pick the merge commit + if ! git cherry-pick -m 1 "$MERGE_COMMIT"; then + echo "Cherry-pick failed. This backport requires manual intervention." + echo "::error::Failed to cherry-pick merge commit $MERGE_COMMIT to v5.0 branch" + exit 1 + fi + + - name: Push backport branch + run: | + git push origin backport-pr-${{ github.event.pull_request.number }}-to-v5.0 + + - name: Create backport pull request + id: create-pr + run: | + # Create the backport PR + PR_TITLE="Backport of #${{ github.event.pull_request.number }}" + PR_BODY="This is an automated backport of #${{ github.event.pull_request.number }} to the v5.0 branch. + + Original PR: #${{ github.event.pull_request.number }} + Original Title: ${{ github.event.pull_request.title }} + Original Author: @${{ github.event.pull_request.user.login }}" + + PR_NUMBER=$(gh pr create \ + --title "$PR_TITLE" \ + --body "$PR_BODY" \ + --base v5.0 \ + --head backport-pr-${{ github.event.pull_request.number }}-to-v5.0 \ + --assignee ${{ github.event.pull_request.user.login }} \ + --json number \ + --jq .number) + + echo "backport-pr-number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "Created backport PR #$PR_NUMBER" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + + - name: Remove backport label from original PR + if: steps.create-pr.outputs.backport-pr-number + run: | + # Remove the backport label from the original PR + gh pr edit ${{ github.event.pull_request.number }} --remove-label backport + echo "Removed backport label from original PR #${{ github.event.pull_request.number }}" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + + - name: Comment on original PR + if: steps.create-pr.outputs.backport-pr-number + run: | + gh pr comment ${{ github.event.pull_request.number }} --body "✅ Backport PR created: #${{ steps.create-pr.outputs.backport-pr-number }}" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} From 459edbdac5a68ff0bcd9e3050c0fe48fc1dd4895 Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 18 Sep 2025 19:29:39 +0200 Subject: [PATCH 059/121] docs: update import path for generateImage tool (#8731) Changed the code sample filename from `tools/get-weather.ts` to `tools/generate-image.ts` to accurately reflect the image generation functionality. --- .../cookbook/01-next/12-generate-image-with-chat-prompt.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/cookbook/01-next/12-generate-image-with-chat-prompt.mdx b/content/cookbook/01-next/12-generate-image-with-chat-prompt.mdx index a37e0e57b7ad..22cf56547c21 100644 --- a/content/cookbook/01-next/12-generate-image-with-chat-prompt.mdx +++ b/content/cookbook/01-next/12-generate-image-with-chat-prompt.mdx @@ -12,7 +12,7 @@ When building a chatbot, you may want to allow the user to generate an image. Th Let's create an endpoint at `/api/chat` that generates the assistant's response based on the conversation history. You will also define a tool called `generateImage` that will generate an image based on the assistant's response. -```typescript filename='tools/get-weather.ts' +```typescript filename='tools/generate-image.ts' import { openai } from '@ai-sdk/openai'; import { experimental_generateImage, tool } from 'ai'; import z from 'zod'; @@ -43,7 +43,7 @@ import { type UIMessage, } from 'ai'; -import { generateImage } from '@/tools/get-weather'; +import { generateImage } from '@/tools/generate-image'; const tools = { generateImage, From 8b4531abbf9dc54144a679df2fce04771046e84f Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:33:19 -0700 Subject: [PATCH 060/121] ci(backport): fix `gh` usage --- .github/workflows/backport.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 8f01b756cb74..fe3de2c540a7 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -75,22 +75,19 @@ jobs: Original Title: ${{ github.event.pull_request.title }} Original Author: @${{ github.event.pull_request.user.login }}" - PR_NUMBER=$(gh pr create \ + PR_URL=$(gh pr create \ --title "$PR_TITLE" \ --body "$PR_BODY" \ --base v5.0 \ - --head backport-pr-${{ github.event.pull_request.number }}-to-v5.0 \ - --assignee ${{ github.event.pull_request.user.login }} \ - --json number \ - --jq .number) + --head backport-pr-${{ github.event.pull_request.number }}-to-v5.0) - echo "backport-pr-number=$PR_NUMBER" >> "$GITHUB_OUTPUT" - echo "Created backport PR #$PR_NUMBER" + echo "backport-pr-url=$PR_URL" >> "$GITHUB_OUTPUT" + echo "Created backport PR $PR_URL" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Remove backport label from original PR - if: steps.create-pr.outputs.backport-pr-number + if: steps.create-pr.outputs.backport-pr-url run: | # Remove the backport label from the original PR gh pr edit ${{ github.event.pull_request.number }} --remove-label backport @@ -99,8 +96,8 @@ jobs: GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Comment on original PR - if: steps.create-pr.outputs.backport-pr-number + if: steps.create-pr.outputs.backport-pr-url run: | - gh pr comment ${{ github.event.pull_request.number }} --body "✅ Backport PR created: #${{ steps.create-pr.outputs.backport-pr-number }}" + gh pr comment ${{ github.event.pull_request.number }} --body "✅ Backport PR created: ${{ steps.create-pr.outputs.backport-pr-url }}" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} From 60e5c245952c6a610731f817e4204f3ce362cd37 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:50:44 -0700 Subject: [PATCH 061/121] docs(pull request template): checklist (#8706) --- .github/pull_request_template.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8dfa57b22180..6498a4f55b8c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,11 +22,10 @@ Please explain how you *manually* verified that the change works end-to-end as e Remove the section if it's not needed (e.g. for docs). --> -## Tasks +## Checklist From 8117305893731f20caaa08306591d93603166f74 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:52:47 -0700 Subject: [PATCH 062/121] ci(backport): improve pull request body --- .github/workflows/backport.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index fe3de2c540a7..7cebe3be3f3e 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -68,12 +68,8 @@ jobs: id: create-pr run: | # Create the backport PR - PR_TITLE="Backport of #${{ github.event.pull_request.number }}" - PR_BODY="This is an automated backport of #${{ github.event.pull_request.number }} to the v5.0 branch. - - Original PR: #${{ github.event.pull_request.number }} - Original Title: ${{ github.event.pull_request.title }} - Original Author: @${{ github.event.pull_request.user.login }}" + PR_TITLE="Backport: ${{ github.event.pull_request.title }}" + PR_BODY="This is an automated backport of #${{ github.event.pull_request.number }} to the v5.0 branch." PR_URL=$(gh pr create \ --title "$PR_TITLE" \ From a7f6f81e623274c783f6f22fc4a2dda61bce92e6 Mon Sep 17 00:00:00 2001 From: Francisco Veiras <74626997+fveiraswww@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:10:29 -0300 Subject: [PATCH 063/121] feat(ai): add safeValidateUIMessages (#8680) ## Background The current validateUIMessages throws on validation failure. For API endpoints and similar contexts it's ergonomically preferable to use a safe-return pattern (like zod's safeParse) to avoid try/catch and get a typed success/failure result. see context in #8673 ## Summary - Add `safeValidateUIMessages` - Returns a discriminated union: `{ success: true, data }` || `{ success: false, reason, error }` ## Manual Verification - Ran unit tests in packages/ai ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues fixes #8673 --------- Co-authored-by: Francisco Veiras <74626997+francisco-svg761@users.noreply.github.com> Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/red-roses-glow.md | 5 + .../33-safe-validate-ui-messages.mdx | 113 ++++++++++ packages/ai/src/ui/index.ts | 6 +- .../ai/src/ui/validate-ui-messages.test.ts | 137 ++++++++++- packages/ai/src/ui/validate-ui-messages.ts | 212 ++++++++++++------ 5 files changed, 400 insertions(+), 73 deletions(-) create mode 100644 .changeset/red-roses-glow.md create mode 100644 content/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx diff --git a/.changeset/red-roses-glow.md b/.changeset/red-roses-glow.md new file mode 100644 index 000000000000..16ea869d6382 --- /dev/null +++ b/.changeset/red-roses-glow.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +Add safeValidateUIMessages utility to validate UI messages without throwing, returning a success/failure result object like Zod’s safeParse diff --git a/content/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx b/content/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx new file mode 100644 index 000000000000..2a4bd4a45c38 --- /dev/null +++ b/content/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx @@ -0,0 +1,113 @@ +--- +title: safeValidateUIMessages +description: API Reference for safeValidateUIMessages +--- + +# `safeValidateUIMessages` + +`safeValidateUIMessages` is an async function that validates UI messages like [`validateUIMessages`](https://ai-sdk.dev/docs/reference/ai-sdk-core/validate-ui-messages), but instead of throwing it returns an object with a `success` key and either `data` or `error`. + +## Basic Usage + +Simple validation without custom schemas: + +```typescript +import { safeValidateUIMessages } from 'ai'; + +const messages = [ + { + id: '1', + role: 'user', + parts: [{ type: 'text', text: 'Hello!' }], + }, +]; + +const result = await safeValidateUIMessages({ + messages, +}); + +if (!result.success) { + console.error(result.error.message); +} else { + const validatedMessages = result.data; +} +``` + +## Advanced Usage + +Comprehensive validation with custom metadata, data parts, and tools: + +```typescript +import { safeValidateUIMessages, tool } from 'ai'; +import { z } from 'zod'; + +// Define schemas +const metadataSchema = z.object({ + timestamp: z.string().datetime(), + userId: z.string(), +}); + +const dataSchemas = { + chart: z.object({ + data: z.array(z.number()), + labels: z.array(z.string()), + }), + image: z.object({ + url: z.string().url(), + caption: z.string(), + }), +}; + +const tools = { + weather: tool({ + description: 'Get weather info', + parameters: z.object({ + location: z.string(), + }), + execute: async ({ location }) => `Weather in ${location}: sunny`, + }), +}; + +// Messages with custom parts +const messages = [ + { + id: '1', + role: 'user', + metadata: { timestamp: '2024-01-01T00:00:00Z', userId: 'user123' }, + parts: [ + { type: 'text', text: 'Show me a chart' }, + { + type: 'data-chart', + data: { data: [1, 2, 3], labels: ['A', 'B', 'C'] }, + }, + ], + }, + { + id: '2', + role: 'assistant', + parts: [ + { + type: 'tool-weather', + toolCallId: 'call_123', + state: 'output-available', + input: { location: 'San Francisco' }, + output: 'Weather in San Francisco: sunny', + }, + ], + }, +]; + +// Validate with all schemas +const result = await safeValidateUIMessages({ + messages, + metadataSchema, + dataSchemas, + tools, +}); + +if (!result.success) { + console.error(result.error.message); +} else { + const validatedMessages = result.data; +} +``` diff --git a/packages/ai/src/ui/index.ts b/packages/ai/src/ui/index.ts index 90eeffd5d51d..2bf6e0a1e13f 100644 --- a/packages/ai/src/ui/index.ts +++ b/packages/ai/src/ui/index.ts @@ -55,4 +55,8 @@ export { type CompletionRequestOptions, type UseCompletionOptions, } from './use-completion'; -export { validateUIMessages } from './validate-ui-messages'; +export { + validateUIMessages, + safeValidateUIMessages, + type SafeValidateUIMessagesResult, +} from './validate-ui-messages'; diff --git a/packages/ai/src/ui/validate-ui-messages.test.ts b/packages/ai/src/ui/validate-ui-messages.test.ts index 0b6316cbd0c1..00ecd018d23b 100644 --- a/packages/ai/src/ui/validate-ui-messages.test.ts +++ b/packages/ai/src/ui/validate-ui-messages.test.ts @@ -1,6 +1,9 @@ import { z } from 'zod/v4'; import { InferUITool, UIMessage } from './ui-messages'; -import { validateUIMessages } from './validate-ui-messages'; +import { + safeValidateUIMessages, + validateUIMessages, +} from './validate-ui-messages'; import { describe, it, expect, expectTypeOf } from 'vitest'; describe('validateUIMessages', () => { @@ -1106,3 +1109,135 @@ describe('validateUIMessages', () => { }); }); }); + +export function expectToBe( + value: boolean, + expected: T, +): asserts value is T { + expect(value).toBe(expected); +} + +describe('safeValidateUIMessages', () => { + it('should return success result for valid messages', async () => { + const result = await safeValidateUIMessages({ + messages: [ + { + id: '1', + role: 'user', + parts: [{ type: 'text', text: 'Hello, world!' }], + }, + ], + }); + + expectToBe(result.success, true); + expect(result.data).toMatchInlineSnapshot(` + [ + { + "id": "1", + "parts": [ + { + "text": "Hello, world!", + "type": "text", + }, + ], + "role": "user", + }, + ] + `); + }); + + it('should return failure result when messages parameter is null', async () => { + const result = await safeValidateUIMessages({ + messages: null, + }); + + expectToBe(result.success, false); + expect(result.error.name).toBe('AI_InvalidArgumentError'); + expect(result.error.message).toBe( + 'Invalid argument for parameter messages: messages parameter must be provided', + ); + }); + + it('should return failure result when metadata validation fails', async () => { + const result = await safeValidateUIMessages>({ + messages: [ + { + id: '1', + role: 'user', + metadata: { foo: 123 }, + parts: [{ type: 'text', text: 'Hello, world!' }], + }, + ], + metadataSchema: z.object({ foo: z.string() }), + }); + + expectToBe(result.success, false); + expect(result.error.name).toBe('AI_TypeValidationError'); + expect(result.error.message).toContain('Type validation failed'); + }); + + it('should return failure result when tool input validation fails', async () => { + const testTool = { + name: 'foo', + inputSchema: z.object({ foo: z.string() }), + outputSchema: z.object({ result: z.string() }), + }; + + const result = await safeValidateUIMessages({ + messages: [ + { + id: '1', + role: 'assistant', + parts: [ + { + type: 'tool-foo', + toolCallId: '1', + state: 'input-available', + input: { foo: 123 }, + providerExecuted: true, + }, + ], + }, + ], + tools: { foo: testTool }, + }); + + expectToBe(result.success, false); + expect(result.error.name).toBe('AI_TypeValidationError'); + expect(result.error.message).toContain('Type validation failed'); + }); + + it('should return failure result when data schema is missing', async () => { + const result = await safeValidateUIMessages({ + messages: [ + { + id: '1', + role: 'assistant', + parts: [{ type: 'data-bar', data: { foo: 'bar' } }], + }, + ], + dataSchemas: { + foo: z.object({ foo: z.string() }), + }, + }); + + expectToBe(result.success, false); + expect(result.error.name).toBe('AI_TypeValidationError'); + expect(result.error.message).toContain( + 'No data schema found for data part bar', + ); + }); + + it('should return failure result for invalid message structure', async () => { + const result = await safeValidateUIMessages({ + messages: [ + { + role: 'user', + }, + ], + }); + + expectToBe(result.success, false); + expect(result.error.name).toBe('AI_TypeValidationError'); + }); +}); diff --git a/packages/ai/src/ui/validate-ui-messages.ts b/packages/ai/src/ui/validate-ui-messages.ts index 3c18de8f5945..c82a6e11c00b 100644 --- a/packages/ai/src/ui/validate-ui-messages.ts +++ b/packages/ai/src/ui/validate-ui-messages.ts @@ -170,14 +170,22 @@ const uiMessageSchema = z.object({ ), }); +export type SafeValidateUIMessagesResult = + | { + success: true; + data: Array; + } + | { + success: false; + error: Error; + }; + /** - * Validates a list of UI messages. - * - * Metadata, data parts, and generic tool call structures are only validated if - * the corresponding schemas are provided. Otherwise, they are assumed to be - * valid. + * Validates a list of UI messages like `validateUIMessages`, + * but instead of throwing it returns `{ success: true, data }` + * or `{ success: false, error }`. */ -export async function validateUIMessages({ +export async function safeValidateUIMessages({ messages, metadataSchema, dataSchemas, @@ -198,91 +206,153 @@ export async function validateUIMessages({ InferUIMessageTools[NAME]['output'] >; }; -}): Promise> { - if (messages == null) { - throw new InvalidArgumentError({ - parameter: 'messages', +}): Promise> { + try { + if (messages == null) { + return { + success: false, + error: new InvalidArgumentError({ + parameter: 'messages', + value: messages, + message: 'messages parameter must be provided', + }), + }; + } + + const validatedMessages = await validateTypes({ value: messages, - message: 'messages parameter must be provided', + schema: z.array(uiMessageSchema), }); - } - - const validatedMessages = await validateTypes({ - value: messages, - schema: z.array(uiMessageSchema), - }); - if (metadataSchema) { - for (const message of validatedMessages) { - await validateTypes({ - value: message.metadata, - schema: metadataSchema, - }); + if (metadataSchema) { + for (const message of validatedMessages) { + await validateTypes({ + value: message.metadata, + schema: metadataSchema, + }); + } } - } - if (dataSchemas) { - for (const message of validatedMessages) { - const dataParts = message.parts.filter(part => - part.type.startsWith('data-'), - ) as DataUIPart>[]; + if (dataSchemas) { + for (const message of validatedMessages) { + const dataParts = message.parts.filter(part => + part.type.startsWith('data-'), + ) as DataUIPart>[]; + + for (const dataPart of dataParts) { + const dataName = dataPart.type.slice(5); + const dataSchema = dataSchemas[dataName]; - for (const dataPart of dataParts) { - const dataName = dataPart.type.slice(5); - const dataSchema = dataSchemas[dataName]; + if (!dataSchema) { + return { + success: false, + error: new TypeValidationError({ + value: dataPart.data, + cause: `No data schema found for data part ${dataName}`, + }), + }; + } - if (!dataSchema) { - throw new TypeValidationError({ + await validateTypes({ value: dataPart.data, - cause: `No data schema found for data part ${dataName}`, + schema: dataSchema, }); } - - await validateTypes({ - value: dataPart.data, - schema: dataSchema, - }); } } - } - if (tools) { - for (const message of validatedMessages) { - const toolParts = message.parts.filter(part => - part.type.startsWith('tool-'), - ) as ToolUIPart>[]; + if (tools) { + for (const message of validatedMessages) { + const toolParts = message.parts.filter(part => + part.type.startsWith('tool-'), + ) as ToolUIPart>[]; - for (const toolPart of toolParts) { - const toolName = toolPart.type.slice(5); - const tool = tools[toolName]; + for (const toolPart of toolParts) { + const toolName = toolPart.type.slice(5); + const tool = tools[toolName]; - if (!tool) { - throw new TypeValidationError({ - value: toolPart.input, - cause: `No tool schema found for tool part ${toolName}`, - }); - } + if (!tool) { + return { + success: false, + error: new TypeValidationError({ + value: toolPart.input, + cause: `No tool schema found for tool part ${toolName}`, + }), + }; + } - if ( - toolPart.state === 'input-available' || - toolPart.state === 'output-available' || - toolPart.state === 'output-error' - ) { - await validateTypes({ - value: toolPart.input, - schema: tool.inputSchema, - }); - } + if ( + toolPart.state === 'input-available' || + toolPart.state === 'output-available' || + toolPart.state === 'output-error' + ) { + await validateTypes({ + value: toolPart.input, + schema: tool.inputSchema, + }); + } - if (toolPart.state === 'output-available' && tool.outputSchema) { - await validateTypes({ - value: toolPart.output, - schema: tool.outputSchema, - }); + if (toolPart.state === 'output-available' && tool.outputSchema) { + await validateTypes({ + value: toolPart.output, + schema: tool.outputSchema, + }); + } } } } + + return { + success: true, + data: validatedMessages as Array, + }; + } catch (error) { + const err = error as Error; + + return { + success: false, + error: err, + }; } +} + +/** + * Validates a list of UI messages. + * + * Metadata, data parts, and generic tool call structures are only validated if + * the corresponding schemas are provided. Otherwise, they are assumed to be + * valid. + */ +export async function validateUIMessages({ + messages, + metadataSchema, + dataSchemas, + tools, +}: { + messages: unknown; + metadataSchema?: + | Validator + | StandardSchemaV1; + dataSchemas?: { + [NAME in keyof InferUIMessageData & string]?: + | Validator[NAME]> + | StandardSchemaV1[NAME]>; + }; + tools?: { + [NAME in keyof InferUIMessageTools & string]?: Tool< + InferUIMessageTools[NAME]['input'], + InferUIMessageTools[NAME]['output'] + >; + }; +}): Promise> { + const response = await safeValidateUIMessages({ + messages, + metadataSchema, + dataSchemas, + tools, + }); + + if (!response.success) throw response.error; - return validatedMessages as Array; + return response.data; } From a31b3993413fa6f08d82737b995cc1d4faa55669 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Thu, 18 Sep 2025 11:15:10 -0700 Subject: [PATCH 064/121] ci(backport): use `pull_request_target` which is safe in this case, as we work with merged pull requests and labels only --- .github/workflows/backport.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 7cebe3be3f3e..15ae0c06d480 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -1,7 +1,7 @@ name: Backport on: - pull_request: + pull_request_target: types: [closed, labeled] concurrency: ${{ github.workflow }}-${{ github.event.pull_request.number }} @@ -42,6 +42,7 @@ jobs: with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} + ref: v5.0 - name: Create backport branch run: | From cbdd4dc82ab02cbfc5d7aacb7835e74cdd909da1 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Thu, 18 Sep 2025 11:16:16 -0700 Subject: [PATCH 065/121] docs(contributing): building new features (#8705) --- contributing/building-new-features.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 contributing/building-new-features.md diff --git a/contributing/building-new-features.md b/contributing/building-new-features.md new file mode 100644 index 000000000000..81939b86bcef --- /dev/null +++ b/contributing/building-new-features.md @@ -0,0 +1,9 @@ +# Building new features + +1. Create/update generateText example +2. Create/update streamText example +3. Create/update UI tests (next-openai) + - always test follow up message + - consider testing with store: false + +Example: https://github.com/vercel/ai/pull/8691 From e01a81a543e2a9071a23c27193cf544672bb5537 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 11:37:58 -0700 Subject: [PATCH 066/121] Version Packages (beta) (#8741) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Releases ## ai@5.1.0-beta.1 ### Patch Changes - a7f6f81: Add safeValidateUIMessages utility to validate UI messages without throwing, returning a success/failure result object like Zod’s safeParse ## @ai-sdk/angular@1.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 ## @ai-sdk/langchain@1.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 ## @ai-sdk/llamaindex@1.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 ## @ai-sdk/react@2.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 ## @ai-sdk/rsc@1.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 ## @ai-sdk/svelte@3.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 ## @ai-sdk/vue@2.1.0-beta.1 ### Patch Changes - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 3 ++- packages/ai/CHANGELOG.md | 6 ++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 7 +++++++ packages/angular/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 7 +++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 7 +++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 7 +++++++ packages/vue/package.json | 2 +- 18 files changed, 72 insertions(+), 9 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 659637727691..41baef068397 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -73,6 +73,7 @@ }, "changesets": [ "curly-glasses-count", - "quiet-pens-suffer" + "quiet-pens-suffer", + "red-roses-glow" ] } diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index a840365dcfba..0259dad2d39f 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 5.1.0-beta.1 + +### Patch Changes + +- a7f6f81: Add safeValidateUIMessages utility to validate UI messages without throwing, returning a success/failure result object like Zod’s safeParse + ## 5.1.0-beta.0 ### Minor Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index ae8cbd8df0ee..854f5b15f145 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.0", + "version": "5.1.0-beta.1", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 6664b352ab65..98f22adcc5d6 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/angular +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 99b9ac7f4e44..a63947710e91 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 8b205a2edfec..6301bd48d36a 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index b70913ac8719..fae5b643d9c9 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 924df9923ee6..0afd3a79fa95 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index b152e0931f7d..8f08ed84ecfc 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index cb55b7af73ed..309ba0d2d294 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/react +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/react/package.json b/packages/react/package.json index 46fcfb7e0e74..e53b311669f2 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 4698150575ac..b9bcb1ac2532 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/rsc +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 9cc6c93e49ed..1aeb62c1ca83 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index f30798b9386e..e564481d49df 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + +## 0.0.1-beta.0 + +### Patch Changes + - Updated dependencies [78928cb] - ai@5.1.0-beta.0 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 918addb57ba2..d783612e77e5 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/svelte +## 3.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 3.1.0-beta.0 ### Minor Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index e5349fdb120b..3c8b06dbc924 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.0", + "version": "3.1.0-beta.1", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 1ffc30e6b005..65a7b2b756c8 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [a7f6f81] + - ai@5.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index efce362c329b..d27c131fa61c 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 953d0f2662e6fc4510f43be256b9d23dee871328 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:49:21 -0400 Subject: [PATCH 067/121] feat(packages/test-server): Add `test-server` as a package (#8588) ## Background When exporting `test-server.ts` from `packages/provider-utils/src/test`, users were facing issues with added dependencies on `msw` and `vitest` See [8469](https://github.com/vercel/ai/issues/8469) ## Summary Created `test-server` package so that it can have the added dependency to msw and vitest, so that users don't face issues exporting `ai/test` ## Manual Verification Verified by e2e testing by installing said package ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Future Work n/a ## Related Issues Fixes #8469 --- .changeset/four-candles-buy.md | 5 + packages/ai/package.json | 1 + .../ai/src/tool/mcp/mcp-sse-transport.test.ts | 2 +- packages/ai/src/ui/chat.test.ts | 4 +- .../ai/src/ui/http-chat-transport.test.ts | 2 +- .../ai/src/util/download/download.test.ts | 2 +- packages/ai/tsconfig.json | 3 + packages/amazon-bedrock/package.json | 1 + .../src/bedrock-chat-language-model.test.ts | 6 +- .../src/bedrock-embedding-model.test.ts | 2 +- .../src/bedrock-image-model.test.ts | 2 +- packages/angular/package.json | 1 + packages/angular/src/lib/chat.ng.test.ts | 4 +- .../angular/src/lib/completion.ng.test.ts | 2 +- .../src/lib/structured-object.ng.test.ts | 2 +- packages/anthropic/package.json | 3 +- .../anthropic-messages-language-model.test.ts | 2 +- packages/assemblyai/package.json | 3 +- .../assemblyai-transcription-model.test.ts | 2 +- packages/azure/package.json | 3 +- .../azure/src/azure-openai-provider.test.ts | 2 +- packages/cohere/package.json | 3 +- .../src/cohere-chat-language-model.test.ts | 2 +- .../cohere/src/cohere-embedding-model.test.ts | 2 +- packages/deepgram/package.json | 3 +- .../src/deepgram-transcription-model.test.ts | 2 +- packages/deepinfra/package.json | 3 +- .../src/deepinfra-image-model.test.ts | 2 +- packages/elevenlabs/package.json | 3 +- .../src/elevenlabs-speech-model.test.ts | 2 +- .../elevenlabs-transcription-model.test.ts | 2 +- packages/fal/package.json | 3 +- packages/fal/src/fal-image-model.test.ts | 2 +- packages/fal/src/fal-speech-model.test.ts | 2 +- .../fal/src/fal-transcription-model.test.ts | 2 +- packages/fireworks/package.json | 3 +- .../src/fireworks-image-model.test.ts | 2 +- packages/gateway/package.json | 1 + .../src/gateway-embedding-model.test.ts | 2 +- .../src/gateway-fetch-metadata.test.ts | 2 +- .../src/gateway-language-model.test.ts | 6 +- packages/gateway/tsconfig.json | 8 +- packages/gladia/package.json | 3 +- .../src/gladia-transcription-model.test.ts | 2 +- packages/google-vertex/package.json | 1 + .../src/google-vertex-embedding-model.test.ts | 2 +- .../src/google-vertex-image-model.test.ts | 2 +- packages/google/package.json | 3 +- ...ogle-generative-ai-embedding-model.test.ts | 2 +- .../google-generative-ai-image-model.test.ts | 2 +- ...oogle-generative-ai-language-model.test.ts | 6 +- packages/groq/package.json | 3 +- .../groq/src/groq-chat-language-model.test.ts | 2 +- .../groq/src/groq-transcription-model.test.ts | 2 +- packages/hume/package.json | 3 +- packages/hume/src/hume-speech-model.test.ts | 2 +- packages/lmnt/package.json | 3 +- packages/lmnt/src/lmnt-speech-model.test.ts | 2 +- packages/luma/package.json | 3 +- packages/luma/src/luma-image-model.test.ts | 2 +- packages/mistral/package.json | 3 +- .../src/mistral-chat-language-model.test.ts | 2 +- .../src/mistral-embedding-model.test.ts | 2 +- packages/openai-compatible/package.json | 3 +- ...nai-compatible-chat-language-model.test.ts | 2 +- ...mpatible-completion-language-model.test.ts | 2 +- .../openai-compatible-embedding-model.test.ts | 2 +- .../openai-compatible-image-model.test.ts | 2 +- packages/openai/package.json | 3 +- .../chat/openai-chat-language-model.test.ts | 2 +- .../openai-completion-language-model.test.ts | 2 +- .../embedding/openai-embedding-model.test.ts | 2 +- .../src/image/openai-image-model.test.ts | 2 +- .../openai-responses-language-model.test.ts | 2 +- .../src/speech/openai-speech-model.test.ts | 2 +- .../openai-transcription-model.test.ts | 2 +- packages/perplexity/package.json | 3 +- .../src/perplexity-language-model.test.ts | 2 +- packages/provider-utils/src/test/index.ts | 1 - packages/react/package.json | 5 +- packages/react/src/use-chat.ui.test.tsx | 4 +- packages/react/src/use-completion.ui.test.tsx | 2 +- packages/react/src/use-object.ui.test.tsx | 2 +- packages/replicate/package.json | 3 +- .../src/replicate-image-model.test.ts | 2 +- packages/revai/package.json | 3 +- .../src/revai-transcription-model.test.ts | 2 +- packages/svelte/package.json | 7 +- packages/svelte/src/chat.svelte.test.ts | 4 +- packages/svelte/src/completion.svelte.test.ts | 2 +- .../src/structured-object.svelte.test.ts | 2 +- packages/test-server/package.json | 68 + .../src/convert-array-to-readable-stream.ts | 15 + .../src/create-test-server.ts} | 22 +- packages/test-server/src/index.ts | 7 + packages/test-server/src/with-vitest.test.ts | 101 + packages/test-server/src/with-vitest.ts | 57 + packages/test-server/tsconfig.build.json | 7 + packages/test-server/tsconfig.json | 23 + packages/test-server/tsup.config.ts | 32 + packages/test-server/vitest.edge.config.js | 9 + packages/test-server/vitest.node.config.js | 9 + packages/togetherai/package.json | 3 +- .../src/togetherai-image-model.test.ts | 2 +- packages/vue/package.json | 3 +- packages/vue/src/chat.vue.ui.test.tsx | 2 +- packages/vue/src/use-completion.ui.test.ts | 2 +- packages/vue/src/use-object.ui.test.tsx | 2 +- packages/xai/package.json | 3 +- .../xai/src/xai-chat-language-model.test.ts | 6 +- pnpm-lock.yaml | 3378 +++++------------ tsconfig.json | 1 + 112 files changed, 1341 insertions(+), 2646 deletions(-) create mode 100644 .changeset/four-candles-buy.md create mode 100644 packages/test-server/package.json create mode 100644 packages/test-server/src/convert-array-to-readable-stream.ts rename packages/{provider-utils/src/test/test-server.ts => test-server/src/create-test-server.ts} (93%) create mode 100644 packages/test-server/src/index.ts create mode 100644 packages/test-server/src/with-vitest.test.ts create mode 100644 packages/test-server/src/with-vitest.ts create mode 100644 packages/test-server/tsconfig.build.json create mode 100644 packages/test-server/tsconfig.json create mode 100644 packages/test-server/tsup.config.ts create mode 100644 packages/test-server/vitest.edge.config.js create mode 100644 packages/test-server/vitest.node.config.js diff --git a/.changeset/four-candles-buy.md b/.changeset/four-candles-buy.md new file mode 100644 index 000000000000..4579aa270a50 --- /dev/null +++ b/.changeset/four-candles-buy.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/test-server': major +--- + +feat(packages/test-server): Add `test-server` as a package diff --git a/packages/ai/package.json b/packages/ai/package.json index 854f5b15f145..f249d4105362 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -54,6 +54,7 @@ } }, "dependencies": { + "@ai-sdk/test-server": "workspace:*", "@ai-sdk/gateway": "workspace:*", "@ai-sdk/provider": "workspace:*", "@ai-sdk/provider-utils": "workspace:*", diff --git a/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts b/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts index 94b24e79d6f1..4fafb87718e4 100644 --- a/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts +++ b/packages/ai/src/tool/mcp/mcp-sse-transport.test.ts @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import { MCPClientError } from '../../error/mcp-client-error'; import { SseMCPTransport } from './mcp-sse-transport'; import { beforeEach, describe, expect, it } from 'vitest'; diff --git a/packages/ai/src/ui/chat.test.ts b/packages/ai/src/ui/chat.test.ts index 6d95f9c7134e..0f6ff62a6b8d 100644 --- a/packages/ai/src/ui/chat.test.ts +++ b/packages/ai/src/ui/chat.test.ts @@ -1,8 +1,8 @@ import { createTestServer, - mockId, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; +import { mockId } from '@ai-sdk/provider-utils/test'; import { createResolvablePromise } from '../util/create-resolvable-promise'; import { AbstractChat, ChatInit, ChatState, ChatStatus } from './chat'; import { UIMessage } from './ui-messages'; diff --git a/packages/ai/src/ui/http-chat-transport.test.ts b/packages/ai/src/ui/http-chat-transport.test.ts index f032e9d7e43c..820dd4d0fc7c 100644 --- a/packages/ai/src/ui/http-chat-transport.test.ts +++ b/packages/ai/src/ui/http-chat-transport.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { UIMessageChunk } from '../ui-message-stream/ui-message-chunks'; import { HttpChatTransport, diff --git a/packages/ai/src/util/download/download.test.ts b/packages/ai/src/util/download/download.test.ts index 5f2c3b240e04..d239b4be5acf 100644 --- a/packages/ai/src/util/download/download.test.ts +++ b/packages/ai/src/util/download/download.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { download } from './download'; import { DownloadError } from './download-error'; import { describe, it, expect } from 'vitest'; diff --git a/packages/ai/tsconfig.json b/packages/ai/tsconfig.json index 7ac521e7e88f..7dedfdb70326 100644 --- a/packages/ai/tsconfig.json +++ b/packages/ai/tsconfig.json @@ -27,6 +27,9 @@ }, { "path": "../gateway" + }, + { + "path": "../test-server" } ] } diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 0e4dae86c383..469ab6b2e8a1 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -35,6 +35,7 @@ "@ai-sdk/anthropic": "workspace:*", "@ai-sdk/provider": "workspace:*", "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" diff --git a/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts b/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts index 8379ec0fa1f0..f5bcbe933e58 100644 --- a/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts +++ b/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts @@ -1,8 +1,6 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; -import { - createTestServer, - convertReadableStreamToArray, -} from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; +import { convertReadableStreamToArray } from '@ai-sdk/provider-utils/test'; import { BedrockChatLanguageModel } from './bedrock-chat-language-model'; import { beforeEach, describe, expect, vi, it } from 'vitest'; import { injectFetchHeaders } from './inject-fetch-headers'; diff --git a/packages/amazon-bedrock/src/bedrock-embedding-model.test.ts b/packages/amazon-bedrock/src/bedrock-embedding-model.test.ts index bff436d1533a..0fb10b6dc3ec 100644 --- a/packages/amazon-bedrock/src/bedrock-embedding-model.test.ts +++ b/packages/amazon-bedrock/src/bedrock-embedding-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { BedrockEmbeddingModel } from './bedrock-embedding-model'; import { injectFetchHeaders } from './inject-fetch-headers'; import { beforeEach, describe, expect, it } from 'vitest'; diff --git a/packages/amazon-bedrock/src/bedrock-image-model.test.ts b/packages/amazon-bedrock/src/bedrock-image-model.test.ts index ac935b38ff51..8dcbcfc14b5b 100644 --- a/packages/amazon-bedrock/src/bedrock-image-model.test.ts +++ b/packages/amazon-bedrock/src/bedrock-image-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createAmazonBedrock } from './bedrock-provider'; import { BedrockImageModel } from './bedrock-image-model'; import { injectFetchHeaders } from './inject-fetch-headers'; diff --git a/packages/angular/package.json b/packages/angular/package.json index a63947710e91..8cb062be29e2 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -31,6 +31,7 @@ ], "dependencies": { "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*", "ai": "workspace:*" }, "devDependencies": { diff --git a/packages/angular/src/lib/chat.ng.test.ts b/packages/angular/src/lib/chat.ng.test.ts index 6c39f3d1c79e..428b60c877f2 100644 --- a/packages/angular/src/lib/chat.ng.test.ts +++ b/packages/angular/src/lib/chat.ng.test.ts @@ -1,8 +1,8 @@ import { createTestServer, - mockId, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; +import { mockId } from '@ai-sdk/provider-utils/test'; import { DefaultChatTransport, isToolUIPart, diff --git a/packages/angular/src/lib/completion.ng.test.ts b/packages/angular/src/lib/completion.ng.test.ts index 2c8f10710a8d..1dee1f33b984 100644 --- a/packages/angular/src/lib/completion.ng.test.ts +++ b/packages/angular/src/lib/completion.ng.test.ts @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import { Completion } from './completion.ng'; import { beforeAll } from 'vitest'; import { describe, it, expect, vi } from 'vitest'; diff --git a/packages/angular/src/lib/structured-object.ng.test.ts b/packages/angular/src/lib/structured-object.ng.test.ts index d749aba174cc..78e6c5d943ee 100644 --- a/packages/angular/src/lib/structured-object.ng.test.ts +++ b/packages/angular/src/lib/structured-object.ng.test.ts @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import { z } from 'zod/v4'; import { StructuredObject } from './structured-object.ng'; import { beforeEach, describe, expect, it, vi } from 'vitest'; diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 97c1fc03cdba..85c2a6b4b2e1 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -40,7 +40,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/anthropic/src/anthropic-messages-language-model.test.ts b/packages/anthropic/src/anthropic-messages-language-model.test.ts index 62c38cf41f81..0a219a26a68d 100644 --- a/packages/anthropic/src/anthropic-messages-language-model.test.ts +++ b/packages/anthropic/src/anthropic-messages-language-model.test.ts @@ -3,9 +3,9 @@ import { LanguageModelV2StreamPart, JSONValue, } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, mockId, } from '@ai-sdk/provider-utils/test'; import { AnthropicProviderOptions } from './anthropic-messages-options'; diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index 2d40afd22570..1c0d4fd41965 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/assemblyai/src/assemblyai-transcription-model.test.ts b/packages/assemblyai/src/assemblyai-transcription-model.test.ts index 2d28de6420eb..48b96fa1c779 100644 --- a/packages/assemblyai/src/assemblyai-transcription-model.test.ts +++ b/packages/assemblyai/src/assemblyai-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { AssemblyAITranscriptionModel } from './assemblyai-transcription-model'; import { createAssemblyAI } from './assemblyai-provider'; import { readFile } from 'node:fs/promises'; diff --git a/packages/azure/package.json b/packages/azure/package.json index a1b8dcc86f26..50baa174459d 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -34,7 +34,8 @@ "dependencies": { "@ai-sdk/openai": "workspace:*", "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/azure/src/azure-openai-provider.test.ts b/packages/azure/src/azure-openai-provider.test.ts index 6ac9e812bb05..c565c54fc7ce 100644 --- a/packages/azure/src/azure-openai-provider.test.ts +++ b/packages/azure/src/azure-openai-provider.test.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV2Embedding, LanguageModelV2Prompt, } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createAzure } from './azure-openai-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/cohere/package.json b/packages/cohere/package.json index e3e8e9f147d7..c777d02dcea6 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/cohere/src/cohere-chat-language-model.test.ts b/packages/cohere/src/cohere-chat-language-model.test.ts index 0f9ccebdca2d..90357371ea95 100644 --- a/packages/cohere/src/cohere-chat-language-model.test.ts +++ b/packages/cohere/src/cohere-chat-language-model.test.ts @@ -1,7 +1,7 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createCohere } from './cohere-provider'; diff --git a/packages/cohere/src/cohere-embedding-model.test.ts b/packages/cohere/src/cohere-embedding-model.test.ts index 135e83b94494..cc87437a5c27 100644 --- a/packages/cohere/src/cohere-embedding-model.test.ts +++ b/packages/cohere/src/cohere-embedding-model.test.ts @@ -1,5 +1,5 @@ import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createCohere } from './cohere-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index b0d52c5fe629..19641c5dfccb 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepgram/src/deepgram-transcription-model.test.ts b/packages/deepgram/src/deepgram-transcription-model.test.ts index 83185a84fd1d..fa7ab63819ab 100644 --- a/packages/deepgram/src/deepgram-transcription-model.test.ts +++ b/packages/deepgram/src/deepgram-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { DeepgramTranscriptionModel } from './deepgram-transcription-model'; import { createDeepgram } from './deepgram-provider'; import { readFile } from 'node:fs/promises'; diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 092e6b4d0e4a..3f22a41891f5 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -34,7 +34,8 @@ "dependencies": { "@ai-sdk/openai-compatible": "workspace:*", "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/deepinfra/src/deepinfra-image-model.test.ts b/packages/deepinfra/src/deepinfra-image-model.test.ts index bde06befad78..5b37ca287af7 100644 --- a/packages/deepinfra/src/deepinfra-image-model.test.ts +++ b/packages/deepinfra/src/deepinfra-image-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it } from 'vitest'; import { DeepInfraImageModel } from './deepinfra-image-model'; import { FetchFunction } from '@ai-sdk/provider-utils'; diff --git a/packages/elevenlabs/package.json b/packages/elevenlabs/package.json index 93f65ef34e8e..ff1d1f4bf570 100644 --- a/packages/elevenlabs/package.json +++ b/packages/elevenlabs/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/elevenlabs/src/elevenlabs-speech-model.test.ts b/packages/elevenlabs/src/elevenlabs-speech-model.test.ts index a9f54fe06a22..c18bcf8088e6 100644 --- a/packages/elevenlabs/src/elevenlabs-speech-model.test.ts +++ b/packages/elevenlabs/src/elevenlabs-speech-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it } from 'vitest'; import { createElevenLabs } from './elevenlabs-provider'; diff --git a/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts b/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts index 9a00556dcba4..33b91e22a208 100644 --- a/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts +++ b/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { ElevenLabsTranscriptionModel } from './elevenlabs-transcription-model'; import { createElevenLabs } from './elevenlabs-provider'; import { readFile } from 'node:fs/promises'; diff --git a/packages/fal/package.json b/packages/fal/package.json index a23cc392ce44..f55bfa2b90cf 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fal/src/fal-image-model.test.ts b/packages/fal/src/fal-image-model.test.ts index de5543c6e630..81062bea5cc0 100644 --- a/packages/fal/src/fal-image-model.test.ts +++ b/packages/fal/src/fal-image-model.test.ts @@ -1,5 +1,5 @@ import { FetchFunction } from '@ai-sdk/provider-utils'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it } from 'vitest'; import { FalImageModel } from './fal-image-model'; diff --git a/packages/fal/src/fal-speech-model.test.ts b/packages/fal/src/fal-speech-model.test.ts index cc125d8e9c42..bd4f0be7e8f3 100644 --- a/packages/fal/src/fal-speech-model.test.ts +++ b/packages/fal/src/fal-speech-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createFal } from './fal-provider'; import { FalSpeechModel } from './fal-speech-model'; import { describe, it, expect } from 'vitest'; diff --git a/packages/fal/src/fal-transcription-model.test.ts b/packages/fal/src/fal-transcription-model.test.ts index 93b03345de28..cb4471ecf4e7 100644 --- a/packages/fal/src/fal-transcription-model.test.ts +++ b/packages/fal/src/fal-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createFal } from './fal-provider'; import { FalTranscriptionModel } from './fal-transcription-model'; import { readFile } from 'node:fs/promises'; diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index 58535e382a43..da6725697e33 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -34,7 +34,8 @@ "dependencies": { "@ai-sdk/openai-compatible": "workspace:*", "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/fireworks/src/fireworks-image-model.test.ts b/packages/fireworks/src/fireworks-image-model.test.ts index 183d6fcd2525..c6fa970fde7b 100644 --- a/packages/fireworks/src/fireworks-image-model.test.ts +++ b/packages/fireworks/src/fireworks-image-model.test.ts @@ -1,5 +1,5 @@ import { FetchFunction } from '@ai-sdk/provider-utils'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it, vi } from 'vitest'; import { FireworksImageModel } from './fireworks-image-model'; diff --git a/packages/gateway/package.json b/packages/gateway/package.json index e58f343ff7c8..d4c016284b0a 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -37,6 +37,7 @@ "@ai-sdk/provider-utils": "workspace:*" }, "devDependencies": { + "@ai-sdk/test-server": "workspace:*", "@types/node": "18.15.11", "@vercel/ai-tsconfig": "workspace:*", "tsup": "^8", diff --git a/packages/gateway/src/gateway-embedding-model.test.ts b/packages/gateway/src/gateway-embedding-model.test.ts index 0259697a9327..f217a3ea4277 100644 --- a/packages/gateway/src/gateway-embedding-model.test.ts +++ b/packages/gateway/src/gateway-embedding-model.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GatewayEmbeddingModel } from './gateway-embedding-model'; import type { GatewayConfig } from './gateway-config'; import { diff --git a/packages/gateway/src/gateway-fetch-metadata.test.ts b/packages/gateway/src/gateway-fetch-metadata.test.ts index 8e7dcd7b383f..4401ad93dd86 100644 --- a/packages/gateway/src/gateway-fetch-metadata.test.ts +++ b/packages/gateway/src/gateway-fetch-metadata.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it, vi } from 'vitest'; import { GatewayFetchMetadata } from './gateway-fetch-metadata'; import type { FetchFunction } from '@ai-sdk/provider-utils'; diff --git a/packages/gateway/src/gateway-language-model.test.ts b/packages/gateway/src/gateway-language-model.test.ts index 5edf029655b4..9013e4fd97c2 100644 --- a/packages/gateway/src/gateway-language-model.test.ts +++ b/packages/gateway/src/gateway-language-model.test.ts @@ -2,10 +2,8 @@ import type { LanguageModelV2Prompt, LanguageModelV2FilePart, } from '@ai-sdk/provider'; -import { - convertReadableStreamToArray, - createTestServer, -} from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; +import { convertReadableStreamToArray } from '@ai-sdk/provider-utils/test'; import { GatewayLanguageModel } from './gateway-language-model'; import type { GatewayConfig } from './gateway-config'; import { diff --git a/packages/gateway/tsconfig.json b/packages/gateway/tsconfig.json index 6d7c00da20f6..e26d6c5085a9 100644 --- a/packages/gateway/tsconfig.json +++ b/packages/gateway/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "composite": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "paths": { + "@ai-sdk/test-server": ["../test-server/src"] + } }, "exclude": ["dist", "build", "node_modules", "tsup.config.ts"], "references": [ @@ -12,6 +15,9 @@ }, { "path": "../provider-utils" + }, + { + "path": "../test-server" } ] } diff --git a/packages/gladia/package.json b/packages/gladia/package.json index 46d0175ba985..5fccb3632a9b 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/gladia/src/gladia-transcription-model.test.ts b/packages/gladia/src/gladia-transcription-model.test.ts index dafe1adc2104..7df3666e1ea4 100644 --- a/packages/gladia/src/gladia-transcription-model.test.ts +++ b/packages/gladia/src/gladia-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GladiaTranscriptionModel } from './gladia-transcription-model'; import { createGladia } from './gladia-provider'; import { readFile } from 'node:fs/promises'; diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 1da5f3cb6ca0..94c5a1b0f79f 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -54,6 +54,7 @@ "@ai-sdk/google": "workspace:*", "@ai-sdk/provider": "workspace:*", "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*", "google-auth-library": "^9.15.0" }, "devDependencies": { diff --git a/packages/google-vertex/src/google-vertex-embedding-model.test.ts b/packages/google-vertex/src/google-vertex-embedding-model.test.ts index 6ea63548fb97..20fae94ecd21 100644 --- a/packages/google-vertex/src/google-vertex-embedding-model.test.ts +++ b/packages/google-vertex/src/google-vertex-embedding-model.test.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV2Embedding, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleVertexEmbeddingModel } from './google-vertex-embedding-model'; import { describe, it, expect, vi } from 'vitest'; 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 d894fd752b13..9a1f171bc94e 100644 --- a/packages/google-vertex/src/google-vertex-image-model.test.ts +++ b/packages/google-vertex/src/google-vertex-image-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleVertexImageModel } from './google-vertex-image-model'; import { describe, it, expect } from 'vitest'; diff --git a/packages/google/package.json b/packages/google/package.json index 3d3760a092f6..d14c942791c5 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -40,7 +40,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/google/src/google-generative-ai-embedding-model.test.ts b/packages/google/src/google-generative-ai-embedding-model.test.ts index b1da11a0f3a1..a3757722bdd1 100644 --- a/packages/google/src/google-generative-ai-embedding-model.test.ts +++ b/packages/google/src/google-generative-ai-embedding-model.test.ts @@ -1,5 +1,5 @@ import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleGenerativeAIEmbeddingModel } from './google-generative-ai-embedding-model'; import { createGoogleGenerativeAI } from './google-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/google/src/google-generative-ai-image-model.test.ts b/packages/google/src/google-generative-ai-image-model.test.ts index 4f875ca6d2f7..f273a1e9f3da 100644 --- a/packages/google/src/google-generative-ai-image-model.test.ts +++ b/packages/google/src/google-generative-ai-image-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleGenerativeAIImageModel } from './google-generative-ai-image-model'; import { describe, it, expect } from 'vitest'; 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 1f63c10ece64..5ca06f9a67f7 100644 --- a/packages/google/src/google-generative-ai-language-model.test.ts +++ b/packages/google/src/google-generative-ai-language-model.test.ts @@ -2,10 +2,8 @@ import { LanguageModelV2Prompt, LanguageModelV2ProviderDefinedTool, } from '@ai-sdk/provider'; -import { - convertReadableStreamToArray, - createTestServer, -} from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; +import { convertReadableStreamToArray } from '@ai-sdk/provider-utils/test'; import { GoogleGenerativeAILanguageModel } from './google-generative-ai-language-model'; import { diff --git a/packages/groq/package.json b/packages/groq/package.json index be0b3f3c3090..5251922da3b3 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/groq/src/groq-chat-language-model.test.ts b/packages/groq/src/groq-chat-language-model.test.ts index 92d0a2f46f8d..0e977a9c99b6 100644 --- a/packages/groq/src/groq-chat-language-model.test.ts +++ b/packages/groq/src/groq-chat-language-model.test.ts @@ -1,7 +1,7 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createGroq } from './groq-provider'; diff --git a/packages/groq/src/groq-transcription-model.test.ts b/packages/groq/src/groq-transcription-model.test.ts index 0907cdd08d25..b50e89129a9d 100644 --- a/packages/groq/src/groq-transcription-model.test.ts +++ b/packages/groq/src/groq-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GroqTranscriptionModel } from './groq-transcription-model'; import { createGroq } from './groq-provider'; import { readFile } from 'node:fs/promises'; diff --git a/packages/hume/package.json b/packages/hume/package.json index 4d6358eb2126..8f0cf578cdda 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/hume/src/hume-speech-model.test.ts b/packages/hume/src/hume-speech-model.test.ts index 937cb507999a..13f8ad084569 100644 --- a/packages/hume/src/hume-speech-model.test.ts +++ b/packages/hume/src/hume-speech-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { HumeSpeechModel } from './hume-speech-model'; import { createHume } from './hume-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index 569a794f6446..eb47c744ff71 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/lmnt/src/lmnt-speech-model.test.ts b/packages/lmnt/src/lmnt-speech-model.test.ts index 07624446cb15..f3fb13062b31 100644 --- a/packages/lmnt/src/lmnt-speech-model.test.ts +++ b/packages/lmnt/src/lmnt-speech-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { LMNTSpeechModel } from './lmnt-speech-model'; import { createLMNT } from './lmnt-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/luma/package.json b/packages/luma/package.json index cc7038777a4d..1019d5fffcdb 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/luma/src/luma-image-model.test.ts b/packages/luma/src/luma-image-model.test.ts index 3e95aa0eb6df..1e1de37e7a35 100644 --- a/packages/luma/src/luma-image-model.test.ts +++ b/packages/luma/src/luma-image-model.test.ts @@ -1,5 +1,5 @@ import { FetchFunction } from '@ai-sdk/provider-utils'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it } from 'vitest'; import { LumaImageModel } from './luma-image-model'; import { InvalidResponseDataError } from '@ai-sdk/provider'; diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 8a48cb7b595e..083453670115 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/mistral/src/mistral-chat-language-model.test.ts b/packages/mistral/src/mistral-chat-language-model.test.ts index 533e56fb8ff2..152e36f50da8 100644 --- a/packages/mistral/src/mistral-chat-language-model.test.ts +++ b/packages/mistral/src/mistral-chat-language-model.test.ts @@ -1,7 +1,7 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, mockId, } from '@ai-sdk/provider-utils/test'; import { createMistral } from './mistral-provider'; diff --git a/packages/mistral/src/mistral-embedding-model.test.ts b/packages/mistral/src/mistral-embedding-model.test.ts index abacf43b04b8..5286a4326f9a 100644 --- a/packages/mistral/src/mistral-embedding-model.test.ts +++ b/packages/mistral/src/mistral-embedding-model.test.ts @@ -1,5 +1,5 @@ import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createMistral } from './mistral-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index bcfd522818f2..1200e6b534ac 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -40,7 +40,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts b/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts index 85f00150946a..0584a85da78e 100644 --- a/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts +++ b/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from 'vitest'; import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createOpenAICompatible } from '../openai-compatible-provider'; diff --git a/packages/openai-compatible/src/completion/openai-compatible-completion-language-model.test.ts b/packages/openai-compatible/src/completion/openai-compatible-completion-language-model.test.ts index 2ded48833d2f..372178feefc1 100644 --- a/packages/openai-compatible/src/completion/openai-compatible-completion-language-model.test.ts +++ b/packages/openai-compatible/src/completion/openai-compatible-completion-language-model.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from 'vitest'; import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createOpenAICompatible } from '../openai-compatible-provider'; diff --git a/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts b/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts index 9e0f6e2308d6..1c05342038f8 100644 --- a/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts +++ b/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAICompatible } from '../openai-compatible-provider'; const dummyEmbeddings = [ diff --git a/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts b/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts index bc5f86e4c21e..06df26e65b15 100644 --- a/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts +++ b/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { FetchFunction } from '@ai-sdk/provider-utils'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { OpenAICompatibleImageModel } from './openai-compatible-image-model'; import { z } from 'zod/v4'; import { ProviderErrorStructure } from '../openai-compatible-error'; diff --git a/packages/openai/package.json b/packages/openai/package.json index 31434007c833..83f230f02589 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -40,7 +40,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/openai/src/chat/openai-chat-language-model.test.ts b/packages/openai/src/chat/openai-chat-language-model.test.ts index a7e19b5d6842..f6db0764318d 100644 --- a/packages/openai/src/chat/openai-chat-language-model.test.ts +++ b/packages/openai/src/chat/openai-chat-language-model.test.ts @@ -1,7 +1,7 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createOpenAI } from '../openai-provider'; diff --git a/packages/openai/src/completion/openai-completion-language-model.test.ts b/packages/openai/src/completion/openai-completion-language-model.test.ts index 6306f86a3a7b..064096fe727d 100644 --- a/packages/openai/src/completion/openai-completion-language-model.test.ts +++ b/packages/openai/src/completion/openai-completion-language-model.test.ts @@ -1,7 +1,7 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createOpenAI } from '../openai-provider'; diff --git a/packages/openai/src/embedding/openai-embedding-model.test.ts b/packages/openai/src/embedding/openai-embedding-model.test.ts index 83542550a827..5c0919976af4 100644 --- a/packages/openai/src/embedding/openai-embedding-model.test.ts +++ b/packages/openai/src/embedding/openai-embedding-model.test.ts @@ -1,5 +1,5 @@ import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; import { describe, it, expect } from 'vitest'; diff --git a/packages/openai/src/image/openai-image-model.test.ts b/packages/openai/src/image/openai-image-model.test.ts index c6a293e41f33..19880945f97d 100644 --- a/packages/openai/src/image/openai-image-model.test.ts +++ b/packages/openai/src/image/openai-image-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; import { OpenAIImageModel } from './openai-image-model'; import { describe, it, expect } from 'vitest'; diff --git a/packages/openai/src/responses/openai-responses-language-model.test.ts b/packages/openai/src/responses/openai-responses-language-model.test.ts index f5b5e75fd7d3..65c6d27a754e 100644 --- a/packages/openai/src/responses/openai-responses-language-model.test.ts +++ b/packages/openai/src/responses/openai-responses-language-model.test.ts @@ -3,9 +3,9 @@ import { LanguageModelV2FunctionTool, LanguageModelV2Prompt, } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, mockId, } from '@ai-sdk/provider-utils/test'; import fs from 'node:fs'; diff --git a/packages/openai/src/speech/openai-speech-model.test.ts b/packages/openai/src/speech/openai-speech-model.test.ts index 1dc6ef4d379e..e5186293d578 100644 --- a/packages/openai/src/speech/openai-speech-model.test.ts +++ b/packages/openai/src/speech/openai-speech-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; import { OpenAISpeechModel } from './openai-speech-model'; import { describe, it, expect } from 'vitest'; diff --git a/packages/openai/src/transcription/openai-transcription-model.test.ts b/packages/openai/src/transcription/openai-transcription-model.test.ts index c8100a2bc546..90bb37da040a 100644 --- a/packages/openai/src/transcription/openai-transcription-model.test.ts +++ b/packages/openai/src/transcription/openai-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { createOpenAI } from '../openai-provider'; diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index 0e599a6afde0..f78f649c2f3e 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/perplexity/src/perplexity-language-model.test.ts b/packages/perplexity/src/perplexity-language-model.test.ts index dfa4652796f3..ef007c962e2c 100644 --- a/packages/perplexity/src/perplexity-language-model.test.ts +++ b/packages/perplexity/src/perplexity-language-model.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from 'vitest'; import { LanguageModelV2Prompt } from '@ai-sdk/provider'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray, - createTestServer, mockId, } from '@ai-sdk/provider-utils/test'; import { z } from 'zod/v4'; diff --git a/packages/provider-utils/src/test/index.ts b/packages/provider-utils/src/test/index.ts index cf0f28e20fcb..a8a334ea8f61 100644 --- a/packages/provider-utils/src/test/index.ts +++ b/packages/provider-utils/src/test/index.ts @@ -5,4 +5,3 @@ export * from './convert-readable-stream-to-array'; export * from './convert-response-stream-to-array'; export * from './is-node-version'; export * from './mock-id'; -export * from './test-server'; diff --git a/packages/react/package.json b/packages/react/package.json index e53b311669f2..e9e43bb0b5be 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -30,8 +30,9 @@ "CHANGELOG.md" ], "dependencies": { - "ai": "workspace:*", "@ai-sdk/provider-utils": "workspace:*", + "ai": "workspace:*", + "@ai-sdk/test-server": "workspace:*", "swr": "^2.2.5", "throttleit": "2.1.0" }, @@ -47,7 +48,7 @@ "eslint-config-vercel-ai": "workspace:*", "jsdom": "^24.0.0", "msw": "2.6.4", - "react-dom": "^18", + "react-dom": "^18 || ^19 || ^19.0.0-rc", "tsup": "^7.2.0", "typescript": "5.8.3", "zod": "3.25.76" diff --git a/packages/react/src/use-chat.ui.test.tsx b/packages/react/src/use-chat.ui.test.tsx index 96a468861cb7..7521413cf64a 100644 --- a/packages/react/src/use-chat.ui.test.tsx +++ b/packages/react/src/use-chat.ui.test.tsx @@ -2,9 +2,9 @@ /* eslint-disable @next/next/no-img-element */ import { createTestServer, - mockId, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; +import { mockId } from '@ai-sdk/provider-utils/test'; import '@testing-library/jest-dom/vitest'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; diff --git a/packages/react/src/use-completion.ui.test.tsx b/packages/react/src/use-completion.ui.test.tsx index 5cac42ba3306..debabd311de1 100644 --- a/packages/react/src/use-completion.ui.test.tsx +++ b/packages/react/src/use-completion.ui.test.tsx @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import '@testing-library/jest-dom/vitest'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; diff --git a/packages/react/src/use-object.ui.test.tsx b/packages/react/src/use-object.ui.test.tsx index a31293956a07..667630b304eb 100644 --- a/packages/react/src/use-object.ui.test.tsx +++ b/packages/react/src/use-object.ui.test.tsx @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import '@testing-library/jest-dom/vitest'; import { cleanup, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; diff --git a/packages/replicate/package.json b/packages/replicate/package.json index 28ab8aa82f21..eb0460aca839 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -33,7 +33,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/replicate/src/replicate-image-model.test.ts b/packages/replicate/src/replicate-image-model.test.ts index dc439fc233f4..373844ab13e5 100644 --- a/packages/replicate/src/replicate-image-model.test.ts +++ b/packages/replicate/src/replicate-image-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createReplicate } from './replicate-provider'; import { ReplicateImageModel } from './replicate-image-model'; import { describe, it, expect } from 'vitest'; diff --git a/packages/revai/package.json b/packages/revai/package.json index 33e08f058468..ecfddd619f70 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/revai/src/revai-transcription-model.test.ts b/packages/revai/src/revai-transcription-model.test.ts index 34e13c9246bc..e8db5719bd4a 100644 --- a/packages/revai/src/revai-transcription-model.test.ts +++ b/packages/revai/src/revai-transcription-model.test.ts @@ -1,4 +1,4 @@ -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { RevaiTranscriptionModel } from './revai-transcription-model'; import { createRevai } from './revai-provider'; import { readFile } from 'node:fs/promises'; diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 3c8b06dbc924..d27ef66d8ad9 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -52,17 +52,18 @@ } }, "dependencies": { - "ai": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*", + "ai": "workspace:*" }, "devDependencies": { - "@types/node": "20.17.24", "@eslint/compat": "^1.2.5", "@eslint/js": "^9.18.0", "@sveltejs/package": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.3", "@testing-library/jest-dom": "^6.6.3", "@testing-library/svelte": "^5.2.4", + "@types/node": "20.17.24", "@vercel/ai-tsconfig": "workspace:*", "eslint": "^9.18.0", "eslint-plugin-svelte": "^3.0.0", diff --git a/packages/svelte/src/chat.svelte.test.ts b/packages/svelte/src/chat.svelte.test.ts index 587e21ee2266..207798ee75a1 100644 --- a/packages/svelte/src/chat.svelte.test.ts +++ b/packages/svelte/src/chat.svelte.test.ts @@ -1,8 +1,8 @@ import { createTestServer, - mockId, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; +import { mockId } from '@ai-sdk/provider-utils/test'; import { DefaultChatTransport, isToolUIPart, diff --git a/packages/svelte/src/completion.svelte.test.ts b/packages/svelte/src/completion.svelte.test.ts index e7b36cf8cf73..653b55dcffa3 100644 --- a/packages/svelte/src/completion.svelte.test.ts +++ b/packages/svelte/src/completion.svelte.test.ts @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import { render } from '@testing-library/svelte'; import type { UIMessageChunk } from 'ai'; import { Completion } from './completion.svelte.js'; diff --git a/packages/svelte/src/structured-object.svelte.test.ts b/packages/svelte/src/structured-object.svelte.test.ts index 10cb6c086fbf..c12ef6250828 100644 --- a/packages/svelte/src/structured-object.svelte.test.ts +++ b/packages/svelte/src/structured-object.svelte.test.ts @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import { render } from '@testing-library/svelte'; import { z } from 'zod/v4'; import { StructuredObject } from './structured-object.svelte.js'; diff --git a/packages/test-server/package.json b/packages/test-server/package.json new file mode 100644 index 000000000000..8346874ac3d8 --- /dev/null +++ b/packages/test-server/package.json @@ -0,0 +1,68 @@ +{ + "name": "@ai-sdk/test-server", + "version": "0.0.0", + "license": "Apache-2.0", + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist/**/*", + "CHANGELOG.md" + ], + "scripts": { + "build": "pnpm clean && tsup --tsconfig tsconfig.build.json", + "build:watch": "pnpm clean && tsup --watch", + "clean": "rm -rf dist *.tsbuildinfo", + "lint": "eslint \"./**/*.ts*\"", + "type-check": "tsc --build", + "prettier-check": "prettier --check \"./**/*.ts*\"", + "test": "pnpm test:node && pnpm test:edge", + "test:update": "pnpm test:node -u", + "test:watch": "vitest --config vitest.node.config.js", + "test:edge": "vitest --config vitest.edge.config.js --run", + "test:node": "vitest --config vitest.node.config.js --run" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./with-vitest": { + "types": "./dist/with-vitest.d.ts", + "import": "./dist/with-vitest.mjs", + "module": "./dist/with-vitest.mjs", + "require": "./dist/with-vitest.js" + } + }, + "devDependencies": { + "@types/node": "20.17.24", + "@vercel/ai-tsconfig": "workspace:*", + "tsup": "^8", + "msw": "^2.7.0", + "typescript": "5.8.3" + }, + "engines": { + "node": ">=18" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://ai-sdk.dev/docs", + "repository": { + "type": "git", + "url": "git+https://github.com/vercel/ai.git" + }, + "bugs": { + "url": "https://github.com/vercel/ai/issues" + }, + "keywords": [ + "ai", + "test-server", + "msw" + ] + } + + \ No newline at end of file diff --git a/packages/test-server/src/convert-array-to-readable-stream.ts b/packages/test-server/src/convert-array-to-readable-stream.ts new file mode 100644 index 000000000000..ac945e5e34b8 --- /dev/null +++ b/packages/test-server/src/convert-array-to-readable-stream.ts @@ -0,0 +1,15 @@ +export function convertArrayToReadableStream( + values: T[], +): ReadableStream { + return new ReadableStream({ + start(controller) { + try { + for (const value of values) { + controller.enqueue(value); + } + } finally { + controller.close(); + } + }, + }); +} diff --git a/packages/provider-utils/src/test/test-server.ts b/packages/test-server/src/create-test-server.ts similarity index 93% rename from packages/provider-utils/src/test/test-server.ts rename to packages/test-server/src/create-test-server.ts index 94b066b01353..cc15e8362687 100644 --- a/packages/provider-utils/src/test/test-server.ts +++ b/packages/test-server/src/create-test-server.ts @@ -1,7 +1,6 @@ import { http, HttpResponse, JsonBodyType } from 'msw'; import { setupServer } from 'msw/node'; import { convertArrayToReadableStream } from './convert-array-to-readable-stream'; -import { beforeAll, beforeEach, afterAll } from 'vitest'; export type UrlResponse = | { @@ -67,8 +66,7 @@ class TestServerCall { 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 => { + ? this.request!.formData().then(formData => { const entries: Record = {}; formData.forEach((value, key) => { entries[key] = value; @@ -85,7 +83,6 @@ class TestServerCall { get requestHeaders() { const requestHeaders = this.request!.headers; - // convert headers to object for easier comparison const headersObject: Record = {}; requestHeaders.forEach((value, key) => { if (key.toLowerCase() === 'user-agent') return; @@ -123,8 +120,9 @@ export function createTestServer< ): { urls: UrlHandlers; calls: TestServerCall[]; + server: { start: () => void; stop: () => void; reset: () => void }; } { - const originalRoutes = structuredClone(routes); // deep copy + const originalRoutes = structuredClone(routes); const mswServer = setupServer( ...Object.entries(routes).map(([url, handler]) => { @@ -224,30 +222,30 @@ export function createTestServer< let calls: TestServerCall[] = []; - beforeAll(() => { + const start = () => { mswServer.listen(); - }); + }; - beforeEach(() => { + const reset = () => { mswServer.resetHandlers(); - // set the responses back to the original values Object.entries(originalRoutes).forEach(([url, handler]) => { routes[url].response = handler.response; }); calls = []; - }); + }; - afterAll(() => { + const stop = () => { mswServer.close(); - }); + }; return { urls: routes as UrlHandlers, get calls() { return calls; }, + server: { start, stop, reset }, }; } diff --git a/packages/test-server/src/index.ts b/packages/test-server/src/index.ts new file mode 100644 index 000000000000..a7c979dddcbc --- /dev/null +++ b/packages/test-server/src/index.ts @@ -0,0 +1,7 @@ +export { + createTestServer, + TestResponseController, + type UrlResponse, + type UrlHandler, + type UrlHandlers, +} from './create-test-server'; diff --git a/packages/test-server/src/with-vitest.test.ts b/packages/test-server/src/with-vitest.test.ts new file mode 100644 index 000000000000..64d29f0d100d --- /dev/null +++ b/packages/test-server/src/with-vitest.test.ts @@ -0,0 +1,101 @@ +import { describe, it, expect } from 'vitest'; +import { createTestServer, TestResponseController } from './with-vitest'; + +describe('createTestServer', () => { + it('should create a test server with basic functionality', () => { + const server = createTestServer({ + 'https://api.example.com/test': { + response: { + type: 'json-value', + body: { message: 'hello world' }, + }, + }, + }); + + expect(server).toBeDefined(); + expect(server.urls).toBeDefined(); + expect(server.calls).toBeDefined(); + expect(Array.isArray(server.calls)).toBe(true); + expect(server.calls.length).toBe(0); + }); + + it('should handle response mutations', () => { + const server = createTestServer({ + 'https://api.example.com/test': { + response: { + type: 'json-value', + body: { count: 1 }, + }, + }, + }); + + // Should be able to mutate responses + server.urls['https://api.example.com/test'].response = { + type: 'json-value', + body: { count: 2 }, + }; + + expect(server.urls['https://api.example.com/test'].response).toEqual({ + type: 'json-value', + body: { count: 2 }, + }); + }); + + it('should support different response types', () => { + const server = createTestServer({ + 'https://api.example.com/json': { + response: { + type: 'json-value', + body: { test: true }, + }, + }, + 'https://api.example.com/stream': { + response: { + type: 'stream-chunks', + chunks: ['chunk1', 'chunk2'], + }, + }, + 'https://api.example.com/error': { + response: { + type: 'error', + status: 400, + body: 'Bad Request', + }, + }, + }); + + expect(server.urls['https://api.example.com/json'].response).toEqual({ + type: 'json-value', + body: { test: true }, + }); + + expect(server.urls['https://api.example.com/stream'].response).toEqual({ + type: 'stream-chunks', + chunks: ['chunk1', 'chunk2'], + }); + + expect(server.urls['https://api.example.com/error'].response).toEqual({ + type: 'error', + status: 400, + body: 'Bad Request', + }); + }); +}); + +describe('TestResponseController', () => { + it('should create a controller with stream access', () => { + const controller = new TestResponseController(); + + expect(controller).toBeDefined(); + expect(controller.stream).toBeDefined(); + expect(controller.stream).toBeInstanceOf(ReadableStream); + }); + + it('should have write, error, and close methods', () => { + const controller = new TestResponseController(); + + expect(typeof controller.write).toBe('function'); + expect(typeof controller.error).toBe('function'); + expect(typeof controller.close).toBe('function'); + }); +}); diff --git a/packages/test-server/src/with-vitest.ts b/packages/test-server/src/with-vitest.ts new file mode 100644 index 000000000000..8196cd71e58e --- /dev/null +++ b/packages/test-server/src/with-vitest.ts @@ -0,0 +1,57 @@ +import { beforeAll, beforeEach, afterAll } from 'vitest'; +import { + createTestServer as createCoreTestServer, + TestResponseController, + type UrlResponse, + type UrlHandler, + type UrlHandlers, +} from './index'; + +export function createTestServer< + URLS extends { + [url: string]: { + response?: + | UrlResponse + | UrlResponse[] + | ((options: { callNumber: number }) => UrlResponse); + }; + }, +>( + routes: URLS, +): { + urls: UrlHandlers; + calls: Array<{ + readonly requestBodyJson: Promise; + readonly requestBodyMultipart: Promise | null> | null; + readonly requestCredentials: RequestCredentials; + readonly requestHeaders: Record; + readonly requestUserAgent: string | undefined; + readonly requestUrlSearchParams: URLSearchParams; + readonly requestUrl: string; + readonly requestMethod: string; + }>; +} { + const server = createCoreTestServer(routes); + + beforeAll(() => { + server.server.start(); + }); + + beforeEach(() => { + server.server.reset(); + }); + + afterAll(() => { + server.server.stop(); + }); + + return { + urls: server.urls, + get calls() { + return server.calls; + }, + }; +} + +export { TestResponseController }; +export type { UrlResponse, UrlHandler, UrlHandlers }; diff --git a/packages/test-server/tsconfig.build.json b/packages/test-server/tsconfig.build.json new file mode 100644 index 000000000000..6242aec27cfe --- /dev/null +++ b/packages/test-server/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": false + } + } + \ No newline at end of file diff --git a/packages/test-server/tsconfig.json b/packages/test-server/tsconfig.json new file mode 100644 index 000000000000..6b9d536feb75 --- /dev/null +++ b/packages/test-server/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "./node_modules/@vercel/ai-tsconfig/ts-library.json", + "compilerOptions": { + "composite": true, + "rootDir": "src", + "outDir": "dist" + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "dist", + "build", + "node_modules", + "tsup.config.ts" + ], + "references": [ + { + "path": "../provider" + } + ] + } + \ No newline at end of file diff --git a/packages/test-server/tsup.config.ts b/packages/test-server/tsup.config.ts new file mode 100644 index 000000000000..8b70cfbd5748 --- /dev/null +++ b/packages/test-server/tsup.config.ts @@ -0,0 +1,32 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig([ + { + entry: ['src/index.ts'], + format: ['cjs', 'esm'], + dts: true, + sourcemap: true, + target: 'es2018', + platform: 'node', + }, + { + entry: ['src/with-vitest.ts'], + format: ['cjs', 'esm'], + dts: true, + sourcemap: true, + target: 'es2020', + platform: 'node', + external: [ + 'chai', + 'msw', + 'msw/*', + 'vitest', + 'vitest/*', + '@vitest/*', + 'vitest/dist/*', + 'vitest/dist/chunks/*', + 'vitest/dist/node/*', + 'vitest/dist/node/chunks/*', + ], + }, +]); diff --git a/packages/test-server/vitest.edge.config.js b/packages/test-server/vitest.edge.config.js new file mode 100644 index 000000000000..3dc49ba29774 --- /dev/null +++ b/packages/test-server/vitest.edge.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + test: { + environment: 'edge-runtime', + include: ['**/*.test.ts', '**/*.test.tsx'], + }, +}); diff --git a/packages/test-server/vitest.node.config.js b/packages/test-server/vitest.node.config.js new file mode 100644 index 000000000000..b7e4a9cabd48 --- /dev/null +++ b/packages/test-server/vitest.node.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + test: { + environment: 'node', + include: ['**/*.test.ts', '**/*.test.tsx'], + }, +}); diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index f9002706459d..be1ca9d152ce 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -34,7 +34,8 @@ "dependencies": { "@ai-sdk/openai-compatible": "workspace:*", "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/togetherai/src/togetherai-image-model.test.ts b/packages/togetherai/src/togetherai-image-model.test.ts index a739a7883838..f6fb46582167 100644 --- a/packages/togetherai/src/togetherai-image-model.test.ts +++ b/packages/togetherai/src/togetherai-image-model.test.ts @@ -1,5 +1,5 @@ import { FetchFunction } from '@ai-sdk/provider-utils'; -import { createTestServer } from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { describe, expect, it } from 'vitest'; import { TogetherAIImageModel } from './togetherai-image-model'; diff --git a/packages/vue/package.json b/packages/vue/package.json index d27c131fa61c..34a7f1394439 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -30,8 +30,9 @@ "CHANGELOG.md" ], "dependencies": { - "ai": "workspace:*", "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*", + "ai": "workspace:*", "swrv": "^1.0.4" }, "devDependencies": { diff --git a/packages/vue/src/chat.vue.ui.test.tsx b/packages/vue/src/chat.vue.ui.test.tsx index 0516e57e4f63..7174c654aae1 100644 --- a/packages/vue/src/chat.vue.ui.test.tsx +++ b/packages/vue/src/chat.vue.ui.test.tsx @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import '@testing-library/jest-dom/vitest'; import userEvent from '@testing-library/user-event'; import { screen, waitFor } from '@testing-library/vue'; diff --git a/packages/vue/src/use-completion.ui.test.ts b/packages/vue/src/use-completion.ui.test.ts index e1823e446d09..f1f07df84536 100644 --- a/packages/vue/src/use-completion.ui.test.ts +++ b/packages/vue/src/use-completion.ui.test.ts @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import '@testing-library/jest-dom/vitest'; import userEvent from '@testing-library/user-event'; import { findByText, screen } from '@testing-library/vue'; diff --git a/packages/vue/src/use-object.ui.test.tsx b/packages/vue/src/use-object.ui.test.tsx index fdc05efd5196..291370a8101f 100644 --- a/packages/vue/src/use-object.ui.test.tsx +++ b/packages/vue/src/use-object.ui.test.tsx @@ -1,7 +1,7 @@ import { createTestServer, TestResponseController, -} from '@ai-sdk/provider-utils/test'; +} from '@ai-sdk/test-server/with-vitest'; import '@testing-library/jest-dom/vitest'; import { cleanup, screen, waitFor } from '@testing-library/vue'; import userEvent from '@testing-library/user-event'; diff --git a/packages/xai/package.json b/packages/xai/package.json index c79b1752008f..61cd28c1f177 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -34,7 +34,8 @@ "dependencies": { "@ai-sdk/openai-compatible": "workspace:*", "@ai-sdk/provider": "workspace:*", - "@ai-sdk/provider-utils": "workspace:*" + "@ai-sdk/provider-utils": "workspace:*", + "@ai-sdk/test-server": "workspace:*" }, "devDependencies": { "@types/node": "20.17.24", diff --git a/packages/xai/src/xai-chat-language-model.test.ts b/packages/xai/src/xai-chat-language-model.test.ts index 4829a5c6f5be..fcde6e247564 100644 --- a/packages/xai/src/xai-chat-language-model.test.ts +++ b/packages/xai/src/xai-chat-language-model.test.ts @@ -1,10 +1,8 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; import { describe, it, expect } from 'vitest'; -import { - convertReadableStreamToArray, - createTestServer, -} from '@ai-sdk/provider-utils/test'; +import { createTestServer } from '@ai-sdk/test-server/with-vitest'; +import { convertReadableStreamToArray } from '@ai-sdk/provider-utils/test'; import { XaiChatLanguageModel } from './xai-chat-language-model'; const TEST_PROMPT: LanguageModelV2Prompt = [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 439a24a532a8..827e7d91231e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.27.10 '@playwright/test': specifier: ^1.44.1 - version: 1.46.0 + version: 1.50.1 eslint: specifier: 8.57.1 version: 8.57.1 @@ -28,10 +28,10 @@ importers: version: 15.2.10 next: specifier: 15.0.0-canary.23 - version: 15.0.0-canary.23(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(react-dom@19.0.0-rc-cc1ec60d0d-20240607(react@19.0.0-rc-cc1ec60d0d-20240607))(react@19.0.0-rc-cc1ec60d0d-20240607)(sass@1.85.0) + version: 15.0.0-canary.23(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0-rc-cc1ec60d0d-20240607(react@19.0.0-rc-cc1ec60d0d-20240607))(react@19.0.0-rc-cc1ec60d0d-20240607)(sass@1.85.0) playwright: specifier: ^1.44.1 - version: 1.46.0 + version: 1.50.1 prettier: specifier: 3.5.3 version: 3.5.3 @@ -190,7 +190,7 @@ importers: version: 2.0.0 valibot: specifier: ^1.0.0-rc.0 || ^1.0.0 - version: 1.0.0-rc.0(typescript@5.8.3) + version: 1.1.0(typescript@5.8.3) zod: specifier: 3.25.76 version: 3.25.76 @@ -443,7 +443,7 @@ importers: version: 10.4.8 '@nestjs/schematics': specifier: ^10.2.3 - version: 10.2.3(chokidar@3.6.0)(typescript@5.5.4) + version: 10.2.3(chokidar@3.6.0)(typescript@5.8.3) '@nestjs/testing': specifier: ^10.4.12 version: 10.4.12(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.2)(@nestjs/platform-express@10.4.9) @@ -461,10 +461,10 @@ importers: version: 6.0.2 '@typescript-eslint/eslint-plugin': specifier: ^8.0.0 - version: 8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4) + version: 8.26.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.0.0 - version: 8.6.0(eslint@8.57.1)(typescript@5.5.4) + version: 8.26.0(eslint@8.57.1)(typescript@5.8.3) '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig @@ -476,13 +476,13 @@ importers: version: 10.0.2(eslint@8.57.1) eslint-plugin-prettier: specifier: ^5.0.0 - version: 5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@10.0.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) + version: 5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@10.0.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3) jest: specifier: ^29.5.0 - version: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) + version: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) prettier: specifier: ^3.0.0 - version: 3.3.3 + version: 3.5.3 source-map-support: specifier: ^0.5.21 version: 0.5.21 @@ -491,19 +491,19 @@ importers: version: 7.0.0 ts-jest: specifier: ^29.1.0 - version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)))(typescript@5.5.4) + version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)))(typescript@5.8.3) ts-loader: specifier: ^9.4.3 - version: 9.5.1(typescript@5.5.4)(webpack@5.96.1) + version: 9.5.1(typescript@5.8.3)(webpack@5.96.1) ts-node: specifier: ^10.9.1 - version: 10.9.2(@types/node@20.17.24)(typescript@5.5.4) + version: 10.9.2(@types/node@20.17.24)(typescript@5.8.3) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 typescript: specifier: ^5.1.3 - version: 5.5.4 + version: 5.8.3 examples/next: dependencies: @@ -518,7 +518,7 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.3.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 version: 18.3.1 @@ -582,7 +582,7 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.5.2(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 version: 18.3.1 @@ -640,16 +640,16 @@ importers: version: link:../../packages/ai geist: specifier: ^1.3.1 - version: 1.3.1(next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0)) + version: 1.3.1(next@15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0)) next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) devDependencies: '@types/node': specifier: 20.17.24 @@ -659,13 +659,13 @@ importers: version: 18.3.3 '@types/react-dom': specifier: ^18 - version: 18.2.4 + version: 18.3.0 '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.19(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) concurrently: specifier: ^9.1.0 version: 9.1.0 @@ -677,10 +677,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.8.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -695,10 +695,10 @@ importers: version: link:../../packages/ai geist: specifier: ^1.3.1 - version: 1.3.1(next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0)) + version: 1.3.1(next@15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0)) next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 version: 18.3.1 @@ -723,10 +723,10 @@ importers: version: link:../../tools/eslint-config postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -753,13 +753,13 @@ importers: version: 0.1.36(@aws-crypto/sha256-js@5.2.0)(@aws-sdk/client-bedrock-runtime@3.663.0)(@aws-sdk/credential-provider-node@3.662.0(@aws-sdk/client-sso-oidc@3.662.0(@aws-sdk/client-sts@3.662.0))(@aws-sdk/client-sts@3.662.0))(@smithy/util-utf8@2.3.0)(@upstash/redis@1.34.3)(@vercel/kv@0.2.4)(encoding@0.1.13)(fast-xml-parser@4.4.1)(ignore@5.3.2)(ioredis@5.4.1)(jsdom@26.0.0)(lodash@4.17.21)(openai@5.6.0(ws@8.18.0)(zod@3.25.76))(playwright@1.50.1)(redis@4.7.0)(ws@8.18.0) next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) devDependencies: '@types/node': specifier: 20.17.24 @@ -769,13 +769,13 @@ importers: version: 18.3.3 '@types/react-dom': specifier: ^18 - version: 18.2.4 + version: 18.3.0 '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.16(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -784,10 +784,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.8.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -850,7 +850,7 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 version: 18.3.1 @@ -884,7 +884,7 @@ importers: version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.20(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -893,10 +893,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.8.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -911,13 +911,13 @@ importers: 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)) + version: 3.1.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0)) ai: specifier: workspace:* version: link:../../packages/ai next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 version: 18.3.1 @@ -942,7 +942,7 @@ importers: version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.20(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -951,10 +951,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.8.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -972,13 +972,13 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) zod: specifier: 3.25.76 version: 3.25.76 @@ -991,13 +991,13 @@ importers: version: 18.3.3 '@types/react-dom': specifier: ^18 - version: 18.2.4 + version: 18.3.0 '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.16(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -1006,10 +1006,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.4.5) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)) typescript: specifier: 5.4.5 version: 5.4.5 @@ -1039,13 +1039,13 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) zod: specifier: 3.25.76 version: 3.25.76 @@ -1058,10 +1058,10 @@ importers: version: 18.3.3 '@types/react-dom': specifier: ^18 - version: 18.2.4 + version: 18.3.0 autoprefixer: specifier: ^10.4.14 - version: 10.4.19(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -1070,10 +1070,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.6.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)) typescript: specifier: 5.6.3 version: 5.6.3 @@ -1097,7 +1097,7 @@ importers: version: 0.55.0(@opentelemetry/api@1.9.0) '@sentry/nextjs': specifier: ^8.42.0 - version: 8.42.0(@opentelemetry/core@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0))(react@18.2.0)(webpack@5.98.0) + version: 8.42.0(@opentelemetry/core@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0))(react@18.3.1)(webpack@5.98.0) '@sentry/opentelemetry': specifier: 8.22.0 version: 8.22.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0) @@ -1109,13 +1109,13 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) zod: specifier: 3.25.76 version: 3.25.76 @@ -1128,13 +1128,13 @@ importers: version: 18.3.3 '@types/react-dom': specifier: ^18 - version: 18.2.4 + version: 18.3.0 '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.19(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -1143,10 +1143,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.8.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1170,7 +1170,7 @@ importers: version: link:../../packages/ai next: specifier: latest - version: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + version: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) react: specifier: ^18 version: 18.3.1 @@ -1195,7 +1195,7 @@ importers: version: link:../../tools/tsconfig autoprefixer: specifier: ^10.4.14 - version: 10.4.20(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) eslint: specifier: 8.57.1 version: 8.57.1 @@ -1204,10 +1204,10 @@ importers: version: 14.2.3(eslint@8.57.1)(typescript@5.8.3) postcss: specifier: ^8.4.49 - version: 8.4.49 + version: 8.5.3 tailwindcss: specifier: ^3.4.15 - version: 3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1317,13 +1317,13 @@ importers: version: 9.21.0 '@sveltejs/adapter-vercel': specifier: ^5.5.2 - version: 5.6.3(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(encoding@0.1.13)(rollup@4.34.9) + version: 5.6.3(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(encoding@0.1.13)(rollup@4.34.9) '@sveltejs/kit': specifier: ^2.16.0 - version: 2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@sveltejs/vite-plugin-svelte': specifier: ^5.0.0 - version: 5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig @@ -1347,7 +1347,7 @@ importers: version: 10.0.2(eslint@9.21.0(jiti@2.4.0)) eslint-plugin-svelte: specifier: ^3.0.0 - version: 3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)) + version: 3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)) globals: specifier: ^16.0.0 version: 16.0.0 @@ -1356,28 +1356,28 @@ importers: version: 5.32.1 svelte-check: specifier: ^4.0.0 - version: 4.1.1(picomatch@4.0.2)(svelte@5.32.1)(typescript@5.6.3) + version: 4.1.1(picomatch@4.0.2)(svelte@5.32.1)(typescript@5.8.3) tailwind-merge: specifier: ^3.0.2 version: 3.0.2 tailwind-variants: specifier: ^1.0.0 - version: 1.0.0(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3))) + version: 1.0.0(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3))) tailwindcss: specifier: ^3.4.17 - version: 3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3))) + version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3))) typescript: specifier: ^5.0.0 - version: 5.6.3 + version: 5.8.3 typescript-eslint: specifier: ^8.20.0 - version: 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) + version: 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) vite: specifier: ^6.0.0 - version: 6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + version: 6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) zod: specifier: 3.25.76 version: 3.25.76 @@ -1393,6 +1393,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server '@opentelemetry/api': specifier: 1.9.0 version: 1.9.0 @@ -1436,6 +1439,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server '@smithy/eventstream-codec': specifier: ^4.0.1 version: 4.0.1 @@ -1467,6 +1473,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server '@angular/core': specifier: '>=16.0.0' version: 19.2.14(rxjs@7.8.1)(zone.js@0.15.1) @@ -1510,6 +1519,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1519,7 +1531,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1535,6 +1547,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1563,6 +1578,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1572,7 +1590,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1649,7 +1667,7 @@ importers: version: 12.1.0 debug: specifier: ^4.3.7 - version: 4.3.7 + version: 4.4.1(supports-color@9.4.0) jscodeshift: specifier: ^17.1.1 version: 17.1.1(@babel/preset-env@7.26.9(@babel/core@7.25.2)) @@ -1699,6 +1717,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1708,7 +1729,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1724,6 +1745,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1752,6 +1776,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1805,6 +1832,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1830,6 +1860,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1858,6 +1891,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1884,6 +1920,9 @@ importers: specifier: workspace:* version: link:../provider-utils devDependencies: + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server '@types/node': specifier: 18.15.11 version: 18.15.11 @@ -1908,6 +1947,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1933,6 +1975,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -1942,7 +1987,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1964,6 +2009,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server google-auth-library: specifier: ^9.15.0 version: 9.15.0(encoding@0.1.13) @@ -1976,7 +2024,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1992,6 +2040,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2017,6 +2068,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2080,6 +2134,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2105,6 +2162,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2130,6 +2190,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2139,7 +2202,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -2155,6 +2218,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2164,7 +2230,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.2.4(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -2180,6 +2246,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2205,6 +2274,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2239,7 +2311,7 @@ importers: version: link:../../tools/tsconfig tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -2267,7 +2339,7 @@ importers: version: 2.7.0(@types/node@20.17.24)(typescript@5.8.3) tsup: specifier: ^8 - version: 8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) typescript: specifier: 5.8.3 version: 5.8.3 @@ -2280,15 +2352,18 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server ai: specifier: workspace:* version: link:../ai react: specifier: ^18 || ^19 || ^19.0.0-rc - version: 18.3.1 + version: 19.0.0-rc.1 swr: specifier: ^2.2.5 - version: 2.2.5(react@18.3.1) + version: 2.2.5(react@19.0.0-rc.1) throttleit: specifier: 2.1.0 version: 2.1.0 @@ -2298,7 +2373,7 @@ importers: version: 6.6.3 '@testing-library/react': specifier: ^16.0.1 - version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) + version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1) '@testing-library/user-event': specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) @@ -2310,7 +2385,7 @@ importers: version: 18.3.3 '@types/react-dom': specifier: ^18 - version: 18.2.4 + version: 18.3.0 '@vercel/ai-tsconfig': specifier: workspace:* version: link:../../tools/tsconfig @@ -2327,8 +2402,8 @@ importers: specifier: 2.6.4 version: 2.6.4(@types/node@20.17.24)(typescript@5.8.3) react-dom: - specifier: ^18 - version: 18.2.0(react@18.3.1) + specifier: ^18 || ^19 || ^19.0.0-rc + version: 19.0.0-rc.1(react@19.0.0-rc.1) tsup: specifier: ^7.2.0 version: 7.2.0(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3) @@ -2347,6 +2422,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2372,6 +2450,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2466,7 +2547,7 @@ importers: version: link:../../../../ai next: specifier: canary - version: 15.3.0-canary.43(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(sass@1.85.0) + version: 15.6.0-canary.13(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(sass@1.85.0) react: specifier: rc version: 19.0.0-rc.1 @@ -2479,6 +2560,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server ai: specifier: workspace:* version: link:../ai @@ -2491,16 +2575,16 @@ importers: version: 9.21.0 '@sveltejs/package': specifier: ^2.0.0 - version: 2.3.10(svelte@5.32.1)(typescript@5.6.3) + version: 2.3.10(svelte@5.32.1)(typescript@5.8.3) '@sveltejs/vite-plugin-svelte': specifier: ^5.0.3 - version: 5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.6.3 '@testing-library/svelte': specifier: ^5.2.4 - version: 5.2.7(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vitest@3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 5.2.7(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vitest@3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@types/node': specifier: 20.17.24 version: 20.17.24 @@ -2512,7 +2596,7 @@ importers: version: 9.21.0(jiti@2.4.0) eslint-plugin-svelte: specifier: ^3.0.0 - version: 3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)) + version: 3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) globals: specifier: ^16.0.0 version: 16.0.0 @@ -2527,23 +2611,41 @@ importers: version: 5.32.1 svelte-check: specifier: ^4.0.0 - version: 4.1.1(picomatch@4.0.2)(svelte@5.32.1)(typescript@5.6.3) + version: 4.1.1(picomatch@4.0.2)(svelte@5.32.1)(typescript@5.8.3) typescript: specifier: ^5.0.0 - version: 5.6.3 + version: 5.8.3 typescript-eslint: specifier: ^8.20.0 - version: 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) + version: 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) vite: specifier: ^6.0.0 - version: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + version: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vitest: specifier: ^3.0.0 - version: 3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + version: 3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) zod: specifier: 3.25.76 version: 3.25.76 + packages/test-server: + devDependencies: + '@types/node': + specifier: 20.17.24 + version: 20.17.24 + '@vercel/ai-tsconfig': + specifier: workspace:* + version: link:../../tools/tsconfig + msw: + specifier: ^2.7.0 + version: 2.7.0(@types/node@20.17.24)(typescript@5.8.3) + tsup: + specifier: ^8 + version: 8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0) + typescript: + specifier: 5.8.3 + version: 5.8.3 + packages/togetherai: dependencies: '@ai-sdk/openai-compatible': @@ -2555,6 +2657,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -2630,15 +2735,18 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server ai: specifier: workspace:* version: link:../ai swrv: specifier: ^1.0.4 - version: 1.0.4(vue@3.3.8(typescript@5.8.3)) + version: 1.0.4(vue@3.5.13(typescript@5.8.3)) vue: specifier: ^3.3.4 - version: 3.3.8(typescript@5.8.3) + version: 3.5.13(typescript@5.8.3) zod: specifier: ^3.25.76 || ^4 version: 3.25.76 @@ -2651,7 +2759,7 @@ importers: version: 14.5.2(@testing-library/dom@10.4.0) '@testing-library/vue': specifier: ^8.1.0 - version: 8.1.0(@vue/compiler-sfc@3.5.13)(@vue/server-renderer@3.5.13(vue@3.3.8(typescript@5.8.3)))(vue@3.3.8(typescript@5.8.3)) + version: 8.1.0(@vue/compiler-sfc@3.5.13)(@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) '@types/node': specifier: 20.17.24 version: 20.17.24 @@ -2660,7 +2768,7 @@ importers: version: link:../../tools/tsconfig '@vitejs/plugin-vue': specifier: 5.2.0 - version: 5.2.0(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.3.8(typescript@5.8.3)) + version: 5.2.0(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.3)) eslint: specifier: 8.57.1 version: 8.57.1 @@ -2694,6 +2802,9 @@ importers: '@ai-sdk/provider-utils': specifier: workspace:* version: link:../provider-utils + '@ai-sdk/test-server': + specifier: workspace:* + version: link:../test-server devDependencies: '@types/node': specifier: 20.17.24 @@ -4119,30 +4230,15 @@ packages: '@emnapi/runtime@1.2.0': resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} - '@emnapi/runtime@1.4.0': - resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} - '@emnapi/runtime@1.5.0': resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} @@ -4173,24 +4269,12 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.23.1': resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} @@ -4221,24 +4305,12 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.23.1': resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} engines: {node: '>=18'} @@ -4269,24 +4341,12 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.23.1': resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} engines: {node: '>=18'} @@ -4317,24 +4377,12 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.23.1': resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} engines: {node: '>=18'} @@ -4365,24 +4413,12 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.23.1': resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} engines: {node: '>=18'} @@ -4413,24 +4449,12 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.23.1': resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} engines: {node: '>=18'} @@ -4461,24 +4485,12 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.23.1': resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} engines: {node: '>=18'} @@ -4509,24 +4521,12 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.23.1': resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} engines: {node: '>=18'} @@ -4557,24 +4557,12 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.23.1': resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} engines: {node: '>=18'} @@ -4605,24 +4593,12 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.23.1': resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} engines: {node: '>=18'} @@ -4653,24 +4629,12 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.23.1': resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} engines: {node: '>=18'} @@ -4701,24 +4665,12 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.23.1': resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} engines: {node: '>=18'} @@ -4749,24 +4701,12 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.23.1': resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} engines: {node: '>=18'} @@ -4797,24 +4737,12 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.23.1': resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} engines: {node: '>=18'} @@ -4845,24 +4773,12 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.23.1': resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} engines: {node: '>=18'} @@ -4893,24 +4809,12 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.23.1': resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} engines: {node: '>=18'} @@ -4953,24 +4857,12 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.23.1': resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} engines: {node: '>=18'} @@ -4995,12 +4887,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.23.1': resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} engines: {node: '>=18'} @@ -5031,24 +4917,12 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.23.1': resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} engines: {node: '>=18'} @@ -5079,24 +4953,12 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.23.1': resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} engines: {node: '>=18'} @@ -5127,24 +4989,12 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.23.1': resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} engines: {node: '>=18'} @@ -5175,24 +5025,12 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.23.1': resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} engines: {node: '>=18'} @@ -5223,24 +5061,12 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.23.1': resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} engines: {node: '>=18'} @@ -5408,20 +5234,24 @@ packages: resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + engines: {node: '>=18'} + '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-arm64@0.34.1': - resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} + '@img/sharp-darwin-arm64@0.34.3': + resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-arm64@0.34.3': - resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} + '@img/sharp-darwin-arm64@0.34.4': + resolution: {integrity: sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] @@ -5432,14 +5262,14 @@ packages: cpu: [x64] os: [darwin] - '@img/sharp-darwin-x64@0.34.1': - resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} + '@img/sharp-darwin-x64@0.34.3': + resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-darwin-x64@0.34.3': - resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} + '@img/sharp-darwin-x64@0.34.4': + resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] @@ -5449,13 +5279,13 @@ packages: cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.1.0': - resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + '@img/sharp-libvips-darwin-arm64@1.2.0': + resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.0': - resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} + '@img/sharp-libvips-darwin-arm64@1.2.3': + resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} cpu: [arm64] os: [darwin] @@ -5464,13 +5294,13 @@ packages: cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.1.0': - resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + '@img/sharp-libvips-darwin-x64@1.2.0': + resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.0': - resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} + '@img/sharp-libvips-darwin-x64@1.2.3': + resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} cpu: [x64] os: [darwin] @@ -5479,13 +5309,13 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm64@1.1.0': - resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + '@img/sharp-libvips-linux-arm64@1.2.0': + resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm64@1.2.0': - resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} + '@img/sharp-libvips-linux-arm64@1.2.3': + resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} cpu: [arm64] os: [linux] @@ -5494,19 +5324,14 @@ packages: cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-arm@1.1.0': - resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} - cpu: [arm] - os: [linux] - '@img/sharp-libvips-linux-arm@1.2.0': resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.1.0': - resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} - cpu: [ppc64] + '@img/sharp-libvips-linux-arm@1.2.3': + resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} + cpu: [arm] os: [linux] '@img/sharp-libvips-linux-ppc64@1.2.0': @@ -5514,18 +5339,23 @@ packages: cpu: [ppc64] os: [linux] + '@img/sharp-libvips-linux-ppc64@1.2.3': + resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} + cpu: [ppc64] + os: [linux] + '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-s390x@1.1.0': - resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + '@img/sharp-libvips-linux-s390x@1.2.0': + resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.0': - resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} + '@img/sharp-libvips-linux-s390x@1.2.3': + resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} cpu: [s390x] os: [linux] @@ -5534,13 +5364,13 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-libvips-linux-x64@1.1.0': - resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + '@img/sharp-libvips-linux-x64@1.2.0': + resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.0': - resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} + '@img/sharp-libvips-linux-x64@1.2.3': + resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} cpu: [x64] os: [linux] @@ -5549,13 +5379,13 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': - resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': + resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} cpu: [arm64] os: [linux] @@ -5564,13 +5394,13 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + '@img/sharp-libvips-linuxmusl-x64@1.2.0': + resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.0': - resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} + '@img/sharp-libvips-linuxmusl-x64@1.2.3': + resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} cpu: [x64] os: [linux] @@ -5580,14 +5410,14 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-linux-arm64@0.34.1': - resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} + '@img/sharp-linux-arm64@0.34.3': + resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm64@0.34.3': - resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} + '@img/sharp-linux-arm64@0.34.4': + resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] @@ -5598,14 +5428,14 @@ packages: cpu: [arm] os: [linux] - '@img/sharp-linux-arm@0.34.1': - resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} + '@img/sharp-linux-arm@0.34.3': + resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-arm@0.34.3': - resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} + '@img/sharp-linux-arm@0.34.4': + resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] @@ -5616,20 +5446,26 @@ packages: cpu: [ppc64] os: [linux] + '@img/sharp-linux-ppc64@0.34.4': + resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-s390x@0.34.1': - resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} + '@img/sharp-linux-s390x@0.34.3': + resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-s390x@0.34.3': - resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} + '@img/sharp-linux-s390x@0.34.4': + resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] @@ -5640,14 +5476,14 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linux-x64@0.34.1': - resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} + '@img/sharp-linux-x64@0.34.3': + resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linux-x64@0.34.3': - resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} + '@img/sharp-linux-x64@0.34.4': + resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] @@ -5658,14 +5494,14 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.1': - resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} + '@img/sharp-linuxmusl-arm64@0.34.3': + resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.3': - resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} + '@img/sharp-linuxmusl-arm64@0.34.4': + resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] @@ -5676,14 +5512,14 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.1': - resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} + '@img/sharp-linuxmusl-x64@0.34.3': + resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.3': - resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} + '@img/sharp-linuxmusl-x64@0.34.4': + resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] @@ -5693,13 +5529,13 @@ packages: engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-wasm32@0.34.1': - resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} + '@img/sharp-wasm32@0.34.3': + resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-wasm32@0.34.3': - resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} + '@img/sharp-wasm32@0.34.4': + resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] @@ -5709,20 +5545,26 @@ packages: cpu: [arm64] os: [win32] + '@img/sharp-win32-arm64@0.34.4': + resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + '@img/sharp-win32-ia32@0.33.5': resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-ia32@0.34.1': - resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} + '@img/sharp-win32-ia32@0.34.3': + resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-ia32@0.34.3': - resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} + '@img/sharp-win32-ia32@0.34.4': + resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] @@ -5733,14 +5575,14 @@ packages: cpu: [x64] os: [win32] - '@img/sharp-win32-x64@0.34.1': - resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} + '@img/sharp-win32-x64@0.34.3': + resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@img/sharp-win32-x64@0.34.3': - resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} + '@img/sharp-win32-x64@0.34.4': + resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] @@ -6962,17 +6804,11 @@ packages: '@next/env@15.0.0-canary.23': resolution: {integrity: sha512-lTWE0vMuSo2Vu4lj2NT5VFdFoRIDrc4cDhAKVT3At1LS10nKWKgjTtjE2uw4X1OXDEbvSNlDSe+asa5d/5O2Dg==} - '@next/env@15.2.4': - resolution: {integrity: sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==} - - '@next/env@15.3.0-canary.43': - resolution: {integrity: sha512-ogryUGufxhtidxr/42NY6+ADlvxt9Hq6Q/DOMS/20vGuePZ70wO6Z5m1RP3Q397RGgpe1gSWyYdlg+Mt7H4KeQ==} + '@next/env@15.5.3': + resolution: {integrity: sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw==} - '@next/env@15.3.3': - resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==} - - '@next/env@15.5.2': - resolution: {integrity: sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg==} + '@next/env@15.6.0-canary.13': + resolution: {integrity: sha512-5kaWAZnxRUehxQVnniAd9l9FWHFyWY7T1KGi7qW+GER1EDQTA46TZAWKgPo0oph7Okow/ePjomS2ONXZ+Et0zg==} '@next/eslint-plugin-next@14.2.3': resolution: {integrity: sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==} @@ -6983,26 +6819,14 @@ packages: cpu: [arm64] os: [darwin] - '@next/swc-darwin-arm64@15.2.4': - resolution: {integrity: sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-arm64@15.3.0-canary.43': - resolution: {integrity: sha512-eXrs8CyIBgdnMTNjku+h/xm61gmRCcKAT+tM2CjpEXbEqXBux5hRIakOk5kJJDu2fA2P3pzQGt5PRD1hg4srXA==} + '@next/swc-darwin-arm64@15.5.3': + resolution: {integrity: sha512-nzbHQo69+au9wJkGKTU9lP7PXv0d1J5ljFpvb+LnEomLtSbJkbZyEs6sbF3plQmiOB2l9OBtN2tNSvCH1nQ9Jg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-arm64@15.3.3': - resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-arm64@15.5.2': - resolution: {integrity: sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ==} + '@next/swc-darwin-arm64@15.6.0-canary.13': + resolution: {integrity: sha512-IXkbwmg+4T+BMPnzNLLFNK0OxbdZhCBbhFTI43AvuL84P5plInGO+zt8OL2j+Mo65/poU5PzplFZZVblvBmCug==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -7013,26 +6837,14 @@ packages: cpu: [x64] os: [darwin] - '@next/swc-darwin-x64@15.2.4': - resolution: {integrity: sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-darwin-x64@15.3.0-canary.43': - resolution: {integrity: sha512-iRGvblEh/b2grxkkp9pT+yea9EzGNM4tLyUZoCzkejkU2jMLsn2DH6h3bQwCfEYZL3YFGsYmVISrVCOVi8LeMw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-darwin-x64@15.3.3': - resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==} + '@next/swc-darwin-x64@15.5.3': + resolution: {integrity: sha512-w83w4SkOOhekJOcA5HBvHyGzgV1W/XvOfpkrxIse4uPWhYTTRwtGEM4v/jiXwNSJvfRvah0H8/uTLBKRXlef8g==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-darwin-x64@15.5.2': - resolution: {integrity: sha512-2DjnmR6JHK4X+dgTXt5/sOCu/7yPtqpYt8s8hLkHFK3MGkka2snTv3yRMdHvuRtJVkPwCGsvBSwmoQCHatauFQ==} + '@next/swc-darwin-x64@15.6.0-canary.13': + resolution: {integrity: sha512-mygRYLZIwFI6dGQoTvvIJpHTrbgR8fm/9ZNC86ExY55LzhekwJv+M03dzcR7iQ5jazvPTQtuOlta8nnbKx2CZg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -7043,26 +6855,14 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-gnu@15.2.4': - resolution: {integrity: sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==} + '@next/swc-linux-arm64-gnu@15.5.3': + resolution: {integrity: sha512-+m7pfIs0/yvgVu26ieaKrifV8C8yiLe7jVp9SpcIzg7XmyyNE7toC1fy5IOQozmr6kWl/JONC51osih2RyoXRw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-gnu@15.3.0-canary.43': - resolution: {integrity: sha512-IqknHGNxpL03uIutIuv7FPjGHuD/AnJVC5exi5g+C7P3f6JVvOjFLS264eqi91tVCXhN2LpcKNGwTlK81bJVVg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-gnu@15.3.3': - resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-gnu@15.5.2': - resolution: {integrity: sha512-3j7SWDBS2Wov/L9q0mFJtEvQ5miIqfO4l7d2m9Mo06ddsgUK8gWfHGgbjdFlCp2Ek7MmMQZSxpGFqcC8zGh2AA==} + '@next/swc-linux-arm64-gnu@15.6.0-canary.13': + resolution: {integrity: sha512-Sna39YXcObj1Zw15zg5HHBUdXhl6WQAVQfsmoIETCZ4FQSuSRw0UpDtiW6+bQGYAP5ScJWX2i14k6htrWBNL4A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -7073,26 +6873,14 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.2.4': - resolution: {integrity: sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@15.3.0-canary.43': - resolution: {integrity: sha512-FbO0dnFsNe3f1LWTn4vyXTWTSrZdwNRnURYExSQ+0AINHphNfwKQNrPqVLrapQ9CAOCOz8R5p9Kf1++IsH3JJQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@15.3.3': - resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==} + '@next/swc-linux-arm64-musl@15.5.3': + resolution: {integrity: sha512-u3PEIzuguSenoZviZJahNLgCexGFhso5mxWCrrIMdvpZn6lkME5vc/ADZG8UUk5K1uWRy4hqSFECrON6UKQBbQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.5.2': - resolution: {integrity: sha512-s6N8k8dF9YGc5T01UPQ08yxsK6fUow5gG1/axWc1HVVBYQBgOjca4oUZF7s4p+kwhkB1bDSGR8QznWrFZ/Rt5g==} + '@next/swc-linux-arm64-musl@15.6.0-canary.13': + resolution: {integrity: sha512-bqybRwJRLRagldV9l70URpRUFePsfnpBqlV3/JVlr0xkzcxYFvRejcuNS4tAA0iQ6HdpMwJBCRXLpie/q30O4A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -7103,26 +6891,14 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-gnu@15.2.4': - resolution: {integrity: sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-gnu@15.3.0-canary.43': - resolution: {integrity: sha512-MAaLEm8eO6Xir3YC3xLYDHDjLGogAAGRrxhuflvaqAtGQZ6NIMG4YjvAyramYTq/SwrUIDobggKxdQLtu8/pPQ==} + '@next/swc-linux-x64-gnu@15.5.3': + resolution: {integrity: sha512-lDtOOScYDZxI2BENN9m0pfVPJDSuUkAD1YXSvlJF0DKwZt0WlA7T7o3wrcEr4Q+iHYGzEaVuZcsIbCps4K27sA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-gnu@15.3.3': - resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-gnu@15.5.2': - resolution: {integrity: sha512-o1RV/KOODQh6dM6ZRJGZbc+MOAHww33Vbs5JC9Mp1gDk8cpEO+cYC/l7rweiEalkSm5/1WGa4zY7xrNwObN4+Q==} + '@next/swc-linux-x64-gnu@15.6.0-canary.13': + resolution: {integrity: sha512-FqE67dfImb3vKeROuIzh2eVzCwj7/95SYizfO/7oaU9UTKfblAj1whj2ESibz2Sx0bjQoK+OboflWnQwsmgkrQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -7133,26 +6909,14 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.2.4': - resolution: {integrity: sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@15.3.0-canary.43': - resolution: {integrity: sha512-gdwF79/EQjY3zgcolO0jlDe0yfII9tXyXQeqL+uvzA8gZT5FpH0KkwSWzxj8EUswWzZcprbDa87sq8H0Eo+whw==} + '@next/swc-linux-x64-musl@15.5.3': + resolution: {integrity: sha512-9vWVUnsx9PrY2NwdVRJ4dUURAQ8Su0sLRPqcCCxtX5zIQUBES12eRVHq6b70bbfaVaxIDGJN2afHui0eDm+cLg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.3.3': - resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@15.5.2': - resolution: {integrity: sha512-/VUnh7w8RElYZ0IV83nUcP/J4KJ6LLYliiBIri3p3aW2giF+PAVgZb6mk8jbQSB3WlTai8gEmCAr7kptFa1H6g==} + '@next/swc-linux-x64-musl@15.6.0-canary.13': + resolution: {integrity: sha512-Kacn33TqI8ljBOjERVU2hJcNohA3RKr2bZ621ca1STclUWQiwb9wMFfJdSUAzS8IOE1oP2WCYoNaN2SrxtHEJw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -7163,26 +6927,14 @@ packages: cpu: [arm64] os: [win32] - '@next/swc-win32-arm64-msvc@15.2.4': - resolution: {integrity: sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==} + '@next/swc-win32-arm64-msvc@15.5.3': + resolution: {integrity: sha512-1CU20FZzY9LFQigRi6jM45oJMU3KziA5/sSG+dXeVaTm661snQP6xu3ykGxxwU5sLG3sh14teO/IOEPVsQMRfA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-arm64-msvc@15.3.0-canary.43': - resolution: {integrity: sha512-5WYne3jvo1478kUfe901wFxvPMdC8tRKundKIgU5Upe1HafMMS7ymm1hQ7CUpp3/1vY/R1TV1oKHHJfqDubiNg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-arm64-msvc@15.3.3': - resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-arm64-msvc@15.5.2': - resolution: {integrity: sha512-sMPyTvRcNKXseNQ/7qRfVRLa0VhR0esmQ29DD6pqvG71+JdVnESJaHPA8t7bc67KD5spP3+DOCNLhqlEI2ZgQg==} + '@next/swc-win32-arm64-msvc@15.6.0-canary.13': + resolution: {integrity: sha512-2vvLWTlk9nKDkvMf8UkBdMbsheyzwQJRBXSngCzZY+85kU6JOQydvUz0D94oDwSyjh/kstUohODjJcCD1fon6g==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -7199,26 +6951,14 @@ packages: cpu: [x64] os: [win32] - '@next/swc-win32-x64-msvc@15.2.4': - resolution: {integrity: sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@next/swc-win32-x64-msvc@15.3.0-canary.43': - resolution: {integrity: sha512-xE3WZhwjb91eezecVsmXn/OtdISfMsIfS3t0ZXsS/+bMvO/LZLdcVBtl0Zy5yR+XJyKfXXmwpdYbL6WH4dGuQg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@next/swc-win32-x64-msvc@15.3.3': - resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==} + '@next/swc-win32-x64-msvc@15.5.3': + resolution: {integrity: sha512-JMoLAq3n3y5tKXPQwCK5c+6tmwkuFDa2XAxz8Wm4+IVthdBZdZGh+lmiLUHg9f9IDwIQpUjp+ysd6OkYTyZRZw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@next/swc-win32-x64-msvc@15.5.2': - resolution: {integrity: sha512-W5VvyZHnxG/2ukhZF/9Ikdra5fdNftxI6ybeVKYvBPDtyx7x4jPPSNduUkfH5fo3zG0JQ0bPxgy41af2JX5D4Q==} + '@next/swc-win32-x64-msvc@15.6.0-canary.13': + resolution: {integrity: sha512-pYgqoL50ibamU4ql3M5hqp/PhvSCw6LSu5wBc+aOWs4oPIaS6O30GvXZ4TwF/ERGUU6vYlXrhThYAIWPwP9Uig==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -8217,11 +7957,6 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.46.0': - resolution: {integrity: sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==} - engines: {node: '>=18'} - hasBin: true - '@playwright/test@1.50.1': resolution: {integrity: sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==} engines: {node: '>=18'} @@ -8391,16 +8126,6 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.14.1': - resolution: {integrity: sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm-eabi@4.20.0': - resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==} - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm-eabi@4.34.8': resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} cpu: [arm] @@ -8411,16 +8136,6 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.14.1': - resolution: {integrity: sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-android-arm64@4.20.0': - resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==} - cpu: [arm64] - os: [android] - '@rollup/rollup-android-arm64@4.34.8': resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==} cpu: [arm64] @@ -8431,16 +8146,6 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.14.1': - resolution: {integrity: sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-arm64@4.20.0': - resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==} - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-arm64@4.34.8': resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==} cpu: [arm64] @@ -8451,16 +8156,6 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.14.1': - resolution: {integrity: sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.20.0': - resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==} - cpu: [x64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.34.8': resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==} cpu: [x64] @@ -8491,16 +8186,6 @@ packages: cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.14.1': - resolution: {integrity: sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-gnueabihf@4.20.0': - resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.34.8': resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==} cpu: [arm] @@ -8511,11 +8196,6 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.20.0': - resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.34.8': resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==} cpu: [arm] @@ -8526,16 +8206,6 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.14.1': - resolution: {integrity: sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.20.0': - resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.34.8': resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==} cpu: [arm64] @@ -8546,16 +8216,6 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.14.1': - resolution: {integrity: sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.20.0': - resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-musl@4.34.8': resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==} cpu: [arm64] @@ -8576,16 +8236,6 @@ packages: cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.14.1': - resolution: {integrity: sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==} - cpu: [ppc64le] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': - resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==} - cpu: [ppc64] - os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.34.8': resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==} cpu: [ppc64] @@ -8596,16 +8246,6 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.14.1': - resolution: {integrity: sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.20.0': - resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.34.8': resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==} cpu: [riscv64] @@ -8616,16 +8256,6 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.14.1': - resolution: {integrity: sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.20.0': - resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==} - cpu: [s390x] - os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.34.8': resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==} cpu: [s390x] @@ -8636,16 +8266,6 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.14.1': - resolution: {integrity: sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.20.0': - resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-gnu@4.34.8': resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==} cpu: [x64] @@ -8656,16 +8276,6 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.14.1': - resolution: {integrity: sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.20.0': - resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-musl@4.34.8': resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==} cpu: [x64] @@ -8676,16 +8286,6 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.14.1': - resolution: {integrity: sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-arm64-msvc@4.20.0': - resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.34.8': resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==} cpu: [arm64] @@ -8696,16 +8296,6 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.14.1': - resolution: {integrity: sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.20.0': - resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.34.8': resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==} cpu: [ia32] @@ -8716,16 +8306,6 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.14.1': - resolution: {integrity: sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.20.0': - resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.34.8': resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==} cpu: [x64] @@ -9174,9 +8754,6 @@ packages: svelte: ^5.0.0 vite: ^6.0.0 - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.11': resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==} @@ -9326,9 +8903,6 @@ packages: '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -9403,6 +8977,9 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/mysql@2.15.26': resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} @@ -9445,9 +9022,6 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@18.2.4': - resolution: {integrity: sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==} - '@types/react-dom@18.3.0': resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} @@ -9528,17 +9102,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/eslint-plugin@8.6.0': - resolution: {integrity: sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/parser@7.2.0': resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -9556,16 +9119,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.6.0': - resolution: {integrity: sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/scope-manager@7.2.0': resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -9574,10 +9127,6 @@ packages: resolution: {integrity: sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.6.0': - resolution: {integrity: sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.26.0': resolution: {integrity: sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9585,15 +9134,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.6.0': - resolution: {integrity: sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/types@7.2.0': resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -9602,10 +9142,6 @@ packages: resolution: {integrity: sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.6.0': - resolution: {integrity: sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.2.0': resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -9621,15 +9157,6 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.6.0': - resolution: {integrity: sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/utils@8.26.0': resolution: {integrity: sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9637,12 +9164,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.6.0': - resolution: {integrity: sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@7.2.0': resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} engines: {node: ^16.0.0 || >=18.0.0} @@ -9651,10 +9172,6 @@ packages: resolution: {integrity: sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.6.0': - resolution: {integrity: sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -9697,9 +9214,9 @@ packages: resolution: {integrity: sha512-5aF+bDYGFx5WgxGE+CeOWWI8GYD1I/JxAWl+R//+MgNjkTPpCKkUVjdchFOr622rEu2wuHAOtpLr5HYg7/uRAA==} engines: {node: '>=16.14'} - '@vercel/functions@2.0.0': - resolution: {integrity: sha512-BSwIihLHoV18gerKZJyGuqd3rtaYM6rJvET1kOwKktshucyaHXTJel7Cxegs+sdX0NZqsX4LO2MFnMU2jG01Cw==} - engines: {node: '>= 18'} + '@vercel/functions@3.1.0': + resolution: {integrity: sha512-V+p8dO+sg1VjiJJUO5rYPp1KG17SzDcR74OWwW7Euyde6L8U5wuTMe9QfEOfLTiWPUPzN1MXZvLcYxqSYhKc4Q==} + engines: {node: '>= 20'} peerDependencies: '@aws-sdk/credential-provider-web-identity': '*' peerDependenciesMeta: @@ -9720,6 +9237,10 @@ packages: engines: {node: '>=18'} hasBin: true + '@vercel/oidc@3.0.0': + resolution: {integrity: sha512-XOoUcf/1VfGArUAfq0ELxk6TD7l4jGcrOsWjQibj4wYM74uNihzZ9gA46ywWegoqKWWdph4y5CKxGI9823deoA==} + engines: {node: '>= 20'} + '@vercel/otel@1.10.0': resolution: {integrity: sha512-bv1FXbFZlFbB89vyA2P9/kr6eZ42bMtXgqBJpgi+8yOrZU8rkg9wMi0TL//AgAf/qKtaryDm1sbCnkLHgCI3PQ==} engines: {node: '>=18'} @@ -9841,27 +9362,15 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@vue/compiler-core@3.3.8': - resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} - '@vue/compiler-core@3.5.13': resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - '@vue/compiler-dom@3.3.8': - resolution: {integrity: sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==} - '@vue/compiler-dom@3.5.13': resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} - '@vue/compiler-sfc@3.3.8': - resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} - '@vue/compiler-sfc@3.5.13': resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - '@vue/compiler-ssr@3.3.8': - resolution: {integrity: sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==} - '@vue/compiler-ssr@3.5.13': resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} @@ -9879,46 +9388,26 @@ packages: '@vue/devtools-shared@7.6.4': resolution: {integrity: sha512-nD6CUvBEel+y7zpyorjiUocy0nh77DThZJ0k1GRnJeOmY3ATq2fWijEp7wk37gb023Cb0R396uYh5qMSBQ5WFg==} - '@vue/reactivity-transform@3.3.8': - resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==} - - '@vue/reactivity@3.3.8': - resolution: {integrity: sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==} - '@vue/reactivity@3.5.12': resolution: {integrity: sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==} '@vue/reactivity@3.5.13': resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} - '@vue/runtime-core@3.3.8': - resolution: {integrity: sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==} - '@vue/runtime-core@3.5.12': resolution: {integrity: sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==} '@vue/runtime-core@3.5.13': resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} - '@vue/runtime-dom@3.3.8': - resolution: {integrity: sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==} - '@vue/runtime-dom@3.5.13': resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} - '@vue/server-renderer@3.3.8': - resolution: {integrity: sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==} - peerDependencies: - vue: 3.3.8 - '@vue/server-renderer@3.5.13': resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} peerDependencies: vue: 3.5.13 - '@vue/shared@3.3.8': - resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} - '@vue/shared@3.5.12': resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==} @@ -10363,20 +9852,6 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - autoprefixer@10.4.16: - resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - - autoprefixer@10.4.19: - resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -10536,24 +10011,10 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.22.1: - resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - browserslist@4.23.1: - resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.23.3: resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -10600,12 +10061,6 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} - bundle-require@4.0.2: - resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.17' - bundle-require@4.2.1: resolution: {integrity: sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -10681,12 +10136,6 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001591: - resolution: {integrity: sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==} - - caniuse-lite@1.0.30001637: - resolution: {integrity: sha512-1x0qRI1mD1o9e+7mBI7XtzFAP4XszbHaVWsMiGbSPLYekKTJF7K+FNk6AsXH4sUpc+qrsI3pVgf1Jdl/uGkuSQ==} - caniuse-lite@1.0.30001649: resolution: {integrity: sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==} @@ -10755,10 +10204,6 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -11430,6 +10875,10 @@ packages: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} + detect-libc@2.1.0: + resolution: {integrity: sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -11549,9 +10998,6 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.4.812: - resolution: {integrity: sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==} - electron-to-chromium@1.5.182: resolution: {integrity: sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==} @@ -11691,21 +11137,11 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true - esbuild@0.23.0: - resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.23.1: resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} engines: {node: '>=18'} @@ -12438,10 +11874,6 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@7.1.6: - resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} - deprecated: Glob versions prior to v9 are no longer supported - glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -14344,6 +13776,7 @@ packages: multer@1.4.4-lts.1: resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} engines: {node: '>= 6.0.0'} + deprecated: Multer 1.x is impacted by a number of vulnerabilities, which have been patched in 2.x. You should upgrade to the latest 2.x version. multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} @@ -14367,11 +13800,6 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - nanoid@3.3.8: resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -14429,55 +13857,13 @@ packages: sass: optional: true - next@15.2.4: - resolution: {integrity: sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==} + next@15.5.3: + resolution: {integrity: sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - - next@15.3.0-canary.43: - resolution: {integrity: sha512-am6xpZIx2P0VJ26N7K2CImmznYUP65XS0e0nkYtypWf/RiMsScwmCqrA4qrEK9u/tiPlA+583IcQPos9yKLg1Q==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - - next@15.3.3: - resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 + '@playwright/test': ^1.51.1 babel-plugin-react-compiler: '*' react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 @@ -14492,9 +13878,9 @@ packages: sass: optional: true - next@15.5.2: - resolution: {integrity: sha512-H8Otr7abj1glFhbGnvUt3gz++0AF1+QoCXEBmd/6aKbfdFwrn0LpA836Ed5+00va/7HQSDD+mOoVhn3tNy3e/Q==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + next@15.6.0-canary.13: + resolution: {integrity: sha512-HU+QKFsIlXu7XOBYVQ3xPZMbO3Dp189vfh9aCy79KZMYhzbxXHR3SitFZjZI9FmLrcr7c6d8aEK+Pg70llg68g==} + engines: {node: '>=20.9.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 @@ -14538,6 +13924,7 @@ packages: node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} @@ -14574,9 +13961,6 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} @@ -15086,9 +14470,6 @@ packages: resolution: {integrity: sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==} engines: {node: '>= 8'} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} @@ -15163,21 +14544,11 @@ packages: pkg-types@1.2.1: resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} - playwright-core@1.46.0: - resolution: {integrity: sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==} - engines: {node: '>=18'} - hasBin: true - playwright-core@1.50.1: resolution: {integrity: sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==} engines: {node: '>=18'} hasBin: true - playwright@1.46.0: - resolution: {integrity: sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==} - engines: {node: '>=18'} - hasBin: true - playwright@1.50.1: resolution: {integrity: sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==} engines: {node: '>=18'} @@ -15269,18 +14640,6 @@ packages: ts-node: optional: true - postcss-load-config@4.0.1: - resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - postcss-load-config@4.0.2: resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} @@ -15510,10 +14869,6 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.49: - resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.2: resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} engines: {node: ^10 || ^12 || >=14} @@ -15557,11 +14912,6 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - prettier@3.5.3: resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} engines: {node: '>=14'} @@ -15691,11 +15041,6 @@ packages: rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - react-dom@18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 - react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -15738,10 +15083,6 @@ packages: react-dom: 18.3.0-canary-eb33bd747-20240312 webpack: ^5.59.0 - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} - react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -15988,16 +15329,6 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true - rollup@4.14.1: - resolution: {integrity: sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rollup@4.20.0: - resolution: {integrity: sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rollup@4.34.8: resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -16102,9 +15433,6 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} - scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -16219,14 +15547,14 @@ packages: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - sharp@0.34.1: - resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - sharp@0.34.3: resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + sharp@0.34.4: + resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -16349,6 +15677,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -16553,11 +15882,6 @@ packages: peerDependencies: postcss: ^8.4.31 - sucrase@3.34.0: - resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} - engines: {node: '>=8'} - hasBin: true - sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -16566,6 +15890,7 @@ packages: superagent@9.0.2: resolution: {integrity: sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==} engines: {node: '>=14.18.0'} + deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net superjson@2.2.1: resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} @@ -16574,6 +15899,7 @@ packages: supertest@7.0.0: resolution: {integrity: sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==} engines: {node: '>=14.18.0'} + deprecated: Please upgrade to supertest v7.1.3+, see release notes at https://github.com/forwardemail/supertest/releases/tag/v7.1.3 - maintenance is supported by Forward Email @ https://forwardemail.net supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -17019,44 +16345,6 @@ packages: typescript: optional: true - tsup@8.0.2: - resolution: {integrity: sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - - tsup@8.2.4: - resolution: {integrity: sha512-akpCPePnBnC/CXgRrcy72ZSntgIEUa1jN0oJbbvpALWKNOz1B7aM+UVDWGRGIO/T/PZugAESWDJUAb5FD48o8Q==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - tsup@8.3.0: resolution: {integrity: sha512-ALscEeyS03IomcuNdFdc0YWGVIkwH1Ws7nfTbAPuoILvEV2hpGQAY72LIOjglGo4ShWpZfpBqP/jpQVCzqYQag==} engines: {node: '>=18'} @@ -17198,11 +16486,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} @@ -17396,12 +16679,6 @@ packages: unwasm@0.3.9: resolution: {integrity: sha512-LDxTx/2DkFURUd+BU1vUsF/moj0JsoTvl+2tcg2AUOiEzVturhGGx17/IMgGvKUYdZwr33EJHtChCJuhu9Ouvg==} - update-browserslist-db@1.0.16: - resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -17470,14 +16747,6 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} - valibot@1.0.0-rc.0: - resolution: {integrity: sha512-9ZUrOXOejY/WaIn8p0Z469R1qBAwNJeqq8jzOIDsl1qR8gqtObHQmyHLFli0UCkcGiTco5kH6/KPLWsTWE9b2g==} - peerDependencies: - typescript: '>=5' - peerDependenciesMeta: - typescript: - optional: true - valibot@1.1.0: resolution: {integrity: sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==} peerDependencies: @@ -17777,14 +17046,6 @@ packages: peerDependencies: vue: ^3.2.0 - vue@3.3.8: - resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - vue@3.5.13: resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: @@ -18069,11 +17330,6 @@ packages: engines: {node: '>= 14'} hasBin: true - yaml@2.4.5: - resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} - engines: {node: '>= 14'} - hasBin: true - yaml@2.5.0: resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} engines: {node: '>= 14'} @@ -18919,7 +18175,7 @@ snapshots: '@babel/traverse': 7.25.9 '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -18939,7 +18195,7 @@ snapshots: '@babel/traverse': 7.25.9 '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -18959,7 +18215,7 @@ snapshots: '@babel/traverse': 7.28.0 '@babel/types': 7.28.0 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -18979,7 +18235,7 @@ snapshots: '@babel/traverse': 7.28.0 '@babel/types': 7.28.0 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -19128,7 +18384,7 @@ snapshots: '@babel/core': 7.25.2 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -19140,7 +18396,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -20637,7 +19893,7 @@ snapshots: '@babel/parser': 7.26.2 '@babel/template': 7.25.9 '@babel/types': 7.26.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -20650,7 +19906,7 @@ snapshots: '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/types': 7.28.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -20928,25 +20184,14 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.0': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.5.0': dependencies: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.19.12': - optional: true - '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/aix-ppc64@0.23.0': - optional: true - '@esbuild/aix-ppc64@0.23.1': optional: true @@ -20962,15 +20207,9 @@ snapshots: '@esbuild/android-arm64@0.18.20': optional: true - '@esbuild/android-arm64@0.19.12': - optional: true - '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm64@0.23.0': - optional: true - '@esbuild/android-arm64@0.23.1': optional: true @@ -20986,15 +20225,9 @@ snapshots: '@esbuild/android-arm@0.18.20': optional: true - '@esbuild/android-arm@0.19.12': - optional: true - '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.23.0': - optional: true - '@esbuild/android-arm@0.23.1': optional: true @@ -21010,15 +20243,9 @@ snapshots: '@esbuild/android-x64@0.18.20': optional: true - '@esbuild/android-x64@0.19.12': - optional: true - '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.23.0': - optional: true - '@esbuild/android-x64@0.23.1': optional: true @@ -21034,15 +20261,9 @@ snapshots: '@esbuild/darwin-arm64@0.18.20': optional: true - '@esbuild/darwin-arm64@0.19.12': - optional: true - '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.23.0': - optional: true - '@esbuild/darwin-arm64@0.23.1': optional: true @@ -21058,15 +20279,9 @@ snapshots: '@esbuild/darwin-x64@0.18.20': optional: true - '@esbuild/darwin-x64@0.19.12': - optional: true - '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.23.0': - optional: true - '@esbuild/darwin-x64@0.23.1': optional: true @@ -21082,15 +20297,9 @@ snapshots: '@esbuild/freebsd-arm64@0.18.20': optional: true - '@esbuild/freebsd-arm64@0.19.12': - optional: true - '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.23.0': - optional: true - '@esbuild/freebsd-arm64@0.23.1': optional: true @@ -21106,15 +20315,9 @@ snapshots: '@esbuild/freebsd-x64@0.18.20': optional: true - '@esbuild/freebsd-x64@0.19.12': - optional: true - '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.23.0': - optional: true - '@esbuild/freebsd-x64@0.23.1': optional: true @@ -21130,15 +20333,9 @@ snapshots: '@esbuild/linux-arm64@0.18.20': optional: true - '@esbuild/linux-arm64@0.19.12': - optional: true - '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm64@0.23.0': - optional: true - '@esbuild/linux-arm64@0.23.1': optional: true @@ -21154,15 +20351,9 @@ snapshots: '@esbuild/linux-arm@0.18.20': optional: true - '@esbuild/linux-arm@0.19.12': - optional: true - '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-arm@0.23.0': - optional: true - '@esbuild/linux-arm@0.23.1': optional: true @@ -21178,15 +20369,9 @@ snapshots: '@esbuild/linux-ia32@0.18.20': optional: true - '@esbuild/linux-ia32@0.19.12': - optional: true - '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-ia32@0.23.0': - optional: true - '@esbuild/linux-ia32@0.23.1': optional: true @@ -21202,15 +20387,9 @@ snapshots: '@esbuild/linux-loong64@0.18.20': optional: true - '@esbuild/linux-loong64@0.19.12': - optional: true - '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-loong64@0.23.0': - optional: true - '@esbuild/linux-loong64@0.23.1': optional: true @@ -21226,15 +20405,9 @@ snapshots: '@esbuild/linux-mips64el@0.18.20': optional: true - '@esbuild/linux-mips64el@0.19.12': - optional: true - '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-mips64el@0.23.0': - optional: true - '@esbuild/linux-mips64el@0.23.1': optional: true @@ -21250,15 +20423,9 @@ snapshots: '@esbuild/linux-ppc64@0.18.20': optional: true - '@esbuild/linux-ppc64@0.19.12': - optional: true - '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.23.0': - optional: true - '@esbuild/linux-ppc64@0.23.1': optional: true @@ -21274,15 +20441,9 @@ snapshots: '@esbuild/linux-riscv64@0.18.20': optional: true - '@esbuild/linux-riscv64@0.19.12': - optional: true - '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.23.0': - optional: true - '@esbuild/linux-riscv64@0.23.1': optional: true @@ -21298,15 +20459,9 @@ snapshots: '@esbuild/linux-s390x@0.18.20': optional: true - '@esbuild/linux-s390x@0.19.12': - optional: true - '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-s390x@0.23.0': - optional: true - '@esbuild/linux-s390x@0.23.1': optional: true @@ -21322,15 +20477,9 @@ snapshots: '@esbuild/linux-x64@0.18.20': optional: true - '@esbuild/linux-x64@0.19.12': - optional: true - '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.23.0': - optional: true - '@esbuild/linux-x64@0.23.1': optional: true @@ -21352,15 +20501,9 @@ snapshots: '@esbuild/netbsd-x64@0.18.20': optional: true - '@esbuild/netbsd-x64@0.19.12': - optional: true - '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.23.0': - optional: true - '@esbuild/netbsd-x64@0.23.1': optional: true @@ -21373,9 +20516,6 @@ snapshots: '@esbuild/netbsd-x64@0.25.4': optional: true - '@esbuild/openbsd-arm64@0.23.0': - optional: true - '@esbuild/openbsd-arm64@0.23.1': optional: true @@ -21391,15 +20531,9 @@ snapshots: '@esbuild/openbsd-x64@0.18.20': optional: true - '@esbuild/openbsd-x64@0.19.12': - optional: true - '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.23.0': - optional: true - '@esbuild/openbsd-x64@0.23.1': optional: true @@ -21415,15 +20549,9 @@ snapshots: '@esbuild/sunos-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.19.12': - optional: true - '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.23.0': - optional: true - '@esbuild/sunos-x64@0.23.1': optional: true @@ -21439,15 +20567,9 @@ snapshots: '@esbuild/win32-arm64@0.18.20': optional: true - '@esbuild/win32-arm64@0.19.12': - optional: true - '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-arm64@0.23.0': - optional: true - '@esbuild/win32-arm64@0.23.1': optional: true @@ -21463,15 +20585,9 @@ snapshots: '@esbuild/win32-ia32@0.18.20': optional: true - '@esbuild/win32-ia32@0.19.12': - optional: true - '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-ia32@0.23.0': - optional: true - '@esbuild/win32-ia32@0.23.1': optional: true @@ -21487,15 +20603,9 @@ snapshots: '@esbuild/win32-x64@0.18.20': optional: true - '@esbuild/win32-x64@0.19.12': - optional: true - '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.23.0': - optional: true - '@esbuild/win32-x64@0.23.1': optional: true @@ -21529,7 +20639,7 @@ snapshots: '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -21541,7 +20651,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -21555,7 +20665,7 @@ snapshots: '@eslint/eslintrc@3.3.0': dependencies: ajv: 6.12.6 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -21666,7 +20776,7 @@ snapshots: '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -21679,14 +20789,12 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} - '@img/sharp-darwin-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/colour@1.0.0': optional: true - '@img/sharp-darwin-arm64@0.34.1': + '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-arm64': 1.0.4 optional: true '@img/sharp-darwin-arm64@0.34.3': @@ -21694,14 +20802,14 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.2.0 optional: true - '@img/sharp-darwin-x64@0.33.5': + '@img/sharp-darwin-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-darwin-arm64': 1.2.3 optional: true - '@img/sharp-darwin-x64@0.34.1': + '@img/sharp-darwin-x64@0.33.5': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.0.4 optional: true '@img/sharp-darwin-x64@0.34.3': @@ -21709,97 +20817,102 @@ snapshots: '@img/sharp-libvips-darwin-x64': 1.2.0 optional: true - '@img/sharp-libvips-darwin-arm64@1.0.4': + '@img/sharp-darwin-x64@0.34.4': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.3 optional: true - '@img/sharp-libvips-darwin-arm64@1.1.0': + '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true '@img/sharp-libvips-darwin-arm64@1.2.0': optional: true - '@img/sharp-libvips-darwin-x64@1.0.4': + '@img/sharp-libvips-darwin-arm64@1.2.3': optional: true - '@img/sharp-libvips-darwin-x64@1.1.0': + '@img/sharp-libvips-darwin-x64@1.0.4': optional: true '@img/sharp-libvips-darwin-x64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm64@1.0.4': + '@img/sharp-libvips-darwin-x64@1.2.3': optional: true - '@img/sharp-libvips-linux-arm64@1.1.0': + '@img/sharp-libvips-linux-arm64@1.0.4': optional: true '@img/sharp-libvips-linux-arm64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm@1.0.5': + '@img/sharp-libvips-linux-arm64@1.2.3': optional: true - '@img/sharp-libvips-linux-arm@1.1.0': + '@img/sharp-libvips-linux-arm@1.0.5': optional: true '@img/sharp-libvips-linux-arm@1.2.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.1.0': + '@img/sharp-libvips-linux-arm@1.2.3': optional: true '@img/sharp-libvips-linux-ppc64@1.2.0': optional: true - '@img/sharp-libvips-linux-s390x@1.0.4': + '@img/sharp-libvips-linux-ppc64@1.2.3': optional: true - '@img/sharp-libvips-linux-s390x@1.1.0': + '@img/sharp-libvips-linux-s390x@1.0.4': optional: true '@img/sharp-libvips-linux-s390x@1.2.0': optional: true - '@img/sharp-libvips-linux-x64@1.0.4': + '@img/sharp-libvips-linux-s390x@1.2.3': optional: true - '@img/sharp-libvips-linux-x64@1.1.0': + '@img/sharp-libvips-linux-x64@1.0.4': optional: true '@img/sharp-libvips-linux-x64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + '@img/sharp-libvips-linux-x64@1.2.3': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': optional: true '@img/sharp-libvips-linuxmusl-arm64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.0.4': + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.1.0': + '@img/sharp-libvips-linuxmusl-x64@1.0.4': optional: true '@img/sharp-libvips-linuxmusl-x64@1.2.0': optional: true + '@img/sharp-libvips-linuxmusl-x64@1.2.3': + optional: true + '@img/sharp-linux-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.4 optional: true - '@img/sharp-linux-arm64@0.34.1': + '@img/sharp-linux-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.2.0 optional: true - '@img/sharp-linux-arm64@0.34.3': + '@img/sharp-linux-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.2.3 optional: true '@img/sharp-linux-arm@0.33.5': @@ -21807,14 +20920,14 @@ snapshots: '@img/sharp-libvips-linux-arm': 1.0.5 optional: true - '@img/sharp-linux-arm@0.34.1': + '@img/sharp-linux-arm@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.2.0 optional: true - '@img/sharp-linux-arm@0.34.3': + '@img/sharp-linux-arm@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.3 optional: true '@img/sharp-linux-ppc64@0.34.3': @@ -21822,14 +20935,14 @@ snapshots: '@img/sharp-libvips-linux-ppc64': 1.2.0 optional: true - '@img/sharp-linux-s390x@0.33.5': + '@img/sharp-linux-ppc64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-ppc64': 1.2.3 optional: true - '@img/sharp-linux-s390x@0.34.1': + '@img/sharp-linux-s390x@0.33.5': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.0.4 optional: true '@img/sharp-linux-s390x@0.34.3': @@ -21837,14 +20950,14 @@ snapshots: '@img/sharp-libvips-linux-s390x': 1.2.0 optional: true - '@img/sharp-linux-x64@0.33.5': + '@img/sharp-linux-s390x@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.2.3 optional: true - '@img/sharp-linux-x64@0.34.1': + '@img/sharp-linux-x64@0.33.5': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.0.4 optional: true '@img/sharp-linux-x64@0.34.3': @@ -21852,14 +20965,14 @@ snapshots: '@img/sharp-libvips-linux-x64': 1.2.0 optional: true - '@img/sharp-linuxmusl-arm64@0.33.5': + '@img/sharp-linux-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.2.3 optional: true - '@img/sharp-linuxmusl-arm64@0.34.1': + '@img/sharp-linuxmusl-arm64@0.33.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 optional: true '@img/sharp-linuxmusl-arm64@0.34.3': @@ -21867,14 +20980,14 @@ snapshots: '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 optional: true - '@img/sharp-linuxmusl-x64@0.33.5': + '@img/sharp-linuxmusl-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 optional: true - '@img/sharp-linuxmusl-x64@0.34.1': + '@img/sharp-linuxmusl-x64@0.33.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 optional: true '@img/sharp-linuxmusl-x64@0.34.3': @@ -21882,17 +20995,22 @@ snapshots: '@img/sharp-libvips-linuxmusl-x64': 1.2.0 optional: true + '@img/sharp-linuxmusl-x64@0.34.4': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.3 + optional: true + '@img/sharp-wasm32@0.33.5': dependencies: '@emnapi/runtime': 1.2.0 optional: true - '@img/sharp-wasm32@0.34.1': + '@img/sharp-wasm32@0.34.3': dependencies: - '@emnapi/runtime': 1.4.0 + '@emnapi/runtime': 1.5.0 optional: true - '@img/sharp-wasm32@0.34.3': + '@img/sharp-wasm32@0.34.4': dependencies: '@emnapi/runtime': 1.5.0 optional: true @@ -21900,24 +21018,27 @@ snapshots: '@img/sharp-win32-arm64@0.34.3': optional: true - '@img/sharp-win32-ia32@0.33.5': + '@img/sharp-win32-arm64@0.34.4': optional: true - '@img/sharp-win32-ia32@0.34.1': + '@img/sharp-win32-ia32@0.33.5': optional: true '@img/sharp-win32-ia32@0.34.3': optional: true - '@img/sharp-win32-x64@0.33.5': + '@img/sharp-win32-ia32@0.34.4': optional: true - '@img/sharp-win32-x64@0.34.1': + '@img/sharp-win32-x64@0.33.5': optional: true '@img/sharp-win32-x64@0.34.3': optional: true + '@img/sharp-win32-x64@0.34.4': + optional: true + '@inquirer/checkbox@4.1.9(@types/node@20.17.24)': dependencies: '@inquirer/core': 10.1.14(@types/node@20.17.24) @@ -22136,41 +21257,6 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.24 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))': dependencies: '@jest/console': 29.7.0 @@ -22205,7 +21291,6 @@ snapshots: - babel-plugin-macros - supports-color - ts-node - optional: true '@jest/environment@29.7.0': dependencies: @@ -22880,7 +21965,7 @@ snapshots: '@koa/router@12.0.1': dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) http-errors: 2.0.0 koa-compose: 4.1.0 methods: 1.1.2 @@ -22890,7 +21975,7 @@ snapshots: '@kwsites/file-exists@1.1.1': dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -23022,14 +22107,14 @@ snapshots: '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': dependencies: - detect-libc: 2.0.3 + detect-libc: 2.0.4 https-proxy-agent: 5.0.1 make-dir: 3.1.0 node-fetch: 2.7.0(encoding@0.1.13) nopt: 5.0.0 npmlog: 5.0.1 rimraf: 3.0.2 - semver: 7.7.1 + semver: 7.7.2 tar: 6.2.0 transitivePeerDependencies: - encoding @@ -23038,11 +22123,11 @@ snapshots: '@mapbox/node-pre-gyp@2.0.0(encoding@0.1.13)': dependencies: consola: 3.2.3 - detect-libc: 2.0.3 + detect-libc: 2.0.4 https-proxy-agent: 7.0.6(supports-color@9.4.0) node-fetch: 2.7.0(encoding@0.1.13) nopt: 8.1.0 - semver: 7.7.1 + semver: 7.7.2 tar: 7.4.3 transitivePeerDependencies: - encoding @@ -23229,25 +22314,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/schematics@10.2.3(chokidar@3.6.0)(typescript@5.5.4)': + '@nestjs/schematics@10.2.3(chokidar@3.6.0)(typescript@5.6.3)': dependencies: '@angular-devkit/core': 17.3.11(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) comment-json: 4.2.5 jsonc-parser: 3.3.1 pluralize: 8.0.0 - typescript: 5.5.4 + typescript: 5.6.3 transitivePeerDependencies: - chokidar - '@nestjs/schematics@10.2.3(chokidar@3.6.0)(typescript@5.6.3)': + '@nestjs/schematics@10.2.3(chokidar@3.6.0)(typescript@5.8.3)': dependencies: '@angular-devkit/core': 17.3.11(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0) comment-json: 4.2.5 jsonc-parser: 3.3.1 pluralize: 8.0.0 - typescript: 5.6.3 + typescript: 5.8.3 transitivePeerDependencies: - chokidar @@ -23272,13 +22357,9 @@ snapshots: '@next/env@15.0.0-canary.23': {} - '@next/env@15.2.4': {} - - '@next/env@15.3.0-canary.43': {} + '@next/env@15.5.3': {} - '@next/env@15.3.3': {} - - '@next/env@15.5.2': {} + '@next/env@15.6.0-canary.13': {} '@next/eslint-plugin-next@14.2.3': dependencies: @@ -23287,106 +22368,64 @@ snapshots: '@next/swc-darwin-arm64@15.0.0-canary.23': optional: true - '@next/swc-darwin-arm64@15.2.4': + '@next/swc-darwin-arm64@15.5.3': optional: true - '@next/swc-darwin-arm64@15.3.0-canary.43': - optional: true - - '@next/swc-darwin-arm64@15.3.3': - optional: true - - '@next/swc-darwin-arm64@15.5.2': + '@next/swc-darwin-arm64@15.6.0-canary.13': optional: true '@next/swc-darwin-x64@15.0.0-canary.23': optional: true - '@next/swc-darwin-x64@15.2.4': - optional: true - - '@next/swc-darwin-x64@15.3.0-canary.43': - optional: true - - '@next/swc-darwin-x64@15.3.3': + '@next/swc-darwin-x64@15.5.3': optional: true - '@next/swc-darwin-x64@15.5.2': + '@next/swc-darwin-x64@15.6.0-canary.13': optional: true '@next/swc-linux-arm64-gnu@15.0.0-canary.23': optional: true - '@next/swc-linux-arm64-gnu@15.2.4': - optional: true - - '@next/swc-linux-arm64-gnu@15.3.0-canary.43': - optional: true - - '@next/swc-linux-arm64-gnu@15.3.3': + '@next/swc-linux-arm64-gnu@15.5.3': optional: true - '@next/swc-linux-arm64-gnu@15.5.2': + '@next/swc-linux-arm64-gnu@15.6.0-canary.13': optional: true '@next/swc-linux-arm64-musl@15.0.0-canary.23': optional: true - '@next/swc-linux-arm64-musl@15.2.4': - optional: true - - '@next/swc-linux-arm64-musl@15.3.0-canary.43': + '@next/swc-linux-arm64-musl@15.5.3': optional: true - '@next/swc-linux-arm64-musl@15.3.3': - optional: true - - '@next/swc-linux-arm64-musl@15.5.2': + '@next/swc-linux-arm64-musl@15.6.0-canary.13': optional: true '@next/swc-linux-x64-gnu@15.0.0-canary.23': optional: true - '@next/swc-linux-x64-gnu@15.2.4': - optional: true - - '@next/swc-linux-x64-gnu@15.3.0-canary.43': + '@next/swc-linux-x64-gnu@15.5.3': optional: true - '@next/swc-linux-x64-gnu@15.3.3': - optional: true - - '@next/swc-linux-x64-gnu@15.5.2': + '@next/swc-linux-x64-gnu@15.6.0-canary.13': optional: true '@next/swc-linux-x64-musl@15.0.0-canary.23': optional: true - '@next/swc-linux-x64-musl@15.2.4': - optional: true - - '@next/swc-linux-x64-musl@15.3.0-canary.43': + '@next/swc-linux-x64-musl@15.5.3': optional: true - '@next/swc-linux-x64-musl@15.3.3': - optional: true - - '@next/swc-linux-x64-musl@15.5.2': + '@next/swc-linux-x64-musl@15.6.0-canary.13': optional: true '@next/swc-win32-arm64-msvc@15.0.0-canary.23': optional: true - '@next/swc-win32-arm64-msvc@15.2.4': - optional: true - - '@next/swc-win32-arm64-msvc@15.3.0-canary.43': + '@next/swc-win32-arm64-msvc@15.5.3': optional: true - '@next/swc-win32-arm64-msvc@15.3.3': - optional: true - - '@next/swc-win32-arm64-msvc@15.5.2': + '@next/swc-win32-arm64-msvc@15.6.0-canary.13': optional: true '@next/swc-win32-ia32-msvc@15.0.0-canary.23': @@ -23395,16 +22434,10 @@ snapshots: '@next/swc-win32-x64-msvc@15.0.0-canary.23': optional: true - '@next/swc-win32-x64-msvc@15.2.4': + '@next/swc-win32-x64-msvc@15.5.3': optional: true - '@next/swc-win32-x64-msvc@15.3.0-canary.43': - optional: true - - '@next/swc-win32-x64-msvc@15.3.3': - optional: true - - '@next/swc-win32-x64-msvc@15.5.2': + '@next/swc-win32-x64-msvc@15.6.0-canary.13': optional: true '@ngtools/webpack@19.2.15(@angular/compiler-cli@19.2.14(@angular/compiler@19.2.14)(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.4))': @@ -23437,7 +22470,7 @@ snapshots: '@npmcli/fs@4.0.0': dependencies: - semver: 7.7.1 + semver: 7.7.2 '@npmcli/git@6.0.3': dependencies: @@ -23447,7 +22480,7 @@ snapshots: npm-pick-manifest: 10.0.0 proc-log: 5.0.0 promise-retry: 2.0.1 - semver: 7.7.1 + semver: 7.7.2 which: 5.0.0 '@npmcli/installed-package-contents@3.0.0': @@ -23464,7 +22497,7 @@ snapshots: hosted-git-info: 8.1.0 json-parse-even-better-errors: 4.0.0 proc-log: 5.0.0 - semver: 7.7.1 + semver: 7.7.2 validate-npm-package-license: 3.0.4 '@npmcli/promise-spawn@8.0.2': @@ -24576,7 +23609,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.11.3 require-in-the-middle: 7.3.0 - semver: 7.7.1 + semver: 7.7.2 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -24951,14 +23984,9 @@ snapshots: '@pkgr/core@0.1.1': {} - '@playwright/test@1.46.0': - dependencies: - playwright: 1.46.0 - '@playwright/test@1.50.1': dependencies: playwright: 1.50.1 - optional: true '@polka/url@1.0.0-next.25': {} @@ -25143,48 +24171,24 @@ snapshots: optionalDependencies: rollup: 4.34.9 - '@rollup/rollup-android-arm-eabi@4.14.1': - optional: true - - '@rollup/rollup-android-arm-eabi@4.20.0': - optional: true - '@rollup/rollup-android-arm-eabi@4.34.8': optional: true '@rollup/rollup-android-arm-eabi@4.34.9': optional: true - '@rollup/rollup-android-arm64@4.14.1': - optional: true - - '@rollup/rollup-android-arm64@4.20.0': - optional: true - '@rollup/rollup-android-arm64@4.34.8': optional: true '@rollup/rollup-android-arm64@4.34.9': optional: true - '@rollup/rollup-darwin-arm64@4.14.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.20.0': - optional: true - '@rollup/rollup-darwin-arm64@4.34.8': optional: true '@rollup/rollup-darwin-arm64@4.34.9': optional: true - '@rollup/rollup-darwin-x64@4.14.1': - optional: true - - '@rollup/rollup-darwin-x64@4.20.0': - optional: true - '@rollup/rollup-darwin-x64@4.34.8': optional: true @@ -25203,45 +24207,24 @@ snapshots: '@rollup/rollup-freebsd-x64@4.34.9': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.14.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.20.0': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.34.8': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.34.9': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.20.0': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.34.8': optional: true '@rollup/rollup-linux-arm-musleabihf@4.34.9': optional: true - '@rollup/rollup-linux-arm64-gnu@4.14.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.34.8': optional: true '@rollup/rollup-linux-arm64-gnu@4.34.9': optional: true - '@rollup/rollup-linux-arm64-musl@4.14.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.20.0': - optional: true - '@rollup/rollup-linux-arm64-musl@4.34.8': optional: true @@ -25254,96 +24237,48 @@ snapshots: '@rollup/rollup-linux-loongarch64-gnu@4.34.9': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.14.1': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.34.8': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.34.9': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.14.1': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.34.8': optional: true '@rollup/rollup-linux-riscv64-gnu@4.34.9': optional: true - '@rollup/rollup-linux-s390x-gnu@4.14.1': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.34.8': optional: true '@rollup/rollup-linux-s390x-gnu@4.34.9': optional: true - '@rollup/rollup-linux-x64-gnu@4.14.1': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-x64-gnu@4.34.8': optional: true '@rollup/rollup-linux-x64-gnu@4.34.9': optional: true - '@rollup/rollup-linux-x64-musl@4.14.1': - optional: true - - '@rollup/rollup-linux-x64-musl@4.20.0': - optional: true - '@rollup/rollup-linux-x64-musl@4.34.8': optional: true '@rollup/rollup-linux-x64-musl@4.34.9': optional: true - '@rollup/rollup-win32-arm64-msvc@4.14.1': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.20.0': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.34.8': optional: true '@rollup/rollup-win32-arm64-msvc@4.34.9': optional: true - '@rollup/rollup-win32-ia32-msvc@4.14.1': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.20.0': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.34.8': optional: true '@rollup/rollup-win32-ia32-msvc@4.34.9': optional: true - '@rollup/rollup-win32-x64-msvc@4.14.1': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.20.0': - optional: true - '@rollup/rollup-win32-x64-msvc@4.34.8': optional: true @@ -25449,7 +24384,7 @@ snapshots: '@sentry/core@8.42.0': {} - '@sentry/nextjs@8.42.0(@opentelemetry/core@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0))(react@18.2.0)(webpack@5.98.0)': + '@sentry/nextjs@8.42.0(@opentelemetry/core@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0))(react@18.3.1)(webpack@5.98.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0) @@ -25459,11 +24394,11 @@ snapshots: '@sentry/core': 8.42.0 '@sentry/node': 8.42.0 '@sentry/opentelemetry': 8.42.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.28.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0) - '@sentry/react': 8.42.0(react@18.2.0) + '@sentry/react': 8.42.0(react@18.3.1) '@sentry/vercel-edge': 8.42.0 '@sentry/webpack-plugin': 2.22.6(encoding@0.1.13)(webpack@5.98.0) chalk: 3.0.0 - next: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) + next: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) resolve: 1.22.8 rollup: 3.29.5 stacktrace-parser: 0.1.10 @@ -25545,12 +24480,12 @@ snapshots: '@opentelemetry/semantic-conventions': 1.27.0 '@sentry/core': 8.42.0 - '@sentry/react@8.42.0(react@18.2.0)': + '@sentry/react@8.42.0(react@18.3.1)': dependencies: '@sentry/browser': 8.42.0 '@sentry/core': 8.42.0 hoist-non-react-statics: 3.3.2 - react: 18.2.0 + react: 18.3.1 '@sentry/types@8.22.0': {} @@ -25568,7 +24503,7 @@ snapshots: '@sentry/bundler-plugin-core': 2.22.6(encoding@0.1.13) unplugin: 1.0.1 uuid: 9.0.1 - webpack: 5.98.0(esbuild@0.25.4) + webpack: 5.98.0 transitivePeerDependencies: - encoding - supports-color @@ -26006,9 +24941,9 @@ snapshots: dependencies: acorn: 8.14.1 - '@sveltejs/adapter-vercel@5.6.3(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(encoding@0.1.13)(rollup@4.34.9)': + '@sveltejs/adapter-vercel@5.6.3(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(encoding@0.1.13)(rollup@4.34.9)': dependencies: - '@sveltejs/kit': 2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + '@sveltejs/kit': 2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@vercel/nft': 0.29.2(encoding@0.1.13)(rollup@4.34.9) esbuild: 0.24.2 transitivePeerDependencies: @@ -26016,9 +24951,9 @@ snapshots: - rollup - supports-color - '@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.1.1 @@ -26031,65 +24966,63 @@ snapshots: set-cookie-parser: 2.6.0 sirv: 3.0.0 svelte: 5.32.1 - vite: 6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - '@sveltejs/package@2.3.10(svelte@5.32.1)(typescript@5.6.3)': + '@sveltejs/package@2.3.10(svelte@5.32.1)(typescript@5.8.3)': dependencies: chokidar: 4.0.3 kleur: 4.1.5 sade: 1.8.1 semver: 7.6.3 svelte: 5.32.1 - svelte2tsx: 0.7.34(svelte@5.32.1)(typescript@5.6.3) + svelte2tsx: 0.7.34(svelte@5.32.1)(typescript@5.8.3) transitivePeerDependencies: - typescript - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) - debug: 4.4.0(supports-color@9.4.0) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + debug: 4.4.1(supports-color@9.4.0) svelte: 5.32.1 - vite: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) - debug: 4.4.0(supports-color@9.4.0) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + debug: 4.4.1(supports-color@9.4.0) svelte: 5.32.1 - vite: 6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) - debug: 4.4.0(supports-color@9.4.0) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + debug: 4.4.1(supports-color@9.4.0) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.32.1 - vite: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vitefu: 1.0.6(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + vite: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vitefu: 1.0.6(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) - debug: 4.4.0(supports-color@9.4.0) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.32.1)(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + debug: 4.4.1(supports-color@9.4.0) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.32.1 - vite: 6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vitefu: 1.0.6(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + vite: 6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vitefu: 1.0.6(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) transitivePeerDependencies: - supports-color - '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.11': dependencies: tslib: 2.8.1 @@ -26130,44 +25063,44 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.7 '@testing-library/dom': 10.4.0 react: 18.3.1 - react-dom: 18.2.0(react@18.3.1) + react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.3 - '@types/react-dom': 18.2.4 + '@types/react-dom': 18.3.0 - '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.7 '@testing-library/dom': 10.4.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.0.0-rc.1 + react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) optionalDependencies: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 - '@testing-library/svelte@5.2.7(svelte@5.32.1)(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vitest@3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@testing-library/svelte@5.2.7(svelte@5.32.1)(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vitest@3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: '@testing-library/dom': 10.4.0 svelte: 5.32.1 optionalDependencies: - vite: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vitest: 3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vitest: 3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': dependencies: '@testing-library/dom': 10.4.0 - '@testing-library/vue@8.1.0(@vue/compiler-sfc@3.5.13)(@vue/server-renderer@3.5.13(vue@3.3.8(typescript@5.8.3)))(vue@3.3.8(typescript@5.8.3))': + '@testing-library/vue@8.1.0(@vue/compiler-sfc@3.5.13)(@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3))': dependencies: '@babel/runtime': 7.25.7 '@testing-library/dom': 9.3.3 - '@vue/test-utils': 2.4.2(@vue/server-renderer@3.5.13(vue@3.3.8(typescript@5.8.3)))(vue@3.3.8(typescript@5.8.3)) - vue: 3.3.8(typescript@5.8.3) + '@vue/test-utils': 2.4.2(@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) + vue: 3.5.13(typescript@5.8.3) optionalDependencies: '@vue/compiler-sfc': 3.5.13 transitivePeerDependencies: @@ -26271,8 +25204,6 @@ snapshots: dependencies: '@types/estree': 1.0.6 - '@types/estree@1.0.5': {} - '@types/estree@1.0.6': {} '@types/express-serve-static-core@4.19.6': @@ -26365,6 +25296,8 @@ snapshots: '@types/ms@0.7.34': {} + '@types/ms@2.1.0': {} + '@types/mysql@2.15.26': dependencies: '@types/node': 20.17.24 @@ -26411,10 +25344,6 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@18.2.4': - dependencies: - '@types/react': 18.3.3 - '@types/react-dom@18.3.0': dependencies: '@types/react': 18.3.3 @@ -26493,38 +25422,37 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.26.0(@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 8.26.0(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/scope-manager': 8.26.0 - '@typescript-eslint/type-utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) - '@typescript-eslint/utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) + '@typescript-eslint/type-utils': 8.26.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.0(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.26.0 - eslint: 9.21.0(jiti@2.4.0) + eslint: 8.57.1 graphemer: 1.4.0 - ignore: 5.3.2 + ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.6.3) - typescript: 5.6.3 + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3))(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 8.6.0(eslint@8.57.1)(typescript@5.5.4) - '@typescript-eslint/scope-manager': 8.6.0 - '@typescript-eslint/type-utils': 8.6.0(eslint@8.57.1)(typescript@5.5.4) - '@typescript-eslint/utils': 8.6.0(eslint@8.57.1)(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 8.6.0 - eslint: 8.57.1 + '@typescript-eslint/parser': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.26.0 + '@typescript-eslint/type-utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.26.0 + eslint: 9.21.0(jiti@2.4.0) graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.4) - optionalDependencies: - typescript: 5.5.4 + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -26534,7 +25462,7 @@ snapshots: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.5) '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) eslint: 8.57.1 optionalDependencies: typescript: 5.4.5 @@ -26547,7 +25475,7 @@ snapshots: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) eslint: 8.57.1 optionalDependencies: typescript: 5.6.3 @@ -26560,7 +25488,7 @@ snapshots: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) eslint: 8.57.1 optionalDependencies: typescript: 5.8.3 @@ -26573,35 +25501,34 @@ snapshots: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) eslint: 9.21.0(jiti@2.4.0) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3)': + '@typescript-eslint/parser@8.26.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.26.0 '@typescript-eslint/types': 8.26.0 - '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.26.0 - debug: 4.4.0(supports-color@9.4.0) - eslint: 9.21.0(jiti@2.4.0) - typescript: 5.6.3 + debug: 4.3.7 + eslint: 8.57.1 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4)': + '@typescript-eslint/parser@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.6.0 - '@typescript-eslint/types': 8.6.0 - '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 8.6.0 + '@typescript-eslint/scope-manager': 8.26.0 + '@typescript-eslint/types': 8.26.0 + '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.26.0 debug: 4.3.7 - eslint: 8.57.1 - optionalDependencies: - typescript: 5.5.4 + eslint: 9.21.0(jiti@2.4.0) + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -26615,45 +25542,37 @@ snapshots: '@typescript-eslint/types': 8.26.0 '@typescript-eslint/visitor-keys': 8.26.0 - '@typescript-eslint/scope-manager@8.6.0': - dependencies: - '@typescript-eslint/types': 8.6.0 - '@typescript-eslint/visitor-keys': 8.6.0 - - '@typescript-eslint/type-utils@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3)': + '@typescript-eslint/type-utils@8.26.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) - debug: 4.4.1 - eslint: 9.21.0(jiti@2.4.0) - ts-api-utils: 2.0.1(typescript@5.6.3) - typescript: 5.6.3 + '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.0(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.1(supports-color@9.4.0) + eslint: 8.57.1 + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.6.0(eslint@8.57.1)(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.6.0(eslint@8.57.1)(typescript@5.5.4) - debug: 4.4.0(supports-color@9.4.0) - ts-api-utils: 1.3.0(typescript@5.5.4) - optionalDependencies: - typescript: 5.5.4 + '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) + debug: 4.4.1(supports-color@9.4.0) + eslint: 9.21.0(jiti@2.4.0) + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - - eslint - supports-color '@typescript-eslint/types@7.2.0': {} '@typescript-eslint/types@8.26.0': {} - '@typescript-eslint/types@8.6.0': {} - '@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.5)': dependencies: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -26668,7 +25587,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -26683,7 +25602,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.2.0 '@typescript-eslint/visitor-keys': 7.2.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -26694,56 +25613,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.26.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.26.0(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 8.26.0 '@typescript-eslint/visitor-keys': 8.26.0 - debug: 4.4.1 - fast-glob: 3.3.2 + debug: 4.4.1(supports-color@9.4.0) + fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.6.3) - typescript: 5.6.3 + semver: 7.7.2 + ts-api-utils: 2.0.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.6.0(typescript@5.5.4)': + '@typescript-eslint/utils@8.26.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.6.0 - '@typescript-eslint/visitor-keys': 8.6.0 - debug: 4.3.7 - fast-glob: 3.3.2 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 1.3.0(typescript@5.5.4) - optionalDependencies: - typescript: 5.5.4 + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.26.0 + '@typescript-eslint/types': 8.26.0 + '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.3) + eslint: 8.57.1 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3)': + '@typescript-eslint/utils@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.0)) '@typescript-eslint/scope-manager': 8.26.0 '@typescript-eslint/types': 8.26.0 - '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.3) eslint: 9.21.0(jiti@2.4.0) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.6.0(eslint@8.57.1)(typescript@5.5.4)': - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.6.0 - '@typescript-eslint/types': 8.6.0 - '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.5.4) - eslint: 8.57.1 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - - typescript '@typescript-eslint/visitor-keys@7.2.0': dependencies: @@ -26755,11 +25659,6 @@ snapshots: '@typescript-eslint/types': 8.26.0 eslint-visitor-keys: 4.2.0 - '@typescript-eslint/visitor-keys@8.6.0': - dependencies: - '@typescript-eslint/types': 8.6.0 - eslint-visitor-keys: 3.4.3 - '@ungap/structured-clone@1.3.0': {} '@unhead/dom@1.11.11': @@ -26819,7 +25718,9 @@ snapshots: throttleit: 2.1.0 undici: 5.28.4 - '@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0))': + '@vercel/functions@3.1.0(@aws-sdk/credential-provider-web-identity@3.662.0(@aws-sdk/client-sts@3.662.0))': + dependencies: + '@vercel/oidc': 3.0.0 optionalDependencies: '@aws-sdk/credential-provider-web-identity': 3.662.0(@aws-sdk/client-sts@3.662.0) @@ -26864,6 +25765,11 @@ snapshots: - rollup - supports-color + '@vercel/oidc@3.0.0': + dependencies: + '@types/ms': 2.1.0 + ms: 2.1.3 + '@vercel/otel@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))': dependencies: '@opentelemetry/api': 1.9.0 @@ -26914,10 +25820,10 @@ snapshots: vite: 5.4.11(@types/node@20.17.24)(less@4.2.2)(sass@1.85.0)(terser@5.39.0) vue: 3.5.13(typescript@5.8.3) - '@vitejs/plugin-vue@5.2.0(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.3.8(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.0(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.3))': dependencies: vite: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vue: 3.3.8(typescript@5.8.3) + vue: 3.5.13(typescript@5.8.3) '@vitest/expect@2.1.4': dependencies: @@ -26942,23 +25848,23 @@ snapshots: msw: 2.6.4(@types/node@20.17.24)(typescript@5.8.3) vite: 5.4.11(@types/node@20.17.24)(less@4.2.2)(sass@1.85.0)(terser@5.39.0) - '@vitest/mocker@2.1.4(msw@2.7.0(@types/node@22.7.4)(typescript@5.8.3))(vite@5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))': + '@vitest/mocker@2.1.4(msw@2.6.4(@types/node@20.17.24)(typescript@5.8.3))(vite@5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))': dependencies: '@vitest/spy': 2.1.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - msw: 2.7.0(@types/node@22.7.4)(typescript@5.8.3) + msw: 2.6.4(@types/node@20.17.24)(typescript@5.8.3) vite: 5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0) - '@vitest/mocker@3.0.7(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + '@vitest/mocker@2.1.4(msw@2.7.0(@types/node@22.7.4)(typescript@5.8.3))(vite@5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))': dependencies: - '@vitest/spy': 3.0.7 + '@vitest/spy': 2.1.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - msw: 2.7.0(@types/node@20.17.24)(typescript@5.6.3) - vite: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + msw: 2.7.0(@types/node@22.7.4)(typescript@5.8.3) + vite: 5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0) '@vitest/mocker@3.0.7(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: @@ -27057,18 +25963,11 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 - '@babel/parser': 7.26.2 + '@babel/parser': 7.28.0 '@vue/compiler-sfc': 3.5.13 transitivePeerDependencies: - supports-color - '@vue/compiler-core@3.3.8': - dependencies: - '@babel/parser': 7.26.2 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - '@vue/compiler-core@3.5.13': dependencies: '@babel/parser': 7.26.2 @@ -27077,32 +25976,14 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.3.8': - dependencies: - '@vue/compiler-core': 3.3.8 - '@vue/shared': 3.3.8 - '@vue/compiler-dom@3.5.13': dependencies: '@vue/compiler-core': 3.5.13 '@vue/shared': 3.5.13 - '@vue/compiler-sfc@3.3.8': - dependencies: - '@babel/parser': 7.26.2 - '@vue/compiler-core': 3.3.8 - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-ssr': 3.3.8 - '@vue/reactivity-transform': 3.3.8 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - magic-string: 0.30.17 - postcss: 8.5.3 - source-map-js: 1.2.1 - '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.26.2 + '@babel/parser': 7.28.0 '@vue/compiler-core': 3.5.13 '@vue/compiler-dom': 3.5.13 '@vue/compiler-ssr': 3.5.13 @@ -27112,11 +25993,6 @@ snapshots: postcss: 8.5.3 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.3.8': - dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/shared': 3.3.8 - '@vue/compiler-ssr@3.5.13': dependencies: '@vue/compiler-dom': 3.5.13 @@ -27150,18 +26026,6 @@ snapshots: dependencies: rfdc: 1.4.1 - '@vue/reactivity-transform@3.3.8': - dependencies: - '@babel/parser': 7.26.2 - '@vue/compiler-core': 3.3.8 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - magic-string: 0.30.17 - - '@vue/reactivity@3.3.8': - dependencies: - '@vue/shared': 3.3.8 - '@vue/reactivity@3.5.12': dependencies: '@vue/shared': 3.5.12 @@ -27170,11 +26034,6 @@ snapshots: dependencies: '@vue/shared': 3.5.13 - '@vue/runtime-core@3.3.8': - dependencies: - '@vue/reactivity': 3.3.8 - '@vue/shared': 3.3.8 - '@vue/runtime-core@3.5.12': dependencies: '@vue/reactivity': 3.5.12 @@ -27185,12 +26044,6 @@ snapshots: '@vue/reactivity': 3.5.13 '@vue/shared': 3.5.13 - '@vue/runtime-dom@3.3.8': - dependencies: - '@vue/runtime-core': 3.3.8 - '@vue/shared': 3.3.8 - csstype: 3.1.3 - '@vue/runtime-dom@3.5.13': dependencies: '@vue/reactivity': 3.5.13 @@ -27198,38 +26051,23 @@ snapshots: '@vue/shared': 3.5.13 csstype: 3.1.3 - '@vue/server-renderer@3.3.8(vue@3.3.8(typescript@5.8.3))': - dependencies: - '@vue/compiler-ssr': 3.3.8 - '@vue/shared': 3.3.8 - vue: 3.3.8(typescript@5.8.3) - - '@vue/server-renderer@3.5.13(vue@3.3.8(typescript@5.8.3))': - dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.3.8(typescript@5.8.3) - optional: true - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3))': dependencies: '@vue/compiler-ssr': 3.5.13 '@vue/shared': 3.5.13 vue: 3.5.13(typescript@5.8.3) - '@vue/shared@3.3.8': {} - '@vue/shared@3.5.12': {} '@vue/shared@3.5.13': {} - '@vue/test-utils@2.4.2(@vue/server-renderer@3.5.13(vue@3.3.8(typescript@5.8.3)))(vue@3.3.8(typescript@5.8.3))': + '@vue/test-utils@2.4.2(@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3))': dependencies: js-beautify: 1.14.11 - vue: 3.3.8(typescript@5.8.3) + vue: 3.5.13(typescript@5.8.3) vue-component-type-helpers: 1.8.22 optionalDependencies: - '@vue/server-renderer': 3.5.13(vue@3.3.8(typescript@5.8.3)) + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.8.3)) '@webassemblyjs/ast@1.12.1': dependencies: @@ -27442,13 +26280,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color agent-base@7.1.1: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -27692,7 +26530,7 @@ snapshots: ast-kit@1.3.1: dependencies: - '@babel/parser': 7.26.2 + '@babel/parser': 7.28.0 pathe: 1.1.2 ast-types-flow@0.0.8: {} @@ -27707,7 +26545,7 @@ snapshots: ast-walker-scope@0.6.2: dependencies: - '@babel/parser': 7.26.2 + '@babel/parser': 7.28.0 ast-kit: 1.3.1 astral-regex@2.0.0: {} @@ -27730,36 +26568,6 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.4.16(postcss@8.4.49): - dependencies: - browserslist: 4.22.1 - caniuse-lite: 1.0.30001591 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.0 - postcss: 8.4.49 - postcss-value-parser: 4.2.0 - - autoprefixer@10.4.19(postcss@8.4.49): - dependencies: - browserslist: 4.23.1 - caniuse-lite: 1.0.30001637 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.1 - postcss: 8.4.49 - postcss-value-parser: 4.2.0 - - autoprefixer@10.4.20(postcss@8.4.49): - dependencies: - browserslist: 4.23.3 - caniuse-lite: 1.0.30001649 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.1 - postcss: 8.4.49 - postcss-value-parser: 4.2.0 - autoprefixer@10.4.20(postcss@8.5.2): dependencies: browserslist: 4.23.3 @@ -28026,28 +26834,10 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: - dependencies: - fill-range: 7.1.1 - braces@3.0.3: dependencies: fill-range: 7.1.1 - browserslist@4.22.1: - dependencies: - caniuse-lite: 1.0.30001666 - electron-to-chromium: 1.4.812 - node-releases: 2.0.14 - update-browserslist-db: 1.0.16(browserslist@4.22.1) - - browserslist@4.23.1: - dependencies: - caniuse-lite: 1.0.30001666 - electron-to-chromium: 1.4.812 - node-releases: 2.0.14 - update-browserslist-db: 1.0.16(browserslist@4.23.1) - browserslist@4.23.3: dependencies: caniuse-lite: 1.0.30001666 @@ -28099,21 +26889,11 @@ snapshots: dependencies: run-applescript: 7.0.0 - bundle-require@4.0.2(esbuild@0.19.12): - dependencies: - esbuild: 0.19.12 - load-tsconfig: 0.2.5 - bundle-require@4.2.1(esbuild@0.18.20): dependencies: esbuild: 0.18.20 load-tsconfig: 0.2.5 - bundle-require@5.0.0(esbuild@0.23.0): - dependencies: - esbuild: 0.23.0 - load-tsconfig: 0.2.5 - bundle-require@5.0.0(esbuild@0.23.1): dependencies: esbuild: 0.23.1 @@ -28204,10 +26984,6 @@ snapshots: lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001591: {} - - caniuse-lite@1.0.30001637: {} - caniuse-lite@1.0.30001649: {} caniuse-lite@1.0.30001666: {} @@ -28274,18 +27050,6 @@ snapshots: check-error@2.1.1: {} - chokidar@3.5.3: - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -28598,21 +27362,6 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.7.0 - create-jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - create-jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: '@jest/types': 29.6.3 @@ -28627,7 +27376,6 @@ snapshots: - babel-plugin-macros - supports-color - ts-node - optional: true create-require@1.1.1: {} @@ -28802,15 +27550,15 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.4.0(supports-color@9.4.0): + debug@4.4.0: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 9.4.0 - debug@4.4.1: + debug@4.4.1(supports-color@9.4.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 9.4.0 decamelize@1.2.0: {} @@ -28911,7 +27659,9 @@ snapshots: detect-libc@2.0.3: {} - detect-libc@2.0.4: + detect-libc@2.0.4: {} + + detect-libc@2.1.0: optional: true detect-newline@3.1.0: {} @@ -29019,7 +27769,7 @@ snapshots: '@one-ini/wasm': 0.1.1 commander: 10.0.1 minimatch: 9.0.1 - semver: 7.7.1 + semver: 7.7.2 ee-first@1.1.1: {} @@ -29027,8 +27777,6 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.4.812: {} - electron-to-chromium@1.5.182: {} electron-to-chromium@1.5.31: {} @@ -29235,32 +27983,6 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 - esbuild@0.19.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -29287,33 +28009,6 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.23.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.23.0 - '@esbuild/android-arm': 0.23.0 - '@esbuild/android-arm64': 0.23.0 - '@esbuild/android-x64': 0.23.0 - '@esbuild/darwin-arm64': 0.23.0 - '@esbuild/darwin-x64': 0.23.0 - '@esbuild/freebsd-arm64': 0.23.0 - '@esbuild/freebsd-x64': 0.23.0 - '@esbuild/linux-arm': 0.23.0 - '@esbuild/linux-arm64': 0.23.0 - '@esbuild/linux-ia32': 0.23.0 - '@esbuild/linux-loong64': 0.23.0 - '@esbuild/linux-mips64el': 0.23.0 - '@esbuild/linux-ppc64': 0.23.0 - '@esbuild/linux-riscv64': 0.23.0 - '@esbuild/linux-s390x': 0.23.0 - '@esbuild/linux-x64': 0.23.0 - '@esbuild/netbsd-x64': 0.23.0 - '@esbuild/openbsd-arm64': 0.23.0 - '@esbuild/openbsd-x64': 0.23.0 - '@esbuild/sunos-x64': 0.23.0 - '@esbuild/win32-arm64': 0.23.0 - '@esbuild/win32-ia32': 0.23.0 - '@esbuild/win32-x64': 0.23.0 - esbuild@0.23.1: optionalDependencies: '@esbuild/aix-ppc64': 0.23.1 @@ -29486,8 +28181,8 @@ snapshots: '@typescript-eslint/parser': 7.2.0(eslint@8.57.1)(typescript@5.8.3) 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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.34.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -29538,7 +28233,7 @@ snapshots: eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1): dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) @@ -29555,7 +28250,7 @@ snapshots: 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): dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) enhanced-resolve: 5.17.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) @@ -29570,13 +28265,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1): dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.3 get-tsconfig: 4.8.1 is-core-module: 2.16.1 @@ -29589,7 +28284,7 @@ snapshots: eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.21.0(jiti@2.4.0)): dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) enhanced-resolve: 5.17.1 eslint: 9.21.0(jiti@2.4.0) eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.21.0(jiti@2.4.0)) @@ -29626,14 +28321,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.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.8.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: '@typescript-eslint/parser': 7.2.0(eslint@8.57.1)(typescript@5.8.3) 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.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -29702,7 +28397,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.8.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.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.8.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -29712,7 +28407,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.8.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.8.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.8.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.16.1 is-glob: 4.0.3 @@ -29796,10 +28491,10 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.0 - eslint-plugin-prettier@5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@10.0.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3): + eslint-plugin-prettier@5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@10.0.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3): dependencies: eslint: 8.57.1 - prettier: 3.3.3 + prettier: 3.5.3 prettier-linter-helpers: 1.0.0 synckit: 0.9.1 optionalDependencies: @@ -29858,7 +28553,7 @@ snapshots: semver: 6.3.1 string.prototype.matchall: 4.0.11 - eslint-plugin-svelte@3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)): + eslint-plugin-svelte@3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.0)) '@jridgewell/sourcemap-codec': 1.5.0 @@ -29867,7 +28562,7 @@ snapshots: esutils: 2.0.3 known-css-properties: 0.35.0 postcss: 8.5.3 - postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)) + postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) postcss-safe-parser: 7.0.1(postcss@8.5.3) semver: 7.6.3 svelte-eslint-parser: 1.0.1(svelte@5.32.1) @@ -29876,7 +28571,7 @@ snapshots: transitivePeerDependencies: - ts-node - eslint-plugin-svelte@3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)): + eslint-plugin-svelte@3.0.3(eslint@9.21.0(jiti@2.4.0))(svelte@5.32.1)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.0)) '@jridgewell/sourcemap-codec': 1.5.0 @@ -29885,7 +28580,7 @@ snapshots: esutils: 2.0.3 known-css-properties: 0.35.0 postcss: 8.5.3 - postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)) + postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)) postcss-safe-parser: 7.0.1(postcss@8.5.3) semver: 7.6.3 svelte-eslint-parser: 1.0.1(svelte@5.32.1) @@ -29931,7 +28626,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -29978,7 +28673,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) escape-string-regexp: 4.0.0 eslint-scope: 8.2.0 eslint-visitor-keys: 4.2.0 @@ -30460,7 +29155,7 @@ snapshots: follow-redirects@1.15.9(debug@4.4.1): optionalDependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) for-each@0.3.3: dependencies: @@ -30617,13 +29312,9 @@ snapshots: - encoding - supports-color - geist@1.3.1(next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0)): - dependencies: - next: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0) - - geist@1.3.1(next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0)): + geist@1.3.1(next@15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0)): dependencies: - next: 15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) + next: 15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0) generic-pool@3.9.0: {} @@ -30731,15 +29422,6 @@ snapshots: package-json-from-dist: 1.0.0 path-scurry: 1.11.1 - glob@7.1.6: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -30987,14 +29669,14 @@ snapshots: http-proxy-agent@7.0.0: dependencies: agent-base: 7.1.1 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -31013,7 +29695,7 @@ snapshots: http-proxy-middleware@3.0.5: dependencies: '@types/http-proxy': 1.17.15 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) http-proxy: 1.18.1(debug@4.4.1) is-glob: 4.0.3 is-plain-object: 5.0.0 @@ -31034,21 +29716,21 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6(supports-color@9.4.0): dependencies: agent-base: 7.1.3 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -31235,7 +29917,7 @@ snapshots: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -31515,7 +30197,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -31594,25 +30276,6 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - jest-cli@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) @@ -31631,38 +30294,6 @@ snapshots: - babel-plugin-macros - supports-color - ts-node - optional: true - - jest-config@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)): - dependencies: - '@babel/core': 7.26.10 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.26.10) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 20.17.24 - ts-node: 10.9.2(@types/node@20.17.24)(typescript@5.5.4) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color jest-config@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: @@ -31694,7 +30325,6 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - supports-color - optional: true jest-diff@29.7.0: dependencies: @@ -31917,18 +30547,6 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) @@ -31940,7 +30558,6 @@ snapshots: - babel-plugin-macros - supports-color - ts-node - optional: true jimp@0.14.0: dependencies: @@ -32196,7 +30813,7 @@ snapshots: koa-send@5.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) http-errors: 1.8.1 resolve-path: 1.4.0 transitivePeerDependencies: @@ -32216,7 +30833,7 @@ snapshots: content-disposition: 0.5.4 content-type: 1.0.5 cookies: 0.8.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) delegates: 1.0.0 depd: 2.0.0 destroy: 1.2.0 @@ -32650,7 +31267,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.2 make-error@1.3.6: {} @@ -32926,7 +31543,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -33166,32 +31783,6 @@ snapshots: transitivePeerDependencies: - '@types/node' - msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3): - dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.0.2(@types/node@20.17.24) - '@mswjs/interceptors': 0.37.5 - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.5 - graphql: 16.9.0 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - strict-event-emitter: 0.5.1 - type-fest: 4.26.1 - yargs: 17.7.2 - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - '@types/node' - optional: true - msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3): dependencies: '@bundled-es-modules/cookie': 2.0.1 @@ -33272,8 +31863,6 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nanoid@3.3.7: {} - nanoid@3.3.8: {} nanoid@5.0.8: {} @@ -33296,7 +31885,7 @@ snapshots: neo-async@2.6.2: {} - next@15.0.0-canary.23(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(react-dom@19.0.0-rc-cc1ec60d0d-20240607(react@19.0.0-rc-cc1ec60d0d-20240607))(react@19.0.0-rc-cc1ec60d0d-20240607)(sass@1.85.0): + next@15.0.0-canary.23(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0-rc-cc1ec60d0d-20240607(react@19.0.0-rc-cc1ec60d0d-20240607))(react@19.0.0-rc-cc1ec60d0d-20240607)(sass@1.85.0): dependencies: '@next/env': 15.0.0-canary.23 '@swc/helpers': 0.5.11 @@ -33318,34 +31907,6 @@ snapshots: '@next/swc-win32-ia32-msvc': 15.0.0-canary.23 '@next/swc-win32-x64-msvc': 15.0.0-canary.23 '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.46.0 - sass: 1.85.0 - sharp: 0.33.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.85.0): - dependencies: - '@next/env': 15.2.4 - '@swc/counter': 0.1.3 - '@swc/helpers': 0.5.15 - busboy: 1.6.0 - caniuse-lite: 1.0.30001666 - postcss: 8.4.31 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.6(react@18.2.0) - optionalDependencies: - '@next/swc-darwin-arm64': 15.2.4 - '@next/swc-darwin-x64': 15.2.4 - '@next/swc-linux-arm64-gnu': 15.2.4 - '@next/swc-linux-arm64-musl': 15.2.4 - '@next/swc-linux-x64-gnu': 15.2.4 - '@next/swc-linux-x64-musl': 15.2.4 - '@next/swc-win32-arm64-msvc': 15.2.4 - '@next/swc-win32-x64-msvc': 15.2.4 - '@opentelemetry/api': 1.9.0 '@playwright/test': 1.50.1 sass: 1.85.0 sharp: 0.33.5 @@ -33353,112 +31914,54 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.2.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0): + next@15.5.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0): dependencies: - '@next/env': 15.2.4 - '@swc/counter': 0.1.3 + '@next/env': 15.5.3 '@swc/helpers': 0.5.15 - busboy: 1.6.0 caniuse-lite: 1.0.30001666 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.6(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.2.4 - '@next/swc-darwin-x64': 15.2.4 - '@next/swc-linux-arm64-gnu': 15.2.4 - '@next/swc-linux-arm64-musl': 15.2.4 - '@next/swc-linux-x64-gnu': 15.2.4 - '@next/swc-linux-x64-musl': 15.2.4 - '@next/swc-win32-arm64-msvc': 15.2.4 - '@next/swc-win32-x64-msvc': 15.2.4 + '@next/swc-darwin-arm64': 15.5.3 + '@next/swc-darwin-x64': 15.5.3 + '@next/swc-linux-arm64-gnu': 15.5.3 + '@next/swc-linux-arm64-musl': 15.5.3 + '@next/swc-linux-x64-gnu': 15.5.3 + '@next/swc-linux-x64-musl': 15.5.3 + '@next/swc-win32-arm64-msvc': 15.5.3 + '@next/swc-win32-x64-msvc': 15.5.3 '@opentelemetry/api': 1.9.0 '@playwright/test': 1.50.1 sass: 1.85.0 - sharp: 0.33.5 + sharp: 0.34.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - next@15.3.0-canary.43(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(sass@1.85.0): + next@15.6.0-canary.13(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0-rc.1(react@19.0.0-rc.1))(react@19.0.0-rc.1)(sass@1.85.0): dependencies: - '@next/env': 15.3.0-canary.43 - '@swc/counter': 0.1.3 + '@next/env': 15.6.0-canary.13 '@swc/helpers': 0.5.15 - busboy: 1.6.0 caniuse-lite: 1.0.30001666 postcss: 8.4.31 react: 19.0.0-rc.1 react-dom: 19.0.0-rc.1(react@19.0.0-rc.1) styled-jsx: 5.1.6(react@19.0.0-rc.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.3.0-canary.43 - '@next/swc-darwin-x64': 15.3.0-canary.43 - '@next/swc-linux-arm64-gnu': 15.3.0-canary.43 - '@next/swc-linux-arm64-musl': 15.3.0-canary.43 - '@next/swc-linux-x64-gnu': 15.3.0-canary.43 - '@next/swc-linux-x64-musl': 15.3.0-canary.43 - '@next/swc-win32-arm64-msvc': 15.3.0-canary.43 - '@next/swc-win32-x64-msvc': 15.3.0-canary.43 + '@next/swc-darwin-arm64': 15.6.0-canary.13 + '@next/swc-darwin-x64': 15.6.0-canary.13 + '@next/swc-linux-arm64-gnu': 15.6.0-canary.13 + '@next/swc-linux-arm64-musl': 15.6.0-canary.13 + '@next/swc-linux-x64-gnu': 15.6.0-canary.13 + '@next/swc-linux-x64-musl': 15.6.0-canary.13 + '@next/swc-win32-arm64-msvc': 15.6.0-canary.13 + '@next/swc-win32-x64-msvc': 15.6.0-canary.13 '@opentelemetry/api': 1.9.0 '@playwright/test': 1.50.1 sass: 1.85.0 - sharp: 0.34.1 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - next@15.3.3(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0): - dependencies: - '@next/env': 15.3.3 - '@swc/counter': 0.1.3 - '@swc/helpers': 0.5.15 - busboy: 1.6.0 - caniuse-lite: 1.0.30001666 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.6(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 15.3.3 - '@next/swc-darwin-x64': 15.3.3 - '@next/swc-linux-arm64-gnu': 15.3.3 - '@next/swc-linux-arm64-musl': 15.3.3 - '@next/swc-linux-x64-gnu': 15.3.3 - '@next/swc-linux-x64-musl': 15.3.3 - '@next/swc-win32-arm64-msvc': 15.3.3 - '@next/swc-win32-x64-msvc': 15.3.3 - '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.50.1 - sass: 1.85.0 - sharp: 0.34.1 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - next@15.5.2(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.0): - dependencies: - '@next/env': 15.5.2 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001727 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.6(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 15.5.2 - '@next/swc-darwin-x64': 15.5.2 - '@next/swc-linux-arm64-gnu': 15.5.2 - '@next/swc-linux-arm64-musl': 15.5.2 - '@next/swc-linux-x64-gnu': 15.5.2 - '@next/swc-linux-x64-musl': 15.5.2 - '@next/swc-win32-arm64-msvc': 15.5.2 - '@next/swc-win32-x64-msvc': 15.5.2 - '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.46.0 - sass: 1.85.0 - sharp: 0.34.3 + sharp: 0.34.4 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -33585,7 +32088,7 @@ snapshots: node-gyp-build-optional-packages@5.2.2: dependencies: - detect-libc: 2.0.3 + detect-libc: 2.0.4 optional: true node-gyp-build@4.6.1: {} @@ -33598,7 +32101,7 @@ snapshots: make-fetch-happen: 14.0.3 nopt: 8.1.0 proc-log: 5.0.0 - semver: 7.7.1 + semver: 7.7.2 tar: 7.4.3 tinyglobby: 0.2.14 which: 5.0.0 @@ -33607,8 +32110,6 @@ snapshots: node-int64@0.4.0: {} - node-releases@2.0.14: {} - node-releases@2.0.18: {} node-releases@2.0.19: {} @@ -33639,7 +32140,7 @@ snapshots: npm-install-checks@7.1.1: dependencies: - semver: 7.7.1 + semver: 7.7.2 npm-normalize-package-bin@2.0.0: {} @@ -34255,8 +32756,6 @@ snapshots: transitivePeerDependencies: - debug - picocolors@1.0.0: {} - picocolors@1.0.1: {} picocolors@1.1.0: {} @@ -34326,23 +32825,13 @@ snapshots: mlly: 1.7.3 pathe: 1.1.2 - playwright-core@1.46.0: {} - - playwright-core@1.50.1: - optional: true - - playwright@1.46.0: - dependencies: - playwright-core: 1.46.0 - optionalDependencies: - fsevents: 2.3.2 + playwright-core@1.50.1: {} playwright@1.50.1: dependencies: playwright-core: 1.50.1 optionalDependencies: fsevents: 2.3.2 - optional: true plist@3.1.0: dependencies: @@ -34413,29 +32902,21 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.5.3 - postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)): + postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.5.3 - ts-node: 10.9.2(@types/node@20.17.24)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@20.17.24)(typescript@5.8.3) - postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)): + postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.5.3 - ts-node: 10.9.2(@types/node@22.7.4)(typescript@5.6.3) - - postcss-load-config@4.0.1(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): - dependencies: - lilconfig: 2.1.0 - yaml: 2.4.5 - optionalDependencies: - postcss: 8.5.3 - ts-node: 10.9.2(@types/node@20.17.24)(typescript@5.8.3) + ts-node: 10.9.2(@types/node@22.7.4)(typescript@5.8.3) postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)): dependencies: @@ -34461,13 +32942,13 @@ snapshots: postcss: 8.5.3 ts-node: 10.9.2(@types/node@20.17.24)(typescript@5.8.3) - postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)): + postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)): dependencies: lilconfig: 3.1.3 yaml: 2.7.0 optionalDependencies: postcss: 8.5.3 - ts-node: 10.9.2(@types/node@22.7.4)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@22.7.4)(typescript@5.8.3) postcss-load-config@6.0.1(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(yaml@2.7.0): dependencies: @@ -34662,12 +33143,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.4.49: - dependencies: - nanoid: 3.3.7 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.2: dependencies: nanoid: 3.3.8 @@ -34703,8 +33178,6 @@ snapshots: prettier@2.8.8: {} - prettier@3.3.3: {} - prettier@3.5.3: {} pretty-bytes@6.1.1: {} @@ -34838,18 +33311,6 @@ snapshots: defu: 6.1.4 destr: 2.0.3 - react-dom@18.2.0(react@18.2.0): - dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 - - react-dom@18.2.0(react@18.3.1): - dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.0 - react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -34897,11 +33358,7 @@ snapshots: neo-async: 2.6.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - webpack: 5.98.0(esbuild@0.25.4) - - react@18.2.0: - dependencies: - loose-envify: 1.4.0 + webpack: 5.98.0 react@18.3.1: dependencies: @@ -35091,7 +33548,7 @@ snapshots: require-in-the-middle@7.3.0: dependencies: - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) module-details-from-path: 1.0.3 resolve: 1.22.8 transitivePeerDependencies: @@ -35187,49 +33644,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - rollup@4.14.1: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.14.1 - '@rollup/rollup-android-arm64': 4.14.1 - '@rollup/rollup-darwin-arm64': 4.14.1 - '@rollup/rollup-darwin-x64': 4.14.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.14.1 - '@rollup/rollup-linux-arm64-gnu': 4.14.1 - '@rollup/rollup-linux-arm64-musl': 4.14.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.14.1 - '@rollup/rollup-linux-riscv64-gnu': 4.14.1 - '@rollup/rollup-linux-s390x-gnu': 4.14.1 - '@rollup/rollup-linux-x64-gnu': 4.14.1 - '@rollup/rollup-linux-x64-musl': 4.14.1 - '@rollup/rollup-win32-arm64-msvc': 4.14.1 - '@rollup/rollup-win32-ia32-msvc': 4.14.1 - '@rollup/rollup-win32-x64-msvc': 4.14.1 - fsevents: 2.3.3 - - rollup@4.20.0: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.20.0 - '@rollup/rollup-android-arm64': 4.20.0 - '@rollup/rollup-darwin-arm64': 4.20.0 - '@rollup/rollup-darwin-x64': 4.20.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.20.0 - '@rollup/rollup-linux-arm-musleabihf': 4.20.0 - '@rollup/rollup-linux-arm64-gnu': 4.20.0 - '@rollup/rollup-linux-arm64-musl': 4.20.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.20.0 - '@rollup/rollup-linux-riscv64-gnu': 4.20.0 - '@rollup/rollup-linux-s390x-gnu': 4.20.0 - '@rollup/rollup-linux-x64-gnu': 4.20.0 - '@rollup/rollup-linux-x64-musl': 4.20.0 - '@rollup/rollup-win32-arm64-msvc': 4.20.0 - '@rollup/rollup-win32-ia32-msvc': 4.20.0 - '@rollup/rollup-win32-x64-msvc': 4.20.0 - fsevents: 2.3.3 - rollup@4.34.8: dependencies: '@types/estree': 1.0.6 @@ -35363,10 +33777,6 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.23.0: - dependencies: - loose-envify: 1.4.0 - scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -35409,8 +33819,7 @@ snapshots: semver@7.7.1: {} - semver@7.7.2: - optional: true + semver@7.7.2: {} send@0.19.0: dependencies: @@ -35432,7 +33841,7 @@ snapshots: send@1.1.0: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) destroy: 1.2.0 encodeurl: 2.0.0 escape-html: 1.0.3 @@ -35545,34 +33954,6 @@ snapshots: '@img/sharp-win32-ia32': 0.33.5 '@img/sharp-win32-x64': 0.33.5 - sharp@0.34.1: - dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - semver: 7.7.1 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.1 - '@img/sharp-darwin-x64': 0.34.1 - '@img/sharp-libvips-darwin-arm64': 1.1.0 - '@img/sharp-libvips-darwin-x64': 1.1.0 - '@img/sharp-libvips-linux-arm': 1.1.0 - '@img/sharp-libvips-linux-arm64': 1.1.0 - '@img/sharp-libvips-linux-ppc64': 1.1.0 - '@img/sharp-libvips-linux-s390x': 1.1.0 - '@img/sharp-libvips-linux-x64': 1.1.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - '@img/sharp-linux-arm': 0.34.1 - '@img/sharp-linux-arm64': 0.34.1 - '@img/sharp-linux-s390x': 0.34.1 - '@img/sharp-linux-x64': 0.34.1 - '@img/sharp-linuxmusl-arm64': 0.34.1 - '@img/sharp-linuxmusl-x64': 0.34.1 - '@img/sharp-wasm32': 0.34.1 - '@img/sharp-win32-ia32': 0.34.1 - '@img/sharp-win32-x64': 0.34.1 - optional: true - sharp@0.34.3: dependencies: color: 4.2.3 @@ -35603,6 +33984,36 @@ snapshots: '@img/sharp-win32-x64': 0.34.3 optional: true + sharp@0.34.4: + dependencies: + '@img/colour': 1.0.0 + detect-libc: 2.1.0 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.4 + '@img/sharp-darwin-x64': 0.34.4 + '@img/sharp-libvips-darwin-arm64': 1.2.3 + '@img/sharp-libvips-darwin-x64': 1.2.3 + '@img/sharp-libvips-linux-arm': 1.2.3 + '@img/sharp-libvips-linux-arm64': 1.2.3 + '@img/sharp-libvips-linux-ppc64': 1.2.3 + '@img/sharp-libvips-linux-s390x': 1.2.3 + '@img/sharp-libvips-linux-x64': 1.2.3 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 + '@img/sharp-libvips-linuxmusl-x64': 1.2.3 + '@img/sharp-linux-arm': 0.34.4 + '@img/sharp-linux-arm64': 0.34.4 + '@img/sharp-linux-ppc64': 0.34.4 + '@img/sharp-linux-s390x': 0.34.4 + '@img/sharp-linux-x64': 0.34.4 + '@img/sharp-linuxmusl-arm64': 0.34.4 + '@img/sharp-linuxmusl-x64': 0.34.4 + '@img/sharp-wasm32': 0.34.4 + '@img/sharp-win32-arm64': 0.34.4 + '@img/sharp-win32-ia32': 0.34.4 + '@img/sharp-win32-x64': 0.34.4 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -35647,7 +34058,7 @@ snapshots: dependencies: '@kwsites/file-exists': 1.1.1 '@kwsites/promise-deferred': 1.1.1 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -35696,7 +34107,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.3 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) socks: 2.8.6 transitivePeerDependencies: - supports-color @@ -35764,7 +34175,7 @@ snapshots: spdy-transport@3.0.0: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -35775,7 +34186,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -35952,11 +34363,6 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - styled-jsx@5.1.6(react@18.2.0): - dependencies: - client-only: 0.0.1 - react: 18.2.0 - styled-jsx@5.1.6(react@18.3.1): dependencies: client-only: 0.0.1 @@ -35978,19 +34384,9 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - sucrase@3.34.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.8 - commander: 4.1.1 - glob: 7.1.6 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 - sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/gen-mapping': 0.3.12 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 @@ -36002,7 +34398,7 @@ snapshots: dependencies: component-emitter: 1.3.1 cookiejar: 2.1.4 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) fast-safe-stringify: 2.1.1 form-data: 4.0.0 formidable: 3.5.1 @@ -36039,7 +34435,7 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.32.1)(typescript@5.6.3): + svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.32.1)(typescript@5.8.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.1 @@ -36047,7 +34443,7 @@ snapshots: picocolors: 1.1.1 sade: 1.8.1 svelte: 5.32.1 - typescript: 5.6.3 + typescript: 5.8.3 transitivePeerDependencies: - picomatch @@ -36069,12 +34465,12 @@ snapshots: style-to-object: 1.0.8 svelte: 5.32.1 - svelte2tsx@0.7.34(svelte@5.32.1)(typescript@5.6.3): + svelte2tsx@0.7.34(svelte@5.32.1)(typescript@5.8.3): dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 svelte: 5.32.1 - typescript: 5.6.3 + typescript: 5.8.3 svelte@5.32.1: dependencies: @@ -36105,15 +34501,15 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - swr@2.2.5(react@18.3.1): + swr@2.2.5(react@19.0.0-rc.1): dependencies: client-only: 0.0.1 - react: 18.3.1 - use-sync-external-store: 1.2.0(react@18.3.1) + react: 19.0.0-rc.1 + use-sync-external-store: 1.2.0(react@19.0.0-rc.1) - swrv@1.0.4(vue@3.3.8(typescript@5.8.3)): + swrv@1.0.4(vue@3.5.13(typescript@5.8.3)): dependencies: - vue: 3.3.8(typescript@5.8.3) + vue: 3.5.13(typescript@5.8.3) symbol-observable@4.0.0: {} @@ -36144,16 +34540,16 @@ snapshots: tailwind-merge@3.0.2: {} - tailwind-variants@1.0.0(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3))): + tailwind-variants@1.0.0(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3))): dependencies: tailwind-merge: 3.0.2 - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3))): dependencies: - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)) - tailwindcss@3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)): + tailwindcss@3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -36172,7 +34568,7 @@ snapshots: postcss: 8.5.3 postcss-import: 15.1.0(postcss@8.5.3) postcss-js: 4.0.1(postcss@8.5.3) - postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) postcss-nested: 6.2.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -36180,7 +34576,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)): + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -36191,7 +34587,7 @@ snapshots: glob-parent: 6.0.2 is-glob: 4.0.3 jiti: 1.21.6 - lilconfig: 2.1.0 + lilconfig: 3.1.3 micromatch: 4.0.8 normalize-path: 3.0.0 object-hash: 3.0.0 @@ -36199,7 +34595,7 @@ snapshots: postcss: 8.5.3 postcss-import: 15.1.0(postcss@8.5.3) postcss-js: 4.0.1(postcss@8.5.3) - postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)) + postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5)) postcss-nested: 6.2.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -36207,7 +34603,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.15(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)): + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -36218,7 +34614,7 @@ snapshots: glob-parent: 6.0.2 is-glob: 4.0.3 jiti: 1.21.6 - lilconfig: 2.1.0 + lilconfig: 3.1.3 micromatch: 4.0.8 normalize-path: 3.0.0 object-hash: 3.0.0 @@ -36226,7 +34622,7 @@ snapshots: postcss: 8.5.3 postcss-import: 15.1.0(postcss@8.5.3) postcss-js: 4.0.1(postcss@8.5.3) - postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) + postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3)) postcss-nested: 6.2.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -36261,7 +34657,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)): + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -36280,7 +34676,7 @@ snapshots: postcss: 8.5.3 postcss-import: 15.1.0(postcss@8.5.3) postcss-js: 4.0.1(postcss@8.5.3) - postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3)) + postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3)) postcss-nested: 6.2.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -36351,6 +34747,15 @@ snapshots: optionalDependencies: esbuild: 0.25.4 + terser-webpack-plugin@5.3.14(webpack@5.98.0): + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + jest-worker: 27.5.1 + schema-utils: 4.3.2 + serialize-javascript: 6.0.2 + terser: 5.39.0 + webpack: 5.98.0 + terser@5.31.3: dependencies: '@jridgewell/source-map': 0.3.6 @@ -36498,10 +34903,6 @@ snapshots: dependencies: typescript: 5.4.5 - ts-api-utils@1.3.0(typescript@5.5.4): - dependencies: - typescript: 5.5.4 - ts-api-utils@1.3.0(typescript@5.6.3): dependencies: typescript: 5.6.3 @@ -36510,24 +34911,24 @@ snapshots: dependencies: typescript: 5.8.3 - ts-api-utils@2.0.1(typescript@5.6.3): + ts-api-utils@2.0.1(typescript@5.8.3): dependencies: - typescript: 5.6.3 + typescript: 5.8.3 ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)))(typescript@5.5.4): + ts-jest@29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4)) + jest: 29.7.0(@types/node@20.17.24)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.3 - typescript: 5.5.4 + typescript: 5.8.3 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.26.10 @@ -36535,14 +34936,14 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.26.10) - ts-loader@9.5.1(typescript@5.5.4)(webpack@5.96.1): + ts-loader@9.5.1(typescript@5.8.3)(webpack@5.96.1): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.1 micromatch: 4.0.7 semver: 7.6.3 source-map: 0.7.4 - typescript: 5.5.4 + typescript: 5.8.3 webpack: 5.96.1 ts-node@10.9.2(@types/node@20.17.24)(typescript@5.4.5): @@ -36564,24 +34965,6 @@ snapshots: yn: 3.1.1 optional: true - ts-node@10.9.2(@types/node@20.17.24)(typescript@5.5.4): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.17.24 - acorn: 8.12.1 - acorn-walk: 8.3.3 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.5.4 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - ts-node@10.9.2(@types/node@20.17.24)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -36618,9 +35001,8 @@ snapshots: typescript: 5.8.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - optional: true - ts-node@10.9.2(@types/node@22.7.4)(typescript@5.6.3): + ts-node@10.9.2(@types/node@22.7.4)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -36634,7 +35016,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.6.3 + typescript: 5.8.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optional: true @@ -36670,7 +35052,7 @@ snapshots: bundle-require: 4.2.1(esbuild@0.18.20) cac: 6.7.14 chokidar: 3.6.0 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.0 esbuild: 0.18.20 execa: 5.1.1 globby: 11.1.0 @@ -36688,63 +35070,13 @@ snapshots: - supports-color - ts-node - tsup@8.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3))(typescript@5.8.3): - dependencies: - bundle-require: 4.0.2(esbuild@0.19.12) - cac: 6.7.14 - chokidar: 3.5.3 - debug: 4.3.7 - esbuild: 0.19.12 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - postcss-load-config: 4.0.1(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.24)(typescript@5.8.3)) - resolve-from: 5.0.0 - rollup: 4.14.1 - source-map: 0.8.0-beta.0 - sucrase: 3.34.0 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.3 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - ts-node - - tsup@8.2.4(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.8.3)(yaml@2.7.0): - dependencies: - bundle-require: 5.0.0(esbuild@0.23.0) - cac: 6.7.14 - chokidar: 3.6.0 - consola: 3.2.3 - debug: 4.3.7 - esbuild: 0.23.0 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - picocolors: 1.0.1 - postcss-load-config: 6.0.1(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(yaml@2.7.0) - resolve-from: 5.0.0 - rollup: 4.20.0 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.3 - typescript: 5.8.3 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - tsup@8.3.0(jiti@2.4.0)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.6.3)(yaml@2.7.0): dependencies: bundle-require: 5.0.0(esbuild@0.23.1) cac: 6.7.14 chokidar: 3.6.0 consola: 3.2.3 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.3.7 esbuild: 0.23.1 execa: 5.1.1 joycon: 3.1.1 @@ -36754,7 +35086,7 @@ snapshots: rollup: 4.34.9 source-map: 0.8.0-beta.0 sucrase: 3.35.0 - tinyglobby: 0.2.10 + tinyglobby: 0.2.14 tree-kill: 1.2.2 optionalDependencies: postcss: 8.5.3 @@ -36771,7 +35103,7 @@ snapshots: cac: 6.7.14 chokidar: 3.6.0 consola: 3.2.3 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.3.7 esbuild: 0.23.1 execa: 5.1.1 joycon: 3.1.1 @@ -36781,7 +35113,7 @@ snapshots: rollup: 4.34.9 source-map: 0.8.0-beta.0 sucrase: 3.35.0 - tinyglobby: 0.2.10 + tinyglobby: 0.2.14 tree-kill: 1.2.2 optionalDependencies: postcss: 8.5.3 @@ -36802,7 +35134,7 @@ snapshots: tuf-js@3.1.0: dependencies: '@tufjs/models': 3.0.1 - debug: 4.4.1 + debug: 4.4.1(supports-color@9.4.0) make-fetch-happen: 14.0.3 transitivePeerDependencies: - supports-color @@ -36899,13 +35231,13 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3): + typescript-eslint@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) - '@typescript-eslint/parser': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) - '@typescript-eslint/utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3))(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) + '@typescript-eslint/parser': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.26.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.8.3) eslint: 9.21.0(jiti@2.4.0) - typescript: 5.6.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -36913,8 +35245,6 @@ snapshots: typescript@5.4.5: {} - typescript@5.5.4: {} - typescript@5.6.3: {} typescript@5.8.3: {} @@ -37020,7 +35350,7 @@ snapshots: pkg-types: 1.2.1 scule: 1.3.0 strip-literal: 2.1.1 - tinyglobby: 0.2.10 + tinyglobby: 0.2.14 unplugin: 1.16.0 transitivePeerDependencies: - rollup @@ -37156,18 +35486,6 @@ snapshots: pkg-types: 1.2.1 unplugin: 1.16.0 - update-browserslist-db@1.0.16(browserslist@4.22.1): - dependencies: - browserslist: 4.22.1 - escalade: 3.2.0 - picocolors: 1.1.1 - - update-browserslist-db@1.0.16(browserslist@4.23.1): - dependencies: - browserslist: 4.23.1 - escalade: 3.2.0 - picocolors: 1.1.1 - update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 @@ -37213,9 +35531,9 @@ snapshots: urlpattern-polyfill@8.0.2: {} - use-sync-external-store@1.2.0(react@18.3.1): + use-sync-external-store@1.2.0(react@19.0.0-rc.1): dependencies: - react: 18.3.1 + react: 19.0.0-rc.1 utif@2.0.1: dependencies: @@ -37237,10 +35555,6 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - valibot@1.0.0-rc.0(typescript@5.8.3): - optionalDependencies: - typescript: 5.8.3 - valibot@1.1.0(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 @@ -37271,7 +35585,7 @@ snapshots: vite-node@2.1.4(@types/node@20.17.24)(less@4.2.2)(sass@1.85.0)(terser@5.39.0): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) pathe: 1.1.2 vite: 5.4.11(@types/node@20.17.24)(less@4.2.2)(sass@1.85.0)(terser@5.39.0) transitivePeerDependencies: @@ -37288,7 +35602,7 @@ snapshots: vite-node@2.1.4(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) pathe: 1.1.2 vite: 5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0) transitivePeerDependencies: @@ -37305,10 +35619,10 @@ snapshots: vite-node@3.0.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -37330,7 +35644,7 @@ snapshots: chalk: 4.1.2 chokidar: 3.6.0 commander: 8.3.0 - fast-glob: 3.3.2 + fast-glob: 3.3.3 fs-extra: 11.2.0 npm-run-path: 4.0.1 strip-ansi: 6.0.1 @@ -37349,7 +35663,7 @@ snapshots: dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.3(rollup@4.34.9) - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.1(supports-color@9.4.0) error-stack-parser-es: 0.1.5 fs-extra: 11.2.0 open: 10.1.0 @@ -37417,13 +35731,13 @@ snapshots: tsx: 4.19.2 yaml: 2.7.0 - vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): + vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: - esbuild: 0.24.2 + esbuild: 0.25.4 postcss: 8.5.3 rollup: 4.34.9 optionalDependencies: - '@types/node': 22.7.4 + '@types/node': 20.17.24 fsevents: 2.3.3 jiti: 2.4.0 less: 4.2.2 @@ -37432,13 +35746,13 @@ snapshots: tsx: 4.19.2 yaml: 2.7.0 - vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): + vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: esbuild: 0.25.4 postcss: 8.5.3 rollup: 4.34.9 optionalDependencies: - '@types/node': 20.17.24 + '@types/node': 22.7.4 fsevents: 2.3.3 jiti: 2.4.0 less: 4.2.2 @@ -37447,13 +35761,13 @@ snapshots: tsx: 4.19.2 yaml: 2.7.0 - vitefu@1.0.6(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): + vitefu@1.0.6(vite@6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): optionalDependencies: - vite: 6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vitefu@1.0.6(vite@6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): + vitefu@1.0.6(vite@6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): optionalDependencies: - vite: 6.0.3(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.7.4)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vitest@2.1.4(@edge-runtime/vm@5.0.0)(@types/node@20.17.24)(jsdom@24.0.0)(less@4.2.2)(msw@2.6.4(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0): dependencies: @@ -37495,7 +35809,7 @@ snapshots: vitest@2.1.4(@edge-runtime/vm@5.0.0)(@types/node@20.17.24)(jsdom@26.0.0)(less@4.2.2)(msw@2.6.4(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0): dependencies: '@vitest/expect': 2.1.4 - '@vitest/mocker': 2.1.4(msw@2.6.4(@types/node@20.17.24)(typescript@5.8.3))(vite@5.4.11(@types/node@20.17.24)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)) + '@vitest/mocker': 2.1.4(msw@2.6.4(@types/node@20.17.24)(typescript@5.8.3))(vite@5.4.11(@types/node@22.7.4)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)) '@vitest/pretty-format': 2.1.4 '@vitest/runner': 2.1.4 '@vitest/snapshot': 2.1.4 @@ -37576,7 +35890,7 @@ snapshots: '@vitest/spy': 3.0.7 '@vitest/utils': 3.0.7 chai: 5.2.0 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.0 expect-type: 1.1.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -37607,17 +35921,17 @@ snapshots: - tsx - yaml - vitest@3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): + vitest@3.0.7(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@20.17.24)(jiti@2.4.0)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: '@vitest/expect': 3.0.7 - '@vitest/mocker': 3.0.7(msw@2.7.0(@types/node@20.17.24)(typescript@5.6.3))(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + '@vitest/mocker': 3.0.7(msw@2.7.0(@types/node@20.17.24)(typescript@5.8.3))(vite@6.0.3(@types/node@20.17.24)(jiti@2.4.0)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@vitest/pretty-format': 3.0.7 '@vitest/runner': 3.0.7 '@vitest/snapshot': 3.0.7 '@vitest/spy': 3.0.7 '@vitest/utils': 3.0.7 chai: 5.2.0 - debug: 4.4.0(supports-color@9.4.0) + debug: 4.4.0 expect-type: 1.1.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -37653,7 +35967,7 @@ snapshots: vscode-languageclient@7.0.0: dependencies: minimatch: 3.1.2 - semver: 7.7.1 + semver: 7.7.2 vscode-languageserver-protocol: 3.16.0 vscode-languageserver-protocol@3.16.0: @@ -37684,16 +35998,6 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.13(typescript@5.8.3) - vue@3.3.8(typescript@5.8.3): - dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-sfc': 3.3.8 - '@vue/runtime-dom': 3.3.8 - '@vue/server-renderer': 3.3.8(vue@3.3.8(typescript@5.8.3)) - '@vue/shared': 3.3.8 - optionalDependencies: - typescript: 5.8.3 - vue@3.5.13(typescript@5.8.3): dependencies: '@vue/compiler-dom': 3.5.13 @@ -37836,6 +36140,36 @@ snapshots: - esbuild - uglify-js + webpack@5.98.0: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.1 + browserslist: 4.25.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.17.1 + es-module-lexer: 1.6.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.2 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.14(webpack@5.98.0) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + webpack@5.98.0(esbuild@0.25.4): dependencies: '@types/eslint-scope': 3.7.7 @@ -38040,8 +36374,6 @@ snapshots: yaml@2.4.2: {} - yaml@2.4.5: {} - yaml@2.5.0: {} yaml@2.7.0: {} diff --git a/tsconfig.json b/tsconfig.json index 4d6270b0bb4d..6d524fe2f329 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -37,6 +37,7 @@ { "path": "packages/revai" }, { "path": "packages/rsc" }, { "path": "packages/svelte" }, + { "path": "packages/test-server" }, { "path": "packages/togetherai" }, { "path": "packages/valibot" }, { "path": "packages/vercel" }, From 3f464f411836f557862f598c553764dee993a62a Mon Sep 17 00:00:00 2001 From: Andrei Dorobantu Date: Thu, 18 Sep 2025 22:15:14 +0300 Subject: [PATCH 068/121] fix(provider/groq): track cached tokens usage (#8723) ## Background Groq now supports prompt caching for kimi-k2, we were not tracking this in `usage`. https://console.groq.com/docs/prompt-caching#tracking-cache-usage ## Summary Added the correct response format handling for usage. ## Manual Verification @gr2m verified with example provided by @andrewdoro ## Tasks - [X] Tests have been added / updated (for bug fixes / features) - [X] Documentation has been added / updated (for bug fixes / features) - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) ## Related Issues fixes #8722 --- .changeset/wise-jobs-knock.md | 5 +++ .../groq/src/groq-chat-language-model.test.ts | 41 +++++++++++++++++++ packages/groq/src/groq-chat-language-model.ts | 16 ++++++++ 3 files changed, 62 insertions(+) create mode 100644 .changeset/wise-jobs-knock.md diff --git a/.changeset/wise-jobs-knock.md b/.changeset/wise-jobs-knock.md new file mode 100644 index 000000000000..9d5a69106f25 --- /dev/null +++ b/.changeset/wise-jobs-knock.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/groq': patch +--- + +fix(provider/groq): track cached tokens usage diff --git a/packages/groq/src/groq-chat-language-model.test.ts b/packages/groq/src/groq-chat-language-model.test.ts index 0e977a9c99b6..16d9892f6594 100644 --- a/packages/groq/src/groq-chat-language-model.test.ts +++ b/packages/groq/src/groq-chat-language-model.test.ts @@ -53,6 +53,9 @@ describe('doGenerate', () => { prompt_tokens?: number; total_tokens?: number; completion_tokens?: number; + prompt_tokens_details?: { + cached_tokens?: number; + }; }; finish_reason?: string; created?: number; @@ -134,6 +137,7 @@ describe('doGenerate', () => { expect(usage).toMatchInlineSnapshot(` { + "cachedInputTokens": undefined, "inputTokens": 20, "outputTokens": 5, "totalTokens": 25, @@ -173,12 +177,40 @@ describe('doGenerate', () => { expect(usage).toMatchInlineSnapshot(` { + "cachedInputTokens": undefined, "inputTokens": 20, "outputTokens": undefined, "totalTokens": 20, } `); }); + + it('should extract cached input tokens', async () => { + prepareJsonResponse({ + usage: { + prompt_tokens: 20, + total_tokens: 25, + completion_tokens: 5, + prompt_tokens_details: { + cached_tokens: 15, + }, + }, + }); + + const { usage } = await model.doGenerate({ + prompt: TEST_PROMPT, + }); + + expect(usage).toMatchInlineSnapshot(` + { + "cachedInputTokens": 15, + "inputTokens": 20, + "outputTokens": 5, + "totalTokens": 25, + } + `); + }); + it('should extract finish reason', async () => { prepareJsonResponse({ finish_reason: 'stop', @@ -812,6 +844,7 @@ describe('doStream', () => { "finishReason": "stop", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": 18, "outputTokens": 439, "totalTokens": 457, @@ -895,6 +928,7 @@ describe('doStream', () => { "finishReason": "stop", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": 18, "outputTokens": 439, "totalTokens": 457, @@ -1025,6 +1059,7 @@ describe('doStream', () => { "finishReason": "tool-calls", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": 18, "outputTokens": 439, "totalTokens": 457, @@ -1160,6 +1195,7 @@ describe('doStream', () => { "finishReason": "tool-calls", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": 18, "outputTokens": 439, "totalTokens": 457, @@ -1286,6 +1322,7 @@ describe('doStream', () => { "finishReason": "tool-calls", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": undefined, "outputTokens": undefined, "totalTokens": undefined, @@ -1365,6 +1402,7 @@ describe('doStream', () => { "finishReason": "tool-calls", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": 18, "outputTokens": 439, "totalTokens": 457, @@ -1405,6 +1443,7 @@ describe('doStream', () => { "finishReason": "error", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": undefined, "outputTokens": undefined, "totalTokens": undefined, @@ -1443,6 +1482,7 @@ describe('doStream', () => { "finishReason": "error", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": undefined, "outputTokens": undefined, "totalTokens": undefined, @@ -1643,6 +1683,7 @@ describe('doStream with raw chunks', () => { "finishReason": "stop", "type": "finish", "usage": { + "cachedInputTokens": undefined, "inputTokens": 10, "outputTokens": 5, "totalTokens": 15, diff --git a/packages/groq/src/groq-chat-language-model.ts b/packages/groq/src/groq-chat-language-model.ts index c3cd0fe73958..a6811c3aadcf 100644 --- a/packages/groq/src/groq-chat-language-model.ts +++ b/packages/groq/src/groq-chat-language-model.ts @@ -224,6 +224,8 @@ export class GroqChatLanguageModel implements LanguageModelV2 { inputTokens: response.usage?.prompt_tokens ?? undefined, outputTokens: response.usage?.completion_tokens ?? undefined, totalTokens: response.usage?.total_tokens ?? undefined, + cachedInputTokens: + response.usage?.prompt_tokens_details?.cached_tokens ?? undefined, }, response: { ...getResponseMetadata(response), @@ -274,6 +276,7 @@ export class GroqChatLanguageModel implements LanguageModelV2 { inputTokens: undefined, outputTokens: undefined, totalTokens: undefined, + cachedInputTokens: undefined, }; let isFirstChunk = true; let isActiveText = false; @@ -326,6 +329,9 @@ export class GroqChatLanguageModel implements LanguageModelV2 { usage.outputTokens = value.x_groq.usage.completion_tokens ?? undefined; usage.totalTokens = value.x_groq.usage.total_tokens ?? undefined; + usage.cachedInputTokens = + value.x_groq.usage.prompt_tokens_details?.cached_tokens ?? + undefined; } const choice = value.choices[0]; @@ -546,6 +552,11 @@ const groqChatResponseSchema = z.object({ prompt_tokens: z.number().nullish(), completion_tokens: z.number().nullish(), total_tokens: z.number().nullish(), + prompt_tokens_details: z + .object({ + cached_tokens: z.number().nullish(), + }) + .nullish(), }) .nullish(), }); @@ -589,6 +600,11 @@ const groqChatChunkSchema = z.union([ prompt_tokens: z.number().nullish(), completion_tokens: z.number().nullish(), total_tokens: z.number().nullish(), + prompt_tokens_details: z + .object({ + cached_tokens: z.number().nullish(), + }) + .nullish(), }) .nullish(), }) From cbb1d35ee59327c35034166dac7f612a4d3a99d9 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:48:24 -0400 Subject: [PATCH 069/121] fix(packages/provider-utils): Update for provider-util changeset (#8749) ## Background Forgot to patch for `provider-utils` package after making changes in PR #8588 ## Summary Added changeset ## Checklist - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) --- .changeset/old-kiwis-hide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/old-kiwis-hide.md diff --git a/.changeset/old-kiwis-hide.md b/.changeset/old-kiwis-hide.md new file mode 100644 index 000000000000..1a087e136ae1 --- /dev/null +++ b/.changeset/old-kiwis-hide.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/provider-utils': patch +--- + +Update for provider-util changeset after change in PR #8588 From c1ba88bf360d37829f91c8408a440c7e3a7c48bd Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 20:57:47 +0000 Subject: [PATCH 070/121] Version Packages (beta) (#8744) # Releases ## @ai-sdk/test-server@1.0.0-beta.0 ### Major Changes - 953d0f2: feat(packages/test-server): Add `test-server` as a package ## ai@5.1.0-beta.2 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/gateway@1.1.0-beta.1 ## @ai-sdk/amazon-bedrock@3.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/anthropic@2.1.0-beta.1 ## @ai-sdk/angular@1.1.0-beta.2 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - ai@5.1.0-beta.2 ## @ai-sdk/anthropic@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/assemblyai@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/azure@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai@2.1.0-beta.1 ## @ai-sdk/baseten@1.0.0-beta.1 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/cerebras@1.1.0-beta.1 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/cohere@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/deepgram@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/deepinfra@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/deepseek@1.1.0-beta.1 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/elevenlabs@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/fal@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/fireworks@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/gateway@1.1.0-beta.1 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/gladia@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/google@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/google-vertex@3.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/anthropic@2.1.0-beta.1 - @ai-sdk/google@2.1.0-beta.1 ## @ai-sdk/groq@2.1.0-beta.1 ### Patch Changes - 3f464f4: fix(provider/groq): track cached tokens usage - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/hume@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/langchain@1.1.0-beta.2 ### Patch Changes - ai@5.1.0-beta.2 ## @ai-sdk/llamaindex@1.1.0-beta.2 ### Patch Changes - ai@5.1.0-beta.2 ## @ai-sdk/lmnt@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/luma@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/mistral@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/openai@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/openai-compatible@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/perplexity@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/provider-utils@3.1.0-beta.1 ### Patch Changes - cbb1d35: Update for provider-util changeset after change in PR #8588 ## @ai-sdk/react@2.1.0-beta.2 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - ai@5.1.0-beta.2 ## @ai-sdk/replicate@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/revai@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/rsc@1.1.0-beta.2 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 - ai@5.1.0-beta.2 ## @ai-sdk/svelte@3.1.0-beta.2 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - ai@5.1.0-beta.2 ## @ai-sdk/togetherai@1.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/valibot@1.1.0-beta.1 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 ## @ai-sdk/vercel@1.1.0-beta.1 ### Patch Changes - Updated dependencies [cbb1d35] - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 ## @ai-sdk/vue@2.1.0-beta.2 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - ai@5.1.0-beta.2 ## @ai-sdk/xai@2.1.0-beta.1 ### Patch Changes - Updated dependencies [953d0f2] - Updated dependencies [cbb1d35] - @ai-sdk/test-server@1.0.0-beta.0 - @ai-sdk/provider-utils@3.1.0-beta.1 - @ai-sdk/openai-compatible@1.1.0-beta.1 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 8 +- packages/ai/CHANGELOG.md | 10 ++ packages/ai/package.json | 2 +- packages/amazon-bedrock/CHANGELOG.md | 10 ++ packages/amazon-bedrock/package.json | 2 +- packages/angular/CHANGELOG.md | 10 ++ packages/angular/package.json | 2 +- packages/anthropic/CHANGELOG.md | 9 ++ packages/anthropic/package.json | 2 +- packages/assemblyai/CHANGELOG.md | 9 ++ packages/assemblyai/package.json | 2 +- packages/azure/CHANGELOG.md | 10 ++ packages/azure/package.json | 2 +- packages/baseten/CHANGELOG.md | 8 ++ packages/baseten/package.json | 2 +- packages/cerebras/CHANGELOG.md | 8 ++ packages/cerebras/package.json | 2 +- packages/cohere/CHANGELOG.md | 9 ++ packages/cohere/package.json | 2 +- packages/deepgram/CHANGELOG.md | 9 ++ packages/deepgram/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 10 ++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 8 ++ packages/deepseek/package.json | 2 +- packages/elevenlabs/CHANGELOG.md | 9 ++ packages/elevenlabs/package.json | 2 +- packages/fal/CHANGELOG.md | 9 ++ packages/fal/package.json | 2 +- packages/fireworks/CHANGELOG.md | 10 ++ packages/fireworks/package.json | 2 +- packages/gateway/CHANGELOG.md | 7 + packages/gateway/package.json | 2 +- packages/gladia/CHANGELOG.md | 9 ++ packages/gladia/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 11 ++ packages/google-vertex/package.json | 2 +- packages/google/CHANGELOG.md | 9 ++ packages/google/package.json | 2 +- packages/groq/CHANGELOG.md | 10 ++ packages/groq/package.json | 2 +- packages/hume/CHANGELOG.md | 9 ++ packages/hume/package.json | 2 +- packages/langchain/CHANGELOG.md | 6 + packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 6 + packages/llamaindex/package.json | 2 +- packages/lmnt/CHANGELOG.md | 9 ++ packages/lmnt/package.json | 2 +- packages/luma/CHANGELOG.md | 9 ++ packages/luma/package.json | 2 +- packages/mistral/CHANGELOG.md | 9 ++ packages/mistral/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 9 ++ packages/openai-compatible/package.json | 2 +- packages/openai/CHANGELOG.md | 9 ++ packages/openai/package.json | 2 +- packages/perplexity/CHANGELOG.md | 9 ++ packages/perplexity/package.json | 2 +- packages/provider-utils/CHANGELOG.md | 6 + packages/provider-utils/package.json | 2 +- packages/react/CHANGELOG.md | 10 ++ packages/react/package.json | 2 +- packages/replicate/CHANGELOG.md | 9 ++ packages/replicate/package.json | 2 +- packages/revai/CHANGELOG.md | 9 ++ packages/revai/package.json | 2 +- packages/rsc/CHANGELOG.md | 8 ++ packages/rsc/package.json | 2 +- .../rsc/tests/e2e/next-server/CHANGELOG.md | 6 + packages/svelte/CHANGELOG.md | 10 ++ packages/svelte/package.json | 2 +- packages/test-server/CHANGELOG.md | 7 + packages/test-server/package.json | 130 +++++++++--------- packages/togetherai/CHANGELOG.md | 10 ++ packages/togetherai/package.json | 2 +- packages/valibot/CHANGELOG.md | 7 + packages/valibot/package.json | 2 +- packages/vercel/CHANGELOG.md | 8 ++ packages/vercel/package.json | 2 +- packages/vue/CHANGELOG.md | 10 ++ packages/vue/package.json | 2 +- packages/xai/CHANGELOG.md | 10 ++ packages/xai/package.json | 2 +- 84 files changed, 479 insertions(+), 108 deletions(-) create mode 100644 packages/test-server/CHANGELOG.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 41baef068397..094eb8f868f3 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -69,11 +69,15 @@ "eslint-config-vercel-ai": "0.0.0", "generate-llms-txt": "0.0.0", "@vercel/ai-tsconfig": "0.0.0", - "@ai-sdk/baseten": "0.0.0" + "@ai-sdk/baseten": "0.0.0", + "@ai-sdk/test-server": "0.0.0" }, "changesets": [ "curly-glasses-count", + "four-candles-buy", + "old-kiwis-hide", "quiet-pens-suffer", - "red-roses-glow" + "red-roses-glow", + "wise-jobs-knock" ] } diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 0259dad2d39f..1884be505055 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,15 @@ # ai +## 5.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/gateway@1.1.0-beta.1 + ## 5.1.0-beta.1 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index f249d4105362..b031b7e30016 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.1", + "version": "5.1.0-beta.2", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index b7ee1a67b6e3..6c5df2b0b2ec 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/amazon-bedrock +## 3.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/anthropic@2.1.0-beta.1 + ## 3.1.0-beta.0 ### Minor Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 469ab6b2e8a1..8e142fdc8123 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.1.0-beta.0", + "version": "3.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 98f22adcc5d6..16a9e50f7e2e 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/angular +## 1.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - ai@5.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 8cb062be29e2..040b11622bb9 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 9b5064fc2626..6bd27e527a6b 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/anthropic +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 85c2a6b4b2e1..24c4feb216bb 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/assemblyai/CHANGELOG.md b/packages/assemblyai/CHANGELOG.md index d0c4bc2a4a2e..5d3c81b6180e 100644 --- a/packages/assemblyai/CHANGELOG.md +++ b/packages/assemblyai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/assemblyai +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index 1c0d4fd41965..b5383ead2a51 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/assemblyai", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index d8884226f045..e12569a40921 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/azure +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai@2.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 50baa174459d..835084f421e1 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/baseten/CHANGELOG.md b/packages/baseten/CHANGELOG.md index 09e1e8f9aaa1..09ce605f44a1 100644 --- a/packages/baseten/CHANGELOG.md +++ b/packages/baseten/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/baseten +## 1.0.0-beta.1 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.0.0-beta.0 ### Major Changes diff --git a/packages/baseten/package.json b/packages/baseten/package.json index 6d67bb5771df..5a39dda5e571 100644 --- a/packages/baseten/package.json +++ b/packages/baseten/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/baseten", - "version": "1.0.0-beta.0", + "version": "1.0.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 96dcffdc481b..3e833f257817 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/cerebras +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index 1acd5442ed9e..ea69d741ee75 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index 04c9ddab18f3..245aa4945e31 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/cohere +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index c777d02dcea6..68e70e1aadad 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepgram/CHANGELOG.md b/packages/deepgram/CHANGELOG.md index 98b8a43f00d5..cbb4a21e8197 100644 --- a/packages/deepgram/CHANGELOG.md +++ b/packages/deepgram/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/deepgram +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index 19641c5dfccb..19e250457c5f 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepgram", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index 9375e8505237..e5e9317a4e3a 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/deepinfra +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 3f22a41891f5..313d62eb8d51 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 4538703c60a3..7cb426f56a78 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/deepseek +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index 00073f350d54..531d57ec0d3a 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/elevenlabs/CHANGELOG.md b/packages/elevenlabs/CHANGELOG.md index f76ffaccd158..ed59b7f63f70 100644 --- a/packages/elevenlabs/CHANGELOG.md +++ b/packages/elevenlabs/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/elevenlabs +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/elevenlabs/package.json b/packages/elevenlabs/package.json index ff1d1f4bf570..efeb3ef9d606 100644 --- a/packages/elevenlabs/package.json +++ b/packages/elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/elevenlabs", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index 765418c49d5d..87147f8f6f36 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/fal +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index f55bfa2b90cf..f35b23082db5 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 59b6151ae22c..9550242cc748 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/fireworks +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index da6725697e33..af2ce2c84604 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index dad882cc9a1f..022a4eb43a36 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/gateway +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index d4c016284b0a..6c8e4bd90798 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gladia/CHANGELOG.md b/packages/gladia/CHANGELOG.md index cd40c09f2dd0..a0098b9666ec 100644 --- a/packages/gladia/CHANGELOG.md +++ b/packages/gladia/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/gladia +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/gladia/package.json b/packages/gladia/package.json index 5fccb3632a9b..0e448c4fcacc 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/gladia", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "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 00e21f68a7ad..0319459d108f 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/google-vertex +## 3.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/anthropic@2.1.0-beta.1 + - @ai-sdk/google@2.1.0-beta.1 + ## 3.1.0-beta.0 ### Minor Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 94c5a1b0f79f..4446d3acca83 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.1.0-beta.0", + "version": "3.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index b71b8e64f32f..473c9229aa40 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/google +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/google/package.json b/packages/google/package.json index d14c942791c5..545d31daf820 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index eac486ff3896..c93b5d400b0e 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/groq +## 2.1.0-beta.1 + +### Patch Changes + +- 3f464f4: fix(provider/groq): track cached tokens usage +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index 5251922da3b3..e6857e8c7590 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/hume/CHANGELOG.md b/packages/hume/CHANGELOG.md index a79a5053efe0..b82bab3ac426 100644 --- a/packages/hume/CHANGELOG.md +++ b/packages/hume/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/hume +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/hume/package.json b/packages/hume/package.json index 8f0cf578cdda..006be55ab731 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/hume", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 6301bd48d36a..054c6a59a51d 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/langchain +## 1.1.0-beta.2 + +### Patch Changes + +- ai@5.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index fae5b643d9c9..bac145e701fd 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 0afd3a79fa95..5d9dd808d5cb 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.2 + +### Patch Changes + +- ai@5.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 8f08ed84ecfc..c466f6f3500b 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/lmnt/CHANGELOG.md b/packages/lmnt/CHANGELOG.md index d0c6301ac0e2..7dd1a5d8eb81 100644 --- a/packages/lmnt/CHANGELOG.md +++ b/packages/lmnt/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/lmnt +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index eb47c744ff71..d33e1088fb56 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/lmnt", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index 52539b2afc2a..acb4abd7ff69 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/luma +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index 1019d5fffcdb..a68ae065777d 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index de1ebacdb928..0a1025187431 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/mistral +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 083453670115..457c0ff0d6ab 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index d39a178681f5..78b8b3584393 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/openai-compatible +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index 1200e6b534ac..0e18fbd9f205 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 6b99dadc070f..6c2c1eaa213d 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/openai +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index 83f230f02589..bc7c783ee338 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index ac0b927b8b1e..b6dde2ee18a9 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/perplexity +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index f78f649c2f3e..97d43cfad858 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index b8ae8c3d8cc4..3224bd90c878 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider-utils +## 3.1.0-beta.1 + +### Patch Changes + +- cbb1d35: Update for provider-util changeset after change in PR #8588 + ## 3.1.0-beta.0 ### Minor Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index 3181451601f4..8f455af820df 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "3.1.0-beta.0", + "version": "3.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 309ba0d2d294..6f38ac6d10d0 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/react +## 2.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - ai@5.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index e9e43bb0b5be..ce30ecc9289b 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index 4b87e403f286..4e35169b6fbb 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/replicate +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index eb0460aca839..70327f3bfa6a 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/revai/CHANGELOG.md b/packages/revai/CHANGELOG.md index ac0216930e60..3af64bb4c724 100644 --- a/packages/revai/CHANGELOG.md +++ b/packages/revai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/revai +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/revai/package.json b/packages/revai/package.json index ecfddd619f70..36e004aeaf31 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/revai", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index b9bcb1ac2532..09252d755b8d 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/rsc +## 1.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + - ai@5.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 1aeb62c1ca83..f4812ca7d7cd 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index e564481d49df..f36fcdd3bc55 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,12 @@ ### Patch Changes +- ai@5.1.0-beta.2 + +## 0.0.1-beta.0 + +### Patch Changes + - Updated dependencies [a7f6f81] - ai@5.1.0-beta.1 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index d783612e77e5..2fc36e48e561 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/svelte +## 3.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - ai@5.1.0-beta.2 + ## 3.1.0-beta.1 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index d27ef66d8ad9..e5c0f0341b3b 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.1", + "version": "3.1.0-beta.2", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/test-server/CHANGELOG.md b/packages/test-server/CHANGELOG.md new file mode 100644 index 000000000000..8b9c55560f9a --- /dev/null +++ b/packages/test-server/CHANGELOG.md @@ -0,0 +1,7 @@ +# @ai-sdk/test-server + +## 1.0.0-beta.0 + +### Major Changes + +- 953d0f2: feat(packages/test-server): Add `test-server` as a package diff --git a/packages/test-server/package.json b/packages/test-server/package.json index 8346874ac3d8..c8c259ee562a 100644 --- a/packages/test-server/package.json +++ b/packages/test-server/package.json @@ -1,68 +1,66 @@ { - "name": "@ai-sdk/test-server", - "version": "0.0.0", - "license": "Apache-2.0", - "sideEffects": false, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "files": [ - "dist/**/*", - "CHANGELOG.md" - ], - "scripts": { - "build": "pnpm clean && tsup --tsconfig tsconfig.build.json", - "build:watch": "pnpm clean && tsup --watch", - "clean": "rm -rf dist *.tsbuildinfo", - "lint": "eslint \"./**/*.ts*\"", - "type-check": "tsc --build", - "prettier-check": "prettier --check \"./**/*.ts*\"", - "test": "pnpm test:node && pnpm test:edge", - "test:update": "pnpm test:node -u", - "test:watch": "vitest --config vitest.node.config.js", - "test:edge": "vitest --config vitest.edge.config.js --run", - "test:node": "vitest --config vitest.node.config.js --run" + "name": "@ai-sdk/test-server", + "version": "1.0.0-beta.0", + "license": "Apache-2.0", + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist/**/*", + "CHANGELOG.md" + ], + "scripts": { + "build": "pnpm clean && tsup --tsconfig tsconfig.build.json", + "build:watch": "pnpm clean && tsup --watch", + "clean": "rm -rf dist *.tsbuildinfo", + "lint": "eslint \"./**/*.ts*\"", + "type-check": "tsc --build", + "prettier-check": "prettier --check \"./**/*.ts*\"", + "test": "pnpm test:node && pnpm test:edge", + "test:update": "pnpm test:node -u", + "test:watch": "vitest --config vitest.node.config.js", + "test:edge": "vitest --config vitest.edge.config.js --run", + "test:node": "vitest --config vitest.node.config.js --run" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" }, - "exports": { - "./package.json": "./package.json", - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.js" - }, - "./with-vitest": { - "types": "./dist/with-vitest.d.ts", - "import": "./dist/with-vitest.mjs", - "module": "./dist/with-vitest.mjs", - "require": "./dist/with-vitest.js" - } - }, - "devDependencies": { - "@types/node": "20.17.24", - "@vercel/ai-tsconfig": "workspace:*", - "tsup": "^8", - "msw": "^2.7.0", - "typescript": "5.8.3" - }, - "engines": { - "node": ">=18" - }, - "publishConfig": { - "access": "public" - }, - "homepage": "https://ai-sdk.dev/docs", - "repository": { - "type": "git", - "url": "git+https://github.com/vercel/ai.git" - }, - "bugs": { - "url": "https://github.com/vercel/ai/issues" - }, - "keywords": [ - "ai", - "test-server", - "msw" - ] - } - - \ No newline at end of file + "./with-vitest": { + "types": "./dist/with-vitest.d.ts", + "import": "./dist/with-vitest.mjs", + "module": "./dist/with-vitest.mjs", + "require": "./dist/with-vitest.js" + } + }, + "devDependencies": { + "@types/node": "20.17.24", + "@vercel/ai-tsconfig": "workspace:*", + "tsup": "^8", + "msw": "^2.7.0", + "typescript": "5.8.3" + }, + "engines": { + "node": ">=18" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://ai-sdk.dev/docs", + "repository": { + "type": "git", + "url": "git+https://github.com/vercel/ai.git" + }, + "bugs": { + "url": "https://github.com/vercel/ai/issues" + }, + "keywords": [ + "ai", + "test-server", + "msw" + ] +} \ No newline at end of file diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index 511a9a3ff34e..fac8686a8280 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/togetherai +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index be1ca9d152ce..b9b187f129ed 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 57628c06ed5d..626cd8d37c1d 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/valibot +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index ff781fdc544a..b2852c95d3c4 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index 779b2b7e4e3a..cafbc0c38a46 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/vercel +## 1.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [cbb1d35] + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 1.1.0-beta.0 ### Minor Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index c816b7dfe03b..28e103b8a02c 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 65a7b2b756c8..90983e400e35 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/vue +## 2.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - ai@5.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 34a7f1394439..b322d510c7f1 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 1459a34c7cac..67357c043849 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/xai +## 2.1.0-beta.1 + +### Patch Changes + +- Updated dependencies [953d0f2] +- Updated dependencies [cbb1d35] + - @ai-sdk/test-server@1.0.0-beta.0 + - @ai-sdk/provider-utils@3.1.0-beta.1 + - @ai-sdk/openai-compatible@1.1.0-beta.1 + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 61cd28c1f177..47f7b4df3f6d 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 3e836338690fc2eb465e8823353b433006f18d20 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 18 Sep 2025 15:50:16 -0700 Subject: [PATCH 071/121] Add get credits method gateway provider (#8750) --- .changeset/neat-news-visit.md | 5 + .../01-ai-sdk-providers/00-ai-gateway.mdx | 18 ++ .../src/gateway-fetch-metadata.test.ts | 267 ++++++++++++++++++ .../gateway/src/gateway-fetch-metadata.ts | 33 +++ packages/gateway/src/gateway-provider.test.ts | 104 ++++++- packages/gateway/src/gateway-provider.ts | 19 ++ packages/gateway/src/index.ts | 1 + 7 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 .changeset/neat-news-visit.md diff --git a/.changeset/neat-news-visit.md b/.changeset/neat-news-visit.md new file mode 100644 index 000000000000..e0a83307895a --- /dev/null +++ b/.changeset/neat-news-visit.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +add getCredits() gateway method diff --git a/content/providers/01-ai-sdk-providers/00-ai-gateway.mdx b/content/providers/01-ai-sdk-providers/00-ai-gateway.mdx index 56e7b13b3edf..2b568426b87b 100644 --- a/content/providers/01-ai-sdk-providers/00-ai-gateway.mdx +++ b/content/providers/01-ai-sdk-providers/00-ai-gateway.mdx @@ -207,6 +207,24 @@ const { text } = await generateText({ }); ``` +## Credit Usage + +You can check your team's current credit balance and usage: + +```ts +import { gateway } from 'ai'; + +const credits = await gateway.getCredits(); + +console.log(`Team balance: ${credits.balance} credits`); +console.log(`Team total used: ${credits.total_used} credits`); +``` + +The `getCredits()` method returns your team's credit information based on the authenticated API key or OIDC token: + +- **balance** _number_ - Your team's current available credit balance +- **total_used** _number_ - Total credits consumed by your team + ## Examples ### Basic Text Generation diff --git a/packages/gateway/src/gateway-fetch-metadata.test.ts b/packages/gateway/src/gateway-fetch-metadata.test.ts index 4401ad93dd86..e90d96c1557c 100644 --- a/packages/gateway/src/gateway-fetch-metadata.test.ts +++ b/packages/gateway/src/gateway-fetch-metadata.test.ts @@ -504,4 +504,271 @@ describe('GatewayFetchMetadata', () => { }); }); }); + + describe('getCredits', () => { + it('should fetch credits from the correct endpoint', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'json-value', + body: { + balance: '150.50', + total_used: '75.25', + }, + }; + + const metadata = createBasicMetadataFetcher(); + const result = await metadata.getCredits(); + + expect(result).toEqual({ + balance: '150.50', + total_used: '75.25', + }); + }); + + it('should pass headers correctly to credits endpoint', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'json-value', + body: { + balance: '100.00', + total_used: '50.00', + }, + }; + + const metadata = createBasicMetadataFetcher({ + headers: () => ({ + Authorization: 'Bearer custom-token', + 'Custom-Header': 'custom-value', + }), + }); + + const result = await metadata.getCredits(); + + expect(server.calls[0].requestHeaders).toEqual({ + authorization: 'Bearer custom-token', + 'custom-header': 'custom-value', + }); + expect(result).toEqual({ + balance: '100.00', + total_used: '50.00', + }); + }); + + it('should handle API errors for credits endpoint', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'error', + status: 401, + body: JSON.stringify({ + error: { + type: 'authentication_error', + message: 'Invalid API key', + }, + }), + }; + + const metadata = createBasicMetadataFetcher(); + + await expect(metadata.getCredits()).rejects.toThrow( + GatewayAuthenticationError, + ); + }); + + it('should handle rate limit errors for credits endpoint', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'error', + status: 429, + body: JSON.stringify({ + error: { + type: 'rate_limit_exceeded', + message: 'Rate limit exceeded', + }, + }), + }; + + const metadata = createBasicMetadataFetcher(); + + await expect(metadata.getCredits()).rejects.toThrow( + GatewayRateLimitError, + ); + }); + + it('should handle internal server errors for credits endpoint', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'error', + status: 500, + body: JSON.stringify({ + error: { + type: 'internal_server_error', + message: 'Database unavailable', + }, + }), + }; + + const metadata = createBasicMetadataFetcher(); + + await expect(metadata.getCredits()).rejects.toThrow( + GatewayInternalServerError, + ); + }); + + it('should handle malformed credits response', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'json-value', + body: { + balance: 'not-a-number', + total_used: '75.25', + }, + }; + + const metadata = createBasicMetadataFetcher(); + const result = await metadata.getCredits(); + + expect(result).toEqual({ + balance: 'not-a-number', + total_used: '75.25', + }); + }); + + it('should use custom fetch function when provided', async () => { + const customFetch = vi.fn().mockResolvedValue( + new Response( + JSON.stringify({ + balance: '200.00', + total_used: '100.50', + }), + { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + }, + ), + ); + + const metadata = createBasicMetadataFetcher({ + fetch: customFetch as unknown as FetchFunction, + }); + + const result = await metadata.getCredits(); + + expect(result).toEqual({ + balance: '200.00', + total_used: '100.50', + }); + + expect(customFetch).toHaveBeenCalledWith( + 'https://api.example.com/v1/credits', + expect.objectContaining({ + method: 'GET', + headers: expect.objectContaining({ + authorization: 'Bearer test-token', + }), + }), + ); + }); + + it('should convert API call errors to Gateway errors', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'error', + status: 403, + body: JSON.stringify({ + error: { + message: 'Forbidden access', + type: 'authentication_error', + }, + }), + }; + + const metadata = createBasicMetadataFetcher(); + + try { + await metadata.getCredits(); + expect.fail('Should have thrown an error'); + } catch (error) { + expect(GatewayAuthenticationError.isInstance(error)).toBe(true); + const authError = error as GatewayAuthenticationError; + expect(authError.message).toContain('No authentication provided'); + expect(authError.type).toBe('authentication_error'); + expect(authError.statusCode).toBe(403); + } + }); + + it('should handle malformed JSON error responses', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'error', + status: 500, + body: '{ invalid json', + }; + + const metadata = createBasicMetadataFetcher(); + + try { + await metadata.getCredits(); + expect.fail('Should have thrown an error'); + } catch (error) { + expect(GatewayResponseError.isInstance(error)).toBe(true); + const responseError = error as GatewayResponseError; + expect(responseError.statusCode).toBe(500); + expect(responseError.type).toBe('response_error'); + } + }); + + it('should not double-wrap existing Gateway errors', async () => { + const existingError = new GatewayAuthenticationError({ + message: 'Already wrapped', + statusCode: 401, + }); + + try { + throw existingError; + } catch (error: unknown) { + if (GatewayError.isInstance(error)) { + expect(error).toBe(existingError); + expect(error.message).toBe('Already wrapped'); + return; + } + throw new Error('Should not reach here'); + } + }); + + it('should preserve error cause chain', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'error', + status: 401, + body: JSON.stringify({ + error: { + message: 'Token expired', + type: 'authentication_error', + }, + }), + }; + + const metadata = createBasicMetadataFetcher(); + + try { + await metadata.getCredits(); + expect.fail('Should have thrown an error'); + } catch (error) { + expect(GatewayAuthenticationError.isInstance(error)).toBe(true); + const authError = error as GatewayAuthenticationError; + expect(authError.cause).toBeDefined(); + } + }); + + it('should handle empty response', async () => { + server.urls['https://api.example.com/*'].response = { + type: 'json-value', + body: { + balance: '0.00', + total_used: '0.00', + }, + }; + + const metadata = createBasicMetadataFetcher(); + const result = await metadata.getCredits(); + + expect(result).toEqual({ + balance: '0.00', + total_used: '0.00', + }); + }); + }); }); diff --git a/packages/gateway/src/gateway-fetch-metadata.ts b/packages/gateway/src/gateway-fetch-metadata.ts index 9b67a70cd581..a57044a8b1ce 100644 --- a/packages/gateway/src/gateway-fetch-metadata.ts +++ b/packages/gateway/src/gateway-fetch-metadata.ts @@ -15,6 +15,11 @@ export interface GatewayFetchMetadataResponse { models: GatewayLanguageModelEntry[]; } +export interface GatewayCreditsResponse { + balance: string; + total_used: string; +} + export class GatewayFetchMetadata { constructor(private readonly config: GatewayFetchMetadataConfig) {} @@ -38,6 +43,29 @@ export class GatewayFetchMetadata { throw asGatewayError(error); } } + + async getCredits(): Promise { + try { + const baseUrl = new URL(this.config.baseURL); + const creditsUrl = `${baseUrl.origin}/v1/credits`; + + const { value } = await getFromApi({ + url: creditsUrl, + headers: await resolve(this.config.headers()), + successfulResponseHandler: + createJsonResponseHandler(gatewayCreditsSchema), + failedResponseHandler: createJsonErrorResponseHandler({ + errorSchema: z.any(), + errorToMessage: data => data, + }), + fetch: this.config.fetch, + }); + + return value; + } catch (error) { + throw asGatewayError(error); + } + } } const gatewayLanguageModelSpecificationSchema = z.object({ @@ -74,3 +102,8 @@ const gatewayLanguageModelEntrySchema = z.object({ const gatewayFetchMetadataSchema = z.object({ models: z.array(gatewayLanguageModelEntrySchema), }); + +const gatewayCreditsSchema = z.object({ + balance: z.string(), + total_used: z.string(), +}); diff --git a/packages/gateway/src/gateway-provider.test.ts b/packages/gateway/src/gateway-provider.test.ts index 5faa4b6c0c64..8090c526eeae 100644 --- a/packages/gateway/src/gateway-provider.test.ts +++ b/packages/gateway/src/gateway-provider.test.ts @@ -23,6 +23,7 @@ vi.mock('./gateway-language-model', () => ({ // Mock the gateway fetch metadata to prevent actual network calls // We'll create a more flexible mock that can simulate auth failures const mockGetAvailableModels = vi.fn(); +const mockGetCredits = vi.fn(); vi.mock('./gateway-fetch-metadata', () => ({ GatewayFetchMetadata: vi.fn().mockImplementation((config: any) => ({ getAvailableModels: async () => { @@ -32,6 +33,13 @@ vi.mock('./gateway-fetch-metadata', () => ({ } return mockGetAvailableModels(); }, + getCredits: async () => { + // Call the headers function to trigger authentication logic + if (config.headers && typeof config.headers === 'function') { + await config.headers(); + } + return mockGetCredits(); + }, })), })); @@ -45,8 +53,9 @@ describe('GatewayProvider', () => { vi.clearAllMocks(); vi.mocked(getVercelOidcToken).mockResolvedValue('mock-oidc-token'); vi.mocked(getVercelRequestId).mockResolvedValue('mock-request-id'); - // Set up default mock behavior for getAvailableModels + // Set up default mock behavior for getAvailableModels and getCredits mockGetAvailableModels.mockReturnValue({ models: [] }); + mockGetCredits.mockReturnValue({ balance: '100.00', total_used: '50.00' }); if ('AI_GATEWAY_API_KEY' in process.env) { Reflect.deleteProperty(process.env, 'AI_GATEWAY_API_KEY'); } @@ -811,6 +820,99 @@ describe('GatewayProvider', () => { }); }); + describe('getCredits method', () => { + it('should fetch credits successfully', async () => { + const mockCredits = { balance: '150.50', total_used: '75.25' }; + mockGetCredits.mockReturnValue(mockCredits); + + const provider = createGatewayProvider({ + apiKey: 'test-key', + }); + + const credits = await provider.getCredits(); + + expect(credits).toEqual({ balance: '150.50', total_used: '75.25' }); + expect(GatewayFetchMetadata).toHaveBeenCalledWith( + expect.objectContaining({ + baseURL: 'https://ai-gateway.vercel.sh/v1/ai', + headers: expect.any(Function), + fetch: undefined, + }), + ); + }); + + it('should handle authentication errors in getCredits', async () => { + const provider = createGatewayProvider(); + + const result = await provider.getCredits(); + expect(result).toEqual({ balance: '100.00', total_used: '50.00' }); + }); + + it('should work with custom baseURL', async () => { + const customBaseURL = 'https://custom-gateway.example.com/v1/ai'; + const provider = createGatewayProvider({ + apiKey: 'test-key', + baseURL: customBaseURL, + }); + + await provider.getCredits(); + + expect(GatewayFetchMetadata).toHaveBeenCalledWith( + expect.objectContaining({ + baseURL: customBaseURL, + }), + ); + }); + + it('should work with OIDC authentication', async () => { + vi.mocked(getVercelOidcToken).mockResolvedValue('oidc-token'); + + const provider = createGatewayProvider(); + + const credits = await provider.getCredits(); + + expect(credits).toBeDefined(); + expect(getVercelOidcToken).toHaveBeenCalled(); + }); + + it('should handle errors from the credits endpoint', async () => { + const testError = new Error('Credits service unavailable'); + mockGetCredits.mockRejectedValue(testError); + + const provider = createGatewayProvider({ + apiKey: 'test-key', + }); + + await expect(provider.getCredits()).rejects.toThrow( + 'Credits service unavailable', + ); + }); + + it('should include proper headers for credits request', async () => { + const provider = createGatewayProvider({ + apiKey: 'test-key', + headers: { 'Custom-Header': 'custom-value' }, + }); + + await provider.getCredits(); + + const config = vi.mocked(GatewayFetchMetadata).mock.calls[0][0]; + const headers = await config.headers(); + + expect(headers).toEqual({ + Authorization: 'Bearer test-key', + 'ai-gateway-protocol-version': '0.0.1', + 'ai-gateway-auth-method': 'api-key', + 'Custom-Header': 'custom-value', + }); + }); + + it('should be available on the provider interface', () => { + const provider = createGatewayProvider({ apiKey: 'test-key' }); + expect(typeof provider.getCredits).toBe('function'); + }); + }); + describe('Error handling in metadata fetching', () => { it('should convert metadata fetch errors to Gateway errors', async () => { mockGetAvailableModels.mockImplementation(() => { diff --git a/packages/gateway/src/gateway-provider.ts b/packages/gateway/src/gateway-provider.ts index 1a76ba35acf1..e0ef0d9dde90 100644 --- a/packages/gateway/src/gateway-provider.ts +++ b/packages/gateway/src/gateway-provider.ts @@ -12,6 +12,7 @@ import { import { GatewayFetchMetadata, type GatewayFetchMetadataResponse, + type GatewayCreditsResponse, } from './gateway-fetch-metadata'; import { GatewayLanguageModel } from './gateway-language-model'; import { GatewayEmbeddingModel } from './gateway-embedding-model'; @@ -37,6 +38,11 @@ Returns available providers and models for use with the remote provider. */ getAvailableModels(): Promise; + /** +Returns credit information for the authenticated user. + */ + getCredits(): Promise; + /** Creates a model for generating text embeddings. */ @@ -174,6 +180,18 @@ export function createGatewayProvider( return metadataCache ? Promise.resolve(metadataCache) : pendingMetadata; }; + const getCredits = async () => { + return new GatewayFetchMetadata({ + baseURL, + headers: getHeaders, + fetch: options.fetch, + }) + .getCredits() + .catch(async (error: unknown) => { + throw asGatewayError(error, parseAuthMethod(await getHeaders())); + }); + }; + const provider = function (modelId: GatewayModelId) { if (new.target) { throw new Error( @@ -185,6 +203,7 @@ export function createGatewayProvider( }; provider.getAvailableModels = getAvailableModels; + provider.getCredits = getCredits; provider.imageModel = (modelId: string) => { throw new NoSuchModelError({ modelId, modelType: 'imageModel' }); }; diff --git a/packages/gateway/src/index.ts b/packages/gateway/src/index.ts index 6a94e0fa315a..f9f929a74918 100644 --- a/packages/gateway/src/index.ts +++ b/packages/gateway/src/index.ts @@ -3,6 +3,7 @@ export type { GatewayLanguageModelEntry, GatewayLanguageModelSpecification, } from './gateway-model-entry'; +export type { GatewayCreditsResponse } from './gateway-fetch-metadata'; export type { GatewayLanguageModelEntry as GatewayModelEntry } from './gateway-model-entry'; export { createGatewayProvider, From f83903df61c1cecf1f809fda9ed4b46be179d847 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 18 Sep 2025 18:45:05 -0700 Subject: [PATCH 072/121] Get credits followup (#8754) --- .changeset/selfish-beers-mate.md | 5 +++++ .../src/gateway-fetch-metadata.test.ts | 10 +++++----- .../gateway/src/gateway-fetch-metadata.ts | 20 ++++++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 .changeset/selfish-beers-mate.md diff --git a/.changeset/selfish-beers-mate.md b/.changeset/selfish-beers-mate.md new file mode 100644 index 000000000000..2db2a3385a2f --- /dev/null +++ b/.changeset/selfish-beers-mate.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +getCredits style improvements diff --git a/packages/gateway/src/gateway-fetch-metadata.test.ts b/packages/gateway/src/gateway-fetch-metadata.test.ts index e90d96c1557c..c64407ed63a8 100644 --- a/packages/gateway/src/gateway-fetch-metadata.test.ts +++ b/packages/gateway/src/gateway-fetch-metadata.test.ts @@ -520,7 +520,7 @@ describe('GatewayFetchMetadata', () => { expect(result).toEqual({ balance: '150.50', - total_used: '75.25', + totalUsed: '75.25', }); }); @@ -548,7 +548,7 @@ describe('GatewayFetchMetadata', () => { }); expect(result).toEqual({ balance: '100.00', - total_used: '50.00', + totalUsed: '50.00', }); }); @@ -623,7 +623,7 @@ describe('GatewayFetchMetadata', () => { expect(result).toEqual({ balance: 'not-a-number', - total_used: '75.25', + totalUsed: '75.25', }); }); @@ -651,7 +651,7 @@ describe('GatewayFetchMetadata', () => { expect(result).toEqual({ balance: '200.00', - total_used: '100.50', + totalUsed: '100.50', }); expect(customFetch).toHaveBeenCalledWith( @@ -767,7 +767,7 @@ describe('GatewayFetchMetadata', () => { expect(result).toEqual({ balance: '0.00', - total_used: '0.00', + totalUsed: '0.00', }); }); }); diff --git a/packages/gateway/src/gateway-fetch-metadata.ts b/packages/gateway/src/gateway-fetch-metadata.ts index a57044a8b1ce..a133cba73ae3 100644 --- a/packages/gateway/src/gateway-fetch-metadata.ts +++ b/packages/gateway/src/gateway-fetch-metadata.ts @@ -16,8 +16,10 @@ export interface GatewayFetchMetadataResponse { } export interface GatewayCreditsResponse { + /** The remaining gateway credit balance available for API usage */ balance: string; - total_used: string; + /** The total amount of gateway credits that have been consumed */ + totalUsed: string; } export class GatewayFetchMetadata { @@ -47,10 +49,9 @@ export class GatewayFetchMetadata { async getCredits(): Promise { try { const baseUrl = new URL(this.config.baseURL); - const creditsUrl = `${baseUrl.origin}/v1/credits`; const { value } = await getFromApi({ - url: creditsUrl, + url: `${baseUrl.origin}/v1/credits`, headers: await resolve(this.config.headers()), successfulResponseHandler: createJsonResponseHandler(gatewayCreditsSchema), @@ -103,7 +104,12 @@ const gatewayFetchMetadataSchema = z.object({ models: z.array(gatewayLanguageModelEntrySchema), }); -const gatewayCreditsSchema = z.object({ - balance: z.string(), - total_used: z.string(), -}); +const gatewayCreditsSchema = z + .object({ + balance: z.string(), + total_used: z.string(), + }) + .transform(({ balance, total_used }) => ({ + balance, + totalUsed: total_used, + })); From e8383669fe9a626940fbbc9feaed831c9be44760 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 20:14:35 -0700 Subject: [PATCH 073/121] Version Packages (beta) (#8752) # Releases ## ai@5.1.0-beta.3 ### Patch Changes - Updated dependencies [3e83633] - Updated dependencies [f83903d] - @ai-sdk/gateway@1.1.0-beta.2 ## @ai-sdk/angular@1.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 ## @ai-sdk/gateway@1.1.0-beta.2 ### Patch Changes - 3e83633: add getCredits() gateway method - f83903d: getCredits style improvements ## @ai-sdk/langchain@1.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 ## @ai-sdk/llamaindex@1.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 ## @ai-sdk/react@2.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 ## @ai-sdk/rsc@1.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 ## @ai-sdk/svelte@3.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 ## @ai-sdk/vue@2.1.0-beta.3 ### Patch Changes - ai@5.1.0-beta.3 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 2 ++ packages/ai/CHANGELOG.md | 8 ++++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 6 ++++++ packages/angular/package.json | 2 +- packages/gateway/CHANGELOG.md | 7 +++++++ packages/gateway/package.json | 2 +- packages/langchain/CHANGELOG.md | 6 ++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 6 ++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 6 ++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 6 ++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 6 ++++++ packages/svelte/CHANGELOG.md | 6 ++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 6 ++++++ packages/vue/package.json | 2 +- 20 files changed, 74 insertions(+), 9 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 094eb8f868f3..c088f13609d0 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -75,9 +75,11 @@ "changesets": [ "curly-glasses-count", "four-candles-buy", + "neat-news-visit", "old-kiwis-hide", "quiet-pens-suffer", "red-roses-glow", + "selfish-beers-mate", "wise-jobs-knock" ] } diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 1884be505055..253c0f1bd251 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,13 @@ # ai +## 5.1.0-beta.3 + +### Patch Changes + +- Updated dependencies [3e83633] +- Updated dependencies [f83903d] + - @ai-sdk/gateway@1.1.0-beta.2 + ## 5.1.0-beta.2 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index b031b7e30016..f166a5d9ee24 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.2", + "version": "5.1.0-beta.3", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 16a9e50f7e2e..53f3138759ce 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/angular +## 1.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 040b11622bb9..4ae5b42e41ed 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index 022a4eb43a36..567db85102de 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/gateway +## 1.1.0-beta.2 + +### Patch Changes + +- 3e83633: add getCredits() gateway method +- f83903d: getCredits style improvements + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 6c8e4bd90798..2c1e09e6d0bf 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 054c6a59a51d..070ba37dbe88 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/langchain +## 1.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index bac145e701fd..cb43dd733827 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 5d9dd808d5cb..1df0508fa553 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index c466f6f3500b..405ad3dbfa14 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 6f38ac6d10d0..d1f1caa0a0a9 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/react +## 2.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index ce30ecc9289b..85420ed74cf6 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 09252d755b8d..dab04a570262 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/rsc +## 1.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index f4812ca7d7cd..b664ce755bcf 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index f36fcdd3bc55..09da27dd97cf 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,12 @@ ### Patch Changes +- ai@5.1.0-beta.3 + +## 0.0.1-beta.0 + +### Patch Changes + - ai@5.1.0-beta.2 ## 0.0.1-beta.0 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 2fc36e48e561..a347af0949bc 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/svelte +## 3.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 3.1.0-beta.2 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index e5c0f0341b3b..e5955a00b977 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.2", + "version": "3.1.0-beta.3", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 90983e400e35..981950300673 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/vue +## 2.1.0-beta.3 + +### Patch Changes + +- ai@5.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index b322d510c7f1..bfe6017a5e5f 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 38db3f1d55d11be63cd55db85700e3e71fe93eb6 Mon Sep 17 00:00:00 2001 From: Alex Ker Date: Fri, 19 Sep 2025 10:52:34 -0400 Subject: [PATCH 074/121] added baseten to website docs (#8737) ## Summary #8136 We recently added Baseten to be a Vercel AI SDK official provider. We need to update docs to reflect this change. I also tried updating this page: https://ai-sdk.dev/providers/ai-sdk-providers, but it looks like on your end vercel is populating logo icons from ``, so I don't think I can add that myself @nicoalbanese. ## Tasks - [x] Documentation has been added / updated (for bug fixes / features) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) --------- Co-authored-by: AlexKer Co-authored-by: josh --- content/cookbook/00-guides/21-llama-3_1.mdx | 2 +- .../02-providers-and-models.mdx | 4 +- .../01-ai-sdk-providers/170-baseten.mdx | 20 +-- .../providers/01-ai-sdk-providers/index.mdx | 10 ++ .../40-baseten.mdx | 116 ------------------ .../02-openai-compatible-providers/index.mdx | 1 - 6 files changed, 26 insertions(+), 127 deletions(-) delete mode 100644 content/providers/02-openai-compatible-providers/40-baseten.mdx diff --git a/content/cookbook/00-guides/21-llama-3_1.mdx b/content/cookbook/00-guides/21-llama-3_1.mdx index 92883fa1d10d..7e9a5bb58109 100644 --- a/content/cookbook/00-guides/21-llama-3_1.mdx +++ b/content/cookbook/00-guides/21-llama-3_1.mdx @@ -57,7 +57,7 @@ const { text } = await generateText({ Llama 3.1 is available to use with many AI SDK providers including [DeepInfra](/providers/ai-sdk-providers/deepinfra), [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock), - [Baseten](/providers/openai-compatible-providers/baseten) + [Baseten](/providers/ai-sdk-providers/baseten) [Fireworks](/providers/ai-sdk-providers/fireworks), and more. diff --git a/content/docs/02-foundations/02-providers-and-models.mdx b/content/docs/02-foundations/02-providers-and-models.mdx index 4977524cbc2c..62aa51860136 100644 --- a/content/docs/02-foundations/02-providers-and-models.mdx +++ b/content/docs/02-foundations/02-providers-and-models.mdx @@ -48,11 +48,11 @@ The AI SDK comes with a wide range of providers that you can use to interact wit - [Gladia Provider](/providers/ai-sdk-providers/gladia) (`@ai-sdk/gladia`) - [LMNT Provider](/providers/ai-sdk-providers/lmnt) (`@ai-sdk/lmnt`) - [AssemblyAI Provider](/providers/ai-sdk-providers/assemblyai) (`@ai-sdk/assemblyai`) +- [Baseten Provider](/providers/ai-sdk-providers/baseten) (`@ai-sdk/baseten`) You can also use the [OpenAI Compatible provider](/providers/openai-compatible-providers) with OpenAI-compatible APIs: - [LM Studio](/providers/openai-compatible-providers/lmstudio) -- [Baseten](/providers/openai-compatible-providers/baseten) - [Heroku](/providers/openai-compatible-providers/heroku) Our [language model specification](https://github.com/vercel/ai/tree/main/packages/provider/src/language-model/v2) is published as an open-source package, which you can use to create [custom providers](/providers/community-providers/custom-providers). @@ -88,7 +88,7 @@ You can access self-hosted models with the following providers: - [Ollama Provider](/providers/community-providers/ollama) - [LM Studio](/providers/openai-compatible-providers/lmstudio) -- [Baseten](/providers/openai-compatible-providers/baseten) +- [Baseten](/providers/ai-sdk-providers/baseten) - [Built-in AI](/providers/community-providers/built-in-ai) Additionally, any self-hosted provider that supports the OpenAI specification can be used with the [OpenAI Compatible Provider](/providers/openai-compatible-providers). diff --git a/content/providers/01-ai-sdk-providers/170-baseten.mdx b/content/providers/01-ai-sdk-providers/170-baseten.mdx index e20a7567b290..4572af55b7f5 100644 --- a/content/providers/01-ai-sdk-providers/170-baseten.mdx +++ b/content/providers/01-ai-sdk-providers/170-baseten.mdx @@ -5,7 +5,7 @@ description: Learn how to use Baseten models with the AI SDK. # Baseten Provider -[Baseten](https://baseten.co/) is an inference platform for serving frontier, enterprise-grade open source AI models[API](https://docs.baseten.co/overview). +[Baseten](https://baseten.co/) is an inference platform for serving frontier, enterprise-grade opensource AI models via their [API](https://docs.baseten.co/overview). ## Setup @@ -71,10 +71,10 @@ You can use the following optional settings to customize the Baseten provider in ## Models API You can select [Baseten models](https://www.baseten.co/products/model-apis/) using a provider instance. -The first argument is the model id, e.g. `'deepseek-ai/DeepSeek-V3-0324'`: The complete supported models under models API can be found [here](https://docs.baseten.co/development/model-apis/overview#supported-models). +The first argument is the model id, e.g. `'moonshotai/Kimi-K2-Instruct-0905'`: The complete supported models under models API can be found [here](https://docs.baseten.co/development/model-apis/overview#supported-models). ```ts -const model = baseten('deepseek-ai/Deepseek-V3-0324'); +const model = baseten('moonshotai/Kimi-K2-Instruct-0905'); ``` ### Example @@ -86,7 +86,7 @@ import { baseten } from '@ai-sdk/baseten'; import { generateText } from 'ai'; const { text } = await generateText({ - model: baseten('deepseek-ai/Deepseek-V3-0324'), + model: baseten('moonshotai/Kimi-K2-Instruct-0905'), prompt: 'What is the meaning of life? Answer in one sentence.', }); ``` @@ -111,8 +111,8 @@ const baseten = createBaseten({ // No modelId is needed because we specified modelURL const model = baseten(); const { text } = await generateText({ - model: customChatModel as any, - prompt: 'Say hello from the OpenAI-compatible chat model!', + model: model, + prompt: 'Say hello from a Baseten chat model!', }); ``` @@ -124,6 +124,12 @@ const { text } = await generateText({ You can create models that call the Baseten embeddings API using the `.textEmbeddingModel()` factory method. The Baseten provider uses the high-performance `@basetenlabs/performance-client` for optimal embedding performance. + + **Important:** Embedding models require a dedicated deployment with a custom + `modelURL`. Unlike chat models, embeddings cannot use Baseten's default Models + API and must specify a dedicated model endpoint. + + ```ts import { createBaseten } from '@ai-sdk/baseten'; import { embed, embedMany } from 'ai'; @@ -181,7 +187,7 @@ import { generateText } from 'ai'; try { const { text } = await generateText({ - model: baseten('deepseek-ai/DeepSeek-V3-0324'), + model: baseten('moonshotai/Kimi-K2-Instruct-0905'), prompt: 'Hello, world!', }); } catch (error) { diff --git a/content/providers/01-ai-sdk-providers/index.mdx b/content/providers/01-ai-sdk-providers/index.mdx index 6ae9288352c5..490818a9c2b0 100644 --- a/content/providers/01-ai-sdk-providers/index.mdx +++ b/content/providers/01-ai-sdk-providers/index.mdx @@ -69,6 +69,16 @@ Not all providers support all AI SDK features. Here's a quick comparison of the | [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.1-8b` | | | | | | [Cerebras](/providers/ai-sdk-providers/cerebras) | `llama3.3-70b` | | | | | | [Fireworks](/providers/ai-sdk-providers/fireworks) | `kimi-k2-instruct` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `openai/gpt-oss-120b` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `Qwen/Qwen3-235B-A22B-Instruct-2507` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `Qwen/Qwen3-Coder-480B-A35B-Instruct` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `moonshotai/Kimi-K2-Instruct-0905` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `moonshotai/Kimi-K2-Instruct` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `deepseek-ai/DeepSeek-V3.1` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `deepseek-ai/DeepSeek-R1-0528` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `deepseek-ai/DeepSeek-V3-0324` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `meta-llama/Llama-4-Maverick-17B-128E-Instruct` | | | | | +| [Baseten](/providers/ai-sdk-providers/baseten) | `meta-llama/Llama-4-Scout-17B-16E-Instruct` | | | | | This table is not exhaustive. Additional models can be found in the provider diff --git a/content/providers/02-openai-compatible-providers/40-baseten.mdx b/content/providers/02-openai-compatible-providers/40-baseten.mdx deleted file mode 100644 index fd4784f8eeb6..000000000000 --- a/content/providers/02-openai-compatible-providers/40-baseten.mdx +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Baseten -description: Use a Baseten OpenAI compatible API with the AI SDK. ---- - -# Baseten Provider - -[Baseten](https://baseten.co/) is a platform for running and testing LLMs. -It allows you to deploy models that are OpenAI API compatible that you can use with the AI SDK. - -## Setup - -The Baseten provider is available via the `@ai-sdk/openai-compatible` module as it is compatible with the OpenAI API. -You can install it with - - - - - - - - - - - - - - - - - -## Provider Instance - -To use Baseten, you can create a custom provider instance with the `createOpenAICompatible` function from `@ai-sdk/openai-compatible`: - -```ts -import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; - -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 ?? ''}`, - }, -}); -``` - -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://www.baseten.co/library/) using a provider instance. -The first argument is the served model name, e.g. `llama`. - -```ts -const model = baseten('llama'); -``` - -### Example - -You can use Baseten language models to generate text with the `generateText` function: - -```ts -import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; -import { generateText } from 'ai'; - -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 ?? ''}`, - }, -}); - -const { text } = await generateText({ - model: baseten('llama'), - prompt: 'Tell me about yourself in one sentence', -}); - -console.log(text); -``` - -Baseten language models are also able to generate text in a streaming fashion with the `streamText` function: - -```ts -import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; -import { streamText } from 'ai'; - -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 ?? ''}`, - }, -}); - -const result = streamText({ - model: baseten('llama'), - prompt: 'Tell me about yourself in one sentence', -}); - -for await (const message of result.textStream) { - console.log(message); -} -``` - -Baseten language models can also be used in the `generateObject`, and `streamObject` functions. diff --git a/content/providers/02-openai-compatible-providers/index.mdx b/content/providers/02-openai-compatible-providers/index.mdx index 28c3b1653ac4..309e1245e9b2 100644 --- a/content/providers/02-openai-compatible-providers/index.mdx +++ b/content/providers/02-openai-compatible-providers/index.mdx @@ -13,7 +13,6 @@ We provide detailed documentation for the following OpenAI compatible providers: - [LM Studio](/providers/openai-compatible-providers/lmstudio) - [NIM](/providers/openai-compatible-providers/nim) -- [Baseten](/providers/openai-compatible-providers/baseten) - [Heroku](/providers/openai-compatible-providers/heroku) The general setup and provider instance creation is the same for all of these providers. From a8fa288b775dd131ec9120f15b67d2d3009df5b7 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 09:01:57 -0700 Subject: [PATCH 075/121] docs(contributing): add new provider (#8773) --- contributing/add-new-provider.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 contributing/add-new-provider.md diff --git a/contributing/add-new-provider.md b/contributing/add-new-provider.md new file mode 100644 index 000000000000..a9543f940ce6 --- /dev/null +++ b/contributing/add-new-provider.md @@ -0,0 +1,25 @@ +# Add new provider + +## `@ai-sdk/` vs 3rd party package + +Every provider is welcome to create a 3rd party package. We are happy to link to it from our documentation. + +If you would prefer a 1st party `@ai-sdk/` package, the decision comes usually down to whether the Vercel AI Gateway will support the provider or not. If AI Gateway is or will support the provider, we prefer the provider package to be part of the `vercel/ai` repository. + +## Example + +https://github.com/vercel/ai/pull/8136/files + +## How + +1. Create new folder `packages/` +2. Set version in `packages//package.json` to `0.0.0` +3. Create changeset for new package with `major` +4. Add examples to `examples/ai-core/src/*/.ts` depending on what model types the provider supports +5. Add documentation in `content/providers/01-ai-sdk-providers/-.mdx` + +See also [providers.md](providers.md) + +## When in pre-release mode + +If `main` is set up to publish `beta` releases, no further action is necessary. Just make sure not to backport it to the `vX.Y` stable branch since it will result in an npm version conflict once we exit pre-release mode on `main` From e0b2c634f7cd859d250e89331203bbf803796f15 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 09:27:03 -0700 Subject: [PATCH 076/121] docs(contributing): issue first (#8775) --- contributing/add-new-provider.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing/add-new-provider.md b/contributing/add-new-provider.md index a9543f940ce6..d6923a084730 100644 --- a/contributing/add-new-provider.md +++ b/contributing/add-new-provider.md @@ -4,7 +4,7 @@ Every provider is welcome to create a 3rd party package. We are happy to link to it from our documentation. -If you would prefer a 1st party `@ai-sdk/` package, the decision comes usually down to whether the Vercel AI Gateway will support the provider or not. If AI Gateway is or will support the provider, we prefer the provider package to be part of the `vercel/ai` repository. +If you would prefer a 1st party `@ai-sdk/` package, please create an issue first to discuss. ## Example From 4d34a896036a5d0604adaf486398c9f4fe0d2784 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Fri, 19 Sep 2025 13:28:23 -0700 Subject: [PATCH 077/121] feat (provider/cerebras): enable structured outputs (#8785) ## Background Cerebras supports structured outputs in at least some models now per https://inference-docs.cerebras.ai/capabilities/structured-outputs In https://github.com/nvie/ai/commit/c79511dd62bcc3b884727e084970f32a7a54716b we added a provider setting to `openai-compatible` to allow derived providers to enable the feature when available. ## Summary Enable `supportsStructuredOutputs` in the Cerebras provider and add example scripts to demonstrate successful operation. ## Manual Verification Ran the scripts. ## Checklist - [x] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Future work Investigate better error handling of > [AI_NoObjectGeneratedError]: No object generated: response did not match schema. Instead make clear that the problem is that the model does not support structured output ## Related Issues Fixes https://github.com/vercel/ai/issues/8475 --- .changeset/grumpy-actors-sleep.md | 5 +++ .../ai-core/src/generate-object/cerebras.ts | 30 +++++++++++++++++ .../ai-core/src/stream-object/cerebras.ts | 33 +++++++++++++++++++ packages/cerebras/src/cerebras-provider.ts | 1 + 4 files changed, 69 insertions(+) create mode 100644 .changeset/grumpy-actors-sleep.md create mode 100644 examples/ai-core/src/generate-object/cerebras.ts create mode 100644 examples/ai-core/src/stream-object/cerebras.ts diff --git a/.changeset/grumpy-actors-sleep.md b/.changeset/grumpy-actors-sleep.md new file mode 100644 index 000000000000..a605c5e22878 --- /dev/null +++ b/.changeset/grumpy-actors-sleep.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/cerebras': patch +--- + +feat (provider/cerebras): enable structured outputs diff --git a/examples/ai-core/src/generate-object/cerebras.ts b/examples/ai-core/src/generate-object/cerebras.ts new file mode 100644 index 000000000000..599b59ef732f --- /dev/null +++ b/examples/ai-core/src/generate-object/cerebras.ts @@ -0,0 +1,30 @@ +import { cerebras } from '@ai-sdk/cerebras'; +import { generateObject } from 'ai'; +import 'dotenv/config'; +import { z } from 'zod'; + +async function main() { + const result = await generateObject({ + model: cerebras('gpt-oss-120b'), + schema: z.object({ + recipe: z.object({ + name: z.string(), + ingredients: z.array( + z.object({ + name: z.string(), + amount: z.string(), + }), + ), + steps: z.array(z.string()), + }), + }), + prompt: 'Generate a lasagna recipe.', + }); + + console.log(JSON.stringify(result.object.recipe, null, 2)); + console.log(); + console.log('Token usage:', result.usage); + console.log('Finish reason:', result.finishReason); +} + +main().catch(console.error); diff --git a/examples/ai-core/src/stream-object/cerebras.ts b/examples/ai-core/src/stream-object/cerebras.ts new file mode 100644 index 000000000000..dc22b5031643 --- /dev/null +++ b/examples/ai-core/src/stream-object/cerebras.ts @@ -0,0 +1,33 @@ +import { cerebras } from '@ai-sdk/cerebras'; +import { streamObject } from 'ai'; +import 'dotenv/config'; +import { z } from 'zod'; + +async function main() { + const result = streamObject({ + model: cerebras('gpt-oss-120b'), + schema: z.object({ + characters: z.array( + z.object({ + name: z.string(), + class: z + .string() + .describe('Character class, e.g. warrior, mage, or thief.'), + description: z.string(), + }), + ), + }), + prompt: + 'Generate 3 character descriptions for a fantasy role playing game.', + }); + + for await (const partialObject of result.partialObjectStream) { + console.clear(); + console.log(partialObject); + } + + console.log(); + console.log('Token usage:', await result.usage); +} + +main().catch(console.error); diff --git a/packages/cerebras/src/cerebras-provider.ts b/packages/cerebras/src/cerebras-provider.ts index 8bf15eb168a4..a5148114a8d2 100644 --- a/packages/cerebras/src/cerebras-provider.ts +++ b/packages/cerebras/src/cerebras-provider.ts @@ -87,6 +87,7 @@ export function createCerebras( headers: getHeaders, fetch: options.fetch, errorStructure: cerebrasErrorStructure, + supportsStructuredOutputs: true, }); }; From 0a74d2e6523f2dc2fef960683d8f6c57feae82ab Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:34:26 -0700 Subject: [PATCH 078/121] ci: send slack message when review requested from @vercel/ai-sdk team (#8782) --- .../slack-team-review-notification.yml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/slack-team-review-notification.yml diff --git a/.github/workflows/slack-team-review-notification.yml b/.github/workflows/slack-team-review-notification.yml new file mode 100644 index 000000000000..9feab3edd836 --- /dev/null +++ b/.github/workflows/slack-team-review-notification.yml @@ -0,0 +1,37 @@ +name: Slack Team Review Notification + +on: + pull_request: + types: [review_requested] + +jobs: + notify-slack: + runs-on: ubuntu-latest + + steps: + - name: debug + run: echo "${{ toJSON(github.event) }}" + - name: Check if ai-sdk team was requested + id: check_team + run: | + echo "Checking requested teams..." + teams='${{ toJson(github.event.pull_request.requested_teams) }}' + + # Check if ai-sdk team is in the requested teams + if echo "$teams" | jq -e '.[] | select(.slug == "ai-sdk")' > /dev/null; then + echo "ai_sdk_requested=true" >> $GITHUB_OUTPUT + echo "✅ ai-sdk team was requested for review" + else + echo "ai_sdk_requested=false" >> $GITHUB_OUTPUT + echo "❌ ai-sdk team was not requested for review" + fi + + - name: Send Slack notification + if: steps.check_team.outputs.ai_sdk_requested == 'true' + run: | + curl ${{ env.SLACK_SEND_MESSAGE_URL }} -X POST -H "Content-Type: application/json" -d '{"channel_id": "${{ env.CHANNEL_ID }}", "text": ${{ toJson(env.TEXT) }}}' + env: + SLACK_SEND_MESSAGE_URL: ${{ secrets.SLACK_SEND_MESSAGE_URL }} + CHANNEL_ID: "C050WU03V3N" + TEXT: | + :pr: ${{ github.event.pull_request.title }} <${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }}>" \ No newline at end of file From b0324a8d84f8641a1ee051291f0577bcd6e20d58 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:36:01 -0700 Subject: [PATCH 079/121] ci(review-notification): fix debugging --- .github/workflows/slack-team-review-notification.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/slack-team-review-notification.yml b/.github/workflows/slack-team-review-notification.yml index 9feab3edd836..324e1e4d0300 100644 --- a/.github/workflows/slack-team-review-notification.yml +++ b/.github/workflows/slack-team-review-notification.yml @@ -10,7 +10,7 @@ jobs: steps: - name: debug - run: echo "${{ toJSON(github.event) }}" + run: cat $GITHUB_EVENT_PATH - name: Check if ai-sdk team was requested id: check_team run: | From f855814dd6eeb9af69b40dd6b3c3af137f9e5352 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:38:22 -0700 Subject: [PATCH 080/121] ci(review-notification): remove quote --- .github/workflows/slack-team-review-notification.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/slack-team-review-notification.yml b/.github/workflows/slack-team-review-notification.yml index 324e1e4d0300..051362cfab48 100644 --- a/.github/workflows/slack-team-review-notification.yml +++ b/.github/workflows/slack-team-review-notification.yml @@ -34,4 +34,4 @@ jobs: SLACK_SEND_MESSAGE_URL: ${{ secrets.SLACK_SEND_MESSAGE_URL }} CHANNEL_ID: "C050WU03V3N" TEXT: | - :pr: ${{ github.event.pull_request.title }} <${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }}>" \ No newline at end of file + :pr: ${{ github.event.pull_request.title }} <${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }}> \ No newline at end of file From 1654c71c503d19576275a78d64e2828e38a72b2c Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:40:15 -0700 Subject: [PATCH 081/121] ci(review-notification): message --- .github/workflows/slack-team-review-notification.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/slack-team-review-notification.yml b/.github/workflows/slack-team-review-notification.yml index 051362cfab48..fe064e4cecc2 100644 --- a/.github/workflows/slack-team-review-notification.yml +++ b/.github/workflows/slack-team-review-notification.yml @@ -29,7 +29,7 @@ jobs: - name: Send Slack notification if: steps.check_team.outputs.ai_sdk_requested == 'true' run: | - curl ${{ env.SLACK_SEND_MESSAGE_URL }} -X POST -H "Content-Type: application/json" -d '{"channel_id": "${{ env.CHANNEL_ID }}", "text": ${{ toJson(env.TEXT) }}}' + curl ${{ env.SLACK_SEND_MESSAGE_URL }} -X POST -H "Content-Type: application/json" -d '{"channel_id": "${{ env.CHANNEL_ID }}", "message": ${{ toJson(env.TEXT) }}}' env: SLACK_SEND_MESSAGE_URL: ${{ secrets.SLACK_SEND_MESSAGE_URL }} CHANNEL_ID: "C050WU03V3N" From 60368a1c7ac86bcdd16cd5fb6d85fa5666d34c78 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:50:46 -0700 Subject: [PATCH 082/121] ci(review-notification): send message as multiple variables for independent formatting --- .github/workflows/slack-team-review-notification.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/slack-team-review-notification.yml b/.github/workflows/slack-team-review-notification.yml index fe064e4cecc2..a6bf4787b542 100644 --- a/.github/workflows/slack-team-review-notification.yml +++ b/.github/workflows/slack-team-review-notification.yml @@ -29,9 +29,10 @@ jobs: - name: Send Slack notification if: steps.check_team.outputs.ai_sdk_requested == 'true' run: | - curl ${{ env.SLACK_SEND_MESSAGE_URL }} -X POST -H "Content-Type: application/json" -d '{"channel_id": "${{ env.CHANNEL_ID }}", "message": ${{ toJson(env.TEXT) }}}' + curl ${{ env.SLACK_SEND_MESSAGE_URL }} -X POST -H "Content-Type: application/json" -d '{"channel_id": "${{ env.CHANNEL_ID }}", "number": "${{ env.NUMBER }}", "title": ${{ toJson(env.TITLE) }}, "url": "${{ env.URL }}"}' env: SLACK_SEND_MESSAGE_URL: ${{ secrets.SLACK_SEND_MESSAGE_URL }} CHANNEL_ID: "C050WU03V3N" - TEXT: | - :pr: ${{ github.event.pull_request.title }} <${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }}> \ No newline at end of file + NUMBER: ${{ github.event.pull_request.number }} + TITLE: ${{ github.event.pull_request.title }} + URL: ${{ github.event.pull_request.html_url }} \ No newline at end of file From e4ac767b712990bf3fc3d9b34ca46bc277839e42 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:19:02 -0700 Subject: [PATCH 083/121] Version Packages (beta) (#8787) # Releases ## @ai-sdk/cerebras@1.1.0-beta.2 ### Patch Changes - 4d34a89: feat (provider/cerebras): enable structured outputs Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 1 + packages/cerebras/CHANGELOG.md | 6 ++++++ packages/cerebras/package.json | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index c088f13609d0..f98617fa6f55 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -75,6 +75,7 @@ "changesets": [ "curly-glasses-count", "four-candles-buy", + "grumpy-actors-sleep", "neat-news-visit", "old-kiwis-hide", "quiet-pens-suffer", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 3e833f257817..ede25a2a8a94 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/cerebras +## 1.1.0-beta.2 + +### Patch Changes + +- 4d34a89: feat (provider/cerebras): enable structured outputs + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index ea69d741ee75..0bb0dae52b4e 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From ea9ca3130e04a5d282683635d8cdb82e739344f6 Mon Sep 17 00:00:00 2001 From: Rohan Taneja <47066511+R-Taneja@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:49:04 -0700 Subject: [PATCH 084/121] feat(provider/gateway): Add new xAI models (#8789) ## Background New xAI models ## Summary Adds new xAI models to Gateway model string autocomplete ## Manual Verification Autocomplete works ## Checklist - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) --- .changeset/angry-hats-cry.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/angry-hats-cry.md diff --git a/.changeset/angry-hats-cry.md b/.changeset/angry-hats-cry.md new file mode 100644 index 000000000000..e46ec6d49ac0 --- /dev/null +++ b/.changeset/angry-hats-cry.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat(provider/gateway): Add new xAI models diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index 60755738bec7..4e3d540516d4 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -97,6 +97,8 @@ export type GatewayModelId = | 'xai/grok-3-mini-fast' | 'xai/grok-4' | 'xai/grok-code-fast-1' + | 'xai/grok-4-fast-non-reasoning' + | 'xai/grok-4-fast-reasoning' | 'zai/glm-4.5' | 'zai/glm-4.5-air' | 'zai/glm-4.5v' From 6481969a1f57f5c33332b6ea932f489dc712a24b Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 17:01:20 -0700 Subject: [PATCH 085/121] Version Packages (beta) (#8790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. ⚠️⚠️⚠️⚠️⚠️⚠️ `main` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `main`. ⚠️⚠️⚠️⚠️⚠️⚠️ # Releases ## ai@5.1.0-beta.4 ### Patch Changes - Updated dependencies [ea9ca31] - @ai-sdk/gateway@1.1.0-beta.3 ## @ai-sdk/angular@1.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 ## @ai-sdk/gateway@1.1.0-beta.3 ### Patch Changes - ea9ca31: feat(provider/gateway): Add new xAI models ## @ai-sdk/langchain@1.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 ## @ai-sdk/llamaindex@1.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 ## @ai-sdk/react@2.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 ## @ai-sdk/rsc@1.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 ## @ai-sdk/svelte@3.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 ## @ai-sdk/vue@2.1.0-beta.4 ### Patch Changes - ai@5.1.0-beta.4 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 1 + packages/ai/CHANGELOG.md | 7 +++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 6 ++++++ packages/angular/package.json | 2 +- packages/gateway/CHANGELOG.md | 6 ++++++ packages/gateway/package.json | 2 +- packages/langchain/CHANGELOG.md | 6 ++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 6 ++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 6 ++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 6 ++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 6 ++++++ packages/svelte/CHANGELOG.md | 6 ++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 6 ++++++ packages/vue/package.json | 2 +- 20 files changed, 71 insertions(+), 9 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index f98617fa6f55..23c6cb485196 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -73,6 +73,7 @@ "@ai-sdk/test-server": "0.0.0" }, "changesets": [ + "angry-hats-cry", "curly-glasses-count", "four-candles-buy", "grumpy-actors-sleep", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 253c0f1bd251..0f0ab5bb29c2 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,12 @@ # ai +## 5.1.0-beta.4 + +### Patch Changes + +- Updated dependencies [ea9ca31] + - @ai-sdk/gateway@1.1.0-beta.3 + ## 5.1.0-beta.3 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index f166a5d9ee24..43c1fb882231 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.3", + "version": "5.1.0-beta.4", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 53f3138759ce..a04d01538693 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/angular +## 1.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 1.1.0-beta.3 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 4ae5b42e41ed..22aebfe64baf 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.3", + "version": "1.1.0-beta.4", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index 567db85102de..13a0c0ef0f28 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/gateway +## 1.1.0-beta.3 + +### Patch Changes + +- ea9ca31: feat(provider/gateway): Add new xAI models + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 2c1e09e6d0bf..5496d1722ab1 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 070ba37dbe88..e8345633af6e 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/langchain +## 1.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 1.1.0-beta.3 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index cb43dd733827..138e1521de37 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.3", + "version": "1.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 1df0508fa553..5b8fc2467fa6 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 1.1.0-beta.3 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 405ad3dbfa14..932f6037c2b7 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.3", + "version": "1.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index d1f1caa0a0a9..e6ac964d85ef 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/react +## 2.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 85420ed74cf6..6501c08d812f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index dab04a570262..db8e4059fae0 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/rsc +## 1.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 1.1.0-beta.3 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index b664ce755bcf..80ac81ae84d5 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.3", + "version": "1.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 09da27dd97cf..b7e8b8fb3332 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,12 @@ ### Patch Changes +- ai@5.1.0-beta.4 + +## 0.0.1-beta.0 + +### Patch Changes + - ai@5.1.0-beta.3 ## 0.0.1-beta.0 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index a347af0949bc..ed83bbe2b10d 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/svelte +## 3.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 3.1.0-beta.3 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index e5955a00b977..dca4d7ba7979 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.3", + "version": "3.1.0-beta.4", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 981950300673..b2c9732346f4 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/vue +## 2.1.0-beta.4 + +### Patch Changes + +- ai@5.1.0-beta.4 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index bfe6017a5e5f..c8e96a90d930 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 7dea60ec21c7a95dab8c91666ca7d5e1ec96e584 Mon Sep 17 00:00:00 2001 From: Ted Li Date: Fri, 19 Sep 2025 20:42:25 -0700 Subject: [PATCH 086/121] feat (provider/google): add promptFeedback outputs (#8682) Based on https://github.com/vercel/ai/pull/4265, using latest head closes #4265 closes #4236 --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/shaggy-emus-try.md | 5 ++ examples/ai-core/src/generate-text/google.ts | 6 ++ examples/ai-core/src/stream-text/google.ts | 6 ++ ...oogle-generative-ai-language-model.test.ts | 63 +++++++++++++++++++ .../google-generative-ai-language-model.ts | 14 +++++ 5 files changed, 94 insertions(+) create mode 100644 .changeset/shaggy-emus-try.md diff --git a/.changeset/shaggy-emus-try.md b/.changeset/shaggy-emus-try.md new file mode 100644 index 000000000000..7e4619114ccd --- /dev/null +++ b/.changeset/shaggy-emus-try.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/google': patch +--- + +add promptFeedback outputs diff --git a/examples/ai-core/src/generate-text/google.ts b/examples/ai-core/src/generate-text/google.ts index a5eb68446547..54539b498b45 100644 --- a/examples/ai-core/src/generate-text/google.ts +++ b/examples/ai-core/src/generate-text/google.ts @@ -8,10 +8,16 @@ async function main() { prompt: 'Invent a new holiday and describe its traditions.', }); + const googleMetadata = result.providerMetadata?.google; + console.log(result.text); console.log(); console.log('Token usage:', result.usage); console.log('Finish reason:', result.finishReason); + console.log('Safety info:', { + promptFeedback: googleMetadata?.promptFeedback, + safetyRatings: googleMetadata?.safetyRatings, + }); } main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/google.ts b/examples/ai-core/src/stream-text/google.ts index 8b2faf47bd58..e7b82ff20706 100644 --- a/examples/ai-core/src/stream-text/google.ts +++ b/examples/ai-core/src/stream-text/google.ts @@ -13,9 +13,15 @@ async function main() { process.stdout.write(textPart); } + const googleMetadata = (await result.providerMetadata)?.google; + console.log(); console.log('Token usage:', await result.usage); console.log('Finish reason:', await result.finishReason); + console.log('Safety info:', { + promptFeedback: googleMetadata?.promptFeedback, + safetyRatings: googleMetadata?.safetyRatings, + }); } main().catch(console.error); 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 5ca06f9a67f7..9c095099c38f 100644 --- a/packages/google/src/google-generative-ai-language-model.test.ts +++ b/packages/google/src/google-generative-ai-language-model.test.ts @@ -923,6 +923,35 @@ describe('doGenerate', () => { ]); }); + it('should expose PromptFeedback in provider metadata', async () => { + server.urls[TEST_URL_GEMINI_PRO].response = { + type: 'json-value', + body: { + candidates: [ + { + content: { parts: [{ text: 'No' }], role: 'model' }, + finishReason: 'SAFETY', + index: 0, + safetyRatings: SAFETY_RATINGS, + }, + ], + promptFeedback: { + blockReason: 'SAFETY', + safetyRatings: SAFETY_RATINGS, + }, + }, + }; + + const { providerMetadata } = await model.doGenerate({ + prompt: TEST_PROMPT, + }); + + expect(providerMetadata?.google.promptFeedback).toStrictEqual({ + blockReason: 'SAFETY', + safetyRatings: SAFETY_RATINGS, + }); + }); + it('should expose grounding metadata in provider metadata', async () => { prepareJsonResponse({ content: 'test response', @@ -1898,6 +1927,7 @@ describe('doStream', () => { "providerMetadata": { "google": { "groundingMetadata": null, + "promptFeedback": null, "safetyRatings": [ { "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", @@ -1971,6 +2001,36 @@ describe('doStream', () => { ]); }); + it('should expose PromptFeedback in provider metadata on finish', async () => { + server.urls[TEST_URL_GEMINI_PRO].response = { + type: 'stream-chunks', + chunks: [ + `data: {"candidates": [{"content": {"parts": [{"text": "No"}],"role": "model"},` + + `"finishReason": "PROHIBITED_CONTENT","index": 0}],` + + `"promptFeedback": {"blockReason": "PROHIBITED_CONTENT","safetyRatings": [` + + `{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT","probability": "NEGLIGIBLE"},` + + `{"category": "HARM_CATEGORY_HATE_SPEECH","probability": "NEGLIGIBLE"},` + + `{"category": "HARM_CATEGORY_HARASSMENT","probability": "NEGLIGIBLE"},` + + `{"category": "HARM_CATEGORY_DANGEROUS_CONTENT","probability": "NEGLIGIBLE"}]}}\n\n`, + ], + }; + + const { stream } = await model.doStream({ + prompt: TEST_PROMPT, + }); + + const events = await convertReadableStreamToArray(stream); + const finishEvent = events.find(event => event.type === 'finish'); + + expect( + finishEvent?.type === 'finish' && + finishEvent.providerMetadata?.google.promptFeedback, + ).toStrictEqual({ + blockReason: 'PROHIBITED_CONTENT', + safetyRatings: SAFETY_RATINGS, + }); + }); + it('should stream code execution tool calls and results', async () => { server.urls[TEST_URL_GEMINI_2_0_PRO].response = { type: 'stream-chunks', @@ -2385,6 +2445,7 @@ describe('doStream', () => { "providerMetadata": { "google": { "groundingMetadata": null, + "promptFeedback": null, "safetyRatings": [ { "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", @@ -2664,6 +2725,7 @@ describe('doStream', () => { "providerMetadata": { "google": { "groundingMetadata": null, + "promptFeedback": null, "safetyRatings": null, "urlContextMetadata": null, "usageMetadata": { @@ -2792,6 +2854,7 @@ describe('doStream', () => { "providerMetadata": { "google": { "groundingMetadata": null, + "promptFeedback": null, "safetyRatings": [ { "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", diff --git a/packages/google/src/google-generative-ai-language-model.ts b/packages/google/src/google-generative-ai-language-model.ts index 4ed0996b08ba..d0aea7454f6a 100644 --- a/packages/google/src/google-generative-ai-language-model.ts +++ b/packages/google/src/google-generative-ai-language-model.ts @@ -292,6 +292,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV2 { warnings, providerMetadata: { google: { + promptFeedback: response.promptFeedback ?? null, groundingMetadata: candidate.groundingMetadata ?? null, urlContextMetadata: candidate.urlContextMetadata ?? null, safetyRatings: candidate.safetyRatings ?? null, @@ -590,6 +591,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV2 { providerMetadata = { google: { + promptFeedback: value.promptFeedback ?? null, groundingMetadata: candidate.groundingMetadata ?? null, urlContextMetadata: candidate.urlContextMetadata ?? null, safetyRatings: candidate.safetyRatings ?? null, @@ -763,6 +765,12 @@ const responseSchema = z.object({ }), ), usageMetadata: usageSchema.nullish(), + promptFeedback: z + .object({ + blockReason: z.string().nullish(), + safetyRatings: z.array(safetyRatingSchema).nullish(), + }) + .nullish(), }); // limited version of the schema, focussed on what is needed for the implementation @@ -780,4 +788,10 @@ const chunkSchema = z.object({ ) .nullish(), usageMetadata: usageSchema.nullish(), + promptFeedback: z + .object({ + blockReason: z.string().nullish(), + safetyRatings: z.array(safetyRatingSchema).nullish(), + }) + .nullish(), }); From 4771f9be8511f85e390589c880ee278895641401 Mon Sep 17 00:00:00 2001 From: abeer0 <47961062+iiio2@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:49:17 +0600 Subject: [PATCH 087/121] ci: bump versions (#8797) ## Background ## Summary ## Manual Verification ## Checklist - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [ ] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [ ] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [ ] I have reviewed this pull request (self-review) ## Future Work ## Related Issues --- .../workflows/assign-team-pull-request.yml | 2 +- .github/workflows/backport.yml | 2 +- .github/workflows/ci.yml | 20 +++++++++---------- .github/workflows/release-snapshot.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- .github/workflows/triage.yml | 2 +- .github/workflows/verify-changesets.yml | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/assign-team-pull-request.yml b/.github/workflows/assign-team-pull-request.yml index 5de0ad5d32fe..411073e99892 100644 --- a/.github/workflows/assign-team-pull-request.yml +++ b/.github/workflows/assign-team-pull-request.yml @@ -14,7 +14,7 @@ jobs: # And only assign if pull request was created by a user, ignore bots if: github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.user.type == 'User' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Assign pull request to author run: gh pr edit $PULL_REQUEST_URL --add-assignee $AUTHOR_LOGIN env: diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 15ae0c06d480..d758415f9bbf 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -38,7 +38,7 @@ jobs: git config --global user.email '${{ steps.app-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87b1e931d06b..807bd88a5127 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -20,7 +20,7 @@ jobs: version: 10.11.0 - name: Use Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 22 cache: 'pnpm' @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -44,7 +44,7 @@ jobs: version: 10.11.0 - name: Use Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 22 cache: 'pnpm' @@ -60,7 +60,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -68,7 +68,7 @@ jobs: version: 10.11.0 - name: Use Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 22 cache: 'pnpm' @@ -84,7 +84,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -92,7 +92,7 @@ jobs: version: 10.11.0 - name: Use Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 22 cache: 'pnpm' @@ -114,7 +114,7 @@ jobs: node-version: [20, 22] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -122,7 +122,7 @@ jobs: version: 10.11.0 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/release-snapshot.yml b/.github/workflows/release-snapshot.yml index 97e198e40651..685cc25a1804 100644 --- a/.github/workflows/release-snapshot.yml +++ b/.github/workflows/release-snapshot.yml @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 @@ -48,7 +48,7 @@ jobs: version: 10.11.0 - name: Setup Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 22 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 82a74e3b62f8..c1423f641063 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: git config --global user.email '${{ steps.app-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' - name: Checkout Repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} @@ -50,7 +50,7 @@ jobs: version: 10.11.0 - name: Setup Node.js 22 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 22 diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index bab6f8393283..a1d1dac18315 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -21,7 +21,7 @@ jobs: private-key: ${{ secrets.VERCEL_AI_SDK_GITHUB_APP_PRIVATE_KEY_PKCS8 }} - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Fetch existing provider labels id: fetch-labels diff --git a/.github/workflows/verify-changesets.yml b/.github/workflows/verify-changesets.yml index 4feca6aef7bb..28e29f89dd06 100644 --- a/.github/workflows/verify-changesets.yml +++ b/.github/workflows/verify-changesets.yml @@ -16,10 +16,10 @@ jobs: verify-changesets: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 'lts/*' - name: get all changed files from .changeset/*.md From 0edf6912fdf0a02f3244e576f2a69223630c5d5e Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 10:11:15 -0700 Subject: [PATCH 088/121] Version Packages (beta) (#8792) # Releases ## @ai-sdk/google@2.1.0-beta.2 ### Patch Changes - 7dea60e: add promptFeedback outputs ## @ai-sdk/google-vertex@3.1.0-beta.2 ### Patch Changes - Updated dependencies [7dea60e] - @ai-sdk/google@2.1.0-beta.2 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 1 + packages/google-vertex/CHANGELOG.md | 7 +++++++ packages/google-vertex/package.json | 2 +- packages/google/CHANGELOG.md | 6 ++++++ packages/google/package.json | 2 +- 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 23c6cb485196..6aa672bed7c6 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -82,6 +82,7 @@ "quiet-pens-suffer", "red-roses-glow", "selfish-beers-mate", + "shaggy-emus-try", "wise-jobs-knock" ] } diff --git a/packages/google-vertex/CHANGELOG.md b/packages/google-vertex/CHANGELOG.md index 0319459d108f..4f597dfdd558 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/google-vertex +## 3.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [7dea60e] + - @ai-sdk/google@2.1.0-beta.2 + ## 3.1.0-beta.1 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 4446d3acca83..7566322395da 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.1.0-beta.1", + "version": "3.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 473c9229aa40..005ff2c95d3e 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/google +## 2.1.0-beta.2 + +### Patch Changes + +- 7dea60e: add promptFeedback outputs + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index 545d31daf820..ef9205a63b26 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From b2cfbcdd95d556d352b95690acc73880d1e8e027 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:13:25 -0700 Subject: [PATCH 089/121] ci(verify-changeset): use `working-directory` --- .github/workflows/verify-changesets.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify-changesets.yml b/.github/workflows/verify-changesets.yml index 28e29f89dd06..a04de6ed5657 100644 --- a/.github/workflows/verify-changesets.yml +++ b/.github/workflows/verify-changesets.yml @@ -12,9 +12,15 @@ on: paths: - '.changeset/*.md' + + + jobs: verify-changesets: runs-on: ubuntu-latest + defaults: + run: + working-directory: .github/workflows/actions/verify-changesets steps: - uses: actions/checkout@v5 with: @@ -25,12 +31,11 @@ jobs: - name: get all changed files from .changeset/*.md id: changeset-files run: | - echo "changed-files=$(git diff --diff-filter=dr --name-only $BASE_SHA -- '.changeset/*.md' | tr '\n' ' ')" >> $GITHUB_OUTPUT + echo "changed-files=$(git diff --diff-filter=dr --name-only $BASE_SHA -- '../../../../.changeset/*.md' | tr '\n' ' ')" >> $GITHUB_OUTPUT env: BASE_SHA: ${{ github.event.pull_request.base.sha }} - name: Verify changesets if: steps.changeset-files.outputs.changed-files != '' - working-directory: .github/workflows/actions/verify-changesets run: | node index.js env: From 73145adf3d006b9ab0cd3bafcaa3341244a5504b Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:14:08 -0700 Subject: [PATCH 090/121] style: prettier --- .github/workflows/verify-changesets.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/verify-changesets.yml b/.github/workflows/verify-changesets.yml index a04de6ed5657..aa6e06a1521c 100644 --- a/.github/workflows/verify-changesets.yml +++ b/.github/workflows/verify-changesets.yml @@ -12,9 +12,6 @@ on: paths: - '.changeset/*.md' - - - jobs: verify-changesets: runs-on: ubuntu-latest From b98c73cffc3fdb8944efb20699fd7861542546c2 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:17:27 -0700 Subject: [PATCH 091/121] ci(verify-changeset): set cache-dependency-path --- .github/workflows/verify-changesets.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/verify-changesets.yml b/.github/workflows/verify-changesets.yml index aa6e06a1521c..0a2853aa6a4d 100644 --- a/.github/workflows/verify-changesets.yml +++ b/.github/workflows/verify-changesets.yml @@ -15,9 +15,6 @@ on: jobs: verify-changesets: runs-on: ubuntu-latest - defaults: - run: - working-directory: .github/workflows/actions/verify-changesets steps: - uses: actions/checkout@v5 with: @@ -25,14 +22,16 @@ jobs: - uses: actions/setup-node@v5 with: node-version: 'lts/*' + cache-dependency-path: .github/workflows/actions/verify-changesets/package.json - name: get all changed files from .changeset/*.md id: changeset-files run: | - echo "changed-files=$(git diff --diff-filter=dr --name-only $BASE_SHA -- '../../../../.changeset/*.md' | tr '\n' ' ')" >> $GITHUB_OUTPUT + echo "changed-files=$(git diff --diff-filter=dr --name-only $BASE_SHA -- '.changeset/*.md' | tr '\n' ' ')" >> $GITHUB_OUTPUT env: BASE_SHA: ${{ github.event.pull_request.base.sha }} - name: Verify changesets if: steps.changeset-files.outputs.changed-files != '' + working-directory: .github/workflows/actions/verify-changesets run: | node index.js env: From dfd64ba5e43676e1af3cf0ea9646aa7c39e846c4 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:22:27 -0700 Subject: [PATCH 092/121] ci(verify-changeset): set `cache` explicitly (#8806) --- .github/workflows/verify-changesets.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/verify-changesets.yml b/.github/workflows/verify-changesets.yml index 0a2853aa6a4d..cf10acc36dd2 100644 --- a/.github/workflows/verify-changesets.yml +++ b/.github/workflows/verify-changesets.yml @@ -22,6 +22,7 @@ jobs: - uses: actions/setup-node@v5 with: node-version: 'lts/*' + cache: 'npm' cache-dependency-path: .github/workflows/actions/verify-changesets/package.json - name: get all changed files from .changeset/*.md id: changeset-files From 1861f6fc45e2319b4b448f4503d751b211c91930 Mon Sep 17 00:00:00 2001 From: Daniel Amitay Date: Sun, 21 Sep 2025 15:31:25 -0400 Subject: [PATCH 093/121] feat(xai): add grok-4-fast model ids (#8801) Just adds the two new grok-4-fast model ids (reasoning and non-reasoning) to the docs and `XaiChatModelId` for the sdk. --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/two-birds-agree.md | 5 +++ .../providers/01-ai-sdk-providers/01-xai.mdx | 42 ++++++++++--------- packages/xai/src/xai-chat-options.ts | 6 +-- 3 files changed, 29 insertions(+), 24 deletions(-) create mode 100644 .changeset/two-birds-agree.md diff --git a/.changeset/two-birds-agree.md b/.changeset/two-birds-agree.md new file mode 100644 index 000000000000..34a72ae5f937 --- /dev/null +++ b/.changeset/two-birds-agree.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/xai': patch +--- + +feat(xai) add grok-4-fast model ids diff --git a/content/providers/01-ai-sdk-providers/01-xai.mdx b/content/providers/01-ai-sdk-providers/01-xai.mdx index fa4c12683df5..b4fc64bcaf52 100644 --- a/content/providers/01-ai-sdk-providers/01-xai.mdx +++ b/content/providers/01-ai-sdk-providers/01-xai.mdx @@ -394,26 +394,28 @@ console.log('Sources:', await result.sources); ## Model Capabilities -| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Reasoning | -| ------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | -| `grok-code-fast-1` | | | | | | -| `grok-4` | | | | | | -| `grok-3` | | | | | | -| `grok-3-latest` | | | | | | -| `grok-3-fast` | | | | | | -| `grok-3-fast-latest` | | | | | | -| `grok-3-mini` | | | | | | -| `grok-3-mini-latest` | | | | | | -| `grok-3-mini-fast` | | | | | | -| `grok-3-mini-fast-latest` | | | | | | -| `grok-2` | | | | | | -| `grok-2-latest` | | | | | | -| `grok-2-1212` | | | | | | -| `grok-2-vision` | | | | | | -| `grok-2-vision-latest` | | | | | | -| `grok-2-vision-1212` | | | | | | -| `grok-beta` | | | | | | -| `grok-vision-beta` | | | | | | +| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Reasoning | +| --------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | +| `grok-4-fast-non-reasoning` | | | | | | +| `grok-4-fast-reasoning` | | | | | | +| `grok-code-fast-1` | | | | | | +| `grok-4` | | | | | | +| `grok-3` | | | | | | +| `grok-3-latest` | | | | | | +| `grok-3-fast` | | | | | | +| `grok-3-fast-latest` | | | | | | +| `grok-3-mini` | | | | | | +| `grok-3-mini-latest` | | | | | | +| `grok-3-mini-fast` | | | | | | +| `grok-3-mini-fast-latest` | | | | | | +| `grok-2` | | | | | | +| `grok-2-latest` | | | | | | +| `grok-2-1212` | | | | | | +| `grok-2-vision` | | | | | | +| `grok-2-vision-latest` | | | | | | +| `grok-2-vision-1212` | | | | | | +| `grok-beta` | | | | | | +| `grok-vision-beta` | | | | | | The table above lists popular models. Please see the [xAI diff --git a/packages/xai/src/xai-chat-options.ts b/packages/xai/src/xai-chat-options.ts index b8a25ae6029a..1b2f2396334b 100644 --- a/packages/xai/src/xai-chat-options.ts +++ b/packages/xai/src/xai-chat-options.ts @@ -2,6 +2,8 @@ import { z } from 'zod/v4'; // https://console.x.ai and see "View models" export type XaiChatModelId = + | 'grok-4-fast-non-reasoning' + | 'grok-4-fast-reasoning' | 'grok-code-fast-1' | 'grok-4' | 'grok-4-0709' @@ -69,10 +71,6 @@ const searchSourceSchema = z.discriminatedUnion('type', [ // xai-specific provider options export const xaiProviderOptions = z.object({ - /** - * reasoning effort for reasoning models - * only supported by grok-3-mini and grok-3-mini-fast models - */ reasoningEffort: z.enum(['low', 'high']).optional(), searchParameters: z From 62731a8ba19c8367dba317504b214ee6aa5e679b Mon Sep 17 00:00:00 2001 From: ANKIT VARSHNEY <132201033+AVtheking@users.noreply.github.com> Date: Mon, 22 Sep 2025 01:24:01 +0530 Subject: [PATCH 094/121] feat(provider/mistral): option to disable parallel tool call in mistral (#8800) ## Background Users reported needing to force Mistral models to use tools sequentially instead of in parallel for specific use cases where tool order matters or rate limits require controlled execution. ## Summary - add `parallelToolCalls` option to Anthropic provider options ## Manual Verification - all tests pass including new disable parallel tool use test - example demonstrates sequential tool execution when option is enabled ## Checklist - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues Fixes #8663 --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/many-lamps-report.md | 5 ++ .../01-ai-sdk-providers/20-mistral.mdx | 7 +++ .../mistral-disable-parallel-tools.ts | 54 +++++++++++++++++++ .../src/mistral-chat-language-model.test.ts | 47 ++++++++++++++++ .../src/mistral-chat-language-model.ts | 3 ++ packages/mistral/src/mistral-chat-options.ts | 8 +++ 6 files changed, 124 insertions(+) create mode 100644 .changeset/many-lamps-report.md create mode 100644 examples/ai-core/src/stream-text/mistral-disable-parallel-tools.ts diff --git a/.changeset/many-lamps-report.md b/.changeset/many-lamps-report.md new file mode 100644 index 000000000000..1f9ea817b927 --- /dev/null +++ b/.changeset/many-lamps-report.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/mistral': patch +--- + +Add option for disabling parallel tool call in mistral diff --git a/content/providers/01-ai-sdk-providers/20-mistral.mdx b/content/providers/01-ai-sdk-providers/20-mistral.mdx index e8d16e44c1d6..dafe5f2c730e 100644 --- a/content/providers/01-ai-sdk-providers/20-mistral.mdx +++ b/content/providers/01-ai-sdk-providers/20-mistral.mdx @@ -91,6 +91,7 @@ await generateText({ providerOptions: { mistral: { safePrompt: true, // optional safety prompt injection + parallelToolCalls: false, // disable parallel tool calls (one tool per response) } satisfies MistralLanguageModelOptions, }, }); @@ -124,6 +125,12 @@ The following optional provider options are available for Mistral models: Defaults to `true`. +- **parallelToolCalls** _boolean_ + + Whether to enable parallel function calling during tool use. When set to false, the model will use at most one tool per response. + + Defaults to `true`. + ### Document OCR Mistral chat models support document OCR for PDF files. diff --git a/examples/ai-core/src/stream-text/mistral-disable-parallel-tools.ts b/examples/ai-core/src/stream-text/mistral-disable-parallel-tools.ts new file mode 100644 index 000000000000..bab8efabbe63 --- /dev/null +++ b/examples/ai-core/src/stream-text/mistral-disable-parallel-tools.ts @@ -0,0 +1,54 @@ +import { streamText, tool } from 'ai'; +import { z } from 'zod'; +import 'dotenv/config'; +import { mistral } from '@ai-sdk/mistral'; + +async function main() { + const result = streamText({ + model: mistral('mistral-small-latest'), + prompt: 'What is the weather in Paris, France and London, UK?', + tools: { + getWeather: tool({ + description: 'Get the current weather for a location', + inputSchema: z.object({ + location: z + .string() + .describe('The city and state, e.g. San Francisco, CA'), + }), + execute: async ({ location }: { location: string }) => { + return `Weather in ${location}: 72°F, sunny`; + }, + }), + }, + providerOptions: { + mistral: { + parallelToolCalls: false, + }, + }, + }); + + for await (const chunk of result.fullStream) { + switch (chunk.type) { + case 'text-delta': { + process.stdout.write(chunk.text); + break; + } + case 'tool-call': { + console.log( + `\nTOOL CALL: ${chunk.toolName}(${JSON.stringify(chunk.input)})`, + ); + break; + } + case 'tool-result': { + console.log(`TOOL RESULT: ${JSON.stringify(chunk.output)}`); + break; + } + } + } + + console.log(); + console.log('Token usage:', await result.usage); + console.log('Finish reason:', await result.finishReason); +} + +main().catch(console.error); diff --git a/packages/mistral/src/mistral-chat-language-model.test.ts b/packages/mistral/src/mistral-chat-language-model.test.ts index 152e36f50da8..986b1947a0a4 100644 --- a/packages/mistral/src/mistral-chat-language-model.test.ts +++ b/packages/mistral/src/mistral-chat-language-model.test.ts @@ -680,6 +680,53 @@ describe('doGenerate', () => { ] `); }); + + it('should pass parallelToolCalls option', async () => { + prepareJsonResponse({ content: '' }); + + await model.doGenerate({ + tools: [ + { + type: 'function', + name: 'test-tool', + inputSchema: { + type: 'object', + properties: { value: { type: 'string' } }, + required: ['value'], + additionalProperties: false, + $schema: 'http://json-schema.org/draft-07/schema#', + }, + }, + ], + prompt: TEST_PROMPT, + providerOptions: { + mistral: { + parallelToolCalls: false, + }, + }, + }); + + expect(await server.calls[0].requestBodyJson).toMatchObject({ + model: 'mistral-small-latest', + messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }], + tools: [ + { + type: 'function', + function: { + name: 'test-tool', + parameters: { + type: 'object', + properties: { value: { type: 'string' } }, + required: ['value'], + additionalProperties: false, + $schema: 'http://json-schema.org/draft-07/schema#', + }, + }, + }, + ], + parallel_tool_calls: false, + }); + }); }); describe('doStream', () => { diff --git a/packages/mistral/src/mistral-chat-language-model.ts b/packages/mistral/src/mistral-chat-language-model.ts index 5e50b6e8d357..1acf029db294 100644 --- a/packages/mistral/src/mistral-chat-language-model.ts +++ b/packages/mistral/src/mistral-chat-language-model.ts @@ -173,6 +173,9 @@ export class MistralChatLanguageModel implements LanguageModelV2 { ...baseArgs, tools: mistralTools, tool_choice: mistralToolChoice, + ...(mistralTools != null && options.parallelToolCalls !== undefined + ? { parallel_tool_calls: options.parallelToolCalls } + : {}), }, warnings: [...warnings, ...toolWarnings], }; diff --git a/packages/mistral/src/mistral-chat-options.ts b/packages/mistral/src/mistral-chat-options.ts index 0433f7695851..5cd15a543e7a 100644 --- a/packages/mistral/src/mistral-chat-options.ts +++ b/packages/mistral/src/mistral-chat-options.ts @@ -48,6 +48,14 @@ Defaults to `false`. * @default false */ strictJsonSchema: z.boolean().optional(), + + /** + * Whether to enable parallel function calling during tool use. + * When set to false, the model will use at most one tool per response. + * + * @default true + */ + parallelToolCalls: z.boolean().optional(), }); export type MistralLanguageModelOptions = z.infer< From 61a16427ad1838d274fe2718ace3e3afc5f83d58 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 17:00:51 -0700 Subject: [PATCH 095/121] Version Packages (beta) (#8808) # Releases ## @ai-sdk/mistral@2.1.0-beta.2 ### Patch Changes - 62731a8: Add option for disabling parallel tool call in mistral ## @ai-sdk/xai@2.1.0-beta.2 ### Patch Changes - 1861f6f: feat(xai) add grok-4-fast model ids Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 2 ++ packages/mistral/CHANGELOG.md | 6 ++++++ packages/mistral/package.json | 2 +- packages/xai/CHANGELOG.md | 6 ++++++ packages/xai/package.json | 2 +- 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 6aa672bed7c6..16e31508bbd3 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -77,12 +77,14 @@ "curly-glasses-count", "four-candles-buy", "grumpy-actors-sleep", + "many-lamps-report", "neat-news-visit", "old-kiwis-hide", "quiet-pens-suffer", "red-roses-glow", "selfish-beers-mate", "shaggy-emus-try", + "two-birds-agree", "wise-jobs-knock" ] } diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index 0a1025187431..d3bd06a40273 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/mistral +## 2.1.0-beta.2 + +### Patch Changes + +- 62731a8: Add option for disabling parallel tool call in mistral + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 457c0ff0d6ab..6c96d329973c 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 67357c043849..2bce7bbf7840 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/xai +## 2.1.0-beta.2 + +### Patch Changes + +- 1861f6f: feat(xai) add grok-4-fast model ids + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 47f7b4df3f6d..828af5a8d01f 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From aec4b58a80eb6f5ce60978a9168b805403cfa26a Mon Sep 17 00:00:00 2001 From: Prince Carlo Juguilon <47204120+princejoogie@users.noreply.github.com> Date: Mon, 22 Sep 2025 22:53:55 +0800 Subject: [PATCH 096/121] docs(examples): typo (#8819) --- .../next-openai/app/api/use-chat-streaming-tool-calls/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts b/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts index bd66360eca2f..666cf065e6a9 100644 --- a/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts +++ b/examples/next-openai/app/api/use-chat-streaming-tool-calls/route.ts @@ -44,7 +44,7 @@ export async function POST(req: Request) { }; }, }, - // client-side tool that displays whether information to the user: + // client-side tool that displays weather information to the user: showWeatherInformation: { description: 'Show the weather information to the user. Always use this tool to tell weather information to the user.', From db7409028e2501d269b8d75b3d0c95432caa3c66 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Mon, 22 Sep 2025 11:29:33 -0700 Subject: [PATCH 097/121] ci(triage): do not comment on pull requests by team members (#8779) --- .github/workflows/triage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index a1d1dac18315..79136f71e5ab 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -92,7 +92,7 @@ jobs: GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Add comment if no provider detected - if: fromJSON(steps.classify-issue.outputs.json).confidence <= 0.6 + if: fromJSON(steps.classify-issue.outputs.json).confidence <= 0.6 && github.event.issue.author_association != 'MEMBER' run: | gh api /repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments \ --method POST \ From 6c766ef53990db98a8ef289bc950569de9723732 Mon Sep 17 00:00:00 2001 From: Rohan Taneja <47066511+R-Taneja@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:58:47 -0700 Subject: [PATCH 098/121] feat(provider/gateway): Add DeepSeek V3.1 Terminus to Gateway autocomplete (#8825) ## Background DeepSeek released a new model ## Summary Added it to the Gateway model string autocomplete ## Manual Verification Autocomplete works ## Checklist - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) --- .changeset/soft-glasses-happen.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/soft-glasses-happen.md diff --git a/.changeset/soft-glasses-happen.md b/.changeset/soft-glasses-happen.md new file mode 100644 index 000000000000..1bd825e7ed6b --- /dev/null +++ b/.changeset/soft-glasses-happen.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat(provider/gateway): Add DeepSeek V3.1 Terminus to Gateway autocomplete diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index 4e3d540516d4..76c50a29cc85 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -27,6 +27,7 @@ export type GatewayModelId = | 'deepseek/deepseek-v3.1' | 'deepseek/deepseek-v3.1-base' | 'deepseek/deepseek-v3.1-thinking' + | 'deepseek/deepseek-v3.1-terminus' | 'google/gemini-2.0-flash' | 'google/gemini-2.0-flash-lite' | 'google/gemini-2.5-flash' From 7ccb36f619b5dd7ac68a04f748fcd156c43451c9 Mon Sep 17 00:00:00 2001 From: Rohan Taneja <47066511+R-Taneja@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:22:04 -0700 Subject: [PATCH 099/121] Add LongCat Thinking model to Gateway autocomplete (#8822) ## Background New LongCat model was released ## Summary Adds it to Gateway autocomplete ## Manual Verification Autocomplete works ## Checklist - [X] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) --- .changeset/itchy-monkeys-nail.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/itchy-monkeys-nail.md diff --git a/.changeset/itchy-monkeys-nail.md b/.changeset/itchy-monkeys-nail.md new file mode 100644 index 000000000000..f23122a14716 --- /dev/null +++ b/.changeset/itchy-monkeys-nail.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat(provider/gateway): Add LongCat Thinking model to Gateway autocomplete diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index 76c50a29cc85..6a5d4ce38919 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -37,6 +37,7 @@ export type GatewayModelId = | 'google/gemma-2-9b' | 'inception/mercury-coder-small' | 'meituan/longcat-flash-chat' + | 'meituan/longcat-flash-thinking' | 'meta/llama-3-70b' | 'meta/llama-3-8b' | 'meta/llama-3.1-70b' From e8fb1e8cc5ef49f0d300ec984ca468553544ce8c Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 20:31:08 -0700 Subject: [PATCH 100/121] Version Packages (beta) (#8826) # Releases ## ai@5.1.0-beta.5 ### Patch Changes - Updated dependencies [7ccb36f] - Updated dependencies [6c766ef] - @ai-sdk/gateway@1.1.0-beta.4 ## @ai-sdk/angular@1.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 ## @ai-sdk/gateway@1.1.0-beta.4 ### Patch Changes - 7ccb36f: feat(provider/gateway): Add LongCat Thinking model to Gateway autocomplete - 6c766ef: feat(provider/gateway): Add DeepSeek V3.1 Terminus to Gateway autocomplete ## @ai-sdk/langchain@1.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 ## @ai-sdk/llamaindex@1.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 ## @ai-sdk/react@2.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 ## @ai-sdk/rsc@1.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 ## @ai-sdk/svelte@3.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 ## @ai-sdk/vue@2.1.0-beta.5 ### Patch Changes - ai@5.1.0-beta.5 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 2 ++ packages/ai/CHANGELOG.md | 8 ++++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 6 ++++++ packages/angular/package.json | 2 +- packages/gateway/CHANGELOG.md | 7 +++++++ packages/gateway/package.json | 2 +- packages/langchain/CHANGELOG.md | 6 ++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 6 ++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 6 ++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 6 ++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 6 ++++++ packages/svelte/CHANGELOG.md | 6 ++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 6 ++++++ packages/vue/package.json | 2 +- 20 files changed, 74 insertions(+), 9 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 16e31508bbd3..64be33c16952 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -77,6 +77,7 @@ "curly-glasses-count", "four-candles-buy", "grumpy-actors-sleep", + "itchy-monkeys-nail", "many-lamps-report", "neat-news-visit", "old-kiwis-hide", @@ -84,6 +85,7 @@ "red-roses-glow", "selfish-beers-mate", "shaggy-emus-try", + "soft-glasses-happen", "two-birds-agree", "wise-jobs-knock" ] diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 0f0ab5bb29c2..3d74cc644772 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,13 @@ # ai +## 5.1.0-beta.5 + +### Patch Changes + +- Updated dependencies [7ccb36f] +- Updated dependencies [6c766ef] + - @ai-sdk/gateway@1.1.0-beta.4 + ## 5.1.0-beta.4 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 43c1fb882231..89e20f6e963e 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.4", + "version": "5.1.0-beta.5", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index a04d01538693..934fde3028cc 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/angular +## 1.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 1.1.0-beta.4 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 22aebfe64baf..63b757ca1548 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.4", + "version": "1.1.0-beta.5", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index 13a0c0ef0f28..e88038629b58 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/gateway +## 1.1.0-beta.4 + +### Patch Changes + +- 7ccb36f: feat(provider/gateway): Add LongCat Thinking model to Gateway autocomplete +- 6c766ef: feat(provider/gateway): Add DeepSeek V3.1 Terminus to Gateway autocomplete + ## 1.1.0-beta.3 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 5496d1722ab1..3f75efa6d42b 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.1.0-beta.3", + "version": "1.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index e8345633af6e..aaf9ca8ac907 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/langchain +## 1.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 1.1.0-beta.4 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 138e1521de37..138f4e7bcabc 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.4", + "version": "1.1.0-beta.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 5b8fc2467fa6..610994bc3ea8 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 1.1.0-beta.4 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 932f6037c2b7..c889e6af03b3 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.4", + "version": "1.1.0-beta.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index e6ac964d85ef..3184b38814e6 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/react +## 2.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 2.1.0-beta.4 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 6501c08d812f..bb9992530dad 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.4", + "version": "2.1.0-beta.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index db8e4059fae0..a215b9a5b085 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/rsc +## 1.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 1.1.0-beta.4 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 80ac81ae84d5..e62189ffba6a 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.4", + "version": "1.1.0-beta.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index b7e8b8fb3332..7a627b5cea70 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,12 @@ ### Patch Changes +- ai@5.1.0-beta.5 + +## 0.0.1-beta.0 + +### Patch Changes + - ai@5.1.0-beta.4 ## 0.0.1-beta.0 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index ed83bbe2b10d..d0b8e0a03ab2 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/svelte +## 3.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 3.1.0-beta.4 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index dca4d7ba7979..e4669b188792 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.4", + "version": "3.1.0-beta.5", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index b2c9732346f4..7874c5d156bc 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/vue +## 2.1.0-beta.5 + +### Patch Changes + +- ai@5.1.0-beta.5 + ## 2.1.0-beta.4 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index c8e96a90d930..31971e7a1b86 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.4", + "version": "2.1.0-beta.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 0c4822dfbe2819ec6562245bfece4061373b1bc4 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Tue, 23 Sep 2025 12:43:17 -0400 Subject: [PATCH 101/121] feat(spec): `EmbeddingModelV3` (#8837) ## Background #8763 #8764 ## Summary Replace `EmbeddingModelV2` with `EmbeddingModelV3` ## Checklist - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Related Issues Fixes #8764 towards #8763 --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- .changeset/funny-olives-reply.md | 20 ++++ content/docs/03-ai-sdk-core/55-testing.mdx | 2 +- .../30-model-is-not-assignable-to-type.mdx | 2 +- .../01-custom-providers.mdx | 4 +- .../01-custom-providers.mdx | 4 +- .../ai-core/src/e2e/feature-test-suite.ts | 8 +- packages/ai/src/embed/embed-many.test.ts | 40 +++---- packages/ai/src/embed/embed.test.ts | 30 ++--- packages/ai/src/model/resolve-model.test.ts | 6 +- packages/ai/src/model/resolve-model.ts | 8 +- .../ai/src/registry/custom-provider.test.ts | 4 +- packages/ai/src/registry/custom-provider.ts | 8 +- .../ai/src/registry/provider-registry.test.ts | 6 +- packages/ai/src/registry/provider-registry.ts | 8 +- .../ai/src/test/mock-embedding-model-v2.ts | 26 ++-- packages/ai/src/test/mock-provider-v2.ts | 4 +- packages/ai/src/types/embedding-model.ts | 6 +- packages/ai/src/types/usage.ts | 2 +- packages/ai/test/index.ts | 2 +- .../src/bedrock-embedding-model.ts | 10 +- .../amazon-bedrock/src/bedrock-provider.ts | 4 +- .../azure/src/azure-openai-provider.test.ts | 4 +- packages/azure/src/azure-openai-provider.ts | 8 +- packages/baseten/src/baseten-provider.ts | 4 +- .../baseten/src/baseten-provider.unit.test.ts | 2 +- .../cohere/src/cohere-embedding-model.test.ts | 4 +- packages/cohere/src/cohere-embedding-model.ts | 10 +- packages/cohere/src/cohere-provider.ts | 6 +- .../deepinfra/src/deepinfra-provider.test.ts | 8 +- packages/deepinfra/src/deepinfra-provider.ts | 4 +- .../fireworks/src/fireworks-provider.test.ts | 8 +- packages/fireworks/src/fireworks-provider.ts | 4 +- .../gateway/src/gateway-embedding-model.ts | 10 +- packages/gateway/src/gateway-provider.ts | 4 +- .../src/google-vertex-embedding-model.test.ts | 4 +- .../src/google-vertex-embedding-model.ts | 10 +- ...ogle-generative-ai-embedding-model.test.ts | 6 +- .../google-generative-ai-embedding-model.ts | 10 +- packages/google/src/google-provider.ts | 8 +- .../src/mistral-embedding-model.test.ts | 4 +- .../mistral/src/mistral-embedding-model.ts | 10 +- packages/mistral/src/mistral-provider.ts | 8 +- .../openai-compatible-embedding-model.test.ts | 4 +- .../openai-compatible-embedding-model.ts | 10 +- .../src/openai-compatible-provider.ts | 4 +- .../embedding/openai-embedding-model.test.ts | 4 +- .../src/embedding/openai-embedding-model.ts | 10 +- packages/openai/src/openai-provider.ts | 8 +- .../provider/src/embedding-model/index.ts | 1 + .../v3/embedding-model-v3-embedding.ts | 5 + .../embedding-model/v3/embedding-model-v3.ts | 113 ++++++++++++++++++ .../provider/src/embedding-model/v3/index.ts | 2 + .../provider/src/provider/v2/provider-v2.ts | 4 +- .../src/togetherai-provider.test.ts | 8 +- .../togetherai/src/togetherai-provider.ts | 4 +- 55 files changed, 329 insertions(+), 188 deletions(-) create mode 100644 .changeset/funny-olives-reply.md create mode 100644 packages/provider/src/embedding-model/v3/embedding-model-v3-embedding.ts create mode 100644 packages/provider/src/embedding-model/v3/embedding-model-v3.ts create mode 100644 packages/provider/src/embedding-model/v3/index.ts diff --git a/.changeset/funny-olives-reply.md b/.changeset/funny-olives-reply.md new file mode 100644 index 000000000000..1dfaf63b225f --- /dev/null +++ b/.changeset/funny-olives-reply.md @@ -0,0 +1,20 @@ +--- +'@ai-sdk/openai-compatible': patch +'@ai-sdk/amazon-bedrock': patch +'@ai-sdk/google-vertex': patch +'@ai-sdk/togetherai': patch +'@ai-sdk/deepinfra': patch +'@ai-sdk/fireworks': patch +'@ai-sdk/provider': patch +'@example/ai-core': patch +'@ai-sdk/baseten': patch +'@ai-sdk/gateway': patch +'@ai-sdk/mistral': patch +'@ai-sdk/cohere': patch +'@ai-sdk/google': patch +'@ai-sdk/openai': patch +'@ai-sdk/azure': patch +'ai': patch +--- + +feat: `EmbeddingModelV3` diff --git a/content/docs/03-ai-sdk-core/55-testing.mdx b/content/docs/03-ai-sdk-core/55-testing.mdx index 2be962fa7be5..2c8a7e349bd7 100644 --- a/content/docs/03-ai-sdk-core/55-testing.mdx +++ b/content/docs/03-ai-sdk-core/55-testing.mdx @@ -11,7 +11,7 @@ and calling them is slow and expensive. To enable you to unit test your code that uses the AI SDK, the AI SDK Core includes mock providers and test helpers. You can import the following helpers from `ai/test`: -- `MockEmbeddingModelV2`: A mock embedding model using the [embedding model v2 specification](https://github.com/vercel/ai/blob/v5/packages/provider/src/embedding-model/v2/embedding-model-v2.ts). +- `MockEmbeddingModelV3`: A mock embedding model using the [embedding model v3 specification](https://github.com/vercel/ai/blob/v5/packages/provider/src/embedding-model/v3/embedding-model-v3.ts). - `MockLanguageModelV2`: A mock language model using the [language model v2 specification](https://github.com/vercel/ai/blob/v5/packages/provider/src/language-model/v2/language-model-v2.ts). - `mockId`: Provides an incrementing integer ID. - `mockValues`: Iterates over an array of values with each call. Returns the last value when the array is exhausted. diff --git a/content/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx b/content/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx index 4255a4c3e2fa..bd1b40a39c6f 100644 --- a/content/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx +++ b/content/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx @@ -9,7 +9,7 @@ description: Troubleshooting errors related to incompatible models. I have updated the AI SDK and now I get the following error: `Type 'SomeModel' is not assignable to type 'LanguageModelV1'.` -Similar errors can occur with `EmbeddingModelV2` as well. +Similar errors can occur with `EmbeddingModelV3` as well. ## Background diff --git a/content/providers/02-openai-compatible-providers/01-custom-providers.mdx b/content/providers/02-openai-compatible-providers/01-custom-providers.mdx index 328966fa82f8..456f5d498243 100644 --- a/content/providers/02-openai-compatible-providers/01-custom-providers.mdx +++ b/content/providers/02-openai-compatible-providers/01-custom-providers.mdx @@ -41,7 +41,7 @@ The completion, embedding, and image settings are implemented similarly to the c 2. **example-provider.ts** - Main provider implementation: ```ts -import { LanguageModelV1, EmbeddingModelV2 } from '@ai-sdk/provider'; +import { LanguageModelV1, EmbeddingModelV3 } from '@ai-sdk/provider'; import { OpenAICompatibleChatLanguageModel, OpenAICompatibleCompletionLanguageModel, @@ -110,7 +110,7 @@ Creates a text embedding model for text generation. textEmbeddingModel( modelId: ExampleEmbeddingModelId, settings?: ExampleEmbeddingSettings, - ): EmbeddingModelV2; + ): EmbeddingModelV3; /** Creates an image model for image generation. diff --git a/content/providers/03-community-providers/01-custom-providers.mdx b/content/providers/03-community-providers/01-custom-providers.mdx index 4e2d77e064c7..9582afe44223 100644 --- a/content/providers/03-community-providers/01-custom-providers.mdx +++ b/content/providers/03-community-providers/01-custom-providers.mdx @@ -31,7 +31,7 @@ At its heart, the V2 specification defines three main interfaces: 1. **ProviderV2**: The top-level interface that serves as a factory for different model types 2. **LanguageModelV2**: The primary interface for text generation models -3. **EmbeddingModelV2** and **ImageModelV2**: Interfaces for embeddings and image generation +3. **EmbeddingModelV3** and **ImageModelV2**: Interfaces for embeddings and image generation ### `ProviderV2` @@ -40,7 +40,7 @@ The `ProviderV2` interface acts as the entry point: ```ts interface ProviderV2 { languageModel(modelId: string): LanguageModelV2; - textEmbeddingModel(modelId: string): EmbeddingModelV2; + textEmbeddingModel(modelId: string): EmbeddingModelV3; imageModel(modelId: string): ImageModelV2; } ``` diff --git a/examples/ai-core/src/e2e/feature-test-suite.ts b/examples/ai-core/src/e2e/feature-test-suite.ts index d4a27801bb5b..4d9def868bcd 100644 --- a/examples/ai-core/src/e2e/feature-test-suite.ts +++ b/examples/ai-core/src/e2e/feature-test-suite.ts @@ -1,6 +1,6 @@ import type { GoogleGenerativeAIProviderMetadata } from '@ai-sdk/google'; import type { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, } from '@ai-sdk/provider'; @@ -58,9 +58,9 @@ export const createLanguageModelWithCapabilities = ( }); export const createEmbeddingModelWithCapabilities = ( - model: EmbeddingModelV2, + model: EmbeddingModelV3, capabilities: ModelCapabilities = ['embedding'], -): ModelWithCapabilities> => ({ +): ModelWithCapabilities> => ({ model, capabilities, }); @@ -76,7 +76,7 @@ export const createImageModelWithCapabilities = ( export interface ModelVariants { invalidModel?: LanguageModelV2; languageModels?: ModelWithCapabilities[]; - embeddingModels?: ModelWithCapabilities>[]; + embeddingModels?: ModelWithCapabilities>[]; invalidImageModel?: ImageModelV2; imageModels?: ModelWithCapabilities[]; } diff --git a/packages/ai/src/embed/embed-many.test.ts b/packages/ai/src/embed/embed-many.test.ts index e72d2c288cfb..599ed905e795 100644 --- a/packages/ai/src/embed/embed-many.test.ts +++ b/packages/ai/src/embed/embed-many.test.ts @@ -1,7 +1,7 @@ -import { EmbeddingModelV2 } from '@ai-sdk/provider'; +import { EmbeddingModelV3 } from '@ai-sdk/provider'; import assert from 'node:assert'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; import { MockTracer } from '../test/mock-tracer'; import { Embedding, EmbeddingModelUsage } from '../types'; import { createResolvablePromise } from '../util/create-resolvable-promise'; @@ -37,7 +37,7 @@ describe('model.supportsParallelCalls', () => { ]; const embedManyPromise = embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ supportsParallelCalls: false, maxEmbeddingsPerCall: 1, doEmbed: async () => { @@ -85,7 +85,7 @@ describe('model.supportsParallelCalls', () => { ]; const embedManyPromise = embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ supportsParallelCalls: true, maxEmbeddingsPerCall: 1, doEmbed: async () => { @@ -134,7 +134,7 @@ describe('model.supportsParallelCalls', () => { const embedManyPromise = embedMany({ maxParallelCalls: 2, - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ supportsParallelCalls: true, maxEmbeddingsPerCall: 1, doEmbed: async () => { @@ -175,7 +175,7 @@ describe('model.supportsParallelCalls', () => { describe('result.embedding', () => { it('should generate embeddings', async () => { const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 5, doEmbed: mockEmbed(testValues, dummyEmbeddings), }), @@ -189,7 +189,7 @@ describe('result.embedding', () => { let callCount = 0; const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 2, doEmbed: async ({ values }) => { switch (callCount++) { @@ -215,7 +215,7 @@ describe('result.responses', () => { it('should include responses in the result', async () => { let callCount = 0; const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 1, doEmbed: async ({ values }) => { @@ -259,7 +259,7 @@ describe('result.responses', () => { describe('result.values', () => { it('should include values in the result', async () => { const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 5, doEmbed: mockEmbed(testValues, dummyEmbeddings), }), @@ -275,7 +275,7 @@ describe('result.usage', () => { let callCount = 0; const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 2, doEmbed: async () => { switch (callCount++) { @@ -304,7 +304,7 @@ describe('result.usage', () => { describe('options.headers', () => { it('should set headers', async () => { const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 5, doEmbed: async ({ headers }) => { assert.deepStrictEqual(headers, { @@ -327,7 +327,7 @@ describe('options.headers', () => { describe('options.providerOptions', () => { it('should pass provider options to model', async () => { - const model = new MockEmbeddingModelV2({ + const model = new MockEmbeddingModelV3({ doEmbed: async ({ providerOptions }) => { return { embeddings: [[1, 2, 3]] }; }, @@ -365,7 +365,7 @@ describe('telemetry', () => { it('should not record any telemetry data when not explicitly enabled', async () => { await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 5, doEmbed: mockEmbed(testValues, dummyEmbeddings), }), @@ -379,7 +379,7 @@ describe('telemetry', () => { let callCount = 0; await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: 2, doEmbed: async ({ values }) => { switch (callCount++) { @@ -417,7 +417,7 @@ describe('telemetry', () => { it('should record telemetry data when enabled (single call path)', async () => { await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: null, doEmbed: mockEmbed(testValues, dummyEmbeddings, { tokens: 10 }), }), @@ -438,7 +438,7 @@ describe('telemetry', () => { it('should not record telemetry inputs / outputs when disabled', async () => { await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ maxEmbeddingsPerCall: null, doEmbed: mockEmbed(testValues, dummyEmbeddings, { tokens: 10 }), }), @@ -462,7 +462,7 @@ describe('result.providerMetadata', () => { }; const result = await embedMany({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ supportsParallelCalls: false, maxEmbeddingsPerCall: 3, doEmbed: mockEmbed( @@ -488,12 +488,12 @@ function mockEmbed( embeddings: Array, usage?: EmbeddingModelUsage, response: Awaited< - ReturnType['doEmbed']> + ReturnType['doEmbed']> >['response'] = { headers: {}, body: {} }, providerMetadata?: Awaited< - ReturnType['doEmbed']> + ReturnType['doEmbed']> >['providerMetadata'], -): EmbeddingModelV2['doEmbed'] { +): EmbeddingModelV3['doEmbed'] { return async ({ values }) => { assert.deepStrictEqual(expectedValues, values); return { embeddings, usage, response, providerMetadata }; diff --git a/packages/ai/src/embed/embed.test.ts b/packages/ai/src/embed/embed.test.ts index 9fd478c68af6..b70a141be332 100644 --- a/packages/ai/src/embed/embed.test.ts +++ b/packages/ai/src/embed/embed.test.ts @@ -1,7 +1,7 @@ -import { EmbeddingModelV2 } from '@ai-sdk/provider'; +import { EmbeddingModelV3 } from '@ai-sdk/provider'; import assert from 'node:assert'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; import { MockTracer } from '../test/mock-tracer'; import { Embedding, EmbeddingModelUsage } from '../types'; import { embed } from './embed'; @@ -18,7 +18,7 @@ vi.mock('../version', () => { describe('result.embedding', () => { it('should generate embedding', async () => { const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding]), }), value: testValue, @@ -31,7 +31,7 @@ describe('result.embedding', () => { describe('result.response', () => { it('should include response in the result', async () => { const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding], undefined, { body: { foo: 'bar' }, headers: { foo: 'bar' }, @@ -56,7 +56,7 @@ describe('result.response', () => { describe('result.value', () => { it('should include value in the result', async () => { const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding]), }), value: testValue, @@ -69,7 +69,7 @@ describe('result.value', () => { describe('result.usage', () => { it('should include usage in the result', async () => { const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding], { tokens: 10 }), }), value: testValue, @@ -90,7 +90,7 @@ describe('result.providerMetadata', () => { }; const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed( [testValue], [dummyEmbedding], @@ -112,7 +112,7 @@ describe('result.providerMetadata', () => { describe('options.headers', () => { it('should set headers', async () => { const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: async ({ headers }) => { assert.deepStrictEqual(headers, { 'custom-request-header': 'request-header-value', @@ -135,7 +135,7 @@ describe('options.headers', () => { describe('options.providerOptions', () => { it('should pass provider options to model', async () => { const result = await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: async ({ providerOptions }) => { expect(providerOptions).toStrictEqual({ aProvider: { someKey: 'someValue' }, @@ -163,7 +163,7 @@ describe('telemetry', () => { it('should not record any telemetry data when not explicitly enabled', async () => { await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding]), }), value: testValue, @@ -175,7 +175,7 @@ describe('telemetry', () => { it('should record telemetry data when enabled', async () => { await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding], { tokens: 10 }), }), value: testValue, @@ -195,7 +195,7 @@ describe('telemetry', () => { it('should not record telemetry inputs / outputs when disabled', async () => { await embed({ - model: new MockEmbeddingModelV2({ + model: new MockEmbeddingModelV3({ doEmbed: mockEmbed([testValue], [dummyEmbedding], { tokens: 10 }), }), value: testValue, @@ -216,12 +216,12 @@ function mockEmbed( embeddings: Array, usage?: EmbeddingModelUsage, response: Awaited< - ReturnType['doEmbed']> + ReturnType['doEmbed']> >['response'] = { headers: {}, body: {} }, providerMetadata?: Awaited< - ReturnType['doEmbed']> + ReturnType['doEmbed']> >['providerMetadata'], -): EmbeddingModelV2['doEmbed'] { +): EmbeddingModelV3['doEmbed'] { return async ({ values }) => { assert.deepStrictEqual(expectedValues, values); return { embeddings, usage, response, providerMetadata }; diff --git a/packages/ai/src/model/resolve-model.test.ts b/packages/ai/src/model/resolve-model.test.ts index f47de854c78f..b7edb3710a4e 100644 --- a/packages/ai/src/model/resolve-model.test.ts +++ b/packages/ai/src/model/resolve-model.test.ts @@ -1,5 +1,5 @@ import { customProvider } from '../registry/custom-provider'; -import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { resolveEmbeddingModel, resolveLanguageModel } from './resolve-model'; import { beforeEach, afterEach, describe, expect, it } from 'vitest'; @@ -57,7 +57,7 @@ describe('resolveEmbeddingModel', () => { describe('when a embedding model v2 is provided', () => { it('should return the embedding model v2', () => { const resolvedModel = resolveEmbeddingModel( - new MockEmbeddingModelV2({ + new MockEmbeddingModelV3({ provider: 'test-provider', modelId: 'test-model-id', }), @@ -81,7 +81,7 @@ describe('resolveEmbeddingModel', () => { beforeEach(() => { globalThis.AI_SDK_DEFAULT_PROVIDER = customProvider({ textEmbeddingModels: { - 'test-model-id': new MockEmbeddingModelV2({ + 'test-model-id': new MockEmbeddingModelV3({ provider: 'global-test-provider', modelId: 'actual-test-model-id', }), diff --git a/packages/ai/src/model/resolve-model.ts b/packages/ai/src/model/resolve-model.ts index cd95bf217041..4da0906a7cb4 100644 --- a/packages/ai/src/model/resolve-model.ts +++ b/packages/ai/src/model/resolve-model.ts @@ -1,6 +1,6 @@ import { gateway } from '@ai-sdk/gateway'; import { - EmbeddingModelV2, + EmbeddingModelV3, LanguageModelV2, ProviderV2, } from '@ai-sdk/provider'; @@ -26,9 +26,9 @@ export function resolveLanguageModel(model: LanguageModel): LanguageModelV2 { export function resolveEmbeddingModel( model: EmbeddingModel, -): EmbeddingModelV2 { +): EmbeddingModelV3 { if (typeof model !== 'string') { - if (model.specificationVersion !== 'v2') { + if (model.specificationVersion !== 'v3') { throw new UnsupportedModelVersionError({ version: model.specificationVersion, provider: model.provider, @@ -42,7 +42,7 @@ export function resolveEmbeddingModel( // TODO AI SDK 6: figure out how to cleanly support different generic types return getGlobalProvider().textEmbeddingModel( model, - ) as EmbeddingModelV2; + ) as EmbeddingModelV3; } function getGlobalProvider(): ProviderV2 { diff --git a/packages/ai/src/registry/custom-provider.test.ts b/packages/ai/src/registry/custom-provider.test.ts index 8a4a0986454a..1e1edfc3a282 100644 --- a/packages/ai/src/registry/custom-provider.test.ts +++ b/packages/ai/src/registry/custom-provider.test.ts @@ -1,6 +1,6 @@ import { NoSuchModelError } from '@ai-sdk/provider'; import { describe, expect, it, vi } from 'vitest'; -import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; import { MockImageModelV2 } from '../test/mock-image-model-v2'; import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { MockTranscriptionModelV2 } from '../test/mock-transcription-model-v2'; @@ -8,7 +8,7 @@ import { MockSpeechModelV2 } from '../test/mock-speech-model-v2'; import { customProvider } from './custom-provider'; const mockLanguageModel = new MockLanguageModelV2(); -const mockEmbeddingModel = new MockEmbeddingModelV2(); +const mockEmbeddingModel = new MockEmbeddingModelV3(); const mockFallbackProvider = { languageModel: vi.fn(), textEmbeddingModel: vi.fn(), diff --git a/packages/ai/src/registry/custom-provider.ts b/packages/ai/src/registry/custom-provider.ts index b235d5e7c26c..6b2efd4f8274 100644 --- a/packages/ai/src/registry/custom-provider.ts +++ b/packages/ai/src/registry/custom-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, NoSuchModelError, @@ -24,7 +24,7 @@ import { */ export function customProvider< LANGUAGE_MODELS extends Record, - EMBEDDING_MODELS extends Record>, + EMBEDDING_MODELS extends Record>, IMAGE_MODELS extends Record, TRANSCRIPTION_MODELS extends Record, SPEECH_MODELS extends Record, @@ -46,7 +46,7 @@ export function customProvider< languageModel(modelId: ExtractModelId): LanguageModelV2; textEmbeddingModel( modelId: ExtractModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; imageModel(modelId: ExtractModelId): ImageModelV2; transcriptionModel( modelId: ExtractModelId, @@ -68,7 +68,7 @@ export function customProvider< textEmbeddingModel( modelId: ExtractModelId, - ): EmbeddingModelV2 { + ): EmbeddingModelV3 { if (textEmbeddingModels != null && modelId in textEmbeddingModels) { return textEmbeddingModels[modelId]; } diff --git a/packages/ai/src/registry/provider-registry.test.ts b/packages/ai/src/registry/provider-registry.test.ts index 6ada32d2a854..b83a6571dbd4 100644 --- a/packages/ai/src/registry/provider-registry.test.ts +++ b/packages/ai/src/registry/provider-registry.test.ts @@ -1,5 +1,5 @@ import { NoSuchModelError } from '@ai-sdk/provider'; -import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { NoSuchProviderError } from './no-such-provider-error'; import { createProviderRegistry } from './provider-registry'; @@ -159,7 +159,7 @@ describe('languageModel', () => { describe('textEmbeddingModel', () => { it('should return embedding model from provider using textEmbeddingModel', () => { - const model = new MockEmbeddingModelV2(); + const model = new MockEmbeddingModelV3(); const modelRegistry = createProviderRegistry({ provider: { @@ -224,7 +224,7 @@ describe('textEmbeddingModel', () => { }); it('should support custom separator', () => { - const model = new MockEmbeddingModelV2(); + const model = new MockEmbeddingModelV3(); const modelRegistry = createProviderRegistry( { diff --git a/packages/ai/src/registry/provider-registry.ts b/packages/ai/src/registry/provider-registry.ts index 929b0d428c17..b5a70aeaef52 100644 --- a/packages/ai/src/registry/provider-registry.ts +++ b/packages/ai/src/registry/provider-registry.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, NoSuchModelError, @@ -34,10 +34,10 @@ export interface ProviderRegistryProvider< id: KEY extends string ? `${KEY & string}${SEPARATOR}${ExtractLiteralUnion>[0]>}` : never, - ): EmbeddingModelV2; + ): EmbeddingModelV3; textEmbeddingModel( id: KEY extends string ? `${KEY & string}${SEPARATOR}${string}` : never, - ): EmbeddingModelV2; + ): EmbeddingModelV3; imageModel( id: KEY extends string @@ -219,7 +219,7 @@ class DefaultProviderRegistry< textEmbeddingModel( id: `${KEY & string}${SEPARATOR}${string}`, - ): EmbeddingModelV2 { + ): EmbeddingModelV3 { const [providerId, modelId] = this.splitId(id, 'textEmbeddingModel'); const provider = this.getProvider(providerId, 'textEmbeddingModel'); diff --git a/packages/ai/src/test/mock-embedding-model-v2.ts b/packages/ai/src/test/mock-embedding-model-v2.ts index 0dccd1734de7..409a329c91b9 100644 --- a/packages/ai/src/test/mock-embedding-model-v2.ts +++ b/packages/ai/src/test/mock-embedding-model-v2.ts @@ -1,15 +1,15 @@ -import { EmbeddingModelV2 } from '@ai-sdk/provider'; +import { EmbeddingModelV3 } from '@ai-sdk/provider'; import { notImplemented } from './not-implemented'; -export class MockEmbeddingModelV2 implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class MockEmbeddingModelV3 implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; - readonly provider: EmbeddingModelV2['provider']; - readonly modelId: EmbeddingModelV2['modelId']; - readonly maxEmbeddingsPerCall: EmbeddingModelV2['maxEmbeddingsPerCall']; - readonly supportsParallelCalls: EmbeddingModelV2['supportsParallelCalls']; + readonly provider: EmbeddingModelV3['provider']; + readonly modelId: EmbeddingModelV3['modelId']; + readonly maxEmbeddingsPerCall: EmbeddingModelV3['maxEmbeddingsPerCall']; + readonly supportsParallelCalls: EmbeddingModelV3['supportsParallelCalls']; - doEmbed: EmbeddingModelV2['doEmbed']; + doEmbed: EmbeddingModelV3['doEmbed']; constructor({ provider = 'mock-provider', @@ -18,13 +18,13 @@ export class MockEmbeddingModelV2 implements EmbeddingModelV2 { supportsParallelCalls = false, doEmbed = notImplemented, }: { - provider?: EmbeddingModelV2['provider']; - modelId?: EmbeddingModelV2['modelId']; + provider?: EmbeddingModelV3['provider']; + modelId?: EmbeddingModelV3['modelId']; maxEmbeddingsPerCall?: - | EmbeddingModelV2['maxEmbeddingsPerCall'] + | EmbeddingModelV3['maxEmbeddingsPerCall'] | null; - supportsParallelCalls?: EmbeddingModelV2['supportsParallelCalls']; - doEmbed?: EmbeddingModelV2['doEmbed']; + supportsParallelCalls?: EmbeddingModelV3['supportsParallelCalls']; + doEmbed?: EmbeddingModelV3['doEmbed']; } = {}) { this.provider = provider; this.modelId = modelId; diff --git a/packages/ai/src/test/mock-provider-v2.ts b/packages/ai/src/test/mock-provider-v2.ts index a07974b1ea13..96828a500e98 100644 --- a/packages/ai/src/test/mock-provider-v2.ts +++ b/packages/ai/src/test/mock-provider-v2.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, NoSuchModelError, @@ -23,7 +23,7 @@ export class MockProviderV2 implements ProviderV2 { speechModels, }: { languageModels?: Record; - embeddingModels?: Record>; + embeddingModels?: Record>; imageModels?: Record; transcriptionModels?: Record; speechModels?: Record; diff --git a/packages/ai/src/types/embedding-model.ts b/packages/ai/src/types/embedding-model.ts index d2788c2ad5cc..6dd7d26a0cc8 100644 --- a/packages/ai/src/types/embedding-model.ts +++ b/packages/ai/src/types/embedding-model.ts @@ -1,11 +1,11 @@ -import { EmbeddingModelV2, EmbeddingModelV2Embedding } from '@ai-sdk/provider'; +import { EmbeddingModelV3, EmbeddingModelV3Embedding } from '@ai-sdk/provider'; /** Embedding model that is used by the AI SDK Core functions. */ -export type EmbeddingModel = string | EmbeddingModelV2; +export type EmbeddingModel = string | EmbeddingModelV3; /** Embedding. */ -export type Embedding = EmbeddingModelV2Embedding; +export type Embedding = EmbeddingModelV3Embedding; diff --git a/packages/ai/src/types/usage.ts b/packages/ai/src/types/usage.ts index af045f39b014..4f82d6b274f4 100644 --- a/packages/ai/src/types/usage.ts +++ b/packages/ai/src/types/usage.ts @@ -8,7 +8,7 @@ export type LanguageModelUsage = LanguageModelV2Usage; /** Represents the number of tokens used in an embedding. */ -// TODO replace with EmbeddingModelV2Usage +// TODO replace with EmbeddingModelV3Usage export type EmbeddingModelUsage = { /** The number of tokens used in the embedding. diff --git a/packages/ai/test/index.ts b/packages/ai/test/index.ts index 4068a8a2814f..8a76107c4117 100644 --- a/packages/ai/test/index.ts +++ b/packages/ai/test/index.ts @@ -4,7 +4,7 @@ export { convertReadableStreamToArray, mockId, } from '@ai-sdk/provider-utils/test'; -export { MockEmbeddingModelV2 } from '../src/test/mock-embedding-model-v2'; +export { MockEmbeddingModelV3 } from '../src/test/mock-embedding-model-v2'; export { MockImageModelV2 } from '../src/test/mock-image-model-v2'; export { MockLanguageModelV2 } from '../src/test/mock-language-model-v2'; export { MockProviderV2 } from '../src/test/mock-provider-v2'; diff --git a/packages/amazon-bedrock/src/bedrock-embedding-model.ts b/packages/amazon-bedrock/src/bedrock-embedding-model.ts index 66953ccb4760..bdcb2453689d 100644 --- a/packages/amazon-bedrock/src/bedrock-embedding-model.ts +++ b/packages/amazon-bedrock/src/bedrock-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -25,10 +25,10 @@ type BedrockEmbeddingConfig = { fetch?: FetchFunction; }; -type DoEmbedResponse = Awaited['doEmbed']>>; +type DoEmbedResponse = Awaited['doEmbed']>>; -export class BedrockEmbeddingModel implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class BedrockEmbeddingModel implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; readonly provider = 'amazon-bedrock'; readonly maxEmbeddingsPerCall = 1; readonly supportsParallelCalls = true; @@ -49,7 +49,7 @@ export class BedrockEmbeddingModel implements EmbeddingModelV2 { abortSignal, providerOptions, }: Parameters< - EmbeddingModelV2['doEmbed'] + EmbeddingModelV3['doEmbed'] >[0]): Promise { if (values.length > this.maxEmbeddingsPerCall) { throw new TooManyEmbeddingValuesForCallError({ diff --git a/packages/amazon-bedrock/src/bedrock-provider.ts b/packages/amazon-bedrock/src/bedrock-provider.ts index 5c58f8a5e732..5128db57c6c4 100644 --- a/packages/amazon-bedrock/src/bedrock-provider.ts +++ b/packages/amazon-bedrock/src/bedrock-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, ProviderV2, @@ -107,7 +107,7 @@ export interface AmazonBedrockProvider extends ProviderV2 { languageModel(modelId: BedrockChatModelId): LanguageModelV2; - embedding(modelId: BedrockEmbeddingModelId): EmbeddingModelV2; + embedding(modelId: BedrockEmbeddingModelId): EmbeddingModelV3; /** Creates a model for image generation. diff --git a/packages/azure/src/azure-openai-provider.test.ts b/packages/azure/src/azure-openai-provider.test.ts index c565c54fc7ce..8c6b3f47ee43 100644 --- a/packages/azure/src/azure-openai-provider.test.ts +++ b/packages/azure/src/azure-openai-provider.test.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2Embedding, + EmbeddingModelV3Embedding, LanguageModelV2Prompt, } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; @@ -302,7 +302,7 @@ describe('embedding', () => { function prepareJsonResponse({ embeddings = dummyEmbeddings, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; } = {}) { server.urls[ 'https://test-resource.openai.azure.com/openai/v1/embeddings' diff --git a/packages/azure/src/azure-openai-provider.ts b/packages/azure/src/azure-openai-provider.ts index a7332d79f285..e90a8fa83824 100644 --- a/packages/azure/src/azure-openai-provider.ts +++ b/packages/azure/src/azure-openai-provider.ts @@ -8,7 +8,7 @@ import { OpenAITranscriptionModel, } from '@ai-sdk/openai/internal'; import { - EmbeddingModelV2, + EmbeddingModelV3, LanguageModelV2, ProviderV2, ImageModelV2, @@ -43,7 +43,7 @@ Creates an Azure OpenAI completion model for text generation. /** @deprecated Use `textEmbedding` instead. */ - embedding(deploymentId: string): EmbeddingModelV2; + embedding(deploymentId: string): EmbeddingModelV3; /** * Creates an Azure OpenAI DALL-E model for image generation. @@ -55,12 +55,12 @@ Creates an Azure OpenAI completion model for text generation. */ imageModel(deploymentId: string): ImageModelV2; - textEmbedding(deploymentId: string): EmbeddingModelV2; + textEmbedding(deploymentId: string): EmbeddingModelV3; /** Creates an Azure OpenAI model for text embeddings. */ - textEmbeddingModel(deploymentId: string): EmbeddingModelV2; + textEmbeddingModel(deploymentId: string): EmbeddingModelV3; /** * Creates an Azure OpenAI model for audio transcription. diff --git a/packages/baseten/src/baseten-provider.ts b/packages/baseten/src/baseten-provider.ts index 2b1aa54ee949..3f4e796ec106 100644 --- a/packages/baseten/src/baseten-provider.ts +++ b/packages/baseten/src/baseten-provider.ts @@ -4,7 +4,7 @@ import { ProviderErrorStructure, } from '@ai-sdk/openai-compatible'; import { - EmbeddingModelV2, + EmbeddingModelV3, LanguageModelV2, NoSuchModelError, ProviderV2, @@ -80,7 +80,7 @@ Creates a text embedding model for text generation. */ textEmbeddingModel( modelId?: BasetenEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; } // by default, we use the Model APIs diff --git a/packages/baseten/src/baseten-provider.unit.test.ts b/packages/baseten/src/baseten-provider.unit.test.ts index 1cee0f14c5a0..5350eb50a9f9 100644 --- a/packages/baseten/src/baseten-provider.unit.test.ts +++ b/packages/baseten/src/baseten-provider.unit.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; import { createBaseten } from './baseten-provider'; import { LanguageModelV2, - EmbeddingModelV2, + EmbeddingModelV3, NoSuchModelError, } from '@ai-sdk/provider'; import { loadApiKey } from '@ai-sdk/provider-utils'; diff --git a/packages/cohere/src/cohere-embedding-model.test.ts b/packages/cohere/src/cohere-embedding-model.test.ts index cc87437a5c27..4c77367ce18d 100644 --- a/packages/cohere/src/cohere-embedding-model.test.ts +++ b/packages/cohere/src/cohere-embedding-model.test.ts @@ -1,4 +1,4 @@ -import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; +import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createCohere } from './cohere-provider'; import { describe, it, expect } from 'vitest'; @@ -22,7 +22,7 @@ describe('doEmbed', () => { meta = { billed_units: { input_tokens: 8 } }, headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; meta?: { billed_units: { input_tokens: number } }; headers?: Record; } = {}) { diff --git a/packages/cohere/src/cohere-embedding-model.ts b/packages/cohere/src/cohere-embedding-model.ts index ce3db277cebc..f1b67a63b872 100644 --- a/packages/cohere/src/cohere-embedding-model.ts +++ b/packages/cohere/src/cohere-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -23,8 +23,8 @@ type CohereEmbeddingConfig = { fetch?: FetchFunction; }; -export class CohereEmbeddingModel implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class CohereEmbeddingModel implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; readonly modelId: CohereEmbeddingModelId; readonly maxEmbeddingsPerCall = 96; @@ -46,8 +46,8 @@ export class CohereEmbeddingModel implements EmbeddingModelV2 { headers, abortSignal, providerOptions, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { const embeddingOptions = await parseProviderOptions({ provider: 'cohere', diff --git a/packages/cohere/src/cohere-provider.ts b/packages/cohere/src/cohere-provider.ts index bb9e98c05b21..370d9098b0b7 100644 --- a/packages/cohere/src/cohere-provider.ts +++ b/packages/cohere/src/cohere-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, LanguageModelV2, NoSuchModelError, ProviderV2, @@ -23,9 +23,9 @@ Creates a model for text generation. */ languageModel(modelId: CohereChatModelId): LanguageModelV2; - embedding(modelId: CohereEmbeddingModelId): EmbeddingModelV2; + embedding(modelId: CohereEmbeddingModelId): EmbeddingModelV3; - textEmbeddingModel(modelId: CohereEmbeddingModelId): EmbeddingModelV2; + textEmbeddingModel(modelId: CohereEmbeddingModelId): EmbeddingModelV3; } export interface CohereProviderSettings { diff --git a/packages/deepinfra/src/deepinfra-provider.test.ts b/packages/deepinfra/src/deepinfra-provider.test.ts index 53699538546f..799248b394f0 100644 --- a/packages/deepinfra/src/deepinfra-provider.test.ts +++ b/packages/deepinfra/src/deepinfra-provider.test.ts @@ -5,7 +5,7 @@ import { OpenAICompatibleCompletionLanguageModel, OpenAICompatibleEmbeddingModel, } from '@ai-sdk/openai-compatible'; -import { LanguageModelV2, EmbeddingModelV2 } from '@ai-sdk/provider'; +import { LanguageModelV2, EmbeddingModelV3 } from '@ai-sdk/provider'; import { loadApiKey } from '@ai-sdk/provider-utils'; import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; @@ -30,7 +30,7 @@ vi.mock('./deepinfra-image-model', () => ({ describe('DeepInfraProvider', () => { let mockLanguageModel: LanguageModelV2; - let mockEmbeddingModel: EmbeddingModelV2; + let mockEmbeddingModel: EmbeddingModelV3; beforeEach(() => { // Mock implementations of models @@ -38,8 +38,8 @@ describe('DeepInfraProvider', () => { // Add any required methods for LanguageModelV2 } as LanguageModelV2; mockEmbeddingModel = { - // Add any required methods for EmbeddingModelV2 - } as EmbeddingModelV2; + // Add any required methods for EmbeddingModelV3 + } as EmbeddingModelV3; // Reset mocks vi.clearAllMocks(); diff --git a/packages/deepinfra/src/deepinfra-provider.ts b/packages/deepinfra/src/deepinfra-provider.ts index abd146bf2c8f..022f7951728e 100644 --- a/packages/deepinfra/src/deepinfra-provider.ts +++ b/packages/deepinfra/src/deepinfra-provider.ts @@ -1,6 +1,6 @@ import { LanguageModelV2, - EmbeddingModelV2, + EmbeddingModelV3, ProviderV2, ImageModelV2, } from '@ai-sdk/provider'; @@ -76,7 +76,7 @@ Creates a text embedding model for text generation. */ textEmbeddingModel( modelId: DeepInfraEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; } export function createDeepInfra( diff --git a/packages/fireworks/src/fireworks-provider.test.ts b/packages/fireworks/src/fireworks-provider.test.ts index 4ad9edc88835..6ff5c9065896 100644 --- a/packages/fireworks/src/fireworks-provider.test.ts +++ b/packages/fireworks/src/fireworks-provider.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; import { createFireworks } from './fireworks-provider'; -import { LanguageModelV2, EmbeddingModelV2 } from '@ai-sdk/provider'; +import { LanguageModelV2, EmbeddingModelV3 } from '@ai-sdk/provider'; import { loadApiKey } from '@ai-sdk/provider-utils'; import { OpenAICompatibleChatLanguageModel, @@ -50,7 +50,7 @@ vi.mock('./fireworks-image-model', () => ({ describe('FireworksProvider', () => { let mockLanguageModel: LanguageModelV2; - let mockEmbeddingModel: EmbeddingModelV2; + let mockEmbeddingModel: EmbeddingModelV3; beforeEach(() => { // Mock implementations of models @@ -58,8 +58,8 @@ describe('FireworksProvider', () => { // Add any required methods for LanguageModelV2 } as LanguageModelV2; mockEmbeddingModel = { - // Add any required methods for EmbeddingModelV2 - } as EmbeddingModelV2; + // Add any required methods for EmbeddingModelV3 + } as EmbeddingModelV3; // Reset mocks vi.clearAllMocks(); diff --git a/packages/fireworks/src/fireworks-provider.ts b/packages/fireworks/src/fireworks-provider.ts index b13eb182b34d..11d48d13de03 100644 --- a/packages/fireworks/src/fireworks-provider.ts +++ b/packages/fireworks/src/fireworks-provider.ts @@ -5,7 +5,7 @@ import { ProviderErrorStructure, } from '@ai-sdk/openai-compatible'; import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, ProviderV2, @@ -80,7 +80,7 @@ Creates a text embedding model for text generation. */ textEmbeddingModel( modelId: FireworksEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; /** Creates a model for image generation. diff --git a/packages/gateway/src/gateway-embedding-model.ts b/packages/gateway/src/gateway-embedding-model.ts index b9249682bdde..0917500954a7 100644 --- a/packages/gateway/src/gateway-embedding-model.ts +++ b/packages/gateway/src/gateway-embedding-model.ts @@ -1,4 +1,4 @@ -import type { EmbeddingModelV2 } from '@ai-sdk/provider'; +import type { EmbeddingModelV3 } from '@ai-sdk/provider'; import { combineHeaders, createJsonResponseHandler, @@ -13,8 +13,8 @@ import { asGatewayError } from './errors'; import { parseAuthMethod } from './errors/parse-auth-method'; import type { SharedV2ProviderMetadata } from '@ai-sdk/provider'; -export class GatewayEmbeddingModel implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class GatewayEmbeddingModel implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; readonly maxEmbeddingsPerCall = 2048; readonly supportsParallelCalls = true; @@ -35,8 +35,8 @@ export class GatewayEmbeddingModel implements EmbeddingModelV2 { headers, abortSignal, providerOptions, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { const resolvedHeaders = await resolve(this.config.headers()); try { diff --git a/packages/gateway/src/gateway-provider.ts b/packages/gateway/src/gateway-provider.ts index e0ef0d9dde90..c0cd0a18f07a 100644 --- a/packages/gateway/src/gateway-provider.ts +++ b/packages/gateway/src/gateway-provider.ts @@ -21,7 +21,7 @@ import { getVercelOidcToken, getVercelRequestId } from './vercel-environment'; import type { GatewayModelId } from './gateway-language-model-settings'; import type { LanguageModelV2, - EmbeddingModelV2, + EmbeddingModelV3, ProviderV2, } from '@ai-sdk/provider'; @@ -48,7 +48,7 @@ Creates a model for generating text embeddings. */ textEmbeddingModel( modelId: GatewayEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; } export interface GatewayProviderSettings { diff --git a/packages/google-vertex/src/google-vertex-embedding-model.test.ts b/packages/google-vertex/src/google-vertex-embedding-model.test.ts index 20fae94ecd21..1191af93ea94 100644 --- a/packages/google-vertex/src/google-vertex-embedding-model.test.ts +++ b/packages/google-vertex/src/google-vertex-embedding-model.test.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2Embedding, + EmbeddingModelV3Embedding, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; @@ -48,7 +48,7 @@ describe('GoogleVertexEmbeddingModel', () => { tokenCounts = [1, 1], headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; tokenCounts?: number[]; headers?: Record; } = {}) { diff --git a/packages/google-vertex/src/google-vertex-embedding-model.ts b/packages/google-vertex/src/google-vertex-embedding-model.ts index e226df34adb1..0f69d45a37bd 100644 --- a/packages/google-vertex/src/google-vertex-embedding-model.ts +++ b/packages/google-vertex/src/google-vertex-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -18,8 +18,8 @@ import { } from './google-vertex-embedding-options'; import { GoogleVertexConfig } from './google-vertex-config'; -export class GoogleVertexEmbeddingModel implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class GoogleVertexEmbeddingModel implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; readonly modelId: GoogleVertexEmbeddingModelId; readonly maxEmbeddingsPerCall = 2048; readonly supportsParallelCalls = true; @@ -43,8 +43,8 @@ export class GoogleVertexEmbeddingModel implements EmbeddingModelV2 { headers, abortSignal, providerOptions, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { // Parse provider options const googleOptions = diff --git a/packages/google/src/google-generative-ai-embedding-model.test.ts b/packages/google/src/google-generative-ai-embedding-model.test.ts index a3757722bdd1..387eb940e745 100644 --- a/packages/google/src/google-generative-ai-embedding-model.test.ts +++ b/packages/google/src/google-generative-ai-embedding-model.test.ts @@ -1,4 +1,4 @@ -import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; +import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleGenerativeAIEmbeddingModel } from './google-generative-ai-embedding-model'; import { createGoogleGenerativeAI } from './google-provider'; @@ -25,7 +25,7 @@ describe('GoogleGenerativeAIEmbeddingModel', () => { embeddings = dummyEmbeddings, headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; headers?: Record; } = {}) { server.urls[URL].response = { @@ -41,7 +41,7 @@ describe('GoogleGenerativeAIEmbeddingModel', () => { embeddings = dummyEmbeddings, headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; headers?: Record; } = {}) { server.urls[URL].response = { diff --git a/packages/google/src/google-generative-ai-embedding-model.ts b/packages/google/src/google-generative-ai-embedding-model.ts index 61bdbf57dd0a..f893bbea7802 100644 --- a/packages/google/src/google-generative-ai-embedding-model.ts +++ b/packages/google/src/google-generative-ai-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -25,9 +25,9 @@ type GoogleGenerativeAIEmbeddingConfig = { }; export class GoogleGenerativeAIEmbeddingModel - implements EmbeddingModelV2 + implements EmbeddingModelV3 { - readonly specificationVersion = 'v2'; + readonly specificationVersion = 'v3'; readonly modelId: GoogleGenerativeAIEmbeddingModelId; readonly maxEmbeddingsPerCall = 2048; readonly supportsParallelCalls = true; @@ -50,8 +50,8 @@ export class GoogleGenerativeAIEmbeddingModel headers, abortSignal, providerOptions, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { // Parse provider options const googleOptions = await parseProviderOptions({ diff --git a/packages/google/src/google-provider.ts b/packages/google/src/google-provider.ts index df81d9cdce2a..be4307330e4b 100644 --- a/packages/google/src/google-provider.ts +++ b/packages/google/src/google-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, LanguageModelV2, ProviderV2, ImageModelV2, @@ -47,15 +47,15 @@ Creates a model for image generation. */ embedding( modelId: GoogleGenerativeAIEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; textEmbedding( modelId: GoogleGenerativeAIEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; textEmbeddingModel( modelId: GoogleGenerativeAIEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; tools: typeof googleTools; } diff --git a/packages/mistral/src/mistral-embedding-model.test.ts b/packages/mistral/src/mistral-embedding-model.test.ts index 5286a4326f9a..c933c2a6b450 100644 --- a/packages/mistral/src/mistral-embedding-model.test.ts +++ b/packages/mistral/src/mistral-embedding-model.test.ts @@ -1,4 +1,4 @@ -import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; +import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createMistral } from './mistral-provider'; import { describe, it, expect } from 'vitest'; @@ -22,7 +22,7 @@ describe('doEmbed', () => { usage = { prompt_tokens: 8, total_tokens: 8 }, headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; usage?: { prompt_tokens: number; total_tokens: number }; headers?: Record; } = {}) { diff --git a/packages/mistral/src/mistral-embedding-model.ts b/packages/mistral/src/mistral-embedding-model.ts index beee67cddeb4..7b91134f1cb4 100644 --- a/packages/mistral/src/mistral-embedding-model.ts +++ b/packages/mistral/src/mistral-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -19,8 +19,8 @@ type MistralEmbeddingConfig = { fetch?: FetchFunction; }; -export class MistralEmbeddingModel implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class MistralEmbeddingModel implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; readonly modelId: MistralEmbeddingModelId; readonly maxEmbeddingsPerCall = 32; readonly supportsParallelCalls = false; @@ -43,8 +43,8 @@ export class MistralEmbeddingModel implements EmbeddingModelV2 { values, abortSignal, headers, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { if (values.length > this.maxEmbeddingsPerCall) { throw new TooManyEmbeddingValuesForCallError({ diff --git a/packages/mistral/src/mistral-provider.ts b/packages/mistral/src/mistral-provider.ts index aa18abad6177..72450977bc90 100644 --- a/packages/mistral/src/mistral-provider.ts +++ b/packages/mistral/src/mistral-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, LanguageModelV2, NoSuchModelError, ProviderV2, @@ -30,13 +30,13 @@ Creates a model for text generation. /** @deprecated Use `textEmbedding()` instead. */ - embedding(modelId: MistralEmbeddingModelId): EmbeddingModelV2; + embedding(modelId: MistralEmbeddingModelId): EmbeddingModelV3; - textEmbedding(modelId: MistralEmbeddingModelId): EmbeddingModelV2; + textEmbedding(modelId: MistralEmbeddingModelId): EmbeddingModelV3; textEmbeddingModel: ( modelId: MistralEmbeddingModelId, - ) => EmbeddingModelV2; + ) => EmbeddingModelV3; } export interface MistralProviderSettings { diff --git a/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts b/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts index 1c05342038f8..b723f419061c 100644 --- a/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts +++ b/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; +import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAICompatible } from '../openai-compatible-provider'; @@ -28,7 +28,7 @@ describe('doEmbed', () => { usage = { prompt_tokens: 8, total_tokens: 8 }, headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; usage?: { prompt_tokens: number; total_tokens: number }; headers?: Record; } = {}) { diff --git a/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.ts b/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.ts index 65251eb1525a..770b7eba147a 100644 --- a/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.ts +++ b/packages/openai-compatible/src/embedding/openai-compatible-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -39,9 +39,9 @@ Override the parallelism of embedding calls. }; export class OpenAICompatibleEmbeddingModel - implements EmbeddingModelV2 + implements EmbeddingModelV3 { - readonly specificationVersion = 'v2'; + readonly specificationVersion = 'v3'; readonly modelId: OpenAICompatibleEmbeddingModelId; private readonly config: OpenAICompatibleEmbeddingConfig; @@ -75,8 +75,8 @@ export class OpenAICompatibleEmbeddingModel headers, abortSignal, providerOptions, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { const compatibleOptions = Object.assign( (await parseProviderOptions({ diff --git a/packages/openai-compatible/src/openai-compatible-provider.ts b/packages/openai-compatible/src/openai-compatible-provider.ts index 58a1ba71d57f..0632e7fc5fc9 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, ProviderV2, @@ -36,7 +36,7 @@ export interface OpenAICompatibleProvider< completionModel(modelId: COMPLETION_MODEL_IDS): LanguageModelV2; - textEmbeddingModel(modelId: EMBEDDING_MODEL_IDS): EmbeddingModelV2; + textEmbeddingModel(modelId: EMBEDDING_MODEL_IDS): EmbeddingModelV3; imageModel(modelId: IMAGE_MODEL_IDS): ImageModelV2; } diff --git a/packages/openai/src/embedding/openai-embedding-model.test.ts b/packages/openai/src/embedding/openai-embedding-model.test.ts index 5c0919976af4..43448e57bdcc 100644 --- a/packages/openai/src/embedding/openai-embedding-model.test.ts +++ b/packages/openai/src/embedding/openai-embedding-model.test.ts @@ -1,4 +1,4 @@ -import { EmbeddingModelV2Embedding } from '@ai-sdk/provider'; +import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; import { describe, it, expect } from 'vitest'; @@ -22,7 +22,7 @@ describe('doEmbed', () => { usage = { prompt_tokens: 8, total_tokens: 8 }, headers, }: { - embeddings?: EmbeddingModelV2Embedding[]; + embeddings?: EmbeddingModelV3Embedding[]; usage?: { prompt_tokens: number; total_tokens: number }; headers?: Record; } = {}) { diff --git a/packages/openai/src/embedding/openai-embedding-model.ts b/packages/openai/src/embedding/openai-embedding-model.ts index 93795b6603a2..4e39fdd1b3b6 100644 --- a/packages/openai/src/embedding/openai-embedding-model.ts +++ b/packages/openai/src/embedding/openai-embedding-model.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, TooManyEmbeddingValuesForCallError, } from '@ai-sdk/provider'; import { @@ -16,8 +16,8 @@ import { openaiEmbeddingProviderOptions, } from './openai-embedding-options'; -export class OpenAIEmbeddingModel implements EmbeddingModelV2 { - readonly specificationVersion = 'v2'; +export class OpenAIEmbeddingModel implements EmbeddingModelV3 { + readonly specificationVersion = 'v3'; readonly modelId: OpenAIEmbeddingModelId; readonly maxEmbeddingsPerCall = 2048; readonly supportsParallelCalls = true; @@ -38,8 +38,8 @@ export class OpenAIEmbeddingModel implements EmbeddingModelV2 { headers, abortSignal, providerOptions, - }: Parameters['doEmbed']>[0]): Promise< - Awaited['doEmbed']>> + }: Parameters['doEmbed']>[0]): Promise< + Awaited['doEmbed']>> > { if (values.length > this.maxEmbeddingsPerCall) { throw new TooManyEmbeddingValuesForCallError({ diff --git a/packages/openai/src/openai-provider.ts b/packages/openai/src/openai-provider.ts index 755b48bd3736..9a1bbb5983e3 100644 --- a/packages/openai/src/openai-provider.ts +++ b/packages/openai/src/openai-provider.ts @@ -1,5 +1,5 @@ import { - EmbeddingModelV2, + EmbeddingModelV3, ImageModelV2, LanguageModelV2, ProviderV2, @@ -53,17 +53,17 @@ Creates an OpenAI completion model for text generation. /** Creates a model for text embeddings. */ - embedding(modelId: OpenAIEmbeddingModelId): EmbeddingModelV2; + embedding(modelId: OpenAIEmbeddingModelId): EmbeddingModelV3; /** Creates a model for text embeddings. */ - textEmbedding(modelId: OpenAIEmbeddingModelId): EmbeddingModelV2; + textEmbedding(modelId: OpenAIEmbeddingModelId): EmbeddingModelV3; /** Creates a model for text embeddings. */ - textEmbeddingModel(modelId: OpenAIEmbeddingModelId): EmbeddingModelV2; + textEmbeddingModel(modelId: OpenAIEmbeddingModelId): EmbeddingModelV3; /** Creates a model for image generation. diff --git a/packages/provider/src/embedding-model/index.ts b/packages/provider/src/embedding-model/index.ts index 5640476d8b82..f0a4a20cc05d 100644 --- a/packages/provider/src/embedding-model/index.ts +++ b/packages/provider/src/embedding-model/index.ts @@ -1 +1,2 @@ +export * from './v3/index'; export * from './v2/index'; diff --git a/packages/provider/src/embedding-model/v3/embedding-model-v3-embedding.ts b/packages/provider/src/embedding-model/v3/embedding-model-v3-embedding.ts new file mode 100644 index 000000000000..1e295e5f70fe --- /dev/null +++ b/packages/provider/src/embedding-model/v3/embedding-model-v3-embedding.ts @@ -0,0 +1,5 @@ +/** +An embedding is a vector, i.e. an array of numbers. +It is e.g. used to represent a text as a vector of word embeddings. + */ +export type EmbeddingModelV3Embedding = Array; diff --git a/packages/provider/src/embedding-model/v3/embedding-model-v3.ts b/packages/provider/src/embedding-model/v3/embedding-model-v3.ts new file mode 100644 index 000000000000..eac4226b438e --- /dev/null +++ b/packages/provider/src/embedding-model/v3/embedding-model-v3.ts @@ -0,0 +1,113 @@ +import { + SharedV2Headers, + SharedV2ProviderOptions, + SharedV2ProviderMetadata, +} from '../../shared'; +import { EmbeddingModelV3Embedding } from './embedding-model-v3-embedding'; + +/** +Specification for an embedding model that implements the embedding model +interface version 1. + +VALUE is the type of the values that the model can embed. +This will allow us to go beyond text embeddings in the future, +e.g. to support image embeddings + */ +export type EmbeddingModelV3 = { + /** +The embedding model must specify which embedding model interface +version it implements. This will allow us to evolve the embedding +model interface and retain backwards compatibility. The different +implementation versions can be handled as a discriminated union +on our side. + */ + readonly specificationVersion: 'v3'; + + /** +Name of the provider for logging purposes. + */ + readonly provider: string; + + /** +Provider-specific model ID for logging purposes. + */ + readonly modelId: string; + + /** +Limit of how many embeddings can be generated in a single API call. + +Use Infinity for models that do not have a limit. + */ + readonly maxEmbeddingsPerCall: + | PromiseLike + | number + | undefined; + + /** +True if the model can handle multiple embedding calls in parallel. + */ + readonly supportsParallelCalls: PromiseLike | boolean; + + /** +Generates a list of embeddings for the given input text. + +Naming: "do" prefix to prevent accidental direct usage of the method +by the user. + */ + doEmbed(options: { + /** +List of values to embed. + */ + values: Array; + + /** +Abort signal for cancelling the operation. + */ + abortSignal?: AbortSignal; + + /** +Additional provider-specific options. They are passed through +to the provider from the AI SDK and enable provider-specific +functionality that can be fully encapsulated in the provider. + */ + providerOptions?: SharedV2ProviderOptions; + + /** + Additional HTTP headers to be sent with the request. + Only applicable for HTTP-based providers. + */ + headers?: Record; + }): PromiseLike<{ + /** +Generated embeddings. They are in the same order as the input values. + */ + embeddings: Array; + + /** +Token usage. We only have input tokens for embeddings. + */ + usage?: { tokens: number }; + + /** +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?: SharedV2ProviderMetadata; + + /** +Optional response information for debugging purposes. + */ + response?: { + /** +Response headers. + */ + headers?: SharedV2Headers; + + /** + The response body. + */ + body?: unknown; + }; + }>; +}; diff --git a/packages/provider/src/embedding-model/v3/index.ts b/packages/provider/src/embedding-model/v3/index.ts new file mode 100644 index 000000000000..38f1a44032d7 --- /dev/null +++ b/packages/provider/src/embedding-model/v3/index.ts @@ -0,0 +1,2 @@ +export * from './embedding-model-v3'; +export * from './embedding-model-v3-embedding'; diff --git a/packages/provider/src/provider/v2/provider-v2.ts b/packages/provider/src/provider/v2/provider-v2.ts index 3f21d37cea12..5163efd3fca1 100644 --- a/packages/provider/src/provider/v2/provider-v2.ts +++ b/packages/provider/src/provider/v2/provider-v2.ts @@ -1,4 +1,4 @@ -import { EmbeddingModelV2 } from '../../embedding-model/v2/embedding-model-v2'; +import { EmbeddingModelV3 } from '../../embedding-model/v3/embedding-model-v3'; import { ImageModelV2 } from '../../image-model/v2/image-model-v2'; import { LanguageModelV2 } from '../../language-model/v2/language-model-v2'; import { SpeechModelV2 } from '../../speech-model/v2/speech-model-v2'; @@ -30,7 +30,7 @@ The model id is then passed to the provider function to get the model. @throws {NoSuchModelError} If no such model exists. */ - textEmbeddingModel(modelId: string): EmbeddingModelV2; + textEmbeddingModel(modelId: string): EmbeddingModelV3; /** Returns the image model with the given id. diff --git a/packages/togetherai/src/togetherai-provider.test.ts b/packages/togetherai/src/togetherai-provider.test.ts index 0a2a3af2db6a..8593022ea9af 100644 --- a/packages/togetherai/src/togetherai-provider.test.ts +++ b/packages/togetherai/src/togetherai-provider.test.ts @@ -3,7 +3,7 @@ import { OpenAICompatibleCompletionLanguageModel, OpenAICompatibleEmbeddingModel, } from '@ai-sdk/openai-compatible'; -import { LanguageModelV2, EmbeddingModelV2 } from '@ai-sdk/provider'; +import { LanguageModelV2, EmbeddingModelV3 } from '@ai-sdk/provider'; import { loadApiKey } from '@ai-sdk/provider-utils'; import { TogetherAIImageModel } from './togetherai-image-model'; import { createTogetherAI } from './togetherai-provider'; @@ -30,7 +30,7 @@ vi.mock('./togetherai-image-model', () => ({ describe('TogetherAIProvider', () => { let mockLanguageModel: LanguageModelV2; - let mockEmbeddingModel: EmbeddingModelV2; + let mockEmbeddingModel: EmbeddingModelV3; let createOpenAICompatibleMock: Mock; beforeEach(() => { @@ -39,8 +39,8 @@ describe('TogetherAIProvider', () => { // Add any required methods for LanguageModelV2 } as LanguageModelV2; mockEmbeddingModel = { - // Add any required methods for EmbeddingModelV2 - } as EmbeddingModelV2; + // Add any required methods for EmbeddingModelV3 + } as EmbeddingModelV3; // Reset mocks vi.clearAllMocks(); diff --git a/packages/togetherai/src/togetherai-provider.ts b/packages/togetherai/src/togetherai-provider.ts index 266b68025c9b..cf47b493b1a9 100644 --- a/packages/togetherai/src/togetherai-provider.ts +++ b/packages/togetherai/src/togetherai-provider.ts @@ -1,6 +1,6 @@ import { LanguageModelV2, - EmbeddingModelV2, + EmbeddingModelV3, ProviderV2, ImageModelV2, } from '@ai-sdk/provider'; @@ -66,7 +66,7 @@ Creates a text embedding model for text generation. */ textEmbeddingModel( modelId: TogetherAIEmbeddingModelId, - ): EmbeddingModelV2; + ): EmbeddingModelV3; /** Creates a model for image generation. From 492011969e64b4cf5f2bf6d49d75d385f0301e25 Mon Sep 17 00:00:00 2001 From: Junyi Date: Wed, 24 Sep 2025 01:55:55 +0800 Subject: [PATCH 102/121] fix(provider/openai): change the "incomplete_details" key from nullable to nullish for better openai compatibility (#8836) ## Background As reported in [#8835](https://github.com/vercel/ai/issues/8835), `incomplete_details` was defined as `.nullable()`, forcing `null` instead of allowing omission. This caused validation issues when the property was simply missing. ## Summary Changed schema: ```diff - incomplete_details: z.object({ reason: z.string() }).nullable(), + incomplete_details: z.object({ reason: z.string() }).nullish(), ```` This matches runtime behavior: `incomplete_details` may be omitted, or provided as an object. `null` remains accepted as well. ## Manual Verification * Verified build passes * Objects with omitted `incomplete_details` now validate correctly * Objects with `incomplete_details: { reason: "..." }` validate correctly * `incomplete_details: null` still accepted ## Checklist * [x] Tests have been added / updated * [x] Documentation has been added / updated * [x] A *patch* changeset for relevant packages has been added (`pnpm changeset`) * [x] Formatting issues fixed (`pnpm prettier-fix`) * [x] Self-review completed ## Related Issues Fixes [#8835](https://github.com/vercel/ai/issues/8835) https://github.com/vllm-project/vllm/issues/11415 --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/beige-bikes-repeat.md | 5 +++++ .../openai/src/responses/openai-responses-language-model.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/beige-bikes-repeat.md diff --git a/.changeset/beige-bikes-repeat.md b/.changeset/beige-bikes-repeat.md new file mode 100644 index 000000000000..d602c7b4af27 --- /dev/null +++ b/.changeset/beige-bikes-repeat.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/openai': patch +--- + +fix the "incomplete_details" key from nullable to nullish for openai compatibility diff --git a/packages/openai/src/responses/openai-responses-language-model.ts b/packages/openai/src/responses/openai-responses-language-model.ts index cd1a4811dd3f..4fb85fa531fe 100644 --- a/packages/openai/src/responses/openai-responses-language-model.ts +++ b/packages/openai/src/responses/openai-responses-language-model.ts @@ -495,7 +495,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV2 { ]), ), service_tier: z.string().nullish(), - incomplete_details: z.object({ reason: z.string() }).nullable(), + incomplete_details: z.object({ reason: z.string() }).nullish(), usage: usageSchema, }), ), From 5d21222e6941b50e6bc2ea8c099155ac01df65ce Mon Sep 17 00:00:00 2001 From: Rohan Taneja <47066511+R-Taneja@users.noreply.github.com> Date: Tue, 23 Sep 2025 11:00:54 -0700 Subject: [PATCH 103/121] feat(provider/gateway): Add gpt-5-codex to Gateway model string autocomplete (#8840) ## Background New OpenAI model ## Summary Add it to the model string autocomplete list ## Manual Verification Autocomplete works ## Checklist - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) --- .changeset/blue-books-hang.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/blue-books-hang.md diff --git a/.changeset/blue-books-hang.md b/.changeset/blue-books-hang.md new file mode 100644 index 000000000000..c00c57bd32fe --- /dev/null +++ b/.changeset/blue-books-hang.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat(provider/gateway): Add gpt-5-codex to Gateway model string autocomplete diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index 6a5d4ce38919..f601da17c09c 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -75,6 +75,7 @@ export type GatewayModelId = | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-5' + | 'openai/gpt-5-codex' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-oss-120b' From 1cad0abad1dc39437aade80055fc90d254002c31 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Tue, 23 Sep 2025 15:09:56 -0400 Subject: [PATCH 104/121] feat: add provider versions to user-agent header (#8703) ## Background This change is added to include the provider versions in the user-agent header that we now pass. Previously, the string only appended `ai` version and runtime env ## Summary - add a `version.ts` file - export version during build by changing `tsup.config` - export verison during tests by changing `vitest.config` - mock a dummy version for tests ## Manual Verification Verified by making changes to the test file ## Tasks - [x] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Future Work Version in user-agent added for: - [x] `gateway` - [x] `openai` - [x] `anthropic` - [x] `google` - [x] `google-vertex` - [x] `azure` - [x] `amazon-bedrock` - [x] `cohere` - [x] `mistral` - [x] `groq` - [x] `cerebras` - [x] `deepinfra` - [x] `deepseek` - [x] `fireworks` - [x] `perplexity` - [x] `replicate` - [x] `togetherai` - [x] `xai` - [x] `vercel` - [x] `openai-compatible` - [x] `elevenlabs` - [x] `assemblyai` - [x] `deepgram` - [x] `gladia` - [x] `revai` - [x] `luma` - [x] `fal` - [x] `hume` - [x] `lmnt` - [x] `langchain` - [x] `llamaindex` - [x] `valibot` ## Related Issues fix in progress for #8699 --------- Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> --- .changeset/lemon-guests-drop.md | 33 ++++++++++++ .../src/bedrock-provider.test.ts | 51 ++++++++++++++----- .../amazon-bedrock/src/bedrock-provider.ts | 13 +++-- .../anthropic-messages-language-model.test.ts | 9 +++- packages/anthropic/src/anthropic-provider.ts | 24 +++++---- packages/anthropic/src/index.ts | 1 + packages/anthropic/src/version.ts | 6 +++ packages/anthropic/tsup.config.ts | 12 +++++ packages/anthropic/vitest.edge.config.js | 8 +++ packages/anthropic/vitest.node.config.js | 8 +++ packages/assemblyai/package.json | 1 + .../assemblyai/src/assemblyai-provider.ts | 27 ++++++---- .../assemblyai-transcription-model.test.ts | 9 +++- packages/assemblyai/src/index.ts | 1 + packages/assemblyai/src/version.ts | 6 +++ packages/assemblyai/tsup.config.ts | 6 +++ packages/assemblyai/vitest.edge.config.js | 4 ++ packages/assemblyai/vitest.node.config.js | 4 ++ .../azure/src/azure-openai-provider.test.ts | 21 +++++++- packages/azure/src/azure-openai-provider.ts | 27 ++++++---- packages/azure/src/index.ts | 1 + packages/azure/src/version.ts | 6 +++ packages/azure/tsup.config.ts | 6 +++ packages/azure/vitest.edge.config.js | 4 ++ packages/azure/vitest.node.config.js | 4 ++ packages/baseten/src/baseten-provider.ts | 22 +++++--- .../baseten/src/baseten-provider.unit.test.ts | 49 ++++++++++++++---- packages/baseten/src/index.ts | 1 + packages/baseten/src/version.ts | 6 +++ packages/baseten/tsup.config.ts | 4 ++ packages/baseten/vitest.edge.config.js | 4 ++ packages/baseten/vitest.node.config.js | 4 ++ .../cerebras/src/cerebras-provider.test.ts | 37 ++++++++++++-- packages/cerebras/src/cerebras-provider.ts | 22 +++++--- packages/cerebras/src/index.ts | 1 + packages/cerebras/src/version.ts | 6 +++ packages/cerebras/tsup.config.ts | 6 +++ packages/cerebras/vitest.edge.config.js | 4 ++ packages/cerebras/vitest.node.config.js | 4 ++ .../cohere/src/cohere-embedding-model.test.ts | 9 +++- packages/cohere/src/cohere-provider.ts | 22 +++++--- packages/cohere/src/index.ts | 1 + packages/cohere/src/version.ts | 6 +++ packages/cohere/tsup.config.ts | 6 +++ packages/cohere/vitest.edge.config.js | 4 ++ packages/cohere/vitest.node.config.js | 4 ++ packages/deepgram/package.json | 1 + packages/deepgram/src/deepgram-provider.ts | 27 ++++++---- .../src/deepgram-transcription-model.test.ts | 9 +++- packages/deepgram/src/index.ts | 1 + packages/deepgram/src/version.ts | 6 +++ packages/deepgram/tsup.config.ts | 6 +++ packages/deepgram/vitest.edge.config.js | 4 ++ packages/deepgram/vitest.node.config.js | 4 ++ .../deepinfra/src/deepinfra-provider.test.ts | 12 +++-- packages/deepinfra/src/deepinfra-provider.ts | 22 +++++--- packages/deepinfra/src/index.ts | 1 + packages/deepinfra/src/version.ts | 6 +++ packages/deepinfra/tsup.config.ts | 6 +++ packages/deepinfra/vitest.edge.config.js | 4 ++ packages/deepinfra/vitest.node.config.js | 4 ++ .../deepseek/src/deepseek-provider.test.ts | 37 ++++++++++++-- packages/deepseek/src/deepseek-provider.ts | 22 +++++--- packages/deepseek/src/index.ts | 1 + packages/deepseek/src/version.ts | 6 +++ packages/deepseek/tsup.config.ts | 6 +++ packages/deepseek/vitest.edge.config.js | 4 ++ packages/deepseek/vitest.node.config.js | 4 ++ .../elevenlabs/src/elevenlabs-provider.ts | 27 ++++++---- .../src/elevenlabs-speech-model.test.ts | 19 ++++++- .../elevenlabs-transcription-model.test.ts | 9 +++- packages/elevenlabs/src/index.ts | 1 + packages/elevenlabs/src/version.ts | 6 +++ packages/elevenlabs/tsup.config.ts | 6 +++ packages/elevenlabs/vitest.edge.config.js | 4 ++ packages/elevenlabs/vitest.node.config.js | 4 ++ packages/fal/src/fal-provider.ts | 22 +++++--- packages/fal/src/index.ts | 1 + packages/fal/src/version.ts | 6 +++ packages/fal/tsup.config.ts | 6 +++ packages/fal/vitest.edge.config.js | 4 ++ packages/fal/vitest.node.config.js | 4 ++ .../fireworks/src/fireworks-provider.test.ts | 12 +++-- packages/fireworks/src/fireworks-provider.ts | 22 +++++--- packages/fireworks/src/index.ts | 1 + packages/fireworks/src/version.ts | 6 +++ packages/fireworks/tsup.config.ts | 6 +++ packages/fireworks/vitest.edge.config.js | 4 ++ packages/fireworks/vitest.node.config.js | 4 ++ packages/gateway/src/gateway-provider.test.ts | 24 ++++++--- packages/gateway/src/gateway-provider.ts | 17 ++++--- packages/gateway/src/version.ts | 6 +++ packages/gateway/tsup.config.ts | 6 +++ packages/gateway/vitest.edge.config.js | 8 +++ packages/gateway/vitest.node.config.js | 8 +++ packages/gladia/package.json | 1 + packages/gladia/src/gladia-provider.ts | 27 ++++++---- .../src/gladia-transcription-model.test.ts | 9 +++- packages/gladia/src/index.ts | 1 + packages/gladia/src/version.ts | 6 +++ packages/gladia/tsup.config.ts | 6 +++ packages/gladia/vitest.edge.config.js | 4 ++ packages/gladia/vitest.node.config.js | 4 ++ .../src/google-vertex-embedding-model.test.ts | 25 +++++---- .../src/google-vertex-image-model.test.ts | 33 ++++++------ .../src/google-vertex-provider.test.ts | 16 +++--- .../src/google-vertex-provider.ts | 14 ++++- packages/google-vertex/src/index.ts | 1 + ...ogle-generative-ai-embedding-model.test.ts | 9 +++- ...oogle-generative-ai-language-model.test.ts | 9 +++- packages/google/src/google-provider.test.ts | 7 ++- packages/google/src/google-provider.ts | 22 +++++--- packages/google/src/index.ts | 1 + packages/google/src/version.ts | 6 +++ packages/google/tsup.config.ts | 12 +++++ packages/google/vitest.edge.config.js | 7 +++ packages/google/vitest.node.config.js | 7 +++ .../groq/src/groq-chat-language-model.test.ts | 9 +++- packages/groq/src/groq-provider.ts | 22 +++++--- .../groq/src/groq-transcription-model.test.ts | 9 +++- packages/groq/src/index.ts | 1 + packages/groq/src/version.ts | 6 +++ packages/groq/tsup.config.ts | 6 +++ packages/groq/vitest.edge.config.js | 4 ++ packages/groq/vitest.node.config.js | 4 ++ packages/hume/package.json | 1 + packages/hume/src/hume-provider.ts | 27 ++++++---- packages/hume/src/hume-speech-model.test.ts | 9 +++- packages/hume/src/index.ts | 1 + packages/hume/src/version.ts | 6 +++ packages/hume/tsup.config.ts | 6 +++ packages/hume/vitest.edge.config.js | 4 ++ packages/hume/vitest.node.config.js | 4 ++ packages/lmnt/package.json | 1 + packages/lmnt/src/index.ts | 1 + packages/lmnt/src/lmnt-provider.ts | 27 ++++++---- packages/lmnt/src/lmnt-speech-model.test.ts | 9 +++- packages/lmnt/src/version.ts | 6 +++ packages/lmnt/tsup.config.ts | 6 +++ packages/lmnt/vitest.edge.config.js | 4 ++ packages/lmnt/vitest.node.config.js | 4 ++ packages/luma/src/index.ts | 1 + packages/luma/src/luma-provider.ts | 22 +++++--- packages/luma/src/version.ts | 6 +++ packages/luma/tsup.config.ts | 6 +++ packages/luma/vitest.edge.config.js | 4 ++ packages/luma/vitest.node.config.js | 4 ++ packages/mistral/src/index.ts | 1 + .../src/mistral-chat-language-model.test.ts | 12 ++++- .../src/mistral-embedding-model.test.ts | 9 +++- packages/mistral/src/mistral-provider.ts | 22 +++++--- packages/mistral/src/version.ts | 6 +++ packages/mistral/tsup.config.ts | 6 +++ packages/mistral/vitest.edge.config.js | 4 ++ packages/mistral/vitest.node.config.js | 4 ++ .../chat/openai-chat-language-model.test.ts | 9 +++- .../openai-completion-language-model.test.ts | 9 +++- .../embedding/openai-embedding-model.test.ts | 9 +++- .../src/image/openai-image-model.test.ts | 9 +++- packages/openai/src/index.ts | 1 + packages/openai/src/openai-provider.ts | 26 ++++++---- .../src/speech/openai-speech-model.test.ts | 10 +++- .../openai-transcription-model.test.ts | 10 +++- packages/openai/src/version.ts | 6 +++ packages/openai/tsup.config.ts | 12 +++++ packages/openai/vitest.edge.config.js | 7 +++ packages/openai/vitest.node.config.js | 7 +++ packages/perplexity/src/index.ts | 1 + .../src/perplexity-language-model.test.ts | 2 + .../perplexity/src/perplexity-provider.ts | 22 +++++--- packages/perplexity/src/version.ts | 6 +++ packages/perplexity/tsup.config.ts | 6 +++ packages/perplexity/vitest.edge.config.js | 4 ++ packages/perplexity/vitest.node.config.js | 4 ++ packages/replicate/src/index.ts | 1 + .../src/replicate-image-model.test.ts | 10 +++- packages/replicate/src/replicate-provider.ts | 22 ++++---- packages/replicate/src/version.ts | 6 +++ packages/replicate/tsup.config.ts | 6 +++ packages/replicate/vitest.edge.config.js | 4 ++ packages/replicate/vitest.node.config.js | 4 ++ packages/revai/package.json | 1 + packages/revai/src/index.ts | 1 + packages/revai/src/revai-provider.ts | 27 ++++++---- .../src/revai-transcription-model.test.ts | 10 +++- packages/revai/src/version.ts | 6 +++ packages/revai/tsup.config.ts | 6 +++ packages/revai/vitest.edge.config.js | 4 ++ packages/revai/vitest.node.config.js | 4 ++ packages/togetherai/src/index.ts | 1 + .../src/togetherai-provider.test.ts | 14 +++-- .../togetherai/src/togetherai-provider.ts | 22 +++++--- packages/togetherai/src/version.ts | 6 +++ packages/togetherai/tsup.config.ts | 6 +++ packages/togetherai/vitest.edge.config.js | 4 ++ packages/togetherai/vitest.node.config.js | 4 ++ packages/vercel/src/index.ts | 1 + packages/vercel/src/vercel-provider.test.ts | 12 +++-- packages/vercel/src/vercel-provider.ts | 22 +++++--- packages/vercel/src/version.ts | 6 +++ packages/vercel/tsup.config.ts | 6 +++ packages/vercel/vitest.edge.config.js | 4 ++ packages/vercel/vitest.node.config.js | 4 ++ packages/xai/src/index.ts | 1 + packages/xai/src/version.ts | 6 +++ .../xai/src/xai-chat-language-model.test.ts | 28 +++++++++- packages/xai/src/xai-provider.test.ts | 23 ++++++--- packages/xai/src/xai-provider.ts | 22 +++++--- packages/xai/tsup.config.ts | 6 +++ packages/xai/vitest.edge.config.js | 4 ++ packages/xai/vitest.node.config.js | 4 ++ 211 files changed, 1591 insertions(+), 348 deletions(-) create mode 100644 .changeset/lemon-guests-drop.md create mode 100644 packages/anthropic/src/version.ts create mode 100644 packages/assemblyai/src/version.ts create mode 100644 packages/azure/src/version.ts create mode 100644 packages/baseten/src/version.ts create mode 100644 packages/cerebras/src/version.ts create mode 100644 packages/cohere/src/version.ts create mode 100644 packages/deepgram/src/version.ts create mode 100644 packages/deepinfra/src/version.ts create mode 100644 packages/deepseek/src/version.ts create mode 100644 packages/elevenlabs/src/version.ts create mode 100644 packages/fal/src/version.ts create mode 100644 packages/fireworks/src/version.ts create mode 100644 packages/gateway/src/version.ts create mode 100644 packages/gladia/src/version.ts create mode 100644 packages/google/src/version.ts create mode 100644 packages/groq/src/version.ts create mode 100644 packages/hume/src/version.ts create mode 100644 packages/lmnt/src/version.ts create mode 100644 packages/luma/src/version.ts create mode 100644 packages/mistral/src/version.ts create mode 100644 packages/openai/src/version.ts create mode 100644 packages/perplexity/src/version.ts create mode 100644 packages/replicate/src/version.ts create mode 100644 packages/revai/src/version.ts create mode 100644 packages/togetherai/src/version.ts create mode 100644 packages/vercel/src/version.ts create mode 100644 packages/xai/src/version.ts diff --git a/.changeset/lemon-guests-drop.md b/.changeset/lemon-guests-drop.md new file mode 100644 index 000000000000..884824144478 --- /dev/null +++ b/.changeset/lemon-guests-drop.md @@ -0,0 +1,33 @@ +--- +'@ai-sdk/gateway': patch +'@ai-sdk/openai': patch +'@ai-sdk/anthropic': patch +'@ai-sdk/google': patch +'@ai-sdk/google-vertex': patch +'@ai-sdk/azure': patch +'@ai-sdk/amazon-bedrock': patch +'@ai-sdk/cohere': patch +'@ai-sdk/mistral': patch +'@ai-sdk/groq': patch +'@ai-sdk/cerebras': patch +'@ai-sdk/deepinfra': patch +'@ai-sdk/deepseek': patch +'@ai-sdk/fireworks': patch +'@ai-sdk/perplexity': patch +'@ai-sdk/replicate': patch +'@ai-sdk/togetherai': patch +'@ai-sdk/xai': patch +'@ai-sdk/vercel': patch +'@ai-sdk/elevenlabs': patch +'@ai-sdk/assemblyai': patch +'@ai-sdk/deepgram': patch +'@ai-sdk/gladia': patch +'@ai-sdk/revai': patch +'@ai-sdk/luma': patch +'@ai-sdk/fal': patch +'@ai-sdk/hume': patch +'@ai-sdk/lmnt': patch +'@ai-sdk/baseten': patch +--- + +feat: add provider version to user-agent header diff --git a/packages/amazon-bedrock/src/bedrock-provider.test.ts b/packages/amazon-bedrock/src/bedrock-provider.test.ts index 978d121e8946..1bdb3298e8d3 100644 --- a/packages/amazon-bedrock/src/bedrock-provider.test.ts +++ b/packages/amazon-bedrock/src/bedrock-provider.test.ts @@ -60,6 +60,10 @@ vi.mock('@ai-sdk/provider-utils', async importOriginal => { }; }); +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + // Import mocked modules to get references import { createSigV4FetchFunction, @@ -89,14 +93,17 @@ describe('AmazonBedrockProvider', () => { const constructorCall = BedrockChatLanguageModelMock.mock.calls[0]; expect(constructorCall[0]).toBe('anthropic.claude-v2'); - expect(constructorCall[1].headers).toEqual({}); + expect(constructorCall[1].headers()).toMatchObject({}); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/0.0.0-test', + ); expect(constructorCall[1].baseUrl()).toBe( 'https://bedrock-runtime.us-east-1.amazonaws.com', ); }); it('should create a provider instance with custom options', () => { - const customHeaders = { 'Custom-Header': 'value' }; + const customHeaders = { 'custom-header': 'value' }; const options = { region: 'eu-west-1', baseURL: 'https://custom.url', @@ -107,7 +114,10 @@ describe('AmazonBedrockProvider', () => { provider('anthropic.claude-v2'); const constructorCall = BedrockChatLanguageModelMock.mock.calls[0]; - expect(constructorCall[1].headers).toEqual(customHeaders); + expect(constructorCall[1].headers()).toMatchObject(customHeaders); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/0.0.0-test', + ); expect(constructorCall[1].baseUrl()).toBe('https://custom.url'); }); @@ -126,7 +136,10 @@ describe('AmazonBedrockProvider', () => { const constructorCall = BedrockChatLanguageModelMock.mock.calls[0]; expect(constructorCall[0]).toBe('anthropic.claude-v2'); - expect(constructorCall[1].headers).toEqual({}); + expect(constructorCall[1].headers()).toMatchObject({}); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/0.0.0-test', + ); expect(constructorCall[1].baseUrl()).toBe( 'https://bedrock-runtime.us-east-1.amazonaws.com', ); @@ -152,7 +165,7 @@ describe('AmazonBedrockProvider', () => { }); it('should pass headers to embedding model', () => { - const customHeaders = { 'Custom-Header': 'value' }; + const customHeaders = { 'custom-header': 'value' }; const provider = createAmazonBedrock({ headers: customHeaders, }); @@ -160,7 +173,10 @@ describe('AmazonBedrockProvider', () => { provider.embedding('amazon.titan-embed-text-v1'); const constructorCall = BedrockEmbeddingModelMock.mock.calls[0]; - expect(constructorCall[1].headers).toEqual(customHeaders); + expect(constructorCall[1].headers()).toMatchObject(customHeaders); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/0.0.0-test', + ); }); it('should throw error when called with new keyword', () => { @@ -190,7 +206,10 @@ describe('AmazonBedrockProvider', () => { const constructorCall = BedrockChatLanguageModelMock.mock.calls[0]; expect(constructorCall[0]).toBe('anthropic.claude-v2'); - expect(constructorCall[1].headers).toEqual({}); + expect(constructorCall[1].headers()).toMatchObject({}); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/', + ); expect(constructorCall[1].baseUrl()).toBe( 'https://bedrock-runtime.us-east-1.amazonaws.com', ); @@ -306,16 +325,19 @@ describe('AmazonBedrockProvider', () => { const provider = createAmazonBedrock({ apiKey: 'test-api-key', region: 'us-east-1', - headers: { 'Custom-Header': 'value' }, + headers: { 'custom-header': 'value' }, }); provider.embedding('amazon.titan-embed-text-v1'); const constructorCall = BedrockEmbeddingModelMock.mock.calls[0]; expect(constructorCall[0]).toBe('amazon.titan-embed-text-v1'); - expect(constructorCall[1].headers).toEqual({ - 'Custom-Header': 'value', + expect(constructorCall[1].headers()).toMatchObject({ + 'custom-header': 'value', }); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/0.0.0-test', + ); expect(mockCreateApiKeyFetchFunction).toHaveBeenCalledWith( 'test-api-key', undefined, @@ -326,16 +348,19 @@ describe('AmazonBedrockProvider', () => { const provider = createAmazonBedrock({ apiKey: 'test-api-key', region: 'us-east-1', - headers: { 'Custom-Header': 'value' }, + headers: { 'custom-header': 'value' }, }); provider.image('amazon.titan-image-generator'); const constructorCall = BedrockImageModelMock.mock.calls[0]; expect(constructorCall[0]).toBe('amazon.titan-image-generator'); - expect(constructorCall[1].headers).toEqual({ - 'Custom-Header': 'value', + expect(constructorCall[1].headers()).toMatchObject({ + 'custom-header': 'value', }); + expect(constructorCall[1].headers()['user-agent']).toContain( + 'ai-sdk/amazon-bedrock/0.0.0-test', + ); expect(mockCreateApiKeyFetchFunction).toHaveBeenCalledWith( 'test-api-key', undefined, diff --git a/packages/amazon-bedrock/src/bedrock-provider.ts b/packages/amazon-bedrock/src/bedrock-provider.ts index 5128db57c6c4..a3efbcf25e34 100644 --- a/packages/amazon-bedrock/src/bedrock-provider.ts +++ b/packages/amazon-bedrock/src/bedrock-provider.ts @@ -10,7 +10,9 @@ import { loadOptionalSetting, loadSetting, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; import { anthropicTools } from '@ai-sdk/anthropic/internal'; import { BedrockChatLanguageModel } from './bedrock-chat-language-model'; import { BedrockChatModelId } from './bedrock-chat-options'; @@ -236,10 +238,15 @@ export function createAmazonBedrock( })}.amazonaws.com`, ) ?? `https://bedrock-runtime.us-east-1.amazonaws.com`; + const getHeaders = () => { + const baseHeaders = options.headers ?? {}; + return withUserAgentSuffix(baseHeaders, `ai-sdk/amazon-bedrock/${VERSION}`); + }; + const createChatModel = (modelId: BedrockChatModelId) => new BedrockChatLanguageModel(modelId, { baseUrl: getBaseUrl, - headers: options.headers ?? {}, + headers: getHeaders, fetch: fetchFunction, generateId, }); @@ -257,14 +264,14 @@ export function createAmazonBedrock( const createEmbeddingModel = (modelId: BedrockEmbeddingModelId) => new BedrockEmbeddingModel(modelId, { baseUrl: getBaseUrl, - headers: options.headers ?? {}, + headers: getHeaders, fetch: fetchFunction, }); const createImageModel = (modelId: BedrockImageModelId) => new BedrockImageModel(modelId, { baseUrl: getBaseUrl, - headers: options.headers ?? {}, + headers: getHeaders, fetch: fetchFunction, }); diff --git a/packages/anthropic/src/anthropic-messages-language-model.test.ts b/packages/anthropic/src/anthropic-messages-language-model.test.ts index 0a219a26a68d..45bac53bc781 100644 --- a/packages/anthropic/src/anthropic-messages-language-model.test.ts +++ b/packages/anthropic/src/anthropic-messages-language-model.test.ts @@ -11,7 +11,11 @@ import { import { AnthropicProviderOptions } from './anthropic-messages-options'; import { createAnthropic } from './anthropic-provider'; import { type DocumentCitation } from './anthropic-messages-language-model'; -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -395,6 +399,9 @@ describe('AnthropicMessagesLanguageModel', () => { // custom header 'test-header': 'test-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/anthropic/0.0.0-test`, + ); }); it('should send the model id and settings', async () => { diff --git a/packages/anthropic/src/anthropic-provider.ts b/packages/anthropic/src/anthropic-provider.ts index 5f9a0e750a75..cd12ad335592 100644 --- a/packages/anthropic/src/anthropic-provider.ts +++ b/packages/anthropic/src/anthropic-provider.ts @@ -8,7 +8,9 @@ import { generateId, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; import { AnthropicMessagesLanguageModel } from './anthropic-messages-language-model'; import { AnthropicMessagesModelId } from './anthropic-messages-options'; import { anthropicTools } from './anthropic-tools'; @@ -70,15 +72,19 @@ export function createAnthropic( const baseURL = withoutTrailingSlash(options.baseURL) ?? 'https://api.anthropic.com/v1'; - const getHeaders = () => ({ - 'anthropic-version': '2023-06-01', - 'x-api-key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'ANTHROPIC_API_KEY', - description: 'Anthropic', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + 'anthropic-version': '2023-06-01', + 'x-api-key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'ANTHROPIC_API_KEY', + description: 'Anthropic', + }), + ...options.headers, + }, + `ai-sdk/anthropic/${VERSION}`, + ); const createChatModel = (modelId: AnthropicMessagesModelId) => new AnthropicMessagesLanguageModel(modelId, { diff --git a/packages/anthropic/src/index.ts b/packages/anthropic/src/index.ts index 2581ae4017d3..85c69f614610 100644 --- a/packages/anthropic/src/index.ts +++ b/packages/anthropic/src/index.ts @@ -4,3 +4,4 @@ export type { AnthropicProvider, AnthropicProviderSettings, } from './anthropic-provider'; +export { VERSION } from './version'; diff --git a/packages/anthropic/src/version.ts b/packages/anthropic/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/anthropic/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/anthropic/tsup.config.ts b/packages/anthropic/tsup.config.ts index 87efcf0d5720..d0b56a7122cd 100644 --- a/packages/anthropic/tsup.config.ts +++ b/packages/anthropic/tsup.config.ts @@ -6,6 +6,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, { entry: ['src/internal/index.ts'], @@ -13,5 +19,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/anthropic/vitest.edge.config.js b/packages/anthropic/vitest.edge.config.js index 3dc49ba29774..82e68f1229bd 100644 --- a/packages/anthropic/vitest.edge.config.js +++ b/packages/anthropic/vitest.edge.config.js @@ -1,4 +1,9 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +11,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, }); diff --git a/packages/anthropic/vitest.node.config.js b/packages/anthropic/vitest.node.config.js index b7e4a9cabd48..740ecb8018f4 100644 --- a/packages/anthropic/vitest.node.config.js +++ b/packages/anthropic/vitest.node.config.js @@ -1,4 +1,9 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +11,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, }); diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index b5383ead2a51..d10118c43b9b 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -18,6 +18,7 @@ "type-check": "tsc --build", "prettier-check": "prettier --check \"./**/*.ts*\"", "test": "pnpm test:node && pnpm test:edge", + "test:watch": "vitest --config vitest.node.config.js", "test:edge": "vitest --config vitest.edge.config.js --run", "test:node": "vitest --config vitest.node.config.js --run", "test:node:watch": "vitest --config vitest.node.config.js --watch" diff --git a/packages/assemblyai/src/assemblyai-provider.ts b/packages/assemblyai/src/assemblyai-provider.ts index 45282dd416be..b2d018cfc44e 100644 --- a/packages/assemblyai/src/assemblyai-provider.ts +++ b/packages/assemblyai/src/assemblyai-provider.ts @@ -3,9 +3,14 @@ import { ProviderV2, NoSuchModelError, } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { AssemblyAITranscriptionModel } from './assemblyai-transcription-model'; import { AssemblyAITranscriptionModelId } from './assemblyai-transcription-settings'; +import { VERSION } from './version'; export interface AssemblyAIProvider extends ProviderV2 { ( @@ -45,14 +50,18 @@ Create an AssemblyAI provider instance. export function createAssemblyAI( options: AssemblyAIProviderSettings = {}, ): AssemblyAIProvider { - const getHeaders = () => ({ - authorization: loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'ASSEMBLYAI_API_KEY', - description: 'AssemblyAI', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + authorization: loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'ASSEMBLYAI_API_KEY', + description: 'AssemblyAI', + }), + ...options.headers, + }, + `ai-sdk/assemblyai/${VERSION}`, + ); const createTranscriptionModel = (modelId: AssemblyAITranscriptionModelId) => new AssemblyAITranscriptionModel(modelId, { diff --git a/packages/assemblyai/src/assemblyai-transcription-model.test.ts b/packages/assemblyai/src/assemblyai-transcription-model.test.ts index 48b96fa1c779..fcd3a34de689 100644 --- a/packages/assemblyai/src/assemblyai-transcription-model.test.ts +++ b/packages/assemblyai/src/assemblyai-transcription-model.test.ts @@ -3,7 +3,11 @@ import { AssemblyAITranscriptionModel } from './assemblyai-transcription-model'; import { createAssemblyAI } from './assemblyai-provider'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); const provider = createAssemblyAI({ apiKey: 'test-api-key' }); @@ -280,6 +284,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/assemblyai/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/assemblyai/src/index.ts b/packages/assemblyai/src/index.ts index 6c90fa17c72b..6346cee20197 100644 --- a/packages/assemblyai/src/index.ts +++ b/packages/assemblyai/src/index.ts @@ -3,3 +3,4 @@ export type { AssemblyAIProvider, AssemblyAIProviderSettings, } from './assemblyai-provider'; +export { VERSION } from './version'; diff --git a/packages/assemblyai/src/version.ts b/packages/assemblyai/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/assemblyai/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/assemblyai/tsup.config.ts b/packages/assemblyai/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/assemblyai/tsup.config.ts +++ b/packages/assemblyai/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/assemblyai/vitest.edge.config.js b/packages/assemblyai/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/assemblyai/vitest.edge.config.js +++ b/packages/assemblyai/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/assemblyai/vitest.node.config.js b/packages/assemblyai/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/assemblyai/vitest.node.config.js +++ b/packages/assemblyai/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/azure/src/azure-openai-provider.test.ts b/packages/azure/src/azure-openai-provider.test.ts index 8c6b3f47ee43..b6c6d6b34f00 100644 --- a/packages/azure/src/azure-openai-provider.test.ts +++ b/packages/azure/src/azure-openai-provider.test.ts @@ -4,7 +4,11 @@ import { } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createAzure } from './azure-openai-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -113,6 +117,9 @@ describe('chat', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/azure/0.0.0-test`, + ); }); it('should use the baseURL correctly', async () => { @@ -208,6 +215,9 @@ describe('completion', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/azure/0.0.0-test`, + ); }); }); }); @@ -356,6 +366,9 @@ describe('embedding', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/azure/0.0.0-test`, + ); }); }); }); @@ -450,6 +463,9 @@ describe('image', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/azure/0.0.0-test`, + ); }); it('should use the baseURL correctly', async () => { @@ -600,6 +616,9 @@ describe('responses', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/azure/0.0.0-test`, + ); }); it('should use the baseURL correctly', async () => { diff --git a/packages/azure/src/azure-openai-provider.ts b/packages/azure/src/azure-openai-provider.ts index e90a8fa83824..060f213ac7db 100644 --- a/packages/azure/src/azure-openai-provider.ts +++ b/packages/azure/src/azure-openai-provider.ts @@ -15,7 +15,13 @@ import { SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey, loadSetting } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + loadSetting, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; export interface AzureOpenAIProvider extends ProviderV2 { (deploymentId: string): LanguageModelV2; @@ -124,14 +130,17 @@ Create an Azure OpenAI provider instance. export function createAzure( options: AzureOpenAIProviderSettings = {}, ): AzureOpenAIProvider { - const getHeaders = () => ({ - 'api-key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'AZURE_API_KEY', - description: 'Azure OpenAI', - }), - ...options.headers, - }); + const getHeaders = () => { + const baseHeaders = { + 'api-key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'AZURE_API_KEY', + description: 'Azure OpenAI', + }), + ...options.headers, + }; + return withUserAgentSuffix(baseHeaders, `ai-sdk/azure/${VERSION}`); + }; const getResourceName = () => loadSetting({ diff --git a/packages/azure/src/index.ts b/packages/azure/src/index.ts index d3462582558c..cf834dd34f3e 100644 --- a/packages/azure/src/index.ts +++ b/packages/azure/src/index.ts @@ -3,3 +3,4 @@ export type { AzureOpenAIProvider, AzureOpenAIProviderSettings, } from './azure-openai-provider'; +export { VERSION } from './version'; diff --git a/packages/azure/src/version.ts b/packages/azure/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/azure/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/azure/tsup.config.ts b/packages/azure/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/azure/tsup.config.ts +++ b/packages/azure/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/azure/vitest.edge.config.js b/packages/azure/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/azure/vitest.edge.config.js +++ b/packages/azure/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/azure/vitest.node.config.js b/packages/azure/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/azure/vitest.node.config.js +++ b/packages/azure/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/baseten/src/baseten-provider.ts b/packages/baseten/src/baseten-provider.ts index 3f4e796ec106..45feb9ec8d24 100644 --- a/packages/baseten/src/baseten-provider.ts +++ b/packages/baseten/src/baseten-provider.ts @@ -13,11 +13,13 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { z } from 'zod/v4'; import { BasetenChatModelId } from './baseten-chat-options'; import { BasetenEmbeddingModelId } from './baseten-embedding-options'; import { PerformanceClient } from '@basetenlabs/performance-client'; +import { VERSION } from './version'; export type BasetenErrorData = z.infer; @@ -90,14 +92,18 @@ export function createBaseten( options: BasetenProviderSettings = {}, ): BasetenProvider { const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'BASETEN_API_KEY', - description: 'Baseten API key', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'BASETEN_API_KEY', + description: 'Baseten API key', + })}`, + ...options.headers, + }, + `ai-sdk/baseten/${VERSION}`, + ); interface CommonModelConfig { provider: string; diff --git a/packages/baseten/src/baseten-provider.unit.test.ts b/packages/baseten/src/baseten-provider.unit.test.ts index 5350eb50a9f9..bd6b74d2d7db 100644 --- a/packages/baseten/src/baseten-provider.unit.test.ts +++ b/packages/baseten/src/baseten-provider.unit.test.ts @@ -39,10 +39,14 @@ vi.mock('@ai-sdk/openai-compatible', () => { }; }); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), -})); +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); vi.mock('@basetenlabs/performance-client', () => ({ PerformanceClient: vi.fn().mockImplementation(() => ({ @@ -51,6 +55,10 @@ vi.mock('@basetenlabs/performance-client', () => ({ })), })); +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + describe('BasetenProvider', () => { beforeEach(() => { vi.clearAllMocks(); @@ -71,7 +79,7 @@ describe('BasetenProvider', () => { environmentVariableName: 'BASETEN_API_KEY', description: 'Baseten API key', }); - expect(headers.Authorization).toBe('Bearer mock-api-key'); + expect(headers.authorization).toBe('Bearer mock-api-key'); expect(config.provider).toBe('baseten.chat'); }); @@ -94,7 +102,7 @@ describe('BasetenProvider', () => { environmentVariableName: 'BASETEN_API_KEY', description: 'Baseten API key', }); - expect(headers['Custom-Header']).toBe('value'); + expect(headers['custom-header']).toBe('value'); }); it('should support optional modelId parameter', () => { @@ -352,7 +360,7 @@ describe('BasetenProvider', () => { const config = constructorCall[1]; const headers = config.headers(); - expect(headers.Authorization).toBe('Bearer mock-api-key'); + expect(headers.authorization).toBe('Bearer mock-api-key'); }); it('should include custom headers when provided', () => { @@ -366,8 +374,31 @@ describe('BasetenProvider', () => { const config = constructorCall[1]; const headers = config.headers(); - expect(headers.Authorization).toBe('Bearer mock-api-key'); - expect(headers['Custom-Header']).toBe('custom-value'); + expect(headers.authorization).toBe('Bearer mock-api-key'); + expect(headers['custom-header']).toBe('custom-value'); + }); + + it('should include user-agent with version', async () => { + const fetchMock = vi + .fn() + .mockResolvedValue(new Response('{}', { status: 200 })); + + const provider = createBaseten({ fetch: fetchMock }); + const model = provider.chatModel('test-model'); + + const constructorCall = + OpenAICompatibleChatLanguageModelMock.mock.calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + await fetchMock('https://example.com/test', { + method: 'POST', + headers, + }); + + expect(fetchMock.mock.calls[0][1].headers['user-agent']).toContain( + 'ai-sdk/baseten/0.0.0-test', + ); }); }); diff --git a/packages/baseten/src/index.ts b/packages/baseten/src/index.ts index 5eec4c4f4727..3bb8b2ead351 100644 --- a/packages/baseten/src/index.ts +++ b/packages/baseten/src/index.ts @@ -5,3 +5,4 @@ export type { BasetenProviderSettings, BasetenErrorData, } from './baseten-provider'; +export { VERSION } from './version'; diff --git a/packages/baseten/src/version.ts b/packages/baseten/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/baseten/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/baseten/tsup.config.ts b/packages/baseten/tsup.config.ts index 3f92041b987c..da74c084b2f1 100644 --- a/packages/baseten/tsup.config.ts +++ b/packages/baseten/tsup.config.ts @@ -1,4 +1,5 @@ import { defineConfig } from 'tsup'; +import packageJson from './package.json'; export default defineConfig([ { @@ -6,5 +7,8 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }, ]); diff --git a/packages/baseten/vitest.edge.config.js b/packages/baseten/vitest.edge.config.js index 700660e913f5..838aa2f38c40 100644 --- a/packages/baseten/vitest.edge.config.js +++ b/packages/baseten/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -7,4 +8,7 @@ export default defineConfig({ globals: true, include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/baseten/vitest.node.config.js b/packages/baseten/vitest.node.config.js index b1d14b21fc11..1c97a185facd 100644 --- a/packages/baseten/vitest.node.config.js +++ b/packages/baseten/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -7,4 +8,7 @@ export default defineConfig({ globals: true, include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/cerebras/src/cerebras-provider.test.ts b/packages/cerebras/src/cerebras-provider.test.ts index 80480332a8df..8cbef81b58e6 100644 --- a/packages/cerebras/src/cerebras-provider.test.ts +++ b/packages/cerebras/src/cerebras-provider.test.ts @@ -11,11 +11,19 @@ vi.mock('@ai-sdk/openai-compatible', () => ({ OpenAICompatibleChatLanguageModel: vi.fn(), })); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', })); +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); + describe('CerebrasProvider', () => { beforeEach(() => { vi.clearAllMocks(); @@ -59,6 +67,29 @@ describe('CerebrasProvider', () => { }); }); + it('should pass header', async () => { + const fetchMock = vi + .fn() + .mockResolvedValue(new Response('{}', { status: 200 })); + + const provider = createCerebras({ fetch: fetchMock }); + provider('model-id'); + + const constructorCall = vi.mocked(OpenAICompatibleChatLanguageModel).mock + .calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + await fetchMock('https://api.cerebras.ai/v1/test', { + method: 'POST', + headers, + }); + + expect(fetchMock.mock.calls[0][1].headers['user-agent']).toContain( + 'ai-sdk/cerebras/0.0.0-test', + ); + }); + it('should return a chat model when called as a function', () => { const provider = createCerebras(); const modelId = 'foo-model-id'; diff --git a/packages/cerebras/src/cerebras-provider.ts b/packages/cerebras/src/cerebras-provider.ts index a5148114a8d2..74332ce9e427 100644 --- a/packages/cerebras/src/cerebras-provider.ts +++ b/packages/cerebras/src/cerebras-provider.ts @@ -8,10 +8,12 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { CerebrasChatModelId } from './cerebras-chat-options'; import { z } from 'zod/v4'; import { ProviderErrorStructure } from '@ai-sdk/openai-compatible'; +import { VERSION } from './version'; // Add error schema and structure const cerebrasErrorSchema = z.object({ @@ -71,14 +73,18 @@ export function createCerebras( const baseURL = withoutTrailingSlash( options.baseURL ?? 'https://api.cerebras.ai/v1', ); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'CEREBRAS_API_KEY', - description: 'Cerebras API key', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'CEREBRAS_API_KEY', + description: 'Cerebras API key', + })}`, + ...options.headers, + }, + `ai-sdk/cerebras/${VERSION}`, + ); const createLanguageModel = (modelId: CerebrasChatModelId) => { return new OpenAICompatibleChatLanguageModel(modelId, { diff --git a/packages/cerebras/src/index.ts b/packages/cerebras/src/index.ts index 1f047216e861..17c7be327c06 100644 --- a/packages/cerebras/src/index.ts +++ b/packages/cerebras/src/index.ts @@ -4,3 +4,4 @@ export type { CerebrasProviderSettings, } from './cerebras-provider'; export type { CerebrasErrorData } from './cerebras-provider'; +export { VERSION } from './version'; diff --git a/packages/cerebras/src/version.ts b/packages/cerebras/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/cerebras/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/cerebras/tsup.config.ts b/packages/cerebras/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/cerebras/tsup.config.ts +++ b/packages/cerebras/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/cerebras/vitest.edge.config.js b/packages/cerebras/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/cerebras/vitest.edge.config.js +++ b/packages/cerebras/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/cerebras/vitest.node.config.js b/packages/cerebras/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/cerebras/vitest.node.config.js +++ b/packages/cerebras/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/cohere/src/cohere-embedding-model.test.ts b/packages/cohere/src/cohere-embedding-model.test.ts index 4c77367ce18d..c8fa45b8a338 100644 --- a/packages/cohere/src/cohere-embedding-model.test.ts +++ b/packages/cohere/src/cohere-embedding-model.test.ts @@ -1,7 +1,11 @@ import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createCohere } from './cohere-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const dummyEmbeddings = [ [0.1, 0.2, 0.3, 0.4, 0.5], @@ -132,5 +136,8 @@ describe('doEmbed', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/cohere/0.0.0-test`, + ); }); }); diff --git a/packages/cohere/src/cohere-provider.ts b/packages/cohere/src/cohere-provider.ts index 370d9098b0b7..6c80a654971d 100644 --- a/packages/cohere/src/cohere-provider.ts +++ b/packages/cohere/src/cohere-provider.ts @@ -9,11 +9,13 @@ import { generateId, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { CohereChatLanguageModel } from './cohere-chat-language-model'; import { CohereChatModelId } from './cohere-chat-options'; import { CohereEmbeddingModel } from './cohere-embedding-model'; import { CohereEmbeddingModelId } from './cohere-embedding-options'; +import { VERSION } from './version'; export interface CohereProvider extends ProviderV2 { (modelId: CohereChatModelId): LanguageModelV2; @@ -67,14 +69,18 @@ export function createCohere( const baseURL = withoutTrailingSlash(options.baseURL) ?? 'https://api.cohere.com/v2'; - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'COHERE_API_KEY', - description: 'Cohere', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'COHERE_API_KEY', + description: 'Cohere', + })}`, + ...options.headers, + }, + `ai-sdk/cohere/${VERSION}`, + ); const createChatModel = (modelId: CohereChatModelId) => new CohereChatLanguageModel(modelId, { diff --git a/packages/cohere/src/index.ts b/packages/cohere/src/index.ts index d36326be7bce..164cab7dfe91 100644 --- a/packages/cohere/src/index.ts +++ b/packages/cohere/src/index.ts @@ -1,3 +1,4 @@ export { cohere, createCohere } from './cohere-provider'; export type { CohereProvider, CohereProviderSettings } from './cohere-provider'; export type { CohereChatModelOptions } from './cohere-chat-options'; +export { VERSION } from './version'; diff --git a/packages/cohere/src/version.ts b/packages/cohere/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/cohere/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/cohere/tsup.config.ts b/packages/cohere/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/cohere/tsup.config.ts +++ b/packages/cohere/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/cohere/vitest.edge.config.js b/packages/cohere/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/cohere/vitest.edge.config.js +++ b/packages/cohere/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/cohere/vitest.node.config.js b/packages/cohere/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/cohere/vitest.node.config.js +++ b/packages/cohere/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index 19e250457c5f..799c691ee894 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -18,6 +18,7 @@ "type-check": "tsc --noEmit", "prettier-check": "prettier --check \"./**/*.ts*\"", "test": "pnpm test:node && pnpm test:edge", + "test:watch": "vitest --config vitest.node.config.js", "test:edge": "vitest --config vitest.edge.config.js --run", "test:node": "vitest --config vitest.node.config.js --run", "test:node:watch": "vitest --config vitest.node.config.js --watch" diff --git a/packages/deepgram/src/deepgram-provider.ts b/packages/deepgram/src/deepgram-provider.ts index 6ff74c7ef77e..4227ce33bed0 100644 --- a/packages/deepgram/src/deepgram-provider.ts +++ b/packages/deepgram/src/deepgram-provider.ts @@ -3,9 +3,14 @@ import { ProviderV2, NoSuchModelError, } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { DeepgramTranscriptionModel } from './deepgram-transcription-model'; import { DeepgramTranscriptionModelId } from './deepgram-transcription-options'; +import { VERSION } from './version'; export interface DeepgramProvider extends ProviderV2 { ( @@ -45,14 +50,18 @@ Create an Deepgram provider instance. export function createDeepgram( options: DeepgramProviderSettings = {}, ): DeepgramProvider { - const getHeaders = () => ({ - authorization: `Token ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'DEEPGRAM_API_KEY', - description: 'Deepgram', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + authorization: `Token ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'DEEPGRAM_API_KEY', + description: 'Deepgram', + })}`, + ...options.headers, + }, + `ai-sdk/deepgram/${VERSION}`, + ); const createTranscriptionModel = (modelId: DeepgramTranscriptionModelId) => new DeepgramTranscriptionModel(modelId, { diff --git a/packages/deepgram/src/deepgram-transcription-model.test.ts b/packages/deepgram/src/deepgram-transcription-model.test.ts index fa7ab63819ab..c73e4a3b1db5 100644 --- a/packages/deepgram/src/deepgram-transcription-model.test.ts +++ b/packages/deepgram/src/deepgram-transcription-model.test.ts @@ -3,7 +3,11 @@ import { DeepgramTranscriptionModel } from './deepgram-transcription-model'; import { createDeepgram } from './deepgram-provider'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); const provider = createDeepgram({ apiKey: 'test-api-key' }); @@ -124,6 +128,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/deepgram/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/deepgram/src/index.ts b/packages/deepgram/src/index.ts index 4abcf2461f66..e86cd82d4153 100644 --- a/packages/deepgram/src/index.ts +++ b/packages/deepgram/src/index.ts @@ -3,3 +3,4 @@ export type { DeepgramProvider, DeepgramProviderSettings, } from './deepgram-provider'; +export { VERSION } from './version'; diff --git a/packages/deepgram/src/version.ts b/packages/deepgram/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/deepgram/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/deepgram/tsup.config.ts b/packages/deepgram/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/deepgram/tsup.config.ts +++ b/packages/deepgram/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/deepgram/vitest.edge.config.js b/packages/deepgram/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/deepgram/vitest.edge.config.js +++ b/packages/deepgram/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/deepgram/vitest.node.config.js b/packages/deepgram/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/deepgram/vitest.node.config.js +++ b/packages/deepgram/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/deepinfra/src/deepinfra-provider.test.ts b/packages/deepinfra/src/deepinfra-provider.test.ts index 799248b394f0..cc59701048fd 100644 --- a/packages/deepinfra/src/deepinfra-provider.test.ts +++ b/packages/deepinfra/src/deepinfra-provider.test.ts @@ -19,10 +19,14 @@ vi.mock('@ai-sdk/openai-compatible', () => ({ OpenAICompatibleEmbeddingModel: vi.fn(), })); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), -})); +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); vi.mock('./deepinfra-image-model', () => ({ DeepInfraImageModel: vi.fn(), diff --git a/packages/deepinfra/src/deepinfra-provider.ts b/packages/deepinfra/src/deepinfra-provider.ts index 022f7951728e..8f2bef69476c 100644 --- a/packages/deepinfra/src/deepinfra-provider.ts +++ b/packages/deepinfra/src/deepinfra-provider.ts @@ -13,12 +13,14 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { DeepInfraChatModelId } from './deepinfra-chat-options'; import { DeepInfraEmbeddingModelId } from './deepinfra-embedding-options'; import { DeepInfraCompletionModelId } from './deepinfra-completion-options'; import { DeepInfraImageModelId } from './deepinfra-image-settings'; import { DeepInfraImageModel } from './deepinfra-image-model'; +import { VERSION } from './version'; export interface DeepInfraProviderSettings { /** @@ -85,14 +87,18 @@ export function createDeepInfra( const baseURL = withoutTrailingSlash( options.baseURL ?? 'https://api.deepinfra.com/v1', ); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'DEEPINFRA_API_KEY', - description: "DeepInfra's API key", - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'DEEPINFRA_API_KEY', + description: "DeepInfra's API key", + })}`, + ...options.headers, + }, + `ai-sdk/deepinfra/${VERSION}`, + ); interface CommonModelConfig { provider: string; diff --git a/packages/deepinfra/src/index.ts b/packages/deepinfra/src/index.ts index 0c5d1535d580..c10ddcf0618d 100644 --- a/packages/deepinfra/src/index.ts +++ b/packages/deepinfra/src/index.ts @@ -4,3 +4,4 @@ export type { DeepInfraProviderSettings, } from './deepinfra-provider'; export type { OpenAICompatibleErrorData as DeepInfraErrorData } from '@ai-sdk/openai-compatible'; +export { VERSION } from './version'; diff --git a/packages/deepinfra/src/version.ts b/packages/deepinfra/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/deepinfra/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/deepinfra/tsup.config.ts b/packages/deepinfra/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/deepinfra/tsup.config.ts +++ b/packages/deepinfra/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/deepinfra/vitest.edge.config.js b/packages/deepinfra/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/deepinfra/vitest.edge.config.js +++ b/packages/deepinfra/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/deepinfra/vitest.node.config.js b/packages/deepinfra/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/deepinfra/vitest.node.config.js +++ b/packages/deepinfra/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/deepseek/src/deepseek-provider.test.ts b/packages/deepseek/src/deepseek-provider.test.ts index e9412214cc2c..95ee32ba45bc 100644 --- a/packages/deepseek/src/deepseek-provider.test.ts +++ b/packages/deepseek/src/deepseek-provider.test.ts @@ -11,9 +11,17 @@ vi.mock('@ai-sdk/openai-compatible', () => ({ OpenAICompatibleChatLanguageModel: vi.fn(), })); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', })); describe('DeepSeekProvider', () => { @@ -66,6 +74,29 @@ describe('DeepSeekProvider', () => { const model = provider(modelId); expect(model).toBeInstanceOf(OpenAICompatibleChatLanguageModel); }); + + it('should include deepseek version in user-agent header', async () => { + const fetchMock = vi + .fn() + .mockResolvedValue(new Response('{}', { status: 200 })); + + const provider = createDeepSeek({ fetch: fetchMock }); + provider('model-id'); + + const constructorCall = vi.mocked(OpenAICompatibleChatLanguageModel).mock + .calls[0]; + const config = constructorCall[1]; + const headers = config.headers(); + + await fetchMock('https://api.deepseek.com/v1/test', { + method: 'POST', + headers, + }); + + expect(fetchMock.mock.calls[0][1].headers['user-agent']).toContain( + 'ai-sdk/deepseek/0.0.0-test', + ); + }); }); describe('chat', () => { diff --git a/packages/deepseek/src/deepseek-provider.ts b/packages/deepseek/src/deepseek-provider.ts index 7ff1b52b474e..e30a4f59c676 100644 --- a/packages/deepseek/src/deepseek-provider.ts +++ b/packages/deepseek/src/deepseek-provider.ts @@ -8,9 +8,11 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { DeepSeekChatModelId } from './deepseek-chat-options'; import { deepSeekMetadataExtractor } from './deepseek-metadata-extractor'; +import { VERSION } from './version'; export interface DeepSeekProviderSettings { /** @@ -55,14 +57,18 @@ export function createDeepSeek( const baseURL = withoutTrailingSlash( options.baseURL ?? 'https://api.deepseek.com/v1', ); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'DEEPSEEK_API_KEY', - description: 'DeepSeek API key', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'DEEPSEEK_API_KEY', + description: 'DeepSeek API key', + })}`, + ...options.headers, + }, + `ai-sdk/deepseek/${VERSION}`, + ); const createLanguageModel = (modelId: DeepSeekChatModelId) => { return new OpenAICompatibleChatLanguageModel(modelId, { diff --git a/packages/deepseek/src/index.ts b/packages/deepseek/src/index.ts index af1912beffb8..7a48f34171f1 100644 --- a/packages/deepseek/src/index.ts +++ b/packages/deepseek/src/index.ts @@ -4,3 +4,4 @@ export type { DeepSeekProviderSettings, } from './deepseek-provider'; export type { OpenAICompatibleErrorData as DeepSeekErrorData } from '@ai-sdk/openai-compatible'; +export { VERSION } from './version'; diff --git a/packages/deepseek/src/version.ts b/packages/deepseek/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/deepseek/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/deepseek/tsup.config.ts b/packages/deepseek/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/deepseek/tsup.config.ts +++ b/packages/deepseek/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/deepseek/vitest.edge.config.js b/packages/deepseek/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/deepseek/vitest.edge.config.js +++ b/packages/deepseek/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/deepseek/vitest.node.config.js b/packages/deepseek/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/deepseek/vitest.node.config.js +++ b/packages/deepseek/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/elevenlabs/src/elevenlabs-provider.ts b/packages/elevenlabs/src/elevenlabs-provider.ts index 22e0f016c89d..ab96eea5f29d 100644 --- a/packages/elevenlabs/src/elevenlabs-provider.ts +++ b/packages/elevenlabs/src/elevenlabs-provider.ts @@ -4,11 +4,16 @@ import { ProviderV2, NoSuchModelError, } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { ElevenLabsTranscriptionModel } from './elevenlabs-transcription-model'; import { ElevenLabsTranscriptionModelId } from './elevenlabs-transcription-options'; import { ElevenLabsSpeechModel } from './elevenlabs-speech-model'; import { ElevenLabsSpeechModelId } from './elevenlabs-speech-options'; +import { VERSION } from './version'; export interface ElevenLabsProvider extends ProviderV2 { ( @@ -53,14 +58,18 @@ Create an ElevenLabs provider instance. export function createElevenLabs( options: ElevenLabsProviderSettings = {}, ): ElevenLabsProvider { - const getHeaders = () => ({ - 'xi-api-key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'ELEVENLABS_API_KEY', - description: 'ElevenLabs', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + 'xi-api-key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'ELEVENLABS_API_KEY', + description: 'ElevenLabs', + }), + ...options.headers, + }, + `ai-sdk/elevenlabs/${VERSION}`, + ); const createTranscriptionModel = (modelId: ElevenLabsTranscriptionModelId) => new ElevenLabsTranscriptionModel(modelId, { diff --git a/packages/elevenlabs/src/elevenlabs-speech-model.test.ts b/packages/elevenlabs/src/elevenlabs-speech-model.test.ts index c18bcf8088e6..209e52e35c87 100644 --- a/packages/elevenlabs/src/elevenlabs-speech-model.test.ts +++ b/packages/elevenlabs/src/elevenlabs-speech-model.test.ts @@ -1,7 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { createElevenLabs } from './elevenlabs-provider'; +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + const provider = createElevenLabs({ apiKey: 'test-api-key' }); const model = provider.speech('eleven_multilingual_v2'); @@ -154,5 +158,18 @@ describe('ElevenLabsSpeechModel', () => { 'output_format=mp3_44100_128', ); }); + + it('should include user-agent header', async () => { + prepareAudioResponse(); + + await model.doGenerate({ + text: 'Hello, world!', + voice: 'test-voice-id', + }); + + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/elevenlabs/0.0.0-test`, + ); + }); }); }); diff --git a/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts b/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts index 33b91e22a208..69725f936b33 100644 --- a/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts +++ b/packages/elevenlabs/src/elevenlabs-transcription-model.test.ts @@ -3,7 +3,11 @@ import { ElevenLabsTranscriptionModel } from './elevenlabs-transcription-model'; import { createElevenLabs } from './elevenlabs-provider'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); const provider = createElevenLabs({ apiKey: 'test-api-key' }); @@ -122,6 +126,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/elevenlabs/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/elevenlabs/src/index.ts b/packages/elevenlabs/src/index.ts index 338220a09065..5054c77bc3ab 100644 --- a/packages/elevenlabs/src/index.ts +++ b/packages/elevenlabs/src/index.ts @@ -7,3 +7,4 @@ export type { ElevenLabsSpeechModelId, ElevenLabsSpeechVoiceId, } from './elevenlabs-speech-options'; +export { VERSION } from './version'; diff --git a/packages/elevenlabs/src/version.ts b/packages/elevenlabs/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/elevenlabs/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/elevenlabs/tsup.config.ts b/packages/elevenlabs/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/elevenlabs/tsup.config.ts +++ b/packages/elevenlabs/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/elevenlabs/vitest.edge.config.js b/packages/elevenlabs/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/elevenlabs/vitest.edge.config.js +++ b/packages/elevenlabs/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/elevenlabs/vitest.node.config.js b/packages/elevenlabs/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/elevenlabs/vitest.node.config.js +++ b/packages/elevenlabs/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/fal/src/fal-provider.ts b/packages/fal/src/fal-provider.ts index 9e9860726965..6e60ba830ee9 100644 --- a/packages/fal/src/fal-provider.ts +++ b/packages/fal/src/fal-provider.ts @@ -6,13 +6,17 @@ import { TranscriptionModelV2, } from '@ai-sdk/provider'; import type { FetchFunction } from '@ai-sdk/provider-utils'; -import { withoutTrailingSlash } from '@ai-sdk/provider-utils'; +import { + withoutTrailingSlash, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { FalImageModel } from './fal-image-model'; import { FalImageModelId } from './fal-image-settings'; import { FalTranscriptionModelId } from './fal-transcription-options'; import { FalTranscriptionModel } from './fal-transcription-model'; import { FalSpeechModelId } from './fal-speech-settings'; import { FalSpeechModel } from './fal-speech-model'; +import { VERSION } from './version'; export interface FalProviderSettings { /** @@ -109,12 +113,16 @@ Create a fal.ai provider instance. */ export function createFal(options: FalProviderSettings = {}): FalProvider { const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL); - const getHeaders = () => ({ - Authorization: `Key ${loadFalApiKey({ - apiKey: options.apiKey, - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Key ${loadFalApiKey({ + apiKey: options.apiKey, + })}`, + ...options.headers, + }, + `ai-sdk/fal/${VERSION}`, + ); const createImageModel = (modelId: FalImageModelId) => new FalImageModel(modelId, { diff --git a/packages/fal/src/index.ts b/packages/fal/src/index.ts index 969dda96f1ab..75c84221d5dc 100644 --- a/packages/fal/src/index.ts +++ b/packages/fal/src/index.ts @@ -1,2 +1,3 @@ export { createFal, fal } from './fal-provider'; export type { FalProvider, FalProviderSettings } from './fal-provider'; +export { VERSION } from './version'; diff --git a/packages/fal/src/version.ts b/packages/fal/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/fal/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/fal/tsup.config.ts b/packages/fal/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/fal/tsup.config.ts +++ b/packages/fal/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/fal/vitest.edge.config.js b/packages/fal/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/fal/vitest.edge.config.js +++ b/packages/fal/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/fal/vitest.node.config.js b/packages/fal/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/fal/vitest.node.config.js +++ b/packages/fal/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/fireworks/src/fireworks-provider.test.ts b/packages/fireworks/src/fireworks-provider.test.ts index 6ff5c9065896..c6a651f959f4 100644 --- a/packages/fireworks/src/fireworks-provider.test.ts +++ b/packages/fireworks/src/fireworks-provider.test.ts @@ -39,10 +39,14 @@ vi.mock('@ai-sdk/openai-compatible', () => { }; }); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), -})); +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); vi.mock('./fireworks-image-model', () => ({ FireworksImageModel: vi.fn(), diff --git a/packages/fireworks/src/fireworks-provider.ts b/packages/fireworks/src/fireworks-provider.ts index 11d48d13de03..be1126fa2790 100644 --- a/packages/fireworks/src/fireworks-provider.ts +++ b/packages/fireworks/src/fireworks-provider.ts @@ -14,6 +14,7 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { z } from 'zod/v4'; import { FireworksChatModelId } from './fireworks-chat-options'; @@ -21,6 +22,7 @@ import { FireworksCompletionModelId } from './fireworks-completion-options'; import { FireworksEmbeddingModelId } from './fireworks-embedding-options'; import { FireworksImageModel } from './fireworks-image-model'; import { FireworksImageModelId } from './fireworks-image-options'; +import { VERSION } from './version'; export type FireworksErrorData = z.infer; @@ -99,14 +101,18 @@ export function createFireworks( options: FireworksProviderSettings = {}, ): FireworksProvider { const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'FIREWORKS_API_KEY', - description: 'Fireworks API key', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'FIREWORKS_API_KEY', + description: 'Fireworks API key', + })}`, + ...options.headers, + }, + `ai-sdk/fireworks/${VERSION}`, + ); interface CommonModelConfig { provider: string; diff --git a/packages/fireworks/src/index.ts b/packages/fireworks/src/index.ts index 48bec1c53551..4a5565e43127 100644 --- a/packages/fireworks/src/index.ts +++ b/packages/fireworks/src/index.ts @@ -10,3 +10,4 @@ export type { FireworksProviderSettings, FireworksErrorData, } from './fireworks-provider'; +export { VERSION } from './version'; diff --git a/packages/fireworks/src/version.ts b/packages/fireworks/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/fireworks/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/fireworks/tsup.config.ts b/packages/fireworks/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/fireworks/tsup.config.ts +++ b/packages/fireworks/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/fireworks/vitest.edge.config.js b/packages/fireworks/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/fireworks/vitest.edge.config.js +++ b/packages/fireworks/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/fireworks/vitest.node.config.js b/packages/fireworks/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/fireworks/vitest.node.config.js +++ b/packages/fireworks/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/gateway/src/gateway-provider.test.ts b/packages/gateway/src/gateway-provider.test.ts index 8090c526eeae..799cfee94575 100644 --- a/packages/gateway/src/gateway-provider.test.ts +++ b/packages/gateway/src/gateway-provider.test.ts @@ -48,6 +48,10 @@ vi.mock('./vercel-environment', () => ({ getVercelRequestId: vi.fn(), })); +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + describe('GatewayProvider', () => { beforeEach(() => { vi.clearAllMocks(); @@ -88,10 +92,11 @@ describe('GatewayProvider', () => { const headers = await config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer test-api-key', - 'Custom-Header': 'value', + authorization: 'Bearer test-api-key', + 'custom-header': 'value', 'ai-gateway-protocol-version': expect.any(String), 'ai-gateway-auth-method': 'api-key', + 'user-agent': 'ai-sdk/gateway/0.0.0-test', }); }); @@ -109,10 +114,11 @@ describe('GatewayProvider', () => { const headers = await config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer mock-oidc-token', - 'Custom-Header': 'value', + authorization: 'Bearer mock-oidc-token', + 'custom-header': 'value', 'ai-gateway-protocol-version': expect.any(String), 'ai-gateway-auth-method': 'oidc', + 'user-agent': 'ai-sdk/gateway/0.0.0-test', }); }); @@ -388,8 +394,9 @@ describe('GatewayProvider', () => { const headers = await resolve(config.headers()); // Verify that the API key was used in the Authorization header - expect(headers.Authorization).toBe(`Bearer ${testApiKey}`); + expect(headers['authorization']).toBe(`Bearer ${testApiKey}`); expect(headers['ai-gateway-auth-method']).toBe('api-key'); + expect(headers['user-agent']).toBe('ai-sdk/gateway/0.0.0-test'); // Verify getVercelOidcToken was never called expect(getVercelOidcToken).not.toHaveBeenCalled(); @@ -891,7 +898,7 @@ describe('GatewayProvider', () => { it('should include proper headers for credits request', async () => { const provider = createGatewayProvider({ apiKey: 'test-key', - headers: { 'Custom-Header': 'custom-value' }, + headers: { 'custom-header': 'custom-value' }, }); await provider.getCredits(); @@ -900,10 +907,11 @@ describe('GatewayProvider', () => { const headers = await config.headers(); expect(headers).toEqual({ - Authorization: 'Bearer test-key', + authorization: 'Bearer test-key', 'ai-gateway-protocol-version': '0.0.1', 'ai-gateway-auth-method': 'api-key', - 'Custom-Header': 'custom-value', + 'custom-header': 'custom-value', + 'user-agent': 'ai-sdk/gateway/0.0.0-test', }); }); diff --git a/packages/gateway/src/gateway-provider.ts b/packages/gateway/src/gateway-provider.ts index c0cd0a18f07a..cd42a58bf24a 100644 --- a/packages/gateway/src/gateway-provider.ts +++ b/packages/gateway/src/gateway-provider.ts @@ -24,6 +24,8 @@ import type { EmbeddingModelV3, ProviderV2, } from '@ai-sdk/provider'; +import { withUserAgentSuffix } from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; export interface GatewayProvider extends ProviderV2 { (modelId: GatewayModelId): LanguageModelV2; @@ -107,12 +109,15 @@ export function createGatewayProvider( const getHeaders = async () => { const auth = await getGatewayAuthToken(options); if (auth) { - return { - Authorization: `Bearer ${auth.token}`, - 'ai-gateway-protocol-version': AI_GATEWAY_PROTOCOL_VERSION, - [GATEWAY_AUTH_METHOD_HEADER]: auth.authMethod, - ...options.headers, - }; + return withUserAgentSuffix( + { + Authorization: `Bearer ${auth.token}`, + 'ai-gateway-protocol-version': AI_GATEWAY_PROTOCOL_VERSION, + [GATEWAY_AUTH_METHOD_HEADER]: auth.authMethod, + ...options.headers, + }, + `ai-sdk/gateway/${VERSION}`, + ); } throw GatewayAuthenticationError.createContextualError({ diff --git a/packages/gateway/src/version.ts b/packages/gateway/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/gateway/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/gateway/tsup.config.ts b/packages/gateway/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/gateway/tsup.config.ts +++ b/packages/gateway/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/gateway/vitest.edge.config.js b/packages/gateway/vitest.edge.config.js index 3dc49ba29774..02b9e8c6cf92 100644 --- a/packages/gateway/vitest.edge.config.js +++ b/packages/gateway/vitest.edge.config.js @@ -1,7 +1,15 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], diff --git a/packages/gateway/vitest.node.config.js b/packages/gateway/vitest.node.config.js index b7e4a9cabd48..5b86131f58c6 100644 --- a/packages/gateway/vitest.node.config.js +++ b/packages/gateway/vitest.node.config.js @@ -1,7 +1,15 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; + +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], diff --git a/packages/gladia/package.json b/packages/gladia/package.json index 0e448c4fcacc..4481b8a4688d 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -18,6 +18,7 @@ "type-check": "tsc --noEmit", "prettier-check": "prettier --check \"./**/*.ts*\"", "test": "pnpm test:node && pnpm test:edge", + "test:watch": "vitest --config vitest.node.config.js", "test:edge": "vitest --config vitest.edge.config.js --run", "test:node": "vitest --config vitest.node.config.js --run", "test:node:watch": "vitest --config vitest.node.config.js --watch" diff --git a/packages/gladia/src/gladia-provider.ts b/packages/gladia/src/gladia-provider.ts index 235dad00d0d9..8425781bbad7 100644 --- a/packages/gladia/src/gladia-provider.ts +++ b/packages/gladia/src/gladia-provider.ts @@ -3,8 +3,13 @@ import { ProviderV2, NoSuchModelError, } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { GladiaTranscriptionModel } from './gladia-transcription-model'; +import { VERSION } from './version'; export interface GladiaProvider extends ProviderV2 { (): { @@ -41,14 +46,18 @@ Create a Gladia provider instance. export function createGladia( options: GladiaProviderSettings = {}, ): GladiaProvider { - const getHeaders = () => ({ - 'x-gladia-key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'GLADIA_API_KEY', - description: 'Gladia', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + 'x-gladia-key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'GLADIA_API_KEY', + description: 'Gladia', + }), + ...options.headers, + }, + `ai-sdk/gladia/${VERSION}`, + ); const createTranscriptionModel = () => new GladiaTranscriptionModel('default', { diff --git a/packages/gladia/src/gladia-transcription-model.test.ts b/packages/gladia/src/gladia-transcription-model.test.ts index 7df3666e1ea4..c89a2184bd87 100644 --- a/packages/gladia/src/gladia-transcription-model.test.ts +++ b/packages/gladia/src/gladia-transcription-model.test.ts @@ -3,7 +3,11 @@ import { GladiaTranscriptionModel } from './gladia-transcription-model'; import { createGladia } from './gladia-provider'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); const provider = createGladia({ apiKey: 'test-api-key' }); @@ -152,6 +156,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/gladia/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/gladia/src/index.ts b/packages/gladia/src/index.ts index 4e5bf690e0d8..35561c23467e 100644 --- a/packages/gladia/src/index.ts +++ b/packages/gladia/src/index.ts @@ -1,2 +1,3 @@ export { createGladia, gladia } from './gladia-provider'; export type { GladiaProvider, GladiaProviderSettings } from './gladia-provider'; +export { VERSION } from './version'; diff --git a/packages/gladia/src/version.ts b/packages/gladia/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/gladia/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/gladia/tsup.config.ts b/packages/gladia/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/gladia/tsup.config.ts +++ b/packages/gladia/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/gladia/vitest.edge.config.js b/packages/gladia/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/gladia/vitest.edge.config.js +++ b/packages/gladia/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/gladia/vitest.node.config.js b/packages/gladia/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/gladia/vitest.node.config.js +++ b/packages/gladia/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/google-vertex/src/google-vertex-embedding-model.test.ts b/packages/google-vertex/src/google-vertex-embedding-model.test.ts index 1191af93ea94..570fe41f683f 100644 --- a/packages/google-vertex/src/google-vertex-embedding-model.test.ts +++ b/packages/google-vertex/src/google-vertex-embedding-model.test.ts @@ -5,6 +5,11 @@ import { import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleVertexEmbeddingModel } from './google-vertex-embedding-model'; import { describe, it, expect, vi } from 'vitest'; +import { createVertex } from './google-vertex-provider'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const dummyEmbeddings = [ [0.1, 0.2, 0.3], @@ -167,21 +172,20 @@ describe('GoogleVertexEmbeddingModel', () => { }); }); + // changed test to go through the provider `createVertex` it('should pass headers correctly', async () => { prepareJsonResponse(); - const model = new GoogleVertexEmbeddingModel(mockModelId, { - ...mockConfig, - headers: () => ({ - 'X-Custom-Header': 'custom-value', - }), + const provider = createVertex({ + project: 'test-project', + location: 'us-central1', + headers: { 'X-Custom-Header': 'custom-value' }, }); - await model.doEmbed({ + await provider.textEmbeddingModel(mockModelId).doEmbed({ values: testValues, - headers: { - 'X-Request-Header': 'request-value', - }, + headers: { 'X-Request-Header': 'request-value' }, + providerOptions: { google: mockProviderOptions }, }); expect(server.calls[0].requestHeaders).toStrictEqual({ @@ -189,6 +193,9 @@ describe('GoogleVertexEmbeddingModel', () => { 'x-custom-header': 'custom-value', 'x-request-header': 'request-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/google-vertex/0.0.0-test`, + ); }); it('should throw TooManyEmbeddingValuesForCallError when too many values provided', async () => { 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 9a1f171bc94e..ee7cf10e57c4 100644 --- a/packages/google-vertex/src/google-vertex-image-model.test.ts +++ b/packages/google-vertex/src/google-vertex-image-model.test.ts @@ -1,6 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleVertexImageModel } from './google-vertex-image-model'; -import { describe, it, expect } from 'vitest'; +import { createVertex } from './google-vertex-provider'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const prompt = 'A cute baby sea otter'; @@ -50,30 +55,25 @@ describe('GoogleVertexImageModel', () => { }; } + // changed test to go through the provider `createVertex` it('should pass headers', async () => { prepareJsonResponse(); - const modelWithHeaders = new GoogleVertexImageModel( - 'imagen-3.0-generate-002', - { - provider: 'google-vertex', - baseURL: 'https://api.example.com', - headers: { - 'Custom-Provider-Header': 'provider-header-value', - }, - }, - ); + const provider = createVertex({ + project: 'test-project', + location: 'us-central1', + baseURL: 'https://api.example.com', + headers: { 'Custom-Provider-Header': 'provider-header-value' }, + }); - await modelWithHeaders.doGenerate({ + await provider.imageModel('imagen-3.0-generate-002').doGenerate({ prompt, n: 2, size: undefined, aspectRatio: undefined, seed: undefined, providerOptions: {}, - headers: { - 'Custom-Request-Header': 'request-header-value', - }, + headers: { 'Custom-Request-Header': 'request-header-value' }, }); expect(server.calls[0].requestHeaders).toStrictEqual({ @@ -81,6 +81,9 @@ describe('GoogleVertexImageModel', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/google-vertex/0.0.0-test`, + ); }); it('should use default maxImagesPerCall when not specified', () => { diff --git a/packages/google-vertex/src/google-vertex-provider.test.ts b/packages/google-vertex/src/google-vertex-provider.test.ts index 3da5e385a7cc..119ea2e10690 100644 --- a/packages/google-vertex/src/google-vertex-provider.test.ts +++ b/packages/google-vertex/src/google-vertex-provider.test.ts @@ -46,7 +46,7 @@ describe('google-vertex-provider', () => { provider: 'google.vertex.chat', baseURL: 'https://test-location-aiplatform.googleapis.com/v1/projects/test-project/locations/test-location/publishers/google', - headers: expect.any(Object), + headers: expect.any(Function), generateId: expect.any(Function), }), ); @@ -71,7 +71,7 @@ describe('google-vertex-provider', () => { 'test-embedding-model', expect.objectContaining({ provider: 'google.vertex.embedding', - headers: expect.any(Object), + headers: expect.any(Function), baseURL: 'https://test-location-aiplatform.googleapis.com/v1/projects/test-project/locations/test-location/publishers/google', }), @@ -90,7 +90,7 @@ describe('google-vertex-provider', () => { expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith( expect.anything(), expect.objectContaining({ - headers: customHeaders, + headers: expect.any(Function), }), ); }); @@ -155,7 +155,7 @@ describe('google-vertex-provider', () => { provider: 'google.vertex.image', baseURL: 'https://test-location-aiplatform.googleapis.com/v1/projects/test-project/locations/test-location/publishers/google', - headers: expect.any(Object), + headers: expect.any(Function), }), ); }); @@ -173,7 +173,7 @@ describe('google-vertex-provider', () => { provider: 'google.vertex.chat', baseURL: 'https://aiplatform.googleapis.com/v1/projects/test-project/locations/global/publishers/google', - headers: expect.any(Object), + headers: expect.any(Function), generateId: expect.any(Function), }), ); @@ -190,7 +190,7 @@ describe('google-vertex-provider', () => { 'test-embedding-model', expect.objectContaining({ provider: 'google.vertex.embedding', - headers: expect.any(Object), + headers: expect.any(Function), baseURL: 'https://aiplatform.googleapis.com/v1/projects/test-project/locations/global/publishers/google', }), @@ -210,7 +210,7 @@ describe('google-vertex-provider', () => { provider: 'google.vertex.image', baseURL: 'https://aiplatform.googleapis.com/v1/projects/test-project/locations/global/publishers/google', - headers: expect.any(Object), + headers: expect.any(Function), }), ); }); @@ -240,7 +240,7 @@ describe('google-vertex-provider', () => { provider: 'google.vertex.chat', baseURL: 'https://us-central1-aiplatform.googleapis.com/v1/projects/test-project/locations/us-central1/publishers/google', - headers: expect.any(Object), + headers: expect.any(Function), generateId: expect.any(Function), }), ); diff --git a/packages/google-vertex/src/google-vertex-provider.ts b/packages/google-vertex/src/google-vertex-provider.ts index badcfa6e77e8..6a20fde5b2a6 100644 --- a/packages/google-vertex/src/google-vertex-provider.ts +++ b/packages/google-vertex/src/google-vertex-provider.ts @@ -4,9 +4,12 @@ import { FetchFunction, generateId, loadSetting, + resolve, Resolvable, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; import { GoogleVertexConfig } from './google-vertex-config'; import { GoogleVertexEmbeddingModel } from './google-vertex-embedding-model'; import { GoogleVertexEmbeddingModelId } from './google-vertex-embedding-options'; @@ -108,9 +111,18 @@ export function createVertex( }; const createConfig = (name: string): GoogleVertexConfig => { + // Create a function that adds the user-agent suffix to headers + const getHeaders = async () => { + const originalHeaders = await resolve(options.headers ?? {}); + return withUserAgentSuffix( + originalHeaders, + `ai-sdk/google-vertex/${VERSION}`, + ); + }; + return { provider: `google.vertex.${name}`, - headers: options.headers ?? {}, + headers: getHeaders, fetch: options.fetch, baseURL: loadBaseURL(), }; diff --git a/packages/google-vertex/src/index.ts b/packages/google-vertex/src/index.ts index e84f8e06d72f..028275566864 100644 --- a/packages/google-vertex/src/index.ts +++ b/packages/google-vertex/src/index.ts @@ -4,3 +4,4 @@ export type { GoogleVertexProvider, GoogleVertexProviderSettings, } from './google-vertex-provider-node'; +export { VERSION } from './version'; diff --git a/packages/google/src/google-generative-ai-embedding-model.test.ts b/packages/google/src/google-generative-ai-embedding-model.test.ts index 387eb940e745..680f95da93d0 100644 --- a/packages/google/src/google-generative-ai-embedding-model.test.ts +++ b/packages/google/src/google-generative-ai-embedding-model.test.ts @@ -2,7 +2,11 @@ import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { GoogleGenerativeAIEmbeddingModel } from './google-generative-ai-embedding-model'; import { createGoogleGenerativeAI } from './google-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const dummyEmbeddings = [ [0.1, 0.2, 0.3, 0.4, 0.5], @@ -153,6 +157,9 @@ describe('GoogleGenerativeAIEmbeddingModel', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/google/0.0.0-test`, + ); }); it('should throw an error if too many values are provided', async () => { 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 9c095099c38f..edab0b770357 100644 --- a/packages/google/src/google-generative-ai-language-model.test.ts +++ b/packages/google/src/google-generative-ai-language-model.test.ts @@ -13,7 +13,11 @@ import { import { createGoogleGenerativeAI } from './google-provider'; import { groundingMetadataSchema } from './tool/google-search'; import { urlContextMetadataSchema } from './tool/url-context'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -673,6 +677,9 @@ describe('doGenerate', () => { 'custom-request-header': 'request-header-value', 'x-goog-api-key': 'test-api-key', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/google/0.0.0-test`, + ); }); it('should pass response format', async () => { diff --git a/packages/google/src/google-provider.test.ts b/packages/google/src/google-provider.test.ts index ca5a1772c65a..baef649c254f 100644 --- a/packages/google/src/google-provider.test.ts +++ b/packages/google/src/google-provider.test.ts @@ -25,7 +25,9 @@ vi.mock('./google-generative-ai-embedding-model', () => ({ vi.mock('./google-generative-ai-image-model', () => ({ GoogleGenerativeAIImageModel: vi.fn(), })); - +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); describe('google-provider', () => { beforeEach(() => { vi.clearAllMocks(); @@ -92,7 +94,8 @@ describe('google-provider', () => { const headers = options.headers(); expect(headers).toEqual({ 'x-goog-api-key': 'test-api-key', - 'Custom-Header': 'custom-value', + 'custom-header': 'custom-value', + 'user-agent': 'ai-sdk/google/0.0.0-test', }); }); diff --git a/packages/google/src/google-provider.ts b/packages/google/src/google-provider.ts index be4307330e4b..aad70d7d147f 100644 --- a/packages/google/src/google-provider.ts +++ b/packages/google/src/google-provider.ts @@ -9,7 +9,9 @@ import { generateId, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; +import { VERSION } from './version'; import { GoogleGenerativeAIEmbeddingModel } from './google-generative-ai-embedding-model'; import { GoogleGenerativeAIEmbeddingModelId } from './google-generative-ai-embedding-options'; import { GoogleGenerativeAILanguageModel } from './google-generative-ai-language-model'; @@ -100,14 +102,18 @@ export function createGoogleGenerativeAI( withoutTrailingSlash(options.baseURL) ?? 'https://generativelanguage.googleapis.com/v1beta'; - const getHeaders = () => ({ - 'x-goog-api-key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'GOOGLE_GENERATIVE_AI_API_KEY', - description: 'Google Generative AI', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + 'x-goog-api-key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'GOOGLE_GENERATIVE_AI_API_KEY', + description: 'Google Generative AI', + }), + ...options.headers, + }, + `ai-sdk/google/${VERSION}`, + ); const createChatModel = (modelId: GoogleGenerativeAIModelId) => new GoogleGenerativeAILanguageModel(modelId, { diff --git a/packages/google/src/index.ts b/packages/google/src/index.ts index 498e6105cc82..983c4f2df1ef 100644 --- a/packages/google/src/index.ts +++ b/packages/google/src/index.ts @@ -8,3 +8,4 @@ export type { GoogleGenerativeAIProvider, GoogleGenerativeAIProviderSettings, } from './google-provider'; +export { VERSION } from './version'; diff --git a/packages/google/src/version.ts b/packages/google/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/google/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/google/tsup.config.ts b/packages/google/tsup.config.ts index 87efcf0d5720..d0b56a7122cd 100644 --- a/packages/google/tsup.config.ts +++ b/packages/google/tsup.config.ts @@ -6,6 +6,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, { entry: ['src/internal/index.ts'], @@ -13,5 +19,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/google/vitest.edge.config.js b/packages/google/vitest.edge.config.js index 3dc49ba29774..265b201c0a28 100644 --- a/packages/google/vitest.edge.config.js +++ b/packages/google/vitest.edge.config.js @@ -1,7 +1,14 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, test: { environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], diff --git a/packages/google/vitest.node.config.js b/packages/google/vitest.node.config.js index b7e4a9cabd48..28e23c82c433 100644 --- a/packages/google/vitest.node.config.js +++ b/packages/google/vitest.node.config.js @@ -1,4 +1,8 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +10,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, }); diff --git a/packages/groq/src/groq-chat-language-model.test.ts b/packages/groq/src/groq-chat-language-model.test.ts index 16d9892f6594..00365a94d351 100644 --- a/packages/groq/src/groq-chat-language-model.test.ts +++ b/packages/groq/src/groq-chat-language-model.test.ts @@ -5,7 +5,11 @@ import { isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createGroq } from './groq-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -383,6 +387,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/groq/0.0.0-test`, + ); }); it('should parse tool results', async () => { diff --git a/packages/groq/src/groq-provider.ts b/packages/groq/src/groq-provider.ts index 8cc8cc6520e2..837a6a1e7717 100644 --- a/packages/groq/src/groq-provider.ts +++ b/packages/groq/src/groq-provider.ts @@ -8,6 +8,7 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { GroqChatLanguageModel } from './groq-chat-language-model'; import { GroqChatModelId } from './groq-chat-options'; @@ -15,6 +16,7 @@ import { GroqTranscriptionModelId } from './groq-transcription-options'; import { GroqTranscriptionModel } from './groq-transcription-model'; import { groqTools } from './groq-tools'; +import { VERSION } from './version'; export interface GroqProvider extends ProviderV2 { /** Creates a model for text generation. @@ -67,14 +69,18 @@ export function createGroq(options: GroqProviderSettings = {}): GroqProvider { const baseURL = withoutTrailingSlash(options.baseURL) ?? 'https://api.groq.com/openai/v1'; - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'GROQ_API_KEY', - description: 'Groq', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'GROQ_API_KEY', + description: 'Groq', + })}`, + ...options.headers, + }, + `ai-sdk/groq/${VERSION}`, + ); const createChatModel = (modelId: GroqChatModelId) => new GroqChatLanguageModel(modelId, { diff --git a/packages/groq/src/groq-transcription-model.test.ts b/packages/groq/src/groq-transcription-model.test.ts index b50e89129a9d..a766bd3346a5 100644 --- a/packages/groq/src/groq-transcription-model.test.ts +++ b/packages/groq/src/groq-transcription-model.test.ts @@ -3,7 +3,11 @@ import { GroqTranscriptionModel } from './groq-transcription-model'; import { createGroq } from './groq-provider'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); const provider = createGroq({ apiKey: 'test-api-key' }); @@ -87,6 +91,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/groq/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/groq/src/index.ts b/packages/groq/src/index.ts index c1a8b38656e7..e5d472087502 100644 --- a/packages/groq/src/index.ts +++ b/packages/groq/src/index.ts @@ -2,3 +2,4 @@ export { createGroq, groq } from './groq-provider'; export type { GroqProvider, GroqProviderSettings } from './groq-provider'; export type { GroqProviderOptions } from './groq-chat-options'; export { browserSearch } from './tool/browser-search'; +export { VERSION } from './version'; diff --git a/packages/groq/src/version.ts b/packages/groq/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/groq/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/groq/tsup.config.ts b/packages/groq/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/groq/tsup.config.ts +++ b/packages/groq/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/groq/vitest.edge.config.js b/packages/groq/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/groq/vitest.edge.config.js +++ b/packages/groq/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/groq/vitest.node.config.js b/packages/groq/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/groq/vitest.node.config.js +++ b/packages/groq/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/hume/package.json b/packages/hume/package.json index 006be55ab731..0bce54c21e06 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -18,6 +18,7 @@ "type-check": "tsc --noEmit", "prettier-check": "prettier --check \"./**/*.ts*\"", "test": "pnpm test:node && pnpm test:edge", + "test:watch": "vitest --config vitest.node.config.js --watch", "test:edge": "vitest --config vitest.edge.config.js --run", "test:node": "vitest --config vitest.node.config.js --run", "test:node:watch": "vitest --config vitest.node.config.js --watch" diff --git a/packages/hume/src/hume-provider.ts b/packages/hume/src/hume-provider.ts index 4d6849adb2e0..f9b8f01fe643 100644 --- a/packages/hume/src/hume-provider.ts +++ b/packages/hume/src/hume-provider.ts @@ -1,6 +1,11 @@ import { SpeechModelV2, ProviderV2 } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { HumeSpeechModel } from './hume-speech-model'; +import { VERSION } from './version'; export interface HumeProvider extends Pick { (settings?: {}): { @@ -35,14 +40,18 @@ or to provide a custom fetch implementation for e.g. testing. Create an Hume provider instance. */ export function createHume(options: HumeProviderSettings = {}): HumeProvider { - const getHeaders = () => ({ - 'X-Hume-Api-Key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'HUME_API_KEY', - description: 'Hume', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + 'X-Hume-Api-Key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'HUME_API_KEY', + description: 'Hume', + }), + ...options.headers, + }, + `ai-sdk/hume/${VERSION}`, + ); const createSpeechModel = () => new HumeSpeechModel('', { diff --git a/packages/hume/src/hume-speech-model.test.ts b/packages/hume/src/hume-speech-model.test.ts index 13f8ad084569..2f8b187856f5 100644 --- a/packages/hume/src/hume-speech-model.test.ts +++ b/packages/hume/src/hume-speech-model.test.ts @@ -1,7 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { HumeSpeechModel } from './hume-speech-model'; import { createHume } from './hume-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const provider = createHume({ apiKey: 'test-api-key' }); const model = provider.speech(); @@ -76,6 +80,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/hume/0.0.0-test`, + ); }); it('should pass options', async () => { diff --git a/packages/hume/src/index.ts b/packages/hume/src/index.ts index 2fd4e0d07b2c..7911ef9ffa11 100644 --- a/packages/hume/src/index.ts +++ b/packages/hume/src/index.ts @@ -1,2 +1,3 @@ export { createHume, hume } from './hume-provider'; export type { HumeProvider, HumeProviderSettings } from './hume-provider'; +export { VERSION } from './version'; diff --git a/packages/hume/src/version.ts b/packages/hume/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/hume/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/hume/tsup.config.ts b/packages/hume/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/hume/tsup.config.ts +++ b/packages/hume/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/hume/vitest.edge.config.js b/packages/hume/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/hume/vitest.edge.config.js +++ b/packages/hume/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/hume/vitest.node.config.js b/packages/hume/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/hume/vitest.node.config.js +++ b/packages/hume/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index d33e1088fb56..d71aa24bc06b 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -18,6 +18,7 @@ "type-check": "tsc --noEmit", "prettier-check": "prettier --check \"./**/*.ts*\"", "test": "pnpm test:node && pnpm test:edge", + "test:watch": "vitest --config vitest.node.config.js --watch", "test:edge": "vitest --config vitest.edge.config.js --run", "test:node": "vitest --config vitest.node.config.js --run", "test:node:watch": "vitest --config vitest.node.config.js --watch" diff --git a/packages/lmnt/src/index.ts b/packages/lmnt/src/index.ts index 879f4bf9eb70..675cb881c797 100644 --- a/packages/lmnt/src/index.ts +++ b/packages/lmnt/src/index.ts @@ -1,2 +1,3 @@ export { createLMNT, lmnt } from './lmnt-provider'; export type { LMNTProvider, LMNTProviderSettings } from './lmnt-provider'; +export { VERSION } from './version'; diff --git a/packages/lmnt/src/lmnt-provider.ts b/packages/lmnt/src/lmnt-provider.ts index 649c88eb6971..1196d2a4cd26 100644 --- a/packages/lmnt/src/lmnt-provider.ts +++ b/packages/lmnt/src/lmnt-provider.ts @@ -1,7 +1,12 @@ import { SpeechModelV2, ProviderV2 } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { LMNTSpeechModel } from './lmnt-speech-model'; import { LMNTSpeechModelId } from './lmnt-speech-options'; +import { VERSION } from './version'; export interface LMNTProvider extends Pick { ( @@ -39,14 +44,18 @@ or to provide a custom fetch implementation for e.g. testing. Create an LMNT provider instance. */ export function createLMNT(options: LMNTProviderSettings = {}): LMNTProvider { - const getHeaders = () => ({ - 'x-api-key': loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'LMNT_API_KEY', - description: 'LMNT', - }), - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + 'x-api-key': loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'LMNT_API_KEY', + description: 'LMNT', + }), + ...options.headers, + }, + `ai-sdk/lmnt/${VERSION}`, + ); const createSpeechModel = (modelId: LMNTSpeechModelId) => new LMNTSpeechModel(modelId, { diff --git a/packages/lmnt/src/lmnt-speech-model.test.ts b/packages/lmnt/src/lmnt-speech-model.test.ts index f3fb13062b31..c63d46afdd2e 100644 --- a/packages/lmnt/src/lmnt-speech-model.test.ts +++ b/packages/lmnt/src/lmnt-speech-model.test.ts @@ -1,7 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { LMNTSpeechModel } from './lmnt-speech-model'; import { createLMNT } from './lmnt-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const provider = createLMNT({ apiKey: 'test-api-key' }); const model = provider.speech('aurora'); @@ -66,6 +70,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/lmnt/0.0.0-test`, + ); }); it('should pass options', async () => { diff --git a/packages/lmnt/src/version.ts b/packages/lmnt/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/lmnt/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/lmnt/tsup.config.ts b/packages/lmnt/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/lmnt/tsup.config.ts +++ b/packages/lmnt/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/lmnt/vitest.edge.config.js b/packages/lmnt/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/lmnt/vitest.edge.config.js +++ b/packages/lmnt/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/lmnt/vitest.node.config.js b/packages/lmnt/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/lmnt/vitest.node.config.js +++ b/packages/lmnt/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/luma/src/index.ts b/packages/luma/src/index.ts index 57e5f4561e47..b811aa9f5029 100644 --- a/packages/luma/src/index.ts +++ b/packages/luma/src/index.ts @@ -1,3 +1,4 @@ export { createLuma, luma } from './luma-provider'; export type { LumaProvider, LumaProviderSettings } from './luma-provider'; export type { LumaErrorData } from './luma-image-model'; +export { VERSION } from './version'; diff --git a/packages/luma/src/luma-provider.ts b/packages/luma/src/luma-provider.ts index d2c9f16b6311..ab1340b67494 100644 --- a/packages/luma/src/luma-provider.ts +++ b/packages/luma/src/luma-provider.ts @@ -3,9 +3,11 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { LumaImageModel } from './luma-image-model'; import { LumaImageModelId } from './luma-image-settings'; +import { VERSION } from './version'; export interface LumaProviderSettings { /** @@ -44,14 +46,18 @@ const defaultBaseURL = 'https://api.lumalabs.ai'; export function createLuma(options: LumaProviderSettings = {}): LumaProvider { const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'LUMA_API_KEY', - description: 'Luma', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'LUMA_API_KEY', + description: 'Luma', + })}`, + ...options.headers, + }, + `ai-sdk/luma/${VERSION}`, + ); const createImageModel = (modelId: LumaImageModelId) => new LumaImageModel(modelId, { diff --git a/packages/luma/src/version.ts b/packages/luma/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/luma/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/luma/tsup.config.ts b/packages/luma/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/luma/tsup.config.ts +++ b/packages/luma/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/luma/vitest.edge.config.js b/packages/luma/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/luma/vitest.edge.config.js +++ b/packages/luma/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/luma/vitest.node.config.js b/packages/luma/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/luma/vitest.node.config.js +++ b/packages/luma/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/mistral/src/index.ts b/packages/mistral/src/index.ts index 1a634dc3b650..d8acf2e24933 100644 --- a/packages/mistral/src/index.ts +++ b/packages/mistral/src/index.ts @@ -4,3 +4,4 @@ export type { MistralProviderSettings, } from './mistral-provider'; export type { MistralLanguageModelOptions } from './mistral-chat-options'; +export { VERSION } from './version'; diff --git a/packages/mistral/src/mistral-chat-language-model.test.ts b/packages/mistral/src/mistral-chat-language-model.test.ts index 986b1947a0a4..38efac6f6670 100644 --- a/packages/mistral/src/mistral-chat-language-model.test.ts +++ b/packages/mistral/src/mistral-chat-language-model.test.ts @@ -5,7 +5,11 @@ import { mockId, } from '@ai-sdk/provider-utils/test'; import { createMistral } from './mistral-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -464,6 +468,9 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/mistral/0.0.0-test`, + ); }); it('should send request body', async () => { @@ -1020,6 +1027,9 @@ describe('doStream', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/mistral/0.0.0-test`, + ); }); it('should send request body', async () => { diff --git a/packages/mistral/src/mistral-embedding-model.test.ts b/packages/mistral/src/mistral-embedding-model.test.ts index c933c2a6b450..17cf1c5a8859 100644 --- a/packages/mistral/src/mistral-embedding-model.test.ts +++ b/packages/mistral/src/mistral-embedding-model.test.ts @@ -1,7 +1,11 @@ import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createMistral } from './mistral-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const dummyEmbeddings = [ [0.1, 0.2, 0.3, 0.4, 0.5], @@ -116,5 +120,8 @@ describe('doEmbed', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/mistral/0.0.0-test`, + ); }); }); diff --git a/packages/mistral/src/mistral-provider.ts b/packages/mistral/src/mistral-provider.ts index 72450977bc90..5bd96397d903 100644 --- a/packages/mistral/src/mistral-provider.ts +++ b/packages/mistral/src/mistral-provider.ts @@ -8,11 +8,13 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { MistralChatLanguageModel } from './mistral-chat-language-model'; import { MistralChatModelId } from './mistral-chat-options'; import { MistralEmbeddingModel } from './mistral-embedding-model'; import { MistralEmbeddingModelId } from './mistral-embedding-options'; +import { VERSION } from './version'; export interface MistralProvider extends ProviderV2 { (modelId: MistralChatModelId): LanguageModelV2; @@ -75,14 +77,18 @@ export function createMistral( const baseURL = withoutTrailingSlash(options.baseURL) ?? 'https://api.mistral.ai/v1'; - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'MISTRAL_API_KEY', - description: 'Mistral', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'MISTRAL_API_KEY', + description: 'Mistral', + })}`, + ...options.headers, + }, + `ai-sdk/mistral/${VERSION}`, + ); const createChatModel = (modelId: MistralChatModelId) => new MistralChatLanguageModel(modelId, { diff --git a/packages/mistral/src/version.ts b/packages/mistral/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/mistral/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/mistral/tsup.config.ts b/packages/mistral/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/mistral/tsup.config.ts +++ b/packages/mistral/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/mistral/vitest.edge.config.js b/packages/mistral/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/mistral/vitest.edge.config.js +++ b/packages/mistral/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/mistral/vitest.node.config.js b/packages/mistral/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/mistral/vitest.node.config.js +++ b/packages/mistral/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/openai/src/chat/openai-chat-language-model.test.ts b/packages/openai/src/chat/openai-chat-language-model.test.ts index f6db0764318d..c5e109340b80 100644 --- a/packages/openai/src/chat/openai-chat-language-model.test.ts +++ b/packages/openai/src/chat/openai-chat-language-model.test.ts @@ -5,7 +5,11 @@ import { isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createOpenAI } from '../openai-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -613,6 +617,9 @@ describe('doGenerate', () => { 'openai-organization': 'test-organization', 'openai-project': 'test-project', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/openai/0.0.0-test`, + ); }); it('should parse tool results', async () => { diff --git a/packages/openai/src/completion/openai-completion-language-model.test.ts b/packages/openai/src/completion/openai-completion-language-model.test.ts index 064096fe727d..fe6426e73c71 100644 --- a/packages/openai/src/completion/openai-completion-language-model.test.ts +++ b/packages/openai/src/completion/openai-completion-language-model.test.ts @@ -5,7 +5,11 @@ import { isNodeVersion, } from '@ai-sdk/provider-utils/test'; import { createOpenAI } from '../openai-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, @@ -678,5 +682,8 @@ describe('doStream', () => { 'openai-organization': 'test-organization', 'openai-project': 'test-project', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/openai/0.0.0-test`, + ); }); }); diff --git a/packages/openai/src/embedding/openai-embedding-model.test.ts b/packages/openai/src/embedding/openai-embedding-model.test.ts index 43448e57bdcc..bcad76aa48d2 100644 --- a/packages/openai/src/embedding/openai-embedding-model.test.ts +++ b/packages/openai/src/embedding/openai-embedding-model.test.ts @@ -1,7 +1,11 @@ import { EmbeddingModelV3Embedding } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); const dummyEmbeddings = [ [0.1, 0.2, 0.3, 0.4, 0.5], @@ -135,5 +139,8 @@ describe('doEmbed', () => { 'openai-organization': 'test-organization', 'openai-project': 'test-project', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/openai/0.0.0-test`, + ); }); }); diff --git a/packages/openai/src/image/openai-image-model.test.ts b/packages/openai/src/image/openai-image-model.test.ts index 19880945f97d..0f9780895936 100644 --- a/packages/openai/src/image/openai-image-model.test.ts +++ b/packages/openai/src/image/openai-image-model.test.ts @@ -1,7 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; import { OpenAIImageModel } from './openai-image-model'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); const prompt = 'A cute baby sea otter'; @@ -91,6 +95,9 @@ describe('doGenerate', () => { 'openai-organization': 'test-organization', 'openai-project': 'test-project', }); + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/openai/0.0.0-test`, + ); }); it('should extract the generated images', async () => { diff --git a/packages/openai/src/index.ts b/packages/openai/src/index.ts index f590b8e2aec9..d48a826891da 100644 --- a/packages/openai/src/index.ts +++ b/packages/openai/src/index.ts @@ -1,3 +1,4 @@ export { createOpenAI, openai } from './openai-provider'; export type { OpenAIProvider, OpenAIProviderSettings } from './openai-provider'; export type { OpenAIResponsesProviderOptions } from './responses/openai-responses-language-model'; +export { VERSION } from './version'; diff --git a/packages/openai/src/openai-provider.ts b/packages/openai/src/openai-provider.ts index 9a1bbb5983e3..de044d4ff82d 100644 --- a/packages/openai/src/openai-provider.ts +++ b/packages/openai/src/openai-provider.ts @@ -10,6 +10,7 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { OpenAIChatLanguageModel } from './chat/openai-chat-language-model'; import { OpenAIChatModelId } from './chat/openai-chat-options'; @@ -26,6 +27,7 @@ import { OpenAISpeechModel } from './speech/openai-speech-model'; import { OpenAISpeechModelId } from './speech/openai-speech-options'; import { OpenAITranscriptionModel } from './transcription/openai-transcription-model'; import { OpenAITranscriptionModelId } from './transcription/openai-transcription-options'; +import { VERSION } from './version'; export interface OpenAIProvider extends ProviderV2 { (modelId: OpenAIResponsesModelId): LanguageModelV2; @@ -140,16 +142,20 @@ export function createOpenAI( const providerName = options.name ?? 'openai'; - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'OPENAI_API_KEY', - description: 'OpenAI', - })}`, - 'OpenAI-Organization': options.organization, - 'OpenAI-Project': options.project, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'OPENAI_API_KEY', + description: 'OpenAI', + })}`, + 'OpenAI-Organization': options.organization, + 'OpenAI-Project': options.project, + ...options.headers, + }, + `ai-sdk/openai/${VERSION}`, + ); const createChatModel = (modelId: OpenAIChatModelId) => new OpenAIChatLanguageModel(modelId, { diff --git a/packages/openai/src/speech/openai-speech-model.test.ts b/packages/openai/src/speech/openai-speech-model.test.ts index e5186293d578..cad685112243 100644 --- a/packages/openai/src/speech/openai-speech-model.test.ts +++ b/packages/openai/src/speech/openai-speech-model.test.ts @@ -1,7 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createOpenAI } from '../openai-provider'; import { OpenAISpeechModel } from './openai-speech-model'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); const provider = createOpenAI({ apiKey: 'test-api-key' }); const model = provider.speech('tts-1'); @@ -70,6 +74,10 @@ describe('doGenerate', () => { 'openai-organization': 'test-organization', 'openai-project': 'test-project', }); + + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/openai/0.0.0-test`, + ); }); it('should pass options', async () => { diff --git a/packages/openai/src/transcription/openai-transcription-model.test.ts b/packages/openai/src/transcription/openai-transcription-model.test.ts index 90bb37da040a..47d80d6b1c23 100644 --- a/packages/openai/src/transcription/openai-transcription-model.test.ts +++ b/packages/openai/src/transcription/openai-transcription-model.test.ts @@ -3,7 +3,11 @@ import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { createOpenAI } from '../openai-provider'; import { OpenAITranscriptionModel } from './openai-transcription-model'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('../version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile( path.join(__dirname, 'transcription-test.mp3'), @@ -114,6 +118,10 @@ describe('doGenerate', () => { 'openai-organization': 'test-organization', 'openai-project': 'test-project', }); + + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/openai/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/openai/src/version.ts b/packages/openai/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/openai/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/openai/tsup.config.ts b/packages/openai/tsup.config.ts index 87efcf0d5720..d0b56a7122cd 100644 --- a/packages/openai/tsup.config.ts +++ b/packages/openai/tsup.config.ts @@ -6,6 +6,12 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, { entry: ['src/internal/index.ts'], @@ -13,5 +19,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/openai/vitest.edge.config.js b/packages/openai/vitest.edge.config.js index 3dc49ba29774..7442befcc27a 100644 --- a/packages/openai/vitest.edge.config.js +++ b/packages/openai/vitest.edge.config.js @@ -1,4 +1,8 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +10,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, }); diff --git a/packages/openai/vitest.node.config.js b/packages/openai/vitest.node.config.js index b7e4a9cabd48..28e23c82c433 100644 --- a/packages/openai/vitest.node.config.js +++ b/packages/openai/vitest.node.config.js @@ -1,4 +1,8 @@ import { defineConfig } from 'vite'; +import { readFileSync } from 'node:fs'; +const version = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url), 'utf-8'), +).version; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +10,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(version), + }, }); diff --git a/packages/perplexity/src/index.ts b/packages/perplexity/src/index.ts index c8d0dbdff943..bff5d76cb0ca 100644 --- a/packages/perplexity/src/index.ts +++ b/packages/perplexity/src/index.ts @@ -3,3 +3,4 @@ export type { PerplexityProvider, PerplexityProviderSettings, } from './perplexity-provider'; +export { VERSION } from './version'; diff --git a/packages/perplexity/src/perplexity-language-model.test.ts b/packages/perplexity/src/perplexity-language-model.test.ts index ef007c962e2c..54453a84ba90 100644 --- a/packages/perplexity/src/perplexity-language-model.test.ts +++ b/packages/perplexity/src/perplexity-language-model.test.ts @@ -1,3 +1,5 @@ +// TEST FILE DOES NOT USE THE PROVIDER `createPerplexity` + import { describe, it, expect } from 'vitest'; import { LanguageModelV2Prompt } from '@ai-sdk/provider'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; diff --git a/packages/perplexity/src/perplexity-provider.ts b/packages/perplexity/src/perplexity-provider.ts index ebe356eefc57..9be529049e5d 100644 --- a/packages/perplexity/src/perplexity-provider.ts +++ b/packages/perplexity/src/perplexity-provider.ts @@ -8,9 +8,11 @@ import { generateId, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { PerplexityLanguageModel } from './perplexity-language-model'; import { PerplexityLanguageModelId } from './perplexity-language-model-options'; +import { VERSION } from './version'; export interface PerplexityProvider extends ProviderV2 { /** @@ -50,14 +52,18 @@ or to provide a custom fetch implementation for e.g. testing. export function createPerplexity( options: PerplexityProviderSettings = {}, ): PerplexityProvider { - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'PERPLEXITY_API_KEY', - description: 'Perplexity', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'PERPLEXITY_API_KEY', + description: 'Perplexity', + })}`, + ...options.headers, + }, + `ai-sdk/perplexity/${VERSION}`, + ); const createLanguageModel = (modelId: PerplexityLanguageModelId) => { return new PerplexityLanguageModel(modelId, { diff --git a/packages/perplexity/src/version.ts b/packages/perplexity/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/perplexity/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/perplexity/tsup.config.ts b/packages/perplexity/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/perplexity/tsup.config.ts +++ b/packages/perplexity/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/perplexity/vitest.edge.config.js b/packages/perplexity/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/perplexity/vitest.edge.config.js +++ b/packages/perplexity/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/perplexity/vitest.node.config.js b/packages/perplexity/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/perplexity/vitest.node.config.js +++ b/packages/perplexity/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/replicate/src/index.ts b/packages/replicate/src/index.ts index 424468a295a7..74bccfe79fab 100644 --- a/packages/replicate/src/index.ts +++ b/packages/replicate/src/index.ts @@ -3,3 +3,4 @@ export type { ReplicateProvider, ReplicateProviderSettings, } from './replicate-provider'; +export { VERSION } from './version'; diff --git a/packages/replicate/src/replicate-image-model.test.ts b/packages/replicate/src/replicate-image-model.test.ts index 373844ab13e5..a958134a19ca 100644 --- a/packages/replicate/src/replicate-image-model.test.ts +++ b/packages/replicate/src/replicate-image-model.test.ts @@ -1,7 +1,11 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { createReplicate } from './replicate-provider'; import { ReplicateImageModel } from './replicate-image-model'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const prompt = 'The Loch Ness monster getting a manicure'; @@ -128,6 +132,10 @@ describe('doGenerate', () => { 'custom-request-header': 'request-header-value', prefer: 'wait', }); + + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/replicate/0.0.0-test`, + ); }); it('should extract the generated image from array response', async () => { diff --git a/packages/replicate/src/replicate-provider.ts b/packages/replicate/src/replicate-provider.ts index 5480728b5213..1b4b2e4faafa 100644 --- a/packages/replicate/src/replicate-provider.ts +++ b/packages/replicate/src/replicate-provider.ts @@ -1,8 +1,9 @@ import { NoSuchModelError, ProviderV2 } from '@ai-sdk/provider'; import type { FetchFunction } from '@ai-sdk/provider-utils'; -import { loadApiKey } from '@ai-sdk/provider-utils'; +import { loadApiKey, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { ReplicateImageModel } from './replicate-image-model'; import { ReplicateImageModelId } from './replicate-image-settings'; +import { VERSION } from './version'; export interface ReplicateProviderSettings { /** @@ -51,14 +52,17 @@ export function createReplicate( new ReplicateImageModel(modelId, { provider: 'replicate', baseURL: options.baseURL ?? 'https://api.replicate.com/v1', - headers: { - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiToken, - environmentVariableName: 'REPLICATE_API_TOKEN', - description: 'Replicate', - })}`, - ...options.headers, - }, + headers: withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiToken, + environmentVariableName: 'REPLICATE_API_TOKEN', + description: 'Replicate', + })}`, + ...options.headers, + }, + `ai-sdk/replicate/${VERSION}`, + ), fetch: options.fetch, }); diff --git a/packages/replicate/src/version.ts b/packages/replicate/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/replicate/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/replicate/tsup.config.ts b/packages/replicate/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/replicate/tsup.config.ts +++ b/packages/replicate/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/replicate/vitest.edge.config.js b/packages/replicate/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/replicate/vitest.edge.config.js +++ b/packages/replicate/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/replicate/vitest.node.config.js b/packages/replicate/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/replicate/vitest.node.config.js +++ b/packages/replicate/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/revai/package.json b/packages/revai/package.json index 36e004aeaf31..60a55520efa3 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -18,6 +18,7 @@ "type-check": "tsc --noEmit", "prettier-check": "prettier --check \"./**/*.ts*\"", "test": "pnpm test:node && pnpm test:edge", + "test:watch": "vitest --config vitest.node.config.js", "test:edge": "vitest --config vitest.edge.config.js --run", "test:node": "vitest --config vitest.node.config.js --run", "test:node:watch": "vitest --config vitest.node.config.js --watch" diff --git a/packages/revai/src/index.ts b/packages/revai/src/index.ts index c6325dc8842d..f756417588e9 100644 --- a/packages/revai/src/index.ts +++ b/packages/revai/src/index.ts @@ -1,2 +1,3 @@ export { createRevai, revai } from './revai-provider'; export type { RevaiProvider, RevaiProviderSettings } from './revai-provider'; +export { VERSION } from './version'; diff --git a/packages/revai/src/revai-provider.ts b/packages/revai/src/revai-provider.ts index 7a69fd130a27..f3bba0a4fbfb 100644 --- a/packages/revai/src/revai-provider.ts +++ b/packages/revai/src/revai-provider.ts @@ -3,9 +3,14 @@ import { ProviderV2, NoSuchModelError, } from '@ai-sdk/provider'; -import { FetchFunction, loadApiKey } from '@ai-sdk/provider-utils'; +import { + FetchFunction, + loadApiKey, + withUserAgentSuffix, +} from '@ai-sdk/provider-utils'; import { RevaiTranscriptionModel } from './revai-transcription-model'; import { RevaiTranscriptionModelId } from './revai-transcription-options'; +import { VERSION } from './version'; export interface RevaiProvider extends ProviderV2 { ( @@ -45,14 +50,18 @@ Create a Rev.ai provider instance. export function createRevai( options: RevaiProviderSettings = {}, ): RevaiProvider { - const getHeaders = () => ({ - authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'REVAI_API_KEY', - description: 'Rev.ai', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'REVAI_API_KEY', + description: 'Rev.ai', + })}`, + ...options.headers, + }, + `ai-sdk/revai/${VERSION}`, + ); const createTranscriptionModel = (modelId: RevaiTranscriptionModelId) => new RevaiTranscriptionModel(modelId, { diff --git a/packages/revai/src/revai-transcription-model.test.ts b/packages/revai/src/revai-transcription-model.test.ts index e8db5719bd4a..bf3fb7455ce7 100644 --- a/packages/revai/src/revai-transcription-model.test.ts +++ b/packages/revai/src/revai-transcription-model.test.ts @@ -3,7 +3,11 @@ import { RevaiTranscriptionModel } from './revai-transcription-model'; import { createRevai } from './revai-provider'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); const audioData = await readFile(path.join(__dirname, 'transcript-test.mp3')); const provider = createRevai({ apiKey: 'test-api-key' }); @@ -201,6 +205,10 @@ describe('doGenerate', () => { 'custom-provider-header': 'provider-header-value', 'custom-request-header': 'request-header-value', }); + + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/revai/0.0.0-test`, + ); }); it('should extract the transcription text', async () => { diff --git a/packages/revai/src/version.ts b/packages/revai/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/revai/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/revai/tsup.config.ts b/packages/revai/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/revai/tsup.config.ts +++ b/packages/revai/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/revai/vitest.edge.config.js b/packages/revai/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/revai/vitest.edge.config.js +++ b/packages/revai/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/revai/vitest.node.config.js b/packages/revai/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/revai/vitest.node.config.js +++ b/packages/revai/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/togetherai/src/index.ts b/packages/togetherai/src/index.ts index 00170cb32954..2383ec72c02a 100644 --- a/packages/togetherai/src/index.ts +++ b/packages/togetherai/src/index.ts @@ -4,3 +4,4 @@ export type { TogetherAIProviderSettings, } from './togetherai-provider'; export type { OpenAICompatibleErrorData as TogetherAIErrorData } from '@ai-sdk/openai-compatible'; +export { VERSION } from './version'; diff --git a/packages/togetherai/src/togetherai-provider.test.ts b/packages/togetherai/src/togetherai-provider.test.ts index 8593022ea9af..0a9b2919f629 100644 --- a/packages/togetherai/src/togetherai-provider.test.ts +++ b/packages/togetherai/src/togetherai-provider.test.ts @@ -4,7 +4,7 @@ import { OpenAICompatibleEmbeddingModel, } from '@ai-sdk/openai-compatible'; import { LanguageModelV2, EmbeddingModelV3 } from '@ai-sdk/provider'; -import { loadApiKey } from '@ai-sdk/provider-utils'; +import { loadApiKey, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { TogetherAIImageModel } from './togetherai-image-model'; import { createTogetherAI } from './togetherai-provider'; import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; @@ -19,10 +19,14 @@ vi.mock('@ai-sdk/openai-compatible', () => ({ OpenAICompatibleEmbeddingModel: vi.fn(), })); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), -})); +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); vi.mock('./togetherai-image-model', () => ({ TogetherAIImageModel: vi.fn(), diff --git a/packages/togetherai/src/togetherai-provider.ts b/packages/togetherai/src/togetherai-provider.ts index cf47b493b1a9..b3a3618a4661 100644 --- a/packages/togetherai/src/togetherai-provider.ts +++ b/packages/togetherai/src/togetherai-provider.ts @@ -13,12 +13,14 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { TogetherAIChatModelId } from './togetherai-chat-options'; import { TogetherAIEmbeddingModelId } from './togetherai-embedding-options'; import { TogetherAICompletionModelId } from './togetherai-completion-options'; import { TogetherAIImageModel } from './togetherai-image-model'; import { TogetherAIImageModelId } from './togetherai-image-settings'; +import { VERSION } from './version'; export interface TogetherAIProviderSettings { /** @@ -85,14 +87,18 @@ export function createTogetherAI( const baseURL = withoutTrailingSlash( options.baseURL ?? 'https://api.together.xyz/v1/', ); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'TOGETHER_AI_API_KEY', - description: 'TogetherAI', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'TOGETHER_AI_API_KEY', + description: 'TogetherAI', + })}`, + ...options.headers, + }, + `ai-sdk/togetherai/${VERSION}`, + ); interface CommonModelConfig { provider: string; diff --git a/packages/togetherai/src/version.ts b/packages/togetherai/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/togetherai/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/togetherai/tsup.config.ts b/packages/togetherai/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/togetherai/tsup.config.ts +++ b/packages/togetherai/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/togetherai/vitest.edge.config.js b/packages/togetherai/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/togetherai/vitest.edge.config.js +++ b/packages/togetherai/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/togetherai/vitest.node.config.js b/packages/togetherai/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/togetherai/vitest.node.config.js +++ b/packages/togetherai/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/vercel/src/index.ts b/packages/vercel/src/index.ts index bc224eeb7903..485da827ddd7 100644 --- a/packages/vercel/src/index.ts +++ b/packages/vercel/src/index.ts @@ -1,3 +1,4 @@ export { createVercel, vercel } from './vercel-provider'; export type { VercelProvider, VercelProviderSettings } from './vercel-provider'; export type { OpenAICompatibleErrorData as VercelErrorData } from '@ai-sdk/openai-compatible'; +export { VERSION } from './version'; diff --git a/packages/vercel/src/vercel-provider.test.ts b/packages/vercel/src/vercel-provider.test.ts index 6b6bce9e5a2d..805b216e0f59 100644 --- a/packages/vercel/src/vercel-provider.test.ts +++ b/packages/vercel/src/vercel-provider.test.ts @@ -12,10 +12,14 @@ vi.mock('@ai-sdk/openai-compatible', () => ({ OpenAICompatibleCompletionLanguageModel: vi.fn(), })); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), -})); +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + }; +}); vi.mock('./vercel-image-model', () => ({ VercelImageModel: vi.fn(), diff --git a/packages/vercel/src/vercel-provider.ts b/packages/vercel/src/vercel-provider.ts index fa00cb9cd80c..5d60268e1ce2 100644 --- a/packages/vercel/src/vercel-provider.ts +++ b/packages/vercel/src/vercel-provider.ts @@ -8,8 +8,10 @@ import { FetchFunction, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { VercelChatModelId } from './vercel-chat-options'; +import { VERSION } from './version'; export interface VercelProviderSettings { /** @@ -49,14 +51,18 @@ export function createVercel( const baseURL = withoutTrailingSlash( options.baseURL ?? 'https://api.v0.dev/v1', ); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'VERCEL_API_KEY', - description: 'Vercel', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'VERCEL_API_KEY', + description: 'Vercel', + })}`, + ...options.headers, + }, + `ai-sdk/vercel/${VERSION}`, + ); interface CommonModelConfig { provider: string; diff --git a/packages/vercel/src/version.ts b/packages/vercel/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/vercel/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/vercel/tsup.config.ts b/packages/vercel/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/vercel/tsup.config.ts +++ b/packages/vercel/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/vercel/vitest.edge.config.js b/packages/vercel/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/vercel/vitest.edge.config.js +++ b/packages/vercel/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/vercel/vitest.node.config.js b/packages/vercel/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/vercel/vitest.node.config.js +++ b/packages/vercel/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/xai/src/index.ts b/packages/xai/src/index.ts index 09c4d4b55273..733e399e0844 100644 --- a/packages/xai/src/index.ts +++ b/packages/xai/src/index.ts @@ -2,3 +2,4 @@ export type { XaiProviderOptions } from './xai-chat-options'; export type { XaiErrorData } from './xai-error'; export { createXai, xai } from './xai-provider'; export type { XaiProvider, XaiProviderSettings } from './xai-provider'; +export { VERSION } from './version'; diff --git a/packages/xai/src/version.ts b/packages/xai/src/version.ts new file mode 100644 index 000000000000..7a35d46f5d20 --- /dev/null +++ b/packages/xai/src/version.ts @@ -0,0 +1,6 @@ +// Version string of this package injected at build time. +declare const __PACKAGE_VERSION__: string | undefined; +export const VERSION: string = + typeof __PACKAGE_VERSION__ !== 'undefined' + ? __PACKAGE_VERSION__ + : '0.0.0-test'; diff --git a/packages/xai/src/xai-chat-language-model.test.ts b/packages/xai/src/xai-chat-language-model.test.ts index fcde6e247564..a4f0386fc289 100644 --- a/packages/xai/src/xai-chat-language-model.test.ts +++ b/packages/xai/src/xai-chat-language-model.test.ts @@ -1,14 +1,19 @@ import { LanguageModelV2Prompt } from '@ai-sdk/provider'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { convertReadableStreamToArray } from '@ai-sdk/provider-utils/test'; import { XaiChatLanguageModel } from './xai-chat-language-model'; +import { createXai } from './xai-provider'; const TEST_PROMPT: LanguageModelV2Prompt = [ { role: 'user', content: [{ type: 'text', text: 'Hello' }] }, ]; +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', +})); + const testConfig = { provider: 'xai.chat', baseURL: 'https://api.x.ai/v1', @@ -307,6 +312,7 @@ describe('XaiChatLanguageModel', () => { authorization: 'Bearer test-api-key', 'Custom-Provider-Header': 'provider-header-value', }), + generateId: () => 'test-id', }); @@ -327,6 +333,26 @@ describe('XaiChatLanguageModel', () => { }); }); + it('should include provider user agent when using createXai', async () => { + prepareJsonResponse({ content: '' }); + + const xai = createXai({ + apiKey: 'test-api-key', + headers: { 'Custom-Provider-Header': 'provider-header-value' }, + }); + + const modelWithHeaders = xai.chat('grok-beta'); + + await modelWithHeaders.doGenerate({ + prompt: TEST_PROMPT, + headers: { 'Custom-Request-Header': 'request-header-value' }, + }); + + expect(server.calls[0].requestUserAgent).toContain( + `ai-sdk/xai/0.0.0-test`, + ); + }); + it('should send request body', async () => { prepareJsonResponse({ content: '' }); diff --git a/packages/xai/src/xai-provider.test.ts b/packages/xai/src/xai-provider.test.ts index 6107072afa7f..88d4fe2a3d10 100644 --- a/packages/xai/src/xai-provider.test.ts +++ b/packages/xai/src/xai-provider.test.ts @@ -23,11 +23,19 @@ vi.mock('./xai-image-model', () => ({ XaiImageModel: vi.fn(), })); -vi.mock('@ai-sdk/provider-utils', () => ({ - loadApiKey: vi.fn().mockReturnValue('mock-api-key'), - withoutTrailingSlash: vi.fn(url => url), - createJsonErrorResponseHandler: vi.fn().mockReturnValue(() => {}), - generateId: vi.fn().mockReturnValue('mock-id'), +vi.mock('@ai-sdk/provider-utils', async () => { + const actual = await vi.importActual('@ai-sdk/provider-utils'); + return { + ...actual, + loadApiKey: vi.fn().mockReturnValue('mock-api-key'), + withoutTrailingSlash: vi.fn(url => url), + createJsonErrorResponseHandler: vi.fn().mockReturnValue(() => {}), + generateId: vi.fn().mockReturnValue('mock-id'), + }; +}); + +vi.mock('./version', () => ({ + VERSION: '0.0.0-test', })); describe('xAIProvider', () => { @@ -150,8 +158,9 @@ describe('xAIProvider', () => { const headers = config.headers(); expect(headers).toMatchObject({ - Authorization: 'Bearer mock-api-key', - 'Custom-Header': 'test-value', + authorization: 'Bearer mock-api-key', + 'custom-header': 'test-value', + 'user-agent': 'ai-sdk/xai/0.0.0-test', }); }); }); diff --git a/packages/xai/src/xai-provider.ts b/packages/xai/src/xai-provider.ts index c2dc843c5774..28f329049b7d 100644 --- a/packages/xai/src/xai-provider.ts +++ b/packages/xai/src/xai-provider.ts @@ -13,11 +13,13 @@ import { generateId, loadApiKey, withoutTrailingSlash, + withUserAgentSuffix, } from '@ai-sdk/provider-utils'; import { XaiChatLanguageModel } from './xai-chat-language-model'; import { XaiChatModelId } from './xai-chat-options'; import { XaiErrorData, xaiErrorDataSchema } from './xai-error'; import { XaiImageModelId } from './xai-image-settings'; +import { VERSION } from './version'; const xaiErrorStructure: ProviderErrorStructure = { errorSchema: xaiErrorDataSchema, @@ -78,14 +80,18 @@ export function createXai(options: XaiProviderSettings = {}): XaiProvider { const baseURL = withoutTrailingSlash( options.baseURL ?? 'https://api.x.ai/v1', ); - const getHeaders = () => ({ - Authorization: `Bearer ${loadApiKey({ - apiKey: options.apiKey, - environmentVariableName: 'XAI_API_KEY', - description: 'xAI API key', - })}`, - ...options.headers, - }); + const getHeaders = () => + withUserAgentSuffix( + { + Authorization: `Bearer ${loadApiKey({ + apiKey: options.apiKey, + environmentVariableName: 'XAI_API_KEY', + description: 'xAI API key', + })}`, + ...options.headers, + }, + `ai-sdk/xai/${VERSION}`, + ); const createLanguageModel = (modelId: XaiChatModelId) => { return new XaiChatLanguageModel(modelId, { diff --git a/packages/xai/tsup.config.ts b/packages/xai/tsup.config.ts index 3f92041b987c..411ecbaf4300 100644 --- a/packages/xai/tsup.config.ts +++ b/packages/xai/tsup.config.ts @@ -6,5 +6,11 @@ export default defineConfig([ format: ['cjs', 'esm'], dts: true, sourcemap: true, + define: { + __PACKAGE_VERSION__: JSON.stringify( + (await import('./package.json', { with: { type: 'json' } })).default + .version, + ), + }, }, ]); diff --git a/packages/xai/vitest.edge.config.js b/packages/xai/vitest.edge.config.js index 3dc49ba29774..3ece1aa35903 100644 --- a/packages/xai/vitest.edge.config.js +++ b/packages/xai/vitest.edge.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'edge-runtime', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); diff --git a/packages/xai/vitest.node.config.js b/packages/xai/vitest.node.config.js index b7e4a9cabd48..bf1b0442d8b8 100644 --- a/packages/xai/vitest.node.config.js +++ b/packages/xai/vitest.node.config.js @@ -1,4 +1,5 @@ import { defineConfig } from 'vite'; +import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ @@ -6,4 +7,7 @@ export default defineConfig({ environment: 'node', include: ['**/*.test.ts', '**/*.test.tsx'], }, + define: { + __PACKAGE_VERSION__: JSON.stringify(packageJson.version), + }, }); From 30403bcb073b457284d6513d4792e5d21759c528 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Tue, 23 Sep 2025 19:18:58 +0000 Subject: [PATCH 105/121] Version Packages (beta) (#8838) # Releases ## ai@5.1.0-beta.6 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - Updated dependencies [5d21222] - Updated dependencies [0c4822d] - Updated dependencies [1cad0ab] - @ai-sdk/gateway@1.1.0-beta.5 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/amazon-bedrock@3.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - Updated dependencies [1cad0ab] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/anthropic@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/angular@1.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/anthropic@2.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/assemblyai@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/azure@2.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [4920119] - Updated dependencies [0c4822d] - Updated dependencies [1cad0ab] - @ai-sdk/openai@2.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/baseten@1.0.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/cerebras@1.1.0-beta.3 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/cohere@2.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/deepgram@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/deepinfra@1.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/deepseek@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/elevenlabs@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/fal@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/fireworks@1.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/gateway@1.1.0-beta.5 ### Patch Changes - 5d21222: feat(provider/gateway): Add gpt-5-codex to Gateway model string autocomplete - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/gladia@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/google@2.1.0-beta.3 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/google-vertex@3.1.0-beta.3 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - Updated dependencies [1cad0ab] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/google@2.1.0-beta.3 - @ai-sdk/anthropic@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/groq@2.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/hume@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/langchain@1.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 ## @ai-sdk/llamaindex@1.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 ## @ai-sdk/lmnt@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/luma@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/mistral@2.1.0-beta.3 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/openai@2.1.0-beta.2 ### Patch Changes - 4920119: fix the "incomplete_details" key from nullable to nullish for openai compatibility - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/openai-compatible@1.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/perplexity@2.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/provider@2.1.0-beta.1 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` ## @ai-sdk/provider-utils@3.1.0-beta.2 ### Patch Changes - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 ## @ai-sdk/react@2.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/replicate@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/revai@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/rsc@1.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - @ai-sdk/provider@2.1.0-beta.1 - ai@5.1.0-beta.6 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/svelte@3.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/togetherai@1.1.0-beta.2 ### Patch Changes - 0c4822d: feat: `EmbeddingModelV3` - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/valibot@1.1.0-beta.2 ### Patch Changes - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/vercel@1.1.0-beta.2 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/vue@2.1.0-beta.6 ### Patch Changes - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 - @ai-sdk/provider-utils@3.1.0-beta.2 ## @ai-sdk/xai@2.1.0-beta.3 ### Patch Changes - 1cad0ab: feat: add provider version to user-agent header - Updated dependencies [0c4822d] - @ai-sdk/openai-compatible@1.1.0-beta.2 - @ai-sdk/provider@2.1.0-beta.1 - @ai-sdk/provider-utils@3.1.0-beta.2 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 4 ++++ packages/ai/CHANGELOG.md | 12 ++++++++++++ packages/ai/package.json | 2 +- packages/amazon-bedrock/CHANGELOG.md | 12 ++++++++++++ packages/amazon-bedrock/package.json | 2 +- packages/angular/CHANGELOG.md | 8 ++++++++ packages/angular/package.json | 2 +- packages/anthropic/CHANGELOG.md | 9 +++++++++ packages/anthropic/package.json | 2 +- packages/assemblyai/CHANGELOG.md | 9 +++++++++ packages/assemblyai/package.json | 2 +- packages/azure/CHANGELOG.md | 13 +++++++++++++ packages/azure/package.json | 2 +- packages/baseten/CHANGELOG.md | 11 +++++++++++ packages/baseten/package.json | 2 +- packages/cerebras/CHANGELOG.md | 10 ++++++++++ packages/cerebras/package.json | 2 +- packages/cohere/CHANGELOG.md | 10 ++++++++++ packages/cohere/package.json | 2 +- packages/deepgram/CHANGELOG.md | 9 +++++++++ packages/deepgram/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 11 +++++++++++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 10 ++++++++++ packages/deepseek/package.json | 2 +- packages/elevenlabs/CHANGELOG.md | 9 +++++++++ packages/elevenlabs/package.json | 2 +- packages/fal/CHANGELOG.md | 9 +++++++++ packages/fal/package.json | 2 +- packages/fireworks/CHANGELOG.md | 11 +++++++++++ packages/fireworks/package.json | 2 +- packages/gateway/CHANGELOG.md | 11 +++++++++++ packages/gateway/package.json | 2 +- packages/gladia/CHANGELOG.md | 9 +++++++++ packages/gladia/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 13 +++++++++++++ packages/google-vertex/package.json | 2 +- packages/google/CHANGELOG.md | 10 ++++++++++ packages/google/package.json | 2 +- packages/groq/CHANGELOG.md | 9 +++++++++ packages/groq/package.json | 2 +- packages/hume/CHANGELOG.md | 9 +++++++++ packages/hume/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/lmnt/CHANGELOG.md | 9 +++++++++ packages/lmnt/package.json | 2 +- packages/luma/CHANGELOG.md | 9 +++++++++ packages/luma/package.json | 2 +- packages/mistral/CHANGELOG.md | 10 ++++++++++ packages/mistral/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 9 +++++++++ packages/openai-compatible/package.json | 2 +- packages/openai/CHANGELOG.md | 11 +++++++++++ packages/openai/package.json | 2 +- packages/perplexity/CHANGELOG.md | 9 +++++++++ packages/perplexity/package.json | 2 +- packages/provider-utils/CHANGELOG.md | 7 +++++++ packages/provider-utils/package.json | 2 +- packages/provider/CHANGELOG.md | 6 ++++++ packages/provider/package.json | 2 +- packages/react/CHANGELOG.md | 8 ++++++++ packages/react/package.json | 2 +- packages/replicate/CHANGELOG.md | 9 +++++++++ packages/replicate/package.json | 2 +- packages/revai/CHANGELOG.md | 9 +++++++++ packages/revai/package.json | 2 +- packages/rsc/CHANGELOG.md | 9 +++++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 8 ++++++++ packages/svelte/package.json | 2 +- packages/togetherai/CHANGELOG.md | 11 +++++++++++ packages/togetherai/package.json | 2 +- packages/valibot/CHANGELOG.md | 6 ++++++ packages/valibot/package.json | 2 +- packages/vercel/CHANGELOG.md | 10 ++++++++++ packages/vercel/package.json | 2 +- packages/vue/CHANGELOG.md | 8 ++++++++ packages/vue/package.json | 2 +- packages/xai/CHANGELOG.md | 10 ++++++++++ packages/xai/package.json | 2 +- 84 files changed, 438 insertions(+), 41 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 64be33c16952..c708d69a08ee 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -74,10 +74,14 @@ }, "changesets": [ "angry-hats-cry", + "beige-bikes-repeat", + "blue-books-hang", "curly-glasses-count", "four-candles-buy", + "funny-olives-reply", "grumpy-actors-sleep", "itchy-monkeys-nail", + "lemon-guests-drop", "many-lamps-report", "neat-news-visit", "old-kiwis-hide", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 3d74cc644772..86d39968074d 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,17 @@ # ai +## 5.1.0-beta.6 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- Updated dependencies [5d21222] +- Updated dependencies [0c4822d] +- Updated dependencies [1cad0ab] + - @ai-sdk/gateway@1.1.0-beta.5 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 5.1.0-beta.5 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 89e20f6e963e..6dc49750d58f 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.5", + "version": "5.1.0-beta.6", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index 6c5df2b0b2ec..ed06aa7217a6 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/amazon-bedrock +## 3.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] +- Updated dependencies [1cad0ab] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/anthropic@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 3.1.0-beta.1 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index 8e142fdc8123..e62f8c7bbb53 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.1.0-beta.1", + "version": "3.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 934fde3028cc..5ad46eec0e8d 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/angular +## 1.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.5 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index 63b757ca1548..f047bfe796d3 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.5", + "version": "1.1.0-beta.6", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 6bd27e527a6b..2a9755908c0f 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/anthropic +## 2.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 24c4feb216bb..43924c16cfc7 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/assemblyai/CHANGELOG.md b/packages/assemblyai/CHANGELOG.md index 5d3c81b6180e..5087815b943a 100644 --- a/packages/assemblyai/CHANGELOG.md +++ b/packages/assemblyai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/assemblyai +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index d10118c43b9b..6bfad467d70b 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/assemblyai", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index e12569a40921..e9c5bea04175 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/azure +## 2.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [4920119] +- Updated dependencies [0c4822d] +- Updated dependencies [1cad0ab] + - @ai-sdk/openai@2.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index 835084f421e1..fee75f2bd38e 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/baseten/CHANGELOG.md b/packages/baseten/CHANGELOG.md index 09ce605f44a1..85b0986156b2 100644 --- a/packages/baseten/CHANGELOG.md +++ b/packages/baseten/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/baseten +## 1.0.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.0.0-beta.1 ### Patch Changes diff --git a/packages/baseten/package.json b/packages/baseten/package.json index 5a39dda5e571..8b1cff3e2eb4 100644 --- a/packages/baseten/package.json +++ b/packages/baseten/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/baseten", - "version": "1.0.0-beta.1", + "version": "1.0.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index ede25a2a8a94..0d125cc2aa3b 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/cerebras +## 1.1.0-beta.3 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index 0bb0dae52b4e..f02a39bc47c5 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index 245aa4945e31..f6d12cdca590 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/cohere +## 2.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index 68e70e1aadad..4d3482fadb4c 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepgram/CHANGELOG.md b/packages/deepgram/CHANGELOG.md index cbb4a21e8197..ceb28abe1887 100644 --- a/packages/deepgram/CHANGELOG.md +++ b/packages/deepgram/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/deepgram +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index 799c691ee894..b7f43bffb9e9 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepgram", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index e5e9317a4e3a..f662cf9bce6b 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/deepinfra +## 1.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 313d62eb8d51..755a8da2c253 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 7cb426f56a78..41959d8be20e 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/deepseek +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index 531d57ec0d3a..e21c8c406a21 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/elevenlabs/CHANGELOG.md b/packages/elevenlabs/CHANGELOG.md index ed59b7f63f70..cdb347bdde81 100644 --- a/packages/elevenlabs/CHANGELOG.md +++ b/packages/elevenlabs/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/elevenlabs +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/elevenlabs/package.json b/packages/elevenlabs/package.json index efeb3ef9d606..6ef2cf6465c1 100644 --- a/packages/elevenlabs/package.json +++ b/packages/elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/elevenlabs", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index 87147f8f6f36..72b029113ca1 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/fal +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index f35b23082db5..016bcb0daf69 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 9550242cc748..3da7875a5011 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/fireworks +## 1.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index af2ce2c84604..63fbc8d2fcd0 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index e88038629b58..702c237eb928 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/gateway +## 1.1.0-beta.5 + +### Patch Changes + +- 5d21222: feat(provider/gateway): Add gpt-5-codex to Gateway model string autocomplete +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.4 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 3f75efa6d42b..8a074773d279 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.1.0-beta.4", + "version": "1.1.0-beta.5", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gladia/CHANGELOG.md b/packages/gladia/CHANGELOG.md index a0098b9666ec..a81efd0d222e 100644 --- a/packages/gladia/CHANGELOG.md +++ b/packages/gladia/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/gladia +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/gladia/package.json b/packages/gladia/package.json index 4481b8a4688d..6a71af2f2452 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/gladia", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "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 4f597dfdd558..58ccf04156cc 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/google-vertex +## 3.1.0-beta.3 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] +- Updated dependencies [1cad0ab] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/google@2.1.0-beta.3 + - @ai-sdk/anthropic@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 3.1.0-beta.2 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index 7566322395da..fb1afb7d2787 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.1.0-beta.2", + "version": "3.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 005ff2c95d3e..6ce86fa2fee6 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/google +## 2.1.0-beta.3 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index ef9205a63b26..b6c2cb3305b2 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index c93b5d400b0e..67e190ddee62 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/groq +## 2.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index e6857e8c7590..e24143f3216f 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/hume/CHANGELOG.md b/packages/hume/CHANGELOG.md index b82bab3ac426..9f5080f79f77 100644 --- a/packages/hume/CHANGELOG.md +++ b/packages/hume/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/hume +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/hume/package.json b/packages/hume/package.json index 0bce54c21e06..404ada9b2d9c 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/hume", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index aaf9ca8ac907..83ef63498630 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + ## 1.1.0-beta.5 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index 138f4e7bcabc..b0db48639b83 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.5", + "version": "1.1.0-beta.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 610994bc3ea8..ed1348175f49 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + ## 1.1.0-beta.5 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index c889e6af03b3..1bbdfe43ea60 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.5", + "version": "1.1.0-beta.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/lmnt/CHANGELOG.md b/packages/lmnt/CHANGELOG.md index 7dd1a5d8eb81..1fffb0d2b53b 100644 --- a/packages/lmnt/CHANGELOG.md +++ b/packages/lmnt/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/lmnt +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index d71aa24bc06b..0e25abfcaaca 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/lmnt", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index acb4abd7ff69..2a4263e1af66 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/luma +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index a68ae065777d..0345c9e0c827 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index d3bd06a40273..8a3ba1492456 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/mistral +## 2.1.0-beta.3 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 6c96d329973c..21fc53a0075c 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index 78b8b3584393..06626468534c 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/openai-compatible +## 1.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index 0e18fbd9f205..35526a1b9be7 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 6c2c1eaa213d..d4da79648f4c 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/openai +## 2.1.0-beta.2 + +### Patch Changes + +- 4920119: fix the "incomplete_details" key from nullable to nullish for openai compatibility +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index bc7c783ee338..c5d9c152a171 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index b6dde2ee18a9..430b6d5f53be 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/perplexity +## 2.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index 97d43cfad858..850ffe643b4d 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index 3224bd90c878..d64a58af4c48 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/provider-utils +## 3.1.0-beta.2 + +### Patch Changes + +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + ## 3.1.0-beta.1 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index 8f455af820df..98cb53c6f4e3 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "3.1.0-beta.1", + "version": "3.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider/CHANGELOG.md b/packages/provider/CHANGELOG.md index 13cc5bcbdcaf..6fdc2c188046 100644 --- a/packages/provider/CHANGELOG.md +++ b/packages/provider/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/provider +## 2.1.0-beta.1 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` + ## 2.1.0-beta.0 ### Minor Changes diff --git a/packages/provider/package.json b/packages/provider/package.json index 365b78b07d70..50fc55290bbc 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider", - "version": "2.1.0-beta.0", + "version": "2.1.0-beta.1", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 3184b38814e6..3aa2557625d6 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/react +## 2.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.5 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index bb9992530dad..ae13436ac88a 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.5", + "version": "2.1.0-beta.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index 4e35169b6fbb..7ad4fce1c325 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/replicate +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index 70327f3bfa6a..483d2748d7f0 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/revai/CHANGELOG.md b/packages/revai/CHANGELOG.md index 3af64bb4c724..7fca8a9ce2a2 100644 --- a/packages/revai/CHANGELOG.md +++ b/packages/revai/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/revai +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/revai/package.json b/packages/revai/package.json index 60a55520efa3..03ee9514684e 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/revai", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index a215b9a5b085..b847e2c86afc 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/rsc +## 1.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - @ai-sdk/provider@2.1.0-beta.1 + - ai@5.1.0-beta.6 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.5 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index e62189ffba6a..7ceb368a4e1d 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.5", + "version": "1.1.0-beta.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 7a627b5cea70..2448a43cd291 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + +## 0.0.1-beta.0 + +### Patch Changes + - ai@5.1.0-beta.5 ## 0.0.1-beta.0 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index d0b8e0a03ab2..eced800d6257 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/svelte +## 3.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 3.1.0-beta.5 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index e4669b188792..353d38451e1d 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.5", + "version": "3.1.0-beta.6", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index fac8686a8280..eca12a485bf9 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/togetherai +## 1.1.0-beta.2 + +### Patch Changes + +- 0c4822d: feat: `EmbeddingModelV3` +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index b9b187f129ed..f83394771443 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 626cd8d37c1d..1ed0f2aee37d 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/valibot +## 1.1.0-beta.2 + +### Patch Changes + +- @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index b2852c95d3c4..977869f863e7 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index cafbc0c38a46..63e21a17f5e4 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/vercel +## 1.1.0-beta.2 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 1.1.0-beta.1 ### Patch Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index 28e103b8a02c..af760b8a7690 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 7874c5d156bc..def248ec95a8 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/vue +## 2.1.0-beta.6 + +### Patch Changes + +- Updated dependencies [0c4822d] + - ai@5.1.0-beta.6 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.5 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 31971e7a1b86..35d278e306c6 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.5", + "version": "2.1.0-beta.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 2bce7bbf7840..1eb082cbcced 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/xai +## 2.1.0-beta.3 + +### Patch Changes + +- 1cad0ab: feat: add provider version to user-agent header +- Updated dependencies [0c4822d] + - @ai-sdk/openai-compatible@1.1.0-beta.2 + - @ai-sdk/provider@2.1.0-beta.1 + - @ai-sdk/provider-utils@3.1.0-beta.2 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index 828af5a8d01f..ebcbb1765ec3 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From 5a4e7321179b60725cc4bc7099ced8c90a02866c Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 23 Sep 2025 15:05:36 -0700 Subject: [PATCH 106/121] Export `parseJsonEventStream` and `uiMessageChunkSchema` from "ai" package (#8849) ## Background While implementing a custom `useChat` transport, I noticed these are missing from the `ai` package exports: * The `parseJsonEventStream()` function. I could grab this from the `@ai-sdk/provider-util` package directly, but since the `ai` package is already re-exporting stuff from this package, this would be nice to have as well. * The `uiMessageChunkSchema` zod schema is necessary for usage of `parseJsonEventStream()`. ## Summary Re-exported `parseJsonEventStream` from `@ai-sdk/provider-util`, and exported `uiMessageChunkSchema`. --- .changeset/gentle-students-begin.md | 5 +++++ packages/ai/src/index.ts | 1 + packages/ai/src/ui-message-stream/index.ts | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/gentle-students-begin.md diff --git a/.changeset/gentle-students-begin.md b/.changeset/gentle-students-begin.md new file mode 100644 index 000000000000..520bcd47bd84 --- /dev/null +++ b/.changeset/gentle-students-begin.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +Export `parseJsonEventStream` and `uiMessageChunkSchema` from "ai" package diff --git a/packages/ai/src/index.ts b/packages/ai/src/index.ts index 6d4cfca5a69f..d842c896f241 100644 --- a/packages/ai/src/index.ts +++ b/packages/ai/src/index.ts @@ -6,6 +6,7 @@ export { dynamicTool, generateId, jsonSchema, + parseJsonEventStream, tool, zodSchema, type IdGenerator, diff --git a/packages/ai/src/ui-message-stream/index.ts b/packages/ai/src/ui-message-stream/index.ts index 29da2f00ff7b..83876a7ac744 100644 --- a/packages/ai/src/ui-message-stream/index.ts +++ b/packages/ai/src/ui-message-stream/index.ts @@ -3,7 +3,11 @@ export { createUIMessageStreamResponse } from './create-ui-message-stream-respon export { JsonToSseTransformStream } from './json-to-sse-transform-stream'; export { pipeUIMessageStreamToResponse } from './pipe-ui-message-stream-to-response'; export { readUIMessageStream } from './read-ui-message-stream'; -export type { InferUIMessageChunk, UIMessageChunk } from './ui-message-chunks'; +export { + uiMessageChunkSchema, + type InferUIMessageChunk, + type UIMessageChunk, +} from './ui-message-chunks'; export { UI_MESSAGE_STREAM_HEADERS } from './ui-message-stream-headers'; export type { UIMessageStreamOnFinishCallback } from './ui-message-stream-on-finish-callback'; export type { UIMessageStreamWriter } from './ui-message-stream-writer'; From f172563d06339c3fa6b600e3f150be1199947dd3 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Tue, 23 Sep 2025 15:13:12 -0700 Subject: [PATCH 107/121] Version Packages (beta) (#8850) # Releases ## ai@5.1.0-beta.7 ### Patch Changes - 5a4e732: Export `parseJsonEventStream` and `uiMessageChunkSchema` from "ai" package ## @ai-sdk/angular@1.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 ## @ai-sdk/langchain@1.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 ## @ai-sdk/llamaindex@1.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 ## @ai-sdk/react@2.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 ## @ai-sdk/rsc@1.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 ## @ai-sdk/svelte@3.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 ## @ai-sdk/vue@2.1.0-beta.7 ### Patch Changes - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 1 + packages/ai/CHANGELOG.md | 6 ++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 7 +++++++ packages/angular/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 7 +++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 7 +++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 7 +++++++ packages/vue/package.json | 2 +- 18 files changed, 71 insertions(+), 8 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index c708d69a08ee..2ee1dc5c22d2 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -79,6 +79,7 @@ "curly-glasses-count", "four-candles-buy", "funny-olives-reply", + "gentle-students-begin", "grumpy-actors-sleep", "itchy-monkeys-nail", "lemon-guests-drop", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 86d39968074d..20074c8ab6ce 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 5.1.0-beta.7 + +### Patch Changes + +- 5a4e732: Export `parseJsonEventStream` and `uiMessageChunkSchema` from "ai" package + ## 5.1.0-beta.6 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 6dc49750d58f..9500444622a3 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.6", + "version": "5.1.0-beta.7", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 5ad46eec0e8d..efb881cdfcc5 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/angular +## 1.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 1.1.0-beta.6 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index f047bfe796d3..a1f025e11a98 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.6", + "version": "1.1.0-beta.7", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 83ef63498630..6b9bdc4c2c88 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 1.1.0-beta.6 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index b0db48639b83..efabab990bd5 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.6", + "version": "1.1.0-beta.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index ed1348175f49..97c0833755ba 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 1.1.0-beta.6 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 1bbdfe43ea60..1f91b13caa18 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.6", + "version": "1.1.0-beta.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 3aa2557625d6..f05eca883e29 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/react +## 2.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 2.1.0-beta.6 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index ae13436ac88a..27b3dcc654a9 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.6", + "version": "2.1.0-beta.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index b847e2c86afc..27af6230ece8 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/rsc +## 1.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 1.1.0-beta.6 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 7ceb368a4e1d..1a90250b0a57 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.6", + "version": "1.1.0-beta.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 2448a43cd291..5645b60fa21d 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + +## 0.0.1-beta.0 + +### Patch Changes + - Updated dependencies [0c4822d] - ai@5.1.0-beta.6 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index eced800d6257..e147af8af639 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/svelte +## 3.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 3.1.0-beta.6 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 353d38451e1d..4a184473af52 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.6", + "version": "3.1.0-beta.7", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index def248ec95a8..ab91f80a9c7e 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 2.1.0-beta.7 + +### Patch Changes + +- Updated dependencies [5a4e732] + - ai@5.1.0-beta.7 + ## 2.1.0-beta.6 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 35d278e306c6..7c9c06cab2f3 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.6", + "version": "2.1.0-beta.7", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From ab990ac903de9906a98443e352a9f930f8f68107 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 23 Sep 2025 15:13:54 -0700 Subject: [PATCH 108/121] ci(backport): comment in case of error (#8847) towards #8845 --- .github/workflows/backport.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index d758415f9bbf..4853a03eac37 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -92,9 +92,16 @@ jobs: env: GH_TOKEN: ${{ steps.app-token.outputs.token }} - - name: Comment on original PR + - name: Success Comment on original PR if: steps.create-pr.outputs.backport-pr-url run: | gh pr comment ${{ github.event.pull_request.number }} --body "✅ Backport PR created: ${{ steps.create-pr.outputs.backport-pr-url }}" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} + + - name: Failure Comment on original PR + if: failure() + run: | + gh pr comment ${{ github.event.pull_request.number }} --body "❌ Backport to v5.0 failed. This backport requires manual intervention. [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} From 641cfe20fa8c1f222c5dd1822c26106fdaab7041 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 23 Sep 2025 15:14:21 -0700 Subject: [PATCH 109/121] ci(backport): handle backticks in PR title and body (#8851) --- .github/workflows/backport.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 4853a03eac37..c5fabc2eca71 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -69,8 +69,6 @@ jobs: id: create-pr run: | # Create the backport PR - PR_TITLE="Backport: ${{ github.event.pull_request.title }}" - PR_BODY="This is an automated backport of #${{ github.event.pull_request.number }} to the v5.0 branch." PR_URL=$(gh pr create \ --title "$PR_TITLE" \ @@ -82,6 +80,8 @@ jobs: echo "Created backport PR $PR_URL" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} + PR_TITLE: "Backport: ${{ github.event.pull_request.title }}" + PR_BODY: "This is an automated backport of #${{ github.event.pull_request.number }} to the v5.0 branch." - name: Remove backport label from original PR if: steps.create-pr.outputs.backport-pr-url From 103c4e5c0a558fbea277d1dd27cfbcee02a6b765 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:20:59 -0700 Subject: [PATCH 110/121] docs(contributing): releases and branches (#8716) --- contributing/branches.md | 8 -------- contributing/releases.md | 41 ++++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 14 deletions(-) delete mode 100644 contributing/branches.md diff --git a/contributing/branches.md b/contributing/branches.md deleted file mode 100644 index 7d0145a5fcd0..000000000000 --- a/contributing/branches.md +++ /dev/null @@ -1,8 +0,0 @@ -# Branches - -`main` is always the development branch. - -When we start working on a new major or minor release, -the old stable release will be branched off, e.g. `v4` -and the changesets for `main` will enter pre-release mode, -e.g. `alpha` or `beta`. diff --git a/contributing/releases.md b/contributing/releases.md index abc1b92f2889..2e46d0fd20d9 100644 --- a/contributing/releases.md +++ b/contributing/releases.md @@ -1,13 +1,42 @@ # Releases +We use [changesets](https://github.com/changesets/action) for automated releases. + ## Changesets -Each pull request that modifies production code (not examples/docs) needs to have a changeset. +- Every pull request that modifies production code (not `examples`/`docs`) must include a changeset. +- By default, use `patch` (non-breaking). +- To override, apply the `minor` or `major` label (CI enforces `patch` otherwise). + +## Regular Releases + +- The [Changesets action](https://github.com/changesets/action) automatically creates a **Version Packages** PR. +- Merging this PR triggers the release workflow, which publishes the npm packages. + +## Maintenance Releases + +- Enable the [`release` workflow](https://github.com/vercel/ai/blob/main/.github/workflows/release.yml) on the maintenance branch. +- Only `patch` releases are allowed. +- To release: + 1. Create a pull request against the maintenance branch. + 2. Merge it to trigger the release workflow. + +## Beta Releases + +- Create a maintenance branch for the current stable minor version (e.g., if latest is `5.0.24`, create `v5.0`). +- Enable the [`release` workflow](https://github.com/vercel/ai/blob/main/.github/workflows/release.yml) on that branch and set up branch protections. +- Switch `main` to beta release mode: + + ```bash + pnpm changeset pre enter beta + ``` -Unless a minor or major release is planned (often on a separate branch), changesets should be `patch` and non-breaking. + (This creates a PR like #8710). -## Releasing +- During beta: All PRs continue to target main. +- In order to backport pull requests to the stable release, add the `backport` label. This will create a new pull request with the same changes against the stable release branch. +- To exit the beta release mode, run: -Patch releases can be created by merging the `Version Packages` pull requests that are automatically created by the corresponding GitHub action. -You might need to close/reopen them to trigger the workflows. -Once merged, the release action will release the npm packages. + ```bash + pnpm changeset pre exit + ``` From 2e860820bb56fe696fbc8003dffbbfffe840f97c Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:36:38 -0700 Subject: [PATCH 111/121] feat(provider/openai): `OpenAILanguageModelOptions` type (#8212) ## Background We are currently not exporting a type for `providerOptions.openai` ## Summary Export `OpenAILanguageModelOptions` to type `providerOptions.openai` as needed ## Manual Verification [examples/ai-core/src/generate-text/openai-provider-options.ts](https://github.com/vercel/ai/blob/gr2m/export-mistral-language-model-options/examples/ai-core/src/generate-text/openai-provider-options.ts#L9-L28) ## Tasks - [ ] ~~Tests have been added / updated (for bug fixes / features)~~ we don't currently do test of module exports, we use examples instead - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Related Issues - #8202 --- .changeset/cyan-mirrors-clap.md | 20 +++++++++++ .../01-ai-sdk-providers/03-openai.mdx | 4 ++- .../generate-text/openai-provider-options.ts | 33 +++++++++++++++++++ .../src/chat/openai-chat-language-model.ts | 4 +-- .../openai/src/chat/openai-chat-options.ts | 6 ++-- packages/openai/src/index.ts | 1 + 6 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 .changeset/cyan-mirrors-clap.md create mode 100644 examples/ai-core/src/generate-text/openai-provider-options.ts diff --git a/.changeset/cyan-mirrors-clap.md b/.changeset/cyan-mirrors-clap.md new file mode 100644 index 000000000000..676515acec5d --- /dev/null +++ b/.changeset/cyan-mirrors-clap.md @@ -0,0 +1,20 @@ +--- +'@ai-sdk/openai': patch +--- + +feat(provider/openai): `OpenAIChatLanguageModelOptions` type + +```ts +import { openai, type OpenAIChatLanguageModelOptions } from '@ai-sdk/openai'; +import { generateText } from 'ai'; + +await generateText({ + model: openai.chat('gpt-4o'), + prompt: 'Invent a new holiday and describe its traditions.', + providerOptions: { + openai: { + user: 'user-123', + } satisfies OpenAIChatLanguageModelOptions, + }, +}); +``` diff --git a/content/providers/01-ai-sdk-providers/03-openai.mdx b/content/providers/01-ai-sdk-providers/03-openai.mdx index 7a4f7c65b8be..4b5483d2d5f6 100644 --- a/content/providers/01-ai-sdk-providers/03-openai.mdx +++ b/content/providers/01-ai-sdk-providers/03-openai.mdx @@ -624,6 +624,8 @@ OpenAI chat models support also some model specific provider options that are no You can pass them in the `providerOptions` argument: ```ts +import { openai, type OpenAIChatLanguageModelOptions } from '@ai-sdk/openai'; + const model = openai.chat('gpt-5'); await generateText({ @@ -635,7 +637,7 @@ await generateText({ '50256': -100, }, user: 'test-user', // optional unique user identifier - }, + } satisfies OpenAIChatLanguageModelOptions, }, }); ``` diff --git a/examples/ai-core/src/generate-text/openai-provider-options.ts b/examples/ai-core/src/generate-text/openai-provider-options.ts new file mode 100644 index 000000000000..fdfc10c02019 --- /dev/null +++ b/examples/ai-core/src/generate-text/openai-provider-options.ts @@ -0,0 +1,33 @@ +import { openai, type OpenAIChatLanguageModelOptions } from '@ai-sdk/openai'; +import { generateText } from 'ai'; +import 'dotenv/config'; + +async function main() { + const { text, usage } = await generateText({ + model: openai.chat('gpt-4o'), + prompt: 'Invent a new holiday and describe its traditions.', + providerOptions: { + openai: { + logitBias: {}, + logprobs: 1, + user: '', + maxCompletionTokens: 100, + store: false, + structuredOutputs: false, + serviceTier: 'auto', + strictJsonSchema: false, + textVerbosity: 'medium', + promptCacheKey: '', + safetyIdentifier: '', + // @ts-expect-error + invalidOption: null, + } satisfies OpenAIChatLanguageModelOptions, + }, + }); + + console.log(text); + console.log(); + console.log('Usage:', usage); +} + +main().catch(console.error); diff --git a/packages/openai/src/chat/openai-chat-language-model.ts b/packages/openai/src/chat/openai-chat-language-model.ts index 41c16c2a9bd1..c2795cf359fe 100644 --- a/packages/openai/src/chat/openai-chat-language-model.ts +++ b/packages/openai/src/chat/openai-chat-language-model.ts @@ -30,7 +30,7 @@ import { getResponseMetadata } from './get-response-metadata'; import { mapOpenAIFinishReason } from './map-openai-finish-reason'; import { OpenAIChatModelId, - openaiProviderOptions, + openaiChatLanguageModelOptions, } from './openai-chat-options'; import { prepareChatTools } from './openai-chat-prepare-tools'; @@ -83,7 +83,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV2 { (await parseProviderOptions({ provider: 'openai', providerOptions, - schema: openaiProviderOptions, + schema: openaiChatLanguageModelOptions, })) ?? {}; const structuredOutputs = openaiOptions.structuredOutputs ?? true; diff --git a/packages/openai/src/chat/openai-chat-options.ts b/packages/openai/src/chat/openai-chat-options.ts index cd1bad7d288a..0ac9b5d3582e 100644 --- a/packages/openai/src/chat/openai-chat-options.ts +++ b/packages/openai/src/chat/openai-chat-options.ts @@ -39,7 +39,7 @@ export type OpenAIChatModelId = | 'gpt-5-chat-latest' | (string & {}); -export const openaiProviderOptions = z.object({ +export const openaiChatLanguageModelOptions = z.object({ /** * Modify the likelihood of specified tokens appearing in the completion. * @@ -141,4 +141,6 @@ export const openaiProviderOptions = z.object({ safetyIdentifier: z.string().optional(), }); -export type OpenAIProviderOptions = z.infer; +export type OpenAIChatLanguageModelOptions = z.infer< + typeof openaiChatLanguageModelOptions +>; diff --git a/packages/openai/src/index.ts b/packages/openai/src/index.ts index d48a826891da..59747996375a 100644 --- a/packages/openai/src/index.ts +++ b/packages/openai/src/index.ts @@ -1,4 +1,5 @@ export { createOpenAI, openai } from './openai-provider'; export type { OpenAIProvider, OpenAIProviderSettings } from './openai-provider'; export type { OpenAIResponsesProviderOptions } from './responses/openai-responses-language-model'; +export type { OpenAIChatLanguageModelOptions } from './chat/openai-chat-options'; export { VERSION } from './version'; From 7eca093fb725e537448cc3daa5ba0345cf9923d5 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 24 Sep 2025 00:50:59 -0700 Subject: [PATCH 112/121] fix(ai): update `uiMessageChunkSchema` to satisfy the `UIMessageChunk` type (#8863) ## Background The `uiMessageChunkSchema` seems to be out of date with the TypeScript `UIMessageChunk` type. Consider the following code: ```ts import { type UIMessageChunk, uiMessageChunkSchema } from "ai"; const m: UIMessageChunk = uiMessageChunkSchema.parse({ type: "text-delta", delta: "Hello, world!", id: "123", }); ``` This was producing the following TypeScript error: ``` Type '{ type: "text-start"; id: string; providerMetadata?: SharedV2ProviderMetadata | undefined; } | { type: "text-delta"; id: string; delta: string; providerMetadata?: SharedV2ProviderMetadata | undefined; } | ... 22 more ... | { ...; }' is not assignable to type 'UIMessageChunk'. Type '{ type: "reasoning"; text: string; providerMetadata?: SharedV2ProviderMetadata | undefined; }' is not assignable to type 'UIMessageChunk'. Type '{ type: "reasoning"; text: string; providerMetadata?: SharedV2ProviderMetadata | undefined; }' is missing the following properties from type '{ type: "source-document"; sourceId: string; mediaType: string; title: string; filename?: string | undefined; providerMetadata?: SharedV2ProviderMetadata | undefined; }': sourceId, mediaType, titlets(2322) ``` ## Summary * remove unused types from schema * add provider metadata for file * update data type parsing to support template string ## Manual Testing - [x] test UI example with reasoning (2 steps, OpenAI) ## Tasks - [x] add type test - [x] investigate expected behavior --------- Co-authored-by: Lars Grammel --- .changeset/great-eels-mate.md | 5 +++++ .../ui-message-stream/ui-message-chunks.test-d.ts | 14 ++++++++++++++ .../ai/src/ui-message-stream/ui-message-chunks.ts | 15 ++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 .changeset/great-eels-mate.md create mode 100644 packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts diff --git a/.changeset/great-eels-mate.md b/.changeset/great-eels-mate.md new file mode 100644 index 000000000000..48fb0a3fb4de --- /dev/null +++ b/.changeset/great-eels-mate.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): update `uiMessageChunkSchema` to satisfy the `UIMessageChunk` type diff --git a/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts b/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts new file mode 100644 index 000000000000..3b7568ce8e1a --- /dev/null +++ b/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts @@ -0,0 +1,14 @@ +import { describe, expectTypeOf, it } from 'vitest'; +import { UIMessageChunk, uiMessageChunkSchema } from './ui-message-chunks'; + +describe('UI message chunks type', () => { + it('should work with fixed inputSchema', () => { + const chunk = uiMessageChunkSchema.parse({ + type: 'text-delta', + delta: 'Hello, world!', + id: '123', + }); + + expectTypeOf(chunk).toEqualTypeOf(); + }); +}); diff --git a/packages/ai/src/ui-message-stream/ui-message-chunks.ts b/packages/ai/src/ui-message-stream/ui-message-chunks.ts index ebda56cc21d5..aad82429aa62 100644 --- a/packages/ai/src/ui-message-stream/ui-message-chunks.ts +++ b/packages/ai/src/ui-message-stream/ui-message-chunks.ts @@ -78,11 +78,6 @@ export const uiMessageChunkSchema = z.union([ providerExecuted: z.boolean().optional(), dynamic: z.boolean().optional(), }), - z.strictObject({ - type: z.literal('reasoning'), - text: z.string(), - providerMetadata: providerMetadataSchema.optional(), - }), z.strictObject({ type: z.literal('reasoning-start'), id: z.string(), @@ -99,9 +94,6 @@ export const uiMessageChunkSchema = z.union([ id: z.string(), providerMetadata: providerMetadataSchema.optional(), }), - z.strictObject({ - type: z.literal('reasoning-part-finish'), - }), z.strictObject({ type: z.literal('source-url'), sourceId: z.string(), @@ -124,7 +116,11 @@ export const uiMessageChunkSchema = z.union([ providerMetadata: providerMetadataSchema.optional(), }), z.strictObject({ - type: z.string().startsWith('data-'), + type: z.custom<`data-${string}`>( + (value): value is `data-${string}` => + typeof value === 'string' && value.startsWith('data-'), + { message: 'Type must start with "data-"' }, + ), id: z.string().optional(), data: z.unknown(), transient: z.boolean().optional(), @@ -267,6 +263,7 @@ export type UIMessageChunk< type: 'file'; url: string; mediaType: string; + providerMetadata?: ProviderMetadata; } | DataUIMessageChunk | { From 37670f4bf10f22313b36d666fc96aae42d830a59 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 24 Sep 2025 10:00:13 +0200 Subject: [PATCH 113/121] chore(ai): update test message (#8864) ## Background Incorrect test name added in #8863 ## Summary Update test name. ## Related Issues Introduced in #8863 --- packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts b/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts index 3b7568ce8e1a..df83b5da3039 100644 --- a/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts +++ b/packages/ai/src/ui-message-stream/ui-message-chunks.test-d.ts @@ -2,7 +2,7 @@ import { describe, expectTypeOf, it } from 'vitest'; import { UIMessageChunk, uiMessageChunkSchema } from './ui-message-chunks'; describe('UI message chunks type', () => { - it('should work with fixed inputSchema', () => { + it('parsed UI message chunk should have UIMessageChunk type', () => { const chunk = uiMessageChunkSchema.parse({ type: 'text-delta', delta: 'Hello, world!', From 6fe07b75c5c8f1e2ec4a2f9ebe547f6095fd67d3 Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 10:02:57 +0200 Subject: [PATCH 114/121] Version Packages (beta) (#8859) # Releases ## ai@5.1.0-beta.8 ### Patch Changes - 7eca093: fix(ai): update `uiMessageChunkSchema` to satisfy the `UIMessageChunk` type ## @ai-sdk/angular@1.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 ## @ai-sdk/azure@2.1.0-beta.3 ### Patch Changes - Updated dependencies [2e86082] - @ai-sdk/openai@2.1.0-beta.3 ## @ai-sdk/langchain@1.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 ## @ai-sdk/llamaindex@1.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 ## @ai-sdk/openai@2.1.0-beta.3 ### Patch Changes - 2e86082: feat(provider/openai): `OpenAIChatLanguageModelOptions` type ```ts import { openai, type OpenAIChatLanguageModelOptions } from '@ai-sdk/openai'; import { generateText } from 'ai'; await generateText({ model: openai.chat('gpt-4o'), prompt: 'Invent a new holiday and describe its traditions.', providerOptions: { openai: { user: 'user-123', } satisfies OpenAIChatLanguageModelOptions, }, }); ``` ## @ai-sdk/react@2.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 ## @ai-sdk/rsc@1.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 ## @ai-sdk/svelte@3.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 ## @ai-sdk/vue@2.1.0-beta.8 ### Patch Changes - Updated dependencies [7eca093] - ai@5.1.0-beta.8 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 2 ++ packages/ai/CHANGELOG.md | 6 ++++++ packages/ai/package.json | 2 +- packages/angular/CHANGELOG.md | 7 +++++++ packages/angular/package.json | 2 +- packages/azure/CHANGELOG.md | 7 +++++++ packages/azure/package.json | 2 +- packages/langchain/CHANGELOG.md | 7 +++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 7 +++++++ packages/llamaindex/package.json | 2 +- packages/openai/CHANGELOG.md | 21 +++++++++++++++++++ packages/openai/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- packages/rsc/CHANGELOG.md | 7 +++++++ packages/rsc/package.json | 2 +- .../rsc/tests/e2e/next-server/CHANGELOG.md | 7 +++++++ packages/svelte/CHANGELOG.md | 7 +++++++ packages/svelte/package.json | 2 +- packages/vue/CHANGELOG.md | 7 +++++++ packages/vue/package.json | 2 +- 22 files changed, 102 insertions(+), 10 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 2ee1dc5c22d2..7c705850132e 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -77,9 +77,11 @@ "beige-bikes-repeat", "blue-books-hang", "curly-glasses-count", + "cyan-mirrors-clap", "four-candles-buy", "funny-olives-reply", "gentle-students-begin", + "great-eels-mate", "grumpy-actors-sleep", "itchy-monkeys-nail", "lemon-guests-drop", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 20074c8ab6ce..5dfdf906b694 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # ai +## 5.1.0-beta.8 + +### Patch Changes + +- 7eca093: fix(ai): update `uiMessageChunkSchema` to satisfy the `UIMessageChunk` type + ## 5.1.0-beta.7 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 9500444622a3..d57b82fd14ed 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.7", + "version": "5.1.0-beta.8", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index efb881cdfcc5..3dd93bed8ad6 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/angular +## 1.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 1.1.0-beta.7 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index a1f025e11a98..bdf192f901ee 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.7", + "version": "1.1.0-beta.8", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index e9c5bea04175..fefba723fe93 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/azure +## 2.1.0-beta.3 + +### Patch Changes + +- Updated dependencies [2e86082] + - @ai-sdk/openai@2.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index fee75f2bd38e..fd58c19d76e4 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 6b9bdc4c2c88..9f7293dee9ab 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/langchain +## 1.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 1.1.0-beta.7 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index efabab990bd5..fab73aa5ef08 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.7", + "version": "1.1.0-beta.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 97c0833755ba..092cad72e4f0 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 1.1.0-beta.7 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 1f91b13caa18..17868cf5780c 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.7", + "version": "1.1.0-beta.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index d4da79648f4c..457791383809 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,26 @@ # @ai-sdk/openai +## 2.1.0-beta.3 + +### Patch Changes + +- 2e86082: feat(provider/openai): `OpenAIChatLanguageModelOptions` type + + ```ts + import { openai, type OpenAIChatLanguageModelOptions } from '@ai-sdk/openai'; + import { generateText } from 'ai'; + + await generateText({ + model: openai.chat('gpt-4o'), + prompt: 'Invent a new holiday and describe its traditions.', + providerOptions: { + openai: { + user: 'user-123', + } satisfies OpenAIChatLanguageModelOptions, + }, + }); + ``` + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index c5d9c152a171..d4f73ea9c5fe 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index f05eca883e29..3b8126afd05c 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/react +## 2.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 2.1.0-beta.7 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 27b3dcc654a9..f45cfa517c5b 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.7", + "version": "2.1.0-beta.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 27af6230ece8..063b0201d55f 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/rsc +## 1.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 1.1.0-beta.7 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 1a90250b0a57..8b692de05f77 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.7", + "version": "1.1.0-beta.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 5645b60fa21d..93156709772c 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,13 @@ ### Patch Changes +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + +## 0.0.1-beta.0 + +### Patch Changes + - Updated dependencies [5a4e732] - ai@5.1.0-beta.7 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index e147af8af639..33689aca600e 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/svelte +## 3.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 3.1.0-beta.7 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 4a184473af52..66a964e4f1fb 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.7", + "version": "3.1.0-beta.8", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index ab91f80a9c7e..b7c813962e47 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/vue +## 2.1.0-beta.8 + +### Patch Changes + +- Updated dependencies [7eca093] + - ai@5.1.0-beta.8 + ## 2.1.0-beta.7 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index 7c9c06cab2f3..bd875da866c9 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.7", + "version": "2.1.0-beta.8", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", From c96db45415ffc35cb7f6ed3aacf0168ea711d6b1 Mon Sep 17 00:00:00 2001 From: Lars Grammel Date: Wed, 24 Sep 2025 16:42:45 +0200 Subject: [PATCH 115/121] chore(examples): remove redundant OpenAI reasoning examples (#8866) ## Background We had many OpenAI reasoning examples that were redundant with each other and with tests. ## Summary Remove redundant OpenAI reasoning examples --- .../openai-responses-reasoning-summary.ts | 31 ------- .../openai-responses-reasoning-websearch.ts | 30 ------- ...responses-reasoning-zero-data-retention.ts | 73 ---------------- .../openai-responses-reasoning.ts | 29 ------- .../src/stream-text/openai-5-reasoning.ts | 86 ------------------- .../stream-text/openai-responses-reasoning.ts | 21 ----- 6 files changed, 270 deletions(-) delete mode 100644 examples/ai-core/src/generate-text/openai-responses-reasoning-summary.ts delete mode 100644 examples/ai-core/src/generate-text/openai-responses-reasoning-websearch.ts delete mode 100644 examples/ai-core/src/generate-text/openai-responses-reasoning-zero-data-retention.ts delete mode 100644 examples/ai-core/src/generate-text/openai-responses-reasoning.ts delete mode 100644 examples/ai-core/src/stream-text/openai-5-reasoning.ts delete mode 100644 examples/ai-core/src/stream-text/openai-responses-reasoning.ts diff --git a/examples/ai-core/src/generate-text/openai-responses-reasoning-summary.ts b/examples/ai-core/src/generate-text/openai-responses-reasoning-summary.ts deleted file mode 100644 index a6f3a2b55d3f..000000000000 --- a/examples/ai-core/src/generate-text/openai-responses-reasoning-summary.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; -import { generateText } from 'ai'; -import 'dotenv/config'; - -async function main() { - const result = await generateText({ - // supported: o4-mini, o3, o3-mini and o1 - model: openai.responses('o3-mini'), - prompt: - 'Tell me about the debate over Taqueria La Cumbre and El Farolito and who created the San Francisco Mission-style burrito.', - providerOptions: { - openai: { - // https://platform.openai.com/docs/guides/reasoning?api-mode=responses#reasoning-summaries - reasoningSummary: 'auto', // auto gives you the best available summary (detailed > auto > None) - } satisfies OpenAIResponsesProviderOptions, - }, - }); - - process.stdout.write('\x1b[34m'); - console.log(JSON.stringify(result.reasoning, null, 2)); - process.stdout.write('\x1b[0m'); - console.log(result.text); - console.log(); - console.log('Finish reason:', result.finishReason); - console.log('Usage:', result.usage); - console.log(); - console.log('Request body:', JSON.stringify(result.request.body, null, 2)); - console.log('Response body:', JSON.stringify(result.response.body, null, 2)); -} - -main().catch(console.error); diff --git a/examples/ai-core/src/generate-text/openai-responses-reasoning-websearch.ts b/examples/ai-core/src/generate-text/openai-responses-reasoning-websearch.ts deleted file mode 100644 index 6f9962fb845e..000000000000 --- a/examples/ai-core/src/generate-text/openai-responses-reasoning-websearch.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { openai } from '@ai-sdk/openai'; -import { generateText } from 'ai'; -import 'dotenv/config'; - -async function main() { - const result = await generateText({ - model: openai.responses('gpt-5-mini'), - prompt: 'What happened in the world today?', - providerOptions: { - openai: { reasoningSummary: 'detailed', reasoningEffort: 'medium' }, - }, - tools: { - web_search: openai.tools.webSearch(), - }, - }); - - console.log(JSON.stringify(result.response?.messages, null, 2)); - - const result2 = await generateText({ - model: openai.responses('gpt-5-mini'), - messages: [ - ...result.response?.messages, - { role: 'user', content: 'Summarize in 2 sentences.' }, - ], - }); - - console.log(JSON.stringify(result2, null, 2)); -} - -main().catch(console.error); diff --git a/examples/ai-core/src/generate-text/openai-responses-reasoning-zero-data-retention.ts b/examples/ai-core/src/generate-text/openai-responses-reasoning-zero-data-retention.ts deleted file mode 100644 index d7b3280eab06..000000000000 --- a/examples/ai-core/src/generate-text/openai-responses-reasoning-zero-data-retention.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; -import { generateText, UserModelMessage } from 'ai'; -import 'dotenv/config'; - -async function main() { - const result1 = await generateText({ - model: openai.responses('o3-mini'), - prompt: - 'Analyze the following encrypted data: U2VjcmV0UGFzc3dvcmQxMjM=. What type of encryption is this and what secret does it contain?', - providerOptions: { - openai: { - store: false, // No data retention - makes interaction stateless - reasoningEffort: 'medium', - reasoningSummary: 'auto', - include: ['reasoning.encrypted_content'], // Hence, we need to retrieve the model's encrypted reasoning to be able to pass it to follow-up requests - } satisfies OpenAIResponsesProviderOptions, - }, - }); - console.log('=== First request ==='); - process.stdout.write('\x1b[34m'); - console.log(JSON.stringify(result1.reasoning, null, 2)); - process.stdout.write('\x1b[0m'); - console.log(result1.text); - console.log(); - console.log('Finish reason:', result1.finishReason); - console.log('Usage:', result1.usage); - console.log(); - console.log('Request body:', JSON.stringify(result1.request.body, null, 2)); - console.log('Response body:', JSON.stringify(result1.response.body, null, 2)); - - const result2 = await generateText({ - model: openai.responses('o3-mini'), - prompt: [ - { - role: 'user', - content: [ - { - type: 'text', - text: 'Analyze the following encrypted data: U2VjcmV0UGFzc3dvcmQxMjM=. What type of encryption is this and what secret does it contain?', - }, - ], - }, - ...result1.response.messages, // Need to pass all previous messages to the follow-up request - { - role: 'user', - content: - 'Based on your previous analysis, what security recommendations would you make?', - } satisfies UserModelMessage, - ], - providerOptions: { - openai: { - store: false, // No data retention - makes interaction stateless - reasoningEffort: 'medium', - reasoningSummary: 'auto', - include: ['reasoning.encrypted_content'], // Hence, we need to retrieve the model's encrypted reasoning to be able to pass it to follow-up requests - } satisfies OpenAIResponsesProviderOptions, - }, - }); - - console.log('=== Second request ==='); - process.stdout.write('\x1b[34m'); - console.log(JSON.stringify(result2.reasoning, null, 2)); - process.stdout.write('\x1b[0m'); - console.log(result2.text); - console.log(); - console.log('Finish reason:', result2.finishReason); - console.log('Usage:', result2.usage); - console.log(); - console.log('Request body:', JSON.stringify(result2.request.body, null, 2)); - console.log('Response body:', JSON.stringify(result2.response.body, null, 2)); -} - -main().catch(console.error); diff --git a/examples/ai-core/src/generate-text/openai-responses-reasoning.ts b/examples/ai-core/src/generate-text/openai-responses-reasoning.ts deleted file mode 100644 index b6c93c1cf92c..000000000000 --- a/examples/ai-core/src/generate-text/openai-responses-reasoning.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai'; -import { generateText } from 'ai'; -import 'dotenv/config'; - -async function main() { - const result = await generateText({ - model: openai.responses('o3-mini'), - prompt: 'How many "r"s are in the word "strawberry"?', - temperature: 0.5, // should get ignored (warning) - providerOptions: { - openai: { - reasoningEffort: 'low', - } satisfies OpenAIResponsesProviderOptions, - }, - }); - - process.stdout.write('\x1b[34m'); - console.log(JSON.stringify(result.reasoning, null, 2)); - process.stdout.write('\x1b[0m'); - console.log(result.text); - console.log(); - console.log('Finish reason:', result.finishReason); - console.log('Usage:', result.usage); - console.log(); - console.log('Request:', JSON.stringify(result.request, null, 2)); - console.log('Response:', JSON.stringify(result.response, null, 2)); -} - -main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/openai-5-reasoning.ts b/examples/ai-core/src/stream-text/openai-5-reasoning.ts deleted file mode 100644 index edd5e7ea12d5..000000000000 --- a/examples/ai-core/src/stream-text/openai-5-reasoning.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { openai } from '@ai-sdk/openai'; -import { streamText } from 'ai'; -import 'dotenv/config'; -import { z } from 'zod'; -import { weatherTool } from '../tools/weather-tool'; - -async function main() { - const result = streamText({ - model: openai('gpt-5'), - tools: { - weather: weatherTool, - cityAttractions: { - inputSchema: z.object({ city: z.string() }), - }, - }, - prompt: 'What is the weather in San Francisco?', - }); - - for await (const part of result.fullStream) { - switch (part.type) { - case 'text-delta': { - console.log('Text:', part.text); - break; - } - - case 'tool-call': { - if (part.dynamic) { - continue; - } - - switch (part.toolName) { - case 'cityAttractions': { - console.log('TOOL CALL cityAttractions'); - console.log(`city: ${part.input.city}`); // string - break; - } - - case 'weather': { - console.log('TOOL CALL weather'); - console.log(`location: ${part.input.location}`); // string - break; - } - } - - break; - } - - case 'tool-result': { - if (part.dynamic) { - continue; - } - - switch (part.toolName) { - // NOT AVAILABLE (NO EXECUTE METHOD) - // case 'cityAttractions': { - // console.log('TOOL RESULT cityAttractions'); - // console.log(`city: ${part.input.city}`); // string - // console.log(`result: ${part.result}`); - // break; - // } - - case 'weather': { - console.log('TOOL RESULT weather'); - console.log(`location: ${part.input.location}`); // string - console.log(`temperature: ${part.output.temperature}`); // number - break; - } - } - - break; - } - - case 'finish': { - console.log('Finish reason:', part.finishReason); - console.log('Total Usage:', part.totalUsage); - break; - } - - case 'error': - console.error('Error:', part.error); - break; - } - } -} - -main().catch(console.error); diff --git a/examples/ai-core/src/stream-text/openai-responses-reasoning.ts b/examples/ai-core/src/stream-text/openai-responses-reasoning.ts deleted file mode 100644 index 463a8daaba89..000000000000 --- a/examples/ai-core/src/stream-text/openai-responses-reasoning.ts +++ /dev/null @@ -1,21 +0,0 @@ -import 'dotenv/config'; -import { openai } from '@ai-sdk/openai'; -import { streamText } from 'ai'; - -async function main() { - const result = streamText({ - model: openai.responses('o3-mini'), - system: 'You are a helpful assistant.', - prompt: 'Invent a new holiday and describe its traditions.', - }); - - for await (const textPart of result.textStream) { - process.stdout.write(textPart); - } - - console.log(); - console.log('Finish reason:', await result.finishReason); - console.log('Usage:', await result.usage); -} - -main().catch(console.error); From 177b47589a27468360465e07d5cd425749fe7e49 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Wed, 24 Sep 2025 10:49:11 -0700 Subject: [PATCH 116/121] fix(ai): download files when intermediate file cannot be downloaded (#8882) ## Background Files where not correctly downloaded when provided items where a mix of supported and unsupported URLs/media types ## Summary Map before filtering to retain correct index ## Manual Verification Verified by testing original bug submit from our security bug bounty program ## Checklist - [x] Tests have been added / updated (for bug fixes / features) - [ ] n/a ~~Documentation has been added / updated (for bug fixes / features)~~ - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues closes #8881 --------- Co-authored-by: Lars Grammel --- .changeset/tall-terms-smash.md | 5 + .../convert-to-language-model-prompt.test.ts | 95 +++++++++++++++++++ .../convert-to-language-model-prompt.ts | 19 ++-- 3 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 .changeset/tall-terms-smash.md diff --git a/.changeset/tall-terms-smash.md b/.changeset/tall-terms-smash.md new file mode 100644 index 000000000000..84db62dc0d36 --- /dev/null +++ b/.changeset/tall-terms-smash.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): download files when intermediate file cannot be downloaded diff --git a/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts b/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts index 867d6cb9d5a4..5401b1b65366 100644 --- a/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts +++ b/packages/ai/src/prompt/convert-to-language-model-prompt.test.ts @@ -673,6 +673,101 @@ describe('convertToLanguageModelPrompt', () => { ]); }); }); + + it('should download files when intermediate file cannot be downloaded', async () => { + const imageUrlA = `http://example.com/my-image-A.png`; // supported + const fileUrl = `http://127.0.0.1:3000/file`; // unsupported + const imageUrlB = `http://example.com/my-image-B.png`; // supported + + const mockDownload = vi.fn().mockResolvedValue([ + { + url: new URL(imageUrlA), + data: new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10, 0]), // empty png and 0 + mediaType: 'image/png', + }, + null, + { + url: new URL(imageUrlB), + data: new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10, 1]), // empty png and 1 + mediaType: 'image/png', + }, + ]); + + const result = await convertToLanguageModelPrompt({ + prompt: { + messages: [ + { + role: 'user', + content: [ + { type: 'image', image: imageUrlA, mediaType: 'image/png' }, + { + type: 'file', + data: new URL(fileUrl), + mediaType: 'application/octet-stream', + }, + { type: 'image', image: imageUrlB, mediaType: 'image/png' }, + ], + }, + ], + }, + supportedUrls: { + '*': [/^https:\/\/.*$/], + }, + download: mockDownload, + }); + + expect(result).toMatchInlineSnapshot(` + [ + { + "content": [ + { + "data": Uint8Array [ + 137, + 80, + 78, + 71, + 13, + 10, + 26, + 10, + 0, + ], + "filename": undefined, + "mediaType": "image/png", + "providerOptions": undefined, + "type": "file", + }, + { + "data": "http://127.0.0.1:3000/file", + "filename": undefined, + "mediaType": "application/octet-stream", + "providerOptions": undefined, + "type": "file", + }, + { + "data": Uint8Array [ + 137, + 80, + 78, + 71, + 13, + 10, + 26, + 10, + 1, + ], + "filename": undefined, + "mediaType": "image/png", + "providerOptions": undefined, + "type": "file", + }, + ], + "providerOptions": undefined, + "role": "user", + }, + ] + `); + }); }); describe('custom download function', () => { diff --git a/packages/ai/src/prompt/convert-to-language-model-prompt.ts b/packages/ai/src/prompt/convert-to-language-model-prompt.ts index 0a9736edd757..13e726f4289e 100644 --- a/packages/ai/src/prompt/convert-to-language-model-prompt.ts +++ b/packages/ai/src/prompt/convert-to-language-model-prompt.ts @@ -245,18 +245,15 @@ async function downloadAssets( return Object.fromEntries( downloadedFiles - .filter( - ( - downloadedFile, - ): downloadedFile is { - mediaType: string | undefined; - data: Uint8Array; - } => downloadedFile?.data != null, + .map((file, index) => + file == null + ? null + : [ + plannedDownloads[index].url.toString(), + { data: file.data, mediaType: file.mediaType }, + ], ) - .map(({ data, mediaType }, index) => [ - plannedDownloads[index].url.toString(), - { data, mediaType }, - ]), + .filter(file => file != null), ); } From aaf5ebfbcf764c0a616753fd14a3acd1b7e59ea0 Mon Sep 17 00:00:00 2001 From: Rohan Taneja <47066511+R-Taneja@users.noreply.github.com> Date: Wed, 24 Sep 2025 12:23:40 -0700 Subject: [PATCH 117/121] feat(provider/gateway): Add new Qwen models to Gateway model string autocomplete (#8890) ## Background New Qwen models launched ## Summary Added them to the Gateway model string autocomplete ## Manual Verification Autocomplete works ## Checklist - [ ] Tests have been added / updated (for bug fixes / features) - [ ] Documentation has been added / updated (for bug fixes / features) - [X] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [X] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [X] I have reviewed this pull request (self-review) --- .changeset/eighty-ghosts-collect.md | 5 +++++ packages/gateway/src/gateway-language-model-settings.ts | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 .changeset/eighty-ghosts-collect.md diff --git a/.changeset/eighty-ghosts-collect.md b/.changeset/eighty-ghosts-collect.md new file mode 100644 index 000000000000..cd9eb78fdb4b --- /dev/null +++ b/.changeset/eighty-ghosts-collect.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/gateway': patch +--- + +feat(provider/gateway): Add new Qwen models to Gateway model string autocomplete diff --git a/packages/gateway/src/gateway-language-model-settings.ts b/packages/gateway/src/gateway-language-model-settings.ts index f601da17c09c..2e3724681b52 100644 --- a/packages/gateway/src/gateway-language-model-settings.ts +++ b/packages/gateway/src/gateway-language-model-settings.ts @@ -4,9 +4,13 @@ export type GatewayModelId = | 'alibaba/qwen-3-30b' | 'alibaba/qwen-3-32b' | 'alibaba/qwen3-coder' + | 'alibaba/qwen3-coder-plus' | 'alibaba/qwen3-max' + | 'alibaba/qwen3-max-preview' | 'alibaba/qwen3-next-80b-a3b-instruct' | 'alibaba/qwen3-next-80b-a3b-thinking' + | 'alibaba/qwen3-vl-instruct' + | 'alibaba/qwen3-vl-thinking' | 'amazon/nova-lite' | 'amazon/nova-micro' | 'amazon/nova-pro' From ed329cb9aa99f1e918cd74f1716914e5ce47d362 Mon Sep 17 00:00:00 2001 From: Aayush Kapoor <83492835+aayush-kapoor@users.noreply.github.com> Date: Wed, 24 Sep 2025 18:19:30 -0400 Subject: [PATCH 118/121] feat: `Provider-V3` (#8893) ## Background #8763 #8769 ## Summary Replaced `ProviderV2` with `ProviderV3` ## Checklist - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) ## Related Issues Fixes #8769 towards #8763 --- .changeset/itchy-peaches-clean.md | 36 +++++++++++ .../01-custom-providers.mdx | 14 ++-- packages/ai/src/global.ts | 4 +- .../ai/src/middleware/wrap-provider.test.ts | 4 +- packages/ai/src/middleware/wrap-provider.ts | 12 ++-- packages/ai/src/model/resolve-model.ts | 4 +- packages/ai/src/registry/custom-provider.ts | 6 +- .../ai/src/registry/provider-registry.test.ts | 6 +- packages/ai/src/registry/provider-registry.ts | 10 +-- ...ock-provider-v2.ts => mock-provider-v3.ts} | 14 ++-- packages/ai/test/index.ts | 2 +- .../amazon-bedrock/src/bedrock-provider.ts | 4 +- packages/anthropic/src/anthropic-provider.ts | 4 +- .../assemblyai/src/assemblyai-provider.ts | 4 +- packages/azure/src/azure-openai-provider.ts | 4 +- packages/baseten/src/baseten-provider.ts | 4 +- packages/cerebras/src/cerebras-provider.ts | 4 +- packages/cohere/src/cohere-provider.ts | 4 +- packages/deepgram/src/deepgram-provider.ts | 6 +- packages/deepinfra/src/deepinfra-provider.ts | 4 +- packages/deepseek/src/deepseek-provider.ts | 4 +- .../elevenlabs/src/elevenlabs-provider.ts | 4 +- packages/fal/src/fal-provider.ts | 4 +- packages/fireworks/src/fireworks-provider.ts | 4 +- packages/gateway/src/gateway-provider.ts | 4 +- packages/gladia/src/gladia-provider.ts | 6 +- .../google-vertex-anthropic-provider.ts | 4 +- .../src/google-vertex-provider.ts | 4 +- packages/google/src/google-provider.ts | 4 +- packages/groq/src/groq-provider.ts | 4 +- packages/hume/src/hume-provider.ts | 4 +- packages/lmnt/src/lmnt-provider.ts | 4 +- packages/luma/src/luma-provider.ts | 4 +- packages/mistral/src/mistral-provider.ts | 4 +- .../src/openai-compatible-provider.ts | 4 +- packages/openai/src/openai-provider.ts | 4 +- .../perplexity/src/perplexity-provider.ts | 4 +- packages/provider/src/provider/index.ts | 1 + .../provider/src/provider/v2/provider-v2.ts | 4 +- packages/provider/src/provider/v3/index.ts | 1 + .../provider/src/provider/v3/provider-v3.ts | 64 +++++++++++++++++++ packages/replicate/src/replicate-provider.ts | 4 +- packages/revai/src/revai-provider.ts | 4 +- .../togetherai/src/togetherai-provider.ts | 4 +- packages/vercel/src/vercel-provider.ts | 4 +- packages/xai/src/xai-provider.ts | 4 +- 46 files changed, 206 insertions(+), 104 deletions(-) create mode 100644 .changeset/itchy-peaches-clean.md rename packages/ai/src/test/{mock-provider-v2.ts => mock-provider-v3.ts} (85%) create mode 100644 packages/provider/src/provider/v3/index.ts create mode 100644 packages/provider/src/provider/v3/provider-v3.ts diff --git a/.changeset/itchy-peaches-clean.md b/.changeset/itchy-peaches-clean.md new file mode 100644 index 000000000000..b6bf09bc47f0 --- /dev/null +++ b/.changeset/itchy-peaches-clean.md @@ -0,0 +1,36 @@ +--- +'@ai-sdk/openai-compatible': patch +'@ai-sdk/amazon-bedrock': patch +'@ai-sdk/google-vertex': patch +'@ai-sdk/assemblyai': patch +'@ai-sdk/elevenlabs': patch +'@ai-sdk/perplexity': patch +'@ai-sdk/togetherai': patch +'@ai-sdk/anthropic': patch +'@ai-sdk/deepinfra': patch +'@ai-sdk/fireworks': patch +'@ai-sdk/replicate': patch +'@ai-sdk/cerebras': patch +'@ai-sdk/deepgram': patch +'@ai-sdk/deepseek': patch +'@ai-sdk/provider': patch +'@ai-sdk/baseten': patch +'@ai-sdk/gateway': patch +'@ai-sdk/mistral': patch +'@ai-sdk/cohere': patch +'@ai-sdk/gladia': patch +'@ai-sdk/google': patch +'@ai-sdk/openai': patch +'@ai-sdk/vercel': patch +'@ai-sdk/azure': patch +'@ai-sdk/revai': patch +'@ai-sdk/groq': patch +'@ai-sdk/hume': patch +'@ai-sdk/lmnt': patch +'@ai-sdk/luma': patch +'@ai-sdk/fal': patch +'@ai-sdk/xai': patch +'ai': patch +--- + +feat: `Provider-V3` diff --git a/content/providers/03-community-providers/01-custom-providers.mdx b/content/providers/03-community-providers/01-custom-providers.mdx index 9582afe44223..b96cf4cd2770 100644 --- a/content/providers/03-community-providers/01-custom-providers.mdx +++ b/content/providers/03-community-providers/01-custom-providers.mdx @@ -29,16 +29,16 @@ The Language Model Specification V2 creates a robust abstraction layer that work At its heart, the V2 specification defines three main interfaces: -1. **ProviderV2**: The top-level interface that serves as a factory for different model types +1. **ProviderV3**: The top-level interface that serves as a factory for different model types 2. **LanguageModelV2**: The primary interface for text generation models 3. **EmbeddingModelV3** and **ImageModelV2**: Interfaces for embeddings and image generation -### `ProviderV2` +### `ProviderV3` -The `ProviderV2` interface acts as the entry point: +The `ProviderV3` interface acts as the entry point: ```ts -interface ProviderV2 { +interface ProviderV3 { languageModel(modelId: string): LanguageModelV2; textEmbeddingModel(modelId: string): EmbeddingModelV3; imageModel(modelId: string): ImageModelV2; @@ -439,11 +439,11 @@ import { loadApiKey, withoutTrailingSlash, } from '@ai-sdk/provider-utils'; -import { ProviderV2 } from '@ai-sdk/provider'; +import { ProviderV3 } from '@ai-sdk/provider'; import { CustomChatLanguageModel } from './custom-chat-language-model'; -// Define your provider interface extending ProviderV2 -interface CustomProvider extends ProviderV2 { +// Define your provider interface extending ProviderV3 +interface CustomProvider extends ProviderV3 { (modelId: string, settings?: CustomChatSettings): CustomChatLanguageModel; // Add specific methods for different model types diff --git a/packages/ai/src/global.ts b/packages/ai/src/global.ts index 5bc6c6ffc1aa..72557a9a1686 100644 --- a/packages/ai/src/global.ts +++ b/packages/ai/src/global.ts @@ -1,4 +1,4 @@ -import { ProviderV2 } from '@ai-sdk/provider'; +import { ProviderV3 } from '@ai-sdk/provider'; import { LogWarningsFunction } from './logger/log-warnings'; // add AI SDK default provider to the globalThis object @@ -11,7 +11,7 @@ declare global { * * @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration */ - var AI_SDK_DEFAULT_PROVIDER: ProviderV2 | undefined; + var AI_SDK_DEFAULT_PROVIDER: ProviderV3 | undefined; /** * The warning logger to use for the AI SDK. diff --git a/packages/ai/src/middleware/wrap-provider.test.ts b/packages/ai/src/middleware/wrap-provider.test.ts index 7d6efb7faae5..6b2cda1769f8 100644 --- a/packages/ai/src/middleware/wrap-provider.test.ts +++ b/packages/ai/src/middleware/wrap-provider.test.ts @@ -1,5 +1,5 @@ import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; -import { MockProviderV2 } from '../test/mock-provider-v2'; +import { MockProviderV3 } from '../test/mock-provider-v3'; import { wrapProvider } from './wrap-provider'; import { describe, it, expect, vi } from 'vitest'; @@ -9,7 +9,7 @@ describe('wrapProvider', () => { const model2 = new MockLanguageModelV2({ modelId: 'model-2' }); const model3 = new MockLanguageModelV2({ modelId: 'model-3' }); - const provider = new MockProviderV2({ + const provider = new MockProviderV3({ languageModels: { 'model-1': model1, 'model-2': model2, diff --git a/packages/ai/src/middleware/wrap-provider.ts b/packages/ai/src/middleware/wrap-provider.ts index b57151e66331..2af57aee5f34 100644 --- a/packages/ai/src/middleware/wrap-provider.ts +++ b/packages/ai/src/middleware/wrap-provider.ts @@ -1,25 +1,25 @@ -import type { ProviderV2 } from '@ai-sdk/provider'; +import type { ProviderV3 } from '@ai-sdk/provider'; import { LanguageModelMiddleware } from '../types/language-model-middleware'; import { wrapLanguageModel } from './wrap-language-model'; /** - * Wraps a ProviderV2 instance with middleware functionality. + * Wraps a ProviderV3 instance with middleware functionality. * This function allows you to apply middleware to all language models * from the provider, enabling you to transform parameters, wrap generate * operations, and wrap stream operations for every language model. * * @param options - Configuration options for wrapping the provider. - * @param options.provider - The original ProviderV2 instance to be wrapped. + * @param options.provider - The original ProviderV3 instance to be wrapped. * @param options.languageModelMiddleware - The middleware to be applied to all language models from the provider. When multiple middlewares are provided, the first middleware will transform the input first, and the last middleware will be wrapped directly around the model. - * @returns A new ProviderV2 instance with middleware applied to all language models. + * @returns A new ProviderV3 instance with middleware applied to all language models. */ export function wrapProvider({ provider, languageModelMiddleware, }: { - provider: ProviderV2; + provider: ProviderV3; languageModelMiddleware: LanguageModelMiddleware | LanguageModelMiddleware[]; -}): ProviderV2 { +}): ProviderV3 { const wrappedProvider = { languageModel(modelId: string) { let model = provider.languageModel(modelId); diff --git a/packages/ai/src/model/resolve-model.ts b/packages/ai/src/model/resolve-model.ts index 4da0906a7cb4..4cdb0fc20f82 100644 --- a/packages/ai/src/model/resolve-model.ts +++ b/packages/ai/src/model/resolve-model.ts @@ -2,7 +2,7 @@ import { gateway } from '@ai-sdk/gateway'; import { EmbeddingModelV3, LanguageModelV2, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { UnsupportedModelVersionError } from '../error'; import { EmbeddingModel } from '../types/embedding-model'; @@ -45,6 +45,6 @@ export function resolveEmbeddingModel( ) as EmbeddingModelV3; } -function getGlobalProvider(): ProviderV2 { +function getGlobalProvider(): ProviderV3 { return globalThis.AI_SDK_DEFAULT_PROVIDER ?? gateway; } diff --git a/packages/ai/src/registry/custom-provider.ts b/packages/ai/src/registry/custom-provider.ts index 6b2efd4f8274..8ec7844bd017 100644 --- a/packages/ai/src/registry/custom-provider.ts +++ b/packages/ai/src/registry/custom-provider.ts @@ -3,7 +3,7 @@ import { ImageModelV2, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; @@ -41,8 +41,8 @@ export function customProvider< imageModels?: IMAGE_MODELS; transcriptionModels?: TRANSCRIPTION_MODELS; speechModels?: SPEECH_MODELS; - fallbackProvider?: ProviderV2; -}): ProviderV2 & { + fallbackProvider?: ProviderV3; +}): ProviderV3 & { languageModel(modelId: ExtractModelId): LanguageModelV2; textEmbeddingModel( modelId: ExtractModelId, diff --git a/packages/ai/src/registry/provider-registry.test.ts b/packages/ai/src/registry/provider-registry.test.ts index b83a6571dbd4..1ce82cc14b8c 100644 --- a/packages/ai/src/registry/provider-registry.test.ts +++ b/packages/ai/src/registry/provider-registry.test.ts @@ -6,7 +6,7 @@ import { createProviderRegistry } from './provider-registry'; import { MockImageModelV2 } from '../test/mock-image-model-v2'; import { MockTranscriptionModelV2 } from '../test/mock-transcription-model-v2'; import { MockSpeechModelV2 } from '../test/mock-speech-model-v2'; -import { MockProviderV2 } from '../test/mock-provider-v2'; +import { MockProviderV3 } from '../test/mock-provider-v3'; import { describe, it, expect, vi } from 'vitest'; describe('languageModel', () => { @@ -435,14 +435,14 @@ describe('middleware functionality', () => { const model2 = new MockLanguageModelV2({ modelId: 'model-2' }); const model3 = new MockLanguageModelV2({ modelId: 'model-3' }); - const provider1 = new MockProviderV2({ + const provider1 = new MockProviderV3({ languageModels: { 'model-1': model1, 'model-2': model2, }, }); - const provider2 = new MockProviderV2({ + const provider2 = new MockProviderV3({ languageModels: { 'model-3': model3, }, diff --git a/packages/ai/src/registry/provider-registry.ts b/packages/ai/src/registry/provider-registry.ts index b5a70aeaef52..a0eb0de6dc34 100644 --- a/packages/ai/src/registry/provider-registry.ts +++ b/packages/ai/src/registry/provider-registry.ts @@ -3,7 +3,7 @@ import { ImageModelV2, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; @@ -18,7 +18,7 @@ type ExtractLiteralUnion = T extends string : never; export interface ProviderRegistryProvider< - PROVIDERS extends Record = Record, + PROVIDERS extends Record = Record, SEPARATOR extends string = ':', > { languageModel( @@ -80,7 +80,7 @@ export interface ProviderRegistryProvider< * @returns A new ProviderRegistryProvider instance that provides access to all registered providers with optional middleware applied to language models. */ export function createProviderRegistry< - PROVIDERS extends Record, + PROVIDERS extends Record, SEPARATOR extends string = ':', >( providers: PROVIDERS, @@ -115,7 +115,7 @@ export function createProviderRegistry< export const experimental_createProviderRegistry = createProviderRegistry; class DefaultProviderRegistry< - PROVIDERS extends Record, + PROVIDERS extends Record, SEPARATOR extends string, > implements ProviderRegistryProvider { @@ -156,7 +156,7 @@ class DefaultProviderRegistry< | 'imageModel' | 'transcriptionModel' | 'speechModel', - ): ProviderV2 { + ): ProviderV3 { const provider = this.providers[id as keyof PROVIDERS]; if (provider == null) { diff --git a/packages/ai/src/test/mock-provider-v2.ts b/packages/ai/src/test/mock-provider-v3.ts similarity index 85% rename from packages/ai/src/test/mock-provider-v2.ts rename to packages/ai/src/test/mock-provider-v3.ts index 96828a500e98..9aa8c7a993bf 100644 --- a/packages/ai/src/test/mock-provider-v2.ts +++ b/packages/ai/src/test/mock-provider-v3.ts @@ -3,17 +3,17 @@ import { ImageModelV2, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; -export class MockProviderV2 implements ProviderV2 { - languageModel: ProviderV2['languageModel']; - textEmbeddingModel: ProviderV2['textEmbeddingModel']; - imageModel: ProviderV2['imageModel']; - transcriptionModel: ProviderV2['transcriptionModel']; - speechModel: ProviderV2['speechModel']; +export class MockProviderV3 implements ProviderV3 { + languageModel: ProviderV3['languageModel']; + textEmbeddingModel: ProviderV3['textEmbeddingModel']; + imageModel: ProviderV3['imageModel']; + transcriptionModel: ProviderV3['transcriptionModel']; + speechModel: ProviderV3['speechModel']; constructor({ languageModels, diff --git a/packages/ai/test/index.ts b/packages/ai/test/index.ts index 8a76107c4117..a9d6a9534233 100644 --- a/packages/ai/test/index.ts +++ b/packages/ai/test/index.ts @@ -7,7 +7,7 @@ export { export { MockEmbeddingModelV3 } from '../src/test/mock-embedding-model-v2'; export { MockImageModelV2 } from '../src/test/mock-image-model-v2'; export { MockLanguageModelV2 } from '../src/test/mock-language-model-v2'; -export { MockProviderV2 } from '../src/test/mock-provider-v2'; +export { MockProviderV3 } from '../src/test/mock-provider-v3'; export { MockSpeechModelV2 } from '../src/test/mock-speech-model-v2'; export { MockTranscriptionModelV2 } from '../src/test/mock-transcription-model-v2'; export { mockValues } from '../src/test/mock-values'; diff --git a/packages/amazon-bedrock/src/bedrock-provider.ts b/packages/amazon-bedrock/src/bedrock-provider.ts index a3efbcf25e34..570a6b3c4c6e 100644 --- a/packages/amazon-bedrock/src/bedrock-provider.ts +++ b/packages/amazon-bedrock/src/bedrock-provider.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV3, ImageModelV2, LanguageModelV2, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -104,7 +104,7 @@ and `sessionToken` settings. generateId?: () => string; } -export interface AmazonBedrockProvider extends ProviderV2 { +export interface AmazonBedrockProvider extends ProviderV3 { (modelId: BedrockChatModelId): LanguageModelV2; languageModel(modelId: BedrockChatModelId): LanguageModelV2; diff --git a/packages/anthropic/src/anthropic-provider.ts b/packages/anthropic/src/anthropic-provider.ts index cd12ad335592..21d1c501cd85 100644 --- a/packages/anthropic/src/anthropic-provider.ts +++ b/packages/anthropic/src/anthropic-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -15,7 +15,7 @@ import { AnthropicMessagesLanguageModel } from './anthropic-messages-language-mo import { AnthropicMessagesModelId } from './anthropic-messages-options'; import { anthropicTools } from './anthropic-tools'; -export interface AnthropicProvider extends ProviderV2 { +export interface AnthropicProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/assemblyai/src/assemblyai-provider.ts b/packages/assemblyai/src/assemblyai-provider.ts index b2d018cfc44e..c9a5991c60e2 100644 --- a/packages/assemblyai/src/assemblyai-provider.ts +++ b/packages/assemblyai/src/assemblyai-provider.ts @@ -1,6 +1,6 @@ import { TranscriptionModelV2, - ProviderV2, + ProviderV3, NoSuchModelError, } from '@ai-sdk/provider'; import { @@ -12,7 +12,7 @@ import { AssemblyAITranscriptionModel } from './assemblyai-transcription-model'; import { AssemblyAITranscriptionModelId } from './assemblyai-transcription-settings'; import { VERSION } from './version'; -export interface AssemblyAIProvider extends ProviderV2 { +export interface AssemblyAIProvider extends ProviderV3 { ( modelId: 'best', settings?: {}, diff --git a/packages/azure/src/azure-openai-provider.ts b/packages/azure/src/azure-openai-provider.ts index 060f213ac7db..76c5edb9fcf4 100644 --- a/packages/azure/src/azure-openai-provider.ts +++ b/packages/azure/src/azure-openai-provider.ts @@ -10,7 +10,7 @@ import { import { EmbeddingModelV3, LanguageModelV2, - ProviderV2, + ProviderV3, ImageModelV2, SpeechModelV2, TranscriptionModelV2, @@ -23,7 +23,7 @@ import { } from '@ai-sdk/provider-utils'; import { VERSION } from './version'; -export interface AzureOpenAIProvider extends ProviderV2 { +export interface AzureOpenAIProvider extends ProviderV3 { (deploymentId: string): LanguageModelV2; /** diff --git a/packages/baseten/src/baseten-provider.ts b/packages/baseten/src/baseten-provider.ts index 45feb9ec8d24..6e9b34f8ba1a 100644 --- a/packages/baseten/src/baseten-provider.ts +++ b/packages/baseten/src/baseten-provider.ts @@ -7,7 +7,7 @@ import { EmbeddingModelV3, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -61,7 +61,7 @@ export interface BasetenProviderSettings { fetch?: FetchFunction; } -export interface BasetenProvider extends ProviderV2 { +export interface BasetenProvider extends ProviderV3 { /** Creates a chat model for text generation. */ diff --git a/packages/cerebras/src/cerebras-provider.ts b/packages/cerebras/src/cerebras-provider.ts index 74332ce9e427..8bd906ba2c8f 100644 --- a/packages/cerebras/src/cerebras-provider.ts +++ b/packages/cerebras/src/cerebras-provider.ts @@ -2,7 +2,7 @@ import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible'; import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -50,7 +50,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface CerebrasProvider extends ProviderV2 { +export interface CerebrasProvider extends ProviderV3 { /** Creates a Cerebras model for text generation. */ diff --git a/packages/cohere/src/cohere-provider.ts b/packages/cohere/src/cohere-provider.ts index 6c80a654971d..4dd541475b68 100644 --- a/packages/cohere/src/cohere-provider.ts +++ b/packages/cohere/src/cohere-provider.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV3, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -17,7 +17,7 @@ import { CohereEmbeddingModel } from './cohere-embedding-model'; import { CohereEmbeddingModelId } from './cohere-embedding-options'; import { VERSION } from './version'; -export interface CohereProvider extends ProviderV2 { +export interface CohereProvider extends ProviderV3 { (modelId: CohereChatModelId): LanguageModelV2; /** diff --git a/packages/deepgram/src/deepgram-provider.ts b/packages/deepgram/src/deepgram-provider.ts index 4227ce33bed0..499261068069 100644 --- a/packages/deepgram/src/deepgram-provider.ts +++ b/packages/deepgram/src/deepgram-provider.ts @@ -1,6 +1,6 @@ import { TranscriptionModelV2, - ProviderV2, + ProviderV3, NoSuchModelError, } from '@ai-sdk/provider'; import { @@ -12,7 +12,7 @@ import { DeepgramTranscriptionModel } from './deepgram-transcription-model'; import { DeepgramTranscriptionModelId } from './deepgram-transcription-options'; import { VERSION } from './version'; -export interface DeepgramProvider extends ProviderV2 { +export interface DeepgramProvider extends ProviderV3 { ( modelId: 'nova-3', settings?: {}, @@ -80,7 +80,7 @@ export function createDeepgram( provider.transcription = createTranscriptionModel; provider.transcriptionModel = createTranscriptionModel; - // Required ProviderV2 methods that are not supported + // Required ProviderV3 methods that are not supported provider.languageModel = () => { throw new NoSuchModelError({ modelId: 'unknown', diff --git a/packages/deepinfra/src/deepinfra-provider.ts b/packages/deepinfra/src/deepinfra-provider.ts index 8f2bef69476c..bdc59d3ff24a 100644 --- a/packages/deepinfra/src/deepinfra-provider.ts +++ b/packages/deepinfra/src/deepinfra-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, EmbeddingModelV3, - ProviderV2, + ProviderV3, ImageModelV2, } from '@ai-sdk/provider'; import { @@ -42,7 +42,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface DeepInfraProvider extends ProviderV2 { +export interface DeepInfraProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/deepseek/src/deepseek-provider.ts b/packages/deepseek/src/deepseek-provider.ts index e30a4f59c676..7b613063d1be 100644 --- a/packages/deepseek/src/deepseek-provider.ts +++ b/packages/deepseek/src/deepseek-provider.ts @@ -2,7 +2,7 @@ import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible'; import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -34,7 +34,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface DeepSeekProvider extends ProviderV2 { +export interface DeepSeekProvider extends ProviderV3 { /** Creates a DeepSeek model for text generation. */ diff --git a/packages/elevenlabs/src/elevenlabs-provider.ts b/packages/elevenlabs/src/elevenlabs-provider.ts index ab96eea5f29d..ce42395a4e24 100644 --- a/packages/elevenlabs/src/elevenlabs-provider.ts +++ b/packages/elevenlabs/src/elevenlabs-provider.ts @@ -1,7 +1,7 @@ import { TranscriptionModelV2, SpeechModelV2, - ProviderV2, + ProviderV3, NoSuchModelError, } from '@ai-sdk/provider'; import { @@ -15,7 +15,7 @@ import { ElevenLabsSpeechModel } from './elevenlabs-speech-model'; import { ElevenLabsSpeechModelId } from './elevenlabs-speech-options'; import { VERSION } from './version'; -export interface ElevenLabsProvider extends ProviderV2 { +export interface ElevenLabsProvider extends ProviderV3 { ( modelId: 'scribe_v1', settings?: {}, diff --git a/packages/fal/src/fal-provider.ts b/packages/fal/src/fal-provider.ts index 6e60ba830ee9..5037b13063ac 100644 --- a/packages/fal/src/fal-provider.ts +++ b/packages/fal/src/fal-provider.ts @@ -1,7 +1,7 @@ import { ImageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; @@ -43,7 +43,7 @@ requests, or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface FalProvider extends ProviderV2 { +export interface FalProvider extends ProviderV3 { /** Creates a model for image generation. */ diff --git a/packages/fireworks/src/fireworks-provider.ts b/packages/fireworks/src/fireworks-provider.ts index be1126fa2790..d5e44b8d6d76 100644 --- a/packages/fireworks/src/fireworks-provider.ts +++ b/packages/fireworks/src/fireworks-provider.ts @@ -8,7 +8,7 @@ import { EmbeddingModelV3, ImageModelV2, LanguageModelV2, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -56,7 +56,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface FireworksProvider extends ProviderV2 { +export interface FireworksProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/gateway/src/gateway-provider.ts b/packages/gateway/src/gateway-provider.ts index cd42a58bf24a..9abbe4376914 100644 --- a/packages/gateway/src/gateway-provider.ts +++ b/packages/gateway/src/gateway-provider.ts @@ -22,12 +22,12 @@ import type { GatewayModelId } from './gateway-language-model-settings'; import type { LanguageModelV2, EmbeddingModelV3, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { VERSION } from './version'; -export interface GatewayProvider extends ProviderV2 { +export interface GatewayProvider extends ProviderV3 { (modelId: GatewayModelId): LanguageModelV2; /** diff --git a/packages/gladia/src/gladia-provider.ts b/packages/gladia/src/gladia-provider.ts index 8425781bbad7..471ff4b4c2f2 100644 --- a/packages/gladia/src/gladia-provider.ts +++ b/packages/gladia/src/gladia-provider.ts @@ -1,6 +1,6 @@ import { TranscriptionModelV2, - ProviderV2, + ProviderV3, NoSuchModelError, } from '@ai-sdk/provider'; import { @@ -11,7 +11,7 @@ import { import { GladiaTranscriptionModel } from './gladia-transcription-model'; import { VERSION } from './version'; -export interface GladiaProvider extends ProviderV2 { +export interface GladiaProvider extends ProviderV3 { (): { transcription: GladiaTranscriptionModel; }; @@ -76,7 +76,7 @@ export function createGladia( provider.transcription = createTranscriptionModel; provider.transcriptionModel = createTranscriptionModel; - // Required ProviderV2 methods that are not supported + // Required ProviderV3 methods that are not supported provider.languageModel = () => { throw new NoSuchModelError({ modelId: 'unknown', 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 6ce30e818edb..4749d80d36c6 100644 --- a/packages/google-vertex/src/anthropic/google-vertex-anthropic-provider.ts +++ b/packages/google-vertex/src/anthropic/google-vertex-anthropic-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -14,7 +14,7 @@ import { AnthropicMessagesLanguageModel, } from '@ai-sdk/anthropic/internal'; import { GoogleVertexAnthropicMessagesModelId } from './google-vertex-anthropic-messages-options'; -export interface GoogleVertexAnthropicProvider extends ProviderV2 { +export interface GoogleVertexAnthropicProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/google-vertex/src/google-vertex-provider.ts b/packages/google-vertex/src/google-vertex-provider.ts index 6a20fde5b2a6..5d44bfa72891 100644 --- a/packages/google-vertex/src/google-vertex-provider.ts +++ b/packages/google-vertex/src/google-vertex-provider.ts @@ -1,5 +1,5 @@ import { GoogleGenerativeAILanguageModel } from '@ai-sdk/google/internal'; -import { ImageModelV2, LanguageModelV2, ProviderV2 } from '@ai-sdk/provider'; +import { ImageModelV2, LanguageModelV2, ProviderV3 } from '@ai-sdk/provider'; import { FetchFunction, generateId, @@ -18,7 +18,7 @@ import { GoogleVertexImageModelId } from './google-vertex-image-settings'; import { GoogleVertexModelId } from './google-vertex-options'; import { googleVertexTools } from './google-vertex-tools'; -export interface GoogleVertexProvider extends ProviderV2 { +export interface GoogleVertexProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/google/src/google-provider.ts b/packages/google/src/google-provider.ts index aad70d7d147f..5d74f3347c46 100644 --- a/packages/google/src/google-provider.ts +++ b/packages/google/src/google-provider.ts @@ -1,7 +1,7 @@ import { EmbeddingModelV3, LanguageModelV2, - ProviderV2, + ProviderV3, ImageModelV2, } from '@ai-sdk/provider'; import { @@ -24,7 +24,7 @@ import { } from './google-generative-ai-image-settings'; import { GoogleGenerativeAIImageModel } from './google-generative-ai-image-model'; -export interface GoogleGenerativeAIProvider extends ProviderV2 { +export interface GoogleGenerativeAIProvider extends ProviderV3 { (modelId: GoogleGenerativeAIModelId): LanguageModelV2; languageModel(modelId: GoogleGenerativeAIModelId): LanguageModelV2; diff --git a/packages/groq/src/groq-provider.ts b/packages/groq/src/groq-provider.ts index 837a6a1e7717..7deadbd9b2a7 100644 --- a/packages/groq/src/groq-provider.ts +++ b/packages/groq/src/groq-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, TranscriptionModelV2, } from '@ai-sdk/provider'; import { @@ -17,7 +17,7 @@ import { GroqTranscriptionModel } from './groq-transcription-model'; import { groqTools } from './groq-tools'; import { VERSION } from './version'; -export interface GroqProvider extends ProviderV2 { +export interface GroqProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/hume/src/hume-provider.ts b/packages/hume/src/hume-provider.ts index f9b8f01fe643..a776494a22ca 100644 --- a/packages/hume/src/hume-provider.ts +++ b/packages/hume/src/hume-provider.ts @@ -1,4 +1,4 @@ -import { SpeechModelV2, ProviderV2 } from '@ai-sdk/provider'; +import { SpeechModelV2, ProviderV3 } from '@ai-sdk/provider'; import { FetchFunction, loadApiKey, @@ -7,7 +7,7 @@ import { import { HumeSpeechModel } from './hume-speech-model'; import { VERSION } from './version'; -export interface HumeProvider extends Pick { +export interface HumeProvider extends Pick { (settings?: {}): { speech: HumeSpeechModel; }; diff --git a/packages/lmnt/src/lmnt-provider.ts b/packages/lmnt/src/lmnt-provider.ts index 1196d2a4cd26..63fe556475f3 100644 --- a/packages/lmnt/src/lmnt-provider.ts +++ b/packages/lmnt/src/lmnt-provider.ts @@ -1,4 +1,4 @@ -import { SpeechModelV2, ProviderV2 } from '@ai-sdk/provider'; +import { SpeechModelV2, ProviderV3 } from '@ai-sdk/provider'; import { FetchFunction, loadApiKey, @@ -8,7 +8,7 @@ import { LMNTSpeechModel } from './lmnt-speech-model'; import { LMNTSpeechModelId } from './lmnt-speech-options'; import { VERSION } from './version'; -export interface LMNTProvider extends Pick { +export interface LMNTProvider extends Pick { ( modelId: 'aurora', settings?: {}, diff --git a/packages/luma/src/luma-provider.ts b/packages/luma/src/luma-provider.ts index ab1340b67494..4cb39a1bed1b 100644 --- a/packages/luma/src/luma-provider.ts +++ b/packages/luma/src/luma-provider.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, NoSuchModelError, ProviderV2 } from '@ai-sdk/provider'; +import { ImageModelV2, NoSuchModelError, ProviderV3 } from '@ai-sdk/provider'; import { FetchFunction, loadApiKey, @@ -30,7 +30,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface LumaProvider extends ProviderV2 { +export interface LumaProvider extends ProviderV3 { /** Creates a model for image generation. */ diff --git a/packages/mistral/src/mistral-provider.ts b/packages/mistral/src/mistral-provider.ts index 5bd96397d903..73a9008e4ca3 100644 --- a/packages/mistral/src/mistral-provider.ts +++ b/packages/mistral/src/mistral-provider.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV3, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -16,7 +16,7 @@ import { MistralEmbeddingModel } from './mistral-embedding-model'; import { MistralEmbeddingModelId } from './mistral-embedding-options'; import { VERSION } from './version'; -export interface MistralProvider extends ProviderV2 { +export interface MistralProvider extends ProviderV3 { (modelId: MistralChatModelId): LanguageModelV2; /** diff --git a/packages/openai-compatible/src/openai-compatible-provider.ts b/packages/openai-compatible/src/openai-compatible-provider.ts index 0632e7fc5fc9..1bd051678ddd 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV3, ImageModelV2, LanguageModelV2, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -24,7 +24,7 @@ export interface OpenAICompatibleProvider< COMPLETION_MODEL_IDS extends string = string, EMBEDDING_MODEL_IDS extends string = string, IMAGE_MODEL_IDS extends string = string, -> extends Omit { +> extends Omit { (modelId: CHAT_MODEL_IDS): LanguageModelV2; languageModel( diff --git a/packages/openai/src/openai-provider.ts b/packages/openai/src/openai-provider.ts index de044d4ff82d..5ec14e5d7808 100644 --- a/packages/openai/src/openai-provider.ts +++ b/packages/openai/src/openai-provider.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV3, ImageModelV2, LanguageModelV2, - ProviderV2, + ProviderV3, SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; @@ -29,7 +29,7 @@ import { OpenAITranscriptionModel } from './transcription/openai-transcription-m import { OpenAITranscriptionModelId } from './transcription/openai-transcription-options'; import { VERSION } from './version'; -export interface OpenAIProvider extends ProviderV2 { +export interface OpenAIProvider extends ProviderV3 { (modelId: OpenAIResponsesModelId): LanguageModelV2; /** diff --git a/packages/perplexity/src/perplexity-provider.ts b/packages/perplexity/src/perplexity-provider.ts index 9be529049e5d..19ad117bb611 100644 --- a/packages/perplexity/src/perplexity-provider.ts +++ b/packages/perplexity/src/perplexity-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -14,7 +14,7 @@ import { PerplexityLanguageModel } from './perplexity-language-model'; import { PerplexityLanguageModelId } from './perplexity-language-model-options'; import { VERSION } from './version'; -export interface PerplexityProvider extends ProviderV2 { +export interface PerplexityProvider extends ProviderV3 { /** Creates an Perplexity chat model for text generation. */ diff --git a/packages/provider/src/provider/index.ts b/packages/provider/src/provider/index.ts index 5640476d8b82..f0a4a20cc05d 100644 --- a/packages/provider/src/provider/index.ts +++ b/packages/provider/src/provider/index.ts @@ -1 +1,2 @@ +export * from './v3/index'; export * from './v2/index'; diff --git a/packages/provider/src/provider/v2/provider-v2.ts b/packages/provider/src/provider/v2/provider-v2.ts index 5163efd3fca1..3f21d37cea12 100644 --- a/packages/provider/src/provider/v2/provider-v2.ts +++ b/packages/provider/src/provider/v2/provider-v2.ts @@ -1,4 +1,4 @@ -import { EmbeddingModelV3 } from '../../embedding-model/v3/embedding-model-v3'; +import { EmbeddingModelV2 } from '../../embedding-model/v2/embedding-model-v2'; import { ImageModelV2 } from '../../image-model/v2/image-model-v2'; import { LanguageModelV2 } from '../../language-model/v2/language-model-v2'; import { SpeechModelV2 } from '../../speech-model/v2/speech-model-v2'; @@ -30,7 +30,7 @@ The model id is then passed to the provider function to get the model. @throws {NoSuchModelError} If no such model exists. */ - textEmbeddingModel(modelId: string): EmbeddingModelV3; + textEmbeddingModel(modelId: string): EmbeddingModelV2; /** Returns the image model with the given id. diff --git a/packages/provider/src/provider/v3/index.ts b/packages/provider/src/provider/v3/index.ts new file mode 100644 index 000000000000..23561cb544d7 --- /dev/null +++ b/packages/provider/src/provider/v3/index.ts @@ -0,0 +1 @@ +export type { ProviderV3 } from './provider-v3'; diff --git a/packages/provider/src/provider/v3/provider-v3.ts b/packages/provider/src/provider/v3/provider-v3.ts new file mode 100644 index 000000000000..b6060d512794 --- /dev/null +++ b/packages/provider/src/provider/v3/provider-v3.ts @@ -0,0 +1,64 @@ +import { EmbeddingModelV3 } from '../../embedding-model/v3/embedding-model-v3'; +import { ImageModelV2 } from '../../image-model/v2/image-model-v2'; +import { LanguageModelV2 } from '../../language-model/v2/language-model-v2'; +import { SpeechModelV2 } from '../../speech-model/v2/speech-model-v2'; +import { TranscriptionModelV2 } from '../../transcription-model/v2/transcription-model-v2'; + +/** + * Provider for language, text embedding, and image generation models. + */ +export interface ProviderV3 { + /** +Returns the language 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 {LanguageModel} The language model associated with the id + +@throws {NoSuchModelError} If no such model exists. + */ + languageModel(modelId: string): LanguageModelV2; + + /** +Returns the text embedding 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 {LanguageModel} The language model associated with the id + +@throws {NoSuchModelError} If no such model exists. + */ + textEmbeddingModel(modelId: string): EmbeddingModelV3; + + /** +Returns the image 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 {ImageModel} The image model associated with the id +*/ + imageModel(modelId: string): ImageModelV2; + + /** +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 + */ + transcriptionModel?(modelId: string): TranscriptionModelV2; + + /** +Returns the speech 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 {SpeechModel} The speech model associated with the id + */ + speechModel?(modelId: string): SpeechModelV2; +} diff --git a/packages/replicate/src/replicate-provider.ts b/packages/replicate/src/replicate-provider.ts index 1b4b2e4faafa..b6a42ec56cec 100644 --- a/packages/replicate/src/replicate-provider.ts +++ b/packages/replicate/src/replicate-provider.ts @@ -1,4 +1,4 @@ -import { NoSuchModelError, ProviderV2 } from '@ai-sdk/provider'; +import { NoSuchModelError, ProviderV3 } from '@ai-sdk/provider'; import type { FetchFunction } from '@ai-sdk/provider-utils'; import { loadApiKey, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { ReplicateImageModel } from './replicate-image-model'; @@ -30,7 +30,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface ReplicateProvider extends ProviderV2 { +export interface ReplicateProvider extends ProviderV3 { /** * Creates a Replicate image generation model. */ diff --git a/packages/revai/src/revai-provider.ts b/packages/revai/src/revai-provider.ts index f3bba0a4fbfb..8065e8c8c5ef 100644 --- a/packages/revai/src/revai-provider.ts +++ b/packages/revai/src/revai-provider.ts @@ -1,6 +1,6 @@ import { TranscriptionModelV2, - ProviderV2, + ProviderV3, NoSuchModelError, } from '@ai-sdk/provider'; import { @@ -12,7 +12,7 @@ import { RevaiTranscriptionModel } from './revai-transcription-model'; import { RevaiTranscriptionModelId } from './revai-transcription-options'; import { VERSION } from './version'; -export interface RevaiProvider extends ProviderV2 { +export interface RevaiProvider extends ProviderV3 { ( modelId: 'machine', settings?: {}, diff --git a/packages/togetherai/src/togetherai-provider.ts b/packages/togetherai/src/togetherai-provider.ts index b3a3618a4661..1150dd0b595d 100644 --- a/packages/togetherai/src/togetherai-provider.ts +++ b/packages/togetherai/src/togetherai-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, EmbeddingModelV3, - ProviderV2, + ProviderV3, ImageModelV2, } from '@ai-sdk/provider'; import { @@ -42,7 +42,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface TogetherAIProvider extends ProviderV2 { +export interface TogetherAIProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/vercel/src/vercel-provider.ts b/packages/vercel/src/vercel-provider.ts index 5d60268e1ce2..625c256977cd 100644 --- a/packages/vercel/src/vercel-provider.ts +++ b/packages/vercel/src/vercel-provider.ts @@ -1,7 +1,7 @@ import { LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible'; import { @@ -33,7 +33,7 @@ or to provide a custom fetch implementation for e.g. testing. fetch?: FetchFunction; } -export interface VercelProvider extends ProviderV2 { +export interface VercelProvider extends ProviderV3 { /** Creates a model for text generation. */ diff --git a/packages/xai/src/xai-provider.ts b/packages/xai/src/xai-provider.ts index 28f329049b7d..46e2689a9f03 100644 --- a/packages/xai/src/xai-provider.ts +++ b/packages/xai/src/xai-provider.ts @@ -6,7 +6,7 @@ import { ImageModelV2, LanguageModelV2, NoSuchModelError, - ProviderV2, + ProviderV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -26,7 +26,7 @@ const xaiErrorStructure: ProviderErrorStructure = { errorToMessage: data => data.error.message, }; -export interface XaiProvider extends ProviderV2 { +export interface XaiProvider extends ProviderV3 { /** Creates an Xai chat model for text generation. */ From 522f6b8feaa16117a90b644244e7fb28e0d97db2 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:08:26 -0700 Subject: [PATCH 119/121] feat(spec): `ImageModelV3` (#8777) ## Background https://github.com/vercel/ai/issues/8763 ## Summary Replace `ImageModelV2` with `ImageModelV3` ## Manual Verification ## Checklist - [x] Tests have been added / updated (for bug fixes / features) - [x] Documentation has been added / updated (for bug fixes / features) - [x] A _patch_ changeset for relevant packages has been added (for bug fixes / features - run `pnpm changeset` in the project root) - [x] Formatting issues have been fixed (run `pnpm prettier-fix` in the project root) - [x] I have reviewed this pull request (self-review) ## Related Issues Closes #8765 Towards #8763 --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- .changeset/thin-shoes-fold.md | 19 ++++ .../01-ai-sdk-core/10-generate-image.mdx | 2 +- .../01-ai-sdk-core/42-custom-provider.mdx | 2 +- .../01-custom-providers.mdx | 2 +- .../01-custom-providers.mdx | 4 +- .../ai-core/src/e2e/feature-test-suite.ts | 10 +- .../ai-core/src/e2e/google-vertex.test.ts | 12 +- examples/ai-core/src/e2e/google.test.ts | 4 +- packages/ai/src/embed/embed-many.test.ts | 2 +- packages/ai/src/embed/embed.test.ts | 2 +- .../src/generate-image/generate-image.test.ts | 50 ++++----- .../ai/src/generate-image/generate-image.ts | 14 +-- packages/ai/src/logger/log-warnings.test.ts | 14 +-- packages/ai/src/logger/log-warnings.ts | 4 +- packages/ai/src/model/resolve-model.test.ts | 2 +- .../ai/src/registry/custom-provider.test.ts | 6 +- packages/ai/src/registry/custom-provider.ts | 8 +- .../ai/src/registry/provider-registry.test.ts | 8 +- packages/ai/src/registry/provider-registry.ts | 8 +- ...model-v2.ts => mock-embedding-model-v3.ts} | 0 packages/ai/src/test/mock-image-model-v2.ts | 28 ----- packages/ai/src/test/mock-image-model-v3.ts | 28 +++++ packages/ai/src/test/mock-provider-v3.ts | 4 +- packages/ai/src/types/image-model.ts | 12 +- packages/ai/test/index.ts | 4 +- .../amazon-bedrock/src/bedrock-image-model.ts | 12 +- .../amazon-bedrock/src/bedrock-provider.ts | 6 +- packages/azure/src/azure-openai-provider.ts | 6 +- .../src/deepinfra-image-model.test.ts | 2 +- .../deepinfra/src/deepinfra-image-model.ts | 12 +- packages/deepinfra/src/deepinfra-provider.ts | 6 +- packages/fal/src/fal-image-model.test.ts | 2 +- packages/fal/src/fal-image-model.ts | 14 +-- packages/fal/src/fal-provider.ts | 6 +- .../src/fireworks-image-model.test.ts | 2 +- .../fireworks/src/fireworks-image-model.ts | 12 +- packages/fireworks/src/fireworks-provider.ts | 6 +- .../src/google-vertex-image-model.ts | 12 +- .../src/google-vertex-provider.ts | 6 +- .../src/google-generative-ai-image-model.ts | 12 +- packages/google/src/google-provider.ts | 4 +- packages/luma/src/luma-image-model.test.ts | 2 +- packages/luma/src/luma-image-model.ts | 14 +-- packages/luma/src/luma-provider.ts | 6 +- .../openai-compatible-image-model.test.ts | 6 +- .../image/openai-compatible-image-model.ts | 12 +- .../src/openai-compatible-provider.ts | 4 +- .../openai/src/image/openai-image-model.ts | 12 +- packages/openai/src/openai-provider.ts | 6 +- packages/provider/src/image-model/index.ts | 1 + .../v3/image-model-v3-call-options.ts | 60 ++++++++++ .../v3/image-model-v3-call-warning.ts | 16 +++ .../src/image-model/v3/image-model-v3.ts | 104 ++++++++++++++++++ packages/provider/src/image-model/v3/index.ts | 6 + .../provider/src/provider/v3/provider-v3.ts | 4 +- .../replicate/src/replicate-image-model.ts | 12 +- .../src/togetherai-image-model.test.ts | 2 +- .../togetherai/src/togetherai-image-model.ts | 12 +- .../togetherai/src/togetherai-provider.ts | 6 +- packages/xai/src/xai-provider.ts | 6 +- 60 files changed, 433 insertions(+), 227 deletions(-) create mode 100644 .changeset/thin-shoes-fold.md rename packages/ai/src/test/{mock-embedding-model-v2.ts => mock-embedding-model-v3.ts} (100%) delete mode 100644 packages/ai/src/test/mock-image-model-v2.ts create mode 100644 packages/ai/src/test/mock-image-model-v3.ts create mode 100644 packages/provider/src/image-model/v3/image-model-v3-call-options.ts create mode 100644 packages/provider/src/image-model/v3/image-model-v3-call-warning.ts create mode 100644 packages/provider/src/image-model/v3/image-model-v3.ts create mode 100644 packages/provider/src/image-model/v3/index.ts diff --git a/.changeset/thin-shoes-fold.md b/.changeset/thin-shoes-fold.md new file mode 100644 index 000000000000..da420db0f70b --- /dev/null +++ b/.changeset/thin-shoes-fold.md @@ -0,0 +1,19 @@ +--- +'@ai-sdk/openai-compatible': patch +'@ai-sdk/amazon-bedrock': patch +'@ai-sdk/google-vertex': patch +'@ai-sdk/togetherai': patch +'@ai-sdk/deepinfra': patch +'@ai-sdk/fireworks': patch +'@ai-sdk/replicate': patch +'@ai-sdk/provider': patch +'@ai-sdk/google': patch +'@ai-sdk/openai': patch +'@ai-sdk/azure': patch +'@ai-sdk/luma': patch +'@ai-sdk/fal': patch +'@ai-sdk/xai': patch +'ai': patch +--- + +feat: `ImageModelV3` diff --git a/content/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx b/content/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx index 289313607a02..fb0b9bf104d1 100644 --- a/content/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx @@ -40,7 +40,7 @@ console.log(images); content={[ { name: 'model', - type: 'ImageModelV2', + type: 'ImageModelV3', description: 'The image model to use.', }, { diff --git a/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx b/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx index abaca7e1ab7c..03ceb44f89bb 100644 --- a/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx @@ -81,7 +81,7 @@ export const myOpenAI = customProvider({ type: 'Record', isOptional: true, description: - 'A record of image models, where keys are model IDs and values are ImageModelV2 instances.', + 'A record of image models, where keys are model IDs and values are image model instances.', }, { name: 'fallbackProvider', diff --git a/content/providers/02-openai-compatible-providers/01-custom-providers.mdx b/content/providers/02-openai-compatible-providers/01-custom-providers.mdx index 456f5d498243..ef45c769704b 100644 --- a/content/providers/02-openai-compatible-providers/01-custom-providers.mdx +++ b/content/providers/02-openai-compatible-providers/01-custom-providers.mdx @@ -118,7 +118,7 @@ Creates an image model for image generation. imageModel( modelId: ExampleImageModelId, settings?: ExampleImageSettings, - ): ImageModelV2; + ): ImageModelV3; } export function createExample( diff --git a/content/providers/03-community-providers/01-custom-providers.mdx b/content/providers/03-community-providers/01-custom-providers.mdx index b96cf4cd2770..b17649a78739 100644 --- a/content/providers/03-community-providers/01-custom-providers.mdx +++ b/content/providers/03-community-providers/01-custom-providers.mdx @@ -31,7 +31,7 @@ At its heart, the V2 specification defines three main interfaces: 1. **ProviderV3**: The top-level interface that serves as a factory for different model types 2. **LanguageModelV2**: The primary interface for text generation models -3. **EmbeddingModelV3** and **ImageModelV2**: Interfaces for embeddings and image generation +3. **EmbeddingModelV3** and **ImageModelV3**: Interfaces for embeddings and image generation ### `ProviderV3` @@ -41,7 +41,7 @@ The `ProviderV3` interface acts as the entry point: interface ProviderV3 { languageModel(modelId: string): LanguageModelV2; textEmbeddingModel(modelId: string): EmbeddingModelV3; - imageModel(modelId: string): ImageModelV2; + imageModel(modelId: string): ImageModelV3; } ``` diff --git a/examples/ai-core/src/e2e/feature-test-suite.ts b/examples/ai-core/src/e2e/feature-test-suite.ts index 4d9def868bcd..def2cbc67e30 100644 --- a/examples/ai-core/src/e2e/feature-test-suite.ts +++ b/examples/ai-core/src/e2e/feature-test-suite.ts @@ -1,7 +1,7 @@ import type { GoogleGenerativeAIProviderMetadata } from '@ai-sdk/google'; import type { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, } from '@ai-sdk/provider'; import { @@ -66,9 +66,9 @@ export const createEmbeddingModelWithCapabilities = ( }); export const createImageModelWithCapabilities = ( - model: ImageModelV2, + model: ImageModelV3, capabilities: ModelCapabilities = ['imageGeneration'], -): ModelWithCapabilities => ({ +): ModelWithCapabilities => ({ model, capabilities, }); @@ -77,8 +77,8 @@ export interface ModelVariants { invalidModel?: LanguageModelV2; languageModels?: ModelWithCapabilities[]; embeddingModels?: ModelWithCapabilities>[]; - invalidImageModel?: ImageModelV2; - imageModels?: ModelWithCapabilities[]; + invalidImageModel?: ImageModelV3; + imageModels?: ModelWithCapabilities[]; } export interface TestSuiteOptions { diff --git a/examples/ai-core/src/e2e/google-vertex.test.ts b/examples/ai-core/src/e2e/google-vertex.test.ts index 3f79e0d2eafb..b7c5ac7886b1 100644 --- a/examples/ai-core/src/e2e/google-vertex.test.ts +++ b/examples/ai-core/src/e2e/google-vertex.test.ts @@ -1,6 +1,6 @@ import { vertex as vertexNode } from '@ai-sdk/google-vertex'; import { vertex as vertexEdge } from '@ai-sdk/google-vertex/edge'; -import { ImageModelV2, LanguageModelV2 } from '@ai-sdk/provider'; +import { ImageModelV3, LanguageModelV2 } from '@ai-sdk/provider'; import { APICallError, experimental_generateImage as generateImage } from 'ai'; import 'dotenv/config'; import { describe, expect, it, vi } from 'vitest'; @@ -55,8 +55,8 @@ const createSearchGroundedModel = ( }); const createModelObject = ( - imageModel: ImageModelV2, -): { model: ImageModelV2; modelId: string } => ({ + imageModel: ImageModelV3, +): { model: ImageModelV3; modelId: string } => ({ model: imageModel, modelId: imageModel.modelId, }); @@ -64,8 +64,8 @@ const createModelObject = ( const createImageModel = ( vertex: typeof vertexNode | typeof vertexEdge, modelId: string, - additionalTests: ((model: ImageModelV2) => void)[] = [], -): ModelWithCapabilities => { + additionalTests: ((model: ImageModelV3) => void)[] = [], +): ModelWithCapabilities => { const model = vertex.image(modelId); if (additionalTests.length > 0) { @@ -151,7 +151,7 @@ function detectImageMediaType( return undefined; } -const imageTest = (model: ImageModelV2) => { +const imageTest = (model: ImageModelV3) => { vi.setConfig({ testTimeout: 10000 }); it('should generate an image with correct dimensions and format', async () => { diff --git a/examples/ai-core/src/e2e/google.test.ts b/examples/ai-core/src/e2e/google.test.ts index 3427e6db4016..6818c16713ba 100644 --- a/examples/ai-core/src/e2e/google.test.ts +++ b/examples/ai-core/src/e2e/google.test.ts @@ -1,5 +1,5 @@ import { GoogleErrorData, google as provider } from '@ai-sdk/google'; -import { APICallError, ImageModelV2, LanguageModelV2 } from '@ai-sdk/provider'; +import { APICallError, ImageModelV3, LanguageModelV2 } from '@ai-sdk/provider'; import 'dotenv/config'; import { expect } from 'vitest'; import { @@ -20,7 +20,7 @@ const createChatModel = ( const createImageModel = ( modelId: string, -): ModelWithCapabilities => +): ModelWithCapabilities => createImageModelWithCapabilities(provider.image(modelId)); const createSearchGroundedModel = ( diff --git a/packages/ai/src/embed/embed-many.test.ts b/packages/ai/src/embed/embed-many.test.ts index 599ed905e795..05227a2f90c6 100644 --- a/packages/ai/src/embed/embed-many.test.ts +++ b/packages/ai/src/embed/embed-many.test.ts @@ -1,7 +1,7 @@ import { EmbeddingModelV3 } from '@ai-sdk/provider'; import assert from 'node:assert'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v3'; import { MockTracer } from '../test/mock-tracer'; import { Embedding, EmbeddingModelUsage } from '../types'; import { createResolvablePromise } from '../util/create-resolvable-promise'; diff --git a/packages/ai/src/embed/embed.test.ts b/packages/ai/src/embed/embed.test.ts index b70a141be332..b6a3776bae3f 100644 --- a/packages/ai/src/embed/embed.test.ts +++ b/packages/ai/src/embed/embed.test.ts @@ -1,7 +1,7 @@ import { EmbeddingModelV3 } from '@ai-sdk/provider'; import assert from 'node:assert'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v3'; import { MockTracer } from '../test/mock-tracer'; import { Embedding, EmbeddingModelUsage } from '../types'; import { embed } from './embed'; diff --git a/packages/ai/src/generate-image/generate-image.test.ts b/packages/ai/src/generate-image/generate-image.test.ts index c5f99b082f5d..3972b5bae25b 100644 --- a/packages/ai/src/generate-image/generate-image.test.ts +++ b/packages/ai/src/generate-image/generate-image.test.ts @@ -1,7 +1,7 @@ import { - ImageModelV2, - ImageModelV2CallWarning, - ImageModelV2ProviderMetadata, + ImageModelV3, + ImageModelV3CallWarning, + ImageModelV3ProviderMetadata, } from '@ai-sdk/provider'; import { convertBase64ToUint8Array, @@ -18,7 +18,7 @@ import { vitest, } from 'vitest'; import * as logWarningsModule from '../logger/log-warnings'; -import { MockImageModelV2 } from '../test/mock-image-model-v2'; +import { MockImageModelV3 } from '../test/mock-image-model-v3'; import { generateImage } from './generate-image'; const prompt = 'sunny day at the beach'; @@ -38,10 +38,10 @@ vi.mock('../version', () => { const createMockResponse = (options: { images: string[] | Uint8Array[]; - warnings?: ImageModelV2CallWarning[]; + warnings?: ImageModelV3CallWarning[]; timestamp?: Date; modelId?: string; - providerMetaData?: ImageModelV2ProviderMetadata; + providerMetaData?: ImageModelV3ProviderMetadata; headers?: Record; }) => ({ images: options.images, @@ -75,10 +75,10 @@ describe('generateImage', () => { const abortController = new AbortController(); const abortSignal = abortController.signal; - let capturedArgs!: Parameters[0]; + let capturedArgs!: Parameters[0]; await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async args => { capturedArgs = args; return createMockResponse({ @@ -118,7 +118,7 @@ describe('generateImage', () => { it('should return warnings', async () => { const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64], @@ -142,7 +142,7 @@ describe('generateImage', () => { }); it('should call logWarnings with the correct warnings', async () => { - const expectedWarnings: ImageModelV2CallWarning[] = [ + const expectedWarnings: ImageModelV3CallWarning[] = [ { type: 'other', message: 'Setting is not supported', @@ -155,7 +155,7 @@ describe('generateImage', () => { ]; await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64], @@ -170,11 +170,11 @@ describe('generateImage', () => { }); it('should call logWarnings with aggregated warnings from multiple calls', async () => { - const warning1: ImageModelV2CallWarning = { + const warning1: ImageModelV3CallWarning = { type: 'other', message: 'Warning from call 1', }; - const warning2: ImageModelV2CallWarning = { + const warning2: ImageModelV3CallWarning = { type: 'other', message: 'Warning from call 2', }; @@ -183,7 +183,7 @@ describe('generateImage', () => { let callCount = 0; await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ maxImagesPerCall: 1, doGenerate: async () => { switch (callCount++) { @@ -212,7 +212,7 @@ describe('generateImage', () => { it('should call logWarnings with empty array when no warnings are present', async () => { await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64], @@ -229,7 +229,7 @@ describe('generateImage', () => { describe('base64 image data', () => { it('should return generated images with correct mime types', async () => { const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64, jpegBase64], @@ -260,7 +260,7 @@ describe('generateImage', () => { it('should return the first image with correct mime type', async () => { const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64, jpegBase64], @@ -289,7 +289,7 @@ describe('generateImage', () => { ]; const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: uint8ArrayImages, @@ -323,7 +323,7 @@ describe('generateImage', () => { let callCount = 0; const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ maxImagesPerCall: 2, doGenerate: async options => { switch (callCount++) { @@ -390,7 +390,7 @@ describe('generateImage', () => { let callCount = 0; const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ maxImagesPerCall: 2, doGenerate: async options => { switch (callCount++) { @@ -464,7 +464,7 @@ describe('generateImage', () => { const maxImagesPerCallMock = vitest.fn(maxImagesPerCall); const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ maxImagesPerCall: maxImagesPerCallMock, doGenerate: async options => { switch (callCount++) { @@ -535,7 +535,7 @@ describe('generateImage', () => { it('should throw NoImageGeneratedError when no images are returned', async () => { await expect( generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [], @@ -559,7 +559,7 @@ describe('generateImage', () => { it('should include response headers in error when no images generated', async () => { await expect( generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [], @@ -593,7 +593,7 @@ describe('generateImage', () => { const testHeaders = { 'x-test': 'value' }; const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64], @@ -616,7 +616,7 @@ describe('generateImage', () => { it('should return provider metadata', async () => { const result = await generateImage({ - model: new MockImageModelV2({ + model: new MockImageModelV3({ doGenerate: async () => createMockResponse({ images: [pngBase64, pngBase64], diff --git a/packages/ai/src/generate-image/generate-image.ts b/packages/ai/src/generate-image/generate-image.ts index 262032c90039..eda33302caa2 100644 --- a/packages/ai/src/generate-image/generate-image.ts +++ b/packages/ai/src/generate-image/generate-image.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2ProviderMetadata } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3ProviderMetadata } from '@ai-sdk/provider'; import { ProviderOptions, withUserAgentSuffix } from '@ai-sdk/provider-utils'; import { NoImageGeneratedError } from '../error/no-image-generated-error'; import { @@ -50,7 +50,7 @@ export async function generateImage({ /** The image model to use. */ - model: ImageModelV2; + model: ImageModelV3; /** The prompt that should be used to generate the image. @@ -116,7 +116,7 @@ Only applicable for HTTP-based providers. */ headers?: Record; }): Promise { - if (model.specificationVersion !== 'v2') { + if (model.specificationVersion !== 'v3') { throw new UnsupportedModelVersionError({ version: model.specificationVersion, provider: model.provider, @@ -171,7 +171,7 @@ Only applicable for HTTP-based providers. const images: Array = []; const warnings: Array = []; const responses: Array = []; - const providerMetadata: ImageModelV2ProviderMetadata = {}; + const providerMetadata: ImageModelV3ProviderMetadata = {}; for (const result of results) { images.push( ...result.images.map( @@ -220,13 +220,13 @@ class DefaultGenerateImageResult implements GenerateImageResult { readonly images: Array; readonly warnings: Array; readonly responses: Array; - readonly providerMetadata: ImageModelV2ProviderMetadata; + readonly providerMetadata: ImageModelV3ProviderMetadata; constructor(options: { images: Array; warnings: Array; responses: Array; - providerMetadata: ImageModelV2ProviderMetadata; + providerMetadata: ImageModelV3ProviderMetadata; }) { this.images = options.images; this.warnings = options.warnings; @@ -239,7 +239,7 @@ class DefaultGenerateImageResult implements GenerateImageResult { } } -async function invokeModelMaxImagesPerCall(model: ImageModelV2) { +async function invokeModelMaxImagesPerCall(model: ImageModelV3) { const isFunction = model.maxImagesPerCall instanceof Function; if (!isFunction) { diff --git a/packages/ai/src/logger/log-warnings.test.ts b/packages/ai/src/logger/log-warnings.test.ts index 43873aee310c..5a748386dd36 100644 --- a/packages/ai/src/logger/log-warnings.test.ts +++ b/packages/ai/src/logger/log-warnings.test.ts @@ -7,7 +7,7 @@ import { } from './log-warnings'; import type { LanguageModelV2CallWarning, - ImageModelV2CallWarning, + ImageModelV3CallWarning, SpeechModelV2CallWarning, TranscriptionModelV2CallWarning, } from '@ai-sdk/provider'; @@ -55,7 +55,7 @@ describe('logWarnings', () => { { type: 'other', message: 'Test warning 2', - } as ImageModelV2CallWarning, + } as ImageModelV3CallWarning, ]; logWarnings(warnings); @@ -96,7 +96,7 @@ describe('logWarnings', () => { { type: 'other', message: 'Another warning', - } as ImageModelV2CallWarning, + } as ImageModelV3CallWarning, ]; logWarnings(warnings); @@ -141,7 +141,7 @@ describe('logWarnings', () => { type: 'other', message: 'First warning', }; - const warning2: ImageModelV2CallWarning = { + const warning2: ImageModelV3CallWarning = { type: 'unsupported-setting', setting: 'size', details: 'Size parameter not supported', @@ -210,8 +210,8 @@ describe('logWarnings', () => { ); }); - it('should log ImageModelV2CallWarning', () => { - const warning: ImageModelV2CallWarning = { + it('should log image model call warning', () => { + const warning: ImageModelV3CallWarning = { type: 'unsupported-setting', setting: 'size', details: 'Image size setting not supported', @@ -266,7 +266,7 @@ describe('logWarnings', () => { type: 'other', message: 'Language model warning', }; - const imageWarning: ImageModelV2CallWarning = { + const imageWarning: ImageModelV3CallWarning = { type: 'other', message: 'Image model warning', }; diff --git a/packages/ai/src/logger/log-warnings.ts b/packages/ai/src/logger/log-warnings.ts index a283cb143700..fe460aa8c70b 100644 --- a/packages/ai/src/logger/log-warnings.ts +++ b/packages/ai/src/logger/log-warnings.ts @@ -1,5 +1,5 @@ import { - ImageModelV2CallWarning, + ImageModelV3CallWarning, LanguageModelV2CallWarning, SpeechModelV2CallWarning, TranscriptionModelV2CallWarning, @@ -7,7 +7,7 @@ import { export type Warning = | LanguageModelV2CallWarning - | ImageModelV2CallWarning + | ImageModelV3CallWarning | SpeechModelV2CallWarning | TranscriptionModelV2CallWarning; diff --git a/packages/ai/src/model/resolve-model.test.ts b/packages/ai/src/model/resolve-model.test.ts index b7edb3710a4e..6f2c85539974 100644 --- a/packages/ai/src/model/resolve-model.test.ts +++ b/packages/ai/src/model/resolve-model.test.ts @@ -1,5 +1,5 @@ import { customProvider } from '../registry/custom-provider'; -import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v3'; import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { resolveEmbeddingModel, resolveLanguageModel } from './resolve-model'; import { beforeEach, afterEach, describe, expect, it } from 'vitest'; diff --git a/packages/ai/src/registry/custom-provider.test.ts b/packages/ai/src/registry/custom-provider.test.ts index 1e1edfc3a282..e3b417161e58 100644 --- a/packages/ai/src/registry/custom-provider.test.ts +++ b/packages/ai/src/registry/custom-provider.test.ts @@ -1,7 +1,7 @@ import { NoSuchModelError } from '@ai-sdk/provider'; import { describe, expect, it, vi } from 'vitest'; -import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; -import { MockImageModelV2 } from '../test/mock-image-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v3'; +import { MockImageModelV3 } from '../test/mock-image-model-v3'; import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { MockTranscriptionModelV2 } from '../test/mock-transcription-model-v2'; import { MockSpeechModelV2 } from '../test/mock-speech-model-v2'; @@ -79,7 +79,7 @@ describe('textEmbeddingModel', () => { }); describe('imageModel', () => { - const mockImageModel = new MockImageModelV2(); + const mockImageModel = new MockImageModelV3(); it('should return the image model if it exists', () => { const provider = customProvider({ diff --git a/packages/ai/src/registry/custom-provider.ts b/packages/ai/src/registry/custom-provider.ts index 8ec7844bd017..8bc5fad834a6 100644 --- a/packages/ai/src/registry/custom-provider.ts +++ b/packages/ai/src/registry/custom-provider.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, NoSuchModelError, ProviderV3, @@ -25,7 +25,7 @@ import { export function customProvider< LANGUAGE_MODELS extends Record, EMBEDDING_MODELS extends Record>, - IMAGE_MODELS extends Record, + IMAGE_MODELS extends Record, TRANSCRIPTION_MODELS extends Record, SPEECH_MODELS extends Record, >({ @@ -47,7 +47,7 @@ export function customProvider< textEmbeddingModel( modelId: ExtractModelId, ): EmbeddingModelV3; - imageModel(modelId: ExtractModelId): ImageModelV2; + imageModel(modelId: ExtractModelId): ImageModelV3; transcriptionModel( modelId: ExtractModelId, ): TranscriptionModelV2; @@ -80,7 +80,7 @@ export function customProvider< throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' }); }, - imageModel(modelId: ExtractModelId): ImageModelV2 { + imageModel(modelId: ExtractModelId): ImageModelV3 { if (imageModels != null && modelId in imageModels) { return imageModels[modelId]; } diff --git a/packages/ai/src/registry/provider-registry.test.ts b/packages/ai/src/registry/provider-registry.test.ts index 1ce82cc14b8c..6b23d5f84a7c 100644 --- a/packages/ai/src/registry/provider-registry.test.ts +++ b/packages/ai/src/registry/provider-registry.test.ts @@ -1,9 +1,9 @@ import { NoSuchModelError } from '@ai-sdk/provider'; -import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v2'; +import { MockEmbeddingModelV3 } from '../test/mock-embedding-model-v3'; import { MockLanguageModelV2 } from '../test/mock-language-model-v2'; import { NoSuchProviderError } from './no-such-provider-error'; import { createProviderRegistry } from './provider-registry'; -import { MockImageModelV2 } from '../test/mock-image-model-v2'; +import { MockImageModelV3 } from '../test/mock-image-model-v3'; import { MockTranscriptionModelV2 } from '../test/mock-transcription-model-v2'; import { MockSpeechModelV2 } from '../test/mock-speech-model-v2'; import { MockProviderV3 } from '../test/mock-provider-v3'; @@ -256,7 +256,7 @@ describe('textEmbeddingModel', () => { describe('imageModel', () => { it('should return image model from provider', () => { - const model = new MockImageModelV2(); + const model = new MockImageModelV3(); const modelRegistry = createProviderRegistry({ provider: { @@ -305,7 +305,7 @@ describe('imageModel', () => { }); it('should support custom separator', () => { - const model = new MockImageModelV2(); + const model = new MockImageModelV3(); const modelRegistry = createProviderRegistry( { diff --git a/packages/ai/src/registry/provider-registry.ts b/packages/ai/src/registry/provider-registry.ts index a0eb0de6dc34..0e4f21f0425e 100644 --- a/packages/ai/src/registry/provider-registry.ts +++ b/packages/ai/src/registry/provider-registry.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, NoSuchModelError, ProviderV3, @@ -43,10 +43,10 @@ export interface ProviderRegistryProvider< id: KEY extends string ? `${KEY & string}${SEPARATOR}${ExtractLiteralUnion>[0]>}` : never, - ): ImageModelV2; + ): ImageModelV3; imageModel( id: KEY extends string ? `${KEY & string}${SEPARATOR}${string}` : never, - ): ImageModelV2; + ): ImageModelV3; transcriptionModel( id: KEY extends string @@ -237,7 +237,7 @@ class DefaultProviderRegistry< imageModel( id: `${KEY & string}${SEPARATOR}${string}`, - ): ImageModelV2 { + ): ImageModelV3 { const [providerId, modelId] = this.splitId(id, 'imageModel'); const provider = this.getProvider(providerId, 'imageModel'); diff --git a/packages/ai/src/test/mock-embedding-model-v2.ts b/packages/ai/src/test/mock-embedding-model-v3.ts similarity index 100% rename from packages/ai/src/test/mock-embedding-model-v2.ts rename to packages/ai/src/test/mock-embedding-model-v3.ts diff --git a/packages/ai/src/test/mock-image-model-v2.ts b/packages/ai/src/test/mock-image-model-v2.ts deleted file mode 100644 index 73876b4c44ea..000000000000 --- a/packages/ai/src/test/mock-image-model-v2.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ImageModelV2 } from '@ai-sdk/provider'; -import { notImplemented } from './not-implemented'; - -export class MockImageModelV2 implements ImageModelV2 { - readonly specificationVersion = 'v2'; - readonly provider: ImageModelV2['provider']; - readonly modelId: ImageModelV2['modelId']; - readonly maxImagesPerCall: ImageModelV2['maxImagesPerCall']; - - doGenerate: ImageModelV2['doGenerate']; - - constructor({ - provider = 'mock-provider', - modelId = 'mock-model-id', - maxImagesPerCall = 1, - doGenerate = notImplemented, - }: { - provider?: ImageModelV2['provider']; - modelId?: ImageModelV2['modelId']; - maxImagesPerCall?: ImageModelV2['maxImagesPerCall']; - doGenerate?: ImageModelV2['doGenerate']; - } = {}) { - this.provider = provider; - this.modelId = modelId; - this.maxImagesPerCall = maxImagesPerCall; - this.doGenerate = doGenerate; - } -} diff --git a/packages/ai/src/test/mock-image-model-v3.ts b/packages/ai/src/test/mock-image-model-v3.ts new file mode 100644 index 000000000000..96d599abd438 --- /dev/null +++ b/packages/ai/src/test/mock-image-model-v3.ts @@ -0,0 +1,28 @@ +import { ImageModelV3 } from '@ai-sdk/provider'; +import { notImplemented } from './not-implemented'; + +export class MockImageModelV3 implements ImageModelV3 { + readonly specificationVersion = 'v3'; + readonly provider: ImageModelV3['provider']; + readonly modelId: ImageModelV3['modelId']; + readonly maxImagesPerCall: ImageModelV3['maxImagesPerCall']; + + doGenerate: ImageModelV3['doGenerate']; + + constructor({ + provider = 'mock-provider', + modelId = 'mock-model-id', + maxImagesPerCall = 1, + doGenerate = notImplemented, + }: { + provider?: ImageModelV3['provider']; + modelId?: ImageModelV3['modelId']; + maxImagesPerCall?: ImageModelV3['maxImagesPerCall']; + doGenerate?: ImageModelV3['doGenerate']; + } = {}) { + this.provider = provider; + this.modelId = modelId; + this.maxImagesPerCall = maxImagesPerCall; + this.doGenerate = doGenerate; + } +} diff --git a/packages/ai/src/test/mock-provider-v3.ts b/packages/ai/src/test/mock-provider-v3.ts index 9aa8c7a993bf..249c85265060 100644 --- a/packages/ai/src/test/mock-provider-v3.ts +++ b/packages/ai/src/test/mock-provider-v3.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, NoSuchModelError, ProviderV3, @@ -24,7 +24,7 @@ export class MockProviderV3 implements ProviderV3 { }: { languageModels?: Record; embeddingModels?: Record>; - imageModels?: Record; + imageModels?: Record; transcriptionModels?: Record; speechModels?: Record; } = {}) { diff --git a/packages/ai/src/types/image-model.ts b/packages/ai/src/types/image-model.ts index efec355395f8..e8ab40cfc376 100644 --- a/packages/ai/src/types/image-model.ts +++ b/packages/ai/src/types/image-model.ts @@ -1,21 +1,21 @@ import { - ImageModelV2, - ImageModelV2CallWarning, - ImageModelV2ProviderMetadata, + ImageModelV3, + ImageModelV3CallWarning, + ImageModelV3ProviderMetadata, } from '@ai-sdk/provider'; /** Image model that is used by the AI SDK Core functions. */ -export type ImageModel = ImageModelV2; +export type ImageModel = ImageModelV3; /** 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 ImageGenerationWarning = ImageModelV2CallWarning; +export type ImageGenerationWarning = ImageModelV3CallWarning; /** Metadata from the model provider for this call */ -export type ImageModelProviderMetadata = ImageModelV2ProviderMetadata; +export type ImageModelProviderMetadata = ImageModelV3ProviderMetadata; diff --git a/packages/ai/test/index.ts b/packages/ai/test/index.ts index a9d6a9534233..fe6aedf7bbce 100644 --- a/packages/ai/test/index.ts +++ b/packages/ai/test/index.ts @@ -4,8 +4,8 @@ export { convertReadableStreamToArray, mockId, } from '@ai-sdk/provider-utils/test'; -export { MockEmbeddingModelV3 } from '../src/test/mock-embedding-model-v2'; -export { MockImageModelV2 } from '../src/test/mock-image-model-v2'; +export { MockEmbeddingModelV3 } from '../src/test/mock-embedding-model-v3'; +export { MockImageModelV3 } from '../src/test/mock-image-model-v3'; export { MockLanguageModelV2 } from '../src/test/mock-language-model-v2'; export { MockProviderV3 } from '../src/test/mock-provider-v3'; export { MockSpeechModelV2 } from '../src/test/mock-speech-model-v2'; diff --git a/packages/amazon-bedrock/src/bedrock-image-model.ts b/packages/amazon-bedrock/src/bedrock-image-model.ts index 966580a763d1..cd5a08ba9e14 100644 --- a/packages/amazon-bedrock/src/bedrock-image-model.ts +++ b/packages/amazon-bedrock/src/bedrock-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { FetchFunction, Resolvable, @@ -24,8 +24,8 @@ type BedrockImageModelConfig = { }; }; -export class BedrockImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class BedrockImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly provider = 'amazon-bedrock'; get maxImagesPerCall(): number { @@ -51,10 +51,10 @@ export class BedrockImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; const [width, height] = size ? size.split('x').map(Number) : []; const args = { taskType: 'TEXT_IMAGE', diff --git a/packages/amazon-bedrock/src/bedrock-provider.ts b/packages/amazon-bedrock/src/bedrock-provider.ts index 570a6b3c4c6e..7fca538d04bb 100644 --- a/packages/amazon-bedrock/src/bedrock-provider.ts +++ b/packages/amazon-bedrock/src/bedrock-provider.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, ProviderV3, } from '@ai-sdk/provider'; @@ -114,12 +114,12 @@ export interface AmazonBedrockProvider extends ProviderV3 { /** Creates a model for image generation. */ - image(modelId: BedrockImageModelId): ImageModelV2; + image(modelId: BedrockImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: BedrockImageModelId): ImageModelV2; + imageModel(modelId: BedrockImageModelId): ImageModelV3; /** Anthropic-specific tools that can be used with Anthropic models on Bedrock. diff --git a/packages/azure/src/azure-openai-provider.ts b/packages/azure/src/azure-openai-provider.ts index 76c5edb9fcf4..9355ee796d7d 100644 --- a/packages/azure/src/azure-openai-provider.ts +++ b/packages/azure/src/azure-openai-provider.ts @@ -11,7 +11,7 @@ import { EmbeddingModelV3, LanguageModelV2, ProviderV3, - ImageModelV2, + ImageModelV3, SpeechModelV2, TranscriptionModelV2, } from '@ai-sdk/provider'; @@ -54,12 +54,12 @@ Creates an Azure OpenAI completion model for text generation. /** * Creates an Azure OpenAI DALL-E model for image generation. */ - image(deploymentId: string): ImageModelV2; + image(deploymentId: string): ImageModelV3; /** * Creates an Azure OpenAI DALL-E model for image generation. */ - imageModel(deploymentId: string): ImageModelV2; + imageModel(deploymentId: string): ImageModelV3; textEmbedding(deploymentId: string): EmbeddingModelV3; diff --git a/packages/deepinfra/src/deepinfra-image-model.test.ts b/packages/deepinfra/src/deepinfra-image-model.test.ts index 5b37ca287af7..81e26f9c178e 100644 --- a/packages/deepinfra/src/deepinfra-image-model.test.ts +++ b/packages/deepinfra/src/deepinfra-image-model.test.ts @@ -228,7 +228,7 @@ describe('DeepInfraImageModel', () => { expect(model.provider).toBe('deepinfra'); expect(model.modelId).toBe('stability-ai/sdxl'); - expect(model.specificationVersion).toBe('v2'); + expect(model.specificationVersion).toBe('v3'); expect(model.maxImagesPerCall).toBe(1); }); }); diff --git a/packages/deepinfra/src/deepinfra-image-model.ts b/packages/deepinfra/src/deepinfra-image-model.ts index 34790f9f218a..f339186cd610 100644 --- a/packages/deepinfra/src/deepinfra-image-model.ts +++ b/packages/deepinfra/src/deepinfra-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { FetchFunction, combineHeaders, @@ -19,8 +19,8 @@ interface DeepInfraImageModelConfig { }; } -export class DeepInfraImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class DeepInfraImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 1; get provider(): string { @@ -41,10 +41,10 @@ export class DeepInfraImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; // Some deepinfra models support size while others support aspect ratio. // Allow passing either and leave it up to the server to validate. diff --git a/packages/deepinfra/src/deepinfra-provider.ts b/packages/deepinfra/src/deepinfra-provider.ts index bdc59d3ff24a..ac64cefa06a4 100644 --- a/packages/deepinfra/src/deepinfra-provider.ts +++ b/packages/deepinfra/src/deepinfra-provider.ts @@ -2,7 +2,7 @@ import { LanguageModelV2, EmbeddingModelV3, ProviderV3, - ImageModelV2, + ImageModelV3, } from '@ai-sdk/provider'; import { OpenAICompatibleChatLanguageModel, @@ -56,12 +56,12 @@ Creates a chat model for text generation. /** Creates a model for image generation. */ - image(modelId: DeepInfraImageModelId): ImageModelV2; + image(modelId: DeepInfraImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: DeepInfraImageModelId): ImageModelV2; + imageModel(modelId: DeepInfraImageModelId): ImageModelV3; /** Creates a chat model for text generation. diff --git a/packages/fal/src/fal-image-model.test.ts b/packages/fal/src/fal-image-model.test.ts index 81062bea5cc0..67333918f2f6 100644 --- a/packages/fal/src/fal-image-model.test.ts +++ b/packages/fal/src/fal-image-model.test.ts @@ -305,7 +305,7 @@ describe('FalImageModel', () => { expect(model.provider).toBe('fal.image'); expect(model.modelId).toBe('fal-ai/qwen-image'); - expect(model.specificationVersion).toBe('v2'); + expect(model.specificationVersion).toBe('v3'); expect(model.maxImagesPerCall).toBe(1); }); }); diff --git a/packages/fal/src/fal-image-model.ts b/packages/fal/src/fal-image-model.ts index 4a6371fbbd02..fbdbad2cef23 100644 --- a/packages/fal/src/fal-image-model.ts +++ b/packages/fal/src/fal-image-model.ts @@ -1,6 +1,6 @@ import type { - ImageModelV2, - ImageModelV2CallWarning, + ImageModelV3, + ImageModelV3CallWarning, JSONObject, } from '@ai-sdk/provider'; import type { Resolvable } from '@ai-sdk/provider-utils'; @@ -28,8 +28,8 @@ interface FalImageModelConfig { }; } -export class FalImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class FalImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 1; get provider(): string { @@ -50,10 +50,10 @@ export class FalImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; let imageSize: FalImageSize | undefined; if (size) { diff --git a/packages/fal/src/fal-provider.ts b/packages/fal/src/fal-provider.ts index 5037b13063ac..6c794db3b27f 100644 --- a/packages/fal/src/fal-provider.ts +++ b/packages/fal/src/fal-provider.ts @@ -1,5 +1,5 @@ import { - ImageModelV2, + ImageModelV3, NoSuchModelError, ProviderV3, SpeechModelV2, @@ -47,12 +47,12 @@ export interface FalProvider extends ProviderV3 { /** Creates a model for image generation. */ - image(modelId: FalImageModelId): ImageModelV2; + image(modelId: FalImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: FalImageModelId): ImageModelV2; + imageModel(modelId: FalImageModelId): ImageModelV3; /** Creates a model for transcription. diff --git a/packages/fireworks/src/fireworks-image-model.test.ts b/packages/fireworks/src/fireworks-image-model.test.ts index c6fa970fde7b..87e95bad9fc1 100644 --- a/packages/fireworks/src/fireworks-image-model.test.ts +++ b/packages/fireworks/src/fireworks-image-model.test.ts @@ -353,7 +353,7 @@ describe('FireworksImageModel', () => { expect(model.provider).toBe('fireworks'); expect(model.modelId).toBe('accounts/fireworks/models/flux-1-dev-fp8'); - expect(model.specificationVersion).toBe('v2'); + expect(model.specificationVersion).toBe('v3'); expect(model.maxImagesPerCall).toBe(1); }); }); diff --git a/packages/fireworks/src/fireworks-image-model.ts b/packages/fireworks/src/fireworks-image-model.ts index 8a86cb34100f..de1463b5fdba 100644 --- a/packages/fireworks/src/fireworks-image-model.ts +++ b/packages/fireworks/src/fireworks-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { combineHeaders, createBinaryResponseHandler, @@ -67,8 +67,8 @@ interface FireworksImageModelConfig { }; } -export class FireworksImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class FireworksImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 1; get provider(): string { @@ -89,10 +89,10 @@ export class FireworksImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; const backendConfig = modelToBackendConfig[this.modelId]; if (!backendConfig?.supportsSize && size != null) { diff --git a/packages/fireworks/src/fireworks-provider.ts b/packages/fireworks/src/fireworks-provider.ts index d5e44b8d6d76..25fd5510bb32 100644 --- a/packages/fireworks/src/fireworks-provider.ts +++ b/packages/fireworks/src/fireworks-provider.ts @@ -6,7 +6,7 @@ import { } from '@ai-sdk/openai-compatible'; import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, ProviderV3, } from '@ai-sdk/provider'; @@ -87,12 +87,12 @@ Creates a text embedding model for text generation. /** Creates a model for image generation. */ - image(modelId: FireworksImageModelId): ImageModelV2; + image(modelId: FireworksImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: FireworksImageModelId): ImageModelV2; + imageModel(modelId: FireworksImageModelId): ImageModelV3; } const defaultBaseURL = 'https://api.fireworks.ai/inference/v1'; diff --git a/packages/google-vertex/src/google-vertex-image-model.ts b/packages/google-vertex/src/google-vertex-image-model.ts index 52133a9f04ae..f1de3f60a3f4 100644 --- a/packages/google-vertex/src/google-vertex-image-model.ts +++ b/packages/google-vertex/src/google-vertex-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { Resolvable, combineHeaders, @@ -22,8 +22,8 @@ interface GoogleVertexImageModelConfig { } // https://cloud.google.com/vertex-ai/generative-ai/docs/image/generate-images -export class GoogleVertexImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class GoogleVertexImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; // https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#parameter_list readonly maxImagesPerCall = 4; @@ -45,10 +45,10 @@ export class GoogleVertexImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; if (size != null) { warnings.push({ diff --git a/packages/google-vertex/src/google-vertex-provider.ts b/packages/google-vertex/src/google-vertex-provider.ts index 5d44bfa72891..6fa9f788f424 100644 --- a/packages/google-vertex/src/google-vertex-provider.ts +++ b/packages/google-vertex/src/google-vertex-provider.ts @@ -1,5 +1,5 @@ import { GoogleGenerativeAILanguageModel } from '@ai-sdk/google/internal'; -import { ImageModelV2, LanguageModelV2, ProviderV3 } from '@ai-sdk/provider'; +import { ImageModelV3, LanguageModelV2, ProviderV3 } from '@ai-sdk/provider'; import { FetchFunction, generateId, @@ -29,12 +29,12 @@ Creates a model for text generation. /** * Creates a model for image generation. */ - image(modelId: GoogleVertexImageModelId): ImageModelV2; + image(modelId: GoogleVertexImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: GoogleVertexImageModelId): ImageModelV2; + imageModel(modelId: GoogleVertexImageModelId): ImageModelV3; tools: typeof googleVertexTools; } diff --git a/packages/google/src/google-generative-ai-image-model.ts b/packages/google/src/google-generative-ai-image-model.ts index 98b6cc6729f7..7dea4f9c0943 100644 --- a/packages/google/src/google-generative-ai-image-model.ts +++ b/packages/google/src/google-generative-ai-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { combineHeaders, createJsonResponseHandler, @@ -25,8 +25,8 @@ interface GoogleGenerativeAIImageModelConfig { }; } -export class GoogleGenerativeAIImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class GoogleGenerativeAIImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; get maxImagesPerCall(): number { // https://ai.google.dev/gemini-api/docs/imagen#imagen-model @@ -44,8 +44,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV2 { ) {} async doGenerate( - options: Parameters[0], - ): Promise>> { + options: Parameters[0], + ): Promise>> { const { prompt, n = 1, @@ -56,7 +56,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV2 { headers, abortSignal, } = options; - const warnings: Array = []; + const warnings: Array = []; if (size != null) { warnings.push({ diff --git a/packages/google/src/google-provider.ts b/packages/google/src/google-provider.ts index 5d74f3347c46..baedc3134cc8 100644 --- a/packages/google/src/google-provider.ts +++ b/packages/google/src/google-provider.ts @@ -2,7 +2,7 @@ import { EmbeddingModelV3, LanguageModelV2, ProviderV3, - ImageModelV2, + ImageModelV3, } from '@ai-sdk/provider'; import { FetchFunction, @@ -37,7 +37,7 @@ Creates a model for image generation. image( modelId: GoogleGenerativeAIImageModelId, settings?: GoogleGenerativeAIImageSettings, - ): ImageModelV2; + ): ImageModelV3; /** * @deprecated Use `chat()` instead. diff --git a/packages/luma/src/luma-image-model.test.ts b/packages/luma/src/luma-image-model.test.ts index 1e1de37e7a35..5c8cabef679f 100644 --- a/packages/luma/src/luma-image-model.test.ts +++ b/packages/luma/src/luma-image-model.test.ts @@ -294,7 +294,7 @@ describe('LumaImageModel', () => { expect(model.provider).toBe('luma'); expect(model.modelId).toBe('test-model'); - expect(model.specificationVersion).toBe('v2'); + expect(model.specificationVersion).toBe('v3'); expect(model.maxImagesPerCall).toBe(1); }); }); diff --git a/packages/luma/src/luma-image-model.ts b/packages/luma/src/luma-image-model.ts index 19dabfcddafd..8a3567a17f6c 100644 --- a/packages/luma/src/luma-image-model.ts +++ b/packages/luma/src/luma-image-model.ts @@ -1,6 +1,6 @@ import { - ImageModelV2, - ImageModelV2CallWarning, + ImageModelV3, + ImageModelV3CallWarning, InvalidResponseDataError, } from '@ai-sdk/provider'; import { @@ -30,8 +30,8 @@ interface LumaImageModelConfig { }; } -export class LumaImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class LumaImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 1; readonly pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS; readonly maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS; @@ -54,10 +54,10 @@ export class LumaImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; if (seed != null) { warnings.push({ diff --git a/packages/luma/src/luma-provider.ts b/packages/luma/src/luma-provider.ts index 4cb39a1bed1b..c72c947c4c76 100644 --- a/packages/luma/src/luma-provider.ts +++ b/packages/luma/src/luma-provider.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, NoSuchModelError, ProviderV3 } from '@ai-sdk/provider'; +import { ImageModelV3, NoSuchModelError, ProviderV3 } from '@ai-sdk/provider'; import { FetchFunction, loadApiKey, @@ -34,12 +34,12 @@ export interface LumaProvider extends ProviderV3 { /** Creates a model for image generation. */ - image(modelId: LumaImageModelId): ImageModelV2; + image(modelId: LumaImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: LumaImageModelId): ImageModelV2; + imageModel(modelId: LumaImageModelId): ImageModelV3; } const defaultBaseURL = 'https://api.lumalabs.ai'; diff --git a/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts b/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts index 06df26e65b15..54089975f7a6 100644 --- a/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts +++ b/packages/openai-compatible/src/image/openai-compatible-image-model.test.ts @@ -4,7 +4,7 @@ import { createTestServer } from '@ai-sdk/test-server/with-vitest'; import { OpenAICompatibleImageModel } from './openai-compatible-image-model'; import { z } from 'zod/v4'; import { ProviderErrorStructure } from '../openai-compatible-error'; -import { ImageModelV2CallOptions } from '@ai-sdk/provider'; +import { ImageModelV3CallOptions } from '@ai-sdk/provider'; const prompt = 'A photorealistic astronaut riding a horse'; @@ -31,7 +31,7 @@ function createBasicModel({ }); } -function createDefaultGenerateParams(overrides = {}): ImageModelV2CallOptions { +function createDefaultGenerateParams(overrides = {}): ImageModelV3CallOptions { return { prompt: 'A photorealistic astronaut riding a horse', n: 1, @@ -70,7 +70,7 @@ describe('OpenAICompatibleImageModel', () => { expect(model.provider).toBe('openai-compatible'); expect(model.modelId).toBe('dall-e-3'); - expect(model.specificationVersion).toBe('v2'); + expect(model.specificationVersion).toBe('v3'); expect(model.maxImagesPerCall).toBe(10); }); }); diff --git a/packages/openai-compatible/src/image/openai-compatible-image-model.ts b/packages/openai-compatible/src/image/openai-compatible-image-model.ts index ea1ff8ba69f6..5c5c2c93bb49 100644 --- a/packages/openai-compatible/src/image/openai-compatible-image-model.ts +++ b/packages/openai-compatible/src/image/openai-compatible-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { combineHeaders, createJsonErrorResponseHandler, @@ -24,8 +24,8 @@ export type OpenAICompatibleImageModelConfig = { }; }; -export class OpenAICompatibleImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class OpenAICompatibleImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 10; get provider(): string { @@ -46,10 +46,10 @@ export class OpenAICompatibleImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; if (aspectRatio != null) { warnings.push({ diff --git a/packages/openai-compatible/src/openai-compatible-provider.ts b/packages/openai-compatible/src/openai-compatible-provider.ts index 1bd051678ddd..3c1687655f3d 100644 --- a/packages/openai-compatible/src/openai-compatible-provider.ts +++ b/packages/openai-compatible/src/openai-compatible-provider.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, ProviderV3, } from '@ai-sdk/provider'; @@ -38,7 +38,7 @@ export interface OpenAICompatibleProvider< textEmbeddingModel(modelId: EMBEDDING_MODEL_IDS): EmbeddingModelV3; - imageModel(modelId: IMAGE_MODEL_IDS): ImageModelV2; + imageModel(modelId: IMAGE_MODEL_IDS): ImageModelV3; } export interface OpenAICompatibleProviderSettings { diff --git a/packages/openai/src/image/openai-image-model.ts b/packages/openai/src/image/openai-image-model.ts index 7f9ac2f204d0..9e750a7cdae9 100644 --- a/packages/openai/src/image/openai-image-model.ts +++ b/packages/openai/src/image/openai-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { combineHeaders, createJsonResponseHandler, @@ -19,8 +19,8 @@ interface OpenAIImageModelConfig extends OpenAIConfig { }; } -export class OpenAIImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class OpenAIImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; get maxImagesPerCall(): number { return modelMaxImagesPerCall[this.modelId] ?? 1; @@ -44,10 +44,10 @@ export class OpenAIImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; if (aspectRatio != null) { warnings.push({ diff --git a/packages/openai/src/openai-provider.ts b/packages/openai/src/openai-provider.ts index 5ec14e5d7808..dc64e82b0241 100644 --- a/packages/openai/src/openai-provider.ts +++ b/packages/openai/src/openai-provider.ts @@ -1,6 +1,6 @@ import { EmbeddingModelV3, - ImageModelV2, + ImageModelV3, LanguageModelV2, ProviderV3, SpeechModelV2, @@ -70,12 +70,12 @@ Creates a model for text embeddings. /** Creates a model for image generation. */ - image(modelId: OpenAIImageModelId): ImageModelV2; + image(modelId: OpenAIImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: OpenAIImageModelId): ImageModelV2; + imageModel(modelId: OpenAIImageModelId): ImageModelV3; /** Creates a model for transcription. diff --git a/packages/provider/src/image-model/index.ts b/packages/provider/src/image-model/index.ts index 5640476d8b82..f0a4a20cc05d 100644 --- a/packages/provider/src/image-model/index.ts +++ b/packages/provider/src/image-model/index.ts @@ -1 +1,2 @@ +export * from './v3/index'; export * from './v2/index'; diff --git a/packages/provider/src/image-model/v3/image-model-v3-call-options.ts b/packages/provider/src/image-model/v3/image-model-v3-call-options.ts new file mode 100644 index 000000000000..9b3644a9d9d6 --- /dev/null +++ b/packages/provider/src/image-model/v3/image-model-v3-call-options.ts @@ -0,0 +1,60 @@ +import { SharedV2ProviderOptions } from '../../shared'; + +export type ImageModelV3CallOptions = { + /** +Prompt for the image generation. + */ + prompt: string; + + /** +Number of images to generate. + */ + n: number; + + /** +Size of the images to generate. +Must have the format `{width}x{height}`. +`undefined` will use the provider's default size. + */ + size: `${number}x${number}` | undefined; + + /** +Aspect ratio of the images to generate. +Must have the format `{width}:{height}`. +`undefined` will use the provider's default aspect ratio. + */ + aspectRatio: `${number}:${number}` | undefined; + + /** +Seed for the image generation. +`undefined` will use the provider's default seed. + */ + seed: number | undefined; + + /** +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": { + "style": "vivid" + } +} +``` + */ + providerOptions: SharedV2ProviderOptions; + + /** +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/image-model/v3/image-model-v3-call-warning.ts b/packages/provider/src/image-model/v3/image-model-v3-call-warning.ts new file mode 100644 index 000000000000..eec316055dde --- /dev/null +++ b/packages/provider/src/image-model/v3/image-model-v3-call-warning.ts @@ -0,0 +1,16 @@ +import { ImageModelV3CallOptions } from './image-model-v3-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 ImageModelV3CallWarning = + | { + type: 'unsupported-setting'; + setting: keyof ImageModelV3CallOptions; + details?: string; + } + | { + type: 'other'; + message: string; + }; diff --git a/packages/provider/src/image-model/v3/image-model-v3.ts b/packages/provider/src/image-model/v3/image-model-v3.ts new file mode 100644 index 000000000000..a06fcd6b1c48 --- /dev/null +++ b/packages/provider/src/image-model/v3/image-model-v3.ts @@ -0,0 +1,104 @@ +import { JSONArray, JSONValue } from '../../json-value'; +import { ImageModelV3CallOptions } from './image-model-v3-call-options'; +import { ImageModelV3CallWarning } from './image-model-v3-call-warning'; + +export type ImageModelV3ProviderMetadata = Record< + string, + { + images: JSONArray; + } & JSONValue +>; + +type GetMaxImagesPerCallFunction = (options: { + modelId: string; +}) => PromiseLike | number | undefined; + +/** +Image generation model specification version 3. + */ +export type ImageModelV3 = { + /** +The image model must specify which image model interface +version it implements. This will allow us to evolve the image +model interface and retain backwards compatibility. The different +implementation versions can be handled as a discriminated union +on our side. + */ + readonly specificationVersion: 'v3'; + + /** +Name of the provider for logging purposes. + */ + readonly provider: string; + + /** +Provider-specific model ID for logging purposes. + */ + readonly modelId: string; + + /** +Limit of how many images can be generated in a single API call. +Can be set to a number for a fixed limit, to undefined to use +the global limit, or a function that returns a number or undefined, +optionally as a promise. + */ + readonly maxImagesPerCall: number | undefined | GetMaxImagesPerCallFunction; + + /** +Generates an array of images. + */ + doGenerate(options: ImageModelV3CallOptions): PromiseLike<{ + /** +Generated images as base64 encoded strings or binary data. +The images should be returned without any unnecessary conversion. +If the API returns base64 encoded strings, the images should be returned +as base64 encoded strings. If the API returns binary data, the images should +be returned as binary data. + */ + images: Array | Array; + + /** +Warnings for the call, e.g. unsupported settings. + */ + warnings: Array; + + /** +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. + +The outer record is keyed by the provider name, and the inner +record is provider-specific metadata. It always includes an +`images` key with image-specific metadata + +```ts +{ + "openai": { + "images": ["revisedPrompt": "Revised prompt here."] + } +} +``` + */ + providerMetadata?: ImageModelV3ProviderMetadata; + + /** +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; + }; + }>; +}; diff --git a/packages/provider/src/image-model/v3/index.ts b/packages/provider/src/image-model/v3/index.ts new file mode 100644 index 000000000000..9eb5613a1b67 --- /dev/null +++ b/packages/provider/src/image-model/v3/index.ts @@ -0,0 +1,6 @@ +export type { + ImageModelV3, + ImageModelV3ProviderMetadata, +} from './image-model-v3'; +export type { ImageModelV3CallOptions } from './image-model-v3-call-options'; +export type { ImageModelV3CallWarning } from './image-model-v3-call-warning'; diff --git a/packages/provider/src/provider/v3/provider-v3.ts b/packages/provider/src/provider/v3/provider-v3.ts index b6060d512794..e595ef5aec46 100644 --- a/packages/provider/src/provider/v3/provider-v3.ts +++ b/packages/provider/src/provider/v3/provider-v3.ts @@ -1,5 +1,5 @@ import { EmbeddingModelV3 } from '../../embedding-model/v3/embedding-model-v3'; -import { ImageModelV2 } from '../../image-model/v2/image-model-v2'; +import { ImageModelV3 } from '../../image-model/v3/image-model-v3'; import { LanguageModelV2 } from '../../language-model/v2/language-model-v2'; import { SpeechModelV2 } from '../../speech-model/v2/speech-model-v2'; import { TranscriptionModelV2 } from '../../transcription-model/v2/transcription-model-v2'; @@ -40,7 +40,7 @@ The model id is then passed to the provider function to get the model. @returns {ImageModel} The image model associated with the id */ - imageModel(modelId: string): ImageModelV2; + imageModel(modelId: string): ImageModelV3; /** Returns the transcription model with the given id. diff --git a/packages/replicate/src/replicate-image-model.ts b/packages/replicate/src/replicate-image-model.ts index 5e1f53ee8ea7..907ff3cbbe81 100644 --- a/packages/replicate/src/replicate-image-model.ts +++ b/packages/replicate/src/replicate-image-model.ts @@ -1,4 +1,4 @@ -import type { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import type { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import type { Resolvable } from '@ai-sdk/provider-utils'; import { FetchFunction, @@ -23,8 +23,8 @@ interface ReplicateImageModelConfig { }; } -export class ReplicateImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class ReplicateImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 1; get provider(): string { @@ -45,10 +45,10 @@ export class ReplicateImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; const [modelId, version] = this.modelId.split(':'); diff --git a/packages/togetherai/src/togetherai-image-model.test.ts b/packages/togetherai/src/togetherai-image-model.test.ts index f6fb46582167..328be7ded236 100644 --- a/packages/togetherai/src/togetherai-image-model.test.ts +++ b/packages/togetherai/src/togetherai-image-model.test.ts @@ -238,7 +238,7 @@ describe('constructor', () => { expect(model.provider).toBe('togetherai'); expect(model.modelId).toBe('stabilityai/stable-diffusion-xl'); - expect(model.specificationVersion).toBe('v2'); + expect(model.specificationVersion).toBe('v3'); expect(model.maxImagesPerCall).toBe(1); }); }); diff --git a/packages/togetherai/src/togetherai-image-model.ts b/packages/togetherai/src/togetherai-image-model.ts index 4a473f06fdac..2e80ad69f81f 100644 --- a/packages/togetherai/src/togetherai-image-model.ts +++ b/packages/togetherai/src/togetherai-image-model.ts @@ -1,4 +1,4 @@ -import { ImageModelV2, ImageModelV2CallWarning } from '@ai-sdk/provider'; +import { ImageModelV3, ImageModelV3CallWarning } from '@ai-sdk/provider'; import { combineHeaders, createJsonResponseHandler, @@ -19,8 +19,8 @@ interface TogetherAIImageModelConfig { }; } -export class TogetherAIImageModel implements ImageModelV2 { - readonly specificationVersion = 'v2'; +export class TogetherAIImageModel implements ImageModelV3 { + readonly specificationVersion = 'v3'; readonly maxImagesPerCall = 1; get provider(): string { @@ -40,10 +40,10 @@ export class TogetherAIImageModel implements ImageModelV2 { providerOptions, headers, abortSignal, - }: Parameters[0]): Promise< - Awaited> + }: Parameters[0]): Promise< + Awaited> > { - const warnings: Array = []; + const warnings: Array = []; if (size != null) { warnings.push({ diff --git a/packages/togetherai/src/togetherai-provider.ts b/packages/togetherai/src/togetherai-provider.ts index 1150dd0b595d..5c5e7378a31b 100644 --- a/packages/togetherai/src/togetherai-provider.ts +++ b/packages/togetherai/src/togetherai-provider.ts @@ -2,7 +2,7 @@ import { LanguageModelV2, EmbeddingModelV3, ProviderV3, - ImageModelV2, + ImageModelV3, } from '@ai-sdk/provider'; import { OpenAICompatibleChatLanguageModel, @@ -73,12 +73,12 @@ Creates a text embedding model for text generation. /** Creates a model for image generation. */ - image(modelId: TogetherAIImageModelId): ImageModelV2; + image(modelId: TogetherAIImageModelId): ImageModelV3; /** Creates a model for image generation. */ - imageModel(modelId: TogetherAIImageModelId): ImageModelV2; + imageModel(modelId: TogetherAIImageModelId): ImageModelV3; } export function createTogetherAI( diff --git a/packages/xai/src/xai-provider.ts b/packages/xai/src/xai-provider.ts index 46e2689a9f03..f3cecf6769c5 100644 --- a/packages/xai/src/xai-provider.ts +++ b/packages/xai/src/xai-provider.ts @@ -3,7 +3,7 @@ import { ProviderErrorStructure, } from '@ai-sdk/openai-compatible'; import { - ImageModelV2, + ImageModelV3, LanguageModelV2, NoSuchModelError, ProviderV3, @@ -45,12 +45,12 @@ Creates an Xai chat model for text generation. /** Creates an Xai image model for image generation. */ - image(modelId: XaiImageModelId): ImageModelV2; + image(modelId: XaiImageModelId): ImageModelV3; /** Creates an Xai image model for image generation. */ - imageModel(modelId: XaiImageModelId): ImageModelV2; + imageModel(modelId: XaiImageModelId): ImageModelV3; } export interface XaiProviderSettings { From 218945625d77ac09cbec55319caabcdb84d40a70 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:43:01 -0700 Subject: [PATCH 120/121] ci(backport): rename v5.0 branch to release-v5.0 (#8896) --- .github/workflows/backport.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index c5fabc2eca71..68c6e61afd93 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -8,7 +8,7 @@ concurrency: ${{ github.workflow }}-${{ github.event.pull_request.number }} jobs: backport: - name: Backport to v5.0 + name: Backport to release-v5.0 runs-on: ubuntu-latest timeout-minutes: 10 # Only run on merged PRs with backport label in the main repository @@ -42,12 +42,12 @@ jobs: with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} - ref: v5.0 + ref: release-v5.0 - name: Create backport branch run: | - # Create a new branch from v5.0 for the backport - git checkout -b backport-pr-${{ github.event.pull_request.number }}-to-v5.0 origin/v5.0 + # Create a new branch from release-v5.0 for the backport + git checkout -b backport-pr-${{ github.event.pull_request.number }}-to-release-v5.0 origin/release-v5.0 - name: Cherry-pick commits run: | @@ -57,13 +57,13 @@ jobs: # Cherry-pick the merge commit if ! git cherry-pick -m 1 "$MERGE_COMMIT"; then echo "Cherry-pick failed. This backport requires manual intervention." - echo "::error::Failed to cherry-pick merge commit $MERGE_COMMIT to v5.0 branch" + echo "::error::Failed to cherry-pick merge commit $MERGE_COMMIT to release-v5.0 branch" exit 1 fi - name: Push backport branch run: | - git push origin backport-pr-${{ github.event.pull_request.number }}-to-v5.0 + git push origin backport-pr-${{ github.event.pull_request.number }}-to-release-v5.0 - name: Create backport pull request id: create-pr @@ -73,15 +73,15 @@ jobs: PR_URL=$(gh pr create \ --title "$PR_TITLE" \ --body "$PR_BODY" \ - --base v5.0 \ - --head backport-pr-${{ github.event.pull_request.number }}-to-v5.0) + --base release-v5.0 \ + --head backport-pr-${{ github.event.pull_request.number }}-to-release-v5.0) echo "backport-pr-url=$PR_URL" >> "$GITHUB_OUTPUT" echo "Created backport PR $PR_URL" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} PR_TITLE: "Backport: ${{ github.event.pull_request.title }}" - PR_BODY: "This is an automated backport of #${{ github.event.pull_request.number }} to the v5.0 branch." + PR_BODY: "This is an automated backport of #${{ github.event.pull_request.number }} to the release-v5.0 branch." - name: Remove backport label from original PR if: steps.create-pr.outputs.backport-pr-url @@ -102,6 +102,6 @@ jobs: - name: Failure Comment on original PR if: failure() run: | - gh pr comment ${{ github.event.pull_request.number }} --body "❌ Backport to v5.0 failed. This backport requires manual intervention. [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" + gh pr comment ${{ github.event.pull_request.number }} --body "❌ Backport to release-v5.0 failed. This backport requires manual intervention. [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} From 67f7e765458500102d6a4e60a4687692b0d03efd Mon Sep 17 00:00:00 2001 From: "vercel-ai-sdk[bot]" <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:57:46 -0700 Subject: [PATCH 121/121] Version Packages (beta) (#8884) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. ⚠️⚠️⚠️⚠️⚠️⚠️ `main` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `main`. ⚠️⚠️⚠️⚠️⚠️⚠️ # Releases ## ai@5.1.0-beta.9 ### Patch Changes - ed329cb: feat: `Provider-V3` - 177b475: fix(ai): download files when intermediate file cannot be downloaded - 522f6b8: feat: `ImageModelV3` - Updated dependencies [aaf5ebf] - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/gateway@1.1.0-beta.6 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/amazon-bedrock@3.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/anthropic@2.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/angular@1.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - ai@5.1.0-beta.9 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/anthropic@2.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/assemblyai@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/azure@2.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/openai@2.1.0-beta.4 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/baseten@1.0.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/cerebras@1.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/cohere@2.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/deepgram@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/deepinfra@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/deepseek@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/elevenlabs@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/fal@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/fireworks@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/gateway@1.1.0-beta.6 ### Patch Changes - aaf5ebf: feat(provider/gateway): Add new Qwen models to Gateway model string autocomplete - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/gladia@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/google@2.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/google-vertex@3.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/anthropic@2.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/google@2.1.0-beta.4 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/groq@2.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/hume@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/langchain@1.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - ai@5.1.0-beta.9 ## @ai-sdk/llamaindex@1.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - ai@5.1.0-beta.9 ## @ai-sdk/lmnt@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/luma@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/mistral@2.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/openai@2.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/openai-compatible@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/perplexity@2.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/provider@2.1.0-beta.2 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` ## @ai-sdk/provider-utils@3.1.0-beta.3 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 ## @ai-sdk/react@2.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - ai@5.1.0-beta.9 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/replicate@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/revai@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/rsc@1.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - @ai-sdk/provider@2.1.0-beta.2 - ai@5.1.0-beta.9 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/svelte@3.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - ai@5.1.0-beta.9 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/togetherai@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/valibot@1.1.0-beta.3 ### Patch Changes - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/vercel@1.1.0-beta.3 ### Patch Changes - ed329cb: feat: `Provider-V3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/vue@2.1.0-beta.9 ### Patch Changes - Updated dependencies [ed329cb] - Updated dependencies [177b475] - Updated dependencies [522f6b8] - ai@5.1.0-beta.9 - @ai-sdk/provider-utils@3.1.0-beta.3 ## @ai-sdk/xai@2.1.0-beta.4 ### Patch Changes - ed329cb: feat: `Provider-V3` - 522f6b8: feat: `ImageModelV3` - Updated dependencies [ed329cb] - Updated dependencies [522f6b8] - @ai-sdk/openai-compatible@1.1.0-beta.3 - @ai-sdk/provider@2.1.0-beta.2 - @ai-sdk/provider-utils@3.1.0-beta.3 Co-authored-by: vercel-ai-sdk[bot] <225926702+vercel-ai-sdk[bot]@users.noreply.github.com> --- .changeset/pre.json | 4 ++++ packages/ai/CHANGELOG.md | 14 ++++++++++++++ packages/ai/package.json | 2 +- packages/amazon-bedrock/CHANGELOG.md | 12 ++++++++++++ packages/amazon-bedrock/package.json | 2 +- packages/angular/CHANGELOG.md | 10 ++++++++++ packages/angular/package.json | 2 +- packages/anthropic/CHANGELOG.md | 10 ++++++++++ packages/anthropic/package.json | 2 +- packages/assemblyai/CHANGELOG.md | 10 ++++++++++ packages/assemblyai/package.json | 2 +- packages/azure/CHANGELOG.md | 12 ++++++++++++ packages/azure/package.json | 2 +- packages/baseten/CHANGELOG.md | 11 +++++++++++ packages/baseten/package.json | 2 +- packages/cerebras/CHANGELOG.md | 11 +++++++++++ packages/cerebras/package.json | 2 +- packages/cohere/CHANGELOG.md | 10 ++++++++++ packages/cohere/package.json | 2 +- packages/deepgram/CHANGELOG.md | 10 ++++++++++ packages/deepgram/package.json | 2 +- packages/deepinfra/CHANGELOG.md | 12 ++++++++++++ packages/deepinfra/package.json | 2 +- packages/deepseek/CHANGELOG.md | 11 +++++++++++ packages/deepseek/package.json | 2 +- packages/elevenlabs/CHANGELOG.md | 10 ++++++++++ packages/elevenlabs/package.json | 2 +- packages/fal/CHANGELOG.md | 11 +++++++++++ packages/fal/package.json | 2 +- packages/fireworks/CHANGELOG.md | 12 ++++++++++++ packages/fireworks/package.json | 2 +- packages/gateway/CHANGELOG.md | 11 +++++++++++ packages/gateway/package.json | 2 +- packages/gladia/CHANGELOG.md | 10 ++++++++++ packages/gladia/package.json | 2 +- packages/google-vertex/CHANGELOG.md | 13 +++++++++++++ packages/google-vertex/package.json | 2 +- packages/google/CHANGELOG.md | 11 +++++++++++ packages/google/package.json | 2 +- packages/groq/CHANGELOG.md | 10 ++++++++++ packages/groq/package.json | 2 +- packages/hume/CHANGELOG.md | 10 ++++++++++ packages/hume/package.json | 2 +- packages/langchain/CHANGELOG.md | 9 +++++++++ packages/langchain/package.json | 2 +- packages/llamaindex/CHANGELOG.md | 9 +++++++++ packages/llamaindex/package.json | 2 +- packages/lmnt/CHANGELOG.md | 10 ++++++++++ packages/lmnt/package.json | 2 +- packages/luma/CHANGELOG.md | 11 +++++++++++ packages/luma/package.json | 2 +- packages/mistral/CHANGELOG.md | 10 ++++++++++ packages/mistral/package.json | 2 +- packages/openai-compatible/CHANGELOG.md | 11 +++++++++++ packages/openai-compatible/package.json | 2 +- packages/openai/CHANGELOG.md | 11 +++++++++++ packages/openai/package.json | 2 +- packages/perplexity/CHANGELOG.md | 10 ++++++++++ packages/perplexity/package.json | 2 +- packages/provider-utils/CHANGELOG.md | 8 ++++++++ packages/provider-utils/package.json | 2 +- packages/provider/CHANGELOG.md | 7 +++++++ packages/provider/package.json | 2 +- packages/react/CHANGELOG.md | 10 ++++++++++ packages/react/package.json | 2 +- packages/replicate/CHANGELOG.md | 11 +++++++++++ packages/replicate/package.json | 2 +- packages/revai/CHANGELOG.md | 10 ++++++++++ packages/revai/package.json | 2 +- packages/rsc/CHANGELOG.md | 11 +++++++++++ packages/rsc/package.json | 2 +- packages/rsc/tests/e2e/next-server/CHANGELOG.md | 9 +++++++++ packages/svelte/CHANGELOG.md | 10 ++++++++++ packages/svelte/package.json | 2 +- packages/togetherai/CHANGELOG.md | 12 ++++++++++++ packages/togetherai/package.json | 2 +- packages/valibot/CHANGELOG.md | 6 ++++++ packages/valibot/package.json | 2 +- packages/vercel/CHANGELOG.md | 11 +++++++++++ packages/vercel/package.json | 2 +- packages/vue/CHANGELOG.md | 10 ++++++++++ packages/vue/package.json | 2 +- packages/xai/CHANGELOG.md | 12 ++++++++++++ packages/xai/package.json | 2 +- 84 files changed, 484 insertions(+), 41 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 7c705850132e..c0193b8cfee1 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -78,12 +78,14 @@ "blue-books-hang", "curly-glasses-count", "cyan-mirrors-clap", + "eighty-ghosts-collect", "four-candles-buy", "funny-olives-reply", "gentle-students-begin", "great-eels-mate", "grumpy-actors-sleep", "itchy-monkeys-nail", + "itchy-peaches-clean", "lemon-guests-drop", "many-lamps-report", "neat-news-visit", @@ -93,6 +95,8 @@ "selfish-beers-mate", "shaggy-emus-try", "soft-glasses-happen", + "tall-terms-smash", + "thin-shoes-fold", "two-birds-agree", "wise-jobs-knock" ] diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 5dfdf906b694..ca74e89ccdff 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,19 @@ # ai +## 5.1.0-beta.9 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 177b475: fix(ai): download files when intermediate file cannot be downloaded +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [aaf5ebf] +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/gateway@1.1.0-beta.6 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 5.1.0-beta.8 ### Patch Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index d57b82fd14ed..760a58fa96a7 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "ai", - "version": "5.1.0-beta.8", + "version": "5.1.0-beta.9", "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", "license": "Apache-2.0", "sideEffects": false, diff --git a/packages/amazon-bedrock/CHANGELOG.md b/packages/amazon-bedrock/CHANGELOG.md index ed06aa7217a6..eb3a98465487 100644 --- a/packages/amazon-bedrock/CHANGELOG.md +++ b/packages/amazon-bedrock/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/amazon-bedrock +## 3.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/anthropic@2.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 3.1.0-beta.2 ### Patch Changes diff --git a/packages/amazon-bedrock/package.json b/packages/amazon-bedrock/package.json index e62f8c7bbb53..965f9321b34e 100644 --- a/packages/amazon-bedrock/package.json +++ b/packages/amazon-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/amazon-bedrock", - "version": "3.1.0-beta.2", + "version": "3.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 3dd93bed8ad6..7d91cbd3f044 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/angular +## 1.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.8 ### Patch Changes diff --git a/packages/angular/package.json b/packages/angular/package.json index bdf192f901ee..df47bacecdbc 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/angular", - "version": "1.1.0-beta.8", + "version": "1.1.0-beta.9", "description": "Angular implementation of ai-sdk.", "license": "Apache-2.0", "main": "dist/index.cjs", diff --git a/packages/anthropic/CHANGELOG.md b/packages/anthropic/CHANGELOG.md index 2a9755908c0f..978e84d37d08 100644 --- a/packages/anthropic/CHANGELOG.md +++ b/packages/anthropic/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/anthropic +## 2.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/anthropic/package.json b/packages/anthropic/package.json index 43924c16cfc7..044837d4c3b3 100644 --- a/packages/anthropic/package.json +++ b/packages/anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/anthropic", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/assemblyai/CHANGELOG.md b/packages/assemblyai/CHANGELOG.md index 5087815b943a..910c12e7e8bc 100644 --- a/packages/assemblyai/CHANGELOG.md +++ b/packages/assemblyai/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/assemblyai +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/assemblyai/package.json b/packages/assemblyai/package.json index 6bfad467d70b..cbdbb591bdcb 100644 --- a/packages/assemblyai/package.json +++ b/packages/assemblyai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/assemblyai", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/azure/CHANGELOG.md b/packages/azure/CHANGELOG.md index fefba723fe93..d5fc3215dabd 100644 --- a/packages/azure/CHANGELOG.md +++ b/packages/azure/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/azure +## 2.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/openai@2.1.0-beta.4 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/azure/package.json b/packages/azure/package.json index fd58c19d76e4..a42b8fb88fa9 100644 --- a/packages/azure/package.json +++ b/packages/azure/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/azure", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/baseten/CHANGELOG.md b/packages/baseten/CHANGELOG.md index 85b0986156b2..f579468bff49 100644 --- a/packages/baseten/CHANGELOG.md +++ b/packages/baseten/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/baseten +## 1.0.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.0.0-beta.2 ### Patch Changes diff --git a/packages/baseten/package.json b/packages/baseten/package.json index 8b1cff3e2eb4..35b3d43a60b1 100644 --- a/packages/baseten/package.json +++ b/packages/baseten/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/baseten", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cerebras/CHANGELOG.md b/packages/cerebras/CHANGELOG.md index 0d125cc2aa3b..8f18088cc9b5 100644 --- a/packages/cerebras/CHANGELOG.md +++ b/packages/cerebras/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/cerebras +## 1.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.3 ### Patch Changes diff --git a/packages/cerebras/package.json b/packages/cerebras/package.json index f02a39bc47c5..be5a28325a4d 100644 --- a/packages/cerebras/package.json +++ b/packages/cerebras/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cerebras", - "version": "1.1.0-beta.3", + "version": "1.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/cohere/CHANGELOG.md b/packages/cohere/CHANGELOG.md index f6d12cdca590..71aba960206c 100644 --- a/packages/cohere/CHANGELOG.md +++ b/packages/cohere/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/cohere +## 2.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/cohere/package.json b/packages/cohere/package.json index 4d3482fadb4c..da1b043eb67e 100644 --- a/packages/cohere/package.json +++ b/packages/cohere/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/cohere", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepgram/CHANGELOG.md b/packages/deepgram/CHANGELOG.md index ceb28abe1887..e8e419cc3b76 100644 --- a/packages/deepgram/CHANGELOG.md +++ b/packages/deepgram/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/deepgram +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/deepgram/package.json b/packages/deepgram/package.json index b7f43bffb9e9..cabd168bcb7a 100644 --- a/packages/deepgram/package.json +++ b/packages/deepgram/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepgram", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepinfra/CHANGELOG.md b/packages/deepinfra/CHANGELOG.md index f662cf9bce6b..458ae6b31eb1 100644 --- a/packages/deepinfra/CHANGELOG.md +++ b/packages/deepinfra/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/deepinfra +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/deepinfra/package.json b/packages/deepinfra/package.json index 755a8da2c253..3d951274c9c0 100644 --- a/packages/deepinfra/package.json +++ b/packages/deepinfra/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepinfra", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/deepseek/CHANGELOG.md b/packages/deepseek/CHANGELOG.md index 41959d8be20e..540585b644e1 100644 --- a/packages/deepseek/CHANGELOG.md +++ b/packages/deepseek/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/deepseek +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/deepseek/package.json b/packages/deepseek/package.json index e21c8c406a21..d3a6f5407074 100644 --- a/packages/deepseek/package.json +++ b/packages/deepseek/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/deepseek", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/elevenlabs/CHANGELOG.md b/packages/elevenlabs/CHANGELOG.md index cdb347bdde81..333d9820aabe 100644 --- a/packages/elevenlabs/CHANGELOG.md +++ b/packages/elevenlabs/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/elevenlabs +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/elevenlabs/package.json b/packages/elevenlabs/package.json index 6ef2cf6465c1..3fe71f3f9e36 100644 --- a/packages/elevenlabs/package.json +++ b/packages/elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/elevenlabs", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fal/CHANGELOG.md b/packages/fal/CHANGELOG.md index 72b029113ca1..42a90972e3f5 100644 --- a/packages/fal/CHANGELOG.md +++ b/packages/fal/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/fal +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/fal/package.json b/packages/fal/package.json index 016bcb0daf69..11cdc979f933 100644 --- a/packages/fal/package.json +++ b/packages/fal/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fal", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/fireworks/CHANGELOG.md b/packages/fireworks/CHANGELOG.md index 3da7875a5011..0e5d1a62fe62 100644 --- a/packages/fireworks/CHANGELOG.md +++ b/packages/fireworks/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/fireworks +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/fireworks/package.json b/packages/fireworks/package.json index 63fbc8d2fcd0..1394a317386b 100644 --- a/packages/fireworks/package.json +++ b/packages/fireworks/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/fireworks", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gateway/CHANGELOG.md b/packages/gateway/CHANGELOG.md index 702c237eb928..7f5aa53f3718 100644 --- a/packages/gateway/CHANGELOG.md +++ b/packages/gateway/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/gateway +## 1.1.0-beta.6 + +### Patch Changes + +- aaf5ebf: feat(provider/gateway): Add new Qwen models to Gateway model string autocomplete +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.5 ### Patch Changes diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 8a074773d279..08859710a393 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,7 +1,7 @@ { "name": "@ai-sdk/gateway", "private": false, - "version": "1.1.0-beta.5", + "version": "1.1.0-beta.6", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/gladia/CHANGELOG.md b/packages/gladia/CHANGELOG.md index a81efd0d222e..fd60468de660 100644 --- a/packages/gladia/CHANGELOG.md +++ b/packages/gladia/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/gladia +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/gladia/package.json b/packages/gladia/package.json index 6a71af2f2452..c1617f5f2e17 100644 --- a/packages/gladia/package.json +++ b/packages/gladia/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/gladia", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "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 58ccf04156cc..2cb79c847dd2 100644 --- a/packages/google-vertex/CHANGELOG.md +++ b/packages/google-vertex/CHANGELOG.md @@ -1,5 +1,18 @@ # @ai-sdk/google-vertex +## 3.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/anthropic@2.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/google@2.1.0-beta.4 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 3.1.0-beta.3 ### Patch Changes diff --git a/packages/google-vertex/package.json b/packages/google-vertex/package.json index fb1afb7d2787..2c84a1c0cf31 100644 --- a/packages/google-vertex/package.json +++ b/packages/google-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google-vertex", - "version": "3.1.0-beta.3", + "version": "3.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/google/CHANGELOG.md b/packages/google/CHANGELOG.md index 6ce86fa2fee6..dad06f11a114 100644 --- a/packages/google/CHANGELOG.md +++ b/packages/google/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/google +## 2.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/google/package.json b/packages/google/package.json index b6c2cb3305b2..5ff40d318437 100644 --- a/packages/google/package.json +++ b/packages/google/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/google", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/groq/CHANGELOG.md b/packages/groq/CHANGELOG.md index 67e190ddee62..4cfe93119fa5 100644 --- a/packages/groq/CHANGELOG.md +++ b/packages/groq/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/groq +## 2.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/groq/package.json b/packages/groq/package.json index e24143f3216f..ab081a84a2a3 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/groq", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/hume/CHANGELOG.md b/packages/hume/CHANGELOG.md index 9f5080f79f77..6f7e90b5fa34 100644 --- a/packages/hume/CHANGELOG.md +++ b/packages/hume/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/hume +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/hume/package.json b/packages/hume/package.json index 404ada9b2d9c..f1aff8b9a87b 100644 --- a/packages/hume/package.json +++ b/packages/hume/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/hume", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/langchain/CHANGELOG.md b/packages/langchain/CHANGELOG.md index 9f7293dee9ab..bec3189c17da 100644 --- a/packages/langchain/CHANGELOG.md +++ b/packages/langchain/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/langchain +## 1.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + ## 1.1.0-beta.8 ### Patch Changes diff --git a/packages/langchain/package.json b/packages/langchain/package.json index fab73aa5ef08..35c1d79783fc 100644 --- a/packages/langchain/package.json +++ b/packages/langchain/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/langchain", - "version": "1.1.0-beta.8", + "version": "1.1.0-beta.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/llamaindex/CHANGELOG.md b/packages/llamaindex/CHANGELOG.md index 092cad72e4f0..7b7a130e0c3e 100644 --- a/packages/llamaindex/CHANGELOG.md +++ b/packages/llamaindex/CHANGELOG.md @@ -1,5 +1,14 @@ # @ai-sdk/llamaindex +## 1.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + ## 1.1.0-beta.8 ### Patch Changes diff --git a/packages/llamaindex/package.json b/packages/llamaindex/package.json index 17868cf5780c..1c254718a524 100644 --- a/packages/llamaindex/package.json +++ b/packages/llamaindex/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/llamaindex", - "version": "1.1.0-beta.8", + "version": "1.1.0-beta.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/lmnt/CHANGELOG.md b/packages/lmnt/CHANGELOG.md index 1fffb0d2b53b..a3fac3a26a23 100644 --- a/packages/lmnt/CHANGELOG.md +++ b/packages/lmnt/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/lmnt +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/lmnt/package.json b/packages/lmnt/package.json index 0e25abfcaaca..c4cf3845b50a 100644 --- a/packages/lmnt/package.json +++ b/packages/lmnt/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/lmnt", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/luma/CHANGELOG.md b/packages/luma/CHANGELOG.md index 2a4263e1af66..ad412ef813e1 100644 --- a/packages/luma/CHANGELOG.md +++ b/packages/luma/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/luma +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/luma/package.json b/packages/luma/package.json index 0345c9e0c827..46f5ea3bf843 100644 --- a/packages/luma/package.json +++ b/packages/luma/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/luma", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/mistral/CHANGELOG.md b/packages/mistral/CHANGELOG.md index 8a3ba1492456..222b6c42cc3c 100644 --- a/packages/mistral/CHANGELOG.md +++ b/packages/mistral/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/mistral +## 2.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/mistral/package.json b/packages/mistral/package.json index 21fc53a0075c..a322b796afbb 100644 --- a/packages/mistral/package.json +++ b/packages/mistral/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/mistral", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai-compatible/CHANGELOG.md b/packages/openai-compatible/CHANGELOG.md index 06626468534c..7cc7a5c9d74d 100644 --- a/packages/openai-compatible/CHANGELOG.md +++ b/packages/openai-compatible/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/openai-compatible +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/openai-compatible/package.json b/packages/openai-compatible/package.json index 35526a1b9be7..f23cc85a62e4 100644 --- a/packages/openai-compatible/package.json +++ b/packages/openai-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai-compatible", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/openai/CHANGELOG.md b/packages/openai/CHANGELOG.md index 457791383809..da447b3d983f 100644 --- a/packages/openai/CHANGELOG.md +++ b/packages/openai/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/openai +## 2.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/openai/package.json b/packages/openai/package.json index d4f73ea9c5fe..d4ad796b0b96 100644 --- a/packages/openai/package.json +++ b/packages/openai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/openai", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/perplexity/CHANGELOG.md b/packages/perplexity/CHANGELOG.md index 430b6d5f53be..1a0aca15edfa 100644 --- a/packages/perplexity/CHANGELOG.md +++ b/packages/perplexity/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/perplexity +## 2.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.2 ### Patch Changes diff --git a/packages/perplexity/package.json b/packages/perplexity/package.json index 850ffe643b4d..e67bfb6d1d92 100644 --- a/packages/perplexity/package.json +++ b/packages/perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/perplexity", - "version": "2.1.0-beta.2", + "version": "2.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider-utils/CHANGELOG.md b/packages/provider-utils/CHANGELOG.md index d64a58af4c48..cd3f77d8181e 100644 --- a/packages/provider-utils/CHANGELOG.md +++ b/packages/provider-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @ai-sdk/provider-utils +## 3.1.0-beta.3 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + ## 3.1.0-beta.2 ### Patch Changes diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index 98cb53c6f4e3..375cc425e234 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider-utils", - "version": "3.1.0-beta.2", + "version": "3.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/provider/CHANGELOG.md b/packages/provider/CHANGELOG.md index 6fdc2c188046..baf05b036f67 100644 --- a/packages/provider/CHANGELOG.md +++ b/packages/provider/CHANGELOG.md @@ -1,5 +1,12 @@ # @ai-sdk/provider +## 2.1.0-beta.2 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` + ## 2.1.0-beta.1 ### Patch Changes diff --git a/packages/provider/package.json b/packages/provider/package.json index 50fc55290bbc..9b1d9f709ae0 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/provider", - "version": "2.1.0-beta.1", + "version": "2.1.0-beta.2", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 3b8126afd05c..c22ceaf7cc29 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/react +## 2.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.8 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index f45cfa517c5b..02743fca2b51 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/react", - "version": "2.1.0-beta.8", + "version": "2.1.0-beta.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/replicate/CHANGELOG.md b/packages/replicate/CHANGELOG.md index 7ad4fce1c325..0b896ade7ba8 100644 --- a/packages/replicate/CHANGELOG.md +++ b/packages/replicate/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/replicate +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/replicate/package.json b/packages/replicate/package.json index 483d2748d7f0..e1e8d8bed799 100644 --- a/packages/replicate/package.json +++ b/packages/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/replicate", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/revai/CHANGELOG.md b/packages/revai/CHANGELOG.md index 7fca8a9ce2a2..aac12e4ae4ab 100644 --- a/packages/revai/CHANGELOG.md +++ b/packages/revai/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/revai +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/revai/package.json b/packages/revai/package.json index 03ee9514684e..e88e2be80241 100644 --- a/packages/revai/package.json +++ b/packages/revai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/revai", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/rsc/CHANGELOG.md b/packages/rsc/CHANGELOG.md index 063b0201d55f..aeb4d88954c5 100644 --- a/packages/rsc/CHANGELOG.md +++ b/packages/rsc/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/rsc +## 1.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - @ai-sdk/provider@2.1.0-beta.2 + - ai@5.1.0-beta.9 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.8 ### Patch Changes diff --git a/packages/rsc/package.json b/packages/rsc/package.json index 8b692de05f77..e9806d03280a 100644 --- a/packages/rsc/package.json +++ b/packages/rsc/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/rsc", - "version": "1.1.0-beta.8", + "version": "1.1.0-beta.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/rsc-client.mjs", diff --git a/packages/rsc/tests/e2e/next-server/CHANGELOG.md b/packages/rsc/tests/e2e/next-server/CHANGELOG.md index 93156709772c..027b7d364278 100644 --- a/packages/rsc/tests/e2e/next-server/CHANGELOG.md +++ b/packages/rsc/tests/e2e/next-server/CHANGELOG.md @@ -4,6 +4,15 @@ ### Patch Changes +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + +## 0.0.1-beta.0 + +### Patch Changes + - Updated dependencies [7eca093] - ai@5.1.0-beta.8 diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 33689aca600e..927384f35330 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/svelte +## 3.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 3.1.0-beta.8 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 66a964e4f1fb..f9b0127ce1ba 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/svelte", - "version": "3.1.0-beta.8", + "version": "3.1.0-beta.9", "license": "Apache-2.0", "scripts": { "build": "pnpm prepack", diff --git a/packages/togetherai/CHANGELOG.md b/packages/togetherai/CHANGELOG.md index eca12a485bf9..cfc381dae91a 100644 --- a/packages/togetherai/CHANGELOG.md +++ b/packages/togetherai/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/togetherai +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/togetherai/package.json b/packages/togetherai/package.json index f83394771443..92e99eb539ea 100644 --- a/packages/togetherai/package.json +++ b/packages/togetherai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/togetherai", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/valibot/CHANGELOG.md b/packages/valibot/CHANGELOG.md index 1ed0f2aee37d..7d2f0143ee0f 100644 --- a/packages/valibot/CHANGELOG.md +++ b/packages/valibot/CHANGELOG.md @@ -1,5 +1,11 @@ # @ai-sdk/valibot +## 1.1.0-beta.3 + +### Patch Changes + +- @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/valibot/package.json b/packages/valibot/package.json index 977869f863e7..cfc81d12765a 100644 --- a/packages/valibot/package.json +++ b/packages/valibot/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/valibot", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vercel/CHANGELOG.md b/packages/vercel/CHANGELOG.md index 63e21a17f5e4..2ecbc39fd268 100644 --- a/packages/vercel/CHANGELOG.md +++ b/packages/vercel/CHANGELOG.md @@ -1,5 +1,16 @@ # @ai-sdk/vercel +## 1.1.0-beta.3 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 1.1.0-beta.2 ### Patch Changes diff --git a/packages/vercel/package.json b/packages/vercel/package.json index af760b8a7690..398dcf5e7684 100644 --- a/packages/vercel/package.json +++ b/packages/vercel/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vercel", - "version": "1.1.0-beta.2", + "version": "1.1.0-beta.3", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index b7c813962e47..bea6399fe6c8 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -1,5 +1,15 @@ # @ai-sdk/vue +## 2.1.0-beta.9 + +### Patch Changes + +- Updated dependencies [ed329cb] +- Updated dependencies [177b475] +- Updated dependencies [522f6b8] + - ai@5.1.0-beta.9 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.8 ### Patch Changes diff --git a/packages/vue/package.json b/packages/vue/package.json index bd875da866c9..2122c588cf9d 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/vue", - "version": "2.1.0-beta.8", + "version": "2.1.0-beta.9", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", diff --git a/packages/xai/CHANGELOG.md b/packages/xai/CHANGELOG.md index 1eb082cbcced..ff2b03b0ad32 100644 --- a/packages/xai/CHANGELOG.md +++ b/packages/xai/CHANGELOG.md @@ -1,5 +1,17 @@ # @ai-sdk/xai +## 2.1.0-beta.4 + +### Patch Changes + +- ed329cb: feat: `Provider-V3` +- 522f6b8: feat: `ImageModelV3` +- Updated dependencies [ed329cb] +- Updated dependencies [522f6b8] + - @ai-sdk/openai-compatible@1.1.0-beta.3 + - @ai-sdk/provider@2.1.0-beta.2 + - @ai-sdk/provider-utils@3.1.0-beta.3 + ## 2.1.0-beta.3 ### Patch Changes diff --git a/packages/xai/package.json b/packages/xai/package.json index ebcbb1765ec3..4030f5efb1ac 100644 --- a/packages/xai/package.json +++ b/packages/xai/package.json @@ -1,6 +1,6 @@ { "name": "@ai-sdk/xai", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.4", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js",