@ai-sdk/provider-utils 4.0.5 → 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.
Files changed (163) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index.js +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/package.json +4 -2
  5. package/src/__snapshots__/schema.test.ts.snap +346 -0
  6. package/src/add-additional-properties-to-json-schema.test.ts +289 -0
  7. package/src/add-additional-properties-to-json-schema.ts +53 -0
  8. package/src/combine-headers.ts +11 -0
  9. package/src/convert-async-iterator-to-readable-stream.test.ts +78 -0
  10. package/src/convert-async-iterator-to-readable-stream.ts +47 -0
  11. package/src/convert-image-model-file-to-data-uri.test.ts +85 -0
  12. package/src/convert-image-model-file-to-data-uri.ts +19 -0
  13. package/src/convert-to-form-data.test.ts +167 -0
  14. package/src/convert-to-form-data.ts +61 -0
  15. package/src/create-tool-name-mapping.test.ts +163 -0
  16. package/src/create-tool-name-mapping.ts +66 -0
  17. package/src/delay.test.ts +212 -0
  18. package/src/delay.ts +47 -0
  19. package/src/delayed-promise.test.ts +132 -0
  20. package/src/delayed-promise.ts +61 -0
  21. package/src/download-blob.test.ts +145 -0
  22. package/src/download-blob.ts +31 -0
  23. package/src/download-error.ts +39 -0
  24. package/src/extract-response-headers.ts +9 -0
  25. package/src/fetch-function.ts +4 -0
  26. package/src/generate-id.test.ts +31 -0
  27. package/src/generate-id.ts +57 -0
  28. package/src/get-error-message.ts +15 -0
  29. package/src/get-from-api.test.ts +199 -0
  30. package/src/get-from-api.ts +97 -0
  31. package/src/get-runtime-environment-user-agent.test.ts +47 -0
  32. package/src/get-runtime-environment-user-agent.ts +24 -0
  33. package/src/handle-fetch-error.ts +39 -0
  34. package/src/index.ts +67 -0
  35. package/src/inject-json-instruction.test.ts +404 -0
  36. package/src/inject-json-instruction.ts +63 -0
  37. package/src/is-abort-error.ts +8 -0
  38. package/src/is-async-iterable.ts +3 -0
  39. package/src/is-non-nullable.ts +12 -0
  40. package/src/is-url-supported.test.ts +282 -0
  41. package/src/is-url-supported.ts +40 -0
  42. package/src/load-api-key.ts +45 -0
  43. package/src/load-optional-setting.ts +30 -0
  44. package/src/load-setting.ts +62 -0
  45. package/src/maybe-promise-like.ts +3 -0
  46. package/src/media-type-to-extension.test.ts +26 -0
  47. package/src/media-type-to-extension.ts +22 -0
  48. package/src/normalize-headers.test.ts +64 -0
  49. package/src/normalize-headers.ts +38 -0
  50. package/src/parse-json-event-stream.ts +33 -0
  51. package/src/parse-json.test.ts +191 -0
  52. package/src/parse-json.ts +122 -0
  53. package/src/parse-provider-options.ts +32 -0
  54. package/src/post-to-api.ts +166 -0
  55. package/src/provider-tool-factory.ts +125 -0
  56. package/src/remove-undefined-entries.test.ts +57 -0
  57. package/src/remove-undefined-entries.ts +12 -0
  58. package/src/resolve.test.ts +125 -0
  59. package/src/resolve.ts +17 -0
  60. package/src/response-handler.test.ts +89 -0
  61. package/src/response-handler.ts +187 -0
  62. package/src/schema.test-d.ts +11 -0
  63. package/src/schema.test.ts +502 -0
  64. package/src/schema.ts +267 -0
  65. package/src/secure-json-parse.test.ts +59 -0
  66. package/src/secure-json-parse.ts +92 -0
  67. package/src/test/convert-array-to-async-iterable.ts +9 -0
  68. package/src/test/convert-array-to-readable-stream.ts +15 -0
  69. package/src/test/convert-async-iterable-to-array.ts +9 -0
  70. package/src/test/convert-readable-stream-to-array.ts +14 -0
  71. package/src/test/convert-response-stream-to-array.ts +9 -0
  72. package/src/test/index.ts +7 -0
  73. package/src/test/is-node-version.ts +4 -0
  74. package/src/test/mock-id.ts +8 -0
  75. package/src/to-json-schema/zod3-to-json-schema/LICENSE +16 -0
  76. package/src/to-json-schema/zod3-to-json-schema/README.md +24 -0
  77. package/src/to-json-schema/zod3-to-json-schema/get-relative-path.ts +7 -0
  78. package/src/to-json-schema/zod3-to-json-schema/index.ts +1 -0
  79. package/src/to-json-schema/zod3-to-json-schema/options.ts +98 -0
  80. package/src/to-json-schema/zod3-to-json-schema/parse-def.test.ts +224 -0
  81. package/src/to-json-schema/zod3-to-json-schema/parse-def.ts +109 -0
  82. package/src/to-json-schema/zod3-to-json-schema/parse-types.ts +57 -0
  83. package/src/to-json-schema/zod3-to-json-schema/parsers/any.ts +5 -0
  84. package/src/to-json-schema/zod3-to-json-schema/parsers/array.test.ts +98 -0
  85. package/src/to-json-schema/zod3-to-json-schema/parsers/array.ts +38 -0
  86. package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.test.ts +51 -0
  87. package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.ts +44 -0
  88. package/src/to-json-schema/zod3-to-json-schema/parsers/boolean.ts +7 -0
  89. package/src/to-json-schema/zod3-to-json-schema/parsers/branded.test.ts +16 -0
  90. package/src/to-json-schema/zod3-to-json-schema/parsers/branded.ts +7 -0
  91. package/src/to-json-schema/zod3-to-json-schema/parsers/catch.test.ts +15 -0
  92. package/src/to-json-schema/zod3-to-json-schema/parsers/catch.ts +7 -0
  93. package/src/to-json-schema/zod3-to-json-schema/parsers/date.test.ts +97 -0
  94. package/src/to-json-schema/zod3-to-json-schema/parsers/date.ts +64 -0
  95. package/src/to-json-schema/zod3-to-json-schema/parsers/default.test.ts +54 -0
  96. package/src/to-json-schema/zod3-to-json-schema/parsers/default.ts +14 -0
  97. package/src/to-json-schema/zod3-to-json-schema/parsers/effects.test.ts +41 -0
  98. package/src/to-json-schema/zod3-to-json-schema/parsers/effects.ts +14 -0
  99. package/src/to-json-schema/zod3-to-json-schema/parsers/enum.ts +13 -0
  100. package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.test.ts +92 -0
  101. package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.ts +52 -0
  102. package/src/to-json-schema/zod3-to-json-schema/parsers/literal.ts +29 -0
  103. package/src/to-json-schema/zod3-to-json-schema/parsers/map.test.ts +48 -0
  104. package/src/to-json-schema/zod3-to-json-schema/parsers/map.ts +47 -0
  105. package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.test.ts +102 -0
  106. package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.ts +31 -0
  107. package/src/to-json-schema/zod3-to-json-schema/parsers/never.ts +9 -0
  108. package/src/to-json-schema/zod3-to-json-schema/parsers/null.ts +9 -0
  109. package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.test.ts +67 -0
  110. package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.ts +42 -0
  111. package/src/to-json-schema/zod3-to-json-schema/parsers/number.test.ts +65 -0
  112. package/src/to-json-schema/zod3-to-json-schema/parsers/number.ts +44 -0
  113. package/src/to-json-schema/zod3-to-json-schema/parsers/object.test.ts +149 -0
  114. package/src/to-json-schema/zod3-to-json-schema/parsers/object.ts +88 -0
  115. package/src/to-json-schema/zod3-to-json-schema/parsers/optional.test.ts +147 -0
  116. package/src/to-json-schema/zod3-to-json-schema/parsers/optional.ts +23 -0
  117. package/src/to-json-schema/zod3-to-json-schema/parsers/pipe.test.ts +35 -0
  118. package/src/to-json-schema/zod3-to-json-schema/parsers/pipeline.ts +29 -0
  119. package/src/to-json-schema/zod3-to-json-schema/parsers/promise.test.ts +15 -0
  120. package/src/to-json-schema/zod3-to-json-schema/parsers/promise.ts +11 -0
  121. package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.test.ts +20 -0
  122. package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.ts +7 -0
  123. package/src/to-json-schema/zod3-to-json-schema/parsers/record.test.ts +108 -0
  124. package/src/to-json-schema/zod3-to-json-schema/parsers/record.ts +71 -0
  125. package/src/to-json-schema/zod3-to-json-schema/parsers/set.test.ts +20 -0
  126. package/src/to-json-schema/zod3-to-json-schema/parsers/set.ts +35 -0
  127. package/src/to-json-schema/zod3-to-json-schema/parsers/string.test.ts +438 -0
  128. package/src/to-json-schema/zod3-to-json-schema/parsers/string.ts +426 -0
  129. package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.test.ts +33 -0
  130. package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.ts +61 -0
  131. package/src/to-json-schema/zod3-to-json-schema/parsers/undefined.ts +11 -0
  132. package/src/to-json-schema/zod3-to-json-schema/parsers/union.test.ts +226 -0
  133. package/src/to-json-schema/zod3-to-json-schema/parsers/union.ts +144 -0
  134. package/src/to-json-schema/zod3-to-json-schema/parsers/unknown.ts +7 -0
  135. package/src/to-json-schema/zod3-to-json-schema/refs.test.ts +919 -0
  136. package/src/to-json-schema/zod3-to-json-schema/refs.ts +39 -0
  137. package/src/to-json-schema/zod3-to-json-schema/select-parser.ts +115 -0
  138. package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.test.ts +862 -0
  139. package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.ts +93 -0
  140. package/src/types/assistant-model-message.ts +39 -0
  141. package/src/types/content-part.ts +379 -0
  142. package/src/types/data-content.ts +4 -0
  143. package/src/types/execute-tool.ts +27 -0
  144. package/src/types/index.ts +40 -0
  145. package/src/types/model-message.ts +14 -0
  146. package/src/types/provider-options.ts +9 -0
  147. package/src/types/system-model-message.ts +20 -0
  148. package/src/types/tool-approval-request.ts +16 -0
  149. package/src/types/tool-approval-response.ts +27 -0
  150. package/src/types/tool-call.ts +31 -0
  151. package/src/types/tool-model-message.ts +23 -0
  152. package/src/types/tool-result.ts +35 -0
  153. package/src/types/tool.test-d.ts +193 -0
  154. package/src/types/tool.ts +324 -0
  155. package/src/types/user-model-message.ts +22 -0
  156. package/src/uint8-utils.ts +26 -0
  157. package/src/validate-types.test.ts +105 -0
  158. package/src/validate-types.ts +81 -0
  159. package/src/version.ts +6 -0
  160. package/src/with-user-agent-suffix.test.ts +84 -0
  161. package/src/with-user-agent-suffix.ts +27 -0
  162. package/src/without-trailing-slash.ts +3 -0
  163. package/LICENSE +0 -13
