ai 7.0.84 → 7.0.86
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 +22 -0
- package/dist/index.d.ts +46 -12
- package/dist/index.js +521 -502
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +23 -3
- package/dist/internal/index.js +141 -149
- package/dist/internal/index.js.map +1 -1
- package/dist/test/index.js +1 -1
- package/dist/test/index.js.map +1 -1
- package/docs/03-agents/06-tool-approvals.mdx +6 -3
- package/docs/03-agents/07-workflow-agent.mdx +43 -0
- package/docs/03-ai-sdk-core/35-image-generation.mdx +22 -5
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +25 -6
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +25 -0
- package/package.json +13 -13
- package/src/batch/batch-types.ts +4 -1
- package/src/batch/batch.ts +38 -9
- package/src/generate-image/generate-image-result.ts +40 -0
- package/src/generate-image/generate-image.ts +126 -28
- package/src/generate-image/index.ts +4 -1
- package/src/generate-text/convert-language-model-content.ts +206 -0
- package/src/generate-text/generate-text.ts +3 -196
- package/src/generate-text/generated-file.ts +15 -1
- package/src/util/canonical-hash.ts +3 -1
|
@@ -1,9 +1,40 @@
|
|
|
1
|
+
import type { ImageModelV4ProviderMetadata } from '@ai-sdk/provider';
|
|
1
2
|
import type { GeneratedFile } from '../generate-text';
|
|
2
3
|
import type { ImageModelProviderMetadata } from '../types/image-model';
|
|
3
4
|
import type { ImageModelResponseMetadata } from '../types/image-model-response-metadata';
|
|
4
5
|
import type { ImageModelUsage } from '../types/usage';
|
|
5
6
|
import type { Warning } from '../types/warning';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* The result of one underlying image model call.
|
|
10
|
+
*/
|
|
11
|
+
export interface GenerateImageCall {
|
|
12
|
+
/**
|
|
13
|
+
* The images generated by this call.
|
|
14
|
+
*/
|
|
15
|
+
readonly images: Array<GeneratedFile>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Provider-specific metadata for this call.
|
|
19
|
+
*/
|
|
20
|
+
readonly providerMetadata?: ImageModelV4ProviderMetadata;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Response metadata from the provider.
|
|
24
|
+
*/
|
|
25
|
+
readonly response: ImageModelResponseMetadata;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Warnings for this call, e.g. unsupported settings.
|
|
29
|
+
*/
|
|
30
|
+
readonly warnings: Array<Warning>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Token usage for this call, if reported by the provider.
|
|
34
|
+
*/
|
|
35
|
+
readonly usage?: ImageModelUsage;
|
|
36
|
+
}
|
|
37
|
+
|
|
7
38
|
/**
|
|
8
39
|
* The result of a `generateImage` call.
|
|
9
40
|
* It contains the images and additional information.
|
|
@@ -19,6 +50,11 @@ export interface GenerateImageResult {
|
|
|
19
50
|
*/
|
|
20
51
|
readonly images: Array<GeneratedFile>;
|
|
21
52
|
|
|
53
|
+
/**
|
|
54
|
+
* The results of the underlying image model calls.
|
|
55
|
+
*/
|
|
56
|
+
readonly calls: Array<GenerateImageCall>;
|
|
57
|
+
|
|
22
58
|
/**
|
|
23
59
|
* Warnings for the call, e.g. unsupported settings.
|
|
24
60
|
*/
|
|
@@ -26,12 +62,16 @@ export interface GenerateImageResult {
|
|
|
26
62
|
|
|
27
63
|
/**
|
|
28
64
|
* Response metadata from the provider. There may be multiple responses if we made multiple calls to the model.
|
|
65
|
+
*
|
|
66
|
+
* @deprecated Use `calls` to preserve each response with its corresponding images, metadata, warnings, and usage.
|
|
29
67
|
*/
|
|
30
68
|
readonly responses: Array<ImageModelResponseMetadata>;
|
|
31
69
|
|
|
32
70
|
/**
|
|
33
71
|
* Provider-specific metadata. They are passed through from the provider to the AI SDK and enable provider-specific
|
|
34
72
|
* results that can be fully encapsulated in the provider.
|
|
73
|
+
*
|
|
74
|
+
* @deprecated Use the provider metadata in `calls` or on individual `images` to preserve its scope.
|
|
35
75
|
*/
|
|
36
76
|
readonly providerMetadata: ImageModelProviderMetadata;
|
|
37
77
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {
|
|
2
|
+
isJSONObject,
|
|
3
|
+
type ImageModelV4,
|
|
4
|
+
type ImageModelV4CallOptions,
|
|
5
|
+
type ImageModelV4File,
|
|
6
|
+
type ImageModelV4ProviderMetadata,
|
|
7
|
+
type JSONObject,
|
|
6
8
|
} from '@ai-sdk/provider';
|
|
7
9
|
import {
|
|
8
10
|
convertBase64ToUint8Array,
|
|
@@ -24,10 +26,27 @@ import { addImageModelUsage, type ImageModelUsage } from '../types/usage';
|
|
|
24
26
|
import type { Warning } from '../types/warning';
|
|
25
27
|
import { prepareRetries } from '../util/prepare-retries';
|
|
26
28
|
import { VERSION } from '../version';
|
|
27
|
-
import type {
|
|
29
|
+
import type {
|
|
30
|
+
GenerateImageCall,
|
|
31
|
+
GenerateImageResult,
|
|
32
|
+
} from './generate-image-result';
|
|
28
33
|
import { convertDataContentToUint8Array } from '../prompt/data-content';
|
|
29
34
|
import { splitDataUrl } from '../prompt/split-data-url';
|
|
30
35
|
|
|
36
|
+
const gatewayCostMetadataKeys = [
|
|
37
|
+
'cost',
|
|
38
|
+
'gatewayCost',
|
|
39
|
+
'inferenceCost',
|
|
40
|
+
'inputInferenceCost',
|
|
41
|
+
'marketCost',
|
|
42
|
+
'outputInferenceCost',
|
|
43
|
+
'surchargeCost',
|
|
44
|
+
] as const;
|
|
45
|
+
|
|
46
|
+
type GatewayCostMetadata = {
|
|
47
|
+
[key in (typeof gatewayCostMetadataKeys)[number]]?: unknown;
|
|
48
|
+
};
|
|
49
|
+
|
|
31
50
|
export type GenerateImagePrompt =
|
|
32
51
|
| string
|
|
33
52
|
| {
|
|
@@ -187,7 +206,8 @@ export async function generateImage({
|
|
|
187
206
|
);
|
|
188
207
|
|
|
189
208
|
// collect result images, warnings, and response metadata
|
|
190
|
-
const images: Array<
|
|
209
|
+
const images: Array<GeneratedFile> = [];
|
|
210
|
+
const calls: Array<GenerateImageCall> = [];
|
|
191
211
|
const warnings: Array<Warning> = [];
|
|
192
212
|
const responses: Array<ImageModelResponseMetadata> = [];
|
|
193
213
|
const providerMetadata: ImageModelV4ProviderMetadata = {};
|
|
@@ -197,19 +217,29 @@ export async function generateImage({
|
|
|
197
217
|
totalTokens: undefined,
|
|
198
218
|
};
|
|
199
219
|
for (const result of results) {
|
|
200
|
-
images.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
const callImages = result.images.map(
|
|
221
|
+
(image, index) =>
|
|
222
|
+
new DefaultGeneratedFile({
|
|
223
|
+
data: image,
|
|
224
|
+
mediaType:
|
|
225
|
+
detectMediaType({
|
|
226
|
+
data: image,
|
|
227
|
+
topLevelType: 'image',
|
|
228
|
+
}) ?? 'image/png',
|
|
229
|
+
providerMetadata: getImageProviderMetadata(
|
|
230
|
+
result.providerMetadata,
|
|
231
|
+
index,
|
|
232
|
+
),
|
|
233
|
+
}),
|
|
212
234
|
);
|
|
235
|
+
images.push(...callImages);
|
|
236
|
+
calls.push({
|
|
237
|
+
images: callImages,
|
|
238
|
+
providerMetadata: result.providerMetadata,
|
|
239
|
+
response: result.response,
|
|
240
|
+
warnings: result.warnings,
|
|
241
|
+
usage: result.usage,
|
|
242
|
+
});
|
|
213
243
|
warnings.push(...result.warnings);
|
|
214
244
|
|
|
215
245
|
if (result.usage != null) {
|
|
@@ -217,19 +247,33 @@ export async function generateImage({
|
|
|
217
247
|
}
|
|
218
248
|
|
|
219
249
|
if (result.providerMetadata) {
|
|
220
|
-
for (const [providerName, metadata] of Object.entries
|
|
221
|
-
|
|
222
|
-
|
|
250
|
+
for (const [providerName, metadata] of Object.entries(
|
|
251
|
+
result.providerMetadata,
|
|
252
|
+
)) {
|
|
223
253
|
if (providerName === 'gateway') {
|
|
224
254
|
const currentEntry = providerMetadata[providerName];
|
|
225
255
|
if (currentEntry != null && typeof currentEntry === 'object') {
|
|
256
|
+
const currentGatewayMetadata = currentEntry as GatewayCostMetadata;
|
|
257
|
+
const newGatewayMetadata = metadata as GatewayCostMetadata;
|
|
258
|
+
|
|
226
259
|
providerMetadata[providerName] = {
|
|
227
260
|
...(currentEntry as object),
|
|
228
|
-
...metadata,
|
|
261
|
+
...(metadata as object),
|
|
262
|
+
...Object.fromEntries(
|
|
263
|
+
gatewayCostMetadataKeys.flatMap(key => {
|
|
264
|
+
const total = addDecimalStrings(
|
|
265
|
+
currentGatewayMetadata[key],
|
|
266
|
+
newGatewayMetadata[key],
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
return total == null ? [] : [[key, total]];
|
|
270
|
+
}),
|
|
271
|
+
),
|
|
229
272
|
} as ImageModelV4ProviderMetadata[string];
|
|
230
273
|
} else {
|
|
231
|
-
providerMetadata[providerName] =
|
|
232
|
-
metadata as
|
|
274
|
+
providerMetadata[providerName] = {
|
|
275
|
+
...(metadata as object),
|
|
276
|
+
} as ImageModelV4ProviderMetadata[string];
|
|
233
277
|
}
|
|
234
278
|
const imagesValue = (
|
|
235
279
|
providerMetadata[providerName] as { images?: unknown }
|
|
@@ -240,9 +284,7 @@ export async function generateImage({
|
|
|
240
284
|
}
|
|
241
285
|
} else {
|
|
242
286
|
providerMetadata[providerName] ??= { images: [] };
|
|
243
|
-
providerMetadata[providerName].images.push(
|
|
244
|
-
...result.providerMetadata[providerName].images,
|
|
245
|
-
);
|
|
287
|
+
providerMetadata[providerName].images.push(...metadata.images);
|
|
246
288
|
}
|
|
247
289
|
}
|
|
248
290
|
}
|
|
@@ -258,6 +300,7 @@ export async function generateImage({
|
|
|
258
300
|
|
|
259
301
|
return new DefaultGenerateImageResult({
|
|
260
302
|
images,
|
|
303
|
+
calls,
|
|
261
304
|
warnings,
|
|
262
305
|
responses,
|
|
263
306
|
providerMetadata,
|
|
@@ -267,6 +310,7 @@ export async function generateImage({
|
|
|
267
310
|
|
|
268
311
|
class DefaultGenerateImageResult implements GenerateImageResult {
|
|
269
312
|
readonly images: Array<GeneratedFile>;
|
|
313
|
+
readonly calls: Array<GenerateImageCall>;
|
|
270
314
|
readonly warnings: Array<Warning>;
|
|
271
315
|
readonly responses: Array<ImageModelResponseMetadata>;
|
|
272
316
|
readonly providerMetadata: ImageModelV4ProviderMetadata;
|
|
@@ -274,12 +318,14 @@ class DefaultGenerateImageResult implements GenerateImageResult {
|
|
|
274
318
|
|
|
275
319
|
constructor(options: {
|
|
276
320
|
images: Array<GeneratedFile>;
|
|
321
|
+
calls: Array<GenerateImageCall>;
|
|
277
322
|
warnings: Array<Warning>;
|
|
278
323
|
responses: Array<ImageModelResponseMetadata>;
|
|
279
324
|
providerMetadata: ImageModelV4ProviderMetadata;
|
|
280
325
|
usage: ImageModelUsage;
|
|
281
326
|
}) {
|
|
282
327
|
this.images = options.images;
|
|
328
|
+
this.calls = options.calls;
|
|
283
329
|
this.warnings = options.warnings;
|
|
284
330
|
this.responses = options.responses;
|
|
285
331
|
this.providerMetadata = options.providerMetadata;
|
|
@@ -291,6 +337,30 @@ class DefaultGenerateImageResult implements GenerateImageResult {
|
|
|
291
337
|
}
|
|
292
338
|
}
|
|
293
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Extracts per-image metadata from the legacy `providerMetadata.<provider>.images` result shape.
|
|
342
|
+
*/
|
|
343
|
+
function getImageProviderMetadata(
|
|
344
|
+
providerMetadata: ImageModelV4ProviderMetadata | undefined,
|
|
345
|
+
imageIndex: number,
|
|
346
|
+
): Record<string, JSONObject> | undefined {
|
|
347
|
+
if (providerMetadata == null) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
let imageMetadata: Record<string, JSONObject> | undefined;
|
|
352
|
+
|
|
353
|
+
for (const [providerName, metadata] of Object.entries(providerMetadata)) {
|
|
354
|
+
const value = metadata.images?.[imageIndex];
|
|
355
|
+
|
|
356
|
+
if (isJSONObject(value) && !Array.isArray(value)) {
|
|
357
|
+
(imageMetadata ??= {})[providerName] = value;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return imageMetadata;
|
|
362
|
+
}
|
|
363
|
+
|
|
294
364
|
async function invokeModelMaxImagesPerCall(model: ImageModelV4) {
|
|
295
365
|
const isFunction = model.maxImagesPerCall instanceof Function;
|
|
296
366
|
|
|
@@ -303,6 +373,34 @@ async function invokeModelMaxImagesPerCall(model: ImageModelV4) {
|
|
|
303
373
|
});
|
|
304
374
|
}
|
|
305
375
|
|
|
376
|
+
function addDecimalStrings(
|
|
377
|
+
value1: unknown,
|
|
378
|
+
value2: unknown,
|
|
379
|
+
): string | undefined {
|
|
380
|
+
if (
|
|
381
|
+
typeof value1 !== 'string' ||
|
|
382
|
+
typeof value2 !== 'string' ||
|
|
383
|
+
!/^\d+(?:\.\d+)?$/.test(value1) ||
|
|
384
|
+
!/^\d+(?:\.\d+)?$/.test(value2)
|
|
385
|
+
) {
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const [integer1, fraction1 = ''] = value1.split('.');
|
|
390
|
+
const [integer2, fraction2 = ''] = value2.split('.');
|
|
391
|
+
const precision = Math.max(fraction1.length, fraction2.length);
|
|
392
|
+
const sum =
|
|
393
|
+
BigInt(integer1 + fraction1.padEnd(precision, '0')) +
|
|
394
|
+
BigInt(integer2 + fraction2.padEnd(precision, '0'));
|
|
395
|
+
const sumString = sum.toString().padStart(precision + 1, '0');
|
|
396
|
+
|
|
397
|
+
return precision === 0
|
|
398
|
+
? sumString
|
|
399
|
+
: `${sumString.slice(0, -precision)}.${sumString.slice(
|
|
400
|
+
-precision,
|
|
401
|
+
)}`.replace(/\.?0+$/, '');
|
|
402
|
+
}
|
|
403
|
+
|
|
306
404
|
function normalizePrompt(
|
|
307
405
|
prompt: GenerateImagePrompt,
|
|
308
406
|
): Pick<ImageModelV4CallOptions, 'prompt' | 'files' | 'mask'> {
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { LanguageModelV4Content } from '@ai-sdk/provider';
|
|
2
|
+
import type { ToolSet } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { ToolCallNotFoundForApprovalError } from '../error/tool-call-not-found-for-approval-error';
|
|
4
|
+
import { getOwn } from '../util/get-own';
|
|
5
|
+
import type { ContentPart } from './content-part';
|
|
6
|
+
import { DefaultGeneratedFile } from './generated-file';
|
|
7
|
+
import type { ToolApprovalRequestOutput } from './tool-approval-request-output';
|
|
8
|
+
import type { ToolApprovalResponseOutput } from './tool-approval-response-output';
|
|
9
|
+
import type { TypedToolCall } from './tool-call';
|
|
10
|
+
import type { TypedToolError } from './tool-error';
|
|
11
|
+
import type { ToolOutput } from './tool-output';
|
|
12
|
+
import type { TypedToolResult } from './tool-result';
|
|
13
|
+
|
|
14
|
+
export function convertLanguageModelContent<TOOLS extends ToolSet>({
|
|
15
|
+
content,
|
|
16
|
+
toolCalls,
|
|
17
|
+
toolOutputs,
|
|
18
|
+
toolApprovalRequests,
|
|
19
|
+
toolApprovalResponses,
|
|
20
|
+
tools,
|
|
21
|
+
}: {
|
|
22
|
+
content: Array<LanguageModelV4Content>;
|
|
23
|
+
toolCalls: Array<TypedToolCall<TOOLS>>;
|
|
24
|
+
toolOutputs: Array<ToolOutput<TOOLS>>;
|
|
25
|
+
toolApprovalRequests: Array<ToolApprovalRequestOutput<TOOLS>>;
|
|
26
|
+
toolApprovalResponses: Array<ToolApprovalResponseOutput<TOOLS>>;
|
|
27
|
+
tools: TOOLS | undefined;
|
|
28
|
+
}): Array<ContentPart<TOOLS>> {
|
|
29
|
+
const contentParts: Array<ContentPart<TOOLS>> = [];
|
|
30
|
+
const toolOutputsWithApprovalResponses: Array<ToolOutput<TOOLS>> = [];
|
|
31
|
+
const toolOutputsWithoutApprovalResponses: Array<ToolOutput<TOOLS>> = [];
|
|
32
|
+
const toolCallIdsWithApprovalResponses = new Set(
|
|
33
|
+
toolApprovalResponses.map(
|
|
34
|
+
toolApprovalResponse => toolApprovalResponse.toolCall.toolCallId,
|
|
35
|
+
),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
for (const part of content) {
|
|
39
|
+
switch (part.type) {
|
|
40
|
+
case 'text':
|
|
41
|
+
case 'reasoning':
|
|
42
|
+
case 'custom':
|
|
43
|
+
case 'source':
|
|
44
|
+
contentParts.push(part);
|
|
45
|
+
break;
|
|
46
|
+
|
|
47
|
+
case 'file':
|
|
48
|
+
case 'reasoning-file': {
|
|
49
|
+
contentParts.push({
|
|
50
|
+
type: part.type as 'file' | 'reasoning-file',
|
|
51
|
+
file: new DefaultGeneratedFile({
|
|
52
|
+
data:
|
|
53
|
+
part.data.type === 'data'
|
|
54
|
+
? part.data.data
|
|
55
|
+
: part.data.url.toString(),
|
|
56
|
+
mediaType: part.mediaType,
|
|
57
|
+
}),
|
|
58
|
+
...(part.providerMetadata != null
|
|
59
|
+
? { providerMetadata: part.providerMetadata }
|
|
60
|
+
: {}),
|
|
61
|
+
});
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
case 'tool-call': {
|
|
66
|
+
const toolCall = toolCalls.find(
|
|
67
|
+
toolCall => toolCall.toolCallId === part.toolCallId,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (toolCall == null) {
|
|
71
|
+
throw new Error(`Tool call ${part.toolCallId} not found.`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
contentParts.push(toolCall);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
case 'tool-result': {
|
|
79
|
+
const toolCall = toolCalls.find(
|
|
80
|
+
toolCall => toolCall.toolCallId === part.toolCallId,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Handle deferred results for provider-executed tools (e.g., programmatic tool calling).
|
|
84
|
+
// When a server tool (like code_execution) triggers a client tool, the server tool's
|
|
85
|
+
// result may be deferred to a later turn. In this case, there's no matching tool-call
|
|
86
|
+
// in the current response.
|
|
87
|
+
if (toolCall == null) {
|
|
88
|
+
const tool = getOwn(tools, part.toolName);
|
|
89
|
+
const supportsDeferredResults =
|
|
90
|
+
tool?.type === 'provider' && tool.supportsDeferredResults;
|
|
91
|
+
|
|
92
|
+
if (!supportsDeferredResults) {
|
|
93
|
+
throw new Error(`Tool call ${part.toolCallId} not found.`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Create tool result without tool call input (deferred result)
|
|
97
|
+
if (part.isError) {
|
|
98
|
+
contentParts.push({
|
|
99
|
+
type: 'tool-error' as const,
|
|
100
|
+
toolCallId: part.toolCallId,
|
|
101
|
+
toolName: part.toolName as keyof TOOLS & string,
|
|
102
|
+
input: undefined,
|
|
103
|
+
error: part.result,
|
|
104
|
+
providerExecuted: true,
|
|
105
|
+
dynamic: part.dynamic,
|
|
106
|
+
...(part.providerMetadata != null
|
|
107
|
+
? { providerMetadata: part.providerMetadata }
|
|
108
|
+
: {}),
|
|
109
|
+
...(tool?.metadata != null
|
|
110
|
+
? { toolMetadata: tool.metadata }
|
|
111
|
+
: {}),
|
|
112
|
+
} as TypedToolError<TOOLS>);
|
|
113
|
+
} else {
|
|
114
|
+
contentParts.push({
|
|
115
|
+
type: 'tool-result' as const,
|
|
116
|
+
toolCallId: part.toolCallId,
|
|
117
|
+
toolName: part.toolName as keyof TOOLS & string,
|
|
118
|
+
input: undefined,
|
|
119
|
+
output: part.result,
|
|
120
|
+
providerExecuted: true,
|
|
121
|
+
dynamic: part.dynamic,
|
|
122
|
+
...(part.providerMetadata != null
|
|
123
|
+
? { providerMetadata: part.providerMetadata }
|
|
124
|
+
: {}),
|
|
125
|
+
...(tool?.metadata != null
|
|
126
|
+
? { toolMetadata: tool.metadata }
|
|
127
|
+
: {}),
|
|
128
|
+
} as TypedToolResult<TOOLS>);
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (part.isError) {
|
|
134
|
+
contentParts.push({
|
|
135
|
+
type: 'tool-error' as const,
|
|
136
|
+
toolCallId: part.toolCallId,
|
|
137
|
+
toolName: part.toolName as keyof TOOLS & string,
|
|
138
|
+
input: toolCall.input,
|
|
139
|
+
error: part.result,
|
|
140
|
+
providerExecuted: true,
|
|
141
|
+
dynamic: toolCall.dynamic,
|
|
142
|
+
...(part.providerMetadata != null
|
|
143
|
+
? { providerMetadata: part.providerMetadata }
|
|
144
|
+
: {}),
|
|
145
|
+
...(toolCall.toolMetadata != null
|
|
146
|
+
? { toolMetadata: toolCall.toolMetadata }
|
|
147
|
+
: {}),
|
|
148
|
+
} as TypedToolError<TOOLS>);
|
|
149
|
+
} else {
|
|
150
|
+
contentParts.push({
|
|
151
|
+
type: 'tool-result' as const,
|
|
152
|
+
toolCallId: part.toolCallId,
|
|
153
|
+
toolName: part.toolName as keyof TOOLS & string,
|
|
154
|
+
input: toolCall.input,
|
|
155
|
+
output: part.result,
|
|
156
|
+
providerExecuted: true,
|
|
157
|
+
dynamic: toolCall.dynamic,
|
|
158
|
+
...(part.providerMetadata != null
|
|
159
|
+
? { providerMetadata: part.providerMetadata }
|
|
160
|
+
: {}),
|
|
161
|
+
...(toolCall.toolMetadata != null
|
|
162
|
+
? { toolMetadata: toolCall.toolMetadata }
|
|
163
|
+
: {}),
|
|
164
|
+
} as TypedToolResult<TOOLS>);
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
case 'tool-approval-request': {
|
|
170
|
+
const toolCall = toolCalls.find(
|
|
171
|
+
toolCall => toolCall.toolCallId === part.toolCallId,
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
if (toolCall == null) {
|
|
175
|
+
throw new ToolCallNotFoundForApprovalError({
|
|
176
|
+
toolCallId: part.toolCallId,
|
|
177
|
+
approvalId: part.approvalId,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
contentParts.push({
|
|
182
|
+
type: 'tool-approval-request' as const,
|
|
183
|
+
approvalId: part.approvalId,
|
|
184
|
+
toolCall,
|
|
185
|
+
});
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
for (const toolOutput of toolOutputs) {
|
|
192
|
+
if (toolCallIdsWithApprovalResponses.has(toolOutput.toolCallId)) {
|
|
193
|
+
toolOutputsWithApprovalResponses.push(toolOutput);
|
|
194
|
+
} else {
|
|
195
|
+
toolOutputsWithoutApprovalResponses.push(toolOutput);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return [
|
|
200
|
+
...contentParts,
|
|
201
|
+
...toolOutputsWithoutApprovalResponses,
|
|
202
|
+
...toolApprovalRequests,
|
|
203
|
+
...toolApprovalResponses,
|
|
204
|
+
...toolOutputsWithApprovalResponses,
|
|
205
|
+
];
|
|
206
|
+
}
|