ai 7.0.145 → 7.0.147

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 (54) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/index.d.ts +16 -8
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +38 -9
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +10 -6
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +1 -1
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/02-foundations/01-overview.mdx +1 -1
  11. package/docs/02-foundations/02-providers-and-models.mdx +2 -2
  12. package/docs/02-foundations/03-prompts.mdx +3 -3
  13. package/docs/02-foundations/04-tools.mdx +2 -2
  14. package/docs/02-getting-started/00-choosing-a-provider.mdx +1 -1
  15. package/docs/02-getting-started/02-nextjs-app-router.mdx +4 -4
  16. package/docs/02-getting-started/03-nextjs-pages-router.mdx +4 -4
  17. package/docs/02-getting-started/04-svelte.mdx +3 -3
  18. package/docs/02-getting-started/05-nuxt.mdx +3 -3
  19. package/docs/02-getting-started/06-nodejs.mdx +2 -2
  20. package/docs/02-getting-started/07-expo.mdx +4 -4
  21. package/docs/02-getting-started/08-tanstack-start.mdx +4 -4
  22. package/docs/03-ai-sdk-core/10-generating-structured-data.mdx +1 -1
  23. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +29 -2
  24. package/docs/03-ai-sdk-core/18-tools.mdx +137 -0
  25. package/docs/03-ai-sdk-core/37-speech.mdx +1 -1
  26. package/docs/03-ai-sdk-core/41-skill-uploads.mdx +24 -10
  27. package/docs/03-ai-sdk-core/index.mdx +6 -0
  28. package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +1 -1
  29. package/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx +8 -8
  30. package/docs/03-ai-sdk-harnesses/06-workflow-utilities.mdx +12 -0
  31. package/docs/03-ai-sdk-harnesses/07-ui.mdx +2 -2
  32. package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +2 -2
  33. package/docs/05-ai-sdk-rsc/01-overview.mdx +1 -1
  34. package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +1 -1
  35. package/docs/06-advanced/01-prompt-engineering.mdx +1 -1
  36. package/docs/06-advanced/03-backpressure.mdx +1 -1
  37. package/docs/06-advanced/10-vercel-deployment-guide.mdx +1 -1
  38. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +1 -1
  39. package/docs/07-reference/01-ai-sdk-core/14-decide.mdx +18 -13
  40. package/docs/07-reference/01-ai-sdk-core/14-upload-skill.mdx +3 -3
  41. package/docs/07-reference/01-ai-sdk-core/22-dynamic-tool.mdx +1 -1
  42. package/docs/08-migration-guides/index.mdx +12 -12
  43. package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +1 -1
  44. package/package.json +12 -12
  45. package/src/decide/decide-events.ts +6 -0
  46. package/src/decide/decide.ts +13 -0
  47. package/src/generate-text/output.ts +1 -1
  48. package/src/generate-text/prune-messages.ts +91 -32
  49. package/src/generate-text/tool-call.ts +1 -1
  50. package/src/generate-text/tool-error.ts +1 -1
  51. package/src/generate-text/tool-execution-events.ts +2 -2
  52. package/src/generate-text/tool-output-denied.ts +1 -1
  53. package/src/generate-text/tool-result.ts +1 -1
  54. package/src/ui/process-ui-message-stream.ts +1 -0
@@ -36,12 +36,12 @@ The AI SDK includes the following harness adapters:
36
36
  | Adapter | Runtime location | Custom tools | Custom skills | Structured output | Built-in tool approval | Built-in tool filtering | Image input | History access |
37
37
  | ------------------------------------------------------------ | ---------------- | ------------ | ------------- | ----------------- | ---------------------- | ---------------------------- | ----------- | -------------- |
