@ai-sdk/provider-utils 5.0.0-beta.9 → 5.0.0-canary.32

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +184 -0
  2. package/dist/index.d.ts +1346 -878
  3. package/dist/index.js +813 -325
  4. package/dist/index.js.map +1 -1
  5. package/dist/test/index.d.ts +2 -1
  6. package/dist/test/index.js +18 -37
  7. package/dist/test/index.js.map +1 -1
  8. package/package.json +13 -11
  9. package/src/add-additional-properties-to-json-schema.ts +1 -1
  10. package/src/as-array.ts +12 -0
  11. package/src/convert-image-model-file-to-data-uri.ts +1 -1
  12. package/src/convert-inline-file-data-to-uint8-array.ts +30 -0
  13. package/src/create-tool-name-mapping.ts +1 -1
  14. package/src/detect-media-type.ts +312 -0
  15. package/src/filter-nullable.ts +11 -0
  16. package/src/get-error-message.ts +1 -15
  17. package/src/get-from-api.ts +2 -2
  18. package/src/has-required-key.ts +6 -0
  19. package/src/index.ts +39 -14
  20. package/src/inject-json-instruction.ts +1 -1
  21. package/src/is-buffer.ts +9 -0
  22. package/src/is-json-serializable.ts +29 -0
  23. package/src/is-provider-reference.ts +21 -0
  24. package/src/is-url-supported.ts +17 -2
  25. package/src/load-api-key.ts +1 -1
  26. package/src/load-setting.ts +1 -1
  27. package/src/map-reasoning-to-provider.ts +4 -1
  28. package/src/maybe-promise-like.ts +3 -0
  29. package/src/parse-json-event-stream.ts +3 -3
  30. package/src/parse-json.ts +3 -3
  31. package/src/parse-provider-options.ts +1 -1
  32. package/src/post-to-api.ts +4 -4
  33. package/src/{provider-tool-factory.ts → provider-defined-tool-factory.ts} +22 -29
  34. package/src/provider-executed-tool-factory.ts +69 -0
  35. package/src/resolve-full-media-type.ts +49 -0
  36. package/src/resolve-provider-reference.ts +26 -0
  37. package/src/resolve.ts +16 -1
  38. package/src/response-handler.ts +3 -3
  39. package/src/schema.ts +6 -3
  40. package/src/secure-json-parse.ts +1 -1
  41. package/src/serialize-model-options.ts +63 -0
  42. package/src/streaming-tool-call-tracker.ts +241 -0
  43. package/src/test/convert-response-stream-to-array.ts +1 -1
  44. package/src/test/is-node-version.ts +22 -1
  45. package/src/to-json-schema/zod3-to-json-schema/options.ts +3 -3
  46. package/src/to-json-schema/zod3-to-json-schema/parse-def.ts +3 -3
  47. package/src/to-json-schema/zod3-to-json-schema/parse-types.ts +22 -22
  48. package/src/to-json-schema/zod3-to-json-schema/parsers/array.ts +3 -3
  49. package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.ts +1 -1
  50. package/src/to-json-schema/zod3-to-json-schema/parsers/branded.ts +2 -2
  51. package/src/to-json-schema/zod3-to-json-schema/parsers/catch.ts +2 -2
  52. package/src/to-json-schema/zod3-to-json-schema/parsers/date.ts +4 -4
  53. package/src/to-json-schema/zod3-to-json-schema/parsers/default.ts +3 -3
  54. package/src/to-json-schema/zod3-to-json-schema/parsers/effects.ts +3 -3
  55. package/src/to-json-schema/zod3-to-json-schema/parsers/enum.ts +1 -1
  56. package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.ts +5 -5
  57. package/src/to-json-schema/zod3-to-json-schema/parsers/literal.ts +1 -1
  58. package/src/to-json-schema/zod3-to-json-schema/parsers/map.ts +4 -5
  59. package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.ts +1 -1
  60. package/src/to-json-schema/zod3-to-json-schema/parsers/never.ts +1 -2
  61. package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.ts +4 -4
  62. package/src/to-json-schema/zod3-to-json-schema/parsers/number.ts +1 -1
  63. package/src/to-json-schema/zod3-to-json-schema/parsers/object.ts +3 -3
  64. package/src/to-json-schema/zod3-to-json-schema/parsers/optional.ts +3 -3
  65. package/src/to-json-schema/zod3-to-json-schema/parsers/pipeline.ts +4 -4
  66. package/src/to-json-schema/zod3-to-json-schema/parsers/promise.ts +3 -3
  67. package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.ts +2 -2
  68. package/src/to-json-schema/zod3-to-json-schema/parsers/record.ts +9 -10
  69. package/src/to-json-schema/zod3-to-json-schema/parsers/set.ts +3 -3
  70. package/src/to-json-schema/zod3-to-json-schema/parsers/string.ts +2 -2
  71. package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.ts +3 -3
  72. package/src/to-json-schema/zod3-to-json-schema/parsers/undefined.ts +1 -2
  73. package/src/to-json-schema/zod3-to-json-schema/parsers/union.ts +3 -3
  74. package/src/to-json-schema/zod3-to-json-schema/parsers/unknown.ts +1 -2
  75. package/src/to-json-schema/zod3-to-json-schema/refs.ts +3 -3
  76. package/src/to-json-schema/zod3-to-json-schema/select-parser.ts +2 -2
  77. package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.ts +3 -3
  78. package/src/types/assistant-model-message.ts +3 -3
  79. package/src/types/content-part.ts +138 -19
  80. package/src/types/executable-tool.ts +17 -0
  81. package/src/types/execute-tool.ts +23 -23
  82. package/src/types/file-data.ts +48 -0
  83. package/src/types/index.ts +19 -3
  84. package/src/types/infer-tool-context.ts +7 -2
  85. package/src/types/infer-tool-set-context.ts +7 -9
  86. package/src/types/model-message.ts +4 -4
  87. package/src/types/never-optional.ts +7 -0
  88. package/src/types/provider-options.ts +1 -1
  89. package/src/types/provider-reference.ts +10 -0
  90. package/src/types/sensitive-context.ts +9 -0
  91. package/src/types/system-model-message.ts +1 -1
  92. package/src/types/tool-approval-request.ts +7 -0
  93. package/src/types/tool-execute-function.ts +50 -0
  94. package/src/types/tool-model-message.ts +3 -3
  95. package/src/types/tool-needs-approval-function.ts +39 -0
  96. package/src/types/tool.ts +236 -223
  97. package/src/types/user-model-message.ts +2 -2
  98. package/src/validate-types.ts +5 -3
  99. package/dist/index.d.mts +0 -1578
  100. package/dist/index.mjs +0 -2817
  101. package/dist/index.mjs.map +0 -1
  102. package/dist/test/index.d.mts +0 -17
  103. package/dist/test/index.mjs +0 -77
  104. package/dist/test/index.mjs.map +0 -1
  105. package/src/types/union-to-intersection.ts +0 -17
