@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,1491 @@
|
|
|
1
|
+
import { availableParallelism } from 'node:os';
|
|
2
|
+
import { delimiter, dirname, join } from 'node:path';
|
|
3
|
+
import { DEFAULT_LOCAL_ENGINE_IDLE_TIMEOUT_MS, createLogger, estimateLlamaCppResidentBytes, } from '@bendyline/gezel';
|
|
4
|
+
import { recordLlamaQuarantine } from '@bendyline/gezel/native';
|
|
5
|
+
import { gezelPaths } from '@bendyline/gezel/paths';
|
|
6
|
+
import { mmprojBudgetBytes, nativeVisionEnabledFor } from '../../chat/vision-capability.js';
|
|
7
|
+
import { effectiveEngineRelease, isEnginePinned } from '../../engines/native-manifest.js';
|
|
8
|
+
import { engineInstallPhase } from '../../engines/registry.js';
|
|
9
|
+
import { localDeviceSettingsLabel, noModelYetMessage, notReadyError, } from '../active-install-message.js';
|
|
10
|
+
import { resolveCatalogLlamaCppEngineConfig, resolveCatalogReasoningBudget, } from '../catalog-model-config.js';
|
|
11
|
+
import { CapacityDeniedError, NOT_ENOUGH_MEMORY_MESSAGE, availableSystemRamBytes, formatContextCapacityDenial, minViableLocalContextTokens, planAdaptiveContextGrowth, pressureIdleGraceMs, resolveLlamaCppContextRequirement, } from '../native/capacity-broker.js';
|
|
12
|
+
import { measureAvailableGpuBytes } from '../native/device-capacity.js';
|
|
13
|
+
import { engineApiKey, withEngineApiKey } from '../native/engine-api-key.js';
|
|
14
|
+
import { makeEngineKey } from '../native/engine-key.js';
|
|
15
|
+
import { pickFreePort } from '../native/port.js';
|
|
16
|
+
import { NativeEngineSupervisor } from '../native/supervisor.js';
|
|
17
|
+
import { patientFetch } from '../patient-fetch.js';
|
|
18
|
+
import { lastArgValue, readLlamaCppBuildMetadata } from './build-metadata.js';
|
|
19
|
+
import { matchNvidiaRuntimeDevice, maxGpuVramBytes, pickBestGpuDevice, probeLlamaDevices, probeNvidiaRuntimeDevices, } from './devices.js';
|
|
20
|
+
import { buildLlamaCppEngineArgs } from './engine-flags.js';
|
|
21
|
+
import { readGgufSummaryAsync } from './gguf-metadata-async.js';
|
|
22
|
+
import { effectiveLazyTensorBytes } from './gguf-metadata.js';
|
|
23
|
+
import { isGemmaModel, planLlamaCppKv, resolveLlamaCppKvCacheType, } from './kv-cache-type.js';
|
|
24
|
+
import { degradeDenseFfnOffloadDecision, degradeMoeOffloadDecision, estimateExactPerSlotKvBytesF16, estimateKvReserveBytes, estimateWindowedKvLinearization, fitsSwaFullInFastMemory, planDenseFfnOffload, planMoeOffload, } from './offload-planner.js';
|
|
25
|
+
import { LlamaCppProvider } from './provider.js';
|
|
26
|
+
import { reasoningLaunchOverridesFromEnv } from './reasoning-launch.js';
|
|
27
|
+
import { resolveSpecDraft } from './spec-draft.js';
|
|
28
|
+
const log = createLogger('chat');
|
|
29
|
+
function activeLlamaInstall(models) {
|
|
30
|
+
return models?.getActiveInstalls().find((i) => i.phase !== undefined) ?? null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Lazy on-device engine-resolver hook for {@link buildLlamaCppProvider}.
|
|
34
|
+
* Kicks (or attaches to) a background download of llama-server for the
|
|
35
|
+
* detected/overridden GPU backend and returns an actionable status to
|
|
36
|
+
* surface this turn. Returns `undefined` when auto-download is disabled —
|
|
37
|
+
* the caller then falls through to the plain "install the engine" error.
|
|
38
|
+
*/
|
|
39
|
+
export function ensureLlamaEngineStatus(registry, config) {
|
|
40
|
+
if (config.autoDownloadEngines === false)
|
|
41
|
+
return undefined;
|
|
42
|
+
// No release pinned (and no dev override) → auto-download can't succeed;
|
|
43
|
+
// stay dormant so the caller shows the existing "install / external
|
|
44
|
+
// engine" guidance instead of a download that immediately fails.
|
|
45
|
+
if (!isEnginePinned())
|
|
46
|
+
return undefined;
|
|
47
|
+
const override = config.llamaCppBackendOverride;
|
|
48
|
+
const backend = override && override !== 'auto'
|
|
49
|
+
? override
|
|
50
|
+
: process.env.GEZEL_LLAMA_DETECTED_BACKEND || undefined;
|
|
51
|
+
const { snapshot } = registry.ensure('llama-server', backend);
|
|
52
|
+
if (snapshot.error) {
|
|
53
|
+
return { detail: `On-device engine couldn't be downloaded: ${snapshot.error}`, failed: true };
|
|
54
|
+
}
|
|
55
|
+
const where = backend ? `, ${backend}` : '';
|
|
56
|
+
return {
|
|
57
|
+
detail: `On-device engine (llama-server${where}) ${engineInstallPhase(snapshot)}. It'll be ready shortly — try again in a moment.`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build the llama.cpp provider for either an externally managed server or a
|
|
62
|
+
* supervised local engine. The supervised path resolves the installed model,
|
|
63
|
+
* plans context/KV/offload against available capacity, and owns the engine's
|
|
64
|
+
* lifecycle through {@link NativeEngineSupervisor}.
|
|
65
|
+
*/
|
|
66
|
+
export async function buildLlamaCppProvider(opts) {
|
|
67
|
+
const { config, affinity, home } = opts;
|
|
68
|
+
const externalBaseUrl = opts.modelOverride
|
|
69
|
+
? undefined
|
|
70
|
+
: (process.env.GEZEL_LLAMA_SERVER_URL ?? config.llamaCppBaseUrl);
|
|
71
|
+
const binary = process.env.GEZEL_LLAMA_SERVER_BIN;
|
|
72
|
+
// Preservation is a two-sided contract: launch llama-server with the
|
|
73
|
+
// explicit preserve/no-preserve flag AND replay captured
|
|
74
|
+
// `reasoning_content` only in the preserve case. v0.4.0 changed the server
|
|
75
|
+
// default to enabled, so omission would leave Gezel and the template on
|
|
76
|
+
// opposite policies. The env lever remains highest-precedence for evals.
|
|
77
|
+
const reasoningLaunchOverrides = reasoningLaunchOverridesFromEnv();
|
|
78
|
+
const reasoningPreserve = process.env.GEZEL_LLAMA_REASONING_PRESERVE !== undefined
|
|
79
|
+
? reasoningLaunchOverrides.preserve
|
|
80
|
+
: (config.llamaCppReasoningPreserve ?? false);
|
|
81
|
+
const defaultModelId = opts.modelOverride?.modelId ?? config.defaultModel?.['llama-cpp'];
|
|
82
|
+
// Slot count (`--parallel N`) is the single source of truth — drives the
|
|
83
|
+
// queue `concurrency`, `--ctx-size × slots`, and the cache adapter's
|
|
84
|
+
// `slotCount` (read back from `provider.queue.concurrency`). For a
|
|
85
|
+
// SUPERVISED engine the final `slots` is auto-sized below — fast-memory
|
|
86
|
+
// demand default, clamped by a per-model KV memory ceiling — once the
|
|
87
|
+
// model + context window are known; an explicit
|
|
88
|
+
// `providerConcurrency['llama-cpp']` overrides verbatim. The EXTERNAL-
|
|
89
|
+
// baseUrl path keeps the conservative default 2 (we don't control that
|
|
90
|
+
// server's `--parallel`).
|
|
91
|
+
const configuredSlots = config.providerConcurrency?.['llama-cpp'];
|
|
92
|
+
// `config.llamaCppNumCtx` is the user-facing setting; `GEZEL_LLAMA_NUM_CTX`
|
|
93
|
+
// is the env override (eval runs, headless scripted experiments). Env
|
|
94
|
+
// wins when set so an experiment can lift the cap without touching
|
|
95
|
+
// config on disk. KV cache memory grows ~linearly with this — bumping
|
|
96
|
+
// a 120B MoE from 64K → 128K adds ~5-10 GB resident, so the override
|
|
97
|
+
// is most useful on the unified-memory boxes that also lift the
|
|
98
|
+
// capacity broker.
|
|
99
|
+
const envNumCtx = (() => {
|
|
100
|
+
const env = process.env.GEZEL_LLAMA_NUM_CTX;
|
|
101
|
+
if (env) {
|
|
102
|
+
const n = Number.parseInt(env, 10);
|
|
103
|
+
if (Number.isFinite(n) && n > 0)
|
|
104
|
+
return n;
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
})();
|
|
108
|
+
const numCtx = envNumCtx ?? config.llamaCppNumCtx;
|
|
109
|
+
// Per-model context override (Settings → Local models → Context size…).
|
|
110
|
+
// More specific than the machine-wide llamaCppNumCtx, still below the env
|
|
111
|
+
// escape hatch. Consumed by the supervised context resolution below — an
|
|
112
|
+
// external llama-server owns its own --ctx-size, so the external path
|
|
113
|
+
// keeps reading `numCtx`.
|
|
114
|
+
const perModelCtxOverride = defaultModelId
|
|
115
|
+
? config.modelContextOverrides?.[`llama-cpp:${defaultModelId}`]
|
|
116
|
+
: undefined;
|
|
117
|
+
const baseProviderOpts = {
|
|
118
|
+
fetchImpl: patientFetch(),
|
|
119
|
+
...(defaultModelId ? { defaultModel: defaultModelId } : {}),
|
|
120
|
+
// llama-server only sends its final `usage` chunk (and the `timings`
|
|
121
|
+
// block that rides with it, carrying decode/prefill rate + cache_n) when
|
|
122
|
+
// the request opts in. Without this the usage tracker stayed empty for
|
|
123
|
+
// every llama-cpp turn, so the product could not show tokens or a decode
|
|
124
|
+
// rate for its own default engine — throughput was reachable only by
|
|
125
|
+
// scraping stdout from the eval harness.
|
|
126
|
+
includeUsageInStream: true,
|
|
127
|
+
replayReasoningContent: reasoningPreserve,
|
|
128
|
+
// External-baseUrl default; the supervised path overrides this with the
|
|
129
|
+
// auto-sized `slots` computed below (after the model resolves).
|
|
130
|
+
concurrency: configuredSlots ?? 2,
|
|
131
|
+
...(affinity !== undefined ? { affinity } : {}),
|
|
132
|
+
...(numCtx ? { numCtx } : {}),
|
|
133
|
+
// User-overridable idle-stream watchdogs. Default 5 min on each is
|
|
134
|
+
// set inside the provider; we forward only when the config carries
|
|
135
|
+
// an explicit override so the provider's defaults stay the source
|
|
136
|
+
// of truth. Mirrors the same pattern Ollama uses.
|
|
137
|
+
...(config.llamaCppStreamingIdleSec
|
|
138
|
+
? { streamingIdleMs: config.llamaCppStreamingIdleSec * 1000 }
|
|
139
|
+
: {}),
|
|
140
|
+
// Pre-first-byte cap: `config.llamaCppPreFirstByteIdleSec` is the
|
|
141
|
+
// user-facing knob; `GEZEL_LLAMA_PRE_FIRST_BYTE_TIMEOUT_MS` is the
|
|
142
|
+
// env override (headless eval runs). Wild-caught (
|
|
143
|
+
// nemotron-super-120b chat-stalled trials): cold-loading the 86 GB
|
|
144
|
+
// GGUF + a 20K-token meester prompt prefill takes 6-10 minutes on
|
|
145
|
+
// unified-memory hardware; the provider's 300s default trips and
|
|
146
|
+
// aborts the meester's first turn before the model has emitted
|
|
147
|
+
// anything, leaving the trial wedged with no completed turn.
|
|
148
|
+
// Honor env first when set so eval runs can lift the ceiling
|
|
149
|
+
// without touching `~/.gezel/config.json`.
|
|
150
|
+
...(() => {
|
|
151
|
+
const envMs = process.env.GEZEL_LLAMA_PRE_FIRST_BYTE_TIMEOUT_MS;
|
|
152
|
+
if (envMs) {
|
|
153
|
+
const n = Number.parseInt(envMs, 10);
|
|
154
|
+
if (Number.isFinite(n) && n > 0) {
|
|
155
|
+
return { preFirstByteIdleMs: n };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return config.llamaCppPreFirstByteIdleSec
|
|
159
|
+
? { preFirstByteIdleMs: config.llamaCppPreFirstByteIdleSec * 1000 }
|
|
160
|
+
: {};
|
|
161
|
+
})(),
|
|
162
|
+
};
|
|
163
|
+
if (externalBaseUrl) {
|
|
164
|
+
// External engine — no supervised process, no stdout to capture.
|
|
165
|
+
// Log file + phase events apply only to the supervised path.
|
|
166
|
+
return new LlamaCppProvider({
|
|
167
|
+
baseUrl: externalBaseUrl,
|
|
168
|
+
...baseProviderOpts,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (!binary) {
|
|
172
|
+
// Lazy resolve: kick (or attach to) a background engine download and
|
|
173
|
+
// surface its progress as an actionable error this turn. A later turn
|
|
174
|
+
// — once the resolver stamps GEZEL_LLAMA_SERVER_BIN — skips this branch.
|
|
175
|
+
const ensured = opts.ensureEngine?.();
|
|
176
|
+
// With no model on disk the turn has nothing to answer with while the
|
|
177
|
+
// engine downloads. Saying "the engine will be ready shortly" sent a
|
|
178
|
+
// first-run person to retry into the same failure; the download above is
|
|
179
|
+
// under way, so the engine is in place by the time the model is. An engine
|
|
180
|
+
// that failed or cannot be fetched is the real problem: naming the model
|
|
181
|
+
// instead sent people to a multi-GB download that could never run.
|
|
182
|
+
const pinnedPath = process.env.GEZEL_LLAMA_CPP_MODEL ?? config.llamaCppModelPath;
|
|
183
|
+
const engineOnItsWay = ensured !== undefined && !ensured.failed;
|
|
184
|
+
if (engineOnItsWay && !opts.modelOverride && !pinnedPath && opts.llamaCppModels) {
|
|
185
|
+
const installed = await opts.llamaCppModels.listInstalled().catch(() => null);
|
|
186
|
+
if (installed?.length === 0) {
|
|
187
|
+
throw notReadyError(noModelYetMessage('Local model', activeLlamaInstall(opts.llamaCppModels)), 'model-not-ready');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (ensured) {
|
|
191
|
+
if (!ensured.failed)
|
|
192
|
+
throw notReadyError(ensured.detail, 'engine-not-ready');
|
|
193
|
+
const dErr = new Error(ensured.detail);
|
|
194
|
+
dErr.isActionable = true;
|
|
195
|
+
throw dErr;
|
|
196
|
+
}
|
|
197
|
+
const err = new Error('On-device provider: no local engine is available on this machine. Open Settings → On-device → Advanced and point the External engine URL at a running llama-server, or install a Gezel build that bundles the engine. (Developers: drop a llama-server binary into native/build/<platform>/ and restart the app.)');
|
|
198
|
+
err.isActionable = true;
|
|
199
|
+
throw err;
|
|
200
|
+
}
|
|
201
|
+
// Model path: explicit env / config wins; otherwise pick the
|
|
202
|
+
// first catalog-installed model. Whenever we resolve through the
|
|
203
|
+
// catalog, we also capture the full summary so we can read the
|
|
204
|
+
// advertised `contextWindow` below.
|
|
205
|
+
//
|
|
206
|
+
// Pool-driven path (`modelOverride` set): skip the env/config
|
|
207
|
+
// override entirely — the pool's caller already decided which
|
|
208
|
+
// modelId to load. Falls back to `resolveModel(modelId)`; on
|
|
209
|
+
// miss this throws so the broker sees a clean failure rather
|
|
210
|
+
// than silently loading some other model.
|
|
211
|
+
const explicitPath = opts.modelOverride
|
|
212
|
+
? undefined
|
|
213
|
+
: (process.env.GEZEL_LLAMA_CPP_MODEL ?? config.llamaCppModelPath);
|
|
214
|
+
let modelPath = explicitPath;
|
|
215
|
+
let modelCatalogInfo = null;
|
|
216
|
+
if (!modelPath && opts.llamaCppModels) {
|
|
217
|
+
if (defaultModelId) {
|
|
218
|
+
modelCatalogInfo = await opts.llamaCppModels.resolveModel(defaultModelId);
|
|
219
|
+
}
|
|
220
|
+
if (!modelCatalogInfo && !opts.modelOverride) {
|
|
221
|
+
modelCatalogInfo = await opts.llamaCppModels.resolveDefaultModel();
|
|
222
|
+
}
|
|
223
|
+
if (modelCatalogInfo)
|
|
224
|
+
modelPath = modelCatalogInfo.weightsPath;
|
|
225
|
+
}
|
|
226
|
+
// Resolved HERE, above the memory planning, because the two must agree: if
|
|
227
|
+
// the launch will pass `--mmproj` the projector is resident and has to be
|
|
228
|
+
// budgeted, and if it will not, budgeting for it silently shrinks the
|
|
229
|
+
// context window this model could otherwise have been granted. Turning
|
|
230
|
+
// vision off is a deliberate trade of modality for context — a night-shift
|
|
231
|
+
// model that will never see a screenshot should get the memory back.
|
|
232
|
+
const nativeVisionEnabled = !!modelCatalogInfo?.mmprojPath &&
|
|
233
|
+
nativeVisionEnabledFor(config.nativeVision, modelCatalogInfo.id);
|
|
234
|
+
const visionBudgetBytes = mmprojBudgetBytes(modelCatalogInfo?.mmprojSizeBytes, nativeVisionEnabled);
|
|
235
|
+
// KV-cache precision. Gemma 3/4 are unusually sensitive to a quantized
|
|
236
|
+
// KV cache: large attention head dims (key/value_length = 512), a final
|
|
237
|
+
// logit softcap, and sliding-window attention mean an 8-bit KV cache
|
|
238
|
+
// corrupts the *stored prompt tokens* — the model reasons fine but
|
|
239
|
+
// recalls cached source/text as garbled multilingual tokens. Wild-caught
|
|
240
|
+
// (gemma4-12b): quoted source lines came back as Korean
|
|
241
|
+
// glyphs + emoji with `K/V = q8_0`. Default the Gemma family to f16 KV;
|
|
242
|
+
// every other family keeps the q8_0 default. An explicit
|
|
243
|
+
// `config.llamaCppKvCacheType` always wins. f16 KV costs ~2x the cache
|
|
244
|
+
// memory on Gemma — the slot-ceiling math below reads THIS value so slot
|
|
245
|
+
// sizing stays consistent with what the engine actually allocates.
|
|
246
|
+
let kvCacheType = resolveLlamaCppKvCacheType({
|
|
247
|
+
architecture: modelCatalogInfo?.architecture,
|
|
248
|
+
modelId: defaultModelId ?? undefined,
|
|
249
|
+
override: config.llamaCppKvCacheType,
|
|
250
|
+
});
|
|
251
|
+
if (!modelPath) {
|
|
252
|
+
// See the MLX path for the rationale: a configured/pinned model ID that
|
|
253
|
+
// no longer resolves is a stale selection, not an empty install — name
|
|
254
|
+
// it so the user knows which saved selection to fix.
|
|
255
|
+
// A first run pins a model and downloads it; the user then tries to chat
|
|
256
|
+
// while they wait. Consult the live install so the failure can say what is
|
|
257
|
+
// actually happening instead of telling them to start the download that is
|
|
258
|
+
// already running.
|
|
259
|
+
if (defaultModelId && !modelCatalogInfo) {
|
|
260
|
+
const installed = opts.llamaCppModels ? await opts.llamaCppModels.listInstalled() : [];
|
|
261
|
+
if (installed.length > 0) {
|
|
262
|
+
const err = new Error(`Local model: the selected model "${defaultModelId}" is no longer available. ` +
|
|
263
|
+
`Pick a local model in Settings → ${localDeviceSettingsLabel()} (${installed
|
|
264
|
+
.map((m) => m.id)
|
|
265
|
+
.join(', ')}), or download "${defaultModelId}" again.`);
|
|
266
|
+
err.isActionable = true;
|
|
267
|
+
throw err;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
throw notReadyError(noModelYetMessage('Local model', activeLlamaInstall(opts.llamaCppModels)), 'model-not-ready');
|
|
271
|
+
}
|
|
272
|
+
// Per Phase 0 measurements on a cold Mac: Metal library compile is
|
|
273
|
+
// ~14s and model load adds model-size-dependent time. Default
|
|
274
|
+
// startupTimeoutMs is 60s which squeaks through for a 7B on a warm
|
|
275
|
+
// machine but fails the first-ever run. 180s gives headroom for
|
|
276
|
+
// the full first-launch cost.
|
|
277
|
+
// ── Effective context-size resolution ──
|
|
278
|
+
// We want a generous working window without allocating a full 128K
|
|
279
|
+
// slot on a 2B model where most of it would sit empty and eat VRAM.
|
|
280
|
+
//
|
|
281
|
+
// adaptive target — per-model manifest
|
|
282
|
+
// `tuning.engine.llamaCpp.contextSize`, else
|
|
283
|
+
// the 65K global default (see below).
|
|
284
|
+
// model maximum — advertised native context from the GGUF
|
|
285
|
+
// metadata captured on install.
|
|
286
|
+
// effectiveNumCtx — the selected policy's target, clamped to the
|
|
287
|
+
// native max and then admitted against memory.
|
|
288
|
+
// Semantics: PER SLOT (i.e. per concurrent turn),
|
|
289
|
+
// not the total KV cache.
|
|
290
|
+
//
|
|
291
|
+
// The launch passes `--ctx-size ${effectiveNumCtx * slots}` because
|
|
292
|
+
// llama-server divides total ctx evenly across `--parallel`, so the
|
|
293
|
+
// multiplication is what makes `effectiveNumCtx` actually land as
|
|
294
|
+
// the per-turn budget. The session reports `numCtx = effectiveNumCtx`
|
|
295
|
+
// (per-slot) so `ChatManager.checkContextPressure` and the MCP
|
|
296
|
+
// bridge's adaptive tool-output cap both work on a single turn's
|
|
297
|
+
// budget — see `capToolOutput` / Layer 2.
|
|
298
|
+
//
|
|
299
|
+
// Why 65K (after 32K and 49K): matrix #3 petshop
|
|
300
|
+
// OOM'd at `tokens=67924/49152` — 138% over the 49K ceiling. The
|
|
301
|
+
// Voorman + Designer + Image-gen team's iteration depth, combined
|
|
302
|
+
// with 4× read_artifact bringing full file contents back into
|
|
303
|
+
// context per call, produces a working set in the 60-70K range.
|
|
304
|
+
// 65K leaves a small safety margin below 70K; combined with the
|
|
305
|
+
// compaction threshold drop to 0.70, sessions should compact at
|
|
306
|
+
// ~45K and have headroom for 2-3 more tool round-trips. KV cache
|
|
307
|
+
// at 65K on a 26B Q4_K_M Gemma is ~2 GB resident — well under
|
|
308
|
+
// the 32+ GB hosts this size model already requires.
|
|
309
|
+
// Per-model engine-launch defaults from the catalog manifest
|
|
310
|
+
// (`tuning.engine.llamaCpp`). Resolved here (stable catalog data) so
|
|
311
|
+
// `contextSize` can feed the Adaptive target below; also consumed later by
|
|
312
|
+
// specDraft / MTP resolution and merged UNDER the user's global
|
|
313
|
+
// `config.llamaCpp*` overrides by `buildLlamaCppEngineArgs`.
|
|
314
|
+
const manifestEngineConfig = opts.catalog
|
|
315
|
+
? await resolveCatalogLlamaCppEngineConfig(opts.catalog, opts.modelOverride?.modelId ?? defaultModelId)
|
|
316
|
+
: undefined;
|
|
317
|
+
const PREFERRED_CTX_DEFAULT = 65_536;
|
|
318
|
+
// Explicit numeric values win: env, then the per-model override, then the
|
|
319
|
+
// machine-wide config. Otherwise Adaptive uses the per-model manifest
|
|
320
|
+
// recommendation (or the 64K practical default) and may GROW toward the
|
|
321
|
+
// native window after admission settles, while Model maximum requests the
|
|
322
|
+
// GGUF's native window and makes it the strict admission floor. Every
|
|
323
|
+
// path still clamps to the native train context.
|
|
324
|
+
const explicitCtx = envNumCtx ?? perModelCtxOverride ?? config.llamaCppNumCtx;
|
|
325
|
+
const hostFloorTokens = minViableLocalContextTokens();
|
|
326
|
+
// A per-model override below the host floor is deliberate user intent —
|
|
327
|
+
// lower the admission floor to the override instead of silently raising
|
|
328
|
+
// the request back to 64K. Env / machine-wide values keep their
|
|
329
|
+
// historical floor semantics.
|
|
330
|
+
const minViableTokens = perModelCtxOverride !== undefined && explicitCtx === perModelCtxOverride
|
|
331
|
+
? Math.min(hostFloorTokens, perModelCtxOverride)
|
|
332
|
+
: hostFloorTokens;
|
|
333
|
+
const contextRequirement = resolveLlamaCppContextRequirement({
|
|
334
|
+
modelContextWindow: modelCatalogInfo?.contextWindow,
|
|
335
|
+
...(explicitCtx !== undefined ? { explicitContextWindow: explicitCtx } : {}),
|
|
336
|
+
adaptiveContextWindow: manifestEngineConfig?.contextSize ?? PREFERRED_CTX_DEFAULT,
|
|
337
|
+
...(manifestEngineConfig?.contextSize !== undefined
|
|
338
|
+
? { manifestContextSize: manifestEngineConfig.contextSize }
|
|
339
|
+
: {}),
|
|
340
|
+
contextSizing: config.llamaCppContextSizing ?? 'adaptive',
|
|
341
|
+
minViableContextTokens: minViableTokens,
|
|
342
|
+
});
|
|
343
|
+
// `let`: RAM-aware admission below may lower this (but never below the
|
|
344
|
+
// model-aware minimum) before anything launch-visible consumes it.
|
|
345
|
+
let effectiveNumCtx = contextRequirement.requestedPerTurnCtxTokens;
|
|
346
|
+
// Auto-size supervised slots now that the model + context window are
|
|
347
|
+
// known: a fast-memory demand default, clamped by a per-model KV memory
|
|
348
|
+
// ceiling so a big model on a small machine can't OOM by over-slotting.
|
|
349
|
+
// Explicit `providerConcurrency['llama-cpp']` overrides verbatim.
|
|
350
|
+
// (Co-resident pool models aren't subtracted here — the broker still
|
|
351
|
+
// denies an over-commit at spawn; threading committed bytes is a TODO.)
|
|
352
|
+
const { defaultLocalEngineSlots, llamaCppSlotCeiling, computeCapacityBudget, estimatePerSlotKvBytes, planCtxTokensForMemory, plannedLocalEngineSlots, } = await import('../native/capacity-broker.js');
|
|
353
|
+
const { measuredCapacityBudget } = await import('../native/measured-budget.js');
|
|
354
|
+
// Measured, not the ambient probe: the singleton path has no broker to read
|
|
355
|
+
// pools from, and a launch that plans against a card this process has not
|
|
356
|
+
// measured yet sizes its slots and its KV rung off system RAM alone.
|
|
357
|
+
const hostCapacity = await measuredCapacityBudget();
|
|
358
|
+
// Subtract co-resident model reservations from the budget when the pool
|
|
359
|
+
// broker is wired (multi-model path), using its actual (possibly config-
|
|
360
|
+
// overridden) budget. Caveat: the broker tracks each model's resident
|
|
361
|
+
// WEIGHTS, not its slot KV, so co-resident KV isn't fully captured — a
|
|
362
|
+
// broader broker improvement. Singleton path has no broker → full budget.
|
|
363
|
+
//
|
|
364
|
+
// Slots are sized against FAST memory, not the admission budget. On a
|
|
365
|
+
// discrete card those differ: the budget also covers the system RAM an
|
|
366
|
+
// offloaded MoE streams experts from, and KV that follows that number
|
|
367
|
+
// instead of the card's own capacity is how a GPU runs out of memory.
|
|
368
|
+
// Unified and CPU-only hosts have one pool, so the two are the same there.
|
|
369
|
+
const brokerSnap = opts.broker?.committed();
|
|
370
|
+
const budgetBytes = brokerSnap?.enforced
|
|
371
|
+
? (opts.broker?.fastBudgetBytes() ?? brokerSnap.pools.fastBytes)
|
|
372
|
+
: hostCapacity.fastBytes;
|
|
373
|
+
const committedOtherBytes = brokerSnap?.enforced ? brokerSnap.committedBytes : 0;
|
|
374
|
+
// Gemma f16-KV vs a second slot: when memory alone forces single-slot,
|
|
375
|
+
// trade to q8_0 KV if that buys ≥2 slots — SWA models get no rescue
|
|
376
|
+
// from llama-server's prompt cache, so single-slot session alternation
|
|
377
|
+
// re-prefills the other session's whole context (~41K tok ≈ 79s,
|
|
378
|
+
// wild-caught). Policy + evidence in planLlamaCppKv; explicit
|
|
379
|
+
// kvCacheType or slot config disables the trade.
|
|
380
|
+
// Header-exact per-slot KV for the slot ceiling (M2); the weights
|
|
381
|
+
// heuristic only when no readable GGUF is at hand (external base URL,
|
|
382
|
+
// manual model path). The tensor-size walk is cached and reused by the
|
|
383
|
+
// offload planner below; doing it here is what exposes lazy sibling shards
|
|
384
|
+
// soon enough for slot and KV admission.
|
|
385
|
+
let headerSummary = null;
|
|
386
|
+
if (modelPath) {
|
|
387
|
+
try {
|
|
388
|
+
// Include exact tensor sizes here as well as below. Split GGUFs can put
|
|
389
|
+
// Qwen's 51B-parameter per-layer embedding table in a dedicated sibling
|
|
390
|
+
// shard (~26.8 GiB in the IQ4 build); pricing only shard 1 (often
|
|
391
|
+
// metadata-only) makes a lazy-loadable model look far larger in RAM than
|
|
392
|
+
// the engine actually runs it.
|
|
393
|
+
headerSummary = await readGgufSummaryAsync(modelPath, { includeTensorSizes: true });
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
headerSummary = null;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const exactPerSlotKvF16 = headerSummary
|
|
400
|
+
? estimateExactPerSlotKvBytesF16({
|
|
401
|
+
blockCount: headerSummary.blockCount,
|
|
402
|
+
embeddingLength: headerSummary.embeddingLength,
|
|
403
|
+
headCount: headerSummary.headCount,
|
|
404
|
+
headCountKv: headerSummary.headCountKv,
|
|
405
|
+
headCountKvPerLayer: headerSummary.headCountKvPerLayer,
|
|
406
|
+
slidingWindow: headerSummary.slidingWindow,
|
|
407
|
+
slidingWindowPattern: headerSummary.slidingWindowPattern,
|
|
408
|
+
sharedKvLayers: headerSummary.sharedKvLayers,
|
|
409
|
+
loopCount: headerSummary.loopCount,
|
|
410
|
+
keyLength: headerSummary.keyLength,
|
|
411
|
+
valueLength: headerSummary.valueLength,
|
|
412
|
+
keyLengthSwa: headerSummary.keyLengthSwa,
|
|
413
|
+
valueLengthSwa: headerSummary.valueLengthSwa,
|
|
414
|
+
}, effectiveNumCtx)
|
|
415
|
+
: undefined;
|
|
416
|
+
// Context-aware so the KV plan can probe "does f16 fit at 64k" without
|
|
417
|
+
// committing the launch to it. The exact header-derived per-slot bytes
|
|
418
|
+
// were measured at the plan-time window; scale linearly for other
|
|
419
|
+
// windows — right for full-attention layers, conservative for the fixed
|
|
420
|
+
// SSM/SWA component (over-reserving is the safe direction, and Gemma
|
|
421
|
+
// never takes the cap ladder anyway).
|
|
422
|
+
const planTimeCtx = effectiveNumCtx;
|
|
423
|
+
const effectiveLazyMode = config.llamaCppLazyMode ?? manifestEngineConfig?.lazyMode ?? 'auto';
|
|
424
|
+
const planApproxWeightsBytes = modelCatalogInfo?.approxSizeBytes ?? headerSummary?.fileSizeBytes ?? 8 * 1024 ** 3;
|
|
425
|
+
const planLazyBytes = headerSummary
|
|
426
|
+
? effectiveLazyTensorBytes(headerSummary, effectiveLazyMode)
|
|
427
|
+
: 0;
|
|
428
|
+
const planWeightsBytes = Math.max(0, planApproxWeightsBytes - planLazyBytes);
|
|
429
|
+
const ceilingFor = (kv, ctxTokens) => llamaCppSlotCeiling({
|
|
430
|
+
budgetBytes,
|
|
431
|
+
sizingBudgetBytes: brokerSnap?.enforced
|
|
432
|
+
? brokerSnap.pools.concurrencySizingBytes
|
|
433
|
+
: hostCapacity.concurrencySizingBytes,
|
|
434
|
+
weightsBytes: planWeightsBytes,
|
|
435
|
+
perTurnCtxTokens: ctxTokens,
|
|
436
|
+
kvCacheType: kv,
|
|
437
|
+
committedOtherBytes,
|
|
438
|
+
...(exactPerSlotKvF16 !== undefined
|
|
439
|
+
? { exactPerSlotKvBytesF16: (exactPerSlotKvF16 * ctxTokens) / planTimeCtx }
|
|
440
|
+
: {}),
|
|
441
|
+
});
|
|
442
|
+
// The admission this launch is held to further down, asked here at plan
|
|
443
|
+
// time so the ladder can tell "does not fit at all" from "fits in exactly
|
|
444
|
+
// one slot" — `ceilingFor` is floored at 1 and cannot. See the `fitsAt`
|
|
445
|
+
// contract in planLlamaCppKv. Priced from the cached exact GGUF walk above,
|
|
446
|
+
// including any v0.4 lazy-tensor deduction.
|
|
447
|
+
const PLAN_REFERENCE_CTX = 4096;
|
|
448
|
+
const planResidentBytes = estimateLlamaCppResidentBytes(planWeightsBytes, {
|
|
449
|
+
mmprojBytes: visionBudgetBytes,
|
|
450
|
+
});
|
|
451
|
+
const planCapacity = hostCapacity;
|
|
452
|
+
const planKvBytesPerToken = (kv) => {
|
|
453
|
+
const exact = headerSummary
|
|
454
|
+
? estimateKvReserveBytes({
|
|
455
|
+
blockCount: headerSummary.blockCount,
|
|
456
|
+
embeddingLength: headerSummary.embeddingLength,
|
|
457
|
+
headCount: headerSummary.headCount,
|
|
458
|
+
headCountKv: headerSummary.headCountKv,
|
|
459
|
+
headCountKvPerLayer: headerSummary.headCountKvPerLayer,
|
|
460
|
+
slidingWindowPattern: headerSummary.slidingWindowPattern,
|
|
461
|
+
sharedKvLayers: headerSummary.sharedKvLayers,
|
|
462
|
+
loopCount: headerSummary.loopCount,
|
|
463
|
+
keyLength: headerSummary.keyLength,
|
|
464
|
+
valueLength: headerSummary.valueLength,
|
|
465
|
+
keyLengthSwa: headerSummary.keyLengthSwa,
|
|
466
|
+
valueLengthSwa: headerSummary.valueLengthSwa,
|
|
467
|
+
fullAttentionInterval: headerSummary.fullAttentionInterval,
|
|
468
|
+
ssmInnerSize: headerSummary.ssmInnerSize,
|
|
469
|
+
ssmStateSize: headerSummary.ssmStateSize,
|
|
470
|
+
ssmConvKernel: headerSummary.ssmConvKernel,
|
|
471
|
+
ctxTokens: PLAN_REFERENCE_CTX,
|
|
472
|
+
kvCacheType: kv,
|
|
473
|
+
})
|
|
474
|
+
: undefined;
|
|
475
|
+
return exact !== undefined
|
|
476
|
+
? exact / PLAN_REFERENCE_CTX
|
|
477
|
+
: estimatePerSlotKvBytes({
|
|
478
|
+
perTurnCtxTokens: PLAN_REFERENCE_CTX,
|
|
479
|
+
weightsBytes: planWeightsBytes,
|
|
480
|
+
kvCacheType: kv,
|
|
481
|
+
}) / PLAN_REFERENCE_CTX;
|
|
482
|
+
};
|
|
483
|
+
const planFitsAt = (kv, ctxTokens, slotCount) => {
|
|
484
|
+
// Asking for the whole window as the minimum: a plan admission would
|
|
485
|
+
// only accept by clamping is not a fit, and clamping is precisely what
|
|
486
|
+
// the q8_0 rung exists to avoid.
|
|
487
|
+
const probe = planCtxTokensForMemory({
|
|
488
|
+
requestedPerTurnCtxTokens: ctxTokens,
|
|
489
|
+
slots: slotCount,
|
|
490
|
+
minimumPerTurnCtxTokens: ctxTokens,
|
|
491
|
+
kvBytesPerToken: planKvBytesPerToken(kv),
|
|
492
|
+
weightsResidentBytes: planResidentBytes,
|
|
493
|
+
budgetBytes: brokerSnap?.enforced ? brokerSnap.budgetBytes : planCapacity.budgetBytes,
|
|
494
|
+
committedOtherBytes,
|
|
495
|
+
freeSystemRamBytes: availableSystemRamBytes(),
|
|
496
|
+
vramBytes: brokerSnap?.enforced ? brokerSnap.pools.vramBytes : planCapacity.vramBytes,
|
|
497
|
+
});
|
|
498
|
+
return probe.minimumSatisfied && probe.slots >= slotCount;
|
|
499
|
+
};
|
|
500
|
+
const kvPlan = planLlamaCppKv({
|
|
501
|
+
architecture: modelCatalogInfo?.architecture,
|
|
502
|
+
modelId: defaultModelId ?? undefined,
|
|
503
|
+
override: config.llamaCppKvCacheType,
|
|
504
|
+
slotsConfigured: configuredSlots !== undefined,
|
|
505
|
+
...(configuredSlots !== undefined ? { configuredSlots } : {}),
|
|
506
|
+
requestedCtxTokens: effectiveNumCtx,
|
|
507
|
+
minimumCtxTokens: contextRequirement.minimumPerTurnCtxTokens,
|
|
508
|
+
ctxConfigured: explicitCtx !== undefined || (config.llamaCppContextSizing ?? 'adaptive') === 'model-max',
|
|
509
|
+
ceilingFor,
|
|
510
|
+
fitsAt: planFitsAt,
|
|
511
|
+
maxSlots: defaultLocalEngineSlots(budgetBytes),
|
|
512
|
+
});
|
|
513
|
+
kvCacheType = kvPlan.kvCacheType;
|
|
514
|
+
if (kvPlan.upgraded) {
|
|
515
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? defaultModelId ?? 'model'}: trading f16 KV for q8_0 to fit a second engine slot (single-slot SWA session alternation re-prefills wholesale; KV A/B 2026-08-03 showed no measurable q8_0 fidelity cost)`);
|
|
516
|
+
}
|
|
517
|
+
else if (kvPlan.ctxCapTokens !== undefined && kvPlan.ctxCapTokens < effectiveNumCtx) {
|
|
518
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? defaultModelId ?? 'model'}: keeping f16 KV by capping context ${effectiveNumCtx} -> ${kvPlan.ctxCapTokens} (f16 prefill is up to ~17% faster at long context than q8_0; reports/llama-kv-q8-longctx-20260828.md)`);
|
|
519
|
+
effectiveNumCtx = kvPlan.ctxCapTokens;
|
|
520
|
+
}
|
|
521
|
+
else if (kvCacheType === 'f16' || kvCacheType === 'q8_0') {
|
|
522
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? defaultModelId ?? 'model'}: kv=${kvCacheType} (${kvPlan.reason})`);
|
|
523
|
+
}
|
|
524
|
+
let slots = plannedLocalEngineSlots({
|
|
525
|
+
configuredSlots,
|
|
526
|
+
ceiling: ceilingFor(kvCacheType, effectiveNumCtx),
|
|
527
|
+
tierDefault: defaultLocalEngineSlots(budgetBytes),
|
|
528
|
+
});
|
|
529
|
+
// The bundled llama.cpp line had known multi-slot MTP allocation failures,
|
|
530
|
+
// so an explicitly selected MTP mode is clamped to one slot.
|
|
531
|
+
//
|
|
532
|
+
// Deliberately NOT extended to the default-on path (engine-flags.ts): this
|
|
533
|
+
// runs BEFORE the GGUF is read, so `ggufHasMtp` is not yet known here.
|
|
534
|
+
// Measured on build 10621, `--parallel 2 --spec-type draft-mtp` served two
|
|
535
|
+
// concurrent requests correctly with zero engine errors, so the failure this
|
|
536
|
+
// clamp guards against looks stale — but one probe is not grounds for
|
|
537
|
+
// deleting a safety measure, so it stays for anyone who opted in explicitly.
|
|
538
|
+
const selectedSpecType = config.llamaCppSpecType ?? manifestEngineConfig?.spec?.type;
|
|
539
|
+
if (selectedSpecType === 'draft-mtp' && slots > 1) {
|
|
540
|
+
log.info(`[llama-cpp] limiting ${modelCatalogInfo?.id ?? 'MTP model'} to one slot because draft-mtp is not reliable with --parallel > 1 in the bundled engine`);
|
|
541
|
+
slots = 1;
|
|
542
|
+
}
|
|
543
|
+
// `slots` is the only width. llama-server serves its `--parallel N` slots
|
|
544
|
+
// with continuous batching on by default, so a slot we reserved KV for is a
|
|
545
|
+
// slot that can generate — there is no second switch that makes some of them
|
|
546
|
+
// dispatch-only. `providerConcurrency['llama-cpp'] = 1` is how you ask for a
|
|
547
|
+
// serial engine, and it shrinks the reservation to match.
|
|
548
|
+
// Rolling log file at ~/.gezel/logs/llama-server-YYYY-MM-DD.log.
|
|
549
|
+
// Captures raw stdout/stderr so users (and bug reports) have a
|
|
550
|
+
// durable record of what the engine was doing. Tee with the
|
|
551
|
+
// default console.log path so dev iteration still sees output live.
|
|
552
|
+
const { LlamaCppLogFile, LlamaProgressLogThrottle } = await import('./log.js');
|
|
553
|
+
const logFile = new LlamaCppLogFile(gezelPaths(home).logs);
|
|
554
|
+
const progressLogThrottle = new LlamaProgressLogThrottle();
|
|
555
|
+
// ── Slot-cache persistence (Phase 1.2) ──
|
|
556
|
+
// Per-model directory passed to llama-server's --slot-save-path.
|
|
557
|
+
// The adapter writes `sess-<sessionId>.bin` and
|
|
558
|
+
// `prefix-<gezelHash>.bin` files we read back on session resume.
|
|
559
|
+
// Per-model fingerprint segmentation prevents wrong-shape cache
|
|
560
|
+
// loads if the user swaps models behind the same path.
|
|
561
|
+
const llamaCacheRoot = join(home, 'engines', 'llama-cpp', 'slots');
|
|
562
|
+
const { createHash: createLlamaHash } = await import('node:crypto');
|
|
563
|
+
const { mkdir: mkdirAsync } = await import('node:fs/promises');
|
|
564
|
+
const llamaFingerprint = createLlamaHash('sha256')
|
|
565
|
+
.update([
|
|
566
|
+
modelCatalogInfo?.id ?? defaultModelId ?? modelPath,
|
|
567
|
+
modelCatalogInfo?.installedAt ?? '',
|
|
568
|
+
modelPath,
|
|
569
|
+
].join('::'), 'utf8')
|
|
570
|
+
.digest('hex')
|
|
571
|
+
.slice(0, 24);
|
|
572
|
+
// Replica isolation: replica 0 keeps the canonical path so an
|
|
573
|
+
// upgrade from singleton to pool reuses the old slot files; 1+
|
|
574
|
+
// get a `replica-N` subdir so concurrent llama-server instances
|
|
575
|
+
// don't trample one another's slot writes.
|
|
576
|
+
const replicaSuffix = opts.modelOverride && opts.modelOverride.replicaIdx > 0
|
|
577
|
+
? `replica-${opts.modelOverride.replicaIdx}`
|
|
578
|
+
: '';
|
|
579
|
+
const slotSavePath = replicaSuffix
|
|
580
|
+
? join(llamaCacheRoot, llamaFingerprint, replicaSuffix)
|
|
581
|
+
: join(llamaCacheRoot, llamaFingerprint);
|
|
582
|
+
// Pre-create the directory so llama-server's save endpoint doesn't
|
|
583
|
+
// fail on first save (it doesn't recursively create paths).
|
|
584
|
+
await mkdirAsync(slotSavePath, { recursive: true }).catch(() => { });
|
|
585
|
+
// `--reasoning-budget N` from the catalog's `tuning.reasoning.thinkingBudget`.
|
|
586
|
+
// llama-server's default is -1 (unrestricted). For qwen3-family models
|
|
587
|
+
// that can think for ~15K tokens then emit nothing, capping the
|
|
588
|
+
// budget at the manifest's recommended value is the difference
|
|
589
|
+
// between "Builder produces code" and "Builder hangs the trial."
|
|
590
|
+
// See `resolveCatalogReasoningBudget` for the lookup rationale.
|
|
591
|
+
const catalogReasoningBudgetTokens = opts.catalog
|
|
592
|
+
? await resolveCatalogReasoningBudget(opts.catalog, opts.modelOverride?.modelId ?? defaultModelId)
|
|
593
|
+
: undefined;
|
|
594
|
+
const reasoningBudgetTokens = reasoningLaunchOverrides.budgetTokens ?? catalogReasoningBudgetTokens;
|
|
595
|
+
const reasoningBudgetSource = reasoningLaunchOverrides.budgetTokens !== undefined
|
|
596
|
+
? 'env'
|
|
597
|
+
: catalogReasoningBudgetTokens !== undefined
|
|
598
|
+
? 'catalog'
|
|
599
|
+
: 'unbounded';
|
|
600
|
+
// Speculative-decoding draft resolution — a manifest names its draft by
|
|
601
|
+
// catalog id; resolve it to the installed GGUF path (or disable) before the
|
|
602
|
+
// argv is built. See providers/llama-cpp/spec-draft.ts for the full rules.
|
|
603
|
+
const specDraft = await resolveSpecDraft({
|
|
604
|
+
perModel: manifestEngineConfig,
|
|
605
|
+
configSpecType: config.llamaCppSpecType,
|
|
606
|
+
configDraftModelPath: config.llamaCppDraftModelPath,
|
|
607
|
+
resolveDraftPath: (id) => opts.llamaCppModels ? opts.llamaCppModels.resolveModelPath(id) : Promise.resolve(null),
|
|
608
|
+
});
|
|
609
|
+
const resolvedManifestEngineConfig = specDraft.perModel;
|
|
610
|
+
if (specDraft.log)
|
|
611
|
+
log[specDraft.log.level](specDraft.log.message);
|
|
612
|
+
// Phase v4 — hardware-aware structured-weight offload. Probe device VRAM (cached to
|
|
613
|
+
// `engines/llama-cpp/devices.json` via `--list-devices`) and read the
|
|
614
|
+
// model's MoE metadata from its GGUF header; the planner decides
|
|
615
|
+
// whether to stream MoE experts (`--cpu-moe` / `--n-cpu-moe`) or a
|
|
616
|
+
// dense model's first N FFN blocks (`--n-cpu-ffn`) from system RAM on
|
|
617
|
+
// a constrained-VRAM GPU. This is the LOWEST-precedence input to
|
|
618
|
+
// `buildLlamaCppEngineArgs` (an explicit global config or manifest
|
|
619
|
+
// value still wins), and we log the rationale so the operator can see
|
|
620
|
+
// WHY a model was — or wasn't — split. Best-effort: any failure falls
|
|
621
|
+
// back to the engine's own `--fit` / `-ngl auto`.
|
|
622
|
+
let offloadDecision;
|
|
623
|
+
let offloadBlockCount;
|
|
624
|
+
// Whether weights + full-attention KV at the requested context fit the
|
|
625
|
+
// fast-memory pool — VRAM on a discrete GPU. Gates the Gemma
|
|
626
|
+
// `--swa-full` auto-default (see `EngineFlagInput.swaFullAutoFits`). Set
|
|
627
|
+
// false to keep the full context on the windowed cache when Full would
|
|
628
|
+
// spill or require a slot/context reduction; undefined means it fits or
|
|
629
|
+
// the exact decision could not be computed.
|
|
630
|
+
let swaFullAutoFits;
|
|
631
|
+
// Broker-ledger reservation for this launch: resident weights + the KV
|
|
632
|
+
// the engine will actually allocate at the granted window and cache
|
|
633
|
+
// mode. Undefined when the GGUF is unreadable — the pool builder then
|
|
634
|
+
// falls back to the legacy weights-multiplier reservation.
|
|
635
|
+
let plannedReservationBytes;
|
|
636
|
+
// Graphics memory the MoE offload plan puts on the card. Device admission
|
|
637
|
+
// charges this rather than the whole card; undefined keeps the old charge.
|
|
638
|
+
let plannedGpuBytes;
|
|
639
|
+
// Whether the model's GGUF ships MTP (`nextn`) layers — a safety
|
|
640
|
+
// cross-check for an explicit draft-mtp request.
|
|
641
|
+
let ggufHasMtp = false;
|
|
642
|
+
let mtpLayerCount = 0;
|
|
643
|
+
const llamaBuildMetadata = binary ? await readLlamaCppBuildMetadata(binary) : null;
|
|
644
|
+
let llamaGpuDevice = null;
|
|
645
|
+
let nvidiaRuntimeDevice;
|
|
646
|
+
let llamaDevices = [];
|
|
647
|
+
if (binary) {
|
|
648
|
+
const [probe, nvidiaDevices] = await Promise.all([
|
|
649
|
+
probeLlamaDevices({ binaryPath: binary, home }),
|
|
650
|
+
probeNvidiaRuntimeDevices(),
|
|
651
|
+
]);
|
|
652
|
+
llamaDevices = probe.devices;
|
|
653
|
+
llamaGpuDevice = pickBestGpuDevice(probe.devices);
|
|
654
|
+
nvidiaRuntimeDevice = matchNvidiaRuntimeDevice(llamaGpuDevice, nvidiaDevices);
|
|
655
|
+
}
|
|
656
|
+
if (binary && modelPath) {
|
|
657
|
+
try {
|
|
658
|
+
// `includeTensorSizes` walks the tensor table (~5 MB read on a 100 GB
|
|
659
|
+
// GGUF, <500 ms) so the planner can budget the exact expert/non-expert
|
|
660
|
+
// byte split instead of a flat resident estimate.
|
|
661
|
+
const summary = await readGgufSummaryAsync(modelPath, { includeTensorSizes: true });
|
|
662
|
+
const isMoE = (summary.expertCount ?? 0) > 1;
|
|
663
|
+
offloadBlockCount = summary.blockCount;
|
|
664
|
+
mtpLayerCount = summary.nextnPredictLayers ?? 0;
|
|
665
|
+
ggufHasMtp = mtpLayerCount > 0;
|
|
666
|
+
if (!ggufHasMtp && modelCatalogInfo?.draftModelPath) {
|
|
667
|
+
const draftSummary = await readGgufSummaryAsync(modelCatalogInfo.draftModelPath);
|
|
668
|
+
mtpLayerCount = draftSummary.nextnPredictLayers ?? 0;
|
|
669
|
+
ggufHasMtp = mtpLayerCount > 0;
|
|
670
|
+
}
|
|
671
|
+
const approxBytes = modelCatalogInfo?.approxSizeBytes ?? summary.fileSizeBytes;
|
|
672
|
+
const lazyTensorBytes = effectiveLazyTensorBytes(summary, effectiveLazyMode);
|
|
673
|
+
const residentWeightBytes = Math.max(0, approxBytes - lazyTensorBytes);
|
|
674
|
+
const residentBytes = estimateLlamaCppResidentBytes(residentWeightBytes, {
|
|
675
|
+
mmprojBytes: visionBudgetBytes,
|
|
676
|
+
});
|
|
677
|
+
if (lazyTensorBytes > 0) {
|
|
678
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? defaultModelId ?? 'model'}: lazy-reading ${(lazyTensorBytes / 1024 ** 3).toFixed(1)} GiB of row-addressable embeddings from the GGUF; budgeting ${(residentWeightBytes / 1024 ** 3).toFixed(1)} GiB as resident model weights`);
|
|
679
|
+
}
|
|
680
|
+
const vramBytes = maxGpuVramBytes(llamaDevices);
|
|
681
|
+
const split = summary.nonExpertBytes !== undefined &&
|
|
682
|
+
summary.expertBytesByLayer !== undefined &&
|
|
683
|
+
summary.expertBytesByLayer.length > 0
|
|
684
|
+
? {
|
|
685
|
+
nonExpertBytes: Math.max(0, summary.nonExpertBytes - lazyTensorBytes),
|
|
686
|
+
expertBytesByLayer: summary.expertBytesByLayer,
|
|
687
|
+
}
|
|
688
|
+
: undefined;
|
|
689
|
+
const denseFfnSplit = summary.nonDenseFfnBytes !== undefined &&
|
|
690
|
+
summary.denseFfnBytesByLayer !== undefined &&
|
|
691
|
+
summary.denseFfnBytesByLayer.length > 0
|
|
692
|
+
? {
|
|
693
|
+
nonFfnBytes: Math.max(0, summary.nonDenseFfnBytes - lazyTensorBytes),
|
|
694
|
+
ffnBytesByLayer: summary.denseFfnBytesByLayer,
|
|
695
|
+
}
|
|
696
|
+
: undefined;
|
|
697
|
+
// ── RAM-aware context admission ──
|
|
698
|
+
// The slot ceiling sizes the slot COUNT and the broker admits
|
|
699
|
+
// WEIGHTS; neither asks whether one slot at the requested context
|
|
700
|
+
// fits at all. On models with outsized attention geometry that gap
|
|
701
|
+
// is enormous — gemma4-12b at f16 KV is ~380 KB/token, so a 64K
|
|
702
|
+
// default projects ~25 GB of KV and turned a 6.7 GB model into a
|
|
703
|
+
// ~25 GB process that paged a 32 GB machine to a standstill
|
|
704
|
+
// (2026-08-03, two daemons × one model each). Clamp the per-turn
|
|
705
|
+
// context so weights + total KV + compute headroom fit both the
|
|
706
|
+
// capacity budget and live free memory. Exact per-token KV from the
|
|
707
|
+
// GGUF header; the weights-scaled heuristic only as fallback.
|
|
708
|
+
// The admission ladder (deny → reduce slots → clamp) is skipped
|
|
709
|
+
// under GEZEL_LLAMA_NUM_CTX — eval runs lift ceilings deliberately
|
|
710
|
+
// and accept the memory consequences.
|
|
711
|
+
//
|
|
712
|
+
// The fit verdict additionally gates the Gemma `--swa-full`
|
|
713
|
+
// auto-default, in BOTH branches: the full cache is a cache-operation
|
|
714
|
+
// performance trade, while the context window is capability. Auto
|
|
715
|
+
// therefore requires resident weights + exact full KV to fit the fast
|
|
716
|
+
// pool (VRAM on a discrete GPU); otherwise it keeps the full window on
|
|
717
|
+
// the windowed cache. Shared-KV layers and SWA-specific head dimensions
|
|
718
|
+
// are load-bearing here — E4B owns only 24 KV caches for 42 logical
|
|
719
|
+
// layers, and pricing all 42 at global dimensions overstated its two-slot
|
|
720
|
+
// 64K KV allocation as 21 GiB instead of llama.cpp's actual 7 GiB.
|
|
721
|
+
// When the windowed cache is what will run, the launch is NOT left
|
|
722
|
+
// ungated: admission re-plans with the windowed-KV linearization
|
|
723
|
+
// (SWA layers = fixed window-capped bytes, global layers = the only
|
|
724
|
+
// per-token cost), so a host too small even for the windowed cache
|
|
725
|
+
// still denies or clamps honestly instead of OOMing one machine
|
|
726
|
+
// class below the 2026-08-05 incident.
|
|
727
|
+
{
|
|
728
|
+
const REFERENCE_CTX = 4096;
|
|
729
|
+
const exactKvAtReference = estimateKvReserveBytes({
|
|
730
|
+
blockCount: summary.blockCount,
|
|
731
|
+
embeddingLength: summary.embeddingLength,
|
|
732
|
+
headCount: summary.headCount,
|
|
733
|
+
headCountKv: summary.headCountKv,
|
|
734
|
+
headCountKvPerLayer: summary.headCountKvPerLayer,
|
|
735
|
+
slidingWindowPattern: summary.slidingWindowPattern,
|
|
736
|
+
sharedKvLayers: summary.sharedKvLayers,
|
|
737
|
+
loopCount: summary.loopCount,
|
|
738
|
+
keyLength: summary.keyLength,
|
|
739
|
+
valueLength: summary.valueLength,
|
|
740
|
+
keyLengthSwa: summary.keyLengthSwa,
|
|
741
|
+
valueLengthSwa: summary.valueLengthSwa,
|
|
742
|
+
fullAttentionInterval: summary.fullAttentionInterval,
|
|
743
|
+
ssmInnerSize: summary.ssmInnerSize,
|
|
744
|
+
ssmStateSize: summary.ssmStateSize,
|
|
745
|
+
ssmConvKernel: summary.ssmConvKernel,
|
|
746
|
+
ctxTokens: REFERENCE_CTX,
|
|
747
|
+
kvCacheType,
|
|
748
|
+
});
|
|
749
|
+
const kvBytesPerToken = exactKvAtReference !== undefined
|
|
750
|
+
? exactKvAtReference / REFERENCE_CTX
|
|
751
|
+
: estimatePerSlotKvBytes({
|
|
752
|
+
perTurnCtxTokens: REFERENCE_CTX,
|
|
753
|
+
weightsBytes: approxBytes,
|
|
754
|
+
kvCacheType,
|
|
755
|
+
}) / REFERENCE_CTX;
|
|
756
|
+
const liveMemory = await (async () => {
|
|
757
|
+
try {
|
|
758
|
+
const { detectMemoryProfileCached } = await import('../../system/memory.js');
|
|
759
|
+
return await detectMemoryProfileCached();
|
|
760
|
+
}
|
|
761
|
+
catch {
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
})();
|
|
765
|
+
const liveBudget = computeCapacityBudget({
|
|
766
|
+
...(liveMemory ? { systemRamBytes: liveMemory.totalRamBytes } : {}),
|
|
767
|
+
gpuVramBytes: (liveMemory?.gpuVramBytes ?? vramBytes) || null,
|
|
768
|
+
...(liveMemory
|
|
769
|
+
? {
|
|
770
|
+
unifiedMemory: liveMemory.gpuMemoryKind === 'integrated' ||
|
|
771
|
+
liveMemory.gpuMemoryKind === 'unified',
|
|
772
|
+
}
|
|
773
|
+
: {}),
|
|
774
|
+
});
|
|
775
|
+
const fastBudgetBytes = brokerSnap?.enforced
|
|
776
|
+
? (opts.broker?.fastBudgetBytes() ?? liveBudget.fastBytes)
|
|
777
|
+
: liveBudget.fastBytes;
|
|
778
|
+
const fullKvBytesAtRequested = exactKvAtReference !== undefined
|
|
779
|
+
? (exactKvAtReference / REFERENCE_CTX) * effectiveNumCtx * slots
|
|
780
|
+
: undefined;
|
|
781
|
+
const fullCacheFitsFastMemory = fullKvBytesAtRequested !== undefined
|
|
782
|
+
? fitsSwaFullInFastMemory({
|
|
783
|
+
residentWeightsBytes: residentBytes,
|
|
784
|
+
fullKvBytes: fullKvBytesAtRequested,
|
|
785
|
+
fastBudgetBytes,
|
|
786
|
+
committedOtherBytes,
|
|
787
|
+
})
|
|
788
|
+
: undefined;
|
|
789
|
+
const admission = planCtxTokensForMemory({
|
|
790
|
+
requestedPerTurnCtxTokens: effectiveNumCtx,
|
|
791
|
+
slots,
|
|
792
|
+
minimumPerTurnCtxTokens: contextRequirement.minimumPerTurnCtxTokens,
|
|
793
|
+
kvBytesPerToken,
|
|
794
|
+
weightsResidentBytes: residentBytes,
|
|
795
|
+
budgetBytes: brokerSnap?.enforced ? brokerSnap.budgetBytes : liveBudget.budgetBytes,
|
|
796
|
+
committedOtherBytes,
|
|
797
|
+
freeSystemRamBytes: availableSystemRamBytes(),
|
|
798
|
+
vramBytes: liveBudget.vramBytes,
|
|
799
|
+
});
|
|
800
|
+
const explicitSwaFull = config.llamaCppSwaFull ?? manifestEngineConfig?.swaFull;
|
|
801
|
+
const swaFullAutoDefault = explicitSwaFull === undefined &&
|
|
802
|
+
isGemmaModel({
|
|
803
|
+
architecture: modelCatalogInfo?.architecture,
|
|
804
|
+
modelId: defaultModelId ?? undefined,
|
|
805
|
+
});
|
|
806
|
+
const fullKvOverBudget = fullCacheFitsFastMemory === false ||
|
|
807
|
+
!admission.minimumSatisfied ||
|
|
808
|
+
admission.slots < slots ||
|
|
809
|
+
admission.clamped;
|
|
810
|
+
// The plan whose ladder (deny → shed slots → clamp) is enforced
|
|
811
|
+
// below. Defaults to the full-attention plan; the windowed-cache
|
|
812
|
+
// branches replace it with windowed math or — only when the GGUF
|
|
813
|
+
// hides its SWA layout — null (no safe estimate; launch untouched,
|
|
814
|
+
// the pre-windowed-admission behavior).
|
|
815
|
+
let ladderPlan = admission;
|
|
816
|
+
// The per-slot KV linearization the accepted plan priced with, so
|
|
817
|
+
// the growth pass below cannot disagree with admission about the
|
|
818
|
+
// same launch. Windowed branch swaps in its slope + fixed block;
|
|
819
|
+
// the no-safe-estimate branch nulls it (no growth either).
|
|
820
|
+
let ladderKvLinearization = {
|
|
821
|
+
bytesPerToken: kvBytesPerToken,
|
|
822
|
+
fixedPerSlotBytes: 0,
|
|
823
|
+
};
|
|
824
|
+
// Strict model-max deliberately does NOT gate this: for SWA models
|
|
825
|
+
// the windowed cache is the only layout whose native-window KV can
|
|
826
|
+
// fit real machines (gemma4-12b at 256K: 4.8 GB windowed vs 164 GB
|
|
827
|
+
// full-attention), and the strict minimum rides inside
|
|
828
|
+
// `contextRequirement.minimumPerTurnCtxTokens`, so the windowed
|
|
829
|
+
// re-plan below sheds slots or denies but never shortens the window.
|
|
830
|
+
const windowedCacheWillRun = fullKvOverBudget && (swaFullAutoDefault || explicitSwaFull === false);
|
|
831
|
+
if (windowedCacheWillRun) {
|
|
832
|
+
// The denial, the slot reduction, and the clamp above are all
|
|
833
|
+
// driven by full-attention KV math, which overstates the windowed
|
|
834
|
+
// cache's real allocation (Gemma 4: global layers are both fewer
|
|
835
|
+
// AND cheaper per token than SWA layers — ~14× on 31b). Re-plan
|
|
836
|
+
// with the windowed linearization: SWA layers become a fixed,
|
|
837
|
+
// context-independent reservation; only global layers scale.
|
|
838
|
+
// Without it a 31b-class Gemma on a ~32 GB host would launch
|
|
839
|
+
// with NO context admission at all — the same lazy-Metal-wiring
|
|
840
|
+
// OOM this gate exists to prevent, one machine class down.
|
|
841
|
+
const windowed = estimateWindowedKvLinearization({
|
|
842
|
+
blockCount: summary.blockCount,
|
|
843
|
+
embeddingLength: summary.embeddingLength,
|
|
844
|
+
headCount: summary.headCount,
|
|
845
|
+
headCountKv: summary.headCountKv,
|
|
846
|
+
headCountKvPerLayer: summary.headCountKvPerLayer,
|
|
847
|
+
slidingWindow: summary.slidingWindow,
|
|
848
|
+
slidingWindowPattern: summary.slidingWindowPattern,
|
|
849
|
+
sharedKvLayers: summary.sharedKvLayers,
|
|
850
|
+
loopCount: summary.loopCount,
|
|
851
|
+
keyLength: summary.keyLength,
|
|
852
|
+
valueLength: summary.valueLength,
|
|
853
|
+
keyLengthSwa: summary.keyLengthSwa,
|
|
854
|
+
valueLengthSwa: summary.valueLengthSwa,
|
|
855
|
+
fullAttentionInterval: summary.fullAttentionInterval,
|
|
856
|
+
ssmInnerSize: summary.ssmInnerSize,
|
|
857
|
+
ssmStateSize: summary.ssmStateSize,
|
|
858
|
+
ssmConvKernel: summary.ssmConvKernel,
|
|
859
|
+
kvCacheType,
|
|
860
|
+
});
|
|
861
|
+
if (swaFullAutoDefault) {
|
|
862
|
+
// Declining `--swa-full` dominates every full-math remedy:
|
|
863
|
+
// the context window is capability, the full cache is a
|
|
864
|
+
// session-switch performance trade. Weights-level admission
|
|
865
|
+
// stays with the capacity broker.
|
|
866
|
+
swaFullAutoFits = false;
|
|
867
|
+
const fastFitDetail = fullCacheFitsFastMemory === false && fullKvBytesAtRequested !== undefined
|
|
868
|
+
? `projected weights + full KV ${((residentBytes + fullKvBytesAtRequested) / 1024 ** 3).toFixed(1)} GiB exceeds available fast memory ${(Math.max(0, fastBudgetBytes - committedOtherBytes) / 1024 ** 3).toFixed(1)} GiB`
|
|
869
|
+
: undefined;
|
|
870
|
+
log.warn([
|
|
871
|
+
`[llama-cpp] ${modelCatalogInfo?.id ?? 'model'}: the full SWA working set at the requested `,
|
|
872
|
+
`${effectiveNumCtx * slots}-token total context does not fit fast memory — keeping the full `,
|
|
873
|
+
'context and declining the --swa-full auto-default instead; the windowed KV cache ',
|
|
874
|
+
'is what actually fits (cross-request prefix reuse unavailable). ',
|
|
875
|
+
`Fit detail: ${fastFitDetail ?? admission.reason ?? 'over budget at the requested slot count'}`,
|
|
876
|
+
].join(''));
|
|
877
|
+
}
|
|
878
|
+
if (windowed) {
|
|
879
|
+
ladderPlan = planCtxTokensForMemory({
|
|
880
|
+
requestedPerTurnCtxTokens: effectiveNumCtx,
|
|
881
|
+
slots,
|
|
882
|
+
minimumPerTurnCtxTokens: contextRequirement.minimumPerTurnCtxTokens,
|
|
883
|
+
kvBytesPerToken: windowed.bytesPerToken,
|
|
884
|
+
weightsResidentBytes: residentBytes + windowed.fixedBytes * slots,
|
|
885
|
+
budgetBytes: brokerSnap?.enforced ? brokerSnap.budgetBytes : liveBudget.budgetBytes,
|
|
886
|
+
committedOtherBytes,
|
|
887
|
+
freeSystemRamBytes: availableSystemRamBytes(),
|
|
888
|
+
vramBytes: liveBudget.vramBytes,
|
|
889
|
+
});
|
|
890
|
+
ladderKvLinearization = {
|
|
891
|
+
bytesPerToken: windowed.bytesPerToken,
|
|
892
|
+
fixedPerSlotBytes: windowed.fixedBytes,
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
else if ((summary.slidingWindow ?? 0) > 0 || swaFullAutoDefault) {
|
|
896
|
+
// A sliding-window model whose GGUF hides the layer layout:
|
|
897
|
+
// full math over-states the real cache and there is no exact
|
|
898
|
+
// substitute — leave the launch alone rather than over-clamp.
|
|
899
|
+
ladderPlan = null;
|
|
900
|
+
ladderKvLinearization = null;
|
|
901
|
+
}
|
|
902
|
+
// else: `swaFull: false` pinned on a model with no SWA layers at
|
|
903
|
+
// all — the flag is a no-op there and the full-attention plan IS
|
|
904
|
+
// the real allocation; fall through with it intact.
|
|
905
|
+
}
|
|
906
|
+
if (ladderPlan !== null && envNumCtx === undefined) {
|
|
907
|
+
const windowedNote = ladderPlan === admission ? '' : ' (windowed KV admission)';
|
|
908
|
+
if (!ladderPlan.minimumSatisfied) {
|
|
909
|
+
log.warn(`[llama-cpp] ${formatContextCapacityDenial({
|
|
910
|
+
modelLabel: modelCatalogInfo?.name ?? defaultModelId ?? 'this local model',
|
|
911
|
+
plan: ladderPlan,
|
|
912
|
+
})}`);
|
|
913
|
+
throw new CapacityDeniedError(NOT_ENOUGH_MEMORY_MESSAGE);
|
|
914
|
+
}
|
|
915
|
+
if (ladderPlan.slots < slots) {
|
|
916
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? 'model'}${windowedNote}: reducing engine slots ${slots} -> ${ladderPlan.slots} to preserve at least ${contextRequirement.minimumPerTurnCtxTokens} context tokens per turn`);
|
|
917
|
+
slots = ladderPlan.slots;
|
|
918
|
+
}
|
|
919
|
+
if (ladderPlan.clamped) {
|
|
920
|
+
log.warn(`[llama-cpp] ${modelCatalogInfo?.id ?? 'model'}${windowedNote}: ${ladderPlan.reason}`);
|
|
921
|
+
effectiveNumCtx = ladderPlan.perTurnCtxTokens;
|
|
922
|
+
}
|
|
923
|
+
// ── Adaptive context growth ──
|
|
924
|
+
// Slots and the base grant are settled; spend whatever FAST
|
|
925
|
+
// memory is left on a longer window, up to the resolver's target
|
|
926
|
+
// (native window ∧ authored tuning ceiling ∧ operator env cap).
|
|
927
|
+
// Exact GGUF geometry only: the weights-scaled heuristic
|
|
928
|
+
// misprices KV by up to ~10× in both directions, and growth on a
|
|
929
|
+
// mispriced slope is how a safe launch becomes a paging one.
|
|
930
|
+
if (contextRequirement.growthTargetTokens !== undefined &&
|
|
931
|
+
ladderKvLinearization !== null &&
|
|
932
|
+
exactKvAtReference !== undefined) {
|
|
933
|
+
const growthBudgetKind = brokerSnap?.enforced ? brokerSnap.pools.kind : liveBudget.kind;
|
|
934
|
+
// Fail open: without a reading, growth keeps the card-sized cap
|
|
935
|
+
// and admission still has the final word.
|
|
936
|
+
const measuredFreeVramBytes = growthBudgetKind === 'discrete-gpu'
|
|
937
|
+
? await measureAvailableGpuBytes().catch(() => undefined)
|
|
938
|
+
: undefined;
|
|
939
|
+
const growth = planAdaptiveContextGrowth({
|
|
940
|
+
basePerTurnCtxTokens: effectiveNumCtx,
|
|
941
|
+
targetPerTurnCtxTokens: contextRequirement.growthTargetTokens,
|
|
942
|
+
slots,
|
|
943
|
+
kvBytesPerToken: ladderKvLinearization.bytesPerToken,
|
|
944
|
+
kvFixedPerSlotBytes: ladderKvLinearization.fixedPerSlotBytes,
|
|
945
|
+
weightsResidentBytes: residentBytes,
|
|
946
|
+
fastBudgetBytes,
|
|
947
|
+
committedOtherBytes,
|
|
948
|
+
budgetKind: growthBudgetKind,
|
|
949
|
+
vramBytes: brokerSnap?.enforced ? brokerSnap.pools.vramBytes : liveBudget.vramBytes,
|
|
950
|
+
...(measuredFreeVramBytes !== undefined ? { measuredFreeVramBytes } : {}),
|
|
951
|
+
freeSystemRamBytes: availableSystemRamBytes(),
|
|
952
|
+
isMoE,
|
|
953
|
+
// A user-chosen lane count is not growth's to spend.
|
|
954
|
+
allowSlotTrade: configuredSlots === undefined,
|
|
955
|
+
});
|
|
956
|
+
if (growth.grown) {
|
|
957
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? defaultModelId ?? 'model'}: ${growth.reason}`);
|
|
958
|
+
effectiveNumCtx = growth.perTurnCtxTokens;
|
|
959
|
+
if (growth.slots < slots) {
|
|
960
|
+
slots = growth.slots;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
// Price the KV the engine will ACTUALLY allocate. Mirrors the
|
|
967
|
+
// `--swa-full` tri-state in buildLlamaCppEngineArgs (explicit config
|
|
968
|
+
// → manifest → Gemma auto-default gated on the fit verdict): an SWA
|
|
969
|
+
// model on the default windowed cache carries only its global layers
|
|
970
|
+
// per token plus a fixed window block per slot. Feeding the offload
|
|
971
|
+
// planner full-attention math for a windowed launch over-biased
|
|
972
|
+
// Gemma experts into system RAM for a cache that never materializes.
|
|
973
|
+
const effectiveSwaFull = config.llamaCppSwaFull ??
|
|
974
|
+
manifestEngineConfig?.swaFull ??
|
|
975
|
+
(swaFullAutoFits !== false &&
|
|
976
|
+
isGemmaModel({
|
|
977
|
+
architecture: modelCatalogInfo?.architecture,
|
|
978
|
+
modelId: defaultModelId ?? undefined,
|
|
979
|
+
}));
|
|
980
|
+
const windowedKvPlan = effectiveSwaFull
|
|
981
|
+
? undefined
|
|
982
|
+
: estimateWindowedKvLinearization({
|
|
983
|
+
blockCount: summary.blockCount,
|
|
984
|
+
embeddingLength: summary.embeddingLength,
|
|
985
|
+
headCount: summary.headCount,
|
|
986
|
+
headCountKv: summary.headCountKv,
|
|
987
|
+
headCountKvPerLayer: summary.headCountKvPerLayer,
|
|
988
|
+
slidingWindow: summary.slidingWindow,
|
|
989
|
+
slidingWindowPattern: summary.slidingWindowPattern,
|
|
990
|
+
sharedKvLayers: summary.sharedKvLayers,
|
|
991
|
+
loopCount: summary.loopCount,
|
|
992
|
+
keyLength: summary.keyLength,
|
|
993
|
+
valueLength: summary.valueLength,
|
|
994
|
+
keyLengthSwa: summary.keyLengthSwa,
|
|
995
|
+
valueLengthSwa: summary.valueLengthSwa,
|
|
996
|
+
fullAttentionInterval: summary.fullAttentionInterval,
|
|
997
|
+
ssmInnerSize: summary.ssmInnerSize,
|
|
998
|
+
ssmStateSize: summary.ssmStateSize,
|
|
999
|
+
ssmConvKernel: summary.ssmConvKernel,
|
|
1000
|
+
kvCacheType,
|
|
1001
|
+
});
|
|
1002
|
+
const kvReserveBytes = windowedKvPlan
|
|
1003
|
+
? Math.round(windowedKvPlan.fixedBytes * slots +
|
|
1004
|
+
windowedKvPlan.bytesPerToken * effectiveNumCtx * slots)
|
|
1005
|
+
: estimateKvReserveBytes({
|
|
1006
|
+
blockCount: summary.blockCount,
|
|
1007
|
+
embeddingLength: summary.embeddingLength,
|
|
1008
|
+
headCount: summary.headCount,
|
|
1009
|
+
headCountKv: summary.headCountKv,
|
|
1010
|
+
headCountKvPerLayer: summary.headCountKvPerLayer,
|
|
1011
|
+
slidingWindowPattern: summary.slidingWindowPattern,
|
|
1012
|
+
sharedKvLayers: summary.sharedKvLayers,
|
|
1013
|
+
loopCount: summary.loopCount,
|
|
1014
|
+
keyLength: summary.keyLength,
|
|
1015
|
+
valueLength: summary.valueLength,
|
|
1016
|
+
keyLengthSwa: summary.keyLengthSwa,
|
|
1017
|
+
valueLengthSwa: summary.valueLengthSwa,
|
|
1018
|
+
fullAttentionInterval: summary.fullAttentionInterval,
|
|
1019
|
+
ssmInnerSize: summary.ssmInnerSize,
|
|
1020
|
+
ssmStateSize: summary.ssmStateSize,
|
|
1021
|
+
ssmConvKernel: summary.ssmConvKernel,
|
|
1022
|
+
ctxTokens: effectiveNumCtx * slots,
|
|
1023
|
+
kvCacheType,
|
|
1024
|
+
});
|
|
1025
|
+
// The broker-ledger reservation for this launch: resident weights
|
|
1026
|
+
// plus the KV the engine will allocate at the granted window (M1 —
|
|
1027
|
+
// the weights-only ledger under-reserved dense models whose KV
|
|
1028
|
+
// rivals their weights: qwen3.5-4b at 64K carries more KV than
|
|
1029
|
+
// parameters). Consumed by the pool builder via
|
|
1030
|
+
// `plannedReservationBytes` so co-residency admission can see it.
|
|
1031
|
+
if (kvReserveBytes !== undefined) {
|
|
1032
|
+
plannedReservationBytes = residentBytes + kvReserveBytes;
|
|
1033
|
+
}
|
|
1034
|
+
if (isMoE) {
|
|
1035
|
+
// Plan against the card as it is now. Sized to the whole card, the
|
|
1036
|
+
// plan counted memory other programs held, and admission then had
|
|
1037
|
+
// to charge the model the whole card and refuse it (2026-10-11).
|
|
1038
|
+
const freeGpuBytes = vramBytes > 0 ? await measureAvailableGpuBytes().catch(() => undefined) : undefined;
|
|
1039
|
+
const moePlan = planMoeOffload({
|
|
1040
|
+
isMoE,
|
|
1041
|
+
residentBytes,
|
|
1042
|
+
vramBytes: freeGpuBytes !== undefined ? Math.min(vramBytes, freeGpuBytes) : vramBytes,
|
|
1043
|
+
...(split
|
|
1044
|
+
? {
|
|
1045
|
+
split,
|
|
1046
|
+
...(summary.blockCount !== undefined ? { blockCount: summary.blockCount } : {}),
|
|
1047
|
+
...(kvReserveBytes !== undefined ? { kvReserveBytes } : {}),
|
|
1048
|
+
}
|
|
1049
|
+
: {}),
|
|
1050
|
+
});
|
|
1051
|
+
offloadDecision = moePlan;
|
|
1052
|
+
// An explicit offload setting shadows the planner's flags, so its
|
|
1053
|
+
// footprint would describe a launch that is not the one made.
|
|
1054
|
+
const plannerPlacesExperts = (config.llamaCppCpuMoe ?? resolvedManifestEngineConfig?.cpuMoe) === undefined &&
|
|
1055
|
+
(config.llamaCppNCpuMoe ?? resolvedManifestEngineConfig?.nCpuMoe) === undefined &&
|
|
1056
|
+
(config.llamaCppNGpuLayers ?? resolvedManifestEngineConfig?.nGpuLayers) === undefined;
|
|
1057
|
+
if (plannerPlacesExperts)
|
|
1058
|
+
plannedGpuBytes = moePlan.gpuBytes;
|
|
1059
|
+
}
|
|
1060
|
+
else {
|
|
1061
|
+
const explicitNCpuFfn = config.llamaCppNCpuFfn ?? resolvedManifestEngineConfig?.nCpuFfn;
|
|
1062
|
+
const explicitNGpuLayers = config.llamaCppNGpuLayers ?? resolvedManifestEngineConfig?.nGpuLayers;
|
|
1063
|
+
// A positive/zero nCpuFfn is already the user's/model's decision.
|
|
1064
|
+
// A finite whole-layer GPU count is a different placement strategy;
|
|
1065
|
+
// don't layer an automatic tensor override on top of it. `-1` means
|
|
1066
|
+
// all and is compatible with the planner's own attention-on-GPU plan.
|
|
1067
|
+
offloadDecision =
|
|
1068
|
+
explicitNCpuFfn === undefined &&
|
|
1069
|
+
(explicitNGpuLayers === undefined || explicitNGpuLayers === -1)
|
|
1070
|
+
? planDenseFfnOffload({
|
|
1071
|
+
isMoE,
|
|
1072
|
+
// Respect the usable accelerator pool, any explicit capacity
|
|
1073
|
+
// ceiling, and co-resident reservations. The raw probe still
|
|
1074
|
+
// gates this to a real discrete-GPU build rather than treating
|
|
1075
|
+
// a CPU/unified fast pool as VRAM.
|
|
1076
|
+
vramBytes: vramBytes > 0 ? Math.max(0, budgetBytes - committedOtherBytes) : 0,
|
|
1077
|
+
...(denseFfnSplit ? { split: denseFfnSplit } : {}),
|
|
1078
|
+
...(summary.blockCount !== undefined ? { blockCount: summary.blockCount } : {}),
|
|
1079
|
+
...(kvReserveBytes !== undefined ? { kvReserveBytes } : {}),
|
|
1080
|
+
additionalGpuBytes: visionBudgetBytes,
|
|
1081
|
+
ramBudgetBytes: brokerSnap?.enforced
|
|
1082
|
+
? brokerSnap.pools.ramShareBytes
|
|
1083
|
+
: hostCapacity.ramShareBytes,
|
|
1084
|
+
freeSystemRamBytes: availableSystemRamBytes(),
|
|
1085
|
+
})
|
|
1086
|
+
: undefined;
|
|
1087
|
+
}
|
|
1088
|
+
if (offloadDecision?.reason) {
|
|
1089
|
+
log.info(`[llama-cpp] offload plan (${modelCatalogInfo?.id ?? 'model'}): ${offloadDecision.reason}`);
|
|
1090
|
+
}
|
|
1091
|
+
// Surface the capability-gated MTP decision. `--spec-type draft-mtp`
|
|
1092
|
+
// on a model llama.cpp can't build an MTP context for is fatal, so the
|
|
1093
|
+
// metadata gate remains load-bearing even though supported GGUFs are
|
|
1094
|
+
// now default-on.
|
|
1095
|
+
if (ggufHasMtp) {
|
|
1096
|
+
log.info(`[llama-cpp] ${modelCatalogInfo?.id ?? 'model'} ships an MTP head (nextn_predict_layers=${mtpLayerCount}); speculative decoding ${config.llamaCppSpecType || manifestEngineConfig?.spec?.type
|
|
1097
|
+
? 'follows the explicit setting'
|
|
1098
|
+
: 'is ON by default (+4-19% decode; disable with llamaCppSpecType: "none")'}.`);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
catch (err) {
|
|
1102
|
+
if (err instanceof CapacityDeniedError)
|
|
1103
|
+
throw err;
|
|
1104
|
+
log.warn(`[llama-cpp] offload planning skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
if (selectedSpecType === 'draft-mtp' && !ggufHasMtp) {
|
|
1108
|
+
log.warn(`[llama-cpp] draft-mtp was requested for ${modelCatalogInfo?.id ?? 'model'}, but its installed target/companion GGUF does not confirm MTP tensors; starting without speculative decoding.`);
|
|
1109
|
+
}
|
|
1110
|
+
// Forward-declared provider reference — the supervisor's onRawLine
|
|
1111
|
+
// callback needs it, but the provider itself needs the supervisor.
|
|
1112
|
+
// One is built, then the other; `providerRef` bridges the cycle.
|
|
1113
|
+
const providerHolder = { current: null };
|
|
1114
|
+
let cachedPort;
|
|
1115
|
+
// Two-stage idle (Phase 2.5): freeze at half the idle budget,
|
|
1116
|
+
// SIGTERM at the full budget. The freeze hook flushes slot caches
|
|
1117
|
+
// to disk while the engine is still healthy — so a SIGKILL during
|
|
1118
|
+
// the freeze→stop window doesn't lose them. The busy guard below is the
|
|
1119
|
+
// provider's physical request gate, so a long generation is protected while
|
|
1120
|
+
// a tool loop parked between requests can release the GPU normally.
|
|
1121
|
+
const llamaIdleMs = config.localEngineIdleTimeoutMs ?? DEFAULT_LOCAL_ENGINE_IDLE_TIMEOUT_MS;
|
|
1122
|
+
const llamaFreezeMs = Math.floor(llamaIdleMs / 2);
|
|
1123
|
+
// Startup timeout: 180s covers a 7B–30B model's CUDA warmup on
|
|
1124
|
+
// typical hardware. Frontier-tier 100B+ MoE models on unified-memory
|
|
1125
|
+
// boxes (DGX Spark, M-series Macs) routinely take 4–6 minutes for
|
|
1126
|
+
// the first KV-cache init; honor `GEZEL_LLAMA_STARTUP_TIMEOUT_MS`
|
|
1127
|
+
// so the user can lift the ceiling without recompiling.
|
|
1128
|
+
const llamaStartupTimeoutMs = (() => {
|
|
1129
|
+
const env = process.env.GEZEL_LLAMA_STARTUP_TIMEOUT_MS;
|
|
1130
|
+
if (env) {
|
|
1131
|
+
const n = Number.parseInt(env, 10);
|
|
1132
|
+
if (Number.isFinite(n) && n > 0)
|
|
1133
|
+
return n;
|
|
1134
|
+
}
|
|
1135
|
+
return 180_000;
|
|
1136
|
+
})();
|
|
1137
|
+
const supervisor = new NativeEngineSupervisor({
|
|
1138
|
+
capacity: {
|
|
1139
|
+
home,
|
|
1140
|
+
priority: () => (providerHolder.current?.queue.describe().runningInteractive ?? 0) > 0
|
|
1141
|
+
? 'interactive'
|
|
1142
|
+
: 'background',
|
|
1143
|
+
requirement: () => plannedReservationBytes !== undefined
|
|
1144
|
+
? {
|
|
1145
|
+
bytes: plannedReservationBytes,
|
|
1146
|
+
...(plannedGpuBytes !== undefined
|
|
1147
|
+
? { gpuBytes: Math.min(plannedGpuBytes, plannedReservationBytes) }
|
|
1148
|
+
: {}),
|
|
1149
|
+
}
|
|
1150
|
+
: undefined,
|
|
1151
|
+
},
|
|
1152
|
+
logPrefix: '[llama-server]',
|
|
1153
|
+
startupTimeoutMs: llamaStartupTimeoutMs,
|
|
1154
|
+
idleTimeoutMs: llamaIdleMs,
|
|
1155
|
+
freezeTimeoutMs: llamaFreezeMs,
|
|
1156
|
+
isBusy: () => providerHolder.current?.isEngineBusy() ?? false,
|
|
1157
|
+
...(opts.arbiter
|
|
1158
|
+
? {
|
|
1159
|
+
memoryPressure: () => opts.arbiter.getMemoryPressureStatus(),
|
|
1160
|
+
pressureIdleTimeoutMs: pressureIdleGraceMs(),
|
|
1161
|
+
}
|
|
1162
|
+
: {}),
|
|
1163
|
+
onFreeze: async () => {
|
|
1164
|
+
// flushAll is best-effort and handles its own try/catch — but
|
|
1165
|
+
// we await so the supervisor's freeze log line aligns with
|
|
1166
|
+
// disk-write completion (the operator log reads as one event).
|
|
1167
|
+
await providerHolder.current?.getCacheAdapter()?.flushAll();
|
|
1168
|
+
},
|
|
1169
|
+
onLog: (line) => {
|
|
1170
|
+
for (const retainedLine of progressLogThrottle.accept(line)) {
|
|
1171
|
+
log.info(retainedLine);
|
|
1172
|
+
logFile.write(retainedLine);
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
onExit: (snapshot) => {
|
|
1176
|
+
providerHolder.current?.getCacheAdapter()?.resetEngineState();
|
|
1177
|
+
if (snapshot.expected)
|
|
1178
|
+
return;
|
|
1179
|
+
logFile.writeIncident(snapshot);
|
|
1180
|
+
// A build that dies by SIGILL before it ever answers /health has
|
|
1181
|
+
// not failed at a task — it cannot run on this CPU at all, and
|
|
1182
|
+
// relaunching it on every request just reproduces the crash while
|
|
1183
|
+
// a working lower-tier build sits in the same directory. Write it
|
|
1184
|
+
// down so the next launch routes around it.
|
|
1185
|
+
//
|
|
1186
|
+
// Deliberately narrow: only SIGILL, and only before readiness.
|
|
1187
|
+
// A SIGSEGV during startup can be a corrupt model file, and any
|
|
1188
|
+
// crash after readiness is attributable to the work rather than
|
|
1189
|
+
// the binary — quarantining a backend over either would demote
|
|
1190
|
+
// users to slow engines for transient reasons.
|
|
1191
|
+
if (snapshot.signal !== 'SIGILL' || snapshot.reachedReady)
|
|
1192
|
+
return;
|
|
1193
|
+
const backend = process.env.GEZEL_LLAMA_SERVER_BACKEND;
|
|
1194
|
+
if (!backend)
|
|
1195
|
+
return;
|
|
1196
|
+
const entry = recordLlamaQuarantine(home, {
|
|
1197
|
+
backend,
|
|
1198
|
+
binaryPath: binary,
|
|
1199
|
+
signal: 'SIGILL',
|
|
1200
|
+
reason: 'crashed with SIGILL before the engine became ready — this build uses CPU instructions ' +
|
|
1201
|
+
'this machine does not support, or faulted inside GPU library startup',
|
|
1202
|
+
});
|
|
1203
|
+
if (entry) {
|
|
1204
|
+
log.warn(`[llama-server] quarantined the ${backend} build after SIGILL (incident=${snapshot.incidentId}); the next launch will fall back to another backend`);
|
|
1205
|
+
}
|
|
1206
|
+
},
|
|
1207
|
+
onRawLine: (line) => providerHolder.current?.onStdoutLine(line),
|
|
1208
|
+
// GPU-OOM recovery ladder: when a start dies of VRAM exhaustion and the
|
|
1209
|
+
// planner's offload decision was in play, degrade it one step
|
|
1210
|
+
// (partial split → all expert/FFN weights to RAM → engine-owned fit) and let the
|
|
1211
|
+
// supervisor retry — `resolveLaunch` below re-reads `offloadDecision`
|
|
1212
|
+
// on every spawn. The degraded plan sticks for later restarts of this
|
|
1213
|
+
// provider, so a recovered engine doesn't re-OOM on its next boot.
|
|
1214
|
+
recoverStartup: ({ panicKind }) => {
|
|
1215
|
+
if (panicKind !== 'cuda-out-of-memory' && panicKind !== 'vulkan-out-of-memory') {
|
|
1216
|
+
return false;
|
|
1217
|
+
}
|
|
1218
|
+
// Explicit config/manifest offload settings shadow the planner
|
|
1219
|
+
// per-field (see `buildLlamaCppEngineArgs`); when every field the
|
|
1220
|
+
// ladder would change is pinned, a retry replays the same argv.
|
|
1221
|
+
const pinned = (globalValue, manifestValue) => globalValue !== undefined || manifestValue !== undefined;
|
|
1222
|
+
const densePlan = typeof offloadDecision?.nCpuFfn === 'number';
|
|
1223
|
+
if (densePlan) {
|
|
1224
|
+
if (pinned(config.llamaCppNGpuLayers, resolvedManifestEngineConfig?.nGpuLayers) &&
|
|
1225
|
+
pinned(config.llamaCppNCpuFfn, resolvedManifestEngineConfig?.nCpuFfn)) {
|
|
1226
|
+
return false;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
else if (pinned(config.llamaCppNGpuLayers, resolvedManifestEngineConfig?.nGpuLayers) &&
|
|
1230
|
+
pinned(config.llamaCppCpuMoe, resolvedManifestEngineConfig?.cpuMoe) &&
|
|
1231
|
+
pinned(config.llamaCppNCpuMoe, resolvedManifestEngineConfig?.nCpuMoe)) {
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
const degraded = densePlan
|
|
1235
|
+
? degradeDenseFfnOffloadDecision(offloadDecision, offloadBlockCount)
|
|
1236
|
+
: degradeMoeOffloadDecision(offloadDecision);
|
|
1237
|
+
if (!degraded)
|
|
1238
|
+
return false;
|
|
1239
|
+
// The dense ladder's last rung removes the planner's `-ngl all`.
|
|
1240
|
+
// If an explicit global/manifest layer count shadows that removal,
|
|
1241
|
+
// retrying would replay byte-identical argv.
|
|
1242
|
+
if (densePlan &&
|
|
1243
|
+
degraded.nGpuLayers === undefined &&
|
|
1244
|
+
degraded.nCpuFfn === offloadDecision?.nCpuFfn &&
|
|
1245
|
+
pinned(config.llamaCppNGpuLayers, resolvedManifestEngineConfig?.nGpuLayers)) {
|
|
1246
|
+
return false;
|
|
1247
|
+
}
|
|
1248
|
+
log.warn(`[llama-cpp] ${panicKind} while starting ${modelCatalogInfo?.id ?? 'model'} — ${degraded.reason}`);
|
|
1249
|
+
offloadDecision = degraded;
|
|
1250
|
+
return true;
|
|
1251
|
+
},
|
|
1252
|
+
resolveLaunch: async () => {
|
|
1253
|
+
const port = cachedPort ?? (await pickFreePort());
|
|
1254
|
+
cachedPort = port;
|
|
1255
|
+
// Prepend the binary's own directory to PATH so the OS finds the
|
|
1256
|
+
// bundled CUDA / GGML peer DLLs at process startup, even when the
|
|
1257
|
+
// inherited PATH is sparse. Electron's PATH on Windows can omit
|
|
1258
|
+
// CUDA_PATH\bin entirely (the user's shell PATH doesn't propagate
|
|
1259
|
+
// when launched via VS Code / Start menu / shortcut), and
|
|
1260
|
+
// cublasLt's static dep on nvJitLink would otherwise exit
|
|
1261
|
+
// 0xC0000135 BEFORE main() runs. The bundle ships every required
|
|
1262
|
+
// DLL alongside the exe; this PATH tweak is what makes the
|
|
1263
|
+
// exe-dir-search-then-PATH-search resolve them all.
|
|
1264
|
+
const binDir = dirname(binary);
|
|
1265
|
+
const inheritedPath = process.env.PATH ?? '';
|
|
1266
|
+
const resolvedAdvancedArgs = buildLlamaCppEngineArgs({
|
|
1267
|
+
config,
|
|
1268
|
+
perModel: resolvedManifestEngineConfig,
|
|
1269
|
+
planner: offloadDecision,
|
|
1270
|
+
kvCacheType,
|
|
1271
|
+
slots,
|
|
1272
|
+
ggufHasMtp,
|
|
1273
|
+
installedDraftModelPath: modelCatalogInfo?.draftModelPath,
|
|
1274
|
+
// Opt-in A/B lever: `GEZEL_LLAMA_REASONING_FORMAT=none`
|
|
1275
|
+
// disables llama-server's chat-template output parsing so mangled
|
|
1276
|
+
// model output reaches `delta.content` for provider-side salvage.
|
|
1277
|
+
reasoningFormat: process.env.GEZEL_LLAMA_REASONING_FORMAT?.trim() || undefined,
|
|
1278
|
+
reasoningPreserve,
|
|
1279
|
+
architecture: modelCatalogInfo?.architecture,
|
|
1280
|
+
modelId: defaultModelId ?? undefined,
|
|
1281
|
+
swaFullAutoFits,
|
|
1282
|
+
backend: llamaBuildMetadata?.backend ?? process.env.GEZEL_LLAMA_SERVER_BACKEND,
|
|
1283
|
+
hostCpuCount: availableParallelism(),
|
|
1284
|
+
});
|
|
1285
|
+
return {
|
|
1286
|
+
command: binary,
|
|
1287
|
+
args: [
|
|
1288
|
+
'--model',
|
|
1289
|
+
modelPath,
|
|
1290
|
+
'--host',
|
|
1291
|
+
'127.0.0.1',
|
|
1292
|
+
'--port',
|
|
1293
|
+
String(port),
|
|
1294
|
+
// Loopback binding is not a closed door. llama.cpp defaults
|
|
1295
|
+
// `--cors-origins` to `*` with credentials enabled, so it echoes
|
|
1296
|
+
// back whatever Origin it is handed — meaning any web page the user
|
|
1297
|
+
// has open can drive this engine and read the answer, given the
|
|
1298
|
+
// port. The `localhost` special value emits no
|
|
1299
|
+
// Access-Control-Allow-Origin at all for a foreign origin, which is
|
|
1300
|
+
// what actually closes it. `--no-webui` drops the built-in chat
|
|
1301
|
+
// page; nothing in Gezel uses it. The matching bearer token goes in
|
|
1302
|
+
// through the environment below — CORS is a browser policy and does
|
|
1303
|
+
// nothing about a native process opening the port directly.
|
|
1304
|
+
'--cors-origins',
|
|
1305
|
+
'localhost',
|
|
1306
|
+
'--no-webui',
|
|
1307
|
+
// --jinja: use the chat template embedded in the GGUF (or
|
|
1308
|
+
// an override via --chat-template). Without it, llama-server
|
|
1309
|
+
// falls back to a generic template that doesn't match most
|
|
1310
|
+
// modern models — the "silent fallback to Llama-2 format"
|
|
1311
|
+
// footgun we surfaced in Phase 0.
|
|
1312
|
+
'--jinja',
|
|
1313
|
+
// `--ctx-size` is the TOTAL KV cache, divided evenly across
|
|
1314
|
+
// `--parallel` slots — so a naive `--ctx-size N` with two
|
|
1315
|
+
// slots gives each turn N/2 tokens of working window. We
|
|
1316
|
+
// want `effectiveNumCtx` to mean "per-turn budget" (matches
|
|
1317
|
+
// what every doc + warning + pressure-check assumes), so
|
|
1318
|
+
// multiply by the slot count here. llama-server prints
|
|
1319
|
+
// `n_ctx_seq (X) < n_ctx_train (Y)` as a hint when the
|
|
1320
|
+
// per-slot value falls below the model's native max — pre-
|
|
1321
|
+
// fix, every multi-slot install was tripping that warning
|
|
1322
|
+
// and quietly running with half the context the user
|
|
1323
|
+
// configured. The session-level `numCtx` reported back to
|
|
1324
|
+
// ChatManager.checkContextPressure stays at the per-slot
|
|
1325
|
+
// value (it's the working window for one turn), so pressure
|
|
1326
|
+
// math doesn't double-count.
|
|
1327
|
+
'--ctx-size',
|
|
1328
|
+
String(effectiveNumCtx * slots),
|
|
1329
|
+
// v0.4.0 can use one shared KV pool when `--kv-unified` is
|
|
1330
|
+
// enabled (including through the raw advanced escape hatch).
|
|
1331
|
+
// Keep one busy slot from consuming another's promised window;
|
|
1332
|
+
// on the default partitioned cache this equals the partition size
|
|
1333
|
+
// and is intentionally a no-op.
|
|
1334
|
+
'--kv-unified-per-slot',
|
|
1335
|
+
String(effectiveNumCtx),
|
|
1336
|
+
// --parallel matches the ProviderQueue's `concurrency` so the
|
|
1337
|
+
// engine has one KV slot per request lane. Without this,
|
|
1338
|
+
// llama-server stays at its default 1 slot and the 2nd
|
|
1339
|
+
// request just blocks server-side until the 1st finishes —
|
|
1340
|
+
// making our lane-aware queue useless.
|
|
1341
|
+
'--parallel',
|
|
1342
|
+
String(slots),
|
|
1343
|
+
// --slot-save-path enables per-slot KV state save/restore via
|
|
1344
|
+
// POST /slots/{id}?action={save|restore}. Without this flag
|
|
1345
|
+
// the endpoint returns 501 and the adapter's persistence
|
|
1346
|
+
// calls all silently fail. Files written here are read back
|
|
1347
|
+
// on supervisor restart / new session for the same gezel.
|
|
1348
|
+
'--slot-save-path',
|
|
1349
|
+
slotSavePath,
|
|
1350
|
+
// KV-cache quantization (`kvCacheType`, computed above). Default
|
|
1351
|
+
// q8_0 — ~50% memory savings with essentially zero quality
|
|
1352
|
+
// impact — EXCEPT the Gemma family, which defaults to f16
|
|
1353
|
+
// because q8_0 corrupts its KV cache (see the computation site).
|
|
1354
|
+
// Operators override either default via `config.llamaCppKvCacheType`.
|
|
1355
|
+
// Both K and V get the same type; asymmetric quant is rarely
|
|
1356
|
+
// worth the complexity.
|
|
1357
|
+
'--cache-type-k',
|
|
1358
|
+
kvCacheType,
|
|
1359
|
+
'--cache-type-v',
|
|
1360
|
+
kvCacheType,
|
|
1361
|
+
// Advanced engine-launch flags: flash-attn (tri-state, forced
|
|
1362
|
+
// `on` under quantized KV), `--ubatch-size`, GPU/MoE/dense offload
|
|
1363
|
+
// (`--n-gpu-layers` / `--cpu-moe` / `--n-cpu-moe` / `--n-cpu-ffn`),
|
|
1364
|
+
// v0.4.0 load/lazy modes,
|
|
1365
|
+
// `--cache-reuse` (auto-on prefix reuse), speculative decoding,
|
|
1366
|
+
// and the `llamaCppExtraArgs` escape hatch. Resolved from
|
|
1367
|
+
// global `config` ⊕ the model's manifest `tuning.engine.llamaCpp`.
|
|
1368
|
+
// Computed inside the closure so a settings change is picked up
|
|
1369
|
+
// on the next spawn.
|
|
1370
|
+
...resolvedAdvancedArgs,
|
|
1371
|
+
// Multimodal projector sidecar. Present only when the catalog
|
|
1372
|
+
// source declared `mmproj`, the installer fetched it, AND the user
|
|
1373
|
+
// opted this model into native vision.
|
|
1374
|
+
//
|
|
1375
|
+
// The opt-in exists because loading a projector makes llama-server
|
|
1376
|
+
// return 501 on slot save/restore, which latches disk-KV prefix
|
|
1377
|
+
// caching off for the whole process (see cache-adapter's
|
|
1378
|
+
// `slotActionsUnsupported`). That costs cached session resume on
|
|
1379
|
+
// every text turn, image or not — so it has to be a choice, not a
|
|
1380
|
+
// side effect of installing a model that happens to ship one.
|
|
1381
|
+
...(nativeVisionEnabled && modelCatalogInfo?.mmprojPath
|
|
1382
|
+
? ['--mmproj', modelCatalogInfo.mmprojPath]
|
|
1383
|
+
: []),
|
|
1384
|
+
// Cap chain-of-thought length per the catalog's tuning.
|
|
1385
|
+
// Without this, llama-server runs `reasoning-budget=-1`
|
|
1386
|
+
// (Int32.MAX) and some models think themselves into silence.
|
|
1387
|
+
...(reasoningBudgetTokens ? ['--reasoning-budget', String(reasoningBudgetTokens)] : []),
|
|
1388
|
+
],
|
|
1389
|
+
diagnostics: {
|
|
1390
|
+
nativeRelease: effectiveEngineRelease(),
|
|
1391
|
+
model: modelCatalogInfo?.id ?? defaultModelId ?? 'manual-path',
|
|
1392
|
+
backend: llamaBuildMetadata?.backend ?? process.env.GEZEL_LLAMA_SERVER_BACKEND ?? 'unknown',
|
|
1393
|
+
upstreamRevision: llamaBuildMetadata?.revision ?? 'unknown',
|
|
1394
|
+
cudaArchitectures: llamaBuildMetadata?.cudaArchitectures?.join(';') ?? 'unknown',
|
|
1395
|
+
...(llamaBuildMetadata?.cudaToolkit
|
|
1396
|
+
? { cudaToolkit: llamaBuildMetadata.cudaToolkit }
|
|
1397
|
+
: {}),
|
|
1398
|
+
...(llamaGpuDevice ? { gpu: llamaGpuDevice.name } : {}),
|
|
1399
|
+
...(nvidiaRuntimeDevice
|
|
1400
|
+
? {
|
|
1401
|
+
computeCapability: nvidiaRuntimeDevice.computeCapability,
|
|
1402
|
+
driverVersion: nvidiaRuntimeDevice.driverVersion,
|
|
1403
|
+
}
|
|
1404
|
+
: {}),
|
|
1405
|
+
contextPerSlot: effectiveNumCtx,
|
|
1406
|
+
contextTotal: effectiveNumCtx * slots,
|
|
1407
|
+
slots,
|
|
1408
|
+
kvCacheType,
|
|
1409
|
+
batchSize: lastArgValue(resolvedAdvancedArgs, '--batch-size') ?? 'default',
|
|
1410
|
+
ubatchSize: lastArgValue(resolvedAdvancedArgs, '--ubatch-size') ?? 'default',
|
|
1411
|
+
flashAttention: lastArgValue(resolvedAdvancedArgs, '--flash-attn') ?? 'default',
|
|
1412
|
+
threads: lastArgValue(resolvedAdvancedArgs, '--threads') ?? 'default',
|
|
1413
|
+
reasoningBudgetTokens: reasoningBudgetTokens ?? 'unbounded',
|
|
1414
|
+
reasoningBudgetSource,
|
|
1415
|
+
reasoningPreserve,
|
|
1416
|
+
cudaGraphs: process.env.GGML_CUDA_DISABLE_GRAPHS ? 'disabled-by-env' : 'default',
|
|
1417
|
+
},
|
|
1418
|
+
env: {
|
|
1419
|
+
PATH: inheritedPath ? `${binDir}${delimiter}${inheritedPath}` : binDir,
|
|
1420
|
+
// Equivalent to `--api-key`, but out of `argv` so it does not show
|
|
1421
|
+
// up in `ps` on a shared machine.
|
|
1422
|
+
LLAMA_API_KEY: engineApiKey(),
|
|
1423
|
+
},
|
|
1424
|
+
baseUrl: `http://127.0.0.1:${port}`,
|
|
1425
|
+
};
|
|
1426
|
+
},
|
|
1427
|
+
});
|
|
1428
|
+
const provider = new LlamaCppProvider({
|
|
1429
|
+
supervisor,
|
|
1430
|
+
logFile,
|
|
1431
|
+
slotSavePath,
|
|
1432
|
+
// Lets `listModels()` enumerate every installed model (not just
|
|
1433
|
+
// the resident one) so `/v1/models` + pickers see the full set
|
|
1434
|
+
// the engine pool can serve.
|
|
1435
|
+
...(opts.llamaCppModels ? { modelManager: opts.llamaCppModels } : {}),
|
|
1436
|
+
...(opts.arbiter ? { arbiter: opts.arbiter } : {}),
|
|
1437
|
+
// Pool replicas register their GPU evictor under their engine key
|
|
1438
|
+
// so concurrently-resident models don't clobber each other's
|
|
1439
|
+
// registration (and unregister cleanly on eviction). The singleton
|
|
1440
|
+
// path keeps the arbiter's 'default' owner.
|
|
1441
|
+
...(opts.modelOverride
|
|
1442
|
+
? {
|
|
1443
|
+
evictorOwnerId: makeEngineKey('llama-cpp', opts.modelOverride.modelId, opts.modelOverride.replicaIdx),
|
|
1444
|
+
}
|
|
1445
|
+
: {}),
|
|
1446
|
+
...baseProviderOpts,
|
|
1447
|
+
// MUST come after the spread: baseProviderOpts carries the bare
|
|
1448
|
+
// `patientFetch()` used by the external-baseUrl path, and later keys win.
|
|
1449
|
+
// Only engines WE launch get the bearer token — an external llama-server
|
|
1450
|
+
// is the user's, and we neither set its flags nor assume a credential.
|
|
1451
|
+
fetchImpl: withEngineApiKey(patientFetch(), engineApiKey()),
|
|
1452
|
+
// The RAM-aware admission pass may have lowered the launch from the
|
|
1453
|
+
// configured/default ceiling. Keep the session-side pressure checks,
|
|
1454
|
+
// tool budgets, and user-facing diagnostics on the exact per-slot value
|
|
1455
|
+
// passed to llama-server instead of falling back to the pre-clamp 65K.
|
|
1456
|
+
numCtx: effectiveNumCtx,
|
|
1457
|
+
// Weights + KV at the granted window/cache mode — the broker-ledger
|
|
1458
|
+
// reservation the pool should hold for this replica (M1).
|
|
1459
|
+
...(plannedReservationBytes !== undefined ? { plannedReservationBytes } : {}),
|
|
1460
|
+
...(plannedReservationBytes !== undefined && plannedGpuBytes !== undefined
|
|
1461
|
+
? { plannedGpuBytes: Math.min(plannedGpuBytes, plannedReservationBytes) }
|
|
1462
|
+
: {}),
|
|
1463
|
+
// Same value that decides `--mmproj` above, so the wire shape and the
|
|
1464
|
+
// launch flag can never disagree: typed image parts are only emitted for
|
|
1465
|
+
// a server that was actually started with a projector.
|
|
1466
|
+
visionEnabled: nativeVisionEnabled,
|
|
1467
|
+
// Supervised slot count (RAM/KV-sized above) overrides the external
|
|
1468
|
+
// default; drives the queue, `--parallel`, and (via
|
|
1469
|
+
// `provider.queue.concurrency`) the cache adapter's slotCount.
|
|
1470
|
+
concurrency: slots,
|
|
1471
|
+
// The same number, deliberately: what we reserved KV for is what can
|
|
1472
|
+
// generate. Passed only on the SUPERVISED path — an external llama-server
|
|
1473
|
+
// owns its own `--parallel` and may be single-slot, so that path leaves
|
|
1474
|
+
// the width at its conservative default.
|
|
1475
|
+
batchMaxConcurrency: slots,
|
|
1476
|
+
// Catalog id surfaced via `getEffectiveModelId()` so the chat
|
|
1477
|
+
// manager can recover a tier-classifiable model id when neither
|
|
1478
|
+
// `record.model` nor `config.defaultModel['llama-cpp']` was set —
|
|
1479
|
+
// without this the user's session uses an auto-picked model and
|
|
1480
|
+
// lands in `tier:tiny`. Falls back to `defaultModelId` when the
|
|
1481
|
+
// catalog lookup didn't fire (explicit `llamaCppModelPath` env
|
|
1482
|
+
// override). Mirrors the symmetric block in `buildMlxProvider`.
|
|
1483
|
+
...(modelCatalogInfo
|
|
1484
|
+
? { catalogModelId: modelCatalogInfo.id }
|
|
1485
|
+
: defaultModelId
|
|
1486
|
+
? { catalogModelId: defaultModelId }
|
|
1487
|
+
: {}),
|
|
1488
|
+
});
|
|
1489
|
+
providerHolder.current = provider;
|
|
1490
|
+
return provider;
|
|
1491
|
+
}
|