refactor: migrated packages to internal utility modules and removed external dependencies
- Implemented in-house, zero-dependency utility modules in `pi-utils` covering DOM manipulation, markdown parsing, templating, browser automation helpers, and terminal buffers. - Migrated packages across the repository to consume the new internal utilities and `omptype` schema validators instead of external dependencies. - Removed multiple external runtime and development dependencies including Zod, Marked, LRU cache, Turndown, and Puppeteer browser packages.
This commit is contained in:
@@ -47,7 +47,6 @@
|
||||
"@oh-my-pi/pi-catalog": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"@oh-my-pi/pi-wire": "catalog:",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bufbuild/protoc-gen-es": "catalog:",
|
||||
@@ -69,7 +68,6 @@
|
||||
"@bufbuild/protobuf": "catalog:",
|
||||
"@oh-my-pi/omptype": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@oh-my-pi/pi-ai": "catalog:",
|
||||
@@ -83,9 +81,7 @@
|
||||
"omp": "src/cli.ts",
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "catalog:",
|
||||
"@babel/parser": "catalog:",
|
||||
"@mozilla/readability": "catalog:",
|
||||
"@oh-my-pi/hashline": "catalog:",
|
||||
"@oh-my-pi/omp-stats": "catalog:",
|
||||
"@oh-my-pi/omptype": "catalog:",
|
||||
@@ -109,25 +105,11 @@
|
||||
"@opentelemetry/sdk-metrics": "catalog:",
|
||||
"@opentelemetry/sdk-trace-base": "catalog:",
|
||||
"@opentelemetry/sdk-trace-node": "catalog:",
|
||||
"@puppeteer/browsers": "catalog:",
|
||||
"@types/turndown": "catalog:",
|
||||
"@xterm/headless": "catalog:",
|
||||
"chalk": "catalog:",
|
||||
"fast-xml-parser": "catalog:",
|
||||
"handlebars": "catalog:",
|
||||
"header-generator": "catalog:",
|
||||
"linkedom": "catalog:",
|
||||
"lru-cache": "catalog:",
|
||||
"mammoth": "catalog:",
|
||||
"mupdf": "catalog:",
|
||||
"puppeteer-core": "catalog:",
|
||||
"turndown": "catalog:",
|
||||
"turndown-plugin-gfm": "catalog:",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
"marked": "catalog:",
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@huggingface/transformers": "catalog:",
|
||||
@@ -138,9 +120,9 @@
|
||||
"name": "@oh-my-pi/collab-web",
|
||||
"version": "16.3.6",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"@oh-my-pi/pi-wire": "catalog:",
|
||||
"lucide-react": "catalog:",
|
||||
"marked": "catalog:",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
},
|
||||
@@ -155,7 +137,7 @@
|
||||
"version": "17.2.9",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-natives": "catalog:",
|
||||
"lru-cache": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
@@ -205,7 +187,6 @@
|
||||
"@oh-my-pi/pi-catalog": "catalog:",
|
||||
"@oh-my-pi/pi-natives": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"lru-cache": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
@@ -240,7 +221,6 @@
|
||||
"@types/bun": "catalog:",
|
||||
"arkregex": "0.0.8",
|
||||
"arktype": "2.2.3",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
},
|
||||
"packages/snapcompact": {
|
||||
@@ -268,7 +248,6 @@
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"@tailwindcss/node": "catalog:",
|
||||
"chart.js": "catalog:",
|
||||
"date-fns": "catalog:",
|
||||
"lucide-react": "catalog:",
|
||||
"react": "catalog:",
|
||||
"react-chartjs-2": "catalog:",
|
||||
@@ -279,7 +258,6 @@
|
||||
"@types/bun": "catalog:",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"linkedom": "catalog:",
|
||||
"postcss": "catalog:",
|
||||
},
|
||||
},
|
||||
@@ -289,11 +267,8 @@
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-natives": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"lru-cache": "catalog:",
|
||||
"marked": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"chalk": "catalog:",
|
||||
"ghostty-web": "catalog:",
|
||||
},
|
||||
},
|
||||
@@ -327,9 +302,6 @@
|
||||
"version": "17.2.9",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-natives": "catalog:",
|
||||
"handlebars": "catalog:",
|
||||
"winston": "catalog:",
|
||||
"winston-daily-rotate-file": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
@@ -361,13 +333,11 @@
|
||||
"patchedDependencies": {
|
||||
"puppeteer-core@25.3.0": "patches/puppeteer-core@25.3.0.patch",
|
||||
"@ark/schema@0.56.2": "patches/@ark%2Fschema@0.56.2.patch",
|
||||
"@agentclientprotocol/sdk@1.2.1": "patches/@agentclientprotocol%2Fsdk@1.2.1.patch",
|
||||
},
|
||||
"overrides": {
|
||||
"@ark/schema": "0.56.2",
|
||||
},
|
||||
"catalog": {
|
||||
"@agentclientprotocol/sdk": "1.2.1",
|
||||
"@babel/generator": "^7.29.7",
|
||||
"@babel/parser": "^7.29.7",
|
||||
"@babel/traverse": "^7.29.7",
|
||||
@@ -376,7 +346,6 @@
|
||||
"@bufbuild/protobuf": "^2.12.1",
|
||||
"@bufbuild/protoc-gen-es": "^2.12.1",
|
||||
"@huggingface/transformers": "^4.2.0",
|
||||
"@mozilla/readability": "^0.6.0",
|
||||
"@napi-rs/cli": "3.7.2",
|
||||
"@oh-my-pi/hashline": "17.2.9",
|
||||
"@oh-my-pi/omp-stats": "17.2.9",
|
||||
@@ -402,7 +371,6 @@
|
||||
"@opentelemetry/sdk-metrics": "^2.9.0",
|
||||
"@opentelemetry/sdk-trace-base": "^2.9.0",
|
||||
"@opentelemetry/sdk-trace-node": "^2.9.0",
|
||||
"@puppeteer/browsers": "^3.0.6",
|
||||
"@tailwindcss/node": "^4.3.2",
|
||||
"@tailwindcss/vite": "^4.3.2",
|
||||
"@types/babel__generator": "^7.27.0",
|
||||
@@ -410,25 +378,13 @@
|
||||
"@types/bun": "^1.3.14",
|
||||
"@types/react": "^19.2.17",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/turndown": "5.0.6",
|
||||
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
||||
"@xterm/headless": "^6.0.0",
|
||||
"chalk": "^5.6.2",
|
||||
"chart.js": "^4.5.1",
|
||||
"date-fns": "^4.4.0",
|
||||
"diff": "^9.0.0",
|
||||
"fast-xml-parser": "^5.9.3",
|
||||
"fastembed": "2.1.0",
|
||||
"fflate": "0.8.3",
|
||||
"ghostty-web": "^0.4.0",
|
||||
"handlebars": "^4.7.9",
|
||||
"header-generator": "^2.1.82",
|
||||
"linkedom": "^0.18.13",
|
||||
"lint-staged": "^17.0.8",
|
||||
"lru-cache": "11.5.2",
|
||||
"lucide-react": "^1.24.0",
|
||||
"mammoth": "^1.12.0",
|
||||
"marked": "^18.0.6",
|
||||
"mupdf": "^1.28.0",
|
||||
"onnxruntime-node": "1.26.0",
|
||||
"postcss": "^8.5.16",
|
||||
@@ -441,18 +397,11 @@
|
||||
"solid-js": "^1.9.14",
|
||||
"tailwindcss": "^4.3.2",
|
||||
"ts-morph": "^28.0.0",
|
||||
"turndown": "7.2.4",
|
||||
"turndown-plugin-gfm": "1.0.2",
|
||||
"typescript": "^7.0.2",
|
||||
"vite": "^8.1.4",
|
||||
"vite-plugin-solid": "^2.11.12",
|
||||
"winston": "^3.19.0",
|
||||
"winston-daily-rotate-file": "5.0.0",
|
||||
"zod": "^4",
|
||||
},
|
||||
"packages": {
|
||||
"@agentclientprotocol/sdk": ["@agentclientprotocol/sdk@1.2.1", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-jwYUdOQR7tc+Zfch53VL4JJyUNK/46q03uUTYb+PjECsmnNl94XFXOfYLJ8RBpMNidXd1rpOAVgb0vqD98xImA=="],
|
||||
|
||||
"@anush008/tokenizers": ["@anush008/tokenizers@0.0.0", "", { "optionalDependencies": { "@anush008/tokenizers-darwin-universal": "0.0.0", "@anush008/tokenizers-linux-x64-gnu": "0.0.0", "@anush008/tokenizers-win32-x64-msvc": "0.0.0" } }, "sha512-IQD9wkVReKAhsEAbDjh/0KrBGTEXelqZLpOBRDaIRvlzZ9sjmUP+gKbpvzyJnei2JHQiE8JAgj7YcNloINbGBw=="],
|
||||
|
||||
"@anush008/tokenizers-darwin-universal": ["@anush008/tokenizers-darwin-universal@0.0.0", "", { "os": "darwin" }, "sha512-SACpWEooTjFX89dFKRVUhivMxxcZRtA3nJGVepdLyrwTkQ1TZQ8581B5JoXp0TcTMHfgnDaagifvVoBiFEdNCQ=="],
|
||||
@@ -529,10 +478,6 @@
|
||||
|
||||
"@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.13.0", "", { "dependencies": { "@bufbuild/protobuf": "2.13.0", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-32eMChKaL/A8Hh5AfMmXSdnuyznN85uoEjoyWiWeRrvtQOtpqX/v1R9PDe0g9vMIgzznK9inMT3CUaal0kjLUQ=="],
|
||||
|
||||
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
|
||||
|
||||
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.8", "", { "dependencies": { "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q=="],
|
||||
|
||||
"@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
||||
@@ -649,10 +594,6 @@
|
||||
|
||||
"@kurkle/color": ["@kurkle/color@0.3.4", "", {}, "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="],
|
||||
|
||||
"@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="],
|
||||
|
||||
"@mozilla/readability": ["@mozilla/readability@0.6.0", "", {}, "sha512-juG5VWh4qAivzTAeMzvY9xs9HY5rAcr2E4I7tiSSCokRFi7XIZCAu92ZkSTsIj1OPceCifL3cpfteP3pDT9/QQ=="],
|
||||
|
||||
"@napi-rs/cli": ["@napi-rs/cli@3.7.2", "", { "dependencies": { "@inquirer/prompts": "^8.5.2", "@napi-rs/cross-toolchain": "^1.0.3", "@napi-rs/wasm-tools": "^1.0.1", "@octokit/rest": "^22.0.1", "clipanion": "^4.0.0-rc.4", "colorette": "^2.0.20", "emnapi": "^1.11.1", "es-toolkit": "^1.47.0", "js-yaml": "^4.2.0", "obug": "^2.1.2", "semver": "^7.8.2", "typanion": "^3.14.0" }, "peerDependencies": { "@emnapi/runtime": "^1.7.1" }, "optionalPeers": ["@emnapi/runtime"], "bin": { "napi": "dist/cli.js", "napi-raw": "cli.mjs" } }, "sha512-shDW0Td/XZQpP04Yy+OsMt1ILMKGGkoLcy1zVAsSAK0fLfWm0Upgkmfs/NOV2ZhMQwkgpR3ZEdyHmTwgrUDQuA=="],
|
||||
|
||||
"@napi-rs/cross-toolchain": ["@napi-rs/cross-toolchain@1.0.3", "", { "dependencies": { "@napi-rs/lzma": "^1.4.5", "@napi-rs/tar": "^1.1.0", "debug": "^4.4.1" }, "peerDependencies": { "@napi-rs/cross-toolchain-arm64-target-aarch64": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-armv7": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-ppc64le": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-s390x": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-x86_64": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-aarch64": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-armv7": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-ppc64le": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-s390x": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-x86_64": "^1.0.3" }, "optionalPeers": ["@napi-rs/cross-toolchain-arm64-target-aarch64", "@napi-rs/cross-toolchain-arm64-target-armv7", "@napi-rs/cross-toolchain-arm64-target-ppc64le", "@napi-rs/cross-toolchain-arm64-target-s390x", "@napi-rs/cross-toolchain-arm64-target-x86_64", "@napi-rs/cross-toolchain-x64-target-aarch64", "@napi-rs/cross-toolchain-x64-target-armv7", "@napi-rs/cross-toolchain-x64-target-ppc64le", "@napi-rs/cross-toolchain-x64-target-s390x", "@napi-rs/cross-toolchain-x64-target-x86_64"] }, "sha512-ENPfLe4937bsKVTDA6zdABx4pq9w0tHqRrJHyaGxgaPq03a2Bd1unD5XSKjXJjebsABJ+MjAv1A2OvCgK9yehg=="],
|
||||
@@ -757,8 +698,6 @@
|
||||
|
||||
"@napi-rs/wasm-tools-win32-x64-msvc": ["@napi-rs/wasm-tools-win32-x64-msvc@1.1.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bVVjuvhlyVX++3eJXfDR63cXdw1ay5QYac6iq0MKQw8wZARInTM+bXCtByDT4fzVFI3+7ZthYb/ERWRdBNIqgQ=="],
|
||||
|
||||
"@nodable/entities": ["@nodable/entities@3.0.0", "", {}, "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw=="],
|
||||
|
||||
"@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"@octokit/core": ["@octokit/core@7.0.7", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.4", "@octokit/request": "^10.0.13", "@octokit/request-error": "^7.1.1", "@octokit/types": "^17.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA=="],
|
||||
@@ -909,10 +848,6 @@
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.34.52", "", {}, "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw=="],
|
||||
|
||||
"@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="],
|
||||
|
||||
"@so-ric/colorspace": ["@so-ric/colorspace@1.1.6", "", { "dependencies": { "color": "^5.0.2", "text-hex": "1.0.x" } }, "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="],
|
||||
|
||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="],
|
||||
@@ -971,10 +906,6 @@
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.2.4", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw=="],
|
||||
|
||||
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
|
||||
|
||||
"@types/turndown": ["@types/turndown@5.0.6", "", {}, "sha512-ru00MoyeeouE5BX4gRL+6m/BsDfbRayOskWqUvh7CLGW+UXxHQItqALa38kKnOiZPqJrtzJUgAC2+F0rL1S4Pg=="],
|
||||
|
||||
"@typescript/analyze-trace": ["@typescript/analyze-trace@0.10.1", "", { "dependencies": { "chalk": "^4.1.2", "exit": "^0.1.2", "jsonparse": "^1.3.1", "jsonstream-next": "^3.0.0", "p-limit": "^3.1.0", "split2": "^3.2.2", "treeify": "^1.1.0", "yargs": "^16.2.0" }, "bin": { "analyze-trace": "bin/analyze-trace", "print-trace-types": "bin/print-trace-types", "simplify-trace-types": "bin/simplify-trace-types" } }, "sha512-RnlSOPh14QbopGCApgkSx5UBgGda5MX1cHqp2fsqfiDyCwGL/m1jaeB9fzu7didVS81LQqGZZuxFBcg8YU8EVw=="],
|
||||
|
||||
"@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260707.2", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260707.2", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260707.2", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260707.2", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260707.2", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260707.2", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260707.2", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260707.2" }, "bin": { "tsgo": "bin/tsgo" } }, "sha512-oUGp+Rep/hqMhPunyinsALUwSlzHINSxitifPiSaeqoKOKD2OlR9NE3TaPqwsl4NlGslsOSUXI1JotWQzpYCPg=="],
|
||||
@@ -1035,42 +966,28 @@
|
||||
|
||||
"@typescript/vfs": ["@typescript/vfs@1.6.1", "", { "dependencies": { "debug": "^4.1.1" }, "peerDependencies": { "typescript": "*" } }, "sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA=="],
|
||||
|
||||
"@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="],
|
||||
|
||||
"@xterm/headless": ["@xterm/headless@6.0.0", "", {}, "sha512-5Yj1QINYCyzrZtf8OFIHi47iQtI+0qYFPHmouEfG8dHNxbZ9Tb9YGSuLcsEwj9Z+OL75GJqPyJbyoFer80a2Hw=="],
|
||||
|
||||
"adm-zip": ["adm-zip@0.5.18", "", {}, "sha512-ufJnssQGbxzLNS1Ho9bCtX4rQKCCvoVuDLHoJyc3F9dOGDB4BkWs2Ci0kv53lqocAEQ/Cbi+I2XCsNYGqVYqng=="],
|
||||
|
||||
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"anynum": ["anynum@1.0.1", "", {}, "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A=="],
|
||||
|
||||
"argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"arkregex": ["arkregex@0.0.8", "", { "dependencies": { "@ark/util": "0.56.2" } }, "sha512-PJcx6G1kQTgLKPUbeYlYecDRaKq15AMSGVajlKFYWlPeJRQL+j3dKE6tyMs40HZ99djS1l9Vhl3ezAHy9JBIqQ=="],
|
||||
|
||||
"arktype": ["arktype@2.2.3", "", { "dependencies": { "@ark/schema": "0.56.2", "@ark/util": "0.56.2", "arkregex": "0.0.8" } }, "sha512-7W+0RLTUNJiBFIIZXwOQxSR8Z273IAd6IvqBeG9+gHnQKFsIx2C0iOtGTmMrPnlX4qLXyc5+ll7A0BIj9WrbTg=="],
|
||||
|
||||
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
|
||||
|
||||
"babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.7", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-/O6JWUmjv03OI9lL2ry9bUjpD5S3PclM55RRJEyCdcFZ5W2SEA/59d+l2hNsk3gI6kiWRdRPdOtqZmsQzFN1pQ=="],
|
||||
|
||||
"babel-preset-solid": ["babel-preset-solid@1.9.12", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.6" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.12" }, "optionalPeers": ["solid-js"] }, "sha512-LLqnuKVDlKpyBlMPcH6qEvs/wmS9a+NczppxJ3ryS/c0O5IiSFOIBQi9GzyiGDSbcJpx4Gr87jyFTos1MyEuWg=="],
|
||||
|
||||
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.11.10", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-35JEvJ5/KKlbCHjMCsONI2w6HE88STjVdHk+C7d8LtcFxUjZR1KeLP9izofn2qs0KUxX5r4z73bwH/rd+JHacw=="],
|
||||
|
||||
"before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"bluebird": ["bluebird@3.4.7", "", {}, "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA=="],
|
||||
|
||||
"boolbase": ["boolbase@2.0.0", "", {}, "sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA=="],
|
||||
|
||||
"boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="],
|
||||
@@ -1079,11 +996,9 @@
|
||||
|
||||
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
||||
|
||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001806", "", {}, "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw=="],
|
||||
|
||||
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"chardet": ["chardet@2.2.0", "", {}, "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA=="],
|
||||
|
||||
@@ -1105,28 +1020,16 @@
|
||||
|
||||
"code-block-writer": ["code-block-writer@13.0.3", "", {}, "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="],
|
||||
|
||||
"color": ["color@5.0.3", "", { "dependencies": { "color-convert": "^3.1.3", "color-string": "^2.1.3" } }, "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"color-string": ["color-string@2.1.4", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg=="],
|
||||
|
||||
"colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="],
|
||||
|
||||
"content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
|
||||
|
||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||
|
||||
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
||||
|
||||
"css-select": ["css-select@7.0.0", "", { "dependencies": { "boolbase": "^2.0.0", "css-what": "^8.0.0", "domhandler": "^6.0.1", "domutils": "^4.0.2", "nth-check": "^3.0.1" } }, "sha512-snmjEVXy+1LnwXdxhYvTMj1d9tOh4HxkA1YmoayVBeeyR2C14Pum7fcxJIm4SswYspVy866eYNwlH6xC3/VH5g=="],
|
||||
|
||||
"css-what": ["css-what@8.0.0", "", {}, "sha512-DH0Bqq3DNp5tdOReuNyAA+Ev4Y2GS5FMbZpeTLP6C4CDi0h5nL0BmUPChXw3o/qbHLDWHl49sbNqQVY7bMSDdw=="],
|
||||
|
||||
"cssom": ["cssom@0.5.0", "", {}, "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="],
|
||||
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
|
||||
@@ -1147,8 +1050,6 @@
|
||||
|
||||
"d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
|
||||
|
||||
"date-fns": ["date-fns@4.4.0", "", {}, "sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
|
||||
@@ -1163,31 +1064,15 @@
|
||||
|
||||
"diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="],
|
||||
|
||||
"dingbat-to-unicode": ["dingbat-to-unicode@1.0.1", "", {}, "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@3.1.1", "", { "dependencies": { "domelementtype": "^3.0.0", "domhandler": "^6.0.0", "entities": "^8.0.0" } }, "sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
||||
"domhandler": ["domhandler@6.0.1", "", { "dependencies": { "domelementtype": "^3.0.0" } }, "sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg=="],
|
||||
|
||||
"domutils": ["domutils@4.0.2", "", { "dependencies": { "dom-serializer": "^3.0.0", "domelementtype": "^3.0.0", "domhandler": "^6.0.0" } }, "sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA=="],
|
||||
|
||||
"dot-prop": ["dot-prop@6.0.1", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA=="],
|
||||
|
||||
"duck": ["duck@0.1.12", "", { "dependencies": { "underscore": "^1.13.1" } }, "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg=="],
|
||||
|
||||
"electron-to-chromium": ["electron-to-chromium@1.5.399", "", {}, "sha512-lEcqhErbHjXRvd41rnWLpzbyU/IXfIYo7QwaFWmxGeLiLyY2TBCdHnWY88vB+p3ubnihRypDm66panXl7TylLA=="],
|
||||
|
||||
"emnapi": ["emnapi@1.11.3", "", { "peerDependencies": { "node-addon-api": ">= 6.1.0" }, "optionalPeers": ["node-addon-api"] }, "sha512-+/ZS90YK/rYfVOHtGLHkGffVsnmD/MAKaBHio+Y4XAtg75RLr4cveV/w0jTkUdLM1CcAlaRgG76mpIemWAlk0A=="],
|
||||
|
||||
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="],
|
||||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.24.5", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A=="],
|
||||
|
||||
"entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
|
||||
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||
|
||||
@@ -1209,22 +1094,12 @@
|
||||
|
||||
"fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="],
|
||||
|
||||
"fast-xml-builder": ["fast-xml-builder@1.3.0", "", { "dependencies": { "path-expression-matcher": "^1.6.2", "xml-naming": "^0.3.0" } }, "sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ=="],
|
||||
|
||||
"fast-xml-parser": ["fast-xml-parser@5.10.1", "", { "dependencies": { "@nodable/entities": "^3.0.0", "fast-xml-builder": "^1.2.0", "is-unsafe": "^2.0.0", "path-expression-matcher": "^1.6.2", "strnum": "^2.4.1", "xml-naming": "^0.3.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw=="],
|
||||
|
||||
"fastembed": ["fastembed@2.1.0", "", { "dependencies": { "@anush008/tokenizers": "^0.0.0", "@huggingface/hub": "^2.7.1", "onnxruntime-node": "1.21.0", "progress": "^2.0.3", "tar": "^6.2.0" } }, "sha512-oQkpcRHBppJ3+a3w9dU0uytSY0N1cnEa/iVMc8AXEd+tvT529GekOEFhNviJy89R3lvQXF6cdIMTXHj1Gi00xQ=="],
|
||||
|
||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="],
|
||||
|
||||
"file-stream-rotator": ["file-stream-rotator@0.6.1", "", { "dependencies": { "moment": "^2.29.1" } }, "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ=="],
|
||||
|
||||
"flatbuffers": ["flatbuffers@25.9.23", "", {}, "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ=="],
|
||||
|
||||
"fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="],
|
||||
|
||||
"framer-motion": ["framer-motion@12.43.0", "", { "dependencies": { "motion-dom": "^12.43.0", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g=="],
|
||||
|
||||
"fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
||||
@@ -1233,8 +1108,6 @@
|
||||
|
||||
"gearhash-jit": ["gearhash-jit@1.0.2", "", {}, "sha512-UhzJL4KXSdqAKepy/tZwmi2Rcy0YMmtiC4DQS4SURCuIWdh8ECZtnXK2ePRMLigfB61hRKdLK/Vgg2bSw73izQ=="],
|
||||
|
||||
"generative-bayesian-network": ["generative-bayesian-network@2.1.87", "", { "dependencies": { "adm-zip": "^0.6.0", "tslib": "^2.4.0" } }, "sha512-Bd14uZSkGGef6gWsJp170xnTMxeMENcnkJega4UjFrgF0KHSG8IOYA5hgFVOIgWlfyYUy9B2qiLGvXsKR/TlYA=="],
|
||||
|
||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||
|
||||
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||
@@ -1253,40 +1126,22 @@
|
||||
|
||||
"guid-typescript": ["guid-typescript@1.0.9", "", {}, "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="],
|
||||
|
||||
"handlebars": ["handlebars@4.7.9", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
|
||||
|
||||
"header-generator": ["header-generator@2.1.87", "", { "dependencies": { "browserslist": "^4.21.1", "generative-bayesian-network": "2.1.87", "ow": "^0.28.1", "tslib": "^2.4.0" } }, "sha512-J3MG508JWaH3UJtHlPM3xaOQ2Iqys8BiW07t6XehzP+HuvVX4MP4C2YztJKasDmB8R3yPwpBfyroOiEi4Ymn6Q=="],
|
||||
|
||||
"html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="],
|
||||
|
||||
"html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="],
|
||||
|
||||
"htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="],
|
||||
|
||||
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
|
||||
|
||||
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
||||
|
||||
"is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="],
|
||||
|
||||
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
||||
|
||||
"is-unsafe": ["is-unsafe@2.0.0", "", {}, "sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA=="],
|
||||
|
||||
"is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="],
|
||||
|
||||
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
|
||||
|
||||
"jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="],
|
||||
|
||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
@@ -1305,12 +1160,6 @@
|
||||
|
||||
"jsonstream-next": ["jsonstream-next@3.0.0", "", { "dependencies": { "jsonparse": "^1.2.0", "through2": "^4.0.2" }, "bin": { "jsonstream-next": "bin.js" } }, "sha512-aAi6oPhdt7BKyQn1SrIIGZBt0ukKuOUE1qV6kJ3GgioSOYzsRc8z9Hfr1BVmacA/jLe9nARfmgMGgn68BqIAgg=="],
|
||||
|
||||
"jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="],
|
||||
|
||||
"kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
|
||||
|
||||
"lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||
|
||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||
@@ -1335,19 +1184,11 @@
|
||||
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||
|
||||
"linkedom": ["linkedom@0.18.13", "", { "dependencies": { "css-select": "^7.0.0", "cssom": "^0.5.0", "html-escaper": "^3.0.3", "htmlparser2": "^10.1.0", "uhyphen": "^0.2.0" }, "peerDependencies": { "canvas": ">= 2" }, "optionalPeers": ["canvas"] }, "sha512-ES/o9qotMpzpN2MHs+Iq/JcVoOj8Fa5wiQYrTdFpvAnwXL0g66XHHUc9WUMk6nAlBtGsFQ24ne+SYnvnaQ2FSw=="],
|
||||
|
||||
"lint-staged": ["lint-staged@17.3.0", "", { "dependencies": { "picomatch": "^4.0.5", "string-argv": "^0.3.2", "tinyexec": "^1.2.4" }, "optionalDependencies": { "yaml": "^2.9.0" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-woZS3vNe3UKqBaLPvbLOtKRY4tLANpWQhom12MGWqC8Mh1lCOO+WgSwmX2amjJAqTY9BkXYW87fCUH5H9Ph6xw=="],
|
||||
|
||||
"lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="],
|
||||
|
||||
"logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="],
|
||||
|
||||
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||
|
||||
"lop": ["lop@0.4.2", "", { "dependencies": { "duck": "^0.1.12", "option": "~0.2.1", "underscore": "^1.13.1" } }, "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw=="],
|
||||
|
||||
"lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="],
|
||||
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"lucide-react": ["lucide-react@1.28.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-fARAFJULsGuDDydjp6+6blekG/sBIM29TerzLjc9bQUKAcEfrSc4ZQKb25KRz4OMKd87cZTb5dgq0w/T6KufVg=="],
|
||||
|
||||
@@ -1355,18 +1196,12 @@
|
||||
|
||||
"make-synchronized": ["make-synchronized@0.8.0", "", {}, "sha512-DZu4lwc0ffoFz581BSQa/BJl+1ZqIkoRQ+VejMlH0VrP4E86StAODnZujZ4sepumQj8rcP7wUnUBGM8Gu+zKUA=="],
|
||||
|
||||
"mammoth": ["mammoth@1.12.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.6", "argparse": "~1.0.3", "base64-js": "^1.5.1", "bluebird": "~3.4.0", "dingbat-to-unicode": "^1.0.1", "jszip": "^3.7.1", "lop": "^0.4.2", "path-is-absolute": "^1.0.0", "underscore": "^1.13.1", "xmlbuilder": "^10.0.0" }, "bin": { "mammoth": "bin/mammoth" } }, "sha512-cwnK1RIcRdDMi2HRx2EXGYlxqIEh0Oo3bLhorgnsVJi2UkbX1+jKxuBNR9PC5+JaX7EkmJxFPmo6mjLpqShI2w=="],
|
||||
|
||||
"marked": ["marked@18.0.7", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-iDVQ5ldaiKXn6b2JroX5kgRfmwgqolW7NpaEzTl1k/2Zh1njIEN9yniyLV/mOvWwtsE8OGgkjsCYvijuPk1dtA=="],
|
||||
|
||||
"matcher": ["matcher@4.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-S6x5wmcDmsDRRU/c2dkccDwQPXoFczc5+HpQ2lON8pnvHlnvHAHj5WlLVvw6n6vNyHuVugYrFohYxbS+pvFpKQ=="],
|
||||
|
||||
"merge-anything": ["merge-anything@5.1.7", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ=="],
|
||||
|
||||
"minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="],
|
||||
|
||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||
|
||||
"minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
||||
|
||||
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
||||
@@ -1377,8 +1212,6 @@
|
||||
|
||||
"modern-tar": ["modern-tar@0.7.7", "", {}, "sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ=="],
|
||||
|
||||
"moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="],
|
||||
|
||||
"motion": ["motion@12.43.0", "", { "dependencies": { "framer-motion": "^12.43.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-BQgQbSa9Hn3/mtbib0MK53y6JSANa+YKUKlaYnWzAVDH424RYQ5LVpV3pNiWH00BA2z4ojsSdMzqT7g2FQwjuQ=="],
|
||||
|
||||
"motion-dom": ["motion-dom@12.43.0", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag=="],
|
||||
@@ -1393,42 +1226,24 @@
|
||||
|
||||
"nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
|
||||
|
||||
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
|
||||
|
||||
"node-releases": ["node-releases@2.0.51", "", {}, "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ=="],
|
||||
|
||||
"nth-check": ["nth-check@3.0.1", "", { "dependencies": { "boolbase": "^2.0.0" } }, "sha512-GX0gsdbGVCgnRgbeGaubfjpBXyYRWOOCVeYh08bSQvDZqxz5ndXs1OTfAt/h36G1xvI94YIspsI0sVFqAV9+RQ=="],
|
||||
|
||||
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
|
||||
|
||||
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
|
||||
|
||||
"obug": ["obug@2.1.4", "", {}, "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA=="],
|
||||
|
||||
"one-time": ["one-time@1.0.0", "", { "dependencies": { "fn.name": "1.x.x" } }, "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g=="],
|
||||
|
||||
"onnxruntime-common": ["onnxruntime-common@1.26.0", "", {}, "sha512-qVyMR4lcWgbkc4getFV+GQijsTnbg/siteoqcDwa3sI/LxbrMSNw4ePyvCq/ymdQaRomCA7YuWmhzsswxvymdw=="],
|
||||
|
||||
"onnxruntime-node": ["onnxruntime-node@1.26.0", "", { "dependencies": { "adm-zip": "^0.5.16", "global-agent": "^4.1.3", "onnxruntime-common": "1.26.0" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-OHl6PiOEOqxaLHL0N9eFrbzS7IGmu3BtJNH3RTEnRAheCIkfc3gjcjl4sGcjp9C22ZC9YTquDOxSdT/stBQ6BQ=="],
|
||||
|
||||
"onnxruntime-web": ["onnxruntime-web@1.26.0-dev.20260416-b7804b056c", "", { "dependencies": { "flatbuffers": "^25.1.24", "guid-typescript": "^1.0.9", "long": "^5.2.3", "onnxruntime-common": "1.24.0-dev.20251116-b39e144322", "platform": "^1.3.6", "protobufjs": "^7.2.4" } }, "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw=="],
|
||||
|
||||
"option": ["option@0.2.4", "", {}, "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A=="],
|
||||
|
||||
"ow": ["ow@0.28.2", "", { "dependencies": { "@sindresorhus/is": "^4.2.0", "callsites": "^3.1.0", "dot-prop": "^6.0.1", "lodash.isequal": "^4.5.0", "vali-date": "^1.0.0" } }, "sha512-dD4UpyBh/9m4X2NVjA+73/ZPBRF+uF4zIMFvvQsabMiEK8x41L3rQ8EENOi35kyyoaJwNxEeJcP6Fj1H4U409Q=="],
|
||||
|
||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||
|
||||
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
||||
|
||||
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
|
||||
|
||||
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
|
||||
|
||||
"path-expression-matcher": ["path-expression-matcher@1.6.2", "", {}, "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ=="],
|
||||
|
||||
"path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="],
|
||||
@@ -1439,8 +1254,6 @@
|
||||
|
||||
"prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="],
|
||||
|
||||
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
||||
|
||||
"progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
|
||||
|
||||
"protobufjs": ["protobufjs@7.6.5", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw=="],
|
||||
@@ -1467,9 +1280,7 @@
|
||||
|
||||
"rolldown": ["rolldown@1.2.1", "", { "dependencies": { "@oxc-project/types": "=0.142.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.2.1", "@rolldown/binding-darwin-arm64": "1.2.1", "@rolldown/binding-darwin-x64": "1.2.1", "@rolldown/binding-freebsd-x64": "1.2.1", "@rolldown/binding-linux-arm-gnueabihf": "1.2.1", "@rolldown/binding-linux-arm64-gnu": "1.2.1", "@rolldown/binding-linux-arm64-musl": "1.2.1", "@rolldown/binding-linux-ppc64-gnu": "1.2.1", "@rolldown/binding-linux-s390x-gnu": "1.2.1", "@rolldown/binding-linux-x64-gnu": "1.2.1", "@rolldown/binding-linux-x64-musl": "1.2.1", "@rolldown/binding-openharmony-arm64": "1.2.1", "@rolldown/binding-wasm32-wasi": "1.2.1", "@rolldown/binding-win32-arm64-msvc": "1.2.1", "@rolldown/binding-win32-x64-msvc": "1.2.1" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw=="],
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
||||
|
||||
"safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
|
||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
@@ -1485,8 +1296,6 @@
|
||||
|
||||
"seroval-plugins": ["seroval-plugins@1.5.6", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ=="],
|
||||
|
||||
"setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="],
|
||||
|
||||
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
|
||||
|
||||
"sherpa-onnx": ["sherpa-onnx@1.13.2", "", {}, "sha512-hheOLl4JlOzERco73u+1Q/LaNDdFChDe4r3+IlMYIO3wggBZrReHDSxWwRUIW+YLw3eLslyiXw/hfb75aOylEA=="],
|
||||
@@ -1511,15 +1320,11 @@
|
||||
|
||||
"solid-refresh": ["solid-refresh@0.6.3", "", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="],
|
||||
|
||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"split2": ["split2@3.2.2", "", { "dependencies": { "readable-stream": "^3.0.0" } }, "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg=="],
|
||||
|
||||
"sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
|
||||
|
||||
"stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="],
|
||||
"sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
|
||||
|
||||
"string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="],
|
||||
|
||||
@@ -1529,8 +1334,6 @@
|
||||
|
||||
"strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
||||
|
||||
"strnum": ["strnum@2.4.1", "", { "dependencies": { "anynum": "^1.0.1" } }, "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg=="],
|
||||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="],
|
||||
@@ -1541,8 +1344,6 @@
|
||||
|
||||
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
||||
|
||||
"text-hex": ["text-hex@1.0.0", "", {}, "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="],
|
||||
|
||||
"through2": ["through2@4.0.2", "", { "dependencies": { "readable-stream": "3" } }, "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw=="],
|
||||
|
||||
"tinyexec": ["tinyexec@1.3.0", "", {}, "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ=="],
|
||||
@@ -1551,16 +1352,10 @@
|
||||
|
||||
"treeify": ["treeify@1.1.0", "", {}, "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A=="],
|
||||
|
||||
"triple-beam": ["triple-beam@1.4.1", "", {}, "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg=="],
|
||||
|
||||
"ts-morph": ["ts-morph@28.0.0", "", { "dependencies": { "@ts-morph/common": "~0.29.0", "code-block-writer": "^13.0.3" } }, "sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"turndown": ["turndown@7.2.4", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ=="],
|
||||
|
||||
"turndown-plugin-gfm": ["turndown-plugin-gfm@1.0.2", "", {}, "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg=="],
|
||||
|
||||
"typanion": ["typanion@3.14.0", "", {}, "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug=="],
|
||||
|
||||
"type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
|
||||
@@ -1569,12 +1364,6 @@
|
||||
|
||||
"typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="],
|
||||
|
||||
"uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
|
||||
|
||||
"uhyphen": ["uhyphen@0.2.0", "", {}, "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA=="],
|
||||
|
||||
"underscore": ["underscore@1.13.8", "", {}, "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ=="],
|
||||
|
||||
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
|
||||
|
||||
"universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="],
|
||||
@@ -1583,8 +1372,6 @@
|
||||
|
||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||
|
||||
"vali-date": ["vali-date@1.0.0", "", {}, "sha512-sgECfZthyaCKW10N0fm27cg8HYTFK5qMWgypqkXMQ4Wbl/zZKx7xZICgcoxIIE+WFAP/MBL2EFwC/YvLxw3Zeg=="],
|
||||
|
||||
"vite": ["vite@8.2.0", "", { "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.5", "postcss": "^8.5.23", "rolldown": "~1.2.0", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.4.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ=="],
|
||||
|
||||
"vite-plugin-solid": ["vite-plugin-solid@2.11.14", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.0.0 || ^7.0.0", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-7ZVBt8rpoyqmlwin2kRIUveaHoF6/kulY7gsnD+qFh4nS29V4OPAnw+ojoAspXIjObiL9o1xh9a/nTuYHm02Rw=="],
|
||||
@@ -1593,22 +1380,10 @@
|
||||
|
||||
"webdriver-bidi-protocol": ["webdriver-bidi-protocol@0.4.2", "", {}, "sha512-VSV+fzfChirL3e7jay2yUC7B4HQCGtEWEg/MSSQbK+qWbqeGlRLlXTzPpYr3XGUvbpDHumWZBJxgesg4N7dbtA=="],
|
||||
|
||||
"winston": ["winston@3.19.0", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.8", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.9.0" } }, "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA=="],
|
||||
|
||||
"winston-daily-rotate-file": ["winston-daily-rotate-file@5.0.0", "", { "dependencies": { "file-stream-rotator": "^0.6.1", "object-hash": "^3.0.0", "triple-beam": "^1.4.1", "winston-transport": "^4.7.0" }, "peerDependencies": { "winston": "^3" } }, "sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw=="],
|
||||
|
||||
"winston-transport": ["winston-transport@4.9.0", "", { "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" } }, "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A=="],
|
||||
|
||||
"wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
|
||||
|
||||
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
|
||||
|
||||
"ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="],
|
||||
|
||||
"xml-naming": ["xml-naming@0.3.0", "", {}, "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ=="],
|
||||
|
||||
"xmlbuilder": ["xmlbuilder@10.1.1", "", {}, "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg=="],
|
||||
|
||||
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
|
||||
|
||||
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
||||
@@ -1621,14 +1396,12 @@
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"@ark/attest/prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||
|
||||
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"@bufbuild/protoplugin/@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="],
|
||||
@@ -1703,62 +1476,30 @@
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"@typescript/analyze-trace/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"@typescript/analyze-trace/yargs": ["yargs@16.2.2", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w=="],
|
||||
|
||||
"babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="],
|
||||
|
||||
"chromium-bidi/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"cli-progress/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
|
||||
"color/color-convert": ["color-convert@3.1.3", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg=="],
|
||||
|
||||
"color-string/color-name": ["color-name@2.1.1", "", {}, "sha512-p2FdgwVx1a9yWBHP2wI0VgShkDpgN4kZISkxdNipGBJWpa5G6b04OINlVWCyJj0JmfvcPrgqt95E9k8yvaOJFg=="],
|
||||
|
||||
"dom-serializer/domelementtype": ["domelementtype@3.0.0", "", {}, "sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg=="],
|
||||
|
||||
"dom-serializer/entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="],
|
||||
|
||||
"domhandler/domelementtype": ["domelementtype@3.0.0", "", {}, "sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg=="],
|
||||
|
||||
"domutils/domelementtype": ["domelementtype@3.0.0", "", {}, "sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg=="],
|
||||
|
||||
"fastembed/onnxruntime-node": ["onnxruntime-node@1.21.0", "", { "dependencies": { "global-agent": "^3.0.0", "onnxruntime-common": "1.21.0", "tar": "^7.0.1" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw=="],
|
||||
|
||||
"fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||
|
||||
"generative-bayesian-network/adm-zip": ["adm-zip@0.6.0", "", {}, "sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg=="],
|
||||
|
||||
"htmlparser2/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"htmlparser2/domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||
|
||||
"js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"jszip/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||
"lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||
|
||||
"onnxruntime-web/onnxruntime-common": ["onnxruntime-common@1.24.0-dev.20251116-b39e144322", "", {}, "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw=="],
|
||||
|
||||
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"roarr/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
|
||||
|
||||
"string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"vite/lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="],
|
||||
|
||||
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||
|
||||
"wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
|
||||
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"@huggingface/transformers/onnxruntime-node/global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="],
|
||||
|
||||
"@huggingface/transformers/onnxruntime-node/onnxruntime-common": ["onnxruntime-common@1.24.3", "", {}, "sha512-GeuPZO6U/LBJXvwdaqHbuUmoXiEdeCjWi/EG7Y1HNnDwJYuk6WUbNXpF6luSUY8yASul3cmUlLGrCCL1ZgVXqA=="],
|
||||
@@ -1785,18 +1526,12 @@
|
||||
|
||||
"cliui/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
|
||||
|
||||
"color/color-convert/color-name": ["color-name@2.1.1", "", {}, "sha512-p2FdgwVx1a9yWBHP2wI0VgShkDpgN4kZISkxdNipGBJWpa5G6b04OINlVWCyJj0JmfvcPrgqt95E9k8yvaOJFg=="],
|
||||
|
||||
"fastembed/onnxruntime-node/global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="],
|
||||
|
||||
"fastembed/onnxruntime-node/onnxruntime-common": ["onnxruntime-common@1.21.0", "", {}, "sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ=="],
|
||||
|
||||
"fastembed/onnxruntime-node/tar": ["tar@7.5.22", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA=="],
|
||||
|
||||
"htmlparser2/domutils/dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||
|
||||
"vite/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="],
|
||||
|
||||
"vite/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="],
|
||||
@@ -1845,8 +1580,6 @@
|
||||
|
||||
"fastembed/onnxruntime-node/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||
|
||||
"htmlparser2/domutils/dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@huggingface/transformers/onnxruntime-node/global-agent/serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="],
|
||||
|
||||
"@typescript/analyze-trace/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
@@ -44,8 +44,8 @@ Removed in the unified-flow refactor:
|
||||
- `strict-mode.ts` (merged into `normalize.ts`).
|
||||
- `sanitize-google.ts` and `normalize-cca.ts` (replaced by
|
||||
`normalizeSchemaFor*` dispatchers).
|
||||
- `StringEnum` helper — use `z.enum([...])` directly; Zod's emitted JSON
|
||||
Schema is already wire-compatible with Google and other providers.
|
||||
- `StringEnum` helper — use `type.enumerated(...)`; omptype emits
|
||||
provider-compatible JSON Schema.
|
||||
- `sanitizeSchemaFor{Google,CCA,MCP}` / `prepareSchemaForCCA` — renamed to
|
||||
`normalizeSchemaFor{Google,CCA,MCP}`.
|
||||
|
||||
@@ -70,9 +70,8 @@ shared Google Claude path.
|
||||
|
||||
## Walk semantics
|
||||
|
||||
`normalizeSchema` first detoxifies serialized Zod-instance-shaped inputs, upgrades them to
|
||||
JSON Schema 2020-12, dereferences the tree, then walks it with the option set
|
||||
pinned by the dispatcher. Each node:
|
||||
`normalizeSchema` upgrades inputs to JSON Schema 2020-12, dereferences the tree,
|
||||
then walks it with the option set pinned by the dispatcher. Each node:
|
||||
|
||||
1. Renames `snake_case` combinator/property keys to camelCase
|
||||
(`any_of` → `anyOf`, etc.; collisions follow python-genai
|
||||
|
||||
@@ -132,7 +132,7 @@ Supported formats:
|
||||
|
||||
Behavior:
|
||||
|
||||
- Validates parsed data against a provided Zod schema.
|
||||
- Validates parsed data against a provided omptype schema.
|
||||
- Caches load result until `invalidate()`.
|
||||
- Returns tri-state result via `tryLoad()`:
|
||||
- `ok`
|
||||
|
||||
@@ -70,8 +70,8 @@ const factory: CustomToolFactory = (pi) => ({
|
||||
name: "repo_stats",
|
||||
label: "Repo Stats",
|
||||
description: "Counts tracked TypeScript files",
|
||||
parameters: pi.arktype({
|
||||
glob: "string?",
|
||||
parameters: pi.zod.object({
|
||||
glob: pi.zod.string().optional(),
|
||||
}),
|
||||
|
||||
async execute(toolCallId, params, onUpdate, ctx, signal) {
|
||||
@@ -109,7 +109,7 @@ const factory: CustomToolFactory = (pi) => ({
|
||||
export default factory;
|
||||
```
|
||||
|
||||
Parameter schemas may use ArkType (`pi.arktype`), Zod (`pi.zod`), or the legacy-compatible TypeBox shim (`pi.typebox`); ArkType is preferred for new tools. Schemas flow through the shared validation/wire pipeline.
|
||||
Parameter schemas may use the Zod-compatible omptype builder (`pi.zod`), native omptype builder (`pi.arktype`), or legacy-compatible TypeBox shim (`pi.typebox`) and flow through the shared validation/wire pipeline.
|
||||
|
||||
Factory return type:
|
||||
|
||||
@@ -126,9 +126,8 @@ From `types.ts` and `loader.ts`:
|
||||
- `ui`: UI context (can be no-op in headless modes)
|
||||
- `hasUI`: `false` in non-interactive flows
|
||||
- `logger`: shared file logger
|
||||
- `arktype`: injected ArkType module (preferred for new schemas)
|
||||
- `arktype`: injected omptype `type(...)` builder
|
||||
- `typebox`: compatibility shim for legacy TypeBox-style schemas
|
||||
- `zod`: injected `zod/v4` module
|
||||
- `pi`: injected `@oh-my-pi/pi-coding-agent` exports
|
||||
- `pushPendingAction(action)`: stage a preview action that is finalized by writing a plain-text reason to `xd://resolve` or `xd://reject`
|
||||
|
||||
@@ -142,7 +141,7 @@ The loader starts with a no-op UI context and requires host code to call `setUIC
|
||||
execute(toolCallId, params, onUpdate, ctx, signal);
|
||||
```
|
||||
|
||||
- `params` is statically typed from its ArkType, Zod, or TypeBox schema via `Static<TParams>`.
|
||||
- `params` is statically typed from its omptype or TypeBox schema via `Static<TParams>`.
|
||||
- Runtime argument validation happens before execution in the agent loop.
|
||||
- `onUpdate` emits partial results for UI streaming.
|
||||
- `ctx` includes `sessionManager`, `modelRegistry`, current `model`, `isIdle()`, `hasQueuedMessages()`, `abort()`, and optional `settings`, `fetch`, `localProtocolOptions`, and `autoApprove`.
|
||||
|
||||
+6
-6
@@ -70,7 +70,7 @@ Important constraint from `loader.ts`:
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
pi.setLabel("Safety + Utilities");
|
||||
|
||||
@@ -132,9 +132,9 @@ In interactive mode, `input` handlers run before the built-in first-message auto
|
||||
Also exposed:
|
||||
|
||||
- `pi.logger`
|
||||
- `pi.arktype` (the ArkType `Type` runtime; this is not ArkType's `type(...)` schema builder)
|
||||
- `pi.zod` (injected `zod/v4` module for Zod-authored tool parameter schemas)
|
||||
- `pi.typebox` (zod-backed compatibility shim for legacy TypeBox-style schemas)
|
||||
- `pi.arktype` (the omptype `type(...)` schema builder)
|
||||
- `pi.zod` (Zod-compatible builder backed by omptype)
|
||||
- `pi.typebox` (legacy TypeBox-compatible shim)
|
||||
- `pi.pi` (package exports)
|
||||
|
||||
### Message delivery semantics
|
||||
@@ -302,7 +302,7 @@ Current runtime note: `ExtensionRunner.emitResourcesDiscover(...)` is implemente
|
||||
|
||||
## Tool authoring details
|
||||
|
||||
`registerTool` uses `ToolDefinition` from `types.ts`. Its `parameters` field accepts ArkType or Zod schemas; the injected TypeBox compatibility shim remains available for legacy extensions.
|
||||
`registerTool` uses `ToolDefinition` from `types.ts`. Its `parameters` field accepts omptype schemas; the injected TypeBox compatibility shim remains available for legacy extensions.
|
||||
|
||||
Current `execute` signature:
|
||||
|
||||
@@ -339,7 +339,7 @@ are already approved as, and delegation depth is guarded against accidental self
|
||||
Template:
|
||||
|
||||
```ts
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
pi.registerTool({
|
||||
name: "my_tool",
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ The factory can:
|
||||
- register slash commands via `pi.registerCommand(...)`
|
||||
- register custom message renderers via `pi.registerMessageRenderer(...)`
|
||||
- run shell commands via `pi.exec(...)` and log through `pi.logger`
|
||||
- use injected `pi.zod`, the legacy-compatible `pi.typebox`, and package exports via `pi.pi`; `pi.arktype` is the ArkType `Type` runtime, not the `type(...)` schema builder
|
||||
- use the injected Zod-compatible builder `pi.zod`, native omptype builder `pi.arktype`, legacy `pi.typebox`, and package exports via `pi.pi`
|
||||
|
||||
## Discovery and loading
|
||||
|
||||
|
||||
+8
-25
@@ -4,9 +4,6 @@ Internal schemas use **`@oh-my-pi/omptype`** — an ArkType-compatible validator
|
||||
with a lazy JIT runtime (`packages/omptype`). Author types with
|
||||
`import { type } from "@oh-my-pi/omptype"`.
|
||||
|
||||
> **Scope rule.** Zod stays supported at the **external boundary** — `Tool.parameters`
|
||||
> accepts Zod _or_ omptype _or_ JSON Schema, and the public `pi.zod` extension API is
|
||||
> untouched. Internal schemas use omptype.
|
||||
|
||||
## Why omptype (perf contract)
|
||||
|
||||
@@ -19,10 +16,9 @@ with a lazy JIT runtime (`packages/omptype`). Author types with
|
||||
|
||||
## The detection contract (don't break it)
|
||||
|
||||
`packages/ai/src/utils/schema/wire.ts` distinguishes the three schema kinds:
|
||||
`packages/ai/src/utils/schema/wire.ts` distinguishes two schema kinds:
|
||||
|
||||
- **omptype** = a _callable function_ with `.toJsonSchema` and `.assert` methods (`isArkSchema`).
|
||||
- **Zod** = a non-callable object carrying `_zod` + `.parse` (`isZodSchema`).
|
||||
- **omptype** = a callable function with `.toJsonSchema` and `.assert` methods (`isArkSchema`).
|
||||
- **JSON Schema** = a plain object.
|
||||
|
||||
At the provider boundary, `toolWireSchema()` calls `toJsonSchema()`, prunes
|
||||
@@ -80,30 +76,17 @@ if (out instanceof type.errors) {
|
||||
Note on `.or()` typing: schema and string operands infer precisely;
|
||||
object-literal operands degrade — wrap them with `type({...})` first.
|
||||
|
||||
## Zod → omptype translation (for new code)
|
||||
|
||||
| Zod | omptype |
|
||||
| ---------------------------------- | ----------------------------------------------------------- |
|
||||
| `z.object({ a: ... })` | `type({ a: ... })` |
|
||||
| `z.enum(["a","b"])` (static) | `"'a' \| 'b'"` |
|
||||
| `z.enum(RUNTIME_ARRAY)` | `type.enumerated(...RUNTIME_ARRAY)` |
|
||||
| `z.record(z.string(), z.number())` | `type({ "[string]": "number" })` |
|
||||
| `.optional()` | optional key `{ "a?": "string" }` |
|
||||
| `.strict()` / `.strip()` | `"+": "reject"` / `"+": "delete"` |
|
||||
| `.refine(fn, msg)` | `.narrow((d, ctx) => fn(d) \|\| ctx.mustBe("<expect>"))` |
|
||||
| `.transform(fn)` | `.pipe(fn)` |
|
||||
| `.catch(fallback)` | `type("unknown").pipe(raw => { const out = inner(raw); return out instanceof type.errors ? FALLBACK : out; })` |
|
||||
| `z.infer<typeof S>` | `typeof S.infer` |
|
||||
|
||||
## Adapters
|
||||
|
||||
For TypeBox-style or Zod-style authoring backed by the omptype runtime:
|
||||
TypeBox-style and Zod-style authoring are backed by the omptype runtime:
|
||||
|
||||
```ts
|
||||
import { Type, type Static } from "@oh-my-pi/omptype/typebox";
|
||||
import { z } from "@oh-my-pi/omptype/zod";
|
||||
|
||||
const User = z.object({ name: z.string() });
|
||||
type User = z.infer<typeof User>;
|
||||
```
|
||||
|
||||
Both produce real omptype schemas (JIT validation, `toJsonSchema`, wire
|
||||
detection). Use them for extension-facing surfaces; internal code authors
|
||||
the string DSL directly.
|
||||
These produce real omptype schemas with JIT validation and `toJsonSchema`.
|
||||
Internal code authors the string DSL directly.
|
||||
|
||||
@@ -364,7 +364,7 @@ Our fork has architectural decisions that differ from upstream. **Do not port th
|
||||
| ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `jiti` for TypeScript loading | Native Bun `import()` |
|
||||
| `pkg.pi` manifest field | `pkg.omp` preferred; fallback to `pkg.pi` remains |
|
||||
| `StringEnum` from `pi-ai` | `Type.Enum` from the `pi.typebox` shim (or author the schema with `pi.zod`); `pi-ai` no longer exports `StringEnum` |
|
||||
| `StringEnum` from `pi-ai` | `Type.Enum` from `pi.typebox`, or `pi.arktype.enumerated(...)`; `pi-ai` no longer exports `StringEnum` |
|
||||
| `formatSize` from `pi-coding-agent` | `formatBytes` from `@oh-my-pi/pi-utils` |
|
||||
| Upstream resource/package/settings managers as the native architecture | Capability-based discovery (`loadCapability(...)`), the `Settings` singleton, and `EventBus`; legacy extension imports of `DefaultResourceLoader`, `DefaultPackageManager`, and `SettingsManager` are compatibility shims in `legacy-pi-coding-agent-shim.ts`, not the native implementation |
|
||||
|
||||
|
||||
@@ -162,7 +162,9 @@ pi.registerCommand("my-cmd", {
|
||||
|
||||
## Registering tools
|
||||
|
||||
Tools are called by the LLM. Parameter definitions accept ArkType or Zod schemas; `pi.typebox` remains available as a compatibility shim for legacy TypeBox-style extensions. The following example uses the injected `zod/v4` module:
|
||||
Tools are called by the LLM. Parameter definitions may use the injected
|
||||
Zod-compatible omptype builder; `pi.arktype` and the legacy-compatible
|
||||
`pi.typebox` are also available:
|
||||
|
||||
```ts
|
||||
const z = pi.zod;
|
||||
@@ -173,7 +175,7 @@ pi.registerTool({
|
||||
description: "Full-text search through project notes",
|
||||
parameters: z.object({
|
||||
query: z.string().describe("Search query"),
|
||||
limit: z.number().default(10).describe("Max results").optional(),
|
||||
limit: z.number().default(10).optional().describe("Max results"),
|
||||
}),
|
||||
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
||||
if (signal?.aborted) {
|
||||
|
||||
@@ -197,7 +197,7 @@ The tool returns one result per call; no streaming partial output is emitted fro
|
||||
- Network
|
||||
- CDP attach paths poll `http://127.0.0.1:<port>/json/version` or the supplied `cdp_url` `/json/version`.
|
||||
- Headless/browser-attach sessions create CDP websocket connections.
|
||||
- Headless first-use Chromium download uses `@puppeteer/browsers`.
|
||||
- Headless first-use Chromium download uses the in-house `@oh-my-pi/pi-utils/browsers` installer.
|
||||
- Loopback relay mode may start the machine-global `omp.browser.relay` daemon. The extension connects outbound to the relay, and Puppeteer connects to its CDP-compatible endpoint.
|
||||
- User `page` / `tab` operations perform normal browser network traffic.
|
||||
- Subprocesses / native bindings
|
||||
|
||||
@@ -40,7 +40,7 @@ Sources: [`packages/omptype/README.md`](../packages/omptype/README.md), [`packag
|
||||
|
||||
- Package: public `@oh-my-pi/omptype`; install with `bun add @oh-my-pi/omptype`; requires Bun 1.3.14 or newer.
|
||||
- Feature: callable ArkType-compatible schemas with cheap interpreted startup, lazy hot-path compilation, validation errors, defaults and morphs, and JSON Schema emission.
|
||||
- Public surfaces: `@oh-my-pi/omptype` for native authoring, `@oh-my-pi/omptype/typebox` and `/zod` for compatibility builders, and `/ark` for the alias-free ArkType compatibility facade.
|
||||
- Public surfaces: `@oh-my-pi/omptype` for native authoring, `/typebox` and `/zod` for compatibility builders, and `/ark` for the alias-free ArkType compatibility facade.
|
||||
- Runtime behavior: schema calls return the validated value or `type.errors`; `.assert()` returns the value or throws; `.allows()` performs a boolean check.
|
||||
- Limits: this is an intentionally focused compatibility surface rather than a complete implementation of every ArkType, TypeBox, or Zod API.
|
||||
|
||||
|
||||
+2
-23
@@ -6,8 +6,7 @@
|
||||
"packageManager": "bun@1.3.14",
|
||||
"patchedDependencies": {
|
||||
"@ark/schema@0.56.2": "patches/@ark%2Fschema@0.56.2.patch",
|
||||
"puppeteer-core@25.3.0": "patches/puppeteer-core@25.3.0.patch",
|
||||
"@agentclientprotocol/sdk@1.2.1": "patches/@agentclientprotocol%2Fsdk@1.2.1.patch"
|
||||
"puppeteer-core@25.3.0": "patches/puppeteer-core@25.3.0.patch"
|
||||
},
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
@@ -15,7 +14,6 @@
|
||||
"python/robomp/web"
|
||||
],
|
||||
"catalog": {
|
||||
"@agentclientprotocol/sdk": "1.2.1",
|
||||
"@babel/generator": "^7.29.7",
|
||||
"@babel/parser": "^7.29.7",
|
||||
"@babel/traverse": "^7.29.7",
|
||||
@@ -24,7 +22,6 @@
|
||||
"@bufbuild/protobuf": "^2.12.1",
|
||||
"@bufbuild/protoc-gen-es": "^2.12.1",
|
||||
"@huggingface/transformers": "^4.2.0",
|
||||
"@mozilla/readability": "^0.6.0",
|
||||
"@napi-rs/cli": "3.7.2",
|
||||
"@oh-my-pi/hashline": "17.2.9",
|
||||
"@oh-my-pi/omp-stats": "17.2.9",
|
||||
@@ -50,7 +47,6 @@
|
||||
"@opentelemetry/sdk-metrics": "^2.9.0",
|
||||
"@opentelemetry/sdk-trace-base": "^2.9.0",
|
||||
"@opentelemetry/sdk-trace-node": "^2.9.0",
|
||||
"@puppeteer/browsers": "^3.0.6",
|
||||
"@tailwindcss/node": "^4.3.2",
|
||||
"@tailwindcss/vite": "^4.3.2",
|
||||
"@types/babel__generator": "^7.27.0",
|
||||
@@ -58,25 +54,13 @@
|
||||
"@types/bun": "^1.3.14",
|
||||
"@types/react": "^19.2.17",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/turndown": "5.0.6",
|
||||
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
||||
"@xterm/headless": "^6.0.0",
|
||||
"chalk": "^5.6.2",
|
||||
"chart.js": "^4.5.1",
|
||||
"date-fns": "^4.4.0",
|
||||
"diff": "^9.0.0",
|
||||
"fflate": "0.8.3",
|
||||
"fastembed": "2.1.0",
|
||||
"fast-xml-parser": "^5.9.3",
|
||||
"ghostty-web": "^0.4.0",
|
||||
"handlebars": "^4.7.9",
|
||||
"header-generator": "^2.1.82",
|
||||
"linkedom": "^0.18.13",
|
||||
"lint-staged": "^17.0.8",
|
||||
"lru-cache": "11.5.2",
|
||||
"lucide-react": "^1.24.0",
|
||||
"mammoth": "^1.12.0",
|
||||
"marked": "^18.0.6",
|
||||
"mupdf": "^1.28.0",
|
||||
"onnxruntime-node": "1.26.0",
|
||||
"postcss": "^8.5.16",
|
||||
@@ -89,14 +73,9 @@
|
||||
"solid-js": "^1.9.14",
|
||||
"tailwindcss": "^4.3.2",
|
||||
"ts-morph": "^28.0.0",
|
||||
"turndown": "7.2.4",
|
||||
"turndown-plugin-gfm": "1.0.2",
|
||||
"typescript": "^7.0.2",
|
||||
"vite": "^8.1.4",
|
||||
"vite-plugin-solid": "^2.11.12",
|
||||
"winston": "^3.19.0",
|
||||
"winston-daily-rotate-file": "5.0.0",
|
||||
"zod": "^4"
|
||||
"vite-plugin-solid": "^2.11.12"
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
|
||||
@@ -279,17 +279,17 @@ const agent = new Agent({
|
||||
|
||||
## Tools
|
||||
|
||||
Define tools using `AgentTool` with a Zod parameter schema (via `z` from `@oh-my-pi/pi-ai`).
|
||||
Define tools using `AgentTool` with an omptype parameter schema.
|
||||
|
||||
```typescript
|
||||
import { z } from "@oh-my-pi/pi-ai";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
|
||||
const readFileTool: AgentTool = {
|
||||
name: "read_file",
|
||||
label: "Read File", // For UI display
|
||||
description: "Read a file's contents",
|
||||
parameters: z.object({
|
||||
path: z.string().describe("File path"),
|
||||
parameters: type({
|
||||
path: type("string").describe("File path"),
|
||||
}),
|
||||
execute: async (toolCallId, params, signal, onUpdate, context) => {
|
||||
const content = await fs.readFile(params.path, "utf-8");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it, mock } from "bun:test";
|
||||
import { type AssistantMessage, type Context, z } from "@oh-my-pi/pi-ai";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { AssistantMessage, Context } from "@oh-my-pi/pi-ai";
|
||||
import { createMockModel } from "@oh-my-pi/pi-ai/providers/mock";
|
||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
@@ -59,7 +60,7 @@ describe("Agent — buildSideRequestContext", () => {
|
||||
name: "test_tool",
|
||||
label: "Test Tool",
|
||||
description: "a cool tool",
|
||||
parameters: z.object({ arg: z.string() }) as unknown as AgentTool["parameters"],
|
||||
parameters: type({ arg: type("string") }) as unknown as AgentTool["parameters"],
|
||||
execute: async () => ({ content: [{ type: "text", text: "success" }], details: { value: "success" } }),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { Agent, AgentBusyError, type AgentEvent, type AgentTool, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
||||
import { type SimpleStreamOptions, type ToolResultMessage, z } from "@oh-my-pi/pi-ai";
|
||||
import type { SimpleStreamOptions, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
||||
import { createMockModel } from "@oh-my-pi/pi-ai/providers/mock";
|
||||
import { kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
|
||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||
@@ -18,7 +19,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("classifies agent-authored steering as a parent steering message", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
const executed: string[] = [];
|
||||
let agent: Agent;
|
||||
const tool: AgentTool<typeof toolSchema, { value: string }> = {
|
||||
@@ -81,7 +82,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("classifies user-attributed custom steering as a queued user message", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
const executed: string[] = [];
|
||||
let agent: Agent;
|
||||
const tool: AgentTool<typeof toolSchema, { value: string }> = {
|
||||
@@ -165,7 +166,7 @@ describe("Agent", () => {
|
||||
];
|
||||
|
||||
for (const scenario of cases) {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
const executed: string[] = [];
|
||||
let agent: Agent;
|
||||
const tool: AgentTool<typeof toolSchema, { value: string }> = {
|
||||
@@ -1036,7 +1037,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("prompt() refreshes tools and system prompt between same-turn model calls", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
type Details = { value: string };
|
||||
|
||||
const betaTool: AgentTool<typeof toolSchema, Details> = {
|
||||
@@ -1101,7 +1102,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("prompt() drops stale forced toolChoice after same-turn tool refresh", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
type Details = { value: string };
|
||||
|
||||
const betaTool: AgentTool<typeof toolSchema, Details> = {
|
||||
@@ -1159,7 +1160,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("drops queued forced toolChoice when the queued tool is not active", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
type Details = { value: string };
|
||||
|
||||
const betaTool: AgentTool<typeof toolSchema, Details> = {
|
||||
@@ -1191,7 +1192,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("re-reads thinking level for each model call within a run", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
type Details = { value: string };
|
||||
const alphaTool: AgentTool<typeof toolSchema, Details> = {
|
||||
name: "alpha",
|
||||
@@ -1252,7 +1253,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("re-reads disableReasoning for each model call within a run", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
type Details = { value: string };
|
||||
const alphaTool: AgentTool<typeof toolSchema, Details> = {
|
||||
name: "alpha",
|
||||
@@ -1344,7 +1345,7 @@ describe("Agent", () => {
|
||||
});
|
||||
|
||||
it("re-reads cwd from cwdResolver for each model call within a run (a /move mid-run is seen)", async () => {
|
||||
const toolSchema = z.object({ value: z.string() });
|
||||
const toolSchema = type({ value: type("string") });
|
||||
type Details = { value: string };
|
||||
const alphaTool: AgentTool<typeof toolSchema, Details> = {
|
||||
name: "alpha",
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { afterEach, describe, expect, test, vi } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { AgentMessage, AgentTool } from "@oh-my-pi/pi-agent-core";
|
||||
import { generateHandoff, generateHandoffFromContext, renderHandoffPrompt } from "@oh-my-pi/pi-agent-core/compaction";
|
||||
import { ThinkingLevel } from "@oh-my-pi/pi-agent-core/thinking";
|
||||
import type { AssistantMessage, Model, ToolCall } from "@oh-my-pi/pi-ai";
|
||||
import * as ai from "@oh-my-pi/pi-ai";
|
||||
import { Effort, z } from "@oh-my-pi/pi-ai";
|
||||
import { Effort } from "@oh-my-pi/pi-ai";
|
||||
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
|
||||
|
||||
function createAssistantMessage(content: AssistantMessage["content"]): AssistantMessage {
|
||||
@@ -36,7 +37,7 @@ function createAssistantError(errorStatus: number, errorMessage: string): Assist
|
||||
};
|
||||
}
|
||||
|
||||
const handoffToolSchema = z.object({ note: z.string().optional() });
|
||||
const handoffToolSchema = type({ note: type("string").optional() });
|
||||
|
||||
function createHandoffTool(): AgentTool<typeof handoffToolSchema> {
|
||||
return {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* lifecycle hook dispatch.
|
||||
*/
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { agentLoop } from "@oh-my-pi/pi-agent-core/agent-loop";
|
||||
import {
|
||||
type AgentTelemetryConfig,
|
||||
@@ -23,7 +24,6 @@ import {
|
||||
} from "@oh-my-pi/pi-agent-core/telemetry";
|
||||
import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, AgentTool } from "@oh-my-pi/pi-agent-core/types";
|
||||
import type { Message } from "@oh-my-pi/pi-ai";
|
||||
import { z } from "@oh-my-pi/pi-ai";
|
||||
import { createMockModel } from "@oh-my-pi/pi-ai/providers/mock";
|
||||
import type { EventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||
import { context, SpanStatusCode, trace } from "@opentelemetry/api";
|
||||
@@ -218,7 +218,7 @@ describe("agent-loop OTEL instrumentation", () => {
|
||||
convertToLlm: identityConverter,
|
||||
telemetry: {},
|
||||
};
|
||||
const alphaSchema = z.object({ value: z.string() });
|
||||
const alphaSchema = type({ value: type("string") });
|
||||
const alphaTool: AgentTool<typeof alphaSchema> = {
|
||||
name: "alpha",
|
||||
label: "Alpha",
|
||||
@@ -263,7 +263,7 @@ describe("agent-loop OTEL instrumentation", () => {
|
||||
convertToLlm: identityConverter,
|
||||
telemetry: {},
|
||||
};
|
||||
const probeSchema = z.object({ value: z.string() });
|
||||
const probeSchema = type({ value: type("string") });
|
||||
const probeTool: AgentTool<typeof probeSchema> = {
|
||||
name: "probe",
|
||||
label: "Probe",
|
||||
@@ -299,7 +299,7 @@ describe("agent-loop OTEL instrumentation", () => {
|
||||
convertToLlm: identityConverter,
|
||||
telemetry: {},
|
||||
};
|
||||
const failSchema = z.object({ value: z.string() });
|
||||
const failSchema = type({ value: type("string") });
|
||||
const failTool: AgentTool<typeof failSchema> = {
|
||||
name: "fail",
|
||||
label: "Fail",
|
||||
@@ -694,7 +694,7 @@ describe("agent-loop OTEL instrumentation", () => {
|
||||
onSpanEnd: ctx => ends.push(ctx),
|
||||
},
|
||||
};
|
||||
const echoSchema = z.object({ value: z.string() });
|
||||
const echoSchema = type({ value: type("string") });
|
||||
const echoTool: AgentTool<typeof echoSchema> = {
|
||||
name: "echo",
|
||||
label: "Echo",
|
||||
@@ -797,7 +797,7 @@ describe("agent-loop OTEL instrumentation", () => {
|
||||
convertToLlm: identityConverter,
|
||||
telemetry: cfg,
|
||||
};
|
||||
const echoSchema = z.object({ value: z.string() });
|
||||
const echoSchema = type({ value: type("string") });
|
||||
const tool: AgentTool<typeof echoSchema> = {
|
||||
name: "echo",
|
||||
label: "Echo",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { agentLoop, agentLoopDetailed } from "@oh-my-pi/pi-agent-core/agent-loop";
|
||||
import {
|
||||
type AgentRunSummary,
|
||||
@@ -18,7 +19,6 @@ import {
|
||||
import { EXECUTE_TOOL_STATUS_ATTR, GenAIAttr, PiGenAIAggregateAttr } from "@oh-my-pi/pi-agent-core/telemetry";
|
||||
import type { AgentEvent, AgentLoopConfig, AgentMessage, AgentTool } from "@oh-my-pi/pi-agent-core/types";
|
||||
import type { AssistantMessage, Message } from "@oh-my-pi/pi-ai";
|
||||
import { z } from "@oh-my-pi/pi-ai";
|
||||
import { createMockModel } from "@oh-my-pi/pi-ai/providers/mock";
|
||||
import type {
|
||||
AttributeValue,
|
||||
@@ -132,7 +132,7 @@ function buildTool(spec: TestTool): AgentTool {
|
||||
name: spec.name,
|
||||
label: spec.name,
|
||||
description: `test tool ${spec.name}`,
|
||||
parameters: z.object({ value: z.string().optional() }),
|
||||
parameters: type({ value: type("string").optional() }),
|
||||
intent: "omit",
|
||||
execute: async () => {
|
||||
if (spec.behavior === "throw") throw new Error(`${spec.name} boom`);
|
||||
@@ -145,7 +145,7 @@ function buildTool(spec: TestTool): AgentTool {
|
||||
name: spec.name,
|
||||
label: spec.name,
|
||||
description: `blocked tool ${spec.name}`,
|
||||
parameters: z.object({ value: z.string().optional() }),
|
||||
parameters: type({ value: type("string").optional() }),
|
||||
intent: "omit",
|
||||
execute: async () => ({ content: [{ type: "text", text: "should not run" }], details: {} }),
|
||||
} satisfies AgentTool;
|
||||
@@ -545,7 +545,7 @@ describe("skipped tools without spans", () => {
|
||||
name: "fast",
|
||||
label: "fast",
|
||||
description: "fast",
|
||||
parameters: z.object({ value: z.string().optional() }),
|
||||
parameters: type({ value: type("string").optional() }),
|
||||
intent: "omit",
|
||||
execute: async () => {
|
||||
fastDone = true;
|
||||
@@ -556,7 +556,7 @@ describe("skipped tools without spans", () => {
|
||||
name: "slow",
|
||||
label: "slow",
|
||||
description: "slow",
|
||||
parameters: z.object({ value: z.string().optional() }),
|
||||
parameters: type({ value: type("string").optional() }),
|
||||
intent: "omit",
|
||||
// concurrency: shared (default) — both run in parallel. Interruptible:
|
||||
// queued steering hard-aborts only interruptible waits; non-interruptible
|
||||
@@ -636,7 +636,7 @@ describe("regressions: agent loop telemetry/run summary", () => {
|
||||
name: "fast",
|
||||
label: "fast",
|
||||
description: "fast",
|
||||
parameters: z.object({ value: z.string().optional() }),
|
||||
parameters: type({ value: type("string").optional() }),
|
||||
intent: "omit",
|
||||
concurrency: "exclusive",
|
||||
execute: async () => {
|
||||
@@ -762,7 +762,7 @@ describe("regressions: agent loop telemetry/run summary", () => {
|
||||
name: "cyclic",
|
||||
label: "cyclic",
|
||||
description: "returns cyclic details",
|
||||
parameters: z.object({ value: z.string().optional() }),
|
||||
parameters: type({ value: type("string").optional() }),
|
||||
intent: "omit",
|
||||
execute: async () => ({
|
||||
content: [{ type: "text", text: "ok" }],
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Breaking Changes
|
||||
- Removed the `zod` dependency and the `z`/`ZodType` re-exports; tool schemas are omptype `type()` schemas, with zod-style authoring still available via `@oh-my-pi/omptype/zod`
|
||||
|
||||
## [17.2.9] - 2026-08-05
|
||||
|
||||
### Fixed
|
||||
|
||||
+15
-19
@@ -94,21 +94,18 @@ npm install @oh-my-pi/pi-ai
|
||||
## Quick Start
|
||||
|
||||
```typescript
|
||||
import { z, getModel, stream, complete, Context, Tool } from "@oh-my-pi/pi-ai";
|
||||
import { getModel, stream, complete, Context, Tool, type } from "@oh-my-pi/pi-ai";
|
||||
|
||||
// Fully typed with auto-complete support for both providers and models
|
||||
const model = getModel("openai", "gpt-4o-mini");
|
||||
|
||||
// Define tools with Zod schemas for type safety and validation
|
||||
// Define tools with omptype schemas for type safety and validation
|
||||
const tools: Tool[] = [
|
||||
{
|
||||
name: "get_time",
|
||||
description: "Get the current time",
|
||||
parameters: z.object({
|
||||
timezone: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional timezone (e.g., America/New_York)"),
|
||||
parameters: type({
|
||||
"timezone?": type("string").describe("Optional timezone (e.g., America/New_York)"),
|
||||
}),
|
||||
},
|
||||
];
|
||||
@@ -221,31 +218,30 @@ for (const block of response.content) {
|
||||
|
||||
## Tools
|
||||
|
||||
Tools enable LLMs to interact with external systems. This library uses **Zod** schemas for type-safe tool definitions with automatic validation. Schemas are converted to JSON Schema for providers as needed.
|
||||
Tools enable LLMs to interact with external systems. Omptype schemas provide type-safe definitions, runtime validation, and JSON Schema conversion for providers.
|
||||
|
||||
### Defining Tools
|
||||
|
||||
```typescript
|
||||
import { z, Tool } from "@oh-my-pi/pi-ai";
|
||||
import { type Tool, type } from "@oh-my-pi/pi-ai";
|
||||
|
||||
// Define tool parameters with Zod
|
||||
const weatherTool: Tool = {
|
||||
name: "get_weather",
|
||||
description: "Get current weather for a location",
|
||||
parameters: z.object({
|
||||
location: z.string().describe("City name or coordinates"),
|
||||
units: z.enum(["celsius", "fahrenheit"]).default("celsius"),
|
||||
parameters: type({
|
||||
location: type("string").describe("City name or coordinates"),
|
||||
units: type.enumerated("celsius", "fahrenheit").default("celsius"),
|
||||
}),
|
||||
};
|
||||
|
||||
const bookMeetingTool: Tool = {
|
||||
name: "book_meeting",
|
||||
description: "Schedule a meeting",
|
||||
parameters: z.object({
|
||||
title: z.string().min(1),
|
||||
startTime: z.string().describe("ISO 8601 date-time"),
|
||||
endTime: z.string().describe("ISO 8601 date-time"),
|
||||
attendees: z.array(z.email()).min(1),
|
||||
parameters: type({
|
||||
title: type("string").atLeastLength(1),
|
||||
startTime: type("string").describe("ISO 8601 date-time"),
|
||||
endTime: type("string").describe("ISO 8601 date-time"),
|
||||
attendees: type("string.email").array().atLeastLength(1),
|
||||
}),
|
||||
};
|
||||
```
|
||||
@@ -345,7 +341,7 @@ for await (const event of s) {
|
||||
|
||||
### Validating Tool Arguments
|
||||
|
||||
When using `agentLoop`, tool arguments are automatically validated against your Zod parameter schemas before execution. If validation fails, the error is returned to the model as a tool result, allowing it to retry.
|
||||
When using `agentLoop`, tool arguments are automatically validated against their omptype schemas before execution. Validation failures are returned to the model as tool results so it can retry.
|
||||
|
||||
When implementing your own tool execution loop with `stream()` or `complete()`, use `validateToolCall` to validate arguments before passing them to your tools:
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@
|
||||
"@oh-my-pi/omptype": "catalog:",
|
||||
"@oh-my-pi/pi-catalog": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"@oh-my-pi/pi-wire": "catalog:",
|
||||
"zod": "catalog:"
|
||||
"@oh-my-pi/pi-wire": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bufbuild/protoc-gen-es": "catalog:",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export { type Type, type } from "@oh-my-pi/omptype";
|
||||
export { type ZodType, z } from "zod/v4";
|
||||
export * from "./api-registry";
|
||||
export type * from "./auth-broker";
|
||||
export type { AuthGatewayBootOptions, ModelResolver } from "./auth-gateway/server";
|
||||
|
||||
@@ -36,7 +36,6 @@ import type {
|
||||
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
||||
import { isOpenAIModelId } from "@oh-my-pi/pi-catalog/identity/family";
|
||||
import type { Api, FetchImpl, KnownApi, Model, Provider, ThinkingBudgets, Usage } from "@oh-my-pi/pi-catalog/types";
|
||||
import type { ZodType, z } from "zod/v4";
|
||||
import type { ApiKey } from "./auth-retry";
|
||||
import type { BedrockOptions } from "./providers/amazon-bedrock";
|
||||
import type { AnthropicOptions } from "./providers/anthropic";
|
||||
@@ -1140,19 +1139,13 @@ export type TJsonSchema = Record<string, unknown>;
|
||||
/**
|
||||
* Schema type accepted by the {@link Tool} interface.
|
||||
*
|
||||
* Canonical authoring uses Zod or ArkType. Extension compat may supply a JSON
|
||||
* Schema object (including TypeBox static schema objects).
|
||||
* Canonical authoring uses ArkType. Extension compat may supply a JSON Schema
|
||||
* object (including TypeBox static schema objects).
|
||||
*/
|
||||
export type TSchema = ZodType | Type | TJsonSchema;
|
||||
export type TSchema = Type | TJsonSchema;
|
||||
|
||||
/** Resolve parameter types for tool execution / handlers. */
|
||||
export type Static<S> = S extends ZodType
|
||||
? z.infer<S>
|
||||
: S extends Type
|
||||
? S["infer"]
|
||||
: S extends { static: infer T }
|
||||
? T
|
||||
: unknown;
|
||||
export type Static<S> = S extends Type ? S["infer"] : S extends { static: infer T } ? T : unknown;
|
||||
|
||||
export interface ToolCallExample<TArgs = Record<string, unknown>> {
|
||||
caption?: string;
|
||||
|
||||
@@ -12,4 +12,3 @@ export * from "./strict-tool-validation";
|
||||
export * from "./types";
|
||||
export * from "./typescript";
|
||||
export * from "./wire";
|
||||
export * from "./zod-decontaminate";
|
||||
|
||||
@@ -24,7 +24,6 @@ import { isValidJsonSchema } from "./meta-validator";
|
||||
import { type DescriptionSpillFormat, spillToDescription } from "./spill";
|
||||
import { enter, epochNext, exit, once, stamp } from "./stamps";
|
||||
import { isJsonObject, isJsonObjectEmpty, type JsonObject } from "./types";
|
||||
import { decontaminateZodInstance } from "./zod-decontaminate";
|
||||
|
||||
export type ResidualSchemaIncompatibility = "type-array" | "type-null" | "nullable" | "combiners" | "not";
|
||||
|
||||
@@ -1069,8 +1068,7 @@ function hasResidualSchemaIncompatibilities(
|
||||
}
|
||||
|
||||
export function normalizeSchema(value: unknown, options: NormalizeSchemaOptions): unknown {
|
||||
const detoxified = decontaminateZodInstance(value);
|
||||
const upgraded = upgradeJsonSchemaTo202012(detoxified);
|
||||
const upgraded = upgradeJsonSchemaTo202012(value);
|
||||
const dereferenced = dereferenceJsonSchema(upgraded);
|
||||
let normalized = normalizeSchemaNode(dereferenced, {
|
||||
...options,
|
||||
|
||||
@@ -1,62 +1,21 @@
|
||||
/**
|
||||
* Compute the wire (JSON Schema) representation of a tool's parameters.
|
||||
*
|
||||
* Tools may author parameters in three shapes:
|
||||
* 1. Zod (canonical) — converted to JSON Schema on demand.
|
||||
* 2. ArkType — converted to JSON Schema via its native `toJsonSchema`.
|
||||
* 3. TypeBox / plain JSON Schema (legacy + extension compat) — upgraded to
|
||||
* draft 2020-12 without converting.
|
||||
*
|
||||
* All three are normalized at the boundary so providers and validators see the same
|
||||
* JSON Schema dialect.
|
||||
* Tools may author parameters as ArkType schemas or legacy TypeBox / plain JSON
|
||||
* Schema documents. Both are normalized at the boundary so providers and
|
||||
* validators see the same JSON Schema dialect.
|
||||
*/
|
||||
|
||||
import type { Type } from "@oh-my-pi/omptype";
|
||||
// We import the Zod *value* (z) for runtime APIs. Marker checks rely on the
|
||||
// `_zod` symbol that every Zod v4 schema instance carries.
|
||||
import { type ZodType, z } from "zod/v4";
|
||||
import type { Tool, TSchema } from "../../types";
|
||||
import { upgradeJsonSchemaTo202012 } from "./draft";
|
||||
import { stamp } from "./stamps";
|
||||
|
||||
/**
|
||||
* True when `value` is a live Zod schema instance.
|
||||
*
|
||||
* The check is stricter than "has a `_zod` property" because a JSON
|
||||
* round-trip preserves the `_zod` key as a plain object and would otherwise
|
||||
* fool the predicate — see issue #1101, where MCP servers ship
|
||||
* `JSON.stringify(zodSchemaInstance)` as a tool's `inputSchema` and the
|
||||
* resulting plain object then explodes `z.toJSONSchema` because the prototype
|
||||
* (and every Zod parsing method) is gone.
|
||||
*
|
||||
* Live Zod instances always carry a `.parse` function on the prototype;
|
||||
* impostors do not.
|
||||
*/
|
||||
export function isZodSchema(value: unknown): value is ZodType {
|
||||
return (
|
||||
typeof value === "object" &&
|
||||
value !== null &&
|
||||
// Zod v4 instances expose a `_zod` internal property with a `def` object.
|
||||
// Tagging on this marker keeps the check stable across Zod minor versions.
|
||||
// (`_zod` is part of Zod's documented internal contract used by introspection.)
|
||||
// We avoid checking constructor name because Zod ships multiple variants
|
||||
// (`ZodObject`, `ZodOptional`, etc.) and a tagged-union style check would
|
||||
// have to enumerate them all.
|
||||
"_zod" in value &&
|
||||
typeof (value as { _zod?: { def?: unknown } })._zod === "object" &&
|
||||
// Reject JSON-roundtripped objects that kept the `_zod` key but lost the
|
||||
// prototype. Real instances have `.parse` on the prototype chain.
|
||||
typeof (value as { parse?: unknown }).parse === "function"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* True when `value` is a live ArkType schema instance.
|
||||
*
|
||||
* ArkType schemas are callable functions carrying `toJsonSchema`/`assert`
|
||||
* methods. Zod v4 instances are non-callable objects (keyed off `_zod`), and
|
||||
* raw JSON Schema is a plain object — the three are disjoint. We deliberately
|
||||
* avoid the Standard Schema `~standard` marker because Zod v4 implements it too.
|
||||
* methods, while raw JSON Schema is a plain object.
|
||||
*/
|
||||
export function isArkSchema(value: unknown): value is Type {
|
||||
return (
|
||||
@@ -149,41 +108,17 @@ function arkJsonAstToWire(value: unknown): unknown {
|
||||
}
|
||||
|
||||
/** Symbol-stamped caches keyed by schema object identity. */
|
||||
const kZodWireSchema = Symbol("pi.schema.zod.wire");
|
||||
const kJsonWireSchema = Symbol("pi.schema.json.wire");
|
||||
const kArkWireSchema = Symbol("pi.schema.ark.wire");
|
||||
const kStrippedSchema = Symbol("pi.schema.descriptions.stripped");
|
||||
|
||||
/**
|
||||
* Post-process Zod-emitted JSON Schema so it matches the wire shape providers
|
||||
* already expect from TypeBox-authored tools:
|
||||
*
|
||||
* - Drop the `$schema` URL (providers parse the body, not the metadata).
|
||||
* - Make fields with a `default` non-required (TypeBox/JSON-Schema semantics
|
||||
* treat defaulted fields as optional; Zod inverts this and keeps them
|
||||
* required at the input boundary, then materializes the default).
|
||||
* - Strip the noisy safe-integer bounds Zod injects for `z.number().int()`.
|
||||
*
|
||||
* The empty-schema normalization (`{}` → `true`, see `normalizeEmptySchemas`)
|
||||
* runs separately from `toolWireSchema` so both Zod and TypeBox tools get it.
|
||||
*/
|
||||
function postProcess(schema: Record<string, unknown>): Record<string, unknown> {
|
||||
delete schema.$schema;
|
||||
walk(schema, true);
|
||||
normalizeArkPropertyComments(schema);
|
||||
normalizeEmptySchemas(schema);
|
||||
return schema;
|
||||
}
|
||||
|
||||
function postProcessJsonSchema(schema: Record<string, unknown>): Record<string, unknown> {
|
||||
walk(schema, false);
|
||||
walk(schema);
|
||||
normalizeArkPropertyComments(schema);
|
||||
normalizeEmptySchemas(schema);
|
||||
return schema;
|
||||
}
|
||||
|
||||
const SAFE_INTEGER_MAX = Number.MAX_SAFE_INTEGER;
|
||||
const SAFE_INTEGER_MIN = Number.MIN_SAFE_INTEGER;
|
||||
const NULLABLE_SCALAR_TYPES = new Set(["string", "number", "integer", "boolean"]);
|
||||
|
||||
const SCHEMA_DEFINING_SIBLING_KEYS = new Set([
|
||||
@@ -226,11 +161,6 @@ function isNullVariant(schema: Record<string, unknown>): boolean {
|
||||
function isScalarVariant(schema: Record<string, unknown>): schema is Record<string, unknown> & { type: string } {
|
||||
return typeof schema.type === "string" && NULLABLE_SCALAR_TYPES.has(schema.type);
|
||||
}
|
||||
|
||||
function hasIntegerType(type: unknown): boolean {
|
||||
return type === "integer" || (Array.isArray(type) && type.includes("integer"));
|
||||
}
|
||||
|
||||
function copyNullableScalarConstraints(schema: Record<string, unknown>, scalarVariant: Record<string, unknown>): void {
|
||||
for (const key in scalarVariant) {
|
||||
if (key === "type" || key === "enum" || key === "const" || Object.hasOwn(schema, key)) continue;
|
||||
@@ -455,9 +385,9 @@ function collapseConstUnionAnyOf(obj: Record<string, unknown>): void {
|
||||
}
|
||||
}
|
||||
|
||||
function walk(node: unknown, zodCleanup: boolean): void {
|
||||
function walk(node: unknown): void {
|
||||
if (Array.isArray(node)) {
|
||||
for (const child of node) walk(child, zodCleanup);
|
||||
for (const child of node) walk(child);
|
||||
return;
|
||||
}
|
||||
if (!node || typeof node !== "object") return;
|
||||
@@ -465,48 +395,16 @@ function walk(node: unknown, zodCleanup: boolean): void {
|
||||
rewriteNullableScalarAnyOf(obj);
|
||||
inferBareEnumScalarType(obj);
|
||||
collapseConstUnionAnyOf(obj);
|
||||
|
||||
if (zodCleanup) {
|
||||
// Drop noise injected for `z.number().int()`.
|
||||
if (hasIntegerType(obj.type)) {
|
||||
if (obj.minimum === SAFE_INTEGER_MIN) delete obj.minimum;
|
||||
if (obj.maximum === SAFE_INTEGER_MAX) delete obj.maximum;
|
||||
}
|
||||
|
||||
// Make defaulted properties non-required.
|
||||
if (Array.isArray(obj.required) && obj.properties && typeof obj.properties === "object") {
|
||||
const properties = obj.properties as Record<string, unknown>;
|
||||
const required = obj.required as string[];
|
||||
const filtered = required.filter(name => {
|
||||
const propertySchema = properties[name];
|
||||
if (!propertySchema || typeof propertySchema !== "object") return true;
|
||||
return !("default" in (propertySchema as Record<string, unknown>));
|
||||
});
|
||||
if (filtered.length !== required.length) {
|
||||
if (filtered.length === 0) {
|
||||
delete obj.required;
|
||||
} else {
|
||||
obj.required = filtered;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const k in obj) walk(obj[k], zodCleanup);
|
||||
for (const k in obj) walk(obj[k]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize `{}` (empty JSON Schema = `z.unknown()` / unconstrained value) to
|
||||
* boolean `true` in every schema-valued position. JSON Schema draft 2020-12
|
||||
* §4.3.1: `{}` and `true` are semantically equivalent ("any JSON value").
|
||||
* Grammar-constrained samplers (llama.cpp, etc.) treat the object form as
|
||||
* "generate an empty object" rather than "any JSON value", causing open-typed
|
||||
* fields like `extra.title` (from `z.record(z.string(), z.unknown())`) to
|
||||
* always emit `{}` instead of the intended string/number/etc. (issue #1179).
|
||||
* Normalize `{}` (an unconstrained schema) to boolean `true` in every
|
||||
* schema-valued position. JSON Schema draft 2020-12 §4.3.1 defines them as
|
||||
* semantically equivalent. Grammar-constrained samplers often treat the object
|
||||
* form as "generate an empty object" rather than "any JSON value".
|
||||
*
|
||||
* Mutates in place. Provider-agnostic — applied to every tool wire schema so
|
||||
* Anthropic, Google, OpenAI, Ollama, Bedrock, and Cursor all see the
|
||||
* normalized form, regardless of whether the source was Zod or TypeBox.
|
||||
* Mutates in place and applies to every tool wire schema.
|
||||
*/
|
||||
export function normalizeEmptySchemas(node: unknown): void {
|
||||
if (Array.isArray(node)) {
|
||||
@@ -539,23 +437,10 @@ export function normalizeEmptySchemas(node: unknown): void {
|
||||
for (const k in obj) normalizeEmptySchemas(obj[k]);
|
||||
}
|
||||
|
||||
/** Convert a Zod schema into the JSON Schema shape providers consume. */
|
||||
export function zodToWireSchema(schema: ZodType): Record<string, unknown> {
|
||||
return stamp(schema, kZodWireSchema, s => {
|
||||
// `target: "draft-2020-12"` matches what Anthropic's `input_schema` validator
|
||||
// requires out of the box; our other provider sanitizers (OpenAI strict,
|
||||
// Google, Anthropic CCA) already handle the superset structurally.
|
||||
const raw = z.toJSONSchema(s, { target: "draft-2020-12" }) as Record<string, unknown>;
|
||||
return postProcess(raw);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively set `additionalProperties: false` on declared object nodes so the
|
||||
* model-facing wire matches Zod's closed emission. Only nodes that declare
|
||||
* `properties` and carry neither `additionalProperties` nor `patternProperties`
|
||||
* are closed — open record/index nodes (which already carry one of those, e.g.
|
||||
* `additionalProperties: true` after empty-schema normalization) stay open.
|
||||
* model-facing wire is closed. Only nodes that declare `properties` and carry
|
||||
* neither `additionalProperties` nor `patternProperties` are closed.
|
||||
*
|
||||
* Traverses only schema-valued positions via the shared traversal-key constants
|
||||
* so it never descends into `default`/`examples`/`enum`/`const` instance data.
|
||||
@@ -665,14 +550,6 @@ function pruneArkUndefinedUnionBranches(node: unknown): void {
|
||||
|
||||
/**
|
||||
* Convert an ArkType schema into the JSON Schema shape providers consume.
|
||||
*
|
||||
* Mirrors {@link zodToWireSchema}: emit draft-2020-12, drop the `$schema`
|
||||
* metadata, run the JSON-schema post-process (NOT the Zod-only cleanup), then
|
||||
* close declared objects so the wire is `additionalProperties: false` like Zod.
|
||||
*
|
||||
* The `fallback` degrades any un-emittable node (a `.narrow()` predicate or a
|
||||
* morph) to its underlying base schema instead of throwing — matching Zod,
|
||||
* whose `.refine()`/`.transform()` likewise never appear in the wire schema.
|
||||
*/
|
||||
export function arkToWireSchema(schema: Type): Record<string, unknown> {
|
||||
return stamp(schema, kArkWireSchema, s => {
|
||||
@@ -687,16 +564,12 @@ export function arkToWireSchema(schema: Type): Record<string, unknown> {
|
||||
|
||||
/**
|
||||
* Resolve a tool's parameters to a JSON Schema object suitable for sending
|
||||
* over the wire. Zod schemas are converted (and cached); legacy TypeBox / raw
|
||||
* JSON Schema parameters are upgraded to draft 2020-12 (and cached).
|
||||
*
|
||||
* Zod schemas also receive Zod-artifact cleanup; both branches normalize
|
||||
* schema-valued positions and nullable scalar unions.
|
||||
* over the wire. ArkType schemas are converted and cached; legacy TypeBox /
|
||||
* raw JSON Schema parameters are upgraded to draft 2020-12 and cached.
|
||||
*/
|
||||
export function toolWireSchema(tool: Tool): Record<string, unknown> {
|
||||
const params: TSchema = tool.parameters;
|
||||
if (isArkSchema(params)) return arkToWireSchema(params);
|
||||
if (isZodSchema(params)) return zodToWireSchema(params);
|
||||
return stamp(params as Record<string, unknown>, kJsonWireSchema, p => {
|
||||
const raw = isArkJsonAst(p) ? arkJsonAstToWire(p) : p;
|
||||
const upgraded = upgradeJsonSchemaTo202012(raw) as Record<string, unknown>;
|
||||
|
||||
@@ -1,331 +0,0 @@
|
||||
/**
|
||||
* Defensive rewrite for nodes that look like `JSON.stringify(zodSchemaInstance)`
|
||||
* output rather than JSON Schema. MCP servers using Zod 4 sometimes ship a
|
||||
* serialised schema instance directly as a tool's `inputSchema`, because the
|
||||
* fields Zod surfaces on its instances (`type`, `enum`, `options`, `def`) shadow
|
||||
* (and clash with) JSON Schema keywords. The resulting payload is neither valid
|
||||
* Zod nor valid JSON Schema 2020-12 and Anthropic's strict validator rejects
|
||||
* the whole tool list.
|
||||
*
|
||||
* Symptoms we've observed (gitnexus_impact.direction):
|
||||
* {
|
||||
* def: { type: "enum", entries: { upstream: "upstream", ... } },
|
||||
* type: "enum", // <- invalid `type` value
|
||||
* enum: { upstream: "upstream", ... }, // <- `enum` MUST be an array
|
||||
* options: ["upstream", "downstream"],
|
||||
* }
|
||||
*
|
||||
* This module recognises the shape (`def.type === node.type` and `def.type` is
|
||||
* a known Zod kind) and rewrites it to clean JSON Schema where deterministic.
|
||||
* For Zod kinds we don't fully model, we strip the toxic siblings (`def`,
|
||||
* `options`, object-shaped `enum`) and drop an invalid `type` so the remainder
|
||||
* passes meta-schema validation as a permissive node.
|
||||
*
|
||||
* Pure / identity-preserving: returns the input reference when nothing changes.
|
||||
*/
|
||||
|
||||
import { isJsonObject, type JsonObject } from "./types";
|
||||
|
||||
const VALID_JSON_SCHEMA_TYPES: Record<string, true> = {
|
||||
string: true,
|
||||
number: true,
|
||||
integer: true,
|
||||
boolean: true,
|
||||
object: true,
|
||||
array: true,
|
||||
null: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Known Zod 4 schema kinds as surfaced on `_def.type` / `.type`. Matching this
|
||||
* set (rather than just "has `def`") is what keeps us from rewriting legitimate
|
||||
* JSON Schemas that happen to use `def` as a property name.
|
||||
*/
|
||||
const ZOD_KINDS: Record<string, true> = {
|
||||
string: true,
|
||||
number: true,
|
||||
int: true,
|
||||
boolean: true,
|
||||
bigint: true,
|
||||
null: true,
|
||||
undefined: true,
|
||||
void: true,
|
||||
any: true,
|
||||
unknown: true,
|
||||
never: true,
|
||||
date: true,
|
||||
symbol: true,
|
||||
nan: true,
|
||||
enum: true,
|
||||
literal: true,
|
||||
object: true,
|
||||
array: true,
|
||||
tuple: true,
|
||||
record: true,
|
||||
map: true,
|
||||
set: true,
|
||||
union: true,
|
||||
discriminatedUnion: true,
|
||||
intersection: true,
|
||||
lazy: true,
|
||||
promise: true,
|
||||
function: true,
|
||||
file: true,
|
||||
custom: true,
|
||||
template_literal: true,
|
||||
optional: true,
|
||||
nullable: true,
|
||||
default: true,
|
||||
prefault: true,
|
||||
catch: true,
|
||||
pipe: true,
|
||||
transform: true,
|
||||
brand: true,
|
||||
readonly: true,
|
||||
success: true,
|
||||
nonoptional: true,
|
||||
};
|
||||
|
||||
const ZOD_SCALAR_TO_JSON_TYPE: Record<string, string> = {
|
||||
string: "string",
|
||||
number: "number",
|
||||
int: "integer",
|
||||
boolean: "boolean",
|
||||
null: "null",
|
||||
bigint: "string",
|
||||
date: "string",
|
||||
nan: "number",
|
||||
};
|
||||
|
||||
const ZOD_NOISE_KEYS: Record<string, true> = {
|
||||
def: true,
|
||||
options: true,
|
||||
_zod: true,
|
||||
checks: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* JSON Schema keywords where `null` is a legal value (literal payload positions).
|
||||
* Anywhere else, a `null`-valued key is a meta-schema violation — Zod scalars
|
||||
* leak `format: null`, `minLength: null`, etc. that we have to scrub.
|
||||
*/
|
||||
const KEYS_THAT_ACCEPT_NULL: Record<string, true> = {
|
||||
default: true,
|
||||
const: true,
|
||||
examples: true,
|
||||
};
|
||||
|
||||
function isZodLeak(node: JsonObject): boolean {
|
||||
const def = node.def;
|
||||
if (!isJsonObject(def)) return false;
|
||||
const defType = def.type;
|
||||
if (typeof defType !== "string" || !ZOD_KINDS[defType]) return false;
|
||||
// Both surface and inner `.type` must agree — Zod always mirrors `_def.type`
|
||||
// onto the instance, so this is a near-zero false-positive guard.
|
||||
return node.type === defType;
|
||||
}
|
||||
|
||||
function inferTypeFromValues(values: readonly unknown[]): string {
|
||||
if (values.length === 0) return "string";
|
||||
const first = values[0];
|
||||
if (typeof first === "number") return Number.isInteger(first) ? "integer" : "number";
|
||||
if (typeof first === "boolean") return "boolean";
|
||||
if (first === null) return "null";
|
||||
return "string";
|
||||
}
|
||||
|
||||
function unwrapInnerSchema(def: JsonObject): unknown {
|
||||
// Zod uses different fields depending on the wrapper:
|
||||
// optional/nullable/readonly/brand/default → `innerType`
|
||||
// pipe → `in` (or `out`)
|
||||
// lazy → `getter` (a function — gone after JSON.stringify); fall back to {}
|
||||
return def.innerType ?? def.in ?? def.out ?? def.schema ?? def.element ?? {};
|
||||
}
|
||||
|
||||
function copyWithoutNoise(node: JsonObject): JsonObject {
|
||||
const out: JsonObject = {};
|
||||
for (const key in node) {
|
||||
if (ZOD_NOISE_KEYS[key]) continue;
|
||||
const value = node[key];
|
||||
if (value === null && !KEYS_THAT_ACCEPT_NULL[key]) continue;
|
||||
out[key] = value;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
||||
const def = node.def as JsonObject;
|
||||
const kind = def.type as string;
|
||||
|
||||
switch (kind) {
|
||||
case "enum": {
|
||||
// Prefer node.options (array form Zod exposes) → def.entries values →
|
||||
// object-shaped node.enum values. All three carry the same data.
|
||||
const optionsArray = Array.isArray(node.options) ? (node.options as unknown[]) : null;
|
||||
const entries = isJsonObject(def.entries) ? Object.values(def.entries) : null;
|
||||
const enumObj = isJsonObject(node.enum) ? Object.values(node.enum) : null;
|
||||
const values = optionsArray ?? entries ?? enumObj ?? [];
|
||||
return { type: inferTypeFromValues(values), enum: values };
|
||||
}
|
||||
|
||||
case "literal": {
|
||||
const values = Array.isArray(def.values) ? (def.values as unknown[]) : [];
|
||||
if (values.length === 1) {
|
||||
return { const: values[0] };
|
||||
}
|
||||
if (values.length > 1) {
|
||||
return { type: inferTypeFromValues(values), enum: values };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
case "union":
|
||||
case "discriminatedUnion": {
|
||||
const arms = Array.isArray(def.options)
|
||||
? (def.options as unknown[])
|
||||
: Array.isArray(node.options)
|
||||
? (node.options as unknown[])
|
||||
: [];
|
||||
return { anyOf: arms.map(x => walk(x, seen)) };
|
||||
}
|
||||
|
||||
case "intersection": {
|
||||
return {
|
||||
allOf: [walk(def.left, seen), walk(def.right, seen)],
|
||||
};
|
||||
}
|
||||
|
||||
case "array": {
|
||||
return { type: "array", items: walk(def.element, seen) };
|
||||
}
|
||||
|
||||
case "set": {
|
||||
const element = def.valueType ?? def.element;
|
||||
return { type: "array", uniqueItems: true, items: walk(element, seen) };
|
||||
}
|
||||
|
||||
case "tuple": {
|
||||
const items = Array.isArray(def.items) ? (def.items as unknown[]) : [];
|
||||
const out: JsonObject = { type: "array", prefixItems: items.map(x => walk(x, seen)) };
|
||||
const rest = def.rest;
|
||||
if (rest != null) out.items = walk(rest, seen);
|
||||
return out;
|
||||
}
|
||||
|
||||
case "record":
|
||||
case "map": {
|
||||
return { type: "object", additionalProperties: walk(def.valueType, seen) };
|
||||
}
|
||||
|
||||
case "object": {
|
||||
const shape = isJsonObject(def.shape) ? def.shape : ({} as JsonObject);
|
||||
const properties: JsonObject = {};
|
||||
const required: string[] = [];
|
||||
for (const key in shape) {
|
||||
const inner = walk(shape[key], seen);
|
||||
properties[key] = inner;
|
||||
if (!isOptionalEntry(shape[key])) required.push(key);
|
||||
}
|
||||
const out: JsonObject = { type: "object", properties };
|
||||
if (required.length > 0) out.required = required;
|
||||
return out;
|
||||
}
|
||||
|
||||
case "nonoptional":
|
||||
case "optional":
|
||||
case "nullable":
|
||||
case "default":
|
||||
case "prefault":
|
||||
case "catch":
|
||||
case "readonly":
|
||||
case "brand":
|
||||
case "lazy":
|
||||
case "pipe":
|
||||
case "transform": {
|
||||
const inner = walk(unwrapInnerSchema(def), seen);
|
||||
if (kind === "nullable" && isJsonObject(inner)) {
|
||||
if (typeof inner.type === "string") {
|
||||
return { ...inner, type: [inner.type, "null"] };
|
||||
}
|
||||
if (Array.isArray(inner.type)) {
|
||||
return (inner.type as string[]).includes("null")
|
||||
? inner
|
||||
: { ...inner, type: [...(inner.type as string[]), "null"] };
|
||||
}
|
||||
// anyOf / allOf / $ref shapes — no scalar `type` field
|
||||
return { anyOf: [inner, { type: "null" }] };
|
||||
}
|
||||
return inner;
|
||||
}
|
||||
|
||||
default: {
|
||||
// Best-effort: drop the noise, map the kind to a JSON Schema type if
|
||||
// we know one, otherwise drop `type` so the node validates as
|
||||
// permissive.
|
||||
const cleaned = copyWithoutNoise(node);
|
||||
const mapped = ZOD_SCALAR_TO_JSON_TYPE[kind];
|
||||
if (mapped) {
|
||||
cleaned.type = mapped;
|
||||
} else if (typeof cleaned.type === "string" && !VALID_JSON_SCHEMA_TYPES[cleaned.type]) {
|
||||
delete cleaned.type;
|
||||
}
|
||||
// Object-shaped `enum` survives as a noise field — remove if present.
|
||||
if (cleaned.enum !== undefined && !Array.isArray(cleaned.enum)) {
|
||||
delete cleaned.enum;
|
||||
}
|
||||
return cleaned;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isOptionalEntry(value: unknown): boolean {
|
||||
if (!isJsonObject(value)) return false;
|
||||
if (!isZodLeak(value)) return false;
|
||||
const kind = (value.def as JsonObject).type;
|
||||
return kind === "optional" || kind === "default" || kind === "prefault";
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks a JSON value and rewrites every Zod-instance-shaped node into clean
|
||||
* JSON Schema 2020-12. Identity-preserving when no rewrite fires. Tolerates
|
||||
* self-referential graphs — a revisited node returns as-is.
|
||||
*/
|
||||
export function decontaminateZodInstance(value: unknown): unknown {
|
||||
return walk(value, new WeakSet());
|
||||
}
|
||||
|
||||
function walk(value: unknown, seen: WeakSet<object>): unknown {
|
||||
if (Array.isArray(value)) {
|
||||
if (seen.has(value)) return value;
|
||||
seen.add(value);
|
||||
let changed = false;
|
||||
const out = value.map(entry => {
|
||||
const rewritten = walk(entry, seen);
|
||||
if (rewritten !== entry) changed = true;
|
||||
return rewritten;
|
||||
});
|
||||
return changed ? out : value;
|
||||
}
|
||||
if (!isJsonObject(value)) return value;
|
||||
if (seen.has(value)) return value;
|
||||
seen.add(value);
|
||||
|
||||
if (isZodLeak(value)) {
|
||||
// Rewrite the node itself, then recurse into the rewrite so any nested
|
||||
// Zod-instance children get cleaned in the same pass.
|
||||
const rewritten = rewriteZodNode(value, seen);
|
||||
return rewritten === value ? value : walk(rewritten, seen);
|
||||
}
|
||||
|
||||
// Plain JSON Schema node: recurse into children, preserving identity when
|
||||
// nothing under us changed.
|
||||
let changed = false;
|
||||
const out: JsonObject = {};
|
||||
for (const key in value) {
|
||||
const child = value[key];
|
||||
const rewritten = walk(child, seen);
|
||||
if (rewritten !== child) changed = true;
|
||||
out[key] = rewritten;
|
||||
}
|
||||
return changed ? out : value;
|
||||
}
|
||||
@@ -1,22 +1,10 @@
|
||||
/**
|
||||
* Tool-call argument validation pipeline.
|
||||
*
|
||||
* Tools may declare their parameters as either Zod schemas (canonical) or
|
||||
* plain JSON Schema (legacy / extensions). This module is the single
|
||||
* entrypoint the agent calls before dispatching a tool — it:
|
||||
*
|
||||
* 1. Builds (or fetches from cache) a `ValidationContext` for the tool —
|
||||
* the Zod schema if available plus the equivalent wire JSON Schema, or
|
||||
* just the JSON Schema for non-Zod tools.
|
||||
* 2. Normalizes LLM quirks (null / "null" → omit-or-default substitution)
|
||||
* against the JSON Schema before validation.
|
||||
* 3. Validates with the Zod or JSON-Schema validator.
|
||||
* 4. On failure, walks the resulting issues and coerces common LLM type
|
||||
* drift (JSON-stringified values, boolean/number/string scalar drift),
|
||||
* drops unrecognized keys, and retries up to `MAX_COERCION_PASSES` times.
|
||||
* 5. Throws a formatted error if reconciliation fails; otherwise returns
|
||||
* the parsed arguments with original unknown root fields preserved (so
|
||||
* hallucinated top-level keys still surface to the caller).
|
||||
* Tools may declare ArkType schemas or plain JSON Schema. This module builds a
|
||||
* cached validation context, normalizes common LLM quirks against the wire
|
||||
* schema, validates, performs conservative schema-directed coercions, and
|
||||
* returns parsed arguments while preserving unknown root fields.
|
||||
*
|
||||
* The goal is to be conservative: every coercion is a structural rewrite that
|
||||
* keeps the schema in charge of acceptance — we never invent values, only
|
||||
@@ -25,8 +13,6 @@
|
||||
|
||||
import { type Type, type } from "@oh-my-pi/omptype";
|
||||
import { structuredCloneJSON } from "@oh-my-pi/pi-utils";
|
||||
import type { ZodType } from "zod/v4";
|
||||
import type { $ZodIssue as ZodIssue } from "zod/v4/core";
|
||||
import * as AIError from "../error";
|
||||
import type { Tool, ToolCall } from "../types";
|
||||
import { upgradeJsonSchemaTo202012 } from "./schema/draft";
|
||||
@@ -36,7 +22,7 @@ import {
|
||||
validateJsonSchemaValue,
|
||||
} from "./schema/json-schema-validator";
|
||||
import { stamp } from "./schema/stamps";
|
||||
import { arkToWireSchema, isArkSchema, isZodSchema, zodToWireSchema } from "./schema/wire";
|
||||
import { arkToWireSchema, isArkSchema } from "./schema/wire";
|
||||
|
||||
// ============================================================================
|
||||
// Type Coercion Utilities
|
||||
@@ -47,12 +33,8 @@ import { arkToWireSchema, isArkSchema, isZodSchema, zodToWireSchema } from "./sc
|
||||
// `"[1, 2, 3]"`, a boolean as `"yes"` or `1`, or a string field as a structured
|
||||
// object that should be embedded verbatim.
|
||||
//
|
||||
// Rather than rejecting these outright, we attempt automatic coercion:
|
||||
// 1. Validate against the tool's schema (Zod, derived from TypeBox when the
|
||||
// tool was authored with TypeBox).
|
||||
// 2. For each type error, perform only the schema-directed rewrite that
|
||||
// matches the expected type.
|
||||
// 3. Re-validate the full argument object after each coercion pass.
|
||||
// Rather than rejecting these outright, validate against the declared schema
|
||||
// and perform only schema-directed rewrites for reported type errors.
|
||||
//
|
||||
// This is intentionally conservative: each rewrite is small and validation
|
||||
// remains the source of truth for whether the result is accepted.
|
||||
@@ -528,13 +510,11 @@ function tryParseJsonForTypes(value: string, expectedTypes: string[], depth = 0)
|
||||
// JSON Pointer Utilities (RFC 6901)
|
||||
// ============================================================================
|
||||
//
|
||||
// Internally we still address error locations using JSON Pointer syntax
|
||||
// (e.g., `/foo/0/bar`). These utilities let coercion read and write values at
|
||||
// those paths regardless of whether the original error came from Zod or
|
||||
// from JSON-Schema-shaped normalization.
|
||||
// Error locations use JSON Pointer syntax so coercion can read and write
|
||||
// validator-reported paths uniformly.
|
||||
// ============================================================================
|
||||
|
||||
/** Encode a structured Zod issue path as a JSON Pointer. */
|
||||
/** Encode a structured issue path as a JSON Pointer. */
|
||||
function pathToPointer(path: ReadonlyArray<PropertyKey>): string {
|
||||
if (path.length === 0) return "";
|
||||
return `/${path.map(seg => String(seg).replace(/~/g, "~0").replace(/\//g, "~1")).join("/")}`;
|
||||
@@ -814,11 +794,8 @@ function normalizeOptionalNullsForSchema(
|
||||
// with non-null unknown values are left intact so genuine schema mistakes
|
||||
// still surface as validation errors.
|
||||
//
|
||||
// At the ROOT level we deliberately keep unknown null-valued keys intact:
|
||||
// Zod-emitted wire schemas always set `additionalProperties: false`, but the
|
||||
// post-validation `preserveUnknownRootFields` pass re-attaches root extras
|
||||
// so callers can observe (and reject) hallucinated fields. Stripping here
|
||||
// would erase the field before that snapshot, hiding the rejection signal.
|
||||
// At the root level unknown null-valued keys stay intact; the
|
||||
// post-validation `preserveUnknownRootFields` pass re-attaches root extras.
|
||||
if (!isRoot && schemaObject.additionalProperties === false) {
|
||||
const knownKeys = new Set(Object.keys(properties));
|
||||
for (const key of Object.keys(nextValue)) {
|
||||
@@ -1049,9 +1026,8 @@ function trimIdentifierStringLeaf(input: unknown): unknown {
|
||||
|
||||
/**
|
||||
* Recursively strip trailing line terminators from string values whose property
|
||||
* key matches {@link IDENTIFIER_STRING_KEYS}. Runs by property name only
|
||||
* (schema-agnostic) so it fires uniformly across Zod, ArkType, and plain JSON
|
||||
* Schema tools while preserving nested payloads under content-carrying keys.
|
||||
* key matches {@link IDENTIFIER_STRING_KEYS}. Runs by property name only so it
|
||||
* fires uniformly across ArkType and plain JSON Schema tools.
|
||||
*/
|
||||
function normalizeIdentifierStringWhitespace(value: unknown): { value: unknown; changed: boolean } {
|
||||
if (Array.isArray(value)) {
|
||||
@@ -1254,12 +1230,9 @@ function parsedArrayMatchesArrayBranch(schema: Record<string, unknown>, value: u
|
||||
|
||||
/**
|
||||
* Pre-validation normalization: when a schema field accepts BOTH `string` and
|
||||
* `array`, providers that double-serialize tool arguments (e.g. Z.AI / GLM)
|
||||
* deliver array values as JSON-encoded strings like `'["a","b"]'`. Zod's
|
||||
* `union([string, array])` happily accepts that string against the string
|
||||
* branch, so the type-error driven coercion in {@link coerceArgsFromIssues}
|
||||
* never fires, and downstream tools treat the literal `["a","b"]` as a path
|
||||
* (silently producing zero matches or glob parse errors).
|
||||
* `array`, providers that double-serialize tool arguments can deliver array
|
||||
* values as JSON-encoded strings like `'["a","b"]'`. A string-or-array union
|
||||
* accepts that value against the string branch before issue-driven coercion.
|
||||
*
|
||||
* Walk the schema; when both shapes are accepted AND the incoming value is a
|
||||
* JSON-array-shaped string, substitute the parsed array only if it validates
|
||||
@@ -1387,9 +1360,7 @@ function normalizeSingleStringField(schema: unknown, value: unknown): { value: u
|
||||
return { value, changed: false };
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Zod issue → coercion bridge
|
||||
// ============================================================================
|
||||
// Validation issue → coercion bridge
|
||||
|
||||
interface FlatIssue {
|
||||
keyword: "type" | "unrecognized" | "other";
|
||||
@@ -1398,81 +1369,6 @@ interface FlatIssue {
|
||||
unionBranch: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the Zod expected-type marker into the JSON-Schema type name our
|
||||
* coercion helpers already understand.
|
||||
*/
|
||||
function mapZodExpectedToJsonSchemaType(expected: unknown): string | null {
|
||||
if (typeof expected !== "string") return null;
|
||||
switch (expected) {
|
||||
case "string":
|
||||
case "number":
|
||||
case "boolean":
|
||||
case "array":
|
||||
case "object":
|
||||
case "null":
|
||||
return expected;
|
||||
case "record":
|
||||
return "object";
|
||||
case "int":
|
||||
case "bigint":
|
||||
return "integer";
|
||||
case "nan":
|
||||
return "number";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten Zod issues into a list of (path, expected-types) records suitable
|
||||
* for the coercion pass. Recurses through `invalid_union` so each inner
|
||||
* candidate produces independent coercion attempts.
|
||||
*/
|
||||
function flattenIssues(issues: ReadonlyArray<ZodIssue>): FlatIssue[] {
|
||||
const out: FlatIssue[] = [];
|
||||
const walk = (issue: ZodIssue, prefix: ReadonlyArray<PropertyKey>, unionBranch: boolean): void => {
|
||||
const fullPath = prefix.length === 0 ? issue.path : [...prefix, ...issue.path];
|
||||
if (issue.code === "invalid_type") {
|
||||
const mapped = mapZodExpectedToJsonSchemaType((issue as { expected?: unknown }).expected);
|
||||
if (mapped) {
|
||||
out.push({ keyword: "type", instancePath: pathToPointer(fullPath), expectedTypes: [mapped], unionBranch });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (issue.code === "unrecognized_keys") {
|
||||
const keys = (issue as { keys?: ReadonlyArray<string> }).keys ?? [];
|
||||
for (const key of keys) {
|
||||
out.push({
|
||||
keyword: "unrecognized",
|
||||
instancePath: pathToPointer([...fullPath, key]),
|
||||
expectedTypes: [],
|
||||
unionBranch,
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (issue.code === "invalid_union") {
|
||||
const inner = (issue as unknown as { errors?: ReadonlyArray<ReadonlyArray<ZodIssue>> }).errors;
|
||||
if (inner) {
|
||||
// A union-branch issue only competes with a sibling branch when it
|
||||
// sits at the union node's own path. Issues whose own path is
|
||||
// non-empty live on a deeper field that an already-identified
|
||||
// branch owns, so the singleton-array repair should still apply.
|
||||
for (const branch of inner) {
|
||||
for (const child of branch) {
|
||||
walk(child, fullPath, child.path.length === 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
out.push({ keyword: "other", instancePath: pathToPointer(fullPath), expectedTypes: [], unionBranch });
|
||||
};
|
||||
for (const issue of issues) walk(issue, [], false);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repair issues raised by the validator before we surface them to the caller.
|
||||
*
|
||||
@@ -1482,11 +1378,9 @@ function flattenIssues(issues: ReadonlyArray<ZodIssue>): FlatIssue[] {
|
||||
* accept boolean spellings, stringify non-null values for string fields,
|
||||
* map booleans to numeric 0/1, and wrap singleton array values for non-union
|
||||
* array expectations.
|
||||
* - **unrecognized**: when a strict object received an extra key (Zod's
|
||||
* `unrecognized_keys` or JSON Schema's `additionalProperties: false`),
|
||||
* drop that key so re-validation succeeds. This effectively coerces every
|
||||
* object schema to loose semantics recursively without rebuilding the
|
||||
* underlying Zod tree.
|
||||
* - **unrecognized**: when a closed object received an extra key
|
||||
* (`additionalProperties: false`), drop that key so re-validation succeeds.
|
||||
* This effectively coerces object schemas to loose semantics recursively.
|
||||
*
|
||||
* The function is safe and conservative:
|
||||
* - Only processes "type" and "unrecognized" issues
|
||||
@@ -1551,11 +1445,6 @@ function coerceArgsFromIssues(args: unknown, issues: FlatIssue[]): { value: unkn
|
||||
// ============================================================================
|
||||
|
||||
type ValidationContext =
|
||||
| {
|
||||
kind: "zod";
|
||||
zod: ZodType;
|
||||
json: Record<string, unknown>;
|
||||
}
|
||||
| {
|
||||
kind: "arktype";
|
||||
ark: Type;
|
||||
@@ -1577,9 +1466,7 @@ function getValidationContext(tool: Tool): ValidationContext {
|
||||
return stamp(tool.parameters as object, kValidationContext, params =>
|
||||
isArkSchema(params)
|
||||
? { kind: "arktype", ark: params, json: arkToWireSchema(params) }
|
||||
: isZodSchema(params)
|
||||
? { kind: "zod", zod: params, json: zodToWireSchema(params) }
|
||||
: { kind: "json", json: upgradeJsonSchemaTo202012(params) as Record<string, unknown> },
|
||||
: { kind: "json", json: upgradeJsonSchemaTo202012(params) as Record<string, unknown> },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1621,18 +1508,6 @@ function formatIssuePath(path: ReadonlyArray<PropertyKey>): string {
|
||||
}
|
||||
|
||||
function validateContext(ctx: ValidationContext, value: unknown): ContextValidationResult {
|
||||
if (ctx.kind === "zod") {
|
||||
const result = ctx.zod.safeParse(value);
|
||||
if (result.success) {
|
||||
return { success: true, value: preserveUnknownRootFields(value, result.data) };
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
flatIssues: flattenIssues(result.error.issues),
|
||||
messages: result.error.issues.map(issue => ` - ${formatIssuePath(issue.path)}: ${issue.message}`),
|
||||
};
|
||||
}
|
||||
|
||||
if (ctx.kind === "arktype") {
|
||||
const out = ctx.ark(value);
|
||||
if (!(out instanceof type.errors)) {
|
||||
@@ -1850,10 +1725,8 @@ function truncateArgsForError(value: unknown): unknown {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates tool call arguments against the tool's schema (Zod or plain JSON
|
||||
* Schema). Applies LLM-quirk coercions (numeric strings, JSON-string
|
||||
* containers, null/invalid-empty-string-for-optional, null-for-default) before
|
||||
* declaring failure.
|
||||
* Validates tool call arguments against an ArkType or plain JSON Schema schema.
|
||||
* Applies conservative LLM-quirk normalization before declaring failure.
|
||||
*
|
||||
* @throws Error with a formatted message when validation cannot be reconciled.
|
||||
*/
|
||||
@@ -1916,9 +1789,7 @@ export function validateToolArguments(tool: Tool, toolCall: ToolCall): ToolCall[
|
||||
}
|
||||
|
||||
// Then re-shape JSON-stringified arrays whose schema accepts both string
|
||||
// and array (e.g. `paths: string | string[]`). Without this, zod accepts
|
||||
// the literal `'["a","b"]'` as a string and downstream tools treat it as
|
||||
// a single path with embedded glob brackets — silent zero results.
|
||||
// and array. Otherwise downstream tools receive the encoded string.
|
||||
const stringEncodedArrayNorm = normalizeStringEncodedArrayUnions(json, normalizedArgs);
|
||||
if (stringEncodedArrayNorm.changed) {
|
||||
normalizedArgs = stringEncodedArrayNorm.value;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { afterAll, beforeAll, describe, expect, it } from "bun:test";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { isContextOverflow } from "@oh-my-pi/pi-ai/error";
|
||||
import {
|
||||
buildGitLabDuoWorkflowApprovalStartRequest,
|
||||
@@ -41,7 +42,6 @@ import type {
|
||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { extractHttpStatusFromError } from "@oh-my-pi/pi-utils";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
beforeAll(() => configureCredentialRedaction(true));
|
||||
afterAll(() => configureCredentialRedaction(false));
|
||||
@@ -67,13 +67,13 @@ const context: Context = {
|
||||
const editTool: Tool = {
|
||||
name: "edit",
|
||||
description: "Apply a hashline patch.",
|
||||
parameters: z.object({ input: z.string() }),
|
||||
parameters: type({ input: type("string") }),
|
||||
};
|
||||
|
||||
const nativeTools: Tool[] = ["read", "write", "grep", "glob", "bash", "lsp", "todo"].map(name => ({
|
||||
name,
|
||||
description: `${name} native bridge`,
|
||||
parameters: z.object({}),
|
||||
parameters: type({}),
|
||||
}));
|
||||
|
||||
function restoreOptionalEnv(name: string, value: string | undefined): void {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { complete } from "@oh-my-pi/pi-ai/stream";
|
||||
import type { Api, AssistantMessage, Context, Message, Model, Tool, ToolResultMessage } from "@oh-my-pi/pi-ai/types";
|
||||
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
|
||||
import { z } from "zod/v4";
|
||||
import { e2eApiKey } from "./oauth";
|
||||
|
||||
// Tool for testing
|
||||
const weatherSchema = z.object({
|
||||
location: z.string().describe("City name"),
|
||||
const weatherSchema = type({
|
||||
location: type("string").describe("City name"),
|
||||
});
|
||||
|
||||
const weatherTool: Tool<typeof weatherSchema> = {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { Api, Context, Model, Tool, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
||||
import { complete } from "@oh-my-pi/pi-ai";
|
||||
import type { OptionsForApi } from "@oh-my-pi/pi-ai/types";
|
||||
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
|
||||
import { z } from "zod/v4";
|
||||
import { e2eApiKey, resolveApiKey } from "./oauth";
|
||||
|
||||
// Resolve OAuth tokens at module level (async, runs before tests)
|
||||
@@ -38,7 +38,7 @@ async function handleToolWithImageResult<TApi extends Api>(model: Model<TApi>, o
|
||||
const base64Image = imageBuffer.toBase64();
|
||||
|
||||
// Define a tool that returns only an image (no text)
|
||||
const getImageSchema = z.object({});
|
||||
const getImageSchema = type({});
|
||||
const getImageTool: Tool<typeof getImageSchema> = {
|
||||
name: "get_circle",
|
||||
description: "Returns a circle image for visualization",
|
||||
@@ -126,7 +126,7 @@ async function handleToolWithTextAndImageResult<TApi extends Api>(model: Model<T
|
||||
const base64Image = imageBuffer.toBase64();
|
||||
|
||||
// Define a tool that returns both text and an image
|
||||
const getImageSchema = z.object({});
|
||||
const getImageSchema = type({});
|
||||
const getImageTool: Tool<typeof getImageSchema> = {
|
||||
name: "get_circle_with_description",
|
||||
description: "Returns a circle image with a text description",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { streamAzureOpenAIResponses } from "@oh-my-pi/pi-ai/providers/azure-openai-responses";
|
||||
import { streamOpenAICodexResponses } from "@oh-my-pi/pi-ai/providers/openai-codex-responses";
|
||||
import { streamOpenAICompletions } from "@oh-my-pi/pi-ai/providers/openai-completions";
|
||||
@@ -6,7 +7,6 @@ import { streamOpenAIResponses } from "@oh-my-pi/pi-ai/providers/openai-response
|
||||
import type { Context, Model, Tool, ToolChoice } from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import * as piUtils from "@oh-my-pi/pi-utils";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
const TEST_INSTALLATION_ID = "00000000-0000-4000-8000-000000000001";
|
||||
|
||||
@@ -73,19 +73,19 @@ const codexModel: Model<"openai-codex-responses"> = buildModel({
|
||||
const forkAgentTool: Tool = {
|
||||
name: "fork_agent",
|
||||
description: "Fork a subagent",
|
||||
parameters: z.object({ prompt: z.string() }),
|
||||
parameters: type({ prompt: type("string") }),
|
||||
};
|
||||
|
||||
const searchTool: Tool = {
|
||||
name: "dataforseo_search",
|
||||
description: "Search via DataForSEO",
|
||||
parameters: z.object({ query: z.string() }),
|
||||
parameters: type({ query: type("string") }),
|
||||
};
|
||||
|
||||
const todoTool: Tool = {
|
||||
name: "todo",
|
||||
description: "Manage a phased task list",
|
||||
parameters: z.object({ ops: z.array(z.object({ op: z.string() })) }),
|
||||
parameters: type({ ops: type.array(type({ op: type("string") })) }),
|
||||
};
|
||||
|
||||
const absentTodoContext: Context = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { afterAll, beforeAll, describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { streamBedrock } from "@oh-my-pi/pi-ai/providers/amazon-bedrock";
|
||||
import { crc32 } from "@oh-my-pi/pi-ai/providers/aws-eventstream";
|
||||
import type { Context, FetchImpl, Model, Tool } from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
const originalSkipAuth = process.env.AWS_BEDROCK_SKIP_AUTH;
|
||||
|
||||
@@ -195,7 +195,7 @@ describe("issue #3124 — Bedrock /btw with tool history", () => {
|
||||
const userTool: Tool = {
|
||||
name: "__no_tools__",
|
||||
description: "Caller-registered tool that collides with the sentinel name.",
|
||||
parameters: z.object({ query: z.string() }),
|
||||
parameters: type({ query: type("string") }),
|
||||
};
|
||||
const context: Context = {
|
||||
messages: [{ role: "user", content: "Use my tool", timestamp: 0 }],
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { streamOpenAICompletions } from "@oh-my-pi/pi-ai/providers/openai-completions";
|
||||
import { streamOpenAIResponses } from "@oh-my-pi/pi-ai/providers/openai-responses";
|
||||
import type { Context, Model, ModelSpec, Tool, ToolChoice } from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
interface ChatCompletionsPayload {
|
||||
tool_choice?: unknown;
|
||||
@@ -18,13 +18,13 @@ interface ResponsesPayload {
|
||||
const resolveTool: Tool = {
|
||||
name: "resolve",
|
||||
description: "Apply or discard a pending preview",
|
||||
parameters: z.object({ action: z.enum(["apply", "discard"]), reason: z.string() }),
|
||||
parameters: type({ action: type.enumeration(["apply", "discard"]), reason: type("string") }),
|
||||
};
|
||||
|
||||
const todoTool: Tool = {
|
||||
name: "todo",
|
||||
description: "Track work items",
|
||||
parameters: z.object({ note: z.string() }),
|
||||
parameters: type({ note: type("string") }),
|
||||
};
|
||||
|
||||
const multiToolContext: Context = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { jsonSchemaToTypeScript, toolWireSchema } from "@oh-my-pi/pi-ai/utils/schema";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
describe("jsonSchemaToTypeScript", () => {
|
||||
it("renders objects with optional markers and JSDoc descriptions", () => {
|
||||
@@ -99,9 +99,9 @@ describe("jsonSchemaToTypeScript", () => {
|
||||
});
|
||||
|
||||
it("converts a Zod schema through the wire pipeline", () => {
|
||||
const parameters = z.object({
|
||||
name: z.string().describe("the name"),
|
||||
count: z.number().int().optional(),
|
||||
const parameters = type({
|
||||
name: type("string").describe("the name"),
|
||||
count: type("number.integer").optional(),
|
||||
});
|
||||
const ts = jsonSchemaToTypeScript(toolWireSchema({ name: "t", description: "", parameters }));
|
||||
expect(ts).toContain("/** the name */");
|
||||
|
||||
@@ -3,7 +3,6 @@ import { type } from "@oh-my-pi/omptype";
|
||||
import type { Tool } from "@oh-my-pi/pi-ai/types";
|
||||
import { isArkSchema, toolWireSchema } from "@oh-my-pi/pi-ai/utils/schema";
|
||||
import { validateToolArguments } from "@oh-my-pi/pi-ai/utils/validation";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Phase-1 parity gate: ArkType schemas must flow through the same wire-emission
|
||||
@@ -36,8 +35,7 @@ describe("isArkSchema", () => {
|
||||
expect(isArkSchema(type("string"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects Zod schemas, JSON Schema objects, and non-objects", () => {
|
||||
expect(isArkSchema(z.object({ a: z.string() }))).toBe(false);
|
||||
it("rejects JSON Schema objects and non-objects", () => {
|
||||
expect(isArkSchema({ type: "object", properties: {} })).toBe(false);
|
||||
expect(isArkSchema(null)).toBe(false);
|
||||
expect(isArkSchema(undefined)).toBe(false);
|
||||
@@ -75,10 +73,10 @@ describe("arkToWireSchema — emission", () => {
|
||||
const zodTwin: Tool = {
|
||||
name: "zod-plain",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
name: z.string().describe("the display name"),
|
||||
count: z.number().describe("how many items"),
|
||||
nested: z.object({ inner: z.string().describe("inner value") }).describe("a nested object"),
|
||||
parameters: type({
|
||||
name: type("string").describe("the display name"),
|
||||
count: type("number").describe("how many items"),
|
||||
nested: type({ inner: type("string").describe("inner value") }).describe("a nested object"),
|
||||
}),
|
||||
};
|
||||
// Normalize key + array ordering (semantically irrelevant to JSON Schema).
|
||||
@@ -160,10 +158,10 @@ describe("validateToolArguments — ArkType contracts", () => {
|
||||
const zodTwin: Tool = {
|
||||
name: "zod-plain",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
name: z.string(),
|
||||
count: z.number(),
|
||||
nested: z.object({ inner: z.string() }),
|
||||
parameters: type({
|
||||
name: type("string"),
|
||||
count: type("number"),
|
||||
nested: type({ inner: type("string") }),
|
||||
}),
|
||||
};
|
||||
const zodResult = validateToolArguments(zodTwin, {
|
||||
|
||||
@@ -461,91 +461,9 @@ describe("normalizeSchemaForMCP", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Regression: issue #1101. Some MCP servers ship `JSON.stringify(zodSchema)`
|
||||
// directly as a tool's `inputSchema`. Zod 4 surfaces `.type`, `.enum`,
|
||||
// `.options`, and `.def` on every schema instance — those keys collide with
|
||||
// JSON Schema keywords, producing payloads that fail Anthropic's strict
|
||||
// JSON Schema 2020-12 validator (`"type":"enum"`, `"enum":{...}` as object).
|
||||
// `normalizeSchemaForMCP` must rewrite the offending nodes into clean JSON
|
||||
// Schema so the tool list still ships.
|
||||
it("rewrites a Zod-enum instance leaked as inputSchema", () => {
|
||||
const leaked = {
|
||||
def: { type: "enum", entries: { upstream: "upstream", downstream: "downstream" } },
|
||||
type: "enum",
|
||||
enum: { upstream: "upstream", downstream: "downstream" },
|
||||
options: ["upstream", "downstream"],
|
||||
};
|
||||
expect(normalizeSchemaForMCP(leaked)).toEqual({
|
||||
type: "string",
|
||||
enum: ["upstream", "downstream"],
|
||||
});
|
||||
});
|
||||
|
||||
it("rewrites a numeric Zod-enum (integer values keep integer type)", () => {
|
||||
const leaked = {
|
||||
def: { type: "enum", entries: { ONE: 1, TWO: 2 } },
|
||||
type: "enum",
|
||||
enum: { ONE: 1, TWO: 2 },
|
||||
options: [1, 2],
|
||||
};
|
||||
expect(normalizeSchemaForMCP(leaked)).toEqual({
|
||||
type: "integer",
|
||||
enum: [1, 2],
|
||||
});
|
||||
});
|
||||
|
||||
it("rewrites a Zod-literal instance to a single-element enum", () => {
|
||||
const leaked = {
|
||||
def: { type: "literal", values: ["only"] },
|
||||
type: "literal",
|
||||
values: ["only"],
|
||||
};
|
||||
// Decontamination emits `{const:"only"}`; downstream normalizer collapses
|
||||
// it to the equivalent enum form. End-to-end contract is what callers see.
|
||||
expect(normalizeSchemaForMCP(leaked)).toEqual({ type: "string", enum: ["only"] });
|
||||
});
|
||||
|
||||
it("rewrites a Zod-union of literals (downstream collapses anyOf-of-consts to enum)", () => {
|
||||
const leaked = {
|
||||
def: {
|
||||
type: "union",
|
||||
options: [
|
||||
{ def: { type: "literal", values: ["on"] }, type: "literal", values: ["on"] },
|
||||
{ def: { type: "literal", values: ["off"] }, type: "literal", values: ["off"] },
|
||||
],
|
||||
},
|
||||
type: "union",
|
||||
};
|
||||
expect(normalizeSchemaForMCP(leaked)).toEqual({
|
||||
type: "string",
|
||||
enum: ["on", "off"],
|
||||
});
|
||||
});
|
||||
|
||||
it("strips null-valued JSON Schema keywords that Zod scalars leak (format: null, minLength: null)", () => {
|
||||
const leaked = {
|
||||
def: { type: "string", checks: [] },
|
||||
type: "string",
|
||||
format: null,
|
||||
minLength: null,
|
||||
maxLength: null,
|
||||
};
|
||||
expect(normalizeSchemaForMCP(leaked)).toEqual({ type: "string" });
|
||||
});
|
||||
|
||||
it("drops invalid `type` for unmodelled Zod kinds so the residue stays valid", () => {
|
||||
const leaked = {
|
||||
def: { type: "any" },
|
||||
type: "any",
|
||||
description: "anything",
|
||||
};
|
||||
expect(normalizeSchemaForMCP(leaked)).toEqual({ description: "anything" });
|
||||
});
|
||||
|
||||
it("leaves a genuine JSON Schema that happens to have a `def` property alone", () => {
|
||||
// `def` is not a JSON Schema keyword but it's also not reserved. The
|
||||
// detoxifier must only fire when `def.type` is a known Zod kind AND
|
||||
// `node.type === def.type`, otherwise it would corrupt real schemas.
|
||||
// `def` is not a JSON Schema keyword, so normalization must not corrupt
|
||||
// schemas that use it as an ordinary property name.
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: { def: { type: "string" } },
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { Tool, ToolCall } from "@oh-my-pi/pi-ai/types";
|
||||
import {
|
||||
adaptSchemaForStrict,
|
||||
arkToWireSchema,
|
||||
enforceStrictSchema,
|
||||
isJsonSchemaValueValid,
|
||||
isValidJsonSchema,
|
||||
@@ -9,10 +11,8 @@ import {
|
||||
sanitizeSchemaForStrictMode,
|
||||
toolWireSchema,
|
||||
tryEnforceStrictSchema,
|
||||
zodToWireSchema,
|
||||
} from "@oh-my-pi/pi-ai/utils/schema";
|
||||
import { validateToolArguments } from "@oh-my-pi/pi-ai/utils/validation";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
describe("sanitizeSchemaForStrictMode", () => {
|
||||
it("infers object type, strips non-structural keywords, and converts const to enum", () => {
|
||||
@@ -490,10 +490,10 @@ describe("sanitizeSchemaForStrictMode", () => {
|
||||
|
||||
describe("enforceStrictSchema", () => {
|
||||
it("converts optional properties to nullable schemas and requires all object keys", () => {
|
||||
const schema = zodToWireSchema(
|
||||
z.object({
|
||||
requiredText: z.string(),
|
||||
optionalCount: z.number().optional(),
|
||||
const schema = arkToWireSchema(
|
||||
type({
|
||||
requiredText: type("string"),
|
||||
optionalCount: type("number").optional(),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -507,9 +507,9 @@ describe("enforceStrictSchema", () => {
|
||||
});
|
||||
|
||||
it("flattens optional union schemas instead of nesting anyOf wrappers", () => {
|
||||
const schema = zodToWireSchema(
|
||||
z.object({
|
||||
paths: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
const schema = arkToWireSchema(
|
||||
type({
|
||||
paths: type.union([type("string"), type("string").array()]).optional(),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -588,12 +588,12 @@ describe("enforceStrictSchema", () => {
|
||||
});
|
||||
|
||||
it("never emits undefined as a schema type", () => {
|
||||
const schema = zodToWireSchema(
|
||||
z.object({
|
||||
questions: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
recommended: z.number().optional(),
|
||||
const schema = arkToWireSchema(
|
||||
type({
|
||||
questions: type.array(
|
||||
type({
|
||||
id: type("string"),
|
||||
recommended: type("number").optional(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -794,22 +794,22 @@ describe("tryEnforceStrictSchema", () => {
|
||||
});
|
||||
|
||||
it("keeps shared object schemas strict-compatible after adaptation", () => {
|
||||
const sharedTaskSchema = z.object({
|
||||
content: z.string(),
|
||||
status: z.string().optional(),
|
||||
notes: z.string().optional(),
|
||||
const sharedTaskSchema = type({
|
||||
content: type("string"),
|
||||
status: type("string").optional(),
|
||||
notes: type("string").optional(),
|
||||
});
|
||||
const schema = zodToWireSchema(
|
||||
z.object({
|
||||
ops: z.array(
|
||||
z.union([
|
||||
z.object({
|
||||
op: z.literal("replace"),
|
||||
tasks: z.array(sharedTaskSchema),
|
||||
const schema = arkToWireSchema(
|
||||
type({
|
||||
ops: type.array(
|
||||
type.union([
|
||||
type({
|
||||
op: type.unit("replace"),
|
||||
tasks: type.array(sharedTaskSchema),
|
||||
}),
|
||||
z.object({
|
||||
op: z.literal("update"),
|
||||
tasks: z.array(sharedTaskSchema).optional(),
|
||||
type({
|
||||
op: type.unit("update"),
|
||||
tasks: type.array(sharedTaskSchema).optional(),
|
||||
}),
|
||||
]),
|
||||
),
|
||||
@@ -1005,7 +1005,7 @@ describe("Zod root extras preserved through normalize", () => {
|
||||
const tool: Tool = {
|
||||
name: "simple_tool",
|
||||
description: "",
|
||||
parameters: z.object({ assignment: z.string() }),
|
||||
parameters: type({ assignment: type("string") }),
|
||||
};
|
||||
const toolCall: ToolCall = {
|
||||
type: "toolCall",
|
||||
@@ -1029,7 +1029,7 @@ describe("adaptSchemaForStrict — unrepresentable open branches fall back to no
|
||||
const wire = toolWireSchema({
|
||||
name: "t",
|
||||
description: "d",
|
||||
parameters: z.object({ a: z.string(), meta: z.unknown() }),
|
||||
parameters: type({ a: type("string"), meta: type("unknown") }),
|
||||
} as Tool);
|
||||
expect((wire.properties as Record<string, unknown>).meta).toBe(true);
|
||||
expect(adaptSchemaForStrict(wire, true).strict).toBe(false);
|
||||
|
||||
@@ -1,149 +1,13 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import { normalizeAnthropicToolSchema } from "@oh-my-pi/pi-ai/providers/anthropic";
|
||||
import type { Tool } from "@oh-my-pi/pi-ai/types";
|
||||
import {
|
||||
adaptSchemaForStrict,
|
||||
decontaminateZodInstance,
|
||||
isZodSchema,
|
||||
normalizeEmptySchemas,
|
||||
normalizeSchemaForCCA,
|
||||
normalizeSchemaForGoogle,
|
||||
stripSchemaDescriptions,
|
||||
stripToolDescriptions,
|
||||
toolWireSchema,
|
||||
zodToWireSchema,
|
||||
} from "@oh-my-pi/pi-ai/utils/schema";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
describe("isZodSchema", () => {
|
||||
it("accepts a live Zod instance", () => {
|
||||
expect(isZodSchema(z.object({ a: z.string() }))).toBe(true);
|
||||
expect(isZodSchema(z.string())).toBe(true);
|
||||
expect(isZodSchema(z.enum({ a: "a", b: "b" }))).toBe(true);
|
||||
});
|
||||
|
||||
// Regression: issue #1101. Before tightening, `isZodSchema` returned true
|
||||
// for `JSON.parse(JSON.stringify(zodSchema))` because the `_zod` property
|
||||
// (and its object value) survived the round-trip — even though every Zod
|
||||
// method had been stripped along with the prototype. The relaxed predicate
|
||||
// fed garbage into `z.toJSONSchema` and (when callers bypassed conversion)
|
||||
// shipped the raw Zod internals to Anthropic's strict validator.
|
||||
it("rejects a JSON-roundtripped Zod schema (prototype lost)", () => {
|
||||
const impostor = JSON.parse(JSON.stringify(z.object({ a: z.string() })));
|
||||
expect(isZodSchema(impostor)).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects the raw gitnexus_impact.direction payload from issue #1101", () => {
|
||||
const impostor = {
|
||||
def: { type: "enum", entries: { upstream: "upstream", downstream: "downstream" } },
|
||||
type: "enum",
|
||||
enum: { upstream: "upstream", downstream: "downstream" },
|
||||
options: ["upstream", "downstream"],
|
||||
};
|
||||
expect(isZodSchema(impostor)).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects plain JSON Schema objects", () => {
|
||||
expect(isZodSchema({ type: "object", properties: {} })).toBe(false);
|
||||
expect(isZodSchema({ type: "string" })).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects non-objects", () => {
|
||||
expect(isZodSchema(null)).toBe(false);
|
||||
expect(isZodSchema(undefined)).toBe(false);
|
||||
expect(isZodSchema("string")).toBe(false);
|
||||
expect(isZodSchema(42)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// zodToWireSchema — empty-schema normalization (issue #1179)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("zodToWireSchema — empty-schema normalization", () => {
|
||||
it("converts z.unknown() additionalProperties from {} to true (z.record case)", () => {
|
||||
// Grammar-constrained samplers treat {} as "emit empty object" rather than
|
||||
// "any JSON value". Normalizing to `true` lets models emit strings.
|
||||
const schema = z.object({ extra: z.record(z.string(), z.unknown()) });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const extra = (wire.properties as Record<string, unknown>).extra as Record<string, unknown>;
|
||||
expect(extra.additionalProperties).toBe(true);
|
||||
});
|
||||
|
||||
it("converts z.unknown() items from {} to true (z.array case)", () => {
|
||||
const schema = z.object({ items: z.array(z.unknown()) });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const items = (wire.properties as Record<string, unknown>).items as Record<string, unknown>;
|
||||
expect(items.items).toBe(true);
|
||||
});
|
||||
|
||||
it("converts z.unknown() property schemas from {} to true", () => {
|
||||
const schema = z.object({ meta: z.unknown() });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const meta = (wire.properties as Record<string, unknown>).meta;
|
||||
expect(meta).toBe(true);
|
||||
});
|
||||
|
||||
it("does not touch non-empty schemas or boolean values", () => {
|
||||
const schema = z.object({ name: z.string() });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const name = (wire.properties as Record<string, unknown>).name as Record<string, unknown>;
|
||||
expect(name.type).toBe("string");
|
||||
expect(name.additionalProperties).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("zodToWireSchema — nullable scalar normalization", () => {
|
||||
it("rewrites nullable scalar anyOf to a type array while preserving metadata", () => {
|
||||
const schema = z.object({ skip: z.number().nullable().describe("matches to skip") });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const skip = (wire.properties as Record<string, unknown>).skip as Record<string, unknown>;
|
||||
expect(skip).toEqual({
|
||||
type: ["number", "null"],
|
||||
description: "matches to skip",
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves null semantics when rewriting nullable scalar enum anyOf", () => {
|
||||
const wire = toolWireSchema({
|
||||
name: "mcp__sentry_search_docs",
|
||||
description: "",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
guide: {
|
||||
anyOf: [{ type: "string", enum: ["javascript", "python"], description: "guide" }, { type: "null" }],
|
||||
},
|
||||
},
|
||||
required: ["guide"],
|
||||
},
|
||||
async execute() {},
|
||||
} as unknown as Tool);
|
||||
const guide = (wire.properties as Record<string, unknown>).guide as Record<string, unknown>;
|
||||
|
||||
expect(guide).toEqual({
|
||||
type: ["string", "null"],
|
||||
enum: ["javascript", "python", null],
|
||||
description: "guide",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps nullable integers free of Zod safe-integer bounds", () => {
|
||||
const schema = z.object({ count: z.number().int().nullable() });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const count = (wire.properties as Record<string, unknown>).count as Record<string, unknown>;
|
||||
expect(count).toEqual({ type: ["integer", "null"] });
|
||||
});
|
||||
|
||||
it("leaves mixed nullable unions as anyOf", () => {
|
||||
const schema = z.object({ value: z.union([z.string(), z.number()]).nullable() });
|
||||
const wire = zodToWireSchema(schema);
|
||||
const value = (wire.properties as Record<string, unknown>).value as Record<string, unknown>;
|
||||
expect(value.type).toBeUndefined();
|
||||
expect(Array.isArray(value.anyOf)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// normalizeEmptySchemas — provider-agnostic post-pipeline normalization
|
||||
@@ -182,23 +46,14 @@ describe("normalizeEmptySchemas", () => {
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// toolWireSchema — covers both Zod and TypeBox paths (issue #1179)
|
||||
// toolWireSchema — raw JSON Schema normalization (issue #1179)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("toolWireSchema — empty-schema normalization across both paths", () => {
|
||||
function zodTool(parameters: z.ZodType): Tool {
|
||||
return { name: "t", description: "", parameters, async execute() {} } as unknown as Tool;
|
||||
}
|
||||
describe("toolWireSchema — raw JSON Schema normalization", () => {
|
||||
function jsonTool(parameters: Record<string, unknown>): Tool {
|
||||
return { name: "t", description: "", parameters, async execute() {} } as unknown as Tool;
|
||||
}
|
||||
|
||||
it("normalizes {} → true for Zod tools (z.record(z.string(), z.unknown()))", () => {
|
||||
const wire = toolWireSchema(zodTool(z.object({ extra: z.record(z.string(), z.unknown()) })));
|
||||
const extra = (wire.properties as Record<string, unknown>).extra as Record<string, unknown>;
|
||||
expect(extra.additionalProperties).toBe(true);
|
||||
});
|
||||
|
||||
it("normalizes {} → true for TypeBox / raw JSON Schema tools", () => {
|
||||
const wire = toolWireSchema(
|
||||
jsonTool({
|
||||
@@ -254,63 +109,6 @@ describe("toolWireSchema — empty-schema normalization across both paths", () =
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Provider downstream behavior with normalized `additionalProperties: true`
|
||||
// (issue #1179 — verify Google and Anthropic don't break)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("provider normalizers on normalized open-record schemas", () => {
|
||||
const wire = zodToWireSchema(
|
||||
z.object({
|
||||
action: z.enum(["apply", "discard"]),
|
||||
extra: z.record(z.string(), z.unknown()).optional(),
|
||||
}),
|
||||
);
|
||||
|
||||
it("Anthropic preserves additionalProperties: true so strict-mode opt-out still fires", () => {
|
||||
// `normalizeAnthropicStrictSchemaNode` rejects nodes where additionalProperties !== false.
|
||||
// With normalization, the value is `true` (was `{}`); still !== false, so strict opts out.
|
||||
const out = normalizeAnthropicToolSchema(wire) as Record<string, unknown>;
|
||||
const extra = (out.properties as Record<string, unknown>).extra as Record<string, unknown>;
|
||||
expect(extra.additionalProperties).toBe(true);
|
||||
});
|
||||
|
||||
it("Google strips additionalProperties entirely (UNSUPPORTED_SCHEMA_FIELDS)", () => {
|
||||
// Pre-existing behavior — Google never sees the open-record marker either way.
|
||||
// `additionalProperties: true` is removed just like `additionalProperties: {}` was.
|
||||
const out = normalizeSchemaForGoogle(wire) as Record<string, unknown>;
|
||||
const extra = (out.properties as Record<string, unknown>).extra as Record<string, unknown>;
|
||||
expect(extra).not.toHaveProperty("additionalProperties");
|
||||
});
|
||||
|
||||
it("CCA (Claude on Cloud Code Assist) strips additionalProperties entirely", () => {
|
||||
const out = normalizeSchemaForCCA(wire) as Record<string, unknown>;
|
||||
const extra = (out.properties as Record<string, unknown>).extra as Record<string, unknown>;
|
||||
expect(extra).not.toHaveProperty("additionalProperties");
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// decontaminateZodInstance — nullable wrapping of non-scalar inner schemas
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("decontaminateZodInstance — nullable union", () => {
|
||||
it("z.union([z.string(), z.number()]).nullable() produces a null-tolerant schema", () => {
|
||||
// Round-trip strips Zod methods; decontaminateZodInstance must then inject null.
|
||||
const roundTripped = JSON.parse(JSON.stringify(z.union([z.string(), z.number()]).nullable()));
|
||||
const out = decontaminateZodInstance(roundTripped) as Record<string, unknown>;
|
||||
// The union inner schema surfaces as an anyOf shape (no scalar `type`), so
|
||||
// nullable wrapping must produce { anyOf: [..., { type: "null" }] }.
|
||||
const toleratesNull =
|
||||
(Array.isArray(out.type) && (out.type as string[]).includes("null")) ||
|
||||
(Array.isArray(out.anyOf) &&
|
||||
(out.anyOf as unknown[]).some(
|
||||
b => typeof b === "object" && b !== null && (b as Record<string, unknown>).type === "null",
|
||||
));
|
||||
expect(toleratesNull).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// arkToWireSchema — `T | undefined` value-union pruning (Codex strict-mode break)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { Tool } from "@oh-my-pi/pi-ai/types";
|
||||
import { validateToolArguments } from "@oh-my-pi/pi-ai/utils/validation";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
describe("Tool argument whitespace normalization", () => {
|
||||
it("trims trailing whitespace from enum strings before validation", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
op: z.enum(["append", "done", "drop", "init", "rm", "start", "view"]),
|
||||
items: z.array(z.string()).optional(),
|
||||
parameters: type({
|
||||
op: type.enumeration(["append", "done", "drop", "init", "rm", "start", "view"]),
|
||||
items: type("string").array().optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -59,8 +59,8 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "tuple-op",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
args: z.tuple([z.enum(["init"])]),
|
||||
parameters: type({
|
||||
args: type.tuple([type.enumeration(["init"])]),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -78,9 +78,9 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "read",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
offset: z.number().optional(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
offset: type("number").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -98,9 +98,9 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "search",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
pattern: z.string(),
|
||||
paths: z.array(z.string()),
|
||||
parameters: type({
|
||||
pattern: type("string"),
|
||||
paths: type("string").array(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -124,8 +124,8 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "search",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
paths: z.union([z.string(), z.array(z.string())]),
|
||||
parameters: type({
|
||||
paths: type.union([type("string"), type("string").array()]),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -145,9 +145,9 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "write",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
content: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
content: type("string"),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -165,9 +165,9 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "http",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
body: z.object({
|
||||
title: z.string(),
|
||||
parameters: type({
|
||||
body: type({
|
||||
title: type("string"),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
@@ -186,10 +186,10 @@ describe("Tool argument whitespace normalization", () => {
|
||||
const tool: Tool = {
|
||||
name: "eval",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
language: z.enum(["py", "js", "rb", "jl"]),
|
||||
code: z.string(),
|
||||
title: z.string().optional(),
|
||||
parameters: type({
|
||||
language: type.enumeration(["py", "js", "rb", "jl"]),
|
||||
code: type("string"),
|
||||
title: type("string").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { Tool, ToolCall } from "@oh-my-pi/pi-ai/types";
|
||||
import { validateToolArguments } from "@oh-my-pi/pi-ai/utils/validation";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
describe("Tool argument coercion", () => {
|
||||
it("coerces numeric strings when schema expects number", () => {
|
||||
const tool: Tool = {
|
||||
name: "t1",
|
||||
description: "",
|
||||
parameters: z.object({ timeout: z.number() }),
|
||||
parameters: type({ timeout: type("number") }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -27,7 +27,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t2",
|
||||
description: "",
|
||||
parameters: z.object({ label: z.string() }),
|
||||
parameters: type({ label: type("string") }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -46,7 +46,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "object-string",
|
||||
description: "",
|
||||
parameters: z.object({ payload: z.string() }),
|
||||
parameters: type({ payload: type("string") }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -63,7 +63,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "array-string",
|
||||
description: "",
|
||||
parameters: z.object({ payload: z.string() }),
|
||||
parameters: type({ payload: type("string") }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -80,7 +80,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "numeric-booleans",
|
||||
description: "",
|
||||
parameters: z.object({ enabled: z.boolean(), disabled: z.boolean() }),
|
||||
parameters: type({ enabled: type("boolean"), disabled: type("boolean") }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -97,7 +97,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "boolean-numbers",
|
||||
description: "",
|
||||
parameters: z.object({ enabled: z.number(), disabled: z.number().int() }),
|
||||
parameters: type({ enabled: type("number"), disabled: type("number.integer") }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -114,7 +114,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "invalid-numeric-boolean",
|
||||
description: "",
|
||||
parameters: z.object({ enabled: z.boolean() }),
|
||||
parameters: type({ enabled: type("boolean") }),
|
||||
};
|
||||
|
||||
expect(() =>
|
||||
@@ -131,7 +131,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "raw-debug",
|
||||
description: "",
|
||||
parameters: z.object({ input: z.string() }),
|
||||
parameters: type({ input: type("string") }),
|
||||
};
|
||||
const rawBlock = '<|start|>assistant<|channel|>commentary to=functions.edit <|message|>{"input":"x"}}<|call|>';
|
||||
|
||||
@@ -159,15 +159,15 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "string-booleans",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
t: z.boolean(),
|
||||
f: z.boolean(),
|
||||
one: z.boolean(),
|
||||
zero: z.boolean(),
|
||||
yes: z.boolean(),
|
||||
no: z.boolean(),
|
||||
on: z.boolean(),
|
||||
off: z.boolean(),
|
||||
parameters: type({
|
||||
t: type("boolean"),
|
||||
f: type("boolean"),
|
||||
one: type("boolean"),
|
||||
zero: type("boolean"),
|
||||
yes: type("boolean"),
|
||||
no: type("boolean"),
|
||||
on: type("boolean"),
|
||||
off: type("boolean"),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -203,7 +203,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t3",
|
||||
description: "",
|
||||
parameters: z.object({ items: z.array(z.number()) }),
|
||||
parameters: type({ items: type("number").array() }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -221,7 +221,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t3b",
|
||||
description: "",
|
||||
parameters: z.object({ paths: z.array(z.string()) }),
|
||||
parameters: type({ paths: type("string").array() }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -239,7 +239,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "glob_paths",
|
||||
description: "",
|
||||
parameters: z.object({ paths: z.array(z.string()) }),
|
||||
parameters: type({ paths: type("string").array() }),
|
||||
};
|
||||
|
||||
const bracketResult = validateToolArguments(tool, {
|
||||
@@ -270,14 +270,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo_like",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(
|
||||
z.object({
|
||||
op: z.literal("init"),
|
||||
list: z.array(
|
||||
z.object({
|
||||
phase: z.string(),
|
||||
items: z.array(z.string()),
|
||||
parameters: type({
|
||||
ops: type.array(
|
||||
type({
|
||||
op: type.unit("init"),
|
||||
list: type.array(
|
||||
type({
|
||||
phase: type("string"),
|
||||
items: type("string").array(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -306,14 +306,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo_like_json_array",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(
|
||||
z.object({
|
||||
op: z.literal("init"),
|
||||
list: z.array(
|
||||
z.object({
|
||||
phase: z.string(),
|
||||
items: z.array(z.string()),
|
||||
parameters: type({
|
||||
ops: type.array(
|
||||
type({
|
||||
op: type.unit("init"),
|
||||
list: type.array(
|
||||
type({
|
||||
phase: type("string"),
|
||||
items: type("string").array(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -339,14 +339,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo_like_double_json_array",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(
|
||||
z.object({
|
||||
op: z.literal("init"),
|
||||
list: z.array(
|
||||
z.object({
|
||||
phase: z.string(),
|
||||
items: z.array(z.string()),
|
||||
parameters: type({
|
||||
ops: type.array(
|
||||
type({
|
||||
op: type.unit("init"),
|
||||
list: type.array(
|
||||
type({
|
||||
phase: type("string"),
|
||||
items: type("string").array(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -373,14 +373,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo_like_json_object",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(
|
||||
z.object({
|
||||
op: z.literal("init"),
|
||||
list: z.array(
|
||||
z.object({
|
||||
phase: z.string(),
|
||||
items: z.array(z.string()),
|
||||
parameters: type({
|
||||
ops: type.array(
|
||||
type({
|
||||
op: type.unit("init"),
|
||||
list: type.array(
|
||||
type({
|
||||
phase: type("string"),
|
||||
items: type("string").array(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -406,14 +406,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo_like_malformed_json_array",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(
|
||||
z.object({
|
||||
op: z.literal("init"),
|
||||
list: z.array(
|
||||
z.object({
|
||||
phase: z.string(),
|
||||
items: z.array(z.string()),
|
||||
parameters: type({
|
||||
ops: type.array(
|
||||
type({
|
||||
op: type.unit("init"),
|
||||
list: type.array(
|
||||
type({
|
||||
phase: type("string"),
|
||||
items: type("string").array(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -436,7 +436,7 @@ describe("Tool argument coercion", () => {
|
||||
else throw error;
|
||||
}
|
||||
|
||||
expect(thrown?.message).toContain("ops: Invalid input: expected array, received string");
|
||||
expect(thrown?.message).toContain("ops must be an array");
|
||||
expect(thrown?.message).not.toContain("ops/0");
|
||||
expect(thrown?.message).not.toContain('"normalized"');
|
||||
});
|
||||
@@ -445,7 +445,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "numeric_list",
|
||||
description: "",
|
||||
parameters: z.object({ values: z.array(z.number()) }),
|
||||
parameters: type({ values: type("number").array() }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -459,11 +459,11 @@ describe("Tool argument coercion", () => {
|
||||
});
|
||||
|
||||
it("does not wrap singleton values for array expectations from failed union branches", () => {
|
||||
const entry = z.object({ id: z.number() });
|
||||
const entry = type({ id: type("number") });
|
||||
const tool: Tool = {
|
||||
name: "union_shape",
|
||||
description: "",
|
||||
parameters: z.union([z.array(entry), entry]),
|
||||
parameters: type.union([type.array(entry), entry]),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -526,9 +526,9 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "tagged_union",
|
||||
description: "",
|
||||
parameters: z.union([
|
||||
z.object({ type: z.literal("indices"), indices: z.array(z.number()) }),
|
||||
z.object({ type: z.literal("all") }),
|
||||
parameters: type.union([
|
||||
type({ type: type.unit("indices"), indices: type("number").array() }),
|
||||
type({ type: type.unit("all") }),
|
||||
]),
|
||||
};
|
||||
|
||||
@@ -581,7 +581,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t4",
|
||||
description: "",
|
||||
parameters: z.object({ payload: z.object({ a: z.number() }) }),
|
||||
parameters: type({ payload: type({ a: type("number") }) }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -599,7 +599,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t4b",
|
||||
description: "",
|
||||
parameters: z.object({ command: z.string() }),
|
||||
parameters: type({ command: type("string") }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -616,7 +616,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t4c",
|
||||
description: "",
|
||||
parameters: z.object({ env: z.record(z.string(), z.string()) }),
|
||||
parameters: type({ env: type.record(type("string"), type("string")) }),
|
||||
};
|
||||
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -682,7 +682,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t5",
|
||||
description: "",
|
||||
parameters: z.object({ payload: z.object({ items: z.array(z.number()) }) }),
|
||||
parameters: type({ payload: type({ items: type("number").array() }) }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -700,11 +700,11 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t9",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
a: z.string(),
|
||||
b: z.array(
|
||||
z.object({
|
||||
k: z.string(),
|
||||
parameters: type({
|
||||
a: type("string"),
|
||||
b: type.array(
|
||||
type({
|
||||
k: type("string"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -726,11 +726,11 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t10",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
a: z.string(),
|
||||
b: z.array(
|
||||
z.object({
|
||||
k: z.string(),
|
||||
parameters: type({
|
||||
a: type("string"),
|
||||
b: type.array(
|
||||
type({
|
||||
k: type("string"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -752,12 +752,12 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t7",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
edits: z.array(
|
||||
z.object({
|
||||
target: z.string(),
|
||||
new_content: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
edits: type.array(
|
||||
type({
|
||||
target: type("string"),
|
||||
new_content: type("string"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -780,19 +780,19 @@ describe("Tool argument coercion", () => {
|
||||
});
|
||||
|
||||
it("coerces quoted edit arrays before stripping optional null fields", () => {
|
||||
const textSchema = z.union([z.array(z.string()), z.string()]);
|
||||
const textSchema = type.union([type("string").array(), type("string")]);
|
||||
const tool: Tool = {
|
||||
name: "atom-like-edit",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
edits: z.array(
|
||||
z.object({
|
||||
loc: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
edits: type.array(
|
||||
type({
|
||||
loc: type("string"),
|
||||
set: textSchema.optional(),
|
||||
pre: textSchema.optional(),
|
||||
post: textSchema.optional(),
|
||||
sub: z.tuple([z.string(), z.string()]).optional(),
|
||||
sub: type.tuple([type("string"), type("string")]).optional(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -815,14 +815,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t16",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
edits: z.array(
|
||||
z.object({
|
||||
op: z.string(),
|
||||
pos: z.string(),
|
||||
end: z.string(),
|
||||
lines: z.array(z.string()),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
edits: type.array(
|
||||
type({
|
||||
op: type("string"),
|
||||
pos: type("string"),
|
||||
end: type("string"),
|
||||
lines: type("string").array(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -852,12 +852,12 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t8",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
edits: z.array(
|
||||
z.object({
|
||||
target: z.string(),
|
||||
new_content: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
edits: type.array(
|
||||
type({
|
||||
target: type("string"),
|
||||
new_content: type("string"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -881,9 +881,9 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t11",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
requiredText: z.string(),
|
||||
optionalCount: z.number().optional(),
|
||||
parameters: type({
|
||||
requiredText: type("string"),
|
||||
optionalCount: type("number").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -928,10 +928,10 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "empty-string-tool",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
requiredText: z.string(),
|
||||
optionalText: z.string().optional(),
|
||||
optionalEnum: z.enum(["", "clear"]).optional(),
|
||||
parameters: type({
|
||||
requiredText: type("string"),
|
||||
optionalText: type("string").optional(),
|
||||
optionalEnum: type.enumeration(["", "clear"]).optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -949,12 +949,12 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t12",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
edits: z.array(
|
||||
z.object({
|
||||
target: z.string(),
|
||||
pos: z.string().optional(),
|
||||
end: z.string().optional(),
|
||||
parameters: type({
|
||||
edits: type.array(
|
||||
type({
|
||||
target: type("string"),
|
||||
pos: type("string").optional(),
|
||||
end: type("string").optional(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -972,26 +972,26 @@ describe("Tool argument coercion", () => {
|
||||
});
|
||||
|
||||
it("drops null while preserving valid empty-string optional properties in anyOf object branches", () => {
|
||||
const opSchema = z.union([
|
||||
z.object({
|
||||
op: z.literal("add_task"),
|
||||
phase: z.string(),
|
||||
content: z.string(),
|
||||
const opSchema = type.union([
|
||||
type({
|
||||
op: type.unit("add_task"),
|
||||
phase: type("string"),
|
||||
content: type("string"),
|
||||
}),
|
||||
z.object({
|
||||
op: z.literal("update"),
|
||||
id: z.string(),
|
||||
status: z.string().optional(),
|
||||
content: z.string().optional(),
|
||||
notes: z.string().optional(),
|
||||
type({
|
||||
op: type.unit("update"),
|
||||
id: type("string"),
|
||||
status: type("string").optional(),
|
||||
content: type("string").optional(),
|
||||
notes: type("string").optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const tool: Tool = {
|
||||
name: "t13",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(opSchema),
|
||||
parameters: type({
|
||||
ops: type.array(opSchema),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1029,7 +1029,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t6",
|
||||
description: "",
|
||||
parameters: z.object({ timeout: z.number() }),
|
||||
parameters: type({ timeout: type("number") }),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -1047,7 +1047,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t14",
|
||||
description: "",
|
||||
parameters: z.object({ tick_size: z.number().optional() }),
|
||||
parameters: type({ tick_size: type("number").optional() }),
|
||||
};
|
||||
const toolCall: ToolCall = {
|
||||
type: "toolCall",
|
||||
@@ -1064,7 +1064,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t15",
|
||||
description: "",
|
||||
parameters: z.object({ tick_size: z.number().optional() }),
|
||||
parameters: type({ tick_size: type("number").optional() }),
|
||||
};
|
||||
const toolCall: ToolCall = {
|
||||
type: "toolCall",
|
||||
@@ -1079,9 +1079,9 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "edit-tool",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
delete: z.boolean().optional(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
delete: type("boolean").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1100,9 +1100,9 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "edit-tool",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
move: z.string().optional(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
move: type("string").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1121,8 +1121,8 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "required-tool",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1143,10 +1143,10 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "multi-optional",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
required: z.string(),
|
||||
optBool: z.boolean().optional(),
|
||||
optString: z.string().optional(),
|
||||
parameters: type({
|
||||
required: type("string"),
|
||||
optBool: type("boolean").optional(),
|
||||
optString: type("string").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1165,12 +1165,12 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "heal-1",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
edits: z.array(
|
||||
z.object({
|
||||
target: z.string(),
|
||||
content: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
edits: type.array(
|
||||
type({
|
||||
target: type("string"),
|
||||
content: type("string"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -1195,12 +1195,12 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "heal-2",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
edits: z.array(
|
||||
z.object({
|
||||
target: z.string(),
|
||||
content: z.string(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
edits: type.array(
|
||||
type({
|
||||
target: type("string"),
|
||||
content: type("string"),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -1225,8 +1225,8 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "heal-esc-1",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
edits: z.array(z.object({ target: z.string(), content: z.string() })),
|
||||
parameters: type({
|
||||
edits: type.array(type({ target: type("string"), content: type("string") })),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1248,8 +1248,8 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "heal-trail-1",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
edits: z.array(z.object({ target: z.string(), op: z.string() })),
|
||||
parameters: type({
|
||||
edits: type.array(type({ target: type("string"), op: type("string") })),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1271,8 +1271,8 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "heal-3",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
edits: z.array(z.object({ target: z.string() })),
|
||||
parameters: type({
|
||||
edits: type.array(type({ target: type("string") })),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1292,14 +1292,14 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "todo_like",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
phases: z.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
tasks: z.array(
|
||||
z.object({
|
||||
content: z.string(),
|
||||
details: z.string().optional(),
|
||||
parameters: type({
|
||||
phases: type.array(
|
||||
type({
|
||||
name: type("string"),
|
||||
tasks: type.array(
|
||||
type({
|
||||
content: type("string"),
|
||||
details: type("string").optional(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -1334,9 +1334,11 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-defaulted-null",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
note: z.union([z.string(), z.null()]),
|
||||
tags: z.array(z.string()).default([]),
|
||||
parameters: type({
|
||||
note: type.union([type("string"), type.unit(null)]),
|
||||
tags: type("string")
|
||||
.array()
|
||||
.default(() => []),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1355,8 +1357,10 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-defaulted-isolation",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
tags: z.array(z.string()).default([]),
|
||||
parameters: type({
|
||||
tags: type("string")
|
||||
.array()
|
||||
.default(() => []),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1382,10 +1386,10 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-optional-nulls",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
path: z.string(),
|
||||
offset: z.number().optional(),
|
||||
limit: z.number().optional(),
|
||||
parameters: type({
|
||||
path: type("string"),
|
||||
offset: type("number").optional(),
|
||||
limit: type("number").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1404,9 +1408,11 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-root-json-null",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
note: z.union([z.string(), z.null()]),
|
||||
tags: z.array(z.string()).default([]),
|
||||
parameters: type({
|
||||
note: type.union([type("string"), type.unit(null)]),
|
||||
tags: type("string")
|
||||
.array()
|
||||
.default(() => []),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1428,10 +1434,10 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-nested-json",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
payload: z.object({
|
||||
flags: z.array(z.boolean()),
|
||||
meta: z.object({ count: z.number() }),
|
||||
parameters: type({
|
||||
payload: type({
|
||||
flags: type("boolean").array(),
|
||||
meta: type({ count: type("number") }),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
@@ -1457,15 +1463,14 @@ describe("Tool argument coercion", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("tolerates extra keys on .strict() Zod object schemas (loose-recursive)", () => {
|
||||
it("tolerates extra keys on a rejecting object schema", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-strict-root",
|
||||
description: "",
|
||||
parameters: z
|
||||
.object({
|
||||
op: z.string(),
|
||||
})
|
||||
.strict(),
|
||||
parameters: type({
|
||||
"+": "reject",
|
||||
op: type("string"),
|
||||
}),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -1483,19 +1488,17 @@ describe("Tool argument coercion", () => {
|
||||
expect(result.timeout).toBeUndefined();
|
||||
});
|
||||
|
||||
it("tolerates extra keys on nested .strict() Zod object schemas", () => {
|
||||
it("tolerates extra keys on nested rejecting object schemas", () => {
|
||||
const tool: Tool = {
|
||||
name: "t-strict-nested",
|
||||
description: "",
|
||||
parameters: z
|
||||
.object({
|
||||
config: z
|
||||
.object({
|
||||
host: z.string(),
|
||||
})
|
||||
.strict(),
|
||||
})
|
||||
.strict(),
|
||||
parameters: type({
|
||||
"+": "reject",
|
||||
config: type({
|
||||
"+": "reject",
|
||||
host: type("string"),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
const toolCall: ToolCall = {
|
||||
@@ -1545,9 +1548,9 @@ describe("Tool argument coercion", () => {
|
||||
const unionTool: Tool = {
|
||||
name: "search",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
pattern: z.string(),
|
||||
paths: z.union([z.string(), z.array(z.string()).min(1)]),
|
||||
parameters: type({
|
||||
pattern: type("string"),
|
||||
paths: type.union([type("string"), type("string").array().atLeastLength(1)]),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1626,7 +1629,7 @@ describe("Tool argument coercion", () => {
|
||||
const stringOnly: Tool = {
|
||||
name: "string_only",
|
||||
description: "",
|
||||
parameters: z.object({ value: z.string() }),
|
||||
parameters: type({ value: type("string") }),
|
||||
};
|
||||
const result = validateToolArguments(stringOnly, {
|
||||
type: "toolCall",
|
||||
@@ -1660,9 +1663,9 @@ describe("Tool argument coercion", () => {
|
||||
const nestedTool: Tool = {
|
||||
name: "nested_search",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
payload: z.object({
|
||||
paths: z.union([z.string(), z.array(z.string()).min(1)]),
|
||||
parameters: type({
|
||||
payload: type({
|
||||
paths: type.union([type("string"), type("string").array().atLeastLength(1)]),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
@@ -1684,11 +1687,11 @@ describe("Tool argument coercion", () => {
|
||||
const opsTool: Tool = {
|
||||
name: "todo",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
ops: z.array(
|
||||
z.object({
|
||||
op: z.string(),
|
||||
task: z.string().optional(),
|
||||
parameters: type({
|
||||
ops: type.array(
|
||||
type({
|
||||
op: type("string"),
|
||||
task: type("string").optional(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
@@ -1716,7 +1719,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "rooted",
|
||||
description: "",
|
||||
parameters: z.object({ label: z.string() }),
|
||||
parameters: type({ label: type("string") }),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
type: "toolCall",
|
||||
@@ -1731,7 +1734,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "deep",
|
||||
description: "",
|
||||
parameters: z.object({ label: z.string() }),
|
||||
parameters: type({ label: type("string") }),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
type: "toolCall",
|
||||
@@ -1747,7 +1750,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "clobber",
|
||||
description: "",
|
||||
parameters: z.object({ value: z.string() }),
|
||||
parameters: type({ value: type("string") }),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
type: "toolCall",
|
||||
@@ -1762,8 +1765,8 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "wrap",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
payload: z.object({ op: z.string() }),
|
||||
parameters: type({
|
||||
payload: type({ op: type("string") }),
|
||||
}),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -1794,8 +1797,8 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "union",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
items: z.union([z.string(), z.array(z.object({ op: z.string() }))]),
|
||||
parameters: type({
|
||||
items: type.union([type("string"), type.array(type({ op: type("string") }))]),
|
||||
}),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
@@ -1812,7 +1815,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "plain",
|
||||
description: "",
|
||||
parameters: z.object({ op: z.string(), count: z.number() }),
|
||||
parameters: type({ op: type("string"), count: type("number") }),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
type: "toolCall",
|
||||
@@ -1829,7 +1832,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "single-arg",
|
||||
description: "",
|
||||
parameters: z.object({ input: z.string() }),
|
||||
parameters: type({ input: type("string") }),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
type: "toolCall",
|
||||
@@ -1844,7 +1847,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "single-arg",
|
||||
description: "",
|
||||
parameters: z.object({ input: z.string() }),
|
||||
parameters: type({ input: type("string") }),
|
||||
};
|
||||
const result = validateToolArguments(tool, {
|
||||
type: "toolCall",
|
||||
@@ -1859,7 +1862,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "multi-arg",
|
||||
description: "",
|
||||
parameters: z.object({ input: z.string(), path: z.string() }),
|
||||
parameters: type({ input: type("string"), path: type("string") }),
|
||||
};
|
||||
expect(() =>
|
||||
validateToolArguments(tool, {
|
||||
@@ -1875,7 +1878,7 @@ describe("Tool argument coercion", () => {
|
||||
const tool: Tool = {
|
||||
name: "single-arg",
|
||||
description: "",
|
||||
parameters: z.object({ input: z.string() }),
|
||||
parameters: type({ input: type("string") }),
|
||||
};
|
||||
expect(() =>
|
||||
validateToolArguments(tool, {
|
||||
@@ -1893,10 +1896,10 @@ describe("In-band arg spill healing", () => {
|
||||
const todoTool: Tool = {
|
||||
name: "todo",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
op: z.enum(["append", "done", "drop", "init", "rm", "start", "view"]),
|
||||
task: z.string().optional(),
|
||||
phase: z.string().optional(),
|
||||
parameters: type({
|
||||
op: type.enumeration(["append", "done", "drop", "init", "rm", "start", "view"]),
|
||||
task: type("string").optional(),
|
||||
phase: type("string").optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1934,9 +1937,9 @@ describe("In-band arg spill healing", () => {
|
||||
const tool: Tool = {
|
||||
name: "spill-coerce",
|
||||
description: "",
|
||||
parameters: z.object({
|
||||
op: z.enum(["read"]),
|
||||
count: z.number().optional(),
|
||||
parameters: type({
|
||||
op: type.enumeration(["read"]),
|
||||
count: type("number").optional(),
|
||||
}),
|
||||
};
|
||||
const result = run(tool, {
|
||||
@@ -1957,7 +1960,7 @@ describe("In-band arg spill healing", () => {
|
||||
const tool: Tool = {
|
||||
name: "spill-content",
|
||||
description: "",
|
||||
parameters: z.object({ content: z.string() }),
|
||||
parameters: type({ content: type("string") }),
|
||||
};
|
||||
const content = "docs: emit </arg_key>\n<arg_key>path</arg_key>\n<arg_value>src/a.ts</arg_value> pairs";
|
||||
const result = run(tool, { content });
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- Migrated GitLab Duo Workflow discovery schemas from zod to omptype and removed the `zod` dependency
|
||||
|
||||
## [17.2.9] - 2026-08-05
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
"dependencies": {
|
||||
"@bufbuild/protobuf": "catalog:",
|
||||
"@oh-my-pi/omptype": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"zod": "catalog:"
|
||||
"@oh-my-pi/pi-utils": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@oh-my-pi/pi-ai": "catalog:",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { z } from "zod/v4";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import type { FetchImpl, ModelSpec } from "../types";
|
||||
import { discoveryFetch, isRecord } from "../utils";
|
||||
|
||||
@@ -54,20 +54,28 @@ const ProjectRootNamespaceQuery = `query omp_gitlabDuoWorkflowProjectRootNamespa
|
||||
}
|
||||
}`;
|
||||
|
||||
const modelRefSchema = z
|
||||
.object({
|
||||
name: z.string().optional().catch(undefined),
|
||||
ref: z.string().optional().catch(undefined),
|
||||
})
|
||||
.loose();
|
||||
const resilientString = type("unknown").pipe(value => {
|
||||
if (value === undefined) return undefined;
|
||||
const parsed = type("string")(value);
|
||||
return parsed instanceof type.errors ? undefined : parsed;
|
||||
});
|
||||
|
||||
const aiChatAvailableModelsSchema = z
|
||||
.object({
|
||||
defaultModel: z.unknown().nullable().optional(),
|
||||
selectableModels: z.array(z.unknown()).nullable().optional().catch([]),
|
||||
pinnedModel: z.unknown().nullable().optional(),
|
||||
})
|
||||
.loose();
|
||||
const resilientUnknownArray = type("unknown").pipe(value => {
|
||||
if (value === undefined || value === null) return value;
|
||||
const parsed = type("unknown[]")(value);
|
||||
return parsed instanceof type.errors ? [] : parsed;
|
||||
});
|
||||
|
||||
const modelRefSchema = type({
|
||||
"name?": resilientString,
|
||||
"ref?": resilientString,
|
||||
});
|
||||
|
||||
const aiChatAvailableModelsSchema = type({
|
||||
"defaultModel?": "unknown",
|
||||
"selectableModels?": resilientUnknownArray,
|
||||
"pinnedModel?": "unknown",
|
||||
});
|
||||
|
||||
type GitLabDuoWorkflowCandidateSource = "override" | "project" | "remote" | "group";
|
||||
|
||||
@@ -540,17 +548,15 @@ async function postGraphQL(
|
||||
}
|
||||
|
||||
function parseAvailability(value: unknown): GitLabDuoWorkflowAvailability | null {
|
||||
const parsed = aiChatAvailableModelsSchema.safeParse(value);
|
||||
if (!parsed.success) {
|
||||
return null;
|
||||
}
|
||||
const parsed = aiChatAvailableModelsSchema(value);
|
||||
if (parsed instanceof type.errors) return null;
|
||||
return {
|
||||
defaultModel: parseModelRef(parsed.data.defaultModel),
|
||||
selectableModels: (parsed.data.selectableModels ?? []).flatMap(model => {
|
||||
defaultModel: parseModelRef(parsed.defaultModel),
|
||||
selectableModels: (parsed.selectableModels ?? []).flatMap(model => {
|
||||
const parsedModel = parseModelRef(model);
|
||||
return parsedModel ? [parsedModel] : [];
|
||||
}),
|
||||
pinnedModel: parseModelRef(parsed.data.pinnedModel),
|
||||
pinnedModel: parseModelRef(parsed.pinnedModel),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -558,15 +564,13 @@ function parseModelRef(value: unknown): GitLabDuoWorkflowModelRef | null {
|
||||
if (value === null || value === undefined) {
|
||||
return null;
|
||||
}
|
||||
const parsed = modelRefSchema.safeParse(value);
|
||||
if (!parsed.success) {
|
||||
return null;
|
||||
}
|
||||
const ref = normalizeIdentifier(parsed.data.ref);
|
||||
const parsed = modelRefSchema(value);
|
||||
if (parsed instanceof type.errors) return null;
|
||||
const ref = normalizeIdentifier(parsed.ref);
|
||||
if (!ref) {
|
||||
return null;
|
||||
}
|
||||
const name = normalizeIdentifier(parsed.data.name) ?? ref;
|
||||
const name = normalizeIdentifier(parsed.name) ?? ref;
|
||||
return { name, ref };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Breaking Changes
|
||||
- Replaced the re-exported zod API with the omptype-backed zod-compat facade (`@oh-my-pi/omptype/zod`); plugins keep the zod-style builder surface while real-zod-specific APIs are gone
|
||||
|
||||
### Changed
|
||||
- Replaced external dependencies with `@oh-my-pi/pi-utils` modules: `@agentclientprotocol/sdk` -> `acp` (also drops the package patch), `@mozilla/readability` -> `readability`, `@puppeteer/browsers` -> `browsers`, `@xterm/headless` -> `vterm`, `chalk` -> `chalk`, `fast-xml-parser` -> `xml`, `header-generator` -> `headers`, `linkedom` -> `dom`, `lru-cache` -> `lru`, `mammoth` -> `docx`, `turndown` and `turndown-plugin-gfm` -> `turndown`, and dev `marked` -> `marked`
|
||||
|
||||
## [17.2.9] - 2026-08-05
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
@@ -96,7 +96,7 @@ renderResult(result, { expanded, isPartial }, theme) {
|
||||
**Use `z.enum` for discriminated string tool args:**
|
||||
|
||||
```typescript
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
parameters: z.object({
|
||||
action: z.enum(["list", "add"]),
|
||||
|
||||
@@ -114,7 +114,7 @@ export default function (pi: ExtensionAPI) {
|
||||
**Use `z.enum` for discriminated string tool args:**
|
||||
|
||||
```typescript
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
parameters: z.object({
|
||||
action: z.enum(["list", "add"]),
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
/**
|
||||
* API Demo Extension
|
||||
*
|
||||
* Demonstrates using ExtensionAPI's logger, injected `pi.zod`, and pi module access.
|
||||
* These features are now exposed directly on the ExtensionAPI, matching
|
||||
* the CustomToolAPI interface.
|
||||
* Demonstrates using ExtensionAPI's logger, injected schema builder, and pi
|
||||
* module access.
|
||||
*/
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
// Access the logger for debugging
|
||||
pi.logger.debug("API demo extension loaded");
|
||||
@@ -16,7 +15,7 @@ export default function (pi: ExtensionAPI) {
|
||||
pi.registerTool({
|
||||
name: "api_demo",
|
||||
label: "API Demo",
|
||||
description: "Demonstrates ExtensionAPI capabilities: logger, zod, and pi module access",
|
||||
description: "Demonstrates ExtensionAPI capabilities: logger, schema validation, and pi module access",
|
||||
parameters: z.object({
|
||||
message: z.string().describe("Test message"),
|
||||
logLevel: z.enum(["error", "warn", "debug"]).default("debug").describe("Log level to use"),
|
||||
@@ -48,7 +47,7 @@ export default function (pi: ExtensionAPI) {
|
||||
``,
|
||||
`Features demonstrated:`,
|
||||
`1. ✓ Logger access via pi.logger`,
|
||||
`2. ✓ Zod access via pi.zod`,
|
||||
`2. ✓ Schema builder access via pi.arktype`,
|
||||
`3. ✓ Pi module access via pi.pi`,
|
||||
``,
|
||||
`Context:`,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Tests that jiti can resolve npm modules correctly.
|
||||
*/
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
// Log with colors using chalk
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Hello Tool - Minimal custom tool example
|
||||
*
|
||||
* Demonstrates using ExtensionAPI's logger, injected `pi.zod`, and pi module access.
|
||||
* Demonstrates using ExtensionAPI's logger and injected schema builder.
|
||||
*/
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
pi.registerTool({
|
||||
name: "hello",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
// Command entrypoint for reload.
|
||||
// Treat reload as terminal for this handler.
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
import ms from "ms";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
// Register a tool that uses ms
|
||||
pi.registerTool({
|
||||
|
||||
@@ -41,7 +41,7 @@ console.log();
|
||||
import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const { z } = pi.zod;
|
||||
const z = pi.zod;
|
||||
|
||||
pi.on("agent_start", async () => {
|
||||
console.log("[Extension] Agent starting");
|
||||
|
||||
@@ -49,9 +49,7 @@
|
||||
"bench:guard": "bun scripts/bench-guard.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "catalog:",
|
||||
"@babel/parser": "catalog:",
|
||||
"@mozilla/readability": "catalog:",
|
||||
"@oh-my-pi/hashline": "catalog:",
|
||||
"@oh-my-pi/omp-stats": "catalog:",
|
||||
"@oh-my-pi/omptype": "catalog:",
|
||||
@@ -75,29 +73,15 @@
|
||||
"@opentelemetry/sdk-metrics": "catalog:",
|
||||
"@opentelemetry/sdk-trace-base": "catalog:",
|
||||
"@opentelemetry/sdk-trace-node": "catalog:",
|
||||
"@puppeteer/browsers": "catalog:",
|
||||
"@types/turndown": "catalog:",
|
||||
"@xterm/headless": "catalog:",
|
||||
"chalk": "catalog:",
|
||||
"fast-xml-parser": "catalog:",
|
||||
"handlebars": "catalog:",
|
||||
"header-generator": "catalog:",
|
||||
"linkedom": "catalog:",
|
||||
"lru-cache": "catalog:",
|
||||
"mammoth": "catalog:",
|
||||
"mupdf": "catalog:",
|
||||
"puppeteer-core": "catalog:",
|
||||
"turndown": "catalog:",
|
||||
"turndown-plugin-gfm": "catalog:",
|
||||
"zod": "catalog:"
|
||||
"puppeteer-core": "catalog:"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@huggingface/transformers": "catalog:",
|
||||
"sherpa-onnx-node": "1.13.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
"marked": "catalog:"
|
||||
"@types/bun": "catalog:"
|
||||
},
|
||||
"engines": {
|
||||
"bun": ">=1.3.14"
|
||||
|
||||
@@ -30,17 +30,7 @@ const ALWAYS_EXTERNAL = [
|
||||
// import would load the unpatched npm package in users' installs (currently
|
||||
// @ark/schema is patched, so it — and arktype, which pulls @ark/schema — stay
|
||||
// bundled).
|
||||
const RUNTIME_EXTERNAL = [
|
||||
"puppeteer-core",
|
||||
"@puppeteer/browsers",
|
||||
"@babel/parser",
|
||||
"@xterm/headless",
|
||||
"turndown",
|
||||
"turndown-plugin-gfm",
|
||||
"@mozilla/readability",
|
||||
"linkedom",
|
||||
"@agentclientprotocol/sdk",
|
||||
];
|
||||
const RUNTIME_EXTERNAL = ["puppeteer-core", "@babel/parser"];
|
||||
|
||||
async function runCommand(command: string[]): Promise<void> {
|
||||
const proc = Bun.spawn(command, {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { getAgentDir, getProjectDir, isEnoent } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { YAML } from "bun";
|
||||
import chalk from "chalk";
|
||||
import { theme } from "../modes/theme/theme";
|
||||
import { loadBundledAgents } from "../task/agents";
|
||||
import type { AgentDefinition } from "../task/types";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* CLI argument parsing and help display
|
||||
*/
|
||||
import { $env, APP_NAME, logger } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import type { ServiceTierOpenAISettingValue } from "../config/service-tier";
|
||||
import { CLI_THINKING_LEVELS, type ConfiguredThinkingLevel, parseCliThinkingLevel } from "../thinking";
|
||||
import { BUILTIN_TOOL_NAMES, HIDDEN_TOOL_NAMES, normalizeToolNames } from "../tools/builtin-names";
|
||||
|
||||
@@ -34,9 +34,9 @@ import {
|
||||
} from "@oh-my-pi/pi-ai";
|
||||
import { AuthBrokerClient, DEFAULT_AUTH_BROKER_BIND, startAuthBroker } from "@oh-my-pi/pi-ai/auth-broker";
|
||||
import { $which, APP_NAME, getAgentDbPath, getConfigRootDir, isEnoent, logger, VERSION } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { setTransports as setLoggerTransports } from "@oh-my-pi/pi-utils/logger";
|
||||
import { $ } from "bun";
|
||||
import chalk from "chalk";
|
||||
import { resolveAuthBrokerConfig } from "../session/auth-broker-config";
|
||||
|
||||
export type AuthBrokerAction = "serve" | "token" | "login" | "logout" | "status" | "import" | "migrate" | "list";
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
import { DEFAULT_AUTH_GATEWAY_BIND, startAuthGateway } from "@oh-my-pi/pi-ai/auth-gateway";
|
||||
import { type GeneratedProvider, getBundledModels } from "@oh-my-pi/pi-catalog/models";
|
||||
import { getConfigRootDir, isEnoent, logger, VERSION } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { ModelRegistry } from "../config/model-registry";
|
||||
import { type AuthBrokerClientConfig, resolveAuthBrokerConfig } from "../session/auth-broker-config";
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import { resolveModelServiceTier, streamSimple } from "@oh-my-pi/pi-ai";
|
||||
import { buildModelProviderPriorityRank } from "@oh-my-pi/pi-catalog/identity";
|
||||
import { replaceTabs, truncateToWidth } from "@oh-my-pi/pi-tui";
|
||||
import { formatDuration, getProjectDir, prompt } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import type { ApiKeyResolverModel } from "../config/api-key-resolver";
|
||||
import { ModelRegistry } from "../config/model-registry";
|
||||
import {
|
||||
|
||||
@@ -10,7 +10,7 @@ import * as path from "node:path";
|
||||
import * as tls from "node:tls";
|
||||
import * as zlib from "node:zlib";
|
||||
import { PtySession } from "@oh-my-pi/pi-natives";
|
||||
import xterm from "@xterm/headless";
|
||||
import xterm from "@oh-my-pi/pi-utils/vterm";
|
||||
|
||||
const DEFAULT_PROXY_HOST = "127.0.0.1";
|
||||
const DEFAULT_PROXY_PORT = 8080;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import { APP_NAME, getAgentDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import {
|
||||
getDefault,
|
||||
getEnumValues,
|
||||
|
||||
@@ -14,7 +14,7 @@ import type {
|
||||
import { streamSimple } from "@oh-my-pi/pi-ai";
|
||||
import { replaceTabs, truncateToWidth } from "@oh-my-pi/pi-tui";
|
||||
import { formatDuration, getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { ModelRegistry } from "../config/model-registry";
|
||||
import {
|
||||
formatModelString,
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
||||
import { getProjectDir, isEnoent, readImageMetadata } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { resolveReadPath } from "../tools/path-utils";
|
||||
import { formatBytes } from "../tools/render-utils";
|
||||
import { formatDimensionNote, resizeImage } from "../utils/image-resize";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as path from "node:path";
|
||||
import { GrepOutputMode, grep } from "@oh-my-pi/pi-natives";
|
||||
import { APP_NAME } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { expandPath } from "../tools/path-utils";
|
||||
|
||||
export interface GrepCommandArgs {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* CLI handler for `omp grievances` — view, clean, and manually push reported tool issues.
|
||||
*/
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { Settings } from "../config/settings";
|
||||
import { flushGrievances, openAutoQaDb } from "../tools/report-tool-issue";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@oh-my-pi/pi-utils/env";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { APP_NAME, CONFIG_DIR_NAME } from "@oh-my-pi/pi-utils/dirs";
|
||||
import chalk from "chalk";
|
||||
|
||||
export function getExtraHelpText(): string {
|
||||
return `${chalk.bold("Environment Variables:")}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import type { Api, Effort, Model } from "@oh-my-pi/pi-ai";
|
||||
import { getSupportedEfforts } from "@oh-my-pi/pi-catalog/model-thinking";
|
||||
import { formatNumber, getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { ModelRegistry } from "../config/model-registry";
|
||||
import { Settings } from "../config/settings";
|
||||
import { discoverAndLoadExtensions, ExtensionRunner, emitSessionShutdownEvent } from "../extensibility/extensions";
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { APP_NAME, getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { resolveOrDefaultProjectRegistryPath } from "../discovery/helpers";
|
||||
import { PluginManager, parseSettingValue, validateSetting } from "../extensibility/plugins";
|
||||
import {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* (including truncation/limit notices appended by the meta-notice wrapper).
|
||||
*/
|
||||
import { getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { Settings } from "../config/settings";
|
||||
import { extractUriScheme } from "../internal-urls/parse";
|
||||
import { InternalUrlRouter } from "../internal-urls/router";
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
import * as path from "node:path";
|
||||
import { APP_NAME, getProjectDir, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { Settings, settings } from "../config/settings";
|
||||
import { checkPythonKernelAvailability } from "../eval/py/kernel";
|
||||
import { theme } from "../modes/theme/theme";
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as path from "node:path";
|
||||
import { createInterface } from "node:readline/promises";
|
||||
import { Shell } from "@oh-my-pi/pi-natives";
|
||||
import { APP_NAME, getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { Settings } from "../config/settings";
|
||||
import { buildMinimizerOptions } from "../exec/bash-executor";
|
||||
import { getOrCreateSnapshot } from "../utils/shell-snapshot";
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { getSSHConfigPath } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { addSSHHost, readSSHConfigFile, removeSSHHost, type SSHHostConfig } from "../ssh/config-writer";
|
||||
|
||||
// =============================================================================
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { truncateToWidth } from "@oh-my-pi/pi-tui/utils";
|
||||
import { APP_NAME, formatDuration, formatNumber, formatPercent } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { openPath } from "../utils/open";
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { formatBytes } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import {
|
||||
DEFAULT_TINY_TITLE_LOCAL_MODEL_KEY,
|
||||
getTinyLocalModelSpec,
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import { AstMatchStrictness, astMatch, FileType, type GlobMatch, glob } from "@oh-my-pi/pi-natives";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { getProjectDir } from "@oh-my-pi/pi-utils/dirs";
|
||||
import chalk from "chalk";
|
||||
import { BUILTIN_DEFAULTS_PROVIDER_ID, compileRuleCondition, type Rule, ruleCapability } from "../capability/rule";
|
||||
import { bucketRules } from "../capability/rule-buckets";
|
||||
import { Settings } from "../config/settings";
|
||||
|
||||
@@ -11,8 +11,8 @@ import * as path from "node:path";
|
||||
import { Transform } from "node:stream";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { $env, $which, APP_NAME, compareVersions, isEnoent, VERSION } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { $ } from "bun";
|
||||
import chalk from "chalk";
|
||||
import { theme } from "../modes/theme/theme";
|
||||
import { isTimeoutError, withTimeoutSignal } from "../utils/fetch-timeout";
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
type UsageUnit,
|
||||
} from "@oh-my-pi/pi-ai";
|
||||
import { formatDuration, formatNumber, sanitizeText } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { ModelRegistry } from "../config/model-registry";
|
||||
import { discoverAuthStorage } from "../sdk";
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { APP_NAME, getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { applyProviderGlobalsFromSettings } from "../config/provider-globals";
|
||||
import { Settings } from "../config/settings";
|
||||
import { initTheme, theme } from "../modes/theme/theme";
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { getWorktreesDir, isEnoent } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { hasLiveIsolationOwner, ISOLATION_OWNER_FILE } from "../task/isolation-ownership";
|
||||
import * as git from "../utils/git";
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
*/
|
||||
|
||||
import { getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
||||
import chalk from "chalk";
|
||||
import { sayHelp as commandHelp } from "../cli/command-help";
|
||||
import { Settings, settings } from "../config/settings";
|
||||
import { TTS_LOCAL_VOICE_VALUES } from "../tts/models";
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
|
||||
import { PROVIDER_REGISTRY } from "@oh-my-pi/pi-ai";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
||||
import chalk from "chalk";
|
||||
import { tokenHelp as commandHelp } from "../cli/command-help";
|
||||
import { isAuthenticated, ModelRegistry } from "../config/model-registry";
|
||||
import { discoverAuthStorage } from "../sdk";
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
||||
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
||||
import { Markdown } from "@oh-my-pi/pi-tui";
|
||||
import { prompt } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
|
||||
import chalk from "chalk";
|
||||
import typesDescriptionPrompt from "../../commit/prompts/types-description.md" with { type: "text" };
|
||||
import type { ModelRegistry } from "../../config/model-registry";
|
||||
import type { Settings } from "../../config/settings";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import type { CommitCommandArgs } from "./types";
|
||||
|
||||
const FLAG_ALIASES = new Map<string, string>([
|
||||
|
||||
@@ -27,7 +27,7 @@ import { DEFAULT_MODEL_PER_PROVIDER } from "@oh-my-pi/pi-catalog/provider-models
|
||||
import { resolveBareVariantAlias, resolveVariantAlias } from "@oh-my-pi/pi-catalog/variant-collapse";
|
||||
import { fuzzyMatch } from "@oh-my-pi/pi-tui";
|
||||
import { logger } from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import MODEL_PRIO from "../priority.json" with { type: "json" };
|
||||
import {
|
||||
AUTO_THINKING,
|
||||
|
||||
@@ -27,14 +27,15 @@ const flag = (opts as { enabled: boolean })["enabled"];
|
||||
|
||||
## Use
|
||||
|
||||
Prefer a schema parse at the boundary when a validator is available (Zod, Valibot, …) — validate once, then read from a fully typed value. If Zod is already in the project (e.g. Zod v4):
|
||||
Prefer a schema parse at the boundary when a validator is available — validate
|
||||
once, then read from a fully typed value:
|
||||
|
||||
```ts
|
||||
import { z } from "zod/v4";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
|
||||
const Resp = z.object({ data: z.object({ id: z.string() }) });
|
||||
const Resp = type({ data: { id: "string" } });
|
||||
|
||||
const resp = Resp.parse(raw); // throws on bad input; resp.data.id is typed string
|
||||
const resp = Resp.assert(raw); // throws on bad input; resp.data.id is typed string
|
||||
const id = resp.data.id;
|
||||
```
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
*/
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import * as arktype from "@oh-my-pi/omptype";
|
||||
import * as zodModule from "@oh-my-pi/omptype/zod";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import * as zod from "@oh-my-pi/omptype/zod";
|
||||
import { getAgentDir, getProjectDir, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
||||
import { getConfigDirs } from "../../config";
|
||||
import { execCommand } from "../../exec/exec";
|
||||
@@ -187,8 +187,8 @@ export async function loadCustomCommands(options: LoadCustomCommandsOptions = {}
|
||||
exec: (command: string, args: string[], execOptions) =>
|
||||
execCommand(command, args, execOptions?.cwd ?? cwd, execOptions),
|
||||
typebox,
|
||||
arktype,
|
||||
zod: zodModule,
|
||||
arktype: type,
|
||||
zod,
|
||||
pi: PiCodingAgent,
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Unlike markdown commands which expand to prompts, custom commands can execute
|
||||
* arbitrary logic with full access to the hook context.
|
||||
*/
|
||||
import type * as arktype from "@oh-my-pi/omptype";
|
||||
import type { type as ArkType } from "@oh-my-pi/omptype";
|
||||
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
||||
import type * as zod from "@oh-my-pi/omptype/zod";
|
||||
import type { ExecOptions, ExecResult, HookCommandContext } from "../../extensibility/hooks/types";
|
||||
@@ -23,11 +23,11 @@ export interface CustomCommandAPI {
|
||||
cwd: string;
|
||||
/** Execute a shell command */
|
||||
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
||||
/** Injected zod-backed typebox shim (legacy/compat). */
|
||||
/** Injected TypeBox shim (legacy/compat). */
|
||||
typebox: typeof TypeBox;
|
||||
/** Injected arktype module for validation in custom commands. */
|
||||
arktype: typeof arktype;
|
||||
/** Injected omptype-backed zod facade for command validation. */
|
||||
/** Injected omptype schema builder for custom commands. */
|
||||
arktype: typeof ArkType;
|
||||
/** Injected Zod-compatible omptype builder for custom commands. */
|
||||
zod: typeof zod;
|
||||
/** Injected pi-coding-agent exports */
|
||||
pi: typeof PiCodingAgent;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Custom tool loader - loads TypeScript tool modules using native Bun import.
|
||||
*
|
||||
* Dependencies (the zod-backed typebox shim and pi-coding-agent) are injected via the
|
||||
* CustomToolAPI to avoid import resolution issues with custom tools loaded from user directories.
|
||||
* Dependencies are injected through CustomToolAPI so tools loaded from user
|
||||
* directories do not depend on workspace module resolution.
|
||||
*/
|
||||
import * as path from "node:path";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import * as zodModule from "@oh-my-pi/omptype/zod";
|
||||
import * as zod from "@oh-my-pi/omptype/zod";
|
||||
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
||||
import { logger } from "@oh-my-pi/pi-utils";
|
||||
import { toolCapability } from "../../capability/tool";
|
||||
@@ -149,7 +149,7 @@ export class CustomToolLoader {
|
||||
logger,
|
||||
typebox,
|
||||
arktype: type,
|
||||
zod: zodModule,
|
||||
zod,
|
||||
pi,
|
||||
pushPendingAction: action => {
|
||||
if (!pushPendingAction) {
|
||||
|
||||
@@ -70,7 +70,7 @@ export interface CustomToolAPI {
|
||||
typebox: typeof TypeBox;
|
||||
/** Injected arktype module for arktype-authored custom tools. */
|
||||
arktype: typeof ArkType;
|
||||
/** Injected omptype-backed zod facade for parameter schemas. */
|
||||
/** Injected Zod-compatible omptype builder for custom tools. */
|
||||
zod: typeof zod;
|
||||
/** Injected pi-coding-agent exports */
|
||||
pi: typeof PiCodingAgent;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
import type * as fs1 from "node:fs";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { Type } from "@oh-my-pi/omptype";
|
||||
import * as zodModule from "@oh-my-pi/omptype/zod";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import * as zod from "@oh-my-pi/omptype/zod";
|
||||
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
||||
import type {
|
||||
ImageContent,
|
||||
@@ -141,8 +141,8 @@ export class ExtensionRuntime implements IExtensionRuntime {
|
||||
class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
||||
readonly logger = logger;
|
||||
readonly typebox = TypeBox;
|
||||
readonly arktype = Type;
|
||||
readonly zod = zodModule;
|
||||
readonly arktype = type;
|
||||
readonly zod = zod;
|
||||
readonly flagValues = new Map<string, boolean | string>();
|
||||
readonly pendingProviderRegistrations: Array<{
|
||||
name: string;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* - Interact with the user via UI primitives
|
||||
*/
|
||||
|
||||
import type { Type as arktype } from "@oh-my-pi/omptype";
|
||||
import type { type as ArkType } from "@oh-my-pi/omptype";
|
||||
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
||||
import type * as zod from "@oh-my-pi/omptype/zod";
|
||||
import type {
|
||||
@@ -1109,12 +1109,13 @@ export interface ExtensionAPI {
|
||||
/** File logger for error/warning/debug messages */
|
||||
logger: typeof PiLogger;
|
||||
|
||||
/** Injected zod-backed typebox shim for legacy `Type.Object(...)` parameter authoring. */
|
||||
/** Injected TypeBox shim for legacy `Type.Object(...)` parameter authoring. */
|
||||
typebox: typeof TypeBox;
|
||||
|
||||
/** Injected arktype module for arktype-authored extension tools (canonical going forward). */
|
||||
arktype: typeof arktype;
|
||||
/** Injected omptype-backed zod facade for extension tool parameter schemas. */
|
||||
/** Injected omptype schema builder for extension tools. */
|
||||
arktype: typeof ArkType;
|
||||
|
||||
/** Injected Zod-compatible omptype builder for extension tools. */
|
||||
zod: typeof zod;
|
||||
|
||||
/** Injected pi-coding-agent exports for accessing SDK utilities */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* Hook loader - loads TypeScript hook modules using native Bun import.
|
||||
*/
|
||||
import * as path from "node:path";
|
||||
import * as arktype from "@oh-my-pi/omptype";
|
||||
import * as zodModule from "@oh-my-pi/omptype/zod";
|
||||
import { type } from "@oh-my-pi/omptype";
|
||||
import * as zod from "@oh-my-pi/omptype/zod";
|
||||
import { logger } from "@oh-my-pi/pi-utils";
|
||||
import { hookCapability } from "../../capability/hook";
|
||||
import type { Hook } from "../../discovery";
|
||||
@@ -122,9 +122,8 @@ async function createHookAPI(
|
||||
},
|
||||
logger,
|
||||
typebox,
|
||||
// HookAPI.arktype is typed as the arktype `Type` constructor; expose it from the module namespace.
|
||||
arktype: arktype.Type,
|
||||
zod: zodModule,
|
||||
arktype: type,
|
||||
zod,
|
||||
pi: PiCodingAgent,
|
||||
} as HookAPI;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Type } from "@oh-my-pi/omptype";
|
||||
import type { type as ArkType } from "@oh-my-pi/omptype";
|
||||
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
||||
import type * as zod from "@oh-my-pi/omptype/zod";
|
||||
import type { ImageContent, Message, Model, TextContent } from "@oh-my-pi/pi-ai";
|
||||
@@ -582,11 +582,11 @@ export interface HookAPI {
|
||||
|
||||
/** File logger for error/warning/debug messages */
|
||||
logger: typeof PiLogger;
|
||||
/** Injected zod-backed typebox shim (legacy/compat — prefer `arktype`). */
|
||||
/** Injected TypeBox shim (legacy/compat — prefer `arktype`). */
|
||||
typebox: typeof TypeBox;
|
||||
/** Injected arktype module for arktype-authored hooks. */
|
||||
arktype: typeof Type;
|
||||
/** Injected omptype-backed zod facade for hook validation. */
|
||||
/** Injected omptype schema builder for hooks. */
|
||||
arktype: typeof ArkType;
|
||||
/** Injected Zod-compatible omptype builder for hooks. */
|
||||
zod: typeof zod;
|
||||
/** Injected pi-coding-agent exports */
|
||||
pi: typeof PiCodingAgent;
|
||||
|
||||
@@ -2,12 +2,12 @@ import { HookEditorComponent, HookInputComponent, HookSelectorComponent } from "
|
||||
|
||||
// Core session management
|
||||
|
||||
export * as zod from "@oh-my-pi/omptype/zod";
|
||||
export { z } from "@oh-my-pi/omptype/zod";
|
||||
// Re-export TUI components for custom tool rendering
|
||||
export { Container, Markdown, Spacer, Text } from "@oh-my-pi/pi-tui";
|
||||
// Logging
|
||||
export { getAgentDir, logger, VERSION } from "@oh-my-pi/pi-utils";
|
||||
export * as zod from "zod/v4";
|
||||
export { z } from "zod/v4";
|
||||
export * from "./config/keybindings";
|
||||
export * from "./config/model-registry";
|
||||
// Prompt templates
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { logger } from "@oh-my-pi/pi-utils";
|
||||
import xterm, { type Terminal as XtermTerminal } from "@xterm/headless";
|
||||
import xterm, { type Terminal as XtermTerminal } from "@oh-my-pi/pi-utils/vterm";
|
||||
import { readTerminalRows } from "../tools/terminal-output";
|
||||
import { DAEMON_PTY_COLUMNS, DAEMON_PTY_ROWS } from "./protocol";
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
setProjectDir,
|
||||
VERSION,
|
||||
} from "@oh-my-pi/pi-utils";
|
||||
import chalk from "chalk";
|
||||
import chalk from "@oh-my-pi/pi-utils/chalk";
|
||||
import { reset as resetCapabilities } from "./capability";
|
||||
import { type Args, reportUnrecognizedFlags } from "./cli/args";
|
||||
import { applyExtensionFlags, type ExtensionFlagSink } from "./cli/extension-flags";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Adapted from markit-ai (MIT). See ../NOTICE.
|
||||
import * as path from "node:path";
|
||||
import mammoth from "mammoth";
|
||||
import mammoth from "@oh-my-pi/pi-utils/docx";
|
||||
import { createTurndown, normalizeTablesHtml } from "../../utils/turndown";
|
||||
import type { ConversionResult, Converter, StreamInfo } from "../types";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Adapted from markit-ai (MIT). See ../NOTICE.
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import { XMLParser } from "@oh-my-pi/pi-utils/xml";
|
||||
import { createTurndown, normalizeTablesHtml } from "../../utils/turndown";
|
||||
import { unzip, unzipText } from "../../utils/zip";
|
||||
import type { ConversionResult, Converter, StreamInfo } from "../types";
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Minimal ambient types for `mammoth` (ships no types). Declares only what
|
||||
// DocxConverter uses. See ../NOTICE.
|
||||
declare module "mammoth" {
|
||||
interface MammothImage {
|
||||
contentType?: string;
|
||||
read(encoding: "base64"): Promise<string>;
|
||||
}
|
||||
interface ImgAttributes {
|
||||
src: string;
|
||||
alt?: string;
|
||||
}
|
||||
type ConvertImageHandler = (image: MammothImage) => Promise<ImgAttributes>;
|
||||
interface ConvertOptions {
|
||||
convertImage?: ConvertImageHandler;
|
||||
}
|
||||
interface ConvertResult {
|
||||
value: string;
|
||||
messages: unknown[];
|
||||
}
|
||||
export const images: { imgElement(fn: ConvertImageHandler): ConvertImageHandler };
|
||||
export function convertToHtml(input: { buffer: Buffer }, options?: ConvertOptions): Promise<ConvertResult>;
|
||||
const _default: { convertToHtml: typeof convertToHtml; images: typeof images };
|
||||
export default _default;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user