ai 6.0.92 → 6.0.94

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 (38) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.d.mts +357 -13
  3. package/dist/index.d.ts +357 -13
  4. package/dist/index.js +198 -26
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +198 -26
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/internal/index.js +1 -1
  9. package/dist/internal/index.mjs +1 -1
  10. package/docs/02-foundations/03-prompts.mdx +1 -1
  11. package/docs/02-getting-started/01-navigating-the-library.mdx +1 -1
  12. package/docs/03-agents/02-building-agents.mdx +8 -7
  13. package/docs/03-agents/03-workflows.mdx +71 -55
  14. package/docs/03-ai-sdk-core/01-overview.mdx +2 -4
  15. package/docs/03-ai-sdk-core/05-generating-text.mdx +54 -0
  16. package/docs/03-ai-sdk-core/10-generating-structured-data.mdx +8 -172
  17. package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +48 -6
  18. package/docs/03-ai-sdk-core/20-prompt-engineering.mdx +14 -12
  19. package/docs/03-ai-sdk-core/55-testing.mdx +8 -8
  20. package/docs/03-ai-sdk-core/60-telemetry.mdx +13 -53
  21. package/docs/05-ai-sdk-rsc/02-streaming-react-components.mdx +1 -1
  22. package/docs/05-ai-sdk-rsc/05-streaming-values.mdx +2 -3
  23. package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +9 -9
  24. package/docs/06-advanced/04-caching.mdx +1 -1
  25. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +667 -146
  26. package/docs/07-reference/01-ai-sdk-core/index.mdx +3 -8
  27. package/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx +2 -2
  28. package/docs/09-troubleshooting/09-client-stream-error.mdx +1 -1
  29. package/docs/09-troubleshooting/14-tool-calling-with-structured-outputs.mdx +4 -4
  30. package/docs/09-troubleshooting/20-no-object-generated-content-filter.mdx +18 -14
  31. package/package.json +2 -2
  32. package/src/generate-text/execute-tool-call.ts +83 -0
  33. package/src/generate-text/generate-text.ts +534 -11
  34. package/src/generate-text/index.ts +4 -0
  35. package/src/generate-text/step-result.ts +52 -0
  36. package/src/generate-text/stream-text.ts +15 -1
  37. package/docs/07-reference/01-ai-sdk-core/03-generate-object.mdx +0 -780
  38. package/docs/07-reference/01-ai-sdk-core/04-stream-object.mdx +0 -1152
@@ -25,14 +25,9 @@ AI SDK Core contains the following main functions:
25
25
  href: '/docs/reference/ai-sdk-core/stream-text',
26
26
  },
27
27
  {
28
- title: 'generateObject()',
29
- description: 'Generate structured data from a language model.',
30
- href: '/docs/reference/ai-sdk-core/generate-object',
31
- },
32
- {
33
- title: 'streamObject()',
34
- description: 'Stream structured data from a language model.',
35
- href: '/docs/reference/ai-sdk-core/stream-object',
28
+ title: 'Output',
29
+ description: 'Structured output types for generateText and streamText.',
30
+ href: '/docs/reference/ai-sdk-core/output',
36
31
  },
