From e5c0cc2cbcf07eb4b9ce3249106fd4ce3e263901 Mon Sep 17 00:00:00 2001 From: Matt Pocock Date: Fri, 20 Feb 2026 10:49:29 +0000 Subject: [PATCH 1/3] RALPH: Bump AI SDK deps to v6 and migrate core types (#379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task: Foundational vertical slice for AI SDK v5→v6 migration. Key decisions: - Public types use version-agnostic aliases (LanguageModel, EmbeddingModel from "ai") - Internal middleware types use version-specific V3 types from @ai-sdk/provider - Usage shape adapted: inputTokens/outputTokens now objects with .total, totalTokens computed as sum - Middleware specificationVersion: 'v3' added per v6 requirement - Removed obsolete "media" content type check (replaced by "file" in v6) Files changed: - packages/evalite/package.json: ai ^5→^6, @ai-sdk/provider ^2→^3 - packages/evalite/src/ai-sdk.ts: V2→V3 types, LanguageModel public API, usage shape migration - packages/evalite/src/types.ts: LanguageModelV2→LanguageModel, EmbeddingModelV2→EmbeddingModel - packages/evalite-tests/package.json: ai ^5→^6, @ai-sdk/openai ^2→^3 - packages/example/package.json: ai ^5→^6, @ai-sdk/openai ^2→^3, @ai-sdk/provider ^2→^3 - apps/evalite-ui/package.json: ai ^5→^6 - pnpm-lock.yaml: updated Blockers: #380 needs MockLanguageModelV2→V3 migration in test fixtures + scorer generateObject→generateText migration. Co-Authored-By: Claude Opus 4.6 --- apps/evalite-ui/package.json | 2 +- packages/evalite-tests/package.json | 4 +- packages/evalite/package.json | 6 +- packages/evalite/src/ai-sdk.ts | 104 ++++++++-------- packages/evalite/src/types.ts | 18 +-- packages/example/package.json | 6 +- pnpm-lock.yaml | 177 +++++++++++++--------------- 7 files changed, 150 insertions(+), 167 deletions(-) diff --git a/apps/evalite-ui/package.json b/apps/evalite-ui/package.json index ecb76548..17a02c89 100644 --- a/apps/evalite-ui/package.json +++ b/apps/evalite-ui/package.json @@ -26,7 +26,7 @@ "@tanstack/react-router": "^1.117.0", "@tanstack/router-devtools": "^1.117.0", "@tanstack/zod-adapter": "^1.117.0", - "ai": "^5.0.89", + "ai": "^6", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", diff --git a/packages/evalite-tests/package.json b/packages/evalite-tests/package.json index 34f049c0..5d0ecbc3 100644 --- a/packages/evalite-tests/package.json +++ b/packages/evalite-tests/package.json @@ -12,7 +12,7 @@ "evalite": "workspace:*", "evalite-ui": "workspace:*", "strip-ansi": "^7.1.2", - "@ai-sdk/openai": "^2.0.42", - "ai": "^5.0.59" + "@ai-sdk/openai": "^3.0.0", + "ai": "^6" } } diff --git a/packages/evalite/package.json b/packages/evalite/package.json index 8a99a7ad..d50686f5 100644 --- a/packages/evalite/package.json +++ b/packages/evalite/package.json @@ -71,7 +71,7 @@ }, "peerDependencies": { "better-sqlite3": "^11.6.0", - "ai": "^5" + "ai": "^6" }, "peerDependenciesMeta": { "better-sqlite3": { @@ -82,11 +82,11 @@ } }, "devDependencies": { - "@ai-sdk/provider": "^2.0.0", + "@ai-sdk/provider": "^3.0.0", "@types/better-sqlite3": "^7.6.13", "@types/js-levenshtein": "^1.1.3", "@types/ws": "^8.18.1", - "ai": "^5.0.59", + "ai": "^6", "better-sqlite3": "^11.6.0", "unstorage": "^1.17.1" } diff --git a/packages/evalite/src/ai-sdk.ts b/packages/evalite/src/ai-sdk.ts index a745fc09..e4771c8f 100644 --- a/packages/evalite/src/ai-sdk.ts +++ b/packages/evalite/src/ai-sdk.ts @@ -1,14 +1,15 @@ import type { - LanguageModelV2, - LanguageModelV2CallOptions, - LanguageModelV2StreamPart, + LanguageModelV3, + LanguageModelV3CallOptions, + LanguageModelV3StreamPart, } from "@ai-sdk/provider"; +import type { LanguageModel } from "ai"; import { wrapLanguageModel } from "ai"; import { reportTraceLocalStorage } from "./traces.js"; import { getCacheContext, generateCacheKey } from "./cache.js"; const handlePromptContent = ( - content: LanguageModelV2CallOptions["prompt"][number]["content"][number] + content: LanguageModelV3CallOptions["prompt"][number]["content"][number] ): unknown => { if (typeof content === "string") { return { @@ -33,18 +34,6 @@ const handlePromptContent = ( } if (content.type === "tool-result") { - const output = content.output; - - // Check for unsupported media content - if ( - output.type === "content" && - output.value.find((item) => item.type === "media") - ) { - throw new Error( - `Unsupported content type: media in tool-result. Not supported yet.` - ); - } - return { type: "tool-result" as const, toolCallId: content.toolCallId, @@ -53,14 +42,14 @@ const handlePromptContent = ( }; } - // Unsupported content types are image and file + // Unsupported content types (file, reasoning, tool-approval-response, etc.) throw new Error( `Unsupported content type: ${content.type}. Not supported yet.` ); }; const processPromptForTracing = ( - prompt: LanguageModelV2CallOptions["prompt"] + prompt: LanguageModelV3CallOptions["prompt"] ) => { return prompt.map((prompt) => { if (!Array.isArray(prompt.content)) { @@ -81,17 +70,31 @@ const processPromptForTracing = ( const fixCacheResponse = ( obj: any -): Awaited> => { +): Awaited> => { if (obj?.response?.timestamp) { obj.response.timestamp = new Date(obj.response.timestamp); } - return obj as Awaited>; + return obj as Awaited>; +}; + +const getModelId = (model: LanguageModel): string => { + if (typeof model === "string") return model; + return model.modelId; }; +const extractUsageForTrace = (usage: { + inputTokens: { total: number | undefined }; + outputTokens: { total: number | undefined }; +}) => ({ + inputTokens: usage.inputTokens.total ?? 0, + outputTokens: usage.outputTokens.total ?? 0, + totalTokens: (usage.inputTokens.total ?? 0) + (usage.outputTokens.total ?? 0), +}); + export const wrapAISDKModel = ( - model: LanguageModelV2, + model: LanguageModel, options?: { tracing?: boolean; caching?: boolean } -): LanguageModelV2 => { +): LanguageModel => { const enableTracing = options?.tracing ?? true; const enableCaching = options?.caching ?? true; @@ -100,9 +103,12 @@ export const wrapAISDKModel = ( return model; } + const modelId = getModelId(model); + return wrapLanguageModel({ - model, + model: model as LanguageModelV3, middleware: { + specificationVersion: "v3" as const, wrapGenerate: async (opts) => { const start = performance.now(); let result: Awaited> | undefined; @@ -111,7 +117,7 @@ export const wrapAISDKModel = ( // Try cache if enabled if (cacheContext) { const keyHash = generateCacheKey({ - model: model.modelId, + model: modelId, params: opts.params, callType: "generate", callParams: opts.params, @@ -138,9 +144,13 @@ export const wrapAISDKModel = ( ReturnType >; result.usage = { - inputTokens: 0, - outputTokens: 0, - totalTokens: 0, + inputTokens: { + total: 0, + noCache: 0, + cacheRead: 0, + cacheWrite: 0, + }, + outputTokens: { total: 0, text: 0, reasoning: 0 }, }; } } @@ -157,7 +167,7 @@ export const wrapAISDKModel = ( // Store in cache if caching enabled if (cacheContext) { const keyHash = generateCacheKey({ - model: model.modelId, + model: modelId, params: opts.params, callType: "generate", callParams: opts.params, @@ -213,11 +223,7 @@ export const wrapAISDKModel = ( toolCalls, }, input: processPromptForTracing(opts.params.prompt), - usage: { - inputTokens: result.usage.inputTokens ?? 0, - outputTokens: result.usage.outputTokens ?? 0, - totalTokens: result.usage.totalTokens ?? 0, - }, + usage: extractUsageForTrace(result.usage), start, end, }); @@ -227,7 +233,7 @@ export const wrapAISDKModel = ( }, wrapStream: async ({ doStream, params }) => { const start = performance.now(); - let cachedParts: LanguageModelV2StreamPart[] | undefined; + let cachedParts: LanguageModelV3StreamPart[] | undefined; const cacheContext = getCacheContext(); const reportTraceFromContext = reportTraceLocalStorage.getStore(); @@ -235,7 +241,7 @@ export const wrapAISDKModel = ( // Try cache if enabled if (cacheContext) { const keyHash = generateCacheKey({ - model: model.modelId, + model: modelId, params: params, callType: "stream", callParams: params, @@ -258,7 +264,7 @@ export const wrapAISDKModel = ( savedDuration: cached.duration, }); - cachedParts = cached.value as LanguageModelV2StreamPart[]; + cachedParts = cached.value as LanguageModelV3StreamPart[]; // If tracing enabled, report trace for cached stream if (reportTraceFromContext) { @@ -271,18 +277,12 @@ export const wrapAISDKModel = ( end: performance.now(), input: processPromptForTracing(params.prompt), output: cachedParts, - usage: usage - ? { - inputTokens: usage.inputTokens ?? 0, - outputTokens: usage.outputTokens ?? 0, - totalTokens: usage.totalTokens ?? 0, - } - : undefined, + usage: usage ? extractUsageForTrace(usage) : undefined, }); } // Reconstruct stream from cached parts - const stream = new ReadableStream({ + const stream = new ReadableStream({ async start(controller) { for (const part of cachedParts!) { controller.enqueue(part); @@ -306,11 +306,11 @@ export const wrapAISDKModel = ( // Execute stream if not cached { const { stream, ...rest } = await doStream(); - const fullResponse: LanguageModelV2StreamPart[] = []; + const fullResponse: LanguageModelV3StreamPart[] = []; const transformStream = new TransformStream< - LanguageModelV2StreamPart, - LanguageModelV2StreamPart + LanguageModelV3StreamPart, + LanguageModelV3StreamPart >({ transform(chunk, controller) { fullResponse.push(chunk); @@ -322,7 +322,7 @@ export const wrapAISDKModel = ( // Store in cache if enabled if (cacheContext) { const keyHash = generateCacheKey({ - model: model.modelId, + model: modelId, params: params, callType: "stream", callParams: params, @@ -362,13 +362,7 @@ export const wrapAISDKModel = ( end: performance.now(), input: processPromptForTracing(params.prompt), output: fullResponse, - usage: usage - ? { - inputTokens: usage.inputTokens ?? 0, - outputTokens: usage.outputTokens ?? 0, - totalTokens: usage.totalTokens ?? 0, - } - : undefined, + usage: usage ? extractUsageForTrace(usage) : undefined, }); } }, diff --git a/packages/evalite/src/types.ts b/packages/evalite/src/types.ts index 29208e3c..34f56161 100644 --- a/packages/evalite/src/types.ts +++ b/packages/evalite/src/types.ts @@ -1,4 +1,4 @@ -import type { EmbeddingModelV2, LanguageModelV2 } from "@ai-sdk/provider"; +import type { EmbeddingModel, LanguageModel } from "ai"; import type { ViteUserConfig } from "vitest/config"; import type { TestUserConfig } from "vitest/node"; @@ -898,7 +898,7 @@ export declare namespace Evalite { question: string; answer: string; groundTruth: string[]; - model: LanguageModelV2; + model: LanguageModel; }; /** @@ -908,8 +908,8 @@ export declare namespace Evalite { question: string; answer: string; reference: string; - model: LanguageModelV2; - embeddingModel: EmbeddingModelV2; + model: LanguageModel; + embeddingModel: EmbeddingModel; weights?: [number, number]; beta?: number; }; @@ -920,8 +920,8 @@ export declare namespace Evalite { export type AnswerRelevancyOpts = { question: string; answer: string; - model: LanguageModelV2; - embeddingModel: EmbeddingModelV2; + model: LanguageModel; + embeddingModel: EmbeddingModel; }; /** @@ -930,7 +930,7 @@ export declare namespace Evalite { export type AnswerSimilarityOpts = { answer: string; reference: string; - embeddingModel: EmbeddingModelV2; + embeddingModel: EmbeddingModel; }; /** @@ -940,7 +940,7 @@ export declare namespace Evalite { question: string; answer: string; groundTruth: string[]; - model: LanguageModelV2; + model: LanguageModel; }; /** @@ -951,7 +951,7 @@ export declare namespace Evalite { answer: string; reference: string; groundTruth: string[]; - model: LanguageModelV2; + model: LanguageModel; mode?: "relevant" | "irrelevant"; }; diff --git a/packages/example/package.json b/packages/example/package.json index e3e64857..07f8a5cc 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -12,9 +12,9 @@ "dependencies": { "unstorage": "^1.17.1", "evalite": "workspace:*", - "ai": "^5.0.59", - "@ai-sdk/openai": "^2.0.42", - "@ai-sdk/provider": "^2.0.0", + "ai": "^6", + "@ai-sdk/openai": "^3.0.0", + "@ai-sdk/provider": "^3.0.0", "dotenv": "^16.4.5", "zod": "^3.25.76", "vitest": "^4.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf550788..68c0244a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,8 +109,8 @@ importers: specifier: ^1.117.0 version: 1.117.0(@tanstack/react-router@1.117.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.1) ai: - specifier: ^5.0.89 - version: 5.0.92(zod@3.24.1) + specifier: ^6 + version: 6.0.94(zod@3.24.1) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -246,8 +246,8 @@ importers: version: 3.0.3 devDependencies: '@ai-sdk/provider': - specifier: ^2.0.0 - version: 2.0.0 + specifier: ^3.0.0 + version: 3.0.8 '@types/better-sqlite3': specifier: ^7.6.13 version: 7.6.13 @@ -258,8 +258,8 @@ importers: specifier: ^8.18.1 version: 8.18.1 ai: - specifier: ^5.0.59 - version: 5.0.59(zod@4.1.12) + specifier: ^6 + version: 6.0.94(zod@4.1.12) better-sqlite3: specifier: ^11.6.0 version: 11.6.0 @@ -270,11 +270,11 @@ importers: packages/evalite-tests: dependencies: '@ai-sdk/openai': - specifier: ^2.0.42 - version: 2.0.42(zod@4.1.12) + specifier: ^3.0.0 + version: 3.0.30(zod@4.1.12) ai: - specifier: ^5.0.59 - version: 5.0.59(zod@4.1.12) + specifier: ^6 + version: 6.0.94(zod@4.1.12) evalite: specifier: workspace:* version: link:../evalite @@ -288,14 +288,14 @@ importers: packages/example: dependencies: '@ai-sdk/openai': - specifier: ^2.0.42 - version: 2.0.42(zod@3.25.76) + specifier: ^3.0.0 + version: 3.0.30(zod@3.25.76) '@ai-sdk/provider': - specifier: ^2.0.0 - version: 2.0.0 + specifier: ^3.0.0 + version: 3.0.8 ai: - specifier: ^5.0.59 - version: 5.0.59(zod@3.25.76) + specifier: ^6 + version: 6.0.94(zod@3.25.76) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -314,38 +314,26 @@ importers: packages: - '@ai-sdk/gateway@1.0.32': - resolution: {integrity: sha512-TQRIM63EI/ccJBc7RxeB8nq/CnGNnyl7eu5stWdLwL41stkV5skVeZJe0QRvFbaOrwCkgUVE0yrUqJi4tgDC1A==} + '@ai-sdk/gateway@3.0.52': + resolution: {integrity: sha512-lYCXP8T3YnIDiz8DP7loAMT27wnblc3IAYzQ7igg89RCRyTUjk6ffbxHXXQ5Pmv8jrdLF0ZIJnH54Dsr1OCKHg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@2.0.8': - resolution: {integrity: sha512-cA5Sh5pjmsMOlzCxsX9B4bGB9qOn9/HRxKb8ry1OYmrXP3i1t34eZMHA7EVFoB09I41p0LPwkRBACYXm15xokw==} + '@ai-sdk/openai@3.0.30': + resolution: {integrity: sha512-YDht3t7TDyWKP+JYZp20VuYqSjyF2brHYh47GGFDUPf2wZiqNQ263ecL+quar2bP3GZ3BeQA8f0m2B7UwLPR+g==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/openai@2.0.42': - resolution: {integrity: sha512-9mM6QS8k0ooH9qMC27nlrYLQmNDnO6Rk0JTmFo/yUxpABEWOcvQhMWNHbp9lFL6Ty5vkdINrujhsAQfWuEleOg==} + '@ai-sdk/provider-utils@4.0.15': + resolution: {integrity: sha512-8XiKWbemmCbvNN0CLR9u3PQiet4gtEVIrX4zzLxnCj06AwsEDJwJVBbKrEI4t6qE8XRSIvU2irka0dcpziKW6w==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@3.0.10': - resolution: {integrity: sha512-T1gZ76gEIwffep6MWI0QNy9jgoybUHE7TRaHB5k54K8mF91ciGFlbtCGxDYhMH3nCRergKwYFIDeFF0hJSIQHQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider-utils@3.0.17': - resolution: {integrity: sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider@2.0.0': - resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} + '@ai-sdk/provider@3.0.8': + resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} engines: {node: '>=18'} '@ampproject/remapping@2.3.0': @@ -2372,6 +2360,9 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@stricli/auto-complete@1.2.0': resolution: {integrity: sha512-r9/msiloVmTF95mdhe04Uzqei1B0ZofhYRLeiPqpJ1W1RMCC8p9iW7kqBZEbALl2aRL5ZK9OEW3Q1cIejH7KEQ==} hasBin: true @@ -2865,8 +2856,8 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - '@vercel/oidc@3.0.3': - resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} engines: {node: '>= 20'} '@vitejs/plugin-react@4.3.4': @@ -2922,14 +2913,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - ai@5.0.59: - resolution: {integrity: sha512-SuAFxKXt2Ha9FiXB3gaOITkOg9ek/3QNVatGVExvTT4gNXc+hJpuNe1dmuwf6Z5Op4fzc8wdbsrYP27ZCXBzlw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - ai@5.0.92: - resolution: {integrity: sha512-EnPe3QXiD06Tg7iAt/oU3JSwedI1nuhEBnTjyfn1qTXaqmJ6qI4YG8wn/eBHRVXnmljDFDNYvGBC5pALYV1rAA==} + ai@6.0.94: + resolution: {integrity: sha512-/F9wh262HbK05b/5vILh38JvPiheonT+kBj1L97712E7VPchqmcx7aJuZN3QSk5Pj6knxUJLm2FFpYJI1pHXUA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -6348,59 +6333,61 @@ packages: snapshots: - '@ai-sdk/gateway@1.0.32(zod@3.25.76)': + '@ai-sdk/gateway@3.0.52(zod@3.24.1)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.10(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@3.24.1) + '@vercel/oidc': 3.1.0 + zod: 3.24.1 - '@ai-sdk/gateway@1.0.32(zod@4.1.12)': + '@ai-sdk/gateway@3.0.52(zod@3.25.76)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.10(zod@4.1.12) - zod: 4.1.12 + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@3.25.76) + '@vercel/oidc': 3.1.0 + zod: 3.25.76 - '@ai-sdk/gateway@2.0.8(zod@3.24.1)': + '@ai-sdk/gateway@3.0.52(zod@4.1.12)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@3.24.1) - '@vercel/oidc': 3.0.3 - zod: 3.24.1 + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@4.1.12) + '@vercel/oidc': 3.1.0 + zod: 4.1.12 - '@ai-sdk/openai@2.0.42(zod@3.25.76)': + '@ai-sdk/openai@3.0.30(zod@3.25.76)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.10(zod@3.25.76) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@3.25.76) zod: 3.25.76 - '@ai-sdk/openai@2.0.42(zod@4.1.12)': + '@ai-sdk/openai@3.0.30(zod@4.1.12)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.10(zod@4.1.12) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@4.1.12) zod: 4.1.12 - '@ai-sdk/provider-utils@3.0.10(zod@3.25.76)': + '@ai-sdk/provider-utils@4.0.15(zod@3.24.1)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@standard-schema/spec': 1.0.0 + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 eventsource-parser: 3.0.6 - zod: 3.25.76 + zod: 3.24.1 - '@ai-sdk/provider-utils@3.0.10(zod@4.1.12)': + '@ai-sdk/provider-utils@4.0.15(zod@3.25.76)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@standard-schema/spec': 1.0.0 + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 eventsource-parser: 3.0.6 - zod: 4.1.12 + zod: 3.25.76 - '@ai-sdk/provider-utils@3.0.17(zod@3.24.1)': + '@ai-sdk/provider-utils@4.0.15(zod@4.1.12)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@standard-schema/spec': 1.0.0 + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 eventsource-parser: 3.0.6 - zod: 3.24.1 + zod: 4.1.12 - '@ai-sdk/provider@2.0.0': + '@ai-sdk/provider@3.0.8': dependencies: json-schema: 0.4.0 @@ -8390,6 +8377,8 @@ snapshots: '@standard-schema/spec@1.0.0': {} + '@standard-schema/spec@1.1.0': {} + '@stricli/auto-complete@1.2.0': dependencies: '@stricli/core': 1.2.0 @@ -8934,7 +8923,7 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vercel/oidc@3.0.3': {} + '@vercel/oidc@3.1.0': {} '@vitejs/plugin-react@4.3.4(vite@7.1.12(@types/node@22.7.7)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.31.5)(tsx@4.19.3)(yaml@2.8.1))': dependencies: @@ -9001,29 +8990,29 @@ snapshots: acorn@8.15.0: {} - ai@5.0.59(zod@3.25.76): + ai@6.0.94(zod@3.24.1): dependencies: - '@ai-sdk/gateway': 1.0.32(zod@3.25.76) - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.10(zod@3.25.76) + '@ai-sdk/gateway': 3.0.52(zod@3.24.1) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@3.24.1) '@opentelemetry/api': 1.9.0 - zod: 3.25.76 + zod: 3.24.1 - ai@5.0.59(zod@4.1.12): + ai@6.0.94(zod@3.25.76): dependencies: - '@ai-sdk/gateway': 1.0.32(zod@4.1.12) - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.10(zod@4.1.12) + '@ai-sdk/gateway': 3.0.52(zod@3.25.76) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@3.25.76) '@opentelemetry/api': 1.9.0 - zod: 4.1.12 + zod: 3.25.76 - ai@5.0.92(zod@3.24.1): + ai@6.0.94(zod@4.1.12): dependencies: - '@ai-sdk/gateway': 2.0.8(zod@3.24.1) - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@3.24.1) + '@ai-sdk/gateway': 3.0.52(zod@4.1.12) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.15(zod@4.1.12) '@opentelemetry/api': 1.9.0 - zod: 3.24.1 + zod: 4.1.12 ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: From 11685f00ef64498472b39d1ab5e6f559afa624a4 Mon Sep 17 00:00:00 2001 From: Matt Pocock Date: Fri, 20 Feb 2026 11:38:57 +0000 Subject: [PATCH 2/3] RALPH: Migrate scorers to generateText + Output.object() and test fixtures to MockLanguageModelV3 (#380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task: Migrate all v5 API usage to v6 patterns per PRD #378. Key decisions: - Scorers: generateObject() → generateText() + Output.object(), result.object → result.output - Mocks: MockLanguageModelV2 → MockLanguageModelV3 with plain object doGenerate (not function) - Usage shape: V3 nested objects { inputTokens: { total }, outputTokens: { total } } - FinishReason: V3 object shape { unified: "stop", raw: undefined } - Removed obsolete rawCall, providerMetadata, request, response from mock fixtures Files changed: - packages/evalite/src/scorers/utils/statement-evaluation.ts (3 call sites) - packages/evalite/src/scorers/answer-correctness.ts (1 call site) - packages/evalite/src/scorers/answer-relevancy.ts (1 call site) - packages/evalite/src/scorers/context-recall.ts (1 call site) - packages/evalite-tests/tests/fixtures/ai-sdk-traces/traces.eval.ts - packages/evalite-tests/tests/fixtures/ai-sdk-caching/caching.eval.ts - packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-disabled/caching.eval.ts - packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-precedence/caching.eval.ts - packages/example/src/fake-models.eval.ts Blockers: #381 (docs + changeset) is now unblocked. Co-Authored-By: Claude Opus 4.6 --- .../caching.eval.ts | 46 +++++++++++-------- .../caching.eval.ts | 46 +++++++++++-------- .../fixtures/ai-sdk-caching/caching.eval.ts | 46 +++++++++++-------- .../fixtures/ai-sdk-traces/traces.eval.ts | 24 ++++++---- .../evalite/src/scorers/answer-correctness.ts | 14 ++++-- .../evalite/src/scorers/answer-relevancy.ts | 18 +++++--- .../evalite/src/scorers/context-recall.ts | 8 ++-- .../src/scorers/utils/statement-evaluation.ts | 20 ++++---- packages/example/src/fake-models.eval.ts | 46 +++++++++++-------- 9 files changed, 158 insertions(+), 110 deletions(-) diff --git a/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-disabled/caching.eval.ts b/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-disabled/caching.eval.ts index ecbd09c6..5cb12a5e 100644 --- a/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-disabled/caching.eval.ts +++ b/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-disabled/caching.eval.ts @@ -1,32 +1,40 @@ import { generateText } from "ai"; -import { MockLanguageModelV2 } from "ai/test"; +import { MockLanguageModelV3 } from "ai/test"; import { wrapAISDKModel } from "evalite/ai-sdk"; import { evalite } from "evalite"; -const model = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 10, outputTokens: 20, totalTokens: 30 }, +const model = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 10, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 20, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `Response for task` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); -const scorerModel = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 5, outputTokens: 10, totalTokens: 15 }, +const scorerModel = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 5, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 10, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `1` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); const tracedModel = wrapAISDKModel(model); diff --git a/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-precedence/caching.eval.ts b/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-precedence/caching.eval.ts index 48ea51db..051678de 100644 --- a/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-precedence/caching.eval.ts +++ b/packages/evalite-tests/tests/fixtures/ai-sdk-caching-config-precedence/caching.eval.ts @@ -1,32 +1,40 @@ import { generateText } from "ai"; -import { MockLanguageModelV2 } from "ai/test"; +import { MockLanguageModelV3 } from "ai/test"; import { wrapAISDKModel } from "evalite/ai-sdk"; import { evalite } from "evalite"; -const model = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 10, outputTokens: 20, totalTokens: 30 }, +const model = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 10, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 20, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `Response for task` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); -const scorerModel = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 5, outputTokens: 10, totalTokens: 15 }, +const scorerModel = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 5, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 10, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `1` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); const tracedModel = wrapAISDKModel(model); diff --git a/packages/evalite-tests/tests/fixtures/ai-sdk-caching/caching.eval.ts b/packages/evalite-tests/tests/fixtures/ai-sdk-caching/caching.eval.ts index 69d24d55..11e900e0 100644 --- a/packages/evalite-tests/tests/fixtures/ai-sdk-caching/caching.eval.ts +++ b/packages/evalite-tests/tests/fixtures/ai-sdk-caching/caching.eval.ts @@ -1,32 +1,40 @@ import { generateText } from "ai"; -import { MockLanguageModelV2 } from "ai/test"; +import { MockLanguageModelV3 } from "ai/test"; import { wrapAISDKModel } from "evalite/ai-sdk"; import { evalite } from "evalite"; -const model = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 10, outputTokens: 20, totalTokens: 30 }, +const model = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 10, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 20, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `Response for task` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); -const scorerModel = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 5, outputTokens: 10, totalTokens: 15 }, +const scorerModel = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 5, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 10, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `1` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); const tracedModel = wrapAISDKModel(model); diff --git a/packages/evalite-tests/tests/fixtures/ai-sdk-traces/traces.eval.ts b/packages/evalite-tests/tests/fixtures/ai-sdk-traces/traces.eval.ts index 1c39709e..e8fa5cb0 100644 --- a/packages/evalite-tests/tests/fixtures/ai-sdk-traces/traces.eval.ts +++ b/packages/evalite-tests/tests/fixtures/ai-sdk-traces/traces.eval.ts @@ -1,13 +1,20 @@ import { generateText } from "ai"; -import { MockLanguageModelV2 } from "ai/test"; +import { MockLanguageModelV3 } from "ai/test"; import { wrapAISDKModel } from "evalite/ai-sdk"; import { evalite } from "evalite"; -const model = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 10, outputTokens: 20, totalTokens: 35 }, +const model = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 10, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 20, text: undefined, reasoning: undefined }, + }, content: [ { type: "text", text: `Hello, world!` }, { @@ -18,10 +25,7 @@ const model = new MockLanguageModelV2({ }, ], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); const tracedModel = wrapAISDKModel(model); diff --git a/packages/evalite/src/scorers/answer-correctness.ts b/packages/evalite/src/scorers/answer-correctness.ts index 96839036..b4f98179 100644 --- a/packages/evalite/src/scorers/answer-correctness.ts +++ b/packages/evalite/src/scorers/answer-correctness.ts @@ -1,4 +1,10 @@ -import { cosineSimilarity, embedMany, generateObject, jsonSchema } from "ai"; +import { + cosineSimilarity, + embedMany, + generateText, + Output, + jsonSchema, +} from "ai"; import { wrapAISDKModel } from "../ai-sdk.js"; import type { Evalite } from "../types.js"; import { promptBuilder } from "./prompt-builder.js"; @@ -231,9 +237,9 @@ export async function answerCorrectness( }; if (responseStatements.length > 0 && referenceStatements.length > 0) { - const result = await generateObject({ + const result = await generateText({ model: cachedModel, - schema: AnswerCorrectnessClassificationSchema, + output: Output.object({ schema: AnswerCorrectnessClassificationSchema }), prompt: correctnessClassifierPrompt({ question: opts.question, answerStatements: responseStatements, @@ -241,7 +247,7 @@ export async function answerCorrectness( }), }); - classification = result.object.classification; + classification = result.output!.classification; factualityScore = computeFBetaScore(classification, beta); } else if ( responseStatements.length === 0 && diff --git a/packages/evalite/src/scorers/answer-relevancy.ts b/packages/evalite/src/scorers/answer-relevancy.ts index 59cc907d..c65e1ac3 100644 --- a/packages/evalite/src/scorers/answer-relevancy.ts +++ b/packages/evalite/src/scorers/answer-relevancy.ts @@ -1,4 +1,10 @@ -import { cosineSimilarity, embedMany, generateObject, jsonSchema } from "ai"; +import { + cosineSimilarity, + embedMany, + generateText, + Output, + jsonSchema, +} from "ai"; import { wrapAISDKModel } from "../ai-sdk.js"; import type { Evalite } from "../types.js"; import { promptBuilder } from "./prompt-builder.js"; @@ -110,15 +116,15 @@ export async function answerRelevancy( for (let i = 0; i < strictness; i++) { try { - const result = await generateObject({ + const result = await generateText({ model: cachedModel, - schema: AnswerRelevancyOutputSchema, + output: Output.object({ schema: AnswerRelevancyOutputSchema }), prompt: answerRelevancyPrompt({ response: opts.answer }), }); - if (result.object.question && result.object.question.trim()) { - generatedQuestions.push(result.object.question.trim()); - noncommittalFlags.push(result.object.noncommittal === 1); + if (result.output?.question && result.output.question.trim()) { + generatedQuestions.push(result.output.question.trim()); + noncommittalFlags.push(result.output.noncommittal === 1); } } catch (error) { console.warn( diff --git a/packages/evalite/src/scorers/context-recall.ts b/packages/evalite/src/scorers/context-recall.ts index 41407899..b7c162d2 100644 --- a/packages/evalite/src/scorers/context-recall.ts +++ b/packages/evalite/src/scorers/context-recall.ts @@ -1,4 +1,4 @@ -import { generateObject, jsonSchema } from "ai"; +import { generateText, Output, jsonSchema } from "ai"; import { wrapAISDKModel } from "../ai-sdk.js"; import type { Evalite } from "../types.js"; import { promptBuilder } from "./prompt-builder.js"; @@ -118,9 +118,9 @@ export async function contextRecall(opts: Evalite.Scorers.ContextRecallOpts) { const context = opts.groundTruth.join("\n"); - const result = await generateObject({ + const result = await generateText({ model: wrapAISDKModel(opts.model), - schema: ContextRecallClassificationsSchema, + output: Output.object({ schema: ContextRecallClassificationsSchema }), prompt: classifyStatementsPrompt({ question: opts.question, context, @@ -128,7 +128,7 @@ export async function contextRecall(opts: Evalite.Scorers.ContextRecallOpts) { }), }); - const classifications = result.object.classifications; + const classifications = result.output!.classifications; if (classifications.length === 0) { throw new Error("No classifications were found from the answer"); diff --git a/packages/evalite/src/scorers/utils/statement-evaluation.ts b/packages/evalite/src/scorers/utils/statement-evaluation.ts index c40dc595..7e328ab6 100644 --- a/packages/evalite/src/scorers/utils/statement-evaluation.ts +++ b/packages/evalite/src/scorers/utils/statement-evaluation.ts @@ -1,4 +1,4 @@ -import { generateObject, jsonSchema, type LanguageModel } from "ai"; +import { generateText, Output, jsonSchema, type LanguageModel } from "ai"; import { promptBuilder } from "../prompt-builder.js"; import type { Evalite } from "../../types.js"; @@ -227,13 +227,13 @@ export async function decomposeIntoStatements( answer: string, model: LanguageModel ): Promise { - const result = await generateObject({ + const result = await generateText({ model: model, - schema: StatementGeneratorOutputSchema, + output: Output.object({ schema: StatementGeneratorOutputSchema }), prompt: generateStatementsPrompt({ question, answer }), }); - return result.object.statements; + return result.output!.statements; } /** @@ -251,16 +251,16 @@ export async function evaluateStatementFaithfulness( statements: string[], model: LanguageModel ): Promise { - const result = await generateObject({ + const result = await generateText({ model: model, - schema: FaithfulnessStatementsOutputSchema, + output: Output.object({ schema: FaithfulnessStatementsOutputSchema }), prompt: evaluateStatementsPrompt({ context, statements: statements.map((s) => ({ statement: s })), }), }); - return result.object.statements.map((s) => ({ + return result.output!.statements.map((s) => ({ statement: s.statement, reason: s.reason, verdict: s.verdict, @@ -281,14 +281,14 @@ export async function evaluateStatementsSimple( statements: string[], model: LanguageModel ): Promise { - const result = await generateObject({ + const result = await generateText({ model: model, - schema: SimpleVerdictOutputSchema, + output: Output.object({ schema: SimpleVerdictOutputSchema }), prompt: simpleNLIPrompt({ context, statements, }), }); - return result.object.verdicts; + return result.output!.verdicts; } diff --git a/packages/example/src/fake-models.eval.ts b/packages/example/src/fake-models.eval.ts index 69d24d55..11e900e0 100644 --- a/packages/example/src/fake-models.eval.ts +++ b/packages/example/src/fake-models.eval.ts @@ -1,32 +1,40 @@ import { generateText } from "ai"; -import { MockLanguageModelV2 } from "ai/test"; +import { MockLanguageModelV3 } from "ai/test"; import { wrapAISDKModel } from "evalite/ai-sdk"; import { evalite } from "evalite"; -const model = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 10, outputTokens: 20, totalTokens: 30 }, +const model = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 10, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 20, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `Response for task` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); -const scorerModel = new MockLanguageModelV2({ - doGenerate: async (options) => ({ - rawCall: { rawPrompt: null, rawSettings: {} }, - finishReason: "stop", - usage: { inputTokens: 5, outputTokens: 10, totalTokens: 15 }, +const scorerModel = new MockLanguageModelV3({ + doGenerate: { + finishReason: { unified: "stop", raw: undefined }, + usage: { + inputTokens: { + total: 5, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { total: 10, text: undefined, reasoning: undefined }, + }, content: [{ type: "text", text: `1` }], warnings: [], - providerMetadata: undefined, - request: undefined, - response: undefined, - }), + }, }); const tracedModel = wrapAISDKModel(model); From 9ee7e17683b716e1d41c1e2118906581fad3ed5e Mon Sep 17 00:00:00 2001 From: Matt Pocock Date: Fri, 20 Feb 2026 11:55:55 +0000 Subject: [PATCH 3/3] RALPH: Update documentation for AI SDK v6 and add changeset (#381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task: Update docs to reflect v6 migration per PRD #378. Key decisions: - Type signature: LanguageModelV2 → LanguageModel (version-agnostic alias) - Structured output: generateObject/streamObject → generateText/streamText + Output.object() - tips/vercel-ai-sdk.mdx already v6-compatible, no changes needed - Minor version changeset for evalite package Files changed: - apps/evalite-docs/src/content/docs/api/ai-sdk.mdx - .changeset/0000-ai-sdk-v6.md Blockers: None. All #378 PRD tasks are now complete. Co-Authored-By: Claude Opus 4.6 --- .changeset/0000-ai-sdk-v6.md | 5 ++++ .../src/content/docs/api/ai-sdk.mdx | 24 ++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 .changeset/0000-ai-sdk-v6.md diff --git a/.changeset/0000-ai-sdk-v6.md b/.changeset/0000-ai-sdk-v6.md new file mode 100644 index 00000000..237b58a0 --- /dev/null +++ b/.changeset/0000-ai-sdk-v6.md @@ -0,0 +1,5 @@ +--- +"evalite": minor +--- + +Migrated AI SDK integration from v5 to v6. The `ai` peer dependency is now `^6` and `@ai-sdk/provider` is `^3`. Users on AI SDK v5 should stay on the previous Evalite version. diff --git a/apps/evalite-docs/src/content/docs/api/ai-sdk.mdx b/apps/evalite-docs/src/content/docs/api/ai-sdk.mdx index 399d5ccf..2d3ec89d 100644 --- a/apps/evalite-docs/src/content/docs/api/ai-sdk.mdx +++ b/apps/evalite-docs/src/content/docs/api/ai-sdk.mdx @@ -35,12 +35,12 @@ evalite("My Eval", { ```typescript wrapAISDKModel( - model: LanguageModelV2, + model: LanguageModel, options?: { tracing?: boolean; caching?: boolean; } -): LanguageModelV2 +): LanguageModel ``` **Parameters:** @@ -137,32 +137,34 @@ const result = await streamText({ const text = await result.text; ``` -**Generate Object:** +**Structured Output:** ```typescript -import { generateObject } from "ai"; +import { generateText, Output } from "ai"; import { z } from "zod"; -const result = await generateObject({ +const result = await generateText({ model: wrapAISDKModel(openai("gpt-4")), - schema: z.object({ name: z.string() }), + output: Output.object({ schema: z.object({ name: z.string() }) }), prompt: "Generate a person", }); + +const person = result.output; // { name: string } ``` -**Stream Object:** +**Streaming Structured Output:** ```typescript -import { streamObject } from "ai"; +import { streamText, Output } from "ai"; import { z } from "zod"; -const result = await streamObject({ +const result = streamText({ model: wrapAISDKModel(openai("gpt-4")), - schema: z.object({ name: z.string() }), + output: Output.object({ schema: z.object({ name: z.string() }) }), prompt: "Generate a person", }); -const object = await result.object; +const person = await result.output; // { name: string } ``` ## Behavior in Production