@ai-sdk/provider-utils 5.0.0-beta.0 → 5.0.0-beta.10
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 +150 -0
- package/dist/index.d.mts +276 -76
- package/dist/index.d.ts +276 -76
- package/dist/index.js +117 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +102 -16
- package/dist/index.mjs.map +1 -1
- package/dist/test/index.js +3 -3
- package/package.json +2 -4
- package/src/convert-image-model-file-to-data-uri.ts +3 -3
- package/src/create-tool-name-mapping.ts +5 -21
- package/src/download-blob.ts +5 -0
- package/src/index.ts +7 -0
- package/src/inject-json-instruction.ts +5 -5
- package/src/is-provider-reference.ts +18 -0
- package/src/map-reasoning-to-provider.ts +105 -0
- package/src/provider-tool-factory.ts +43 -32
- package/src/resolve-provider-reference.ts +27 -0
- package/src/types/assistant-model-message.ts +4 -0
- package/src/types/content-part.ts +90 -4
- package/src/types/context.ts +4 -0
- package/src/types/execute-tool.ts +24 -4
- package/src/types/index.ts +10 -9
- package/src/types/infer-tool-context.ts +7 -0
- package/src/types/infer-tool-input.ts +7 -0
- package/src/types/infer-tool-output.ts +7 -0
- package/src/types/infer-tool-set-context.ts +17 -0
- package/src/types/provider-options.ts +2 -2
- package/src/types/provider-reference.ts +10 -0
- package/src/types/tool-set.ts +22 -0
- package/src/types/tool.ts +57 -35
- package/src/types/union-to-intersection.ts +17 -0
- package/src/validate-download-url.ts +7 -2
package/dist/test/index.js
CHANGED
|
@@ -18,8 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/test/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
23
|
convertArrayToAsyncIterable: () => convertArrayToAsyncIterable,
|
|
24
24
|
convertArrayToReadableStream: () => convertArrayToReadableStream,
|
|
25
25
|
convertAsyncIterableToArray: () => convertAsyncIterableToArray,
|
|
@@ -28,7 +28,7 @@ __export(test_exports, {
|
|
|
28
28
|
isNodeVersion: () => isNodeVersion,
|
|
29
29
|
mockId: () => mockId
|
|
30
30
|
});
|
|
31
|
-
module.exports = __toCommonJS(
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
32
|
|
|
33
33
|
// src/test/convert-array-to-async-iterable.ts
|
|
34
34
|
function convertArrayToAsyncIterable(values) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/provider-utils",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.10",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@standard-schema/spec": "^1.1.0",
|
|
37
37
|
"eventsource-parser": "^3.0.6",
|
|
38
|
-
"@ai-sdk/provider": "4.0.0-beta.
|
|
38
|
+
"@ai-sdk/provider": "4.0.0-beta.6"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "20.17.24",
|
|
@@ -69,9 +69,7 @@
|
|
|
69
69
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
70
70
|
"build:watch": "pnpm clean && tsup --watch",
|
|
71
71
|
"clean": "del-cli dist *.tsbuildinfo",
|
|
72
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
73
72
|
"type-check": "tsc --build",
|
|
74
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
75
73
|
"test": "pnpm test:node && pnpm test:edge",
|
|
76
74
|
"test:update": "pnpm test:node -u",
|
|
77
75
|
"test:watch": "vitest --config vitest.node.config.js",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ImageModelV4File } from '@ai-sdk/provider';
|
|
2
2
|
import { convertUint8ArrayToBase64 } from './uint8-utils';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Convert an
|
|
5
|
+
* Convert an ImageModelV4File to a URL or data URI string.
|
|
6
6
|
*
|
|
7
7
|
* If the file is a URL, it returns the URL as-is.
|
|
8
8
|
* If the file is base64 data, it returns a data URI with the base64 data.
|
|
9
9
|
* If the file is a Uint8Array, it converts it to base64 and returns a data URI.
|
|
10
10
|
*/
|
|
11
|
-
export function convertImageModelFileToDataUri(file:
|
|
11
|
+
export function convertImageModelFileToDataUri(file: ImageModelV4File): string {
|
|
12
12
|
if (file.type === 'url') return file.url;
|
|
13
13
|
|
|
14
14
|
return `data:${file.mediaType};base64,${
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
LanguageModelV4FunctionTool,
|
|
3
|
+
LanguageModelV4ProviderTool,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -33,41 +33,25 @@ export interface ToolNameMapping {
|
|
|
33
33
|
export function createToolNameMapping({
|
|
34
34
|
tools = [],
|
|
35
35
|
providerToolNames,
|
|
36
|
-
resolveProviderToolName,
|
|
37
36
|
}: {
|
|
38
37
|
/**
|
|
39
38
|
* Tools that were passed to the language model.
|
|
40
39
|
*/
|
|
41
40
|
tools:
|
|
42
|
-
| Array<
|
|
41
|
+
| Array<LanguageModelV4FunctionTool | LanguageModelV4ProviderTool>
|
|
43
42
|
| undefined;
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
45
|
* Maps the provider tool ids to the provider tool names.
|
|
47
46
|
*/
|
|
48
47
|
providerToolNames: Record<`${string}.${string}`, string>;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Optional resolver for provider tool names that cannot be represented as
|
|
52
|
-
* static id -> name mappings (e.g. dynamic provider names).
|
|
53
|
-
*/
|
|
54
|
-
resolveProviderToolName?: (
|
|
55
|
-
tool: LanguageModelV3ProviderTool,
|
|
56
|
-
) => string | undefined;
|
|
57
48
|
}): ToolNameMapping {
|
|
58
49
|
const customToolNameToProviderToolName: Record<string, string> = {};
|
|
59
50
|
const providerToolNameToCustomToolName: Record<string, string> = {};
|
|
60
51
|
|
|
61
52
|
for (const tool of tools) {
|
|
62
|
-
if (tool.type === 'provider') {
|
|
63
|
-
const providerToolName =
|
|
64
|
-
resolveProviderToolName?.(tool) ??
|
|
65
|
-
(tool.id in providerToolNames ? providerToolNames[tool.id] : undefined);
|
|
66
|
-
|
|
67
|
-
if (providerToolName == null) {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
53
|
+
if (tool.type === 'provider' && tool.id in providerToolNames) {
|
|
54
|
+
const providerToolName = providerToolNames[tool.id];
|
|
71
55
|
customToolNameToProviderToolName[tool.name] = providerToolName;
|
|
72
56
|
providerToolNameToCustomToolName[providerToolName] = tool.name;
|
|
73
57
|
}
|
package/src/download-blob.ts
CHANGED
|
@@ -26,6 +26,11 @@ export async function downloadBlob(
|
|
|
26
26
|
signal: options?.abortSignal,
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
// Validate final URL after redirects to prevent SSRF via open redirect
|
|
30
|
+
if (response.redirected) {
|
|
31
|
+
validateDownloadUrl(response.url);
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
if (!response.ok) {
|
|
30
35
|
throw new DownloadError({
|
|
31
36
|
url,
|
package/src/index.ts
CHANGED
|
@@ -23,8 +23,14 @@ export { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-a
|
|
|
23
23
|
export { injectJsonInstructionIntoMessages } from './inject-json-instruction';
|
|
24
24
|
export * from './is-abort-error';
|
|
25
25
|
export { isNonNullable } from './is-non-nullable';
|
|
26
|
+
export { isProviderReference } from './is-provider-reference';
|
|
26
27
|
export { isUrlSupported } from './is-url-supported';
|
|
27
28
|
export * from './load-api-key';
|
|
29
|
+
export {
|
|
30
|
+
isCustomReasoning,
|
|
31
|
+
mapReasoningToProviderBudget,
|
|
32
|
+
mapReasoningToProviderEffort,
|
|
33
|
+
} from './map-reasoning-to-provider';
|
|
28
34
|
export { loadOptionalSetting } from './load-optional-setting';
|
|
29
35
|
export { loadSetting } from './load-setting';
|
|
30
36
|
export { type MaybePromiseLike } from './maybe-promise-like';
|
|
@@ -41,6 +47,7 @@ export {
|
|
|
41
47
|
type ProviderToolFactoryWithOutputSchema,
|
|
42
48
|
} from './provider-tool-factory';
|
|
43
49
|
export * from './remove-undefined-entries';
|
|
50
|
+
export { resolveProviderReference } from './resolve-provider-reference';
|
|
44
51
|
export * from './resolve';
|
|
45
52
|
export * from './response-handler';
|
|
46
53
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JSONSchema7,
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
LanguageModelV4Message,
|
|
4
|
+
LanguageModelV4Prompt,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
6
|
|
|
7
7
|
const DEFAULT_SCHEMA_PREFIX = 'JSON schema:';
|
|
@@ -39,12 +39,12 @@ export function injectJsonInstructionIntoMessages({
|
|
|
39
39
|
schemaPrefix,
|
|
40
40
|
schemaSuffix,
|
|
41
41
|
}: {
|
|
42
|
-
messages:
|
|
42
|
+
messages: LanguageModelV4Prompt;
|
|
43
43
|
schema?: JSONSchema7;
|
|
44
44
|
schemaPrefix?: string;
|
|
45
45
|
schemaSuffix?: string;
|
|
46
|
-
}):
|
|
47
|
-
const systemMessage:
|
|
46
|
+
}): LanguageModelV4Prompt {
|
|
47
|
+
const systemMessage: LanguageModelV4Message =
|
|
48
48
|
messages[0]?.role === 'system'
|
|
49
49
|
? { ...messages[0] }
|
|
50
50
|
: { role: 'system', content: '' };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LanguageModelV4FilePart,
|
|
3
|
+
SharedV4ProviderReference,
|
|
4
|
+
} from '@ai-sdk/provider';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether file part data is a provider reference (a mapping of provider
|
|
8
|
+
* names to provider-specific identifiers) as opposed to raw bytes or a URL.
|
|
9
|
+
*/
|
|
10
|
+
export function isProviderReference(
|
|
11
|
+
data: LanguageModelV4FilePart['data'],
|
|
12
|
+
): data is SharedV4ProviderReference {
|
|
13
|
+
return (
|
|
14
|
+
typeof data === 'object' &&
|
|
15
|
+
!(data instanceof Uint8Array) &&
|
|
16
|
+
!(data instanceof URL)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { LanguageModelV4CallOptions, SharedV4Warning } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
export type ReasoningLevel = Exclude<
|
|
4
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
5
|
+
'none' | 'provider-default' | undefined
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export function isCustomReasoning(
|
|
9
|
+
reasoning: LanguageModelV4CallOptions['reasoning'],
|
|
10
|
+
): reasoning is Exclude<
|
|
11
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
12
|
+
'provider-default' | undefined
|
|
13
|
+
> {
|
|
14
|
+
return reasoning !== undefined && reasoning !== 'provider-default';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Maps a top-level reasoning level to a provider-specific effort string using
|
|
19
|
+
* the given effort map. Pushes a compatibility warning if the reasoning level
|
|
20
|
+
* maps to a different string, or an unsupported warning if the level is not
|
|
21
|
+
* present in the map.
|
|
22
|
+
*
|
|
23
|
+
* @returns The mapped effort string, or `undefined` if the level is not
|
|
24
|
+
* supported.
|
|
25
|
+
*/
|
|
26
|
+
export function mapReasoningToProviderEffort<T extends string>({
|
|
27
|
+
reasoning,
|
|
28
|
+
effortMap,
|
|
29
|
+
warnings,
|
|
30
|
+
}: {
|
|
31
|
+
reasoning: ReasoningLevel;
|
|
32
|
+
effortMap: Partial<Record<ReasoningLevel, T>>;
|
|
33
|
+
warnings: SharedV4Warning[];
|
|
34
|
+
}): T | undefined {
|
|
35
|
+
const mapped = effortMap[reasoning];
|
|
36
|
+
|
|
37
|
+
if (mapped == null) {
|
|
38
|
+
warnings.push({
|
|
39
|
+
type: 'unsupported',
|
|
40
|
+
feature: 'reasoning',
|
|
41
|
+
details: `reasoning "${reasoning}" is not supported by this model.`,
|
|
42
|
+
});
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (mapped !== reasoning) {
|
|
47
|
+
warnings.push({
|
|
48
|
+
type: 'compatibility',
|
|
49
|
+
feature: 'reasoning',
|
|
50
|
+
details: `reasoning "${reasoning}" is not directly supported by this model. mapped to effort "${mapped}".`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return mapped;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const DEFAULT_REASONING_BUDGET_PERCENTAGES: Record<ReasoningLevel, number> = {
|
|
58
|
+
minimal: 0.02,
|
|
59
|
+
low: 0.1,
|
|
60
|
+
medium: 0.3,
|
|
61
|
+
high: 0.6,
|
|
62
|
+
xhigh: 0.9,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Maps a top-level reasoning level to an absolute token budget by multiplying
|
|
67
|
+
* the model's max output tokens by a percentage from the budget percentages
|
|
68
|
+
* map. The result is clamped between `minReasoningBudget` (default 1024) and
|
|
69
|
+
* `maxReasoningBudget`. Pushes an unsupported warning if the level is not
|
|
70
|
+
* present in the budget percentages map.
|
|
71
|
+
*
|
|
72
|
+
* @returns The computed token budget, or `undefined` if the level is not
|
|
73
|
+
* supported.
|
|
74
|
+
*/
|
|
75
|
+
export function mapReasoningToProviderBudget({
|
|
76
|
+
reasoning,
|
|
77
|
+
maxOutputTokens,
|
|
78
|
+
maxReasoningBudget,
|
|
79
|
+
minReasoningBudget = 1024,
|
|
80
|
+
budgetPercentages = DEFAULT_REASONING_BUDGET_PERCENTAGES,
|
|
81
|
+
warnings,
|
|
82
|
+
}: {
|
|
83
|
+
reasoning: ReasoningLevel;
|
|
84
|
+
maxOutputTokens: number;
|
|
85
|
+
maxReasoningBudget: number;
|
|
86
|
+
minReasoningBudget?: number;
|
|
87
|
+
budgetPercentages?: Partial<Record<ReasoningLevel, number>>;
|
|
88
|
+
warnings: SharedV4Warning[];
|
|
89
|
+
}): number | undefined {
|
|
90
|
+
const pct = budgetPercentages[reasoning];
|
|
91
|
+
|
|
92
|
+
if (pct == null) {
|
|
93
|
+
warnings.push({
|
|
94
|
+
type: 'unsupported',
|
|
95
|
+
feature: 'reasoning',
|
|
96
|
+
details: `reasoning "${reasoning}" is not supported by this model.`,
|
|
97
|
+
});
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return Math.min(
|
|
102
|
+
maxReasoningBudget,
|
|
103
|
+
Math.max(minReasoningBudget, Math.round(maxOutputTokens * pct)),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
import { tool, Tool, ToolExecuteFunction } from './types/tool';
|
|
2
2
|
import { FlexibleSchema } from './schema';
|
|
3
|
+
import { Context } from './types/context';
|
|
3
4
|
|
|
4
|
-
export type ProviderToolFactory<
|
|
5
|
+
export type ProviderToolFactory<
|
|
6
|
+
INPUT,
|
|
7
|
+
ARGS extends object,
|
|
8
|
+
CONTEXT extends Context = {},
|
|
9
|
+
> = <OUTPUT>(
|
|
5
10
|
options: ARGS & {
|
|
6
|
-
execute?: ToolExecuteFunction<INPUT, OUTPUT>;
|
|
7
|
-
needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
|
|
8
|
-
toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
|
|
9
|
-
onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
|
|
10
|
-
onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
|
|
11
|
-
onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
|
|
11
|
+
execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
|
|
12
|
+
needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
|
|
13
|
+
toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
|
|
14
|
+
onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
|
|
15
|
+
onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
|
|
16
|
+
onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
|
|
12
17
|
},
|
|
13
|
-
) => Tool<INPUT, OUTPUT>;
|
|
18
|
+
) => Tool<INPUT, OUTPUT, CONTEXT>;
|
|
14
19
|
|
|
15
|
-
export function createProviderToolFactory<
|
|
20
|
+
export function createProviderToolFactory<
|
|
21
|
+
INPUT,
|
|
22
|
+
ARGS extends object,
|
|
23
|
+
CONTEXT extends Context = {},
|
|
24
|
+
>({
|
|
16
25
|
id,
|
|
17
26
|
inputSchema,
|
|
18
27
|
}: {
|
|
19
28
|
id: `${string}.${string}`;
|
|
20
29
|
inputSchema: FlexibleSchema<INPUT>;
|
|
21
|
-
}): ProviderToolFactory<INPUT, ARGS> {
|
|
30
|
+
}): ProviderToolFactory<INPUT, ARGS, CONTEXT> {
|
|
22
31
|
return <OUTPUT>({
|
|
23
32
|
execute,
|
|
24
33
|
outputSchema,
|
|
@@ -29,14 +38,14 @@ export function createProviderToolFactory<INPUT, ARGS extends object>({
|
|
|
29
38
|
onInputAvailable,
|
|
30
39
|
...args
|
|
31
40
|
}: ARGS & {
|
|
32
|
-
execute?: ToolExecuteFunction<INPUT, OUTPUT>;
|
|
41
|
+
execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
|
|
33
42
|
outputSchema?: FlexibleSchema<OUTPUT>;
|
|
34
|
-
needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
|
|
35
|
-
toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
|
|
36
|
-
onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
|
|
37
|
-
onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
|
|
38
|
-
onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
|
|
39
|
-
}): Tool<INPUT, OUTPUT> =>
|
|
43
|
+
needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
|
|
44
|
+
toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
|
|
45
|
+
onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
|
|
46
|
+
onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
|
|
47
|
+
onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
|
|
48
|
+
}): Tool<INPUT, OUTPUT, CONTEXT> =>
|
|
40
49
|
tool({
|
|
41
50
|
type: 'provider',
|
|
42
51
|
id,
|
|
@@ -56,21 +65,23 @@ export type ProviderToolFactoryWithOutputSchema<
|
|
|
56
65
|
INPUT,
|
|
57
66
|
OUTPUT,
|
|
58
67
|
ARGS extends object,
|
|
68
|
+
CONTEXT extends Context = {},
|
|
59
69
|
> = (
|
|
60
70
|
options: ARGS & {
|
|
61
|
-
execute?: ToolExecuteFunction<INPUT, OUTPUT>;
|
|
62
|
-
needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
|
|
63
|
-
toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
|
|
64
|
-
onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
|
|
65
|
-
onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
|
|
66
|
-
onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
|
|
71
|
+
execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
|
|
72
|
+
needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
|
|
73
|
+
toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
|
|
74
|
+
onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
|
|
75
|
+
onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
|
|
76
|
+
onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
|
|
67
77
|
},
|
|
68
|
-
) => Tool<INPUT, OUTPUT>;
|
|
78
|
+
) => Tool<INPUT, OUTPUT, CONTEXT>;
|
|
69
79
|
|
|
70
80
|
export function createProviderToolFactoryWithOutputSchema<
|
|
71
81
|
INPUT,
|
|
72
82
|
OUTPUT,
|
|
73
83
|
ARGS extends object,
|
|
84
|
+
CONTEXT extends Context = {},
|
|
74
85
|
>({
|
|
75
86
|
id,
|
|
76
87
|
inputSchema,
|
|
@@ -91,7 +102,7 @@ export function createProviderToolFactoryWithOutputSchema<
|
|
|
91
102
|
* @default false
|
|
92
103
|
*/
|
|
93
104
|
supportsDeferredResults?: boolean;
|
|
94
|
-
}): ProviderToolFactoryWithOutputSchema<INPUT, OUTPUT, ARGS> {
|
|
105
|
+
}): ProviderToolFactoryWithOutputSchema<INPUT, OUTPUT, ARGS, CONTEXT> {
|
|
95
106
|
return ({
|
|
96
107
|
execute,
|
|
97
108
|
needsApproval,
|
|
@@ -101,13 +112,13 @@ export function createProviderToolFactoryWithOutputSchema<
|
|
|
101
112
|
onInputAvailable,
|
|
102
113
|
...args
|
|
103
114
|
}: ARGS & {
|
|
104
|
-
execute?: ToolExecuteFunction<INPUT, OUTPUT>;
|
|
105
|
-
needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
|
|
106
|
-
toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
|
|
107
|
-
onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
|
|
108
|
-
onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
|
|
109
|
-
onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
|
|
110
|
-
}): Tool<INPUT, OUTPUT> =>
|
|
115
|
+
execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
|
|
116
|
+
needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
|
|
117
|
+
toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
|
|
118
|
+
onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
|
|
119
|
+
onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
|
|
120
|
+
onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
|
|
121
|
+
}): Tool<INPUT, OUTPUT, CONTEXT> =>
|
|
111
122
|
tool({
|
|
112
123
|
type: 'provider',
|
|
113
124
|
id,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NoSuchProviderReferenceError,
|
|
3
|
+
SharedV4ProviderReference,
|
|
4
|
+
} from '@ai-sdk/provider';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolves a provider reference to the provider-specific identifier for the
|
|
8
|
+
* given provider. Throws `NoSuchProviderReferenceError` if the provider is not
|
|
9
|
+
* found in the reference mapping.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveProviderReference({
|
|
12
|
+
reference,
|
|
13
|
+
provider,
|
|
14
|
+
}: {
|
|
15
|
+
reference: SharedV4ProviderReference;
|
|
16
|
+
provider: string;
|
|
17
|
+
}): string {
|
|
18
|
+
const id = reference[provider];
|
|
19
|
+
if (id != null) {
|
|
20
|
+
return id;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
throw new NoSuchProviderReferenceError({
|
|
24
|
+
provider,
|
|
25
|
+
reference,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CustomPart,
|
|
2
3
|
FilePart,
|
|
4
|
+
ReasoningFilePart,
|
|
3
5
|
ReasoningPart,
|
|
4
6
|
TextPart,
|
|
5
7
|
ToolCallPart,
|
|
@@ -31,8 +33,10 @@ export type AssistantContent =
|
|
|
31
33
|
| string
|
|
32
34
|
| Array<
|
|
33
35
|
| TextPart
|
|
36
|
+
| CustomPart
|
|
34
37
|
| FilePart
|
|
35
38
|
| ReasoningPart
|
|
39
|
+
| ReasoningFilePart
|
|
36
40
|
| ToolCallPart
|
|
37
41
|
| ToolResultPart
|
|
38
42
|
| ToolApprovalRequest
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { JSONValue } from '@ai-sdk/provider';
|
|
2
2
|
import { DataContent } from './data-content';
|
|
3
3
|
import { ProviderOptions } from './provider-options';
|
|
4
|
+
import { ProviderReference } from './provider-reference';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Text content part of a prompt. It contains a string of text.
|
|
@@ -32,8 +33,9 @@ export interface ImagePart {
|
|
|
32
33
|
*
|
|
33
34
|
* - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
|
|
34
35
|
* - URL: a URL that points to the image
|
|
36
|
+
* - ProviderReference: a provider reference from `uploadFile`
|
|
35
37
|
*/
|
|
36
|
-
image: DataContent | URL;
|
|
38
|
+
image: DataContent | URL | ProviderReference;
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
41
|
* Optional IANA media type of the image.
|
|
@@ -60,9 +62,10 @@ export interface FilePart {
|
|
|
60
62
|
* File data. Can either be:
|
|
61
63
|
*
|
|
62
64
|
* - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
|
|
63
|
-
* - URL: a URL that points to the
|
|
65
|
+
* - URL: a URL that points to the file
|
|
66
|
+
* - ProviderReference: a provider reference from `uploadFile`
|
|
64
67
|
*/
|
|
65
|
-
data: DataContent | URL;
|
|
68
|
+
data: DataContent | URL | ProviderReference;
|
|
66
69
|
|
|
67
70
|
/**
|
|
68
71
|
* Optional filename of the file.
|
|
@@ -103,6 +106,55 @@ export interface ReasoningPart {
|
|
|
103
106
|
providerOptions?: ProviderOptions;
|
|
104
107
|
}
|
|
105
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Custom content part of a prompt. It contains no standardized payload beyond
|
|
111
|
+
* provider-specific options.
|
|
112
|
+
*/
|
|
113
|
+
export interface CustomPart {
|
|
114
|
+
type: 'custom';
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The kind of custom content, in the format `{provider}.{provider-type}`.
|
|
118
|
+
*/
|
|
119
|
+
kind: `${string}.${string}`;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Additional provider-specific metadata. They are passed through
|
|
123
|
+
* to the provider from the AI SDK and enable provider-specific
|
|
124
|
+
* functionality that can be fully encapsulated in the provider.
|
|
125
|
+
*/
|
|
126
|
+
providerOptions?: ProviderOptions;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Reasoning file content part of a prompt. It contains a file generated as part of reasoning.
|
|
131
|
+
*/
|
|
132
|
+
export interface ReasoningFilePart {
|
|
133
|
+
type: 'reasoning-file';
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* File data. Can either be:
|
|
137
|
+
*
|
|
138
|
+
* - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
|
|
139
|
+
* - URL: a URL that points to the file
|
|
140
|
+
*/
|
|
141
|
+
data: DataContent | URL;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* IANA media type of the file.
|
|
145
|
+
*
|
|
146
|
+
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
|
|
147
|
+
*/
|
|
148
|
+
mediaType: string;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Additional provider-specific metadata. They are passed through
|
|
152
|
+
* to the provider from the AI SDK and enable provider-specific
|
|
153
|
+
* functionality that can be fully encapsulated in the provider.
|
|
154
|
+
*/
|
|
155
|
+
providerOptions?: ProviderOptions;
|
|
156
|
+
}
|
|
157
|
+
|
|
106
158
|
/**
|
|
107
159
|
* Tool call content part of a prompt. It contains a tool call (usually generated by the AI model).
|
|
108
160
|
*/
|
|
@@ -287,6 +339,9 @@ export type ToolResultOutput =
|
|
|
287
339
|
providerOptions?: ProviderOptions;
|
|
288
340
|
}
|
|
289
341
|
| {
|
|
342
|
+
/**
|
|
343
|
+
* @deprecated Use file-reference instead.
|
|
344
|
+
*/
|
|
290
345
|
type: 'file-id';
|
|
291
346
|
|
|
292
347
|
/**
|
|
@@ -299,6 +354,20 @@ export type ToolResultOutput =
|
|
|
299
354
|
*/
|
|
300
355
|
fileId: string | Record<string, string>;
|
|
301
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Provider-specific options.
|
|
359
|
+
*/
|
|
360
|
+
providerOptions?: ProviderOptions;
|
|
361
|
+
}
|
|
362
|
+
| {
|
|
363
|
+
type: 'file-reference';
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Provider-specific references for the file.
|
|
367
|
+
* The key is the provider name, e.g. 'openai' or 'anthropic'.
|
|
368
|
+
*/
|
|
369
|
+
providerReference: ProviderReference;
|
|
370
|
+
|
|
302
371
|
/**
|
|
303
372
|
* Provider-specific options.
|
|
304
373
|
*/
|
|
@@ -344,7 +413,7 @@ export type ToolResultOutput =
|
|
|
344
413
|
}
|
|
345
414
|
| {
|
|
346
415
|
/**
|
|
347
|
-
*
|
|
416
|
+
* @deprecated Use image-file-reference instead.
|
|
348
417
|
*/
|
|
349
418
|
type: 'image-file-id';
|
|
350
419
|
|
|
@@ -358,6 +427,23 @@ export type ToolResultOutput =
|
|
|
358
427
|
*/
|
|
359
428
|
fileId: string | Record<string, string>;
|
|
360
429
|
|
|
430
|
+
/**
|
|
431
|
+
* Provider-specific options.
|
|
432
|
+
*/
|
|
433
|
+
providerOptions?: ProviderOptions;
|
|
434
|
+
}
|
|
435
|
+
| {
|
|
436
|
+
/**
|
|
437
|
+
* Images that are referenced using a provider reference.
|
|
438
|
+
*/
|
|
439
|
+
type: 'image-file-reference';
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Provider-specific references for the image file.
|
|
443
|
+
* The key is the provider name, e.g. 'openai' or 'anthropic'.
|
|
444
|
+
*/
|
|
445
|
+
providerReference: ProviderReference;
|
|
446
|
+
|
|
361
447
|
/**
|
|
362
448
|
* Provider-specific options.
|
|
363
449
|
*/
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
import { isAsyncIterable } from '../is-async-iterable';
|
|
2
|
-
import {
|
|
2
|
+
import { Context } from './context';
|
|
3
|
+
import { ToolExecuteFunction, ToolExecutionOptions } from './tool';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Executes a tool function, supporting both synchronous and streaming/asynchronous results.
|
|
7
|
+
*
|
|
8
|
+
* This generator yields intermediate ("preliminary") outputs as they're produced, allowing callers
|
|
9
|
+
* to stream partial tool results before completion. When execution is finished, it yields a final output,
|
|
10
|
+
* ensuring all consumers receive a conclusive result.
|
|
11
|
+
*
|
|
12
|
+
* - If the tool's `execute` function returns an `AsyncIterable`, all intermediate values are yielded
|
|
13
|
+
* as `{ type: "preliminary", output }` except the last, which is yielded as `{ type: "final", output }`.
|
|
14
|
+
* - If the tool returns a direct value or Promise, a single `{ type: "final", output }` is yielded.
|
|
15
|
+
*
|
|
16
|
+
* @template INPUT Input type for the tool execution.
|
|
17
|
+
* @template OUTPUT Output type for the tool execution.
|
|
18
|
+
* @template CONTEXT Context object extension for execution (extends Context).
|
|
19
|
+
* @param params.execute The tool execute function.
|
|
20
|
+
* @param params.input Input value to pass to the execute function.
|
|
21
|
+
* @param params.options Additional options for tool execution.
|
|
22
|
+
* @yields An object containing either a preliminary or final output from the tool.
|
|
23
|
+
*/
|
|
24
|
+
export async function* executeTool<INPUT, OUTPUT, CONTEXT extends Context>({
|
|
5
25
|
execute,
|
|
6
26
|
input,
|
|
7
27
|
options,
|
|
8
28
|
}: {
|
|
9
|
-
execute: ToolExecuteFunction<INPUT, OUTPUT>;
|
|
29
|
+
execute: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
|
|
10
30
|
input: INPUT;
|
|
11
|
-
options: ToolExecutionOptions
|
|
31
|
+
options: ToolExecutionOptions<NoInfer<CONTEXT>>;
|
|
12
32
|
}): AsyncGenerator<
|
|
13
33
|
{ type: 'preliminary'; output: OUTPUT } | { type: 'final'; output: OUTPUT }
|
|
14
34
|
> {
|