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.
- package/CHANGELOG.md +29 -0
- package/dist/index.d.ts +234 -154
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +307 -199
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +278 -68
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +371 -72
- package/dist/internal/index.js.map +1 -1
- package/dist/test/index.d.ts +25 -17
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +27 -21
- package/dist/test/index.js.map +1 -1
- package/docs/02-getting-started/03-nextjs-pages-router.mdx +1 -1
- package/docs/02-getting-started/07-expo.mdx +1 -1
- package/docs/03-agents/07-workflow-agent.mdx +80 -12
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +44 -0
- package/docs/03-ai-sdk-core/19-tool-search.mdx +40 -4
- package/docs/03-ai-sdk-core/{32-evaluation.mdx → 32-decisions.mdx} +49 -49
- package/docs/03-ai-sdk-core/35-image-generation.mdx +6 -1
- package/docs/03-ai-sdk-core/36-transcription.mdx +42 -39
- package/docs/03-ai-sdk-core/37-speech.mdx +2 -0
- package/docs/03-ai-sdk-core/45-provider-management.mdx +8 -8
- package/docs/03-ai-sdk-core/60-telemetry.mdx +40 -31
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +21 -22
- package/docs/03-ai-sdk-harnesses/08-terminal-ui.mdx +2 -2
- package/docs/04-ai-sdk-ui/02-chatbot.mdx +2 -1
- package/docs/06-advanced/09-multistep-interfaces.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/14-decide.mdx +74 -0
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +58 -4
- package/docs/07-reference/01-ai-sdk-core/23-tool-search.mdx +62 -6
- package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +11 -11
- package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +9 -9
- package/docs/07-reference/01-ai-sdk-core/66-extract-reasoning-middleware.mdx +24 -8
- package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +13 -0
- package/docs/07-reference/02-ai-sdk-ui/32-prune-messages.mdx +1 -1
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +1 -0
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +39 -2
- package/docs/07-reference/05-ai-sdk-errors/ai-decision-unsupported-question-type-error.mdx +31 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-model-error.mdx +3 -3
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-provider-error.mdx +3 -3
- package/docs/08-migration-guides/23-migration-guide-7-0.mdx +1 -1
- package/docs/08-migration-guides/29-migration-guide-4-0.mdx +1 -1
- package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +2 -2
- package/package.json +12 -12
- package/src/decide/decide-events.ts +129 -0
- package/src/{evaluate/evaluate.ts → decide/decide.ts} +36 -38
- package/src/decide/decision-provider.ts +11 -0
- package/src/decide/decision-result.ts +39 -0
- package/src/decide/index.ts +64 -0
- package/src/{evaluate → decide}/restricted-telemetry-dispatcher.ts +7 -7
- package/src/{evaluate/validate-evaluation.ts → decide/validate-decision.ts} +9 -9
- package/src/error/index.ts +10 -1
- package/src/generate-speech/generated-audio-file.ts +5 -4
- package/src/generate-text/default-generate-text-result.ts +127 -0
- package/src/generate-text/generate-text.ts +2 -122
- package/src/generate-text/validate-tool-approvals.ts +5 -1
- package/src/global.ts +1 -1
- package/src/index.ts +1 -1
- package/src/middleware/extract-reasoning-middleware.ts +25 -6
- package/src/model/resolve-model.ts +45 -14
- package/src/registry/custom-provider.ts +38 -26
- package/src/registry/index.ts +13 -1
- package/src/registry/no-such-provider-error.ts +2 -0
- package/src/registry/provider-registry.ts +56 -29
- package/src/telemetry/create-telemetry-dispatcher.ts +17 -5
- package/src/telemetry/telemetry.ts +35 -19
- package/src/telemetry/tracing-channel.ts +1 -1
- package/src/test/decision-mock-model-v4.ts +35 -0
- package/src/tool-search/prepare-tool-search.ts +49 -29
- package/src/tool-search/tool-search.ts +58 -4
- package/src/transcribe/transcribe.ts +1 -1
- package/src/ui/chat.ts +9 -1
- package/src/ui/process-ui-message-stream.ts +21 -0
- package/src/ui-message-stream/create-ui-message-stream.ts +29 -4
- package/docs/07-reference/01-ai-sdk-core/14-evaluate.mdx +0 -74
- package/docs/07-reference/05-ai-sdk-errors/ai-evaluation-unsupported-question-type-error.mdx +0 -31
- package/src/evaluate/evaluate-events.ts +0 -131
- package/src/evaluate/evaluation-provider.ts +0 -6
- package/src/evaluate/evaluation-result.ts +0 -39
- package/src/evaluate/index.ts +0 -13
- 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
|
|
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 `
|
|
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
|
-
### `
|
|
455
|
+
### `experimental_decide`
|
|
456
456
|
|
|
457
457
|
<PropertiesTable
|
|
458
458
|
content={[
|
|
459
459
|
{
|
|
460
460
|
name: 'onStart',
|
|
461
|
-
type: '(event:
|
|
461
|
+
type: '(event: Experimental_DecideStartEvent) => void | Promise<void>',
|
|
462
462
|
description:
|
|
463
|
-
'Called when the
|
|
463
|
+
'Called when the decision operation begins, before the decision model is called.',
|
|
464
464
|
},
|
|
465
465
|
{
|
|
466
466
|
name: 'onEnd',
|
|
467
|
-
type: '(event:
|
|
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
|
-
###
|
|
1176
|
+
### Decision Events
|
|
1178
1177
|
|
|
1179
|
-
|
|
1180
|
-
`
|
|
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
|
|
1188
|
+
description: 'Unique identifier for this decision call.',
|
|
1190
1189
|
},
|
|
1191
1190
|
{
|
|
1192
1191
|
name: 'operationId',
|
|
1193
|
-
type: "'ai.
|
|
1194
|
-
description: '
|
|
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
|
|
1203
|
+
description: 'Provider identifier for the decision model.',
|
|
1205
1204
|
},
|
|
1206
1205
|
{
|
|
1207
1206
|
name: 'modelId',
|
|
1208
1207
|
type: 'string',
|
|
1209
|
-
description: '
|
|
1208
|
+
description: 'Decision model identifier.',
|
|
1210
1209
|
},
|
|
1211
1210
|
{
|
|
1212
1211
|
name: 'state',
|
|
1213
1212
|
type: 'string | object | array',
|
|
1214
|
-
description: 'Shared state
|
|
1213
|
+
description: 'Shared state used to make decisions.',
|
|
1215
1214
|
},
|
|
1216
1215
|
{
|
|
1217
1216
|
name: 'questions',
|
|
1218
|
-
type: 'Readonly<Record<string,
|
|
1219
|
-
description: 'Questions
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
10
|
-
|
|
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,
|
|
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
|
-
|
|
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: '
|
|
372
|
-
type: 'TOOL_SCHEMAS',
|
|
371
|
+
name: 'options',
|
|
372
|
+
type: '{ schemas?: TOOL_SCHEMAS }',
|
|
373
373
|
isOptional: true,
|
|
374
|
-
description:
|
|
375
|
-
|
|
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
|
|
9
|
-
|
|
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
|
|
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.
|
|
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
|
|
48
|
-
descriptions. They do not include schemas. No matches returns
|
|
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
|
|
302
|
+
## Experimental decision models
|
|
303
303
|
|
|
304
|
-
The inferred return type also exposes `
|
|
305
|
-
returning `
|
|
306
|
-
`
|
|
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
|
|
309
|
-
use the inferred return type or `
|
|
310
|
-
retain experimental
|
|
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
|
|
313
|
-
`modelType: '
|
|
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
|
|
315
|
+
added to the stable `ProviderV4` contract. Direct decision string IDs default
|
|
316
316
|
to Gateway when no default provider is configured.
|
|
317
|
-
See [
|
|
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
|
|
205
|
+
## Experimental decision models
|
|
206
206
|
|
|
207
|
-
Pass `
|
|
208
|
-
aliases for
|
|
209
|
-
`
|
|
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
|
-
|
|
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
|
|
216
|
-
`modelType: '
|
|
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
|
|
218
|
+
added to the stable `ProviderV4` contract. Direct decision string IDs default
|
|
219
219
|
to Gateway when no default provider is configured.
|
|
220
|
-
See [
|
|
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
|
|
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
|
|
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
|
-
'
|
|
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
|
|
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
|
|
62
|
-
- Removes the
|
|
63
|
-
-
|
|
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' |
|
|
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
|
},
|
|
@@ -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,
|
|
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: '
|
|
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',
|