ai 6.0.220 → 6.0.221
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 +24 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +57 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +56 -23
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/package.json +3 -3
- package/src/generate-text/generate-text.ts +6 -4
- package/src/generate-text/output.ts +4 -1
- package/src/generate-text/run-tools-transformation.ts +3 -7
- package/src/generate-text/stream-text.ts +24 -13
- package/src/ui/chat.ts +1 -1
- package/src/ui/convert-to-model-messages.ts +7 -5
- package/src/ui/index.ts +1 -0
- package/src/util/set-abort-timeout.ts +37 -0
package/dist/internal/index.js
CHANGED
|
@@ -152,7 +152,7 @@ function detectMediaType({
|
|
|
152
152
|
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
153
153
|
|
|
154
154
|
// src/version.ts
|
|
155
|
-
var VERSION = true ? "6.0.
|
|
155
|
+
var VERSION = true ? "6.0.221" : "0.0.0-test";
|
|
156
156
|
|
|
157
157
|
// src/util/download/download.ts
|
|
158
158
|
var download = async ({
|
package/dist/internal/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.221",
|
|
4
4
|
"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.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@opentelemetry/api": "^1.9.0",
|
|
48
|
-
"@ai-sdk/gateway": "3.0.
|
|
48
|
+
"@ai-sdk/gateway": "3.0.145",
|
|
49
49
|
"@ai-sdk/provider": "3.0.13",
|
|
50
|
-
"@ai-sdk/provider-utils": "4.0.
|
|
50
|
+
"@ai-sdk/provider-utils": "4.0.37"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@edge-runtime/vm": "^5.0.0",
|
|
@@ -52,6 +52,7 @@ import { asArray } from '../util/as-array';
|
|
|
52
52
|
import type { DownloadFunction } from '../util/download/download-function';
|
|
53
53
|
import { mergeObjects } from '../util/merge-objects';
|
|
54
54
|
import { prepareRetries } from '../util/prepare-retries';
|
|
55
|
+
import { setAbortTimeout } from '../util/set-abort-timeout';
|
|
55
56
|
import { VERSION } from '../version';
|
|
56
57
|
import type {
|
|
57
58
|
OnFinishEvent,
|
|
@@ -684,10 +685,11 @@ export async function generateText<
|
|
|
684
685
|
|
|
685
686
|
do {
|
|
686
687
|
// Set up step timeout if configured
|
|
687
|
-
const stepTimeoutId =
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
688
|
+
const stepTimeoutId = setAbortTimeout({
|
|
689
|
+
abortController: stepAbortController,
|
|
690
|
+
label: 'Step',
|
|
691
|
+
timeoutMs: stepTimeoutMs,
|
|
692
|
+
});
|
|
691
693
|
|
|
692
694
|
try {
|
|
693
695
|
const stepInputMessages = [...initialMessages, ...responseMessages];
|
|
@@ -278,6 +278,7 @@ export const array = <ELEMENT>({
|
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
const validatedElements: Array<ELEMENT> = [];
|
|
281
282
|
for (const element of outerValue.elements) {
|
|
282
283
|
const validationResult = await safeValidateTypes({
|
|
283
284
|
value: element,
|
|
@@ -294,9 +295,11 @@ export const array = <ELEMENT>({
|
|
|
294
295
|
finishReason: context.finishReason,
|
|
295
296
|
});
|
|
296
297
|
}
|
|
298
|
+
|
|
299
|
+
validatedElements.push(validationResult.value);
|
|
297
300
|
}
|
|
298
301
|
|
|
299
|
-
return
|
|
302
|
+
return validatedElements;
|
|
300
303
|
},
|
|
301
304
|
|
|
302
305
|
async parsePartialOutput({ text }: { text: string }) {
|
|
@@ -171,10 +171,8 @@ export function runToolsTransformation<TOOLS extends ToolSet>({
|
|
|
171
171
|
// keep track of outstanding tool results for stream closing:
|
|
172
172
|
const outstandingToolResults = new Set<string>();
|
|
173
173
|
|
|
174
|
-
// keep track of tool inputs for provider-side tool results
|
|
175
|
-
const toolInputs = new Map<string, unknown>();
|
|
176
|
-
|
|
177
174
|
// keep track of parsed tool calls so provider-emitted approval requests can reference them
|
|
175
|
+
// keep track of tool inputs for provider-side tool results
|
|
178
176
|
const toolCallsByToolCallId = new Map<string, TypedToolCall<TOOLS>>();
|
|
179
177
|
|
|
180
178
|
let canClose = false;
|
|
@@ -349,8 +347,6 @@ export function runToolsTransformation<TOOLS extends ToolSet>({
|
|
|
349
347
|
break;
|
|
350
348
|
}
|
|
351
349
|
|
|
352
|
-
toolInputs.set(toolCall.toolCallId, toolCall.input);
|
|
353
|
-
|
|
354
350
|
// Only execute tools that are not provider-executed:
|
|
355
351
|
if (tool.execute != null && toolCall.providerExecuted !== true) {
|
|
356
352
|
const toolExecutionId = generateId(); // use our own id to guarantee uniqueness
|
|
@@ -405,7 +401,7 @@ export function runToolsTransformation<TOOLS extends ToolSet>({
|
|
|
405
401
|
type: 'tool-error',
|
|
406
402
|
toolCallId: chunk.toolCallId,
|
|
407
403
|
toolName,
|
|
408
|
-
input:
|
|
404
|
+
input: toolCall?.input,
|
|
409
405
|
providerExecuted: true,
|
|
410
406
|
error: chunk.result,
|
|
411
407
|
dynamic: chunk.dynamic,
|
|
@@ -421,7 +417,7 @@ export function runToolsTransformation<TOOLS extends ToolSet>({
|
|
|
421
417
|
type: 'tool-result',
|
|
422
418
|
toolCallId: chunk.toolCallId,
|
|
423
419
|
toolName,
|
|
424
|
-
input:
|
|
420
|
+
input: toolCall?.input,
|
|
425
421
|
output: chunk.result,
|
|
426
422
|
providerExecuted: true,
|
|
427
423
|
dynamic: chunk.dynamic,
|
|
@@ -82,6 +82,7 @@ import { mergeAbortSignals } from '../util/merge-abort-signals';
|
|
|
82
82
|
import { mergeObjects } from '../util/merge-objects';
|
|
83
83
|
import { now as originalNow } from '../util/now';
|
|
84
84
|
import { prepareRetries } from '../util/prepare-retries';
|
|
85
|
+
import { setAbortTimeout } from '../util/set-abort-timeout';
|
|
85
86
|
import { collectToolApprovals } from './collect-tool-approvals';
|
|
86
87
|
import { validateApprovedToolApprovals } from './validate-tool-approvals';
|
|
87
88
|
import type {
|
|
@@ -1567,25 +1568,25 @@ class DefaultStreamTextResult<
|
|
|
1567
1568
|
const includeRawChunks = self.includeRawChunks;
|
|
1568
1569
|
|
|
1569
1570
|
// Set up step timeout if configured
|
|
1570
|
-
const stepTimeoutId =
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1571
|
+
const stepTimeoutId = setAbortTimeout({
|
|
1572
|
+
abortController: stepAbortController,
|
|
1573
|
+
label: 'Step',
|
|
1574
|
+
timeoutMs: stepTimeoutMs,
|
|
1575
|
+
});
|
|
1574
1576
|
|
|
1575
1577
|
// Set up chunk timeout tracking (will be reset on each chunk)
|
|
1576
1578
|
let chunkTimeoutId: ReturnType<typeof setTimeout> | undefined =
|
|
1577
1579
|
undefined;
|
|
1578
1580
|
|
|
1579
1581
|
function resetChunkTimeout() {
|
|
1580
|
-
if (
|
|
1581
|
-
|
|
1582
|
-
clearTimeout(chunkTimeoutId);
|
|
1583
|
-
}
|
|
1584
|
-
chunkTimeoutId = setTimeout(
|
|
1585
|
-
() => chunkAbortController!.abort(),
|
|
1586
|
-
chunkTimeoutMs,
|
|
1587
|
-
);
|
|
1582
|
+
if (chunkTimeoutId != null) {
|
|
1583
|
+
clearTimeout(chunkTimeoutId);
|
|
1588
1584
|
}
|
|
1585
|
+
chunkTimeoutId = setAbortTimeout({
|
|
1586
|
+
abortController: chunkAbortController,
|
|
1587
|
+
label: 'Chunk',
|
|
1588
|
+
timeoutMs: chunkTimeoutMs,
|
|
1589
|
+
});
|
|
1589
1590
|
}
|
|
1590
1591
|
|
|
1591
1592
|
function clearChunkTimeout() {
|
|
@@ -1601,6 +1602,13 @@ class DefaultStreamTextResult<
|
|
|
1601
1602
|
}
|
|
1602
1603
|
}
|
|
1603
1604
|
|
|
1605
|
+
// The step's stream is registered lazily and consumed long after this
|
|
1606
|
+
// function returns, so the step timer must stay armed past setup. When
|
|
1607
|
+
// the merged abort signal fires (any step/chunk/total timeout or caller
|
|
1608
|
+
// abort), drop both step-scoped timers so neither outlives the step.
|
|
1609
|
+
abortSignal?.addEventListener('abort', clearStepTimeout);
|
|
1610
|
+
abortSignal?.addEventListener('abort', clearChunkTimeout);
|
|
1611
|
+
|
|
1604
1612
|
try {
|
|
1605
1613
|
stepFinish = new DelayedPromise<void>();
|
|
1606
1614
|
|
|
@@ -2244,9 +2252,12 @@ class DefaultStreamTextResult<
|
|
|
2244
2252
|
}),
|
|
2245
2253
|
),
|
|
2246
2254
|
);
|
|
2247
|
-
}
|
|
2255
|
+
} catch (error) {
|
|
2256
|
+
// Setup failed before the stream was registered, so neither the
|
|
2257
|
+
// stream's flush nor an abort will clear the timers — clear them here.
|
|
2248
2258
|
clearStepTimeout();
|
|
2249
2259
|
clearChunkTimeout();
|
|
2260
|
+
throw error;
|
|
2250
2261
|
}
|
|
2251
2262
|
}
|
|
2252
2263
|
|
package/src/ui/chat.ts
CHANGED
|
@@ -246,10 +246,12 @@ export async function convertToModelMessages<UI_MESSAGE extends UIMessage>(
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
249
|
+
if (content.length > 0) {
|
|
250
|
+
modelMessages.push({
|
|
251
|
+
role: 'assistant',
|
|
252
|
+
content,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
253
255
|
|
|
254
256
|
// check if there are tool invocations with results in the block
|
|
255
257
|
// Include non-provider-executed tools, OR provider-executed tools with approval responses
|
|
@@ -297,7 +299,7 @@ export async function convertToModelMessages<UI_MESSAGE extends UIMessage>(
|
|
|
297
299
|
type: 'error-text' as const,
|
|
298
300
|
value:
|
|
299
301
|
toolPart.approval?.reason ??
|
|
300
|
-
'Tool execution denied.',
|
|
302
|
+
'Tool call execution denied.',
|
|
301
303
|
},
|
|
302
304
|
...(toolPart.callProviderMetadata != null
|
|
303
305
|
? { providerOptions: toolPart.callProviderMetadata }
|
package/src/ui/index.ts
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schedules a timeout that aborts the given controller with a `TimeoutError`
|
|
3
|
+
* `DOMException`, matching the reason produced by `AbortSignal.timeout(ms)`.
|
|
4
|
+
*
|
|
5
|
+
* @param abortController - The controller to abort when the timeout elapses.
|
|
6
|
+
* If undefined, no timeout is scheduled.
|
|
7
|
+
* @param label - Human-readable label included in the error message
|
|
8
|
+
* (e.g. "Step", "Chunk").
|
|
9
|
+
* @param timeoutMs - Duration in milliseconds before the controller is aborted.
|
|
10
|
+
* If undefined, no timeout is scheduled.
|
|
11
|
+
* @returns The timeout id (suitable for passing to `clearTimeout`), or
|
|
12
|
+
* `undefined` if no timeout was scheduled.
|
|
13
|
+
*/
|
|
14
|
+
export function setAbortTimeout({
|
|
15
|
+
abortController,
|
|
16
|
+
label,
|
|
17
|
+
timeoutMs,
|
|
18
|
+
}: {
|
|
19
|
+
abortController: AbortController | undefined;
|
|
20
|
+
label: string;
|
|
21
|
+
timeoutMs: number | undefined;
|
|
22
|
+
}): ReturnType<typeof setTimeout> | undefined {
|
|
23
|
+
if (abortController == null || timeoutMs == null) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return setTimeout(
|
|
28
|
+
() =>
|
|
29
|
+
abortController.abort(
|
|
30
|
+
new DOMException(
|
|
31
|
+
`${label} timeout of ${timeoutMs}ms exceeded`,
|
|
32
|
+
'TimeoutError',
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
timeoutMs,
|
|
36
|
+
);
|
|
37
|
+
}
|