@ai-sdk/provider-utils 5.0.0-beta.3 → 5.0.0-beta.30
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 +284 -0
- package/dist/index.d.ts +1339 -813
- package/dist/index.js +837 -288
- package/dist/index.js.map +1 -1
- package/dist/test/index.d.ts +2 -1
- package/dist/test/index.js +18 -37
- package/dist/test/index.js.map +1 -1
- package/package.json +13 -13
- package/src/add-additional-properties-to-json-schema.ts +1 -1
- package/src/as-array.ts +12 -0
- package/src/convert-image-model-file-to-data-uri.ts +3 -3
- package/src/convert-inline-file-data-to-uint8-array.ts +30 -0
- package/src/create-tool-name-mapping.ts +6 -22
- package/src/detect-media-type.ts +312 -0
- package/src/filter-nullable.ts +11 -0
- package/src/get-error-message.ts +1 -15
- package/src/get-from-api.ts +2 -2
- package/src/has-required-key.ts +6 -0
- package/src/index.ts +42 -12
- package/src/inject-json-instruction.ts +6 -6
- package/src/is-buffer.ts +9 -0
- package/src/is-json-serializable.ts +29 -0
- package/src/is-provider-reference.ts +21 -0
- package/src/is-url-supported.ts +17 -2
- package/src/load-api-key.ts +1 -1
- package/src/load-setting.ts +1 -1
- package/src/map-reasoning-to-provider.ts +108 -0
- package/src/maybe-promise-like.ts +3 -0
- package/src/parse-json-event-stream.ts +3 -3
- package/src/parse-json.ts +3 -3
- package/src/parse-provider-options.ts +1 -1
- package/src/post-to-api.ts +4 -4
- package/src/provider-defined-tool-factory.ts +129 -0
- package/src/provider-executed-tool-factory.ts +69 -0
- package/src/resolve-full-media-type.ts +49 -0
- package/src/resolve-provider-reference.ts +26 -0
- package/src/resolve.ts +16 -1
- package/src/response-handler.ts +3 -3
- package/src/schema.ts +6 -3
- package/src/secure-json-parse.ts +1 -1
- package/src/serialize-model-options.ts +63 -0
- package/src/streaming-tool-call-tracker.ts +241 -0
- package/src/test/convert-response-stream-to-array.ts +1 -1
- package/src/test/is-node-version.ts +22 -1
- package/src/to-json-schema/zod3-to-json-schema/options.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parse-def.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parse-types.ts +22 -22
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.ts +1 -1
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.ts +2 -2
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.ts +2 -2
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.ts +4 -4
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/enum.ts +1 -1
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.ts +5 -5
- package/src/to-json-schema/zod3-to-json-schema/parsers/literal.ts +1 -1
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.ts +4 -5
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.ts +1 -1
- package/src/to-json-schema/zod3-to-json-schema/parsers/never.ts +1 -2
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.ts +4 -4
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.ts +1 -1
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipeline.ts +4 -4
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.ts +2 -2
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.ts +9 -10
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.ts +2 -2
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/undefined.ts +1 -2
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/parsers/unknown.ts +1 -2
- package/src/to-json-schema/zod3-to-json-schema/refs.ts +3 -3
- package/src/to-json-schema/zod3-to-json-schema/select-parser.ts +2 -2
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.ts +3 -3
- package/src/types/assistant-model-message.ts +5 -3
- package/src/types/content-part.ts +102 -24
- package/src/types/context.ts +4 -0
- package/src/types/executable-tool.ts +17 -0
- package/src/types/execute-tool.ts +29 -9
- package/src/types/file-data.ts +48 -0
- package/src/types/index.ts +26 -11
- package/src/types/infer-tool-context.ts +12 -0
- package/src/types/infer-tool-input.ts +7 -0
- package/src/types/infer-tool-output.ts +7 -0
- package/src/types/infer-tool-set-context.ts +15 -0
- package/src/types/model-message.ts +4 -4
- package/src/types/never-optional.ts +7 -0
- package/src/types/provider-options.ts +2 -2
- package/src/types/provider-reference.ts +10 -0
- package/src/types/sensitive-context.ts +9 -0
- package/src/types/system-model-message.ts +1 -1
- package/src/types/tool-approval-request.ts +7 -0
- package/src/types/tool-execute-function.ts +50 -0
- package/src/types/tool-model-message.ts +3 -3
- package/src/types/tool-needs-approval-function.ts +39 -0
- package/src/types/tool-set.ts +22 -0
- package/src/types/tool.ts +251 -222
- package/src/types/user-model-message.ts +2 -2
- package/src/validate-download-url.ts +7 -2
- package/src/validate-types.ts +5 -3
- package/dist/index.d.mts +0 -1458
- package/dist/index.mjs +0 -2759
- package/dist/index.mjs.map +0 -1
- package/dist/test/index.d.mts +0 -17
- package/dist/test/index.mjs +0 -77
- package/dist/test/index.mjs.map +0 -1
- package/src/provider-tool-factory.ts +0 -125
package/dist/test/index.d.ts
CHANGED
|
@@ -9,9 +9,10 @@ declare function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Pro
|
|
|
9
9
|
declare function convertResponseStreamToArray(response: Response): Promise<string[]>;
|
|
10
10
|
|
|
11
11
|
declare function isNodeVersion(version: number): boolean;
|
|
12
|
+
declare function isNodeVersionAtLeast(major: number, minor?: number, patch?: number): boolean;
|
|
12
13
|
|
|
13
14
|
declare function mockId({ prefix, }?: {
|
|
14
15
|
prefix?: string;
|
|
15
16
|
}): () => string;
|
|
16
17
|
|
|
17
|
-
export { convertArrayToAsyncIterable, convertArrayToReadableStream, convertAsyncIterableToArray, convertReadableStreamToArray, convertResponseStreamToArray, isNodeVersion, mockId };
|
|
18
|
+
export { convertArrayToAsyncIterable, convertArrayToReadableStream, convertAsyncIterableToArray, convertReadableStreamToArray, convertResponseStreamToArray, isNodeVersion, isNodeVersionAtLeast, mockId };
|
package/dist/test/index.js
CHANGED
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/test/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
convertArrayToAsyncIterable: () => convertArrayToAsyncIterable,
|
|
24
|
-
convertArrayToReadableStream: () => convertArrayToReadableStream,
|
|
25
|
-
convertAsyncIterableToArray: () => convertAsyncIterableToArray,
|
|
26
|
-
convertReadableStreamToArray: () => convertReadableStreamToArray,
|
|
27
|
-
convertResponseStreamToArray: () => convertResponseStreamToArray,
|
|
28
|
-
isNodeVersion: () => isNodeVersion,
|
|
29
|
-
mockId: () => mockId
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(index_exports);
|
|
32
|
-
|
|
33
1
|
// src/test/convert-array-to-async-iterable.ts
|
|
34
2
|
function convertArrayToAsyncIterable(values) {
|
|
35
3
|
return {
|
|
@@ -79,16 +47,29 @@ async function convertReadableStreamToArray(stream) {
|
|
|
79
47
|
|
|
80
48
|
// src/test/convert-response-stream-to-array.ts
|
|
81
49
|
async function convertResponseStreamToArray(response) {
|
|
82
|
-
return convertReadableStreamToArray(
|
|
50
|
+
return await convertReadableStreamToArray(
|
|
83
51
|
response.body.pipeThrough(new TextDecoderStream())
|
|
84
52
|
);
|
|
85
53
|
}
|
|
86
54
|
|
|
87
55
|
// src/test/is-node-version.ts
|
|
56
|
+
function getNodeVersionParts() {
|
|
57
|
+
return process.versions.node.split(".").map((version) => Number.parseInt(version, 10));
|
|
58
|
+
}
|
|
88
59
|
function isNodeVersion(version) {
|
|
89
|
-
const nodeMajorVersion =
|
|
60
|
+
const [nodeMajorVersion] = getNodeVersionParts();
|
|
90
61
|
return nodeMajorVersion === version;
|
|
91
62
|
}
|
|
63
|
+
function isNodeVersionAtLeast(major, minor = 0, patch = 0) {
|
|
64
|
+
const [nodeMajorVersion, nodeMinorVersion, nodePatchVersion] = getNodeVersionParts();
|
|
65
|
+
if (nodeMajorVersion !== major) {
|
|
66
|
+
return nodeMajorVersion > major;
|
|
67
|
+
}
|
|
68
|
+
if (nodeMinorVersion !== minor) {
|
|
69
|
+
return nodeMinorVersion > minor;
|
|
70
|
+
}
|
|
71
|
+
return nodePatchVersion >= patch;
|
|
72
|
+
}
|
|
92
73
|
|
|
93
74
|
// src/test/mock-id.ts
|
|
94
75
|
function mockId({
|
|
@@ -97,14 +78,14 @@ function mockId({
|
|
|
97
78
|
let counter = 0;
|
|
98
79
|
return () => `${prefix}-${counter++}`;
|
|
99
80
|
}
|
|
100
|
-
|
|
101
|
-
0 && (module.exports = {
|
|
81
|
+
export {
|
|
102
82
|
convertArrayToAsyncIterable,
|
|
103
83
|
convertArrayToReadableStream,
|
|
104
84
|
convertAsyncIterableToArray,
|
|
105
85
|
convertReadableStreamToArray,
|
|
106
86
|
convertResponseStreamToArray,
|
|
107
87
|
isNodeVersion,
|
|
88
|
+
isNodeVersionAtLeast,
|
|
108
89
|
mockId
|
|
109
|
-
}
|
|
90
|
+
};
|
|
110
91
|
//# sourceMappingURL=index.js.map
|
package/dist/test/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/
|
|
1
|
+
{"version":3,"sources":["../../src/test/convert-array-to-async-iterable.ts","../../src/test/convert-array-to-readable-stream.ts","../../src/test/convert-async-iterable-to-array.ts","../../src/test/convert-readable-stream-to-array.ts","../../src/test/convert-response-stream-to-array.ts","../../src/test/is-node-version.ts","../../src/test/mock-id.ts"],"sourcesContent":["export function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of values) {\n yield value;\n }\n },\n };\n}\n","export function convertArrayToReadableStream<T>(\n values: T[],\n): ReadableStream<T> {\n return new ReadableStream({\n start(controller) {\n try {\n for (const value of values) {\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n}\n","export async function convertAsyncIterableToArray<T>(\n iterable: AsyncIterable<T>,\n): Promise<T[]> {\n const result: T[] = [];\n for await (const item of iterable) {\n result.push(item);\n }\n return result;\n}\n","export async function convertReadableStreamToArray<T>(\n stream: ReadableStream<T>,\n): Promise<T[]> {\n const reader = stream.getReader();\n const result: T[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n result.push(value);\n }\n\n return result;\n}\n","import { convertReadableStreamToArray } from './convert-readable-stream-to-array';\n\nexport async function convertResponseStreamToArray(\n response: Response,\n): Promise<string[]> {\n return await convertReadableStreamToArray(\n response.body!.pipeThrough(new TextDecoderStream()),\n );\n}\n","function getNodeVersionParts() {\n return process.versions.node\n .split('.')\n .map(version => Number.parseInt(version, 10));\n}\n\nexport function isNodeVersion(version: number) {\n const [nodeMajorVersion] = getNodeVersionParts();\n return nodeMajorVersion === version;\n}\n\nexport function isNodeVersionAtLeast(major: number, minor = 0, patch = 0) {\n const [nodeMajorVersion, nodeMinorVersion, nodePatchVersion] =\n getNodeVersionParts();\n\n if (nodeMajorVersion !== major) {\n return nodeMajorVersion > major;\n }\n\n if (nodeMinorVersion !== minor) {\n return nodeMinorVersion > minor;\n }\n\n return nodePatchVersion >= patch;\n}\n","export function mockId({\n prefix = 'id',\n}: {\n prefix?: string;\n} = {}): () => string {\n let counter = 0;\n return () => `${prefix}-${counter++}`;\n}\n"],"mappings":";AAAO,SAAS,4BAA+B,QAA+B;AAC5E,SAAO;AAAA,IACL,QAAQ,OAAO,aAAa,IAAI;AAC9B,iBAAW,SAAS,QAAQ;AAC1B,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;ACRO,SAAS,6BACd,QACmB;AACnB,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,YAAY;AAChB,UAAI;AACF,mBAAW,SAAS,QAAQ;AAC1B,qBAAW,QAAQ,KAAK;AAAA,QAC1B;AAAA,MACF,UAAE;AACA,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACdA,eAAsB,4BACpB,UACc;AACd,QAAM,SAAc,CAAC;AACrB,mBAAiB,QAAQ,UAAU;AACjC,WAAO,KAAK,IAAI;AAAA,EAClB;AACA,SAAO;AACT;;;ACRA,eAAsB,6BACpB,QACc;AACd,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAc,CAAC;AAErB,SAAO,MAAM;AACX,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,KAAM;AACV,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,SAAO;AACT;;;ACXA,eAAsB,6BACpB,UACmB;AACnB,SAAO,MAAM;AAAA,IACX,SAAS,KAAM,YAAY,IAAI,kBAAkB,CAAC;AAAA,EACpD;AACF;;;ACRA,SAAS,sBAAsB;AAC7B,SAAO,QAAQ,SAAS,KACrB,MAAM,GAAG,EACT,IAAI,aAAW,OAAO,SAAS,SAAS,EAAE,CAAC;AAChD;AAEO,SAAS,cAAc,SAAiB;AAC7C,QAAM,CAAC,gBAAgB,IAAI,oBAAoB;AAC/C,SAAO,qBAAqB;AAC9B;AAEO,SAAS,qBAAqB,OAAe,QAAQ,GAAG,QAAQ,GAAG;AACxE,QAAM,CAAC,kBAAkB,kBAAkB,gBAAgB,IACzD,oBAAoB;AAEtB,MAAI,qBAAqB,OAAO;AAC9B,WAAO,mBAAmB;AAAA,EAC5B;AAEA,MAAI,qBAAqB,OAAO;AAC9B,WAAO,mBAAmB;AAAA,EAC5B;AAEA,SAAO,oBAAoB;AAC7B;;;ACxBO,SAAS,OAAO;AAAA,EACrB,SAAS;AACX,IAEI,CAAC,GAAiB;AACpB,MAAI,UAAU;AACd,SAAO,MAAM,GAAG,MAAM,IAAI,SAAS;AACrC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/provider-utils",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.30",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"license": "Apache-2.0",
|
|
5
6
|
"sideEffects": false,
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
|
-
"module": "./dist/index.mjs",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"source": "./src/index.ts",
|
|
10
10
|
"files": [
|
|
@@ -22,20 +22,20 @@
|
|
|
22
22
|
"./package.json": "./package.json",
|
|
23
23
|
".": {
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
25
|
-
"import": "./dist/index.
|
|
26
|
-
"
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
27
|
},
|
|
28
28
|
"./test": {
|
|
29
29
|
"types": "./dist/test/index.d.ts",
|
|
30
|
-
"import": "./dist/test/index.
|
|
31
|
-
"
|
|
32
|
-
"require": "./dist/test/index.js"
|
|
30
|
+
"import": "./dist/test/index.js",
|
|
31
|
+
"default": "./dist/test/index.js"
|
|
33
32
|
}
|
|
34
33
|
},
|
|
35
34
|
"dependencies": {
|
|
36
35
|
"@standard-schema/spec": "^1.1.0",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
36
|
+
"@workflow/serde": "4.1.0",
|
|
37
|
+
"eventsource-parser": "^3.0.8",
|
|
38
|
+
"@ai-sdk/provider": "4.0.0-beta.14"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "20.17.24",
|
|
@@ -52,12 +52,14 @@
|
|
|
52
52
|
"node": ">=18"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
|
-
"access": "public"
|
|
55
|
+
"access": "public",
|
|
56
|
+
"provenance": true
|
|
56
57
|
},
|
|
57
58
|
"homepage": "https://ai-sdk.dev/docs",
|
|
58
59
|
"repository": {
|
|
59
60
|
"type": "git",
|
|
60
|
-
"url": "
|
|
61
|
+
"url": "https://github.com/vercel/ai",
|
|
62
|
+
"directory": "packages/provider-utils"
|
|
61
63
|
},
|
|
62
64
|
"bugs": {
|
|
63
65
|
"url": "https://github.com/vercel/ai/issues"
|
|
@@ -69,9 +71,7 @@
|
|
|
69
71
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
70
72
|
"build:watch": "pnpm clean && tsup --watch",
|
|
71
73
|
"clean": "del-cli dist *.tsbuildinfo",
|
|
72
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
73
74
|
"type-check": "tsc --build",
|
|
74
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
75
75
|
"test": "pnpm test:node && pnpm test:edge",
|
|
76
76
|
"test:update": "pnpm test:node -u",
|
|
77
77
|
"test:watch": "vitest --config vitest.node.config.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JSONSchema7, JSONSchema7Definition } from '@ai-sdk/provider';
|
|
1
|
+
import type { JSONSchema7, JSONSchema7Definition } from '@ai-sdk/provider';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Recursively adds additionalProperties: false to the JSON schema. This is necessary because some providers (e.g. OpenAI) do not support additionalProperties: true.
|
package/src/as-array.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A value that can be provided either as a single item, an array of items,
|
|
3
|
+
* or be left undefined.
|
|
4
|
+
*/
|
|
5
|
+
export type Arrayable<T> = T | T[] | undefined;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Normalizes a possibly undefined or non-array value into an array.
|
|
9
|
+
*/
|
|
10
|
+
export function asArray<T>(value: Arrayable<T>): T[] {
|
|
11
|
+
return value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
12
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ImageModelV4File } from '@ai-sdk/provider';
|
|
2
2
|
import { convertUint8ArrayToBase64 } from './uint8-utils';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Convert an
|
|
5
|
+
* Convert an ImageModelV4File to a URL or data URI string.
|
|
6
6
|
*
|
|
7
7
|
* If the file is a URL, it returns the URL as-is.
|
|
8
8
|
* If the file is base64 data, it returns a data URI with the base64 data.
|
|
9
9
|
* If the file is a Uint8Array, it converts it to base64 and returns a data URI.
|
|
10
10
|
*/
|
|
11
|
-
export function convertImageModelFileToDataUri(file:
|
|
11
|
+
export function convertImageModelFileToDataUri(file: ImageModelV4File): string {
|
|
12
12
|
if (file.type === 'url') return file.url;
|
|
13
13
|
|
|
14
14
|
return `data:${file.mediaType};base64,${
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FilePart } from './types/content-part';
|
|
2
|
+
import { convertBase64ToUint8Array } from './uint8-utils';
|
|
3
|
+
|
|
4
|
+
type InlineFileData = Extract<
|
|
5
|
+
FilePart['data'],
|
|
6
|
+
{ type: 'data' } | { type: 'text' }
|
|
7
|
+
>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Converts inline file data (a tagged `data` or `text` shape) into raw bytes.
|
|
11
|
+
*
|
|
12
|
+
* - `{ type: 'text', text }` → UTF-8 encoded bytes
|
|
13
|
+
* - `{ type: 'data', data: Uint8Array | Buffer }` → returned as-is
|
|
14
|
+
* - `{ type: 'data', data: ArrayBuffer }` → wrapped in a `Uint8Array`
|
|
15
|
+
* - `{ type: 'data', data: string }` → decoded as base64
|
|
16
|
+
*/
|
|
17
|
+
export function convertInlineFileDataToUint8Array(
|
|
18
|
+
data: InlineFileData,
|
|
19
|
+
): Uint8Array {
|
|
20
|
+
if (data.type === 'text') {
|
|
21
|
+
return new TextEncoder().encode(data.text);
|
|
22
|
+
}
|
|
23
|
+
if (data.data instanceof Uint8Array) {
|
|
24
|
+
return data.data;
|
|
25
|
+
}
|
|
26
|
+
if (data.data instanceof ArrayBuffer) {
|
|
27
|
+
return new Uint8Array(data.data);
|
|
28
|
+
}
|
|
29
|
+
return convertBase64ToUint8Array(data.data);
|
|
30
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type {
|
|
2
|
+
LanguageModelV4FunctionTool,
|
|
3
|
+
LanguageModelV4ProviderTool,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -33,41 +33,25 @@ export interface ToolNameMapping {
|
|
|
33
33
|
export function createToolNameMapping({
|
|
34
34
|
tools = [],
|
|
35
35
|
providerToolNames,
|
|
36
|
-
resolveProviderToolName,
|
|
37
36
|
}: {
|
|
38
37
|
/**
|
|
39
38
|
* Tools that were passed to the language model.
|
|
40
39
|
*/
|
|
41
40
|
tools:
|
|
42
|
-
| Array<
|
|
41
|
+
| Array<LanguageModelV4FunctionTool | LanguageModelV4ProviderTool>
|
|
43
42
|
| undefined;
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
45
|
* Maps the provider tool ids to the provider tool names.
|
|
47
46
|
*/
|
|
48
47
|
providerToolNames: Record<`${string}.${string}`, string>;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Optional resolver for provider tool names that cannot be represented as
|
|
52
|
-
* static id -> name mappings (e.g. dynamic provider names).
|
|
53
|
-
*/
|
|
54
|
-
resolveProviderToolName?: (
|
|
55
|
-
tool: LanguageModelV3ProviderTool,
|
|
56
|
-
) => string | undefined;
|
|
57
48
|
}): ToolNameMapping {
|
|
58
49
|
const customToolNameToProviderToolName: Record<string, string> = {};
|
|
59
50
|
const providerToolNameToCustomToolName: Record<string, string> = {};
|
|
60
51
|
|
|
61
52
|
for (const tool of tools) {
|
|
62
|
-
if (tool.type === 'provider') {
|
|
63
|
-
const providerToolName =
|
|
64
|
-
resolveProviderToolName?.(tool) ??
|
|
65
|
-
(tool.id in providerToolNames ? providerToolNames[tool.id] : undefined);
|
|
66
|
-
|
|
67
|
-
if (providerToolName == null) {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
53
|
+
if (tool.type === 'provider' && tool.id in providerToolNames) {
|
|
54
|
+
const providerToolName = providerToolNames[tool.id];
|
|
71
55
|
customToolNameToProviderToolName[tool.name] = providerToolName;
|
|
72
56
|
providerToolNameToCustomToolName[providerToolName] = tool.name;
|
|
73
57
|
}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { convertBase64ToUint8Array } from './uint8-utils';
|
|
2
|
+
|
|
3
|
+
const imageMediaTypeSignatures = [
|
|
4
|
+
{
|
|
5
|
+
mediaType: 'image/gif' as const,
|
|
6
|
+
bytesPrefix: [0x47, 0x49, 0x46], // GIF
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
mediaType: 'image/png' as const,
|
|
10
|
+
bytesPrefix: [0x89, 0x50, 0x4e, 0x47], // PNG
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
mediaType: 'image/jpeg' as const,
|
|
14
|
+
bytesPrefix: [0xff, 0xd8], // JPEG
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
mediaType: 'image/webp' as const,
|
|
18
|
+
bytesPrefix: [
|
|
19
|
+
0x52,
|
|
20
|
+
0x49,
|
|
21
|
+
0x46,
|
|
22
|
+
0x46, // "RIFF"
|
|
23
|
+
null,
|
|
24
|
+
null,
|
|
25
|
+
null,
|
|
26
|
+
null, // file size (variable)
|
|
27
|
+
0x57,
|
|
28
|
+
0x45,
|
|
29
|
+
0x42,
|
|
30
|
+
0x50, // "WEBP"
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
mediaType: 'image/bmp' as const,
|
|
35
|
+
bytesPrefix: [0x42, 0x4d],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
mediaType: 'image/tiff' as const,
|
|
39
|
+
bytesPrefix: [0x49, 0x49, 0x2a, 0x00],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
mediaType: 'image/tiff' as const,
|
|
43
|
+
bytesPrefix: [0x4d, 0x4d, 0x00, 0x2a],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
mediaType: 'image/avif' as const,
|
|
47
|
+
bytesPrefix: [
|
|
48
|
+
0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66,
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
mediaType: 'image/heic' as const,
|
|
53
|
+
bytesPrefix: [
|
|
54
|
+
0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63,
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
] as const;
|
|
58
|
+
|
|
59
|
+
const documentMediaTypeSignatures = [
|
|
60
|
+
{
|
|
61
|
+
mediaType: 'application/pdf' as const,
|
|
62
|
+
bytesPrefix: [0x25, 0x50, 0x44, 0x46], // %PDF
|
|
63
|
+
},
|
|
64
|
+
] as const;
|
|
65
|
+
|
|
66
|
+
const audioMediaTypeSignatures = [
|
|
67
|
+
{
|
|
68
|
+
mediaType: 'audio/mpeg' as const,
|
|
69
|
+
bytesPrefix: [0xff, 0xfb],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
mediaType: 'audio/mpeg' as const,
|
|
73
|
+
bytesPrefix: [0xff, 0xfa],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
mediaType: 'audio/mpeg' as const,
|
|
77
|
+
bytesPrefix: [0xff, 0xf3],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
mediaType: 'audio/mpeg' as const,
|
|
81
|
+
bytesPrefix: [0xff, 0xf2],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
mediaType: 'audio/mpeg' as const,
|
|
85
|
+
bytesPrefix: [0xff, 0xe3],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
mediaType: 'audio/mpeg' as const,
|
|
89
|
+
bytesPrefix: [0xff, 0xe2],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
mediaType: 'audio/wav' as const,
|
|
93
|
+
bytesPrefix: [
|
|
94
|
+
0x52, // R
|
|
95
|
+
0x49, // I
|
|
96
|
+
0x46, // F
|
|
97
|
+
0x46, // F
|
|
98
|
+
null,
|
|
99
|
+
null,
|
|
100
|
+
null,
|
|
101
|
+
null,
|
|
102
|
+
0x57, // W
|
|
103
|
+
0x41, // A
|
|
104
|
+
0x56, // V
|
|
105
|
+
0x45, // E
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
mediaType: 'audio/ogg' as const,
|
|
110
|
+
bytesPrefix: [0x4f, 0x67, 0x67, 0x53],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
mediaType: 'audio/flac' as const,
|
|
114
|
+
bytesPrefix: [0x66, 0x4c, 0x61, 0x43],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
mediaType: 'audio/aac' as const,
|
|
118
|
+
bytesPrefix: [0x40, 0x15, 0x00, 0x00],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
mediaType: 'audio/mp4' as const,
|
|
122
|
+
bytesPrefix: [0x66, 0x74, 0x79, 0x70],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
mediaType: 'audio/webm',
|
|
126
|
+
bytesPrefix: [0x1a, 0x45, 0xdf, 0xa3],
|
|
127
|
+
},
|
|
128
|
+
] as const;
|
|
129
|
+
|
|
130
|
+
const videoMediaTypeSignatures = [
|
|
131
|
+
{
|
|
132
|
+
mediaType: 'video/mp4' as const,
|
|
133
|
+
bytesPrefix: [
|
|
134
|
+
0x00,
|
|
135
|
+
0x00,
|
|
136
|
+
0x00,
|
|
137
|
+
null,
|
|
138
|
+
0x66,
|
|
139
|
+
0x74,
|
|
140
|
+
0x79,
|
|
141
|
+
0x70, // ftyp
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
mediaType: 'video/webm' as const,
|
|
146
|
+
bytesPrefix: [0x1a, 0x45, 0xdf, 0xa3], // EBML
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
mediaType: 'video/quicktime' as const,
|
|
150
|
+
bytesPrefix: [
|
|
151
|
+
0x00,
|
|
152
|
+
0x00,
|
|
153
|
+
0x00,
|
|
154
|
+
0x14,
|
|
155
|
+
0x66,
|
|
156
|
+
0x74,
|
|
157
|
+
0x79,
|
|
158
|
+
0x70,
|
|
159
|
+
0x71,
|
|
160
|
+
0x74, // ftypqt
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
mediaType: 'video/x-msvideo' as const,
|
|
165
|
+
bytesPrefix: [0x52, 0x49, 0x46, 0x46], // RIFF (AVI)
|
|
166
|
+
},
|
|
167
|
+
] as const;
|
|
168
|
+
|
|
169
|
+
const stripID3 = (data: Uint8Array | string) => {
|
|
170
|
+
const bytes =
|
|
171
|
+
typeof data === 'string' ? convertBase64ToUint8Array(data) : data;
|
|
172
|
+
const id3Size =
|
|
173
|
+
((bytes[6] & 0x7f) << 21) |
|
|
174
|
+
((bytes[7] & 0x7f) << 14) |
|
|
175
|
+
((bytes[8] & 0x7f) << 7) |
|
|
176
|
+
(bytes[9] & 0x7f);
|
|
177
|
+
|
|
178
|
+
// The raw MP3 starts here
|
|
179
|
+
return bytes.slice(id3Size + 10);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
function stripID3TagsIfPresent(data: Uint8Array | string): Uint8Array | string {
|
|
183
|
+
const hasId3 =
|
|
184
|
+
(typeof data === 'string' && data.startsWith('SUQz')) ||
|
|
185
|
+
(typeof data !== 'string' &&
|
|
186
|
+
data.length > 10 &&
|
|
187
|
+
data[0] === 0x49 && // 'I'
|
|
188
|
+
data[1] === 0x44 && // 'D'
|
|
189
|
+
data[2] === 0x33); // '3'
|
|
190
|
+
|
|
191
|
+
return hasId3 ? stripID3(data) : data;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
type MediaTypeSignatures = ReadonlyArray<{
|
|
195
|
+
readonly mediaType: string;
|
|
196
|
+
readonly bytesPrefix: ReadonlyArray<number | null>;
|
|
197
|
+
}>;
|
|
198
|
+
|
|
199
|
+
function detectMediaTypeBySignatures<T extends MediaTypeSignatures>({
|
|
200
|
+
data,
|
|
201
|
+
signatures,
|
|
202
|
+
}: {
|
|
203
|
+
data: Uint8Array | string;
|
|
204
|
+
signatures: T;
|
|
205
|
+
}): T[number]['mediaType'] | undefined {
|
|
206
|
+
const processedData = stripID3TagsIfPresent(data);
|
|
207
|
+
|
|
208
|
+
// Convert the first ~18 bytes (24 base64 chars) for consistent detection logic:
|
|
209
|
+
const bytes =
|
|
210
|
+
typeof processedData === 'string'
|
|
211
|
+
? convertBase64ToUint8Array(
|
|
212
|
+
processedData.substring(0, Math.min(processedData.length, 24)),
|
|
213
|
+
)
|
|
214
|
+
: processedData;
|
|
215
|
+
|
|
216
|
+
for (const signature of signatures) {
|
|
217
|
+
if (
|
|
218
|
+
bytes.length >= signature.bytesPrefix.length &&
|
|
219
|
+
signature.bytesPrefix.every(
|
|
220
|
+
(byte, index) => byte === null || bytes[index] === byte,
|
|
221
|
+
)
|
|
222
|
+
) {
|
|
223
|
+
return signature.mediaType;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const topLevelSignatureTables = {
|
|
231
|
+
image: imageMediaTypeSignatures,
|
|
232
|
+
audio: audioMediaTypeSignatures,
|
|
233
|
+
video: videoMediaTypeSignatures,
|
|
234
|
+
application: documentMediaTypeSignatures,
|
|
235
|
+
} as const;
|
|
236
|
+
|
|
237
|
+
type TopLevelMediaType = keyof typeof topLevelSignatureTables;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Detect the IANA media type of a file from its raw bytes or base64 string.
|
|
241
|
+
*
|
|
242
|
+
* - When `topLevelType` is omitted, every known signature is considered
|
|
243
|
+
* (image, audio, video, and application). Returns `undefined` when the
|
|
244
|
+
* bytes do not match any known signature.
|
|
245
|
+
* - When `topLevelType` is provided, only signatures for that top-level
|
|
246
|
+
* segment are considered. Returns `undefined` for unsupported segments
|
|
247
|
+
* (e.g. `"text"`) or when no signature matches.
|
|
248
|
+
*/
|
|
249
|
+
export function detectMediaType({
|
|
250
|
+
data,
|
|
251
|
+
topLevelType,
|
|
252
|
+
}: {
|
|
253
|
+
data: Uint8Array | string;
|
|
254
|
+
topLevelType?: string;
|
|
255
|
+
}): string | undefined {
|
|
256
|
+
if (topLevelType === undefined) {
|
|
257
|
+
return detectMediaTypeBySignatures({
|
|
258
|
+
data,
|
|
259
|
+
signatures: [
|
|
260
|
+
...imageMediaTypeSignatures,
|
|
261
|
+
...documentMediaTypeSignatures,
|
|
262
|
+
...audioMediaTypeSignatures,
|
|
263
|
+
...videoMediaTypeSignatures,
|
|
264
|
+
],
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const signatures = topLevelSignatureTables[topLevelType as TopLevelMediaType];
|
|
269
|
+
|
|
270
|
+
if (signatures === undefined) {
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return detectMediaTypeBySignatures({ data, signatures });
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Returns the top-level segment of a media type (the portion before `/`).
|
|
279
|
+
*
|
|
280
|
+
* Examples:
|
|
281
|
+
* - `"image/png"` -> `"image"`
|
|
282
|
+
* - `"image/*"` -> `"image"`
|
|
283
|
+
* - `"image"` -> `"image"`
|
|
284
|
+
* - `"image/"` -> `"image"`
|
|
285
|
+
* - `""` -> `""`
|
|
286
|
+
* - `"/"` -> `""`
|
|
287
|
+
*/
|
|
288
|
+
export function getTopLevelMediaType(mediaType: string): string {
|
|
289
|
+
const slashIndex = mediaType.indexOf('/');
|
|
290
|
+
return slashIndex === -1 ? mediaType : mediaType.substring(0, slashIndex);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Returns `true` only when the given media type has a non-empty, non-wildcard
|
|
295
|
+
* subtype (i.e. matches the form `type/subtype`, and `subtype` is not `*`).
|
|
296
|
+
*
|
|
297
|
+
* Examples:
|
|
298
|
+
* - `"image/png"` -> `true`
|
|
299
|
+
* - `"image/*"` -> `false`
|
|
300
|
+
* - `"image"` -> `false`
|
|
301
|
+
* - `"image/"` -> `false`
|
|
302
|
+
* - `""` -> `false`
|
|
303
|
+
* - `"/"` -> `false`
|
|
304
|
+
*/
|
|
305
|
+
export function isFullMediaType(mediaType: string): boolean {
|
|
306
|
+
const slashIndex = mediaType.indexOf('/');
|
|
307
|
+
if (slashIndex === -1) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
const subtype = mediaType.substring(slashIndex + 1);
|
|
311
|
+
return subtype.length > 0 && subtype !== '*';
|
|
312
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filters `null` and `undefined` values out of a list of values.
|
|
3
|
+
*
|
|
4
|
+
* @param values - The values to filter.
|
|
5
|
+
* @returns A new array containing only non-nullish values.
|
|
6
|
+
*/
|
|
7
|
+
export function filterNullable<T>(
|
|
8
|
+
...values: Array<T | undefined | null>
|
|
9
|
+
): Array<T> {
|
|
10
|
+
return values.filter((value): value is NonNullable<T> => value != null);
|
|
11
|
+
}
|
package/src/get-error-message.ts
CHANGED
|
@@ -1,15 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
if (error == null) {
|
|
3
|
-
return 'unknown error';
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
if (typeof error === 'string') {
|
|
7
|
-
return error;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (error instanceof Error) {
|
|
11
|
-
return error.message;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return JSON.stringify(error);
|
|
15
|
-
}
|
|
1
|
+
export { getErrorMessage } from '@ai-sdk/provider';
|
package/src/get-from-api.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { APICallError } from '@ai-sdk/provider';
|
|
2
2
|
import { extractResponseHeaders } from './extract-response-headers';
|
|
3
|
-
import { FetchFunction } from './fetch-function';
|
|
3
|
+
import type { FetchFunction } from './fetch-function';
|
|
4
4
|
import { handleFetchError } from './handle-fetch-error';
|
|
5
5
|
import { isAbortError } from './is-abort-error';
|
|
6
|
-
import { ResponseHandler } from './response-handler';
|
|
6
|
+
import type { ResponseHandler } from './response-handler';
|
|
7
7
|
import { getRuntimeEnvironmentUserAgent } from './get-runtime-environment-user-agent';
|
|
8
8
|
import { withUserAgentSuffix } from './with-user-agent-suffix';
|
|
9
9
|
import { VERSION } from './version';
|