@bendyline/gezel-inference 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +13 -2
- package/dist/cache/adapter.d.ts +115 -0
- package/dist/cache/adapter.js +23 -0
- package/dist/cache/budget.d.ts +15 -0
- package/dist/cache/budget.js +31 -0
- package/dist/cache/controller.d.ts +205 -0
- package/dist/cache/controller.js +377 -0
- package/dist/catalog/LICENSE +21 -0
- package/dist/catalog/chat-models/bt/btl4-35b-q4/manifest.json +146 -0
- package/dist/catalog/chat-models/bt/btl4-35b-q4/versions/1.0.0/manifest.json +15 -0
- package/dist/catalog/chat-models/bt/btl4-35b-q4/versions/1.0.1/manifest.json +15 -0
- package/dist/catalog/chat-models/bt/btl4-compact-iq2/manifest.json +146 -0
- package/dist/catalog/chat-models/bt/btl4-compact-iq2/versions/1.0.0/manifest.json +15 -0
- package/dist/catalog/chat-models/bt/btl4-compact-iq2/versions/1.0.1/manifest.json +15 -0
- package/dist/catalog/chat-models/bt/btl4-compact-iq2/versions/1.0.2/manifest.json +15 -0
- package/dist/catalog/chat-models/de/deepseek-r1-8b-q4/manifest.json +166 -0
- package/dist/catalog/chat-models/de/deepseek-r1-8b-q4/versions/1.1.0/manifest.json +62 -0
- package/dist/catalog/chat-models/de/deepseek-r1-8b-q4/versions/1.1.1/manifest.json +61 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-mxfp4/manifest.json +125 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-mxfp4/versions/1.0.0/manifest.json +27 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2/manifest.json +125 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.0.0/manifest.json +27 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.1.0/manifest.json +27 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2q4/manifest.json +126 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2q4/versions/1.0.0/manifest.json +27 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q4/manifest.json +318 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.0.0/manifest.json +225 -0
- package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.1.0/manifest.json +225 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/manifest.json +249 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.0.0/manifest.json +70 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.1.0/manifest.json +72 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.1.2/manifest.json +78 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.1.3/manifest.json +78 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.2.0/manifest.json +98 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q8/manifest.json +228 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.0.0/manifest.json +72 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.0.2/manifest.json +78 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.0.3/manifest.json +78 -0
- package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.1.0/manifest.json +78 -0
- package/dist/catalog/chat-models/ge/gemma4-26b-q4/manifest.json +220 -0
- package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.1.0/manifest.json +75 -0
- package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.2.0/manifest.json +75 -0
- package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.2.1/manifest.json +80 -0
- package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.2.2/manifest.json +80 -0
- package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.3.0/manifest.json +81 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/manifest.json +226 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.1.0/manifest.json +80 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.1.1/manifest.json +82 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.2.0/manifest.json +82 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.2.1/manifest.json +95 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.2.2/manifest.json +95 -0
- package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.3.0/manifest.json +86 -0
- package/dist/catalog/chat-models/ge/gemma4-e2b-q4/manifest.json +213 -0
- package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.1.0/manifest.json +67 -0
- package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.1.2/manifest.json +75 -0
- package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.2.0/manifest.json +71 -0
- package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.2.1/manifest.json +71 -0
- package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.3.0/manifest.json +71 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/manifest.json +205 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.1.0/manifest.json +72 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.1.2/manifest.json +75 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.2.0/manifest.json +76 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.2.1/manifest.json +76 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.3.0/manifest.json +76 -0
- package/dist/catalog/chat-models/gl/glm-5.2-754b-q2/manifest.json +127 -0
- package/dist/catalog/chat-models/gl/glm-5.2-754b-q2/versions/1.0.0/manifest.json +20 -0
- package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/manifest.json +140 -0
- package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.0/manifest.json +23 -0
- package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.1/manifest.json +26 -0
- package/dist/catalog/chat-models/gp/gpt-oss-120b-q4/manifest.json +247 -0
- package/dist/catalog/chat-models/gp/gpt-oss-120b-q4/versions/1.0.0/manifest.json +137 -0
- package/dist/catalog/chat-models/gp/gpt-oss-120b-q4/versions/1.1.0/manifest.json +135 -0
- package/dist/catalog/chat-models/gp/gpt-oss-20b-q4/manifest.json +195 -0
- package/dist/catalog/chat-models/gp/gpt-oss-20b-q4/versions/1.1.0/manifest.json +72 -0
- package/dist/catalog/chat-models/gp/gpt-oss-20b-q4/versions/1.1.1/manifest.json +71 -0
- package/dist/catalog/chat-models/gr/granite4.2-30b-q4/manifest.json +200 -0
- package/dist/catalog/chat-models/gr/granite4.2-30b-q4/versions/1.0.0/manifest.json +72 -0
- package/dist/catalog/chat-models/gr/granite4.2-3b-q4/manifest.json +196 -0
- package/dist/catalog/chat-models/gr/granite4.2-3b-q4/versions/1.0.0/manifest.json +57 -0
- package/dist/catalog/chat-models/gr/granite4.2-8b-q4/manifest.json +189 -0
- package/dist/catalog/chat-models/gr/granite4.2-8b-q4/versions/1.0.0/manifest.json +57 -0
- package/dist/catalog/chat-models/index.json +1 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/manifest.json +235 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.0/manifest.json +124 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.1/manifest.json +124 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.2/manifest.json +123 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q6/manifest.json +257 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q6/versions/1.0.0/manifest.json +145 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q6/versions/1.0.1/manifest.json +145 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/manifest.json +285 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.0/manifest.json +174 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.1/manifest.json +174 -0
- package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.2/manifest.json +173 -0
- package/dist/catalog/chat-models/lf/lfm2.5-2.6b-q4/manifest.json +162 -0
- package/dist/catalog/chat-models/lf/lfm2.5-2.6b-q4/versions/1.0.0/manifest.json +59 -0
- package/dist/catalog/chat-models/lf/lfm2.5-2.6b-q4/versions/1.0.1/manifest.json +58 -0
- package/dist/catalog/chat-models/ll/llama3.2-3b-q4/manifest.json +134 -0
- package/dist/catalog/chat-models/ll/llama3.2-3b-q4/versions/1.1.0/manifest.json +57 -0
- package/dist/catalog/chat-models/ll/llama3.2-3b-q4/versions/1.1.1/manifest.json +56 -0
- package/dist/catalog/chat-models/mi/minicpm5-1b-q4/manifest.json +156 -0
- package/dist/catalog/chat-models/mi/minicpm5-1b-q4/versions/1.0.0/manifest.json +57 -0
- package/dist/catalog/chat-models/mi/minicpm5-2b-q4/manifest.json +161 -0
- package/dist/catalog/chat-models/mi/minicpm5-2b-q4/versions/1.0.0/manifest.json +57 -0
- package/dist/catalog/chat-models/mi/mistral-7b-q4/manifest.json +159 -0
- package/dist/catalog/chat-models/mi/mistral-7b-q4/versions/1.1.0/manifest.json +62 -0
- package/dist/catalog/chat-models/mi/mistral-7b-q4/versions/1.1.1/manifest.json +61 -0
- package/dist/catalog/chat-models/mi/mistral-medium-3.5-128b-q4/manifest.json +275 -0
- package/dist/catalog/chat-models/mi/mistral-medium-3.5-128b-q4/versions/1.0.0/manifest.json +154 -0
- package/dist/catalog/chat-models/mi/mistral-medium-3.5-128b-q4/versions/1.0.1/manifest.json +153 -0
- package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/manifest.json +135 -0
- package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.0/manifest.json +20 -0
- package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.1/manifest.json +20 -0
- package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.2/manifest.json +20 -0
- package/dist/catalog/chat-models/na/nanbeige4.2-3b-q4/manifest.json +138 -0
- package/dist/catalog/chat-models/na/nanbeige4.2-3b-q4/versions/1.0.0/manifest.json +14 -0
- package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/manifest.json +212 -0
- package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/versions/1.0.0/manifest.json +94 -0
- package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/versions/1.0.1/manifest.json +94 -0
- package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/versions/1.0.2/manifest.json +93 -0
- package/dist/catalog/chat-models/ne/nemotron3-super-120b-q4/manifest.json +135 -0
- package/dist/catalog/chat-models/ne/nemotron3-super-120b-q4/versions/1.0.0/manifest.json +30 -0
- package/dist/catalog/chat-models/ne/nemotron3-super-120b-q4/versions/1.0.1/manifest.json +30 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q4/manifest.json +192 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q4/versions/1.0.0/manifest.json +74 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q4/versions/1.0.1/manifest.json +73 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q8/manifest.json +207 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q8/versions/1.0.0/manifest.json +89 -0
- package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q8/versions/1.0.1/manifest.json +88 -0
- package/dist/catalog/chat-models/or/ornith-35b-q4/manifest.json +224 -0
- package/dist/catalog/chat-models/or/ornith-35b-q4/versions/1.0.0/manifest.json +94 -0
- package/dist/catalog/chat-models/or/ornith-35b-q4/versions/1.0.1/manifest.json +93 -0
- package/dist/catalog/chat-models/or/ornith-35b-q8/manifest.json +244 -0
- package/dist/catalog/chat-models/or/ornith-35b-q8/versions/1.0.0/manifest.json +114 -0
- package/dist/catalog/chat-models/or/ornith-35b-q8/versions/1.0.1/manifest.json +113 -0
- package/dist/catalog/chat-models/or/ornith-9b-q4/manifest.json +215 -0
- package/dist/catalog/chat-models/or/ornith-9b-q4/versions/1.0.0/manifest.json +84 -0
- package/dist/catalog/chat-models/or/ornith-9b-q4/versions/1.0.1/manifest.json +83 -0
- package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q4/manifest.json +208 -0
- package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q4/versions/1.0.0/manifest.json +74 -0
- package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q8/manifest.json +223 -0
- package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q8/versions/1.0.0/manifest.json +89 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q4/manifest.json +187 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q4/versions/1.0.0/manifest.json +53 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q4/versions/1.0.1/manifest.json +77 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q8/manifest.json +192 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q8/versions/1.0.0/manifest.json +58 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q8/versions/1.0.1/manifest.json +82 -0
- package/dist/catalog/chat-models/qw/qwen3.5-0.8b-q4/manifest.json +192 -0
- package/dist/catalog/chat-models/qw/qwen3.5-0.8b-q4/versions/1.0.0/manifest.json +75 -0
- package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/manifest.json +315 -0
- package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.0/manifest.json +164 -0
- package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.1/manifest.json +164 -0
- package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.2/manifest.json +164 -0
- package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.3/manifest.json +163 -0
- package/dist/catalog/chat-models/qw/qwen3.5-27b-q4/manifest.json +217 -0
- package/dist/catalog/chat-models/qw/qwen3.5-27b-q4/versions/1.0.0/manifest.json +90 -0
- package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/manifest.json +194 -0
- package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/versions/1.1.0/manifest.json +77 -0
- package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/versions/1.1.2/manifest.json +76 -0
- package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/versions/1.1.3/manifest.json +76 -0
- package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/manifest.json +188 -0
- package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/versions/1.1.0/manifest.json +77 -0
- package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/versions/1.1.2/manifest.json +76 -0
- package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/versions/1.1.3/manifest.json +76 -0
- package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/manifest.json +205 -0
- package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/versions/1.1.0/manifest.json +82 -0
- package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/versions/1.1.2/manifest.json +81 -0
- package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/versions/1.1.3/manifest.json +81 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/manifest.json +230 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.0/manifest.json +92 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.4/manifest.json +91 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.5/manifest.json +91 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.6/manifest.json +115 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/manifest.json +240 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.0/manifest.json +102 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.2/manifest.json +103 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.3/manifest.json +103 -0
- package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.4/manifest.json +127 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/manifest.json +233 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.0/manifest.json +92 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.1/manifest.json +93 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.2/manifest.json +93 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.3/manifest.json +117 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/manifest.json +252 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.0/manifest.json +112 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.1/manifest.json +113 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.2/manifest.json +113 -0
- package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.3/manifest.json +137 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-iq1-s/manifest.json +195 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-iq1-s/versions/1.0.0/manifest.json +19 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q2/manifest.json +194 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q2/versions/1.0.0/manifest.json +19 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q3/manifest.json +194 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q3/versions/1.0.0/manifest.json +19 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q3/versions/1.0.1/manifest.json +19 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/manifest.json +291 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.0/manifest.json +20 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.1/manifest.json +93 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.2/manifest.json +92 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.3/manifest.json +116 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.4/manifest.json +116 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.5/manifest.json +116 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/manifest.json +278 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.0/manifest.json +20 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.1/manifest.json +104 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.2/manifest.json +103 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.3/manifest.json +127 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/manifest.json +278 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/versions/1.0.0/manifest.json +113 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/versions/1.0.1/manifest.json +113 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/versions/1.0.2/manifest.json +137 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq3/manifest.json +221 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq3/versions/1.0.0/manifest.json +36 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/manifest.json +429 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.0.0/manifest.json +36 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.1.0/manifest.json +205 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.1.1/manifest.json +244 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/manifest.json +203 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.0/manifest.json +21 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.1/manifest.json +31 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.2/manifest.json +30 -0
- package/dist/catalog/chat-models/raw-index.json +1 -0
- package/dist/catalog/chat-models/ta/talkie-1930-13b-q4/manifest.json +79 -0
- package/dist/catalog/chat-models/ta/talkie-1930-13b-q4/versions/1.0.0/manifest.json +15 -0
- package/dist/catalog/chat-models/ta/talkie-1930-13b-q4/versions/1.0.1/manifest.json +15 -0
- package/dist/catalog/chat-models/te/ternary-bonsai-27b-q2/manifest.json +204 -0
- package/dist/catalog/chat-models/te/ternary-bonsai-27b-q2/versions/1.0.0/manifest.json +70 -0
- package/dist/catalog/chat-models/te/ternary-bonsai-27b-q2/versions/1.0.1/manifest.json +70 -0
- package/dist/catalog/chat-models/un/underdog-saluki-27b-iq2-mix/manifest.json +164 -0
- package/dist/catalog/chat-models/un/underdog-saluki-27b-iq2-mix/versions/1.0.0/manifest.json +14 -0
- package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/manifest.json +26 -0
- package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/versions/2026.10.8/manifest.json +8950 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/versions/2026.10.1/manifest.json +658 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/versions/2026.10.1/manifest.json +666 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/versions/2026.10.2/manifest.json +182 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/manifest.json +25 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/versions/2026.10.5/manifest.json +38 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/versions/2026.10.1/manifest.json +558 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/versions/2026.10.1/manifest.json +258 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/versions/2026.10.1/manifest.json +318 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/versions/2026.10.1/manifest.json +266 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/versions/2026.10.1/manifest.json +186 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/versions/2026.10.1/manifest.json +138 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/versions/2026.10.1/manifest.json +138 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/manifest.json +24 -0
- package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/versions/2026.10.3/manifest.json +626 -0
- package/dist/catalog/knowledge-catalogs/index.json +1 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/versions/2026.10.16/manifest.json +18270 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/manifest.json +23 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/versions/2026.10.16/manifest.json +1098 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/manifest.json +23 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/versions/2026.10.16/manifest.json +722 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/manifest.json +23 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/versions/2026.10.16/manifest.json +530 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/manifest.json +23 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/versions/2026.10.16/manifest.json +602 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/manifest.json +23 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/versions/2026.10.16/manifest.json +250 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/versions/2026.10.16/manifest.json +16794 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/versions/2026.10.16/manifest.json +1106 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/versions/2026.10.16/manifest.json +234 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/versions/2026.10.16/manifest.json +522 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/versions/2026.10.16/manifest.json +1850 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/versions/2026.10.16/manifest.json +1734 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/manifest.json +22 -0
- package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/versions/2026.10.16/manifest.json +774 -0
- package/dist/catalog/knowledge-catalogs/raw-index.json +1 -0
- package/dist/catalog/knowledge-catalogs/re/regional-american-south/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-american-south/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-american-south/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-american-south/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-brazil/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-brazil/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-brazil/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-brazil/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-asia/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-asia/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-asia/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-asia/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-middle-east/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-middle-east/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-middle-east/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-middle-east/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-midwest/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-midwest/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-midwest/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-midwest/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-north-africa/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-north-africa/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-north-africa/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-north-africa/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northeast/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northeast/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northeast/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northeast/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-south-asia/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-south-asia/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-south-asia/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-south-asia/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe/manifest.json +48 -0
- package/dist/catalog/knowledge-catalogs/re/regional-western-europe/versions/2026.10.3/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/manifest.json +28 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.4.2/manifest.json +53 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.4.3/manifest.json +885 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.4.5/manifest.json +157 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/art.json +11 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/manifest.json +32 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.4.2/manifest.json +69 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.4.3/manifest.json +741 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.4.5/manifest.json +173 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/manifest.json +69 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.4.4/manifest.json +217 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.4.5/manifest.json +217 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/manifest.json +64 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.4.4/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.4.5/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/manifest.json +64 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.4.5/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/art.json +11 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/manifest.json +29 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.4.2/manifest.json +57 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.4.3/manifest.json +925 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.4.5/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/manifest.json +28 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.4.2/manifest.json +53 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.4.3/manifest.json +1665 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.4.5/manifest.json +133 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/manifest.json +29 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.4.2/manifest.json +57 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.4.3/manifest.json +1233 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.4.5/manifest.json +141 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/art.json +11 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/manifest.json +29 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.4.2/manifest.json +57 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.4.3/manifest.json +493 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.4.5/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/manifest.json +63 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.4.4/manifest.json +193 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.4.5/manifest.json +193 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/manifest.json +30 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.4.2/manifest.json +61 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.4.3/manifest.json +665 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.4.5/manifest.json +177 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/manifest.json +29 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.4.2/manifest.json +57 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.4.3/manifest.json +745 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.4.5/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/manifest.json +62 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.4.4/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.4.5/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/manifest.json +64 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.4.5/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/manifest.json +64 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.4.4/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.4.5/manifest.json +197 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/manifest.json +30 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.4.2/manifest.json +61 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.4.3/manifest.json +1253 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.4.5/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/manifest.json +29 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.4.2/manifest.json +57 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.4.3/manifest.json +1957 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.4.5/manifest.json +185 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/manifest.json +63 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.4.5/manifest.json +193 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/art.json +11 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/manifest.json +45 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.4.4/manifest.json +121 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.4.5/manifest.json +173 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/art.json +12 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/logo.webp +0 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/manifest.json +62 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.4.4/manifest.json +189 -0
- package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.4.5/manifest.json +189 -0
- package/dist/catalog/provenance.json +8 -0
- package/dist/chat/catalog-model-lookup.d.ts +21 -0
- package/dist/chat/catalog-model-lookup.js +48 -0
- package/dist/chat/local-model-tier.d.ts +1 -0
- package/dist/chat/local-model-tier.js +2 -0
- package/dist/chat/vision-capability.d.ts +1 -0
- package/dist/chat/vision-capability.js +3 -0
- package/dist/engine-components.d.ts +30 -0
- package/dist/engine-components.js +144 -0
- package/dist/engines/electron-native-reuse.d.ts +65 -0
- package/dist/engines/electron-native-reuse.js +305 -0
- package/dist/engines/native-file-manifest.json +1320 -0
- package/dist/engines/native-manifest.d.ts +70 -0
- package/dist/engines/native-manifest.js +98 -0
- package/dist/engines/registry.d.ts +88 -0
- package/dist/engines/registry.js +217 -0
- package/dist/engines/resolver.d.ts +121 -0
- package/dist/engines/resolver.js +894 -0
- package/dist/engines/signature.d.ts +85 -0
- package/dist/engines/signature.js +231 -0
- package/dist/fs/atomic.d.ts +53 -0
- package/dist/fs/atomic.js +202 -0
- package/dist/fs/config-store.d.ts +14 -0
- package/dist/fs/config-store.js +101 -0
- package/dist/fs/home-permissions.d.ts +18 -0
- package/dist/fs/home-permissions.js +27 -0
- package/dist/fs/safe-paths.d.ts +107 -0
- package/dist/fs/safe-paths.js +264 -0
- package/dist/fs/security-json.d.ts +13 -0
- package/dist/fs/security-json.js +67 -0
- package/dist/http/auth-context.d.ts +23 -0
- package/dist/http/auth-context.js +1 -0
- package/dist/http/engine-runtime-context.d.ts +30 -0
- package/dist/http/engine-runtime-context.js +1 -0
- package/dist/http/external-conversation-contract.d.ts +49 -0
- package/dist/http/external-conversation-contract.js +1 -0
- package/dist/http/external-conversation-headers.d.ts +11 -0
- package/dist/http/external-conversation-headers.js +11 -0
- package/dist/http/inference-context.d.ts +36 -0
- package/dist/http/inference-context.js +1 -0
- package/dist/http/model-inventory-cache.d.ts +8 -0
- package/dist/http/model-inventory-cache.js +8 -0
- package/dist/http/openai-compat/action-ledger.d.ts +15 -0
- package/dist/http/openai-compat/action-ledger.js +119 -0
- package/dist/http/openai-compat/apple-model.d.ts +3 -0
- package/dist/http/openai-compat/apple-model.js +44 -0
- package/dist/http/openai-compat/caller-owned-profile.d.ts +7 -0
- package/dist/http/openai-compat/caller-owned-profile.js +18 -0
- package/dist/http/openai-compat/chat-progress.d.ts +9 -0
- package/dist/http/openai-compat/chat-progress.js +69 -0
- package/dist/http/openai-compat/chat-target.d.ts +76 -0
- package/dist/http/openai-compat/chat-target.js +97 -0
- package/dist/http/openai-compat/embeddings.d.ts +37 -0
- package/dist/http/openai-compat/embeddings.js +86 -0
- package/dist/http/openai-compat/request-tuning.d.ts +35 -0
- package/dist/http/openai-compat/request-tuning.js +87 -0
- package/dist/http/openai-compat/responses-streaming.d.ts +351 -0
- package/dist/http/openai-compat/responses-streaming.js +717 -0
- package/dist/http/openai-compat/responses-translate.d.ts +215 -0
- package/dist/http/openai-compat/responses-translate.js +377 -0
- package/dist/http/openai-compat/streaming-telemetry.d.ts +30 -0
- package/dist/http/openai-compat/streaming-telemetry.js +88 -0
- package/dist/http/openai-compat/streaming.d.ts +141 -0
- package/dist/http/openai-compat/streaming.js +687 -0
- package/dist/http/openai-compat/tool-call-stream-filter.d.ts +33 -0
- package/dist/http/openai-compat/tool-call-stream-filter.js +110 -0
- package/dist/http/openai-compat/translate.d.ts +254 -0
- package/dist/http/openai-compat/translate.js +485 -0
- package/dist/http/routes/engines.d.ts +13 -0
- package/dist/http/routes/engines.js +366 -0
- package/dist/http/routes/machine-engine-proxy.d.ts +26 -0
- package/dist/http/routes/machine-engine-proxy.js +43 -0
- package/dist/http/routes/model-bundles.d.ts +4 -0
- package/dist/http/routes/model-bundles.js +190 -0
- package/dist/http/routes/v1-chat.d.ts +72 -0
- package/dist/http/routes/v1-chat.js +645 -0
- package/dist/http/routes/v1-embeddings.d.ts +3 -0
- package/dist/http/routes/v1-embeddings.js +82 -0
- package/dist/http/routes/v1-knowledge.d.ts +4 -0
- package/dist/http/routes/v1-knowledge.js +304 -0
- package/dist/http/routes/v1-models-ensure.d.ts +32 -0
- package/dist/http/routes/v1-models-ensure.js +122 -0
- package/dist/http/routes/v1-models.d.ts +8 -0
- package/dist/http/routes/v1-models.js +189 -0
- package/dist/http/routes/v1-responses.d.ts +20 -0
- package/dist/http/routes/v1-responses.js +327 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/inference-service.d.ts +28 -0
- package/dist/inference-service.js +275 -0
- package/dist/knowledge/admission.d.ts +3 -0
- package/dist/knowledge/admission.js +22 -0
- package/dist/knowledge/bundled-catalog.d.ts +2 -0
- package/dist/knowledge/bundled-catalog.js +2 -0
- package/dist/knowledge/catalog-host.d.ts +103 -0
- package/dist/knowledge/catalog-host.js +180 -0
- package/dist/knowledge/catalog-source.d.ts +22 -0
- package/dist/knowledge/catalog-source.js +35 -0
- package/dist/knowledge/install.d.ts +55 -0
- package/dist/knowledge/install.js +274 -0
- package/dist/knowledge/manager.d.ts +287 -0
- package/dist/knowledge/manager.js +1540 -0
- package/dist/knowledge/registry.d.ts +35 -0
- package/dist/knowledge/registry.js +123 -0
- package/dist/knowledge/search-worker.d.ts +17 -0
- package/dist/knowledge/search-worker.js +36 -0
- package/dist/knowledge/shared-install-contract.d.ts +19 -0
- package/dist/knowledge/shared-install-contract.js +1 -0
- package/dist/knowledge/spatial-query.d.ts +11 -0
- package/dist/knowledge/spatial-query.js +33 -0
- package/dist/knowledge/trust-anchors.d.ts +11 -0
- package/dist/knowledge/trust-anchors.js +51 -0
- package/dist/knowledge/vector-floors.d.ts +44 -0
- package/dist/knowledge/vector-floors.js +92 -0
- package/dist/knowledge/worker-host.d.ts +9 -0
- package/dist/knowledge/worker-host.js +179 -0
- package/dist/kokoro-lexicon/LICENSE +202 -0
- package/dist/kokoro-lexicon/lexicon-gb-en.txt.gz +0 -0
- package/dist/kokoro-lexicon/lexicon-us-en.txt.gz +0 -0
- package/dist/kokoro-lexicon/manifest.json +23 -0
- package/dist/machine-engine/inspect-runtime.d.ts +3 -0
- package/dist/machine-engine/inspect-runtime.js +48 -0
- package/dist/machine-engine/knowledge-assets.d.ts +79 -0
- package/dist/machine-engine/knowledge-assets.js +505 -0
- package/dist/memory/embed-core.d.ts +131 -0
- package/dist/memory/embed-core.js +398 -0
- package/dist/memory/embed-worker.d.ts +23 -0
- package/dist/memory/embed-worker.js +49 -0
- package/dist/memory/embeddings.d.ts +105 -0
- package/dist/memory/embeddings.js +467 -0
- package/dist/model-profile/behaviors/tools-mlx-template-fix.d.ts +1 -0
- package/dist/model-profile/behaviors/tools-mlx-template-fix.js +2 -0
- package/dist/model-profile/behaviors/turn-ramble-detection.d.ts +1 -0
- package/dist/model-profile/behaviors/turn-ramble-detection.js +2 -0
- package/dist/model-profile/defaults.d.ts +1 -0
- package/dist/model-profile/defaults.js +2 -0
- package/dist/model-profile/index.d.ts +9 -0
- package/dist/model-profile/index.js +7 -0
- package/dist/model-profile/registry.d.ts +15 -0
- package/dist/model-profile/registry.js +18 -0
- package/dist/model-profile/runtime.d.ts +48 -0
- package/dist/model-profile/runtime.js +131 -0
- package/dist/model-profile/tool-grammar.d.ts +1 -0
- package/dist/model-profile/tool-grammar.js +2 -0
- package/dist/model-profile/tuning.d.ts +19 -0
- package/dist/model-profile/tuning.js +21 -0
- package/dist/model-profile/types.d.ts +1 -0
- package/dist/model-profile/types.js +2 -0
- package/dist/models/bundle-storage.d.ts +28 -0
- package/dist/models/bundle-storage.js +80 -0
- package/dist/models/catalog-drift.d.ts +48 -0
- package/dist/models/catalog-drift.js +94 -0
- package/dist/models/catalog-payload-identity.d.ts +107 -0
- package/dist/models/catalog-payload-identity.js +254 -0
- package/dist/models/ensure.d.ts +125 -0
- package/dist/models/ensure.js +205 -0
- package/dist/models/gezmodel.d.ts +47 -0
- package/dist/models/gezmodel.js +742 -0
- package/dist/models/install-registry.d.ts +101 -0
- package/dist/models/install-registry.js +216 -0
- package/dist/models/model-id.d.ts +22 -0
- package/dist/models/model-id.js +40 -0
- package/dist/models/storage-roots.d.ts +274 -0
- package/dist/models/storage-roots.js +865 -0
- package/dist/native-release-entry.d.ts +16 -0
- package/dist/native-release-entry.js +16 -0
- package/dist/perf/redact-path.d.ts +2 -0
- package/dist/perf/redact-path.js +27 -0
- package/dist/perf/responsiveness.d.ts +70 -0
- package/dist/perf/responsiveness.js +560 -0
- package/dist/providers/active-install-message.d.ts +42 -0
- package/dist/providers/active-install-message.js +49 -0
- package/dist/providers/apple-foundation-models/binary.d.ts +4 -0
- package/dist/providers/apple-foundation-models/binary.js +18 -0
- package/dist/providers/apple-foundation-models/helper.d.ts +66 -0
- package/dist/providers/apple-foundation-models/helper.js +262 -0
- package/dist/providers/apple-foundation-models/provider.d.ts +82 -0
- package/dist/providers/apple-foundation-models/provider.js +389 -0
- package/dist/providers/apple-foundation-models/status.d.ts +9 -0
- package/dist/providers/apple-foundation-models/status.js +49 -0
- package/dist/providers/audio/kokoro-frontend.d.ts +50 -0
- package/dist/providers/audio/kokoro-frontend.js +113 -0
- package/dist/providers/audio/managed-speech-model.d.ts +9 -0
- package/dist/providers/audio/managed-speech-model.js +86 -0
- package/dist/providers/audio/types.d.ts +202 -0
- package/dist/providers/audio/types.js +17 -0
- package/dist/providers/audio/whisper-cpp.d.ts +99 -0
- package/dist/providers/audio/whisper-cpp.js +420 -0
- package/dist/providers/audio-persister-contract.d.ts +13 -0
- package/dist/providers/audio-persister-contract.js +1 -0
- package/dist/providers/catalog-model-config.d.ts +63 -0
- package/dist/providers/catalog-model-config.js +95 -0
- package/dist/providers/code-block-salvage.d.ts +1 -0
- package/dist/providers/code-block-salvage.js +2 -0
- package/dist/providers/codex-cli/reasoning.d.ts +8 -0
- package/dist/providers/codex-cli/reasoning.js +17 -0
- package/dist/providers/complete-tool-call.d.ts +16 -0
- package/dist/providers/complete-tool-call.js +25 -0
- package/dist/providers/constrained-turn.d.ts +1 -0
- package/dist/providers/constrained-turn.js +2 -0
- package/dist/providers/deliverable-read-pacing.d.ts +1 -0
- package/dist/providers/deliverable-read-pacing.js +2 -0
- package/dist/providers/direct-file-work-prompt.d.ts +1 -0
- package/dist/providers/direct-file-work-prompt.js +2 -0
- package/dist/providers/ds4/build-provider.d.ts +100 -0
- package/dist/providers/ds4/build-provider.js +539 -0
- package/dist/providers/ds4/cache-adapter.d.ts +42 -0
- package/dist/providers/ds4/cache-adapter.js +110 -0
- package/dist/providers/ds4/dspark.d.ts +83 -0
- package/dist/providers/ds4/dspark.js +107 -0
- package/dist/providers/ds4/mtp.d.ts +32 -0
- package/dist/providers/ds4/mtp.js +46 -0
- package/dist/providers/ds4/provider.d.ts +67 -0
- package/dist/providers/ds4/provider.js +104 -0
- package/dist/providers/ds4/residency.d.ts +143 -0
- package/dist/providers/ds4/residency.js +139 -0
- package/dist/providers/ds4/stdout-parser.d.ts +47 -0
- package/dist/providers/ds4/stdout-parser.js +134 -0
- package/dist/providers/duplicate-tool-calls.d.ts +1 -0
- package/dist/providers/duplicate-tool-calls.js +2 -0
- package/dist/providers/file-repair-policy.d.ts +1 -0
- package/dist/providers/file-repair-policy.js +2 -0
- package/dist/providers/gpu-arbiter.d.ts +159 -0
- package/dist/providers/gpu-arbiter.js +301 -0
- package/dist/providers/image-persister-contract.d.ts +15 -0
- package/dist/providers/image-persister-contract.js +1 -0
- package/dist/providers/llama-cpp/build-metadata.d.ts +13 -0
- package/dist/providers/llama-cpp/build-metadata.js +39 -0
- package/dist/providers/llama-cpp/build-provider.d.ts +66 -0
- package/dist/providers/llama-cpp/build-provider.js +1491 -0
- package/dist/providers/llama-cpp/cache-adapter.d.ts +242 -0
- package/dist/providers/llama-cpp/cache-adapter.js +689 -0
- package/dist/providers/llama-cpp/devices.d.ts +130 -0
- package/dist/providers/llama-cpp/devices.js +256 -0
- package/dist/providers/llama-cpp/disk-cache.d.ts +8 -0
- package/dist/providers/llama-cpp/disk-cache.js +112 -0
- package/dist/providers/llama-cpp/engine-flags.d.ts +181 -0
- package/dist/providers/llama-cpp/engine-flags.js +279 -0
- package/dist/providers/llama-cpp/gguf-metadata-async.d.ts +11 -0
- package/dist/providers/llama-cpp/gguf-metadata-async.js +180 -0
- package/dist/providers/llama-cpp/gguf-metadata-worker.d.ts +7 -0
- package/dist/providers/llama-cpp/gguf-metadata-worker.js +27 -0
- package/dist/providers/llama-cpp/gguf-metadata.d.ts +198 -0
- package/dist/providers/llama-cpp/gguf-metadata.js +615 -0
- package/dist/providers/llama-cpp/gguf-quantization-backfill.d.ts +32 -0
- package/dist/providers/llama-cpp/gguf-quantization-backfill.js +75 -0
- package/dist/providers/llama-cpp/index.d.ts +10 -0
- package/dist/providers/llama-cpp/index.js +13 -0
- package/dist/providers/llama-cpp/kv-cache-type.d.ts +118 -0
- package/dist/providers/llama-cpp/kv-cache-type.js +140 -0
- package/dist/providers/llama-cpp/log.d.ts +92 -0
- package/dist/providers/llama-cpp/log.js +280 -0
- package/dist/providers/llama-cpp/models.d.ts +389 -0
- package/dist/providers/llama-cpp/models.js +1011 -0
- package/dist/providers/llama-cpp/offload-planner.d.ts +339 -0
- package/dist/providers/llama-cpp/offload-planner.js +524 -0
- package/dist/providers/llama-cpp/provider.d.ts +493 -0
- package/dist/providers/llama-cpp/provider.js +862 -0
- package/dist/providers/llama-cpp/reasoning-launch.d.ts +7 -0
- package/dist/providers/llama-cpp/reasoning-launch.js +14 -0
- package/dist/providers/llama-cpp/spec-draft.d.ts +44 -0
- package/dist/providers/llama-cpp/spec-draft.js +44 -0
- package/dist/providers/llama-cpp/stdout-parser.d.ts +70 -0
- package/dist/providers/llama-cpp/stdout-parser.js +197 -0
- package/dist/providers/local-tool-call-salvage.d.ts +1 -0
- package/dist/providers/local-tool-call-salvage.js +2 -0
- package/dist/providers/local-turn-policy.d.ts +1 -0
- package/dist/providers/local-turn-policy.js +2 -0
- package/dist/providers/mlx/async-file-handoff.d.ts +11 -0
- package/dist/providers/mlx/async-file-handoff.js +25 -0
- package/dist/providers/mlx/build-provider.d.ts +65 -0
- package/dist/providers/mlx/build-provider.js +717 -0
- package/dist/providers/mlx/cache-adapter.d.ts +161 -0
- package/dist/providers/mlx/cache-adapter.js +445 -0
- package/dist/providers/mlx/chat-protocol.d.ts +48 -0
- package/dist/providers/mlx/chat-protocol.js +8 -0
- package/dist/providers/mlx/config-parser.d.ts +29 -0
- package/dist/providers/mlx/config-parser.js +81 -0
- package/dist/providers/mlx/engine-gate.d.ts +51 -0
- package/dist/providers/mlx/engine-gate.js +207 -0
- package/dist/providers/mlx/engine-hold.d.ts +41 -0
- package/dist/providers/mlx/engine-hold.js +59 -0
- package/dist/providers/mlx/engine-log-router.d.ts +84 -0
- package/dist/providers/mlx/engine-log-router.js +137 -0
- package/dist/providers/mlx/engine-stats-sampler.d.ts +36 -0
- package/dist/providers/mlx/engine-stats-sampler.js +59 -0
- package/dist/providers/mlx/index.d.ts +10 -0
- package/dist/providers/mlx/index.js +10 -0
- package/dist/providers/mlx/log.d.ts +55 -0
- package/dist/providers/mlx/log.js +157 -0
- package/dist/providers/mlx/model-geometry.d.ts +35 -0
- package/dist/providers/mlx/model-geometry.js +118 -0
- package/dist/providers/mlx/models.d.ts +289 -0
- package/dist/providers/mlx/models.js +1079 -0
- package/dist/providers/mlx/provider.d.ts +404 -0
- package/dist/providers/mlx/provider.js +3017 -0
- package/dist/providers/mlx/python/cache_persist.py +348 -0
- package/dist/providers/mlx/python/cache_seed.py +402 -0
- package/dist/providers/mlx/python/gezel_mlx_server.py +4491 -0
- package/dist/providers/mlx/python/lfm2_compat.py +55 -0
- package/dist/providers/mlx/python/qwen3_5_text_compat.py +60 -0
- package/dist/providers/mlx/python/qwen4_ple.py +159 -0
- package/dist/providers/mlx/python/spec_decode.py +775 -0
- package/dist/providers/mlx/python/template_stability.py +133 -0
- package/dist/providers/mlx/python/think_budget.py +113 -0
- package/dist/providers/mlx/python/tool_args_json.py +297 -0
- package/dist/providers/mlx/python/tool_call_stream.py +265 -0
- package/dist/providers/mlx/python/tool_grammar.py +794 -0
- package/dist/providers/mlx/python/vision_inputs.py +64 -0
- package/dist/providers/mlx/python/wave_policy.py +147 -0
- package/dist/providers/mlx/reasoning-stream.d.ts +85 -0
- package/dist/providers/mlx/reasoning-stream.js +196 -0
- package/dist/providers/mlx/request-shape.d.ts +34 -0
- package/dist/providers/mlx/request-shape.js +42 -0
- package/dist/providers/mlx/runtime-diagnostics.d.ts +29 -0
- package/dist/providers/mlx/runtime-diagnostics.js +162 -0
- package/dist/providers/mlx/spec-drafter.d.ts +25 -0
- package/dist/providers/mlx/spec-drafter.js +73 -0
- package/dist/providers/mlx/stdout-parser.d.ts +60 -0
- package/dist/providers/mlx/stdout-parser.js +254 -0
- package/dist/providers/mlx/textual-tool-call-salvage.d.ts +46 -0
- package/dist/providers/mlx/textual-tool-call-salvage.js +396 -0
- package/dist/providers/mlx/tool-call-protocol.d.ts +65 -0
- package/dist/providers/mlx/tool-call-protocol.js +140 -0
- package/dist/providers/mlx/tool-call-stripper.d.ts +68 -0
- package/dist/providers/mlx/tool-call-stripper.js +153 -0
- package/dist/providers/mlx/tool-image-retention.d.ts +23 -0
- package/dist/providers/mlx/tool-image-retention.js +43 -0
- package/dist/providers/mlx/turn-telemetry.d.ts +22 -0
- package/dist/providers/mlx/turn-telemetry.js +45 -0
- package/dist/providers/mlx/venv.d.ts +91 -0
- package/dist/providers/mlx/venv.js +111 -0
- package/dist/providers/mlx/vision-mode.d.ts +92 -0
- package/dist/providers/mlx/vision-mode.js +187 -0
- package/dist/providers/mlx/vision.d.ts +2 -0
- package/dist/providers/mlx/vision.js +12 -0
- package/dist/providers/mlx/wire-transcript.d.ts +14 -0
- package/dist/providers/mlx/wire-transcript.js +43 -0
- package/dist/providers/native/capacity-broker.d.ts +812 -0
- package/dist/providers/native/capacity-broker.js +1058 -0
- package/dist/providers/native/capacity-budget.d.ts +133 -0
- package/dist/providers/native/capacity-budget.js +265 -0
- package/dist/providers/native/device-capacity-ledger.d.ts +31 -0
- package/dist/providers/native/device-capacity-ledger.js +196 -0
- package/dist/providers/native/device-capacity.d.ts +84 -0
- package/dist/providers/native/device-capacity.js +431 -0
- package/dist/providers/native/engine-api-key.d.ts +57 -0
- package/dist/providers/native/engine-api-key.js +72 -0
- package/dist/providers/native/engine-key.d.ts +18 -0
- package/dist/providers/native/engine-key.js +41 -0
- package/dist/providers/native/engine-router.d.ts +145 -0
- package/dist/providers/native/engine-router.js +191 -0
- package/dist/providers/native/gpu-panic-guard.d.ts +54 -0
- package/dist/providers/native/gpu-panic-guard.js +59 -0
- package/dist/providers/native/inference.d.ts +33 -0
- package/dist/providers/native/inference.js +49 -0
- package/dist/providers/native/local-engine-runtime.d.ts +412 -0
- package/dist/providers/native/local-engine-runtime.js +1714 -0
- package/dist/providers/native/measured-budget.d.ts +32 -0
- package/dist/providers/native/measured-budget.js +54 -0
- package/dist/providers/native/port.d.ts +11 -0
- package/dist/providers/native/port.js +29 -0
- package/dist/providers/native/provider-pool.d.ts +474 -0
- package/dist/providers/native/provider-pool.js +1166 -0
- package/dist/providers/native/supervisor.d.ts +503 -0
- package/dist/providers/native/supervisor.js +1466 -0
- package/dist/providers/observation-context.d.ts +16 -0
- package/dist/providers/observation-context.js +1 -0
- package/dist/providers/openai-compatible/sse.d.ts +1 -0
- package/dist/providers/openai-compatible/sse.js +2 -0
- package/dist/providers/patient-fetch.d.ts +36 -0
- package/dist/providers/patient-fetch.js +44 -0
- package/dist/providers/project-macro-loop-bail.d.ts +7 -0
- package/dist/providers/project-macro-loop-bail.js +21 -0
- package/dist/providers/prose-document-salvage.d.ts +1 -0
- package/dist/providers/prose-document-salvage.js +2 -0
- package/dist/providers/provider-disposal.d.ts +1 -0
- package/dist/providers/provider-disposal.js +2 -0
- package/dist/providers/queue.d.ts +15 -0
- package/dist/providers/queue.js +23 -0
- package/dist/providers/ramble-abort-message.d.ts +1 -0
- package/dist/providers/ramble-abort-message.js +2 -0
- package/dist/providers/ramble-detector.d.ts +1 -0
- package/dist/providers/ramble-detector.js +2 -0
- package/dist/providers/reasoning-depth.d.ts +1 -0
- package/dist/providers/reasoning-depth.js +2 -0
- package/dist/providers/required-input-reads.d.ts +1 -0
- package/dist/providers/required-input-reads.js +2 -0
- package/dist/providers/session-defaults.d.ts +13 -0
- package/dist/providers/session-defaults.js +49 -0
- package/dist/providers/session-hooks.d.ts +26 -0
- package/dist/providers/session-hooks.js +1 -0
- package/dist/providers/streaming-session.d.ts +1 -0
- package/dist/providers/streaming-session.js +2 -0
- package/dist/providers/terminal-tool-policy.d.ts +1 -0
- package/dist/providers/terminal-tool-policy.js +2 -0
- package/dist/providers/tool-arg-schema-coercion.d.ts +1 -0
- package/dist/providers/tool-arg-schema-coercion.js +2 -0
- package/dist/providers/tool-executor.d.ts +12 -0
- package/dist/providers/tool-executor.js +20 -0
- package/dist/providers/tool-failure-tracker.d.ts +1 -0
- package/dist/providers/tool-failure-tracker.js +2 -0
- package/dist/providers/tool-repeat-tracker.d.ts +1 -0
- package/dist/providers/tool-repeat-tracker.js +2 -0
- package/dist/providers/turn-timeout.d.ts +1 -0
- package/dist/providers/turn-timeout.js +1 -0
- package/dist/providers/types.d.ts +834 -0
- package/dist/providers/types.js +42 -0
- package/dist/providers/usage-builder.d.ts +1 -0
- package/dist/providers/usage-builder.js +2 -0
- package/dist/providers/vision-capability.d.ts +109 -0
- package/dist/providers/vision-capability.js +137 -0
- package/dist/python/mlx-runtime-status-bus.d.ts +39 -0
- package/dist/python/mlx-runtime-status-bus.js +27 -0
- package/dist/python/uv-runtime.d.ts +176 -0
- package/dist/python/uv-runtime.js +492 -0
- package/dist/relevance/install.d.ts +28 -0
- package/dist/relevance/install.js +114 -0
- package/dist/relevance/manager.d.ts +79 -0
- package/dist/relevance/manager.js +211 -0
- package/dist/relevance/registry.d.ts +11 -0
- package/dist/relevance/registry.js +158 -0
- package/dist/relevance/relevance-core.d.ts +67 -0
- package/dist/relevance/relevance-core.js +189 -0
- package/dist/relevance/relevance-model.d.ts +42 -0
- package/dist/relevance/relevance-model.js +292 -0
- package/dist/relevance/relevance-worker.d.ts +20 -0
- package/dist/relevance/relevance-worker.js +57 -0
- package/dist/relevance/settings.d.ts +30 -0
- package/dist/relevance/settings.js +81 -0
- package/dist/remotes/identity.d.ts +121 -0
- package/dist/remotes/identity.js +348 -0
- package/dist/remotes/pinned-fetch.d.ts +45 -0
- package/dist/remotes/pinned-fetch.js +193 -0
- package/dist/remotes/types.d.ts +54 -0
- package/dist/remotes/types.js +1 -0
- package/dist/runtime-lock.d.ts +29 -0
- package/dist/runtime-lock.js +85 -0
- package/dist/search/relevance-stage.d.ts +81 -0
- package/dist/search/relevance-stage.js +177 -0
- package/dist/secrets/types.d.ts +63 -0
- package/dist/secrets/types.js +64 -0
- package/dist/speech.d.ts +1 -0
- package/dist/speech.js +1 -0
- package/dist/system/darwin-memory.d.ts +26 -0
- package/dist/system/darwin-memory.js +81 -0
- package/dist/system/gezel-process-memory.d.ts +55 -0
- package/dist/system/gezel-process-memory.js +156 -0
- package/dist/system/memory.d.ts +154 -0
- package/dist/system/memory.js +501 -0
- package/dist/transformers-cache.d.ts +112 -0
- package/dist/transformers-cache.js +392 -0
- package/dist/utils/disk-space.d.ts +55 -0
- package/dist/utils/disk-space.js +72 -0
- package/dist/utils/download-common.d.ts +138 -0
- package/dist/utils/download-common.js +196 -0
- package/dist/utils/download-with-retry.d.ts +85 -0
- package/dist/utils/download-with-retry.js +522 -0
- package/dist/utils/extract-zip.d.ts +22 -0
- package/dist/utils/extract-zip.js +103 -0
- package/dist/utils/retire-model-worker.d.ts +15 -0
- package/dist/utils/retire-model-worker.js +24 -0
- package/dist/utils/service-worker-entry.d.ts +59 -0
- package/dist/utils/service-worker-entry.js +69 -0
- package/dist/utils/xet-download.d.ts +40 -0
- package/dist/utils/xet-download.js +526 -0
- package/dist/utils/xet.d.ts +86 -0
- package/dist/utils/xet.js +201 -0
- package/package.json +103 -3
- package/scripts/embedding-packaging.cjs +264 -0
- package/scripts/embedding-packaging.d.cts +16 -0
|
@@ -0,0 +1,894 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { createReadStream, existsSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { HttpStatusError, createLogger, nowIso, resolveDistributionProfile, retryTransient, } from '@bendyline/gezel';
|
|
6
|
+
import { DUCKDB_APPLE_TEAM_ID, DUCKDB_ARCHIVE_SHA256, DUCKDB_ASSET, DUCKDB_BINARY_SHA256, DUCKDB_VERSION, DUCKDB_WINDOWS_PUBLISHER, MXC_EXECUTOR_NAME, MXC_EXECUTOR_SHA256, MXC_LICENSE_SHA256, MXC_TARBALL_INTEGRITY, MXC_TARBALL_LICENSE_ENTRY, MXC_TARBALL_SHA256, MXC_TARBALL_URL, MXC_VERIFIED_SENTINEL, MXC_VERSION, MXC_WINDOWS_PUBLISHER, duckdbAssetUrl, duckdbBinaryName, duckdbInstallDir, duckdbPlatformKey, mxcArch, mxcInstallDir, mxcTarballEntry, resolvePlatformKey, windowsHeadlessSpawnOptions, } from '@bendyline/gezel/native';
|
|
7
|
+
import * as tar from 'tar';
|
|
8
|
+
import { downloadWithRetry, friendlyErrors, } from '../utils/download-with-retry.js';
|
|
9
|
+
import { extractZip } from '../utils/extract-zip.js';
|
|
10
|
+
import { NATIVE_ENGINE_ARCHIVE_SHA256, SHA256SUMS_DIGEST, effectiveEngineRelease, isPlaceholderDigest, } from './native-manifest.js';
|
|
11
|
+
import { BENDYLINE_APPLE_TEAM_ID, BENDYLINE_PUBLISHER, stripQuarantine, verifyCodeSignature, } from './signature.js';
|
|
12
|
+
const log = createLogger('engine-resolver');
|
|
13
|
+
const REPO = 'bendyline/gezel';
|
|
14
|
+
const GITHUB_API = 'https://api.github.com';
|
|
15
|
+
/** Map each engine to the env var the providers read (mirrors discover.ts). */
|
|
16
|
+
/**
|
|
17
|
+
* Engines we redistribute exactly as their upstream published them. They keep
|
|
18
|
+
* the upstream file name (no `gezel-` prefix) and, on Windows, ship unsigned —
|
|
19
|
+
* so the signature policy softens to `prefer` and no publisher is asserted.
|
|
20
|
+
* Kept in lockstep with `UNPREFIXED_BINARIES` in core's native/discover.ts and
|
|
21
|
+
* the Windows allowlist in packages/app/scripts/third-party-binaries.cjs.
|
|
22
|
+
*/
|
|
23
|
+
const VENDORED_UNMODIFIED_ENGINES = new Set(['uv', 'duckdb']);
|
|
24
|
+
function isVendoredUnmodifiedEngine(engine) {
|
|
25
|
+
return VENDORED_UNMODIFIED_ENGINES.has(engine);
|
|
26
|
+
}
|
|
27
|
+
const ENGINE_ENV_VAR = {
|
|
28
|
+
'llama-server': 'GEZEL_LLAMA_SERVER_BIN',
|
|
29
|
+
'ds4-server': 'GEZEL_DS4_SERVER_BIN',
|
|
30
|
+
'sd-server': 'GEZEL_SD_SERVER_BIN',
|
|
31
|
+
'whisper-server': 'GEZEL_WHISPER_SERVER_BIN',
|
|
32
|
+
'device-health': 'GEZEL_DEVICE_HEALTH_BIN',
|
|
33
|
+
uv: 'GEZEL_UV_BIN',
|
|
34
|
+
duckdb: 'GEZEL_DUCKDB_BIN',
|
|
35
|
+
'apple-fm': 'GEZEL_APPLE_FM_BIN',
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Thrown for the "can't resolve, and that's expected/actionable" cases:
|
|
39
|
+
* no pinned release, asset missing, verification failed. Callers surface
|
|
40
|
+
* the message; they don't retry blindly.
|
|
41
|
+
*/
|
|
42
|
+
export class EngineUnavailableError extends Error {
|
|
43
|
+
constructor(message) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = 'EngineUnavailableError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve an engine binary: return a cached one if present, else download
|
|
50
|
+
* the right platform+variant archive from the pinned `native-v<version>`
|
|
51
|
+
* release, verify (SHA256SUMS digest → archive sha → code signature),
|
|
52
|
+
* extract atomically into `~/.gezel/engines/native-bin/<version>/<key>/`,
|
|
53
|
+
* and stamp the provider env var.
|
|
54
|
+
*
|
|
55
|
+
* macOS release notarization happens in CI against the signed archive before
|
|
56
|
+
* its hashes are pinned here. Bare command-line binaries cannot be stapled or
|
|
57
|
+
* assessed as app bundles, so runtime verification deliberately checks the
|
|
58
|
+
* source-pinned bytes and Developer ID identity without invoking `spctl`.
|
|
59
|
+
*
|
|
60
|
+
* Yields `progress`/`retrying`/`verifying`/`done`/`error`; the generator's
|
|
61
|
+
* RETURN value carries the resolved result. On a handled failure it yields
|
|
62
|
+
* a terminal `error` then throws {@link EngineUnavailableError} on the next
|
|
63
|
+
* pull (so registry consumers break on the event and direct drainers see
|
|
64
|
+
* the throw — see `resolveEngineToCompletion`).
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Resolve a **vendored** engine — one Gezel redistributes exactly as its
|
|
68
|
+
* upstream published it, rather than building.
|
|
69
|
+
*
|
|
70
|
+
* Today that is DuckDB alone. It does not go through the flow below because
|
|
71
|
+
* almost none of that flow applies: there is no `native-v*` release to look
|
|
72
|
+
* up, no `SHA256SUMS` manifest to digest-pin, no `gezel-` prefixed artifact
|
|
73
|
+
* name, and no Bendyline signature to assert. What replaces them is a
|
|
74
|
+
* stronger, simpler chain — the archive digest and the executable digest are
|
|
75
|
+
* both baked into this build (`packages/core/src/native/duckdb-pin.ts`), so
|
|
76
|
+
* the bytes are pinned twice over without trusting any intermediary manifest.
|
|
77
|
+
*
|
|
78
|
+
* The signature check asserts the **vendor's** identity, not ours: the
|
|
79
|
+
* DuckDB Foundation's Apple team on macOS, their Authenticode subject on
|
|
80
|
+
* Windows. That is deliberately stricter than the Windows precedent for
|
|
81
|
+
* vendored binaries, which asserts no publisher at all — the point of
|
|
82
|
+
* shipping the vendor's bytes is that the vendor's attestation travels with
|
|
83
|
+
* them, so we should be checking it.
|
|
84
|
+
*
|
|
85
|
+
* Landing directory is {@link duckdbInstallDir}, keyed by DuckDB's own
|
|
86
|
+
* version rather than the Gezel native-release version, and shared with the
|
|
87
|
+
* Electron bundle installer. One machine gets one verified copy no matter
|
|
88
|
+
* which install path produced it.
|
|
89
|
+
*/
|
|
90
|
+
async function* resolveVendoredDuckdb(opts) {
|
|
91
|
+
const key = duckdbPlatformKey(process.platform, process.arch);
|
|
92
|
+
if (!key) {
|
|
93
|
+
yield* fail(`DuckDB publishes no build for ${process.platform}/${process.arch}. Install DuckDB with your package manager (https://install.duckdb.org) and set GEZEL_DUCKDB_BIN to its path.`);
|
|
94
|
+
}
|
|
95
|
+
const platformKey = key;
|
|
96
|
+
const isWin = process.platform === 'win32';
|
|
97
|
+
const binaryName = duckdbBinaryName(process.platform);
|
|
98
|
+
const cacheDir = duckdbInstallDir(opts.home);
|
|
99
|
+
const binPath = join(cacheDir, binaryName);
|
|
100
|
+
const sentinelPath = join(cacheDir, '.verified.json');
|
|
101
|
+
const archiveName = DUCKDB_ASSET[platformKey];
|
|
102
|
+
const expectedArchiveSha = (opts.expectedArchiveSha256?.[archiveName] ?? DUCKDB_ARCHIVE_SHA256[platformKey]).toLowerCase();
|
|
103
|
+
const expectedBinarySha = (opts.expectedBinarySha256 ?? DUCKDB_BINARY_SHA256[platformKey]).toLowerCase();
|
|
104
|
+
const verifyAuthenticity = opts.verifyOverride ?? verifyCodeSignature;
|
|
105
|
+
// Vendor identity, per platform. Linux ELF carries no signature at all, so
|
|
106
|
+
// the digests are the whole check there — which is also true of every other
|
|
107
|
+
// Linux engine we ship.
|
|
108
|
+
const verifyOptions = process.platform === 'darwin'
|
|
109
|
+
? {
|
|
110
|
+
policy: 'require',
|
|
111
|
+
expectedAppleTeamId: DUCKDB_APPLE_TEAM_ID,
|
|
112
|
+
}
|
|
113
|
+
: isWin
|
|
114
|
+
? {
|
|
115
|
+
policy: 'prefer',
|
|
116
|
+
expectedPublisher: DUCKDB_WINDOWS_PUBLISHER,
|
|
117
|
+
}
|
|
118
|
+
: { policy: 'skip' };
|
|
119
|
+
// Warm cache: the sentinel records the digest this build expects, so a pin
|
|
120
|
+
// bump invalidates it without a version-string comparison.
|
|
121
|
+
if (existsSync(binPath) && existsSync(sentinelPath)) {
|
|
122
|
+
const sentinel = await readSentinel(sentinelPath);
|
|
123
|
+
if (sentinel.archiveSha?.toLowerCase() === expectedArchiveSha) {
|
|
124
|
+
const { result: signature, accepted } = await verifyAuthenticity(binPath, verifyOptions);
|
|
125
|
+
if (!accepted) {
|
|
126
|
+
yield* fail(`cached DuckDB failed signature policy '${verifyOptions.policy}': ${signature.status}${signature.detail ? ` (${signature.detail})` : ''}`);
|
|
127
|
+
}
|
|
128
|
+
process.env[ENGINE_ENV_VAR.duckdb] = binPath;
|
|
129
|
+
yield { type: 'done', binPath, cached: true };
|
|
130
|
+
return {
|
|
131
|
+
binPath,
|
|
132
|
+
cached: true,
|
|
133
|
+
signature,
|
|
134
|
+
version: DUCKDB_VERSION,
|
|
135
|
+
assetPlatformKey: platformKey,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Same placement rationale as the native-engine gate: after the warm cache,
|
|
140
|
+
// before the first byte of network.
|
|
141
|
+
const duckdbDistribution = resolveDistributionProfile();
|
|
142
|
+
if (!duckdbDistribution.allowEngineBinaryDownloads) {
|
|
143
|
+
yield* fail(duckdbDistribution.refusalReason('engine-download'));
|
|
144
|
+
}
|
|
145
|
+
await mkdir(cacheDir, { recursive: true });
|
|
146
|
+
const tmpExtractDir = `${cacheDir}.tmp`;
|
|
147
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
148
|
+
const archivePath = join(cacheDir, `${archiveName}.download`);
|
|
149
|
+
// No auth header and no GitHub API call: these are public release assets
|
|
150
|
+
// fetched by direct URL, so the 60-request/hour unauthenticated API limit
|
|
151
|
+
// that constrains the native-release path does not apply here at all.
|
|
152
|
+
const dl = downloadWithRetry({
|
|
153
|
+
url: opts.vendoredUrlOverride ?? duckdbAssetUrl(platformKey),
|
|
154
|
+
destPath: archivePath,
|
|
155
|
+
approxSizeBytes: 0,
|
|
156
|
+
fetchImpl: opts.fetchImpl ?? globalThis.fetch,
|
|
157
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
158
|
+
});
|
|
159
|
+
let outcome;
|
|
160
|
+
while (true) {
|
|
161
|
+
const step = await dl.next();
|
|
162
|
+
if (step.done) {
|
|
163
|
+
outcome = step.value;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
const ev = step.value;
|
|
167
|
+
if (ev.type === 'progress') {
|
|
168
|
+
yield { type: 'progress', bytesWritten: ev.bytesWritten, totalBytes: ev.totalBytes };
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
yield {
|
|
172
|
+
type: 'retrying',
|
|
173
|
+
attempt: ev.attempt,
|
|
174
|
+
maxAttempts: ev.maxAttempts,
|
|
175
|
+
delayMs: ev.delayMs,
|
|
176
|
+
reason: ev.reason,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const partialPath = `${archivePath}.partial`;
|
|
181
|
+
if (!outcome || outcome.kind === 'aborted')
|
|
182
|
+
yield* fail('DuckDB download was cancelled');
|
|
183
|
+
if (outcome && outcome.kind === 'error')
|
|
184
|
+
yield* fail(outcome.error);
|
|
185
|
+
yield { type: 'verifying', what: 'sha256' };
|
|
186
|
+
const actualSha = (await sha256File(partialPath)).toLowerCase();
|
|
187
|
+
if (actualSha !== expectedArchiveSha) {
|
|
188
|
+
await rm(partialPath, { force: true });
|
|
189
|
+
yield* fail(`${archiveName} failed integrity check: expected ${expectedArchiveSha.slice(0, 16)}…, got ${actualSha.slice(0, 16)}…`);
|
|
190
|
+
}
|
|
191
|
+
await mkdir(tmpExtractDir, { recursive: true });
|
|
192
|
+
try {
|
|
193
|
+
yield* extractWithProgress((onProgress) => extractZip(partialPath, tmpExtractDir, { ...signalOpt(opts.signal), onProgress }));
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
await rm(partialPath, { force: true });
|
|
197
|
+
}
|
|
198
|
+
// The CLI archive holds a single `duckdb` at its root, but locate it by
|
|
199
|
+
// walk so an upstream layout change fails loudly instead of publishing an
|
|
200
|
+
// empty directory.
|
|
201
|
+
const tmpBin = findNamedFile(tmpExtractDir, binaryName);
|
|
202
|
+
if (!tmpBin) {
|
|
203
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
204
|
+
yield* fail(`extracted ${archiveName} but no '${binaryName}' was inside it`);
|
|
205
|
+
}
|
|
206
|
+
if (!isWin)
|
|
207
|
+
await chmod(tmpBin, 0o755).catch(() => { });
|
|
208
|
+
// Second digest: the archive check above proves we downloaded the published
|
|
209
|
+
// asset; this proves the executable inside it is the one the Electron
|
|
210
|
+
// bundle also ships, which is what makes the two install paths equivalent.
|
|
211
|
+
const binarySha = (await sha256File(tmpBin)).toLowerCase();
|
|
212
|
+
if (binarySha !== expectedBinarySha) {
|
|
213
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
214
|
+
yield* fail(`${binaryName} inside ${archiveName} failed integrity check: expected ${expectedBinarySha.slice(0, 16)}…, got ${binarySha.slice(0, 16)}…`);
|
|
215
|
+
}
|
|
216
|
+
yield { type: 'verifying', what: 'signature' };
|
|
217
|
+
await stripQuarantine(tmpBin);
|
|
218
|
+
const { result: signature, accepted } = await verifyAuthenticity(tmpBin, verifyOptions);
|
|
219
|
+
if (!accepted) {
|
|
220
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
221
|
+
yield* fail(`DuckDB failed signature policy '${verifyOptions.policy}': ${signature.status}${signature.detail ? ` (${signature.detail})` : ''}`);
|
|
222
|
+
}
|
|
223
|
+
await rm(cacheDir, { recursive: true, force: true });
|
|
224
|
+
await rename(tmpExtractDir, cacheDir);
|
|
225
|
+
await writeFile(sentinelPath, `${JSON.stringify({
|
|
226
|
+
engine: 'duckdb',
|
|
227
|
+
version: DUCKDB_VERSION,
|
|
228
|
+
assetPlatformKey: platformKey,
|
|
229
|
+
archiveName,
|
|
230
|
+
archiveSha: actualSha,
|
|
231
|
+
binarySha,
|
|
232
|
+
signature,
|
|
233
|
+
verifiedAt: nowIso(),
|
|
234
|
+
}, null, 2)}\n`, 'utf8');
|
|
235
|
+
// Deliberately NOT stampEnv: that also repoints GEZEL_NATIVE_BIN_DIR, which
|
|
236
|
+
// is the root the other engines resolve their siblings from. DuckDB lives in
|
|
237
|
+
// its own version-keyed tree and has no siblings there, so pointing the
|
|
238
|
+
// native-bin root at it would break llama/sd/whisper discovery on next boot.
|
|
239
|
+
process.env[ENGINE_ENV_VAR.duckdb] = binPath;
|
|
240
|
+
log.info(`[engine-resolver] resolved duckdb ${DUCKDB_VERSION} → ${binPath} [sig=${signature.status}]`);
|
|
241
|
+
yield { type: 'done', binPath, cached: false };
|
|
242
|
+
return {
|
|
243
|
+
binPath,
|
|
244
|
+
cached: false,
|
|
245
|
+
signature,
|
|
246
|
+
version: DUCKDB_VERSION,
|
|
247
|
+
assetPlatformKey: platformKey,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/** Ceiling on the tarball download; the pinned 1.0.0 tarball is ~38 MB. */
|
|
251
|
+
const MXC_TARBALL_MAX_BYTES = 128 * 1024 * 1024;
|
|
252
|
+
const mxcResolutions = new Map();
|
|
253
|
+
/**
|
|
254
|
+
* Resolve Microsoft's MXC launcher (`wxc-exec.exe`) for an npm / CLI install,
|
|
255
|
+
* which has no Electron bundle to install it from. Windows only.
|
|
256
|
+
*
|
|
257
|
+
* Returns the verified launcher path, or `null` when there is none: another
|
|
258
|
+
* platform, an arch MXC ships nothing for, a store build, `allowDownload:
|
|
259
|
+
* false` with nothing installed, or any failed check. Never throws — without a
|
|
260
|
+
* launcher, sandboxed scripts run uncontained and the sandbox status says so.
|
|
261
|
+
*
|
|
262
|
+
* Unlike {@link resolveVendoredDuckdb} it does not stamp an environment
|
|
263
|
+
* variable: whether the launcher is used is the caller's decision, and the
|
|
264
|
+
* sandbox's lookup finds a verified install through `readVerifiedMxcExecutor`.
|
|
265
|
+
*
|
|
266
|
+
* The chain is entirely pinned in this build (`core/src/native/mxc-pin.ts`):
|
|
267
|
+
* npm's sha512 integrity and the sha256 of the tarball, the per-arch
|
|
268
|
+
* executable digest, the license digest, and Microsoft's Authenticode
|
|
269
|
+
* signature under policy `require`. Only the launcher and the license leave
|
|
270
|
+
* the tarball. The result lands in the directory the Electron installer also
|
|
271
|
+
* uses, with the same sentinel, so either installer satisfies the other.
|
|
272
|
+
*/
|
|
273
|
+
export function resolveVendoredMxc(home, opts = {}) {
|
|
274
|
+
// Concurrent callers share one download; a no-download probe never waits on
|
|
275
|
+
// or rides a download it did not ask for.
|
|
276
|
+
const key = `${home}\0${opts.allowDownload !== false}`;
|
|
277
|
+
const pending = mxcResolutions.get(key);
|
|
278
|
+
if (pending)
|
|
279
|
+
return pending;
|
|
280
|
+
const run = resolveVendoredMxcOnce(home, opts)
|
|
281
|
+
.catch((err) => {
|
|
282
|
+
log.warn(`[engine-resolver] mxc launcher unavailable: ${String(err)}`);
|
|
283
|
+
return null;
|
|
284
|
+
})
|
|
285
|
+
.finally(() => mxcResolutions.delete(key));
|
|
286
|
+
mxcResolutions.set(key, run);
|
|
287
|
+
return run;
|
|
288
|
+
}
|
|
289
|
+
async function resolveVendoredMxcOnce(home, opts) {
|
|
290
|
+
if ((opts.platform ?? process.platform) !== 'win32')
|
|
291
|
+
return null;
|
|
292
|
+
const arch = opts.arch !== undefined ? opts.arch : mxcArch();
|
|
293
|
+
if (!arch) {
|
|
294
|
+
log.info('[engine-resolver] MXC ships no launcher for this machine architecture');
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
const expectedExecutorSha = (opts.expectedExecutorSha256 ?? MXC_EXECUTOR_SHA256[arch]).toLowerCase();
|
|
298
|
+
const verifyAuthenticity = opts.verifyOverride ?? verifyCodeSignature;
|
|
299
|
+
const verifyOptions = {
|
|
300
|
+
policy: 'require',
|
|
301
|
+
expectedPublisher: MXC_WINDOWS_PUBLISHER,
|
|
302
|
+
};
|
|
303
|
+
const installDir = mxcInstallDir(home);
|
|
304
|
+
const executor = join(installDir, MXC_EXECUTOR_NAME);
|
|
305
|
+
const sentinelPath = join(installDir, MXC_VERIFIED_SENTINEL);
|
|
306
|
+
if (existsSync(executor) && existsSync(sentinelPath)) {
|
|
307
|
+
const sentinel = await readMxcSentinel(sentinelPath);
|
|
308
|
+
if (sentinel?.version === MXC_VERSION &&
|
|
309
|
+
sentinel.sha256?.toLowerCase() === expectedExecutorSha &&
|
|
310
|
+
(await sha256File(executor)) === expectedExecutorSha) {
|
|
311
|
+
const { result, accepted } = await verifyAuthenticity(executor, verifyOptions);
|
|
312
|
+
if (accepted)
|
|
313
|
+
return executor;
|
|
314
|
+
// The bytes are already the pinned ones, so downloading them again
|
|
315
|
+
// would meet the same verdict.
|
|
316
|
+
log.warn(`[engine-resolver] installed mxc launcher failed signature policy 'require': ${result.status}${result.detail ? ` (${result.detail})` : ''}`);
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (opts.allowDownload === false)
|
|
321
|
+
return null;
|
|
322
|
+
const distribution = resolveDistributionProfile();
|
|
323
|
+
if (!distribution.allowEngineBinaryDownloads) {
|
|
324
|
+
log.info(`[engine-resolver] ${distribution.refusalReason('engine-download')}`);
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
const expectedIntegrity = opts.expectedIntegrity ?? MXC_TARBALL_INTEGRITY;
|
|
328
|
+
const expectedTarballSha = (opts.expectedTarballSha256 ?? MXC_TARBALL_SHA256).toLowerCase();
|
|
329
|
+
const expectedLicenseSha = (opts.expectedLicenseSha256 ?? MXC_LICENSE_SHA256).toLowerCase();
|
|
330
|
+
const enginesDir = dirname(installDir);
|
|
331
|
+
await mkdir(enginesDir, { recursive: true });
|
|
332
|
+
const tarballPath = join(enginesDir, `mxc-sdk-${MXC_VERSION}.tgz.download`);
|
|
333
|
+
const partialPath = `${tarballPath}.partial`;
|
|
334
|
+
const stagingDir = `${installDir}.tmp-${process.pid}-${Date.now()}`;
|
|
335
|
+
try {
|
|
336
|
+
const dl = downloadWithRetry({
|
|
337
|
+
url: opts.tarballUrl ?? MXC_TARBALL_URL,
|
|
338
|
+
destPath: tarballPath,
|
|
339
|
+
approxSizeBytes: 0,
|
|
340
|
+
maxBytes: MXC_TARBALL_MAX_BYTES,
|
|
341
|
+
fetchImpl: opts.fetchImpl ?? globalThis.fetch,
|
|
342
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
343
|
+
});
|
|
344
|
+
let outcome;
|
|
345
|
+
while (true) {
|
|
346
|
+
const step = await dl.next();
|
|
347
|
+
if (step.done) {
|
|
348
|
+
outcome = step.value;
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (!outcome || outcome.kind === 'aborted')
|
|
353
|
+
return null;
|
|
354
|
+
if (outcome.kind === 'error')
|
|
355
|
+
throw new Error(`download failed: ${outcome.error}`);
|
|
356
|
+
const digests = await tarballDigests(partialPath);
|
|
357
|
+
if (digests.integrity !== expectedIntegrity || digests.sha256 !== expectedTarballSha) {
|
|
358
|
+
await rm(partialPath, { force: true });
|
|
359
|
+
throw new Error(`mxc-sdk ${MXC_VERSION} tarball failed integrity check: expected ${expectedIntegrity}, got ${digests.integrity}`);
|
|
360
|
+
}
|
|
361
|
+
const executorEntry = mxcTarballEntry(arch);
|
|
362
|
+
await mkdir(stagingDir, { recursive: true });
|
|
363
|
+
try {
|
|
364
|
+
await tar.extract({ file: partialPath, cwd: stagingDir, strict: true }, [
|
|
365
|
+
executorEntry,
|
|
366
|
+
MXC_TARBALL_LICENSE_ENTRY,
|
|
367
|
+
]);
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
await rm(partialPath, { force: true });
|
|
371
|
+
}
|
|
372
|
+
const stagedExecutor = join(stagingDir, MXC_EXECUTOR_NAME);
|
|
373
|
+
const stagedLicense = join(stagingDir, 'LICENSE.txt');
|
|
374
|
+
const extractedExecutor = join(stagingDir, ...executorEntry.split('/'));
|
|
375
|
+
const extractedLicense = join(stagingDir, ...MXC_TARBALL_LICENSE_ENTRY.split('/'));
|
|
376
|
+
if (!existsSync(extractedExecutor) || !existsSync(extractedLicense)) {
|
|
377
|
+
throw new Error(`mxc-sdk ${MXC_VERSION} tarball lacks ${executorEntry} or its license`);
|
|
378
|
+
}
|
|
379
|
+
await rename(extractedExecutor, stagedExecutor);
|
|
380
|
+
await rename(extractedLicense, stagedLicense);
|
|
381
|
+
await rm(join(stagingDir, 'package'), { recursive: true, force: true });
|
|
382
|
+
const executorSha = await sha256File(stagedExecutor);
|
|
383
|
+
if (executorSha !== expectedExecutorSha) {
|
|
384
|
+
throw new Error(`${executorEntry} failed integrity check: expected ${expectedExecutorSha.slice(0, 16)}…, got ${executorSha.slice(0, 16)}…`);
|
|
385
|
+
}
|
|
386
|
+
const licenseSha = await sha256File(stagedLicense);
|
|
387
|
+
if (licenseSha !== expectedLicenseSha) {
|
|
388
|
+
throw new Error(`mxc-sdk ${MXC_VERSION} license differs from the pinned text`);
|
|
389
|
+
}
|
|
390
|
+
await stripQuarantine(stagedExecutor);
|
|
391
|
+
const { result: signature, accepted } = await verifyAuthenticity(stagedExecutor, verifyOptions);
|
|
392
|
+
if (!accepted) {
|
|
393
|
+
throw new Error(`mxc launcher failed signature policy 'require': ${signature.status}${signature.detail ? ` (${signature.detail})` : ''}`);
|
|
394
|
+
}
|
|
395
|
+
const sentinel = {
|
|
396
|
+
engine: 'mxc',
|
|
397
|
+
version: MXC_VERSION,
|
|
398
|
+
arch,
|
|
399
|
+
sha256: executorSha,
|
|
400
|
+
source: 'npm-download',
|
|
401
|
+
verifiedAt: nowIso(),
|
|
402
|
+
};
|
|
403
|
+
await writeFile(join(stagingDir, MXC_VERIFIED_SENTINEL), `${JSON.stringify({ ...sentinel, integrity: digests.integrity, signature }, null, 2)}\n`, 'utf8');
|
|
404
|
+
// The staged directory already holds the launcher, its license and its
|
|
405
|
+
// sentinel, so one rename publishes all three together.
|
|
406
|
+
await rm(installDir, { recursive: true, force: true });
|
|
407
|
+
await rename(stagingDir, installDir);
|
|
408
|
+
log.info(`[engine-resolver] resolved mxc launcher ${MXC_VERSION} (${arch}) → ${executor} [sig=${signature.status}]`);
|
|
409
|
+
return executor;
|
|
410
|
+
}
|
|
411
|
+
finally {
|
|
412
|
+
await rm(stagingDir, { recursive: true, force: true });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
async function readMxcSentinel(path) {
|
|
416
|
+
try {
|
|
417
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/** npm's `sha512-<base64>` integrity and the hex sha256, in one read. */
|
|
424
|
+
async function tarballDigests(path) {
|
|
425
|
+
const sha512 = createHash('sha512');
|
|
426
|
+
const sha256 = createHash('sha256');
|
|
427
|
+
await new Promise((resolve, reject) => {
|
|
428
|
+
const stream = createReadStream(path, { highWaterMark: HASH_READ_BUFFER_BYTES });
|
|
429
|
+
stream.on('data', (chunk) => {
|
|
430
|
+
sha512.update(chunk);
|
|
431
|
+
sha256.update(chunk);
|
|
432
|
+
});
|
|
433
|
+
stream.on('end', () => resolve());
|
|
434
|
+
stream.on('error', reject);
|
|
435
|
+
});
|
|
436
|
+
return { integrity: `sha512-${sha512.digest('base64')}`, sha256: sha256.digest('hex') };
|
|
437
|
+
}
|
|
438
|
+
export async function* resolveEngine(opts) {
|
|
439
|
+
// DuckDB is vendored, not built — it has no artifact in our native release.
|
|
440
|
+
if (opts.engine === 'duckdb')
|
|
441
|
+
return yield* resolveVendoredDuckdb(opts);
|
|
442
|
+
const platformKey = resolvePlatformKey();
|
|
443
|
+
if (!platformKey) {
|
|
444
|
+
yield* fail(`unsupported platform ${process.platform}/${process.arch} — no native engine build exists`);
|
|
445
|
+
}
|
|
446
|
+
const engine = opts.engine;
|
|
447
|
+
const version = stripVer(opts.version ?? effectiveEngineRelease());
|
|
448
|
+
const variant = opts.variant ?? impliedEngineVariant(engine, process.platform);
|
|
449
|
+
const assetPlatformKey = variant ? `${platformKey}-${variant}` : platformKey;
|
|
450
|
+
const isWin = process.platform === 'win32';
|
|
451
|
+
const ext = isWin ? 'zip' : 'tar.gz';
|
|
452
|
+
const exeExt = isWin ? '.exe' : '';
|
|
453
|
+
// Build scripts emit the server under a `gezel-` prefix (so the running
|
|
454
|
+
// process reads as `gezel-llama-server` for attribution while keeping the
|
|
455
|
+
// upstream lineage in the suffix). Prefer that name, but fall back to the
|
|
456
|
+
// bare upstream name so releases cut BEFORE the rename still resolve.
|
|
457
|
+
// Vendored-unmodified engines are never prefixed. `engine` stays the
|
|
458
|
+
// logical id.
|
|
459
|
+
const vendored = isVendoredUnmodifiedEngine(engine);
|
|
460
|
+
const primaryBinaryFile = vendored ? `${engine}${exeExt}` : `gezel-${engine}${exeExt}`;
|
|
461
|
+
const binaryFileCandidates = vendored
|
|
462
|
+
? [primaryBinaryFile]
|
|
463
|
+
: [primaryBinaryFile, `${engine}${exeExt}`];
|
|
464
|
+
const requestedPolicy = opts.signaturePolicy ?? 'require';
|
|
465
|
+
// Astral ships uv.exe and the DuckDB Foundation ships duckdb.exe unsigned.
|
|
466
|
+
// A narrow, explicit exception: the source-bundled archive SHA plus the
|
|
467
|
+
// upstream bytes are authoritative, while an actually invalid Authenticode
|
|
468
|
+
// signature is still rejected by `prefer`. macOS is NOT exempt — the native
|
|
469
|
+
// build re-signs every Mach-O there because notarization demands it.
|
|
470
|
+
const policy = process.platform === 'win32' && vendored && requestedPolicy === 'require'
|
|
471
|
+
? 'prefer'
|
|
472
|
+
: requestedPolicy;
|
|
473
|
+
const archiveName = `gezel-native-${version}-${assetPlatformKey}.${ext}`;
|
|
474
|
+
const usesSourcePin = opts.version === undefined &&
|
|
475
|
+
opts.expectedSha256sumsDigest === undefined &&
|
|
476
|
+
opts.expectedArchiveSha256 === undefined &&
|
|
477
|
+
!process.env.GEZEL_NATIVE_ENGINE_VERSION;
|
|
478
|
+
const archivePins = opts.expectedArchiveSha256 ?? (usesSourcePin ? NATIVE_ENGINE_ARCHIVE_SHA256 : undefined);
|
|
479
|
+
const bundledArchiveSha = archivePins?.[archiveName]?.toLowerCase();
|
|
480
|
+
if (archivePins && !bundledArchiveSha) {
|
|
481
|
+
yield* fail(`'${archiveName}' is missing from this build's bundled native checksum map — refusing to install an unpinned archive`);
|
|
482
|
+
}
|
|
483
|
+
const verifyAuthenticity = opts.verifyOverride ?? verifyCodeSignature;
|
|
484
|
+
const verifyOptions = {
|
|
485
|
+
policy,
|
|
486
|
+
...(vendored && process.platform === 'win32'
|
|
487
|
+
? {}
|
|
488
|
+
: { expectedPublisher: BENDYLINE_PUBLISHER, expectedAppleTeamId: BENDYLINE_APPLE_TEAM_ID }),
|
|
489
|
+
};
|
|
490
|
+
const versionDir = join(opts.home, 'engines', 'native-bin', version);
|
|
491
|
+
const cacheDir = join(versionDir, assetPlatformKey);
|
|
492
|
+
const sentinelPath = join(cacheDir, '.verified.json');
|
|
493
|
+
// Pick whichever candidate is actually on disk (gezel- preferred). binPath is
|
|
494
|
+
// reassigned after extraction once we see what the downloaded archive holds.
|
|
495
|
+
let binPath = join(cacheDir, primaryBinaryFile);
|
|
496
|
+
for (const cand of binaryFileCandidates) {
|
|
497
|
+
if (existsSync(join(cacheDir, cand))) {
|
|
498
|
+
binPath = join(cacheDir, cand);
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// ── Fast path: already resolved + verified ──
|
|
503
|
+
if (existsSync(binPath) && existsSync(sentinelPath)) {
|
|
504
|
+
const sentinel = await readSentinel(sentinelPath);
|
|
505
|
+
if (!bundledArchiveSha || sentinel.archiveSha?.toLowerCase() === bundledArchiveSha) {
|
|
506
|
+
const { result: signature, accepted } = await verifyAuthenticity(binPath, verifyOptions);
|
|
507
|
+
if (!accepted) {
|
|
508
|
+
yield* fail(`cached engine binary failed signature policy '${policy}': ${signature.status}${signature.detail ? ` (${signature.detail})` : ''}`);
|
|
509
|
+
}
|
|
510
|
+
stampEnv(engine, binPath, variant, versionDir);
|
|
511
|
+
yield { type: 'done', binPath, cached: true };
|
|
512
|
+
return {
|
|
513
|
+
binPath,
|
|
514
|
+
cached: true,
|
|
515
|
+
signature,
|
|
516
|
+
version,
|
|
517
|
+
assetPlatformKey,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
log.warn(`[engine-resolver] cached ${archiveName} was verified against ${sentinel.archiveSha ?? 'no archive hash'}, but this build pins ${bundledArchiveSha}; replacing it`);
|
|
521
|
+
}
|
|
522
|
+
// ── Availability gates ──
|
|
523
|
+
// Placed after the warm-cache path above on purpose: a store build resolves
|
|
524
|
+
// an engine it already has exactly like any other build, and refuses only
|
|
525
|
+
// the download. Refusing in `ensure` instead would have broken resolution
|
|
526
|
+
// of the binaries such a build ships with.
|
|
527
|
+
const distribution = resolveDistributionProfile();
|
|
528
|
+
if (!distribution.allowEngineBinaryDownloads) {
|
|
529
|
+
yield* fail(distribution.refusalReason('engine-download'));
|
|
530
|
+
}
|
|
531
|
+
const expectedDigest = (opts.expectedSha256sumsDigest ?? (usesSourcePin ? SHA256SUMS_DIGEST : '0'.repeat(64))).toLowerCase();
|
|
532
|
+
const unpinned = isPlaceholderDigest(expectedDigest);
|
|
533
|
+
const hasOverride = opts.version !== undefined ||
|
|
534
|
+
opts.expectedSha256sumsDigest !== undefined ||
|
|
535
|
+
opts.expectedArchiveSha256 !== undefined ||
|
|
536
|
+
!!process.env.GEZEL_NATIVE_ENGINE_VERSION;
|
|
537
|
+
if (unpinned && !hasOverride) {
|
|
538
|
+
yield* fail('on-device engine auto-download is not available in this build yet (no native release pinned). Point GEZEL_LLAMA_SERVER_BIN / the External engine URL at a llama-server, or use a build that bundles the engine.');
|
|
539
|
+
}
|
|
540
|
+
const apiBase = opts.githubApiBase ?? GITHUB_API;
|
|
541
|
+
// `bendyline/gezel` is public, so release metadata and assets are readable
|
|
542
|
+
// anonymously. A token stays OPTIONAL and is used when present purely to
|
|
543
|
+
// lift GitHub's 60-request/hour unauthenticated API rate limit. Do not
|
|
544
|
+
// reinstate a hard gate here: users who install from npm have no `gh`
|
|
545
|
+
// login, and requiring one would make on-device engines unreachable for
|
|
546
|
+
// every consumer outside this repo.
|
|
547
|
+
const token = opts.token !== undefined ? opts.token : await resolveGitHubToken();
|
|
548
|
+
const baseFetch = opts.fetchImpl ?? globalThis.fetch;
|
|
549
|
+
const tag = `native-v${version}`;
|
|
550
|
+
// ── 1. Resolve release + assets ──
|
|
551
|
+
const release = await ghJson(`${apiBase}/repos/${REPO}/releases/tags/${tag}`, baseFetch, token);
|
|
552
|
+
const archiveAsset = release.assets?.find((a) => a.name === archiveName);
|
|
553
|
+
const sumsAsset = release.assets?.find((a) => a.name === 'SHA256SUMS');
|
|
554
|
+
if (!archiveAsset) {
|
|
555
|
+
yield* fail(`release ${tag} has no asset '${archiveName}' (this platform/variant isn't built for that release)`);
|
|
556
|
+
}
|
|
557
|
+
if (!sumsAsset) {
|
|
558
|
+
yield* fail(`release ${tag} is missing its SHA256SUMS manifest — refusing to install unverified`);
|
|
559
|
+
}
|
|
560
|
+
// ── 2. SHA256SUMS: verify own digest against the source pin, then parse ──
|
|
561
|
+
const sumsBytes = await ghBytes(sumsAsset.url, baseFetch, token);
|
|
562
|
+
const sumsDigest = createHash('sha256').update(sumsBytes).digest('hex');
|
|
563
|
+
if (!unpinned && sumsDigest !== expectedDigest) {
|
|
564
|
+
yield* fail(`SHA256SUMS digest mismatch for ${tag}: this build pins ${expectedDigest.slice(0, 16)}… but the release served ${sumsDigest.slice(0, 16)}…. Refusing — the release may have been tampered with or re-cut.`);
|
|
565
|
+
}
|
|
566
|
+
if (unpinned) {
|
|
567
|
+
log.warn(`[engine-resolver] ${tag} resolved UNPINNED (no baked digest) — verifying the archive against the release's own SHA256SUMS only`);
|
|
568
|
+
}
|
|
569
|
+
const sums = parseSums(sumsBytes.toString('utf8'));
|
|
570
|
+
const manifestArchiveSha = sums.get(archiveName) ?? '';
|
|
571
|
+
if (!manifestArchiveSha) {
|
|
572
|
+
yield* fail(`'${archiveName}' is not listed in ${tag}'s SHA256SUMS — refusing to install unverified`);
|
|
573
|
+
}
|
|
574
|
+
if (bundledArchiveSha && manifestArchiveSha !== bundledArchiveSha) {
|
|
575
|
+
yield* fail(`archive checksum mismatch for '${archiveName}': this build pins ${bundledArchiveSha.slice(0, 16)}… but ${tag}'s SHA256SUMS lists ${manifestArchiveSha.slice(0, 16)}…. Refusing — the release may have been tampered with or re-cut.`);
|
|
576
|
+
}
|
|
577
|
+
const expectedArchiveSha = bundledArchiveSha ?? manifestArchiveSha;
|
|
578
|
+
// ── 3. Download the archive (auth headers injected into the fetch) ──
|
|
579
|
+
await mkdir(versionDir, { recursive: true });
|
|
580
|
+
const tmpExtractDir = `${cacheDir}.tmp`;
|
|
581
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
582
|
+
const archivePath = join(versionDir, `${archiveName}.download`);
|
|
583
|
+
const dl = downloadWithRetry({
|
|
584
|
+
url: archiveAsset.url,
|
|
585
|
+
destPath: archivePath,
|
|
586
|
+
approxSizeBytes: archiveAsset.size ?? 0,
|
|
587
|
+
fetchImpl: makeAuthedFetch(baseFetch, token),
|
|
588
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
589
|
+
});
|
|
590
|
+
let outcome;
|
|
591
|
+
while (true) {
|
|
592
|
+
const step = await dl.next();
|
|
593
|
+
if (step.done) {
|
|
594
|
+
outcome = step.value;
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
const ev = step.value;
|
|
598
|
+
if (ev.type === 'progress') {
|
|
599
|
+
yield { type: 'progress', bytesWritten: ev.bytesWritten, totalBytes: ev.totalBytes };
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
yield {
|
|
603
|
+
type: 'retrying',
|
|
604
|
+
attempt: ev.attempt,
|
|
605
|
+
maxAttempts: ev.maxAttempts,
|
|
606
|
+
delayMs: ev.delayMs,
|
|
607
|
+
reason: ev.reason,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
const partialPath = `${archivePath}.partial`;
|
|
612
|
+
if (!outcome || outcome.kind === 'aborted') {
|
|
613
|
+
yield* fail('engine download was cancelled');
|
|
614
|
+
}
|
|
615
|
+
if (outcome && outcome.kind === 'error') {
|
|
616
|
+
yield* fail(outcome.error);
|
|
617
|
+
}
|
|
618
|
+
// ── 4. Verify archive sha256 against SHA256SUMS ──
|
|
619
|
+
yield { type: 'verifying', what: 'sha256' };
|
|
620
|
+
const actualSha = (await sha256File(partialPath)).toLowerCase();
|
|
621
|
+
if (actualSha !== expectedArchiveSha.toLowerCase()) {
|
|
622
|
+
await rm(partialPath, { force: true });
|
|
623
|
+
yield* fail(`${archiveName} failed integrity check: expected ${expectedArchiveSha.slice(0, 16)}…, got ${actualSha.slice(0, 16)}…`);
|
|
624
|
+
}
|
|
625
|
+
// ── 5. Extract into a temp dir ──
|
|
626
|
+
await mkdir(tmpExtractDir, { recursive: true });
|
|
627
|
+
try {
|
|
628
|
+
yield* extractWithProgress((onProgress) => ext === 'zip'
|
|
629
|
+
? extractZip(partialPath, tmpExtractDir, { ...signalOpt(opts.signal), onProgress })
|
|
630
|
+
: tar.extract({ file: partialPath, cwd: tmpExtractDir }));
|
|
631
|
+
}
|
|
632
|
+
finally {
|
|
633
|
+
await rm(partialPath, { force: true });
|
|
634
|
+
}
|
|
635
|
+
// Find the binary inside the extracted archive — gezel- prefixed name
|
|
636
|
+
// (current releases) preferred, bare upstream name for pre-rename releases.
|
|
637
|
+
// Reassign binPath so the publish + env stamp below use the real name.
|
|
638
|
+
let tmpBin = '';
|
|
639
|
+
for (const cand of binaryFileCandidates) {
|
|
640
|
+
const p = join(tmpExtractDir, cand);
|
|
641
|
+
if (existsSync(p)) {
|
|
642
|
+
tmpBin = p;
|
|
643
|
+
binPath = join(cacheDir, cand);
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (!tmpBin) {
|
|
648
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
649
|
+
yield* fail(`extracted ${archiveName} but none of [${binaryFileCandidates.join(', ')}] were inside it`);
|
|
650
|
+
}
|
|
651
|
+
if (!isWin)
|
|
652
|
+
await chmod(tmpBin, 0o755).catch(() => { });
|
|
653
|
+
// ── 6. Code-signature ──
|
|
654
|
+
yield { type: 'verifying', what: 'signature' };
|
|
655
|
+
await stripQuarantine(tmpBin);
|
|
656
|
+
const { result: signature, accepted } = await verifyAuthenticity(tmpBin, verifyOptions);
|
|
657
|
+
if (!accepted) {
|
|
658
|
+
await rm(tmpExtractDir, { recursive: true, force: true });
|
|
659
|
+
yield* fail(`engine binary failed signature policy '${policy}': ${signature.status}${signature.detail ? ` (${signature.detail})` : ''}`);
|
|
660
|
+
}
|
|
661
|
+
// ── 7. Atomic publish + sentinel ──
|
|
662
|
+
await rm(cacheDir, { recursive: true, force: true });
|
|
663
|
+
await rename(tmpExtractDir, cacheDir);
|
|
664
|
+
await writeFile(sentinelPath, `${JSON.stringify({
|
|
665
|
+
engine,
|
|
666
|
+
version,
|
|
667
|
+
assetPlatformKey,
|
|
668
|
+
archiveName,
|
|
669
|
+
archiveSha: actualSha,
|
|
670
|
+
signature,
|
|
671
|
+
verifiedAt: nowIso(),
|
|
672
|
+
}, null, 2)}\n`, 'utf8');
|
|
673
|
+
// ── 8. Stamp env so the providers (and discoverNativeBinaries) find it ──
|
|
674
|
+
stampEnv(engine, binPath, variant, versionDir);
|
|
675
|
+
log.info(`[engine-resolver] resolved ${engine} (${assetPlatformKey}) → ${binPath} [sig=${signature.status}]`);
|
|
676
|
+
yield { type: 'done', binPath, cached: false };
|
|
677
|
+
return { binPath, cached: false, signature, version, assetPlatformKey };
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Drain {@link resolveEngine} to its terminal result. Forwards each event
|
|
681
|
+
* to `onEvent`; throws {@link EngineUnavailableError} on a handled failure.
|
|
682
|
+
*/
|
|
683
|
+
export async function resolveEngineToCompletion(opts, onEvent) {
|
|
684
|
+
const gen = resolveEngine(opts);
|
|
685
|
+
while (true) {
|
|
686
|
+
const step = await gen.next();
|
|
687
|
+
if (step.done)
|
|
688
|
+
return step.value;
|
|
689
|
+
onEvent?.(step.value);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
// ── helpers ──
|
|
693
|
+
const EXTRACT_PROGRESS_INTERVAL_MS = 500;
|
|
694
|
+
/**
|
|
695
|
+
* Run an archive extraction, yielding `extracting` progress until it settles.
|
|
696
|
+
* A tar extraction reports no byte counts, so its events carry zeros and the
|
|
697
|
+
* person sees the phase without a percentage.
|
|
698
|
+
*/
|
|
699
|
+
async function* extractWithProgress(run) {
|
|
700
|
+
let progress = { bytesWritten: 0, totalBytes: 0 };
|
|
701
|
+
const work = run((bytesWritten, totalBytes) => {
|
|
702
|
+
progress = { bytesWritten, totalBytes };
|
|
703
|
+
});
|
|
704
|
+
const settled = work.then(() => true, () => true);
|
|
705
|
+
const tick = () => new Promise((resolve) => {
|
|
706
|
+
setTimeout(() => resolve(false), EXTRACT_PROGRESS_INTERVAL_MS).unref?.();
|
|
707
|
+
});
|
|
708
|
+
yield { type: 'extracting', ...progress };
|
|
709
|
+
while (!(await Promise.race([settled, tick()]))) {
|
|
710
|
+
yield { type: 'extracting', ...progress };
|
|
711
|
+
}
|
|
712
|
+
await work;
|
|
713
|
+
}
|
|
714
|
+
function signalOpt(signal) {
|
|
715
|
+
return signal ? { signal } : {};
|
|
716
|
+
}
|
|
717
|
+
/** Yield a terminal error event, then throw on the next pull. */
|
|
718
|
+
async function* fail(message) {
|
|
719
|
+
yield { type: 'error', error: message };
|
|
720
|
+
throw new EngineUnavailableError(message);
|
|
721
|
+
}
|
|
722
|
+
function stripVer(v) {
|
|
723
|
+
return v.replace(/^native-v/, '').replace(/^v/, '');
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* The archive variant an engine lives in when the caller names none.
|
|
727
|
+
*
|
|
728
|
+
* These are facts about *where the archive is*, not backend choices:
|
|
729
|
+
*
|
|
730
|
+
* - **ds4-server on Linux** ships only in the `-cuda` archive, sharing one
|
|
731
|
+
* copy of the NVIDIA redistributables with llama-server's CUDA build
|
|
732
|
+
* instead of shipping them twice (see scripts/native-payload.mjs).
|
|
733
|
+
* - **llama-server on macOS** ships only in the `-metal` archive; there is no
|
|
734
|
+
* `darwin-arm64-cpu` asset, and the bare `darwin-arm64` key holds
|
|
735
|
+
* ds4/sd/whisper/uv but no llama-server. Omitting the variant there fails
|
|
736
|
+
* the extract with "none of [gezel-llama-server, llama-server] were inside
|
|
737
|
+
* it" — a loud error, but an avoidable one.
|
|
738
|
+
*
|
|
739
|
+
* Deriving both here is the point: every call site would otherwise have to
|
|
740
|
+
* remember, and one eventually won't. Where the variant is a genuine choice
|
|
741
|
+
* (llama-server on Linux/Windows: cuda / vulkan / cpu) this returns undefined
|
|
742
|
+
* and the decision stays with the caller.
|
|
743
|
+
*/
|
|
744
|
+
export function impliedEngineVariant(engine, platform) {
|
|
745
|
+
if (engine === 'ds4-server' && platform === 'linux')
|
|
746
|
+
return 'cuda';
|
|
747
|
+
if (engine === 'llama-server' && platform === 'darwin')
|
|
748
|
+
return 'metal';
|
|
749
|
+
return undefined;
|
|
750
|
+
}
|
|
751
|
+
function stampEnv(engine, binPath, variant, versionDir) {
|
|
752
|
+
process.env[ENGINE_ENV_VAR[engine]] = binPath;
|
|
753
|
+
// Also point discoverNativeBinaries at the cache root so sibling engines
|
|
754
|
+
// resolve from the same place on a later boot.
|
|
755
|
+
process.env.GEZEL_NATIVE_BIN_DIR = versionDir;
|
|
756
|
+
if (engine === 'llama-server' && variant)
|
|
757
|
+
process.env.GEZEL_LLAMA_SERVER_BACKEND = variant;
|
|
758
|
+
}
|
|
759
|
+
async function resolveGitHubToken() {
|
|
760
|
+
if (process.env.GEZEL_GITHUB_TOKEN)
|
|
761
|
+
return process.env.GEZEL_GITHUB_TOKEN;
|
|
762
|
+
if (process.env.GITHUB_TOKEN)
|
|
763
|
+
return process.env.GITHUB_TOKEN;
|
|
764
|
+
try {
|
|
765
|
+
const { execFileSync } = await import('node:child_process');
|
|
766
|
+
const out = execFileSync('gh', ['auth', 'token'], {
|
|
767
|
+
encoding: 'utf8',
|
|
768
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
769
|
+
...windowsHeadlessSpawnOptions(),
|
|
770
|
+
});
|
|
771
|
+
return out.trim() || null;
|
|
772
|
+
}
|
|
773
|
+
catch {
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
function makeAuthedFetch(base, token) {
|
|
778
|
+
return ((input, init) => base(input, {
|
|
779
|
+
...init,
|
|
780
|
+
headers: {
|
|
781
|
+
...init?.headers,
|
|
782
|
+
Accept: 'application/octet-stream',
|
|
783
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
784
|
+
},
|
|
785
|
+
}));
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* The archive itself goes through `downloadWithRetry`, but the two small
|
|
789
|
+
* requests in front of it — the release metadata and the SHA256SUMS manifest —
|
|
790
|
+
* used to be single-shot. One dropped packet against api.github.com during
|
|
791
|
+
* first-run setup aborted the whole engine install, which is a miserable
|
|
792
|
+
* outcome for a request that would have succeeded a second later.
|
|
793
|
+
*/
|
|
794
|
+
const GH_METADATA_ATTEMPTS = 3;
|
|
795
|
+
function ghRetryLog(what) {
|
|
796
|
+
return (info) => {
|
|
797
|
+
log.warn(`[engine-resolver] ${what} failed (${info.reason}); retrying in ${info.delayMs}ms (attempt ${info.attempt}/${info.maxAttempts})`);
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
async function ghJson(url, fetchImpl, token) {
|
|
801
|
+
return retryTransient(async () => {
|
|
802
|
+
const res = await fetchImpl(url, {
|
|
803
|
+
headers: {
|
|
804
|
+
Accept: 'application/vnd.github+json',
|
|
805
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
806
|
+
},
|
|
807
|
+
});
|
|
808
|
+
if (!res.ok) {
|
|
809
|
+
await res.body?.cancel().catch(() => { });
|
|
810
|
+
// A transient status is thrown as HttpStatusError so retryTransient
|
|
811
|
+
// takes another pass; 4xx becomes the terminal EngineUnavailableError.
|
|
812
|
+
throw new HttpStatusError(res.status, `GitHub API returned ${res.status} for ${url}${res.status === 404 ? ' (release not found — or no access while private)' : ''}`);
|
|
813
|
+
}
|
|
814
|
+
return (await res.json());
|
|
815
|
+
}, { attempts: GH_METADATA_ATTEMPTS, onRetry: ghRetryLog('GitHub release lookup') }).catch(rethrowAsEngineUnavailable);
|
|
816
|
+
}
|
|
817
|
+
async function ghBytes(assetApiUrl, fetchImpl, token) {
|
|
818
|
+
return retryTransient(async () => {
|
|
819
|
+
const res = await fetchImpl(assetApiUrl, {
|
|
820
|
+
headers: {
|
|
821
|
+
Accept: 'application/octet-stream',
|
|
822
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
if (!res.ok) {
|
|
826
|
+
await res.body?.cancel().catch(() => { });
|
|
827
|
+
throw new HttpStatusError(res.status, `asset download returned ${res.status} for ${assetApiUrl}`);
|
|
828
|
+
}
|
|
829
|
+
return Buffer.from(await res.arrayBuffer());
|
|
830
|
+
}, { attempts: GH_METADATA_ATTEMPTS, onRetry: ghRetryLog('GitHub asset fetch') }).catch(rethrowAsEngineUnavailable);
|
|
831
|
+
}
|
|
832
|
+
function rethrowAsEngineUnavailable(err) {
|
|
833
|
+
if (err instanceof EngineUnavailableError)
|
|
834
|
+
throw err;
|
|
835
|
+
if (err instanceof HttpStatusError)
|
|
836
|
+
throw new EngineUnavailableError(err.message);
|
|
837
|
+
// Raw `TypeError: fetch failed` reads as a gezel bug rather than a bad link.
|
|
838
|
+
throw new EngineUnavailableError(`${friendlyErrors.fetch(err)} while contacting GitHub for the engine download (after ${GH_METADATA_ATTEMPTS} attempts)`);
|
|
839
|
+
}
|
|
840
|
+
/** Parse `sha256sum`-style lines: `<64-hex>␠␠[*]<filename>`. */
|
|
841
|
+
function parseSums(text) {
|
|
842
|
+
const map = new Map();
|
|
843
|
+
for (const line of text.split('\n')) {
|
|
844
|
+
const m = /^([0-9a-fA-F]{64})\s+\*?(.+)$/.exec(line.trim());
|
|
845
|
+
const sha = m?.[1];
|
|
846
|
+
const name = m?.[2];
|
|
847
|
+
if (sha && name)
|
|
848
|
+
map.set(name.trim(), sha.toLowerCase());
|
|
849
|
+
}
|
|
850
|
+
return map;
|
|
851
|
+
}
|
|
852
|
+
// Big read buffer so hashing a multi-hundred-MB engine archive doesn't starve
|
|
853
|
+
// inside the busy daemon event loop — a 64 KB stream yields to the loop ~100k
|
|
854
|
+
// times and the hash queues behind chat/scheduler/index work. Engines is a
|
|
855
|
+
// lower layer than models, so this mirrors models' MODEL_HASH_READ_BUFFER_BYTES
|
|
856
|
+
// rather than importing it.
|
|
857
|
+
const HASH_READ_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
858
|
+
async function sha256File(path) {
|
|
859
|
+
const hash = createHash('sha256');
|
|
860
|
+
await new Promise((resolve, reject) => {
|
|
861
|
+
const stream = createReadStream(path, { highWaterMark: HASH_READ_BUFFER_BYTES });
|
|
862
|
+
stream.on('data', (chunk) => hash.update(chunk));
|
|
863
|
+
stream.on('end', () => resolve());
|
|
864
|
+
stream.on('error', reject);
|
|
865
|
+
});
|
|
866
|
+
return hash.digest('hex');
|
|
867
|
+
}
|
|
868
|
+
async function readSentinel(path) {
|
|
869
|
+
try {
|
|
870
|
+
const j = JSON.parse(await readFile(path, 'utf8'));
|
|
871
|
+
return {
|
|
872
|
+
signature: j.signature ?? { status: 'unsupported' },
|
|
873
|
+
...(j.archiveSha ? { archiveSha: j.archiveSha } : {}),
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
catch {
|
|
877
|
+
return { signature: { status: 'unsupported' } };
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
/** First file named `name` anywhere under `root`, or null. */
|
|
881
|
+
function findNamedFile(root, name) {
|
|
882
|
+
const stack = [root];
|
|
883
|
+
while (stack.length > 0) {
|
|
884
|
+
const dir = stack.pop();
|
|
885
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
886
|
+
const full = join(dir, entry.name);
|
|
887
|
+
if (entry.isDirectory())
|
|
888
|
+
stack.push(full);
|
|
889
|
+
else if (entry.isFile() && entry.name === name)
|
|
890
|
+
return full;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
return null;
|
|
894
|
+
}
|