Files
maka/patches/@ai-sdk+provider-utils+5.0.28.patch
agent-radar 7be535059e
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 19:05:14 +08:00

174 lines
7.2 KiB
Diff

diff --git a/node_modules/@ai-sdk/provider-utils/dist/index.js b/node_modules/@ai-sdk/provider-utils/dist/index.js
index 7de9a2a..c3c87d8 100644
--- a/node_modules/@ai-sdk/provider-utils/dist/index.js
+++ b/node_modules/@ai-sdk/provider-utils/dist/index.js
@@ -3745,11 +3745,12 @@ function resolveSync(value) {
import {
InvalidResponseDataError
} from "@ai-sdk/provider";
+function absentIfBlank(value) {
+ return value != null && value.trim() !== "" ? value : void 0;
+}
var StreamingToolCallTracker = class {
constructor(controller, options = {}) {
- this.toolCalls = /* @__PURE__ */ new Set();
- this.toolCallsById = /* @__PURE__ */ new Map();
- this.toolCallsByIndex = /* @__PURE__ */ new Map();
+ this.toolCalls = [];
var _a3, _b3;
this.controller = controller;
this._generateId = (_a3 = options.generateId) != null ? _a3 : generateId;
@@ -3763,31 +3764,90 @@ var StreamingToolCallTracker = class {
* events as appropriate.
*/
processDelta(toolCallDelta) {
- const { id, index } = toolCallDelta;
- let toolCall = id != null && id.length > 0 ? this.toolCallsById.get(id) : index != null ? this.toolCallsByIndex.get(index) : this.latestToolCall;
+ var _a3;
+ const wireId = absentIfBlank(toolCallDelta.id);
+ const wireIndex = toolCallDelta.index != null ? toolCallDelta.index : void 0;
+ const wireName = absentIfBlank((_a3 = toolCallDelta.function) == null ? void 0 : _a3.name);
+ let toolCall = this.findByAlias(wireId, wireIndex, wireName);
+ if (toolCall == null && this.toolCalls.length === 1) {
+ const only = this.toolCalls[0];
+ if ((wireName === void 0 || only.function.name === wireName) && (wireId === void 0 || only.wireId === void 0) && (wireIndex === void 0 || only.index === void 0)) {
+ toolCall = only;
+ }
+ }
if (toolCall == null) {
- toolCall = this.processNewToolCall(toolCallDelta);
- } else {
- this.processExistingToolCall(toolCall, toolCallDelta);
+ this.processNewToolCall(toolCallDelta, wireId, wireIndex, wireName);
+ return;
}
- if (index != null) {
- this.toolCallsByIndex.set(index, toolCall);
+ if (wireId !== void 0) {
+ toolCall.wireId = wireId;
}
- this.latestToolCall = toolCall;
+ if (wireIndex !== void 0) {
+ toolCall.index = wireIndex;
+ }
+ this.processExistingToolCall(toolCall, toolCallDelta);
+ }
+ /**
+ * The most recent tool call this delta's aliases claim. An alias the candidate has not
+ * seen yet cannot disagree, so it neither matches nor rejects; at least one alias must
+ * actually match, which is why a delta carrying only arguments never resolves here.
+ *
+ * Scanning stops at the first call an alias claims, and a `function.name` that disagrees
+ * with that call rejects the delta rather than letting the scan continue. Continuing past
+ * it reaches a call whose claim on the alias a later call has already superseded, which
+ * files a whole new call as a continuation of one two positions back.
+ */
+ /**
+ * Whether an alias the delta carries, but the matched call has not claimed, belongs to some
+ * other call. The delta then addresses two calls at once, which resolves to neither — the
+ * other claimant cannot be it either, because the alias it did match rejected that call
+ * already. Agreement has to be read across the record set: a candidate missing the alias is
+ * not contradicted by it on its own, and reading only the candidate let exactly this
+ * contradiction resolve, silently, onto a call the gateway never addressed.
+ */
+ claimedByAnother(candidate, alias, value) {
+ return value !== void 0 && candidate[alias] === void 0 && this.toolCalls.some((other) => other !== candidate && other[alias] === value);
+ }
+ findByAlias(wireId, wireIndex, wireName) {
+ for (let position = this.toolCalls.length - 1; position >= 0; position--) {
+ const candidate = this.toolCalls[position];
+ let matched = false;
+ if (wireIndex !== void 0 && candidate.index !== void 0) {
+ if (candidate.index !== wireIndex) {
+ continue;
+ }
+ matched = true;
+ }
+ if (wireId !== void 0 && candidate.wireId !== void 0) {
+ if (candidate.wireId !== wireId) {
+ continue;
+ }
+ matched = true;
+ }
+ if (matched) {
+ if (this.claimedByAnother(candidate, "wireId", wireId) || this.claimedByAnother(candidate, "index", wireIndex)) {
+ return void 0;
+ }
+ return wireName !== void 0 && candidate.function.name !== wireName ? void 0 : candidate;
+ }
+ }
+ return void 0;
}
/**
* Finalize any unfinished tool calls. Should be called during the stream's
* flush handler to ensure all tool calls are properly completed.
*/
flush() {
- for (const toolCall of this.toolCalls) {
+ const indices = this.toolCalls.map((toolCall) => toolCall.index);
+ const ordered = indices.every((index) => index !== void 0) && new Set(indices).size === indices.length ? [...this.toolCalls].sort((a, b) => a.index - b.index) : this.toolCalls;
+ for (const toolCall of ordered) {
if (!toolCall.hasFinished) {
this.finishToolCall(toolCall);
}
}
}
- processNewToolCall(toolCallDelta) {
- var _a3, _b3, _c;
+ processNewToolCall(toolCallDelta, wireId, wireIndex, wireName) {
+ var _a3, _b3;
if (this.typeValidation === "required") {
if (toolCallDelta.type !== "function") {
throw new InvalidResponseDataError({
@@ -3803,38 +3863,32 @@ var StreamingToolCallTracker = class {
});
}
}
- if (toolCallDelta.id == null) {
- throw new InvalidResponseDataError({
- data: toolCallDelta,
- message: `Expected 'id' to be a string.`
- });
- }
- if (((_a3 = toolCallDelta.function) == null ? void 0 : _a3.name) == null) {
+ if (wireName === void 0) {
throw new InvalidResponseDataError({
data: toolCallDelta,
message: `Expected 'function.name' to be a string.`
});
}
+ const mintedId = wireId === void 0 || this.toolCalls.some((candidate) => candidate.id === wireId) ? this._generateId() : wireId;
this.controller.enqueue({
type: "tool-input-start",
- id: toolCallDelta.id,
- toolName: toolCallDelta.function.name
+ id: mintedId,
+ toolName: wireName
});
- const metadata = (_b3 = this.extractMetadata) == null ? void 0 : _b3.call(this, toolCallDelta);
+ const metadata = (_a3 = this.extractMetadata) == null ? void 0 : _a3.call(this, toolCallDelta);
const toolCall = {
- id: toolCallDelta.id,
+ id: mintedId,
type: "function",
function: {
- name: toolCallDelta.function.name,
- arguments: (_c = toolCallDelta.function.arguments) != null ? _c : ""
+ name: wireName,
+ arguments: (_b3 = toolCallDelta.function.arguments) != null ? _b3 : ""
},
hasFinished: false,
- metadata
+ metadata,
+ wireId,
+ index: wireIndex
};
- this.toolCalls.add(toolCall);
- if (toolCall.id.length > 0) {
- this.toolCallsById.set(toolCall.id, toolCall);
- }
+ this.toolCalls.push(toolCall);
if (toolCall.function.arguments.length > 0) {
this.controller.enqueue({
type: "tool-input-delta",