@ai-sdk/provider-utils 4.0.4 → 4.0.6
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.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
- package/src/__snapshots__/schema.test.ts.snap +346 -0
- package/src/add-additional-properties-to-json-schema.test.ts +289 -0
- package/src/add-additional-properties-to-json-schema.ts +53 -0
- package/src/combine-headers.ts +11 -0
- package/src/convert-async-iterator-to-readable-stream.test.ts +78 -0
- package/src/convert-async-iterator-to-readable-stream.ts +47 -0
- package/src/convert-image-model-file-to-data-uri.test.ts +85 -0
- package/src/convert-image-model-file-to-data-uri.ts +19 -0
- package/src/convert-to-form-data.test.ts +167 -0
- package/src/convert-to-form-data.ts +61 -0
- package/src/create-tool-name-mapping.test.ts +163 -0
- package/src/create-tool-name-mapping.ts +66 -0
- package/src/delay.test.ts +212 -0
- package/src/delay.ts +47 -0
- package/src/delayed-promise.test.ts +132 -0
- package/src/delayed-promise.ts +61 -0
- package/src/download-blob.test.ts +145 -0
- package/src/download-blob.ts +31 -0
- package/src/download-error.ts +39 -0
- package/src/extract-response-headers.ts +9 -0
- package/src/fetch-function.ts +4 -0
- package/src/generate-id.test.ts +31 -0
- package/src/generate-id.ts +57 -0
- package/src/get-error-message.ts +15 -0
- package/src/get-from-api.test.ts +199 -0
- package/src/get-from-api.ts +97 -0
- package/src/get-runtime-environment-user-agent.test.ts +47 -0
- package/src/get-runtime-environment-user-agent.ts +24 -0
- package/src/handle-fetch-error.ts +39 -0
- package/src/index.ts +67 -0
- package/src/inject-json-instruction.test.ts +404 -0
- package/src/inject-json-instruction.ts +63 -0
- package/src/is-abort-error.ts +8 -0
- package/src/is-async-iterable.ts +3 -0
- package/src/is-non-nullable.ts +12 -0
- package/src/is-url-supported.test.ts +282 -0
- package/src/is-url-supported.ts +40 -0
- package/src/load-api-key.ts +45 -0
- package/src/load-optional-setting.ts +30 -0
- package/src/load-setting.ts +62 -0
- package/src/maybe-promise-like.ts +3 -0
- package/src/media-type-to-extension.test.ts +26 -0
- package/src/media-type-to-extension.ts +22 -0
- package/src/normalize-headers.test.ts +64 -0
- package/src/normalize-headers.ts +38 -0
- package/src/parse-json-event-stream.ts +33 -0
- package/src/parse-json.test.ts +191 -0
- package/src/parse-json.ts +122 -0
- package/src/parse-provider-options.ts +32 -0
- package/src/post-to-api.ts +166 -0
- package/src/provider-tool-factory.ts +125 -0
- package/src/remove-undefined-entries.test.ts +57 -0
- package/src/remove-undefined-entries.ts +12 -0
- package/src/resolve.test.ts +125 -0
- package/src/resolve.ts +17 -0
- package/src/response-handler.test.ts +89 -0
- package/src/response-handler.ts +187 -0
- package/src/schema.test-d.ts +11 -0
- package/src/schema.test.ts +502 -0
- package/src/schema.ts +267 -0
- package/src/secure-json-parse.test.ts +59 -0
- package/src/secure-json-parse.ts +92 -0
- package/src/test/convert-array-to-async-iterable.ts +9 -0
- package/src/test/convert-array-to-readable-stream.ts +15 -0
- package/src/test/convert-async-iterable-to-array.ts +9 -0
- package/src/test/convert-readable-stream-to-array.ts +14 -0
- package/src/test/convert-response-stream-to-array.ts +9 -0
- package/src/test/index.ts +7 -0
- package/src/test/is-node-version.ts +4 -0
- package/src/test/mock-id.ts +8 -0
- package/src/to-json-schema/zod3-to-json-schema/LICENSE +16 -0
- package/src/to-json-schema/zod3-to-json-schema/README.md +24 -0
- package/src/to-json-schema/zod3-to-json-schema/get-relative-path.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/index.ts +1 -0
- package/src/to-json-schema/zod3-to-json-schema/options.ts +98 -0
- package/src/to-json-schema/zod3-to-json-schema/parse-def.test.ts +224 -0
- package/src/to-json-schema/zod3-to-json-schema/parse-def.ts +109 -0
- package/src/to-json-schema/zod3-to-json-schema/parse-types.ts +57 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/any.ts +5 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.test.ts +98 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.ts +38 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.test.ts +51 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.ts +44 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/boolean.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.test.ts +16 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.test.ts +15 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.test.ts +97 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.ts +64 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.test.ts +54 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.ts +14 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.test.ts +41 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.ts +14 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/enum.ts +13 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.test.ts +92 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.ts +52 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/literal.ts +29 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.test.ts +48 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.ts +47 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.test.ts +102 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.ts +31 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/never.ts +9 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/null.ts +9 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.test.ts +67 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.ts +42 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.test.ts +65 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.ts +44 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.test.ts +149 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.ts +88 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.test.ts +147 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.ts +23 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipe.test.ts +35 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipeline.ts +29 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.test.ts +15 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.ts +11 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.test.ts +20 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.test.ts +108 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.ts +71 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.test.ts +20 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.ts +35 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.test.ts +438 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.ts +426 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.test.ts +33 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.ts +61 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/undefined.ts +11 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.test.ts +226 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.ts +144 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/unknown.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/refs.test.ts +919 -0
- package/src/to-json-schema/zod3-to-json-schema/refs.ts +39 -0
- package/src/to-json-schema/zod3-to-json-schema/select-parser.ts +115 -0
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.test.ts +862 -0
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.ts +93 -0
- package/src/types/assistant-model-message.ts +39 -0
- package/src/types/content-part.ts +379 -0
- package/src/types/data-content.ts +4 -0
- package/src/types/execute-tool.ts +27 -0
- package/src/types/index.ts +40 -0
- package/src/types/model-message.ts +14 -0
- package/src/types/provider-options.ts +9 -0
- package/src/types/system-model-message.ts +20 -0
- package/src/types/tool-approval-request.ts +16 -0
- package/src/types/tool-approval-response.ts +27 -0
- package/src/types/tool-call.ts +31 -0
- package/src/types/tool-model-message.ts +23 -0
- package/src/types/tool-result.ts +35 -0
- package/src/types/tool.test-d.ts +193 -0
- package/src/types/tool.ts +324 -0
- package/src/types/user-model-message.ts +22 -0
- package/src/uint8-utils.ts +26 -0
- package/src/validate-types.test.ts +105 -0
- package/src/validate-types.ts +81 -0
- package/src/version.ts +6 -0
- package/src/with-user-agent-suffix.test.ts +84 -0
- package/src/with-user-agent-suffix.ts +27 -0
- package/src/without-trailing-slash.ts +3 -0
- package/LICENSE +0 -13
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ToolResultPart } from './content-part';
|
|
2
|
+
import { ProviderOptions } from './provider-options';
|
|
3
|
+
import { ToolApprovalResponse } from './tool-approval-response';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
A tool message. It contains the result of one or more tool calls.
|
|
7
|
+
*/
|
|
8
|
+
export type ToolModelMessage = {
|
|
9
|
+
role: 'tool';
|
|
10
|
+
content: ToolContent;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
Additional provider-specific metadata. They are passed through
|
|
14
|
+
to the provider from the AI SDK and enable provider-specific
|
|
15
|
+
functionality that can be fully encapsulated in the provider.
|
|
16
|
+
*/
|
|
17
|
+
providerOptions?: ProviderOptions;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
Content of a tool message. It is an array of tool result parts.
|
|
22
|
+
*/
|
|
23
|
+
export type ToolContent = Array<ToolResultPart | ToolApprovalResponse>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Typed tool result that is returned by `generateText` and `streamText`.
|
|
3
|
+
It contains the tool call ID, the tool name, the tool arguments, and the tool result.
|
|
4
|
+
*/
|
|
5
|
+
export interface ToolResult<NAME extends string, INPUT, OUTPUT> {
|
|
6
|
+
/**
|
|
7
|
+
ID of the tool call. This ID is used to match the tool call with the tool result.
|
|
8
|
+
*/
|
|
9
|
+
toolCallId: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
Name of the tool that was called.
|
|
13
|
+
*/
|
|
14
|
+
toolName: NAME;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
Arguments of the tool call. This is a JSON-serializable object that matches the tool's input schema.
|
|
18
|
+
*/
|
|
19
|
+
input: INPUT;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
Result of the tool call. This is the result of the tool's execution.
|
|
23
|
+
*/
|
|
24
|
+
output: OUTPUT;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Whether the tool result has been executed by the provider.
|
|
28
|
+
*/
|
|
29
|
+
providerExecuted?: boolean;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Whether the tool is dynamic.
|
|
33
|
+
*/
|
|
34
|
+
dynamic?: boolean;
|
|
35
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { LanguageModelV3ToolResultPart } from '@ai-sdk/provider';
|
|
2
|
+
import { describe, expectTypeOf, it } from 'vitest';
|
|
3
|
+
import { z } from 'zod/v4';
|
|
4
|
+
import { FlexibleSchema } from '../schema';
|
|
5
|
+
import { ModelMessage } from './model-message';
|
|
6
|
+
import { Tool, tool, ToolExecuteFunction } from './tool';
|
|
7
|
+
import { ToolResultOutput } from './content-part';
|
|
8
|
+
|
|
9
|
+
describe('tool type', () => {
|
|
10
|
+
describe('input type', () => {
|
|
11
|
+
it('should work with fixed inputSchema', () => {
|
|
12
|
+
const aTool = tool({
|
|
13
|
+
inputSchema: z.object({ number: z.number() }),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expectTypeOf(aTool).toEqualTypeOf<Tool<{ number: number }, never>>();
|
|
17
|
+
expectTypeOf(aTool.execute).toEqualTypeOf<undefined>();
|
|
18
|
+
expectTypeOf(aTool.execute).not.toEqualTypeOf<Function>();
|
|
19
|
+
expectTypeOf(aTool.inputSchema).toEqualTypeOf<
|
|
20
|
+
FlexibleSchema<{ number: number }>
|
|
21
|
+
>();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should work with flexible inputSchema', <T>() => {
|
|
25
|
+
const aTool = tool({
|
|
26
|
+
inputSchema: null as unknown as FlexibleSchema<T>,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expectTypeOf(aTool).toEqualTypeOf<Tool<T, never>>();
|
|
30
|
+
expectTypeOf(aTool.execute).toEqualTypeOf<undefined>();
|
|
31
|
+
expectTypeOf(aTool.execute).not.toEqualTypeOf<Function>();
|
|
32
|
+
expectTypeOf(aTool.inputSchema).toEqualTypeOf<FlexibleSchema<T>>();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('output type', () => {
|
|
37
|
+
it('should derive output type from execute function', () => {
|
|
38
|
+
const aTool = tool({
|
|
39
|
+
inputSchema: z.object({ number: z.number() }),
|
|
40
|
+
execute: async input => {
|
|
41
|
+
expectTypeOf(input).toEqualTypeOf<{ number: number }>();
|
|
42
|
+
return 'test' as const;
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expectTypeOf(aTool).toEqualTypeOf<Tool<{ number: number }, 'test'>>();
|
|
47
|
+
expectTypeOf(aTool.execute).toMatchTypeOf<
|
|
48
|
+
ToolExecuteFunction<{ number: number }, 'test'> | undefined
|
|
49
|
+
>();
|
|
50
|
+
expectTypeOf(aTool.execute).not.toEqualTypeOf<undefined>();
|
|
51
|
+
expectTypeOf(aTool.inputSchema).toEqualTypeOf<
|
|
52
|
+
FlexibleSchema<{ number: number }>
|
|
53
|
+
>();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should derive const schema from async generator execute function', () => {
|
|
57
|
+
const aTool = tool({
|
|
58
|
+
inputSchema: z.object({ number: z.number() }),
|
|
59
|
+
execute: async function* () {
|
|
60
|
+
yield 'test' as const;
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
expectTypeOf(aTool).toEqualTypeOf<Tool<{ number: number }, 'test'>>();
|
|
65
|
+
expectTypeOf(aTool.execute).toEqualTypeOf<
|
|
66
|
+
ToolExecuteFunction<{ number: number }, 'test'> | undefined
|
|
67
|
+
>();
|
|
68
|
+
expectTypeOf(aTool.inputSchema).toEqualTypeOf<
|
|
69
|
+
FlexibleSchema<{ number: number }>
|
|
70
|
+
>();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('toModelOutput', () => {
|
|
75
|
+
it('should infer toModelOutput argument when there is only an input schema', () => {
|
|
76
|
+
const aTool = tool({
|
|
77
|
+
inputSchema: z.object({ number: z.number() }),
|
|
78
|
+
toModelOutput: ({ output }) => {
|
|
79
|
+
expectTypeOf(output).toEqualTypeOf<any>();
|
|
80
|
+
return { type: 'text', value: 'test' };
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expectTypeOf(aTool.toModelOutput).toMatchTypeOf<
|
|
85
|
+
| ((options: {
|
|
86
|
+
toolCallId: string;
|
|
87
|
+
input: { number: number };
|
|
88
|
+
output: any;
|
|
89
|
+
}) => ToolResultOutput | PromiseLike<ToolResultOutput>)
|
|
90
|
+
| undefined
|
|
91
|
+
>();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should infer toModelOutput argument when there is an execute function', () => {
|
|
95
|
+
const aTool = tool({
|
|
96
|
+
inputSchema: z.object({ number: z.number() }),
|
|
97
|
+
execute: async () => 'test' as const,
|
|
98
|
+
toModelOutput: ({ output }) => {
|
|
99
|
+
expectTypeOf(output).toEqualTypeOf<'test'>();
|
|
100
|
+
return { type: 'text', value: 'test' };
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expectTypeOf(aTool.toModelOutput).toMatchTypeOf<
|
|
105
|
+
| ((options: {
|
|
106
|
+
toolCallId: string;
|
|
107
|
+
input: { number: number };
|
|
108
|
+
output: 'test';
|
|
109
|
+
}) => ToolResultOutput | PromiseLike<ToolResultOutput>)
|
|
110
|
+
| undefined
|
|
111
|
+
>();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should infer toModelOutput argument when there is an output schema', () => {
|
|
115
|
+
const aTool = tool({
|
|
116
|
+
inputSchema: z.object({ number: z.number() }),
|
|
117
|
+
outputSchema: z.literal('test'),
|
|
118
|
+
toModelOutput: ({ output }) => {
|
|
119
|
+
expectTypeOf(output).toEqualTypeOf<'test'>();
|
|
120
|
+
return { type: 'text', value: 'test' };
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
expectTypeOf(aTool.toModelOutput).toMatchTypeOf<
|
|
125
|
+
| ((options: {
|
|
126
|
+
toolCallId: string;
|
|
127
|
+
input: { number: number };
|
|
128
|
+
output: 'test';
|
|
129
|
+
}) => ToolResultOutput | PromiseLike<ToolResultOutput>)
|
|
130
|
+
| undefined
|
|
131
|
+
>();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('needsApproval (function)', () => {
|
|
136
|
+
it('should infer needsApproval argument when there is only an input schema', () => {
|
|
137
|
+
const aTool = tool({
|
|
138
|
+
inputSchema: z.object({ number: z.number() }),
|
|
139
|
+
needsApproval: (input, options) => {
|
|
140
|
+
expectTypeOf(input).toEqualTypeOf<{ number: number }>();
|
|
141
|
+
expectTypeOf(options).toEqualTypeOf<{
|
|
142
|
+
toolCallId: string;
|
|
143
|
+
messages: ModelMessage[];
|
|
144
|
+
experimental_context?: unknown;
|
|
145
|
+
}>();
|
|
146
|
+
return true;
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expectTypeOf(aTool.needsApproval).toMatchTypeOf<
|
|
151
|
+
| boolean
|
|
152
|
+
| ((
|
|
153
|
+
input: { number: number },
|
|
154
|
+
options: {
|
|
155
|
+
toolCallId: string;
|
|
156
|
+
messages: ModelMessage[];
|
|
157
|
+
experimental_context: unknown;
|
|
158
|
+
},
|
|
159
|
+
) => boolean | PromiseLike<boolean>)
|
|
160
|
+
| undefined
|
|
161
|
+
>();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should infer needsApproval argument when there is an execute function', () => {
|
|
165
|
+
const aTool = tool({
|
|
166
|
+
inputSchema: z.object({ number: z.number() }),
|
|
167
|
+
execute: async () => 'test' as const,
|
|
168
|
+
needsApproval: (input, options) => {
|
|
169
|
+
expectTypeOf(input).toEqualTypeOf<{ number: number }>();
|
|
170
|
+
expectTypeOf(options).toEqualTypeOf<{
|
|
171
|
+
toolCallId: string;
|
|
172
|
+
messages: ModelMessage[];
|
|
173
|
+
experimental_context?: unknown;
|
|
174
|
+
}>();
|
|
175
|
+
return true;
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
expectTypeOf(aTool.needsApproval).toMatchTypeOf<
|
|
180
|
+
| boolean
|
|
181
|
+
| ((
|
|
182
|
+
input: { number: number },
|
|
183
|
+
options: {
|
|
184
|
+
toolCallId: string;
|
|
185
|
+
messages: ModelMessage[];
|
|
186
|
+
experimental_context: unknown;
|
|
187
|
+
},
|
|
188
|
+
) => boolean | PromiseLike<boolean>)
|
|
189
|
+
| undefined
|
|
190
|
+
>();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { JSONValue } from '@ai-sdk/provider';
|
|
2
|
+
import { FlexibleSchema } from '../schema';
|
|
3
|
+
import { ToolResultOutput } from './content-part';
|
|
4
|
+
import { ModelMessage } from './model-message';
|
|
5
|
+
import { ProviderOptions } from './provider-options';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Additional options that are sent into each tool call.
|
|
9
|
+
*/
|
|
10
|
+
export interface ToolExecutionOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
|
|
13
|
+
*/
|
|
14
|
+
toolCallId: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Messages that were sent to the language model to initiate the response that contained the tool call.
|
|
18
|
+
* The messages **do not** include the system prompt nor the assistant response that contained the tool call.
|
|
19
|
+
*/
|
|
20
|
+
messages: ModelMessage[];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* An optional abort signal that indicates that the overall operation should be aborted.
|
|
24
|
+
*/
|
|
25
|
+
abortSignal?: AbortSignal;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* User-defined context.
|
|
29
|
+
*
|
|
30
|
+
* Treat the context object as immutable inside tools.
|
|
31
|
+
* Mutating the context object can lead to race conditions and unexpected results
|
|
32
|
+
* when tools are called in parallel.
|
|
33
|
+
*
|
|
34
|
+
* If you need to mutate the context, analyze the tool calls and results
|
|
35
|
+
* in `prepareStep` and update it there.
|
|
36
|
+
*
|
|
37
|
+
* Experimental (can break in patch releases).
|
|
38
|
+
*/
|
|
39
|
+
experimental_context?: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Function that is called to determine if the tool needs approval before it can be executed.
|
|
44
|
+
*/
|
|
45
|
+
export type ToolNeedsApprovalFunction<INPUT> = (
|
|
46
|
+
input: INPUT,
|
|
47
|
+
options: {
|
|
48
|
+
/**
|
|
49
|
+
* The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
|
|
50
|
+
*/
|
|
51
|
+
toolCallId: string;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Messages that were sent to the language model to initiate the response that contained the tool call.
|
|
55
|
+
* The messages **do not** include the system prompt nor the assistant response that contained the tool call.
|
|
56
|
+
*/
|
|
57
|
+
messages: ModelMessage[];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Additional context.
|
|
61
|
+
*
|
|
62
|
+
* Experimental (can break in patch releases).
|
|
63
|
+
*/
|
|
64
|
+
experimental_context?: unknown;
|
|
65
|
+
},
|
|
66
|
+
) => boolean | PromiseLike<boolean>;
|
|
67
|
+
|
|
68
|
+
export type ToolExecuteFunction<INPUT, OUTPUT> = (
|
|
69
|
+
input: INPUT,
|
|
70
|
+
options: ToolExecutionOptions,
|
|
71
|
+
) => AsyncIterable<OUTPUT> | PromiseLike<OUTPUT> | OUTPUT;
|
|
72
|
+
|
|
73
|
+
// 0 extends 1 & N checks for any
|
|
74
|
+
// [N] extends [never] checks for never
|
|
75
|
+
type NeverOptional<N, T> = 0 extends 1 & N
|
|
76
|
+
? Partial<T>
|
|
77
|
+
: [N] extends [never]
|
|
78
|
+
? Partial<Record<keyof T, undefined>>
|
|
79
|
+
: T;
|
|
80
|
+
|
|
81
|
+
type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
|
|
82
|
+
OUTPUT,
|
|
83
|
+
| {
|
|
84
|
+
/**
|
|
85
|
+
An async function that is called with the arguments from the tool call and produces a result.
|
|
86
|
+
If not provided, the tool will not be executed automatically.
|
|
87
|
+
|
|
88
|
+
@args is the input of the tool call.
|
|
89
|
+
@options.abortSignal is a signal that can be used to abort the tool call.
|
|
90
|
+
*/
|
|
91
|
+
execute: ToolExecuteFunction<INPUT, OUTPUT>;
|
|
92
|
+
|
|
93
|
+
outputSchema?: FlexibleSchema<OUTPUT>;
|
|
94
|
+
}
|
|
95
|
+
| {
|
|
96
|
+
outputSchema: FlexibleSchema<OUTPUT>;
|
|
97
|
+
|
|
98
|
+
execute?: never;
|
|
99
|
+
}
|
|
100
|
+
>;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
A tool contains the description and the schema of the input that the tool expects.
|
|
104
|
+
This enables the language model to generate the input.
|
|
105
|
+
|
|
106
|
+
The tool can also contain an optional execute function for the actual execution function of the tool.
|
|
107
|
+
*/
|
|
108
|
+
export type Tool<
|
|
109
|
+
INPUT extends JSONValue | unknown | never = any,
|
|
110
|
+
OUTPUT extends JSONValue | unknown | never = any,
|
|
111
|
+
> = {
|
|
112
|
+
/**
|
|
113
|
+
An optional description of what the tool does.
|
|
114
|
+
Will be used by the language model to decide whether to use the tool.
|
|
115
|
+
Not used for provider-defined tools.
|
|
116
|
+
*/
|
|
117
|
+
description?: string;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* An optional title of the tool.
|
|
121
|
+
*/
|
|
122
|
+
title?: string;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
Additional provider-specific metadata. They are passed through
|
|
126
|
+
to the provider from the AI SDK and enable provider-specific
|
|
127
|
+
functionality that can be fully encapsulated in the provider.
|
|
128
|
+
*/
|
|
129
|
+
providerOptions?: ProviderOptions;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The schema of the input that the tool expects.
|
|
133
|
+
* The language model will use this to generate the input.
|
|
134
|
+
* It is also used to validate the output of the language model.
|
|
135
|
+
*
|
|
136
|
+
* You can use descriptions on the schema properties to make the input understandable for the language model.
|
|
137
|
+
*/
|
|
138
|
+
inputSchema: FlexibleSchema<INPUT>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* An optional list of input examples that show the language
|
|
142
|
+
* model what the input should look like.
|
|
143
|
+
*/
|
|
144
|
+
inputExamples?: Array<{ input: INPUT }>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Whether the tool needs approval before it can be executed.
|
|
148
|
+
*/
|
|
149
|
+
needsApproval?:
|
|
150
|
+
| boolean
|
|
151
|
+
| ToolNeedsApprovalFunction<[INPUT] extends [never] ? unknown : INPUT>;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Strict mode setting for the tool.
|
|
155
|
+
*
|
|
156
|
+
* Providers that support strict mode will use this setting to determine
|
|
157
|
+
* how the input should be generated. Strict mode will always produce
|
|
158
|
+
* valid inputs, but it might limit what input schemas are supported.
|
|
159
|
+
*/
|
|
160
|
+
strict?: boolean;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Optional function that is called when the argument streaming starts.
|
|
164
|
+
* Only called when the tool is used in a streaming context.
|
|
165
|
+
*/
|
|
166
|
+
onInputStart?: (options: ToolExecutionOptions) => void | PromiseLike<void>;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Optional function that is called when an argument streaming delta is available.
|
|
170
|
+
* Only called when the tool is used in a streaming context.
|
|
171
|
+
*/
|
|
172
|
+
onInputDelta?: (
|
|
173
|
+
options: { inputTextDelta: string } & ToolExecutionOptions,
|
|
174
|
+
) => void | PromiseLike<void>;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Optional function that is called when a tool call can be started,
|
|
178
|
+
* even if the execute function is not provided.
|
|
179
|
+
*/
|
|
180
|
+
onInputAvailable?: (
|
|
181
|
+
options: {
|
|
182
|
+
input: [INPUT] extends [never] ? unknown : INPUT;
|
|
183
|
+
} & ToolExecutionOptions,
|
|
184
|
+
) => void | PromiseLike<void>;
|
|
185
|
+
} & ToolOutputProperties<INPUT, OUTPUT> & {
|
|
186
|
+
/**
|
|
187
|
+
* Optional conversion function that maps the tool result to an output that can be used by the language model.
|
|
188
|
+
*
|
|
189
|
+
* If not provided, the tool result will be sent as a JSON object.
|
|
190
|
+
*/
|
|
191
|
+
toModelOutput?: (options: {
|
|
192
|
+
/**
|
|
193
|
+
* The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
|
|
194
|
+
*/
|
|
195
|
+
toolCallId: string;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The input of the tool call.
|
|
199
|
+
*/
|
|
200
|
+
input: [INPUT] extends [never] ? unknown : INPUT;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The output of the tool call.
|
|
204
|
+
*/
|
|
205
|
+
output: 0 extends 1 & OUTPUT
|
|
206
|
+
? any
|
|
207
|
+
: [OUTPUT] extends [never]
|
|
208
|
+
? any
|
|
209
|
+
: NoInfer<OUTPUT>;
|
|
210
|
+
}) => ToolResultOutput | PromiseLike<ToolResultOutput>;
|
|
211
|
+
} & (
|
|
212
|
+
| {
|
|
213
|
+
/**
|
|
214
|
+
Tool with user-defined input and output schemas.
|
|
215
|
+
*/
|
|
216
|
+
type?: undefined | 'function';
|
|
217
|
+
}
|
|
218
|
+
| {
|
|
219
|
+
/**
|
|
220
|
+
Tool that is defined at runtime (e.g. an MCP tool).
|
|
221
|
+
The types of input and output are not known at development time.
|
|
222
|
+
*/
|
|
223
|
+
type: 'dynamic';
|
|
224
|
+
}
|
|
225
|
+
| {
|
|
226
|
+
/**
|
|
227
|
+
Tool with provider-defined input and output schemas.
|
|
228
|
+
*/
|
|
229
|
+
type: 'provider';
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
The ID of the tool. Must follow the format `<provider-name>.<unique-tool-name>`.
|
|
233
|
+
*/
|
|
234
|
+
id: `${string}.${string}`;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
The arguments for configuring the tool. Must match the expected arguments defined by the provider for this tool.
|
|
238
|
+
*/
|
|
239
|
+
args: Record<string, unknown>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Whether this provider-executed tool supports deferred results.
|
|
243
|
+
*
|
|
244
|
+
* When true, the tool result may not be returned in the same turn as the
|
|
245
|
+
* tool call (e.g., when using programmatic tool calling where a server tool
|
|
246
|
+
* triggers a client-executed tool, and the server tool's result is deferred
|
|
247
|
+
* until the client tool is resolved).
|
|
248
|
+
*
|
|
249
|
+
* This flag allows the AI SDK to handle tool results that arrive without
|
|
250
|
+
* a matching tool call in the current response.
|
|
251
|
+
*
|
|
252
|
+
* @default false
|
|
253
|
+
*/
|
|
254
|
+
supportsDeferredResults?: boolean;
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Infer the input type of a tool.
|
|
260
|
+
*/
|
|
261
|
+
export type InferToolInput<TOOL extends Tool> =
|
|
262
|
+
TOOL extends Tool<infer INPUT, any> ? INPUT : never;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Infer the output type of a tool.
|
|
266
|
+
*/
|
|
267
|
+
export type InferToolOutput<TOOL extends Tool> =
|
|
268
|
+
TOOL extends Tool<any, infer OUTPUT> ? OUTPUT : never;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
Helper function for inferring the execute args of a tool.
|
|
272
|
+
*/
|
|
273
|
+
// Note: overload order is important for auto-completion
|
|
274
|
+
export function tool<INPUT, OUTPUT>(
|
|
275
|
+
tool: Tool<INPUT, OUTPUT>,
|
|
276
|
+
): Tool<INPUT, OUTPUT>;
|
|
277
|
+
export function tool<INPUT>(tool: Tool<INPUT, never>): Tool<INPUT, never>;
|
|
278
|
+
export function tool<OUTPUT>(tool: Tool<never, OUTPUT>): Tool<never, OUTPUT>;
|
|
279
|
+
export function tool(tool: Tool<never, never>): Tool<never, never>;
|
|
280
|
+
export function tool(tool: any): any {
|
|
281
|
+
return tool;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Defines a dynamic tool.
|
|
286
|
+
*/
|
|
287
|
+
export function dynamicTool(tool: {
|
|
288
|
+
description?: string;
|
|
289
|
+
title?: string;
|
|
290
|
+
providerOptions?: ProviderOptions;
|
|
291
|
+
inputSchema: FlexibleSchema<unknown>;
|
|
292
|
+
execute: ToolExecuteFunction<unknown, unknown>;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Optional conversion function that maps the tool result to an output that can be used by the language model.
|
|
296
|
+
*
|
|
297
|
+
* If not provided, the tool result will be sent as a JSON object.
|
|
298
|
+
*/
|
|
299
|
+
toModelOutput?: (options: {
|
|
300
|
+
/**
|
|
301
|
+
* The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
|
|
302
|
+
*/
|
|
303
|
+
toolCallId: string;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* The input of the tool call.
|
|
307
|
+
*/
|
|
308
|
+
input: unknown;
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* The output of the tool call.
|
|
312
|
+
*/
|
|
313
|
+
output: unknown;
|
|
314
|
+
}) => ToolResultOutput | PromiseLike<ToolResultOutput>;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Whether the tool needs approval before it can be executed.
|
|
318
|
+
*/
|
|
319
|
+
needsApproval?: boolean | ToolNeedsApprovalFunction<unknown>;
|
|
320
|
+
}): Tool<unknown, unknown> & {
|
|
321
|
+
type: 'dynamic';
|
|
322
|
+
} {
|
|
323
|
+
return { ...tool, type: 'dynamic' };
|
|
324
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FilePart, ImagePart, TextPart } from './content-part';
|
|
2
|
+
import { ProviderOptions } from './provider-options';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
A user message. It can contain text or a combination of text and images.
|
|
6
|
+
*/
|
|
7
|
+
export type UserModelMessage = {
|
|
8
|
+
role: 'user';
|
|
9
|
+
content: UserContent;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
Additional provider-specific metadata. They are passed through
|
|
13
|
+
to the provider from the AI SDK and enable provider-specific
|
|
14
|
+
functionality that can be fully encapsulated in the provider.
|
|
15
|
+
*/
|
|
16
|
+
providerOptions?: ProviderOptions;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
Content of a user message. It can be a string or an array of text and image parts.
|
|
21
|
+
*/
|
|
22
|
+
export type UserContent = string | Array<TextPart | ImagePart | FilePart>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// btoa and atob need to be invoked as a function call, not as a method call.
|
|
2
|
+
// Otherwise CloudFlare will throw a
|
|
3
|
+
// "TypeError: Illegal invocation: function called with incorrect this reference"
|
|
4
|
+
const { btoa, atob } = globalThis;
|
|
5
|
+
|
|
6
|
+
export function convertBase64ToUint8Array(base64String: string) {
|
|
7
|
+
const base64Url = base64String.replace(/-/g, '+').replace(/_/g, '/');
|
|
8
|
+
const latin1string = atob(base64Url);
|
|
9
|
+
return Uint8Array.from(latin1string, byte => byte.codePointAt(0)!);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function convertUint8ArrayToBase64(array: Uint8Array): string {
|
|
13
|
+
let latin1string = '';
|
|
14
|
+
|
|
15
|
+
// Note: regular for loop to support older JavaScript versions that
|
|
16
|
+
// do not support for..of on Uint8Array
|
|
17
|
+
for (let i = 0; i < array.length; i++) {
|
|
18
|
+
latin1string += String.fromCodePoint(array[i]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return btoa(latin1string);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function convertToBase64(value: string | Uint8Array): string {
|
|
25
|
+
return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
|
|
26
|
+
}
|