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.
Files changed (53) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/index.d.ts +224 -9
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1071 -893
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +54 -7
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +29 -399
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/02-getting-started/02-nextjs-app-router.mdx +2 -2
  11. package/docs/02-getting-started/08-angular.mdx +327 -0
  12. package/docs/02-getting-started/{03-nextjs-pages-router.mdx → 10-nextjs-pages-router.mdx} +12 -20
  13. package/docs/02-getting-started/index.mdx +2 -0
  14. package/docs/03-agents/01-overview.mdx +1 -0
  15. package/docs/03-agents/04-loop-control.mdx +117 -0
  16. package/docs/03-agents/06-tool-approvals.mdx +1 -0
  17. package/docs/03-agents/09-chat-platforms.mdx +164 -0
  18. package/docs/03-agents/index.mdx +6 -0
  19. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +7 -0
  20. package/docs/03-ai-sdk-core/60-telemetry.mdx +16 -3
  21. package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +10 -0
  22. package/docs/04-ai-sdk-ui/21-transport.mdx +86 -0
  23. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +46 -0
  24. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +46 -0
  25. package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +35 -0
  26. package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +7 -0
  27. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-prompt-error.mdx +25 -10
  28. package/package.json +11 -11
  29. package/src/agent/create-agent-ui-stream-response.ts +3 -0
  30. package/src/agent/create-agent-ui-stream.ts +16 -0
  31. package/src/agent/pipe-agent-ui-stream-to-response.ts +3 -0
  32. package/src/agent/tool-loop-agent-settings.ts +37 -1
  33. package/src/agent/tool-loop-agent.ts +43 -7
  34. package/src/batch/batch.ts +0 -8
  35. package/src/decide/validate-decision.ts +39 -64
  36. package/src/generate-object/validate-object-generation-input.ts +1 -39
  37. package/src/generate-speech/stream-speech.ts +6 -18
  38. package/src/generate-text/generate-text-events.ts +37 -0
  39. package/src/generate-text/generate-text.ts +521 -373
  40. package/src/generate-text/index.ts +8 -0
  41. package/src/generate-text/prepare-step.ts +12 -0
  42. package/src/generate-text/restricted-telemetry-dispatcher.ts +31 -18
  43. package/src/generate-text/smooth-stream.ts +2 -14
  44. package/src/generate-text/steering.ts +285 -0
  45. package/src/generate-text/step-result.ts +18 -0
  46. package/src/generate-text/stream-text.ts +664 -473
  47. package/src/generate-text/tool-caller-configuration.ts +2 -26
  48. package/src/prompt/prepare-language-model-call-options.ts +0 -50
  49. package/src/prompt/standardize-prompt.ts +9 -58
  50. package/src/telemetry/create-telemetry-dispatcher.ts +3 -0
  51. package/src/telemetry/telemetry.ts +15 -1
  52. package/src/test/mock-sandbox.ts +5 -11
  53. package/src/util/is-caused-by-abort.ts +20 -0
@@ -47,33 +47,9 @@ export function resolveToolCallerConfiguration<TOOLS extends ToolSet>({
47
47
  });
48
48
  }
49
49
 
50
- if (!Array.isArray(callers)) {
51
- throw new InvalidArgumentError({
52
- parameter: 'experimental_toolCallers',
53
- value: toolCallers,
54
- message: `callers for tool "${toolName}" must be an array.`,
55
- });
50
+ if (callers != null) {
51
+ resolved[toolName] = callers;
56
52
  }
57
-
58
- resolved[toolName] = callers.map(caller => {
59
- if (caller === DIRECT_TOOL_CALL) {
60
- return caller;
61
- }
62
-
63
- if (
64
- typeof caller !== 'string' ||
65
- !Object.prototype.hasOwnProperty.call(tools, caller) ||
66
- experimental_getToolCaller(tools[caller]) == null
67
- ) {
68
- throw new InvalidArgumentError({
69
- parameter: 'experimental_toolCallers',
70
- value: toolCallers,
71
- message: `tool "${toolName}" contains an invalid caller.`,
72
- });
73
- }
74
-
75
- return caller;
76
- });
77
53
  }
78
54
 
79
55
  return resolved;
@@ -33,56 +33,6 @@ export function prepareLanguageModelCallOptions({
33
33
  }
34
34
  }
35
35
 
