Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d1427e7
wip
gr2m May 7, 2025
5cf9e1e
wip
gr2m May 7, 2025
0b60713
Implement standard-schema in `packages/provider-utils/src/validator.ts`
lgrammel May 7, 2025
5f155ab
Merge branch 'v5' into v5-gr2m/5766-replace-zod-with-standard-schema
gr2m May 7, 2025
4178db1
wip
gr2m May 13, 2025
0ae0198
Merge branch 'v5' into v5-gr2m/5766-replace-zod-with-standard-schema
gr2m May 13, 2025
f9c6496
wip
gr2m May 13, 2025
1863dfd
wip
gr2m May 13, 2025
6a17b21
wip
gr2m May 13, 2025
9b95f49
wip
gr2m May 13, 2025
049e376
wip
gr2m May 13, 2025
351182f
wip
gr2m May 13, 2025
83be4e6
wip
gr2m May 13, 2025
a770a76
wip
gr2m May 13, 2025
0cac1bd
wip
gr2m May 13, 2025
3395c3d
wip
gr2m May 13, 2025
fd960ef
wip
gr2m May 13, 2025
71ea96e
wip
gr2m May 13, 2025
3edd3e7
wip
gr2m May 14, 2025
7b3d1f2
Merge branch 'v5' into v5-gr2m/5766-replace-zod-with-standard-schema
gr2m May 14, 2025
1d4bb39
revert `OBJECT` back to `ELEMENT`
gr2m May 14, 2025
3ce7553
reverse changes to `schema.ts` and `zod-schema.ts`
gr2m May 15, 2025
b41723d
remove `T_` prefix from type generics
gr2m May 15, 2025
1d0ba87
style: prettier
gr2m May 15, 2025
dad65b2
wip
gr2m May 15, 2025
a59486b
revert more changes
gr2m May 15, 2025
5f020ca
revert more changes
gr2m May 15, 2025
fa0f0d1
gca revert more changes
gr2m May 15, 2025
15b28ce
make `validate` async in `schema.ts`
gr2m May 15, 2025
446415a
undo debug changes in test
gr2m May 15, 2025
1cc03ca
make `validate` async in `zod-schema.ts` - we might want to allow a s…
gr2m May 15, 2025
bcb9690
undo formatting changes
gr2m May 15, 2025
8e9bd55
revert formatting changes and type generic name
gr2m May 15, 2025
7dd4d9e
make `validate` async in `valibot-schema`
gr2m May 15, 2025
94c9668
re-export `zodSchema` from `@ai-sdk/provider-utils`
gr2m May 15, 2025
6932097
revert changes to packages/provider-utils/src/parse-json.ts
gr2m May 15, 2025
7bdb620
revert changes to packages/provider-utils/src/parse-json.ts
gr2m May 15, 2025
a706a80
make `validate()` method optionally async
gr2m May 15, 2025
23ff810
style: prettier
gr2m May 15, 2025
732b9f3
adapt packages/provider-utils/src/validate-types.test.ts
gr2m May 15, 2025
cc0a0cd
add todo comment
gr2m May 15, 2025
5720b01
adapt tests
gr2m May 15, 2025
5e27626
use `ts-expect-error` instead of `ts-ignore`
gr2m May 15, 2025
430f527
fx
lgrammel May 15, 2025
b4ba863
Merge branch 'v5-gr2m/5766-replace-zod-with-standard-schema' of https…
lgrammel May 15, 2025
9592c8b
cs
lgrammel May 15, 2025
f284b6d
Merge branch 'v5' into v5-gr2m/5766-replace-zod-with-standard-schema
lgrammel May 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/ai-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"mathjs": "14.0.0",
"sharp": "^0.33.5",
"terminal-image": "^2.0.0",
"zod": "3.23.8",
"zod": "3.24.4",
"zod-to-json-schema": "3.23.5",
"valibot": "^1.0.0-rc.0 || ^1.0.0"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/mcp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"ai": "workspace:*",
"dotenv": "16.4.5",
"express": "5.0.1",
"zod": "3.23.8"
"zod": "3.24.4"
},
"devDependencies": {
"@types/express": "5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion examples/next-openai-pages/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"next": "latest",
"react": "^18",
"react-dom": "^18",
"zod": "3.23.8"
"zod": "3.24.4"
},
"devDependencies": {
"@types/node": "20.17.24",
Expand Down
2 changes: 1 addition & 1 deletion examples/next-openai-telemetry-sentry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"next": "latest",
"react": "^18",
"react-dom": "^18",
"zod": "3.23.8"
"zod": "3.24.4"
},
"devDependencies": {
"@types/node": "20.17.24",
Expand Down
2 changes: 1 addition & 1 deletion examples/next-openai-telemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"next": "latest",
"react": "^18",
"react-dom": "^18",
"zod": "3.23.8"
"zod": "3.24.4"
},
"devDependencies": {
"@types/node": "20.17.24",
Expand Down
2 changes: 1 addition & 1 deletion examples/next-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"react-markdown": "9.0.1",
"redis": "^4.7.0",
"resumable-stream": "^2.0.0",
"zod": "3.23.8"
"zod": "3.24.4"
},
"devDependencies": {
"@types/node": "20.17.24",
Expand Down
2 changes: 1 addition & 1 deletion examples/node-http-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"@ai-sdk/openai": "workspace:*",
"ai": "workspace:*",
"dotenv": "16.4.5",
"zod": "3.23.8",
"zod": "3.24.4",
"zod-to-json-schema": "3.23.5"
},
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion examples/nuxt-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@ai-sdk/vue": "workspace:*",
"@ai-sdk/openai": "workspace:*",
"ai": "workspace:*",
"zod": "3.23.8"
"zod": "3.24.4"
},
"devDependencies": {
"@nuxt/devtools": "1.6.3",
Expand Down
2 changes: 1 addition & 1 deletion examples/sveltekit-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"typescript": "^5.0.0",
"typescript-eslint": "^8.20.0",
"vite": "^6.0.0",
"zod": "3.23.8",
"zod": "3.24.4",
"@vercel/ai-tsconfig": "workspace:*"
}
}
32 changes: 16 additions & 16 deletions packages/ai/core/generate-object/generate-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export async function generateObject<
? {
/**
The enum values that the model should use.
*/
*/
enum: Array<RESULT>;
mode?: 'json';
output: 'enum';
Expand All @@ -147,21 +147,21 @@ The enum values that the model should use.
: {
/**
The schema of the object that the model should generate.
*/
*/
schema: SCHEMA;

/**
Optional name of the output that should be generated.
Used by some providers for additional LLM guidance, e.g.
via tool or schema name.
*/
*/
schemaName?: string;

/**
Optional description of the output that should be generated.
Used by some providers for additional LLM guidance, e.g.
via tool or schema description.
*/
*/
schemaDescription?: string;

/**
Expand All @@ -176,32 +176,32 @@ The schema is converted into a JSON schema and used in one of the following ways
Please note that most providers do not support all modes.

Default and recommended: 'auto' (best mode for the model).
*/
*/
mode?: 'auto' | 'json' | 'tool';
}) & {
output?: Output;

/**
The language model to use.
*/
The language model to use.
*/
model: LanguageModel;
/**
A function that attempts to repair the raw output of the mode
to enable JSON parsing.
*/
A function that attempts to repair the raw output of the mode
to enable JSON parsing.
*/
experimental_repairText?: RepairTextFunction;

/**
Optional telemetry configuration (experimental).
*/
Optional telemetry configuration (experimental).
*/

experimental_telemetry?: TelemetrySettings;

/**
Additional provider-specific options. They are passed through
to the provider from the AI SDK and enable provider-specific
functionality that can be fully encapsulated in the provider.
*/
Additional provider-specific options. They are passed through
to the provider from the AI SDK and enable provider-specific
functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;

/**
Expand Down
73 changes: 46 additions & 27 deletions packages/ai/core/generate-object/output-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ const noSchemaOutputStrategy: OutputStrategy<JSONValue, JSONValue, never> = {
): Promise<ValidationResult<JSONValue>> {
return value === undefined
? {
success: false,
error: new NoObjectGeneratedError({
message: 'No object generated: response did not match schema.',
text: context.text,
response: context.response,
usage: context.usage,
finishReason: context.finishReason,
}),
}
success: false,
error: new NoObjectGeneratedError({
message: 'No object generated: response did not match schema.',
text: context.text,
response: context.response,
usage: context.usage,
finishReason: context.finishReason,
}),
}
: { success: true, value };
},

Expand All @@ -101,7 +101,11 @@ const noSchemaOutputStrategy: OutputStrategy<JSONValue, JSONValue, never> = {

const objectOutputStrategy = <OBJECT>(
schema: Schema<OBJECT>,
): OutputStrategy<DeepPartial<OBJECT>, OBJECT, never> => ({
): OutputStrategy<
DeepPartial<OBJECT>,
OBJECT,
never
> => ({
type: 'object',
jsonSchema: schema.jsonSchema,

Expand All @@ -119,6 +123,7 @@ const objectOutputStrategy = <OBJECT>(
async validateFinalResult(
value: JSONValue | undefined,
): Promise<ValidationResult<OBJECT>> {
// @gr2m TODO: `schema` should matche the Validator type.
return safeValidateTypes({ value, schema });
},

Expand All @@ -129,9 +134,13 @@ const objectOutputStrategy = <OBJECT>(
},
});

const arrayOutputStrategy = <ELEMENT>(
schema: Schema<ELEMENT>,
): OutputStrategy<ELEMENT[], ELEMENT[], AsyncIterableStream<ELEMENT>> => {
const arrayOutputStrategy = <OBJECT>(
schema: Schema<OBJECT>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ELEMENT was on purpose because it is an array element

): OutputStrategy<
OBJECT[],
OBJECT[],
AsyncIterableStream<OBJECT>
> => {
// remove $schema from schema.jsonSchema:
const { $schema, ...itemSchema } = schema.jsonSchema;

Expand Down Expand Up @@ -169,7 +178,7 @@ const arrayOutputStrategy = <ELEMENT>(
}

const inputArray = value.elements as Array<JSONObject>;
const resultArray: Array<ELEMENT> = [];
const resultArray: Array<OBJECT> = [];

for (let i = 0; i < inputArray.length; i++) {
const element = inputArray[i];
Expand Down Expand Up @@ -223,7 +232,9 @@ const arrayOutputStrategy = <ELEMENT>(

async validateFinalResult(
value: JSONValue | undefined,
): Promise<ValidationResult<Array<ELEMENT>>> {
): Promise<
ValidationResult<Array<OBJECT>>
> {
// check that the value is an object that contains an array of elements:
if (!isJSONObject(value) || !isJSONArray(value.elements)) {
return {
Expand All @@ -245,17 +256,25 @@ const arrayOutputStrategy = <ELEMENT>(
}
}

return { success: true, value: inputArray as Array<ELEMENT> };
return {
success: true,
value: inputArray as Array<OBJECT>,
};
},

createElementStream(
originalStream: ReadableStream<ObjectStreamPart<ELEMENT[]>>,
originalStream: ReadableStream<
ObjectStreamPart<OBJECT[]>
>,
) {
let publishedElements = 0;

return createAsyncIterableStream(
originalStream.pipeThrough(
new TransformStream<ObjectStreamPart<ELEMENT[]>, ELEMENT>({
new TransformStream<
ObjectStreamPart<OBJECT[]>,
OBJECT
>({
transform(chunk, controller) {
switch (chunk.type) {
case 'object': {
Expand Down Expand Up @@ -332,12 +351,12 @@ const enumOutputStrategy = <ENUM extends string>(
return enumValues.includes(result as ENUM)
? { success: true, value: result as ENUM }
: {
success: false,
error: new TypeValidationError({
value,
cause: 'value must be a string in the enum',
}),
};
success: false,
error: new TypeValidationError({
value,
cause: 'value must be a string in the enum',
}),
};
},

async validatePartialResult({ value, textDelta }) {
Expand Down Expand Up @@ -386,14 +405,14 @@ const enumOutputStrategy = <ENUM extends string>(
};
};

export function getOutputStrategy<SCHEMA>({
export function getOutputStrategy<OBJECT>({
output,
schema,
enumValues,
}: {
output: 'object' | 'array' | 'enum' | 'no-schema';
schema?: z.Schema<SCHEMA, z.ZodTypeDef, any> | Schema<SCHEMA>;
enumValues?: Array<SCHEMA>;
schema?: Schema<OBJECT>;
enumValues?: Array<OBJECT>;
}): OutputStrategy<any, any, any> {
switch (output) {
case 'object':
Expand Down
2 changes: 1 addition & 1 deletion packages/ai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"eslint-config-vercel-ai": "workspace:*",
"tsup": "^7.2.0",
"typescript": "5.8.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.23.8"
Expand Down
4 changes: 2 additions & 2 deletions packages/amazon-bedrock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
"@vercel/ai-tsconfig": "workspace:*",
"tsup": "^8.3.0",
"typescript": "5.8.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.0.0"
"zod": "^3.24.0"
},
"engines": {
"node": ">=18"
Expand Down
4 changes: 2 additions & 2 deletions packages/anthropic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@
"@vercel/ai-tsconfig": "workspace:*",
"tsup": "^8",
"typescript": "5.8.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.0.0"
"zod": "^3.24.0"
},
"engines": {
"node": ">=18"
Expand Down
4 changes: 2 additions & 2 deletions packages/assemblyai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
"@vercel/ai-tsconfig": "workspace:*",
"tsup": "^8",
"typescript": "5.6.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.0.0"
"zod": "^3.24.0"
},
"engines": {
"node": ">=18"
Expand Down
4 changes: 2 additions & 2 deletions packages/azure/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
"@vercel/ai-tsconfig": "workspace:*",
"tsup": "^8",
"typescript": "5.8.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.0.0"
"zod": "^3.24.0"
},
"engines": {
"node": ">=18"
Expand Down
4 changes: 2 additions & 2 deletions packages/cerebras/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
"@vercel/ai-tsconfig": "workspace:*",
"tsup": "^8",
"typescript": "5.8.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.0.0"
"zod": "^3.24.0"
},
"engines": {
"node": ">=18"
Expand Down
4 changes: 2 additions & 2 deletions packages/cohere/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
"@vercel/ai-tsconfig": "workspace:*",
"tsup": "^8",
"typescript": "5.8.3",
"zod": "3.23.8"
"zod": "3.24.4"
},
"peerDependencies": {
"zod": "^3.0.0"
"zod": "^3.24.0"
},
"engines": {
"node": ">=18"
Expand Down
Loading
Loading