Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions .changeset/tricky-moons-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ai-sdk/provider-utils': patch
'@ai-sdk/valibot': patch
'ai': patch
---

feat: Standard JSON Schema support
51 changes: 9 additions & 42 deletions content/docs/02-foundations/04-tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,53 +41,20 @@ using [multi-step calls](/docs/ai-sdk-core/tools-and-tool-calling#multi-step-cal

## Schemas

Schemas are used to define the parameters for tools and to validate the [tool calls](/docs/ai-sdk-core/tools-and-tool-calling).
Schemas are used to define and validate the [tool input](/docs/ai-sdk-core/tools-and-tool-calling), tools outputs, and structured output generation.

The AI SDK supports both raw JSON schemas (using the [`jsonSchema` function](/docs/reference/ai-sdk-core/json-schema))
and [Zod](https://zod.dev/) schemas (either directly or using the [`zodSchema` function](/docs/reference/ai-sdk-core/zod-schema)).
The AI SDK supports the following schemas:

[Zod](https://zod.dev/) is a popular TypeScript schema validation library.
You can install it with:

<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
<Tab>
<Snippet text="pnpm add zod" dark />
</Tab>
<Tab>
<Snippet text="npm install zod" dark />
</Tab>
<Tab>
<Snippet text="yarn add zod" dark />
</Tab>

<Tab>
<Snippet text="bun add zod" dark />
</Tab>
</Tabs>

You can then specify a Zod schema, for example:

```ts
import z from 'zod';

const recipeSchema = z.object({
recipe: z.object({
name: z.string(),
ingredients: z.array(
z.object({
name: z.string(),
amount: z.string(),
}),
),
steps: z.array(z.string()),
}),
});
```
- [Zod](https://zod.dev/) v3 and v4 directly or via [`zodSchema()`](/docs/reference/ai-sdk-core/zod-schema)
- [Valibot](https://valibot.dev/) via [`valibotSchema()`](/docs/reference/ai-sdk-core/valibot-schema) from `@ai-sdk/valibot`
- [Standard JSON Schema](https://standardschema.dev/json-schema) compatible schemas
- Raw JSON schemas via [`jsonSchema()`](/docs/reference/ai-sdk-core/json-schema)

<Note>
You can also use schemas for structured output generation with
[`generateObject`](/docs/reference/ai-sdk-core/generate-object) and
[`streamObject`](/docs/reference/ai-sdk-core/stream-object).
[`generateText`](/docs/reference/ai-sdk-core/generate-text) and
[`streamText`](/docs/reference/ai-sdk-core/stream-text) using the `output`
setting.
</Note>

## Tool Packages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ description: Helper function for creating Valibot schemas

# `valibotSchema()`

<Note type="warning">`valibotSchema` is currently experimental.</Note>

`valibotSchema` is a helper function that converts a Valibot schema into a JSON schema object that is compatible with the AI SDK.
`valibotSchema` is a helper function that converts a Valibot schema into a JSON schema object
that is compatible with the AI SDK.
It takes a Valibot schema as input, and returns a typed schema.

You can use it to [generate structured data](/docs/ai-sdk-core/generating-structured-data) and in [tools](/docs/ai-sdk-core/tools-and-tool-calling).
You can use it to [generate structured data](/docs/ai-sdk-core/generating-structured-data) and
in [tools](/docs/ai-sdk-core/tools-and-tool-calling).

## Example

Expand Down
2 changes: 1 addition & 1 deletion content/docs/07-reference/01-ai-sdk-core/28-output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const { output } = await generateText({
name: 'schema',
type: 'FlexibleSchema<OBJECT>',
description:
'The schema that defines the structure of the object to generate. Supports Zod schemas, Valibot schemas, or JSON schemas.',
'The schema that defines the structure of the object to generate. Supports Zod schemas, Standard JSON schemas, and custom JSON schemas.',
},
{
name: 'name',
Expand Down
4 changes: 2 additions & 2 deletions examples/ai-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
"@opentelemetry/sdk-trace-node": "1.28.0",
"@valibot/to-json-schema": "^1.3.0",
"ai": "workspace:*",
"arktype": "2.1.22",
"arktype": "2.1.28",
"dotenv": "16.4.5",
"effect": "3.18.4",
"image-type": "^5.2.0",
"mathjs": "14.0.0",
"sharp": "^0.33.5",
"@standard-schema/spec": "1.0.0",
"@standard-schema/spec": "1.1.0",
"terminal-image": "^2.0.0",
"valibot": "1.1.0",
"zod": "3.25.76"
Expand Down
20 changes: 0 additions & 20 deletions examples/ai-core/src/generate-object/anthropic-arktype.ts

This file was deleted.

27 changes: 0 additions & 27 deletions examples/ai-core/src/generate-object/anthropic-effect.ts

This file was deleted.

25 changes: 0 additions & 25 deletions examples/ai-core/src/generate-object/anthropic-valibot.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, Output } from 'ai';
import { type } from 'arktype';
import { run } from '../lib/run';

run(async () => {
const result = await generateText({
model: anthropic('claude-3-7-sonnet-latest'),
output: Output.object({
schema: type({
recipe: {
name: 'string',
ingredients: type({ name: 'string', amount: 'string' }).array(),
steps: 'string[]',
},
}),
}),
prompt: 'Generate a lasagna recipe.',
});

console.dir(result.output.recipe, { depth: Infinity });
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { anthropic } from '@ai-sdk/anthropic';
import { valibotSchema } from '@ai-sdk/valibot';
import { generateText, Output } from 'ai';
import * as v from 'valibot';
import { run } from '../lib/run';

run(async () => {
const result = await generateText({
model: anthropic('claude-3-7-sonnet-latest'),
output: Output.object({
schema: valibotSchema(
v.object({
recipe: v.object({
name: v.string(),
ingredients: v.array(
v.object({
name: v.string(),
amount: v.string(),
}),
),
steps: v.array(v.string()),
}),
}),
),
}),
prompt: 'Generate a lasagna recipe.',
});

console.dir(result.output.recipe, { depth: Infinity });
});
26 changes: 26 additions & 0 deletions examples/ai-core/src/generate-text/anthropic-output-object-zod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, Output } from 'ai';
import { z } from 'zod';
import { print } from '../lib/print';
import { run } from '../lib/run';

run(async () => {
const result = await generateText({
model: anthropic('claude-sonnet-4-5'),
output: Output.object({
schema: z.object({
recipe: z.object({
name: z.string(),
ingredients: z.array(
z.object({ name: z.string(), amount: z.string() }),
),
steps: z.array(z.string()),
}),
}),
}),
prompt: 'Generate a lasagna recipe.',
});

print('Output:', result.output);
print('Request:', result.request.body);
});
21 changes: 12 additions & 9 deletions examples/next-openai/app/api/use-object-valibot/schema.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { DeepPartial } from 'ai';
import * as v from 'valibot';
import { valibotSchema } from '@ai-sdk/valibot';

// define a schema for the notifications
export const notificationSchema = v.object({
notifications: v.array(
v.object({
name: v.string(),
message: v.string(),
minutesAgo: v.number(),
}),
),
});
export const notificationSchema = valibotSchema(
v.object({
notifications: v.array(
v.object({
name: v.string(),
message: v.string(),
minutesAgo: v.number(),
}),
),
}),
);

// define a type for the partial notifications during generation
export type PartialNotification = DeepPartial<typeof notificationSchema>;
1 change: 1 addition & 0 deletions examples/next-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@ai-sdk/provider-utils": "4.0.0-beta.51",
"@ai-sdk/react": "3.0.0-beta.159",
"@ai-sdk/rsc": "2.0.0-beta.158",
"@ai-sdk/valibot": "2.0.0-beta.51",
"@ai-sdk/xai": "3.0.0-beta.60",
"@modelcontextprotocol/sdk": "^1.10.2",
"@radix-ui/react-collapsible": "^1.1.12",
Expand Down
3 changes: 2 additions & 1 deletion examples/next-openai/tool/weather-tool-valibot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UIToolInvocation, tool } from 'ai';
import * as v from 'valibot';
import { valibotSchema } from '@ai-sdk/valibot';

function randomWeather() {
const weatherOptions = ['sunny', 'cloudy', 'rainy', 'windy'];
Expand All @@ -8,7 +9,7 @@ function randomWeather() {

export const weatherToolValibot = tool({
description: 'Get the weather in a location',
inputSchema: v.object({ city: v.string() }),
inputSchema: valibotSchema(v.object({ city: v.string() })),
async *execute() {
yield { state: 'loading' as const };

Expand Down
22 changes: 2 additions & 20 deletions packages/provider-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,37 +41,19 @@
},
"dependencies": {
"@ai-sdk/provider": "workspace:*",
"@standard-schema/spec": "^1.0.0",
"@standard-schema/spec": "^1.1.0",
"eventsource-parser": "^3.0.6"
},
"devDependencies": {
"@types/node": "20.17.24",
"@valibot/to-json-schema": "^1.3.0",
"@vercel/ai-tsconfig": "workspace:*",
"arktype": "^2.1.22",
"effect": "^3.18.4",
"msw": "2.7.0",
"tsup": "^8",
"typescript": "5.8.3",
"valibot": "1.1.0",
"zod": "3.25.76"
},
"peerDependencies": {
"arktype": "^2.1.22",
"effect": "^3.18.4",
"zod": "^3.25.76 || ^4.1.8",
"@valibot/to-json-schema": "^1.3.0"
},
"peerDependenciesMeta": {
"arktype": {
"optional": true
},
"effect": {
"optional": true
},
"@valibot/to-json-schema": {
"optional": true
}
"zod": "^3.25.76 || ^4.1.8"
},
"engines": {
"node": ">=18"
Expand Down
Loading
Loading