@@ -0,0 +1,105 @@
1
+ import { TypeValidationError } from '@ai-sdk/provider';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { safeValidateTypes, validateTypes } from './validate-types';
4
+ import { StandardSchema } from './schema';
5
+
6
+ const customSchema: StandardSchema<{ name: string; age: number }> = {
7
+ '~standard': {
8
+ version: 1,
9
+ vendor: 'custom',
10
+ validate: async (value: any) => {
11
+ return typeof value === 'object' &&
12
+ value !== null &&
13
+ 'name' in value &&
14
+ typeof value.name === 'string' &&
15
+ 'age' in value &&
16
+ typeof value.age === 'number'
17
+ ? { value }
18
+ : { issues: [new Error('Invalid input')] };
19
+ },
20
+ jsonSchema: {
21
+ input: () => ({
22
+ type: 'object',
23
+ properties: {
24
+ name: { type: 'string' },
25
+ age: { type: 'number' },
26
+ },
27
+ }),
28
+ output: () => ({
29
+ type: 'object',
30
+ properties: {
31
+ name: { type: 'string' },
32
+ age: { type: 'number' },
33
+ },
34
+ }),
35
+ },
36
+ },
37
+ };
38
+
39
+ describe('validateTypes', () => {
40
+ it('should return validated object for valid input', async () => {
41
+ const input = { name: 'John', age: 30 };
42
+ expect(await validateTypes({ value: input, schema: customSchema })).toEqual(
43
+ input,
44
+ );
45
+ });
46
+
47
+ it('should throw TypeValidationError for invalid input', async () => {
48
+ const input = { name: 'John', age: '30' };
49
+
50
+ try {
51
+ await validateTypes({
52
+ value: input,
53
+ schema: customSchema,
54
+ });
55
+ expect.fail('Expected TypeValidationError to be thrown');
56
+ } catch (error) {
57
+ expect(error).toBeInstanceOf(TypeValidationError);
58
+
59
+ const typedError = error as TypeValidationError;
60
+
61
+ expect({
62
+ name: typedError.name,
63
+ value: typedError.value,
64
+ cause: typedError.cause,
65
+ message: typedError.message,
66
+ }).toStrictEqual({
67
+ name: 'AI_TypeValidationError',
68
+ value: input,
69
+ cause: [expect.any(Error)],
70
+ message: expect.stringContaining('Type validation failed'),
71
+ });
72
+ }
73
+ });
74
+ });
75
+
76
+ describe('safeValidateTypes', () => {
77
+ it('should return validated object for valid input', async () => {
78
+ const input = { name: 'John', age: 30 };
79
+ const result = await safeValidateTypes({
80
+ value: input,
81
+ schema: customSchema,
82
+ });
83
+ expect(result).toEqual({ success: true, value: input, rawValue: input });
84
+ });
85
+
86
+ it('should return error object for invalid input', async () => {
87
+ const input = { name: 'John', age: '30' };
88
+ const result = await safeValidateTypes({
89
+ value: input,
90
+ schema: customSchema,
91
+ });
92
+
93
+ expect(result).toEqual({
94
+ success: false,
95
+ error: expect.any(TypeValidationError),
96
+ rawValue: input,
97
+ });
98
+
99
+ if (!result.success) {
100
+ expect(result.error).toBeInstanceOf(TypeValidationError);
101
+ expect(result.error.value).toEqual(input);
102
+ expect(result.error.message).toContain('Type validation failed');
103
+ }
104
+ });
105
+ });
@@ -0,0 +1,81 @@
1
+ import { TypeValidationError } from '@ai-sdk/provider';
2
+ import { FlexibleSchema, asSchema } from './schema';
3
+
4
+ /**
5
+ * Validates the types of an unknown object using a schema and
6
+ * return a strongly-typed object.
7
+ *
8
+ * @template T - The type of the object to validate.
9
+ * @param {string} options.value - The object to validate.
10
+ * @param {Validator<T>} options.schema - The schema to use for validating the JSON.
11
+ * @returns {Promise<T>} - The typed object.
12
+ */
13
+ export async function validateTypes<OBJECT>({
14
+ value,
15
+ schema,
16
+ }: {
17
+ value: unknown;
18
+ schema: FlexibleSchema<OBJECT>;
19
+ }): Promise<OBJECT> {
20
+ const result = await safeValidateTypes({ value, schema });
21
+
22
+ if (!result.success) {
23
+ throw TypeValidationError.wrap({ value, cause: result.error });
24
+ }
25
+
26
+ return result.value;
27
+ }
28
+
29
+ /**
30
+ * Safely validates the types of an unknown object using a schema and
31
+ * return a strongly-typed object.
32
+ *
33
+ * @template T - The type of the object to validate.
34
+ * @param {string} options.value - The JSON object to validate.
35
+ * @param {Validator<T>} options.schema - The schema to use for validating the JSON.
36
+ * @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object.
37
+ */
38
+ export async function safeValidateTypes<OBJECT>({
39
+ value,
40
+ schema,
41
+ }: {
42
+ value: unknown;
43
+ schema: FlexibleSchema<OBJECT>;
44
+ }): Promise<
45
+ | {
46
+ success: true;
47
+ value: OBJECT;
48
+ rawValue: unknown;
49
+ }
50
+ | {
51
+ success: false;
52
+ error: TypeValidationError;
53
+ rawValue: unknown;
54
+ }
55
+ > {
56
+ const actualSchema = asSchema(schema);
57
+
58
+ try {
59
+ if (actualSchema.validate == null) {
60
+ return { success: true, value: value as OBJECT, rawValue: value };
61
+ }
62
+
63
+ const result = await actualSchema.validate(value);
64
+
65
+ if (result.success) {
66
+ return { success: true, value: result.value, rawValue: value };
67
+ }
68
+
69
+ return {
70
+ success: false,
71
+ error: TypeValidationError.wrap({ value, cause: result.error }),
72
+ rawValue: value,
73
+ };
74
+ } catch (error) {
75
+ return {
76
+ success: false,
77
+ error: TypeValidationError.wrap({ value, cause: error }),
78
+ rawValue: value,
79
+ };
80
+ }
81
+ }
package/src/version.ts ADDED
@@ -0,0 +1,6 @@
1
+ // Version string of this package injected at build time.
2
+ declare const __PACKAGE_VERSION__: string | undefined;
3
+ export const VERSION: string =
4
+ typeof __PACKAGE_VERSION__ !== 'undefined'
5
+ ? __PACKAGE_VERSION__
6
+ : '0.0.0-test';
@@ -0,0 +1,84 @@
1
+ import { describe, it, expect } from 'vitest';
2
+
3
+ import { withUserAgentSuffix } from './with-user-agent-suffix';
4
+
5
+ describe('withUserAgentSuffix', () => {
6
+ it('should create a new user-agent header when no existing user-agent exists', () => {
7
+ const headers = {
8
+ 'content-type': 'application/json',
9
+ authorization: 'Bearer token123',
10
+ };
11
+
12
+ const result = withUserAgentSuffix(
13
+ headers,
14
+ 'ai-sdk/0.0.0-test',
15
+ 'provider/test-openai',
16
+ );
17
+
18
+ expect(result['user-agent']).toBe('ai-sdk/0.0.0-test provider/test-openai');
19
+ expect(result['content-type']).toBe('application/json');
20
+ expect(result['authorization']).toBe('Bearer token123');
21
+ });
22
+
23
+ it('should append suffix parts to existing user-agent header', () => {
24
+ const headers = {
25
+ 'user-agent': 'TestApp/0.0.0-test',
26
+ accept: 'application/json',
27
+ };
28
+
29
+ const result = withUserAgentSuffix(
30
+ headers,
31
+ 'ai-sdk/0.0.0-test',
32
+ 'provider/test-anthropic',
33
+ );
34
+
35
+ expect(result['user-agent']).toBe(
36
+ 'TestApp/0.0.0-test ai-sdk/0.0.0-test provider/test-anthropic',
37
+ );
38
+ expect(result['accept']).toBe('application/json');
39
+ });
40
+
41
+ it('should automatically remove undefined entries from headers', () => {
42
+ const headers = {
43
+ 'content-type': 'application/json',
44
+ authorization: undefined,
45
+ 'user-agent': 'TestApp/0.0.0-test',
46
+ accept: 'application/json',
47
+ 'cache-control': null,
48
+ };
49
+
50
+ const result = withUserAgentSuffix(headers as any, 'ai-sdk/0.0.0-test');
51
+
52
+ expect(result['user-agent']).toBe('TestApp/0.0.0-test ai-sdk/0.0.0-test');
53
+ expect(result['content-type']).toBe('application/json');
54
+ expect(result['accept']).toBe('application/json');
55
+ expect(result['authorization']).toBeUndefined();
56
+ expect(result['cache-control']).toBeUndefined();
57
+ });
58
+
59
+ it('should preserve headers when given a Headers instance', () => {
60
+ const headers = new Headers({
61
+ Authorization: 'Bearer token123',
62
+ 'X-Custom': 'value',
63
+ });
64
+
65
+ const result = withUserAgentSuffix(headers, 'ai-sdk/0.0.0-test');
66
+
67
+ expect(result['authorization']).toBe('Bearer token123');
68
+ expect(result['x-custom']).toBe('value');
69
+ expect(result['user-agent']).toBe('ai-sdk/0.0.0-test');
70
+ });
71
+
72
+ it('should handle array header entries', () => {
73
+ const headers: HeadersInit = [
74
+ ['Authorization', 'Bearer token123'],
75
+ ['X-Feature', 'alpha'],
76
+ ];
77
+
78
+ const result = withUserAgentSuffix(headers, 'ai-sdk/0.0.0-test');
79
+
80
+ expect(result['authorization']).toBe('Bearer token123');
81
+ expect(result['x-feature']).toBe('alpha');
82
+ expect(result['user-agent']).toBe('ai-sdk/0.0.0-test');
83
+ });
84
+ });
@@ -0,0 +1,27 @@
1
+ import { normalizeHeaders } from './normalize-headers';
2
+
3
+ /**
4
+ * Appends suffix parts to the `user-agent` header.
5
+ * If a `user-agent` header already exists, the suffix parts are appended to it.
6
+ * If no `user-agent` header exists, a new one is created with the suffix parts.
7
+ * Automatically removes undefined entries from the headers.
8
+ *
9
+ * @param headers - The original headers.
10
+ * @param userAgentSuffixParts - The parts to append to the `user-agent` header.
11
+ * @returns The new headers with the `user-agent` header set or updated.
12
+ */
13
+ export function withUserAgentSuffix(
14
+ headers: HeadersInit | Record<string, string | undefined> | undefined,
15
+ ...userAgentSuffixParts: string[]
16
+ ): Record<string, string> {
17
+ const normalizedHeaders = new Headers(normalizeHeaders(headers));
18
+
19
+ const currentUserAgentHeader = normalizedHeaders.get('user-agent') || '';
20
+
21
+ normalizedHeaders.set(
22
+ 'user-agent',
23
+ [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(' '),
24
+ );
25
+
26
+ return Object.fromEntries(normalizedHeaders.entries());
27
+ }
@@ -0,0 +1,3 @@
1
+ export function withoutTrailingSlash(url: string | undefined) {
2
+ return url?.replace(/\/$/, '');
3
+ }
package/LICENSE DELETED
@@ -1,13 +0,0 @@
1
- Copyright 2023 Vercel, Inc.
2
-
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
-
7
- http://www.apache.org/licenses/LICENSE-2.0
8
-
9
- Unless required by applicable law or agreed to in writing, software
10
- distributed under the License is distributed on an "AS IS" BASIS,
11
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- See the License for the specific language governing permissions and
13
- limitations under the License.