ai 7.0.126 → 7.0.128

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 (82) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/index.d.ts +234 -154
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +307 -199
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +278 -68
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +371 -72
  9. package/dist/internal/index.js.map +1 -1
  10. package/dist/test/index.d.ts +25 -17
  11. package/dist/test/index.d.ts.map +1 -1
  12. package/dist/test/index.js +27 -21
  13. package/dist/test/index.js.map +1 -1
  14. package/docs/02-getting-started/03-nextjs-pages-router.mdx +1 -1
  15. package/docs/02-getting-started/07-expo.mdx +1 -1
  16. package/docs/03-agents/07-workflow-agent.mdx +80 -12
  17. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +44 -0
  18. package/docs/03-ai-sdk-core/19-tool-search.mdx +40 -4
  19. package/docs/03-ai-sdk-core/{32-evaluation.mdx → 32-decisions.mdx} +49 -49
  20. package/docs/03-ai-sdk-core/35-image-generation.mdx +6 -1
  21. package/docs/03-ai-sdk-core/36-transcription.mdx +42 -39
  22. package/docs/03-ai-sdk-core/37-speech.mdx +2 -0
  23. package/docs/03-ai-sdk-core/45-provider-management.mdx +8 -8
  24. package/docs/03-ai-sdk-core/60-telemetry.mdx +40 -31
  25. package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +21 -22
  26. package/docs/03-ai-sdk-harnesses/08-terminal-ui.mdx +2 -2
  27. package/docs/04-ai-sdk-ui/02-chatbot.mdx +2 -1
  28. package/docs/06-advanced/09-multistep-interfaces.mdx +1 -1
  29. package/docs/07-reference/01-ai-sdk-core/14-decide.mdx +74 -0
  30. package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +58 -4
  31. package/docs/07-reference/01-ai-sdk-core/23-tool-search.mdx +62 -6
  32. package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +11 -11
  33. package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +9 -9
  34. package/docs/07-reference/01-ai-sdk-core/66-extract-reasoning-middleware.mdx +24 -8
  35. package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +13 -0
  36. package/docs/07-reference/02-ai-sdk-ui/32-prune-messages.mdx +1 -1
  37. package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +1 -0
  38. package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +39 -2
  39. package/docs/07-reference/05-ai-sdk-errors/ai-decision-unsupported-question-type-error.mdx +31 -0
  40. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-model-error.mdx +3 -3
  41. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-provider-error.mdx +3 -3
  42. package/docs/08-migration-guides/23-migration-guide-7-0.mdx +1 -1
  43. package/docs/08-migration-guides/29-migration-guide-4-0.mdx +1 -1
  44. package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +2 -2
  45. package/package.json +12 -12
  46. package/src/decide/decide-events.ts +129 -0
  47. package/src/{evaluate/evaluate.ts → decide/decide.ts} +36 -38
  48. package/src/decide/decision-provider.ts +11 -0
  49. package/src/decide/decision-result.ts +39 -0
  50. package/src/decide/index.ts +64 -0
  51. package/src/{evaluate → decide}/restricted-telemetry-dispatcher.ts +7 -7
  52. package/src/{evaluate/validate-evaluation.ts → decide/validate-decision.ts} +9 -9
  53. package/src/error/index.ts +10 -1
  54. package/src/generate-speech/generated-audio-file.ts +5 -4
  55. package/src/generate-text/default-generate-text-result.ts +127 -0
  56. package/src/generate-text/generate-text.ts +2 -122
  57. package/src/generate-text/validate-tool-approvals.ts +5 -1
  58. package/src/global.ts +1 -1
  59. package/src/index.ts +1 -1
  60. package/src/middleware/extract-reasoning-middleware.ts +25 -6
  61. package/src/model/resolve-model.ts +45 -14
  62. package/src/registry/custom-provider.ts +38 -26
  63. package/src/registry/index.ts +13 -1
  64. package/src/registry/no-such-provider-error.ts +2 -0
  65. package/src/registry/provider-registry.ts +56 -29
  66. package/src/telemetry/create-telemetry-dispatcher.ts +17 -5
  67. package/src/telemetry/telemetry.ts +35 -19
  68. package/src/telemetry/tracing-channel.ts +1 -1
  69. package/src/test/decision-mock-model-v4.ts +35 -0
  70. package/src/tool-search/prepare-tool-search.ts +49 -29
  71. package/src/tool-search/tool-search.ts +58 -4
  72. package/src/transcribe/transcribe.ts +1 -1
  73. package/src/ui/chat.ts +9 -1
  74. package/src/ui/process-ui-message-stream.ts +21 -0
  75. package/src/ui-message-stream/create-ui-message-stream.ts +29 -4
  76. package/docs/07-reference/01-ai-sdk-core/14-evaluate.mdx +0 -74
  77. package/docs/07-reference/05-ai-sdk-errors/ai-evaluation-unsupported-question-type-error.mdx +0 -31
  78. package/src/evaluate/evaluate-events.ts +0 -131
  79. package/src/evaluate/evaluation-provider.ts +0 -6
  80. package/src/evaluate/evaluation-result.ts +0 -39
  81. package/src/evaluate/index.ts +0 -13
  82. package/src/test/evaluation-mock-model-v4.ts +0 -27
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  title: Lifecycle Callbacks
3
- description: Observe AI SDK lifecycle events in generateText, streamText, embed, embedMany, rerank, and experimental_evaluate calls
3
+ description: Observe AI SDK lifecycle events in generateText, streamText, embed, embedMany, rerank, and experimental_decide calls
4
4
  ---
