From 2612aa229d110a5dade44678e1c97cf858dff58d Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Mon, 15 Sep 2025 12:26:55 +0300 Subject: [PATCH 01/10] feat: change files path to library (PLAT-962) --- .../studio/conversational-rag/rag-engine.ts | 12 +- package-lock.json | 1285 ++++++----------- src/AI21.ts | 6 +- src/index.ts | 2 +- src/resources/files/index.ts | 1 - src/resources/index.ts | 2 +- src/resources/{files => library}/files.ts | 8 +- src/resources/library/index.ts | 1 + src/resources/library/library.ts | 6 + src/resources/maestro/index.ts | 0 10 files changed, 446 insertions(+), 877 deletions(-) delete mode 100644 src/resources/files/index.ts rename src/resources/{files => library}/files.ts (80%) create mode 100644 src/resources/library/index.ts create mode 100644 src/resources/library/library.ts create mode 100644 src/resources/maestro/index.ts diff --git a/examples/studio/conversational-rag/rag-engine.ts b/examples/studio/conversational-rag/rag-engine.ts index 5dcc0c0..ca745b1 100644 --- a/examples/studio/conversational-rag/rag-engine.ts +++ b/examples/studio/conversational-rag/rag-engine.ts @@ -15,7 +15,7 @@ async function waitForFileProcessing( const startTime = Date.now(); while (Date.now() - startTime < timeout) { - const file: FileResponse = await client.files.get(fileId); + const file: FileResponse = await client.library.files.get(fileId); if (file.status !== 'PROCESSING') { return file; } @@ -29,7 +29,7 @@ async function uploadGetUpdateDelete(fileInput, path) { const client = new AI21({ apiKey: process.env.AI21_API_KEY }); try { console.log(`Starting upload for file:`, typeof fileInput); - const uploadFileResponse: UploadFileResponse = await client.files.create({ + const uploadFileResponse: UploadFileResponse = await client.library.files.create({ file: fileInput, path: path, }); @@ -41,12 +41,12 @@ async function uploadGetUpdateDelete(fileInput, path) { if (file.status === 'PROCESSED') { console.log('Starting file update...'); - await client.files.update({ + await client.library.files.update({ fileId: uploadFileResponse.fileId, labels: ['test99'], publicUrl: 'https://www.miri.com', }); - file = await client.files.get(uploadFileResponse.fileId); + file = await client.library.files.get(uploadFileResponse.fileId); console.log('✓ File update completed'); } else { console.log(`⚠ File processing failed with status ${file.status}`); @@ -54,7 +54,7 @@ async function uploadGetUpdateDelete(fileInput, path) { } console.log('Starting file deletion...'); - await client.files.delete(uploadFileResponse.fileId); + await client.library.files.delete(uploadFileResponse.fileId); console.log('✓ File deletion completed'); // Add buffer time between operations @@ -67,7 +67,7 @@ async function uploadGetUpdateDelete(fileInput, path) { async function listFiles() { const client = new AI21({ apiKey: process.env.AI21_API_KEY }); - const files = await client.files.list({ limit: 4 }); + const files = await client.library.files.list({ limit: 4 }); console.log(`Listed files: ${files}`); } diff --git a/package-lock.json b/package-lock.json index ece605d..74e46bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ai21", - "version": "1.0.1", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ai21", - "version": "1.0.1", + "version": "1.1.1", "license": "MIT", "dependencies": { "@types/node": "^18.11.18", @@ -33,7 +33,7 @@ "jest-environment-jsdom": "^29.7.0", "madge": "^6.1.0", "prettier": "^3.3.3", - "semantic-release": "^24.2.0", + "semantic-release": "^24.2.3", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "tsc-multi": "^1.1.0", @@ -44,6 +44,9 @@ "uuid": "^11.0.3", "vite": "^5.4.11", "vite-plugin-dts": "^4.3.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@ampproject/remapping": { @@ -2951,9 +2954,9 @@ } }, "node_modules/@semantic-release/npm": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz", - "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.2.tgz", + "integrity": "sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2964,7 +2967,7 @@ "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^8.0.0", - "npm": "^10.5.0", + "npm": "^10.9.3", "rc": "^1.2.8", "read-pkg": "^9.0.0", "registry-auth-token": "^5.0.0", @@ -3048,24 +3051,24 @@ } }, "node_modules/@semantic-release/npm/node_modules/execa": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.1.tgz", - "integrity": "sha512-QY5PPtSonnGwhhHDNI7+3RvY285c7iuJFFB+lU+oEzMY/gEGJ808owqJsrr8Otd1E/x07po1LkUBmdAc5duPAg==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", + "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", - "human-signals": "^8.0.0", + "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", - "pretty-ms": "^9.0.0", + "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.0.0" + "yoctocolors": "^2.1.1" }, "engines": { "node": "^18.19.0 || >=20.5.0" @@ -3092,9 +3095,9 @@ } }, "node_modules/@semantic-release/npm/node_modules/human-signals": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", - "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3997,9 +4000,9 @@ } }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -4475,9 +4478,9 @@ "license": "CC-BY-4.0" }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { @@ -4962,9 +4965,9 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -6664,9 +6667,9 @@ } }, "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "dev": true, "license": "MIT", "dependencies": { @@ -7030,13 +7033,13 @@ } }, "node_modules/hook-std": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", - "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-4.0.0.tgz", + "integrity": "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8762,9 +8765,9 @@ } }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { @@ -9122,9 +9125,9 @@ } }, "node_modules/marked": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", - "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", "dev": true, "license": "MIT", "bin": { @@ -9135,31 +9138,31 @@ } }, "node_modules/marked-terminal": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.2.1.tgz", - "integrity": "sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", - "chalk": "^5.3.0", + "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", - "node-emoji": "^2.1.3", + "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "marked": ">=1 <15" + "marked": ">=1 <16" } }, "node_modules/marked-terminal/node_modules/ansi-escapes": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", - "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.0.tgz", + "integrity": "sha512-YdhtCd19sKRKfAAUsrcC1wzm4JuzJoiX4pOJqIoW2qmKj5WzG/dL8uUJ0361zaXtHqK7gEhOwtAtz7t3Yq3X5g==", "dev": true, "license": "MIT", "dependencies": { @@ -9438,9 +9441,9 @@ "license": "MIT" }, "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", "dev": true, "license": "MIT", "dependencies": { @@ -9568,9 +9571,9 @@ } }, "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz", + "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==", "dev": true, "license": "MIT", "engines": { @@ -9581,9 +9584,9 @@ } }, "node_modules/npm": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.0.tgz", - "integrity": "sha512-ZanDioFylI9helNhl2LNd+ErmVD+H5I53ry41ixlLyCBgkuYb+58CvbAp99hW+zr5L9W4X7CchSoeqKdngOLSw==", + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.3.tgz", + "integrity": "sha512-6Eh1u5Q+kIVXeA8e7l2c/HpnFFcwrkt37xDMujD5be1gloWa9p6j3Fsv3mByXXmqJHy+2cElRMML8opNT7xIJQ==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -9665,63 +9668,63 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/config": "^9.0.0", "@npmcli/fs": "^4.0.0", - "@npmcli/map-workspaces": "^4.0.1", - "@npmcli/package-json": "^6.0.1", - "@npmcli/promise-spawn": "^8.0.1", - "@npmcli/redact": "^3.0.0", - "@npmcli/run-script": "^9.0.1", - "@sigstore/tuf": "^2.3.4", - "abbrev": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.2", + "@npmcli/package-json": "^6.2.0", + "@npmcli/promise-spawn": "^8.0.2", + "@npmcli/redact": "^3.2.2", + "@npmcli/run-script": "^9.1.0", + "@sigstore/tuf": "^3.1.1", + "abbrev": "^3.0.1", "archy": "~1.0.0", "cacache": "^19.0.1", - "chalk": "^5.3.0", - "ci-info": "^4.0.0", + "chalk": "^5.4.1", + "ci-info": "^4.2.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^8.0.0", + "hosted-git-info": "^8.1.0", "ini": "^5.0.0", - "init-package-json": "^7.0.1", - "is-cidr": "^5.1.0", + "init-package-json": "^7.0.2", + "is-cidr": "^5.1.1", "json-parse-even-better-errors": "^4.0.0", "libnpmaccess": "^9.0.0", - "libnpmdiff": "^7.0.0", - "libnpmexec": "^9.0.0", - "libnpmfund": "^6.0.0", + "libnpmdiff": "^7.0.1", + "libnpmexec": "^9.0.1", + "libnpmfund": "^6.0.1", "libnpmhook": "^11.0.0", "libnpmorg": "^7.0.0", - "libnpmpack": "^8.0.0", - "libnpmpublish": "^10.0.0", + "libnpmpack": "^8.0.1", + "libnpmpublish": "^10.0.1", "libnpmsearch": "^8.0.0", "libnpmteam": "^7.0.0", "libnpmversion": "^7.0.0", - "make-fetch-happen": "^14.0.1", + "make-fetch-happen": "^14.0.3", "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.2.0", - "nopt": "^8.0.0", + "node-gyp": "^11.2.0", + "nopt": "^8.1.0", "normalize-package-data": "^7.0.0", "npm-audit-report": "^6.0.0", - "npm-install-checks": "^7.1.0", - "npm-package-arg": "^12.0.0", + "npm-install-checks": "^7.1.1", + "npm-package-arg": "^12.0.2", "npm-pick-manifest": "^10.0.0", "npm-profile": "^11.0.1", - "npm-registry-fetch": "^18.0.1", + "npm-registry-fetch": "^18.0.2", "npm-user-validate": "^3.0.0", - "p-map": "^4.0.0", - "pacote": "^19.0.0", + "p-map": "^7.0.3", + "pacote": "^19.0.1", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", - "read": "^4.0.0", - "semver": "^7.6.3", + "read": "^4.1.0", + "semver": "^7.7.2", "spdx-expression-parse": "^4.0.0", "ssri": "^12.0.0", "supports-color": "^9.4.0", @@ -9729,7 +9732,7 @@ "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^6.0.0", + "validate-npm-package-name": "^6.0.1", "which": "^5.0.0", "write-file-atomic": "^6.0.0" }, @@ -9772,7 +9775,7 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -9856,7 +9859,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "8.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -9936,7 +9939,7 @@ } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "6.0.1", + "version": "6.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -9946,7 +9949,6 @@ "lru-cache": "^10.0.1", "npm-pick-manifest": "^10.0.0", "proc-log": "^5.0.0", - "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^5.0.0" @@ -9972,7 +9974,7 @@ } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "4.0.1", + "version": "4.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -9987,14 +9989,14 @@ } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "8.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "cacache": "^19.0.0", "json-parse-even-better-errors": "^4.0.0", - "pacote": "^19.0.0", + "pacote": "^20.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5" }, @@ -10002,6 +10004,37 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "3.0.0", "dev": true, @@ -10021,7 +10054,7 @@ } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "6.0.1", + "version": "6.2.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10030,16 +10063,16 @@ "glob": "^10.2.2", "hosted-git-info": "^8.0.0", "json-parse-even-better-errors": "^4.0.0", - "normalize-package-data": "^7.0.0", "proc-log": "^5.0.0", - "semver": "^7.5.3" + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "8.0.1", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -10051,19 +10084,19 @@ } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "4.0.0", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.1.2" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "3.0.0", + "version": "3.2.2", "dev": true, "inBundle": true, "license": "ISC", @@ -10072,7 +10105,7 @@ } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "9.0.1", + "version": "9.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10080,7 +10113,7 @@ "@npmcli/node-gyp": "^4.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", - "node-gyp": "^10.0.0", + "node-gyp": "^11.0.0", "proc-log": "^5.0.0", "which": "^5.0.0" }, @@ -10098,353 +10131,136 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", + "version": "0.4.3", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.3.2", + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "3.1.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/agent": { - "version": "2.2.2", + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, + "license": "MIT", "engines": { "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/fs": { - "version": "3.1.1", + "node_modules/npm/node_modules/abbrev": { + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/cacache": { - "version": "18.0.4", + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.3", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">= 14" } }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/make-fetch-happen": { - "version": "13.0.1", + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, + "license": "MIT", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/minipass-fetch": { - "version": "3.0.5", + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" }, - "optionalDependencies": { - "encoding": "^0.1.13" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { - "version": "4.2.0", + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "ISC" }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/ssri": { - "version": "10.0.6", + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "MIT" }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-filename": { - "version": "3.0.0", + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "MIT" }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-slug": { - "version": "4.0.0", + "node_modules/npm/node_modules/bin-links": { + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "imurmurhash": "^0.1.4" + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.4", + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.3.0", "dev": true, "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.2.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" + "node": ">=8" }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.1", + "node_modules/npm/node_modules/cacache": { + "version": "19.0.1", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/agent-base": { - "version": "7.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^7.0.0", - "npm-normalize-package-bin": "^4.0.0", - "proc-log": "^5.0.0", - "read-cmd-shim": "^5.0.0", - "write-file-atomic": "^6.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "19.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", + "license": "ISC", "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", @@ -10472,19 +10288,6 @@ "node": ">=18" } }, - "node_modules/npm/node_modules/cacache/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { "version": "3.0.1", "dev": true, @@ -10500,18 +10303,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/cacache/node_modules/p-map": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm/node_modules/cacache/node_modules/tar": { "version": "7.4.3", "dev": true, @@ -10539,7 +10330,7 @@ } }, "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", + "version": "5.4.1", "dev": true, "inBundle": true, "license": "MIT", @@ -10560,7 +10351,7 @@ } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", + "version": "4.2.0", "dev": true, "funding": [ { @@ -10575,7 +10366,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.1.1", + "version": "4.1.3", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -10586,15 +10377,6 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/npm/node_modules/cli-columns": { "version": "4.0.0", "dev": true, @@ -10642,7 +10424,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -10683,12 +10465,12 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.6", + "version": "4.4.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -10699,12 +10481,6 @@ } } }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/diff": { "version": "5.2.0", "dev": true, @@ -10752,7 +10528,7 @@ "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", + "version": "3.1.2", "dev": true, "inBundle": true, "license": "Apache-2.0" @@ -10767,12 +10543,12 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.3.0", + "version": "3.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -10821,7 +10597,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "8.0.0", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10833,7 +10609,7 @@ } }, "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", + "version": "4.2.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause" @@ -10852,12 +10628,12 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.5", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -10898,15 +10674,6 @@ "node": ">=0.8.19" } }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/ini": { "version": "5.0.0", "dev": true, @@ -10917,7 +10684,7 @@ } }, "node_modules/npm/node_modules/init-package-json": { - "version": "7.0.1", + "version": "7.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -10960,7 +10727,7 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.1.0", + "version": "5.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -10980,12 +10747,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/isexe": { "version": "2.0.0", "dev": true, @@ -11066,12 +10827,12 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "7.0.0", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", @@ -11085,12 +10846,12 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "9.0.0", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", "npm-package-arg": "^12.0.0", @@ -11106,12 +10867,12 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "6.0.0", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0" + "@npmcli/arborist": "^8.0.1" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -11144,12 +10905,12 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "8.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.0", + "@npmcli/arborist": "^8.0.1", "@npmcli/run-script": "^9.0.1", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0" @@ -11159,7 +10920,7 @@ } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "10.0.0", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -11170,7 +10931,7 @@ "npm-registry-fetch": "^18.0.1", "proc-log": "^5.0.0", "semver": "^7.3.7", - "sigstore": "^2.2.0", + "sigstore": "^3.0.0", "ssri": "^12.0.0" }, "engines": { @@ -11225,7 +10986,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "14.0.1", + "version": "14.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -11237,7 +10998,7 @@ "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", + "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" @@ -11246,6 +11007,15 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/npm/node_modules/minimatch": { "version": "9.0.5", "dev": true, @@ -11283,7 +11053,7 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "4.0.0", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "MIT", @@ -11299,19 +11069,6 @@ "encoding": "^0.1.13" } }, - "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/minipass-flush": { "version": "1.0.5", "dev": true, @@ -11385,28 +11142,15 @@ } }, "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, "node_modules/npm/node_modules/mkdirp": { @@ -11436,230 +11180,87 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.2.0", + "version": "11.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^4.1.0", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^4.0.0" + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/agent": { - "version": "2.2.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/fs": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/cacache": { - "version": "18.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/isexe": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/make-fetch-happen": { - "version": "13.0.1", + "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=18" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/minipass-fetch": { - "version": "3.0.5", + "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { - "version": "7.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/ssri": { - "version": "10.0.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/unique-filename": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" + "node": ">=10" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/unique-slug": { - "version": "4.0.0", + "node_modules/npm/node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "imurmurhash": "^0.1.4" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=18" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/which": { - "version": "4.0.0", + "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": ">=18" } }, "node_modules/npm/node_modules/nopt": { - "version": "8.0.0", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "abbrev": "^2.0.0" + "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" @@ -11668,15 +11269,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/nopt/node_modules/abbrev": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/normalize-package-data": { "version": "7.0.0", "dev": true, @@ -11713,7 +11305,7 @@ } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "7.1.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -11734,7 +11326,7 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "12.0.0", + "version": "12.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -11789,7 +11381,7 @@ } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "18.0.1", + "version": "18.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -11807,19 +11399,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/npm/node_modules/npm-user-validate": { "version": "3.0.0", "dev": true, @@ -11830,28 +11409,25 @@ } }, "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", + "version": "7.0.3", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/package-json-from-dist": { - "version": "1.0.0", + "version": "1.0.1", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0" }, "node_modules/npm/node_modules/pacote": { - "version": "19.0.0", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -11870,7 +11446,7 @@ "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "sigstore": "^2.2.0", + "sigstore": "^3.0.0", "ssri": "^12.0.0", "tar": "^6.1.11" }, @@ -11921,7 +11497,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "version": "7.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -11961,7 +11537,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.1", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -11969,12 +11545,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", "dev": true, @@ -12009,7 +11579,7 @@ } }, "node_modules/npm/node_modules/read": { - "version": "4.0.0", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -12051,21 +11621,6 @@ "node": ">= 4" } }, - "node_modules/npm/node_modules/rimraf": { - "version": "5.0.10", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", "dev": true, @@ -12074,7 +11629,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.3", + "version": "7.7.2", "dev": true, "inBundle": true, "license": "ISC", @@ -12119,20 +11674,72 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.3.1", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -12146,7 +11753,7 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.3", + "version": "2.8.5", "dev": true, "inBundle": true, "license": "MIT", @@ -12160,12 +11767,12 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.4", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -12210,7 +11817,7 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.18", + "version": "3.0.21", "dev": true, "inBundle": true, "license": "CC0-1.0" @@ -12349,175 +11956,119 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.1", + "node_modules/npm/node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">= 8" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/agent": { - "version": "2.2.2", + "node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" + "yallist": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/fs": { - "version": "3.1.1", + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "MIT" }, - "node_modules/npm/node_modules/tuf-js/node_modules/cacache": { - "version": "18.0.4", + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } + "license": "MIT" }, - "node_modules/npm/node_modules/tuf-js/node_modules/make-fetch-happen": { - "version": "13.0.1", + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.14", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "fdir": "^6.4.4", + "picomatch": "^4.0.2" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/minipass-fetch": { - "version": "3.0.5", + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "optionalDependencies": { - "encoding": "^0.1.13" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/npm/node_modules/tuf-js/node_modules/proc-log": { - "version": "4.2.0", + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/ssri": { - "version": "10.0.6", + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/unique-filename": { - "version": "3.0.0", + "node_modules/npm/node_modules/tuf-js": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "unique-slug": "^4.0.0" + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/unique-slug": { - "version": "4.0.0", + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "imurmurhash": "^0.1.4" + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-filename": { @@ -12571,7 +12122,7 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "6.0.0", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -12660,7 +12211,7 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -14000,9 +13551,9 @@ } }, "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", + "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", "dev": true, "license": "MIT", "dependencies": { @@ -14300,16 +13851,16 @@ } }, "node_modules/semantic-release": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.0.tgz", - "integrity": "sha512-fQfn6e/aYToRtVJYKqneFM1Rg3KP2gh3wSWtpYsLlz6uaPKlISrTzvYAFn+mYWo07F0X1Cz5ucU89AVE8X1mbg==", + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.8.tgz", + "integrity": "sha512-uvoLiKEB/AvvA3SCPE78cd90nVJXn220kkEA6sNGzDpas4s7pe4OgYWvhfR0lvWBdBH/T0RFCI6U+GvcT2CypQ==", "dev": true, "license": "MIT", "dependencies": { "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^11.0.0", - "@semantic-release/npm": "^12.0.0", + "@semantic-release/npm": "^12.0.2", "@semantic-release/release-notes-generator": "^14.0.0-beta.1", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", @@ -14320,12 +13871,12 @@ "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", - "hook-std": "^3.0.0", + "hook-std": "^4.0.0", "hosted-git-info": "^8.0.0", - "import-from-esm": "^1.3.1", + "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", - "marked": "^12.0.0", - "marked-terminal": "^7.0.0", + "marked": "^15.0.0", + "marked-terminal": "^7.3.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", @@ -14466,6 +14017,20 @@ "node": ">=18.18.0" } }, + "node_modules/semantic-release/node_modules/import-from-esm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-2.0.0.tgz", + "integrity": "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.20" + } + }, "node_modules/semantic-release/node_modules/indent-string": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", @@ -15197,9 +14762,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", - "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, "license": "MIT", "dependencies": { @@ -15210,7 +14775,7 @@ "node": ">=14.18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { diff --git a/src/AI21.ts b/src/AI21.ts index 36b8d27..f5c6ad8 100644 --- a/src/AI21.ts +++ b/src/AI21.ts @@ -1,12 +1,10 @@ import * as Types from './types'; import { AI21EnvConfig } from './EnvConfig'; import { AI21Error, MissingAPIKeyError } from './errors'; -import { Chat } from './resources/chat'; import { APIClient } from './APIClient'; import { Headers } from './types'; import * as Runtime from './runtime'; -import { ConversationalRag } from './resources/rag/conversational-rag'; -import { Files } from './resources'; +import { Chat, ConversationalRag, Library } from './resources'; export interface ClientOptions { baseURL?: string | undefined; @@ -68,7 +66,7 @@ export class AI21 extends APIClient { // Resources chat: Chat = new Chat(this); conversationalRag: ConversationalRag = new ConversationalRag(this); - files: Files = new Files(this); + library: Library = new Library(this); // eslint-disable-next-line @typescript-eslint/no-unused-vars protected override authHeaders(_: Types.FinalRequestOptions): Types.Headers { diff --git a/src/index.ts b/src/index.ts index 015eb97..17219f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,5 +49,5 @@ export { APIClient } from './APIClient'; export { AI21Error, MissingAPIKeyError } from './errors'; export { Stream } from './streaming'; export { APIResource } from './APIResource'; -export { Chat, Completions, ConversationalRag, Files } from './resources'; +export { Chat, Completions, ConversationalRag, Library } from './resources'; export { isBrowser, isNode } from './runtime'; diff --git a/src/resources/files/index.ts b/src/resources/files/index.ts deleted file mode 100644 index 21742ad..0000000 --- a/src/resources/files/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Files } from './files'; diff --git a/src/resources/index.ts b/src/resources/index.ts index 12d4ba4..b8680b6 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,3 +1,3 @@ export { Chat, Completions } from './chat'; export { ConversationalRag } from './rag'; -export { Files } from './files'; +export { Library } from './library'; diff --git a/src/resources/files/files.ts b/src/resources/library/files.ts similarity index 80% rename from src/resources/files/files.ts rename to src/resources/library/files.ts index f3bf691..6689ec0 100644 --- a/src/resources/files/files.ts +++ b/src/resources/library/files.ts @@ -14,28 +14,28 @@ export class Files extends APIResource { } as Models.RequestOptions) as Promise; } - get(fileId: string, options?: Models.RequestOptions): Promise { + async get(fileId: string, options?: Models.RequestOptions): Promise { return this.client.get( `${FILES_PATH}/${fileId}`, options as Models.RequestOptions, ) as Promise; } - delete(fileId: string, options?: Models.RequestOptions): Promise { + async delete(fileId: string, options?: Models.RequestOptions): Promise { return this.client.delete( `${FILES_PATH}/${fileId}`, options as Models.RequestOptions, ) as Promise; } - list(body?: ListFilesFilters, options?: Models.RequestOptions): Promise { + async list(body?: ListFilesFilters, options?: Models.RequestOptions): Promise { return this.client.get(FILES_PATH, { query: body, ...options, } as Models.RequestOptions) as Promise; } - update(body: UpdateFileRequest, options?: Models.RequestOptions): Promise { + async update(body: UpdateFileRequest, options?: Models.RequestOptions): Promise { return this.client.put(`${FILES_PATH}/${body.fileId}`, { body, ...options, diff --git a/src/resources/library/index.ts b/src/resources/library/index.ts new file mode 100644 index 0000000..2bd534f --- /dev/null +++ b/src/resources/library/index.ts @@ -0,0 +1 @@ +export { Library } from './library'; diff --git a/src/resources/library/library.ts b/src/resources/library/library.ts new file mode 100644 index 0000000..d9751ae --- /dev/null +++ b/src/resources/library/library.ts @@ -0,0 +1,6 @@ +import { APIResource } from '../../APIResource'; +import { Files } from './files'; + +export class Library extends APIResource { + files: Files = new Files(this.client); +} diff --git a/src/resources/maestro/index.ts b/src/resources/maestro/index.ts new file mode 100644 index 0000000..e69de29 From 9f9656e21972221055681229e920a4aba5247d71 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Mon, 15 Sep 2025 16:15:41 +0300 Subject: [PATCH 02/10] feat: added maestro functions --- .../maestro/maestro-run-create-and-poll.ts | 21 ++++ examples/studio/maestro/maestro-run.ts | 15 +++ src/AI21.ts | 3 +- src/resources/chat/completions.ts | 2 +- src/resources/index.ts | 1 + src/resources/maestro/beta.ts | 6 ++ src/resources/maestro/index.ts | 3 + src/resources/maestro/maestro.ts | 6 ++ src/resources/maestro/runs.ts | 55 ++++++++++ src/types/index.ts | 2 + src/types/maestro/MaestroRunRequest.ts | 101 ++++++++++++++++++ src/types/maestro/MaestroRunResponse.ts | 34 ++++++ src/types/maestro/index.ts | 2 + 13 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 examples/studio/maestro/maestro-run-create-and-poll.ts create mode 100644 examples/studio/maestro/maestro-run.ts create mode 100644 src/resources/maestro/beta.ts create mode 100644 src/resources/maestro/maestro.ts create mode 100644 src/resources/maestro/runs.ts create mode 100644 src/types/maestro/MaestroRunRequest.ts create mode 100644 src/types/maestro/MaestroRunResponse.ts create mode 100644 src/types/maestro/index.ts diff --git a/examples/studio/maestro/maestro-run-create-and-poll.ts b/examples/studio/maestro/maestro-run-create-and-poll.ts new file mode 100644 index 0000000..905f234 --- /dev/null +++ b/examples/studio/maestro/maestro-run-create-and-poll.ts @@ -0,0 +1,21 @@ +import { AI21 } from 'ai21'; + +const TIMEOUT = 20000; +const INTERVAL = 1500; + +async function main() { + const client = new AI21({ apiKey: process.env.AI21_API_KEY }); + + const response = await client.beta.maestro.runs.create_and_poll( + { + input: 'Hello, how are you? tell me a short story about a wizard', + }, + { + timeout: TIMEOUT, + interval: INTERVAL, + }, + ); + console.log(response); +} + +main().catch(console.error); diff --git a/examples/studio/maestro/maestro-run.ts b/examples/studio/maestro/maestro-run.ts new file mode 100644 index 0000000..054edb7 --- /dev/null +++ b/examples/studio/maestro/maestro-run.ts @@ -0,0 +1,15 @@ +import { AI21 } from 'ai21'; + +async function main() { + const client = new AI21({ apiKey: process.env.AI21_API_KEY }); + + const { id } = await client.beta.maestro.runs.create({ + input: 'Hello, how are you? tell me a short story about a wizard', + }); + + const response = await client.beta.maestro.runs.get(id); + + console.log(response); +} + +main().catch(console.error); diff --git a/src/AI21.ts b/src/AI21.ts index f5c6ad8..4f5fa13 100644 --- a/src/AI21.ts +++ b/src/AI21.ts @@ -4,7 +4,7 @@ import { AI21Error, MissingAPIKeyError } from './errors'; import { APIClient } from './APIClient'; import { Headers } from './types'; import * as Runtime from './runtime'; -import { Chat, ConversationalRag, Library } from './resources'; +import { Beta, Chat, ConversationalRag, Library } from './resources'; export interface ClientOptions { baseURL?: string | undefined; @@ -67,6 +67,7 @@ export class AI21 extends APIClient { chat: Chat = new Chat(this); conversationalRag: ConversationalRag = new ConversationalRag(this); library: Library = new Library(this); + beta: Beta = new Beta(this); // eslint-disable-next-line @typescript-eslint/no-unused-vars protected override authHeaders(_: Types.FinalRequestOptions): Types.Headers { diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts index 7a521a9..7d41761 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions.ts @@ -2,7 +2,7 @@ import * as Models from '../../types'; import { APIResource } from '../../APIResource'; import { Stream } from '../../streaming'; -const deprecatedModels = ['jamba-1.5-mini', 'jamba-1.5-large']; +const deprecatedModels = ['jamba-1.6-mini', 'jamba-1.6-large']; export class Completions extends APIResource { create( diff --git a/src/resources/index.ts b/src/resources/index.ts index b8680b6..b8228a0 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,3 +1,4 @@ export { Chat, Completions } from './chat'; export { ConversationalRag } from './rag'; export { Library } from './library'; +export { Maestro, Beta, Runs } from './maestro'; diff --git a/src/resources/maestro/beta.ts b/src/resources/maestro/beta.ts new file mode 100644 index 0000000..66ef8e8 --- /dev/null +++ b/src/resources/maestro/beta.ts @@ -0,0 +1,6 @@ +import { APIResource } from '../../APIResource'; +import { Maestro } from './maestro'; + +export class Beta extends APIResource { + maestro: Maestro = new Maestro(this.client); +} diff --git a/src/resources/maestro/index.ts b/src/resources/maestro/index.ts index e69de29..aea96a2 100644 --- a/src/resources/maestro/index.ts +++ b/src/resources/maestro/index.ts @@ -0,0 +1,3 @@ +export { Beta } from './beta'; +export { Maestro } from './maestro'; +export { Runs } from './runs'; diff --git a/src/resources/maestro/maestro.ts b/src/resources/maestro/maestro.ts new file mode 100644 index 0000000..8f233aa --- /dev/null +++ b/src/resources/maestro/maestro.ts @@ -0,0 +1,6 @@ +import { APIResource } from '../../APIResource'; +import { Runs } from './runs'; + +export class Maestro extends APIResource { + runs: Runs = new Runs(this.client); +} diff --git a/src/resources/maestro/runs.ts b/src/resources/maestro/runs.ts new file mode 100644 index 0000000..9f05bfd --- /dev/null +++ b/src/resources/maestro/runs.ts @@ -0,0 +1,55 @@ +import { APIResource } from '../../APIResource'; +import { MaestroRunRequest, MaestroRunResponse, RequestOptions, MaestroRunRequestOptions } from '../../types'; + +const MAESTRO_PATH = '/maestro/runs'; +const DEFAULT_TIMEOUT = 30000; +const DEFAULT_INTERVAL = 1000; + +export class Runs extends APIResource { + async create(body: MaestroRunRequest): Promise { + return this.client.post(MAESTRO_PATH, { + body, + } as RequestOptions) as Promise; + } + + async get(runId: string): Promise { + return this.client.get( + `${MAESTRO_PATH}/${runId}`, + ) as Promise; + } + + private async poll({ + runId, + timeout, + interval, + }: { + runId: string; + timeout: number; + interval: number; + }): Promise { + const startTime = Date.now(); + + while (Date.now() - startTime < timeout) { + const response = await this.get(runId); + if (response.status === 'completed') { + return response; + } + + await new Promise((resolve) => setTimeout(resolve, interval)); + } + + throw new Error(`Maestro run ${runId} timed out after ${timeout}ms`); + } + + async create_and_poll( + body: MaestroRunRequest, + options?: MaestroRunRequestOptions, + ): Promise { + const response = await this.create(body); + return this.poll({ + runId: response.id, + timeout: options?.timeout ?? DEFAULT_TIMEOUT, + interval: options?.interval ?? DEFAULT_INTERVAL, + }); + } +} diff --git a/src/types/index.ts b/src/types/index.ts index d40670f..0695315 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -53,3 +53,5 @@ export { type UpdateFileRequest, type FilePathOrFileObject, } from './files'; + +export { type MaestroRunRequest, type MaestroRunResponse, type MaestroRunRequestOptions } from './maestro'; diff --git a/src/types/maestro/MaestroRunRequest.ts b/src/types/maestro/MaestroRunRequest.ts new file mode 100644 index 0000000..d48e369 --- /dev/null +++ b/src/types/maestro/MaestroRunRequest.ts @@ -0,0 +1,101 @@ +type MaestroRunInputObject = { + role: string; + content: string; +}; + +type MaestroRunInput = string | MaestroRunInputObject[]; + +type MaestroRunRequirement = { + name: string; + description: string; + isMandatory?: boolean; +}; + +type MaestroRunTool = 'file_search' | 'web_search'; + +export type MaestroToolResources = { + /* + When provided, this object defines filters that AI21 Maestro will apply whenever it performs a file search. + */ + file_search?: { + /* + Restrict file search to these file IDs. + */ + file_ids?: string[]; + /* + Restrict file search to files with these labels. + */ + labels?: string[]; + }; + /* + When provided, this object defines filters that AI21 Maestro will apply whenever it performs a web search. + */ + web_search?: { + /* + Restrict web search to the specified URL prefixes. + */ + urls: string[]; + }; +}; + +type MaestroRunFirstPartyModel = 'jamba-mini' | 'jamba-large'; + +type MaestroRunManagedThirdPartyModel = 'gpt-4o' | 'mistral-7b' | 'mistral-8x7b' | 'mistral-small'; + +type MaestroRunModel = MaestroRunFirstPartyModel | MaestroRunManagedThirdPartyModel; + +type MaestroRunBudget = 'low' | 'medium' | 'high'; + +type MaestroRunIncludeFields = 'data_sources' | 'requirements_result'; + +type MaestroRunResponseLanguage = + | 'arabic' + | 'dutch' + | 'english' + | 'french' + | 'german' + | 'hebrew' + | 'italian' + | 'portuguese' + | 'spanish'; + +export interface MaestroRunRequest { + /* + The input for the maestro run. Plain text instruction or input messages. + */ + input: MaestroRunInput; + /* + The requirements for the maestro run. Maximum 10 requirements. + Works only if no tools are selected. + */ + requirements?: MaestroRunRequirement[]; + /* + Tools for the maestro run. + */ + tools?: MaestroRunTool[]; + /* + A set of resources used by AI21 Maestro’s tools. + */ + tool_resources?: MaestroToolResources; + /* + The models to use for the maestro run. + */ + models?: MaestroRunModel[]; + /* + Controls how many resources AI21 Maestro allocates to fulfill the requirements. + */ + budget?: MaestroRunBudget; + /* + Specify which extra fields to include in the output. + */ + include?: MaestroRunIncludeFields[]; + /* + Controls the output language of AI21 Maestro responses + */ + response_language?: MaestroRunResponseLanguage; +} + +export interface MaestroRunRequestOptions { + timeout?: number; + interval?: number; +} \ No newline at end of file diff --git a/src/types/maestro/MaestroRunResponse.ts b/src/types/maestro/MaestroRunResponse.ts new file mode 100644 index 0000000..203c9de --- /dev/null +++ b/src/types/maestro/MaestroRunResponse.ts @@ -0,0 +1,34 @@ +import { MaestroToolResources } from './MaestroRunRequest'; + +type MaestroRunResponseStatus = 'completed' | 'failed' | 'in_progress'; + +type MaestroRunRequirementResult = { + score: number; + finish_reason: string | null; + requirements: { + name: string | null; + description: string | null; + score: number | null; + reason: string | null; + }; +}; + +export interface MaestroRunResponse { + /* + The ID of the maestro run for polling the status. + */ + id: string; + status: MaestroRunResponseStatus; + /* + The final result object, may vary based on task type. + */ + result: string | null; + /* + Specifies the data sources used to retrieve contextual information for a run. + */ + data_sources: MaestroToolResources; + /* + Detailed results for each requirement. + */ + requirements_result: MaestroRunRequirementResult[]; +} diff --git a/src/types/maestro/index.ts b/src/types/maestro/index.ts new file mode 100644 index 0000000..be3ff3b --- /dev/null +++ b/src/types/maestro/index.ts @@ -0,0 +1,2 @@ +export { MaestroRunRequest, MaestroRunRequestOptions } from './MaestroRunRequest'; +export { MaestroRunResponse } from './MaestroRunResponse'; From 02113db1470463a0e68f4cf561c3bcd889f7a3b1 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Tue, 16 Sep 2025 10:43:01 +0300 Subject: [PATCH 03/10] feat: added tests --- src/types/chat/ChatModel.ts | 4 +- .../resources/chat/completions.test.ts | 8 +- .../resources/maestro/maestro.test.ts | 70 ++++ .../unittests/resources/maestro/runs.test.ts | 359 ++++++++++++++++++ tests/unittests/resources/rag-engine.test.ts | 2 +- 5 files changed, 435 insertions(+), 8 deletions(-) create mode 100644 tests/unittests/resources/maestro/maestro.test.ts create mode 100644 tests/unittests/resources/maestro/runs.test.ts diff --git a/src/types/chat/ChatModel.ts b/src/types/chat/ChatModel.ts index 230f442..7f5d276 100644 --- a/src/types/chat/ChatModel.ts +++ b/src/types/chat/ChatModel.ts @@ -4,6 +4,4 @@ export type ChatModel = | 'jamba-large-1.6-2025-03' | 'jamba-mini-1.6-2025-03' | 'jamba-large-1.6' - | 'jamba-mini-1.6' - | 'jamba-1.5-mini' - | 'jamba-1.5-large'; + | 'jamba-mini-1.6'; diff --git a/tests/unittests/resources/chat/completions.test.ts b/tests/unittests/resources/chat/completions.test.ts index bda8b5a..424c0af 100644 --- a/tests/unittests/resources/chat/completions.test.ts +++ b/tests/unittests/resources/chat/completions.test.ts @@ -30,7 +30,7 @@ describe('Completions', () => { it('should create a non-streaming completion when stream is false', async () => { const body: Models.ChatCompletionCreateParamsNonStreaming = { - model: "jamba-1.5-mini", + model: "jamba-mini", messages: [{role: "user", content: "Hello"}], }; const options: Models.RequestOptions = { headers: { 'Authorization': `Bearer ${dummyAPIKey}` } }; @@ -58,7 +58,7 @@ describe('Completions', () => { }); it('should create a streaming completion when stream is true', async () => { - const body: Models.ChatCompletionCreateParamsStreaming = { model: "jamba-1.5-mini", messages: [{role: "user", content: "Hello"}], stream: true }; + const body: Models.ChatCompletionCreateParamsStreaming = { model: "jamba-mini", messages: [{role: "user", content: "Hello"}], stream: true }; const options: Models.RequestOptions = { headers: { 'Authorization': `Bearer ${dummyAPIKey}` } }; const expectedStream: Models.ChatCompletionChunk = { id: "test-id", @@ -85,7 +85,7 @@ describe('Completions', () => { }); it('should use default options when options parameter is omitted', async () => { - const body: Models.ChatCompletionCreateParamsNonStreaming = { model: "jamba-1.5-mini", messages: [{role: "user", content: "Hello"}], stream: false }; + const body: Models.ChatCompletionCreateParamsNonStreaming = { model: "jamba-mini", messages: [{role: "user", content: "Hello"}], stream: false }; const expectedResponse: Models.ChatCompletionResponse = { id: "test-id", usage: { @@ -108,7 +108,7 @@ describe('Completions', () => { }); it('should handle errors thrown by the API client', async () => { - const body: Models.ChatCompletionCreateParamsNonStreaming = { model: "jamba-1.5-mini", messages: [{role: "user", content: "Hello"}], stream: false }; + const body: Models.ChatCompletionCreateParamsNonStreaming = { model: "jamba-mini", messages: [{role: "user", content: "Hello"}], stream: false }; const error = new AI21Error(); mockClient.post.mockRejectedValue(error); diff --git a/tests/unittests/resources/maestro/maestro.test.ts b/tests/unittests/resources/maestro/maestro.test.ts new file mode 100644 index 0000000..f5c0f05 --- /dev/null +++ b/tests/unittests/resources/maestro/maestro.test.ts @@ -0,0 +1,70 @@ +import { Maestro } from '../../../../src/resources/maestro/maestro'; +import { Beta } from '../../../../src/resources/maestro/beta'; +import { Runs } from '../../../../src/resources/maestro/runs'; +import { APIClient } from '../../../../src/APIClient'; + +class MockAPIClient extends APIClient { + public post = jest.fn(); + public get = jest.fn(); +} + +describe('Maestro', () => { + let maestro: Maestro; + let mockClient: MockAPIClient; + + beforeEach(() => { + mockClient = new MockAPIClient({ + baseURL: 'https://api.example.com', + maxRetries: 3, + timeout: 5000, + }); + + maestro = new Maestro(mockClient); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should initialize with a Runs instance', () => { + expect(maestro).toBeInstanceOf(Maestro); + expect(maestro.runs).toBeInstanceOf(Runs); + }); + + it('should share the same client with runs', () => { + expect(maestro.runs['client']).toBe(mockClient); + }); +}); + +describe('Beta', () => { + let beta: Beta; + let mockClient: MockAPIClient; + + beforeEach(() => { + mockClient = new MockAPIClient({ + baseURL: 'https://api.example.com', + maxRetries: 3, + timeout: 5000, + }); + + beta = new Beta(mockClient); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should initialize with a Maestro instance', () => { + expect(beta).toBeInstanceOf(Beta); + expect(beta.maestro).toBeInstanceOf(Maestro); + }); + + it('should have access to runs through maestro', () => { + expect(beta.maestro.runs).toBeInstanceOf(Runs); + }); + + it('should share the same client through the hierarchy', () => { + expect(beta.maestro['client']).toBe(mockClient); + expect(beta.maestro.runs['client']).toBe(mockClient); + }); +}); diff --git a/tests/unittests/resources/maestro/runs.test.ts b/tests/unittests/resources/maestro/runs.test.ts new file mode 100644 index 0000000..6fd0bd4 --- /dev/null +++ b/tests/unittests/resources/maestro/runs.test.ts @@ -0,0 +1,359 @@ +import * as Models from '../../../../src/types'; +import { Runs } from '../../../../src/resources/maestro/runs'; +import { APIClient } from '../../../../src/APIClient'; +import { AI21Error } from '../../../../src/errors'; + +class MockAPIClient extends APIClient { + public post = jest.fn(); + public get = jest.fn(); +} + +describe('Maestro Runs', () => { + let runs: Runs; + let mockClient: MockAPIClient; + + beforeEach(() => { + mockClient = new MockAPIClient({ + baseURL: 'https://api.example.com', + maxRetries: 3, + timeout: 5000, + }); + + runs = new Runs(mockClient); + jest.clearAllTimers(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.clearAllMocks(); + jest.runOnlyPendingTimers(); + jest.useRealTimers(); + }); + + describe('create', () => { + it('should create a maestro run with minimal required fields', async () => { + const body: Models.MaestroRunRequest = { + input: 'Write a summary of the latest AI developments', + }; + + const expectedResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'in_progress', + result: null, + data_sources: {}, + requirements_result: [], + }; + + mockClient.post.mockResolvedValue(expectedResponse); + + const response = await runs.create(body); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(response).toEqual(expectedResponse); + }); + + it('should create a maestro run with all optional fields', async () => { + const body: Models.MaestroRunRequest = { + input: [ + { role: 'user', content: 'What are the latest trends in AI?' }, + { role: 'assistant', content: 'I need more context to provide a comprehensive answer.' }, + { role: 'user', content: 'Focus on machine learning and natural language processing.' }, + ], + requirements: [ + { + name: 'accuracy', + description: 'Information should be accurate and up-to-date', + isMandatory: true, + }, + { name: 'completeness', description: 'Cover all major areas', isMandatory: false }, + ], + tools: ['web_search', 'file_search'], + tool_resources: { + file_search: { + file_ids: ['file_123', 'file_456'], + labels: ['ai', 'ml', 'nlp'], + }, + web_search: { + urls: ['https://arxiv.org', 'https://openai.com'], + }, + }, + models: ['jamba-large', 'gpt-4o'], + budget: 'high', + include: ['data_sources', 'requirements_result'], + response_language: 'english', + }; + + const expectedResponse: Models.MaestroRunResponse = { + id: 'run_456', + status: 'in_progress', + result: null, + data_sources: { + file_search: { + file_ids: ['file_123', 'file_456'], + labels: ['ai', 'ml', 'nlp'], + }, + web_search: { + urls: ['https://arxiv.org', 'https://openai.com'], + }, + }, + requirements_result: [ + { + score: 0.95, + finish_reason: 'completed', + requirements: { + name: 'accuracy', + description: 'Information should be accurate and up-to-date', + score: 0.95, + reason: 'All sources are recent and credible', + }, + }, + ], + }; + + mockClient.post.mockResolvedValue(expectedResponse); + + const response = await runs.create(body); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(response).toEqual(expectedResponse); + }); + + it('should handle errors thrown by the API client', async () => { + const body: Models.MaestroRunRequest = { + input: 'Test input', + }; + const error = new AI21Error(); + + mockClient.post.mockRejectedValue(error); + + await expect(runs.create(body)).rejects.toThrow(); + }); + }); + + describe('get', () => { + it('should get a maestro run by ID', async () => { + const runId = 'run_123'; + const expectedResponse: Models.MaestroRunResponse = { + id: runId, + status: 'completed', + result: 'Here is a comprehensive summary of the latest AI developments...', + data_sources: { + web_search: { + urls: ['https://arxiv.org', 'https://openai.com'], + }, + }, + requirements_result: [ + { + score: 0.92, + finish_reason: 'completed', + requirements: { + name: 'accuracy', + description: 'Information should be accurate and up-to-date', + score: 0.92, + reason: 'Sources are recent but some claims need verification', + }, + }, + ], + }; + + mockClient.get.mockResolvedValue(expectedResponse); + + const response = await runs.get(runId); + + expect(mockClient.get).toHaveBeenCalledWith(`/maestro/runs/${runId}`); + expect(response).toEqual(expectedResponse); + }); + + it('should handle errors when getting a run', async () => { + const runId = 'run_123'; + const error = new AI21Error(); + + mockClient.get.mockRejectedValue(error); + + await expect(runs.get(runId)).rejects.toThrow(); + }); + }); + + describe('create_and_poll', () => { + it('should create and poll until completion with default options', async () => { + const body: Models.MaestroRunRequest = { + input: 'Test input', + }; + + const createResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'in_progress', + result: null, + data_sources: {}, + requirements_result: [], + }; + + const completedResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'completed', + result: 'Task completed successfully', + data_sources: {}, + requirements_result: [], + }; + + mockClient.post.mockResolvedValue(createResponse); + mockClient.get.mockResolvedValue(completedResponse); + + const response = await runs.create_and_poll(body); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(mockClient.get).toHaveBeenCalledWith('/maestro/runs/run_123'); + expect(response).toEqual(completedResponse); + }); + + it('should create and poll with custom timeout and interval', async () => { + const body: Models.MaestroRunRequest = { + input: 'Test input', + }; + + const options: Models.MaestroRunRequestOptions = { + timeout: 60000, + interval: 2000, + }; + + const createResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'in_progress', + result: null, + data_sources: {}, + requirements_result: [], + }; + + const completedResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'completed', + result: 'Task completed successfully', + data_sources: {}, + requirements_result: [], + }; + + mockClient.post.mockResolvedValue(createResponse); + mockClient.get.mockResolvedValue(completedResponse); + + const response = await runs.create_and_poll(body, options); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(mockClient.get).toHaveBeenCalledWith('/maestro/runs/run_123'); + expect(response).toEqual(completedResponse); + }); + + it('should call create_and_poll with correct parameters', async () => { + const body: Models.MaestroRunRequest = { + input: 'Test input', + }; + + const options: Models.MaestroRunRequestOptions = { + timeout: 60000, + interval: 2000, + }; + + const createResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'in_progress', + result: null, + data_sources: {}, + requirements_result: [], + }; + + const completedResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'completed', + result: 'Task completed successfully', + data_sources: {}, + requirements_result: [], + }; + + mockClient.post.mockResolvedValue(createResponse); + mockClient.get.mockResolvedValue(completedResponse); + + const response = await runs.create_and_poll(body, options); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(mockClient.get).toHaveBeenCalledWith('/maestro/runs/run_123'); + expect(response).toEqual(completedResponse); + }); + + it('should handle creation errors', async () => { + const body: Models.MaestroRunRequest = { + input: 'Test input', + }; + + const error = new AI21Error(); + mockClient.post.mockRejectedValue(error); + + await expect(runs.create_and_poll(body)).rejects.toThrow(); + }); + + it('should handle polling errors', async () => { + const body: Models.MaestroRunRequest = { + input: 'Test input', + }; + + const createResponse: Models.MaestroRunResponse = { + id: 'run_123', + status: 'in_progress', + result: null, + data_sources: {}, + requirements_result: [], + }; + + const error = new AI21Error(); + mockClient.post.mockResolvedValue(createResponse); + mockClient.get.mockRejectedValue(error); + + await expect(runs.create_and_poll(body)).rejects.toThrow(); + }); + }); + + describe('edge cases', () => { + it('should handle string input type', async () => { + const body: Models.MaestroRunRequest = { + input: 'Simple string input for maestro run', + }; + + const expectedResponse: Models.MaestroRunResponse = { + id: 'run_789', + status: 'completed', + result: 'Response to string input', + data_sources: {}, + requirements_result: [], + }; + + mockClient.post.mockResolvedValue(expectedResponse); + + const response = await runs.create(body); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(response).toEqual(expectedResponse); + }); + + it('should handle array input type', async () => { + const body: Models.MaestroRunRequest = { + input: [ + { role: 'user', content: 'Hello' }, + { role: 'assistant', content: 'Hi there!' }, + ], + }; + + const expectedResponse: Models.MaestroRunResponse = { + id: 'run_789', + status: 'completed', + result: 'Response to array input', + data_sources: {}, + requirements_result: [], + }; + + mockClient.post.mockResolvedValue(expectedResponse); + + const response = await runs.create(body); + + expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); + expect(response).toEqual(expectedResponse); + }); + }); +}); diff --git a/tests/unittests/resources/rag-engine.test.ts b/tests/unittests/resources/rag-engine.test.ts index 88b2dc1..4bcc44d 100644 --- a/tests/unittests/resources/rag-engine.test.ts +++ b/tests/unittests/resources/rag-engine.test.ts @@ -1,5 +1,5 @@ import * as Models from '../../../src/types'; -import { Files } from '../../../src/resources/files/files'; +import { Files } from '../../../src/resources/library/files'; import { APIClient } from '../../../src/APIClient'; class MockAPIClient extends APIClient { From 4b94d953fa80ba7b0b877c94e88f2bdc8d5201a6 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Tue, 16 Sep 2025 14:47:53 +0300 Subject: [PATCH 04/10] feat: added readme + fixes following comments --- README.md | 186 ++++++++++++++++-- .../maestro/maestro-run-create-and-poll.ts | 13 +- src/Constants.ts | 1 + src/errors.ts | 6 + src/resources/chat/completions.ts | 2 +- src/resources/maestro/runs.ts | 6 +- src/types/chat/ChatModel.ts | 8 +- src/types/maestro/MaestroRunRequest.ts | 10 +- 8 files changed, 198 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index b841004..6d75147 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ The AI21 API Client is a TypeScript library that provides a convenient interface - [Examples](#examples-tldr) 🗂️ - [AI21 Official Documentation](#Documentation) - [Chat](#Chat) +- [Maestro (Beta)](#Maestro) - [Conversational RAG (Beta)](#Conversational-RAG) -- [Files](#Files) - +- [Library](#Library) ## Environment Support @@ -32,7 +32,7 @@ This client supports both Node.js and browser environments: // Browser usage example const client = new AI21({ apiKey: process.env.AI21_API_KEY, // or pass it in directly - dangerouslyAllowBrowser: true // Required for browser environments + dangerouslyAllowBrowser: true, // Required for browser environments }); ``` @@ -64,7 +64,6 @@ Feel free to dive in, experiment, and adapt these examples to suit your needs. W The full documentation for the REST API can be found on [docs.ai21.com](https://docs.ai21.com/). - ## Chat To use the AI21 API Client, you'll need to have an API key. You can obtain an API key by signing up for an account on the AI21 website. @@ -82,7 +81,9 @@ const client = new AI21({ const response = await client.chat.completions.create({ model: 'jamba-mini', - messages: [{ role: 'user', content: 'Hello, how are you? tell me a 100 line story about a cat named "Fluffy"' }], + messages: [ + { role: 'user', content: 'Hello, how are you? tell me a 100 line story about a cat named "Fluffy"' }, + ], }); console.log(response); @@ -105,12 +106,121 @@ for await (const chunk of streamResponse) { console.log(chunk.choices[0]?.delta?.content || ''); } ``` + --- -### Files +## Maestro (Beta) -The `AI21` class provides a `files` property that gives you access to the Files API. You can use it to upload, retrieve, update, list, and delete files. +AI21 Maestro is an advanced AI orchestration platform that can intelligently use tools and manage complex workflows. The `AI21` class provides a `beta.maestro` property that gives you access to the Maestro API. + +### Basic Usage + +```typescript +import { AI21 } from 'ai21'; + +const client = new AI21({ + apiKey: process.env.AI21_API_KEY, +}); + +// Create a maestro run +const run = await client.beta.maestro.runs.create({ + input: 'Analyze the latest market trends in renewable energy', +}); + +// Get the run status +const result = await client.beta.maestro.runs.get(run.id); +console.log(result); +``` + +### Create and Poll (Recommended) + +For convenience, you can use `create_and_poll()` which automatically waits for completion: + +```typescript +const result = await client.beta.maestro.runs.create_and_poll( + { + input: 'Write a comprehensive report on AI trends in 2024', + tools: ['web_search'], + budget: 'medium', + }, + { + timeout: 30000, // 30 seconds + interval: 2000, // Poll every 2 seconds + }, +); + +console.log(result.result); +``` + +### Advanced Features + +Maestro supports various advanced configurations: + +```typescript +const advancedRun = await client.beta.maestro.runs.create_and_poll({ + input: 'Research sustainable energy solutions', + + // Specify tools to use + tools: ['web_search', 'file_search'], + + // Configure tool resources + tool_resources: { + web_search: { + urls: ['https://example.com', 'https://research.org'], + }, + file_search: { + file_ids: ['file-123', 'file-456'], + labels: ['research', 'energy'], + }, + }, + + // Define specific requirements + requirements: [ + { + name: 'Data Sources', + description: 'Include at least 3 credible sources', + isMandatory: true, + }, + { + name: 'Length', + description: 'Report should be 1000-2000 words', + isMandatory: false, + }, + ], + + // Specify models to use + models: ['jamba-large'], + + // Control resource allocation + budget: 'high', + + // Request additional fields in response + include: ['data_sources', 'requirements_result'], + + // Set response language + response_language: 'english', +}); +``` + +### Structured Input messages + +You can also provide structured input messages: + +```typescript +const structuredRun = await client.beta.maestro.runs.create({ + input: [ + { role: 'system', content: 'You are a research assistant specializing in technology trends.' }, + { role: 'user', content: 'What are the emerging AI technologies in healthcare?' }, + ], + tools: ['web_search'], +}); +``` + +--- + +### Files +The `AI21` class provides a `files` property that gives you access to the Files API. You can use it to upload, retrieve, update, list, and delete files. ```typescript import { AI21 } from 'ai21'; @@ -120,23 +230,20 @@ const client = new AI21({ }); const fileUploadResponse = await client.files.create({ - file: './articles/article1.pdf', - labels: ['science', 'biology'], - path: 'virtual-path/to/science-articles', + file: './articles/article1.pdf', + labels: ['science', 'biology'], + path: 'virtual-path/to/science-articles', }); - const file = await client.files.get(fileUploadResponse.fileId); - ``` --- -### Conversational-RAG +### Conversational-RAG The `AI21` class provides a `conversationalRag` property that gives you access to the Conversational RAG API. You can use it to ask questions that are answered based on the files you uploaded. - ```typescript import { AI21 } from 'ai21'; @@ -145,11 +252,56 @@ const client = new AI21({ }); const convRagResponse = await client.conversationalRag.create({ - messages: [{ role: 'user', content: 'This question presumes that the answer can be found within the uploaded files.' }], - }); - + messages: [ + { + role: 'user', + content: 'This question presumes that the answer can be found within the uploaded files.', + }, + ], +}); ``` +--- + +## Library + +The `AI21` class provides a `library` property that gives you access to the Library Files API. This is a separate file management system designed for library-specific operations. + +### Library Files Management + +```typescript +import { AI21 } from 'ai21'; + +const client = new AI21({ + apiKey: process.env.AI21_API_KEY, +}); + +// Upload a file to the library +const libraryFile = await client.library.files.create({ + file: './documents/research-paper.pdf', + labels: ['research', 'academic'], + path: 'library/research/papers', +}); + +// Get a library file +const file = await client.library.files.get(libraryFile.fileId); + +// List library files with filters +const files = await client.library.files.list({ + labels: ['research'], + path: 'library/research', +}); + +// Update a library file +await client.library.files.update({ + fileId: libraryFile.fileId, + labels: ['research', 'academic', 'updated'], + path: 'library/research/updated-papers', +}); + +// Delete a library file +await client.library.files.delete(libraryFile.fileId); +``` ## Configuration diff --git a/examples/studio/maestro/maestro-run-create-and-poll.ts b/examples/studio/maestro/maestro-run-create-and-poll.ts index 905f234..209fc30 100644 --- a/examples/studio/maestro/maestro-run-create-and-poll.ts +++ b/examples/studio/maestro/maestro-run-create-and-poll.ts @@ -8,7 +8,18 @@ async function main() { const response = await client.beta.maestro.runs.create_and_poll( { - input: 'Hello, how are you? tell me a short story about a wizard', + input: 'Write a poem about the ocean', + requirements: [ + { + name: 'length requirement', + description: 'The length of the poem should be less than 1000 characters', + }, + { + name: 'rhyme requirement', + description: 'The poem should rhyme', + }, + ], + include: ['requirements_result'], }, { timeout: TIMEOUT, diff --git a/src/Constants.ts b/src/Constants.ts index 73e0baf..a244cc1 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -1,2 +1,3 @@ export const STUDIO_BASE_URL = 'https://api.ai21.com/studio/v1'; export const DEFAULT_TIMEOUT = 60000; +export const DEFAULT_INTERVAL = 1000; diff --git a/src/errors.ts b/src/errors.ts index 8325294..ea9d872 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -11,3 +11,9 @@ export class StreamingDecodeError extends Error { super(`Failed to decode chunk: ${chunk}`); } } + +export class TimeoutError extends Error { + constructor(message: string, timeout: number) { + super(`Timeout: ${message} timed out after ${timeout}ms`); + } +} diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts index 7d41761..7e115a4 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions.ts @@ -2,7 +2,7 @@ import * as Models from '../../types'; import { APIResource } from '../../APIResource'; import { Stream } from '../../streaming'; -const deprecatedModels = ['jamba-1.6-mini', 'jamba-1.6-large']; +const deprecatedModels = ['jamba-mini-1.6', 'jamba-large-1.6']; export class Completions extends APIResource { create( diff --git a/src/resources/maestro/runs.ts b/src/resources/maestro/runs.ts index 9f05bfd..7d1defe 100644 --- a/src/resources/maestro/runs.ts +++ b/src/resources/maestro/runs.ts @@ -1,9 +1,9 @@ +import { TimeoutError } from '../../errors'; import { APIResource } from '../../APIResource'; import { MaestroRunRequest, MaestroRunResponse, RequestOptions, MaestroRunRequestOptions } from '../../types'; +import { DEFAULT_INTERVAL, DEFAULT_TIMEOUT } from '../../Constants'; const MAESTRO_PATH = '/maestro/runs'; -const DEFAULT_TIMEOUT = 30000; -const DEFAULT_INTERVAL = 1000; export class Runs extends APIResource { async create(body: MaestroRunRequest): Promise { @@ -38,7 +38,7 @@ export class Runs extends APIResource { await new Promise((resolve) => setTimeout(resolve, interval)); } - throw new Error(`Maestro run ${runId} timed out after ${timeout}ms`); + throw new TimeoutError(`Maestro run ${runId}`, timeout); } async create_and_poll( diff --git a/src/types/chat/ChatModel.ts b/src/types/chat/ChatModel.ts index 7f5d276..6095f3f 100644 --- a/src/types/chat/ChatModel.ts +++ b/src/types/chat/ChatModel.ts @@ -1,7 +1 @@ -export type ChatModel = - | 'jamba-mini' - | 'jamba-large' - | 'jamba-large-1.6-2025-03' - | 'jamba-mini-1.6-2025-03' - | 'jamba-large-1.6' - | 'jamba-mini-1.6'; +export type ChatModel = 'jamba-mini' | 'jamba-large'; diff --git a/src/types/maestro/MaestroRunRequest.ts b/src/types/maestro/MaestroRunRequest.ts index d48e369..aaf1911 100644 --- a/src/types/maestro/MaestroRunRequest.ts +++ b/src/types/maestro/MaestroRunRequest.ts @@ -40,13 +40,13 @@ export type MaestroToolResources = { type MaestroRunFirstPartyModel = 'jamba-mini' | 'jamba-large'; -type MaestroRunManagedThirdPartyModel = 'gpt-4o' | 'mistral-7b' | 'mistral-8x7b' | 'mistral-small'; +type MaestroRunManagedThirdPartyModel = string; type MaestroRunModel = MaestroRunFirstPartyModel | MaestroRunManagedThirdPartyModel; type MaestroRunBudget = 'low' | 'medium' | 'high'; -type MaestroRunIncludeFields = 'data_sources' | 'requirements_result'; +type MaestroRunIncludeFields = 'data_sources' | 'requirements_result' | string; type MaestroRunResponseLanguage = | 'arabic' @@ -57,7 +57,8 @@ type MaestroRunResponseLanguage = | 'hebrew' | 'italian' | 'portuguese' - | 'spanish'; + | 'spanish' + | string; export interface MaestroRunRequest { /* @@ -66,7 +67,6 @@ export interface MaestroRunRequest { input: MaestroRunInput; /* The requirements for the maestro run. Maximum 10 requirements. - Works only if no tools are selected. */ requirements?: MaestroRunRequirement[]; /* @@ -98,4 +98,4 @@ export interface MaestroRunRequest { export interface MaestroRunRequestOptions { timeout?: number; interval?: number; -} \ No newline at end of file +} From 53ceb56f6c93394b6fc1b73628bb67788b76ab3d Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Tue, 16 Sep 2025 16:20:49 +0300 Subject: [PATCH 05/10] feat: added new tools --- README.md | 6 +-- .../maestro/maestro-run-create-and-poll.ts | 2 +- src/resources/maestro/runs.ts | 2 +- src/types/maestro/MaestroRunRequest.ts | 4 +- src/types/maestro/MaestroTools.ts | 47 +++++++++++++++++++ .../unittests/resources/maestro/runs.test.ts | 42 +++++++++++++---- 6 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 src/types/maestro/MaestroTools.ts diff --git a/README.md b/README.md index 6d75147..167242c 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,10 @@ console.log(result); ### Create and Poll (Recommended) -For convenience, you can use `create_and_poll()` which automatically waits for completion: +For convenience, you can use `createAndPoll()` which automatically waits for completion: ```typescript -const result = await client.beta.maestro.runs.create_and_poll( +const result = await client.beta.maestro.runs.createAndPoll( { input: 'Write a comprehensive report on AI trends in 2024', tools: ['web_search'], @@ -157,7 +157,7 @@ console.log(result.result); Maestro supports various advanced configurations: ```typescript -const advancedRun = await client.beta.maestro.runs.create_and_poll({ +const advancedRun = await client.beta.maestro.runs.createAndPoll({ input: 'Research sustainable energy solutions', // Specify tools to use diff --git a/examples/studio/maestro/maestro-run-create-and-poll.ts b/examples/studio/maestro/maestro-run-create-and-poll.ts index 209fc30..7180ce1 100644 --- a/examples/studio/maestro/maestro-run-create-and-poll.ts +++ b/examples/studio/maestro/maestro-run-create-and-poll.ts @@ -6,7 +6,7 @@ const INTERVAL = 1500; async function main() { const client = new AI21({ apiKey: process.env.AI21_API_KEY }); - const response = await client.beta.maestro.runs.create_and_poll( + const response = await client.beta.maestro.runs.createAndPoll( { input: 'Write a poem about the ocean', requirements: [ diff --git a/src/resources/maestro/runs.ts b/src/resources/maestro/runs.ts index 7d1defe..96956d5 100644 --- a/src/resources/maestro/runs.ts +++ b/src/resources/maestro/runs.ts @@ -41,7 +41,7 @@ export class Runs extends APIResource { throw new TimeoutError(`Maestro run ${runId}`, timeout); } - async create_and_poll( + async createAndPoll( body: MaestroRunRequest, options?: MaestroRunRequestOptions, ): Promise { diff --git a/src/types/maestro/MaestroRunRequest.ts b/src/types/maestro/MaestroRunRequest.ts index aaf1911..d4dde42 100644 --- a/src/types/maestro/MaestroRunRequest.ts +++ b/src/types/maestro/MaestroRunRequest.ts @@ -1,3 +1,5 @@ +import { FileSearchTool, HttpTool, MCPTool, WebSearchTool } from './MaestroTools'; + type MaestroRunInputObject = { role: string; content: string; @@ -11,7 +13,7 @@ type MaestroRunRequirement = { isMandatory?: boolean; }; -type MaestroRunTool = 'file_search' | 'web_search'; +type MaestroRunTool = HttpTool | MCPTool | FileSearchTool | WebSearchTool; export type MaestroToolResources = { /* diff --git a/src/types/maestro/MaestroTools.ts b/src/types/maestro/MaestroTools.ts new file mode 100644 index 0000000..4ab5db3 --- /dev/null +++ b/src/types/maestro/MaestroTools.ts @@ -0,0 +1,47 @@ +interface HttpToolFunctionParametersProperty { + type: string; + description: string; +} + +interface HttpToolFunctionParameters { + type: 'object'; + properties: Record; + required: string[]; + additional_properties?: boolean; +} + +interface HttpToolFunction { + name: string; + description: string; + parameters: HttpToolFunctionParameters; +} + +interface HttpToolEndpoint { + url: string; + headers?: Record; +} + +export interface HttpTool { + type: 'http'; + function: HttpToolFunction; + endpoint: HttpToolEndpoint; +} + +export interface MCPTool { + type: 'mcp'; + server_label: string; + server_url: string; + headers?: Record; + allowed_tools?: string[]; +} + +export interface FileSearchTool { + type: 'file_search'; + file_ids?: string[]; + labels?: string[]; +} + +export interface WebSearchTool { + type: 'web_search'; + urls?: string[]; +} diff --git a/tests/unittests/resources/maestro/runs.test.ts b/tests/unittests/resources/maestro/runs.test.ts index 6fd0bd4..e53b0ca 100644 --- a/tests/unittests/resources/maestro/runs.test.ts +++ b/tests/unittests/resources/maestro/runs.test.ts @@ -67,7 +67,33 @@ describe('Maestro Runs', () => { }, { name: 'completeness', description: 'Cover all major areas', isMandatory: false }, ], - tools: ['web_search', 'file_search'], + tools: [ + { type: 'web_search', urls: ['https://arxiv.org', 'https://openai.com'] }, + { type: 'file_search', file_ids: ['file_123', 'file_456'], labels: ['ai', 'ml', 'nlp'] }, + { + type: 'http', + function: { + name: 'get_weather', + description: 'Get the weather for a given city', + parameters: { + type: 'object', + properties: { city: { type: 'string', description: 'The city to get the weather for' } }, + required: ['city'], + }, + }, + endpoint: { + url: 'https://api.openweathermap.org/data/2.5/weather', + headers: { Authorization: 'Bearer 1234567890' }, + }, + }, + { + type: 'mcp', + server_label: 'openai', + server_url: 'https://my-mcp-server.com', + headers: { Authorization: 'Bearer 1234567890' }, + allowed_tools: ['get_weather'], + }, + ], tool_resources: { file_search: { file_ids: ['file_123', 'file_456'], @@ -174,7 +200,7 @@ describe('Maestro Runs', () => { }); }); - describe('create_and_poll', () => { + describe('createAndPoll', () => { it('should create and poll until completion with default options', async () => { const body: Models.MaestroRunRequest = { input: 'Test input', @@ -199,7 +225,7 @@ describe('Maestro Runs', () => { mockClient.post.mockResolvedValue(createResponse); mockClient.get.mockResolvedValue(completedResponse); - const response = await runs.create_and_poll(body); + const response = await runs.createAndPoll(body); expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); expect(mockClient.get).toHaveBeenCalledWith('/maestro/runs/run_123'); @@ -235,14 +261,14 @@ describe('Maestro Runs', () => { mockClient.post.mockResolvedValue(createResponse); mockClient.get.mockResolvedValue(completedResponse); - const response = await runs.create_and_poll(body, options); + const response = await runs.createAndPoll(body, options); expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); expect(mockClient.get).toHaveBeenCalledWith('/maestro/runs/run_123'); expect(response).toEqual(completedResponse); }); - it('should call create_and_poll with correct parameters', async () => { + it('should call createAndPoll with correct parameters', async () => { const body: Models.MaestroRunRequest = { input: 'Test input', }; @@ -271,7 +297,7 @@ describe('Maestro Runs', () => { mockClient.post.mockResolvedValue(createResponse); mockClient.get.mockResolvedValue(completedResponse); - const response = await runs.create_and_poll(body, options); + const response = await runs.createAndPoll(body, options); expect(mockClient.post).toHaveBeenCalledWith('/maestro/runs', { body }); expect(mockClient.get).toHaveBeenCalledWith('/maestro/runs/run_123'); @@ -286,7 +312,7 @@ describe('Maestro Runs', () => { const error = new AI21Error(); mockClient.post.mockRejectedValue(error); - await expect(runs.create_and_poll(body)).rejects.toThrow(); + await expect(runs.createAndPoll(body)).rejects.toThrow(); }); it('should handle polling errors', async () => { @@ -306,7 +332,7 @@ describe('Maestro Runs', () => { mockClient.post.mockResolvedValue(createResponse); mockClient.get.mockRejectedValue(error); - await expect(runs.create_and_poll(body)).rejects.toThrow(); + await expect(runs.createAndPoll(body)).rejects.toThrow(); }); }); From 584012f539dc81f3cd925c2ba24a4899ee9a3182 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Wed, 17 Sep 2025 12:22:12 +0300 Subject: [PATCH 06/10] feat: review --- src/resources/maestro/runs.ts | 3 +- src/types/maestro/MaestroRunRequest.ts | 32 ++----------------- src/types/maestro/MaestroRunResponse.ts | 11 +++++-- src/types/maestro/MaestroTools.ts | 7 +++- .../unittests/resources/maestro/runs.test.ts | 12 ++----- 5 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/resources/maestro/runs.ts b/src/resources/maestro/runs.ts index 96956d5..06e8ba9 100644 --- a/src/resources/maestro/runs.ts +++ b/src/resources/maestro/runs.ts @@ -4,6 +4,7 @@ import { MaestroRunRequest, MaestroRunResponse, RequestOptions, MaestroRunReques import { DEFAULT_INTERVAL, DEFAULT_TIMEOUT } from '../../Constants'; const MAESTRO_PATH = '/maestro/runs'; +const MAESTRO_TERMINATED_RUN_STATUSES = ['completed', 'failed', 'requires_action']; export class Runs extends APIResource { async create(body: MaestroRunRequest): Promise { @@ -31,7 +32,7 @@ export class Runs extends APIResource { while (Date.now() - startTime < timeout) { const response = await this.get(runId); - if (response.status === 'completed') { + if (MAESTRO_TERMINATED_RUN_STATUSES.includes(response.status)) { return response; } diff --git a/src/types/maestro/MaestroRunRequest.ts b/src/types/maestro/MaestroRunRequest.ts index d4dde42..eb0a4c5 100644 --- a/src/types/maestro/MaestroRunRequest.ts +++ b/src/types/maestro/MaestroRunRequest.ts @@ -15,31 +15,6 @@ type MaestroRunRequirement = { type MaestroRunTool = HttpTool | MCPTool | FileSearchTool | WebSearchTool; -export type MaestroToolResources = { - /* - When provided, this object defines filters that AI21 Maestro will apply whenever it performs a file search. - */ - file_search?: { - /* - Restrict file search to these file IDs. - */ - file_ids?: string[]; - /* - Restrict file search to files with these labels. - */ - labels?: string[]; - }; - /* - When provided, this object defines filters that AI21 Maestro will apply whenever it performs a web search. - */ - web_search?: { - /* - Restrict web search to the specified URL prefixes. - */ - urls: string[]; - }; -}; - type MaestroRunFirstPartyModel = 'jamba-mini' | 'jamba-large'; type MaestroRunManagedThirdPartyModel = string; @@ -50,7 +25,7 @@ type MaestroRunBudget = 'low' | 'medium' | 'high'; type MaestroRunIncludeFields = 'data_sources' | 'requirements_result' | string; -type MaestroRunResponseLanguage = +export type MaestroRunResponseLanguage = | 'arabic' | 'dutch' | 'english' @@ -60,6 +35,7 @@ type MaestroRunResponseLanguage = | 'italian' | 'portuguese' | 'spanish' + | 'unset' | string; export interface MaestroRunRequest { @@ -76,10 +52,6 @@ export interface MaestroRunRequest { */ tools?: MaestroRunTool[]; /* - A set of resources used by AI21 Maestro’s tools. - */ - tool_resources?: MaestroToolResources; - /* The models to use for the maestro run. */ models?: MaestroRunModel[]; diff --git a/src/types/maestro/MaestroRunResponse.ts b/src/types/maestro/MaestroRunResponse.ts index 203c9de..ac923ac 100644 --- a/src/types/maestro/MaestroRunResponse.ts +++ b/src/types/maestro/MaestroRunResponse.ts @@ -1,6 +1,6 @@ -import { MaestroToolResources } from './MaestroRunRequest'; +import { FileSearchTool, WebSearchTool } from './MaestroTools'; -type MaestroRunResponseStatus = 'completed' | 'failed' | 'in_progress'; +type MaestroRunResponseStatus = 'completed' | 'failed' | 'in_progress' | 'requires_action'; type MaestroRunRequirementResult = { score: number; @@ -13,6 +13,11 @@ type MaestroRunRequirementResult = { }; }; +type DataSources = { + file_search?: FileSearchTool; + web_search?: WebSearchTool; +}; + export interface MaestroRunResponse { /* The ID of the maestro run for polling the status. @@ -26,7 +31,7 @@ export interface MaestroRunResponse { /* Specifies the data sources used to retrieve contextual information for a run. */ - data_sources: MaestroToolResources; + data_sources: DataSources; /* Detailed results for each requirement. */ diff --git a/src/types/maestro/MaestroTools.ts b/src/types/maestro/MaestroTools.ts index 4ab5db3..ad5a3ba 100644 --- a/src/types/maestro/MaestroTools.ts +++ b/src/types/maestro/MaestroTools.ts @@ -37,8 +37,13 @@ export interface MCPTool { export interface FileSearchTool { type: 'file_search'; - file_ids?: string[]; + retrieval_similarity_threshold?: number; labels?: string[]; + labels_filter_mode?: 'AND' | 'OR'; + labels_filter?: Record; + file_ids?: string[]; + retrieval_strategy?: string; + max_neighbors?: number; } export interface WebSearchTool { diff --git a/tests/unittests/resources/maestro/runs.test.ts b/tests/unittests/resources/maestro/runs.test.ts index e53b0ca..df8b2c8 100644 --- a/tests/unittests/resources/maestro/runs.test.ts +++ b/tests/unittests/resources/maestro/runs.test.ts @@ -94,15 +94,6 @@ describe('Maestro Runs', () => { allowed_tools: ['get_weather'], }, ], - tool_resources: { - file_search: { - file_ids: ['file_123', 'file_456'], - labels: ['ai', 'ml', 'nlp'], - }, - web_search: { - urls: ['https://arxiv.org', 'https://openai.com'], - }, - }, models: ['jamba-large', 'gpt-4o'], budget: 'high', include: ['data_sources', 'requirements_result'], @@ -115,10 +106,12 @@ describe('Maestro Runs', () => { result: null, data_sources: { file_search: { + type: 'file_search', file_ids: ['file_123', 'file_456'], labels: ['ai', 'ml', 'nlp'], }, web_search: { + type: 'web_search', urls: ['https://arxiv.org', 'https://openai.com'], }, }, @@ -165,6 +158,7 @@ describe('Maestro Runs', () => { result: 'Here is a comprehensive summary of the latest AI developments...', data_sources: { web_search: { + type: 'web_search', urls: ['https://arxiv.org', 'https://openai.com'], }, }, From 2c972248af633470604ee71d6f1cb3119d0fd4e2 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Wed, 17 Sep 2025 12:47:13 +0300 Subject: [PATCH 07/10] feat: trigger quality on push --- .github/workflows/quality-checks.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 9117e41..4a40a4b 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -6,6 +6,7 @@ concurrency: cancel-in-progress: true on: pull_request: + push: jobs: quality-checks: runs-on: ubuntu-20.04 @@ -19,11 +20,9 @@ jobs: with: node-version: 20.18.0 cache: 'npm' - + - name: Install dependencies run: npm install - + - name: Run quality checks run: npm run quality - - \ No newline at end of file From a03d6b6e65246b36ed7b89bc87533ec0c3b109da Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Wed, 17 Sep 2025 12:53:32 +0300 Subject: [PATCH 08/10] feat: trigger quality on push --- .github/workflows/quality-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 4a40a4b..6f453b9 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -9,7 +9,7 @@ on: push: jobs: quality-checks: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout From 61542a08bb3fc765384e958106e8ac61f4192c19 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Wed, 17 Sep 2025 13:08:22 +0300 Subject: [PATCH 09/10] feat: readme --- README.md | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 167242c..2b7718d 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ For convenience, you can use `createAndPoll()` which automatically waits for com const result = await client.beta.maestro.runs.createAndPoll( { input: 'Write a comprehensive report on AI trends in 2024', - tools: ['web_search'], + tools: [{ type: 'web_search' }], budget: 'medium', }, { @@ -161,18 +161,17 @@ const advancedRun = await client.beta.maestro.runs.createAndPoll({ input: 'Research sustainable energy solutions', // Specify tools to use - tools: ['web_search', 'file_search'], - - // Configure tool resources - tool_resources: { - web_search: { + tools: [ + { + type: 'web_search', urls: ['https://example.com', 'https://research.org'], }, - file_search: { + { + type: 'file_search', file_ids: ['file-123', 'file-456'], labels: ['research', 'energy'], }, - }, + ], // Define specific requirements requirements: [ @@ -212,35 +211,13 @@ const structuredRun = await client.beta.maestro.runs.create({ { role: 'system', content: 'You are a research assistant specializing in technology trends.' }, { role: 'user', content: 'What are the emerging AI technologies in healthcare?' }, ], - tools: ['web_search'], -}); -``` - ---- - -### Files - -The `AI21` class provides a `files` property that gives you access to the Files API. You can use it to upload, retrieve, update, list, and delete files. - -```typescript -import { AI21 } from 'ai21'; - -const client = new AI21({ - apiKey: process.env.AI21_API_KEY, // or pass it in directly + tools: [{ type: 'web_search' }], }); - -const fileUploadResponse = await client.files.create({ - file: './articles/article1.pdf', - labels: ['science', 'biology'], - path: 'virtual-path/to/science-articles', -}); - -const file = await client.files.get(fileUploadResponse.fileId); ``` --- -### Conversational-RAG +## Conversational RAG (Beta) The `AI21` class provides a `conversationalRag` property that gives you access to the Conversational RAG API. You can use it to ask questions that are answered based on the files you uploaded. From 1e341aa585f34dbf072262ef702060e3478810b1 Mon Sep 17 00:00:00 2001 From: Michael Arbib Date: Wed, 17 Sep 2025 20:48:34 +0300 Subject: [PATCH 10/10] fix: request / response types --- src/index.ts | 5 +- src/types/maestro/MaestroRunResponse.ts | 36 +++++-- .../unittests/resources/maestro/runs.test.ts | 102 +++++++++++------- 3 files changed, 94 insertions(+), 49 deletions(-) diff --git a/src/index.ts b/src/index.ts index 17219f8..e30fa63 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,10 +44,13 @@ export { type ListFilesFilters, type UpdateFileRequest, type FilePathOrFileObject, + type MaestroRunRequest, + type MaestroRunResponse, + type MaestroRunRequestOptions, } from './types'; export { APIClient } from './APIClient'; export { AI21Error, MissingAPIKeyError } from './errors'; export { Stream } from './streaming'; export { APIResource } from './APIResource'; -export { Chat, Completions, ConversationalRag, Library } from './resources'; +export { Chat, Completions, ConversationalRag, Library, Maestro } from './resources'; export { isBrowser, isNode } from './runtime'; diff --git a/src/types/maestro/MaestroRunResponse.ts b/src/types/maestro/MaestroRunResponse.ts index ac923ac..33d28fd 100644 --- a/src/types/maestro/MaestroRunResponse.ts +++ b/src/types/maestro/MaestroRunResponse.ts @@ -1,21 +1,35 @@ -import { FileSearchTool, WebSearchTool } from './MaestroTools'; - type MaestroRunResponseStatus = 'completed' | 'failed' | 'in_progress' | 'requires_action'; +export type MaestroRunRequirement = { + name: string; + description: string; + score: number; + reason: string; +}; + type MaestroRunRequirementResult = { score: number; finish_reason: string | null; - requirements: { - name: string | null; - description: string | null; - score: number | null; - reason: string | null; - }; + requirements: MaestroRunRequirement[]; +}; + +type FileSearchResult = { + text?: string; + file_id: string; + file_name: string; + score: number; + order: number; +}; + +type WebSearchResult = { + url: string; + score: number; + text: string; }; type DataSources = { - file_search?: FileSearchTool; - web_search?: WebSearchTool; + file_search?: FileSearchResult[]; + web_search?: WebSearchResult[]; }; export interface MaestroRunResponse { @@ -35,5 +49,5 @@ export interface MaestroRunResponse { /* Detailed results for each requirement. */ - requirements_result: MaestroRunRequirementResult[]; + requirements_result: MaestroRunRequirementResult; } diff --git a/tests/unittests/resources/maestro/runs.test.ts b/tests/unittests/resources/maestro/runs.test.ts index df8b2c8..bafe536 100644 --- a/tests/unittests/resources/maestro/runs.test.ts +++ b/tests/unittests/resources/maestro/runs.test.ts @@ -30,6 +30,19 @@ describe('Maestro Runs', () => { jest.useRealTimers(); }); + const defaultRequirementsResult = { + score: 0, + finish_reason: null, + requirements: [ + { + name: 'accuracy', + description: 'Information should be accurate and up-to-date', + score: 0, + reason: 'All sources are recent and credible', + }, + ], + }; + describe('create', () => { it('should create a maestro run with minimal required fields', async () => { const body: Models.MaestroRunRequest = { @@ -41,7 +54,7 @@ describe('Maestro Runs', () => { status: 'in_progress', result: null, data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; mockClient.post.mockResolvedValue(expectedResponse); @@ -105,28 +118,40 @@ describe('Maestro Runs', () => { status: 'in_progress', result: null, data_sources: { - file_search: { - type: 'file_search', - file_ids: ['file_123', 'file_456'], - labels: ['ai', 'ml', 'nlp'], - }, - web_search: { - type: 'web_search', - urls: ['https://arxiv.org', 'https://openai.com'], - }, + file_search: [ + { + file_id: 'file_123', + file_name: 'file_123.txt', + score: 0.92, + order: 1, + }, + { + file_id: 'file_456', + file_name: 'file_456.txt', + score: 0.92, + order: 2, + }, + ], + web_search: [ + { + url: 'https://arxiv.org', + score: 0.92, + text: 'Here is a comprehensive summary of the latest AI developments...', + }, + ], }, - requirements_result: [ - { - score: 0.95, - finish_reason: 'completed', - requirements: { + requirements_result: { + score: 0.95, + finish_reason: 'completed', + requirements: [ + { name: 'accuracy', description: 'Information should be accurate and up-to-date', score: 0.95, reason: 'All sources are recent and credible', }, - }, - ], + ], + }, }; mockClient.post.mockResolvedValue(expectedResponse); @@ -157,23 +182,26 @@ describe('Maestro Runs', () => { status: 'completed', result: 'Here is a comprehensive summary of the latest AI developments...', data_sources: { - web_search: { - type: 'web_search', - urls: ['https://arxiv.org', 'https://openai.com'], - }, + web_search: [ + { + score: 0.92, + text: 'Here is a comprehensive summary of the latest AI developments...', + url: 'https://arxiv.org', + }, + ], }, - requirements_result: [ - { - score: 0.92, - finish_reason: 'completed', - requirements: { + requirements_result: { + score: 0.92, + finish_reason: 'completed', + requirements: [ + { name: 'accuracy', description: 'Information should be accurate and up-to-date', score: 0.92, reason: 'Sources are recent but some claims need verification', }, - }, - ], + ], + }, }; mockClient.get.mockResolvedValue(expectedResponse); @@ -205,7 +233,7 @@ describe('Maestro Runs', () => { status: 'in_progress', result: null, data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; const completedResponse: Models.MaestroRunResponse = { @@ -213,7 +241,7 @@ describe('Maestro Runs', () => { status: 'completed', result: 'Task completed successfully', data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; mockClient.post.mockResolvedValue(createResponse); @@ -241,7 +269,7 @@ describe('Maestro Runs', () => { status: 'in_progress', result: null, data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; const completedResponse: Models.MaestroRunResponse = { @@ -249,7 +277,7 @@ describe('Maestro Runs', () => { status: 'completed', result: 'Task completed successfully', data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; mockClient.post.mockResolvedValue(createResponse); @@ -277,7 +305,7 @@ describe('Maestro Runs', () => { status: 'in_progress', result: null, data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; const completedResponse: Models.MaestroRunResponse = { @@ -285,7 +313,7 @@ describe('Maestro Runs', () => { status: 'completed', result: 'Task completed successfully', data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; mockClient.post.mockResolvedValue(createResponse); @@ -319,7 +347,7 @@ describe('Maestro Runs', () => { status: 'in_progress', result: null, data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; const error = new AI21Error(); @@ -341,7 +369,7 @@ describe('Maestro Runs', () => { status: 'completed', result: 'Response to string input', data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; mockClient.post.mockResolvedValue(expectedResponse); @@ -365,7 +393,7 @@ describe('Maestro Runs', () => { status: 'completed', result: 'Response to array input', data_sources: {}, - requirements_result: [], + requirements_result: defaultRequirementsResult, }; mockClient.post.mockResolvedValue(expectedResponse);