37
32
  {
38
33
  title: 'embed()',
@@ -26,10 +26,10 @@ It can arise due to the following reasons:
26
26
  You can check if an error is an instance of `AI_NoObjectGeneratedError` using:
27
27
 
28
28
  ```typescript
29
- import { generateObject, NoObjectGeneratedError } from 'ai';
29
+ import { generateText, NoObjectGeneratedError, Output } from 'ai';
30
30
 
31
31
  try {
32
- await generateObject({ model, schema, prompt });
32
+ await generateText({ model, output: Output.object({ schema }), prompt });
33
33
  } catch (error) {
34
34
  if (NoObjectGeneratedError.isInstance(error)) {
35
35
  console.log('NoObjectGeneratedError');
@@ -7,7 +7,7 @@ description: Troubleshooting errors related to using AI SDK Core functions with
7
7
 
8
8
  ## Issue
9
9
 
10
- I am using [`streamText`](/docs/reference/ai-sdk-core/stream-text) or [`streamObject`](/docs/reference/ai-sdk-core/stream-object) with Server Actions, and I am getting a `"only plain objects and a few built ins can be passed from client components"` error.
10
+ I am using [`streamText`](/docs/reference/ai-sdk-core/stream-text) with Server Actions, and I am getting a `"only plain objects and a few built ins can be passed from client components"` error.
11
11
 
12
12
  ## Background
13
13
 
@@ -1,13 +1,13 @@
1
1
  ---
2
- title: Tool calling with generateObject and streamObject
3
- description: Troubleshooting tool calling when combined with generateObject and streamObject
2
+ title: Tool calling with structured outputs
3
+ description: Troubleshooting tool calling when combined with structured output generation
4
4
  ---
5
5
 
6
- # Tool calling with generateObject and streamObject (structured outputs)
6
+ # Tool calling with structured outputs
7
7
 
8
8
  ## Issue
9
9
 
10
- You may want to combine tool calling with structured output generation. While `generateObject` and `streamObject` are designed specifically for structured outputs, they don't support tool calling.
10
+ You may want to combine tool calling with structured output generation.
11
11
 
12
12
  ## Background
13
13
 
@@ -7,20 +7,22 @@ description: Troubleshooting NoObjectGeneratedError with finish-reason content-f
7
7
 
8
8
  ## Issue
9
9
 
10
- When using `generateObject` or `streamObject` with OpenAI's structured output generation, you may encounter a `NoObjectGeneratedError` with the finish reason `content-filter`. This error occurs when your Zod schema contains incompatible types that OpenAI's structured output feature cannot process.
10
+ When using structured output generation with OpenAI, you may encounter a `NoObjectGeneratedError` with the finish reason `content-filter`. This error occurs when your Zod schema contains incompatible types that OpenAI's structured output feature cannot process.
11
11
 
12
12
  ```typescript
13
13
  // Problematic code - incompatible schema types
14
- import { generateObject } from 'ai';
14
+ import { generateText, Output } from 'ai';
15
15
  import { openai } from '@ai-sdk/openai';
16
16
  import { z } from 'zod';
17
17
 
18
- const result = await generateObject({
18
+ const result = await generateText({
19
19
  model: openai('gpt-4o-2024-08-06'),
20
- schema: z.object({
21
- name: z.string().nullish(), // ❌ .nullish() is not supported
22
- email: z.string().optional(), // ❌ .optional() is not supported
23
- age: z.number().nullable(), // .nullable() is supported
20
+ output: Output.object({
21
+ schema: z.object({
22
+ name: z.string().nullish(), // ❌ .nullish() is not supported
23
+ email: z.string().optional(), // .optional() is not supported
24
+ age: z.number().nullable(), // ✅ .nullable() is supported
25
+ }),
24
26
  }),
25
27
  prompt: 'Generate a user profile',
26
28
  });
@@ -38,22 +40,24 @@ OpenAI's structured output generation uses JSON Schema under the hood and has sp
38
40
  Replace `.nullish()` and `.optional()` with `.nullable()` in your Zod schemas when using structured output generation with OpenAI models.
39
41
 
40
42
  ```typescript
41
- import { generateObject } from 'ai';
43
+ import { generateText, Output } from 'ai';
42
44
  import { openai } from '@ai-sdk/openai';
43
45
  import { z } from 'zod';
44
46
 
45
47
  // Correct approach - use .nullable()
46
- const result = await generateObject({
48
+ const result = await generateText({
47
49
  model: openai('gpt-4o-2024-08-06'),
48
- schema: z.object({
49
- name: z.string().nullable(), // ✅ Use .nullable() instead of .nullish()
50
- email: z.string().nullable(), // ✅ Use .nullable() instead of .optional()
51
- age: z.number().nullable(),
50
+ output: Output.object({
51
+ schema: z.object({
52
+ name: z.string().nullable(), // ✅ Use .nullable() instead of .nullish()
53
+ email: z.string().nullable(), // ✅ Use .nullable() instead of .optional()
54
+ age: z.number().nullable(),
55
+ }),
52
56
  }),
53
57
  prompt: 'Generate a user profile',
54
58
  });
55
59
 
56
- console.log(result.object);
60
+ console.log(result.output);
57
61
  // { name: "John Doe", email: "john@example.com", age: 30 }
58
62
  // or { name: null, email: null, age: 25 }
59
63
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "6.0.92",
3
+ "version": "6.0.94",
4
4
  "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@opentelemetry/api": "1.9.0",
48
- "@ai-sdk/gateway": "3.0.51",
48
+ "@ai-sdk/gateway": "3.0.52",
49
49
  "@ai-sdk/provider": "3.0.8",
50
50
  "@ai-sdk/provider-utils": "4.0.15"
51
51
  },
@@ -4,12 +4,28 @@ import { assembleOperationName } from '../telemetry/assemble-operation-name';
4
4
  import { recordErrorOnSpan, recordSpan } from '../telemetry/record-span';
5
5
  import { selectTelemetryAttributes } from '../telemetry/select-telemetry-attributes';
6
6
  import { TelemetrySettings } from '../telemetry/telemetry-settings';
7
+ import { now } from '../util/now';
8
+ import {
9
+ GenerateTextOnToolCallFinishCallback,
10
+ GenerateTextOnToolCallStartCallback,
11
+ } from './generate-text';
7
12
  import { TypedToolCall } from './tool-call';
8
13
  import { ToolOutput } from './tool-output';
9
14
  import { ToolSet } from './tool-set';
10
15
  import { TypedToolResult } from './tool-result';
11
16
  import { TypedToolError } from './tool-error';
12
17
 
18
+ /**
19
+ * Executes a single tool call and manages its lifecycle callbacks.
20
+ *
21
+ * This function handles the complete tool execution flow:
22
+ * 1. Invokes `onToolCallStart` callback before execution
23
+ * 2. Executes the tool's `execute` function with proper context
24
+ * 3. Handles streaming outputs via `onPreliminaryToolResult`
25
+ * 4. Invokes `onToolCallFinish` callback with success or error result
26
+ *
27
+ * @returns The tool output (result or error), or undefined if the tool has no execute function.
28
+ */
13
29
  export async function executeToolCall<TOOLS extends ToolSet>({
14
30
  toolCall,
15
31
  tools,
@@ -18,7 +34,11 @@ export async function executeToolCall<TOOLS extends ToolSet>({
18
34
  messages,
19
35
  abortSignal,
20
36
  experimental_context,
37
+ stepNumber,
38
+ model,
21
39
  onPreliminaryToolResult,
40
+ onToolCallStart,
41
+ onToolCallFinish,
22
42
  }: {
23
43
  toolCall: TypedToolCall<TOOLS>;
24
44
  tools: TOOLS | undefined;
@@ -27,7 +47,11 @@ export async function executeToolCall<TOOLS extends ToolSet>({
27
47
  messages: ModelMessage[];
28
48
  abortSignal: AbortSignal | undefined;
29
49
  experimental_context: unknown;
50
+ stepNumber?: number;
51
+ model?: { provider: string; modelId: string };
30
52
  onPreliminaryToolResult?: (result: TypedToolResult<TOOLS>) => void;
53
+ onToolCallStart?: GenerateTextOnToolCallStartCallback<TOOLS>;
54
+ onToolCallFinish?: GenerateTextOnToolCallFinishCallback<TOOLS>;
31
55
  }): Promise<ToolOutput<TOOLS> | undefined> {
32
56
  const { toolName, toolCallId, input } = toolCall;
33
57
  const tool = tools?.[toolName];
@@ -56,6 +80,23 @@ export async function executeToolCall<TOOLS extends ToolSet>({
56
80
  fn: async span => {
57
81
  let output: unknown;
58
82
 
83
+ try {
84
+ await onToolCallStart?.({
85
+ stepNumber,
86
+ model,
87
+ toolCall,
88
+ messages,
89
+ abortSignal,
90
+ functionId: telemetry?.functionId,
91
+ metadata: telemetry?.metadata as Record<string, unknown> | undefined,
92
+ experimental_context,
93
+ });
94
+ } catch (_ignored) {
95
+ // Errors in callbacks should not break the generation flow.
96
+ }
97
+
98
+ const startTime = now();
99
+
59
100
  try {
60
101
  const stream = executeTool({
61
102
  execute: tool.execute!.bind(tool),
@@ -81,6 +122,28 @@ export async function executeToolCall<TOOLS extends ToolSet>({
81
122
  }
82
123
  }
83
124
  } catch (error) {
125
+ const durationMs = now() - startTime;
126
+
127
+ try {
128
+ await onToolCallFinish?.({
129
+ stepNumber,
130
+ model,
131
+ toolCall,
132
+ messages,
133
+ abortSignal,
134
+ success: false,
135
+ error,
136
+ durationMs,
137
+ functionId: telemetry?.functionId,
138
+ metadata: telemetry?.metadata as
139
+ | Record<string, unknown>
140
+ | undefined,
141
+ experimental_context,
142
+ });
143
+ } catch (_ignored) {
144
+ // Errors in callbacks should not break the generation flow.
145
+ }
146
+
84
147
  recordErrorOnSpan(span, error);
85
148
  return {
86
149
  type: 'tool-error',
@@ -95,6 +158,26 @@ export async function executeToolCall<TOOLS extends ToolSet>({
95
158
  } as TypedToolError<TOOLS>;
96
159
  }
97
160
 
161
+ const durationMs = now() - startTime;
162
+
163
+ try {
164
+ await onToolCallFinish?.({
165
+ stepNumber,
166
+ model,
167
+ toolCall,
168
+ messages,
169
+ abortSignal,
170
+ success: true,
171
+ output,
172
+ durationMs,
173
+ functionId: telemetry?.functionId,
174
+ metadata: telemetry?.metadata as Record<string, unknown> | undefined,
175
+ experimental_context,
176
+ });
177
+ } catch (_ignored) {
178
+ // Errors in callbacks should not break the generation flow.
179
+ }
180
+
98
181
  try {
99
182
  span.setAttributes(
100
183
  await selectTelemetryAttributes({