@ai-sdk/provider-utils 5.0.0-beta.19 → 5.0.0-beta.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/provider-utils",
3
- "version": "5.0.0-beta.19",
3
+ "version": "5.0.0-beta.20",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -33,8 +33,9 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@standard-schema/spec": "^1.1.0",
36
+ "@workflow/serde": "4.1.0",
36
37
  "eventsource-parser": "^3.0.6",
37
- "@ai-sdk/provider": "4.0.0-beta.11"
38
+ "@ai-sdk/provider": "4.0.0-beta.12"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@types/node": "20.17.24",
package/src/index.ts CHANGED
@@ -1,20 +1,16 @@
1
1
  export * from './combine-headers';
2
2
  export { convertAsyncIteratorToReadableStream } from './convert-async-iterator-to-readable-stream';
3
+ export { convertImageModelFileToDataUri } from './convert-image-model-file-to-data-uri';
4
+ export { convertToFormData } from './convert-to-form-data';
3
5
  export {
4
6
  createToolNameMapping,
5
7
  type ToolNameMapping,
6
8
  } from './create-tool-name-mapping';
7
9
  export * from './delay';
8
10
  export { DelayedPromise } from './delayed-promise';
9
- export * from './extract-response-headers';
10
- export { convertImageModelFileToDataUri } from './convert-image-model-file-to-data-uri';
11
- export { convertToFormData } from './convert-to-form-data';
12
11
  export { downloadBlob } from './download-blob';
13
12
  export { DownloadError } from './download-error';
14
- export {
15
- readResponseWithSizeLimit,
16
- DEFAULT_MAX_DOWNLOAD_SIZE,
17
- } from './read-response-with-size-limit';
13
+ export * from './extract-response-headers';
18
14
  export * from './fetch-function';
19
15
  export { createIdGenerator, generateId, type IdGenerator } from './generate-id';
20
16
  export * from './get-error-message';
@@ -27,13 +23,13 @@ export { isNonNullable } from './is-non-nullable';
27
23
  export { isProviderReference } from './is-provider-reference';
28
24
  export { isUrlSupported } from './is-url-supported';
29
25
  export * from './load-api-key';
26
+ export { loadOptionalSetting } from './load-optional-setting';
27
+ export { loadSetting } from './load-setting';
30
28
  export {
31
29
  isCustomReasoning,
32
30
  mapReasoningToProviderBudget,
33
31
  mapReasoningToProviderEffort,
34
32
  } from './map-reasoning-to-provider';
35
- export { loadOptionalSetting } from './load-optional-setting';
36
- export { loadSetting } from './load-setting';
37
33
  export { type MaybePromiseLike } from './maybe-promise-like';
38
34
  export { mediaTypeToExtension } from './media-type-to-extension';
39
35
  export { normalizeHeaders } from './normalize-headers';
@@ -47,9 +43,13 @@ export {
47
43
  type ProviderToolFactory,
48
44
  type ProviderToolFactoryWithOutputSchema,
49
45
  } from './provider-tool-factory';
46
+ export {
47
+ DEFAULT_MAX_DOWNLOAD_SIZE,
48
+ readResponseWithSizeLimit,
49
+ } from './read-response-with-size-limit';
50
50
  export * from './remove-undefined-entries';
51
- export { resolveProviderReference } from './resolve-provider-reference';
52
51
  export * from './resolve';
52
+ export { resolveProviderReference } from './resolve-provider-reference';
53
53
  export * from './response-handler';
