ai 7.0.57 → 7.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/dist/index.d.ts +9 -8
- package/dist/index.js +563 -534
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +183 -152
- package/dist/internal/index.js.map +1 -1
- package/docs/03-ai-sdk-core/38-video-generation.mdx +16 -0
- package/docs/03-ai-sdk-harnesses/03-tools.mdx +3 -1
- package/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx +2 -0
- package/docs/06-advanced/02-stopping-streams.mdx +22 -1
- package/docs/06-advanced/04-caching.mdx +1 -3
- package/docs/06-advanced/06-rate-limiting.mdx +5 -6
- package/docs/06-advanced/10-vercel-deployment-guide.mdx +41 -0
- package/docs/07-reference/01-ai-sdk-core/13-generate-video.mdx +1 -1
- package/package.json +4 -4
- package/src/agent/tool-loop-agent.ts +2 -2
- package/src/generate-video/generate-video.ts +4 -3
- package/src/prompt/content-part.ts +18 -17
- package/src/prompt/message.ts +10 -12
- package/src/prompt/standardize-prompt.ts +1 -1
- package/src/types/json-value.ts +2 -2
- package/src/types/provider-metadata.ts +2 -2
- package/src/ui/validate-ui-messages.ts +2 -2
- package/src/ui-message-stream/ui-message-chunks.ts +2 -2
- package/src/util/zod.ts +43 -0
|
@@ -48,6 +48,22 @@ const { video } = await generateVideo({
|
|
|
48
48
|
});
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
Some models also accept `'adaptive'`, which lets the provider derive the output
|
|
52
|
+
ratio from the input media instead of a fixed value. This is typically required
|
|
53
|
+
for image-to-video, video editing, and video extension, where the output
|
|
54
|
+
inherits the ratio of the input and an explicit ratio is rejected.
|
|
55
|
+
|
|
56
|
+
```tsx highlight={"7"}
|
|
57
|
+
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
58
|
+
__PROVIDER_IMPORT__;
|
|
59
|
+
|
|
60
|
+
const { video } = await generateVideo({
|
|
61
|
+
model: __VIDEO_MODEL__,
|
|
62
|
+
prompt: { image: firstFrame, text: 'A cat walking on a treadmill' },
|
|
63
|
+
aspectRatio: 'adaptive',
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
51
67
|
### Resolution
|
|
52
68
|
|
|
53
69
|
The resolution is specified as a string in the format `{width}x{height}`.
|
|
@@ -5,11 +5,13 @@ description: Use tools with AI SDK harnesses.
|
|
|
5
5
|
|
|
6
6
|
# Harness Tools
|
|
7
7
|
|
|
8
|
-
Harnesses have
|
|
8
|
+
Harnesses have three tool surfaces:
|
|
9
9
|
|
|
10
10
|
- Built-in tools exposed by the underlying harness runtime, such as file reads,
|
|
11
11
|
edits, shell commands, and web search.
|
|
12
12
|
- AI SDK tools that you pass to `HarnessAgent` with the `tools` setting.
|
|
13
|
+
- External MCP tools configured through the harness adapter's `mcpServers`
|
|
14
|
+
setting.
|
|
13
15
|
|
|
14
16
|
This page covers harness-specific behavior. For general AI SDK tool concepts,
|
|
15
17
|
schemas, tool results, and `tool()` usage, see [Tools](/docs/foundations/tools).
|
|
@@ -17,6 +17,7 @@ The AI SDK includes the following harness adapters:
|
|
|
17
17
|
- [Claude Code](/providers/ai-sdk-harnesses/claude-code) (`@ai-sdk/harness-claude-code`)
|
|
18
18
|
- [Codex](/providers/ai-sdk-harnesses/codex) (`@ai-sdk/harness-codex`)
|
|
19
19
|
- [Deep Agents](/providers/ai-sdk-harnesses/deepagents) (`@ai-sdk/harness-deepagents`)
|
|
20
|
+
- [Grok Build](/providers/ai-sdk-harnesses/grok-build) (`@ai-sdk/harness-grok-build`)
|
|
20
21
|
- [OpenCode](/providers/ai-sdk-harnesses/opencode) (`@ai-sdk/harness-opencode`)
|
|
21
22
|
- [Pi](/providers/ai-sdk-harnesses/pi) (`@ai-sdk/harness-pi`)
|
|
22
23
|
|
|
@@ -33,5 +34,6 @@ The AI SDK includes the following harness adapters:
|
|
|
33
34
|
| [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
34
35
|
| [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check /> | <Check /> | <Cross /> | <Cross /> |
|
|
35
36
|
| [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection |
|
|
37
|
+
| [Grok Build](/providers/ai-sdk-harnesses/grok-build) | Sandbox via ACP | <Check /> | <Check /> | <Check /> | <Cross /> |
|
|
36
38
|
| [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection |
|
|
37
39
|
| [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
@@ -44,7 +44,7 @@ export async function POST(req: Request) {
|
|
|
44
44
|
## AI SDK UI
|
|
45
45
|
|
|
46
46
|
The hooks, e.g. `useChat` or `useCompletion`, provide a `stop` helper function that can be used to cancel a stream.
|
|
47
|
-
This
|
|
47
|
+
This aborts the HTTP request from the client. To also stop the model request on the server, your server runtime must propagate the client disconnect to the request's `AbortSignal`, and your route must forward that signal to the AI SDK Core call as shown above.
|
|
48
48
|
|
|
49
49
|
<Note type="warning">
|
|
50
50
|
Stream abort functionality is not compatible with stream resumption. If you're
|
|
@@ -78,6 +78,27 @@ export default function Chat() {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
### Vercel
|
|
82
|
+
|
|
83
|
+
On Vercel, [request cancellation](https://vercel.com/docs/functions/functions-api-reference#cancel-requests) is only supported in the Node.js runtime and must be enabled for each function that needs it. Add `supportsCancellation` to the function's configuration in `vercel.json`:
|
|
84
|
+
|
|
85
|
+
```json filename="vercel.json"
|
|
86
|
+
{
|
|
87
|
+
"functions": {
|
|
88
|
+
"app/api/chat/route.ts": {
|
|
89
|
+
"supportsCancellation": true
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
With cancellation enabled, calling `stop()` aborts the client request, Vercel aborts `req.signal`, and forwarding `req.signal` as `abortSignal` cancels the model request.
|
|
96
|
+
|
|
97
|
+
<Note type="warning">
|
|
98
|
+
Without `supportsCancellation`, `stop()` still stops the client-side stream
|
|
99
|
+
but the server-side generation may continue.
|
|
100
|
+
</Note>
|
|
101
|
+
|
|
81
102
|
## Handling stream abort cleanup
|
|
82
103
|
|
|
83
104
|
When streams are aborted, you may need to perform cleanup operations such as persisting partial results or cleaning up resources. The `onAbort` callback provides a way to handle these scenarios on the server side.
|
|
@@ -120,9 +120,7 @@ You can see a full example of caching with Redis in a Next.js application in our
|
|
|
120
120
|
|
|
121
121
|
Alternatively, each AI SDK Core function has special lifecycle callbacks you can use. The one of interest is likely `onEnd`, which is called when the generation is complete. This is where you can cache the full response.
|
|
122
122
|
|
|
123
|
-
Here's an example of how you can
|
|
124
|
-
|
|
125
|
-
This example uses [Upstash Redis](https://upstash.com/docs/redis/overall/getstarted) and Next.js to cache the response for 1 hour.
|
|
123
|
+
Here's an example of how you can use [Upstash Redis](https://upstash.com/redis) and Next.js to cache the OpenAI response for 1 hour:
|
|
126
124
|
|
|
127
125
|
```tsx filename="app/api/chat/route.ts"
|
|
128
126
|
import {
|
|
@@ -11,13 +11,11 @@ specified timeframe. This simple technique acts as a gatekeeper,
|
|
|
11
11
|
preventing excessive usage that can degrade service performance and incur
|
|
12
12
|
unnecessary costs.
|
|
13
13
|
|
|
14
|
-
## Rate Limiting with
|
|
14
|
+
## Rate Limiting with Upstash Redis and Upstash Ratelimit
|
|
15
15
|
|
|
16
|
-
In this example, you will protect an API endpoint using [
|
|
17
|
-
and [Upstash Ratelimit](https://github.com/upstash/ratelimit).
|
|
16
|
+
In this example, you will protect an API endpoint using [Upstash Redis](https://upstash.com/redis) and [Upstash Ratelimit](https://github.com/upstash/ratelimit).
|
|
18
17
|
|
|
19
18
|
```tsx filename='app/api/generate/route.ts'
|
|
20
|
-
import kv from '@vercel/kv';
|
|
21
19
|
import {
|
|
22
20
|
createUIMessageStreamResponse,
|
|
23
21
|
streamText,
|
|
@@ -25,6 +23,7 @@ import {
|
|
|
25
23
|
} from 'ai';
|
|
26
24
|
__PROVIDER_IMPORT__;
|
|
27
25
|
import { Ratelimit } from '@upstash/ratelimit';
|
|
26
|
+
import { Redis } from '@upstash/redis';
|
|
28
27
|
import { NextRequest } from 'next/server';
|
|
29
28
|
|
|
30
29
|
// Allow streaming responses up to 30 seconds
|
|
@@ -32,7 +31,7 @@ export const maxDuration = 30;
|
|
|
32
31
|
|
|
33
32
|
// Create Rate limit
|
|
34
33
|
const ratelimit = new Ratelimit({
|
|
35
|
-
redis:
|
|
34
|
+
redis: Redis.fromEnv(),
|
|
36
35
|
limiter: Ratelimit.fixedWindow(5, '30s'),
|
|
37
36
|
});
|
|
38
37
|
|
|
@@ -61,6 +60,6 @@ export async function POST(req: NextRequest) {
|
|
|
61
60
|
|
|
62
61
|
## Simplify API Protection
|
|
63
62
|
|
|
64
|
-
With
|
|
63
|
+
With Upstash Redis and Upstash Ratelimit, it is possible to protect your APIs
|
|
65
64
|
from such attacks with ease. To learn more about how Ratelimit works and
|
|
66
65
|
how it can be configured to your needs, see [Ratelimit Documentation](https://upstash.com/docs/oss/sdks/ts/ratelimit/overview).
|
|
@@ -95,6 +95,47 @@ export const maxDuration = 30;
|
|
|
95
95
|
|
|
96
96
|
You can increase the max duration to 60 seconds on the Hobby Tier. For other tiers, [see the documentation](https://vercel.com/docs/functions/runtimes#max-duration) for limits.
|
|
97
97
|
|
|
98
|
+
### Request Cancellation
|
|
99
|
+
|
|
100
|
+
AI SDK UI helpers such as `useChat` and `useCompletion` abort the client request when you call `stop()`. To propagate that cancellation to a Vercel Function and its model request, you must:
|
|
101
|
+
|
|
102
|
+
1. Use the Node.js runtime, which is the default for Next.js route handlers.
|
|
103
|
+
2. Enable [`supportsCancellation`](https://vercel.com/docs/functions/functions-api-reference#cancel-requests) for the route in `vercel.json`.
|
|
104
|
+
3. Forward the route's `req.signal` to `streamText` or `generateText` as `abortSignal`.
|
|
105
|
+
|
|
106
|
+
For example, enable cancellation for your chat route:
|
|
107
|
+
|
|
108
|
+
```json filename="vercel.json"
|
|
109
|
+
{
|
|
110
|
+
"functions": {
|
|
111
|
+
"app/api/chat/route.ts": {
|
|
112
|
+
"supportsCancellation": true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Then forward the request signal to the AI SDK:
|
|
119
|
+
|
|
120
|
+
```ts filename="app/api/chat/route.ts" highlight="10"
|
|
121
|
+
import { convertToModelMessages, streamText, type UIMessage } from 'ai';
|
|
122
|
+
__PROVIDER_IMPORT__;
|
|
123
|
+
|
|
124
|
+
export async function POST(req: Request) {
|
|
125
|
+
const { messages }: { messages: UIMessage[] } = await req.json();
|
|
126
|
+
|
|
127
|
+
const result = streamText({
|
|
128
|
+
model: __MODEL__,
|
|
129
|
+
messages: convertToModelMessages(messages),
|
|
130
|
+
abortSignal: req.signal,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return result.toUIMessageStreamResponse();
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Without `supportsCancellation`, calling `stop()` closes the client-side stream but does not cancel the Vercel Function or model request. See [Stopping Streams](/docs/advanced/stopping-streams) for the complete client and server setup.
|
|
138
|
+
|
|
98
139
|
## Security Considerations
|
|
99
140
|
|
|
100
141
|
Given the high cost of calling an LLM, it's important to have measures in place that can protect your application from abuse.
|
|
@@ -83,7 +83,7 @@ console.log(videos);
|
|
|
83
83
|
type: 'string',
|
|
84
84
|
isOptional: true,
|
|
85
85
|
description:
|
|
86
|
-
|
|
86
|
+
"Aspect ratio of the videos to generate. Format: `{width}:{height}`, or `'adaptive'` to inherit the ratio from the input media (e.g. a first-frame image or a source video). Support for `'adaptive'` is provider-specific.",
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
name: 'resolution',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.59",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@ai-sdk/gateway": "4.0.
|
|
46
|
-
"@ai-sdk/provider": "4.0.
|
|
47
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.47",
|
|
46
|
+
"@ai-sdk/provider": "4.0.7",
|
|
47
|
+
"@ai-sdk/provider-utils": "5.0.26"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@edge-runtime/vm": "^5.0.0",
|
|
@@ -219,7 +219,7 @@ export class ToolLoopAgent<
|
|
|
219
219
|
});
|
|
220
220
|
const callbackArgs = {
|
|
221
221
|
abortSignal,
|
|
222
|
-
timeout,
|
|
222
|
+
timeout: timeout ?? preparedCall.timeout,
|
|
223
223
|
experimental_sandbox: sandbox,
|
|
224
224
|
onStart: mergeCallbacks(
|
|
225
225
|
this.settings.onStart ?? this.settings.experimental_onStart,
|
|
@@ -284,7 +284,7 @@ export class ToolLoopAgent<
|
|
|
284
284
|
});
|
|
285
285
|
const callbackArgs = {
|
|
286
286
|
abortSignal,
|
|
287
|
-
timeout,
|
|
287
|
+
timeout: timeout ?? preparedCall.timeout,
|
|
288
288
|
experimental_sandbox: sandbox,
|
|
289
289
|
experimental_transform,
|
|
290
290
|
onStart: mergeCallbacks(
|
|
@@ -93,7 +93,7 @@ export type GenerateVideoWebhookFactory = () => PromiseLike<{
|
|
|
93
93
|
* @param model - The video model to use.
|
|
94
94
|
* @param prompt - The prompt that should be used to generate the video.
|
|
95
95
|
* @param n - Number of videos to generate. Default: 1.
|
|
96
|
-
* @param aspectRatio - Aspect ratio of the videos to generate. Must have the format `{width}:{height}`.
|
|
96
|
+
* @param aspectRatio - Aspect ratio of the videos to generate. Must have the format `{width}:{height}`, or `'adaptive'`.
|
|
97
97
|
* @param resolution - Resolution of the videos to generate. Must have the format `{width}x{height}`.
|
|
98
98
|
* @param duration - Duration of the video in seconds.
|
|
99
99
|
* @param fps - Frames per second for the video.
|
|
@@ -155,9 +155,10 @@ export async function experimental_generateVideo({
|
|
|
155
155
|
maxVideosPerCall?: number;
|
|
156
156
|
|
|
157
157
|
/**
|
|
158
|
-
* Aspect ratio of the videos to generate. Must have the format
|
|
158
|
+
* Aspect ratio of the videos to generate. Must have the format
|
|
159
|
+
* `{width}:{height}`, or `'adaptive'` to inherit the ratio from the input media.
|
|
159
160
|
*/
|
|
160
|
-
aspectRatio?: `${number}:${number}
|
|
161
|
+
aspectRatio?: `${number}:${number}` | 'adaptive';
|
|
161
162
|
|
|
162
163
|
/**
|
|
163
164
|
* Resolution of the videos to generate. Must have the format `{width}x${height}`.
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
type ToolResultOutput,
|
|
14
14
|
type ToolResultPart,
|
|
15
15
|
} from '@ai-sdk/provider-utils';
|
|
16
|
-
import { z } from 'zod/v4';
|
|
17
16
|
import { jsonValueSchema } from '../types/json-value';
|
|
18
17
|
import { providerMetadataSchema } from '../types/provider-metadata';
|
|
18
|
+
import { z, type ZodType } from '../util/zod';
|
|
19
19
|
|
|
20
|
-
const fileInlineDataSchema:
|
|
20
|
+
const fileInlineDataSchema: ZodType<DataContent> = z.union([
|
|
21
21
|
z.string(),
|
|
22
22
|
z.instanceof(Uint8Array),
|
|
23
23
|
z.instanceof(ArrayBuffer),
|
|
@@ -29,7 +29,7 @@ const providerReferenceSchema = z.record(z.string(), z.string());
|
|
|
29
29
|
/**
|
|
30
30
|
* @internal
|
|
31
31
|
*/
|
|
32
|
-
export const textPartSchema:
|
|
32
|
+
export const textPartSchema: ZodType<TextPart> = z.object({
|
|
33
33
|
type: z.literal('text'),
|
|
34
34
|
text: z.string(),
|
|
35
35
|
providerOptions: providerMetadataSchema.optional(),
|
|
@@ -40,7 +40,7 @@ export const textPartSchema: z.ZodType<TextPart> = z.object({
|
|
|
40
40
|
* @deprecated Use `filePartSchema` with `mediaType: 'image'` instead:
|
|
41
41
|
* `{ type: 'file', mediaType: 'image', data: { type: 'data', data } }`.
|
|
42
42
|
*/
|
|
43
|
-
export const imagePartSchema:
|
|
43
|
+
export const imagePartSchema: ZodType<ImagePart> = z.object({
|
|
44
44
|
type: z.literal('image'),
|
|
45
45
|
image: z.union([
|
|
46
46
|
fileInlineDataSchema,
|
|
@@ -69,7 +69,7 @@ const taggedReasoningFileDataSchema = z.discriminatedUnion('type', [
|
|
|
69
69
|
/**
|
|
70
70
|
* @internal
|
|
71
71
|
*/
|
|
72
|
-
export const filePartSchema:
|
|
72
|
+
export const filePartSchema: ZodType<FilePart> = z.object({
|
|
73
73
|
type: z.literal('file'),
|
|
74
74
|
data: z.union([
|
|
75
75
|
taggedFileDataSchema,
|
|
@@ -85,7 +85,7 @@ export const filePartSchema: z.ZodType<FilePart> = z.object({
|
|
|
85
85
|
/**
|
|
86
86
|
* @internal
|
|
87
87
|
*/
|
|
88
|
-
export const reasoningPartSchema:
|
|
88
|
+
export const reasoningPartSchema: ZodType<ReasoningPart> = z.object({
|
|
89
89
|
type: z.literal('reasoning'),
|
|
90
90
|
text: z.string(),
|
|
91
91
|
providerOptions: providerMetadataSchema.optional(),
|
|
@@ -94,7 +94,7 @@ export const reasoningPartSchema: z.ZodType<ReasoningPart> = z.object({
|
|
|
94
94
|
/**
|
|
95
95
|
* @internal
|
|
96
96
|
*/
|
|
97
|
-
export const customPartSchema:
|
|
97
|
+
export const customPartSchema: ZodType<CustomPart> = z.object({
|
|
98
98
|
type: z.literal('custom'),
|
|
99
99
|
kind: z.string().transform(value => value as `${string}.${string}`),
|
|
100
100
|
providerOptions: providerMetadataSchema.optional(),
|
|
@@ -103,7 +103,7 @@ export const customPartSchema: z.ZodType<CustomPart> = z.object({
|
|
|
103
103
|
/**
|
|
104
104
|
* @internal
|
|
105
105
|
*/
|
|
106
|
-
export const reasoningFilePartSchema:
|
|
106
|
+
export const reasoningFilePartSchema: ZodType<ReasoningFilePart> = z.object({
|
|
107
107
|
type: z.literal('reasoning-file'),
|
|
108
108
|
data: z.union([
|
|
109
109
|
taggedReasoningFileDataSchema,
|
|
@@ -146,19 +146,19 @@ export interface ToolCallPart {
|
|
|
146
146
|
/**
|
|
147
147
|
* @internal
|
|
148
148
|
*/
|
|
149
|
-
export const toolCallPartSchema:
|
|
149
|
+
export const toolCallPartSchema: ZodType<ToolCallPart> = z.object({
|
|
150
150
|
type: z.literal('tool-call'),
|
|
151
151
|
toolCallId: z.string(),
|
|
152
152
|
toolName: z.string(),
|
|
153
153
|
input: z.unknown(),
|
|
154
154
|
providerOptions: providerMetadataSchema.optional(),
|
|
155
155
|
providerExecuted: z.boolean().optional(),
|
|
156
|
-
}) as
|
|
156
|
+
}) as ZodType<ToolCallPart>; // necessary bc input is optional on Zod type
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
159
|
* @internal
|
|
160
160
|
*/
|
|
161
|
-
export const outputSchema:
|
|
161
|
+
export const outputSchema: ZodType<ToolResultOutput> = z.discriminatedUnion(
|
|
162
162
|
'type',
|
|
163
163
|
[
|
|
164
164
|
z.object({
|
|
@@ -267,28 +267,29 @@ export const outputSchema: z.ZodType<ToolResultOutput> = z.discriminatedUnion(
|
|
|
267
267
|
/**
|
|
268
268
|
* @internal
|
|
269
269
|
*/
|
|
270
|
-
export const toolResultPartSchema:
|
|
270
|
+
export const toolResultPartSchema: ZodType<ToolResultPart> = z.object({
|
|
271
271
|
type: z.literal('tool-result'),
|
|
272
272
|
toolCallId: z.string(),
|
|
273
273
|
toolName: z.string(),
|
|
274
274
|
output: outputSchema,
|
|
275
275
|
providerOptions: providerMetadataSchema.optional(),
|
|
276
|
-
}) as
|
|
276
|
+
}) as ZodType<ToolResultPart>; // necessary bc result is optional on Zod type
|
|
277
277
|
|
|
278
278
|
/**
|
|
279
279
|
* @internal
|
|
280
280
|
*/
|
|
281
|
-
export const toolApprovalRequestSchema:
|
|
282
|
-
|
|
281
|
+
export const toolApprovalRequestSchema: ZodType<ToolApprovalRequest> = z.object(
|
|
282
|
+
{
|
|
283
283
|
type: z.literal('tool-approval-request'),
|
|
284
284
|
approvalId: z.string(),
|
|
285
285
|
toolCallId: z.string(),
|
|
286
|
-
}
|
|
286
|
+
},
|
|
287
|
+
);
|
|
287
288
|
|
|
288
289
|
/**
|
|
289
290
|
* @internal
|
|
290
291
|
*/
|
|
291
|
-
export const toolApprovalResponseSchema:
|
|
292
|
+
export const toolApprovalResponseSchema: ZodType<ToolApprovalResponse> =
|
|
292
293
|
z.object({
|
|
293
294
|
type: z.literal('tool-approval-response'),
|
|
294
295
|
approvalId: z.string(),
|
package/src/prompt/message.ts
CHANGED
|
@@ -5,8 +5,8 @@ import type {
|
|
|
5
5
|
ToolModelMessage,
|
|
6
6
|
UserModelMessage,
|
|
7
7
|
} from '@ai-sdk/provider-utils';
|
|
8
|
-
import { z } from 'zod/v4';
|
|
9
8
|
import { providerMetadataSchema } from '../types/provider-metadata';
|
|
9
|
+
import { z, type ZodType } from '../util/zod';
|
|
10
10
|
import {
|
|
11
11
|
customPartSchema,
|
|
12
12
|
filePartSchema,
|
|
@@ -20,15 +20,13 @@ import {
|
|
|
20
20
|
toolResultPartSchema,
|
|
21
21
|
} from './content-part';
|
|
22
22
|
|
|
23
|
-
export const systemModelMessageSchema:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
);
|
|
23
|
+
export const systemModelMessageSchema: ZodType<SystemModelMessage> = z.object({
|
|
24
|
+
role: z.literal('system'),
|
|
25
|
+
content: z.string(),
|
|
26
|
+
providerOptions: providerMetadataSchema.optional(),
|
|
27
|
+
});
|
|
30
28
|
|
|
31
|
-
export const userModelMessageSchema:
|
|
29
|
+
export const userModelMessageSchema: ZodType<UserModelMessage> = z.object({
|
|
32
30
|
role: z.literal('user'),
|
|
33
31
|
content: z.union([
|
|
34
32
|
z.string(),
|
|
@@ -37,7 +35,7 @@ export const userModelMessageSchema: z.ZodType<UserModelMessage> = z.object({
|
|
|
37
35
|
providerOptions: providerMetadataSchema.optional(),
|
|
38
36
|
});
|
|
39
37
|
|
|
40
|
-
export const assistantModelMessageSchema:
|
|
38
|
+
export const assistantModelMessageSchema: ZodType<AssistantModelMessage> =
|
|
41
39
|
z.object({
|
|
42
40
|
role: z.literal('assistant'),
|
|
43
41
|
content: z.union([
|
|
@@ -58,13 +56,13 @@ export const assistantModelMessageSchema: z.ZodType<AssistantModelMessage> =
|
|
|
58
56
|
providerOptions: providerMetadataSchema.optional(),
|
|
59
57
|
});
|
|
60
58
|
|
|
61
|
-
export const toolModelMessageSchema:
|
|
59
|
+
export const toolModelMessageSchema: ZodType<ToolModelMessage> = z.object({
|
|
62
60
|
role: z.literal('tool'),
|
|
63
61
|
content: z.array(z.union([toolResultPartSchema, toolApprovalResponseSchema])),
|
|
64
62
|
providerOptions: providerMetadataSchema.optional(),
|
|
65
63
|
});
|
|
66
64
|
|
|
67
|
-
export const modelMessageSchema:
|
|
65
|
+
export const modelMessageSchema: ZodType<ModelMessage> = z.union([
|
|
68
66
|
systemModelMessageSchema,
|
|
69
67
|
userModelMessageSchema,
|
|
70
68
|
assistantModelMessageSchema,
|
package/src/types/json-value.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { JSONValue as OriginalJSONValue } from '@ai-sdk/provider';
|
|
2
|
-
import { z } from 'zod
|
|
2
|
+
import { z, type ZodType } from '../util/zod';
|
|
3
3
|
|
|
4
|
-
export const jsonValueSchema:
|
|
4
|
+
export const jsonValueSchema: ZodType<JSONValue> = z.lazy(() =>
|
|
5
5
|
z.union([
|
|
6
6
|
z.null(),
|
|
7
7
|
z.string(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SharedV4ProviderMetadata } from '@ai-sdk/provider';
|
|
2
|
-
import { z } from 'zod
|
|
2
|
+
import { z, type ZodType } from '../util/zod';
|
|
3
3
|
import { jsonValueSchema } from './json-value';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -10,7 +10,7 @@ import { jsonValueSchema } from './json-value';
|
|
|
10
10
|
*/
|
|
11
11
|
export type ProviderMetadata = SharedV4ProviderMetadata;
|
|
12
12
|
|
|
13
|
-
export const providerMetadataSchema:
|
|
13
|
+
export const providerMetadataSchema: ZodType<ProviderMetadata> = z.record(
|
|
14
14
|
z.string(),
|
|
15
15
|
z.record(z.string(), jsonValueSchema.optional()),
|
|
16
16
|
);
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
type FlexibleSchema,
|
|
7
7
|
type Tool,
|
|
8
8
|
} from '@ai-sdk/provider-utils';
|
|
9
|
-
import { z } from 'zod/v4';
|
|
10
9
|
import { InvalidArgumentError } from '../error';
|
|
11
10
|
import { jsonValueSchema } from '../types/json-value';
|
|
12
11
|
import { getOwn } from '../util/get-own';
|
|
13
12
|
import { providerMetadataSchema } from '../types/provider-metadata';
|
|
13
|
+
import { z, type ZodType } from '../util/zod';
|
|
14
14
|
import type {
|
|
15
15
|
DataUIPart,
|
|
16
16
|
InferUIMessageData,
|
|
@@ -19,7 +19,7 @@ import type {
|
|
|
19
19
|
UIMessage,
|
|
20
20
|
} from './ui-messages';
|
|
21
21
|
|
|
22
|
-
const toolMetadataSchema:
|
|
22
|
+
const toolMetadataSchema: ZodType<JSONObject> = z.record(
|
|
23
23
|
z.string(),
|
|
24
24
|
jsonValueSchema.optional(),
|
|
25
25
|
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { JSONObject } from '@ai-sdk/provider';
|
|
2
|
-
import { z } from 'zod/v4';
|
|
3
2
|
import {
|
|
4
3
|
providerMetadataSchema,
|
|
5
4
|
type ProviderMetadata,
|
|
@@ -13,9 +12,10 @@ import type {
|
|
|
13
12
|
UIMessage,
|
|
14
13
|
} from '../ui/ui-messages';
|
|
15
14
|
import type { ValueOf } from '../util/value-of';
|
|
15
|
+
import { z, type ZodType } from '../util/zod';
|
|
16
16
|
import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';
|
|
17
17
|
|
|
18
|
-
const toolMetadataSchema:
|
|
18
|
+
const toolMetadataSchema: ZodType<JSONObject> = z.record(
|
|
19
19
|
z.string(),
|
|
20
20
|
jsonValueSchema.optional(),
|
|
21
21
|
);
|
package/src/util/zod.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
array,
|
|
3
|
+
boolean,
|
|
4
|
+
custom,
|
|
5
|
+
discriminatedUnion,
|
|
6
|
+
enum as enumType,
|
|
7
|
+
instanceof as instanceOf,
|
|
8
|
+
lazy,
|
|
9
|
+
literal,
|
|
10
|
+
looseObject,
|
|
11
|
+
never,
|
|
12
|
+
null as nullType,
|
|
13
|
+
number,
|
|
14
|
+
object,
|
|
15
|
+
record,
|
|
16
|
+
string,
|
|
17
|
+
union,
|
|
18
|
+
unknown,
|
|
19
|
+
} from 'zod/v4';
|
|
20
|
+
|
|
21
|
+
// Import individual Zod factories so bundlers can tree-shake the full `z`
|
|
22
|
+
// namespace, which also re-exports every locale.
|
|
23
|
+
export const z = {
|
|
24
|
+
array,
|
|
25
|
+
boolean,
|
|
26
|
+
custom,
|
|
27
|
+
discriminatedUnion,
|
|
28
|
+
enum: enumType,
|
|
29
|
+
instanceof: instanceOf,
|
|
30
|
+
lazy,
|
|
31
|
+
literal,
|
|
32
|
+
looseObject,
|
|
33
|
+
never,
|
|
34
|
+
null: nullType,
|
|
35
|
+
number,
|
|
36
|
+
object,
|
|
37
|
+
record,
|
|
38
|
+
string,
|
|
39
|
+
union,
|
|
40
|
+
unknown,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type { ZodType } from 'zod/v4';
|