@@ -1,16 +1,15 @@
1
1
  import {
2
2
  ZodFirstPartyTypeKind,
3
- ZodMapDef,
4
- ZodRecordDef,
5
- ZodTypeAny,
3
+ type ZodMapDef,
4
+ type ZodRecordDef,
5
+ type ZodTypeAny,
6
6
  } from 'zod/v3';
7
7
  import { parseDef } from '../parse-def';
8
- import { JsonSchema7Type } from '../parse-types';
9
- import { Refs } from '../refs';
8
+ import type { JsonSchema7Type } from '../parse-types';
9
+ import type { Refs } from '../refs';
10
10
  import { parseBrandedDef } from './branded';
11
- import { JsonSchema7EnumType } from './enum';
12
- import { JsonSchema7StringType, parseStringDef } from './string';
13
-
11
+ import type { JsonSchema7EnumType } from './enum';
12
+ import { parseStringDef, type JsonSchema7StringType } from './string';
14
13
  type JsonSchema7RecordPropertyNamesType =
15
14
  | Omit<JsonSchema7StringType, 'type'>
16
15
  | Omit<JsonSchema7EnumType, 'type'>;
@@ -38,7 +37,7 @@ export function parseRecordDef(
38
37
  def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodString &&
39
38
  def.keyType._def.checks?.length
40
39
  ) {
41
- const { type, ...keyType } = parseStringDef(def.keyType._def, refs);
40
+ const { type: _type, ...keyType } = parseStringDef(def.keyType._def, refs);
42
41
 
43
42
  return {
44
43
  ...schema,
@@ -56,7 +55,7 @@ export function parseRecordDef(
56
55
  def.keyType._def.type._def.typeName === ZodFirstPartyTypeKind.ZodString &&
57
56
  def.keyType._def.type._def.checks?.length
58
57
  ) {
59
- const { type, ...keyType } = parseBrandedDef(
58
+ const { type: _type, ...keyType } = parseBrandedDef(
60
59
  def.keyType._def,
61
60
  refs,
62
61
  ) as JsonSchema7StringType;
@@ -1,7 +1,7 @@
1
- import { ZodSetDef } from 'zod/v3';
1
+ import type { ZodSetDef } from 'zod/v3';
2
2
  import { parseDef } from '../parse-def';
3
- import { JsonSchema7Type } from '../parse-types';
4
- import { Refs } from '../refs';
3
+ import type { JsonSchema7Type } from '../parse-types';
4
+ import type { Refs } from '../refs';
5
5
 
6
6
  export type JsonSchema7SetType = {
7
7
  type: 'array';
@@ -1,5 +1,5 @@
1
- import { ZodStringDef } from 'zod/v3';
2
- import { Refs } from '../refs';
1
+ import type { ZodStringDef } from 'zod/v3';
2
+ import type { Refs } from '../refs';
3
3
 
4
4
  let emojiRegex: RegExp | undefined = undefined;
5
5
 
@@ -1,7 +1,7 @@
1
- import { ZodTupleDef, ZodTupleItems, ZodTypeAny } from 'zod/v3';
1
+ import type { ZodTupleDef, ZodTupleItems, ZodTypeAny } from 'zod/v3';
2
2
  import { parseDef } from '../parse-def';
3
- import { JsonSchema7Type } from '../parse-types';
4
- import { Refs } from '../refs';
3
+ import type { JsonSchema7Type } from '../parse-types';
4
+ import type { Refs } from '../refs';
5
5
 
6
6
  export type JsonSchema7TupleType = {
7
7
  type: 'array';
@@ -1,5 +1,4 @@
1
- import { JsonSchema7AnyType, parseAnyDef } from './any';
2
-
1
+ import { parseAnyDef, type JsonSchema7AnyType } from './any';
3
2
  export type JsonSchema7UndefinedType = {
4
3
  not: JsonSchema7AnyType;
5
4
  };
@@ -1,12 +1,12 @@
1
- import {
1
+ import type {
2
2
  ZodDiscriminatedUnionDef,
3
3
  ZodLiteralDef,
4
4
  ZodTypeAny,
5
5
  ZodUnionDef,
6
6
  } from 'zod/v3';
7
7
  import { parseDef } from '../parse-def';
8
- import { JsonSchema7Type } from '../parse-types';
9
- import { Refs } from '../refs';
8
+ import type { JsonSchema7Type } from '../parse-types';
9
+ import type { Refs } from '../refs';
10
10
 
11
11
  export const primitiveMappings = {
12
12
  ZodString: 'string',
@@ -1,5 +1,4 @@
1
- import { JsonSchema7AnyType, parseAnyDef } from './any';
2
-
1
+ import { parseAnyDef, type JsonSchema7AnyType } from './any';
3
2
  export type JsonSchema7UnknownType = JsonSchema7AnyType;
4
3
 
5
4
  export function parseUnknownDef(): JsonSchema7UnknownType {
@@ -1,6 +1,6 @@
1
- import { ZodTypeDef } from 'zod/v3';
2
- import { getDefaultOptions, Options } from './options';
3
- import { JsonSchema7Type } from './parse-types';
1
+ import type { ZodTypeDef } from 'zod/v3';
2
+ import { getDefaultOptions, type Options } from './options';
3
+ import type { JsonSchema7Type } from './parse-types';
4
4
 
5
5
  export type Refs = {
6
6
  seen: Map<ZodTypeDef, Seen>;
@@ -28,9 +28,9 @@ import { parseTupleDef } from './parsers/tuple';
28
28
  import { parseUndefinedDef } from './parsers/undefined';
29
29
  import { parseUnionDef } from './parsers/union';
30
30
  import { parseUnknownDef } from './parsers/unknown';
31
- import { Refs } from './refs';
31
+ import type { Refs } from './refs';
32
32
  import { parseReadonlyDef } from './parsers/readonly';
33
- import { JsonSchema7Type } from './parse-types';
33
+ import type { JsonSchema7Type } from './parse-types';
34
34
 
35
35
  export type InnerDefGetter = () => any;
36
36
 
@@ -1,7 +1,7 @@
1
- import { ZodSchema } from 'zod/v3';
2
- import { Options } from './options';
1
+ import type { ZodSchema } from 'zod/v3';
2
+ import type { Options } from './options';
3
3
  import { parseDef } from './parse-def';
4
- import { JsonSchema7Type } from './parse-types';
4
+ import type { JsonSchema7Type } from './parse-types';
5
5
  import { getRefs } from './refs';
6
6
  import { parseAnyDef } from './parsers/any';
7
7
 
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  CustomPart,
3
3
  FilePart,
4
4
  ReasoningFilePart,
@@ -7,8 +7,8 @@ import {
7
7
  ToolCallPart,
8
8
  ToolResultPart,
9
9
  } from './content-part';
10
- import { ProviderOptions } from './provider-options';
11
- import { ToolApprovalRequest } from './tool-approval-request';
10
+ import type { ProviderOptions } from './provider-options';
11
+ import type { ToolApprovalRequest } from './tool-approval-request';
12
12
 
13
13
  /**
14
14
  * An assistant message. It can contain text, tool calls, or a combination of text and tool calls.
@@ -1,6 +1,8 @@
1
- import { JSONValue } from '@ai-sdk/provider';
2
- import { DataContent } from './data-content';
3
- import { ProviderOptions } from './provider-options';
1
+ import type { JSONValue } from '@ai-sdk/provider';
2
+ import type { DataContent } from './data-content';
3
+ import type { FileData, FileDataData, FileDataUrl } from './file-data';
4
+ import type { ProviderOptions } from './provider-options';
5
+ import type { ProviderReference } from './provider-reference';
4
6
 
5
7
  /**
6
8
  * Text content part of a prompt. It contains a string of text.
@@ -23,6 +25,9 @@ export interface TextPart {
23
25
 
24
26
  /**
25
27
  * Image content part of a prompt. It contains an image.
28
+ *
29
+ * @deprecated Use `FilePart` with `mediaType: 'image'` instead:
30
+ * `{ type: 'file', mediaType: 'image', data: { type: 'data', data } }`.
26
31
  */
27
32
  export interface ImagePart {
28
33
  type: 'image';
@@ -32,8 +37,9 @@ export interface ImagePart {
32
37
  *
33
38
  * - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
34
39
  * - URL: a URL that points to the image
40
+ * - ProviderReference: a provider reference from `uploadFile`
35
41
  */
36
- image: DataContent | URL;
42
+ image: DataContent | URL | ProviderReference;
37
43
 
38
44
  /**
39
45
  * Optional IANA media type of the image.
@@ -57,12 +63,16 @@ export interface FilePart {
57
63
  type: 'file';
58
64
 
59
65
  /**
60
- * File data. Can either be:
66
+ * File data. Either a tagged shape or a bare shorthand:
61
67
  *
62
- * - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
63
- * - URL: a URL that points to the image
68
+ * - `{ type: 'data', data }` or bare `DataContent`: raw bytes
69
+ * (base64 string, Uint8Array, ArrayBuffer, Buffer)
70
+ * - `{ type: 'url', url }` or bare `URL`: a URL that points to the file
71
+ * - `{ type: 'reference', reference }` or bare `ProviderReference`:
72
+ * a provider reference from `uploadFile`
73
+ * - `{ type: 'text', text }`: inline text content (tagged only)
64
74
  */
65
- data: DataContent | URL;
75
+ data: FileData | DataContent | URL | ProviderReference;
66
76
 
67
77
  /**
68
78
  * Optional filename of the file.
@@ -70,7 +80,14 @@ export interface FilePart {
70
80
  filename?: string;
71
81
 
72
82
  /**
73
- * IANA media type of the file.
83
+ * Either a full IANA media type (`type/subtype`, e.g. `image/png`) or just
84
+ * the top-level IANA segment (e.g. `image`, `audio`, `video`, `text`).
85
+ *
86
+ * `*`-subtype wildcards (e.g. `image/*`) are normalized as equivalent to the
87
+ * top-level segment alone (e.g. `image`). Providers can use the helpers in
88
+ * `@ai-sdk/provider-utils` (`isFullMediaType`, `getTopLevelMediaType`,
89
+ * `detectMediaType`) to resolve the field according to their API
90
+ * requirements.
74
91
  *
75
92
  * @see https://www.iana.org/assignments/media-types/media-types.xhtml
76
93
  */
@@ -130,12 +147,21 @@ export interface ReasoningFilePart {
130
147
  type: 'reasoning-file';
131
148
 
132
149
  /**
133
- * File data. Can either be:
150
+ * Reasoning file data.
134
151
  *
135
- * - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
136
- * - URL: a URL that points to the file
152
+ * Reasoning files originate from a model's reasoning output and are always
153
+ * raw bytes or a fetchable URL. Unlike `FilePart.data`, the `reference` and
154
+ * `text` shapes are not supported here: provider references describe files
155
+ * uploaded by the user (not produced as model output), and reasoning text is
156
+ * carried by `ReasoningPart` rather than as a file.
157
+ *
158
+ * Either a tagged shape or a bare shorthand:
159
+ *
160
+ * - `{ type: 'data', data }` or bare `DataContent`: raw bytes
161
+ * (base64 string, Uint8Array, ArrayBuffer, Buffer)
162
+ * - `{ type: 'url', url }` or bare `URL`: a URL that points to the file
137
163
  */
138
- data: DataContent | URL;
164
+ data: FileDataData | FileDataUrl | DataContent | URL;
139
165
 
140
166
  /**
141
167
  * IANA media type of the file.
@@ -291,14 +317,50 @@ export type ToolResultOutput =
291
317
  providerOptions?: ProviderOptions;
292
318
  }
293
319
  | {
320
+ type: 'file';
321
+
294
322
  /**
295
- * @deprecated Use image-data or file-data instead.
323
+ * File data as a tagged discriminated union:
324
+ *
325
+ * - `{ type: 'data', data }`: raw bytes
326
+ * (base64 string, Uint8Array, ArrayBuffer, Buffer)
327
+ * - `{ type: 'url', url }`: a URL that points to the file
328
+ * - `{ type: 'reference', reference }`: a provider reference
329
+ * from `uploadFile`
330
+ * - `{ type: 'text', text }`: inline text content (e.g. an inline
331
+ * text document)
332
+ */
333
+ data: FileData;
334
+
335
+ /**
336
+ * Either a full IANA media type (`type/subtype`, e.g. `image/png`) or just
337
+ * the top-level IANA segment (e.g. `image`, `audio`, `video`, `text`).
338
+ *
339
+ * `*`-subtype wildcards (e.g. `image/*`) are normalized as equivalent to the
340
+ * top-level segment alone (e.g. `image`). Providers can use the helpers in
341
+ * `@ai-sdk/provider-utils` (`isFullMediaType`, `getTopLevelMediaType`,
342
+ * `detectMediaType`) to resolve the field according to their API
343
+ * requirements.
344
+ *
345
+ * @see https://www.iana.org/assignments/media-types/media-types.xhtml
296
346
  */
297
- type: 'media';
298
- data: string;
299
347
  mediaType: string;
348
+
349
+ /**
350
+ * Optional filename of the file.
351
+ */
352
+ filename?: string;
353
+
354
+ /**
355
+ * Provider-specific options.
356
+ */
357
+ providerOptions?: ProviderOptions;
300
358
  }
301
359
  | {
360
+ /**
361
+ * @deprecated Use 'file' with mediaType + tagged data instead:
362
+ * `{ type: 'file', mediaType, data: { type: 'data', data } }`.
363
+ */
302
364
  type: 'file-data';
303
365
 
304
366
  /**
@@ -323,6 +385,10 @@ export type ToolResultOutput =
323
385
  providerOptions?: ProviderOptions;
324
386
  }
325
387
  | {
388
+ /**
389
+ * @deprecated Use 'file' with mediaType and tagged data instead:
390
+ * `{ type: 'file', mediaType, data: { type: 'url', url: new URL(url) } }`.
391
+ */
326
392
  type: 'file-url';
327
393
 
328
394
  /**
@@ -330,12 +396,22 @@ export type ToolResultOutput =
330
396
  */
331
397
  url: string;
332
398
 
399
+ /**
400
+ * IANA media type.
401
+ * @see https://www.iana.org/assignments/media-types/media-types.xhtml
402
+ */
403
+ mediaType?: string;
404
+
333
405
  /**
334
406
  * Provider-specific options.
335
407
  */
336
408
  providerOptions?: ProviderOptions;
337
409
  }
338
410
  | {
411
+ /**
412
+ * @deprecated Use 'file' with tagged data instead:
413
+ * `{ type: 'file', mediaType, data: { type: 'reference', reference } }`.
414
+ */
339
415
  type: 'file-id';
340
416
 
341
417
  /**
@@ -355,7 +431,27 @@ export type ToolResultOutput =
355
431
  }
356
432
  | {
357
433
  /**
358
- * Images that are referenced using base64 encoded data.
434
+ * @deprecated Use 'file' with tagged data instead:
435
+ * `{ type: 'file', mediaType, data: { type: 'reference', reference } }`.
436
+ */
437
+ type: 'file-reference';
438
+
439
+ /**
440
+ * Provider-specific references for the file.
441
+ * The key is the provider name, e.g. 'openai' or 'anthropic'.
442
+ */
443
+ providerReference: ProviderReference;
444
+
445
+ /**
446
+ * Provider-specific options.
447
+ */
448
+ providerOptions?: ProviderOptions;
449
+ }
450
+ | {
451
+ /**
452
+ * @deprecated Use 'file' with mediaType (e.g. 'image' or a specific
453
+ * `image/*` subtype) and tagged data instead:
454
+ * `{ type: 'file', mediaType: 'image', data: { type: 'data', data } }`.
359
455
  */
360
456
  type: 'image-data';
361
457
 
@@ -377,7 +473,9 @@ export type ToolResultOutput =
377
473
  }
378
474
  | {
379
475
  /**
380
- * Images that are referenced using a URL.
476
+ * @deprecated Use 'file' with `mediaType: 'image'` (or a specific
477
+ * `image/*` subtype) and tagged data instead:
478
+ * `{ type: 'file', mediaType: 'image', data: { type: 'url', url: new URL(url) } }`.
381
479
  */
382
480
  type: 'image-url';
383
481
 
@@ -393,7 +491,9 @@ export type ToolResultOutput =
393
491
  }
394
492
  | {
395
493
  /**
396
- * Images that are referenced using a provider file id.
494
+ * @deprecated Use 'file' with `mediaType: 'image'` (or a specific
495
+ * `image/*` subtype) and tagged data instead:
496
+ * `{ type: 'file', mediaType: 'image', data: { type: 'reference', reference } }`.
397
497
  */
398
498
  type: 'image-file-id';
399
499
 
@@ -407,6 +507,25 @@ export type ToolResultOutput =
407
507
  */
408
508
  fileId: string | Record<string, string>;
409
509
 
510
+ /**
511
+ * Provider-specific options.
512
+ */
513
+ providerOptions?: ProviderOptions;
514
+ }
515
+ | {
516
+ /**
517
+ * @deprecated Use 'file' with `mediaType: 'image'` (or a specific
518
+ * `image/*` subtype) and tagged data instead:
519
+ * `{ type: 'file', mediaType: 'image', data: { type: 'reference', reference } }`.
520
+ */
521
+ type: 'image-file-reference';
522
+
523
+ /**
524
+ * Provider-specific references for the image file.
525
+ * The key is the provider name, e.g. 'openai' or 'anthropic'.
526
+ */
527
+ providerReference: ProviderReference;
528
+
410
529
  /**
411
530
  * Provider-specific options.
412
531
  */
@@ -0,0 +1,17 @@
1
+ import type { Tool } from './tool';
2
+
3
+ /**
4
+ * A tool that is guaranteed to expose an execute function.
5
+ */
6
+ export type ExecutableTool<TOOL extends Tool = Tool> = TOOL & {
7
+ execute: NonNullable<TOOL['execute']>;
8
+ };
9
+
10
+ /**
11
+ * Checks whether a tool exposes an execute function.
12
+ */
13
+ export function isExecutableTool<TOOL extends Tool>(
14
+ tool: TOOL | undefined,
15
+ ): tool is ExecutableTool<TOOL> {
16
+ return tool != null && typeof tool.execute === 'function';
17
+ }
@@ -1,41 +1,41 @@
1
1
  import { isAsyncIterable } from '../is-async-iterable';
2
- import { Context } from './context';
3
- import { ToolExecuteFunction, ToolExecutionOptions } from './tool';
2
+ import type { ExecutableTool } from './executable-tool';
3
+ import type { InferToolContext } from './infer-tool-context';
4
+ import type { InferToolInput } from './infer-tool-input';
5
+ import type { InferToolOutput } from './infer-tool-output';
6
+ import type { Tool } from './tool';
7
+ import type { ToolExecutionOptions } from './tool-execute-function';
4
8
 
5
9
  /**
6
- * Executes a tool function, supporting both synchronous and streaming/asynchronous results.
10
+ * Executes a tool function and normalizes its results into a stream of outputs.
7
11
  *
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 }`.
12
+ * - If the tool's `execute` function returns an `AsyncIterable`, each yielded value is emitted as
13
+ * `{ type: "preliminary", output }`. After iteration completes, the last yielded value is emitted
14
+ * again as `{ type: "final", output }`.
14
15
  * - If the tool returns a direct value or Promise, a single `{ type: "final", output }` is yielded.
15
16
  *
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.
17
+ * @param params.tool The tool whose `execute` function should be invoked.
18
+ * @param params.input The input value to pass to the tool.
21
19
  * @param params.options Additional options for tool execution.
22
- * @yields An object containing either a preliminary or final output from the tool.
20
+ * @yields A preliminary output for each streamed value, followed by a final output, or a single final
21
+ * output for non-streaming tools.
23
22
  */
24
- export async function* executeTool<INPUT, OUTPUT, CONTEXT extends Context>({
25
- execute,
23
+ export async function* executeTool<TOOL extends Tool>({
24
+ tool,
26
25
  input,
27
26
  options,
28
27
  }: {
29
- execute: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
30
- input: INPUT;
31
- options: ToolExecutionOptions<NoInfer<CONTEXT>>;
28
+ tool: ExecutableTool<TOOL>;
29
+ input: InferToolInput<TOOL>;
30
+ options: ToolExecutionOptions<InferToolContext<TOOL>>;
32
31
  }): AsyncGenerator<
33
- { type: 'preliminary'; output: OUTPUT } | { type: 'final'; output: OUTPUT }
32
+ | { type: 'preliminary'; output: InferToolOutput<TOOL> }
33
+ | { type: 'final'; output: InferToolOutput<TOOL> }
34
34
  > {
35
- const result = execute(input, options);
35
+ const result = tool.execute(input, options);
36
36
 
37
37
  if (isAsyncIterable(result)) {
38
- let lastOutput: OUTPUT | undefined;
38
+ let lastOutput: InferToolOutput<TOOL> | undefined;
39
39
  for await (const output of result) {
40
40
  lastOutput = output;
41
41
  yield { type: 'preliminary', output };
@@ -0,0 +1,48 @@
1
+ import type {
2
+ SharedV4FileDataReference,
3
+ SharedV4FileDataText,
4
+ SharedV4FileDataUrl,
5
+ } from '@ai-sdk/provider';
6
+ import type { DataContent } from './data-content';
7
+
8
+ /**
9
+ * File data variant containing raw bytes (`Uint8Array`, `ArrayBuffer`, or
10
+ * `Buffer`) or a base64-encoded string.
11
+ *
12
+ * This is slightly more permissive than `SharedV4FileDataData`.
13
+ */
14
+ export interface FileDataData {
15
+ type: 'data';
16
+ data: DataContent;
17
+ }
18
+
19
+ /**
20
+ * File data variant containing a URL that points to the file.
21
+ */
22
+ export type FileDataUrl = SharedV4FileDataUrl;
23
+
24
+ /**
25
+ * File data variant containing a provider reference (`{ [provider]: id }`).
26
+ */
27
+ export type FileDataReference = SharedV4FileDataReference;
28
+
29
+ /**
30
+ * File data variant containing inline text content (e.g. an inline text
31
+ * document).
32
+ */
33
+ export type FileDataText = SharedV4FileDataText;
34
+
35
+ /**
36
+ * File data as a tagged discriminated union:
37
+ *
38
+ * - `{ type: 'data', data }`: raw bytes (`Uint8Array`, `ArrayBuffer`, or
39
+ * `Buffer`) or a base64-encoded string.
40
+ * - `{ type: 'url', url }`: a URL that points to the file.
41
+ * - `{ type: 'reference', reference }`: a provider reference (`{ [provider]: id }`).
42
+ * - `{ type: 'text', text }`: inline text content (e.g. an inline text document).
43
+ */
44
+ export type FileData =
45
+ | FileDataData
46
+ | FileDataUrl
47
+ | FileDataReference
48
+ | FileDataText;
@@ -16,21 +16,37 @@ export type {
16
16
  export type { Context } from './context';
17
17
  export type { DataContent } from './data-content';
18
18
  export { executeTool } from './execute-tool';
19
+ export type {
20
+ FileData,
21
+ FileDataData,
22
+ FileDataReference,
23
+ FileDataText,
24
+ FileDataUrl,
25
+ } from './file-data';
26
+ export { isExecutableTool, type ExecutableTool } from './executable-tool';
19
27
  export type { InferToolContext } from './infer-tool-context';
20
28
  export type { InferToolInput } from './infer-tool-input';
21
29
  export type { InferToolOutput } from './infer-tool-output';
22
30
  export type { InferToolSetContext } from './infer-tool-set-context';
23
31
  export type { ModelMessage } from './model-message';
24
32
  export type { ProviderOptions } from './provider-options';
33
+ export type { ProviderReference } from './provider-reference';
34
+ export type { SensitiveContext } from './sensitive-context';
25
35
  export type { SystemModelMessage } from './system-model-message';
26
36
  export {
27
37
  dynamicTool,
28
38
  tool,
39
+ type DynamicTool,
40
+ type FunctionTool,
41
+ type ProviderDefinedTool,
42
+ type ProviderExecutedTool,
29
43
  type Tool,
30
- type ToolExecuteFunction,
31
- type ToolExecutionOptions,
32
- type ToolNeedsApprovalFunction,
33
44
  } from './tool';
45
+ export type {
46
+ ToolExecuteFunction,
47
+ ToolExecutionOptions,
48
+ } from './tool-execute-function';
49
+ export type { ToolNeedsApprovalFunction } from './tool-needs-approval-function';
34
50
  export type { ToolSet } from './tool-set';
35
51
  export type { ToolApprovalRequest } from './tool-approval-request';
36
52
  export type { ToolApprovalResponse } from './tool-approval-response';
@@ -1,7 +1,12 @@
1
+ import type { HasRequiredKey } from '../has-required-key';
1
2
  import type { Tool } from './tool';
2
3
 
3
4
  /**
4
5
  * Infer the context type of a tool.
5
6
  */
6
- export type InferToolContext<TOOL extends Tool<any, any, any>> =
7
- TOOL extends Tool<any, any, infer CONTEXT> ? CONTEXT : never;
7
+ export type InferToolContext<TOOL extends Tool> =
8
+ TOOL extends Tool<any, any, infer CONTEXT>
9
+ ? HasRequiredKey<CONTEXT> extends true
10
+ ? CONTEXT
11
+ : never
12
+ : never;
@@ -1,17 +1,15 @@
1
1
  import type { InferToolContext } from './infer-tool-context';
2
2
  import type { ToolSet } from './tool-set';
3
- import type { UnionToIntersection } from './union-to-intersection';
4
3
 
5
4
  /**
6
5
  * Infer the context type for a tool set.
7
6
  *
8
- * The inferred type contains all properties required by the contexts of the
9
- * tools in the set.
7
+ * The inferred type maps each tool name to its required context type.
10
8
  *
11
- * If there are incompatible properties, they will be of type `never`.
9
+ * Tools without required context properties are omitted from the result.
12
10
  */
13
- export type InferToolSetContext<TOOLS extends ToolSet> = UnionToIntersection<
14
- {
15
- [K in keyof TOOLS]: InferToolContext<NoInfer<TOOLS[K]>>;
16
- }[keyof TOOLS]
17
- >;
11
+ export type InferToolSetContext<TOOLS extends ToolSet> = {
12
+ [K in keyof TOOLS as InferToolContext<NoInfer<TOOLS[K]>> extends never
13
+ ? never
14
+ : K]: InferToolContext<NoInfer<TOOLS[K]>>;
15
+ };
@@ -1,7 +1,7 @@
1
- import { AssistantModelMessage } from './assistant-model-message';
2
- import { SystemModelMessage } from './system-model-message';
3
- import { ToolModelMessage } from './tool-model-message';
4
- import { UserModelMessage } from './user-model-message';
1
+ import type { AssistantModelMessage } from './assistant-model-message';
2
+ import type { SystemModelMessage } from './system-model-message';
3
+ import type { ToolModelMessage } from './tool-model-message';
4
+ import type { UserModelMessage } from './user-model-message';
5
5
 
6
6
  /**
7
7
  * A message that can be used in the `messages` field of a prompt.
@@ -0,0 +1,7 @@
1
+ // 0 extends 1 & N checks for any
2
+ // [N] extends [never] checks for never
3
+ export type NeverOptional<N, T> = 0 extends 1 & N
4
+ ? Partial<T>
5
+ : [N] extends [never]
6
+ ? Partial<Record<keyof T, undefined>>
7
+ : T;