54
54
  export {
55
55
  asSchema,
@@ -62,6 +62,7 @@ export {
62
62
  type Schema,
63
63
  type ValidationResult,
64
64
  } from './schema';
65
+ export { serializeModelOptions } from './serialize-model-options';
65
66
  export { stripFileExtension } from './strip-file-extension';
66
67
  export * from './uint8-utils';
67
68
  export { validateDownloadUrl } from './validate-download-url';
@@ -75,6 +76,7 @@ export * from './types';
75
76
 
76
77
  // external re-exports
77
78
  export type * from '@standard-schema/spec';
79
+ export { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde';
78
80
  export {
79
81
  EventSourceParserStream,
80
82
  type EventSourceMessage,
@@ -0,0 +1,29 @@
1
+ import { JSONValue } from '@ai-sdk/provider';
2
+
3
+ /**
4
+ * Checks whether a value can cross a workflow serialization boundary.
5
+ *
6
+ * The check accepts JSON-like primitives, arrays, and plain objects whose
7
+ * nested values are also serializable. It rejects functions, symbols,
8
+ * bigints, and non-plain objects such as class instances, dates, and regexes.
9
+ */
10
+ export function isJSONSerializable(value: unknown): value is JSONValue {
11
+ if (value === null || value === undefined) return true;
12
+
13
+ const type = typeof value;
14
+ if (type === 'string' || type === 'number' || type === 'boolean') return true;
15
+ if (type === 'function' || type === 'symbol' || type === 'bigint')
16
+ return false;
17
+
18
+ if (Array.isArray(value)) {
19
+ return value.every(isJSONSerializable);
20
+ }
21
+
22
+ if (Object.getPrototypeOf(value) === Object.prototype) {
23
+ return Object.values(value as Record<string, unknown>).every(
24
+ isJSONSerializable,
25
+ );
26
+ }
27
+
28
+ return false;
29
+ }
package/src/resolve.ts CHANGED
@@ -1,5 +1,20 @@
1
1
  import { MaybePromiseLike } from './maybe-promise-like';
2
2
 
3
+ /**
4
+ * A value or a lazy provider of a value, each of which may be synchronous or asynchronous.
5
+ *
6
+ * @template T The resolved type after {@link resolve} runs.
7
+ *
8
+ * One of:
9
+ * - A plain value of type {@link T}
10
+ * - A {@link PromiseLike} of {@link T} (e.g. a `Promise<T>`)
11
+ * - A zero-argument function that returns a plain {@link T}
12
+ * - A zero-argument function that returns a {@link PromiseLike} of {@link T}
13
+ *
14
+ * The function form is only invoked when passed to {@link resolve}; it is not distinguished from
15
+ * a {@link T} that happens to be a function—callers should wrap function values if disambiguation
16
+ * is required.
17
+ */
3
18
  export type Resolvable<T> = MaybePromiseLike<T> | (() => MaybePromiseLike<T>);
4
19
 
5
20
  /**
@@ -0,0 +1,63 @@
1
+ import { JSONObject } from '@ai-sdk/provider';
2
+ import { isJSONSerializable } from './is-json-serializable';
3
+ import { Resolvable } from './resolve';
4
+
5
+ /**
6
+ * Serializes a model instance for workflow step boundaries.
7
+ * Returns the `modelId` plus the JSON-serializable config properties.
8
+ *
9
+ * Non-serializable values are omitted. As a special case, a
10
+ * function-valued `headers` property is resolved during serialization
11
+ * and included if the returned value is JSON-serializable.
12
+ *
13
+ * Used as the body of `static [WORKFLOW_SERIALIZE]` in provider models.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * static [WORKFLOW_SERIALIZE](model: MyLanguageModel) {
18
+ * return serializeModelOptions({
19
+ * modelId: model.modelId,
20
+ * config: model.config,
21
+ * });
22
+ * }
23
+ * ```
24
+ */
25
+ export function serializeModelOptions<
26
+ CONFIG extends {
27
+ headers?: Resolvable<Record<string, string | undefined>>;
28
+ },
29
+ >(options: {
30
+ modelId: string;
31
+ config: CONFIG;
32
+ }): {
33
+ modelId: string;
34
+ config: JSONObject;
35
+ } {
36
+ const serializableConfig: JSONObject = {};
37
+ for (const [key, value] of Object.entries(options.config)) {
38
+ if (key === 'headers') {
39
+ const resolvedHeaders = resolveSync(value);
40
+ if (isJSONSerializable(resolvedHeaders)) {
41
+ serializableConfig[key] = resolvedHeaders;
42
+ }
43
+ } else if (isJSONSerializable(value)) {
44
+ serializableConfig[key] = value;
45
+ }
46
+ }
47
+ return { modelId: options.modelId, config: serializableConfig };
48
+ }
49
+
50
+ function resolveSync<T>(value: Resolvable<T>): T {
51
+ let next: unknown = value;
52
+ if (typeof value === 'function') {
53
+ next = (value as () => unknown)();
54
+ }
55
+
56
+ // the serialization for workflows currently only supports synchronous values
57
+ // TODO introduce SerializationError
58
+ if (next instanceof Promise) {
59
+ throw new Error('Promise returned from resolveSync');
60
+ }
61
+
62
+ return next as T;
63
+ }
@@ -325,6 +325,12 @@ export type ToolResultOutput =
325
325
  */
326
326
  url: string;
327
327
 
328
+ /**
329
+ * IANA media type.
330
+ * @see https://www.iana.org/assignments/media-types/media-types.xhtml
331
+ */
332
+ mediaType?: string; // Temporarily optional. TODO: make required in v8, after migration period.
333
+
328
334
  /**
329
335
  * Provider-specific options.
330
336
  */
@@ -367,7 +373,7 @@ export type ToolResultOutput =
367
373
  }
368
374
  | {
369
375
  /**
370
- * Images that are referenced using base64 encoded data.
376
+ * @deprecated Use file-data instead.
371
377
  */
372
378
  type: 'image-data';
373
379
 
@@ -389,7 +395,7 @@ export type ToolResultOutput =
389
395
  }
390
396
  | {
391
397
  /**
392
- * Images that are referenced using a URL.
398
+ * @deprecated Use file-url instead.
393
399
  */
394
400
  type: 'image-url';
395
401
 
@@ -405,7 +411,7 @@ export type ToolResultOutput =
405
411
  }
406
412
  | {
407
413
  /**
408
- * @deprecated Use image-file-reference instead.
414
+ * @deprecated Use file-reference instead.
409
415
  */
410
416
  type: 'image-file-id';
411
417
 
@@ -426,7 +432,7 @@ export type ToolResultOutput =
426
432
  }
427
433
  | {
428
434
  /**
429
- * Images that are referenced using a provider reference.
435
+ * @deprecated Use file-reference instead.
430
436
  */
431
437
  type: 'image-file-reference';
432
438