38
38
  | [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
39
- | [Cline](/providers/ai-sdk-harnesses/cline) | Host process | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
40
- | [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
41
- | [Cursor](/providers/ai-sdk-harnesses/cursor) | Sandbox via ACP | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
42
- | [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection | <Cross /> | <Cross /> |
39
+ | [Cline](/providers/ai-sdk-harnesses/cline) | Host process | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
40
+ | [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Check /> | <Cross /> |
41
+ | [Cursor](/providers/ai-sdk-harnesses/cursor) | Sandbox via ACP | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Check /> | <Cross /> |
42
+ | [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection | <Check /> | <Cross /> |
43
43
  | [fx](/providers/ai-sdk-harnesses/fx) | Host process | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
44
- | [GitHub Copilot](/providers/ai-sdk-harnesses/github-copilot) | Sandbox via ACP | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
45
- | [Grok Build](/providers/ai-sdk-harnesses/grok-build) | Sandbox via ACP | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
46
- | [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
47
- | [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check /> | <Check /> | <Cross /> | <Check /> | <Check /> | <Cross /> | <Cross /> |
44
+ | [GitHub Copilot](/providers/ai-sdk-harnesses/github-copilot) | Sandbox via ACP | <Check /> | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Check /> | <Cross /> |
45
+ | [Grok Build](/providers/ai-sdk-harnesses/grok-build) | Sandbox via ACP | <Check /> | <Check /> | <Check /> | <Cross /> | <Cross /> | <Check /> | <Cross /> |
46
+ | [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
47
+ | [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check /> | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> | <Cross /> |
@@ -308,6 +308,18 @@ export async function POST(request: Request) {
308
308
  }
309
309
  ```
310
310
 
311
+ If you use Next.js, wrap your config with `withWorkflow()` so the Workflow SDK
312
+ transforms `'use workflow'` and `'use step'` modules. Other frameworks have
313
+ their own Workflow SDK setup.
314
+
315
+ ```js filename='next.config.js'
316
+ import { withWorkflow } from 'workflow/next';
317
+
318
+ const nextConfig = {};
319
+
320
+ export default withWorkflow(nextConfig);
321
+ ```
322
+
311
323
  The workflow state `sessionId` identifies the harness session. The step derives
312
324
  `sandboxId` from it; otherwise, you must persist `sandboxSession.id` separately
313
325
  to reattach across steps. Keep
@@ -93,7 +93,7 @@ export const agent = new HarnessAgent({
93
93
 
94
94
  Persist the opaque resume state returned by `session.detach()`. If the
95
95
  turn paused for approval or was otherwise interrupted, that resume state carries
96
- the continuation state internally. The chat id can also be the harness
96
+ the continuation state internally. The chat ID can also be the harness
97
97
  `sessionId`. Here we derive a stable `sandboxId` from that known chat id. If
98
98
  you do not derive one, persist the returned `sandboxSession.id` separately.
99
99
 
@@ -170,7 +170,7 @@ export async function POST(request: Request) {
170
170
  } = await request.json();
171
171
 
172
172
  if (!body.id) {
173
- throw new Error('Missing chat id');
173
+ return new Response('Missing chat ID', { status: 400 });
174
174
  }
175
175
 
176
176
  const chatId = body.id;
@@ -16,12 +16,12 @@ The flow is as follows:
16
16
 
17
17
  1. The user enters a message in the chat UI.
18
18
  1. The message is sent to the API route.
19
- 1. In your server side route, the language model generates tool calls during the `streamText` call.
19
+ 1. In your server-side route, the language model generates tool calls during the `streamText` call.
20
20
  1. All tool calls are forwarded to the client.
21
21
  1. Server-side tools are executed using their `execute` method and their results are forwarded to the client.
22
22
  1. Client-side tools that should be automatically executed are handled with the `onToolCall` callback.
23
23
  You must call `addToolOutput` to provide the tool result.
24
- 1. Client-side tool that require user interactions can be displayed in the UI.
24
+ 1. Client-side tools that require user interactions can be displayed in the UI.
25
25
  The tool calls and results are available as tool invocation parts in the `parts` property of the last assistant message.
26
26
  1. When the user interaction is done, `addToolOutput` can be used to add the tool result to the chat.
27
27
  1. The chat can be configured to automatically submit when all tool results are available using `sendAutomaticallyWhen`.
@@ -16,7 +16,7 @@ description: An overview of AI SDK RSC.
16
16
  Server Components.
17
17
  </Note>
18
18
 
19
- [React Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components) (RSC) allow you to write UI that can be rendered on the server and streamed to the client. RSCs enable [ Server Actions ](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#with-client-components), a new way to call server-side code directly from the client just like any other function with end-to-end type-safety. This combination opens the door to a new way of building AI applications, allowing the large language model (LLM) to generate and stream UI directly from the server to the client.
19
+ [React Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components) (RSC) allow you to write UI that can be rendered on the server and streamed to the client. RSCs enable [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#with-client-components), a new way to call server-side code directly from the client just like any other function with end-to-end type-safety. This combination opens the door to a new way of building AI applications, allowing the large language model (LLM) to generate and stream UI directly from the server to the client.
20
20
 
21
21
  ## AI SDK RSC Functions
22
22
 
@@ -166,7 +166,7 @@ export default function Page() {
166
166
 
167
167
  In AI SDK RSC, `streamUI` does not support parallel tool calls. You will have to use a combination of `streamText`, `createStreamableUI` and `createStreamableValue`.
168
168
 
169
- With AI SDK UI, `useChat` comes with built-in support for parallel tool calls. You can define multiple tools in the `streamText` and have them called them in parallel. The `useChat` hook will then handle the parallel tool calls for you automatically.
169
+ With AI SDK UI, `useChat` comes with built-in support for parallel tool calls. You can define multiple tools in the `streamText` and have them called in parallel. The `useChat` hook will then handle the parallel tool calls for you automatically.
170
170
 
171
171
  ### Multi-Step Tool Calls
172
172
 
@@ -17,7 +17,7 @@ Prompts are the starting points for LLMs. They are the inputs that trigger the m
17
17
 
18
18
  ## Why is prompt engineering needed?
19
19
 
20
- Prompt engineering currently plays a pivotal role in shaping the responses of LLMs. It allows us to tweak the model to respond more effectively to a broader range of queries. This includes the use of techniques like semantic search, command grammars, and the ReActive model architecture. The performance, context window, and cost of LLMs varies between models and model providers which adds further constraints to the mix. For example, the GPT-4 model is more expensive than GPT-3.5-turbo and significantly slower, but it can also be more effective at certain tasks. And so, like many things in software engineering, there is a trade-offs between cost and performance.
20
+ Prompt engineering currently plays a pivotal role in shaping the responses of LLMs. It allows us to tweak the model to respond more effectively to a broader range of queries. This includes the use of techniques like semantic search, command grammars, and the ReActive model architecture. The performance, context window, and cost of LLMs varies between models and model providers which adds further constraints to the mix. For example, the GPT-4 model is more expensive than GPT-3.5-turbo and significantly slower, but it can also be more effective at certain tasks. And so, like many things in software engineering, there is a trade-off between cost and performance.
21
21
 
22
22
  To assist with comparing and tweaking LLMs, we've built an AI playground that allows you to compare the performance of different models side-by-side online. When you're ready, you can even generate code with the AI SDK to quickly use your prompt and your selected model into your own applications.
23
23
 
@@ -120,7 +120,7 @@ function createStream(iterator) {
120
120
  }
121
121
  // Collect data from stream
122
122
  async function run() {
123
- // Set up a stream that of integers
123
+ // Set up a stream of integers
124
124
  const stream = createStream(integers());
125
125
 
126
126
  // Read values from our stream
@@ -16,7 +16,7 @@ Vercel allows for automatic deployments on every branch push and merges onto the
16
16
  To follow along with this guide, you will need:
17
17
 
18
18
  - a Vercel account
19
- - an account with a Git provider (this tutorial will use [Github](https://github.com))
19
+ - an account with a Git provider (this tutorial will use [GitHub](https://github.com))
20
20
  - an OpenAI API key
21
21
 
22
22
  This guide will teach you how to deploy the application you built in the Next.js (App Router) quickstart tutorial to Vercel. If you haven’t completed the quickstart guide, you can start with [this repo](https://github.com/vercel-labs/ai-sdk-deployment-guide).
@@ -7,7 +7,7 @@ description: API Reference for generateText.
7
7
 
8
8
  Generates text and calls tools for a given prompt using a language model.
9
9
 
10
- It is ideal for non-interactive use cases such as automation tasks where you need to write text (e.g. drafting email or summarizing web pages) and for agents that use tools.
10
+ It is ideal for non-interactive use cases such as automation tasks where you need to write text (e.g. drafting emails or summarizing web pages) and for agents that use tools.
11
11
 
12
12
  ```ts
13
13
  import { generateText } from 'ai';
@@ -14,19 +14,24 @@ state. See [Decisions](/docs/ai-sdk-core/decisions) for examples and semantics.
14
14
 
15
15
  ## Parameters
16
16
 
17
- | Parameter | Type | Description |
18
- | ----------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
19
- | `model` | `Experimental_DecisionModel` | Required experimental v4 model instance or a string ID resolved by Gateway or an explicitly configured decision-capable default provider. |
20
- | `state` | `Experimental_DecisionState` | Required string, JSON object, or ordered array of text, file, and JSON parts. |
21
- | `questions` | `Record<string, Experimental_DecisionQuestion>` | Required nonempty question map. |
22
- | `maxRetries` | `number` | Nonnegative integer; defaults to 2. |
23
- | `abortSignal` | `AbortSignal` | Cancels the decisions request. |
24
- | `headers` | `Record<string, string>` | Additional HTTP headers. |
25
- | `providerOptions` | `ProviderOptions` | Provider-specific options. |
26
- | `telemetry` | `TelemetryOptions` | Telemetry configuration, including per-call integrations, input/output recording, and a function ID. |
27
- | `runtimeContext` | `Record<string, unknown>` | Context available to lifecycle callbacks and selectively included in telemetry with `telemetry.includeRuntimeContext`. |
28
- | `onStart` | `(event: Experimental_DecideStartEvent) => void` | Called when the decision operation begins. |
29
- | `onEnd` | `(event: Experimental_DecideEndEvent) => void` | Called when the decision operation completes successfully. |
17
+ | Parameter | Type | Description |
18
+ | ----------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | `model` | `Experimental_DecisionModel` | Required experimental v4 model instance or a string ID resolved by Gateway or an explicitly configured decision-capable default provider. |
20
+ | `state` | `Experimental_DecisionState` | Required string, JSON object, or ordered array of text, file, and JSON parts. |
21
+ | `questions` | `Record<string, Experimental_DecisionQuestion>` | Required nonempty question map. |
22
+ | `maxOutputTokens` | `number` | Optional maximum output tokens, an integer >= 1. |
23
+ | `reasoning` | `'provider-default' \| 'none' \| 'minimal' \| 'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max'` | Optional reasoning effort. Language-model adapters default to `'none'`. Native decision providers return an unsupported-setting warning. |
24
+ | `maxRetries` | `number` | Nonnegative integer; defaults to 2. |
25
+ | `abortSignal` | `AbortSignal` | Cancels the decisions request. |
26
+ | `headers` | `Record<string, string>` | Additional HTTP headers. |
27
+ | `providerOptions` | `ProviderOptions` | Provider-specific options. |
28
+ | `telemetry` | `TelemetryOptions` | Telemetry configuration, including per-call integrations, input/output recording, and a function ID. |
29
+ | `runtimeContext` | `Record<string, unknown>` | Context available to lifecycle callbacks and selectively included in telemetry with `telemetry.includeRuntimeContext`. |
30
+ | `onStart` | `(event: Experimental_DecideStartEvent) => void` | Called when the decision operation begins. |
31
+ | `onEnd` | `(event: Experimental_DecideEndEvent) => void` | Called when the decision operation completes successfully. |
32
+
33
+ Set `reasoning: 'provider-default'` to use the underlying language model's default
34
+ reasoning effort instead of the adapter's `'none'` default.
30
35
 
31
36
  See [Lifecycle Callbacks](/docs/ai-sdk-core/lifecycle-callbacks#experimental_decide)
32
37
  for the complete `onStart` and `onEnd` event fields.
@@ -17,7 +17,7 @@ const { providerReference } = await uploadSkill({
17
17
  files: [
18
18
  {
19
19
  path: 'my-skill/SKILL.md',
20
- content: readFileSync('./SKILL.md'),
20
+ data: readFileSync('./SKILL.md'),
21
21
  },
22
22
  ],
23
23
  displayTitle: 'My Skill',
@@ -42,9 +42,9 @@ const { providerReference } = await uploadSkill({
42
42
  },
43
43
  {
44
44
  name: 'files',
45
- type: 'SkillsV4File[]',
45
+ type: 'UploadSkillFile[]',
46
46
  description:
47
- 'The files that make up the skill. Each file has a relative `path` and `content` (either a `Uint8Array` or a base64-encoded string).',
47
+ "The files that make up the skill. Each file must have a relative `path` and `data`. The `data` can be a string, a `Uint8Array`, or an object with `type: 'text'` and a string `text` value, or `type: 'data'` and a string `data` value.",
48
48
  },
49
49
  {
50
50
  name: 'displayTitle',
@@ -224,7 +224,7 @@ When used with useChat (`UIMessage` format), dynamic tools appear as `dynamic-to
224
224
  switch (part.type) {
225
225
  case 'dynamic-tool':
226
226
  return (
227
- <div>
227
+ <div key={part.toolCallId}>
228
228
  <h4>Tool: {part.toolName}</h4>
229
229
  <pre>{JSON.stringify(part.input, null, 2)}</pre>
230
230
  </div>
@@ -6,18 +6,18 @@ collapsed: true
6
6
 
7
7
  # Migration Guides
8
8
 
9
- - [ Migrate AI SDK 6.x to 7.0 ](/docs/migration-guides/migration-guide-7-0)
10
- - [ Migrate AI SDK 5.x to 6.0 ](/docs/migration-guides/migration-guide-6-0)
11
- - [ Migrate AI SDK 4.x to 5.0 ](/docs/migration-guides/migration-guide-5-0)
12
- - [ Migrate your data to AI SDK 5.0 ](/docs/migration-guides/migration-guide-5-0-data)
13
- - [ Migrate AI SDK 4.1 to 4.2 ](/docs/migration-guides/migration-guide-4-2)
14
- - [ Migrate AI SDK 4.0 to 4.1 ](/docs/migration-guides/migration-guide-4-1)
15
- - [ Migrate AI SDK 3.4 to 4.0 ](/docs/migration-guides/migration-guide-4-0)
16
- - [ Migrate AI SDK 3.3 to 3.4 ](/docs/migration-guides/migration-guide-3-4)
17
- - [ Migrate AI SDK 3.2 to 3.3 ](/docs/migration-guides/migration-guide-3-3)
18
- - [ Migrate AI SDK 3.1 to 3.2 ](/docs/migration-guides/migration-guide-3-2)
19
- - [ Migrate AI SDK 3.0 to 3.1 ](/docs/migration-guides/migration-guide-3-1)
9
+ - [Migrate AI SDK 6.x to 7.0](/docs/migration-guides/migration-guide-7-0)
10
+ - [Migrate AI SDK 5.x to 6.0](/docs/migration-guides/migration-guide-6-0)
11
+ - [Migrate AI SDK 4.x to 5.0](/docs/migration-guides/migration-guide-5-0)
12
+ - [Migrate your data to AI SDK 5.0](/docs/migration-guides/migration-guide-5-0-data)
13
+ - [Migrate AI SDK 4.1 to 4.2](/docs/migration-guides/migration-guide-4-2)
14
+ - [Migrate AI SDK 4.0 to 4.1](/docs/migration-guides/migration-guide-4-1)
15
+ - [Migrate AI SDK 3.4 to 4.0](/docs/migration-guides/migration-guide-4-0)
16
+ - [Migrate AI SDK 3.3 to 3.4](/docs/migration-guides/migration-guide-3-4)
17
+ - [Migrate AI SDK 3.2 to 3.3](/docs/migration-guides/migration-guide-3-3)
18
+ - [Migrate AI SDK 3.1 to 3.2](/docs/migration-guides/migration-guide-3-2)
19
+ - [Migrate AI SDK 3.0 to 3.1](/docs/migration-guides/migration-guide-3-1)
20
20
 
21
21
  ## Versioning
22
22
 
23
- - [ Versioning ](/docs/migration-guides/versioning)
23
+ - [Versioning](/docs/migration-guides/versioning)
@@ -38,7 +38,7 @@ const tools = {
38
38
  };
39
39
  ```
40
40
 
41
- 2. Client-side execution with `useChat` (omitting the `execute` function), you must provide results using `addToolOutput`:
41
+ 2. For client-side execution with `useChat` (omitting the `execute` function), you must provide results using `addToolOutput`:
42
42
 
43
43
  ```tsx
44
44
  import { useChat } from '@ai-sdk/react';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.145",
3
+ "version": "7.0.147",
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,20 +42,20 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@ai-sdk/gateway": "4.0.118",
46
- "@ai-sdk/provider": "4.0.30",
47
- "@ai-sdk/provider-utils": "5.0.63"
45
+ "@ai-sdk/gateway": "4.0.120",
46
+ "@ai-sdk/provider": "4.0.31",
47
+ "@ai-sdk/provider-utils": "5.0.64"
48
48
  },
49
49
  "devDependencies": {
50
- "@ai-sdk/amazon-bedrock": "5.0.119",
51
- "@ai-sdk/deepseek": "3.0.68",
52
- "@ai-sdk/google": "4.0.100",
53
- "@ai-sdk/groq": "4.0.65",
54
- "@ai-sdk/huggingface": "2.0.73",
55
- "@ai-sdk/moonshotai": "3.0.72",
56
- "@ai-sdk/openai": "4.0.97",
50
+ "@ai-sdk/amazon-bedrock": "5.0.120",
51
+ "@ai-sdk/deepseek": "3.0.69",
52
+ "@ai-sdk/google": "4.0.101",
53
+ "@ai-sdk/groq": "4.0.66",
54
+ "@ai-sdk/huggingface": "2.0.74",
55
+ "@ai-sdk/moonshotai": "3.0.73",
56
+ "@ai-sdk/openai": "4.0.98",
57
57
  "@ai-sdk/test-server": "2.0.4",
58
- "@ai-sdk/xai": "5.0.25",
58
+ "@ai-sdk/xai": "5.0.26",
59
59
  "@edge-runtime/vm": "^5.0.0",
60
60
  "@smithy/eventstream-codec": "^4.3.3",
61
61
  "@smithy/util-utf8": "^4.3.3",
@@ -34,6 +34,12 @@ export type DecideStartEvent<RUNTIME_CONTEXT extends Context = Context> = {
34
34
  /** The questions to decide against the shared state. */
35
35
  readonly questions: Readonly<Record<string, DecisionQuestion>>;
36
36
 
37
+ /** Maximum output tokens requested for the decision. */
38
+ readonly maxOutputTokens?: number;
39
+
40
+ /** Reasoning effort requested for the decision. */
41
+ readonly reasoning?: DecisionModelV4CallOptions['reasoning'];
42
+
37
43
  /** Maximum number of retries for the decision model call. */
38
44
  readonly maxRetries: number;
39
45
 
@@ -2,6 +2,7 @@ import {
2
2
  Experimental_DecisionRefusalError as DecisionRefusalError,
3
3
  Experimental_DecisionUnsupportedQuestionTypeError as DecisionUnsupportedQuestionTypeError,
4
4
  type Experimental_DecisionModelV4Question as DecisionQuestion,
5
+ type Experimental_DecisionModelV4CallOptions as DecisionCallOptions,
5
6
  } from '@ai-sdk/provider';
6
7
  import {
7
8
  createIdGenerator,
@@ -16,6 +17,7 @@ import type { TelemetryOptions } from '../telemetry/telemetry-options';
16
17
  import type { Callback } from '../util/callback';
17
18
  import { notify } from '../util/notify';
18
19
  import { prepareRetries } from '../util/prepare-retries';
20
+ import { prepareLanguageModelCallOptions } from '../prompt/prepare-language-model-call-options';
19
21
  import { VERSION } from '../version';
20
22
  import type { DecideEndEvent, DecideStartEvent } from './decide-events';
21
23
  import type { DecisionModel, DecisionResult } from './decision-result';
@@ -38,6 +40,8 @@ export async function decide<
38
40
  model: modelArg,
39
41
  state,
40
42
  questions,
43
+ maxOutputTokens,
44
+ reasoning,
41
45
  maxRetries,
42
46
  abortSignal,
43
47
  headers,
@@ -52,6 +56,10 @@ export async function decide<
52
56
  model: DecisionModel;
53
57
  state: DecisionState;
54
58
  questions: QUESTIONS;
59
+ /** Maximum output tokens for supported models. Must be an integer >= 1. */
60
+ maxOutputTokens?: number;
61
+ /** Reasoning effort for supported models. Language-model adapters default to none. */
62
+ reasoning?: DecisionCallOptions['reasoning'];
55
63
  /** Maximum retries for transient provider failures. Defaults to 2. */
56
64
  maxRetries?: number;
57
65
  abortSignal?: AbortSignal;
@@ -72,6 +80,7 @@ export async function decide<
72
80
  }): Promise<DecisionResult<QUESTIONS>> {
73
81
  const model = resolveDecisionModel(modelArg);
74
82
 
83
+ prepareLanguageModelCallOptions({ maxOutputTokens });
75
84
  validateDecisionInput({ state, questions });
76
85
 
77
86
  for (const [questionId, question] of Object.entries(questions)) {
@@ -105,6 +114,8 @@ export async function decide<
105
114
  modelId: model.modelId,
106
115
  state,
107
116
  questions,
117
+ maxOutputTokens,
118
+ reasoning,
108
119
  maxRetries: resolvedMaxRetries,
109
120
  headers,
110
121
  providerOptions,
@@ -139,6 +150,8 @@ export async function decide<
139
150
  return await model.doDecide({
140
151
  state: preparedState,
141
152
  questions,
153
+ maxOutputTokens,
154
+ reasoning,
142
155
  abortSignal,
143
156
  headers: withUserAgentSuffix(headers ?? {}, `ai/${VERSION}`),
144
157
  providerOptions,
@@ -491,7 +491,7 @@ function getArrayLengthValidationError({
491
491
 
492
492
  /**
493
493
  * Output specification for choice generation.
494
- * When the model generates a text response, it will return a one of the choice options.
494
+ * When the model generates a text response, it will return one of the choice options.
495
495
  *
496
496
  * @param options - The available choices.
497
497
  * @param name - Optional name of the output that should be generated. Used by some providers for additional LLM guidance, e.g. via tool or schema name.
@@ -163,42 +163,101 @@ export function pruneMessages({
163
163
  return message;
164
164
  }
165
165
 
166
- return {
167
- ...message,
168
- content: message.content.filter(part => {
169
- // keep non-tool parts:
170
- if (
171
- part.type !== 'tool-call' &&
172
- part.type !== 'tool-result' &&
173
- part.type !== 'tool-approval-request' &&
174
- part.type !== 'tool-approval-response'
175
- ) {
176
- return true;
166
+ const keepParts = message.content.map(part => {
167
+ // keep non-tool parts:
168
+ if (
169
+ part.type !== 'tool-call' &&
170
+ part.type !== 'tool-result' &&
171
+ part.type !== 'tool-approval-request' &&
172
+ part.type !== 'tool-approval-response'
173
+ ) {
174
+ return true;
175
+ }
176
+
177
+ // keep parts that are associated with a tool call or approval that needs to be kept:
178
+ if (
179
+ ((part.type === 'tool-call' || part.type === 'tool-result') &&
180
+ keptToolCallIds.has(part.toolCallId)) ||
181
+ ((part.type === 'tool-approval-request' ||
182
+ part.type === 'tool-approval-response') &&
183
+ keptApprovalIds.has(part.approvalId))
184
+ ) {
185
+ return true;
186
+ }
187
+
188
+ // keep parts that are not associated with a tool that should be removed:
189
+ const partToolName =
190
+ part.type === 'tool-call' || part.type === 'tool-result'
191
+ ? part.toolName
192
+ : approvalIdToToolName.get(part.approvalId);
193
+
194
+ return (
195
+ toolCall.tools != null &&
196
+ partToolName != null &&
197
+ !toolCall.tools.includes(partToolName)
198
+ );
199
+ });
200
+
201
+ // Consecutive reasoning parts can belong to the same provider item.
202
+ // Remove the whole group when its following content was pruned.
203
+ if (message.role === 'assistant') {
204
+ for (
205
+ let reasoningIndex = 0;
206
+ reasoningIndex < message.content.length;
207
+ reasoningIndex++
208
+ ) {
209
+ const part = message.content[reasoningIndex];
210
+ if (part.type !== 'reasoning' && part.type !== 'reasoning-file') {
211
+ continue;
212
+ }
213
+
214
+ let reasoningEndIndex = reasoningIndex + 1;
215
+ while (reasoningEndIndex < message.content.length) {
216
+ const nextPart = message.content[reasoningEndIndex];
217
+ if (
218
+ nextPart.type !== 'reasoning' &&
219
+ nextPart.type !== 'reasoning-file'
220
+ ) {
221
+ break;
222
+ }
223
+ reasoningEndIndex++;
177
224
  }
178
225
 
179
- // keep parts that are associated with a tool call or approval that needs to be kept:
180
- if (
181
- ((part.type === 'tool-call' || part.type === 'tool-result') &&
182
- keptToolCallIds.has(part.toolCallId)) ||
183
- ((part.type === 'tool-approval-request' ||
184
- part.type === 'tool-approval-response') &&
185
- keptApprovalIds.has(part.approvalId))
186
- ) {
187
- return true;
226
+ let followingPartIndex = reasoningEndIndex;
227
+ let hasFollowingPart = false;
228
+ let hasKeptFollowingPart = false;
229
+
230
+ while (followingPartIndex < message.content.length) {
231
+ const followingPart = message.content[followingPartIndex];
232
+ if (
233
+ followingPart.type === 'reasoning' ||
234
+ followingPart.type === 'reasoning-file'
235
+ ) {
236
+ break;
237
+ }
238
+
239
+ hasFollowingPart = true;
240
+ hasKeptFollowingPart ||= keepParts[followingPartIndex];
241
+ followingPartIndex++;
188
242
  }
189
243
 
190
- // keep parts that are not associated with a tool that should be removed:
191
- const partToolName =
192
- part.type === 'tool-call' || part.type === 'tool-result'
193
- ? part.toolName
194
- : approvalIdToToolName.get(part.approvalId);
195
-
196
- return (
197
- toolCall.tools != null &&
198
- partToolName != null &&
199
- !toolCall.tools.includes(partToolName)
200
- );
201
- }),
244
+ if (hasFollowingPart && !hasKeptFollowingPart) {
245
+ for (
246
+ let index = reasoningIndex;
247
+ index < reasoningEndIndex;
248
+ index++
249
+ ) {
250
+ keepParts[index] = false;
251
+ }
252
+ }
253
+
254
+ reasoningIndex = followingPartIndex - 1;
255
+ }
256
+ }
257
+
258
+ return {
259
+ ...message,
260
+ content: message.content.filter((_, index) => keepParts[index]),
202
261
  } as AssistantModelMessage | ToolModelMessage;
203
262
  });
204
263
  }
@@ -18,7 +18,7 @@ type BaseToolCall = {
18
18
  * with an `input` type inferred from that tool's input schema.
19
19
  */
20
20
  export type StaticToolCall<TOOLS extends ToolSet> = ValueOf<{
21
- [NAME in keyof TOOLS]: BaseToolCall & {
21
+ [NAME in keyof TOOLS]-?: BaseToolCall & {
22
22
  toolName: NAME & string;
23
23
  input: InferToolInput<TOOLS[NAME]>;
24
24
  dynamic?: false | undefined;
@@ -4,7 +4,7 @@ import type { ProviderMetadata } from '../types';
4
4
  import type { ValueOf } from '../util/value-of';
5
5
 
6
6
  export type StaticToolError<TOOLS extends ToolSet> = ValueOf<{
7
- [NAME in keyof TOOLS]: {
7
+ [NAME in keyof TOOLS]-?: {
8
8
  type: 'tool-error';
9
9
  toolCallId: string;
10
10
  toolName: NAME & string;
@@ -36,7 +36,7 @@ type BaseToolExecutionStartFields = {
36
36
  * validated `toolContext` type.
37
37
  */
38
38
  type StaticToolExecutionStartEvent<TOOLS extends ToolSet> = ValueOf<{
39
- [NAME in keyof TOOLS]: BaseToolExecutionStartFields & {
39
+ [NAME in keyof TOOLS]-?: BaseToolExecutionStartFields & {
40
40
  readonly toolCall: Extract<StaticToolCall<TOOLS>, { toolName: NAME }>;
41
41
  readonly toolContext: ToolContextFor<TOOLS[NAME]>;
42
42
  };
@@ -93,7 +93,7 @@ type BaseToolExecutionEndFields = {
93
93
  * corresponding validated `toolContext`, and the tool execution result.
94
94
  */
95
95
  type StaticToolExecutionEndEvent<TOOLS extends ToolSet> = ValueOf<{
96
- [NAME in keyof TOOLS]: BaseToolExecutionEndFields & {
96
+ [NAME in keyof TOOLS]-?: BaseToolExecutionEndFields & {
97
97
  readonly toolCall: Extract<StaticToolCall<TOOLS>, { toolName: NAME }>;
98
98
  readonly toolContext: ToolContextFor<TOOLS[NAME]>;
99
99
  readonly toolOutput: ToolOutput<TOOLS>;
@@ -5,7 +5,7 @@ import type { ToolSet } from '@ai-sdk/provider-utils';
5
5
  * Tool output when the tool execution has been denied (for static tools).
6
6
  */
7
7
  export type StaticToolOutputDenied<TOOLS extends ToolSet> = ValueOf<{
8
- [NAME in keyof TOOLS]: {
8
+ [NAME in keyof TOOLS]-?: {
9
9
  type: 'tool-output-denied';
10
10
  toolCallId: string;
11
11
  toolName: NAME & string;
@@ -8,7 +8,7 @@ import type { ProviderMetadata } from '../types';
8
8
  import type { ValueOf } from '../../src/util/value-of';
9
9
 
10
10
  export type StaticToolResult<TOOLS extends ToolSet> = ValueOf<{
11
- [NAME in keyof TOOLS]: {
11
+ [NAME in keyof TOOLS]-?: {
12
12
  type: 'tool-result';
13
13
  toolCallId: string;
14
14
  toolName: NAME & string;
@@ -271,6 +271,7 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
271
271
 
272
272
  if (part != null) {
273
273
  part.state = options.state;
274
+ anyPart.type = `tool-${options.toolName}`;
274
275
  anyPart.input = anyOptions.input;
275
276
  anyPart.output = anyOptions.output;
276
277
  anyPart.errorText = anyOptions.errorText;