@ai-sdk/provider-utils 5.0.49 → 5.0.51
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 +14 -0
- package/dist/index.d.ts +25 -2
- package/dist/index.js +280 -37
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/delete-from-api.ts +1 -1
- package/src/get-from-api.ts +1 -1
- package/src/get-runtime-environment-user-agent.ts +6 -11
- package/src/post-multipart-stream-to-api.ts +1 -1
- package/src/post-to-api.ts +1 -1
- package/src/streaming-tool-call-argument-state.ts +100 -0
- package/src/streaming-tool-call-tracker.ts +313 -36
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ai-sdk/provider-utils
|
|
2
2
|
|
|
3
|
+
## 5.0.51
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c2511c1: fix: use standards-compliant User-Agent header
|
|
8
|
+
|
|
9
|
+
## 5.0.50
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- e3605f6: Fix streamed tool calls with missing, blank, or repeated IDs.
|
|
14
|
+
- Updated dependencies [525efc5]
|
|
15
|
+
- @ai-sdk/provider@4.0.19
|
|
16
|
+
|
|
3
17
|
## 5.0.49
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -2470,6 +2470,7 @@ interface StreamingToolCallDelta {
|
|
|
2470
2470
|
interface StreamingToolCallTrackerOptions<DELTA extends StreamingToolCallDelta = StreamingToolCallDelta> {
|
|
2471
2471
|
/**
|
|
2472
2472
|
* ID generator function for tool call IDs.
|
|
2473
|
+
* Blank or repeated outputs are converted to usable unique IDs.
|
|
2473
2474
|
* Defaults to the standard generateId.
|
|
2474
2475
|
*/
|
|
2475
2476
|
generateId?: () => string;
|
|
@@ -2501,13 +2502,15 @@ type StreamingToolCallTrackerController = Pick<TransformStreamDefaultController<
|
|
|
2501
2502
|
* emits tool-input-start/delta/end and tool-call events, and finalizes
|
|
2502
2503
|
* unfinished tool calls on flush.
|
|
2503
2504
|
*
|
|
2504
|
-
* Used by openai, openai-compatible, groq, deepseek,
|
|
2505
|
+
* Used by openai, openai-compatible, groq, deepseek, alibaba, mistral, and
|
|
2506
|
+
* moonshotai providers.
|
|
2505
2507
|
*/
|
|
2506
2508
|
declare class StreamingToolCallTracker<DELTA extends StreamingToolCallDelta = StreamingToolCallDelta> {
|
|
2507
2509
|
private toolCalls;
|
|
2508
2510
|
private toolCallsById;
|
|
2509
2511
|
private toolCallsByIndex;
|
|
2510
|
-
private
|
|
2512
|
+
private usedToolCallIds;
|
|
2513
|
+
private nextGeneratedIdSuffixes;
|
|
2511
2514
|
private readonly controller;
|
|
2512
2515
|
private readonly _generateId;
|
|
2513
2516
|
private readonly typeValidation;
|
|
@@ -2525,7 +2528,27 @@ declare class StreamingToolCallTracker<DELTA extends StreamingToolCallDelta = St
|
|
|
2525
2528
|
* flush handler to ensure all tool calls are properly completed.
|
|
2526
2529
|
*/
|
|
2527
2530
|
flush(): void;
|
|
2531
|
+
/**
|
|
2532
|
+
* Correlation precedence for streamed deltas:
|
|
2533
|
+
*
|
|
2534
|
+
* | ID evidence | index/name evidence | start evidence | resolution |
|
|
2535
|
+
* | --- | --- | --- | --- |
|
|
2536
|
+
* | known | matching | any | matching call, new call, or ambiguity |
|
|
2537
|
+
* | known | conflicting | named | new call |
|
|
2538
|
+
* | unseen | matching | structured start | new call |
|
|
2539
|
+
* | unseen | matching | continuation | matching call or ambiguity |
|
|
2540
|
+
* | absent | matching | any | matching call, new call, or ambiguity |
|
|
2541
|
+
* | absent | absent | named | new call |
|
|
2542
|
+
* | absent | absent | unnamed | sole unfinished call, new call, or ambiguity |
|
|
2543
|
+
*/
|
|
2544
|
+
private resolveToolCall;
|
|
2545
|
+
private filterToolCallsByName;
|
|
2546
|
+
private resolveMatchingToolCall;
|
|
2528
2547
|
private processNewToolCall;
|
|
2548
|
+
private associateWireId;
|
|
2549
|
+
private associateIndex;
|
|
2550
|
+
private createToolCallId;
|
|
2551
|
+
private getNonBlankString;
|
|
2529
2552
|
private processExistingToolCall;
|
|
2530
2553
|
private finishToolCall;
|
|
2531
2554
|
}
|
package/dist/index.js
CHANGED
|
@@ -404,19 +404,16 @@ function extractResponseHeaders(response) {
|
|
|
404
404
|
|
|
405
405
|
// src/get-runtime-environment-user-agent.ts
|
|
406
406
|
function getRuntimeEnvironmentUserAgent(globalThisAny = globalThis) {
|
|
407
|
-
if (globalThisAny.window) {
|
|
408
|
-
return `runtime/browser`;
|
|
409
|
-
}
|
|
410
407
|
if (globalThisAny.navigator?.userAgent) {
|
|
411
|
-
return
|
|
408
|
+
return globalThisAny.navigator.userAgent.toLowerCase();
|
|
412
409
|
}
|
|
413
410
|
if (globalThisAny.process?.versions?.node) {
|
|
414
|
-
return `
|
|
411
|
+
return `node.js/${globalThisAny.process.version}`;
|
|
415
412
|
}
|
|
416
413
|
if (globalThisAny.EdgeRuntime) {
|
|
417
|
-
return
|
|
414
|
+
return "vercel-edge";
|
|
418
415
|
}
|
|
419
|
-
return "
|
|
416
|
+
return "";
|
|
420
417
|
}
|
|
421
418
|
|
|
422
419
|
// src/handle-fetch-error.ts
|
|
@@ -503,7 +500,7 @@ function handleFetchError({
|
|
|
503
500
|
}
|
|
504
501
|
|
|
505
502
|
// src/version.ts
|
|
506
|
-
var VERSION = true ? "5.0.
|
|
503
|
+
var VERSION = true ? "5.0.51" : "0.0.0-test";
|
|
507
504
|
|
|
508
505
|
// src/normalize-headers.ts
|
|
509
506
|
function normalizeHeaders(headers) {
|
|
@@ -554,7 +551,7 @@ var deleteFromApi = async ({
|
|
|
554
551
|
method: "DELETE",
|
|
555
552
|
headers: withUserAgentSuffix(
|
|
556
553
|
headers,
|
|
557
|
-
`ai-sdk
|
|
554
|
+
`ai-sdk-provider-utils/${VERSION}`,
|
|
558
555
|
getRuntimeEnvironmentUserAgent()
|
|
559
556
|
),
|
|
560
557
|
signal: abortSignal
|
|
@@ -1549,7 +1546,7 @@ var getFromApi = async ({
|
|
|
1549
1546
|
const outgoingHeaders = credentialedOrigin !== void 0 && !isSameOrigin(url, credentialedOrigin) ? {} : headers;
|
|
1550
1547
|
const requestHeaders = withUserAgentSuffix(
|
|
1551
1548
|
outgoingHeaders,
|
|
1552
|
-
`ai-sdk
|
|
1549
|
+
`ai-sdk-provider-utils/${VERSION}`,
|
|
1553
1550
|
getRuntimeEnvironmentUserAgent()
|
|
1554
1551
|
);
|
|
1555
1552
|
const response = validateUrl ? await fetchWithValidatedRedirects({
|
|
@@ -3499,7 +3496,7 @@ var postMultipartStreamToApi = async ({
|
|
|
3499
3496
|
...headers,
|
|
3500
3497
|
"Content-Type": `multipart/form-data; boundary=${boundary}`
|
|
3501
3498
|
},
|
|
3502
|
-
`ai-sdk
|
|
3499
|
+
`ai-sdk-provider-utils/${VERSION}`,
|
|
3503
3500
|
getRuntimeEnvironmentUserAgent()
|
|
3504
3501
|
),
|
|
3505
3502
|
body: body.stream,
|
|
@@ -3618,7 +3615,7 @@ var postToApi = async ({
|
|
|
3618
3615
|
method: "POST",
|
|
3619
3616
|
headers: withUserAgentSuffix(
|
|
3620
3617
|
headers,
|
|
3621
|
-
`ai-sdk
|
|
3618
|
+
`ai-sdk-provider-utils/${VERSION}`,
|
|
3622
3619
|
getRuntimeEnvironmentUserAgent()
|
|
3623
3620
|
),
|
|
3624
3621
|
body: body.content,
|
|
@@ -4249,11 +4246,84 @@ function resolveSync(value) {
|
|
|
4249
4246
|
import {
|
|
4250
4247
|
InvalidResponseDataError
|
|
4251
4248
|
} from "@ai-sdk/provider";
|
|
4249
|
+
|
|
4250
|
+
// src/streaming-tool-call-argument-state.ts
|
|
4251
|
+
function startsWithStructuredValue(value) {
|
|
4252
|
+
if (typeof value !== "string") {
|
|
4253
|
+
return false;
|
|
4254
|
+
}
|
|
4255
|
+
const firstCharacter = value.trimStart()[0];
|
|
4256
|
+
return firstCharacter === "{" || firstCharacter === "[";
|
|
4257
|
+
}
|
|
4258
|
+
var StreamingToolCallArgumentState = class {
|
|
4259
|
+
constructor(initialValue = "") {
|
|
4260
|
+
this.structure = { kind: "undetermined" };
|
|
4261
|
+
this.append(initialValue);
|
|
4262
|
+
}
|
|
4263
|
+
get hasCompleteStructuredValue() {
|
|
4264
|
+
return this.structure.kind === "structured" && this.structure.complete === true;
|
|
4265
|
+
}
|
|
4266
|
+
append(delta) {
|
|
4267
|
+
let nextStructure = this.structure;
|
|
4268
|
+
for (const character of delta) {
|
|
4269
|
+
if (nextStructure.kind === "undetermined") {
|
|
4270
|
+
if (/\s/.test(character)) {
|
|
4271
|
+
continue;
|
|
4272
|
+
}
|
|
4273
|
+
if (character !== "{" && character !== "[") {
|
|
4274
|
+
nextStructure = { kind: "other" };
|
|
4275
|
+
continue;
|
|
4276
|
+
}
|
|
4277
|
+
nextStructure = {
|
|
4278
|
+
kind: "structured",
|
|
4279
|
+
stack: [character],
|
|
4280
|
+
inString: false,
|
|
4281
|
+
escaped: false,
|
|
4282
|
+
complete: false
|
|
4283
|
+
};
|
|
4284
|
+
continue;
|
|
4285
|
+
}
|
|
4286
|
+
if (nextStructure.kind !== "structured" || nextStructure.complete) {
|
|
4287
|
+
continue;
|
|
4288
|
+
}
|
|
4289
|
+
if (nextStructure.inString) {
|
|
4290
|
+
if (nextStructure.escaped) {
|
|
4291
|
+
nextStructure.escaped = false;
|
|
4292
|
+
} else if (character === "\\") {
|
|
4293
|
+
nextStructure.escaped = true;
|
|
4294
|
+
} else if (character === '"') {
|
|
4295
|
+
nextStructure.inString = false;
|
|
4296
|
+
}
|
|
4297
|
+
continue;
|
|
4298
|
+
}
|
|
4299
|
+
if (character === '"') {
|
|
4300
|
+
nextStructure.inString = true;
|
|
4301
|
+
} else if (character === "{" || character === "[") {
|
|
4302
|
+
nextStructure.stack.push(character);
|
|
4303
|
+
} else if (character === "}" || character === "]") {
|
|
4304
|
+
const expectedOpening = character === "}" ? "{" : "[";
|
|
4305
|
+
if (nextStructure.stack.at(-1) !== expectedOpening) {
|
|
4306
|
+
nextStructure = { kind: "other" };
|
|
4307
|
+
continue;
|
|
4308
|
+
}
|
|
4309
|
+
nextStructure.stack.pop();
|
|
4310
|
+
if (nextStructure.stack.length === 0) {
|
|
4311
|
+
nextStructure.complete = true;
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
}
|
|
4315
|
+
this.structure = nextStructure;
|
|
4316
|
+
}
|
|
4317
|
+
};
|
|
4318
|
+
|
|
4319
|
+
// src/streaming-tool-call-tracker.ts
|
|
4252
4320
|
var StreamingToolCallTracker = class {
|
|
4253
4321
|
constructor(controller, options = {}) {
|
|
4254
|
-
this.toolCalls =
|
|
4322
|
+
this.toolCalls = [];
|
|
4255
4323
|
this.toolCallsById = /* @__PURE__ */ new Map();
|
|
4256
4324
|
this.toolCallsByIndex = /* @__PURE__ */ new Map();
|
|
4325
|
+
this.usedToolCallIds = /* @__PURE__ */ new Set();
|
|
4326
|
+
this.nextGeneratedIdSuffixes = /* @__PURE__ */ new Map();
|
|
4257
4327
|
this.controller = controller;
|
|
4258
4328
|
this._generateId = options.generateId ?? generateId;
|
|
4259
4329
|
this.typeValidation = options.typeValidation ?? "none";
|
|
@@ -4266,30 +4336,162 @@ var StreamingToolCallTracker = class {
|
|
|
4266
4336
|
* events as appropriate.
|
|
4267
4337
|
*/
|
|
4268
4338
|
processDelta(toolCallDelta) {
|
|
4269
|
-
const
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4339
|
+
const wireName = toolCallDelta.function?.name;
|
|
4340
|
+
const hasBlankName = typeof wireName === "string" && wireName.trim().length === 0;
|
|
4341
|
+
const wireId = this.getNonBlankString(toolCallDelta.id);
|
|
4342
|
+
const name3 = this.getNonBlankString(wireName);
|
|
4343
|
+
const { index } = toolCallDelta;
|
|
4344
|
+
const resolution = this.resolveToolCall({
|
|
4345
|
+
wireId,
|
|
4346
|
+
index,
|
|
4347
|
+
name: name3,
|
|
4348
|
+
hasExplicitCallStart: name3 != null && startsWithStructuredValue(toolCallDelta.function?.arguments)
|
|
4349
|
+
});
|
|
4350
|
+
if (resolution.kind === "ambiguous") {
|
|
4351
|
+
return;
|
|
4352
|
+
}
|
|
4353
|
+
let toolCall;
|
|
4354
|
+
if (resolution.kind === "new") {
|
|
4355
|
+
if (hasBlankName) {
|
|
4356
|
+
return;
|
|
4357
|
+
}
|
|
4358
|
+
toolCall = this.processNewToolCall(toolCallDelta, {
|
|
4359
|
+
wireId,
|
|
4360
|
+
index,
|
|
4361
|
+
name: name3
|
|
4362
|
+
});
|
|
4273
4363
|
} else {
|
|
4364
|
+
toolCall = resolution.toolCall;
|
|
4365
|
+
if (wireId != null) {
|
|
4366
|
+
this.associateWireId(toolCall, wireId);
|
|
4367
|
+
}
|
|
4274
4368
|
this.processExistingToolCall(toolCall, toolCallDelta);
|
|
4275
4369
|
}
|
|
4276
4370
|
if (index != null) {
|
|
4277
|
-
this.
|
|
4371
|
+
this.associateIndex(toolCall, index);
|
|
4278
4372
|
}
|
|
4279
|
-
this.latestToolCall = toolCall;
|
|
4280
4373
|
}
|
|
4281
4374
|
/**
|
|
4282
4375
|
* Finalize any unfinished tool calls. Should be called during the stream's
|
|
4283
4376
|
* flush handler to ensure all tool calls are properly completed.
|
|
4284
4377
|
*/
|
|
4285
4378
|
flush() {
|
|
4286
|
-
|
|
4379
|
+
const toolCalls = this.toolCalls.every((toolCall) => toolCall.index != null) ? [...this.toolCalls].sort(
|
|
4380
|
+
(a, b) => a.index - b.index || a.sequence - b.sequence
|
|
4381
|
+
) : this.toolCalls;
|
|
4382
|
+
for (const toolCall of toolCalls) {
|
|
4287
4383
|
if (!toolCall.hasFinished) {
|
|
4288
4384
|
this.finishToolCall(toolCall);
|
|
4289
4385
|
}
|
|
4290
4386
|
}
|
|
4291
4387
|
}
|
|
4292
|
-
|
|
4388
|
+
/**
|
|
4389
|
+
* Correlation precedence for streamed deltas:
|
|
4390
|
+
*
|
|
4391
|
+
* | ID evidence | index/name evidence | start evidence | resolution |
|
|
4392
|
+
* | --- | --- | --- | --- |
|
|
4393
|
+
* | known | matching | any | matching call, new call, or ambiguity |
|
|
4394
|
+
* | known | conflicting | named | new call |
|
|
4395
|
+
* | unseen | matching | structured start | new call |
|
|
4396
|
+
* | unseen | matching | continuation | matching call or ambiguity |
|
|
4397
|
+
* | absent | matching | any | matching call, new call, or ambiguity |
|
|
4398
|
+
* | absent | absent | named | new call |
|
|
4399
|
+
* | absent | absent | unnamed | sole unfinished call, new call, or ambiguity |
|
|
4400
|
+
*/
|
|
4401
|
+
resolveToolCall({
|
|
4402
|
+
wireId,
|
|
4403
|
+
index,
|
|
4404
|
+
name: name3,
|
|
4405
|
+
hasExplicitCallStart
|
|
4406
|
+
}) {
|
|
4407
|
+
const indexedToolCalls = index != null ? this.toolCallsByIndex.get(index) : void 0;
|
|
4408
|
+
const matchingIndexedToolCalls = this.filterToolCallsByName(
|
|
4409
|
+
indexedToolCalls,
|
|
4410
|
+
name3
|
|
4411
|
+
);
|
|
4412
|
+
if (wireId != null) {
|
|
4413
|
+
const toolCallsWithId = this.toolCallsById.get(wireId);
|
|
4414
|
+
if (toolCallsWithId != null) {
|
|
4415
|
+
if (index != null) {
|
|
4416
|
+
const matchingToolCalls = matchingIndexedToolCalls.filter(
|
|
4417
|
+
(toolCall) => toolCallsWithId.has(toolCall)
|
|
4418
|
+
);
|
|
4419
|
+
const matchingToolCall = this.resolveMatchingToolCall(
|
|
4420
|
+
matchingToolCalls,
|
|
4421
|
+
hasExplicitCallStart
|
|
4422
|
+
);
|
|
4423
|
+
if (matchingToolCall.kind !== "new") {
|
|
4424
|
+
return matchingToolCall;
|
|
4425
|
+
}
|
|
4426
|
+
if (name3 != null) {
|
|
4427
|
+
return { kind: "new" };
|
|
4428
|
+
}
|
|
4429
|
+
if (indexedToolCalls != null) {
|
|
4430
|
+
return { kind: "ambiguous" };
|
|
4431
|
+
}
|
|
4432
|
+
return this.resolveMatchingToolCall([...toolCallsWithId], false);
|
|
4433
|
+
}
|
|
4434
|
+
if (name3 != null) {
|
|
4435
|
+
const matchingToolCalls = [...toolCallsWithId].filter(
|
|
4436
|
+
(toolCall) => toolCall.function.name === name3
|
|
4437
|
+
);
|
|
4438
|
+
return this.resolveMatchingToolCall(
|
|
4439
|
+
matchingToolCalls,
|
|
4440
|
+
hasExplicitCallStart
|
|
4441
|
+
);
|
|
4442
|
+
}
|
|
4443
|
+
return this.resolveMatchingToolCall([...toolCallsWithId], false);
|
|
4444
|
+
}
|
|
4445
|
+
if (matchingIndexedToolCalls.length > 0) {
|
|
4446
|
+
return hasExplicitCallStart ? { kind: "new" } : this.resolveMatchingToolCall(matchingIndexedToolCalls, false);
|
|
4447
|
+
}
|
|
4448
|
+
return { kind: "new" };
|
|
4449
|
+
}
|
|
4450
|
+
if (indexedToolCalls != null) {
|
|
4451
|
+
return this.resolveMatchingToolCall(
|
|
4452
|
+
matchingIndexedToolCalls,
|
|
4453
|
+
hasExplicitCallStart
|
|
4454
|
+
);
|
|
4455
|
+
}
|
|
4456
|
+
if (name3 != null) {
|
|
4457
|
+
return { kind: "new" };
|
|
4458
|
+
}
|
|
4459
|
+
const unfinishedToolCalls = this.toolCalls.filter(
|
|
4460
|
+
(toolCall) => !toolCall.hasFinished
|
|
4461
|
+
);
|
|
4462
|
+
if (unfinishedToolCalls.length === 1) {
|
|
4463
|
+
return { kind: "existing", toolCall: unfinishedToolCalls[0] };
|
|
4464
|
+
}
|
|
4465
|
+
return unfinishedToolCalls.length > 1 ? { kind: "ambiguous" } : { kind: "new" };
|
|
4466
|
+
}
|
|
4467
|
+
filterToolCallsByName(toolCalls, name3) {
|
|
4468
|
+
if (toolCalls == null) {
|
|
4469
|
+
return [];
|
|
4470
|
+
}
|
|
4471
|
+
return [...toolCalls].filter(
|
|
4472
|
+
(toolCall) => name3 == null || toolCall.function.name === name3
|
|
4473
|
+
);
|
|
4474
|
+
}
|
|
4475
|
+
resolveMatchingToolCall(toolCalls, hasExplicitCallStart) {
|
|
4476
|
+
if (toolCalls.length === 0) {
|
|
4477
|
+
return { kind: "new" };
|
|
4478
|
+
}
|
|
4479
|
+
if (!hasExplicitCallStart) {
|
|
4480
|
+
return toolCalls.length === 1 ? { kind: "existing", toolCall: toolCalls[0] } : { kind: "ambiguous" };
|
|
4481
|
+
}
|
|
4482
|
+
const continuableToolCalls = toolCalls.filter(
|
|
4483
|
+
(toolCall) => !toolCall.argumentState.hasCompleteStructuredValue
|
|
4484
|
+
);
|
|
4485
|
+
if (continuableToolCalls.length === 1) {
|
|
4486
|
+
return { kind: "existing", toolCall: continuableToolCalls[0] };
|
|
4487
|
+
}
|
|
4488
|
+
return continuableToolCalls.length > 1 ? { kind: "ambiguous" } : { kind: "new" };
|
|
4489
|
+
}
|
|
4490
|
+
processNewToolCall(toolCallDelta, {
|
|
4491
|
+
wireId,
|
|
4492
|
+
index,
|
|
4493
|
+
name: name3
|
|
4494
|
+
}) {
|
|
4293
4495
|
if (this.typeValidation === "required") {
|
|
4294
4496
|
if (toolCallDelta.type !== "function") {
|
|
4295
4497
|
throw new InvalidResponseDataError({
|
|
@@ -4305,37 +4507,36 @@ var StreamingToolCallTracker = class {
|
|
|
4305
4507
|
});
|
|
4306
4508
|
}
|
|
4307
4509
|
}
|
|
4308
|
-
if (
|
|
4309
|
-
throw new InvalidResponseDataError({
|
|
4310
|
-
data: toolCallDelta,
|
|
4311
|
-
message: `Expected 'id' to be a string.`
|
|
4312
|
-
});
|
|
4313
|
-
}
|
|
4314
|
-
if (toolCallDelta.function?.name == null) {
|
|
4510
|
+
if (name3 == null) {
|
|
4315
4511
|
throw new InvalidResponseDataError({
|
|
4316
4512
|
data: toolCallDelta,
|
|
4317
4513
|
message: `Expected 'function.name' to be a string.`
|
|
4318
4514
|
});
|
|
4319
4515
|
}
|
|
4516
|
+
const id = this.createToolCallId(wireId);
|
|
4320
4517
|
this.controller.enqueue({
|
|
4321
4518
|
type: "tool-input-start",
|
|
4322
|
-
id
|
|
4323
|
-
toolName:
|
|
4519
|
+
id,
|
|
4520
|
+
toolName: name3
|
|
4324
4521
|
});
|
|
4325
4522
|
const metadata = this.extractMetadata?.(toolCallDelta);
|
|
4523
|
+
const initialArguments = toolCallDelta.function?.arguments ?? "";
|
|
4326
4524
|
const toolCall = {
|
|
4327
|
-
id
|
|
4525
|
+
id,
|
|
4526
|
+
index: index ?? void 0,
|
|
4527
|
+
sequence: this.toolCalls.length,
|
|
4328
4528
|
type: "function",
|
|
4329
4529
|
function: {
|
|
4330
|
-
name:
|
|
4331
|
-
arguments:
|
|
4530
|
+
name: name3,
|
|
4531
|
+
arguments: initialArguments
|
|
4332
4532
|
},
|
|
4533
|
+
argumentState: new StreamingToolCallArgumentState(initialArguments),
|
|
4333
4534
|
hasFinished: false,
|
|
4334
4535
|
metadata
|
|
4335
4536
|
};
|
|
4336
|
-
this.toolCalls.
|
|
4337
|
-
if (
|
|
4338
|
-
this.
|
|
4537
|
+
this.toolCalls.push(toolCall);
|
|
4538
|
+
if (wireId != null) {
|
|
4539
|
+
this.associateWireId(toolCall, wireId);
|
|
4339
4540
|
}
|
|
4340
4541
|
if (toolCall.function.arguments.length > 0) {
|
|
4341
4542
|
this.controller.enqueue({
|
|
@@ -4346,11 +4547,53 @@ var StreamingToolCallTracker = class {
|
|
|
4346
4547
|
}
|
|
4347
4548
|
return toolCall;
|
|
4348
4549
|
}
|
|
4550
|
+
associateWireId(toolCall, wireId) {
|
|
4551
|
+
let toolCallsWithId = this.toolCallsById.get(wireId);
|
|
4552
|
+
if (toolCallsWithId == null) {
|
|
4553
|
+
toolCallsWithId = /* @__PURE__ */ new Set();
|
|
4554
|
+
this.toolCallsById.set(wireId, toolCallsWithId);
|
|
4555
|
+
}
|
|
4556
|
+
toolCallsWithId.add(toolCall);
|
|
4557
|
+
}
|
|
4558
|
+
associateIndex(toolCall, index) {
|
|
4559
|
+
let toolCallsWithIndex = this.toolCallsByIndex.get(index);
|
|
4560
|
+
if (toolCallsWithIndex == null) {
|
|
4561
|
+
toolCallsWithIndex = /* @__PURE__ */ new Set();
|
|
4562
|
+
this.toolCallsByIndex.set(index, toolCallsWithIndex);
|
|
4563
|
+
}
|
|
4564
|
+
toolCallsWithIndex.add(toolCall);
|
|
4565
|
+
}
|
|
4566
|
+
createToolCallId(wireId) {
|
|
4567
|
+
if (wireId != null && !this.usedToolCallIds.has(wireId)) {
|
|
4568
|
+
this.usedToolCallIds.add(wireId);
|
|
4569
|
+
return wireId;
|
|
4570
|
+
}
|
|
4571
|
+
const generatedId = this.getNonBlankString(this._generateId()) ?? "tool-call";
|
|
4572
|
+
if (!this.usedToolCallIds.has(generatedId)) {
|
|
4573
|
+
this.usedToolCallIds.add(generatedId);
|
|
4574
|
+
return generatedId;
|
|
4575
|
+
}
|
|
4576
|
+
const initialSuffix = this.nextGeneratedIdSuffixes.get(generatedId) ?? 1;
|
|
4577
|
+
const maximumSuffix = initialSuffix + this.usedToolCallIds.size;
|
|
4578
|
+
for (let suffix = initialSuffix; suffix <= maximumSuffix; suffix++) {
|
|
4579
|
+
const suffixedId = `${generatedId}-${suffix}`;
|
|
4580
|
+
if (!this.usedToolCallIds.has(suffixedId)) {
|
|
4581
|
+
this.usedToolCallIds.add(suffixedId);
|
|
4582
|
+
this.nextGeneratedIdSuffixes.set(generatedId, suffix + 1);
|
|
4583
|
+
return suffixedId;
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
throw new Error("Failed to create a unique tool call ID.");
|
|
4587
|
+
}
|
|
4588
|
+
getNonBlankString(value) {
|
|
4589
|
+
return value != null && value.trim().length > 0 ? value : void 0;
|
|
4590
|
+
}
|
|
4349
4591
|
processExistingToolCall(toolCall, toolCallDelta) {
|
|
4350
4592
|
if (toolCall.hasFinished) {
|
|
4351
4593
|
return;
|
|
4352
4594
|
}
|
|
4353
4595
|
if (toolCallDelta.function?.arguments != null) {
|
|
4596
|
+
toolCall.argumentState.append(toolCallDelta.function.arguments);
|
|
4354
4597
|
toolCall.function.arguments += toolCallDelta.function.arguments;
|
|
4355
4598
|
this.controller.enqueue({
|
|
4356
4599
|
type: "tool-input-delta",
|
|
@@ -4369,7 +4612,7 @@ var StreamingToolCallTracker = class {
|
|
|
4369
4612
|
);
|
|
4370
4613
|
this.controller.enqueue({
|
|
4371
4614
|
type: "tool-call",
|
|
4372
|
-
toolCallId: toolCall.id
|
|
4615
|
+
toolCallId: toolCall.id,
|
|
4373
4616
|
toolName: toolCall.function.name,
|
|
4374
4617
|
input: toolCall.function.arguments,
|
|
4375
4618
|
...providerMetadata ? { providerMetadata } : {}
|