ai 7.0.122 → 7.0.124
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 +7598 -7268
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19555 -22545
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2235 -2004
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +3261 -3921
- package/dist/internal/index.js.map +1 -1
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/test/index.d.ts +294 -273
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +325 -469
- package/dist/test/index.js.map +1 -1
- package/docs/02-foundations/03-prompts.mdx +3 -1
- package/docs/02-foundations/06-provider-options.mdx +1 -1
- package/docs/02-getting-started/06-nodejs.mdx +4 -4
- package/docs/02-getting-started/08-tanstack-start.mdx +1 -1
- package/docs/03-agents/05-configuring-call-options.mdx +1 -1
- package/docs/03-ai-sdk-core/10-generating-structured-data.mdx +1 -1
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +3 -0
- package/docs/03-ai-sdk-core/17-mcp-apps.mdx +5 -5
- package/docs/03-ai-sdk-core/36-transcription.mdx +36 -0
- package/docs/03-ai-sdk-core/37-speech.mdx +22 -1
- package/docs/03-ai-sdk-core/42-batch.mdx +1 -1
- package/docs/03-ai-sdk-core/60-telemetry.mdx +51 -3
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +24 -0
- package/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx +12 -12
- package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +9 -7
- package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +2 -2
- package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +7 -9
- package/docs/04-ai-sdk-ui/05-completion.mdx +1 -1
- package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +2 -2
- package/docs/05-ai-sdk-rsc/03-generative-ui-state.mdx +8 -7
- package/docs/05-ai-sdk-rsc/06-loading-state.mdx +19 -10
- package/docs/05-ai-sdk-rsc/08-error-handling.mdx +2 -0
- package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +4 -3
- package/docs/06-advanced/02-stopping-streams.mdx +2 -2
- package/docs/06-advanced/04-caching.mdx +9 -5
- package/docs/06-advanced/05-multiple-streamables.mdx +1 -1
- package/docs/06-advanced/07-rendering-ui-with-language-models.mdx +16 -16
- package/docs/06-advanced/09-multistep-interfaces.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +4 -4
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +4 -4
- 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/14-upload-file.mdx +4 -4
- package/docs/07-reference/01-ai-sdk-core/14-upload-skill.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/15-agent.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +1 -4
- package/docs/07-reference/01-ai-sdk-core/22-dynamic-tool.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/30-model-message.mdx +2 -2
- package/docs/07-reference/01-ai-sdk-core/69-add-tool-input-examples-middleware.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx +1 -1
- package/docs/07-reference/02-ai-sdk-ui/31-convert-to-model-messages.mdx +5 -4
- package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +3 -2
- package/docs/07-reference/02-ai-sdk-ui/41-create-ui-message-stream-response.mdx +7 -0
- package/docs/07-reference/02-ai-sdk-ui/42-pipe-ui-message-stream-to-response.mdx +7 -0
- package/docs/07-reference/02-ai-sdk-ui/50-direct-chat-transport.mdx +2 -2
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +2 -2
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +1 -1
- package/docs/08-migration-guides/25-migration-guide-5-0-data.mdx +4 -5
- package/docs/08-migration-guides/26-migration-guide-5-0.mdx +2 -1
- package/docs/08-migration-guides/29-migration-guide-4-0.mdx +4 -4
- package/docs/08-migration-guides/38-migration-guide-3-2.mdx +1 -1
- package/docs/08-migration-guides/39-migration-guide-3-1.mdx +1 -1
- package/docs/09-troubleshooting/12-use-chat-an-error-occurred.mdx +8 -6
- package/docs/09-troubleshooting/50-react-maximum-update-depth-exceeded.mdx +6 -6
- package/docs/09-troubleshooting/70-high-memory-usage-with-images.mdx +1 -1
- package/package.json +17 -17
- package/src/agent/create-agent-ui-stream-response.ts +3 -0
- package/src/agent/pipe-agent-ui-stream-to-response.ts +3 -0
- 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/generate-text/prune-messages.ts +1 -1
- package/src/middleware/extract-reasoning-middleware.ts +27 -11
- 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/convert-to-model-messages.ts +18 -6
- package/src/ui-message-stream/create-sse-stream-with-keep-alive.ts +89 -0
- package/src/ui-message-stream/create-ui-message-stream-response.ts +7 -1
- package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +7 -1
- package/src/ui-message-stream/ui-message-stream-response-init.ts +7 -0
|
@@ -218,7 +218,7 @@ The diagram above shows the complete lifecycle of a resumable stream:
|
|
|
218
218
|
2. **Stream tracking**: Your persistence layer saves the `activeStreamId` in the chat data
|
|
219
219
|
3. **Client reconnection**: When the client reconnects (page reload), the `resume` option triggers a GET request to `/api/chat/[id]/stream`
|
|
220
220
|
4. **Stream recovery**: The GET handler checks for an `activeStreamId` and uses `resumeExistingStream` to reconnect. If no active stream exists, it returns a 204 (No Content) response
|
|
221
|
-
5. **Completion cleanup**: When the stream finishes, the `
|
|
221
|
+
5. **Completion cleanup**: When the stream finishes, the `onEnd` callback clears the `activeStreamId` by setting it to `null`
|
|
222
222
|
|
|
223
223
|
## Customize the resume endpoint
|
|
224
224
|
|
|
@@ -310,7 +310,7 @@ export function Chat({
|
|
|
310
310
|
const assistantMessage =
|
|
311
311
|
lastMessage?.role === 'assistant' ? lastMessage : undefined;
|
|
312
312
|
|
|
313
|
-
void fetch(`/api/chat/${chatData.id}/stop`, {
|
|
313
|
+
void fetch(`/api/chat/${encodeURIComponent(chatData.id)}/stop`, {
|
|
314
314
|
method: 'POST',
|
|
315
315
|
headers: { 'Content-Type': 'application/json' },
|
|
316
316
|
body: JSON.stringify(
|
|
@@ -228,9 +228,7 @@ export default function Chat() {
|
|
|
228
228
|
return <div key={callId}>Approval response received.</div>;
|
|
229
229
|
case 'output-available':
|
|
230
230
|
return (
|
|
231
|
-
<div key={callId}>
|
|
232
|
-
Location access allowed: {part.output}
|
|
233
|
-
</div>
|
|
231
|
+
<div key={callId}>Confirmation result: {part.output}</div>
|
|
234
232
|
);
|
|
235
233
|
case 'output-error':
|
|
236
234
|
return <div key={callId}>Error: {part.errorText}</div>;
|
|
@@ -356,22 +354,22 @@ export default function Chat() {
|
|
|
356
354
|
return;
|
|
357
355
|
}
|
|
358
356
|
|
|
359
|
-
if (toolCall.toolName === '
|
|
357
|
+
if (toolCall.toolName === 'getLocation') {
|
|
360
358
|
try {
|
|
361
|
-
const
|
|
359
|
+
const location = await getLocation();
|
|
362
360
|
|
|
363
361
|
// No await - avoids potential deadlocks
|
|
364
362
|
addToolOutput({
|
|
365
|
-
tool: '
|
|
363
|
+
tool: 'getLocation',
|
|
366
364
|
toolCallId: toolCall.toolCallId,
|
|
367
|
-
output:
|
|
365
|
+
output: location,
|
|
368
366
|
});
|
|
369
367
|
} catch (err) {
|
|
370
368
|
addToolOutput({
|
|
371
|
-
tool: '
|
|
369
|
+
tool: 'getLocation',
|
|
372
370
|
toolCallId: toolCall.toolCallId,
|
|
373
371
|
state: 'output-error',
|
|
374
|
-
errorText: 'Unable to get the
|
|
372
|
+
errorText: 'Unable to get the user location',
|
|
375
373
|
});
|
|
376
374
|
}
|
|
377
375
|
}
|
|
@@ -184,7 +184,7 @@ const { messages, input, handleInputChange, handleSubmit } = useCompletion({
|
|
|
184
184
|
});
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
In this example, the `useCompletion` hook sends a POST request to the `/api/completion` endpoint with the specified headers, additional body fields, and credentials for that fetch request. On your server side, you can handle the request with these additional information.
|
|
187
|
+
In this example, the `useCompletion` hook sends a POST request to the `/api/custom-completion` endpoint with the specified headers, additional body fields, and credentials for that fetch request. On your server side, you can handle the request with these additional information.
|
|
188
188
|
|
|
189
189
|
You can provide a type for the additional body fields. The type applies to
|
|
190
190
|
both the body configured on the hook and the body passed to `complete`:
|
|
@@ -21,8 +21,8 @@ A text stream contains chunks in plain text, that are streamed to the frontend.
|
|
|
21
21
|
Each chunk is then appended together to form a full text response.
|
|
22
22
|
|
|
23
23
|
Text streams are supported by `useChat`, `useCompletion`, and `useObject`.
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
To enable text streaming, use `TextStreamChatTransport` with `useChat`, or set
|
|
25
|
+
the `streamProtocol` option to `text` with `useCompletion`.
|
|
26
26
|
|
|
27
27
|
You can generate text streams with `streamText` in the backend.
|
|
28
28
|
Pass the result's `stream` to `toTextStream` and return it with
|
|
@@ -236,17 +236,18 @@ export default function Page() {
|
|
|
236
236
|
const handleSubmit = async event => {
|
|
237
237
|
event.preventDefault();
|
|
238
238
|
|
|
239
|
-
setMessages([
|
|
240
|
-
...
|
|
241
|
-
{
|
|
239
|
+
setMessages(currentMessages => [
|
|
240
|
+
...currentMessages,
|
|
241
|
+
{
|
|
242
|
+
id: Date.now().toString(),
|
|
243
|
+
role: 'user',
|
|
244
|
+
display: event.target.message.value,
|
|
245
|
+
},
|
|
242
246
|
]);
|
|
243
247
|
|
|
244
248
|
const response = await sendMessage(event.target.message.value);
|
|
245
249
|
|
|
246
|
-
setMessages([
|
|
247
|
-
...messages,
|
|
248
|
-
{ id: Date.now(), role: 'assistant', display: response },
|
|
249
|
-
]);
|
|
250
|
+
setMessages(currentMessages => [...currentMessages, response]);
|
|
250
251
|
};
|
|
251
252
|
|
|
252
253
|
return (
|
|
@@ -143,7 +143,7 @@ export async function generateResponse(prompt: string) {
|
|
|
143
143
|
|
|
144
144
|
### Client
|
|
145
145
|
|
|
146
|
-
```tsx filename='app/page.tsx' highlight="22,
|
|
146
|
+
```tsx filename='app/page.tsx' highlight="22,34-42"
|
|
147
147
|
'use client';
|
|
148
148
|
|
|
149
149
|
import { useState } from 'react';
|
|
@@ -169,15 +169,24 @@ export default function Home() {
|
|
|
169
169
|
|
|
170
170
|
let textContent = '';
|
|
171
171
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
172
|
+
// read both streamable values concurrently
|
|
173
|
+
await Promise.all([
|
|
174
|
+
(async () => {
|
|
175
|
+
for await (const responseDelta of readStreamableValue(response)) {
|
|
176
|
+
textContent = `${textContent}${responseDelta}`;
|
|
177
|
+
setGeneration(textContent);
|
|
178
|
+
}
|
|
179
|
+
})(),
|
|
180
|
+
(async () => {
|
|
181
|
+
for await (const loadingDelta of readStreamableValue(
|
|
182
|
+
loadingState,
|
|
183
|
+
)) {
|
|
184
|
+
if (loadingDelta) {
|
|
185
|
+
setLoading(loadingDelta.loading);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
})(),
|
|
189
|
+
]);
|
|
181
190
|
setInput('');
|
|
182
191
|
setLoading(false);
|
|
183
192
|
}}
|
|
@@ -40,6 +40,8 @@ export async function getStreamedUI() {
|
|
|
40
40
|
With this method, you can catch any error with the stream, and return relevant UI. On the client, you can also use a [React Error Boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) to wrap the streamed component and catch any additional errors.
|
|
41
41
|
|
|
42
42
|
```tsx filename='app/page.tsx'
|
|
43
|
+
'use client';
|
|
44
|
+
|
|
43
45
|
import { getStreamedUI } from '@/actions';
|
|
44
46
|
import { useState } from 'react';
|
|
45
47
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
@@ -82,7 +82,8 @@ export default function Page() {
|
|
|
82
82
|
{messages.map(message => message)}
|
|
83
83
|
|
|
84
84
|
<form
|
|
85
|
-
onSubmit={async
|
|
85
|
+
onSubmit={async event => {
|
|
86
|
+
event.preventDefault();
|
|
86
87
|
const response: ReactNode = await sendMessage(input);
|
|
87
88
|
setMessages(msgs => [...msgs, response]);
|
|
88
89
|
}}
|
|
@@ -642,9 +643,9 @@ export async function generateSampleNotifications() {
|
|
|
642
643
|
for await (const partialObject of partialOutputStream) {
|
|
643
644
|
stream.update(partialObject);
|
|
644
645
|
}
|
|
645
|
-
})();
|
|
646
646
|
|
|
647
|
-
|
|
647
|
+
stream.done();
|
|
648
|
+
})();
|
|
648
649
|
|
|
649
650
|
return { partialNotificationsStream: stream.value };
|
|
650
651
|
}
|
|
@@ -120,12 +120,12 @@ const result = streamText({
|
|
|
120
120
|
model: __MODEL__,
|
|
121
121
|
prompt: 'Write a long story...',
|
|
122
122
|
abortSignal: controller.signal,
|
|
123
|
-
onAbort: ({ steps }) => {
|
|
123
|
+
onAbort: async ({ steps }) => {
|
|
124
124
|
// Called when stream is aborted - persist partial results
|
|
125
125
|
await savePartialResults(steps);
|
|
126
126
|
await logAbortEvent(steps.length);
|
|
127
127
|
},
|
|
128
|
-
onEnd: ({ steps, totalUsage }) => {
|
|
128
|
+
onEnd: async ({ steps, totalUsage }) => {
|
|
129
129
|
// Called when stream completes normally
|
|
130
130
|
await saveFinalResults(steps, totalUsage);
|
|
131
131
|
},
|
|
@@ -133,9 +133,9 @@ Here's an example of how you can use [Upstash Redis](https://upstash.com/redis)
|
|
|
133
133
|
```tsx filename="app/api/chat/route.ts"
|
|
134
134
|
import {
|
|
135
135
|
convertToModelMessages,
|
|
136
|
-
|
|
136
|
+
createTextStreamResponse,
|
|
137
137
|
streamText,
|
|
138
|
-
|
|
138
|
+
toTextStream,
|
|
139
139
|
UIMessage,
|
|
140
140
|
} from 'ai';
|
|
141
141
|
__PROVIDER_IMPORT__;
|
|
@@ -175,9 +175,13 @@ export async function POST(req: Request) {
|
|
|
175
175
|
},
|
|
176
176
|
});
|
|
177
177
|
|
|
178
|
-
// Respond with the
|
|
179
|
-
return
|
|
180
|
-
stream:
|
|
178
|
+
// Respond with a text stream, matching the cached plain text response
|
|
179
|
+
return createTextStreamResponse({
|
|
180
|
+
stream: toTextStream({ stream: result.stream }),
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
183
|
```
|
|
184
|
+
|
|
185
|
+
Both the cached and the fresh responses use the
|
|
186
|
+
[text stream protocol](/docs/ai-sdk-ui/stream-protocol#text-stream-protocol),
|
|
187
|
+
so use `TextStreamChatTransport` when calling this route with `useChat`.
|
|
@@ -45,7 +45,7 @@ The client side code is similar to the previous example, but the [tool call](/do
|
|
|
45
45
|
You can stream UI components within other UI components. This allows you to create complex UIs that are built up from smaller, reusable components. In the example below, we pass a `historyChart` streamable as a prop to a `StockCard` component. The StockCard can render the `historyChart` streamable, and it will automatically update as the server responds with new data.
|
|
46
46
|
|
|
47
47
|
```tsx file='app/actions.tsx'
|
|
48
|
-
async function getStockHistoryChart({ symbol: string }) {
|
|
48
|
+
async function getStockHistoryChart({ symbol }: { symbol: string }) {
|
|
49
49
|
'use server';
|
|
50
50
|
|
|
51
51
|
const ui = createStreamableUI(<Spinner />);
|
|
@@ -48,7 +48,7 @@ const text = generateText({
|
|
|
48
48
|
}),
|
|
49
49
|
execute: async ({ city, unit }) => {
|
|
50
50
|
const weather = getWeather({ city, unit });
|
|
51
|
-
const { temperature,
|
|
51
|
+
const { temperature, description, forecast } = weather;
|
|
52
52
|
|
|
53
53
|
return {
|
|
54
54
|
temperature,
|
|
@@ -158,14 +158,14 @@ The **AI SDK RSC (`@ai-sdk/rsc`)** takes advantage of RSCs to solve the problem
|
|
|
158
158
|
Rather than conditionally rendering user interfaces on the client based on the data returned by the language model, you can directly stream them from the server during a model generation.
|
|
159
159
|
|
|
160
160
|
```tsx highlight="3,22-31,38" filename="app/action.ts"
|
|
161
|
-
import { createStreamableUI } from '@ai-sdk/rsc'
|
|
161
|
+
import { createStreamableUI } from '@ai-sdk/rsc';
|
|
162
162
|
|
|
163
163
|
const uiStream = createStreamableUI();
|
|
164
164
|
|
|
165
165
|
const text = generateText({
|
|
166
166
|
model: __MODEL__,
|
|
167
|
-
instructions: 'you are a friendly assistant'
|
|
168
|
-
prompt: 'what is the weather in SF?'
|
|
167
|
+
instructions: 'you are a friendly assistant',
|
|
168
|
+
prompt: 'what is the weather in SF?',
|
|
169
169
|
tools: {
|
|
170
170
|
getWeather: {
|
|
171
171
|
description: 'Get the weather for a location',
|
|
@@ -173,30 +173,30 @@ const text = generateText({
|
|
|
173
173
|
city: z.string().describe('The city to get the weather for'),
|
|
174
174
|
unit: z
|
|
175
175
|
.enum(['C', 'F'])
|
|
176
|
-
.describe('The unit to display the temperature in')
|
|
176
|
+
.describe('The unit to display the temperature in'),
|
|
177
177
|
}),
|
|
178
178
|
execute: async ({ city, unit }) => {
|
|
179
|
-
const weather = getWeather({ city, unit })
|
|
180
|
-
const { temperature,
|
|
179
|
+
const weather = getWeather({ city, unit });
|
|
180
|
+
const { temperature, description, forecast } = weather;
|
|
181
181
|
|
|
182
182
|
uiStream.done(
|
|
183
183
|
<WeatherCard
|
|
184
184
|
weather={{
|
|
185
185
|
temperature: 47,
|
|
186
186
|
unit: 'F',
|
|
187
|
-
description: 'sunny'
|
|
187
|
+
description: 'sunny',
|
|
188
188
|
forecast,
|
|
189
189
|
}}
|
|
190
|
-
|
|
191
|
-
)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
})
|
|
190
|
+
/>,
|
|
191
|
+
);
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
196
|
|
|
197
197
|
return {
|
|
198
|
-
display: uiStream.value
|
|
199
|
-
}
|
|
198
|
+
display: uiStream.value,
|
|
199
|
+
};
|
|
200
200
|
```
|
|
201
201
|
|
|
202
202
|
The [`createStreamableUI`](/docs/reference/ai-sdk-rsc/create-streamable-ui) function belongs to the `@ai-sdk/rsc` module and creates a stream that can send React components to the client.
|
|
@@ -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
|
+
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.
|
|
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
|
|
|
@@ -278,7 +278,7 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
278
278
|
{
|
|
279
279
|
name: 'role',
|
|
280
280
|
type: "'tool'",
|
|
281
|
-
description: 'The role for the
|
|
281
|
+
description: 'The role for the tool message.',
|
|
282
282
|
},
|
|
283
283
|
{
|
|
284
284
|
name: 'content',
|
|
@@ -476,7 +476,7 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
476
476
|
},
|
|
477
477
|
{
|
|
478
478
|
name: 'timeout',
|
|
479
|
-
type: 'number | { totalMs?: number; stepMs?: number; toolMs?: number; tools?: {
|
|
479
|
+
type: 'number | { totalMs?: number; stepMs?: number; toolMs?: number; tools?: Partial<Record<`${toolName}Ms`, number>> }',
|
|
480
480
|
isOptional: true,
|
|
481
481
|
description:
|
|
482
482
|
'Timeout in milliseconds. Can be specified as a number or as an object with totalMs, stepMs, toolMs, and/or tools properties. totalMs sets the total timeout for the entire call. stepMs sets the timeout for each individual step (LLM call). toolMs sets the default timeout for all tool executions. tools sets per-tool timeout overrides using the pattern {toolName}Ms (e.g. weatherMs, slowApiMs) that take precedence over toolMs - tool names are type-checked for autocomplete. If a tool takes longer than its timeout, it aborts and returns a tool-error so the model can respond or retry. Can be used alongside abortSignal.',
|
|
@@ -1199,9 +1199,9 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
1199
1199
|
},
|
|
1200
1200
|
{
|
|
1201
1201
|
name: 'timeout',
|
|
1202
|
-
type: 'number | { totalMs?: number; stepMs?: number; chunkMs?: number } | undefined',
|
|
1202
|
+
type: 'number | { totalMs?: number; stepMs?: number; firstChunkMs?: number; chunkMs?: number; toolMs?: number; tools?: Partial<Record<`${toolName}Ms`, number>> } | undefined',
|
|
1203
1203
|
description:
|
|
1204
|
-
'Timeout configuration for the generation. Can be a number (milliseconds) or an object with totalMs, stepMs, chunkMs.',
|
|
1204
|
+
'Timeout configuration for the generation. Can be a number (milliseconds) or an object with totalMs, stepMs, firstChunkMs (streaming only), chunkMs, toolMs, and per-tool overrides via tools.',
|
|
1205
1205
|
},
|
|
1206
1206
|
{
|
|
1207
1207
|
name: 'headers',
|
|
@@ -279,7 +279,7 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
279
279
|
{
|
|
280
280
|
name: 'role',
|
|
281
281
|
type: "'tool'",
|
|
282
|
-
description: 'The role for the
|
|
282
|
+
description: 'The role for the tool message.',
|
|
283
283
|
},
|
|
284
284
|
{
|
|
285
285
|
name: 'content',
|
|
@@ -484,7 +484,7 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
484
484
|
},
|
|
485
485
|
{
|
|
486
486
|
name: 'timeout',
|
|
487
|
-
type: 'number | { totalMs?: number; stepMs?: number; firstChunkMs?: number; chunkMs?: number; toolMs?: number; tools?: {
|
|
487
|
+
type: 'number | { totalMs?: number; stepMs?: number; firstChunkMs?: number; chunkMs?: number; toolMs?: number; tools?: Partial<Record<`${toolName}Ms`, number>> }',
|
|
488
488
|
isOptional: true,
|
|
489
489
|
description:
|
|
490
490
|
'Timeout in milliseconds. Can be specified as a number or as an object with totalMs, stepMs, firstChunkMs, chunkMs, toolMs, and/or tools properties. totalMs sets the total timeout for the entire call. stepMs sets the timeout for each individual step (LLM call). firstChunkMs sets the timeout until the first content-bearing output in each step; metadata, stream starts, empty deltas, raw chunks, and transport activity do not satisfy it. chunkMs sets the timeout between content-bearing output chunks after output has started; non-content chunks do not reset it. toolMs sets the default timeout for all tool executions. tools sets per-tool timeout overrides using the pattern {toolName}Ms (e.g. weatherMs, slowApiMs) that take precedence over toolMs - tool names are type-checked for autocomplete. If a tool takes longer than its timeout, it aborts and returns a tool-error so the model can respond or retry. Can be used alongside abortSignal.',
|
|
@@ -2213,9 +2213,9 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
2213
2213
|
},
|
|
2214
2214
|
{
|
|
2215
2215
|
name: 'timeout',
|
|
2216
|
-
type: 'number | { totalMs?: number; stepMs?: number; chunkMs?: number } | undefined',
|
|
2216
|
+
type: 'number | { totalMs?: number; stepMs?: number; firstChunkMs?: number; chunkMs?: number; toolMs?: number; tools?: Partial<Record<`${toolName}Ms`, number>> } | undefined',
|
|
2217
2217
|
description:
|
|
2218
|
-
'Timeout configuration for the generation. Can be a number (milliseconds) or an object with totalMs, stepMs, chunkMs.',
|
|
2218
|
+
'Timeout configuration for the generation. Can be a number (milliseconds) or an object with totalMs, stepMs, firstChunkMs (streaming only), chunkMs, toolMs, and per-tool overrides via tools.',
|
|
2219
2219
|
},
|
|
2220
2220
|
{
|
|
2221
2221
|
name: 'headers',
|
|
@@ -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
|
|
|
@@ -5,9 +5,9 @@ description: API Reference for uploadFile.
|
|
|
5
5
|
|
|
6
6
|
# `uploadFile()`
|
|
7
7
|
|
|
8
|
-
Uploads a file to a provider and returns a `
|
|
9
|
-
subsequent API calls, such as in message
|
|
10
|
-
`streamText`.
|
|
8
|
+
Uploads a file to a provider and returns a result whose `providerReference` (a
|
|
9
|
+
`ProviderReference`) can be used in subsequent API calls, such as in message
|
|
10
|
+
content parts passed to `generateText` or `streamText`.
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
13
|
import { uploadFile } from 'ai';
|
|
@@ -74,7 +74,7 @@ const { providerReference } = await uploadFile({
|
|
|
74
74
|
type: 'ProviderOptions',
|
|
75
75
|
isOptional: true,
|
|
76
76
|
description:
|
|
77
|
-
'Additional provider-specific options. For example, OpenAI
|
|
77
|
+
'Additional provider-specific options. For example, OpenAI accepts a `purpose` field, which defaults to `"assistants"`.',
|
|
78
78
|
},
|
|
79
79
|
]}
|
|
80
80
|
/>
|
|
@@ -5,7 +5,7 @@ description: API Reference for uploadSkill.
|
|
|
5
5
|
|
|
6
6
|
# `uploadSkill()`
|
|
7
7
|
|
|
8
|
-
Uploads a skill (a bundle of files) to a provider and returns a `ProviderReference`
|
|
8
|
+
Uploads a skill (a bundle of files) to a provider and returns a result whose `providerReference` (a `ProviderReference`) can be used in subsequent inference calls.
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
11
|
import { uploadSkill } from 'ai';
|
|
@@ -174,7 +174,7 @@ export interface Agent<
|
|
|
174
174
|
|
|
175
175
|
## Method Parameters
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
`generate()` accepts an `AgentCallParameters<CALL_OPTIONS, TOOLS>` object, and `stream()` accepts an `AgentStreamParameters<CALL_OPTIONS, TOOLS>` object, which extends `AgentCallParameters` with an optional `experimental_transform`. Both accept:
|
|
178
178
|
|
|
179
179
|
- `prompt` (optional): A string prompt or array of `ModelMessage` objects
|
|
180
180
|
- `messages` (optional): An array of `ModelMessage` objects (mutually exclusive with `prompt`)
|
|
@@ -29,13 +29,10 @@ const agent = new ToolLoopAgent({
|
|
|
29
29
|
export async function POST(request: Request) {
|
|
30
30
|
const { messages } = await request.json();
|
|
31
31
|
|
|
32
|
-
// Optional: support cancellation (aborts on disconnect, etc.)
|
|
33
|
-
const abortController = new AbortController();
|
|
34
|
-
|
|
35
32
|
return createAgentUIStreamResponse({
|
|
36
33
|
agent,
|
|
37
34
|
uiMessages: messages,
|
|
38
|
-
abortSignal:
|
|
35
|
+
abortSignal: request.signal, // optional: aborts when the client disconnects
|
|
39
36
|
// experimental_sandbox, // optional: passed through to tool execution
|
|
40
37
|
// ...other UIMessageStreamOptions like sendSources, experimental_transform, etc.
|
|
41
38
|
});
|
|
@@ -20,7 +20,7 @@ import { z } from 'zod';
|
|
|
20
20
|
|
|
21
21
|
export const customTool = dynamicTool({
|
|
22
22
|
description: 'Execute a custom user-defined function',
|
|
23
|
-
inputSchema: z.object({}),
|
|
23
|
+
inputSchema: z.object({ action: z.string(), parameters: z.unknown() }),
|
|
24
24
|
// input is typed as 'unknown'
|
|
25
25
|
execute: async input => {
|
|
26
26
|
const { action, parameters } = input as any;
|
|
@@ -13,7 +13,7 @@ Creates a lightweight Model Context Protocol (MCP) client that connects to an MC
|
|
|
13
13
|
- **Completions**: Methods to request autocompletion suggestions for prompt arguments and resource template variables
|
|
14
14
|
- **Elicitation**: Support for handling server requests for additional input during tool execution
|
|
15
15
|
|
|
16
|
-
It currently does not support accepting notifications from an MCP server
|
|
16
|
+
It currently does not support accepting notifications from an MCP server.
|
|
17
17
|
|
|
18
18
|
## Import
|
|
19
19
|
|
|
@@ -228,7 +228,7 @@ export interface ToolResultPart {
|
|
|
228
228
|
/**
|
|
229
229
|
* Result of the tool call. This is a JSON-serializable object.
|
|
230
230
|
*/
|
|
231
|
-
output:
|
|
231
|
+
output: ToolResultOutput;
|
|
232
232
|
|
|
233
233
|
/**
|
|
234
234
|
Additional provider-specific metadata. They are passed through
|
|
@@ -239,7 +239,7 @@ export interface ToolResultPart {
|
|
|
239
239
|
}
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
-
### `
|
|
242
|
+
### `ToolResultOutput`
|
|
243
243
|
|
|
244
244
|
```ts
|
|
245
245
|
/**
|
|
@@ -60,7 +60,7 @@ A [LanguageModelMiddleware](/docs/ai-sdk-core/middleware) that:
|
|
|
60
60
|
|
|
61
61
|
- Locates function tools with an `inputExamples` property.
|
|
62
62
|
- Serializes each input example (by default as JSON, or using your custom formatter).
|
|
63
|
-
-
|
|
63
|
+
- Appends a section at the end of the tool description containing all formatted examples, prefixed by the `prefix`.
|
|
64
64
|
- Removes the `inputExamples` property from the tool (unless `remove: false`).
|
|
65
65
|
- Passes through all other tools (including those without examples) unchanged.
|
|
66
66
|
|
|
@@ -6,7 +6,7 @@ description: Stream transformer for smoothing text and reasoning output
|
|
|
6
6
|
# `smoothStream()`
|
|
7
7
|
|
|
8
8
|
`smoothStream` is a utility function that creates a TransformStream
|
|
9
|
-
for the `streamText` `
|
|
9
|
+
for the `streamText` `experimental_transform` option
|
|
10
10
|
to smooth out text and reasoning streaming by buffering and releasing complete chunks with configurable delays.
|
|
11
11
|
This creates a more natural reading experience when streaming text and reasoning responses.
|
|
12
12
|
|
|
@@ -110,7 +110,7 @@ const screenshotTool = tool({
|
|
|
110
110
|
|
|
111
111
|
const result = streamText({
|
|
112
112
|
model: __MODEL__,
|
|
113
|
-
messages: convertToModelMessages(messages, {
|
|
113
|
+
messages: await convertToModelMessages(messages, {
|
|
114
114
|
tools: {
|
|
115
115
|
screenshot: screenshotTool,
|
|
116
116
|
},
|
|
@@ -134,6 +134,7 @@ import {
|
|
|
134
134
|
createUIMessageStreamResponse,
|
|
135
135
|
streamText,
|
|
136
136
|
toUIMessageStream,
|
|
137
|
+
type UIMessage,
|
|
137
138
|
} from 'ai';
|
|
138
139
|
|
|
139
140
|
type CustomUIMessage = UIMessage<
|
|
@@ -149,7 +150,7 @@ export async function POST(req: Request) {
|
|
|
149
150
|
|
|
150
151
|
const result = streamText({
|
|
151
152
|
model: __MODEL__,
|
|
152
|
-
messages: convertToModelMessages<CustomUIMessage>(messages, {
|
|
153
|
+
messages: await convertToModelMessages<CustomUIMessage>(messages, {
|
|
153
154
|
convertDataPart: part => {
|
|
154
155
|
// Convert URL attachments to text
|
|
155
156
|
if (part.type === 'data-url') {
|
|
@@ -219,7 +220,7 @@ Only data parts for which you return a text or file model message part are inclu
|
|
|
219
220
|
all other data parts are ignored.
|
|
220
221
|
|
|
221
222
|
```ts
|
|
222
|
-
const result = convertToModelMessages<
|
|
223
|
+
const result = await convertToModelMessages<
|
|
223
224
|
UIMessage<
|
|
224
225
|
unknown,
|
|
225
226
|
{
|
|
@@ -237,7 +238,7 @@ const result = convertToModelMessages<
|
|
|
237
238
|
};
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
// data-code and data-
|
|
241
|
+
// data-code and data-note are ignored
|
|
241
242
|
},
|
|
242
243
|
});
|
|
243
244
|
```
|
|
@@ -62,7 +62,8 @@ const stream = createUIMessageStream({
|
|
|
62
62
|
}),
|
|
63
63
|
);
|
|
64
64
|
},
|
|
65
|
-
onError: error =>
|
|
65
|
+
onError: error =>
|
|
66
|
+
`Custom error: ${error instanceof Error ? error.message : String(error)}`,
|
|
66
67
|
originalMessages: existingMessages,
|
|
67
68
|
onEnd: ({ messages, isContinuation, outcome, responseMessage }) => {
|
|
68
69
|
console.log('Stream ended with messages:', messages);
|
|
@@ -124,7 +125,7 @@ outcomes and call `setOutcome` once.
|
|
|
124
125
|
name: 'onError',
|
|
125
126
|
type: '(error: unknown) => string',
|
|
126
127
|
description:
|
|
127
|
-
'A function that handles errors and returns an error message string. By default, it returns
|
|
128
|
+
'A function that handles errors and returns an error message string. By default, it returns `"An error occurred."` so server-side error details are not sent to the client.',
|
|
128
129
|
},
|
|
129
130
|
{
|
|
130
131
|
name: 'originalMessages',
|
|
@@ -108,6 +108,13 @@ const response = createUIMessageStreamResponse({
|
|
|
108
108
|
isOptional: true,
|
|
109
109
|
description: 'Additional headers for the response.',
|
|
110
110
|
},
|
|
111
|
+
{
|
|
112
|
+
name: 'keepAliveMs',
|
|
113
|
+
type: 'number',
|
|
114
|
+
isOptional: true,
|
|
115
|
+
description:
|
|
116
|
+
'Interval in milliseconds for sending SSE keep-alive comments. When set, an opening comment is sent immediately and additional comments are sent after the stream has been idle for the configured interval.',
|
|
117
|
+
},
|
|
111
118
|
{
|
|
112
119
|
name: 'consumeSseStream',
|
|
113
120
|
type: '(options: { stream: ReadableStream<string> }) => PromiseLike<void> | void',
|
|
@@ -66,6 +66,13 @@ await pipeUIMessageStreamToResponse({
|
|
|
66
66
|
isOptional: true,
|
|
67
67
|
description: 'Additional headers for the response.',
|
|
68
68
|
},
|
|
69
|
+
{
|
|
70
|
+
name: 'keepAliveMs',
|
|
71
|
+
type: 'number',
|
|
72
|
+
isOptional: true,
|
|
73
|
+
description:
|
|
74
|
+
'Interval in milliseconds for sending SSE keep-alive comments. When set, an opening comment is sent immediately and additional comments are sent after the stream has been idle for the configured interval.',
|
|
75
|
+
},
|
|
69
76
|
{
|
|
70
77
|
name: 'consumeSseStream',
|
|
71
78
|
type: '({ stream }: { stream: ReadableStream<string> }) => PromiseLike<void> | void',
|