ai 7.0.153 → 7.0.155
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 +25 -0
- package/dist/index.d.ts +224 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1071 -893
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +54 -7
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +29 -399
- package/dist/internal/index.js.map +1 -1
- package/docs/02-getting-started/02-nextjs-app-router.mdx +2 -2
- package/docs/02-getting-started/08-angular.mdx +327 -0
- package/docs/02-getting-started/{03-nextjs-pages-router.mdx → 10-nextjs-pages-router.mdx} +12 -20
- package/docs/02-getting-started/index.mdx +2 -0
- package/docs/03-agents/01-overview.mdx +1 -0
- package/docs/03-agents/04-loop-control.mdx +117 -0
- package/docs/03-agents/06-tool-approvals.mdx +1 -0
- package/docs/03-agents/09-chat-platforms.mdx +164 -0
- package/docs/03-agents/index.mdx +6 -0
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +7 -0
- package/docs/03-ai-sdk-core/60-telemetry.mdx +16 -3
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +10 -0
- package/docs/04-ai-sdk-ui/21-transport.mdx +86 -0
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +46 -0
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +46 -0
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +35 -0
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +7 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-prompt-error.mdx +25 -10
- package/package.json +11 -11
- package/src/agent/create-agent-ui-stream-response.ts +3 -0
- package/src/agent/create-agent-ui-stream.ts +16 -0
- package/src/agent/pipe-agent-ui-stream-to-response.ts +3 -0
- package/src/agent/tool-loop-agent-settings.ts +37 -1
- package/src/agent/tool-loop-agent.ts +43 -7
- package/src/batch/batch.ts +0 -8
- package/src/decide/validate-decision.ts +39 -64
- package/src/generate-object/validate-object-generation-input.ts +1 -39
- package/src/generate-speech/stream-speech.ts +6 -18
- package/src/generate-text/generate-text-events.ts +37 -0
- package/src/generate-text/generate-text.ts +521 -373
- package/src/generate-text/index.ts +8 -0
- package/src/generate-text/prepare-step.ts +12 -0
- package/src/generate-text/restricted-telemetry-dispatcher.ts +31 -18
- package/src/generate-text/smooth-stream.ts +2 -14
- package/src/generate-text/steering.ts +285 -0
- package/src/generate-text/step-result.ts +18 -0
- package/src/generate-text/stream-text.ts +664 -473
- package/src/generate-text/tool-caller-configuration.ts +2 -26
- package/src/prompt/prepare-language-model-call-options.ts +0 -50
- package/src/prompt/standardize-prompt.ts +9 -58
- package/src/telemetry/create-telemetry-dispatcher.ts +3 -0
- package/src/telemetry/telemetry.ts +15 -1
- package/src/test/mock-sandbox.ts +5 -11
- package/src/util/is-caused-by-abort.ts +20 -0
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
createAgentUIStream,
|
|
17
17
|
type AgentUIMessageStreamOptions,
|
|
18
18
|
} from './create-agent-ui-stream';
|
|
19
|
+
import type { Steering } from '../generate-text/steering';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Runs the agent and returns a response object with a UI message stream.
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
* @param abortSignal - Abort signal. Optional.
|
|
27
28
|
* @param timeout - Timeout in milliseconds. Optional.
|
|
28
29
|
* @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
|
|
30
|
+
* @param experimental_steering - A steering object that adds user messages to the run at the next step boundary. Only supported by `ToolLoopAgent`. Optional.
|
|
29
31
|
* @param options - The options for the agent. Optional.
|
|
30
32
|
* @param experimental_transform - Stream transformations. Optional.
|
|
31
33
|
* @param onStepEnd - Callback that is called when each step ends. Optional.
|
|
@@ -70,6 +72,7 @@ export async function createAgentUIStreamResponse<
|
|
|
70
72
|
abortSignal?: AbortSignal;
|
|
71
73
|
timeout?: TimeoutConfiguration<TOOLS>;
|
|
72
74
|
experimental_sandbox?: SandboxSession;
|
|
75
|
+
experimental_steering?: Steering;
|
|
73
76
|
options?: CALL_OPTIONS;
|
|
74
77
|
experimental_transform?: Arrayable<StreamTextTransform<TOOLS>>;
|
|
75
78
|
} & UIMessageStreamResponseInit &
|
|
@@ -28,7 +28,10 @@ import {
|
|
|
28
28
|
createAsyncIterableStream,
|
|
29
29
|
type AsyncIterableStream,
|
|
30
30
|
} from '../util/async-iterable-stream';
|
|
31
|
+
import { InvalidArgumentError } from '../error/invalid-argument-error';
|
|
32
|
+
import type { Steering } from '../generate-text/steering';
|
|
31
33
|
import type { Agent } from './agent';
|
|
34
|
+
import { ToolLoopAgent } from './tool-loop-agent';
|
|
32
35
|
|
|
33
36
|
/**
|
|
34
37
|
* UI stream options with separate generation and UI message step callbacks.
|
|
@@ -56,6 +59,7 @@ export type AgentUIMessageStreamOptions<
|
|
|
56
59
|
* @param abortSignal - The abort signal. Optional.
|
|
57
60
|
* @param timeout - Timeout in milliseconds. Optional.
|
|
58
61
|
* @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
|
|
62
|
+
* @param experimental_steering - A steering object that adds user messages to the run at the next step boundary. Only supported by `ToolLoopAgent`. Optional.
|
|
59
63
|
* @param options - The options for the agent.
|
|
60
64
|
* @param experimental_transform - The stream transformations. Optional.
|
|
61
65
|
* @param onStepEnd - Callback that is called when each step ends. Optional.
|
|
@@ -83,6 +87,7 @@ export async function createAgentUIStream<
|
|
|
83
87
|
abortSignal,
|
|
84
88
|
timeout,
|
|
85
89
|
experimental_sandbox: sandbox,
|
|
90
|
+
experimental_steering: steering,
|
|
86
91
|
experimental_transform,
|
|
87
92
|
onStepEnd,
|
|
88
93
|
onStepFinish,
|
|
@@ -101,12 +106,22 @@ export async function createAgentUIStream<
|
|
|
101
106
|
abortSignal?: AbortSignal;
|
|
102
107
|
timeout?: TimeoutConfiguration<TOOLS>;
|
|
103
108
|
experimental_sandbox?: SandboxSession;
|
|
109
|
+
experimental_steering?: Steering;
|
|
104
110
|
options?: CALL_OPTIONS;
|
|
105
111
|
experimental_transform?: Arrayable<StreamTextTransform<TOOLS>>;
|
|
106
112
|
// TODO `originalMessages` is part of this for bc, omit in v7
|
|
107
113
|
} & AgentUIMessageStreamOptions<TOOLS, UI_MESSAGE>): Promise<
|
|
108
114
|
AsyncIterableStream<InferUIMessageChunk<UI_MESSAGE>>
|
|
109
115
|
> {
|
|
116
|
+
// other agents would ignore the steering object and never resolve its messages:
|
|
117
|
+
if (steering != null && !(agent instanceof ToolLoopAgent)) {
|
|
118
|
+
throw new InvalidArgumentError({
|
|
119
|
+
parameter: 'experimental_steering',
|
|
120
|
+
value: steering,
|
|
121
|
+
message: 'Steering is only supported by ToolLoopAgent.',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
110
125
|
const validatedMessages = await validateUIMessagesForAgent<UI_MESSAGE>({
|
|
111
126
|
messages: uiMessages,
|
|
112
127
|
// tools are compatible; the casting is required because the context param is
|
|
@@ -130,6 +145,7 @@ export async function createAgentUIStream<
|
|
|
130
145
|
abortSignal,
|
|
131
146
|
timeout,
|
|
132
147
|
experimental_sandbox: sandbox,
|
|
148
|
+
experimental_steering: steering,
|
|
133
149
|
experimental_transform,
|
|
134
150
|
onStepEnd: onStepEnd ?? onStepFinish,
|
|
135
151
|
});
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
createAgentUIStream,
|
|
18
18
|
type AgentUIMessageStreamOptions,
|
|
19
19
|
} from './create-agent-ui-stream';
|
|
20
|
+
import type { Steering } from '../generate-text/steering';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Pipes the agent UI message stream to a Node.js ServerResponse object.
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
* @param abortSignal - Abort signal. Optional.
|
|
29
30
|
* @param timeout - Timeout in milliseconds. Optional.
|
|
30
31
|
* @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
|
|
32
|
+
* @param experimental_steering - A steering object that adds user messages to the run at the next step boundary. Only supported by `ToolLoopAgent`. Optional.
|
|
31
33
|
* @param options - The options for the agent. Optional.
|
|
32
34
|
* @param experimental_transform - Stream transformations. Optional.
|
|
33
35
|
* @param onStepEnd - Callback that is called when each step ends. Optional.
|
|
@@ -72,6 +74,7 @@ export async function pipeAgentUIStreamToResponse<
|
|
|
72
74
|
abortSignal?: AbortSignal;
|
|
73
75
|
timeout?: TimeoutConfiguration<TOOLS>;
|
|
74
76
|
experimental_sandbox?: SandboxSession;
|
|
77
|
+
experimental_steering?: Steering;
|
|
75
78
|
options?: CALL_OPTIONS;
|
|
76
79
|
experimental_transform?: Arrayable<StreamTextTransform<TOOLS>>;
|
|
77
80
|
} & UIMessageStreamResponseInit &
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
GenerateTextOnEndCallback,
|
|
14
14
|
GenerateTextOnStartCallback,
|
|
15
15
|
GenerateTextOnStepEndCallback,
|
|
16
|
+
GenerateTextOnStepErrorCallback,
|
|
16
17
|
GenerateTextOnStepFinishCallback,
|
|
17
18
|
GenerateTextOnStepStartCallback,
|
|
18
19
|
} from '../generate-text/generate-text-events';
|
|
@@ -24,7 +25,11 @@ import type {
|
|
|
24
25
|
import type { Output } from '../generate-text/output';
|
|
25
26
|
import type { PrepareStepFunction } from '../generate-text/prepare-step';
|
|
26
27
|
import type { StopCondition } from '../generate-text/stop-condition';
|
|
27
|
-
import type {
|
|
28
|
+
import type {
|
|
29
|
+
StreamTextInclude,
|
|
30
|
+
StreamTextOnAbortCallback,
|
|
31
|
+
StreamTextOnErrorCallback,
|
|
32
|
+
} from '../generate-text/stream-text';
|
|
28
33
|
import type { ToolApprovalConfiguration } from '../generate-text/tool-approval-configuration';
|
|
29
34
|
import type { Experimental_ToolCallers } from '../generate-text/tool-caller-configuration';
|
|
30
35
|
import type { ToolCallRepairFunction } from '../generate-text/tool-call-repair-function';
|
|
@@ -253,6 +258,37 @@ export type ToolLoopAgentSettings<
|
|
|
253
258
|
NoInfer<RUNTIME_CONTEXT>
|
|
254
259
|
>;
|
|
255
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Callback that is called when a step that started fails before it
|
|
263
|
+
* produces a step result. `onStepEnd` is not called for such a step.
|
|
264
|
+
*
|
|
265
|
+
* Unlike `onStepStart` and `onStepEnd`, it can only be set here and not
|
|
266
|
+
* per call, because the per-call callbacks are shared with other `Agent`
|
|
267
|
+
* implementations that do not report step errors.
|
|
268
|
+
*/
|
|
269
|
+
onStepError?: GenerateTextOnStepErrorCallback<
|
|
270
|
+
NoInfer<TOOLS>,
|
|
271
|
+
NoInfer<RUNTIME_CONTEXT>,
|
|
272
|
+
NoInfer<OUTPUT>
|
|
273
|
+
>;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Callback that is called when an error occurs. For `stream()` it receives
|
|
277
|
+
* the errors of the stream, for `generate()` it receives the error before
|
|
278
|
+
* it is thrown. Aborts and timeouts are not reported.
|
|
279
|
+
*/
|
|
280
|
+
onError?: StreamTextOnErrorCallback;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Callback that is called when `stream()` is aborted or times out.
|
|
284
|
+
* `generate()` does not call it: an aborted or timed out `generate()` call
|
|
285
|
+
* rejects, and its step ends with `onStepError`.
|
|
286
|
+
*/
|
|
287
|
+
onAbort?: StreamTextOnAbortCallback<
|
|
288
|
+
NoInfer<TOOLS>,
|
|
289
|
+
NoInfer<RUNTIME_CONTEXT>
|
|
290
|
+
>;
|
|
291
|
+
|
|
256
292
|
/**
|
|
257
293
|
* Callback that is called when each step (LLM call) ends, including intermediate steps.
|
|
258
294
|
*
|
|
@@ -15,8 +15,11 @@ import type { GenerateTextResult } from '../generate-text/generate-text-result';
|
|
|
15
15
|
import type { Output } from '../generate-text/output';
|
|
16
16
|
import { streamText } from '../generate-text/stream-text';
|
|
17
17
|
import type { StreamTextResult } from '../generate-text/stream-text-result';
|
|
18
|
+
import type { Steering } from '../generate-text/steering';
|
|
18
19
|
import type { Prompt } from '../prompt';
|
|
20
|
+
import { isCausedByAbort } from '../util/is-caused-by-abort';
|
|
19
21
|
import { mergeCallbacks } from '../util/merge-callbacks';
|
|
22
|
+
import { notify } from '../util/notify';
|
|
20
23
|
import type {
|
|
21
24
|
Agent,
|
|
22
25
|
AgentCallParameters,
|
|
@@ -25,6 +28,17 @@ import type {
|
|
|
25
28
|
import type { ToolLoopAgentSettings } from './tool-loop-agent-settings';
|
|
26
29
|
import { createDefaultStopCondition } from './default-stop-condition';
|
|
27
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Call parameters that only `ToolLoopAgent` supports.
|
|
33
|
+
*/
|
|
34
|
+
export interface ToolLoopAgentCallExtensions {
|
|
35
|
+
/**
|
|
36
|
+
* A steering object created with `experimental_createSteering()`.
|
|
37
|
+
* Messages sent with it are added to the run at the next step boundary.
|
|
38
|
+
*/
|
|
39
|
+
experimental_steering?: Steering;
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
/**
|
|
29
43
|
* A tool loop agent is an agent that runs tools in a loop. In each step,
|
|
30
44
|
* it calls the LLM, and if there are tool calls, it executes the tools
|
|
@@ -96,6 +110,8 @@ export class ToolLoopAgent<
|
|
|
96
110
|
| 'onToolExecutionEnd'
|
|
97
111
|
| 'onStepEnd'
|
|
98
112
|
| 'onStepFinish'
|
|
113
|
+
| 'onError'
|
|
114
|
+
| 'onAbort'
|
|
99
115
|
| 'onEnd'
|
|
100
116
|
| 'onFinish'
|
|
101
117
|
> &
|
|
@@ -122,6 +138,8 @@ export class ToolLoopAgent<
|
|
|
122
138
|
onToolExecutionEnd: _settingsOnToolExecutionEnd,
|
|
123
139
|
onStepEnd: _settingsOnStepEnd,
|
|
124
140
|
onStepFinish: _settingsOnStepFinish,
|
|
141
|
+
onError: _settingsOnError,
|
|
142
|
+
onAbort: _settingsOnAbort,
|
|
125
143
|
onFinish: _settingsOnFinish,
|
|
126
144
|
onEnd: _settingsOnEnd,
|
|
127
145
|
...settingsWithoutCallbacks
|
|
@@ -198,6 +216,7 @@ export class ToolLoopAgent<
|
|
|
198
216
|
abortSignal,
|
|
199
217
|
timeout,
|
|
200
218
|
experimental_sandbox: sandbox,
|
|
219
|
+
experimental_steering: steering,
|
|
201
220
|
onStart,
|
|
202
221
|
experimental_onStart,
|
|
203
222
|
onStepStart,
|
|
@@ -209,7 +228,8 @@ export class ToolLoopAgent<
|
|
|
209
228
|
onFinish,
|
|
210
229
|
onEnd = onFinish,
|
|
211
230
|
...options
|
|
212
|
-
}: AgentCallParameters<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT>
|
|
231
|
+
}: AgentCallParameters<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT> &
|
|
232
|
+
ToolLoopAgentCallExtensions): Promise<
|
|
213
233
|
GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>
|
|
214
234
|
> {
|
|
215
235
|
const generate = generateText<TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
@@ -221,6 +241,7 @@ export class ToolLoopAgent<
|
|
|
221
241
|
abortSignal,
|
|
222
242
|
timeout: timeout ?? preparedCall.timeout,
|
|
223
243
|
experimental_sandbox: sandbox,
|
|
244
|
+
experimental_steering: steering,
|
|
224
245
|
onStart: mergeCallbacks(
|
|
225
246
|
this.settings.onStart ?? this.settings.experimental_onStart,
|
|
226
247
|
(onStart ?? experimental_onStart) as
|
|
@@ -248,11 +269,21 @@ export class ToolLoopAgent<
|
|
|
248
269
|
onEnd: mergeCallbacks(this.settings.onEnd, onEnd),
|
|
249
270
|
};
|
|
250
271
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
272
|
+
try {
|
|
273
|
+
return await generate({
|
|
274
|
+
...preparedCall,
|
|
275
|
+
...callbackArgs,
|
|
276
|
+
headers: this.agentHeaders(preparedCall),
|
|
277
|
+
} as unknown as Parameters<typeof generate>[0]);
|
|
278
|
+
} catch (error) {
|
|
279
|
+
// generateText has no onError option, so report the error before it is
|
|
280
|
+
// thrown. Aborts (with any reason) and timeouts are not reported, like in
|
|
281
|
+
// streamText:
|
|
282
|
+
if (!isCausedByAbort(error) && !abortSignal?.aborted) {
|
|
283
|
+
await notify({ event: { error }, callbacks: this.settings.onError });
|
|
284
|
+
}
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
256
287
|
}
|
|
257
288
|
|
|
258
289
|
/**
|
|
@@ -262,6 +293,7 @@ export class ToolLoopAgent<
|
|
|
262
293
|
abortSignal,
|
|
263
294
|
timeout,
|
|
264
295
|
experimental_sandbox: sandbox,
|
|
296
|
+
experimental_steering: steering,
|
|
265
297
|
experimental_transform,
|
|
266
298
|
onStart,
|
|
267
299
|
experimental_onStart,
|
|
@@ -274,7 +306,8 @@ export class ToolLoopAgent<
|
|
|
274
306
|
onFinish,
|
|
275
307
|
onEnd = onFinish,
|
|
276
308
|
...options
|
|
277
|
-
}: AgentStreamParameters<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT>
|
|
309
|
+
}: AgentStreamParameters<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT> &
|
|
310
|
+
ToolLoopAgentCallExtensions): Promise<
|
|
278
311
|
StreamTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>
|
|
279
312
|
> {
|
|
280
313
|
const stream = streamText<TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
@@ -286,6 +319,7 @@ export class ToolLoopAgent<
|
|
|
286
319
|
abortSignal,
|
|
287
320
|
timeout: timeout ?? preparedCall.timeout,
|
|
288
321
|
experimental_sandbox: sandbox,
|
|
322
|
+
experimental_steering: steering,
|
|
289
323
|
experimental_transform,
|
|
290
324
|
onStart: mergeCallbacks(
|
|
291
325
|
this.settings.onStart ?? this.settings.experimental_onStart,
|
|
@@ -312,6 +346,8 @@ export class ToolLoopAgent<
|
|
|
312
346
|
onStepEnd ?? onStepFinish,
|
|
313
347
|
),
|
|
314
348
|
onEnd: mergeCallbacks(this.settings.onEnd, onEnd),
|
|
349
|
+
onError: this.settings.onError,
|
|
350
|
+
onAbort: this.settings.onAbort,
|
|
315
351
|
};
|
|
316
352
|
|
|
317
353
|
return await stream({
|
package/src/batch/batch.ts
CHANGED
|
@@ -491,14 +491,6 @@ function validateBatchReference({
|
|
|
491
491
|
batchApi: BatchV4;
|
|
492
492
|
batch: BatchReference;
|
|
493
493
|
}) {
|
|
494
|
-
if (batch.version !== 2) {
|
|
495
|
-
throw new InvalidArgumentError({
|
|
496
|
-
parameter: 'batch',
|
|
497
|
-
value: batch,
|
|
498
|
-
message: 'batch must be a supported batch reference',
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
|
|
502
494
|
if (batch.provider !== batchApi.provider) {
|
|
503
495
|
throw new InvalidArgumentError({
|
|
504
496
|
parameter: 'provider',
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
type Experimental_DecisionModelV4Result as DecisionModelV4Result,
|
|
4
4
|
type Experimental_DecisionModelV4Question as DecisionQuestion,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
|
-
import { filePartSchema, textPartSchema } from '../prompt/content-part';
|
|
7
6
|
import type { DecisionState } from './decision-state';
|
|
8
7
|
import { InvalidArgumentError } from '../error/invalid-argument-error';
|
|
9
8
|
|
|
@@ -17,30 +16,28 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
17
16
|
return prototype === Object.prototype || prototype === null;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Checks the JSON constraints that types cannot express: finite numbers, no
|
|
21
|
+
* cycles, and no array holes. These would otherwise be silently changed by
|
|
22
|
+
* `JSON.stringify` or make it throw.
|
|
23
|
+
*/
|
|
24
|
+
function isSerializableJSON(
|
|
25
|
+
value: unknown,
|
|
26
|
+
ancestors = new Set<object>(),
|
|
27
|
+
): boolean {
|
|
23
28
|
if (typeof value === 'number') return Number.isFinite(value);
|
|
24
|
-
if (typeof value !== 'object'
|
|
25
|
-
return false;
|
|
29
|
+
if (value == null || typeof value !== 'object') return true;
|
|
26
30
|
if (ancestors.has(value)) return false;
|
|
27
31
|
ancestors.add(value);
|
|
28
|
-
const valid =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const valid = Array.isArray(value)
|
|
33
|
+
? Array.from(value.keys()).every(
|
|
34
|
+
index => index in value && isSerializableJSON(value[index], ancestors),
|
|
35
|
+
)
|
|
36
|
+
: Object.values(value).every(item => isSerializableJSON(item, ancestors));
|
|
33
37
|
ancestors.delete(value);
|
|
34
38
|
return valid;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
function isInput(value: unknown): boolean {
|
|
38
|
-
return (
|
|
39
|
-
(typeof value === 'string' || Array.isArray(value) || isRecord(value)) &&
|
|
40
|
-
isJSON(value)
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
41
|
function invalidInput(
|
|
45
42
|
parameter: string,
|
|
46
43
|
value: unknown,
|
|
@@ -56,50 +53,43 @@ export function validateDecisionInput({
|
|
|
56
53
|
state: DecisionState;
|
|
57
54
|
questions: Readonly<Record<string, DecisionQuestion>>;
|
|
58
55
|
}) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
: (typeof state === 'string' || isRecord(state)) && isJSON(state);
|
|
74
|
-
if (!validState) {
|
|
56
|
+
if (
|
|
57
|
+
Array.isArray(state) &&
|
|
58
|
+
Array.from(state.keys()).some(index => !(index in state))
|
|
59
|
+
) {
|
|
60
|
+
invalidInput('state', state, 'state parts must not contain array holes');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const stateJSON = Array.isArray(state)
|
|
64
|
+
? state.flatMap(part => (part.type === 'json' ? [part.value] : []))
|
|
65
|
+
: state;
|
|
66
|
+
if (!isSerializableJSON(stateJSON)) {
|
|
75
67
|
invalidInput(
|
|
76
68
|
'state',
|
|
77
69
|
state,
|
|
78
|
-
'
|
|
70
|
+
'JSON content must not contain non-finite numbers, cycles, or array holes',
|
|
79
71
|
);
|
|
80
72
|
}
|
|
81
|
-
|
|
73
|
+
|
|
74
|
+
if (Object.keys(questions).length === 0) {
|
|
82
75
|
invalidInput('questions', questions, 'must be a nonempty question map');
|
|
83
76
|
}
|
|
84
77
|
|
|
85
78
|
for (const [id, question] of Object.entries(questions)) {
|
|
86
79
|
const parameter = `questions.${id}`;
|
|
87
80
|
if (
|
|
88
|
-
!
|
|
89
|
-
(
|
|
90
|
-
!isInput(question.instructions))
|
|
81
|
+
!isSerializableJSON(question.instructions) ||
|
|
82
|
+
('criteria' in question && !isSerializableJSON(question.criteria))
|
|
91
83
|
) {
|
|
92
84
|
invalidInput(
|
|
93
85
|
parameter,
|
|
94
86
|
question,
|
|
95
|
-
'instructions must
|
|
87
|
+
'instructions and criteria must not contain non-finite numbers, cycles, or array holes',
|
|
96
88
|
);
|
|
97
89
|
}
|
|
98
|
-
if (question.type === 'box') continue;
|
|
99
|
-
const criteria = question.criteria;
|
|
100
90
|
switch (question.type) {
|
|
101
91
|
case 'choice':
|
|
102
|
-
if (
|
|
92
|
+
if (Object.keys(question.criteria).length === 0) {
|
|
103
93
|
invalidInput(
|
|
104
94
|
parameter,
|
|
105
95
|
question,
|
|
@@ -108,7 +98,7 @@ export function validateDecisionInput({
|
|
|
108
98
|
}
|
|
109
99
|
break;
|
|
110
100
|
case 'score':
|
|
111
|
-
if (
|
|
101
|
+
if (question.criteria.length === 0) {
|
|
112
102
|
invalidInput(
|
|
113
103
|
parameter,
|
|
114
104
|
question,
|
|
@@ -116,10 +106,11 @@ export function validateDecisionInput({
|
|
|
116
106
|
);
|
|
117
107
|
}
|
|
118
108
|
break;
|
|
119
|
-
case 'boolean':
|
|
109
|
+
case 'boolean': {
|
|
110
|
+
const criteria = question.criteria;
|
|
120
111
|
if (
|
|
121
112
|
question.instructions == null &&
|
|
122
|
-
(
|
|
113
|
+
(criteria == null ||
|
|
123
114
|
!Object.values(criteria).some(value => value != null))
|
|
124
115
|
) {
|
|
125
116
|
invalidInput(
|
|
@@ -128,9 +119,8 @@ export function validateDecisionInput({
|
|
|
128
119
|
'boolean questions require instructions or at least one non-null criterion',
|
|
129
120
|
);
|
|
130
121
|
}
|
|
131
|
-
if (criteria === undefined) continue;
|
|
132
122
|
if (
|
|
133
|
-
|
|
123
|
+
criteria != null &&
|
|
134
124
|
Object.keys(criteria).some(key => key !== 'true' && key !== 'false')
|
|
135
125
|
) {
|
|
136
126
|
invalidInput(
|
|
@@ -140,22 +130,7 @@ export function validateDecisionInput({
|
|
|
140
130
|
);
|
|
141
131
|
}
|
|
142
132
|
break;
|
|
143
|
-
|
|
144
|
-
invalidInput(
|
|
145
|
-
parameter,
|
|
146
|
-
question,
|
|
147
|
-
'question type must be choice, score, boolean, or box',
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
if (
|
|
151
|
-
!isJSON(criteria) ||
|
|
152
|
-
Object.values(criteria).some(value => value !== null && !isInput(value))
|
|
153
|
-
) {
|
|
154
|
-
invalidInput(
|
|
155
|
-
parameter,
|
|
156
|
-
question,
|
|
157
|
-
'criteria descriptions must be JSON-compatible strings, objects, arrays, or null',
|
|
158
|
-
);
|
|
133
|
+
}
|
|
159
134
|
}
|
|
160
135
|
}
|
|
161
136
|
}
|
|
@@ -14,20 +14,6 @@ export function validateObjectGenerationInput({
|
|
|
14
14
|
schemaDescription?: string;
|
|
15
15
|
enumValues?: Array<unknown>;
|
|
16
16
|
}) {
|
|
17
|
-
if (
|
|
18
|
-
output != null &&
|
|
19
|
-
output !== 'object' &&
|
|
20
|
-
output !== 'array' &&
|
|
21
|
-
output !== 'enum' &&
|
|
22
|
-
output !== 'no-schema'
|
|
23
|
-
) {
|
|
24
|
-
throw new InvalidArgumentError({
|
|
25
|
-
parameter: 'output',
|
|
26
|
-
value: output,
|
|
27
|
-
message: 'Invalid output type.',
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
17
|
if (output === 'no-schema') {
|
|
32
18
|
if (schema != null) {
|
|
33
19
|
throw new InvalidArgumentError({
|
|
@@ -63,14 +49,6 @@ export function validateObjectGenerationInput({
|
|
|
63
49
|
}
|
|
64
50
|
|
|
65
51
|
if (output === 'object') {
|
|
66
|
-
if (schema == null) {
|
|
67
|
-
throw new InvalidArgumentError({
|
|
68
|
-
parameter: 'schema',
|
|
69
|
-
value: schema,
|
|
70
|
-
message: 'Schema is required for object output.',
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
52
|
if (enumValues != null) {
|
|
75
53
|
throw new InvalidArgumentError({
|
|
76
54
|
parameter: 'enumValues',
|
|
@@ -81,14 +59,6 @@ export function validateObjectGenerationInput({
|
|
|
81
59
|
}
|
|
82
60
|
|
|
83
61
|
if (output === 'array') {
|
|
84
|
-
if (schema == null) {
|
|
85
|
-
throw new InvalidArgumentError({
|
|
86
|
-
parameter: 'schema',
|
|
87
|
-
value: schema,
|
|
88
|
-
message: 'Element schema is required for array output.',
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
62
|
if (enumValues != null) {
|
|
93
63
|
throw new InvalidArgumentError({
|
|
94
64
|
parameter: 'enumValues',
|
|
@@ -123,15 +93,7 @@ export function validateObjectGenerationInput({
|
|
|
123
93
|
});
|
|
124
94
|
}
|
|
125
95
|
|
|
126
|
-
|
|
127
|
-
throw new InvalidArgumentError({
|
|
128
|
-
parameter: 'enumValues',
|
|
129
|
-
value: enumValues,
|
|
130
|
-
message: 'Enum values are required for enum output.',
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
for (const value of enumValues) {
|
|
96
|
+
for (const value of enumValues ?? []) {
|
|
135
97
|
if (typeof value !== 'string') {
|
|
136
98
|
throw new InvalidArgumentError({
|
|
137
99
|
parameter: 'enumValues',
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
withUserAgentSuffix,
|
|
13
13
|
type ProviderOptions,
|
|
14
14
|
} from '@ai-sdk/provider-utils';
|
|
15
|
-
import { InvalidArgumentError } from '../error/invalid-argument-error';
|
|
16
15
|
import { NoSpeechGeneratedError } from '../error/no-speech-generated-error';
|
|
17
16
|
import { StreamProviderError } from '../error/stream-provider-error';
|
|
18
17
|
import { logWarnings } from '../logger/log-warnings';
|
|
@@ -533,23 +532,12 @@ function toSourceStream(
|
|
|
533
532
|
iterable[Symbol.asyncIterator](),
|
|
534
533
|
);
|
|
535
534
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
(async function* () {
|
|
543
|
-
yield* iterable;
|
|
544
|
-
})(),
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
throw new InvalidArgumentError({
|
|
548
|
-
parameter: 'text',
|
|
549
|
-
value: text,
|
|
550
|
-
message:
|
|
551
|
-
'Expected a string, an iterable or async iterable, or a ReadableStream of strings or text parts.',
|
|
552
|
-
});
|
|
535
|
+
const iterable = text as Iterable<string | SpeechTextPart>;
|
|
536
|
+
return convertAsyncIteratorToReadableStream(
|
|
537
|
+
(async function* () {
|
|
538
|
+
yield* iterable;
|
|
539
|
+
})(),
|
|
540
|
+
);
|
|
553
541
|
}
|
|
554
542
|
|
|
555
543
|
function toTextPart(
|
|
@@ -392,6 +392,43 @@ export type GenerateTextOnStepFinishCallback<
|
|
|
392
392
|
RUNTIME_CONTEXT extends Context = Context,
|
|
393
393
|
> = GenerateTextOnStepEndCallback<TOOLS, RUNTIME_CONTEXT>;
|
|
394
394
|
|
|
395
|
+
/**
|
|
396
|
+
* Event passed to the `onStepError` callback.
|
|
397
|
+
*
|
|
398
|
+
* Contains the step start event of the step that failed before it produced
|
|
399
|
+
* a step result, along with the error.
|
|
400
|
+
*/
|
|
401
|
+
export type GenerateTextStepErrorEvent<
|
|
402
|
+
TOOLS extends ToolSet = ToolSet,
|
|
403
|
+
RUNTIME_CONTEXT extends Context = Context,
|
|
404
|
+
OUTPUT extends Output = Output,
|
|
405
|
+
> = GenerateTextStepStartEvent<TOOLS, RUNTIME_CONTEXT, OUTPUT> & {
|
|
406
|
+
/** The error that ended the step. */
|
|
407
|
+
readonly error: unknown;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Callback that is set using the `onStepError` option.
|
|
412
|
+
*
|
|
413
|
+
* Called when a step that started fails before it produces a step result:
|
|
414
|
+
* when the provider call throws or rejects, or when the model stream ends
|
|
415
|
+
* without output. `onStepEnd` is not called for such a step. A provider
|
|
416
|
+
* `error` chunk does not fail the step, it still ends with `onStepEnd` and
|
|
417
|
+
* `finishReason: 'error'`.
|
|
418
|
+
*
|
|
419
|
+
* In `generateText`, an abort or timeout also ends the step here. The error
|
|
420
|
+
* is the abort or timeout error, or a provider error that has it as its
|
|
421
|
+
* `cause`. In `streamText`, an abort or timeout ends the step
|
|
422
|
+
* with `onAbort` instead.
|
|
423
|
+
*
|
|
424
|
+
* @param event - The step that failed and the error.
|
|
425
|
+
*/
|
|
426
|
+
export type GenerateTextOnStepErrorCallback<
|
|
427
|
+
TOOLS extends ToolSet = ToolSet,
|
|
428
|
+
RUNTIME_CONTEXT extends Context = Context,
|
|
429
|
+
OUTPUT extends Output = Output,
|
|
430
|
+
> = Callback<GenerateTextStepErrorEvent<TOOLS, RUNTIME_CONTEXT, OUTPUT>>;
|
|
431
|
+
|
|
395
432
|
/**
|
|
396
433
|
* Callback that is set using the `onEnd` option.
|
|
397
434
|
*
|