ai 7.0.65 → 7.0.67
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 +14 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/docs/03-ai-sdk-core/18-code-mode.mdx +11 -3
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +55 -0
- package/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx +14 -8
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +8 -1
- package/package.json +2 -2
- package/src/generate-text/index.ts +1 -0
- package/src/ui/chat.ts +6 -4
- package/src/ui/process-ui-message-stream.ts +6 -2
- package/src/ui-message-stream/handle-ui-message-stream-finish.ts +2 -1
- package/src/ui-message-stream/read-ui-message-stream.ts +2 -1
package/dist/internal/index.js
CHANGED
|
@@ -180,6 +180,17 @@ const result = await runCodeMode({
|
|
|
180
180
|
`runCodeMode` returns the value returned by the program. It uses the same
|
|
181
181
|
sandbox and execution limits as the AI SDK tool.
|
|
182
182
|
|
|
183
|
+
## Tool Approval
|
|
184
|
+
|
|
185
|
+
Code mode does not currently integrate with AI SDK tool approval flows. Tool
|
|
186
|
+
calls made by generated code are nested inside the code mode invocation, so
|
|
187
|
+
they cannot pause the generation and surface a tool approval request to your
|
|
188
|
+
application.
|
|
189
|
+
|
|
190
|
+
Do not expose tools that rely on user approval to code mode. Keep those tools
|
|
191
|
+
directly callable by the model instead. If a nested tool requires approval,
|
|
192
|
+
the call is rejected rather than executed.
|
|
193
|
+
|
|
183
194
|
## Execution Limits
|
|
184
195
|
|
|
185
196
|
Every invocation has limits for runtime, memory, source size, results, tool
|
|
@@ -244,6 +255,3 @@ to code mode.
|
|
|
244
255
|
|
|
245
256
|
Tool input schemas are validated before their `execute` functions run. Abort
|
|
246
257
|
signals and AI SDK tool execution context are forwarded to nested tool calls.
|
|
247
|
-
|
|
248
|
-
Code mode does not currently support approval flows for nested tool calls.
|
|
249
|
-
Tools that require approval are rejected instead of being executed.
|
|
@@ -93,6 +93,60 @@ try {
|
|
|
93
93
|
}
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
## Generate Structured Output
|
|
97
|
+
|
|
98
|
+
Set `output` when constructing `HarnessAgent` to require the same typed output
|
|
99
|
+
on every turn. The agent converts the output specification to JSON Schema for
|
|
100
|
+
the harness adapter, validates the completed response, and returns the parsed
|
|
101
|
+
value through `result.output`.
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { HarnessAgent } from '@ai-sdk/harness/agent';
|
|
105
|
+
import { Output } from 'ai';
|
|
106
|
+
import { z } from 'zod';
|
|
107
|
+
|
|
108
|
+
const agent = new HarnessAgent({
|
|
109
|
+
harness: claudeCode,
|
|
110
|
+
sandbox,
|
|
111
|
+
output: Output.object({
|
|
112
|
+
schema: z.object({
|
|
113
|
+
recipe: z.object({
|
|
114
|
+
name: z.string(),
|
|
115
|
+
ingredients: z.array(
|
|
116
|
+
z.object({
|
|
117
|
+
name: z.string(),
|
|
118
|
+
amount: z.number(),
|
|
119
|
+
unit: z.enum(['oz', 'fl oz', 'cup', 'gallon']),
|
|
120
|
+
}),
|
|
121
|
+
),
|
|
122
|
+
steps: z.array(z.string()),
|
|
123
|
+
}),
|
|
124
|
+
}),
|
|
125
|
+
}),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const session = await agent.createSession();
|
|
129
|
+
try {
|
|
130
|
+
const result = await agent.generate({
|
|
131
|
+
session,
|
|
132
|
+
prompt: 'Generate a lasagna recipe.',
|
|
133
|
+
});
|
|
134
|
+
console.dir(result.output, { depth: Infinity });
|
|
135
|
+
} finally {
|
|
136
|
+
await session.destroy();
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
With `stream()`, read `partialOutputStream` for incrementally parsed values and
|
|
141
|
+
await `result.output` for the validated final value. Structured data also remains
|
|
142
|
+
available as JSON in the normal text and stream surfaces; adapters do not add it
|
|
143
|
+
to the `finish` part.
|
|
144
|
+
|
|
145
|
+
Harness structured output requires a schema. Schema-less `Output.json()` and
|
|
146
|
+
adapters or runtime configurations that cannot enforce the schema throw
|
|
147
|
+
`HarnessCapabilityUnsupportedError`; see the
|
|
148
|
+
[adapter capability table](/docs/ai-sdk-harnesses/harness-adapters#adapter-capabilities).
|
|
149
|
+
|
|
96
150
|
## Messages and History
|
|
97
151
|
|
|
98
152
|
A harness session owns its native conversation history. When you pass `messages`
|
|
@@ -366,6 +420,7 @@ console.log(preparation.identity);
|
|
|
366
420
|
- `id`: optional stable agent identifier.
|
|
367
421
|
- `instructions`: instructions appended to the runtime's system or developer
|
|
368
422
|
prompt when supported, or prepended to the first user prompt otherwise.
|
|
423
|
+
- `output`: typed output specification applied to every turn.
|
|
369
424
|
- `stopWhen`: condition(s) for finishing a result slice after a completed
|
|
370
425
|
harness tool step that can continue into another model step.
|
|
371
426
|
- `tools`: AI SDK tools executed by the host when the harness calls them.
|
|
@@ -15,6 +15,7 @@ configuration into the harness contract.
|
|
|
15
15
|
The AI SDK includes the following harness adapters:
|
|
16
16
|
|
|
17
17
|
- [Claude Code](/providers/ai-sdk-harnesses/claude-code) (`@ai-sdk/harness-claude-code`)
|
|
18
|
+
- [Cline](/providers/ai-sdk-harnesses/cline) (`@ai-sdk/harness-cline`)
|
|
18
19
|
- [Codex](/providers/ai-sdk-harnesses/codex) (`@ai-sdk/harness-codex`)
|
|
19
20
|
- [Deep Agents](/providers/ai-sdk-harnesses/deepagents) (`@ai-sdk/harness-deepagents`)
|
|
20
21
|
- [Grok Build](/providers/ai-sdk-harnesses/grok-build) (`@ai-sdk/harness-grok-build`)
|
|
@@ -29,11 +30,16 @@ The AI SDK includes the following harness adapters:
|
|
|
29
30
|
|
|
30
31
|
## Adapter Capabilities
|
|
31
32
|
|
|
32
|
-
| Adapter | Runtime location | Custom tools | Custom skills | Built-in tool approval | Built-in tool filtering |
|
|
33
|
-
| ------------------------------------------------------ | ---------------- | ------------ | ------------- | ---------------------- | ---------------------------- |
|
|
34
|
-
| [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
35
|
-
| [
|
|
36
|
-
| [
|
|
37
|
-
| [
|
|
38
|
-
| [
|
|
39
|
-
| [
|
|
33
|
+
| Adapter | Runtime location | Custom tools | Custom skills | Structured output | Built-in tool approval | Built-in tool filtering |
|
|
34
|
+
| ------------------------------------------------------ | ---------------- | ------------ | ------------- | ----------------- | ---------------------- | ---------------------------- |
|
|
35
|
+
| [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
36
|
+
| [Cline](/providers/ai-sdk-harnesses/cline) | Host process | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
37
|
+
| [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
|
|
38
|
+
| [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection |
|
|
39
|
+
| [Grok Build](/providers/ai-sdk-harnesses/grok-build) | Sandbox via ACP | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
|
|
40
|
+
| [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection |
|
|
41
|
+
| [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check /> | <Check /> | <Cross /> | <Check /> | <Check /> |
|
|
42
|
+
|
|
43
|
+
Generic ACP profiles do not support structured output unless they configure an
|
|
44
|
+
implementation-specific prompt metadata mapping; Grok Build includes the
|
|
45
|
+
required mapping, while Codex ACP does not expose one.
|
|
@@ -404,7 +404,8 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
|
|
|
404
404
|
name: 'maxRetries',
|
|
405
405
|
type: 'number',
|
|
406
406
|
isOptional: true,
|
|
407
|
-
description:
|
|
407
|
+
description:
|
|
408
|
+
'How many times to retry retryable model-call failures. Set to 0 to disable retries. Retry-After response headers are respected, and durable workflow step retries are not stacked. Default: 2.',
|
|
408
409
|
},
|
|
409
410
|
{
|
|
410
411
|
name: 'headers',
|
|
@@ -678,6 +679,12 @@ Returns a `Promise<WorkflowAgentStreamResult>` with the following properties:
|
|
|
678
679
|
description:
|
|
679
680
|
'Tool results from the last step. Only includes results for tools that were executed.',
|
|
680
681
|
},
|
|
682
|
+
{
|
|
683
|
+
name: 'error',
|
|
684
|
+
type: 'unknown | undefined',
|
|
685
|
+
description:
|
|
686
|
+
"The original value from a model stream error part. The property is present when an error part was emitted, even if its value is undefined; use `'error' in result` to distinguish that case.",
|
|
687
|
+
},
|
|
681
688
|
{
|
|
682
689
|
name: 'output',
|
|
683
690
|
type: 'OUTPUT',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.67",
|
|
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,7 +42,7 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@ai-sdk/gateway": "4.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.53",
|
|
46
46
|
"@ai-sdk/provider": "4.0.7",
|
|
47
47
|
"@ai-sdk/provider-utils": "5.0.27"
|
|
48
48
|
},
|
|
@@ -34,6 +34,7 @@ export type {
|
|
|
34
34
|
OnLanguageModelCallStartCallback,
|
|
35
35
|
} from './language-model-events';
|
|
36
36
|
export * as Output from './output';
|
|
37
|
+
export type { Output as OutputInterface } from './output';
|
|
37
38
|
export type {
|
|
38
39
|
InferCompleteOutput as InferGenerateOutput,
|
|
39
40
|
InferPartialOutput as InferStreamOutput,
|
package/src/ui/chat.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
createStreamingUIMessageState,
|
|
16
16
|
processUIMessageStream,
|
|
17
17
|
type StreamingUIMessageState,
|
|
18
|
+
type UIMessageStreamWriteOptions,
|
|
18
19
|
} from './process-ui-message-stream';
|
|
19
20
|
import {
|
|
20
21
|
isToolUIPart,
|
|
@@ -757,7 +758,7 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
757
758
|
const runUpdateMessageJob = (
|
|
758
759
|
job: (options: {
|
|
759
760
|
state: StreamingUIMessageState<UI_MESSAGE>;
|
|
760
|
-
write: () => void;
|
|
761
|
+
write: (options?: UIMessageStreamWriteOptions) => void;
|
|
761
762
|
}) => Promise<void>,
|
|
762
763
|
) =>
|
|
763
764
|
// serialize the job execution to avoid race conditions:
|
|
@@ -768,13 +769,14 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
768
769
|
|
|
769
770
|
return job({
|
|
770
771
|
state: response.state,
|
|
771
|
-
write: () => {
|
|
772
|
+
write: ({ updateStatus = true } = {}) => {
|
|
772
773
|
if (response.abortController.signal.aborted) {
|
|
773
774
|
return;
|
|
774
775
|
}
|
|
775
776
|
|
|
776
|
-
|
|
777
|
-
|
|
777
|
+
if (updateStatus) {
|
|
778
|
+
this.setStatus({ status: 'streaming' });
|
|
779
|
+
}
|
|
778
780
|
|
|
779
781
|
const replaceLastMessage =
|
|
780
782
|
response.state.message.id === this.lastMessage?.id;
|
|
@@ -49,6 +49,10 @@ export type StreamingUIMessageState<UI_MESSAGE extends UIMessage> = {
|
|
|
49
49
|
finishReason?: FinishReason;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
export type UIMessageStreamWriteOptions = {
|
|
53
|
+
updateStatus?: boolean;
|
|
54
|
+
};
|
|
55
|
+
|
|
52
56
|
export function createStreamingUIMessageState<UI_MESSAGE extends UIMessage>({
|
|
53
57
|
lastMessage,
|
|
54
58
|
messageId,
|
|
@@ -95,7 +99,7 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
|
|
|
95
99
|
runUpdateMessageJob: (
|
|
96
100
|
job: (options: {
|
|
97
101
|
state: StreamingUIMessageState<UI_MESSAGE>;
|
|
98
|
-
write: () => void;
|
|
102
|
+
write: (options?: UIMessageStreamWriteOptions) => void;
|
|
99
103
|
}) => Promise<void>,
|
|
100
104
|
) => Promise<void>;
|
|
101
105
|
onError: ErrorHandler;
|
|
@@ -891,7 +895,7 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
|
|
|
891
895
|
await updateMessageMetadata(chunk.messageMetadata);
|
|
892
896
|
|
|
893
897
|
if (chunk.messageId != null || chunk.messageMetadata != null) {
|
|
894
|
-
write();
|
|
898
|
+
write({ updateStatus: false });
|
|
895
899
|
}
|
|
896
900
|
break;
|
|
897
901
|
}
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
createStreamingUIMessageState,
|
|
3
3
|
processUIMessageStream,
|
|
4
4
|
type StreamingUIMessageState,
|
|
5
|
+
type UIMessageStreamWriteOptions,
|
|
5
6
|
} from '../ui/process-ui-message-stream';
|
|
6
7
|
import type { UIMessage } from '../ui/ui-messages';
|
|
7
8
|
import type { ErrorHandler } from '../util/error-handler';
|
|
@@ -109,7 +110,7 @@ export function handleUIMessageStreamFinish<UI_MESSAGE extends UIMessage>({
|
|
|
109
110
|
const runUpdateMessageJob = async (
|
|
110
111
|
job: (options: {
|
|
111
112
|
state: StreamingUIMessageState<UI_MESSAGE>;
|
|
112
|
-
write: () => void;
|
|
113
|
+
write: (options?: UIMessageStreamWriteOptions) => void;
|
|
113
114
|
}) => Promise<void>,
|
|
114
115
|
) => {
|
|
115
116
|
await job({ state, write: () => {} });
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
createStreamingUIMessageState,
|
|
5
5
|
processUIMessageStream,
|
|
6
6
|
type StreamingUIMessageState,
|
|
7
|
+
type UIMessageStreamWriteOptions,
|
|
7
8
|
} from '../ui/process-ui-message-stream';
|
|
8
9
|
import {
|
|
9
10
|
createAsyncIterableStream,
|
|
@@ -91,7 +92,7 @@ export function readUIMessageStream<UI_MESSAGE extends UIMessage>({
|
|
|
91
92
|
runUpdateMessageJob(
|
|
92
93
|
job: (options: {
|
|
93
94
|
state: StreamingUIMessageState<UI_MESSAGE>;
|
|
94
|
-
write: () => void;
|
|
95
|
+
write: (options?: UIMessageStreamWriteOptions) => void;
|
|
95
96
|
}) => Promise<void>,
|
|
96
97
|
) {
|
|
97
98
|
return job({
|