@ai-sdk/provider-utils 3.0.39 → 3.0.40

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/dist/index.mjs CHANGED
@@ -708,7 +708,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
708
708
  }
709
709
 
710
710
  // src/version.ts
711
- var VERSION = true ? "3.0.39" : "0.0.0-test";
711
+ var VERSION = true ? "3.0.40" : "0.0.0-test";
712
712
 
713
713
  // src/get-from-api.ts
714
714
  var getOriginalFetch = () => globalThis.fetch;
@@ -2899,6 +2899,367 @@ function asSchema(schema) {
2899
2899
  }) : isSchema(schema) ? schema : typeof schema === "function" ? schema() : zodSchema(schema);
2900
2900
  }
2901
2901
 
2902
+ // src/streaming-tool-call-tracker.ts
2903
+ import {
2904
+ InvalidResponseDataError
2905
+ } from "@ai-sdk/provider";
2906
+
2907
+ // src/streaming-tool-call-argument-state.ts
2908
+ function startsWithStructuredValue(value) {
2909
+ if (typeof value !== "string") {
2910
+ return false;
2911
+ }
2912
+ const firstCharacter = value.trimStart()[0];
2913
+ return firstCharacter === "{" || firstCharacter === "[";
2914
+ }
2915
+ var StreamingToolCallArgumentState = class {
2916
+ constructor(initialValue = "") {
2917
+ this.structure = { kind: "undetermined" };
2918
+ this.append(initialValue);
2919
+ }
2920
+ get hasCompleteStructuredValue() {
2921
+ return this.structure.kind === "structured" && this.structure.complete === true;
2922
+ }
2923
+ append(delta) {
2924
+ let nextStructure = this.structure;
2925
+ for (const character of delta) {
2926
+ if (nextStructure.kind === "undetermined") {
2927
+ if (/\s/.test(character)) {
2928
+ continue;
2929
+ }
2930
+ if (character !== "{" && character !== "[") {
2931
+ nextStructure = { kind: "other" };
2932
+ continue;
2933
+ }
2934
+ nextStructure = {
2935
+ kind: "structured",
2936
+ stack: [character],
2937
+ inString: false,
2938
+ escaped: false,
2939
+ complete: false
2940
+ };
2941
+ continue;
2942
+ }
2943
+ if (nextStructure.kind !== "structured" || nextStructure.complete) {
2944
+ continue;
2945
+ }
2946
+ if (nextStructure.inString) {
2947
+ if (nextStructure.escaped) {
2948
+ nextStructure.escaped = false;
2949
+ } else if (character === "\\") {
2950
+ nextStructure.escaped = true;
2951
+ } else if (character === '"') {
2952
+ nextStructure.inString = false;
2953
+ }
2954
+ continue;
2955
+ }
2956
+ if (character === '"') {
2957
+ nextStructure.inString = true;
2958
+ } else if (character === "{" || character === "[") {
2959
+ nextStructure.stack.push(character);
2960
+ } else if (character === "}" || character === "]") {
2961
+ const expectedOpening = character === "}" ? "{" : "[";
2962
+ if (nextStructure.stack[nextStructure.stack.length - 1] !== expectedOpening) {
2963
+ nextStructure = { kind: "other" };
2964
+ continue;
2965
+ }
2966
+ nextStructure.stack.pop();
2967
+ if (nextStructure.stack.length === 0) {
2968
+ nextStructure.complete = true;
2969
+ }
2970
+ }
2971
+ }
2972
+ this.structure = nextStructure;
2973
+ }
2974
+ };
2975
+
2976
+ // src/streaming-tool-call-tracker.ts
2977
+ var StreamingToolCallTracker = class {
2978
+ constructor(controller, options = {}) {
2979
+ this.toolCalls = [];
2980
+ this.toolCallsById = /* @__PURE__ */ new Map();
2981
+ this.toolCallsByIndex = /* @__PURE__ */ new Map();
2982
+ this.usedToolCallIds = /* @__PURE__ */ new Set();
2983
+ this.nextGeneratedIdSuffixes = /* @__PURE__ */ new Map();
2984
+ var _a2, _b2;
2985
+ this.controller = controller;
2986
+ this._generateId = (_a2 = options.generateId) != null ? _a2 : generateId;
2987
+ this.typeValidation = (_b2 = options.typeValidation) != null ? _b2 : "none";
2988
+ this.extractMetadata = options.extractMetadata;
2989
+ this.buildToolCallProviderMetadata = options.buildToolCallProviderMetadata;
2990
+ }
2991
+ processDelta(toolCallDelta) {
2992
+ var _a2, _b2;
2993
+ const wireName = (_a2 = toolCallDelta.function) == null ? void 0 : _a2.name;
2994
+ const hasBlankName = typeof wireName === "string" && wireName.trim().length === 0;
2995
+ const wireId = this.getNonBlankString(toolCallDelta.id);
2996
+ const name2 = this.getNonBlankString(wireName);
2997
+ const { index } = toolCallDelta;
2998
+ const resolution = this.resolveToolCall({
2999
+ wireId,
3000
+ index,
3001
+ name: name2,
3002
+ hasExplicitCallStart: name2 != null && startsWithStructuredValue((_b2 = toolCallDelta.function) == null ? void 0 : _b2.arguments)
3003
+ });
3004
+ if (resolution.kind === "ambiguous") {
3005
+ return;
3006
+ }
3007
+ let toolCall;
3008
+ if (resolution.kind === "new") {
3009
+ if (hasBlankName) {
3010
+ return;
3011
+ }
3012
+ toolCall = this.processNewToolCall(toolCallDelta, {
3013
+ wireId,
3014
+ index,
3015
+ name: name2
3016
+ });
3017
+ } else {
3018
+ toolCall = resolution.toolCall;
3019
+ if (wireId != null) {
3020
+ this.associateWireId(toolCall, wireId);
3021
+ }
3022
+ this.processExistingToolCall(toolCall, toolCallDelta);
3023
+ }
3024
+ if (index != null) {
3025
+ this.associateIndex(toolCall, index);
3026
+ }
3027
+ }
3028
+ flush() {
3029
+ const toolCalls = this.toolCalls.every((toolCall) => toolCall.index != null) ? [...this.toolCalls].sort(
3030
+ (a, b) => a.index - b.index || a.sequence - b.sequence
3031
+ ) : this.toolCalls;
3032
+ for (const toolCall of toolCalls) {
3033
+ if (!toolCall.hasFinished) {
3034
+ this.finishToolCall(toolCall);
3035
+ }
3036
+ }
3037
+ }
3038
+ resolveToolCall({
3039
+ wireId,
3040
+ index,
3041
+ name: name2,
3042
+ hasExplicitCallStart
3043
+ }) {
3044
+ const indexedToolCalls = index != null ? this.toolCallsByIndex.get(index) : void 0;
3045
+ const matchingIndexedToolCalls = this.filterToolCallsByName(
3046
+ indexedToolCalls,
3047
+ name2
3048
+ );
3049
+ if (wireId != null) {
3050
+ const toolCallsWithId = this.toolCallsById.get(wireId);
3051
+ if (toolCallsWithId != null) {
3052
+ if (index != null) {
3053
+ const matchingToolCalls = matchingIndexedToolCalls.filter(
3054
+ (toolCall) => toolCallsWithId.has(toolCall)
3055
+ );
3056
+ const matchingToolCall = this.resolveMatchingToolCall(
3057
+ matchingToolCalls,
3058
+ hasExplicitCallStart
3059
+ );
3060
+ if (matchingToolCall.kind !== "new") {
3061
+ return matchingToolCall;
3062
+ }
3063
+ if (name2 != null) {
3064
+ return { kind: "new" };
3065
+ }
3066
+ if (indexedToolCalls != null) {
3067
+ return { kind: "ambiguous" };
3068
+ }
3069
+ return this.resolveMatchingToolCall([...toolCallsWithId], false);
3070
+ }
3071
+ if (name2 != null) {
3072
+ const matchingToolCalls = [...toolCallsWithId].filter(
3073
+ (toolCall) => toolCall.function.name === name2
3074
+ );
3075
+ return this.resolveMatchingToolCall(
3076
+ matchingToolCalls,
3077
+ hasExplicitCallStart
3078
+ );
3079
+ }
3080
+ return this.resolveMatchingToolCall([...toolCallsWithId], false);
3081
+ }
3082
+ if (matchingIndexedToolCalls.length > 0) {
3083
+ return hasExplicitCallStart ? { kind: "new" } : this.resolveMatchingToolCall(matchingIndexedToolCalls, false);
3084
+ }
3085
+ return { kind: "new" };
3086
+ }
3087
+ if (indexedToolCalls != null) {
3088
+ return this.resolveMatchingToolCall(
3089
+ matchingIndexedToolCalls,
3090
+ hasExplicitCallStart
3091
+ );
3092
+ }
3093
+ if (name2 != null) {
3094
+ return { kind: "new" };
3095
+ }
3096
+ const unfinishedToolCalls = this.toolCalls.filter(
3097
+ (toolCall) => !toolCall.hasFinished
3098
+ );
3099
+ if (unfinishedToolCalls.length === 1) {
3100
+ return { kind: "existing", toolCall: unfinishedToolCalls[0] };
3101
+ }
3102
+ return unfinishedToolCalls.length > 1 ? { kind: "ambiguous" } : { kind: "new" };
3103
+ }
3104
+ filterToolCallsByName(toolCalls, name2) {
3105
+ if (toolCalls == null) {
3106
+ return [];
3107
+ }
3108
+ return [...toolCalls].filter(
3109
+ (toolCall) => name2 == null || toolCall.function.name === name2
3110
+ );
3111
+ }
3112
+ resolveMatchingToolCall(toolCalls, hasExplicitCallStart) {
3113
+ if (toolCalls.length === 0) {
3114
+ return { kind: "new" };
3115
+ }
3116
+ if (!hasExplicitCallStart) {
3117
+ return toolCalls.length === 1 ? { kind: "existing", toolCall: toolCalls[0] } : { kind: "ambiguous" };
3118
+ }
3119
+ const continuableToolCalls = toolCalls.filter(
3120
+ (toolCall) => !toolCall.argumentState.hasCompleteStructuredValue
3121
+ );
3122
+ if (continuableToolCalls.length === 1) {
3123
+ return { kind: "existing", toolCall: continuableToolCalls[0] };
3124
+ }
3125
+ return continuableToolCalls.length > 1 ? { kind: "ambiguous" } : { kind: "new" };
3126
+ }
3127
+ processNewToolCall(toolCallDelta, {
3128
+ wireId,
3129
+ index,
3130
+ name: name2
3131
+ }) {
3132
+ var _a2, _b2, _c, _d, _e;
3133
+ if (this.typeValidation === "required") {
3134
+ if (toolCallDelta.type !== "function") {
3135
+ throw new InvalidResponseDataError({
3136
+ data: toolCallDelta,
3137
+ message: `Expected 'function' type.`
3138
+ });
3139
+ }
3140
+ } else if (this.typeValidation === "if-present") {
3141
+ if (toolCallDelta.type != null && toolCallDelta.type !== "function") {
3142
+ throw new InvalidResponseDataError({
3143
+ data: toolCallDelta,
3144
+ message: `Expected 'function' type.`
3145
+ });
3146
+ }
3147
+ }
3148
+ if (name2 == null) {
3149
+ throw new InvalidResponseDataError({
3150
+ data: toolCallDelta,
3151
+ message: `Expected 'function.name' to be a string.`
3152
+ });
3153
+ }
3154
+ const id = this.createToolCallId(wireId);
3155
+ this.controller.enqueue({
3156
+ type: "tool-input-start",
3157
+ id,
3158
+ toolName: name2
3159
+ });
3160
+ const toolCall = {
3161
+ id,
3162
+ index: index != null ? index : void 0,
3163
+ sequence: this.toolCalls.length,
3164
+ type: "function",
3165
+ function: {
3166
+ name: name2,
3167
+ arguments: (_b2 = (_a2 = toolCallDelta.function) == null ? void 0 : _a2.arguments) != null ? _b2 : ""
3168
+ },
3169
+ argumentState: new StreamingToolCallArgumentState(
3170
+ (_d = (_c = toolCallDelta.function) == null ? void 0 : _c.arguments) != null ? _d : ""
3171
+ ),
3172
+ hasFinished: false,
3173
+ metadata: (_e = this.extractMetadata) == null ? void 0 : _e.call(this, toolCallDelta)
3174
+ };
3175
+ this.toolCalls.push(toolCall);
3176
+ if (wireId != null) {
3177
+ this.associateWireId(toolCall, wireId);
3178
+ }
3179
+ if (toolCall.function.arguments.length > 0) {
3180
+ this.controller.enqueue({
3181
+ type: "tool-input-delta",
3182
+ id: toolCall.id,
3183
+ delta: toolCall.function.arguments
3184
+ });
3185
+ }
3186
+ return toolCall;
3187
+ }
3188
+ associateWireId(toolCall, wireId) {
3189
+ let toolCallsWithId = this.toolCallsById.get(wireId);
3190
+ if (toolCallsWithId == null) {
3191
+ toolCallsWithId = /* @__PURE__ */ new Set();
3192
+ this.toolCallsById.set(wireId, toolCallsWithId);
3193
+ }
3194
+ toolCallsWithId.add(toolCall);
3195
+ }
3196
+ associateIndex(toolCall, index) {
3197
+ let toolCallsWithIndex = this.toolCallsByIndex.get(index);
3198
+ if (toolCallsWithIndex == null) {
3199
+ toolCallsWithIndex = /* @__PURE__ */ new Set();
3200
+ this.toolCallsByIndex.set(index, toolCallsWithIndex);
3201
+ }
3202
+ toolCallsWithIndex.add(toolCall);
3203
+ }
3204
+ createToolCallId(wireId) {
3205
+ var _a2, _b2;
3206
+ if (wireId != null && !this.usedToolCallIds.has(wireId)) {
3207
+ this.usedToolCallIds.add(wireId);
3208
+ return wireId;
3209
+ }
3210
+ const generatedId = (_a2 = this.getNonBlankString(this._generateId())) != null ? _a2 : "tool-call";
3211
+ if (!this.usedToolCallIds.has(generatedId)) {
3212
+ this.usedToolCallIds.add(generatedId);
3213
+ return generatedId;
3214
+ }
3215
+ const initialSuffix = (_b2 = this.nextGeneratedIdSuffixes.get(generatedId)) != null ? _b2 : 1;
3216
+ const maximumSuffix = initialSuffix + this.usedToolCallIds.size;
3217
+ for (let suffix = initialSuffix; suffix <= maximumSuffix; suffix++) {
3218
+ const suffixedId = `${generatedId}-${suffix}`;
3219
+ if (!this.usedToolCallIds.has(suffixedId)) {
3220
+ this.usedToolCallIds.add(suffixedId);
3221
+ this.nextGeneratedIdSuffixes.set(generatedId, suffix + 1);
3222
+ return suffixedId;
3223
+ }
3224
+ }
3225
+ throw new Error("Failed to create a unique tool call ID.");
3226
+ }
3227
+ getNonBlankString(value) {
3228
+ return value != null && value.trim().length > 0 ? value : void 0;
3229
+ }
3230
+ processExistingToolCall(toolCall, toolCallDelta) {
3231
+ var _a2;
3232
+ if (!toolCall.hasFinished && ((_a2 = toolCallDelta.function) == null ? void 0 : _a2.arguments) != null) {
3233
+ toolCall.argumentState.append(toolCallDelta.function.arguments);
3234
+ toolCall.function.arguments += toolCallDelta.function.arguments;
3235
+ this.controller.enqueue({
3236
+ type: "tool-input-delta",
3237
+ id: toolCall.id,
3238
+ delta: toolCallDelta.function.arguments
3239
+ });
3240
+ }
3241
+ }
3242
+ finishToolCall(toolCall) {
3243
+ var _a2;
3244
+ this.controller.enqueue({
3245
+ type: "tool-input-end",
3246
+ id: toolCall.id
3247
+ });
3248
+ const providerMetadata = (_a2 = this.buildToolCallProviderMetadata) == null ? void 0 : _a2.call(
3249
+ this,
3250
+ toolCall.metadata
3251
+ );
3252
+ this.controller.enqueue({
3253
+ type: "tool-call",
3254
+ toolCallId: toolCall.id,
3255
+ toolName: toolCall.function.name,
3256
+ input: toolCall.function.arguments,
3257
+ ...providerMetadata ? { providerMetadata } : {}
3258
+ });
3259
+ toolCall.hasFinished = true;
3260
+ }
3261
+ };
3262
+
2902
3263
  // src/uint8-utils.ts
2903
3264
  var { btoa, atob } = globalThis;
2904
3265
  function convertBase64ToUint8Array(base64String) {
@@ -2958,6 +3319,7 @@ export {
2958
3319
  DownloadError,
2959
3320
  EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL as EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL,
2960
3321
  EventSourceParserStream2 as EventSourceParserStream,
3322
+ StreamingToolCallTracker,
2961
3323
  VERSION,
2962
3324
  asSchema,
2963
3325
  asValidator,