5
5
 
6
6
  # Lifecycle Callbacks
7
7
 
8
8
  Event callbacks let you run your own code at important points in an AI SDK call.
9
- You can attach them directly to `generateText`, `streamText`, `embed`, `embedMany`, `rerank`, and `experimental_evaluate` calls to observe what happened, record usage, debug multi-step generations, and monitor tool execution.
9
+ You can attach them directly to `generateText`, `streamText`, `embed`, `embedMany`, `rerank`, and `experimental_decide` calls to observe what happened, record usage, debug multi-step generations, and monitor tool execution.
10
10
 
11
11
  They are especially useful when you want application-specific logic close to the call site:
12
12
 
@@ -452,21 +452,20 @@ const result = await generateText({
452
452
  ]}
453
453
  />
454
454
 
455
- ### `experimental_evaluate`
455
+ ### `experimental_decide`
456
456
 
457
457
  <PropertiesTable
458
458
  content={[
459
459
  {
460
460
  name: 'onStart',
461
- type: '(event: Experimental_EvaluateStartEvent) => void | Promise<void>',
461
+ type: '(event: Experimental_DecideStartEvent) => void | Promise<void>',
462
462
  description:
463
- 'Called when the evaluation operation begins, before the evaluation model is called.',
463
+ 'Called when the decision operation begins, before the decision model is called.',
464
464
  },
465
465
  {
466
466
  name: 'onEnd',
467
- type: '(event: Experimental_EvaluateEndEvent) => void | Promise<void>',
468
- description:
469
- 'Called when the evaluation operation completes successfully.',
467
+ type: '(event: Experimental_DecideEndEvent) => void | Promise<void>',
468
+ description: 'Called when the decision operation completes successfully.',
470
469
  },
471
470
  ]}
472
471
  />
@@ -1174,10 +1173,10 @@ For `embed`, `value` is a single string. For `embedMany`, `value` is an array of
1174
1173
  ]}
1175
1174
  />
1176
1175
 
1177
- ### Evaluation Events
1176
+ ### Decision Events
1178
1177
 
1179
- Evaluation callbacks are experimental. Their exported types are
1180
- `Experimental_EvaluateStartEvent` and `Experimental_EvaluateEndEvent`.
1178
+ Decision callbacks are experimental. Their exported types are
1179
+ `Experimental_DecideStartEvent` and `Experimental_DecideEndEvent`.
1181
1180
 
1182
1181
  #### onStart
1183
1182
 
@@ -1186,12 +1185,12 @@ Evaluation callbacks are experimental. Their exported types are
1186
1185
  {
1187
1186
  name: 'callId',
1188
1187
  type: 'string',
1189
- description: 'Unique identifier for this evaluation call.',
1188
+ description: 'Unique identifier for this decision call.',
1190
1189
  },
1191
1190
  {
1192
1191
  name: 'operationId',
1193
- type: "'ai.evaluate'",
1194
- description: 'Evaluation operation identifier.',
1192
+ type: "'ai.decide'",
1193
+ description: 'Decision operation identifier.',
1195
1194
  },