36
- if (temperature != null) {
37
- if (typeof temperature !== 'number') {
38
- throw new InvalidArgumentError({
39
- parameter: 'temperature',
40
- value: temperature,
41
- message: 'temperature must be a number',
42
- });
43
- }
44
- }
45
-
46
- if (topP != null) {
47
- if (typeof topP !== 'number') {
48
- throw new InvalidArgumentError({
49
- parameter: 'topP',
50
- value: topP,
51
- message: 'topP must be a number',
52
- });
53
- }
54
- }
55
-
56
- if (topK != null) {
57
- if (typeof topK !== 'number') {
58
- throw new InvalidArgumentError({
59
- parameter: 'topK',
60
- value: topK,
61
- message: 'topK must be a number',
62
- });
63
- }
64
- }
65
-
66
- if (presencePenalty != null) {
67
- if (typeof presencePenalty !== 'number') {
68
- throw new InvalidArgumentError({
69
- parameter: 'presencePenalty',
70
- value: presencePenalty,
71
- message: 'presencePenalty must be a number',
72
- });
73
- }
74
- }
75
-
76
- if (frequencyPenalty != null) {
77
- if (typeof frequencyPenalty !== 'number') {
78
- throw new InvalidArgumentError({
79
- parameter: 'frequencyPenalty',
80
- value: frequencyPenalty,
81
- message: 'frequencyPenalty must be a number',
82
- });
83
- }
84
- }
85
-
86
36
  if (seed != null) {
87
37
  if (!Number.isInteger(seed)) {
88
38
  throw new InvalidArgumentError({
@@ -1,11 +1,5 @@
1
1
  import { InvalidPromptError } from '@ai-sdk/provider';
2
- import {
3
- asArray,
4
- safeValidateTypes,
5
- type ModelMessage,
6
- } from '@ai-sdk/provider-utils';
7
- import { z } from '../util/zod';
8
- import { modelMessageSchema } from './message';
2
+ import type { ModelMessage } from '@ai-sdk/provider-utils';
9
3
  import type { Instructions, Prompt } from './prompt';
10
4
 
11
5
  export type StandardizedPrompt = {
@@ -21,8 +15,7 @@ export type StandardizedPrompt = {
21
15
  };
22
16
 
23
17
  /**
24
- * Converts a prompt input into a standardized prompt with validated model
25
- * messages.
18
+ * Converts a prompt input into a standardized prompt with model messages.
26
19
  *
27
20
  * @param prompt - The prompt definition to standardize.
28
21
  * Set `allowSystemInMessages` to true to allow system messages in the
@@ -38,42 +31,13 @@ export async function standardizePrompt({
38
31
  prompt,
39
32
  messages,
40
33
  }: Prompt): Promise<StandardizedPrompt> {
41
- if (prompt == null && messages == null) {
42
- throw new InvalidPromptError({
43
- prompt,
44
- message: 'prompt or messages must be defined',
45
- });
46
- }
47
-
48
- if (prompt != null && messages != null) {
49
- throw new InvalidPromptError({
50
- prompt,
51
- message: 'prompt and messages cannot be defined at the same time',
52
- });
53
- }
54
-
55
- // validate that instructions is a string or a SystemModelMessage
56
- if (
57
- typeof instructions !== 'string' &&
58
- !asArray(instructions).every(message => message.role === 'system')
59
- ) {
60
- throw new InvalidPromptError({
61
- prompt,
62
- message:
63
- 'instructions must be a string, SystemModelMessage, or array of SystemModelMessage',
64
- });
65
- }
66
-
67
- if (prompt != null && typeof prompt === 'string') {
68
- messages = [{ role: 'user', content: prompt }];
69
- } else if (prompt != null && Array.isArray(prompt)) {
70
- messages = prompt;
71
- } else if (messages == null) {
72
- throw new InvalidPromptError({
73
- prompt,
74
- message: 'prompt or messages must be defined',
75
- });
76
- }
34
+ // `Prompt` requires exactly one of `prompt` or `messages`:
35
+ messages =
36
+ prompt == null
37
+ ? messages!
38
+ : typeof prompt === 'string'
39
+ ? [{ role: 'user', content: prompt }]
40
+ : prompt;
77
41
 
78
42
  if (messages.length === 0) {
79
43
  throw new InvalidPromptError({
@@ -95,18 +59,5 @@ export async function standardizePrompt({
95
59
  });
96
60
  }
97
61
 
98
- const validationResult = await safeValidateTypes({
99
- value: messages,
100
- schema: z.array(modelMessageSchema),
101
- });
102
-
103
- if (!validationResult.success) {
104
- throw new InvalidPromptError({
105
- prompt,
106
- message: 'The messages do not match the ModelMessage[] schema.',
107
- cause: validationResult.error,
108
- });
109
- }
110
-
111
62
  return { messages, instructions };
112
63
  }
@@ -1,5 +1,6 @@
1
1
  import { asArray, type Context } from '@ai-sdk/provider-utils';
2
2
  import type { Callback } from '../util/callback';
3
+ import { VERSION } from '../version';
3
4
  import {
4
5
  filterIncludedContext,
5
6
  filterToolContext,
@@ -61,6 +62,7 @@ function augmentEvent<EVENT>(
61
62
  recordInputs: telemetry.recordInputs,
62
63
  recordOutputs: telemetry.recordOutputs,
63
64
  functionId: telemetry.functionId,
65
+ aiVersion: VERSION,
64
66
  },
65
67
  );
66
68
 
@@ -224,6 +226,7 @@ export function createTelemetryDispatcher({
224
226
  onStepEnd == null && onStepFinish == null
225
227
  ? undefined
226
228
  : mergeCallbacks(onStepEnd, onStepFinish),
229
+ onStepError: mergeTelemetryCallback('onStepError'),
227
230
  onObjectStepStart: mergeTelemetryCallback('onObjectStepStart'),
228
231
  onObjectStepEnd: mergeTelemetryCallback('onObjectStepEnd'),
229
232
  onEmbedStart: mergeTelemetryCallback('onEmbedStart'),
@@ -22,6 +22,7 @@ import type {
22
22
  GenerateTextEndEvent,
23
23
  GenerateTextStartEvent,
24
24
  GenerateTextStepEndEvent,
25
+ GenerateTextStepErrorEvent,
25
26
  GenerateTextStepStartEvent,
26
27
  } from '../generate-text/generate-text-events';
27
28
  import type {
@@ -59,7 +60,13 @@ export type InferTelemetryEvent<EVENT> = EVENT &
59
60
  Omit<
60
61
  TelemetryOptions,
61
62
  'integrations' | 'isEnabled' | 'includeRuntimeContext'
62
- >;
63
+ > & {
64
+ /**
65
+ * The version of the `ai` package that emitted this event.
66
+ * Absent in older releases.
67
+ */
68
+ readonly aiVersion?: string;
69
+ };
63
70
 
64
71
  type BivariantCallback<EVENT> = {
65
72
  bivarianceHack(event: EVENT): PromiseLike<void> | void;
@@ -110,6 +117,7 @@ export interface TelemetryDispatcher {
110
117
  onStepEnd?: Callback<GenerateTextStepEndEvent>;
111
118
  /** @deprecated Use `onStepEnd` instead. */
112
119
  onStepFinish?: Callback<GenerateTextStepEndEvent>;
120
+ onStepError?: Callback<GenerateTextStepErrorEvent>;
113
121
  onObjectStepStart?: Callback<GenerateObjectStepStartEvent>;
114
122
  onObjectStepEnd?: Callback<GenerateObjectStepEndEvent>;
115
123
  onEmbedStart?: Callback<EmbeddingModelCallStartEvent>;
@@ -202,6 +210,12 @@ export interface Telemetry {
202
210
  */
203
211
  onStepFinish?: Callback<InferTelemetryEvent<GenerateTextStepEndEvent>>;
204
212
 
213
+ /**
214
+ * Called when a step that started fails before it produces a step result.
215
+ * Use it to close step-level spans. The call then ends with `onError`.
216
+ */
217
+ onStepError?: Callback<InferTelemetryEvent<GenerateTextStepErrorEvent>>;
218
+
205
219
  /**
206
220
  * Called when an object generation step (single LLM invocation) begins.
207
221
  * For generateObject/streamObject there is always exactly one step.
@@ -1,10 +1,7 @@
1
- import type {
2
- Experimental_SandboxSession,
3
- Experimental_SandboxProcess,
4
- } from '@ai-sdk/provider-utils';
1
+ import type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';
5
2
 
6
3
  /**
7
- * No-op stubs for the file and spawn methods on `Experimental_SandboxSession`,
4
+ * File stubs and an unimplemented spawn method on `Experimental_SandboxSession`,
8
5
  * intended to be spread into test fixtures that only care about `run`.
9
6
  */
10
7
  export const mockSandboxSessionFileStubs: Pick<
@@ -23,10 +20,7 @@ export const mockSandboxSessionFileStubs: Pick<
23
20
  writeFile: async () => {},
24
21
  writeBinaryFile: async () => {},
25
22
  writeTextFile: async () => {},
26
- spawn: async (): Promise<Experimental_SandboxProcess> => ({
27
- stdout: new ReadableStream<Uint8Array>({ start: c => c.close() }),
28
- stderr: new ReadableStream<Uint8Array>({ start: c => c.close() }),
29
- wait: async () => ({ exitCode: 0 }),
30
- kill: async () => {},
31
- }),
23
+ spawn: async () => {
24
+ throw new Error('spawn is not implemented in this mock.');
25
+ },
32
26
  };
@@ -0,0 +1,20 @@
1
+ import { isAbortError } from '@ai-sdk/provider-utils';
2
+
3
+ /**
4
+ * Checks if the error is an abort or timeout error, or is caused by one.
5
+ * Providers can wrap the abort or timeout error, e.g. as the cause of an
6
+ * API call error.
7
+ */
8
+ export function isCausedByAbort(error: unknown): boolean {
9
+ let current = error;
10
+
11
+ for (let depth = 0; current != null && depth < 5; depth++) {
12
+ if (isAbortError(current)) {
13
+ return true;
14
+ }
15
+
16
+ current = (current as { cause?: unknown }).cause;
17
+ }
18
+
19
+ return false;
20
+ }