@ai-sdk/provider-utils 5.0.0-beta.23 → 5.0.0-beta.25
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 +12 -0
- package/dist/index.d.ts +80 -2
- package/dist/index.js +142 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/filter-nullable.ts +11 -0
- package/src/index.ts +6 -0
- package/src/streaming-tool-call-tracker.ts +243 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ai-sdk/provider-utils
|
|
2
2
|
|
|
3
|
+
## 5.0.0-beta.25
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- eea8d98: refactoring: rename tool execution events
|
|
8
|
+
|
|
9
|
+
## 5.0.0-beta.24
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- f807e45: Extract shared `StreamingToolCallTracker` class into `@ai-sdk/provider-utils` to deduplicate streaming tool call handling across OpenAI-compatible providers. Also adds missing `generateId()` fallback for `toolCallId` in Alibaba's `doGenerate` path and ensures all providers finalize unfinished tool calls during stream flush.
|
|
14
|
+
|
|
3
15
|
## 5.0.0-beta.23
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ImageModelV4File, LanguageModelV4FunctionTool, LanguageModelV4ProviderTool, AISDKError, JSONSchema7, JSONParseError, TypeValidationError, JSONValue, APICallError, LanguageModelV4Prompt, LanguageModelV4FilePart, SharedV4ProviderReference, LanguageModelV4CallOptions, SharedV4Warning, SharedV4ProviderOptions, JSONObject, TypeValidationContext } from '@ai-sdk/provider';
|
|
1
|
+
import { ImageModelV4File, LanguageModelV4FunctionTool, LanguageModelV4ProviderTool, AISDKError, JSONSchema7, JSONParseError, TypeValidationError, JSONValue, APICallError, LanguageModelV4Prompt, LanguageModelV4FilePart, SharedV4ProviderReference, LanguageModelV4CallOptions, SharedV4Warning, SharedV4ProviderOptions, JSONObject, SharedV4ProviderMetadata, LanguageModelV4StreamPart, TypeValidationContext } from '@ai-sdk/provider';
|
|
2
2
|
export { getErrorMessage } from '@ai-sdk/provider';
|
|
3
3
|
import { StandardSchemaV1, StandardJSONSchemaV1 } from '@standard-schema/spec';
|
|
4
4
|
export * from '@standard-schema/spec';
|
|
@@ -184,6 +184,14 @@ declare function extractResponseHeaders(response: Response): {
|
|
|
184
184
|
*/
|
|
185
185
|
type FetchFunction = typeof globalThis.fetch;
|
|
186
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Filters `null` and `undefined` values out of a list of values.
|
|
189
|
+
*
|
|
190
|
+
* @param values - The values to filter.
|
|
191
|
+
* @returns A new array containing only non-nullish values.
|
|
192
|
+
*/
|
|
193
|
+
declare function filterNullable<T>(...values: Array<T | undefined | null>): Array<T>;
|
|
194
|
+
|
|
187
195
|
/**
|
|
188
196
|
* Creates an ID generator.
|
|
189
197
|
* The total length of the ID is the sum of the prefix, separator, and random part length.
|
|
@@ -1479,6 +1487,76 @@ declare function serializeModelOptions<CONFIG extends {
|
|
|
1479
1487
|
config: JSONObject;
|
|
1480
1488
|
};
|
|
1481
1489
|
|
|
1490
|
+
/**
|
|
1491
|
+
* Minimal interface for a streaming tool call delta from an OpenAI-compatible API.
|
|
1492
|
+
*/
|
|
1493
|
+
interface StreamingToolCallDelta {
|
|
1494
|
+
index?: number | null;
|
|
1495
|
+
id?: string | null;
|
|
1496
|
+
type?: string | null;
|
|
1497
|
+
function?: {
|
|
1498
|
+
name?: string | null;
|
|
1499
|
+
arguments?: string | null;
|
|
1500
|
+
} | null;
|
|
1501
|
+
}
|
|
1502
|
+
interface StreamingToolCallTrackerOptions {
|
|
1503
|
+
/**
|
|
1504
|
+
* ID generator function for tool call IDs.
|
|
1505
|
+
* Defaults to the standard generateId.
|
|
1506
|
+
*/
|
|
1507
|
+
generateId?: () => string;
|
|
1508
|
+
/**
|
|
1509
|
+
* How to validate the `type` field on new tool call deltas.
|
|
1510
|
+
* - `'none'`: no validation (default)
|
|
1511
|
+
* - `'if-present'`: throw if type is present and not `'function'`
|
|
1512
|
+
* - `'required'`: throw if type is not exactly `'function'`
|
|
1513
|
+
*/
|
|
1514
|
+
typeValidation?: 'none' | 'if-present' | 'required';
|
|
1515
|
+
/**
|
|
1516
|
+
* Extract provider-specific metadata from a tool call delta.
|
|
1517
|
+
* Called once when a new tool call is detected.
|
|
1518
|
+
* The returned metadata is stored on the tool call and passed to
|
|
1519
|
+
* `buildToolCallProviderMetadata` when the tool call is finalized.
|
|
1520
|
+
*/
|
|
1521
|
+
extractMetadata?: (delta: StreamingToolCallDelta) => SharedV4ProviderMetadata | undefined;
|
|
1522
|
+
/**
|
|
1523
|
+
* Build the `providerMetadata` object for a `tool-call` event.
|
|
1524
|
+
* Receives the metadata previously extracted via `extractMetadata`.
|
|
1525
|
+
* If `undefined` is returned, no `providerMetadata` is included in the event.
|
|
1526
|
+
*/
|
|
1527
|
+
buildToolCallProviderMetadata?: (metadata: SharedV4ProviderMetadata | undefined) => SharedV4ProviderMetadata | undefined;
|
|
1528
|
+
}
|
|
1529
|
+
/**
|
|
1530
|
+
* Tracks streaming tool call state across multiple deltas from an
|
|
1531
|
+
* OpenAI-compatible chat completion stream. Handles argument accumulation,
|
|
1532
|
+
* emits tool-input-start/delta/end and tool-call events, and finalizes
|
|
1533
|
+
* unfinished tool calls on flush.
|
|
1534
|
+
*
|
|
1535
|
+
* Used by openai, openai-compatible, groq, deepseek, and alibaba providers.
|
|
1536
|
+
*/
|
|
1537
|
+
declare class StreamingToolCallTracker {
|
|
1538
|
+
private toolCalls;
|
|
1539
|
+
private readonly _generateId;
|
|
1540
|
+
private readonly typeValidation;
|
|
1541
|
+
private readonly extractMetadata?;
|
|
1542
|
+
private readonly buildToolCallProviderMetadata?;
|
|
1543
|
+
constructor(options?: StreamingToolCallTrackerOptions);
|
|
1544
|
+
/**
|
|
1545
|
+
* Process a tool call delta from a streaming response chunk.
|
|
1546
|
+
* Emits tool-input-start, tool-input-delta, tool-input-end, and tool-call
|
|
1547
|
+
* events as appropriate.
|
|
1548
|
+
*/
|
|
1549
|
+
processDelta(toolCallDelta: StreamingToolCallDelta, enqueue: (part: LanguageModelV4StreamPart) => void): void;
|
|
1550
|
+
/**
|
|
1551
|
+
* Finalize any unfinished tool calls. Should be called during the stream's
|
|
1552
|
+
* flush handler to ensure all tool calls are properly completed.
|
|
1553
|
+
*/
|
|
1554
|
+
flush(enqueue: (part: LanguageModelV4StreamPart) => void): void;
|
|
1555
|
+
private processNewToolCall;
|
|
1556
|
+
private processExistingToolCall;
|
|
1557
|
+
private finishToolCall;
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1482
1560
|
/**
|
|
1483
1561
|
* Strips file extension segments from a filename.
|
|
1484
1562
|
*
|
|
@@ -1684,4 +1762,4 @@ interface ToolResult<NAME extends string, INPUT, OUTPUT> {
|
|
|
1684
1762
|
dynamic?: boolean;
|
|
1685
1763
|
}
|
|
1686
1764
|
|
|
1687
|
-
export { type Arrayable, type AssistantContent, type AssistantModelMessage, type Context, type CustomPart, DEFAULT_MAX_DOWNLOAD_SIZE, type DataContent, DelayedPromise, DownloadError, type ExecutableTool, type FetchFunction, type FilePart, type FlexibleSchema, type HasRequiredKey, type IdGenerator, type ImagePart, type InferSchema, type InferToolContext, type InferToolInput, type InferToolOutput, type InferToolSetContext, type LazySchema, type MaybePromiseLike, type ModelMessage, type ParseResult, type ProviderOptions, type ProviderReference, type ProviderToolFactory, type ProviderToolFactoryWithOutputSchema, type ReasoningFilePart, type ReasoningPart, type Resolvable, type ResponseHandler, type Schema, type SystemModelMessage, type TextPart, type Tool, type ToolApprovalRequest, type ToolApprovalResponse, type ToolCall, type ToolCallPart, type ToolContent, type ToolExecuteFunction, type ToolExecutionOptions, type ToolModelMessage, type ToolNameMapping, type ToolNeedsApprovalFunction, type ToolResult, type ToolResultOutput, type ToolResultPart, type ToolSet, type UserContent, type UserModelMessage, VERSION, type ValidationResult, asArray, asSchema, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertImageModelFileToDataUri, convertToBase64, convertToFormData, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createProviderToolFactory, createProviderToolFactoryWithOutputSchema, createStatusCodeErrorResponseHandler, createToolNameMapping, delay, downloadBlob, dynamicTool, executeTool, extractResponseHeaders, generateId, getFromApi, getRuntimeEnvironmentUserAgent, injectJsonInstructionIntoMessages, isAbortError, isCustomReasoning, isExecutableTool, isNonNullable, isParsableJson, isProviderReference, isUrlSupported, jsonSchema, lazySchema, loadApiKey, loadOptionalSetting, loadSetting, mapReasoningToProviderBudget, mapReasoningToProviderEffort, mediaTypeToExtension, normalizeHeaders, parseJSON, parseJsonEventStream, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, readResponseWithSizeLimit, removeUndefinedEntries, resolve, resolveProviderReference, safeParseJSON, safeValidateTypes, serializeModelOptions, stripFileExtension, tool, validateDownloadUrl, validateTypes, withUserAgentSuffix, withoutTrailingSlash, zodSchema };
|
|
1765
|
+
export { type Arrayable, type AssistantContent, type AssistantModelMessage, type Context, type CustomPart, DEFAULT_MAX_DOWNLOAD_SIZE, type DataContent, DelayedPromise, DownloadError, type ExecutableTool, type FetchFunction, type FilePart, type FlexibleSchema, type HasRequiredKey, type IdGenerator, type ImagePart, type InferSchema, type InferToolContext, type InferToolInput, type InferToolOutput, type InferToolSetContext, type LazySchema, type MaybePromiseLike, type ModelMessage, type ParseResult, type ProviderOptions, type ProviderReference, type ProviderToolFactory, type ProviderToolFactoryWithOutputSchema, type ReasoningFilePart, type ReasoningPart, type Resolvable, type ResponseHandler, type Schema, type StreamingToolCallDelta, StreamingToolCallTracker, type StreamingToolCallTrackerOptions, type SystemModelMessage, type TextPart, type Tool, type ToolApprovalRequest, type ToolApprovalResponse, type ToolCall, type ToolCallPart, type ToolContent, type ToolExecuteFunction, type ToolExecutionOptions, type ToolModelMessage, type ToolNameMapping, type ToolNeedsApprovalFunction, type ToolResult, type ToolResultOutput, type ToolResultPart, type ToolSet, type UserContent, type UserModelMessage, VERSION, type ValidationResult, asArray, asSchema, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertImageModelFileToDataUri, convertToBase64, convertToFormData, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createProviderToolFactory, createProviderToolFactoryWithOutputSchema, createStatusCodeErrorResponseHandler, createToolNameMapping, delay, downloadBlob, dynamicTool, executeTool, extractResponseHeaders, filterNullable, generateId, getFromApi, getRuntimeEnvironmentUserAgent, injectJsonInstructionIntoMessages, isAbortError, isCustomReasoning, isExecutableTool, isNonNullable, isParsableJson, isProviderReference, isUrlSupported, jsonSchema, lazySchema, loadApiKey, loadOptionalSetting, loadSetting, mapReasoningToProviderBudget, mapReasoningToProviderEffort, mediaTypeToExtension, normalizeHeaders, parseJSON, parseJsonEventStream, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, readResponseWithSizeLimit, removeUndefinedEntries, resolve, resolveProviderReference, safeParseJSON, safeValidateTypes, serializeModelOptions, stripFileExtension, tool, validateDownloadUrl, validateTypes, withUserAgentSuffix, withoutTrailingSlash, zodSchema };
|
package/dist/index.js
CHANGED
|
@@ -420,6 +420,11 @@ function extractResponseHeaders(response) {
|
|
|
420
420
|
return Object.fromEntries([...response.headers]);
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
// src/filter-nullable.ts
|
|
424
|
+
function filterNullable(...values) {
|
|
425
|
+
return values.filter((value) => value != null);
|
|
426
|
+
}
|
|
427
|
+
|
|
423
428
|
// src/generate-id.ts
|
|
424
429
|
import { InvalidArgumentError } from "@ai-sdk/provider";
|
|
425
430
|
var createIdGenerator = ({
|
|
@@ -571,7 +576,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
|
|
|
571
576
|
}
|
|
572
577
|
|
|
573
578
|
// src/version.ts
|
|
574
|
-
var VERSION = true ? "5.0.0-beta.
|
|
579
|
+
var VERSION = true ? "5.0.0-beta.25" : "0.0.0-test";
|
|
575
580
|
|
|
576
581
|
// src/get-from-api.ts
|
|
577
582
|
var getOriginalFetch = () => globalThis.fetch;
|
|
@@ -2770,6 +2775,140 @@ function resolveSync(value) {
|
|
|
2770
2775
|
return next;
|
|
2771
2776
|
}
|
|
2772
2777
|
|
|
2778
|
+
// src/streaming-tool-call-tracker.ts
|
|
2779
|
+
import {
|
|
2780
|
+
InvalidResponseDataError
|
|
2781
|
+
} from "@ai-sdk/provider";
|
|
2782
|
+
var StreamingToolCallTracker = class {
|
|
2783
|
+
constructor(options = {}) {
|
|
2784
|
+
this.toolCalls = [];
|
|
2785
|
+
var _a2, _b2;
|
|
2786
|
+
this._generateId = (_a2 = options.generateId) != null ? _a2 : generateId;
|
|
2787
|
+
this.typeValidation = (_b2 = options.typeValidation) != null ? _b2 : "none";
|
|
2788
|
+
this.extractMetadata = options.extractMetadata;
|
|
2789
|
+
this.buildToolCallProviderMetadata = options.buildToolCallProviderMetadata;
|
|
2790
|
+
}
|
|
2791
|
+
/**
|
|
2792
|
+
* Process a tool call delta from a streaming response chunk.
|
|
2793
|
+
* Emits tool-input-start, tool-input-delta, tool-input-end, and tool-call
|
|
2794
|
+
* events as appropriate.
|
|
2795
|
+
*/
|
|
2796
|
+
processDelta(toolCallDelta, enqueue) {
|
|
2797
|
+
var _a2;
|
|
2798
|
+
const index = (_a2 = toolCallDelta.index) != null ? _a2 : this.toolCalls.length;
|
|
2799
|
+
if (this.toolCalls[index] == null) {
|
|
2800
|
+
this.processNewToolCall(index, toolCallDelta, enqueue);
|
|
2801
|
+
} else {
|
|
2802
|
+
this.processExistingToolCall(index, toolCallDelta, enqueue);
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
/**
|
|
2806
|
+
* Finalize any unfinished tool calls. Should be called during the stream's
|
|
2807
|
+
* flush handler to ensure all tool calls are properly completed.
|
|
2808
|
+
*/
|
|
2809
|
+
flush(enqueue) {
|
|
2810
|
+
for (const toolCall of this.toolCalls) {
|
|
2811
|
+
if (!toolCall.hasFinished) {
|
|
2812
|
+
this.finishToolCall(toolCall, enqueue);
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
processNewToolCall(index, toolCallDelta, enqueue) {
|
|
2817
|
+
var _a2, _b2, _c;
|
|
2818
|
+
if (this.typeValidation === "required") {
|
|
2819
|
+
if (toolCallDelta.type !== "function") {
|
|
2820
|
+
throw new InvalidResponseDataError({
|
|
2821
|
+
data: toolCallDelta,
|
|
2822
|
+
message: `Expected 'function' type.`
|
|
2823
|
+
});
|
|
2824
|
+
}
|
|
2825
|
+
} else if (this.typeValidation === "if-present") {
|
|
2826
|
+
if (toolCallDelta.type != null && toolCallDelta.type !== "function") {
|
|
2827
|
+
throw new InvalidResponseDataError({
|
|
2828
|
+
data: toolCallDelta,
|
|
2829
|
+
message: `Expected 'function' type.`
|
|
2830
|
+
});
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
if (toolCallDelta.id == null) {
|
|
2834
|
+
throw new InvalidResponseDataError({
|
|
2835
|
+
data: toolCallDelta,
|
|
2836
|
+
message: `Expected 'id' to be a string.`
|
|
2837
|
+
});
|
|
2838
|
+
}
|
|
2839
|
+
if (((_a2 = toolCallDelta.function) == null ? void 0 : _a2.name) == null) {
|
|
2840
|
+
throw new InvalidResponseDataError({
|
|
2841
|
+
data: toolCallDelta,
|
|
2842
|
+
message: `Expected 'function.name' to be a string.`
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2845
|
+
enqueue({
|
|
2846
|
+
type: "tool-input-start",
|
|
2847
|
+
id: toolCallDelta.id,
|
|
2848
|
+
toolName: toolCallDelta.function.name
|
|
2849
|
+
});
|
|
2850
|
+
const metadata = (_b2 = this.extractMetadata) == null ? void 0 : _b2.call(this, toolCallDelta);
|
|
2851
|
+
this.toolCalls[index] = {
|
|
2852
|
+
id: toolCallDelta.id,
|
|
2853
|
+
type: "function",
|
|
2854
|
+
function: {
|
|
2855
|
+
name: toolCallDelta.function.name,
|
|
2856
|
+
arguments: (_c = toolCallDelta.function.arguments) != null ? _c : ""
|
|
2857
|
+
},
|
|
2858
|
+
hasFinished: false,
|
|
2859
|
+
metadata
|
|
2860
|
+
};
|
|
2861
|
+
const toolCall = this.toolCalls[index];
|
|
2862
|
+
if (toolCall.function.arguments.length > 0) {
|
|
2863
|
+
enqueue({
|
|
2864
|
+
type: "tool-input-delta",
|
|
2865
|
+
id: toolCall.id,
|
|
2866
|
+
delta: toolCall.function.arguments
|
|
2867
|
+
});
|
|
2868
|
+
}
|
|
2869
|
+
if (isParsableJson(toolCall.function.arguments)) {
|
|
2870
|
+
this.finishToolCall(toolCall, enqueue);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
processExistingToolCall(index, toolCallDelta, enqueue) {
|
|
2874
|
+
var _a2;
|
|
2875
|
+
const toolCall = this.toolCalls[index];
|
|
2876
|
+
if (toolCall.hasFinished) {
|
|
2877
|
+
return;
|
|
2878
|
+
}
|
|
2879
|
+
if (((_a2 = toolCallDelta.function) == null ? void 0 : _a2.arguments) != null) {
|
|
2880
|
+
toolCall.function.arguments += toolCallDelta.function.arguments;
|
|
2881
|
+
enqueue({
|
|
2882
|
+
type: "tool-input-delta",
|
|
2883
|
+
id: toolCall.id,
|
|
2884
|
+
delta: toolCallDelta.function.arguments
|
|
2885
|
+
});
|
|
2886
|
+
}
|
|
2887
|
+
if (isParsableJson(toolCall.function.arguments)) {
|
|
2888
|
+
this.finishToolCall(toolCall, enqueue);
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
finishToolCall(toolCall, enqueue) {
|
|
2892
|
+
var _a2, _b2;
|
|
2893
|
+
enqueue({
|
|
2894
|
+
type: "tool-input-end",
|
|
2895
|
+
id: toolCall.id
|
|
2896
|
+
});
|
|
2897
|
+
const providerMetadata = (_a2 = this.buildToolCallProviderMetadata) == null ? void 0 : _a2.call(
|
|
2898
|
+
this,
|
|
2899
|
+
toolCall.metadata
|
|
2900
|
+
);
|
|
2901
|
+
enqueue({
|
|
2902
|
+
type: "tool-call",
|
|
2903
|
+
toolCallId: (_b2 = toolCall.id) != null ? _b2 : this._generateId(),
|
|
2904
|
+
toolName: toolCall.function.name,
|
|
2905
|
+
input: toolCall.function.arguments,
|
|
2906
|
+
...providerMetadata ? { providerMetadata } : {}
|
|
2907
|
+
});
|
|
2908
|
+
toolCall.hasFinished = true;
|
|
2909
|
+
}
|
|
2910
|
+
};
|
|
2911
|
+
|
|
2773
2912
|
// src/strip-file-extension.ts
|
|
2774
2913
|
function stripFileExtension(filename) {
|
|
2775
2914
|
const firstDotIndex = filename.indexOf(".");
|
|
@@ -2820,6 +2959,7 @@ export {
|
|
|
2820
2959
|
DelayedPromise,
|
|
2821
2960
|
DownloadError,
|
|
2822
2961
|
EventSourceParserStream2 as EventSourceParserStream,
|
|
2962
|
+
StreamingToolCallTracker,
|
|
2823
2963
|
VERSION,
|
|
2824
2964
|
WORKFLOW_DESERIALIZE,
|
|
2825
2965
|
WORKFLOW_SERIALIZE,
|
|
@@ -2846,6 +2986,7 @@ export {
|
|
|
2846
2986
|
dynamicTool,
|
|
2847
2987
|
executeTool,
|
|
2848
2988
|
extractResponseHeaders,
|
|
2989
|
+
filterNullable,
|
|
2849
2990
|
generateId,
|
|
2850
2991
|
getErrorMessage,
|
|
2851
2992
|
getFromApi,
|