1196
1195
  {
1197
1196
  name: 'runtimeContext',
@@ -1201,22 +1200,22 @@ Evaluation callbacks are experimental. Their exported types are
1201
1200
  {
1202
1201
  name: 'provider',
1203
1202
  type: 'string',
1204
- description: 'Provider identifier for the evaluation model.',
1203
+ description: 'Provider identifier for the decision model.',
1205
1204
  },
1206
1205
  {
1207
1206
  name: 'modelId',
1208
1207
  type: 'string',
1209
- description: 'Evaluation model identifier.',
1208
+ description: 'Decision model identifier.',
1210
1209
  },
1211
1210
  {
1212
1211
  name: 'state',
1213
1212
  type: 'string | object | array',
1214
- description: 'Shared state being evaluated.',
1213
+ description: 'Shared state used to make decisions.',
1215
1214
  },
1216
1215
  {
1217
1216
  name: 'questions',
1218
- type: 'Readonly<Record<string, Experimental_EvaluationQuestion>>',
1219
- description: 'Questions being evaluated against the shared state.',
1217
+ type: 'Readonly<Record<string, Experimental_DecisionQuestion>>',
1218
+ description: 'Questions to decide against the shared state.',
1220
1219
  },
1221
1220
  {
1222
1221
  name: 'maxRetries',
@@ -1244,18 +1243,18 @@ Includes every `onStart` field plus:
1244
1243
  content={[
1245
1244
  {
1246
1245
  name: 'answers',
1247
- type: 'Record<string, Experimental_EvaluationAnswer>',
1246
+ type: 'Record<string, Experimental_DecisionAnswer>',
1248
1247
  description: 'Exactly one typed answer per question ID.',
1249
1248
  },
1250
1249
  {
1251
1250
  name: 'usage',
1252
1251
  type: '{ inputTokens: number | undefined; outputTokens: number | undefined; totalTokens: number | undefined }',
1253
- description: 'Token usage for the evaluation operation.',
1252
+ description: 'Token usage for the decision operation.',
1254
1253
  },
1255
1254
  {
1256
1255
  name: 'warnings',
1257
1256
  type: 'Array<Warning>',
1258
- description: 'Warnings from the evaluation model.',
1257
+ description: 'Warnings from the decision model.',
1259
1258
  },
1260
1259
  {
1261
1260
  name: 'rounding',
@@ -6,8 +6,8 @@ description: Use @ai-sdk/tui with HarnessAgent.
6
6
  # Harnesses with Terminal UI
7
7
 
8
8
  `@ai-sdk/tui` can render harness streams, tool calls, reasoning sections, and
9
- approval prompts in a terminal. Because `HarnessAgent` requires a session on
10
- every call, wrap it with a small `AgentTUIAgent` adapter that injects one
9
+ approval prompts in a terminal. Because `HarnessAgent` requires a session for
10
+ `generate` and `stream` calls, wrap it with a small `AgentTUIAgent` adapter that injects one
11
11
  session for the lifetime of the terminal UI.
12
12
 
13
13
  ## Installation
@@ -323,7 +323,8 @@ When the user clicks the "Regenerate" button, the AI provider will regenerate th
323
323
 
324
324
  ### Throttling UI Updates
325
325
 
326
- By default, the `useChat` hook will trigger a render every time a new chunk is received.
326
+ By default, `useChat` publishes message updates as each chunk is processed.
327
+ React may batch multiple updates into a single render.
327
328
  React and Vue applications can throttle reactive message updates with the `throttle` option.
328
329
  Stream processing and event callbacks remain immediate, and the latest messages are published before the chat enters a terminal `ready` or `error` status.
329
330
 
@@ -84,7 +84,7 @@ Tool: bookFlight("BA123", "12th December", ["John Doe", "Jane Doe"])
84
84
  Model: Your flight has been booked!
85
85
  ```
86
86
 
87
- Before the last tool call, the passenger details needed by the `bookFlight` tool are not available in the application context. As a result, the model asks the user to provide the passenger details before proceeding with the booking.
87
+ After `lookupFlight` returns, the passenger details needed by the `bookFlight` tool are not yet available in the application context. The model asks the user for those details; once the user supplies the names, the model can call `bookFlight`.
88
88
 
89
89
  Looking up passenger information could've been another tool that the model could've called before calling the `bookFlight` tool assuming that the user is logged into the application. This way, the model does not have to ask the user for the passenger details and can proceed with the booking.
90
90
 
@@ -0,0 +1,74 @@
1
+ ---
2
+ title: experimental_decide
3
+ description: Decide answers to typed questions against shared state with a decision model.
4
+ ---
5
+
6
+ # `experimental_decide()`
7
+
8
+ ```ts
9
+ import { experimental_decide } from 'ai';
10
+ ```
11
+
12
+ Decides answers to a nonempty map of `choice`, `score`, and `boolean` questions against one
13
+ state. See [Decisions](/docs/ai-sdk-core/decisions) for examples and semantics.
14
+
15
+ ## Parameters
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` | `string \| object \| array` | Required JSON-compatible shared state. |
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. |
30
+
31
+ See [Lifecycle Callbacks](/docs/ai-sdk-core/lifecycle-callbacks#experimental_decide)
32
+ for the complete `onStart` and `onEnd` event fields.
33
+
34
+ ## Result
35
+
36
+ Returns `Promise<Experimental_DecisionResult<QUESTIONS>>`:
37
+
38
+ - `answers`: One typed answer per question ID, with literal Choice option inference.
39
+ - `usage`: `inputTokens`, `outputTokens`, and `totalTokens`, each possibly undefined.
40
+ - `warnings`: Provider warnings, also passed to the SDK warning logger.
41
+ - `rounding`: Optional provider-declared decimal precision for probabilities and scores.
42
+ - `providerMetadata`: Optional provider-specific metadata.
43
+ - `response`: Timestamp, model ID, and optional response ID, headers, and body.
44
+
45
+ ## Provider specification
46
+
47
+ `Experimental_DecisionModelV4` is exported from `@ai-sdk/provider` and declares
48
+ `specificationVersion: 'v4'`, `provider`, `modelId`, `supportedQuestionTypes`, and
49
+ `doDecide(options)`. Decision models are isolated from stable `ProviderV4`.
50
+
51
+ The public core types are `Experimental_DecisionModel`,
52
+ `Experimental_DecisionQuestion`, `Experimental_DecisionAnswer`, and
53
+ `Experimental_DecisionResult`. All decision-specific classes use the
54
+ `Decision` prefix, with `Experimental_` aliases at package boundaries.
55
+
56
+ ## Errors
57
+
58
+ Unsupported types throw `Experimental_DecisionUnsupportedQuestionTypeError`
59
+ before provider I/O. Invalid inputs throw `InvalidArgumentError`; malformed
60
+ answers throw `InvalidResponseDataError`. Invalid answers are not retried.
61
+ Neither partial results nor missing probability synthesis are supported.
62
+
63
+ ## Model resolution
64
+
65
+ Use `registry.decisionModel('provider:model')` or
66
+ `customProvider({ decisionModels: { alias: model } }).decisionModel('alias')`
67
+ to resolve models. Strings passed directly to `experimental_decide` use
68
+ `globalThis.AI_SDK_DEFAULT_PROVIDER.decisionModel(id)` when a default provider is
69
+ configured, or Gateway when no default provider is configured.
70
+
71
+ Resolution errors use the existing `NoSuchModelError` and `NoSuchProviderError`
72
+ classes with `modelType: 'decisionModel'`. Model instances and resolved models
73
+ must implement v4; other versions throw `UnsupportedModelVersionError`.
74
+ See [model resolution examples](/docs/ai-sdk-core/decisions#model-aliases-and-registries).
@@ -368,11 +368,24 @@ Returns a Promise that resolves to an `MCPClient` with the following properties
368
368
  'Tool definitions, typically returned by `listTools`.',
369
369
  },
370
370
  {
371
- name: 'schemas',
372
- type: 'TOOL_SCHEMAS',
371
+ name: 'options',
372
+ type: '{ schemas?: TOOL_SCHEMAS }',
373
373
  isOptional: true,
374
- description:
375
- 'Optional schema definitions for compile-time type checking and typed outputs.',
374
+ description: 'Options for converting the tool definitions.',
375
+ properties: [
376
+ {
377
+ type: 'options',
378
+ parameters: [
379
+ {
380
+ name: 'schemas',
381
+ type: 'TOOL_SCHEMAS',
382
+ isOptional: true,
383
+ description:
384
+ 'Optional schema definitions for compile-time type checking and typed outputs.',
385
+ },
386
+ ],
387
+ },
388
+ ],
376
389
  },
377
390
  ],
378
391
  },
@@ -641,6 +654,47 @@ The client throws `MCPClientError` for:
641
654
  - Missing server capabilities
642
655
  - Connection failures
643
656
 
657
+ Import `MCPClientError` from `@ai-sdk/mcp` and use its `isInstance` method to
658
+ safely narrow unknown errors:
659
+
660
+ ```typescript
661
+ import { createMCPClient, MCPClientError } from '@ai-sdk/mcp';
662
+
663
+ try {
664
+ await createMCPClient({
665
+ transport: {
666
+ type: 'http',
667
+ url: 'https://your-server.com/mcp',
668
+ },
669
+ });
670
+ } catch (error) {
671
+ if (MCPClientError.isInstance(error)) {
672
+ if (error.statusCode === 401 || error.statusCode === 403) {
673
+ // Authentication or authorization must be fixed before retrying.
674
+ throw error;
675
+ }
676
+
677
+ // Inspect error.code and error.statusCode according to your application's policy.
678
+ }
679
+
680
+ throw error;
681
+ }
682
+ ```
683
+
684
+ The error exposes the optional `code`, `statusCode`, `url`, and `responseBody`
685
+ properties. `code` is the JSON-RPC application error code. `statusCode`, `url`,
686
+ and `responseBody` contain HTTP transport context when it is available. They
687
+ are `undefined` for failures without an HTTP response, such as network errors,
688
+ timeouts, aborted requests, and stdio transport failures.
689
+
690
+ `MCPClientError` also represents configuration and protocol errors, so its
691
+ type or a missing `statusCode` alone does not indicate a retryable failure.
692
+ OAuth failures can instead throw the separately exported `UnauthorizedError`
693
+ or `MCPClientOAuthError`.
694
+
695
+ Avoid logging `url` or `responseBody` without redacting sensitive endpoint,
696
+ query parameter, or server response data.
697
+
644
698
  For tool execution, errors are propagated as `CallToolError` errors.
645
699
 
646
700
  For unknown errors, the client exposes an `onUncaughtError` callback that can be used to manually log or handle errors that are not covered by known error types.
@@ -5,8 +5,8 @@ description: Search deferred tools and load their definitions on demand for dire
5
5
 
6
6
  # `toolSearch()`
7
7
 
8
- Creates a tool that searches the surrounding generation's deferred tools by name
9
- and description. The factory takes no arguments. Use it with `generateText`,
8
+ Creates a tool that searches the surrounding generation's deferred tools, using
9
+ keyword matching by default or a custom search callback. Use it with `generateText`,
10
10
  `streamText`, `ToolLoopAgent`, or `WorkflowAgent` from `@ai-sdk/workflow`.
11
11
  `WorkflowAgent` supports direct tool calling. The other APIs also support code
12
12
  mode configured with `toolDiscovery: 'conversation'`.
@@ -20,6 +20,60 @@ const search = toolSearch();
20
20
  See the [Tool Search guide](/docs/ai-sdk-core/tool-search) for direct-calling and
21
21
  code mode examples, including how code mode preserves the tool-definition cache.
22
22
 
23
+ ## Options
24
+
25
+ Pass an optional configuration object to control the result limit:
26
+
27
+ ```ts
28
+ const search = toolSearch({ maxResults: 10 });
29
+ ```
30
+
31
+ `maxResults` is the maximum number of matching tools returned and discovered per
32
+ search. It defaults to `5` and must be a positive safe integer. Invalid values
33
+ throw `InvalidArgumentError` when creating the search tool. The model-facing
34
+ description reflects the configured limit.
35
+
36
+ The limit applies to both default keyword search and custom search callbacks,
37
+ without changing their matching or ranking. Discovered tools accumulate across
38
+ searches, so this is not a limit on the total number of tools loaded during a
39
+ generation.
40
+
41
+ Pass a `search` callback to select and rank tools using your application's search
42
+ logic. The callback can return synchronously or asynchronously:
43
+
44
+ ```ts
45
+ const search = toolSearch({
46
+ search: ({ query, tools }) => {
47
+ const preferred = /\bgmail\b/i.test(query)
48
+ ? ['gmail_list_messages', 'gmail_get_message']
49
+ : [];
50
+ return preferred.filter(name => tools.some(tool => tool.name === name));
51
+ },
52
+ });
53
+ ```
54
+
55
+ The callback has this signature:
56
+
57
+ ```ts
58
+ search?: (options: {
59
+ query: string;
60
+ tools: Array<{ name: string; description?: string }>;
61
+ }) => string[] | PromiseLike<string[]>;
62
+ ```
63
+
64
+ `tools` contains all eligible deferred tools, before keyword matching or ranking.
65
+ Eligibility respects `activeTools` and caller routing. Descriptions are resolved
66
+ using the current tool context and sandbox; schemas are not included.
67
+
68
+ Return tool names in ranked order. The SDK ignores unknown or ineligible names,
69
+ removes duplicates while preserving order, and keeps the first `maxResults` valid
70
+ names (five by default). Returned descriptions come from the SDK's candidate
71
+ catalog. An empty array
72
+ discovers no tools. Callback errors follow normal tool-execution error handling;
73
+ the SDK does not fall back to keyword search.
74
+
75
+ Without a callback, `toolSearch()` uses the default keyword search described below.
76
+
23
77
  ## Model Input
24
78
 
25
79
  The model supplies the following input to the search tool:
@@ -28,11 +82,12 @@ The model supplies the following input to the search tool:
28
82
  { "query": "weather forecast" }
29
83
  ```
30
84
 
31
- `query` is a required, nonempty string of search keywords. Search is local and
85
+ `query` is a required, nonempty string. By default, search is local and
32
86
  case-insensitive, matching words in tool names and descriptions. Camel-case names
33
87
  are split into words. Name matches rank above description matches; equal scores
34
88
  preserve registration order. Function descriptions are resolved with the current
35
- tool context and sandbox. No embedding service or additional model call is used.
89
+ tool context and sandbox. The default search uses no embedding service or
90
+ additional model call. A custom callback can use either.
36
91
 
37
92
  ## Output
38
93
 
@@ -44,8 +99,9 @@ tool context and sandbox. No embedding service or additional model call is used.
44
99
  }
45
100
  ```
46
101
 
47
- Results contain at most five matching tools, with their names and optional
48
- descriptions. They do not include schemas. No matches returns `{ tools: [] }`.
102
+ Results contain at most `maxResults` matching tools (five by default), with their
103
+ names and optional descriptions. They do not include schemas. No matches returns
104
+ `{ tools: [] }`.
49
105
  Every returned match is queued for discovery. Newly discovered tools can only be
50
106
  called on the next model step, after their definitions have been provided. A
51
107
  parallel call in the same response as the search cannot use a newly discovered
@@ -299,20 +299,20 @@ The `createProviderRegistry` function returns a `Provider` instance. It has the
299
299
  ]}
300
300
  />
301
301
 
302
- ## Experimental evaluation models
302
+ ## Experimental decision models
303
303
 
304
- The inferred return type also exposes `evaluationModel('providerId:modelId')`,
305
- returning `Experimental_EvaluationModelV4`. The provider must expose an
306
- `evaluationModel` factory. Custom separators and model ID
304
+ The inferred return type also exposes `decisionModel('providerId:modelId')`,
305
+ returning `Experimental_DecisionModelV4`. The provider must expose an
306
+ `decisionModel` factory. Custom separators and model ID
307
307
  inference work as they do for video models. Language and image middleware do not
308
- wrap evaluation models. `ProviderRegistryProvider` remains a stable interface;
309
- use the inferred return type or `Experimental_EvaluationProviderRegistry` to
310
- retain experimental evaluation access.
308
+ wrap decision models. `ProviderRegistryProvider` remains a stable interface;
309
+ use the inferred return type or `Experimental_DecisionProviderRegistry` to
310
+ retain experimental decision access.
311
311
 
312
- Unavailable evaluation capabilities or models throw `NoSuchModelError` with
313
- `modelType: 'evaluationModel'`; unknown registry providers throw
312
+ Unavailable decision capabilities or models throw `NoSuchModelError` with
313
+ `modelType: 'decisionModel'`; unknown registry providers throw
314
314
  `NoSuchProviderError`. These capabilities are structural extensions and are not
315
- added to the stable `ProviderV4` contract. Direct evaluation string IDs default
315
+ added to the stable `ProviderV4` contract. Direct decision string IDs default
316
316
  to Gateway when no default provider is configured.
317
- See [Evaluation](/docs/ai-sdk-core/evaluation#model-aliases-and-registries)
317
+ See [Decisions](/docs/ai-sdk-core/decisions#model-aliases-and-registries)
318
318
  for runnable usage patterns.
@@ -202,20 +202,20 @@ The `customProvider` function returns a `Provider` instance. It has the followin
202
202
  ]}
203
203
  />
204
204
 
205
- ## Experimental evaluation models
205
+ ## Experimental decision models
206
206
 
207
- Pass `evaluationModels: Record<string, Experimental_EvaluationModel>` to define
208
- aliases for evaluation model instances or string IDs. The returned provider adds
209
- `evaluationModel(alias): Experimental_EvaluationModelV4`. String aliases resolve
207
+ Pass `decisionModels: Record<string, Experimental_DecisionModel>` to define
208
+ aliases for decision model instances or string IDs. The returned provider adds
209
+ `decisionModel(alias): Experimental_DecisionModelV4`. String aliases resolve
210
210
  through Gateway by default, or an explicitly configured default provider with
211
- an `evaluationModel` method. Unknown aliases use the fallback provider's evaluation
211
+ a `decisionModel` method. Unknown aliases use the fallback provider's decision
212
212
  factory when available; model failures and unsupported questions do not trigger
213
213
  substitution.
214
214
 
215
- Unavailable evaluation capabilities or models throw `NoSuchModelError` with
216
- `modelType: 'evaluationModel'`; unknown registry providers throw
215
+ Unavailable decision capabilities or models throw `NoSuchModelError` with
216
+ `modelType: 'decisionModel'`; unknown registry providers throw
217
217
  `NoSuchProviderError`. These capabilities are structural extensions and are not
218
- added to the stable `ProviderV4` contract. Direct evaluation string IDs default
218
+ added to the stable `ProviderV4` contract. Direct decision string IDs default
219
219
  to Gateway when no default provider is configured.
220
- See [Evaluation](/docs/ai-sdk-core/evaluation#model-aliases-and-registries)
220
+ See [Decisions](/docs/ai-sdk-core/decisions#model-aliases-and-registries)
221
221
  for runnable usage patterns.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: extractReasoningMiddleware
3
- description: Middleware that extracts XML-tagged reasoning sections from generated text
3
+ description: Middleware that extracts reasoning sections from generated text using configurable delimiters
4
4
  ---
5
5
 
6
6
  # `extractReasoningMiddleware()`
7
7
 
8
- `extractReasoningMiddleware` is a middleware function that extracts XML-tagged reasoning sections from generated text and exposes them separately from the main text content. This is particularly useful when you want to separate an AI model's reasoning process from its final output.
8
+ `extractReasoningMiddleware` is a middleware function that extracts delimited reasoning sections from generated text and exposes them separately from the main text content. This is particularly useful when you want to separate an AI model's reasoning process from its final output.
9
9
 
10
10
  ```ts
11
11
  import { extractReasoningMiddleware } from 'ai';
@@ -16,6 +16,22 @@ const middleware = extractReasoningMiddleware({
16
16
  });
17
17
  ```
18
18
 
19
+ For models that emit non-XML delimiters, pass literal `opening` and `closing`
20
+ strings. For example, Gemma 4's raw thought-channel output uses a newline in its
21
+ opening delimiter:
22
+
23
+ ```ts
24
+ const middleware = extractReasoningMiddleware({
25
+ tagName: { opening: '<|channel>thought\n', closing: '<channel|>' },
26
+ });
27
+ ```
28
+
29
+ Custom delimiters must be non-empty. They are matched literally, including
30
+ characters such as `|`, and can span multiple streaming chunks. Empty reasoning
31
+ blocks are removed from the answer text as well. Use this middleware when the
32
+ server returns these markers in text; providers that already return reasoning
33
+ separately do not need it.
34
+
19
35
  ## Import
20
36
 
21
37
  <Snippet
@@ -31,10 +47,10 @@ const middleware = extractReasoningMiddleware({
31
47
  content={[
32
48
  {
33
49
  name: 'tagName',
34
- type: 'string',
50
+ type: 'string | { opening: string; closing: string }',
35
51
  isOptional: false,
36
52
  description:
37
- 'The name of the XML tag to extract reasoning from (without angle brackets)',
53
+ 'An XML tag name without angle brackets (e.g. "think" for <think> / </think>), or an object containing non-empty literal opening and closing delimiters.',
38
54
  },
39
55
  {
40
56
  name: 'separator',
@@ -48,7 +64,7 @@ const middleware = extractReasoningMiddleware({
48
64
  type: 'boolean',
49
65
  isOptional: true,
50
66
  description:
51
- 'Starts with reasoning tokens. Set to true when the response always starts with reasoning and the initial tag is omitted. Defaults to false.',
67
+ 'Starts with reasoning tokens. Set to true when the response always starts with reasoning and the opening delimiter is omitted. Defaults to false.',
52
68
  },
53
69
  ]}
54
70
  />
@@ -58,9 +74,9 @@ const middleware = extractReasoningMiddleware({
58
74
  Returns a middleware object that:
59
75
 
60
76
  - Processes both streaming and non-streaming responses
61
- - Extracts content between specified XML tags as reasoning
62
- - Removes the XML tags and reasoning from the main text
63
- - Adds a `reasoning` property to the result containing the extracted content
77
+ - Extracts content between the specified delimiters as reasoning
78
+ - Removes the delimiters and reasoning from the main text
79
+ - Emits reasoning content parts separately from text content parts
64
80
  - Maintains proper separation between text sections using the specified separator
65
81
 
66
82
  ### Type Parameters
@@ -486,6 +486,19 @@ Allows you to easily create a conversational user interface for your chatbot app
486
486
  ]}
487
487
  />
488
488
 
489
+ ## React rendering and shared Chat instances
490
+
491
+ In React, `messages`, `status`, and `error` describe the snapshot for the current render.
492
+ The underlying `Chat` updates as stream chunks are processed. React may batch updates,
493
+ and `throttle` can delay message rendering without delaying stream processing or callbacks.
494
+ Status and error updates include the latest messages, so a completed or failed response
495
+ is rendered with its final message snapshot.
496
+
497
+ Each `useChat({ chat })` call subscribes independently. Consumers sharing a `Chat`
498
+ can display different message snapshots when they use different throttle intervals.
499
+ A functional `setMessages` updater receives the Chat's latest messages, which may be
500
+ newer than the messages in the current render.
501
+
489
502
  ## Learn more
490
503
 
491
504
  - [Chatbot](/docs/ai-sdk-ui/chatbot)
@@ -60,7 +60,7 @@ export async function POST(req: Request) {
60
60
  },
61
61
  {
62
62
  name: 'toolCalls',
63
- type: `'all' | 'before-last-message' | 'before-last-\${number}-messages' | 'none' | Array<{ type: 'all' | 'before-last-message' | 'before-last-\${number}-messages'; tools?: string[] }>`,
63
+ type: `'all' | 'before-last-message' | \`before-last-\${number}-messages\` | 'none' | Array<{ type: 'all' | 'before-last-message' | \`before-last-\${number}-messages\`; tools?: string[] }>`,
64
64
  description:
65
65
  'How to prune tool call/results/approval content. Can specify a strategy string or an array for per-tool fine control. Default: [] (empty array, equivalent to "none").',
66
66
  },
@@ -517,6 +517,7 @@ To see `streamUI` in action, check out [these examples](#examples).
517
517
  {
518
518
  name: 'response',
519
519
  type: 'Response',
520
+ isOptional: true,
520
521
  description: 'Optional response data.',
521
522
  properties: [
522
523
  {
@@ -99,7 +99,7 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
99
99
  type: 'StopCondition | StopCondition[]',
100
100
  isOptional: true,
101
101
  description:
102
- 'Default stop condition for the agent loop. When omitted, WorkflowAgent has no maximum step count and continues until natural completion. Use `isStepCount()` to bound execution. Per-stream values override this default.',
102
+ 'Default stop condition for the agent loop. When omitted, generate defaults to 20 steps, while stream has no maximum step count. Use `isStepCount()` to bound execution. Per-call values override this default.',
103
103
  },
104
104
  {
105
105
  name: 'activeTools',
@@ -478,6 +478,43 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
478
478
 
479
479
  ## Methods
480
480
 
481
+ ### `generate()`
482
+
483
+ Runs the durable agent loop using the model's non-streaming `doGenerate()` method. Model calls and tool execution use the same orchestration as `stream()`.
484
+
485
+ ```ts
486
+ const result = await agent.generate({ prompt: 'Summarize the findings.' });
487
+ console.log(result.text);
488
+ console.log(result.usage);
489
+ ```
490
+
491
+ Accepts `WorkflowAgentGenerateOptions`, sharing prompt/messages, instructions, generation settings, tools and runtime context, preparation, stopping, output, and lifecycle options with `stream()`. It does not accept `writable`, `includeRawChunks`, `experimental_transform`, `sendFinish`, or `preventClose`. Without a configured stop condition, generation stops after at most 20 steps. `stream()` retains its existing unbounded default.
492
+
493
+ The `include` option accepts `requestBody`, `responseBody`, and `requestMessages` booleans, all defaulting to `false`. Enable them only when the additional request/response data is needed. Response IDs, timestamps, model IDs, headers, and provider metadata are retained when supplied by the model.
494
+
495
+ #### Returns
496
+
497
+ Returns `Promise<WorkflowAgentGenerateResult>` with the core [`GenerateTextResult`](/docs/reference/ai-sdk-core/generate-text#returns) semantics:
498
+
499
+ - `text`, `finishReason`, `rawFinishReason`, and `finalStep` describe the final step.
500
+ - `content`, `files`, `sources`, `warnings`, tool calls, and tool results cover all steps.
501
+ - `usage` and `totalUsage` sum all steps while retaining token details and unknown counts.
502
+ - `responseMessages` includes generated messages, even when `prepareStep` replaces the input history.
503
+ - `output` defaults to text, or follows the constructor/per-call output specification. Reading it throws `NoOutputGeneratedError` when output is unavailable, such as a final `tool-calls` response.
504
+
505
+ Inside a workflow, `timeout` bounds model calls, including retries and dispatch after suspension. It does not cancel a hook that a tool is waiting on. Use the Workflow runtime’s `run.cancel()` to stop a suspended run. See [deadlines, cancellation, and replay](/docs/agents/workflow-agent#deadlines-cancellation-and-replay).
506
+
507
+ Generation failures reject. The end callback runs before complete-output parsing; a parsing failure can therefore reject after `onEnd` has run. Existing Workflow callback shapes and preparation precedence apply; they are not all identical to core's callback APIs.
508
+
509
+ <Note>
510
+ Use the result API inside workflow code and return selected serializable
511
+ fields (for example, `text` and `usage`) through `run.returnValue`. Returning
512
+ the whole result class is not supported. Performance data currently measures
513
+ the model response; complete tool/step timing is not yet reported.
514
+ </Note>
515
+
516
+ Approval requests appear in `content` and `responseMessages` without requiring a writable. To continue, append `responseMessages` to the original history and add a tool message containing the user's `tool-approval-response`. Preserve the request signature and tool-call input; use the same `experimental_toolApprovalSecret` environment-variable reference on continuation. Local approvals are validated before execution, and provider-executed approval responses are forwarded to the provider. See [approval round trips](/docs/agents/workflow-agent#approval-round-trips-without-streaming).
517
+
481
518
  ### `stream()`
482
519
 
483
520
  Runs the agent loop, streaming responses and executing tool calls as needed. Returns a promise resolving to a `WorkflowAgentStreamResult`.
@@ -549,7 +586,7 @@ const result = await agent.stream({
549
586
  name: 'timeout',
550
587
  type: 'number',
551
588
  isOptional: true,
552
- description: 'Timeout in milliseconds. Creates an AbortSignal that aborts the operation after the given time.',
589
+ description: 'Model-call deadline in milliseconds. Inside a workflow, the absolute deadline is checked at dispatch and retry and remains in effect across suspension. It does not cancel a tool waiting on a Workflow hook; use run.cancel() to stop the suspended run.',
553
590
  },
554
591
  {
555
592
  name: 'sendFinish',