Compare commits

...

2 Commits

5 changed files with 142 additions and 52 deletions

View File

@@ -0,0 +1 @@
- fix(install): make the ONNX dependency chain optional so Termux/Android installs succeed again (#11095)

72
package-lock.json generated
View File

@@ -18,7 +18,6 @@
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@huggingface/transformers": "^4.2.0",
"@lobehub/icons": "^5.16.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@monaco-editor/react": "^4.7.0",
@@ -61,7 +60,6 @@
"next-themes": "^0.4.6",
"node-machine-id": "^1.1.12",
"omniglyph": "^1.4.0",
"onnxruntime-node": "1.24.3",
"open": "^11.0.1",
"ora": "^9.4.1",
"parse5": "^8.0.1",
@@ -156,9 +154,11 @@
},
"optionalDependencies": {
"@atjsh/llmlingua-2": "3.0.0",
"@huggingface/transformers": "^4.2.0",
"better-sqlite3": "^13.0.2",
"js-tiktoken": "^1.0.20",
"keytar": "^7.9.0",
"onnxruntime-node": "1.24.3",
"sqlite-vec": "^0.1.9",
"tls-client-node": "^0.2.0",
"wreq-js": "^3.0.0"
@@ -4510,6 +4510,7 @@
"resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.5.9.tgz",
"integrity": "sha512-uWTG+l3VJRsl7EXxYizuL3P+cCPoc3cRqbWWRcQN0FhejRfbdq0RNhCmbY/YDtnTcz9icdLYuLDjsnz4d8JMuw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=18"
}
@@ -4518,13 +4519,15 @@
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@huggingface/tokenizers/-/tokenizers-0.1.3.tgz",
"integrity": "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA==",
"license": "Apache-2.0"
"license": "Apache-2.0",
"optional": true
},
"node_modules/@huggingface/transformers": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-4.2.0.tgz",
"integrity": "sha512-8BRCoBMH0XsWaEIamuR0LrJGAfftgHAfb2Vrffy0VKlSAE/MnUJ5/h/zTfEP3fDIft+nk7TqB8xXEyABGitBjQ==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@huggingface/jinja": "^0.5.6",
"@huggingface/tokenizers": "^0.1.3",
@@ -9483,30 +9486,35 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/codegen": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
"integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/eventemitter": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
"integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/fetch": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
"integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
"devOptional": true,
"license": "BSD-3-Clause",
"dependencies": {
"@protobufjs/aspromise": "^1.1.1"
@@ -9516,24 +9524,28 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@protobufjs/utf8": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
"integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
"devOptional": true,
"license": "BSD-3-Clause"
},
"node_modules/@radix-ui/number": {
@@ -12737,6 +12749,7 @@
"version": "26.2.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz",
"integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~8.3.0"
@@ -13998,6 +14011,7 @@
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.6.0.tgz",
"integrity": "sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=14.0"
}
@@ -14971,7 +14985,8 @@
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/bottleneck": {
"version": "2.19.5",
@@ -17935,6 +17950,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
@@ -17964,6 +17980,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"define-data-property": "^1.0.1",
@@ -18064,7 +18081,8 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/detect-node-es": {
"version": "1.1.0",
@@ -18908,7 +18926,8 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/es6-promisify": {
"version": "7.0.0",
@@ -20400,7 +20419,8 @@
"version": "25.9.23",
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz",
"integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==",
"license": "Apache-2.0"
"license": "Apache-2.0",
"optional": true
},
"node_modules/flatted": {
"version": "3.4.2",
@@ -21226,6 +21246,7 @@
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"boolean": "^3.0.1",
"es6-error": "^4.1.1",
@@ -21243,6 +21264,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
},
@@ -21291,6 +21313,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"define-properties": "^1.2.1",
@@ -21645,7 +21668,8 @@
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz",
"integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==",
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/hachure-fill": {
"version": "0.5.2",
@@ -21679,6 +21703,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
@@ -24790,7 +24815,8 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/json5": {
"version": "2.2.3",
@@ -26654,6 +26680,7 @@
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
"license": "MIT",
"optional": true,
"dependencies": {
"escape-string-regexp": "^4.0.0"
},
@@ -29425,6 +29452,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -29632,7 +29660,8 @@
"version": "1.24.3",
"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.3.tgz",
"integrity": "sha512-GeuPZO6U/LBJXvwdaqHbuUmoXiEdeCjWi/EG7Y1HNnDwJYuk6WUbNXpF6luSUY8yASul3cmUlLGrCCL1ZgVXqA==",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/onnxruntime-node": {
"version": "1.24.3",
@@ -29640,6 +29669,7 @@
"integrity": "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"win32",
"darwin",
@@ -29656,6 +29686,7 @@
"resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.26.0-dev.20260416-b7804b056c.tgz",
"integrity": "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw==",
"license": "MIT",
"optional": true,
"dependencies": {
"flatbuffers": "^25.1.24",
"guid-typescript": "^1.0.9",
@@ -29669,13 +29700,15 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"license": "Apache-2.0"
"license": "Apache-2.0",
"optional": true
},
"node_modules/onnxruntime-web/node_modules/onnxruntime-common": {
"version": "1.24.0-dev.20251116-b39e144322",
"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.0-dev.20251116-b39e144322.tgz",
"integrity": "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw==",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/open": {
"version": "11.0.1",
@@ -30906,7 +30939,8 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/playwright": {
"version": "1.62.1",
@@ -31861,6 +31895,7 @@
"version": "7.6.5",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz",
"integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==",
"devOptional": true,
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -31884,6 +31919,7 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"devOptional": true,
"license": "Apache-2.0"
},
"node_modules/proxy-addr": {
@@ -33280,6 +33316,7 @@
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
"integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"boolean": "^3.0.1",
"detect-node": "^2.0.4",
@@ -33655,7 +33692,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/send": {
"version": "1.2.1",
@@ -33688,6 +33726,7 @@
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
"license": "MIT",
"optional": true,
"dependencies": {
"type-fest": "^0.13.1"
},
@@ -33703,6 +33742,7 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"license": "(MIT OR CC0-1.0)",
"optional": true,
"engines": {
"node": ">=10"
},
@@ -34474,7 +34514,8 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
"license": "BSD-3-Clause"
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/sql.js": {
"version": "1.14.2",
@@ -36187,6 +36228,7 @@
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
"devOptional": true,
"license": "MIT"
},
"node_modules/unicode-emoji-modifier-base": {

View File

@@ -265,7 +265,6 @@
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@huggingface/transformers": "^4.2.0",
"@lobehub/icons": "^5.16.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@monaco-editor/react": "^4.7.0",
@@ -308,7 +307,6 @@
"next-themes": "^0.4.6",
"node-machine-id": "^1.1.12",
"omniglyph": "^1.4.0",
"onnxruntime-node": "1.24.3",
"open": "^11.0.1",
"ora": "^9.4.1",
"parse5": "^8.0.1",
@@ -343,9 +341,11 @@
},
"optionalDependencies": {
"@atjsh/llmlingua-2": "3.0.0",
"@huggingface/transformers": "^4.2.0",
"better-sqlite3": "^13.0.2",
"js-tiktoken": "^1.0.20",
"keytar": "^7.9.0",
"onnxruntime-node": "1.24.3",
"sqlite-vec": "^0.1.9",
"tls-client-node": "^0.2.0",
"wreq-js": "^3.0.0"

View File

@@ -1,12 +1,12 @@
---
name: omni-webhooks
description: Register, list, test, and remove webhook endpoints. Configure event subscriptions (request.completed, provider.error, budget.exceeded, etc.) and manage delivery retries.
description: Register, list, test, and remove webhook endpoints. Configure event subscriptions (request.completed, request.failed, quota.exceeded, etc.) and manage delivery retries.
---
<!-- generated by src/lib/agentSkills/generator.ts; manual edits will be overwritten -->
## Overview
Register, list, test, and remove webhook endpoints. Configure event subscriptions (request.completed, provider.error, budget.exceeded, etc.) and manage delivery retries.
Register, list, test, and remove webhook endpoints. Configure event subscriptions (request.completed, request.failed, quota.exceeded, etc.) and manage delivery retries.
## Authentication

View File

@@ -9,40 +9,52 @@ function readJson<T = Record<string, unknown>>(relPath: string): T {
return JSON.parse(readFileSync(join(repoRoot, relPath), "utf8")) as T;
}
test("@huggingface/transformers is a regular dependency so npm ci never skips it", () => {
// #9962 deliberately moved @huggingface/transformers out of optionalDependencies:
// as an optional dep, npm silently skipped the whole subtree on Node 24/26 (old
// pin dragged onnxruntime-node@1.21.0 whose NAN build no longer compiles), which
// broke `npm ci`/`next build` with "Can't resolve @huggingface/transformers"
// (lazy import in src/lib/memory/embedding/transformersLocal.ts). As a regular
// dep with onnxruntime-node@~1.24.3 (napi prebuilds, no node-gyp) it stays
// installable and the memory embedding path requires() cleanly.
test("ONNX chain (@huggingface/transformers + onnxruntime-node) stays optional so Termux/Android installs succeed", () => {
// #11095: onnxruntime-node declares os ["win32","darwin","linux"], so while
// these lived in `dependencies` every npm install on Android/Termux aborted
// with a fatal EBADPLATFORM. As optionalDependencies npm skips only the
// unsupported-platform subtree (with a warning) and installs normally
// everywhere else. This deliberately reverses the MECHANISM of #9962 while
// keeping its goal: #9962's skip happened because the old onnxruntime-node@
// 1.21.0 pin built from source (NAN) and failed to compile on Node 24/26;
// the current 1.24.3 pin ships napi prebuilds, so on supported platforms the
// chain always installs and `npm ci`/`next build` keep resolving it. On
// platforms where it IS skipped, both consumers degrade gracefully via lazy/
// dynamic imports (asserted below).
const pkg = readJson<{
dependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
overrides?: Record<string, string>;
}>("package.json");
assert.equal(
pkg.dependencies?.["@huggingface/transformers"],
undefined,
"transformers must NOT be a hard dependency (fatal EBADPLATFORM on Android)"
);
assert.equal(
pkg.optionalDependencies?.["@huggingface/transformers"],
"^4.2.0",
"transformers must be a regular dependency (never optional) so npm ci cannot skip it"
"transformers must be an optionalDependency"
);
assert.equal(pkg.optionalDependencies?.["@huggingface/transformers"], undefined);
});
test("transformers + onnxruntime-node are regular dependencies (not optional)", () => {
const pkg = readJson<{
dependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
}>("package.json");
assert.equal(
pkg.dependencies?.["onnxruntime-node"],
"1.24.3",
"onnxruntime-node is a regular dep (napi prebuilds, installable on Node 24/26)"
undefined,
"onnxruntime-node must NOT be a hard dependency (fatal EBADPLATFORM on Android)"
);
assert.equal(pkg.optionalDependencies?.["onnxruntime-node"], undefined);
assert.equal(
pkg.optionalDependencies?.["onnxruntime-node"],
"1.24.3",
"onnxruntime-node must be an optionalDependency pinned in lockstep with the overrides pin"
);
assert.equal(
pkg.overrides?.["onnxruntime-node"],
"1.24.3",
"the overrides pin must stay aligned with @huggingface/transformers' own pin (single-copy invariant)"
);
});
test("lockfile marks the whole ONNX chain optional", () => {
const lock = readJson<{
packages: Record<
string,
@@ -51,26 +63,61 @@ test("transformers + onnxruntime-node are regular dependencies (not optional)",
dependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
}
>;
>;
}>("package-lock.json");
assert.equal(
lock.packages[""]?.dependencies?.["@huggingface/transformers"],
lock.packages[""]?.optionalDependencies?.["@huggingface/transformers"],
"^4.2.0",
"root lock dependencies must hold transformers as a regular (non-optional) dep"
"root lock optionalDependencies must hold transformers"
);
// Optional flag is only written `true` for genuinely optional packages;
// regular deps leave it absent/null. Assert each is NOT optional.
assert.ok(
!lock.packages["node_modules/@huggingface/transformers"]?.optional,
"transformers must not be marked optional in the lockfile"
assert.equal(
lock.packages[""]?.optionalDependencies?.["onnxruntime-node"],
"1.24.3",
"root lock optionalDependencies must hold onnxruntime-node"
);
assert.ok(
!lock.packages["node_modules/onnxruntime-node"]?.optional,
"onnxruntime-node must not be marked optional in the lockfile"
lock.packages["node_modules/@huggingface/transformers"]?.optional,
"transformers must be marked optional in the lockfile"
);
assert.ok(
!lock.packages["node_modules/onnxruntime-common"]?.optional,
"onnxruntime-common must not be marked optional in the lockfile"
lock.packages["node_modules/onnxruntime-node"]?.optional,
"onnxruntime-node must be marked optional in the lockfile"
);
assert.ok(
lock.packages["node_modules/onnxruntime-common"]?.optional,
"onnxruntime-common must be marked optional in the lockfile"
);
});
test("every @huggingface/transformers consumer loads it lazily so absent installs degrade gracefully", () => {
// If any module ever switches to a STATIC import of the optional chain,
// startup crashes on platforms where npm skipped it (Android/Termux).
// transformersLocal.ts must keep its lazy await import() (D8/D25);
// onnxWorker.ts must keep its runtime-variable dynamicImport indirection.
const embeddingSrc = readFileSync(
join(repoRoot, "src/lib/memory/embedding/transformersLocal.ts"),
"utf8"
);
assert.doesNotMatch(
embeddingSrc,
/^\s*import\s+(?:[^'"]*?\s+from\s+)?["']@huggingface\/transformers["']/m,
"transformersLocal.ts must not statically import @huggingface/transformers"
);
assert.match(
embeddingSrc,
/await import\(["']@huggingface\/transformers["']\)/,
"transformersLocal.ts must load @huggingface/transformers via await import()"
);
const workerSrc = readFileSync(
join(repoRoot, "open-sse/services/compression/engines/llmlingua/onnxWorker.ts"),
"utf8"
);
assert.doesNotMatch(
workerSrc,
/^\s*import\s+(?:[^'"]*?\s+from\s+)?["']@huggingface\/transformers["']/m,
"onnxWorker.ts must not statically import @huggingface/transformers"
);
});