ai 7.0.123 → 7.0.126
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 +26 -0
- package/dist/index.d.ts +232 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +415 -100
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +199 -8
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +9 -3
- package/dist/internal/index.js.map +1 -1
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +25 -0
- package/docs/03-ai-sdk-core/36-transcription.mdx +38 -1
- package/docs/03-ai-sdk-core/37-speech.mdx +23 -0
- package/docs/03-ai-sdk-core/60-telemetry.mdx +49 -1
- package/docs/07-reference/01-ai-sdk-core/11-stream-transcribe.mdx +7 -0
- package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +7 -0
- package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +7 -0
- package/docs/07-reference/01-ai-sdk-core/17-create-agent-ui-stream.mdx +7 -0
- package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +7 -0
- package/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx +7 -0
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +60 -3
- package/package.json +12 -12
- package/src/agent/create-agent-ui-stream-response.ts +16 -4
- package/src/agent/create-agent-ui-stream.ts +16 -2
- package/src/agent/pipe-agent-ui-stream-to-response.ts +16 -4
- package/src/generate-speech/generate-speech.ts +163 -38
- package/src/generate-speech/index.ts +4 -0
- package/src/generate-speech/speech-events.ts +91 -0
- package/src/telemetry/create-telemetry-dispatcher.ts +18 -5
- package/src/telemetry/telemetry.ts +38 -6
- package/src/telemetry/tracing-channel.ts +3 -0
- package/src/transcribe/index.ts +6 -0
- package/src/transcribe/stream-transcribe.ts +182 -31
- package/src/transcribe/transcribe.ts +186 -33
- package/src/transcribe/transcription-events.ts +111 -0
- package/src/ui/chat.ts +36 -5
|
@@ -178,6 +178,31 @@ transports by providing an `authProvider`.
|
|
|
178
178
|
|
|
179
179
|
</Note>
|
|
180
180
|
|
|
181
|
+
### Shared OAuth Credential Storage
|
|
182
|
+
|
|
183
|
+
When multiple MCP clients or replicas share OAuth credentials, a rotating refresh
|
|
184
|
+
token can be used concurrently. One refresh may save new tokens while another
|
|
185
|
+
receives `invalid_grant` for the old refresh token.
|
|
186
|
+
|
|
187
|
+
The optional `OAuthClientProvider.invalidateCredentials` method receives a
|
|
188
|
+
second argument identifying the tokens used by a failed refresh:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
invalidateCredentials(
|
|
192
|
+
scope: 'all' | 'client' | 'tokens' | 'verifier',
|
|
193
|
+
context?: { tokens: OAuthTokens },
|
|
194
|
+
): void | Promise<void>;
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
For `scope === 'tokens'` with a context, delete the credential only if the stored
|
|
198
|
+
access and refresh tokens still match `context.tokens`. The comparison and
|
|
199
|
+
deletion must be atomic, using a conditional database operation or a transaction.
|
|
200
|
+
If they no longer match, leave the newer tokens in storage. The SDK retries
|
|
201
|
+
authorization and reads the stored tokens again.
|
|
202
|
+
|
|
203
|
+
The SDK also provides this context when invalidating stored tokens that lack an
|
|
204
|
+
authorization server pin. Other invalidations can omit the context.
|
|
205
|
+
|
|
181
206
|
### OAuth Authorization Server Validation
|
|
182
207
|
|
|
183
208
|
When using MCP OAuth in server-side applications, the MCP server can advertise
|
|
@@ -30,6 +30,42 @@ const language = transcript.language; // language of the transcript e.g. "en", i
|
|
|
30
30
|
const durationInSeconds = transcript.durationInSeconds; // duration of the transcript in seconds, if available
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
## Telemetry
|
|
34
|
+
|
|
35
|
+
`transcribe` and `experimental_streamTranscribe` accept the standard
|
|
36
|
+
`telemetry` option. Registered integrations receive start, end, and error
|
|
37
|
+
events with the provider and model, audio byte length and media type, final
|
|
38
|
+
transcript, warnings, response metadata, provider metadata, and usage when the
|
|
39
|
+
provider reports it. Because streaming transcription is experimental, custom
|
|
40
|
+
integrations receive its lifecycle through
|
|
41
|
+
`experimental_onStreamTranscriptionStart` and
|
|
42
|
+
`experimental_onStreamTranscriptionEnd`; errors continue to use `onError`.
|
|
43
|
+
Integrations that wrap or delegate to another telemetry integration must
|
|
44
|
+
forward these experimental callbacks explicitly for streaming transcription
|
|
45
|
+
to be observed.
|
|
46
|
+
|
|
47
|
+
```ts highlight="5-7"
|
|
48
|
+
const transcript = await transcribe({
|
|
49
|
+
model: openai.transcription('gpt-4o-transcribe'),
|
|
50
|
+
audio: await readFile('audio.mp3'),
|
|
51
|
+
telemetry: {
|
|
52
|
+
functionId: 'transcribe-customer-call',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Raw audio is not included in telemetry events. For streaming transcription,
|
|
58
|
+
the final byte length is emitted only after the input stream is consumed and
|
|
59
|
+
the transcription finishes. Use `recordInputs: false` or
|
|
60
|
+
`recordOutputs: false` to prevent integrations from recording sensitive input
|
|
61
|
+
or output fields.
|
|
62
|
+
|
|
63
|
+
For URL audio, the downloaded media type is passed to the provider and reported
|
|
64
|
+
on successful telemetry events. If downloading or decoding input audio fails,
|
|
65
|
+
the start event is still emitted before the correlated error event, but its
|
|
66
|
+
audio byte length and media type can be undefined because preparation did not
|
|
67
|
+
complete.
|
|
68
|
+
|
|
33
69
|
## Streaming Transcription
|
|
34
70
|
|
|
35
71
|
<Note type="warning">Streaming transcription is an experimental feature.</Note>
|
|
@@ -307,7 +343,8 @@ try {
|
|
|
307
343
|
| [Groq](/providers/ai-sdk-providers/groq#transcription-models) | `whisper-large-v3` |
|
|
308
344
|
| [Mistral](/providers/ai-sdk-providers/mistral#transcription-models) | `voxtral-mini-latest` |
|
|
309
345
|
| [Azure OpenAI](/providers/ai-sdk-providers/azure#transcription-models) | `whisper-1` |
|
|
310
|
-
| [Azure Speech](/providers/ai-sdk-providers/azure#mai-transcribe
|
|
346
|
+
| [Azure Speech](/providers/ai-sdk-providers/azure#mai-transcribe) | `mai-transcribe-2` |
|
|
347
|
+
| [Azure Speech](/providers/ai-sdk-providers/azure#mai-transcribe) | `mai-transcribe-1.5` |
|
|
311
348
|
| [Azure OpenAI](/providers/ai-sdk-providers/azure#transcription-models) | `gpt-4o-transcribe` |
|
|
312
349
|
| [Azure OpenAI](/providers/ai-sdk-providers/azure#transcription-models) | `gpt-4o-mini-transcribe` |
|
|
313
350
|
| [Rev.ai](/providers/ai-sdk-providers/revai#transcription-models) | `machine` |
|
|
@@ -19,6 +19,27 @@ const result = await generateSpeech({
|
|
|
19
19
|
});
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## Telemetry
|
|
23
|
+
|
|
24
|
+
`generateSpeech` accepts the standard `telemetry` option. Registered
|
|
25
|
+
integrations receive start, end, and error events with the provider and model,
|
|
26
|
+
source text, generated audio byte length, media type and format, warnings,
|
|
27
|
+
response metadata, provider metadata, and usage when the provider reports it.
|
|
28
|
+
Raw generated audio is not included in telemetry events.
|
|
29
|
+
|
|
30
|
+
```ts highlight="5-7"
|
|
31
|
+
const result = await generateSpeech({
|
|
32
|
+
model: openai.speech('gpt-4o-mini-tts'),
|
|
33
|
+
text: 'Hello from the AI SDK!',
|
|
34
|
+
telemetry: {
|
|
35
|
+
functionId: 'speak-greeting',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Use `recordInputs: false` or `recordOutputs: false` when the text or output
|
|
41
|
+
metadata should not be recorded by telemetry integrations.
|
|
42
|
+
|
|
22
43
|
To access the generated audio:
|
|
23
44
|
|
|
24
45
|
```ts
|
|
@@ -137,6 +158,8 @@ try {
|
|
|
137
158
|
| [OpenAI](/providers/ai-sdk-providers/openai#speech-models) | `tts-1-hd` |
|
|
138
159
|
| [OpenAI](/providers/ai-sdk-providers/openai#speech-models) | `gpt-4o-mini-tts` |
|
|
139
160
|
| [Mistral](/providers/ai-sdk-providers/mistral#speech-models) | `voxtral-mini-tts-2603` |
|
|
161
|
+
| [Azure Speech](/providers/ai-sdk-providers/azure#mai-voice) | `mai-voice-2-flash` |
|
|
162
|
+
| [Azure Speech](/providers/ai-sdk-providers/azure#mai-voice) | `mai-voice-2` |
|
|
140
163
|
| [ElevenLabs](/providers/ai-sdk-providers/elevenlabs#speech-models) | `eleven_v3` |
|
|
141
164
|
| [ElevenLabs](/providers/ai-sdk-providers/elevenlabs#speech-models) | `eleven_multilingual_v2` |
|
|
142
165
|
| [ElevenLabs](/providers/ai-sdk-providers/elevenlabs#speech-models) | `eleven_flash_v2_5` |
|
|
@@ -53,7 +53,10 @@ For Node.js applications (without Next.js), register the integration at the top
|
|
|
53
53
|
|
|
54
54
|
### Step 2: Enabling Telemetry
|
|
55
55
|
|
|
56
|
-
Once a telemetry integration is registered,
|
|
56
|
+
Once a telemetry integration is registered, supported AI SDK calls emit
|
|
57
|
+
telemetry events by default. This includes text and object generation,
|
|
58
|
+
embeddings, reranking, speech generation, and both non-streaming and streaming
|
|
59
|
+
transcription.
|
|
57
60
|
You can still pass `telemetry` to attach metadata (like `functionId`) or to opt out of a specific call:
|
|
58
61
|
|
|
59
62
|
```ts highlight="4-6"
|
|
@@ -71,6 +74,34 @@ By default, both inputs and outputs are recorded. You can disable them by settin
|
|
|
71
74
|
Disabling the recording of inputs and outputs can be useful for privacy, data transfer, and performance reasons.
|
|
72
75
|
You might for example want to disable recording inputs if they contain sensitive information.
|
|
73
76
|
|
|
77
|
+
For `generateSpeech`, input telemetry contains the source text and output
|
|
78
|
+
telemetry contains the generated audio byte length, media type, and format.
|
|
79
|
+
For `transcribe` and `experimental_streamTranscribe`, telemetry contains the
|
|
80
|
+
input audio byte length and media type plus the output transcript. Raw audio is
|
|
81
|
+
never included in telemetry events. Streaming transcription reports its final
|
|
82
|
+
byte length when the audio stream has been consumed and the transcription
|
|
83
|
+
finishes.
|
|
84
|
+
|
|
85
|
+
Custom integrations receive stable `generateSpeech` and `transcribe`
|
|
86
|
+
operations through `onStart` and `onEnd`. To keep the experimental API isolated,
|
|
87
|
+
`experimental_streamTranscribe` uses
|
|
88
|
+
`experimental_onStreamTranscriptionStart` and
|
|
89
|
+
`experimental_onStreamTranscriptionEnd`; all three operations report failures
|
|
90
|
+
through `onError`.
|
|
91
|
+
|
|
92
|
+
An integration that wraps or delegates to another integration must explicitly
|
|
93
|
+
forward the experimental streaming transcription callbacks. Forwarding only
|
|
94
|
+
the stable `onStart` and `onEnd` callbacks does not observe
|
|
95
|
+
`experimental_streamTranscribe`.
|
|
96
|
+
|
|
97
|
+
The built-in OpenTelemetry integrations record numeric provider usage by
|
|
98
|
+
default, preserving each reported unit. The modern integration uses attributes
|
|
99
|
+
such as `gen_ai.usage.characters`, `gen_ai.usage.seconds`, and
|
|
100
|
+
`gen_ai.usage.input_tokens`; `LegacyOpenTelemetry` uses the corresponding
|
|
101
|
+
`ai.usage.*` attributes. The provider-native usage object remains available to
|
|
102
|
+
callbacks, and can also be included as the supplemental `ai.response.usage`
|
|
103
|
+
attribute by enabling `usage: true`.
|
|
104
|
+
|
|
74
105
|
### Opting out
|
|
75
106
|
|
|
76
107
|
Telemetry is opt-out. To disable telemetry for a specific call, set `isEnabled: false`:
|
|
@@ -550,6 +581,23 @@ For `rerank`, the integration records spans with `CLIENT` kind:
|
|
|
550
581
|
- `gen_ai.provider.name`: the provider
|
|
551
582
|
- `gen_ai.request.model`: the model ID
|
|
552
583
|
|
|
584
|
+
#### generateSpeech / transcribe / experimental_streamTranscribe
|
|
585
|
+
|
|
586
|
+
Each call records a single `CLIENT` span named `{operationId} {modelId}`, where
|
|
587
|
+
`operationId` is `ai.generateSpeech`, `ai.transcribe`, or `ai.streamTranscribe`.
|
|
588
|
+
|
|
589
|
+
- `gen_ai.output.type`: `"speech"` for speech generation and `"text"` for transcription.
|
|
590
|
+
- `gen_ai.request.stream`: `true` for streaming transcription and `false` otherwise.
|
|
591
|
+
- `gen_ai.input.messages`: speech generation input text as a user message with a text part, when `recordInputs` is enabled.
|
|
592
|
+
- `gen_ai.output.messages`: the completed transcript as an assistant message with a text part, when `recordOutputs` is enabled. Streaming transcription records this once on completion.
|
|
593
|
+
|
|
594
|
+
The existing `ai.request.text` and `ai.response.text` attributes are also retained.
|
|
595
|
+
Audio byte length, media type, and output format remain in the
|
|
596
|
+
`ai.request.audio.*` and `ai.response.audio.*` attributes, subject to the
|
|
597
|
+
corresponding input/output recording controls. Raw audio is not captured, so
|
|
598
|
+
transcription input and speech output do not populate message attributes with
|
|
599
|
+
audio content or placeholder audio parts.
|
|
600
|
+
|
|
553
601
|
#### experimental_evaluate
|
|
554
602
|
|
|
555
603
|
For `experimental_evaluate`, the integration records two spans with `CLIENT`
|
|
@@ -88,6 +88,13 @@ console.log(await result.text);
|
|
|
88
88
|
description:
|
|
89
89
|
'When true, the provider includes raw provider chunks in the stream as `raw` parts.',
|
|
90
90
|
},
|
|
91
|
+
{
|
|
92
|
+
name: 'telemetry',
|
|
93
|
+
type: 'TelemetryOptions',
|
|
94
|
+
isOptional: true,
|
|
95
|
+
description:
|
|
96
|
+
'Telemetry configuration. Experimental lifecycle callbacks use experimental_onStreamTranscriptionStart and experimental_onStreamTranscriptionEnd. The end event is emitted after the audio stream is consumed and includes the final input byte length.',
|
|
97
|
+
},
|
|
91
98
|
]}
|
|
92
99
|
/>
|
|
93
100
|
|
|
@@ -64,6 +64,13 @@ console.log(transcript);
|
|
|
64
64
|
isOptional: true,
|
|
65
65
|
description: 'Additional HTTP headers for the request.',
|
|
66
66
|
},
|
|
67
|
+
{
|
|
68
|
+
name: 'telemetry',
|
|
69
|
+
type: 'TelemetryOptions',
|
|
70
|
+
isOptional: true,
|
|
71
|
+
description:
|
|
72
|
+
'Telemetry configuration. Supports functionId, recordInputs, recordOutputs, isEnabled, and per-call integrations.',
|
|
73
|
+
},
|
|
67
74
|
{
|
|
68
75
|
name: 'download',
|
|
69
76
|
type: '(options: { url: URL; abortSignal?: AbortSignal }) => Promise<{ data: Uint8Array; mediaType: string | undefined }>',
|
|
@@ -124,6 +124,13 @@ const { audio } = await generateSpeech({
|
|
|
124
124
|
isOptional: true,
|
|
125
125
|
description: 'Additional HTTP headers for the request.',
|
|
126
126
|
},
|
|
127
|
+
{
|
|
128
|
+
name: 'telemetry',
|
|
129
|
+
type: 'TelemetryOptions',
|
|
130
|
+
isOptional: true,
|
|
131
|
+
description:
|
|
132
|
+
'Telemetry configuration. Supports functionId, recordInputs, recordOutputs, isEnabled, and per-call integrations.',
|
|
133
|
+
},
|
|
127
134
|
]}
|
|
128
135
|
/>
|
|
129
136
|
|
|
@@ -59,6 +59,13 @@ export async function* streamAgent(
|
|
|
59
59
|
description:
|
|
60
60
|
'Array of input UI message objects (e.g., user/assistant/chat history). These will be validated and converted for the agent.',
|
|
61
61
|
},
|
|
62
|
+
{
|
|
63
|
+
name: 'convertDataPart',
|
|
64
|
+
type: '(part: DataUIPart) => TextPart | FilePart | undefined',
|
|
65
|
+
isRequired: false,
|
|
66
|
+
description:
|
|
67
|
+
'Converts custom UI data parts into text or file parts for the model. Data parts are ignored when this callback is omitted or returns undefined.',
|
|
68
|
+
},
|
|
62
69
|
{
|
|
63
70
|
name: 'abortSignal',
|
|
64
71
|
type: 'AbortSignal',
|
|
@@ -57,6 +57,13 @@ export async function POST(request: Request) {
|
|
|
57
57
|
description:
|
|
58
58
|
'Array of input UI messages provided to the agent (e.g., user and assistant messages).',
|
|
59
59
|
},
|
|
60
|
+
{
|
|
61
|
+
name: 'convertDataPart',
|
|
62
|
+
type: '(part: DataUIPart) => TextPart | FilePart | undefined',
|
|
63
|
+
isRequired: false,
|
|
64
|
+
description:
|
|
65
|
+
'Converts custom UI data parts into text or file parts for the model. Data parts are ignored when this callback is omitted or returns undefined.',
|
|
66
|
+
},
|
|
60
67
|
{
|
|
61
68
|
name: 'abortSignal',
|
|
62
69
|
type: 'AbortSignal',
|
|
@@ -61,6 +61,13 @@ export async function handler(req, res) {
|
|
|
61
61
|
description:
|
|
62
62
|
'Array of input UI messages sent to the agent (such as user/assistant message objects).',
|
|
63
63
|
},
|
|
64
|
+
{
|
|
65
|
+
name: 'convertDataPart',
|
|
66
|
+
type: '(part: DataUIPart) => TextPart | FilePart | undefined',
|
|
67
|
+
isRequired: false,
|
|
68
|
+
description:
|
|
69
|
+
'Converts custom UI data parts into text or file parts for the model. Data parts are ignored when this callback is omitted or returns undefined.',
|
|
70
|
+
},
|
|
64
71
|
{
|
|
65
72
|
name: 'abortSignal',
|
|
66
73
|
type: 'AbortSignal',
|
|
@@ -120,7 +120,7 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
|
|
|
120
120
|
type: 'ToolCallRepairFunction',
|
|
121
121
|
isOptional: true,
|
|
122
122
|
description:
|
|
123
|
-
|
|
123
|
+
"Default function to repair tool calls that fail to parse. Mark the function with 'use step' when used in a workflow. Per-stream values override this default.",
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
126
|
name: 'experimental_download',
|
|
@@ -573,13 +573,13 @@ const result = await agent.stream({
|
|
|
573
573
|
name: 'repairToolCall',
|
|
574
574
|
type: 'ToolCallRepairFunction',
|
|
575
575
|
isOptional: true,
|
|
576
|
-
description:
|
|
576
|
+
description: "Callback to attempt automatic recovery when a tool call cannot be parsed. Mark the function with 'use step' when used in a workflow.",
|
|
577
577
|
},
|
|
578
578
|
{
|
|
579
579
|
name: 'experimental_transform',
|
|
580
580
|
type: 'StreamTextTransform | Array<StreamTextTransform>',
|
|
581
581
|
isOptional: true,
|
|
582
|
-
description:
|
|
582
|
+
description: "Factories for stream transformations, applied in order to raw provider events before model processing and writable output. Each factory must return a TransformStream synchronously and maintain the stream structure. Mark each factory with 'use step' when used in a workflow.",
|
|
583
583
|
},
|
|
584
584
|
{
|
|
585
585
|
name: 'experimental_download',
|
|
@@ -750,6 +750,63 @@ Returns a `Promise<WorkflowAgentStreamResult>` with the following properties:
|
|
|
750
750
|
]}
|
|
751
751
|
/>
|
|
752
752
|
|
|
753
|
+
### `repairToolCall` in a workflow
|
|
754
|
+
|
|
755
|
+
`repairToolCall` runs inside the model step. When you use it in a workflow,
|
|
756
|
+
define the callback as a function with a `'use step'` directive. You can set
|
|
757
|
+
it on the constructor or pass it to `stream()`.
|
|
758
|
+
|
|
759
|
+
Workflow saves a reference to the registered function and loads its
|
|
760
|
+
implementation inside the model step. Keep any values captured by the
|
|
761
|
+
function serializable. An ordinary inline callback causes a serialization
|
|
762
|
+
error when it crosses this step boundary.
|
|
763
|
+
|
|
764
|
+
The callback can be asynchronous. Return the repaired tool call, or `null`
|
|
765
|
+
if the repair cannot be completed. See [tool call repair](/docs/ai-sdk-core/tools-and-tool-calling#tool-call-repair)
|
|
766
|
+
for repair strategies.
|
|
767
|
+
|
|
768
|
+
### `experimental_transform` in a workflow
|
|
769
|
+
|
|
770
|
+
Pass a transform factory, or an array of factories, to `stream()`.
|
|
771
|
+
Mark each factory with `'use step'` so Workflow can load it inside the model
|
|
772
|
+
step. The factory must return a `TransformStream` synchronously. Keep any
|
|
773
|
+
captured values serializable.
|
|
774
|
+
|
|
775
|
+
```ts
|
|
776
|
+
import type { LanguageModelV4StreamPart } from '@ai-sdk/provider';
|
|
777
|
+
import { WorkflowAgent } from '@ai-sdk/workflow';
|
|
778
|
+
import { getWritable } from 'workflow';
|
|
779
|
+
|
|
780
|
+
function uppercaseText() {
|
|
781
|
+
'use step';
|
|
782
|
+
|
|
783
|
+
return new TransformStream<
|
|
784
|
+
LanguageModelV4StreamPart,
|
|
785
|
+
LanguageModelV4StreamPart
|
|
786
|
+
>({
|
|
787
|
+
transform(part, controller) {
|
|
788
|
+
controller.enqueue(
|
|
789
|
+
part.type === 'text-delta'
|
|
790
|
+
? { ...part, delta: part.delta.toUpperCase() }
|
|
791
|
+
: part,
|
|
792
|
+
);
|
|
793
|
+
},
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
export async function uppercaseWorkflow() {
|
|
798
|
+
'use workflow';
|
|
799
|
+
|
|
800
|
+
const agent = new WorkflowAgent({ model: 'openai/gpt-5' });
|
|
801
|
+
|
|
802
|
+
return agent.stream({
|
|
803
|
+
messages: [{ role: 'user', content: 'Write a short greeting.' }],
|
|
804
|
+
writable: getWritable(),
|
|
805
|
+
experimental_transform: uppercaseText,
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
```
|
|
809
|
+
|
|
753
810
|
## Utilities
|
|
754
811
|
|
|
755
812
|
### `createModelCallToUIChunkTransform(options?)`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.126",
|
|
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.
|
|
46
|
-
"@ai-sdk/provider": "4.0.
|
|
47
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.102",
|
|
46
|
+
"@ai-sdk/provider": "4.0.21",
|
|
47
|
+
"@ai-sdk/provider-utils": "5.0.53"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@ai-sdk/amazon-bedrock": "5.0.
|
|
51
|
-
"@ai-sdk/deepseek": "3.0.
|
|
52
|
-
"@ai-sdk/google": "4.0.
|
|
53
|
-
"@ai-sdk/groq": "4.0.
|
|
54
|
-
"@ai-sdk/huggingface": "2.0.
|
|
55
|
-
"@ai-sdk/moonshotai": "3.0.
|
|
56
|
-
"@ai-sdk/openai": "4.0.
|
|
50
|
+
"@ai-sdk/amazon-bedrock": "5.0.104",
|
|
51
|
+
"@ai-sdk/deepseek": "3.0.58",
|
|
52
|
+
"@ai-sdk/google": "4.0.87",
|
|
53
|
+
"@ai-sdk/groq": "4.0.54",
|
|
54
|
+
"@ai-sdk/huggingface": "2.0.62",
|
|
55
|
+
"@ai-sdk/moonshotai": "3.0.62",
|
|
56
|
+
"@ai-sdk/openai": "4.0.83",
|
|
57
57
|
"@ai-sdk/test-server": "2.0.3",
|
|
58
|
-
"@ai-sdk/xai": "5.0.
|
|
58
|
+
"@ai-sdk/xai": "5.0.14",
|
|
59
59
|
"@edge-runtime/vm": "^5.0.0",
|
|
60
60
|
"@smithy/eventstream-codec": "^4.3.3",
|
|
61
61
|
"@smithy/util-utf8": "^4.3.3",
|
|
@@ -14,8 +14,9 @@ import type { UIMessageStreamOptions } from '../generate-text/stream-text-result
|
|
|
14
14
|
import type { TimeoutConfiguration } from '../prompt/request-options';
|
|
15
15
|
import { createUIMessageStreamResponse } from '../ui-message-stream';
|
|
16
16
|
import type { UIMessageStreamResponseInit } from '../ui-message-stream/ui-message-stream-response-init';
|
|
17
|
-
import type { InferUITools, UIMessage } from '../ui/ui-messages';
|
|
17
|
+
import type { InferUITools, UIMessage, UIDataTypes } from '../ui/ui-messages';
|
|
18
18
|
import type { Agent } from './agent';
|
|
19
|
+
import type { convertToModelMessages } from '../ui/convert-to-model-messages';
|
|
19
20
|
import { createAgentUIStream } from './create-agent-ui-stream';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -23,6 +24,7 @@ import { createAgentUIStream } from './create-agent-ui-stream';
|
|
|
23
24
|
*
|
|
24
25
|
* @param agent - The agent to run.
|
|
25
26
|
* @param uiMessages - The input UI messages.
|
|
27
|
+
* @param convertDataPart - Optional function to convert custom data parts to text or file model message parts.
|
|
26
28
|
* @param abortSignal - Abort signal. Optional.
|
|
27
29
|
* @param timeout - Timeout in milliseconds. Optional.
|
|
28
30
|
* @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
|
|
@@ -44,6 +46,11 @@ export async function createAgentUIStreamResponse<
|
|
|
44
46
|
RUNTIME_CONTEXT extends Context = Context,
|
|
45
47
|
OUTPUT extends Output = never,
|
|
46
48
|
MESSAGE_METADATA = unknown,
|
|
49
|
+
UI_MESSAGE extends UIMessage<
|
|
50
|
+
MESSAGE_METADATA,
|
|
51
|
+
UIDataTypes,
|
|
52
|
+
InferUITools<TOOLS>
|
|
53
|
+
> = UIMessage<MESSAGE_METADATA, UIDataTypes, InferUITools<TOOLS>>,
|
|
47
54
|
>({
|
|
48
55
|
headers,
|
|
49
56
|
status,
|
|
@@ -54,6 +61,13 @@ export async function createAgentUIStreamResponse<
|
|
|
54
61
|
}: {
|
|
55
62
|
agent: Agent<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
56
63
|
uiMessages: unknown[];
|
|
64
|
+
/**
|
|
65
|
+
* Converts custom UI data parts to text or file model message parts.
|
|
66
|
+
* Data parts are ignored when omitted or when the callback returns undefined.
|
|
67
|
+
*/
|
|
68
|
+
convertDataPart?: NonNullable<
|
|
69
|
+
Parameters<typeof convertToModelMessages<UI_MESSAGE>>[1]
|
|
70
|
+
>['convertDataPart'];
|
|
57
71
|
abortSignal?: AbortSignal;
|
|
58
72
|
timeout?: TimeoutConfiguration<TOOLS>;
|
|
59
73
|
experimental_sandbox?: SandboxSession;
|
|
@@ -63,9 +77,7 @@ export async function createAgentUIStreamResponse<
|
|
|
63
77
|
/** @deprecated Use `onStepEnd` instead. */
|
|
64
78
|
onStepFinish?: GenerateTextOnStepFinishCallback<TOOLS>;
|
|
65
79
|
} & UIMessageStreamResponseInit &
|
|
66
|
-
UIMessageStreamOptions<
|
|
67
|
-
UIMessage<MESSAGE_METADATA, never, InferUITools<TOOLS>>
|
|
68
|
-
>): Promise<Response> {
|
|
80
|
+
UIMessageStreamOptions<UI_MESSAGE>): Promise<Response> {
|
|
69
81
|
return createUIMessageStreamResponse({
|
|
70
82
|
headers,
|
|
71
83
|
status,
|
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
InferUIMessageTools,
|
|
21
21
|
InferUITools,
|
|
22
22
|
UIMessage,
|
|
23
|
+
UIDataTypes,
|
|
23
24
|
} from '../ui/ui-messages';
|
|
24
25
|
import { validateUIMessagesForAgent } from '../ui/validate-ui-messages';
|
|
25
26
|
import {
|
|
@@ -33,6 +34,7 @@ import type { Agent } from './agent';
|
|
|
33
34
|
*
|
|
34
35
|
* @param agent - The agent to run.
|
|
35
36
|
* @param uiMessages - The input UI messages.
|
|
37
|
+
* @param convertDataPart - Optional function to convert custom data parts to text or file model message parts.
|
|
36
38
|
* @param abortSignal - The abort signal. Optional.
|
|
37
39
|
* @param timeout - Timeout in milliseconds. Optional.
|
|
38
40
|
* @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
|
|
@@ -49,11 +51,15 @@ export async function createAgentUIStream<
|
|
|
49
51
|
RUNTIME_CONTEXT extends Context = Context,
|
|
50
52
|
OUTPUT extends Output = never,
|
|
51
53
|
MESSAGE_METADATA = unknown,
|
|
52
|
-
UI_MESSAGE extends UIMessage<
|
|
53
|
-
|
|
54
|
+
UI_MESSAGE extends UIMessage<
|
|
55
|
+
MESSAGE_METADATA,
|
|
56
|
+
UIDataTypes,
|
|
57
|
+
InferUITools<TOOLS>
|
|
58
|
+
> = UIMessage<MESSAGE_METADATA, UIDataTypes, InferUITools<TOOLS>>,
|
|
54
59
|
>({
|
|
55
60
|
agent,
|
|
56
61
|
uiMessages,
|
|
62
|
+
convertDataPart,
|
|
57
63
|
options,
|
|
58
64
|
abortSignal,
|
|
59
65
|
timeout,
|
|
@@ -65,6 +71,13 @@ export async function createAgentUIStream<
|
|
|
65
71
|
}: {
|
|
66
72
|
agent: Agent<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
67
73
|
uiMessages: unknown[];
|
|
74
|
+
/**
|
|
75
|
+
* Converts custom UI data parts to text or file model message parts.
|
|
76
|
+
* Data parts are ignored when omitted or when the callback returns undefined.
|
|
77
|
+
*/
|
|
78
|
+
convertDataPart?: NonNullable<
|
|
79
|
+
Parameters<typeof convertToModelMessages<UI_MESSAGE>>[1]
|
|
80
|
+
>['convertDataPart'];
|
|
68
81
|
abortSignal?: AbortSignal;
|
|
69
82
|
timeout?: TimeoutConfiguration<TOOLS>;
|
|
70
83
|
experimental_sandbox?: SandboxSession;
|
|
@@ -91,6 +104,7 @@ export async function createAgentUIStream<
|
|
|
91
104
|
|
|
92
105
|
const modelMessages = await convertToModelMessages(validatedMessages, {
|
|
93
106
|
tools: agent.tools,
|
|
107
|
+
convertDataPart,
|
|
94
108
|
});
|
|
95
109
|
|
|
96
110
|
const result = await agent.stream({
|
|
@@ -15,8 +15,9 @@ import type { UIMessageStreamOptions } from '../generate-text/stream-text-result
|
|
|
15
15
|
import type { TimeoutConfiguration } from '../prompt/request-options';
|
|
16
16
|
import { pipeUIMessageStreamToResponse } from '../ui-message-stream';
|
|
17
17
|
import type { UIMessageStreamResponseInit } from '../ui-message-stream/ui-message-stream-response-init';
|
|
18
|
-
import type { InferUITools, UIMessage } from '../ui/ui-messages';
|
|
18
|
+
import type { InferUITools, UIMessage, UIDataTypes } from '../ui/ui-messages';
|
|
19
19
|
import type { Agent } from './agent';
|
|
20
|
+
import type { convertToModelMessages } from '../ui/convert-to-model-messages';
|
|
20
21
|
import { createAgentUIStream } from './create-agent-ui-stream';
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -25,6 +26,7 @@ import { createAgentUIStream } from './create-agent-ui-stream';
|
|
|
25
26
|
* @param response - The Node.js ServerResponse object to pipe to.
|
|
26
27
|
* @param agent - The agent to run.
|
|
27
28
|
* @param uiMessages - The input UI messages.
|
|
29
|
+
* @param convertDataPart - Optional function to convert custom data parts to text or file model message parts.
|
|
28
30
|
* @param abortSignal - Abort signal. Optional.
|
|
29
31
|
* @param timeout - Timeout in milliseconds. Optional.
|
|
30
32
|
* @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
|
|
@@ -44,6 +46,11 @@ export async function pipeAgentUIStreamToResponse<
|
|
|
44
46
|
RUNTIME_CONTEXT extends Context = Context,
|
|
45
47
|
OUTPUT extends Output = never,
|
|
46
48
|
MESSAGE_METADATA = unknown,
|
|
49
|
+
UI_MESSAGE extends UIMessage<
|
|
50
|
+
MESSAGE_METADATA,
|
|
51
|
+
UIDataTypes,
|
|
52
|
+
InferUITools<TOOLS>
|
|
53
|
+
> = UIMessage<MESSAGE_METADATA, UIDataTypes, InferUITools<TOOLS>>,
|
|
47
54
|
>({
|
|
48
55
|
response,
|
|
49
56
|
headers,
|
|
@@ -56,6 +63,13 @@ export async function pipeAgentUIStreamToResponse<
|
|
|
56
63
|
response: ServerResponse;
|
|
57
64
|
agent: Agent<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
58
65
|
uiMessages: unknown[];
|
|
66
|
+
/**
|
|
67
|
+
* Converts custom UI data parts to text or file model message parts.
|
|
68
|
+
* Data parts are ignored when omitted or when the callback returns undefined.
|
|
69
|
+
*/
|
|
70
|
+
convertDataPart?: NonNullable<
|
|
71
|
+
Parameters<typeof convertToModelMessages<UI_MESSAGE>>[1]
|
|
72
|
+
>['convertDataPart'];
|
|
59
73
|
abortSignal?: AbortSignal;
|
|
60
74
|
timeout?: TimeoutConfiguration<TOOLS>;
|
|
61
75
|
experimental_sandbox?: SandboxSession;
|
|
@@ -65,9 +79,7 @@ export async function pipeAgentUIStreamToResponse<
|
|
|
65
79
|
/** @deprecated Use `onStepEnd` instead. */
|
|
66
80
|
onStepFinish?: GenerateTextOnStepFinishCallback<TOOLS>;
|
|
67
81
|
} & UIMessageStreamResponseInit &
|
|
68
|
-
UIMessageStreamOptions<
|
|
69
|
-
UIMessage<MESSAGE_METADATA, never, InferUITools<TOOLS>>
|
|
70
|
-
>): Promise<void> {
|
|
82
|
+
UIMessageStreamOptions<UI_MESSAGE>): Promise<void> {
|
|
71
83
|
return pipeUIMessageStreamToResponse({
|
|
72
84
|
response,
|
|
73
85
|
headers,
|