diff --git a/.changeset/dark-pans-carry.md b/.changeset/dark-pans-carry.md new file mode 100644 index 000000000..c5f3ab23c --- /dev/null +++ b/.changeset/dark-pans-carry.md @@ -0,0 +1,5 @@ +--- +"@browserbasehq/stagehand": patch +--- + +Add support for zod 4, while maintaining backwards compatibility for zod 3 diff --git a/packages/core/examples/2048.ts b/packages/core/examples/2048.ts index c97e96a87..5cb76b3d9 100644 --- a/packages/core/examples/2048.ts +++ b/packages/core/examples/2048.ts @@ -1,5 +1,5 @@ import { Stagehand } from "../lib/v3"; -import { z } from "zod/v3"; +import { z } from "zod"; async function example() { console.log("🎮 Starting 2048 bot..."); diff --git a/packages/core/examples/agent-custom-tools.ts b/packages/core/examples/agent-custom-tools.ts index 115c0f485..ad5d63dc9 100644 --- a/packages/core/examples/agent-custom-tools.ts +++ b/packages/core/examples/agent-custom-tools.ts @@ -1,7 +1,7 @@ /** * This example shows how to pass custom tools to stagehand agent (both CUA and non-CUA) */ -import { z } from "zod/v3"; +import { z } from "zod"; import { tool } from "ai"; import { Stagehand } from "../lib/v3"; import chalk from "chalk"; diff --git a/packages/core/examples/custom_client_aisdk.ts b/packages/core/examples/custom_client_aisdk.ts index 18cb76a46..7d7708574 100644 --- a/packages/core/examples/custom_client_aisdk.ts +++ b/packages/core/examples/custom_client_aisdk.ts @@ -7,7 +7,7 @@ */ import { Stagehand } from "../lib/v3"; import { AISdkClient } from "./external_clients/aisdk"; -import { z } from "zod/v3"; +import { z } from "zod"; import { openai } from "@ai-sdk/openai"; async function example() { diff --git a/packages/core/examples/custom_client_langchain.ts b/packages/core/examples/custom_client_langchain.ts index f15d0beb2..3f1f1c62f 100644 --- a/packages/core/examples/custom_client_langchain.ts +++ b/packages/core/examples/custom_client_langchain.ts @@ -3,15 +3,17 @@ * * You will need to reference the Langchain Client in /external_clients/langchain.ts */ -import { z } from "zod/v3"; +import { z } from "zod"; import { Stagehand } from "../lib/v3"; import { LangchainClient } from "./external_clients/langchain"; import { ChatOpenAI } from "@langchain/openai"; async function example() { + // @ts-expect-error Type instantiation is excessively deep and possibly infinite const stagehand = new Stagehand({ env: "BROWSERBASE", verbose: 1, + // @ts-expect-error Type instantiation is excessively deep and possibly infinite llmClient: new LangchainClient( new ChatOpenAI({ model: "gpt-4o", diff --git a/packages/core/examples/custom_client_openai.ts b/packages/core/examples/custom_client_openai.ts index 499d7db67..e92c4c4ba 100644 --- a/packages/core/examples/custom_client_openai.ts +++ b/packages/core/examples/custom_client_openai.ts @@ -6,7 +6,7 @@ * You will need to reference the Custom OpenAI Client in /external_clients/customOpenAI.ts */ import { Stagehand } from "../lib/v3"; -import { z } from "zod/v3"; +import { z } from "zod"; import { CustomOpenAIClient } from "./external_clients/customOpenAI"; import OpenAI from "openai"; diff --git a/packages/core/examples/external_clients/customOpenAI.ts b/packages/core/examples/external_clients/customOpenAI.ts index d43f37cc4..e8bf04f68 100644 --- a/packages/core/examples/external_clients/customOpenAI.ts +++ b/packages/core/examples/external_clients/customOpenAI.ts @@ -11,7 +11,6 @@ import { LLMClient, } from "../../lib/v3"; import OpenAI from "openai"; -import { zodResponseFormat } from "openai/helpers/zod"; import type { ChatCompletion, ChatCompletionAssistantMessageParam, @@ -22,10 +21,10 @@ import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, } from "openai/resources/chat/completions"; -import { z } from "zod/v3"; import { CreateChatCompletionResponseError } from "../../lib/v3"; +import { StagehandZodSchema, toJsonSchema } from "../../lib/v3/zodCompat"; -function validateZodSchema(schema: z.ZodTypeAny, data: unknown) { +function validateZodSchema(schema: StagehandZodSchema, data: unknown) { try { schema.parse(data); return true; @@ -83,12 +82,18 @@ export class CustomOpenAIClient extends LLMClient { ); } - let responseFormat = undefined; + let responseFormat: + | ChatCompletionCreateParamsNonStreaming["response_format"] + | undefined; if (options.response_model) { - responseFormat = zodResponseFormat( - options.response_model.schema, - options.response_model.name, - ); + const responseModelSchema = options.response_model.schema; + responseFormat = { + type: "json_schema", + json_schema: { + name: options.response_model.name, + schema: toJsonSchema(responseModelSchema), + }, + }; } /* eslint-disable */ diff --git a/packages/core/examples/external_clients/langchain.ts b/packages/core/examples/external_clients/langchain.ts index 8bb6b9566..7394daeb6 100644 --- a/packages/core/examples/external_clients/langchain.ts +++ b/packages/core/examples/external_clients/langchain.ts @@ -4,7 +4,6 @@ import { LLMClient, AvailableModel, } from "../../lib/v3"; -import { zodToJsonSchema } from "zod-to-json-schema"; import { AIMessage, BaseMessageLike, @@ -12,6 +11,7 @@ import { SystemMessage, } from "@langchain/core/messages"; import { ChatCompletion } from "openai/resources"; +import { toJsonSchema } from "../../lib/v3/zodCompat"; export class LangchainClient extends LLMClient { public type = "langchainClient" as const; @@ -60,9 +60,8 @@ export class LangchainClient extends LLMClient { ); if (options.response_model) { - const responseSchema = zodToJsonSchema(options.response_model.schema, { - $refStrategy: "none", - }); + //ref string no longer needed, this is now default behavior + const responseSchema = toJsonSchema(options.response_model.schema); const structuredModel = this.model.withStructuredOutput(responseSchema); const response = await structuredModel.invoke(formattedMessages); diff --git a/packages/core/examples/operator-example.ts b/packages/core/examples/operator-example.ts index d09ba63da..0bcc30aba 100644 --- a/packages/core/examples/operator-example.ts +++ b/packages/core/examples/operator-example.ts @@ -5,17 +5,14 @@ * * To learn more about Stagehand Agents, see: https://docs.stagehand.dev/concepts/agent */ - import { Stagehand } from "../lib/v3"; import dotenv from "dotenv"; import chalk from "chalk"; // Load environment variables dotenv.config(); - async function main() { console.log(`\n${chalk.bold("Stagehand 🤘 Operator Example")}\n`); - // Initialize Stagehand const stagehand = new Stagehand({ env: "LOCAL", @@ -48,5 +45,4 @@ async function main() { // await stagehand.close(); } } - main(); diff --git a/packages/core/examples/parameterizeApiKey.ts b/packages/core/examples/parameterizeApiKey.ts index afdeedec3..5da677321 100644 --- a/packages/core/examples/parameterizeApiKey.ts +++ b/packages/core/examples/parameterizeApiKey.ts @@ -1,5 +1,5 @@ import { Stagehand } from "../lib/v3"; -import { z } from "zod/v3"; +import { z } from "zod"; /** * This example shows how to parameterize the API key for the LLM provider. diff --git a/packages/core/examples/v3/patchright.ts b/packages/core/examples/v3/patchright.ts index 1b901b2bd..023cc726c 100644 --- a/packages/core/examples/v3/patchright.ts +++ b/packages/core/examples/v3/patchright.ts @@ -1,6 +1,6 @@ import { Stagehand } from "../../lib/v3"; import { chromium } from "patchright-core"; -import { z } from "zod/v3"; +import { z } from "zod"; async function example(stagehand: Stagehand) { const browser = await chromium.connectOverCDP({ diff --git a/packages/core/examples/v3/playwright.ts b/packages/core/examples/v3/playwright.ts index ea3ab5af7..dce44dc99 100644 --- a/packages/core/examples/v3/playwright.ts +++ b/packages/core/examples/v3/playwright.ts @@ -1,6 +1,6 @@ import { Stagehand } from "../../lib/v3"; import { chromium } from "playwright-core"; -import { z } from "zod/v3"; +import { z } from "zod"; async function example(stagehand: Stagehand) { const browser = await chromium.connectOverCDP({ diff --git a/packages/core/examples/v3/recordVideo.ts b/packages/core/examples/v3/recordVideo.ts index aa8e142b7..23c355874 100644 --- a/packages/core/examples/v3/recordVideo.ts +++ b/packages/core/examples/v3/recordVideo.ts @@ -2,7 +2,7 @@ import path from "node:path"; import { mkdir } from "node:fs/promises"; import { Stagehand } from "../../lib/v3"; import { chromium } from "playwright-core"; -import { z } from "zod/v3"; +import { z } from "zod"; async function recordPlaywrightVideo(stagehand: Stagehand): Promise { const browser = await chromium.connectOverCDP({ diff --git a/packages/core/examples/v3/targetedExtract.ts b/packages/core/examples/v3/targetedExtract.ts index cf6b6a4f8..c95c67a99 100644 --- a/packages/core/examples/v3/targetedExtract.ts +++ b/packages/core/examples/v3/targetedExtract.ts @@ -1,5 +1,5 @@ import { Stagehand } from "../../lib/v3"; -import { z } from "zod/v3"; +import { z } from "zod"; async function example(stagehand: Stagehand) { const page = stagehand.context.pages()[0]; diff --git a/packages/core/examples/v3_example.ts b/packages/core/examples/v3_example.ts index 9304e1b5a..a30f30e9d 100644 --- a/packages/core/examples/v3_example.ts +++ b/packages/core/examples/v3_example.ts @@ -1,5 +1,5 @@ import { V3 } from "../lib/v3"; -import { z } from "zod/v3"; +import { z } from "zod"; async function example(v3: V3) { const page = v3.context.pages()[0]; diff --git a/packages/core/lib/inference.ts b/packages/core/lib/inference.ts index 18ad40324..9b843e043 100644 --- a/packages/core/lib/inference.ts +++ b/packages/core/lib/inference.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { LogLine } from "./v3/types/public/logs"; import { ChatMessage, LLMClient } from "./v3/llm/LLMClient"; import { @@ -11,25 +11,12 @@ import { buildObserveUserMessage, } from "./prompt"; import { appendSummary, writeTimestampedTxtFile } from "./inferenceLogUtils"; +import type { InferStagehandSchema, StagehandZodObject } from "./v3/zodCompat"; -/** Simple usage shape if your LLM returns usage tokens. */ -interface LLMUsage { - prompt_tokens: number; - completion_tokens: number; - total_tokens: number; - reasoning_tokens?: number; - cached_input_tokens?: number; -} - -/** - * For calls that use a schema: the LLMClient may return { data: T; usage?: LLMUsage } - */ -export interface LLMParsedResponse { - data: T; - usage?: LLMUsage; -} +// Re-export for backward compatibility +export type { LLMParsedResponse, LLMUsage } from "./v3/llm/LLMClient"; -export async function extract({ +export async function extract({ instruction, domElements, schema, @@ -40,7 +27,7 @@ export async function extract({ }: { instruction: string; domElements: string; - schema: z.ZodObject; + schema: T; llmClient: LLMClient; userProvidedInstructions?: string; logger: (message: LogLine) => void; @@ -59,7 +46,7 @@ export async function extract({ ), }); - type ExtractionResponse = z.infer; + type ExtractionResponse = InferStagehandSchema; type MetadataResponse = z.infer; const isUsingAnthropic = llmClient.type === "anthropic"; @@ -103,8 +90,7 @@ export async function extract({ }); const extractEndTime = Date.now(); - const { data: extractedData, usage: extractUsage } = - extractionResponse as LLMParsedResponse; + const { data: extractedData, usage: extractUsage } = extractionResponse; let extractResponseFile = ""; if (logInferenceToFile) { @@ -175,7 +161,7 @@ export async function extract({ progress: metadataResponseProgress, }, usage: metadataResponseUsage, - } = metadataResponse as LLMParsedResponse; + } = metadataResponse; let metadataResponseFile = ""; if (logInferenceToFile) { @@ -322,8 +308,7 @@ export async function observe({ const end = Date.now(); const usageTimeMs = end - start; - const { data: observeData, usage: observeUsage } = - rawResponse as LLMParsedResponse; + const { data: observeData, usage: observeUsage } = rawResponse; const promptTokens = observeUsage?.prompt_tokens ?? 0; const completionTokens = observeUsage?.completion_tokens ?? 0; const reasoningTokens = observeUsage?.reasoning_tokens ?? 0; @@ -456,8 +441,7 @@ export async function act({ const end = Date.now(); const usageTimeMs = end - start; - const { data: actData, usage: actUsage } = - rawResponse as LLMParsedResponse; + const { data: actData, usage: actUsage } = rawResponse; const promptTokens = actUsage?.prompt_tokens ?? 0; const completionTokens = actUsage?.completion_tokens ?? 0; const reasoningTokens = actUsage?.reasoning_tokens ?? 0; diff --git a/packages/core/lib/utils.ts b/packages/core/lib/utils.ts index 476d99bf3..f6dfadad8 100644 --- a/packages/core/lib/utils.ts +++ b/packages/core/lib/utils.ts @@ -1,13 +1,207 @@ import { ZodSchemaValidationError } from "./v3/types/public/sdkErrors"; import { Schema, Type } from "@google/genai"; -import { ZodFirstPartyTypeKind as Kind, z, ZodTypeAny } from "zod/v3"; +import { z, ZodTypeAny } from "zod"; +import z3 from "zod/v3"; import { LogLine } from "./v3/types/public/logs"; import { ModelProvider } from "./v3/types/public/model"; import { ZodPathSegments } from "./v3/types/private/internal"; +import type { StagehandZodSchema } from "./v3/zodCompat"; +import { isZod4Schema } from "./v3/zodCompat"; const ID_PATTERN = /^\d+-\d+$/; -export function validateZodSchema(schema: z.ZodTypeAny, data: unknown) { +const zFactories = { + v4: z, + v3: z3 as unknown as typeof z, +}; + +function getZFactory(schema: StagehandZodSchema): typeof z { + return isZod4Schema(schema) ? zFactories.v4 : zFactories.v3; +} + +const TYPE_NAME_MAP: Record = { + ZodString: "string", + string: "string", + ZodNumber: "number", + number: "number", + ZodBoolean: "boolean", + boolean: "boolean", + ZodObject: "object", + object: "object", + ZodArray: "array", + array: "array", + ZodUnion: "union", + union: "union", + ZodIntersection: "intersection", + intersection: "intersection", + ZodOptional: "optional", + optional: "optional", + ZodNullable: "nullable", + nullable: "nullable", + ZodLiteral: "literal", + literal: "literal", + ZodEnum: "enum", + enum: "enum", + ZodDefault: "default", + default: "default", + ZodEffects: "effects", + effects: "effects", + pipe: "pipe", +}; + +function getZ4Def(schema: StagehandZodSchema) { + return (schema as SchemaInternals)._zod?.def as + | Record + | undefined; +} + +function getZ4Bag(schema: StagehandZodSchema) { + return (schema as SchemaInternals)._zod?.bag as + | Record + | undefined; +} + +function getZ3Def(schema: StagehandZodSchema) { + return (schema as SchemaInternals)._def as + | Record + | undefined; +} + +function getObjectShape( + schema: StagehandZodSchema, +): Record | undefined { + const z4Shape = getZ4Def(schema)?.shape as + | Record + | undefined; + if (z4Shape) { + return z4Shape; + } + + const z3Shape = getZ3Def(schema)?.shape; + if (!z3Shape) { + return undefined; + } + + if (typeof z3Shape === "function") { + return (z3Shape as () => Record)(); + } + + return z3Shape as Record; +} + +function getArrayElement( + schema: StagehandZodSchema, +): StagehandZodSchema | undefined { + return (getZ4Def(schema)?.element ?? getZ3Def(schema)?.type) as + | StagehandZodSchema + | undefined; +} + +function getInnerType( + schema: StagehandZodSchema, +): StagehandZodSchema | undefined { + return (getZ4Def(schema)?.innerType ?? getZ3Def(schema)?.innerType) as + | StagehandZodSchema + | undefined; +} + +function getUnionOptions( + schema: StagehandZodSchema, +): StagehandZodSchema[] | undefined { + const z4Options = getZ4Def(schema)?.options; + if (Array.isArray(z4Options)) { + return z4Options as StagehandZodSchema[]; + } + const z3Options = getZ3Def(schema)?.options; + return Array.isArray(z3Options) + ? (z3Options as StagehandZodSchema[]) + : undefined; +} + +function getIntersectionSides(schema: StagehandZodSchema): { + left?: StagehandZodSchema; + right?: StagehandZodSchema; +} { + const z4Def = getZ4Def(schema); + if (z4Def?.left || z4Def?.right) { + return { + left: z4Def?.left as StagehandZodSchema | undefined, + right: z4Def?.right as StagehandZodSchema | undefined, + }; + } + const z3Def = getZ3Def(schema); + return { + left: z3Def?.left as StagehandZodSchema | undefined, + right: z3Def?.right as StagehandZodSchema | undefined, + }; +} + +function getEnumValues(schema: StagehandZodSchema): string[] | undefined { + const z4Entries = getZ4Def(schema)?.entries; + if (z4Entries && typeof z4Entries === "object") { + return Object.values(z4Entries as Record); + } + const z3Values = getZ3Def(schema)?.values; + return Array.isArray(z3Values) ? (z3Values as string[]) : undefined; +} + +function getLiteralValues(schema: StagehandZodSchema): unknown[] { + const z4Values = getZ4Def(schema)?.values; + if (Array.isArray(z4Values)) { + return z4Values as unknown[]; + } + const value = getZ3Def(schema)?.value; + return typeof value !== "undefined" ? [value] : []; +} + +function getStringChecks(schema: StagehandZodSchema): unknown[] { + const z4Checks = getZ4Def(schema)?.checks; + if (Array.isArray(z4Checks)) { + return z4Checks; + } + const z3Checks = getZ3Def(schema)?.checks; + return Array.isArray(z3Checks) ? z3Checks : []; +} + +function getStringFormat(schema: StagehandZodSchema): string | undefined { + const bagFormat = getZ4Bag(schema)?.format; + if (typeof bagFormat === "string") { + return bagFormat; + } + const z4Format = getZ4Def(schema)?.format; + if (typeof z4Format === "string") { + return z4Format; + } + const z3Format = getZ3Def(schema)?.format; + return typeof z3Format === "string" ? z3Format : undefined; +} + +function getPipeEndpoints(schema: StagehandZodSchema): { + in?: StagehandZodSchema; + out?: StagehandZodSchema; +} { + const z4Def = getZ4Def(schema); + if (z4Def?.in || z4Def?.out) { + return { + in: z4Def?.in as StagehandZodSchema | undefined, + out: z4Def?.out as StagehandZodSchema | undefined, + }; + } + return {}; +} + +function getEffectsBaseSchema( + schema: StagehandZodSchema, +): StagehandZodSchema | undefined { + return getZ3Def(schema)?.schema as StagehandZodSchema | undefined; +} + +type SchemaInternals = { + _zod?: { def?: Record; bag?: Record }; + _def?: Record; +}; + +export function validateZodSchema(schema: StagehandZodSchema, data: unknown) { const result = schema.safeParse(data); if (result.success) { @@ -46,33 +240,35 @@ function decorateGeminiSchema( return geminiSchema; } -export function toGeminiSchema(zodSchema: z.ZodTypeAny): Schema { +export function toGeminiSchema(zodSchema: StagehandZodSchema): Schema { + const normalizedSchema = zodSchema as z.ZodTypeAny; const zodType = getZodType(zodSchema); - switch (zodType) { - case "ZodArray": { + case "array": { + const element = getArrayElement(zodSchema) ?? z.any(); return decorateGeminiSchema( { type: Type.ARRAY, - items: toGeminiSchema( - (zodSchema as z.ZodArray).element, - ), + items: toGeminiSchema(element), }, - zodSchema, + normalizedSchema, ); } - case "ZodObject": { + case "object": { const properties: Record = {}; const required: string[] = []; - Object.entries((zodSchema as z.ZodObject).shape).forEach( - ([key, value]: [string, z.ZodTypeAny]) => { - properties[key] = toGeminiSchema(value); - if (getZodType(value) !== "ZodOptional") { - required.push(key); - } - }, - ); + const shape = getObjectShape(zodSchema); + if (shape) { + Object.entries(shape).forEach( + ([key, value]: [string, StagehandZodSchema]) => { + properties[key] = toGeminiSchema(value); + if (getZodType(value) !== "optional") { + required.push(key); + } + }, + ); + } return decorateGeminiSchema( { @@ -80,72 +276,101 @@ export function toGeminiSchema(zodSchema: z.ZodTypeAny): Schema { properties, required: required.length > 0 ? required : undefined, }, - zodSchema, + normalizedSchema, ); } - case "ZodString": + case "string": return decorateGeminiSchema( { type: Type.STRING, }, - zodSchema, + normalizedSchema, ); - case "ZodNumber": + case "number": return decorateGeminiSchema( { type: Type.NUMBER, }, - zodSchema, + normalizedSchema, ); - case "ZodBoolean": + case "boolean": return decorateGeminiSchema( { type: Type.BOOLEAN, }, - zodSchema, + normalizedSchema, ); - case "ZodEnum": + case "enum": { + const values = getEnumValues(zodSchema); return decorateGeminiSchema( { type: Type.STRING, - enum: zodSchema._def.values, + enum: values, }, - zodSchema, + normalizedSchema, ); - case "ZodDefault": - case "ZodNullable": - case "ZodOptional": { - const innerSchema = toGeminiSchema(zodSchema._def.innerType); + } + case "default": + case "nullable": + case "optional": { + const innerType = getInnerType(zodSchema) ?? z.any(); + const innerSchema = toGeminiSchema(innerType); return decorateGeminiSchema( { ...innerSchema, nullable: true, }, - zodSchema, + normalizedSchema, + ); + } + case "literal": { + const values = getLiteralValues(zodSchema); + return decorateGeminiSchema( + { + type: Type.STRING, + enum: values as string[], + }, + normalizedSchema, ); } - case "ZodLiteral": + case "pipe": { + const endpoints = getPipeEndpoints(zodSchema); + if (endpoints.in) { + return toGeminiSchema(endpoints.in); + } return decorateGeminiSchema( { type: Type.STRING, - enum: [zodSchema._def.value], }, - zodSchema, + normalizedSchema, ); + } + // Standalone transforms and any unknown types fall through to default default: return decorateGeminiSchema( { - type: Type.OBJECT, - nullable: true, + type: Type.STRING, }, - zodSchema, + normalizedSchema, ); } } // Helper function to check the type of Zod schema -export function getZodType(schema: z.ZodTypeAny): string { - return schema._def.typeName; +export function getZodType(schema: StagehandZodSchema): string { + const schemaWithDef = schema as SchemaInternals & { + _zod?: { def?: { type?: string } }; + }; + const rawType = + (schemaWithDef._zod?.def?.type as string | undefined) ?? + (schemaWithDef._def?.typeName as string | undefined) ?? + (schemaWithDef._def?.type as string | undefined); + + if (!rawType) { + return "unknown"; + } + + return TYPE_NAME_MAP[rawType] ?? rawType; } /** @@ -162,83 +387,99 @@ export function getZodType(schema: z.ZodTypeAny): string { * 2. An array of {@link ZodPathSegments} objects representing each replaced field, including the path segments. */ export function transformSchema( - schema: z.ZodTypeAny, + schema: StagehandZodSchema, currentPath: Array, -): [z.ZodTypeAny, ZodPathSegments[]] { - // 1) If it's a string with .url(), convert to z.number() - if (isKind(schema, Kind.ZodString)) { +): [StagehandZodSchema, ZodPathSegments[]] { + if (isKind(schema, "string")) { + const checks = getStringChecks(schema); + const format = getStringFormat(schema); const hasUrlCheck = - schema._def.checks?.some( - (check: { kind: string }) => check.kind === "url", - ) ?? false; + checks.some((check) => { + const candidate = check as { + kind?: string; + format?: string; + _zod?: { def?: { check?: string; format?: string } }; + }; + return ( + candidate.kind === "url" || + candidate.format === "url" || + candidate._zod?.def?.check === "url" || + candidate._zod?.def?.format === "url" + ); + }) || format === "url"; + if (hasUrlCheck) { - return [makeIdStringSchema(schema as z.ZodString), [{ segments: [] }]]; + return [makeIdStringSchema(schema), [{ segments: [] }]]; } return [schema, []]; } - // 2) If it's an object, transform each field - if (isKind(schema, Kind.ZodObject)) { - // The shape is a raw object containing fields keyed by string (no symbols): - const shape = schema._def.shape() as Record; - const newShape: Record = {}; + if (isKind(schema, "object")) { + const shape = getObjectShape(schema); + if (!shape) { + return [schema, []]; + } + const newShape: Record = {}; const urlPaths: ZodPathSegments[] = []; let changed = false; - const shapeKeys = Object.keys(shape); - - for (const key of shapeKeys) { + for (const key of Object.keys(shape)) { const child = shape[key]; const [transformedChild, childPaths] = transformSchema(child, [ ...currentPath, key, ]); - if (transformedChild !== child) { changed = true; } newShape[key] = transformedChild; - - if (childPaths.length > 0) { - for (const cp of childPaths) { - urlPaths.push({ segments: [key, ...cp.segments] }); - } - } + childPaths.forEach((cp) => { + urlPaths.push({ segments: [key, ...cp.segments] }); + }); } if (changed) { - return [z.object(newShape), urlPaths]; + const factory = getZFactory(schema); + return [ + factory.object(newShape as Record), + urlPaths, + ]; } return [schema, urlPaths]; } - // 3) If it's an array, transform its item type - if (isKind(schema, Kind.ZodArray)) { - const itemType = schema._def.type as z.ZodTypeAny; + if (isKind(schema, "array")) { + const itemType = getArrayElement(schema); + if (!itemType) { + return [schema, []]; + } const [transformedItem, childPaths] = transformSchema(itemType, [ ...currentPath, "*", ]); - const changed = transformedItem !== itemType; const arrayPaths: ZodPathSegments[] = childPaths.map((cp) => ({ segments: ["*", ...cp.segments], })); - - if (changed) { - return [z.array(transformedItem), arrayPaths]; + if (transformedItem !== itemType) { + const factory = getZFactory(schema); + return [ + factory.array(transformedItem as unknown as z.ZodTypeAny), + arrayPaths, + ]; } return [schema, arrayPaths]; } - // 4) If it's a union, transform each option - if (isKind(schema, Kind.ZodUnion)) { - // Cast the union’s options to an array of ZodTypeAny - const unionOptions = schema._def.options as z.ZodTypeAny[]; - const newOptions: z.ZodTypeAny[] = []; + if (isKind(schema, "union")) { + const unionOptions = getUnionOptions(schema); + if (!unionOptions || unionOptions.length === 0) { + return [schema, []]; + } + const newOptions: StagehandZodSchema[] = []; let changed = false; let allPaths: ZodPathSegments[] = []; - unionOptions.forEach((option: z.ZodTypeAny, idx: number) => { + unionOptions.forEach((option, idx) => { const [newOption, childPaths] = transformSchema(option, [ ...currentPath, `union_${idx}`, @@ -251,67 +492,107 @@ export function transformSchema( }); if (changed) { - // We assume at least two options remain: + const factory = getZFactory(schema); return [ - z.union(newOptions as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]), + factory.union( + newOptions as unknown as [ + z.ZodTypeAny, + z.ZodTypeAny, + ...z.ZodTypeAny[], + ], + ), allPaths, ]; } return [schema, allPaths]; } - // 5) If it's an intersection, transform left and right - if (isKind(schema, Kind.ZodIntersection)) { - const leftType = schema._def.left as z.ZodTypeAny; - const rightType = schema._def.right as z.ZodTypeAny; - - const [left, leftPaths] = transformSchema(leftType, [ + if (isKind(schema, "intersection")) { + const { left, right } = getIntersectionSides(schema); + if (!left || !right) { + return [schema, []]; + } + const [newLeft, leftPaths] = transformSchema(left, [ ...currentPath, "intersection_left", ]); - const [right, rightPaths] = transformSchema(rightType, [ + const [newRight, rightPaths] = transformSchema(right, [ ...currentPath, "intersection_right", ]); - const changed = left !== leftType || right !== rightType; + const changed = newLeft !== left || newRight !== right; const allPaths = [...leftPaths, ...rightPaths]; if (changed) { - return [z.intersection(left, right), allPaths]; + const factory = getZFactory(schema); + return [ + factory.intersection( + newLeft as unknown as z.ZodTypeAny, + newRight as unknown as z.ZodTypeAny, + ), + allPaths, + ]; } return [schema, allPaths]; } - // 6) If it's optional, transform inner - if (isKind(schema, Kind.ZodOptional)) { - const innerType = schema._def.innerType as z.ZodTypeAny; + if (isKind(schema, "optional")) { + const innerType = getInnerType(schema); + if (!innerType) { + return [schema, []]; + } const [inner, innerPaths] = transformSchema(innerType, currentPath); if (inner !== innerType) { - return [z.optional(inner), innerPaths]; + return [ + (inner as z.ZodTypeAny).optional() as unknown as StagehandZodSchema, + innerPaths, + ]; } return [schema, innerPaths]; } - // 7) If it's nullable, transform inner - if (isKind(schema, Kind.ZodNullable)) { - const innerType = schema._def.innerType as z.ZodTypeAny; + if (isKind(schema, "nullable")) { + const innerType = getInnerType(schema); + if (!innerType) { + return [schema, []]; + } const [inner, innerPaths] = transformSchema(innerType, currentPath); if (inner !== innerType) { - return [z.nullable(inner), innerPaths]; + return [ + (inner as z.ZodTypeAny).nullable() as unknown as StagehandZodSchema, + innerPaths, + ]; } return [schema, innerPaths]; } - // 8) If it's an effect, transform base schema - if (isKind(schema, Kind.ZodEffects)) { - const baseSchema = schema._def.schema as z.ZodTypeAny; - const [newBaseSchema, basePaths] = transformSchema(baseSchema, currentPath); - if (newBaseSchema !== baseSchema) { - return [z.effect(newBaseSchema, schema._def.effect), basePaths]; + if (isKind(schema, "pipe") && isZod4Schema(schema)) { + const { in: inSchema, out: outSchema } = getPipeEndpoints(schema); + if (!inSchema || !outSchema) { + return [schema, []]; } - return [schema, basePaths]; + + const [newIn, inPaths] = transformSchema(inSchema, currentPath); + const [newOut, outPaths] = transformSchema(outSchema, currentPath); + const allPaths = [...inPaths, ...outPaths]; + + if (newIn !== inSchema || newOut !== outSchema) { + const result = z.pipe( + newIn as unknown as z.ZodTypeAny, + newOut as unknown as z.ZodTypeAny, + ) as StagehandZodSchema; + return [result, allPaths]; + } + return [schema, allPaths]; + } + + if (isKind(schema, "effects")) { + const baseSchema = getEffectsBaseSchema(schema); + if (!baseSchema) { + return [schema, []]; + } + return transformSchema(baseSchema, currentPath); } - // 9) If none of the above, return as-is return [schema, []]; } @@ -368,17 +649,18 @@ export function injectUrls( } } -function isKind(s: z.ZodTypeAny, kind: Kind): boolean { - return (s as z.ZodTypeAny)._def.typeName === kind; +// Helper to check if a schema is of a specific type +function isKind(s: StagehandZodSchema, kind: string): boolean { + try { + return getZodType(s) === kind; + } catch { + return false; + } } -function makeIdStringSchema(orig: z.ZodString): z.ZodString { +function makeIdStringSchema(orig: StagehandZodSchema): StagehandZodSchema { const userDesc = - // Zod ≥3.23 exposes .description directly; fall back to _def for older minor versions - (orig as unknown as { description?: string }).description ?? - (orig as unknown as { _def?: { description?: string } })._def - ?.description ?? - ""; + (orig as unknown as { description?: string }).description ?? ""; const base = "This field must be the element-ID in the form 'frameId-backendId' " + @@ -388,7 +670,8 @@ function makeIdStringSchema(orig: z.ZodString): z.ZodString { ? `${base} that follows this user-defined description: ${userDesc}` : base; - return z.string().regex(ID_PATTERN).describe(composed); + const factory = getZFactory(orig); + return factory.string().regex(ID_PATTERN).describe(composed); } /** @@ -464,6 +747,7 @@ export interface JsonSchemaProperty { minimum?: number; maximum?: number; description?: string; + format?: string; // JSON Schema format field (e.g., "uri", "url", "email", etc.) } export interface JsonSchema extends JsonSchemaProperty { type: string; @@ -512,6 +796,17 @@ export function jsonSchemaToZod(schema: JsonSchema): ZodTypeAny { return z.string().refine((val) => schema.enum!.includes(val)); } let zodString = z.string(); + + // Handle JSON Schema format field + if (schema.format === "uri" || schema.format === "url") { + zodString = zodString.url(); + } else if (schema.format === "email") { + zodString = zodString.email(); + } else if (schema.format === "uuid") { + zodString = zodString.uuid(); + } + // Add more format handlers as needed + if (schema.description) { zodString = zodString.describe(schema.description); } diff --git a/packages/core/lib/v3/agent/AnthropicCUAClient.ts b/packages/core/lib/v3/agent/AnthropicCUAClient.ts index d30905e03..62947f531 100644 --- a/packages/core/lib/v3/agent/AnthropicCUAClient.ts +++ b/packages/core/lib/v3/agent/AnthropicCUAClient.ts @@ -13,11 +13,11 @@ import { LogLine } from "../types/public/logs"; import { AgentScreenshotProviderError } from "../types/public/sdkErrors"; import Anthropic from "@anthropic-ai/sdk"; import { ToolSet } from "ai"; -import { zodToJsonSchema } from "zod-to-json-schema"; -import { z } from "zod/v3"; import { AgentClient } from "./AgentClient"; import { mapKeyToPlaywright } from "./utils/cuaKeyMapping"; import { compressConversationImages } from "./utils/imageCompression"; +import { toJsonSchema } from "../zodCompat"; +import type { StagehandZodSchema } from "../zodCompat"; export type ResponseInputItem = AnthropicMessage | AnthropicToolResult; @@ -443,8 +443,10 @@ export class AnthropicCUAClient extends AgentClient { // Add custom tools if available if (this.tools && Object.keys(this.tools).length > 0) { const customTools = Object.entries(this.tools).map(([name, tool]) => { + const schema = tool.inputSchema as StagehandZodSchema; + // Convert Zod schema to proper JSON schema format for Anthropic - const jsonSchema = zodToJsonSchema(tool.inputSchema as z.ZodType) as { + const jsonSchema = toJsonSchema(schema) as { properties?: Record; required?: string[]; }; diff --git a/packages/core/lib/v3/agent/tools/v3-act.ts b/packages/core/lib/v3/agent/tools/v3-act.ts index ab66d279a..d05f84239 100644 --- a/packages/core/lib/v3/agent/tools/v3-act.ts +++ b/packages/core/lib/v3/agent/tools/v3-act.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; import type { Action } from "../../types/public/methods"; diff --git a/packages/core/lib/v3/agent/tools/v3-ariaTree.ts b/packages/core/lib/v3/agent/tools/v3-ariaTree.ts index 252a23eda..82c883ae8 100644 --- a/packages/core/lib/v3/agent/tools/v3-ariaTree.ts +++ b/packages/core/lib/v3/agent/tools/v3-ariaTree.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; export const createAriaTreeTool = (v3: V3) => diff --git a/packages/core/lib/v3/agent/tools/v3-close.ts b/packages/core/lib/v3/agent/tools/v3-close.ts index 4f492787c..258d92724 100644 --- a/packages/core/lib/v3/agent/tools/v3-close.ts +++ b/packages/core/lib/v3/agent/tools/v3-close.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; export const createCloseTool = () => tool({ diff --git a/packages/core/lib/v3/agent/tools/v3-extract.ts b/packages/core/lib/v3/agent/tools/v3-extract.ts index 542b9af54..eece9fa7f 100644 --- a/packages/core/lib/v3/agent/tools/v3-extract.ts +++ b/packages/core/lib/v3/agent/tools/v3-extract.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; import type { LogLine } from "../../types/public/logs"; function evaluateZodSchema( diff --git a/packages/core/lib/v3/agent/tools/v3-fillform.ts b/packages/core/lib/v3/agent/tools/v3-fillform.ts index 8059f40fe..5be1e13be 100644 --- a/packages/core/lib/v3/agent/tools/v3-fillform.ts +++ b/packages/core/lib/v3/agent/tools/v3-fillform.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; import type { Action } from "../../types/public/methods"; diff --git a/packages/core/lib/v3/agent/tools/v3-goto.ts b/packages/core/lib/v3/agent/tools/v3-goto.ts index 45dcf49b5..3093977e1 100644 --- a/packages/core/lib/v3/agent/tools/v3-goto.ts +++ b/packages/core/lib/v3/agent/tools/v3-goto.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; export const createGotoTool = (v3: V3) => diff --git a/packages/core/lib/v3/agent/tools/v3-navback.ts b/packages/core/lib/v3/agent/tools/v3-navback.ts index 3b9e3b105..2d9abba45 100644 --- a/packages/core/lib/v3/agent/tools/v3-navback.ts +++ b/packages/core/lib/v3/agent/tools/v3-navback.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; export const createNavBackTool = (v3: V3) => diff --git a/packages/core/lib/v3/agent/tools/v3-screenshot.ts b/packages/core/lib/v3/agent/tools/v3-screenshot.ts index 3ebcca546..1ef81cf90 100644 --- a/packages/core/lib/v3/agent/tools/v3-screenshot.ts +++ b/packages/core/lib/v3/agent/tools/v3-screenshot.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; export const createScreenshotTool = (v3: V3) => diff --git a/packages/core/lib/v3/agent/tools/v3-scroll.ts b/packages/core/lib/v3/agent/tools/v3-scroll.ts index 311a4ed75..65229b495 100644 --- a/packages/core/lib/v3/agent/tools/v3-scroll.ts +++ b/packages/core/lib/v3/agent/tools/v3-scroll.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; export const createScrollTool = (v3: V3) => diff --git a/packages/core/lib/v3/agent/tools/v3-wait.ts b/packages/core/lib/v3/agent/tools/v3-wait.ts index 2d6de2f63..567ad8ead 100644 --- a/packages/core/lib/v3/agent/tools/v3-wait.ts +++ b/packages/core/lib/v3/agent/tools/v3-wait.ts @@ -1,5 +1,5 @@ import { tool } from "ai"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { V3 } from "../../v3"; export const createWaitTool = (v3: V3) => diff --git a/packages/core/lib/v3/agent/utils/googleCustomToolHandler.ts b/packages/core/lib/v3/agent/utils/googleCustomToolHandler.ts index 3343c775b..7766c5d02 100644 --- a/packages/core/lib/v3/agent/utils/googleCustomToolHandler.ts +++ b/packages/core/lib/v3/agent/utils/googleCustomToolHandler.ts @@ -1,8 +1,8 @@ import { Part, FunctionCall, FunctionDeclaration, Type } from "@google/genai"; import { ToolSet } from "ai"; import { LogLine } from "../../types/public/logs"; -import { zodToJsonSchema } from "zod-to-json-schema"; -import { z } from "zod/v3"; +import { toJsonSchema } from "../../zodCompat"; +import type { StagehandZodSchema } from "../../zodCompat"; /** * Result of executing a custom tool for Google CUA @@ -122,7 +122,8 @@ function convertToolToFunctionDeclaration( ): FunctionDeclaration | null { try { // Convert Zod schema to JSON schema - const jsonSchema = zodToJsonSchema(tool.inputSchema as z.ZodType) as { + const schema = tool.inputSchema as StagehandZodSchema; + const jsonSchema = toJsonSchema(schema) as { properties?: Record; required?: string[]; type?: string; diff --git a/packages/core/lib/v3/api.ts b/packages/core/lib/v3/api.ts index 996be1629..e873db32b 100644 --- a/packages/core/lib/v3/api.ts +++ b/packages/core/lib/v3/api.ts @@ -1,6 +1,4 @@ import makeFetchCookie from "fetch-cookie"; -import zodToJsonSchema from "zod-to-json-schema"; -import z from "zod/v3"; import { Action } from "./types/public"; import { STAGEHAND_VERSION } from "../version"; import { @@ -30,6 +28,8 @@ import { ExperimentalNotConfiguredError, } from "./types/public"; import type { SerializableResponse } from "./types/private"; +import { toJsonSchema } from "./zodCompat"; +import type { StagehandZodSchema } from "./zodCompat"; /** * API response structure for replay metrics endpoint @@ -157,13 +157,13 @@ export class StagehandAPIClient { }); } - async extract({ + async extract({ instruction, schema: zodSchema, options, frameId, }: APIExtractParameters): Promise> { - const jsonSchema = zodSchema ? zodToJsonSchema(zodSchema) : undefined; + const jsonSchema = zodSchema ? toJsonSchema(zodSchema) : undefined; const args: Record = { schema: jsonSchema, diff --git a/packages/core/lib/v3/handlers/extractHandler.ts b/packages/core/lib/v3/handlers/extractHandler.ts index bb77b114d..20d8282a0 100644 --- a/packages/core/lib/v3/handlers/extractHandler.ts +++ b/packages/core/lib/v3/handlers/extractHandler.ts @@ -1,10 +1,11 @@ // lib/v3/handlers/extractHandler.ts import { extract as runExtract } from "../../inference"; -import { injectUrls, transformSchema } from "../../utils"; +import { getZodType, injectUrls, transformSchema } from "../../utils"; import { v3Logger } from "../logger"; import { V3FunctionName } from "../types/public/methods"; import { captureHybridSnapshot } from "../understudy/a11y/snapshot"; -import { z, ZodTypeAny } from "zod/v3"; +import { z } from "zod"; +import type { ZodTypeAny } from "zod"; import { LLMClient } from "../llm/LLMClient"; import { ExtractHandlerParams } from "../types/private/handlers"; import { EncodedId, ZodPathSegments } from "../types/private/internal"; @@ -15,6 +16,11 @@ import { ModelConfiguration, } from "../types/public/model"; import { StagehandInvalidArgumentError } from "../types/public/sdkErrors"; +import type { + InferStagehandSchema, + StagehandZodObject, + StagehandZodSchema, +} from "../zodCompat"; /** * Scans the provided Zod schema for any `z.string().url()` fields and @@ -26,11 +32,11 @@ import { StagehandInvalidArgumentError } from "../types/public/sdkErrors"; * 2. An array of {@link ZodPathSegments} objects representing all the replaced URL fields, * with each path segment showing where in the schema the replacement occurred. */ -export function transformUrlStringsToNumericIds( +export function transformUrlStringsToNumericIds( schema: T, -): [T, ZodPathSegments[]] { +): [StagehandZodSchema, ZodPathSegments[]] { const [finalSchema, urlPaths] = transformSchema(schema, []); - return [finalSchema as T, urlPaths]; + return [finalSchema, urlPaths]; } interface ExtractionResponseBase { @@ -42,8 +48,8 @@ interface ExtractionResponseBase { inference_time_ms: number; } -type ExtractionResponse = ExtractionResponseBase & - z.infer; +type ExtractionResponse = ExtractionResponseBase & + InferStagehandSchema; export class ExtractHandler { private readonly llmClient: LLMClient; @@ -89,14 +95,16 @@ export class ExtractHandler { this.onMetrics = onMetrics; } - async extract( + async extract( params: ExtractHandlerParams, - ): Promise | { pageText: string }> { + ): Promise | { pageText: string }> { const { instruction, schema, page, selector, timeout, model } = params; const llmClient = this.resolveLlmClient(model); - const doExtract = async (): Promise | { pageText: string }> => { + const doExtract = async (): Promise< + InferStagehandSchema | { pageText: string } + > => { // No-args → page text (parity with v2) const noArgs = !instruction && !schema; if (noArgs) { @@ -138,29 +146,30 @@ export class ExtractHandler { }); // Normalize schema: if instruction provided without schema, use defaultExtractSchema - const baseSchema: ZodTypeAny = (schema ?? - defaultExtractSchema) as ZodTypeAny; + const baseSchema: StagehandZodSchema = (schema ?? + defaultExtractSchema) as StagehandZodSchema; // Ensure we pass an object schema into inference; wrap non-object schemas - const isObjectSchema = !!( - baseSchema as unknown as { _def?: { shape?: unknown } } - )._def?.shape; + const isObjectSchema = getZodType(baseSchema) === "object"; const WRAP_KEY = "value" as const; - const objectSchema = isObjectSchema - ? (baseSchema as unknown as z.ZodObject) - : z.object({ [WRAP_KEY]: baseSchema }); + const objectSchema: StagehandZodObject = isObjectSchema + ? (baseSchema as StagehandZodObject) + : (z.object({ + [WRAP_KEY]: baseSchema as unknown as ZodTypeAny, + }) as StagehandZodObject); const [transformedSchema, urlFieldPaths] = transformUrlStringsToNumericIds(objectSchema); - const extractionResponse = (await runExtract({ - instruction, - domElements: combinedTree, - schema: transformedSchema as z.ZodObject, - llmClient, - userProvidedInstructions: this.systemPrompt, - logger: v3Logger, - logInferenceToFile: this.logInferenceToFile, - })) as ExtractionResponse>; + const extractionResponse: ExtractionResponse = + await runExtract({ + instruction, + domElements: combinedTree, + schema: transformedSchema as StagehandZodObject, + llmClient, + userProvidedInstructions: this.systemPrompt, + logger: v3Logger, + logInferenceToFile: this.logInferenceToFile, + }); const { metadata: { completed }, @@ -171,7 +180,7 @@ export class ExtractHandler { inference_time_ms, ...rest } = extractionResponse; - let output: unknown = rest; + let output = rest as InferStagehandSchema; v3Logger({ category: "extraction", @@ -218,18 +227,20 @@ export class ExtractHandler { output = (output as Record)[WRAP_KEY]; } - return output as z.infer; + return output as InferStagehandSchema; }; if (!timeout) return doExtract(); return await Promise.race([ doExtract(), - new Promise | { pageText: string }>((_, reject) => { - setTimeout( - () => reject(new Error(`extract() timed out after ${timeout}ms`)), - timeout, - ); - }), + new Promise | { pageText: string }>( + (_, reject) => { + setTimeout( + () => reject(new Error(`extract() timed out after ${timeout}ms`)), + timeout, + ); + }, + ), ]); } } diff --git a/packages/core/lib/v3/index.ts b/packages/core/lib/v3/index.ts index 838e15298..ad799c2df 100644 --- a/packages/core/lib/v3/index.ts +++ b/packages/core/lib/v3/index.ts @@ -6,5 +6,6 @@ export * from "./llm/LLMClient"; export * from "./types/public"; export * from "./agent/AgentProvider"; export * from "../utils"; +export * from "./zodCompat"; export { connectToMCPServer } from "./mcp/connection"; export { V3Evaluator } from "../v3Evaluator"; diff --git a/packages/core/lib/v3/llm/AnthropicClient.ts b/packages/core/lib/v3/llm/AnthropicClient.ts index 2a06e8219..90b10035e 100644 --- a/packages/core/lib/v3/llm/AnthropicClient.ts +++ b/packages/core/lib/v3/llm/AnthropicClient.ts @@ -5,7 +5,6 @@ import { TextBlockParam, Tool, } from "@anthropic-ai/sdk/resources"; -import { zodToJsonSchema } from "zod-to-json-schema"; import { LogLine } from "../types/public/logs"; import { AnthropicJsonSchemaObject, @@ -17,6 +16,7 @@ import { LLMResponse, } from "./LLMClient"; import { CreateChatCompletionResponseError } from "../types/public/sdkErrors"; +import { toJsonSchema } from "../zodCompat"; export class AnthropicClient extends LLMClient { public type = "anthropic" as const; @@ -145,7 +145,7 @@ export class AnthropicClient extends LLMClient { let toolDefinition: Tool | undefined; if (options.response_model) { - const jsonSchema = zodToJsonSchema(options.response_model.schema); + const jsonSchema = toJsonSchema(options.response_model.schema); const { properties: schemaProperties, required: schemaRequired } = extractSchemaProperties(jsonSchema); diff --git a/packages/core/lib/v3/llm/CerebrasClient.ts b/packages/core/lib/v3/llm/CerebrasClient.ts index cfbc56051..281ce5be4 100644 --- a/packages/core/lib/v3/llm/CerebrasClient.ts +++ b/packages/core/lib/v3/llm/CerebrasClient.ts @@ -1,6 +1,5 @@ import OpenAI from "openai"; import type { ClientOptions } from "openai"; -import { zodToJsonSchema } from "zod-to-json-schema"; import { LogLine } from "../types/public/logs"; import { AvailableModel } from "../types/public/model"; import { @@ -10,6 +9,7 @@ import { LLMResponse, } from "./LLMClient"; import { CreateChatCompletionResponseError } from "../types/public/sdkErrors"; +import { toJsonSchema } from "../zodCompat"; export class CerebrasClient extends LLMClient { public type = "cerebras" as const; @@ -100,7 +100,7 @@ export class CerebrasClient extends LLMClient { // Add response model as a tool if provided if (options.response_model) { - const jsonSchema = zodToJsonSchema(options.response_model.schema) as { + const jsonSchema = toJsonSchema(options.response_model.schema) as { properties?: Record; required?: string[]; }; diff --git a/packages/core/lib/v3/llm/GroqClient.ts b/packages/core/lib/v3/llm/GroqClient.ts index af967295e..e4cff6266 100644 --- a/packages/core/lib/v3/llm/GroqClient.ts +++ b/packages/core/lib/v3/llm/GroqClient.ts @@ -1,6 +1,5 @@ import type { ClientOptions } from "openai"; import OpenAI from "openai"; -import { zodToJsonSchema } from "zod-to-json-schema"; import { LogLine } from "../types/public/logs"; import { AvailableModel } from "../types/public/model"; import { @@ -10,6 +9,7 @@ import { LLMResponse, } from "./LLMClient"; import { CreateChatCompletionResponseError } from "../types/public/sdkErrors"; +import { toJsonSchema } from "../zodCompat"; export class GroqClient extends LLMClient { public type = "groq" as const; @@ -100,7 +100,7 @@ export class GroqClient extends LLMClient { // Add response model as a tool if provided if (options.response_model) { - const jsonSchema = zodToJsonSchema(options.response_model.schema) as { + const jsonSchema = toJsonSchema(options.response_model.schema) as { properties?: Record; required?: string[]; }; diff --git a/packages/core/lib/v3/llm/LLMClient.ts b/packages/core/lib/v3/llm/LLMClient.ts index a2a317c43..70bf2b7a1 100644 --- a/packages/core/lib/v3/llm/LLMClient.ts +++ b/packages/core/lib/v3/llm/LLMClient.ts @@ -11,9 +11,9 @@ import { streamText, } from "ai"; import type { LanguageModelV2 } from "@ai-sdk/provider"; -import { ZodType } from "zod/v3"; import { LogLine } from "../types/public/logs"; import { AvailableModel, ClientOptions } from "../types/public/model"; +import type { StagehandZodSchema } from "../zodCompat"; export interface ChatMessage { role: "system" | "user" | "assistant"; @@ -55,7 +55,7 @@ export interface ChatCompletionOptions { }; response_model?: { name: string; - schema: ZodType; + schema: StagehandZodSchema; }; tools?: LLMTool[]; tool_choice?: "auto" | "none" | "required"; @@ -97,6 +97,23 @@ export interface CreateChatCompletionOptions { retries?: number; } +/** Simple usage shape if your LLM returns usage tokens. */ +export interface LLMUsage { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + reasoning_tokens?: number; + cached_input_tokens?: number; +} + +/** + * For calls that use a schema: the LLMClient may return { data: T; usage?: LLMUsage } + */ +export interface LLMParsedResponse { + data: T; + usage?: LLMUsage; +} + export abstract class LLMClient { public type: "openai" | "anthropic" | "cerebras" | "groq" | (string & {}); public modelName: AvailableModel | (string & {}); @@ -109,11 +126,19 @@ export abstract class LLMClient { this.userProvidedInstructions = userProvidedInstructions; } - abstract createChatCompletion< - T = LLMResponse & { - usage?: LLMResponse["usage"]; + // Overload 1: When response_model is provided, returns LLMParsedResponse + abstract createChatCompletion( + options: CreateChatCompletionOptions & { + options: { + response_model: { name: string; schema: StagehandZodSchema }; + }; }, - >(options: CreateChatCompletionOptions): Promise; + ): Promise>; + + // Overload 2: When response_model is not provided, returns T (defaults to LLMResponse) + abstract createChatCompletion( + options: CreateChatCompletionOptions, + ): Promise; public generateObject = generateObject; public generateText = generateText; diff --git a/packages/core/lib/v3/llm/OpenAIClient.ts b/packages/core/lib/v3/llm/OpenAIClient.ts index ba1d052cb..c564f0b9b 100644 --- a/packages/core/lib/v3/llm/OpenAIClient.ts +++ b/packages/core/lib/v3/llm/OpenAIClient.ts @@ -1,5 +1,4 @@ import OpenAI, { ClientOptions } from "openai"; -import { zodResponseFormat } from "openai/helpers/zod"; import { ChatCompletionAssistantMessageParam, ChatCompletionContentPartImage, @@ -9,7 +8,6 @@ import { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, } from "openai/resources/chat"; -import zodToJsonSchema from "zod-to-json-schema"; import { LogLine } from "../types/public/logs"; import { AvailableModel } from "../types/public/model"; import { validateZodSchema } from "../../utils"; @@ -25,6 +23,7 @@ import { StagehandError, ZodSchemaValidationError, } from "../types/public/sdkErrors"; +import { toJsonSchema } from "../zodCompat"; export class OpenAIClient extends LLMClient { public type = "openai" as const; @@ -152,13 +151,15 @@ export class OpenAIClient extends LLMClient { options.messages.push(screenshotMessage); } - let responseFormat = undefined; + let responseFormat: + | ChatCompletionCreateParamsNonStreaming["response_format"] + | undefined; if (options.response_model) { // For O1 models, we need to add the schema as a user message. if (this.modelName.startsWith("o1") || this.modelName.startsWith("o3")) { try { const parsedSchema = JSON.stringify( - zodToJsonSchema(options.response_model.schema), + toJsonSchema(options.response_model.schema), ); options.messages.push({ role: "user", @@ -185,10 +186,13 @@ export class OpenAIClient extends LLMClient { throw error; } } else { - responseFormat = zodResponseFormat( - options.response_model.schema, - options.response_model.name, - ); + responseFormat = { + type: "json_schema", + json_schema: { + name: options.response_model.name, + schema: toJsonSchema(options.response_model.schema), + }, + }; } } diff --git a/packages/core/lib/v3/tests/timeouts.spec.ts b/packages/core/lib/v3/tests/timeouts.spec.ts index 605904e96..623b11ea2 100644 --- a/packages/core/lib/v3/tests/timeouts.spec.ts +++ b/packages/core/lib/v3/tests/timeouts.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from "@playwright/test"; import { V3 } from "../v3"; import { v3DynamicTestConfig } from "./v3.dynamic.config"; -import { z } from "zod/v3"; +import { z } from "zod"; test.describe("V3 hard timeouts", () => { let v3: V3; diff --git a/packages/core/lib/v3/types/private/api.ts b/packages/core/lib/v3/types/private/api.ts index 304b95487..230584d28 100644 --- a/packages/core/lib/v3/types/private/api.ts +++ b/packages/core/lib/v3/types/private/api.ts @@ -1,5 +1,4 @@ import Browserbase from "@browserbasehq/sdk"; -import { ZodTypeAny } from "zod/v3"; import { Action, ActOptions, @@ -8,6 +7,7 @@ import { ObserveOptions, } from "../public"; import type { Protocol } from "devtools-protocol"; +import type { StagehandZodSchema } from "../../zodCompat"; export interface StagehandAPIConstructorParams { apiKey: string; @@ -60,7 +60,7 @@ export interface APIActParameters { export interface APIExtractParameters { instruction?: string; - schema?: ZodTypeAny; + schema?: StagehandZodSchema; options?: ExtractOptions; frameId?: string; } diff --git a/packages/core/lib/v3/types/private/handlers.ts b/packages/core/lib/v3/types/private/handlers.ts index df58577d4..5bab7f3c0 100644 --- a/packages/core/lib/v3/types/private/handlers.ts +++ b/packages/core/lib/v3/types/private/handlers.ts @@ -1,6 +1,6 @@ -import { ZodTypeAny } from "zod/v3"; import { Page } from "../../understudy/page"; import { ModelConfiguration } from "../public/model"; +import type { StagehandZodSchema } from "../../zodCompat"; export interface ActHandlerParams { instruction: string; @@ -10,7 +10,7 @@ export interface ActHandlerParams { page: Page; } -export interface ExtractHandlerParams { +export interface ExtractHandlerParams { instruction?: string; schema?: T; model?: ModelConfiguration; diff --git a/packages/core/lib/v3/types/public/methods.ts b/packages/core/lib/v3/types/public/methods.ts index e91c578fd..d0e17fe81 100644 --- a/packages/core/lib/v3/types/public/methods.ts +++ b/packages/core/lib/v3/types/public/methods.ts @@ -1,7 +1,8 @@ import { Page as PatchrightPage } from "patchright-core"; import { Page as PlaywrightPage } from "playwright-core"; import { Page as PuppeteerPage } from "puppeteer-core"; -import { z } from "zod/v3"; +import { z } from "zod"; +import type { InferStagehandSchema, StagehandZodSchema } from "../../zodCompat"; import { Page } from "../../understudy/page"; import { ModelConfiguration } from "../public/model"; @@ -19,7 +20,8 @@ export interface ActResult { actions: Action[]; } -export type ExtractResult = z.infer; +export type ExtractResult = + InferStagehandSchema; export interface Action { selector: string; diff --git a/packages/core/lib/v3/types/public/sdkErrors.ts b/packages/core/lib/v3/types/public/sdkErrors.ts index 73fc50e38..3131414e1 100644 --- a/packages/core/lib/v3/types/public/sdkErrors.ts +++ b/packages/core/lib/v3/types/public/sdkErrors.ts @@ -1,4 +1,4 @@ -import { ZodError } from "zod/v3"; +import { ZodError } from "zod"; // Avoid .js extension so tsup/esbuild resolves TS source import { STAGEHAND_VERSION } from "../../../version"; diff --git a/packages/core/lib/v3/v3.ts b/packages/core/lib/v3/v3.ts index a66c2a26f..f57067a46 100644 --- a/packages/core/lib/v3/v3.ts +++ b/packages/core/lib/v3/v3.ts @@ -3,8 +3,8 @@ import fs from "fs"; import os from "os"; import path from "path"; import process from "process"; -import type { ZodTypeAny } from "zod/v3"; -import { z } from "zod/v3"; +import { z } from "zod"; +import type { InferStagehandSchema, StagehandZodSchema } from "./zodCompat"; import { loadApiKeyFromEnv } from "../utils"; import { StagehandLogger, LoggerOptions } from "../logger"; import { ActCache } from "./cache/ActCache"; @@ -1091,15 +1091,15 @@ export class V3 { instruction: string, options?: ExtractOptions, ): Promise>; - async extract( + async extract( instruction: string, schema: T, options?: ExtractOptions, - ): Promise>; + ): Promise>; async extract( a?: string | ExtractOptions, - b?: ZodTypeAny | ExtractOptions, + b?: StagehandZodSchema | ExtractOptions, c?: ExtractOptions, ): Promise { return await withInstanceLogContext(this.instanceId, async () => { @@ -1109,18 +1109,18 @@ export class V3 { // Normalize args let instruction: string | undefined; - let schema: ZodTypeAny | undefined; + let schema: StagehandZodSchema | undefined; let options: ExtractOptions | undefined; if (typeof a === "string") { instruction = a; - const isZodSchema = (val: unknown): val is ZodTypeAny => + const isZodSchema = (val: unknown): val is StagehandZodSchema => !!val && typeof val === "object" && "parse" in val && "safeParse" in val; if (isZodSchema(b)) { - schema = b as ZodTypeAny; + schema = b as StagehandZodSchema; options = c as ExtractOptions | undefined; } else { options = b as ExtractOptions | undefined; @@ -1143,9 +1143,9 @@ export class V3 { // Resolve page from options or use active page const page = await this.resolvePage(options?.page); - const handlerParams: ExtractHandlerParams = { + const handlerParams: ExtractHandlerParams = { instruction, - schema: effectiveSchema as unknown as ZodTypeAny | undefined, + schema: effectiveSchema as StagehandZodSchema | undefined, model: options?.model, timeout: options?.timeout, selector: options?.selector, @@ -1161,7 +1161,8 @@ export class V3 { frameId, }); } else { - result = await this.extractHandler.extract(handlerParams); + result = + await this.extractHandler.extract(handlerParams); } return result; }); diff --git a/packages/core/lib/v3/zodCompat.ts b/packages/core/lib/v3/zodCompat.ts new file mode 100644 index 000000000..2ff7ea057 --- /dev/null +++ b/packages/core/lib/v3/zodCompat.ts @@ -0,0 +1,49 @@ +import { z } from "zod"; +import type { + ZodObject as Zod4Object, + ZodRawShape as Zod4RawShape, + ZodTypeAny as Zod4TypeAny, +} from "zod"; +import zodToJsonSchema from "zod-to-json-schema"; +import type * as z3 from "zod/v3"; +export type StagehandZodSchema = Zod4TypeAny | z3.ZodTypeAny; + +export type StagehandZodObject = + | Zod4Object + | z3.ZodObject; + +export type InferStagehandSchema = + T extends z3.ZodTypeAny + ? z3.infer + : T extends Zod4TypeAny + ? z.infer + : never; + +export const isZod4Schema = ( + schema: StagehandZodSchema, +): schema is Zod4TypeAny & { _zod: unknown } => + typeof (schema as { _zod?: unknown })._zod !== "undefined"; + +export const isZod3Schema = ( + schema: StagehandZodSchema, +): schema is z3.ZodTypeAny => !isZod4Schema(schema); + +export type JsonSchemaDocument = Record; + +export function toJsonSchema(schema: StagehandZodSchema): JsonSchemaDocument { + if (!isZod4Schema(schema)) { + return zodToJsonSchema(schema); + } + + // For v4 schemas, use built-in z.toJSONSchema() method + const zodWithJsonSchema = z as typeof z & { + toJSONSchema?: (schema: Zod4TypeAny) => JsonSchemaDocument; + }; + + if (zodWithJsonSchema.toJSONSchema) { + return zodWithJsonSchema.toJSONSchema(schema as Zod4TypeAny); + } + + // This should never happen with Zod v4.1+ + throw new Error("Zod v4 toJSONSchema method not found"); +} diff --git a/packages/core/lib/v3Evaluator.ts b/packages/core/lib/v3Evaluator.ts index d3df688d0..f98973e34 100644 --- a/packages/core/lib/v3Evaluator.ts +++ b/packages/core/lib/v3Evaluator.ts @@ -5,7 +5,7 @@ */ import dotenv from "dotenv"; -import { z } from "zod/v3"; +import { z } from "zod"; import type { AvailableModel, ClientOptions } from "./v3/types/public/model"; import type { EvaluateOptions, diff --git a/packages/core/package.json b/packages/core/package.json index 979fc57c1..0d0e240a0 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -40,7 +40,7 @@ "peerDependencies": { "deepmerge": "^4.3.1", "dotenv": "^16.4.5", - "zod": "3.25.67" + "zod": "3.25.76 || 4.1.8" }, "dependencies": { "@ai-sdk/provider": "^2.0.0", @@ -57,7 +57,7 @@ "pino-pretty": "^13.0.0", "playwright": "^1.52.0", "ws": "^8.18.0", - "zod-to-json-schema": "^3.23.5" + "zod-to-json-schema": "^3.25.0" }, "optionalDependencies": { "@ai-sdk/anthropic": "^2.0.34", @@ -85,7 +85,8 @@ "tsup": "^8.2.1", "tsx": "^4.10.5", "typescript": "^5.2.2", - "vitest": "^4.0.8" + "vitest": "^4.0.8", + "zod": "3.25.76 || 4.1.8" }, "repository": { "type": "git", diff --git a/packages/core/tests/public-types.test.ts b/packages/core/tests/public-types.test.ts index ec36d3b07..611f1d17c 100644 --- a/packages/core/tests/public-types.test.ts +++ b/packages/core/tests/public-types.test.ts @@ -69,12 +69,15 @@ const publicApiShape = { getZodType: Stagehand.getZodType, injectUrls: Stagehand.injectUrls, isRunningInBun: Stagehand.isRunningInBun, + isZod3Schema: Stagehand.isZod3Schema, + isZod4Schema: Stagehand.isZod4Schema, jsonSchemaToZod: Stagehand.jsonSchemaToZod, loadApiKeyFromEnv: Stagehand.loadApiKeyFromEnv, modelToAgentProviderMap: Stagehand.modelToAgentProviderMap, pageTextSchema: Stagehand.pageTextSchema, providerEnvVarMap: Stagehand.providerEnvVarMap, toGeminiSchema: Stagehand.toGeminiSchema, + toJsonSchema: Stagehand.toJsonSchema, transformSchema: Stagehand.transformSchema, trimTrailingTextNode: Stagehand.trimTrailingTextNode, validateZodSchema: Stagehand.validateZodSchema, diff --git a/packages/evals/llm_clients/hn_aisdk.ts b/packages/evals/llm_clients/hn_aisdk.ts index 822ba5b79..f69211e85 100644 --- a/packages/evals/llm_clients/hn_aisdk.ts +++ b/packages/evals/llm_clients/hn_aisdk.ts @@ -1,6 +1,6 @@ // import { Stagehand } from "@browserbasehq/stagehand"; // import { EvalFunction } from "@/types/evals"; -// import { z } from "zod/v3"; +// import { z } from "zod"; // // export const hn_aisdk: EvalFunction = async ({ // debugUrl, diff --git a/packages/evals/llm_clients/hn_customOpenAI.ts b/packages/evals/llm_clients/hn_customOpenAI.ts index a6007dcdb..8dd35f31b 100644 --- a/packages/evals/llm_clients/hn_customOpenAI.ts +++ b/packages/evals/llm_clients/hn_customOpenAI.ts @@ -1,5 +1,5 @@ // import { EvalFunction } from "@/types/evals"; -// import { z } from "zod/v3"; +// import { z } from "zod"; // import { CustomOpenAIClient } from "@/examples/external_clients/customOpenAI"; // import OpenAI from "openai"; // import { Stagehand } from "@browserbasehq/stagehand"; diff --git a/packages/evals/llm_clients/hn_langchain.ts b/packages/evals/llm_clients/hn_langchain.ts index 012d9198f..a86fecb87 100644 --- a/packages/evals/llm_clients/hn_langchain.ts +++ b/packages/evals/llm_clients/hn_langchain.ts @@ -1,5 +1,5 @@ // import { EvalFunction } from "@/types/evals"; -// import { z } from "zod/v3"; +// import { z } from "zod"; // import { LangchainClient } from "@/examples/external_clients/langchain"; // import { ChatOpenAI } from "@langchain/openai"; // import { Stagehand } from "@browserbasehq/stagehand"; diff --git a/packages/evals/package.json b/packages/evals/package.json index 64fc11823..b8dde1ed1 100644 --- a/packages/evals/package.json +++ b/packages/evals/package.json @@ -18,7 +18,7 @@ "@ai-sdk/provider": "^2.0.0", "openai": "^4.87.1", "dotenv": "16.4.5", - "zod": "3.25.67" + "zod": "^4.1.8" }, "devDependencies": { "tsx": "^4.10.5" diff --git a/packages/evals/tasks/agent/google_maps_2.ts b/packages/evals/tasks/agent/google_maps_2.ts index c0fdb45c2..bf0d386b9 100644 --- a/packages/evals/tasks/agent/google_maps_2.ts +++ b/packages/evals/tasks/agent/google_maps_2.ts @@ -1,7 +1,7 @@ import { EvalFunction } from "../../types/evals"; import { V3Evaluator } from "@browserbasehq/stagehand"; import type { AvailableModel } from "@browserbasehq/stagehand"; -import { z } from "zod/v3"; +import { z } from "zod"; export const google_maps_2: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/allrecipes.ts b/packages/evals/tasks/allrecipes.ts index c5c46fcef..c6d85f8ec 100644 --- a/packages/evals/tasks/allrecipes.ts +++ b/packages/evals/tasks/allrecipes.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const allrecipes: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/arxiv.ts b/packages/evals/tasks/arxiv.ts index ea58937fa..932cad5d1 100644 --- a/packages/evals/tasks/arxiv.ts +++ b/packages/evals/tasks/arxiv.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const arxiv: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/combination_sauce.ts b/packages/evals/tasks/combination_sauce.ts index e5fd71234..54110dd01 100644 --- a/packages/evals/tasks/combination_sauce.ts +++ b/packages/evals/tasks/combination_sauce.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const combination_sauce: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/costar.ts b/packages/evals/tasks/costar.ts index e62518b48..98364fc32 100644 --- a/packages/evals/tasks/costar.ts +++ b/packages/evals/tasks/costar.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const costar: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_aigrant_companies.ts b/packages/evals/tasks/extract_aigrant_companies.ts index 8f75173c5..bbc09bb3a 100644 --- a/packages/evals/tasks/extract_aigrant_companies.ts +++ b/packages/evals/tasks/extract_aigrant_companies.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_aigrant_companies: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_aigrant_targeted.ts b/packages/evals/tasks/extract_aigrant_targeted.ts index 7cfe4d27d..677da27cf 100644 --- a/packages/evals/tasks/extract_aigrant_targeted.ts +++ b/packages/evals/tasks/extract_aigrant_targeted.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_aigrant_targeted: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_aigrant_targeted_2.ts b/packages/evals/tasks/extract_aigrant_targeted_2.ts index c793040d0..6a9b76e7a 100644 --- a/packages/evals/tasks/extract_aigrant_targeted_2.ts +++ b/packages/evals/tasks/extract_aigrant_targeted_2.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_aigrant_targeted_2: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_apartments.ts b/packages/evals/tasks/extract_apartments.ts index 6634f291f..75fe13b07 100644 --- a/packages/evals/tasks/extract_apartments.ts +++ b/packages/evals/tasks/extract_apartments.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_apartments: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_area_codes.ts b/packages/evals/tasks/extract_area_codes.ts index 8759d5800..719170e41 100644 --- a/packages/evals/tasks/extract_area_codes.ts +++ b/packages/evals/tasks/extract_area_codes.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_area_codes: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_baptist_health.ts b/packages/evals/tasks/extract_baptist_health.ts index f619f4ae3..c586ebbbb 100644 --- a/packages/evals/tasks/extract_baptist_health.ts +++ b/packages/evals/tasks/extract_baptist_health.ts @@ -1,6 +1,6 @@ import { EvalFunction } from "../types/evals"; import { compareStrings } from "../utils"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_baptist_health: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_capacitor_info.ts b/packages/evals/tasks/extract_capacitor_info.ts index 6328c990f..5b9e8aa1c 100644 --- a/packages/evals/tasks/extract_capacitor_info.ts +++ b/packages/evals/tasks/extract_capacitor_info.ts @@ -1,6 +1,6 @@ import { EvalFunction } from "../types/evals"; import { normalizeString } from "../utils"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_capacitor_info: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_collaborators.ts b/packages/evals/tasks/extract_collaborators.ts index 5b5e571a7..944679636 100644 --- a/packages/evals/tasks/extract_collaborators.ts +++ b/packages/evals/tasks/extract_collaborators.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_collaborators: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_csa.ts b/packages/evals/tasks/extract_csa.ts index aa986f1a7..9ab07e855 100644 --- a/packages/evals/tasks/extract_csa.ts +++ b/packages/evals/tasks/extract_csa.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_csa: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_geniusee.ts b/packages/evals/tasks/extract_geniusee.ts index da6f51f8e..2561b1897 100644 --- a/packages/evals/tasks/extract_geniusee.ts +++ b/packages/evals/tasks/extract_geniusee.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_geniusee: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_geniusee_2.ts b/packages/evals/tasks/extract_geniusee_2.ts index 90d0d6281..52fff6660 100644 --- a/packages/evals/tasks/extract_geniusee_2.ts +++ b/packages/evals/tasks/extract_geniusee_2.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_geniusee_2: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_github_commits.ts b/packages/evals/tasks/extract_github_commits.ts index 6635ef92e..fcf35aa92 100644 --- a/packages/evals/tasks/extract_github_commits.ts +++ b/packages/evals/tasks/extract_github_commits.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_github_commits: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_github_stars.ts b/packages/evals/tasks/extract_github_stars.ts index 1725465b4..d0651a186 100644 --- a/packages/evals/tasks/extract_github_stars.ts +++ b/packages/evals/tasks/extract_github_stars.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_github_stars: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_hamilton_weather.ts b/packages/evals/tasks/extract_hamilton_weather.ts index 9519676c5..a1501e4a9 100644 --- a/packages/evals/tasks/extract_hamilton_weather.ts +++ b/packages/evals/tasks/extract_hamilton_weather.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; import { compareStrings } from "../utils"; export const extract_hamilton_weather: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_jfk_links.ts b/packages/evals/tasks/extract_jfk_links.ts index d4c285c07..049ff5ca6 100644 --- a/packages/evals/tasks/extract_jfk_links.ts +++ b/packages/evals/tasks/extract_jfk_links.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_jfk_links: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_jstor_news.ts b/packages/evals/tasks/extract_jstor_news.ts index 7dbe40d15..5d5a449eb 100644 --- a/packages/evals/tasks/extract_jstor_news.ts +++ b/packages/evals/tasks/extract_jstor_news.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_jstor_news: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_memorial_healthcare.ts b/packages/evals/tasks/extract_memorial_healthcare.ts index d7fcbe062..37015d2d4 100644 --- a/packages/evals/tasks/extract_memorial_healthcare.ts +++ b/packages/evals/tasks/extract_memorial_healthcare.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; import { compareStrings } from "../utils"; export const extract_memorial_healthcare: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_nhl_stats.ts b/packages/evals/tasks/extract_nhl_stats.ts index 00301f718..8701fd405 100644 --- a/packages/evals/tasks/extract_nhl_stats.ts +++ b/packages/evals/tasks/extract_nhl_stats.ts @@ -1,6 +1,6 @@ import { EvalFunction } from "../types/evals"; import { normalizeString } from "../utils"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_nhl_stats: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_partners.ts b/packages/evals/tasks/extract_partners.ts index 328413597..1c1e7a18f 100644 --- a/packages/evals/tasks/extract_partners.ts +++ b/packages/evals/tasks/extract_partners.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_partners: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_press_releases.ts b/packages/evals/tasks/extract_press_releases.ts index 52b75c52e..3b86a745a 100644 --- a/packages/evals/tasks/extract_press_releases.ts +++ b/packages/evals/tasks/extract_press_releases.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; import { compareStrings } from "../utils"; export const extract_press_releases: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_professional_info.ts b/packages/evals/tasks/extract_professional_info.ts index 941cd1695..3c77caada 100644 --- a/packages/evals/tasks/extract_professional_info.ts +++ b/packages/evals/tasks/extract_professional_info.ts @@ -1,6 +1,6 @@ import { EvalFunction } from "../types/evals"; import { normalizeString } from "../utils"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_professional_info: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_public_notices.ts b/packages/evals/tasks/extract_public_notices.ts index 85db71626..72d612874 100644 --- a/packages/evals/tasks/extract_public_notices.ts +++ b/packages/evals/tasks/extract_public_notices.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; import { compareStrings } from "../utils"; export const extract_public_notices: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_recipe.ts b/packages/evals/tasks/extract_recipe.ts index 9ba0f34b1..b50e55b70 100644 --- a/packages/evals/tasks/extract_recipe.ts +++ b/packages/evals/tasks/extract_recipe.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_recipe: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_regulations_table.ts b/packages/evals/tasks/extract_regulations_table.ts index 1ca130f20..2c645f97f 100644 --- a/packages/evals/tasks/extract_regulations_table.ts +++ b/packages/evals/tasks/extract_regulations_table.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_regulations_table: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_resistor_info.ts b/packages/evals/tasks/extract_resistor_info.ts index 7e214e868..ff6d05e7f 100644 --- a/packages/evals/tasks/extract_resistor_info.ts +++ b/packages/evals/tasks/extract_resistor_info.ts @@ -1,6 +1,6 @@ import { EvalFunction } from "../types/evals"; import { normalizeString } from "../utils"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_resistor_info: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_rockauto.ts b/packages/evals/tasks/extract_rockauto.ts index eada3e9ed..9bcd361df 100644 --- a/packages/evals/tasks/extract_rockauto.ts +++ b/packages/evals/tasks/extract_rockauto.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_rockauto: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/extract_single_link.ts b/packages/evals/tasks/extract_single_link.ts index b4ca2c0d1..eee2584b0 100644 --- a/packages/evals/tasks/extract_single_link.ts +++ b/packages/evals/tasks/extract_single_link.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const extract_single_link: EvalFunction = async ({ logger, diff --git a/packages/evals/tasks/extract_snowshoeing_destinations.ts b/packages/evals/tasks/extract_snowshoeing_destinations.ts index 02dd18012..067f0ad9f 100644 --- a/packages/evals/tasks/extract_snowshoeing_destinations.ts +++ b/packages/evals/tasks/extract_snowshoeing_destinations.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_snowshoeing_destinations: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_staff_members.ts b/packages/evals/tasks/extract_staff_members.ts index 82f82b5d4..a67958d7a 100644 --- a/packages/evals/tasks/extract_staff_members.ts +++ b/packages/evals/tasks/extract_staff_members.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_staff_members: EvalFunction = async ({ diff --git a/packages/evals/tasks/extract_zillow.ts b/packages/evals/tasks/extract_zillow.ts index d6f75ca9a..76fd567ac 100644 --- a/packages/evals/tasks/extract_zillow.ts +++ b/packages/evals/tasks/extract_zillow.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import { EvalFunction } from "../types/evals"; export const extract_zillow: EvalFunction = async ({ diff --git a/packages/evals/tasks/homedepot.ts b/packages/evals/tasks/homedepot.ts index 884a94025..aa904f6b8 100644 --- a/packages/evals/tasks/homedepot.ts +++ b/packages/evals/tasks/homedepot.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const homedepot: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/iframe_hn.ts b/packages/evals/tasks/iframe_hn.ts index 69a50b57b..5984f1fb4 100644 --- a/packages/evals/tasks/iframe_hn.ts +++ b/packages/evals/tasks/iframe_hn.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const iframe_hn: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/imdb_movie_details.ts b/packages/evals/tasks/imdb_movie_details.ts index 28a9f5dbe..400fa72d3 100644 --- a/packages/evals/tasks/imdb_movie_details.ts +++ b/packages/evals/tasks/imdb_movie_details.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const imdb_movie_details: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/peeler_complex.ts b/packages/evals/tasks/peeler_complex.ts index 3cadd106d..ea442415c 100644 --- a/packages/evals/tasks/peeler_complex.ts +++ b/packages/evals/tasks/peeler_complex.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const peeler_complex: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/sciquest.ts b/packages/evals/tasks/sciquest.ts index 0d8f50e29..7aa13be92 100644 --- a/packages/evals/tasks/sciquest.ts +++ b/packages/evals/tasks/sciquest.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const sciquest: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/ted_talk.ts b/packages/evals/tasks/ted_talk.ts index 0fe243bf1..057c63836 100644 --- a/packages/evals/tasks/ted_talk.ts +++ b/packages/evals/tasks/ted_talk.ts @@ -1,6 +1,6 @@ import { EvalFunction } from "../types/evals"; import { normalizeString } from "../utils"; -import { z } from "zod/v3"; +import { z } from "zod"; export const ted_talk: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/tasks/wichita.ts b/packages/evals/tasks/wichita.ts index a729652ac..0ecf69fdc 100644 --- a/packages/evals/tasks/wichita.ts +++ b/packages/evals/tasks/wichita.ts @@ -1,5 +1,5 @@ import { EvalFunction } from "../types/evals"; -import { z } from "zod/v3"; +import { z } from "zod"; export const wichita: EvalFunction = async ({ debugUrl, diff --git a/packages/evals/types/evals.ts b/packages/evals/types/evals.ts index ea5c3ce85..4ccbe1637 100644 --- a/packages/evals/types/evals.ts +++ b/packages/evals/types/evals.ts @@ -1,4 +1,4 @@ -import { z } from "zod/v3"; +import { z } from "zod"; import type { AvailableModel } from "@browserbasehq/stagehand"; import type { LogLine } from "@browserbasehq/stagehand"; import type { AgentInstance } from "@browserbasehq/stagehand"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cd2a88bcc..4b4b0aefe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,13 +19,13 @@ importers: version: 9.25.1 '@langchain/community': specifier: ^1.0.0 - version: 1.0.0(@browserbasehq/sdk@2.5.0)(@browserbasehq/stagehand@3.0.1(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67))(@ibm-cloud/watsonx-ai@1.7.0)(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(@opentelemetry/api@1.9.0)(cheerio@1.0.0)(google-auth-library@9.15.1)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@6.7.0(ws@8.18.3)(zod@3.25.67))(playwright@1.54.2)(puppeteer@22.15.0(typescript@5.8.3))(ws@8.18.3) + version: 1.0.0(@browserbasehq/sdk@2.5.0)(@browserbasehq/stagehand@3.0.3(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67))(@ibm-cloud/watsonx-ai@1.7.0)(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(@opentelemetry/api@1.9.0)(cheerio@1.0.0)(google-auth-library@9.15.1)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@6.7.0(ws@8.18.3)(zod@3.25.67))(playwright@1.54.2)(puppeteer@22.15.0(typescript@5.8.3))(ws@8.18.3) '@langchain/core': specifier: ^0.3.40 version: 0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)) '@langchain/langgraph': specifier: ^1.0.1 - version: 1.0.1(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod-to-json-schema@3.24.5(zod@3.25.67))(zod@3.25.67) + version: 1.0.1(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod-to-json-schema@3.25.0(zod@3.25.67))(zod@3.25.67) '@langchain/openai': specifier: ^0.4.4 version: 0.4.9(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(ws@8.18.3) @@ -130,13 +130,13 @@ importers: version: 1.24.0(@modelcontextprotocol/sdk@1.17.2) '@langchain/openai': specifier: ^0.4.4 - version: 0.4.9(@langchain/core@0.3.50(openai@4.96.2(ws@8.18.3)(zod@3.25.67)))(ws@8.18.3) + version: 0.4.9(@langchain/core@0.3.50(openai@4.96.2(ws@8.18.3)(zod@4.1.8)))(ws@8.18.3) '@modelcontextprotocol/sdk': specifier: ^1.17.2 version: 1.17.2 ai: specifier: ^5.0.0 - version: 5.0.76(zod@3.25.67) + version: 5.0.76(zod@4.1.8) deepmerge: specifier: ^4.3.1 version: 4.3.1 @@ -151,7 +151,7 @@ importers: version: 3.1.0 openai: specifier: ^4.87.1 - version: 4.96.2(ws@8.18.3)(zod@3.25.67) + version: 4.96.2(ws@8.18.3)(zod@4.1.8) pino: specifier: ^9.6.0 version: 9.6.0 @@ -164,55 +164,52 @@ importers: ws: specifier: ^8.18.0 version: 8.18.3 - zod: - specifier: 3.25.67 - version: 3.25.67 zod-to-json-schema: - specifier: ^3.23.5 - version: 3.24.5(zod@3.25.67) + specifier: ^3.25.0 + version: 3.25.0(zod@4.1.8) optionalDependencies: '@ai-sdk/anthropic': specifier: ^2.0.34 - version: 2.0.34(zod@3.25.67) + version: 2.0.34(zod@4.1.8) '@ai-sdk/azure': specifier: ^2.0.54 - version: 2.0.54(zod@3.25.67) + version: 2.0.54(zod@4.1.8) '@ai-sdk/cerebras': specifier: ^1.0.25 - version: 1.0.25(zod@3.25.67) + version: 1.0.25(zod@4.1.8) '@ai-sdk/deepseek': specifier: ^1.0.23 - version: 1.0.23(zod@3.25.67) + version: 1.0.23(zod@4.1.8) '@ai-sdk/google': specifier: ^2.0.23 - version: 2.0.23(zod@3.25.67) + version: 2.0.23(zod@4.1.8) '@ai-sdk/groq': specifier: ^2.0.24 - version: 2.0.24(zod@3.25.67) + version: 2.0.24(zod@4.1.8) '@ai-sdk/mistral': specifier: ^2.0.19 - version: 2.0.19(zod@3.25.67) + version: 2.0.19(zod@4.1.8) '@ai-sdk/openai': specifier: ^2.0.53 - version: 2.0.53(zod@3.25.67) + version: 2.0.53(zod@4.1.8) '@ai-sdk/perplexity': specifier: ^2.0.13 - version: 2.0.13(zod@3.25.67) + version: 2.0.13(zod@4.1.8) '@ai-sdk/togetherai': specifier: ^1.0.23 - version: 1.0.23(zod@3.25.67) + version: 1.0.23(zod@4.1.8) '@ai-sdk/xai': specifier: ^2.0.26 - version: 2.0.26(zod@3.25.67) + version: 2.0.26(zod@4.1.8) '@langchain/core': specifier: ^0.3.40 - version: 0.3.50(openai@4.96.2(ws@8.18.3)(zod@3.25.67)) + version: 0.3.50(openai@4.96.2(ws@8.18.3)(zod@4.1.8)) chrome-launcher: specifier: ^1.2.0 version: 1.2.0 ollama-ai-provider-v2: specifier: ^1.5.0 - version: 1.5.0(zod@3.25.67) + version: 1.5.0(zod@4.1.8) patchright-core: specifier: ^1.55.2 version: 1.55.2 @@ -243,7 +240,10 @@ importers: version: 5.8.3 vitest: specifier: ^4.0.8 - version: 4.0.8(@types/debug@4.1.12)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + version: 4.0.10(@types/debug@4.1.12)(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + zod: + specifier: 3.25.76 || 4.1.8 + version: 4.1.8 packages/docs: dependencies: @@ -267,16 +267,16 @@ importers: version: link:../core ai: specifier: ^5.0.0 - version: 5.0.76(zod@3.25.67) + version: 5.0.76(zod@4.1.12) dotenv: specifier: 16.4.5 version: 16.4.5 openai: specifier: ^4.87.1 - version: 4.96.2(ws@8.18.3)(zod@3.25.67) + version: 4.96.2(ws@8.18.3)(zod@4.1.12) zod: - specifier: 3.25.67 - version: 3.25.67 + specifier: ^4.1.8 + version: 4.1.12 devDependencies: tsx: specifier: ^4.10.5 @@ -422,8 +422,8 @@ packages: '@browserbasehq/sdk@2.5.0': resolution: {integrity: sha512-bcnbYZvm5Ht1nrHUfWDK4crspiTy1ESJYMApsMiOTUnlKOan0ocRD6m7hZH34iSC2c2XWsoryR80cwsYgCBWzQ==} - '@browserbasehq/stagehand@3.0.1': - resolution: {integrity: sha512-GfI6qWAGBj3obGvIgi8wbE1e65y29hB7u9FUmlQIz2wUX/izFFchlq+PszafPr9d2q4ZzbqzqNoc9WSjhxT65w==} + '@browserbasehq/stagehand@3.0.3': + resolution: {integrity: sha512-O/9VgmOmIX4ZYuu2hgQ+7BmK8wkSgPX/kLzGQ/SJLCNYRW9yuU6/b4NRdFU5uJ7OlCKdEOcV1u4Cc4PhY67S0w==} peerDependencies: deepmerge: ^4.3.1 dotenv: ^16.4.5 @@ -2339,11 +2339,11 @@ packages: resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} engines: {node: '>= 20'} - '@vitest/expect@4.0.8': - resolution: {integrity: sha512-Rv0eabdP/xjAHQGr8cjBm+NnLHNoL268lMDK85w2aAGLFoVKLd8QGnVon5lLtkXQCoYaNL0wg04EGnyKkkKhPA==} + '@vitest/expect@4.0.10': + resolution: {integrity: sha512-3QkTX/lK39FBNwARCQRSQr0TP9+ywSdxSX+LgbJ2M1WmveXP72anTbnp2yl5fH+dU6SUmBzNMrDHs80G8G2DZg==} - '@vitest/mocker@4.0.8': - resolution: {integrity: sha512-9FRM3MZCedXH3+pIh+ME5Up2NBBHDq0wqwhOKkN4VnvCiKbVxddqH9mSGPZeawjd12pCOGnl+lo/ZGHt0/dQSg==} + '@vitest/mocker@4.0.10': + resolution: {integrity: sha512-e2OfdexYkjkg8Hh3L9NVEfbwGXq5IZbDovkf30qW2tOh7Rh9sVtmSr2ztEXOFbymNxS4qjzLXUQIvATvN4B+lg==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -2353,20 +2353,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.8': - resolution: {integrity: sha512-qRrjdRkINi9DaZHAimV+8ia9Gq6LeGz2CgIEmMLz3sBDYV53EsnLZbJMR1q84z1HZCMsf7s0orDgZn7ScXsZKg==} + '@vitest/pretty-format@4.0.10': + resolution: {integrity: sha512-99EQbpa/zuDnvVjthwz5bH9o8iPefoQZ63WV8+bsRJZNw3qQSvSltfut8yu1Jc9mqOYi7pEbsKxYTi/rjaq6PA==} - '@vitest/runner@4.0.8': - resolution: {integrity: sha512-mdY8Sf1gsM8hKJUQfiPT3pn1n8RF4QBcJYFslgWh41JTfrK1cbqY8whpGCFzBl45LN028g0njLCYm0d7XxSaQQ==} + '@vitest/runner@4.0.10': + resolution: {integrity: sha512-EXU2iSkKvNwtlL8L8doCpkyclw0mc/t4t9SeOnfOFPyqLmQwuceMPA4zJBa6jw0MKsZYbw7kAn+gl7HxrlB8UQ==} - '@vitest/snapshot@4.0.8': - resolution: {integrity: sha512-Nar9OTU03KGiubrIOFhcfHg8FYaRaNT+bh5VUlNz8stFhCZPNrJvmZkhsr1jtaYvuefYFwK2Hwrq026u4uPWCw==} + '@vitest/snapshot@4.0.10': + resolution: {integrity: sha512-2N4X2ZZl7kZw0qeGdQ41H0KND96L3qX1RgwuCfy6oUsF2ISGD/HpSbmms+CkIOsQmg2kulwfhJ4CI0asnZlvkg==} - '@vitest/spy@4.0.8': - resolution: {integrity: sha512-nvGVqUunyCgZH7kmo+Ord4WgZ7lN0sOULYXUOYuHr55dvg9YvMz3izfB189Pgp28w0vWFbEEfNc/c3VTrqrXeA==} + '@vitest/spy@4.0.10': + resolution: {integrity: sha512-AsY6sVS8OLb96GV5RoG8B6I35GAbNrC49AO+jNRF9YVGb/g9t+hzNm1H6kD0NDp8tt7VJLs6hb7YMkDXqu03iw==} - '@vitest/utils@4.0.8': - resolution: {integrity: sha512-pdk2phO5NDvEFfUTxcTP8RFYjVj/kfLSPIN5ebP2Mu9kcIMeAQTbknqcFEyBcC4z2pJlJI9aS5UQjcYfhmKAow==} + '@vitest/utils@4.0.10': + resolution: {integrity: sha512-kOuqWnEwZNtQxMKg3WmPK1vmhZu9WcoX69iwWjVz+jvKTsF1emzsv3eoPcDr6ykA3qP2bsCQE7CwqfNtAVzsmg==} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -2738,8 +2738,8 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chai@6.2.0: - resolution: {integrity: sha512-aUTnJc/JipRzJrNADXVvpVqi6CO0dn3nx4EVPxijri+fj3LUUDyZQOgVeW54Ob3Y1Xh9Iz8f+CgaCl8v0mn9bA==} + chai@6.2.1: + resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} engines: {node: '>=18'} chalk@4.1.2: @@ -6197,18 +6197,18 @@ packages: yaml: optional: true - vitest@4.0.8: - resolution: {integrity: sha512-urzu3NCEV0Qa0Y2PwvBtRgmNtxhj5t5ULw7cuKhIHh3OrkKTLlut0lnBOv9qe5OvbkMH2g38G7KPDCTpIytBVg==} + vitest@4.0.10: + resolution: {integrity: sha512-2Fqty3MM9CDwOVet/jaQalYlbcjATZwPYGcqpiYQqgQ/dLC7GuHdISKgTYIVF/kaishKxLzleKWWfbSDklyIKg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.8 - '@vitest/browser-preview': 4.0.8 - '@vitest/browser-webdriverio': 4.0.8 - '@vitest/ui': 4.0.8 + '@vitest/browser-playwright': 4.0.10 + '@vitest/browser-preview': 4.0.10 + '@vitest/browser-webdriverio': 4.0.10 + '@vitest/ui': 4.0.10 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -6393,6 +6393,11 @@ packages: peerDependencies: zod: ^3.24.1 + zod-to-json-schema@3.25.0: + resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} + peerDependencies: + zod: ^3.25 || ^4 + zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} @@ -6402,6 +6407,12 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + + zod@4.1.8: + resolution: {integrity: sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -6414,6 +6425,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/anthropic@2.0.34(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/azure@2.0.54(zod@3.25.67)': dependencies: '@ai-sdk/openai': 2.0.53(zod@3.25.67) @@ -6422,6 +6440,14 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/azure@2.0.54(zod@4.1.8)': + dependencies: + '@ai-sdk/openai': 2.0.53(zod@4.1.8) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/cerebras@1.0.25(zod@3.25.67)': dependencies: '@ai-sdk/openai-compatible': 1.0.22(zod@3.25.67) @@ -6430,6 +6456,14 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/cerebras@1.0.25(zod@4.1.8)': + dependencies: + '@ai-sdk/openai-compatible': 1.0.22(zod@4.1.8) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/deepseek@1.0.23(zod@3.25.67)': dependencies: '@ai-sdk/openai-compatible': 1.0.22(zod@3.25.67) @@ -6438,6 +6472,14 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/deepseek@1.0.23(zod@4.1.8)': + dependencies: + '@ai-sdk/openai-compatible': 1.0.22(zod@4.1.8) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/gateway@2.0.0(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6445,6 +6487,20 @@ snapshots: '@vercel/oidc': 3.0.3 zod: 3.25.67 + '@ai-sdk/gateway@2.0.0(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) + '@vercel/oidc': 3.0.3 + zod: 4.1.12 + + '@ai-sdk/gateway@2.0.0(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + '@vercel/oidc': 3.0.3 + zod: 4.1.8 + '@ai-sdk/google@2.0.23(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6452,6 +6508,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/google@2.0.23(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/groq@2.0.24(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6459,6 +6522,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/groq@2.0.24(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/mistral@2.0.19(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6466,6 +6536,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/mistral@2.0.19(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/openai-compatible@1.0.22(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6473,6 +6550,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/openai-compatible@1.0.22(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/openai@2.0.53(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6480,6 +6564,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/openai@2.0.53(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/perplexity@2.0.13(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6487,6 +6578,13 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/perplexity@2.0.13(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/provider-utils@3.0.12(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -6494,6 +6592,20 @@ snapshots: eventsource-parser: 3.0.6 zod: 3.25.67 + '@ai-sdk/provider-utils@3.0.12(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.12 + + '@ai-sdk/provider-utils@3.0.12(zod@4.1.8)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.8 + '@ai-sdk/provider@1.1.3': dependencies: json-schema: 0.4.0 @@ -6510,6 +6622,14 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/togetherai@1.0.23(zod@4.1.8)': + dependencies: + '@ai-sdk/openai-compatible': 1.0.22(zod@4.1.8) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@ai-sdk/xai@2.0.26(zod@3.25.67)': dependencies: '@ai-sdk/openai-compatible': 1.0.22(zod@3.25.67) @@ -6518,6 +6638,14 @@ snapshots: zod: 3.25.67 optional: true + '@ai-sdk/xai@2.0.26(zod@4.1.8)': + dependencies: + '@ai-sdk/openai-compatible': 1.0.22(zod@4.1.8) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + '@alcalzone/ansi-tokenize@0.1.3': dependencies: ansi-styles: 6.2.1 @@ -6543,10 +6671,10 @@ snapshots: '@ark/util@0.46.0': {} - '@asteasolutions/zod-to-openapi@6.4.0(zod@3.25.67)': + '@asteasolutions/zod-to-openapi@6.4.0(zod@3.25.76)': dependencies: openapi3-ts: 4.4.0 - zod: 3.25.67 + zod: 3.25.76 '@asyncapi/parser@3.4.0': dependencies: @@ -6588,9 +6716,9 @@ snapshots: '@braintrust/core@0.0.34': dependencies: - '@asteasolutions/zod-to-openapi': 6.4.0(zod@3.25.67) + '@asteasolutions/zod-to-openapi': 6.4.0(zod@3.25.76) uuid: 9.0.1 - zod: 3.25.67 + zod: 3.25.76 '@browserbasehq/sdk@2.5.0': dependencies: @@ -6604,7 +6732,7 @@ snapshots: transitivePeerDependencies: - encoding - '@browserbasehq/stagehand@3.0.1(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67)': + '@browserbasehq/stagehand@3.0.3(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67)': dependencies: '@ai-sdk/provider': 2.0.0 '@anthropic-ai/sdk': 0.39.0 @@ -6623,7 +6751,7 @@ snapshots: playwright: 1.54.2 ws: 8.18.3 zod: 3.25.67 - zod-to-json-schema: 3.24.5(zod@3.25.67) + zod-to-json-schema: 3.25.0(zod@3.25.67) optionalDependencies: '@ai-sdk/anthropic': 2.0.34(zod@3.25.67) '@ai-sdk/azure': 2.0.54(zod@3.25.67) @@ -7364,7 +7492,7 @@ snapshots: p-retry: 4.6.2 uuid: 10.0.0 yaml: 2.7.1 - zod: 3.25.76 + zod: 4.1.8 optionalDependencies: cheerio: 1.0.0 langsmith: 0.3.75(@opentelemetry/api@1.9.0)(openai@6.7.0(ws@8.18.3)(zod@3.25.67)) @@ -7375,9 +7503,9 @@ snapshots: - openai - ws - '@langchain/community@1.0.0(@browserbasehq/sdk@2.5.0)(@browserbasehq/stagehand@3.0.1(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67))(@ibm-cloud/watsonx-ai@1.7.0)(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(@opentelemetry/api@1.9.0)(cheerio@1.0.0)(google-auth-library@9.15.1)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@6.7.0(ws@8.18.3)(zod@3.25.67))(playwright@1.54.2)(puppeteer@22.15.0(typescript@5.8.3))(ws@8.18.3)': + '@langchain/community@1.0.0(@browserbasehq/sdk@2.5.0)(@browserbasehq/stagehand@3.0.3(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67))(@ibm-cloud/watsonx-ai@1.7.0)(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(@opentelemetry/api@1.9.0)(cheerio@1.0.0)(google-auth-library@9.15.1)(ibm-cloud-sdk-core@5.4.3)(ignore@5.3.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@6.7.0(ws@8.18.3)(zod@3.25.67))(playwright@1.54.2)(puppeteer@22.15.0(typescript@5.8.3))(ws@8.18.3)': dependencies: - '@browserbasehq/stagehand': 3.0.1(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67) + '@browserbasehq/stagehand': 3.0.3(deepmerge@4.3.1)(dotenv@16.5.0)(zod@3.25.67) '@ibm-cloud/watsonx-ai': 1.7.0 '@langchain/classic': 1.0.0(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(@opentelemetry/api@1.9.0)(cheerio@1.0.0)(openai@6.7.0(ws@8.18.3)(zod@3.25.67))(ws@8.18.3) '@langchain/core': 0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)) @@ -7418,8 +7546,26 @@ snapshots: p-queue: 6.6.2 p-retry: 4.6.2 uuid: 10.0.0 - zod: 3.25.67 - zod-to-json-schema: 3.24.5(zod@3.25.67) + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) + transitivePeerDependencies: + - openai + optional: true + + '@langchain/core@0.3.50(openai@4.96.2(ws@8.18.3)(zod@4.1.8))': + dependencies: + '@cfworker/json-schema': 4.1.1 + ansi-styles: 5.2.0 + camelcase: 6.3.0 + decamelize: 1.2.0 + js-tiktoken: 1.0.20 + langsmith: 0.3.23(openai@4.96.2(ws@8.18.3)(zod@4.1.8)) + mustache: 4.2.0 + p-queue: 6.6.2 + p-retry: 4.6.2 + uuid: 10.0.0 + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: - openai @@ -7435,8 +7581,8 @@ snapshots: p-queue: 6.6.2 p-retry: 4.6.2 uuid: 10.0.0 - zod: 3.25.67 - zod-to-json-schema: 3.24.5(zod@3.25.67) + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: - openai @@ -7455,7 +7601,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@langchain/langgraph@1.0.1(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod-to-json-schema@3.24.5(zod@3.25.67))(zod@3.25.67)': + '@langchain/langgraph@1.0.1(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod-to-json-schema@3.25.0(zod@3.25.67))(zod@3.25.67)': dependencies: '@langchain/core': 0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)) '@langchain/langgraph-checkpoint': 1.0.0(@langchain/core@0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67))) @@ -7463,14 +7609,14 @@ snapshots: uuid: 10.0.0 zod: 3.25.67 optionalDependencies: - zod-to-json-schema: 3.24.5(zod@3.25.67) + zod-to-json-schema: 3.25.0(zod@3.25.67) transitivePeerDependencies: - react - react-dom - '@langchain/openai@0.4.9(@langchain/core@0.3.50(openai@4.96.2(ws@8.18.3)(zod@3.25.67)))(ws@8.18.3)': + '@langchain/openai@0.4.9(@langchain/core@0.3.50(openai@4.96.2(ws@8.18.3)(zod@4.1.8)))(ws@8.18.3)': dependencies: - '@langchain/core': 0.3.50(openai@4.96.2(ws@8.18.3)(zod@3.25.67)) + '@langchain/core': 0.3.50(openai@4.96.2(ws@8.18.3)(zod@4.1.8)) js-tiktoken: 1.0.20 openai: 4.96.2(ws@8.18.3)(zod@3.25.67) zod: 3.25.67 @@ -7494,8 +7640,8 @@ snapshots: dependencies: '@langchain/core': 0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)) js-tiktoken: 1.0.20 - openai: 6.7.0(ws@8.18.3)(zod@3.25.76) - zod: 3.25.76 + openai: 6.7.0(ws@8.18.3)(zod@4.1.8) + zod: 4.1.8 transitivePeerDependencies: - ws @@ -7503,8 +7649,8 @@ snapshots: dependencies: '@langchain/core': 0.3.50(openai@6.7.0(ws@8.18.3)(zod@3.25.67)) js-tiktoken: 1.0.20 - openai: 6.7.0(ws@8.18.3)(zod@3.25.76) - zod: 3.25.76 + openai: 6.7.0(ws@8.18.3)(zod@4.1.8) + zod: 4.1.8 transitivePeerDependencies: - ws @@ -7790,7 +7936,7 @@ snapshots: unified: 11.0.5 unist-util-visit: 5.0.0 yargs: 17.7.2 - zod: 3.25.67 + zod: 3.25.76 transitivePeerDependencies: - '@types/react' - bare-buffer @@ -7811,8 +7957,8 @@ snapshots: lcm: 0.0.3 lodash: 4.17.21 openapi-types: 12.1.3 - zod: 3.25.67 - zod-to-json-schema: 3.24.5(zod@3.25.67) + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: - debug @@ -7828,8 +7974,8 @@ snapshots: express-rate-limit: 7.5.1(express@5.1.0) pkce-challenge: 5.0.0 raw-body: 3.0.0 - zod: 3.25.67 - zod-to-json-schema: 3.24.5(zod@3.25.67) + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: - supports-color @@ -8426,43 +8572,43 @@ snapshots: '@vercel/oidc@3.0.3': {} - '@vitest/expect@4.0.8': + '@vitest/expect@4.0.10': dependencies: '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.8 - '@vitest/utils': 4.0.8 - chai: 6.2.0 + '@vitest/spy': 4.0.10 + '@vitest/utils': 4.0.10 + chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.8(vite@7.2.2(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1))': + '@vitest/mocker@4.0.10(vite@7.2.2(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1))': dependencies: - '@vitest/spy': 4.0.8 + '@vitest/spy': 4.0.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.2.2(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + vite: 7.2.2(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) - '@vitest/pretty-format@4.0.8': + '@vitest/pretty-format@4.0.10': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.8': + '@vitest/runner@4.0.10': dependencies: - '@vitest/utils': 4.0.8 + '@vitest/utils': 4.0.10 pathe: 2.0.3 - '@vitest/snapshot@4.0.8': + '@vitest/snapshot@4.0.10': dependencies: - '@vitest/pretty-format': 4.0.8 + '@vitest/pretty-format': 4.0.10 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.8': {} + '@vitest/spy@4.0.10': {} - '@vitest/utils@4.0.8': + '@vitest/utils@4.0.10': dependencies: - '@vitest/pretty-format': 4.0.8 + '@vitest/pretty-format': 4.0.10 tinyrainbow: 3.0.3 abort-controller@3.0.0: @@ -8514,6 +8660,22 @@ snapshots: '@opentelemetry/api': 1.9.0 zod: 3.25.67 + ai@5.0.76(zod@4.1.12): + dependencies: + '@ai-sdk/gateway': 2.0.0(zod@4.1.12) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) + '@opentelemetry/api': 1.9.0 + zod: 4.1.12 + + ai@5.0.76(zod@4.1.8): + dependencies: + '@ai-sdk/gateway': 2.0.0(zod@4.1.8) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + '@opentelemetry/api': 1.9.0 + zod: 4.1.8 + ajv-draft-04@1.0.0(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -8854,7 +9016,7 @@ snapshots: ccount@2.0.1: {} - chai@6.2.0: {} + chai@6.2.1: {} chalk@4.1.2: dependencies: @@ -10768,6 +10930,19 @@ snapshots: uuid: 10.0.0 optionalDependencies: openai: 4.96.2(ws@8.18.3)(zod@3.25.67) + optional: true + + langsmith@0.3.23(openai@4.96.2(ws@8.18.3)(zod@4.1.8)): + dependencies: + '@types/uuid': 10.0.0 + chalk: 4.1.2 + console-table-printer: 2.12.1 + p-queue: 6.6.2 + p-retry: 4.6.2 + semver: 7.7.1 + uuid: 10.0.0 + optionalDependencies: + openai: 4.96.2(ws@8.18.3)(zod@4.1.8) langsmith@0.3.23(openai@6.7.0(ws@8.18.3)(zod@3.25.67)): dependencies: @@ -11586,6 +11761,13 @@ snapshots: zod: 3.25.67 optional: true + ollama-ai-provider-v2@1.5.0(zod@4.1.8): + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.8) + zod: 4.1.8 + optional: true + on-exit-leak-free@2.1.2: {} on-finished@2.4.1: @@ -11643,15 +11825,45 @@ snapshots: transitivePeerDependencies: - encoding + openai@4.96.2(ws@8.18.3)(zod@4.1.12): + dependencies: + '@types/node': 18.19.87 + '@types/node-fetch': 2.6.12 + abort-controller: 3.0.0 + agentkeepalive: 4.6.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + optionalDependencies: + ws: 8.18.3 + zod: 4.1.12 + transitivePeerDependencies: + - encoding + + openai@4.96.2(ws@8.18.3)(zod@4.1.8): + dependencies: + '@types/node': 18.19.87 + '@types/node-fetch': 2.6.12 + abort-controller: 3.0.0 + agentkeepalive: 4.6.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + optionalDependencies: + ws: 8.18.3 + zod: 4.1.8 + transitivePeerDependencies: + - encoding + openai@6.7.0(ws@8.18.3)(zod@3.25.67): optionalDependencies: ws: 8.18.3 zod: 3.25.67 - openai@6.7.0(ws@8.18.3)(zod@3.25.76): + openai@6.7.0(ws@8.18.3)(zod@4.1.8): optionalDependencies: ws: 8.18.3 - zod: 3.25.76 + zod: 4.1.8 openapi-types@12.1.3: {} @@ -13279,7 +13491,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite@7.2.2(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1): + vite@7.2.2(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) @@ -13288,20 +13500,21 @@ snapshots: rollup: 4.53.2 tinyglobby: 0.2.15 optionalDependencies: + '@types/node': 20.17.32 fsevents: 2.3.3 jiti: 1.21.7 tsx: 4.19.4 yaml: 2.7.1 - vitest@4.0.8(@types/debug@4.1.12)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1): + vitest@4.0.10(@types/debug@4.1.12)(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1): dependencies: - '@vitest/expect': 4.0.8 - '@vitest/mocker': 4.0.8(vite@7.2.2(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1)) - '@vitest/pretty-format': 4.0.8 - '@vitest/runner': 4.0.8 - '@vitest/snapshot': 4.0.8 - '@vitest/spy': 4.0.8 - '@vitest/utils': 4.0.8 + '@vitest/expect': 4.0.10 + '@vitest/mocker': 4.0.10(vite@7.2.2(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1)) + '@vitest/pretty-format': 4.0.10 + '@vitest/runner': 4.0.10 + '@vitest/snapshot': 4.0.10 + '@vitest/spy': 4.0.10 + '@vitest/utils': 4.0.10 debug: 4.4.3 es-module-lexer: 1.7.0 expect-type: 1.2.2 @@ -13313,10 +13526,11 @@ snapshots: tinyexec: 0.3.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.2.2(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + vite: 7.2.2(@types/node@20.17.32)(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 + '@types/node': 20.17.32 transitivePeerDependencies: - jiti - less @@ -13488,10 +13702,26 @@ snapshots: dependencies: zod: 3.25.67 + zod-to-json-schema@3.25.0(zod@3.25.67): + dependencies: + zod: 3.25.67 + + zod-to-json-schema@3.25.0(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-to-json-schema@3.25.0(zod@4.1.8): + dependencies: + zod: 4.1.8 + zod@3.23.8: {} zod@3.25.67: {} zod@3.25.76: {} + zod@4.1.12: {} + + zod@4.1.8: {} + zwitch@2.0.4: {}