@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.
Files changed (967) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -2
  3. package/dist/cache/adapter.d.ts +115 -0
  4. package/dist/cache/adapter.js +23 -0
  5. package/dist/cache/budget.d.ts +15 -0
  6. package/dist/cache/budget.js +31 -0
  7. package/dist/cache/controller.d.ts +205 -0
  8. package/dist/cache/controller.js +377 -0
  9. package/dist/catalog/LICENSE +21 -0
  10. package/dist/catalog/chat-models/bt/btl4-35b-q4/manifest.json +146 -0
  11. package/dist/catalog/chat-models/bt/btl4-35b-q4/versions/1.0.0/manifest.json +15 -0
  12. package/dist/catalog/chat-models/bt/btl4-35b-q4/versions/1.0.1/manifest.json +15 -0
  13. package/dist/catalog/chat-models/bt/btl4-compact-iq2/manifest.json +146 -0
  14. package/dist/catalog/chat-models/bt/btl4-compact-iq2/versions/1.0.0/manifest.json +15 -0
  15. package/dist/catalog/chat-models/bt/btl4-compact-iq2/versions/1.0.1/manifest.json +15 -0
  16. package/dist/catalog/chat-models/bt/btl4-compact-iq2/versions/1.0.2/manifest.json +15 -0
  17. package/dist/catalog/chat-models/de/deepseek-r1-8b-q4/manifest.json +166 -0
  18. package/dist/catalog/chat-models/de/deepseek-r1-8b-q4/versions/1.1.0/manifest.json +62 -0
  19. package/dist/catalog/chat-models/de/deepseek-r1-8b-q4/versions/1.1.1/manifest.json +61 -0
  20. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-mxfp4/manifest.json +125 -0
  21. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-mxfp4/versions/1.0.0/manifest.json +27 -0
  22. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2/manifest.json +125 -0
  23. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.0.0/manifest.json +27 -0
  24. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.1.0/manifest.json +27 -0
  25. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2q4/manifest.json +126 -0
  26. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q2q4/versions/1.0.0/manifest.json +27 -0
  27. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q4/manifest.json +318 -0
  28. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.0.0/manifest.json +225 -0
  29. package/dist/catalog/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.1.0/manifest.json +225 -0
  30. package/dist/catalog/chat-models/ge/gemma4-12b-q4/manifest.json +249 -0
  31. package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.0.0/manifest.json +70 -0
  32. package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.1.0/manifest.json +72 -0
  33. package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.1.2/manifest.json +78 -0
  34. package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.1.3/manifest.json +78 -0
  35. package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.2.0/manifest.json +98 -0
  36. package/dist/catalog/chat-models/ge/gemma4-12b-q8/manifest.json +228 -0
  37. package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.0.0/manifest.json +72 -0
  38. package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.0.2/manifest.json +78 -0
  39. package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.0.3/manifest.json +78 -0
  40. package/dist/catalog/chat-models/ge/gemma4-12b-q8/versions/1.1.0/manifest.json +78 -0
  41. package/dist/catalog/chat-models/ge/gemma4-26b-q4/manifest.json +220 -0
  42. package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.1.0/manifest.json +75 -0
  43. package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.2.0/manifest.json +75 -0
  44. package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.2.1/manifest.json +80 -0
  45. package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.2.2/manifest.json +80 -0
  46. package/dist/catalog/chat-models/ge/gemma4-26b-q4/versions/1.3.0/manifest.json +81 -0
  47. package/dist/catalog/chat-models/ge/gemma4-31b-q4/manifest.json +226 -0
  48. package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.1.0/manifest.json +80 -0
  49. package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.1.1/manifest.json +82 -0
  50. package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.2.0/manifest.json +82 -0
  51. package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.2.1/manifest.json +95 -0
  52. package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.2.2/manifest.json +95 -0
  53. package/dist/catalog/chat-models/ge/gemma4-31b-q4/versions/1.3.0/manifest.json +86 -0
  54. package/dist/catalog/chat-models/ge/gemma4-e2b-q4/manifest.json +213 -0
  55. package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.1.0/manifest.json +67 -0
  56. package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.1.2/manifest.json +75 -0
  57. package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.2.0/manifest.json +71 -0
  58. package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.2.1/manifest.json +71 -0
  59. package/dist/catalog/chat-models/ge/gemma4-e2b-q4/versions/1.3.0/manifest.json +71 -0
  60. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/manifest.json +205 -0
  61. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.1.0/manifest.json +72 -0
  62. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.1.2/manifest.json +75 -0
  63. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.2.0/manifest.json +76 -0
  64. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.2.1/manifest.json +76 -0
  65. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/versions/1.3.0/manifest.json +76 -0
  66. package/dist/catalog/chat-models/gl/glm-5.2-754b-q2/manifest.json +127 -0
  67. package/dist/catalog/chat-models/gl/glm-5.2-754b-q2/versions/1.0.0/manifest.json +20 -0
  68. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/manifest.json +140 -0
  69. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.0/manifest.json +23 -0
  70. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.1/manifest.json +26 -0
  71. package/dist/catalog/chat-models/gp/gpt-oss-120b-q4/manifest.json +247 -0
  72. package/dist/catalog/chat-models/gp/gpt-oss-120b-q4/versions/1.0.0/manifest.json +137 -0
  73. package/dist/catalog/chat-models/gp/gpt-oss-120b-q4/versions/1.1.0/manifest.json +135 -0
  74. package/dist/catalog/chat-models/gp/gpt-oss-20b-q4/manifest.json +195 -0
  75. package/dist/catalog/chat-models/gp/gpt-oss-20b-q4/versions/1.1.0/manifest.json +72 -0
  76. package/dist/catalog/chat-models/gp/gpt-oss-20b-q4/versions/1.1.1/manifest.json +71 -0
  77. package/dist/catalog/chat-models/gr/granite4.2-30b-q4/manifest.json +200 -0
  78. package/dist/catalog/chat-models/gr/granite4.2-30b-q4/versions/1.0.0/manifest.json +72 -0
  79. package/dist/catalog/chat-models/gr/granite4.2-3b-q4/manifest.json +196 -0
  80. package/dist/catalog/chat-models/gr/granite4.2-3b-q4/versions/1.0.0/manifest.json +57 -0
  81. package/dist/catalog/chat-models/gr/granite4.2-8b-q4/manifest.json +189 -0
  82. package/dist/catalog/chat-models/gr/granite4.2-8b-q4/versions/1.0.0/manifest.json +57 -0
  83. package/dist/catalog/chat-models/index.json +1 -0
  84. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/manifest.json +235 -0
  85. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.0/manifest.json +124 -0
  86. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.1/manifest.json +124 -0
  87. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.2/manifest.json +123 -0
  88. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q6/manifest.json +257 -0
  89. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q6/versions/1.0.0/manifest.json +145 -0
  90. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q6/versions/1.0.1/manifest.json +145 -0
  91. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/manifest.json +285 -0
  92. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.0/manifest.json +174 -0
  93. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.1/manifest.json +174 -0
  94. package/dist/catalog/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.2/manifest.json +173 -0
  95. package/dist/catalog/chat-models/lf/lfm2.5-2.6b-q4/manifest.json +162 -0
  96. package/dist/catalog/chat-models/lf/lfm2.5-2.6b-q4/versions/1.0.0/manifest.json +59 -0
  97. package/dist/catalog/chat-models/lf/lfm2.5-2.6b-q4/versions/1.0.1/manifest.json +58 -0
  98. package/dist/catalog/chat-models/ll/llama3.2-3b-q4/manifest.json +134 -0
  99. package/dist/catalog/chat-models/ll/llama3.2-3b-q4/versions/1.1.0/manifest.json +57 -0
  100. package/dist/catalog/chat-models/ll/llama3.2-3b-q4/versions/1.1.1/manifest.json +56 -0
  101. package/dist/catalog/chat-models/mi/minicpm5-1b-q4/manifest.json +156 -0
  102. package/dist/catalog/chat-models/mi/minicpm5-1b-q4/versions/1.0.0/manifest.json +57 -0
  103. package/dist/catalog/chat-models/mi/minicpm5-2b-q4/manifest.json +161 -0
  104. package/dist/catalog/chat-models/mi/minicpm5-2b-q4/versions/1.0.0/manifest.json +57 -0
  105. package/dist/catalog/chat-models/mi/mistral-7b-q4/manifest.json +159 -0
  106. package/dist/catalog/chat-models/mi/mistral-7b-q4/versions/1.1.0/manifest.json +62 -0
  107. package/dist/catalog/chat-models/mi/mistral-7b-q4/versions/1.1.1/manifest.json +61 -0
  108. package/dist/catalog/chat-models/mi/mistral-medium-3.5-128b-q4/manifest.json +275 -0
  109. package/dist/catalog/chat-models/mi/mistral-medium-3.5-128b-q4/versions/1.0.0/manifest.json +154 -0
  110. package/dist/catalog/chat-models/mi/mistral-medium-3.5-128b-q4/versions/1.0.1/manifest.json +153 -0
  111. package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/manifest.json +135 -0
  112. package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.0/manifest.json +20 -0
  113. package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.1/manifest.json +20 -0
  114. package/dist/catalog/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.2/manifest.json +20 -0
  115. package/dist/catalog/chat-models/na/nanbeige4.2-3b-q4/manifest.json +138 -0
  116. package/dist/catalog/chat-models/na/nanbeige4.2-3b-q4/versions/1.0.0/manifest.json +14 -0
  117. package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/manifest.json +212 -0
  118. package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/versions/1.0.0/manifest.json +94 -0
  119. package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/versions/1.0.1/manifest.json +94 -0
  120. package/dist/catalog/chat-models/ne/nemotron3-nano-30b-q4/versions/1.0.2/manifest.json +93 -0
  121. package/dist/catalog/chat-models/ne/nemotron3-super-120b-q4/manifest.json +135 -0
  122. package/dist/catalog/chat-models/ne/nemotron3-super-120b-q4/versions/1.0.0/manifest.json +30 -0
  123. package/dist/catalog/chat-models/ne/nemotron3-super-120b-q4/versions/1.0.1/manifest.json +30 -0
  124. package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q4/manifest.json +192 -0
  125. package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q4/versions/1.0.0/manifest.json +74 -0
  126. package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q4/versions/1.0.1/manifest.json +73 -0
  127. package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q8/manifest.json +207 -0
  128. package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q8/versions/1.0.0/manifest.json +89 -0
  129. package/dist/catalog/chat-models/ne/nemotron3.5-lightning-30b-q8/versions/1.0.1/manifest.json +88 -0
  130. package/dist/catalog/chat-models/or/ornith-35b-q4/manifest.json +224 -0
  131. package/dist/catalog/chat-models/or/ornith-35b-q4/versions/1.0.0/manifest.json +94 -0
  132. package/dist/catalog/chat-models/or/ornith-35b-q4/versions/1.0.1/manifest.json +93 -0
  133. package/dist/catalog/chat-models/or/ornith-35b-q8/manifest.json +244 -0
  134. package/dist/catalog/chat-models/or/ornith-35b-q8/versions/1.0.0/manifest.json +114 -0
  135. package/dist/catalog/chat-models/or/ornith-35b-q8/versions/1.0.1/manifest.json +113 -0
  136. package/dist/catalog/chat-models/or/ornith-9b-q4/manifest.json +215 -0
  137. package/dist/catalog/chat-models/or/ornith-9b-q4/versions/1.0.0/manifest.json +84 -0
  138. package/dist/catalog/chat-models/or/ornith-9b-q4/versions/1.0.1/manifest.json +83 -0
  139. package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q4/manifest.json +208 -0
  140. package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q4/versions/1.0.0/manifest.json +74 -0
  141. package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q8/manifest.json +223 -0
  142. package/dist/catalog/chat-models/or/ornith1.5-35b-a3b-q8/versions/1.0.0/manifest.json +89 -0
  143. package/dist/catalog/chat-models/or/ornith1.5-9b-q4/manifest.json +187 -0
  144. package/dist/catalog/chat-models/or/ornith1.5-9b-q4/versions/1.0.0/manifest.json +53 -0
  145. package/dist/catalog/chat-models/or/ornith1.5-9b-q4/versions/1.0.1/manifest.json +77 -0
  146. package/dist/catalog/chat-models/or/ornith1.5-9b-q8/manifest.json +192 -0
  147. package/dist/catalog/chat-models/or/ornith1.5-9b-q8/versions/1.0.0/manifest.json +58 -0
  148. package/dist/catalog/chat-models/or/ornith1.5-9b-q8/versions/1.0.1/manifest.json +82 -0
  149. package/dist/catalog/chat-models/qw/qwen3.5-0.8b-q4/manifest.json +192 -0
  150. package/dist/catalog/chat-models/qw/qwen3.5-0.8b-q4/versions/1.0.0/manifest.json +75 -0
  151. package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/manifest.json +315 -0
  152. package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.0/manifest.json +164 -0
  153. package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.1/manifest.json +164 -0
  154. package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.2/manifest.json +164 -0
  155. package/dist/catalog/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.3/manifest.json +163 -0
  156. package/dist/catalog/chat-models/qw/qwen3.5-27b-q4/manifest.json +217 -0
  157. package/dist/catalog/chat-models/qw/qwen3.5-27b-q4/versions/1.0.0/manifest.json +90 -0
  158. package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/manifest.json +194 -0
  159. package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/versions/1.1.0/manifest.json +77 -0
  160. package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/versions/1.1.2/manifest.json +76 -0
  161. package/dist/catalog/chat-models/qw/qwen3.5-2b-q4/versions/1.1.3/manifest.json +76 -0
  162. package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/manifest.json +188 -0
  163. package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/versions/1.1.0/manifest.json +77 -0
  164. package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/versions/1.1.2/manifest.json +76 -0
  165. package/dist/catalog/chat-models/qw/qwen3.5-4b-q4/versions/1.1.3/manifest.json +76 -0
  166. package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/manifest.json +205 -0
  167. package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/versions/1.1.0/manifest.json +82 -0
  168. package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/versions/1.1.2/manifest.json +81 -0
  169. package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/versions/1.1.3/manifest.json +81 -0
  170. package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/manifest.json +230 -0
  171. package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.0/manifest.json +92 -0
  172. package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.4/manifest.json +91 -0
  173. package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.5/manifest.json +91 -0
  174. package/dist/catalog/chat-models/qw/qwen3.6-27b-q4/versions/1.1.6/manifest.json +115 -0
  175. package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/manifest.json +240 -0
  176. package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.0/manifest.json +102 -0
  177. package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.2/manifest.json +103 -0
  178. package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.3/manifest.json +103 -0
  179. package/dist/catalog/chat-models/qw/qwen3.6-27b-q8/versions/1.0.4/manifest.json +127 -0
  180. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/manifest.json +233 -0
  181. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.0/manifest.json +92 -0
  182. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.1/manifest.json +93 -0
  183. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.2/manifest.json +93 -0
  184. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.3/manifest.json +117 -0
  185. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/manifest.json +252 -0
  186. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.0/manifest.json +112 -0
  187. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.1/manifest.json +113 -0
  188. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.2/manifest.json +113 -0
  189. package/dist/catalog/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.3/manifest.json +137 -0
  190. package/dist/catalog/chat-models/qw/qwen3.8-27b-iq1-s/manifest.json +195 -0
  191. package/dist/catalog/chat-models/qw/qwen3.8-27b-iq1-s/versions/1.0.0/manifest.json +19 -0
  192. package/dist/catalog/chat-models/qw/qwen3.8-27b-q2/manifest.json +194 -0
  193. package/dist/catalog/chat-models/qw/qwen3.8-27b-q2/versions/1.0.0/manifest.json +19 -0
  194. package/dist/catalog/chat-models/qw/qwen3.8-27b-q3/manifest.json +194 -0
  195. package/dist/catalog/chat-models/qw/qwen3.8-27b-q3/versions/1.0.0/manifest.json +19 -0
  196. package/dist/catalog/chat-models/qw/qwen3.8-27b-q3/versions/1.0.1/manifest.json +19 -0
  197. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/manifest.json +291 -0
  198. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.0/manifest.json +20 -0
  199. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.1/manifest.json +93 -0
  200. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.2/manifest.json +92 -0
  201. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.3/manifest.json +116 -0
  202. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.4/manifest.json +116 -0
  203. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/versions/1.0.5/manifest.json +116 -0
  204. package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/manifest.json +278 -0
  205. package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.0/manifest.json +20 -0
  206. package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.1/manifest.json +104 -0
  207. package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.2/manifest.json +103 -0
  208. package/dist/catalog/chat-models/qw/qwen3.8-27b-q6/versions/1.0.3/manifest.json +127 -0
  209. package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/manifest.json +278 -0
  210. package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/versions/1.0.0/manifest.json +113 -0
  211. package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/versions/1.0.1/manifest.json +113 -0
  212. package/dist/catalog/chat-models/qw/qwen3.8-27b-q8/versions/1.0.2/manifest.json +137 -0
  213. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq3/manifest.json +221 -0
  214. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq3/versions/1.0.0/manifest.json +36 -0
  215. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/manifest.json +429 -0
  216. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.0.0/manifest.json +36 -0
  217. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.1.0/manifest.json +205 -0
  218. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.1.1/manifest.json +244 -0
  219. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/manifest.json +203 -0
  220. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.0/manifest.json +21 -0
  221. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.1/manifest.json +31 -0
  222. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.2/manifest.json +30 -0
  223. package/dist/catalog/chat-models/raw-index.json +1 -0
  224. package/dist/catalog/chat-models/ta/talkie-1930-13b-q4/manifest.json +79 -0
  225. package/dist/catalog/chat-models/ta/talkie-1930-13b-q4/versions/1.0.0/manifest.json +15 -0
  226. package/dist/catalog/chat-models/ta/talkie-1930-13b-q4/versions/1.0.1/manifest.json +15 -0
  227. package/dist/catalog/chat-models/te/ternary-bonsai-27b-q2/manifest.json +204 -0
  228. package/dist/catalog/chat-models/te/ternary-bonsai-27b-q2/versions/1.0.0/manifest.json +70 -0
  229. package/dist/catalog/chat-models/te/ternary-bonsai-27b-q2/versions/1.0.1/manifest.json +70 -0
  230. package/dist/catalog/chat-models/un/underdog-saluki-27b-iq2-mix/manifest.json +164 -0
  231. package/dist/catalog/chat-models/un/underdog-saluki-27b-iq2-mix/versions/1.0.0/manifest.json +14 -0
  232. package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/manifest.json +26 -0
  233. package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/versions/2026.10.8/manifest.json +8950 -0
  234. package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/manifest.json +24 -0
  235. package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/versions/2026.10.1/manifest.json +658 -0
  236. package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/manifest.json +24 -0
  237. package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/versions/2026.10.1/manifest.json +666 -0
  238. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/manifest.json +24 -0
  239. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/versions/2026.10.2/manifest.json +182 -0
  240. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/manifest.json +25 -0
  241. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/versions/2026.10.5/manifest.json +38 -0
  242. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/manifest.json +24 -0
  243. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/versions/2026.10.1/manifest.json +558 -0
  244. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/manifest.json +24 -0
  245. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/versions/2026.10.1/manifest.json +258 -0
  246. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/manifest.json +24 -0
  247. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/versions/2026.10.1/manifest.json +318 -0
  248. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/manifest.json +24 -0
  249. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/versions/2026.10.1/manifest.json +266 -0
  250. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/manifest.json +24 -0
  251. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/versions/2026.10.1/manifest.json +186 -0
  252. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/manifest.json +24 -0
  253. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/versions/2026.10.1/manifest.json +138 -0
  254. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/manifest.json +24 -0
  255. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/versions/2026.10.1/manifest.json +138 -0
  256. package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/manifest.json +24 -0
  257. package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/versions/2026.10.3/manifest.json +626 -0
  258. package/dist/catalog/knowledge-catalogs/index.json +1 -0
  259. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/manifest.json +22 -0
  260. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/versions/2026.10.16/manifest.json +18270 -0
  261. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/manifest.json +23 -0
  262. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/versions/2026.10.16/manifest.json +1098 -0
  263. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/manifest.json +23 -0
  264. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/versions/2026.10.16/manifest.json +722 -0
  265. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/manifest.json +23 -0
  266. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/versions/2026.10.16/manifest.json +530 -0
  267. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/manifest.json +23 -0
  268. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/versions/2026.10.16/manifest.json +602 -0
  269. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/manifest.json +23 -0
  270. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/versions/2026.10.16/manifest.json +250 -0
  271. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/manifest.json +22 -0
  272. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/versions/2026.10.16/manifest.json +16794 -0
  273. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/manifest.json +22 -0
  274. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/versions/2026.10.16/manifest.json +1106 -0
  275. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/manifest.json +22 -0
  276. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/versions/2026.10.16/manifest.json +234 -0
  277. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/manifest.json +22 -0
  278. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/versions/2026.10.16/manifest.json +522 -0
  279. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/manifest.json +22 -0
  280. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/versions/2026.10.16/manifest.json +1850 -0
  281. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/manifest.json +22 -0
  282. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/versions/2026.10.16/manifest.json +1734 -0
  283. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/manifest.json +22 -0
  284. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/versions/2026.10.16/manifest.json +774 -0
  285. package/dist/catalog/knowledge-catalogs/raw-index.json +1 -0
  286. package/dist/catalog/knowledge-catalogs/re/regional-american-south/art.json +12 -0
  287. package/dist/catalog/knowledge-catalogs/re/regional-american-south/logo.webp +0 -0
  288. package/dist/catalog/knowledge-catalogs/re/regional-american-south/manifest.json +48 -0
  289. package/dist/catalog/knowledge-catalogs/re/regional-american-south/versions/2026.10.3/manifest.json +133 -0
  290. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/art.json +12 -0
  291. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/logo.webp +0 -0
  292. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/manifest.json +48 -0
  293. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/versions/2026.10.3/manifest.json +133 -0
  294. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/art.json +12 -0
  295. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/logo.webp +0 -0
  296. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/manifest.json +48 -0
  297. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/versions/2026.10.3/manifest.json +133 -0
  298. package/dist/catalog/knowledge-catalogs/re/regional-brazil/art.json +12 -0
  299. package/dist/catalog/knowledge-catalogs/re/regional-brazil/logo.webp +0 -0
  300. package/dist/catalog/knowledge-catalogs/re/regional-brazil/manifest.json +48 -0
  301. package/dist/catalog/knowledge-catalogs/re/regional-brazil/versions/2026.10.3/manifest.json +133 -0
  302. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/art.json +12 -0
  303. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/logo.webp +0 -0
  304. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/manifest.json +48 -0
  305. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/versions/2026.10.3/manifest.json +133 -0
  306. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/art.json +12 -0
  307. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/logo.webp +0 -0
  308. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/manifest.json +48 -0
  309. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/versions/2026.10.3/manifest.json +133 -0
  310. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/art.json +12 -0
  311. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/logo.webp +0 -0
  312. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/manifest.json +48 -0
  313. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/versions/2026.10.3/manifest.json +133 -0
  314. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/art.json +12 -0
  315. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/logo.webp +0 -0
  316. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/manifest.json +48 -0
  317. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/versions/2026.10.3/manifest.json +133 -0
  318. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/art.json +12 -0
  319. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/logo.webp +0 -0
  320. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/manifest.json +48 -0
  321. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/versions/2026.10.3/manifest.json +133 -0
  322. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/art.json +12 -0
  323. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/logo.webp +0 -0
  324. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/manifest.json +48 -0
  325. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/versions/2026.10.3/manifest.json +133 -0
  326. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/art.json +12 -0
  327. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/logo.webp +0 -0
  328. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/manifest.json +48 -0
  329. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/versions/2026.10.3/manifest.json +133 -0
  330. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/art.json +12 -0
  331. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/logo.webp +0 -0
  332. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/manifest.json +48 -0
  333. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/versions/2026.10.3/manifest.json +133 -0
  334. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/art.json +12 -0
  335. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/logo.webp +0 -0
  336. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/manifest.json +48 -0
  337. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/versions/2026.10.3/manifest.json +133 -0
  338. package/dist/catalog/knowledge-catalogs/re/regional-midwest/art.json +12 -0
  339. package/dist/catalog/knowledge-catalogs/re/regional-midwest/logo.webp +0 -0
  340. package/dist/catalog/knowledge-catalogs/re/regional-midwest/manifest.json +48 -0
  341. package/dist/catalog/knowledge-catalogs/re/regional-midwest/versions/2026.10.3/manifest.json +133 -0
  342. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/art.json +12 -0
  343. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/logo.webp +0 -0
  344. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/manifest.json +48 -0
  345. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/versions/2026.10.3/manifest.json +133 -0
  346. package/dist/catalog/knowledge-catalogs/re/regional-northeast/art.json +12 -0
  347. package/dist/catalog/knowledge-catalogs/re/regional-northeast/logo.webp +0 -0
  348. package/dist/catalog/knowledge-catalogs/re/regional-northeast/manifest.json +48 -0
  349. package/dist/catalog/knowledge-catalogs/re/regional-northeast/versions/2026.10.3/manifest.json +133 -0
  350. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/art.json +12 -0
  351. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/logo.webp +0 -0
  352. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/manifest.json +48 -0
  353. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/versions/2026.10.3/manifest.json +133 -0
  354. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/art.json +12 -0
  355. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/logo.webp +0 -0
  356. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/manifest.json +48 -0
  357. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/versions/2026.10.3/manifest.json +133 -0
  358. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/art.json +12 -0
  359. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/logo.webp +0 -0
  360. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/manifest.json +48 -0
  361. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/versions/2026.10.3/manifest.json +133 -0
  362. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/art.json +12 -0
  363. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/logo.webp +0 -0
  364. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/manifest.json +48 -0
  365. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/versions/2026.10.3/manifest.json +133 -0
  366. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/art.json +12 -0
  367. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/logo.webp +0 -0
  368. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/manifest.json +48 -0
  369. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/versions/2026.10.3/manifest.json +133 -0
  370. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/art.json +12 -0
  371. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/logo.webp +0 -0
  372. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/manifest.json +48 -0
  373. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/versions/2026.10.3/manifest.json +133 -0
  374. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/art.json +12 -0
  375. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/logo.webp +0 -0
  376. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/manifest.json +48 -0
  377. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/versions/2026.10.3/manifest.json +133 -0
  378. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/art.json +12 -0
  379. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/logo.webp +0 -0
  380. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/manifest.json +48 -0
  381. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/versions/2026.10.3/manifest.json +133 -0
  382. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/art.json +12 -0
  383. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/logo.webp +0 -0
  384. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/manifest.json +48 -0
  385. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/versions/2026.10.3/manifest.json +133 -0
  386. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/art.json +12 -0
  387. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/logo.webp +0 -0
  388. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/manifest.json +48 -0
  389. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/versions/2026.10.3/manifest.json +133 -0
  390. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/art.json +12 -0
  391. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/logo.webp +0 -0
  392. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/manifest.json +28 -0
  393. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.4.2/manifest.json +53 -0
  394. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.4.3/manifest.json +885 -0
  395. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.4.5/manifest.json +157 -0
  396. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/art.json +11 -0
  397. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/logo.webp +0 -0
  398. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/manifest.json +32 -0
  399. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.4.2/manifest.json +69 -0
  400. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.4.3/manifest.json +741 -0
  401. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.4.5/manifest.json +173 -0
  402. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/art.json +12 -0
  403. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/logo.webp +0 -0
  404. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/manifest.json +69 -0
  405. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.4.4/manifest.json +217 -0
  406. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.4.5/manifest.json +217 -0
  407. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/art.json +12 -0
  408. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/logo.webp +0 -0
  409. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/manifest.json +64 -0
  410. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.4.4/manifest.json +197 -0
  411. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.4.5/manifest.json +197 -0
  412. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/art.json +12 -0
  413. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/logo.webp +0 -0
  414. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/manifest.json +64 -0
  415. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.4.5/manifest.json +197 -0
  416. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/art.json +11 -0
  417. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/logo.webp +0 -0
  418. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/manifest.json +29 -0
  419. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.4.2/manifest.json +57 -0
  420. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.4.3/manifest.json +925 -0
  421. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.4.5/manifest.json +185 -0
  422. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/art.json +12 -0
  423. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/logo.webp +0 -0
  424. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/manifest.json +28 -0
  425. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.4.2/manifest.json +53 -0
  426. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.4.3/manifest.json +1665 -0
  427. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.4.5/manifest.json +133 -0
  428. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/art.json +12 -0
  429. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/logo.webp +0 -0
  430. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/manifest.json +29 -0
  431. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.4.2/manifest.json +57 -0
  432. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.4.3/manifest.json +1233 -0
  433. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.4.5/manifest.json +141 -0
  434. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/art.json +11 -0
  435. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/logo.webp +0 -0
  436. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/manifest.json +29 -0
  437. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.4.2/manifest.json +57 -0
  438. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.4.3/manifest.json +493 -0
  439. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.4.5/manifest.json +185 -0
  440. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/art.json +12 -0
  441. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/logo.webp +0 -0
  442. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/manifest.json +63 -0
  443. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.4.4/manifest.json +193 -0
  444. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.4.5/manifest.json +193 -0
  445. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/art.json +12 -0
  446. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/logo.webp +0 -0
  447. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/manifest.json +30 -0
  448. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.4.2/manifest.json +61 -0
  449. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.4.3/manifest.json +665 -0
  450. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.4.5/manifest.json +177 -0
  451. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/art.json +12 -0
  452. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/logo.webp +0 -0
  453. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/manifest.json +29 -0
  454. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.4.2/manifest.json +57 -0
  455. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.4.3/manifest.json +745 -0
  456. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.4.5/manifest.json +185 -0
  457. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/art.json +12 -0
  458. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/logo.webp +0 -0
  459. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/manifest.json +62 -0
  460. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.4.4/manifest.json +189 -0
  461. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.4.5/manifest.json +189 -0
  462. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/art.json +12 -0
  463. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/logo.webp +0 -0
  464. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/manifest.json +64 -0
  465. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.4.5/manifest.json +197 -0
  466. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/art.json +12 -0
  467. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/logo.webp +0 -0
  468. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/manifest.json +64 -0
  469. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.4.4/manifest.json +197 -0
  470. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.4.5/manifest.json +197 -0
  471. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/art.json +12 -0
  472. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/logo.webp +0 -0
  473. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/manifest.json +30 -0
  474. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.4.2/manifest.json +61 -0
  475. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.4.3/manifest.json +1253 -0
  476. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.4.5/manifest.json +189 -0
  477. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/art.json +12 -0
  478. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/logo.webp +0 -0
  479. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/manifest.json +29 -0
  480. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.4.2/manifest.json +57 -0
  481. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.4.3/manifest.json +1957 -0
  482. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.4.5/manifest.json +185 -0
  483. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/art.json +12 -0
  484. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/logo.webp +0 -0
  485. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/manifest.json +63 -0
  486. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.4.5/manifest.json +193 -0
  487. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/art.json +11 -0
  488. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/logo.webp +0 -0
  489. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/manifest.json +45 -0
  490. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.4.4/manifest.json +121 -0
  491. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.4.5/manifest.json +173 -0
  492. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/art.json +12 -0
  493. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/logo.webp +0 -0
  494. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/manifest.json +62 -0
  495. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.4.4/manifest.json +189 -0
  496. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.4.5/manifest.json +189 -0
  497. package/dist/catalog/provenance.json +8 -0
  498. package/dist/chat/catalog-model-lookup.d.ts +21 -0
  499. package/dist/chat/catalog-model-lookup.js +48 -0
  500. package/dist/chat/local-model-tier.d.ts +1 -0
  501. package/dist/chat/local-model-tier.js +2 -0
  502. package/dist/chat/vision-capability.d.ts +1 -0
  503. package/dist/chat/vision-capability.js +3 -0
  504. package/dist/engine-components.d.ts +30 -0
  505. package/dist/engine-components.js +144 -0
  506. package/dist/engines/electron-native-reuse.d.ts +65 -0
  507. package/dist/engines/electron-native-reuse.js +305 -0
  508. package/dist/engines/native-file-manifest.json +1320 -0
  509. package/dist/engines/native-manifest.d.ts +70 -0
  510. package/dist/engines/native-manifest.js +98 -0
  511. package/dist/engines/registry.d.ts +88 -0
  512. package/dist/engines/registry.js +217 -0
  513. package/dist/engines/resolver.d.ts +121 -0
  514. package/dist/engines/resolver.js +894 -0
  515. package/dist/engines/signature.d.ts +85 -0
  516. package/dist/engines/signature.js +231 -0
  517. package/dist/fs/atomic.d.ts +53 -0
  518. package/dist/fs/atomic.js +202 -0
  519. package/dist/fs/config-store.d.ts +14 -0
  520. package/dist/fs/config-store.js +101 -0
  521. package/dist/fs/home-permissions.d.ts +18 -0
  522. package/dist/fs/home-permissions.js +27 -0
  523. package/dist/fs/safe-paths.d.ts +107 -0
  524. package/dist/fs/safe-paths.js +264 -0
  525. package/dist/fs/security-json.d.ts +13 -0
  526. package/dist/fs/security-json.js +67 -0
  527. package/dist/http/auth-context.d.ts +23 -0
  528. package/dist/http/auth-context.js +1 -0
  529. package/dist/http/engine-runtime-context.d.ts +30 -0
  530. package/dist/http/engine-runtime-context.js +1 -0
  531. package/dist/http/external-conversation-contract.d.ts +49 -0
  532. package/dist/http/external-conversation-contract.js +1 -0
  533. package/dist/http/external-conversation-headers.d.ts +11 -0
  534. package/dist/http/external-conversation-headers.js +11 -0
  535. package/dist/http/inference-context.d.ts +36 -0
  536. package/dist/http/inference-context.js +1 -0
  537. package/dist/http/model-inventory-cache.d.ts +8 -0
  538. package/dist/http/model-inventory-cache.js +8 -0
  539. package/dist/http/openai-compat/action-ledger.d.ts +15 -0
  540. package/dist/http/openai-compat/action-ledger.js +119 -0
  541. package/dist/http/openai-compat/apple-model.d.ts +3 -0
  542. package/dist/http/openai-compat/apple-model.js +44 -0
  543. package/dist/http/openai-compat/caller-owned-profile.d.ts +7 -0
  544. package/dist/http/openai-compat/caller-owned-profile.js +18 -0
  545. package/dist/http/openai-compat/chat-progress.d.ts +9 -0
  546. package/dist/http/openai-compat/chat-progress.js +69 -0
  547. package/dist/http/openai-compat/chat-target.d.ts +76 -0
  548. package/dist/http/openai-compat/chat-target.js +97 -0
  549. package/dist/http/openai-compat/embeddings.d.ts +37 -0
  550. package/dist/http/openai-compat/embeddings.js +86 -0
  551. package/dist/http/openai-compat/request-tuning.d.ts +35 -0
  552. package/dist/http/openai-compat/request-tuning.js +87 -0
  553. package/dist/http/openai-compat/responses-streaming.d.ts +351 -0
  554. package/dist/http/openai-compat/responses-streaming.js +717 -0
  555. package/dist/http/openai-compat/responses-translate.d.ts +215 -0
  556. package/dist/http/openai-compat/responses-translate.js +377 -0
  557. package/dist/http/openai-compat/streaming-telemetry.d.ts +30 -0
  558. package/dist/http/openai-compat/streaming-telemetry.js +88 -0
  559. package/dist/http/openai-compat/streaming.d.ts +141 -0
  560. package/dist/http/openai-compat/streaming.js +687 -0
  561. package/dist/http/openai-compat/tool-call-stream-filter.d.ts +33 -0
  562. package/dist/http/openai-compat/tool-call-stream-filter.js +110 -0
  563. package/dist/http/openai-compat/translate.d.ts +254 -0
  564. package/dist/http/openai-compat/translate.js +485 -0
  565. package/dist/http/routes/engines.d.ts +13 -0
  566. package/dist/http/routes/engines.js +366 -0
  567. package/dist/http/routes/machine-engine-proxy.d.ts +26 -0
  568. package/dist/http/routes/machine-engine-proxy.js +43 -0
  569. package/dist/http/routes/model-bundles.d.ts +4 -0
  570. package/dist/http/routes/model-bundles.js +190 -0
  571. package/dist/http/routes/v1-chat.d.ts +72 -0
  572. package/dist/http/routes/v1-chat.js +645 -0
  573. package/dist/http/routes/v1-embeddings.d.ts +3 -0
  574. package/dist/http/routes/v1-embeddings.js +82 -0
  575. package/dist/http/routes/v1-knowledge.d.ts +4 -0
  576. package/dist/http/routes/v1-knowledge.js +304 -0
  577. package/dist/http/routes/v1-models-ensure.d.ts +32 -0
  578. package/dist/http/routes/v1-models-ensure.js +122 -0
  579. package/dist/http/routes/v1-models.d.ts +8 -0
  580. package/dist/http/routes/v1-models.js +189 -0
  581. package/dist/http/routes/v1-responses.d.ts +20 -0
  582. package/dist/http/routes/v1-responses.js +327 -0
  583. package/dist/index.d.ts +2 -0
  584. package/dist/index.js +2 -0
  585. package/dist/inference-service.d.ts +28 -0
  586. package/dist/inference-service.js +275 -0
  587. package/dist/knowledge/admission.d.ts +3 -0
  588. package/dist/knowledge/admission.js +22 -0
  589. package/dist/knowledge/bundled-catalog.d.ts +2 -0
  590. package/dist/knowledge/bundled-catalog.js +2 -0
  591. package/dist/knowledge/catalog-host.d.ts +103 -0
  592. package/dist/knowledge/catalog-host.js +180 -0
  593. package/dist/knowledge/catalog-source.d.ts +22 -0
  594. package/dist/knowledge/catalog-source.js +35 -0
  595. package/dist/knowledge/install.d.ts +55 -0
  596. package/dist/knowledge/install.js +274 -0
  597. package/dist/knowledge/manager.d.ts +287 -0
  598. package/dist/knowledge/manager.js +1540 -0
  599. package/dist/knowledge/registry.d.ts +35 -0
  600. package/dist/knowledge/registry.js +123 -0
  601. package/dist/knowledge/search-worker.d.ts +17 -0
  602. package/dist/knowledge/search-worker.js +36 -0
  603. package/dist/knowledge/shared-install-contract.d.ts +19 -0
  604. package/dist/knowledge/shared-install-contract.js +1 -0
  605. package/dist/knowledge/spatial-query.d.ts +11 -0
  606. package/dist/knowledge/spatial-query.js +33 -0
  607. package/dist/knowledge/trust-anchors.d.ts +11 -0
  608. package/dist/knowledge/trust-anchors.js +51 -0
  609. package/dist/knowledge/vector-floors.d.ts +44 -0
  610. package/dist/knowledge/vector-floors.js +92 -0
  611. package/dist/knowledge/worker-host.d.ts +9 -0
  612. package/dist/knowledge/worker-host.js +179 -0
  613. package/dist/kokoro-lexicon/LICENSE +202 -0
  614. package/dist/kokoro-lexicon/lexicon-gb-en.txt.gz +0 -0
  615. package/dist/kokoro-lexicon/lexicon-us-en.txt.gz +0 -0
  616. package/dist/kokoro-lexicon/manifest.json +23 -0
  617. package/dist/machine-engine/inspect-runtime.d.ts +3 -0
  618. package/dist/machine-engine/inspect-runtime.js +48 -0
  619. package/dist/machine-engine/knowledge-assets.d.ts +79 -0
  620. package/dist/machine-engine/knowledge-assets.js +505 -0
  621. package/dist/memory/embed-core.d.ts +131 -0
  622. package/dist/memory/embed-core.js +398 -0
  623. package/dist/memory/embed-worker.d.ts +23 -0
  624. package/dist/memory/embed-worker.js +49 -0
  625. package/dist/memory/embeddings.d.ts +105 -0
  626. package/dist/memory/embeddings.js +467 -0
  627. package/dist/model-profile/behaviors/tools-mlx-template-fix.d.ts +1 -0
  628. package/dist/model-profile/behaviors/tools-mlx-template-fix.js +2 -0
  629. package/dist/model-profile/behaviors/turn-ramble-detection.d.ts +1 -0
  630. package/dist/model-profile/behaviors/turn-ramble-detection.js +2 -0
  631. package/dist/model-profile/defaults.d.ts +1 -0
  632. package/dist/model-profile/defaults.js +2 -0
  633. package/dist/model-profile/index.d.ts +9 -0
  634. package/dist/model-profile/index.js +7 -0
  635. package/dist/model-profile/registry.d.ts +15 -0
  636. package/dist/model-profile/registry.js +18 -0
  637. package/dist/model-profile/runtime.d.ts +48 -0
  638. package/dist/model-profile/runtime.js +131 -0
  639. package/dist/model-profile/tool-grammar.d.ts +1 -0
  640. package/dist/model-profile/tool-grammar.js +2 -0
  641. package/dist/model-profile/tuning.d.ts +19 -0
  642. package/dist/model-profile/tuning.js +21 -0
  643. package/dist/model-profile/types.d.ts +1 -0
  644. package/dist/model-profile/types.js +2 -0
  645. package/dist/models/bundle-storage.d.ts +28 -0
  646. package/dist/models/bundle-storage.js +80 -0
  647. package/dist/models/catalog-drift.d.ts +48 -0
  648. package/dist/models/catalog-drift.js +94 -0
  649. package/dist/models/catalog-payload-identity.d.ts +107 -0
  650. package/dist/models/catalog-payload-identity.js +254 -0
  651. package/dist/models/ensure.d.ts +125 -0
  652. package/dist/models/ensure.js +205 -0
  653. package/dist/models/gezmodel.d.ts +47 -0
  654. package/dist/models/gezmodel.js +742 -0
  655. package/dist/models/install-registry.d.ts +101 -0
  656. package/dist/models/install-registry.js +216 -0
  657. package/dist/models/model-id.d.ts +22 -0
  658. package/dist/models/model-id.js +40 -0
  659. package/dist/models/storage-roots.d.ts +274 -0
  660. package/dist/models/storage-roots.js +865 -0
  661. package/dist/native-release-entry.d.ts +16 -0
  662. package/dist/native-release-entry.js +16 -0
  663. package/dist/perf/redact-path.d.ts +2 -0
  664. package/dist/perf/redact-path.js +27 -0
  665. package/dist/perf/responsiveness.d.ts +70 -0
  666. package/dist/perf/responsiveness.js +560 -0
  667. package/dist/providers/active-install-message.d.ts +42 -0
  668. package/dist/providers/active-install-message.js +49 -0
  669. package/dist/providers/apple-foundation-models/binary.d.ts +4 -0
  670. package/dist/providers/apple-foundation-models/binary.js +18 -0
  671. package/dist/providers/apple-foundation-models/helper.d.ts +66 -0
  672. package/dist/providers/apple-foundation-models/helper.js +262 -0
  673. package/dist/providers/apple-foundation-models/provider.d.ts +82 -0
  674. package/dist/providers/apple-foundation-models/provider.js +389 -0
  675. package/dist/providers/apple-foundation-models/status.d.ts +9 -0
  676. package/dist/providers/apple-foundation-models/status.js +49 -0
  677. package/dist/providers/audio/kokoro-frontend.d.ts +50 -0
  678. package/dist/providers/audio/kokoro-frontend.js +113 -0
  679. package/dist/providers/audio/managed-speech-model.d.ts +9 -0
  680. package/dist/providers/audio/managed-speech-model.js +86 -0
  681. package/dist/providers/audio/types.d.ts +202 -0
  682. package/dist/providers/audio/types.js +17 -0
  683. package/dist/providers/audio/whisper-cpp.d.ts +99 -0
  684. package/dist/providers/audio/whisper-cpp.js +420 -0
  685. package/dist/providers/audio-persister-contract.d.ts +13 -0
  686. package/dist/providers/audio-persister-contract.js +1 -0
  687. package/dist/providers/catalog-model-config.d.ts +63 -0
  688. package/dist/providers/catalog-model-config.js +95 -0
  689. package/dist/providers/code-block-salvage.d.ts +1 -0
  690. package/dist/providers/code-block-salvage.js +2 -0
  691. package/dist/providers/codex-cli/reasoning.d.ts +8 -0
  692. package/dist/providers/codex-cli/reasoning.js +17 -0
  693. package/dist/providers/complete-tool-call.d.ts +16 -0
  694. package/dist/providers/complete-tool-call.js +25 -0
  695. package/dist/providers/constrained-turn.d.ts +1 -0
  696. package/dist/providers/constrained-turn.js +2 -0
  697. package/dist/providers/deliverable-read-pacing.d.ts +1 -0
  698. package/dist/providers/deliverable-read-pacing.js +2 -0
  699. package/dist/providers/direct-file-work-prompt.d.ts +1 -0
  700. package/dist/providers/direct-file-work-prompt.js +2 -0
  701. package/dist/providers/ds4/build-provider.d.ts +100 -0
  702. package/dist/providers/ds4/build-provider.js +539 -0
  703. package/dist/providers/ds4/cache-adapter.d.ts +42 -0
  704. package/dist/providers/ds4/cache-adapter.js +110 -0
  705. package/dist/providers/ds4/dspark.d.ts +83 -0
  706. package/dist/providers/ds4/dspark.js +107 -0
  707. package/dist/providers/ds4/mtp.d.ts +32 -0
  708. package/dist/providers/ds4/mtp.js +46 -0
  709. package/dist/providers/ds4/provider.d.ts +67 -0
  710. package/dist/providers/ds4/provider.js +104 -0
  711. package/dist/providers/ds4/residency.d.ts +143 -0
  712. package/dist/providers/ds4/residency.js +139 -0
  713. package/dist/providers/ds4/stdout-parser.d.ts +47 -0
  714. package/dist/providers/ds4/stdout-parser.js +134 -0
  715. package/dist/providers/duplicate-tool-calls.d.ts +1 -0
  716. package/dist/providers/duplicate-tool-calls.js +2 -0
  717. package/dist/providers/file-repair-policy.d.ts +1 -0
  718. package/dist/providers/file-repair-policy.js +2 -0
  719. package/dist/providers/gpu-arbiter.d.ts +159 -0
  720. package/dist/providers/gpu-arbiter.js +301 -0
  721. package/dist/providers/image-persister-contract.d.ts +15 -0
  722. package/dist/providers/image-persister-contract.js +1 -0
  723. package/dist/providers/llama-cpp/build-metadata.d.ts +13 -0
  724. package/dist/providers/llama-cpp/build-metadata.js +39 -0
  725. package/dist/providers/llama-cpp/build-provider.d.ts +66 -0
  726. package/dist/providers/llama-cpp/build-provider.js +1491 -0
  727. package/dist/providers/llama-cpp/cache-adapter.d.ts +242 -0
  728. package/dist/providers/llama-cpp/cache-adapter.js +689 -0
  729. package/dist/providers/llama-cpp/devices.d.ts +130 -0
  730. package/dist/providers/llama-cpp/devices.js +256 -0
  731. package/dist/providers/llama-cpp/disk-cache.d.ts +8 -0
  732. package/dist/providers/llama-cpp/disk-cache.js +112 -0
  733. package/dist/providers/llama-cpp/engine-flags.d.ts +181 -0
  734. package/dist/providers/llama-cpp/engine-flags.js +279 -0
  735. package/dist/providers/llama-cpp/gguf-metadata-async.d.ts +11 -0
  736. package/dist/providers/llama-cpp/gguf-metadata-async.js +180 -0
  737. package/dist/providers/llama-cpp/gguf-metadata-worker.d.ts +7 -0
  738. package/dist/providers/llama-cpp/gguf-metadata-worker.js +27 -0
  739. package/dist/providers/llama-cpp/gguf-metadata.d.ts +198 -0
  740. package/dist/providers/llama-cpp/gguf-metadata.js +615 -0
  741. package/dist/providers/llama-cpp/gguf-quantization-backfill.d.ts +32 -0
  742. package/dist/providers/llama-cpp/gguf-quantization-backfill.js +75 -0
  743. package/dist/providers/llama-cpp/index.d.ts +10 -0
  744. package/dist/providers/llama-cpp/index.js +13 -0
  745. package/dist/providers/llama-cpp/kv-cache-type.d.ts +118 -0
  746. package/dist/providers/llama-cpp/kv-cache-type.js +140 -0
  747. package/dist/providers/llama-cpp/log.d.ts +92 -0
  748. package/dist/providers/llama-cpp/log.js +280 -0
  749. package/dist/providers/llama-cpp/models.d.ts +389 -0
  750. package/dist/providers/llama-cpp/models.js +1011 -0
  751. package/dist/providers/llama-cpp/offload-planner.d.ts +339 -0
  752. package/dist/providers/llama-cpp/offload-planner.js +524 -0
  753. package/dist/providers/llama-cpp/provider.d.ts +493 -0
  754. package/dist/providers/llama-cpp/provider.js +862 -0
  755. package/dist/providers/llama-cpp/reasoning-launch.d.ts +7 -0
  756. package/dist/providers/llama-cpp/reasoning-launch.js +14 -0
  757. package/dist/providers/llama-cpp/spec-draft.d.ts +44 -0
  758. package/dist/providers/llama-cpp/spec-draft.js +44 -0
  759. package/dist/providers/llama-cpp/stdout-parser.d.ts +70 -0
  760. package/dist/providers/llama-cpp/stdout-parser.js +197 -0
  761. package/dist/providers/local-tool-call-salvage.d.ts +1 -0
  762. package/dist/providers/local-tool-call-salvage.js +2 -0
  763. package/dist/providers/local-turn-policy.d.ts +1 -0
  764. package/dist/providers/local-turn-policy.js +2 -0
  765. package/dist/providers/mlx/async-file-handoff.d.ts +11 -0
  766. package/dist/providers/mlx/async-file-handoff.js +25 -0
  767. package/dist/providers/mlx/build-provider.d.ts +65 -0
  768. package/dist/providers/mlx/build-provider.js +717 -0
  769. package/dist/providers/mlx/cache-adapter.d.ts +161 -0
  770. package/dist/providers/mlx/cache-adapter.js +445 -0
  771. package/dist/providers/mlx/chat-protocol.d.ts +48 -0
  772. package/dist/providers/mlx/chat-protocol.js +8 -0
  773. package/dist/providers/mlx/config-parser.d.ts +29 -0
  774. package/dist/providers/mlx/config-parser.js +81 -0
  775. package/dist/providers/mlx/engine-gate.d.ts +51 -0
  776. package/dist/providers/mlx/engine-gate.js +207 -0
  777. package/dist/providers/mlx/engine-hold.d.ts +41 -0
  778. package/dist/providers/mlx/engine-hold.js +59 -0
  779. package/dist/providers/mlx/engine-log-router.d.ts +84 -0
  780. package/dist/providers/mlx/engine-log-router.js +137 -0
  781. package/dist/providers/mlx/engine-stats-sampler.d.ts +36 -0
  782. package/dist/providers/mlx/engine-stats-sampler.js +59 -0
  783. package/dist/providers/mlx/index.d.ts +10 -0
  784. package/dist/providers/mlx/index.js +10 -0
  785. package/dist/providers/mlx/log.d.ts +55 -0
  786. package/dist/providers/mlx/log.js +157 -0
  787. package/dist/providers/mlx/model-geometry.d.ts +35 -0
  788. package/dist/providers/mlx/model-geometry.js +118 -0
  789. package/dist/providers/mlx/models.d.ts +289 -0
  790. package/dist/providers/mlx/models.js +1079 -0
  791. package/dist/providers/mlx/provider.d.ts +404 -0
  792. package/dist/providers/mlx/provider.js +3017 -0
  793. package/dist/providers/mlx/python/cache_persist.py +348 -0
  794. package/dist/providers/mlx/python/cache_seed.py +402 -0
  795. package/dist/providers/mlx/python/gezel_mlx_server.py +4491 -0
  796. package/dist/providers/mlx/python/lfm2_compat.py +55 -0
  797. package/dist/providers/mlx/python/qwen3_5_text_compat.py +60 -0
  798. package/dist/providers/mlx/python/qwen4_ple.py +159 -0
  799. package/dist/providers/mlx/python/spec_decode.py +775 -0
  800. package/dist/providers/mlx/python/template_stability.py +133 -0
  801. package/dist/providers/mlx/python/think_budget.py +113 -0
  802. package/dist/providers/mlx/python/tool_args_json.py +297 -0
  803. package/dist/providers/mlx/python/tool_call_stream.py +265 -0
  804. package/dist/providers/mlx/python/tool_grammar.py +794 -0
  805. package/dist/providers/mlx/python/vision_inputs.py +64 -0
  806. package/dist/providers/mlx/python/wave_policy.py +147 -0
  807. package/dist/providers/mlx/reasoning-stream.d.ts +85 -0
  808. package/dist/providers/mlx/reasoning-stream.js +196 -0
  809. package/dist/providers/mlx/request-shape.d.ts +34 -0
  810. package/dist/providers/mlx/request-shape.js +42 -0
  811. package/dist/providers/mlx/runtime-diagnostics.d.ts +29 -0
  812. package/dist/providers/mlx/runtime-diagnostics.js +162 -0
  813. package/dist/providers/mlx/spec-drafter.d.ts +25 -0
  814. package/dist/providers/mlx/spec-drafter.js +73 -0
  815. package/dist/providers/mlx/stdout-parser.d.ts +60 -0
  816. package/dist/providers/mlx/stdout-parser.js +254 -0
  817. package/dist/providers/mlx/textual-tool-call-salvage.d.ts +46 -0
  818. package/dist/providers/mlx/textual-tool-call-salvage.js +396 -0
  819. package/dist/providers/mlx/tool-call-protocol.d.ts +65 -0
  820. package/dist/providers/mlx/tool-call-protocol.js +140 -0
  821. package/dist/providers/mlx/tool-call-stripper.d.ts +68 -0
  822. package/dist/providers/mlx/tool-call-stripper.js +153 -0
  823. package/dist/providers/mlx/tool-image-retention.d.ts +23 -0
  824. package/dist/providers/mlx/tool-image-retention.js +43 -0
  825. package/dist/providers/mlx/turn-telemetry.d.ts +22 -0
  826. package/dist/providers/mlx/turn-telemetry.js +45 -0
  827. package/dist/providers/mlx/venv.d.ts +91 -0
  828. package/dist/providers/mlx/venv.js +111 -0
  829. package/dist/providers/mlx/vision-mode.d.ts +92 -0
  830. package/dist/providers/mlx/vision-mode.js +187 -0
  831. package/dist/providers/mlx/vision.d.ts +2 -0
  832. package/dist/providers/mlx/vision.js +12 -0
  833. package/dist/providers/mlx/wire-transcript.d.ts +14 -0
  834. package/dist/providers/mlx/wire-transcript.js +43 -0
  835. package/dist/providers/native/capacity-broker.d.ts +812 -0
  836. package/dist/providers/native/capacity-broker.js +1058 -0
  837. package/dist/providers/native/capacity-budget.d.ts +133 -0
  838. package/dist/providers/native/capacity-budget.js +265 -0
  839. package/dist/providers/native/device-capacity-ledger.d.ts +31 -0
  840. package/dist/providers/native/device-capacity-ledger.js +196 -0
  841. package/dist/providers/native/device-capacity.d.ts +84 -0
  842. package/dist/providers/native/device-capacity.js +431 -0
  843. package/dist/providers/native/engine-api-key.d.ts +57 -0
  844. package/dist/providers/native/engine-api-key.js +72 -0
  845. package/dist/providers/native/engine-key.d.ts +18 -0
  846. package/dist/providers/native/engine-key.js +41 -0
  847. package/dist/providers/native/engine-router.d.ts +145 -0
  848. package/dist/providers/native/engine-router.js +191 -0
  849. package/dist/providers/native/gpu-panic-guard.d.ts +54 -0
  850. package/dist/providers/native/gpu-panic-guard.js +59 -0
  851. package/dist/providers/native/inference.d.ts +33 -0
  852. package/dist/providers/native/inference.js +49 -0
  853. package/dist/providers/native/local-engine-runtime.d.ts +412 -0
  854. package/dist/providers/native/local-engine-runtime.js +1714 -0
  855. package/dist/providers/native/measured-budget.d.ts +32 -0
  856. package/dist/providers/native/measured-budget.js +54 -0
  857. package/dist/providers/native/port.d.ts +11 -0
  858. package/dist/providers/native/port.js +29 -0
  859. package/dist/providers/native/provider-pool.d.ts +474 -0
  860. package/dist/providers/native/provider-pool.js +1166 -0
  861. package/dist/providers/native/supervisor.d.ts +503 -0
  862. package/dist/providers/native/supervisor.js +1466 -0
  863. package/dist/providers/observation-context.d.ts +16 -0
  864. package/dist/providers/observation-context.js +1 -0
  865. package/dist/providers/openai-compatible/sse.d.ts +1 -0
  866. package/dist/providers/openai-compatible/sse.js +2 -0
  867. package/dist/providers/patient-fetch.d.ts +36 -0
  868. package/dist/providers/patient-fetch.js +44 -0
  869. package/dist/providers/project-macro-loop-bail.d.ts +7 -0
  870. package/dist/providers/project-macro-loop-bail.js +21 -0
  871. package/dist/providers/prose-document-salvage.d.ts +1 -0
  872. package/dist/providers/prose-document-salvage.js +2 -0
  873. package/dist/providers/provider-disposal.d.ts +1 -0
  874. package/dist/providers/provider-disposal.js +2 -0
  875. package/dist/providers/queue.d.ts +15 -0
  876. package/dist/providers/queue.js +23 -0
  877. package/dist/providers/ramble-abort-message.d.ts +1 -0
  878. package/dist/providers/ramble-abort-message.js +2 -0
  879. package/dist/providers/ramble-detector.d.ts +1 -0
  880. package/dist/providers/ramble-detector.js +2 -0
  881. package/dist/providers/reasoning-depth.d.ts +1 -0
  882. package/dist/providers/reasoning-depth.js +2 -0
  883. package/dist/providers/required-input-reads.d.ts +1 -0
  884. package/dist/providers/required-input-reads.js +2 -0
  885. package/dist/providers/session-defaults.d.ts +13 -0
  886. package/dist/providers/session-defaults.js +49 -0
  887. package/dist/providers/session-hooks.d.ts +26 -0
  888. package/dist/providers/session-hooks.js +1 -0
  889. package/dist/providers/streaming-session.d.ts +1 -0
  890. package/dist/providers/streaming-session.js +2 -0
  891. package/dist/providers/terminal-tool-policy.d.ts +1 -0
  892. package/dist/providers/terminal-tool-policy.js +2 -0
  893. package/dist/providers/tool-arg-schema-coercion.d.ts +1 -0
  894. package/dist/providers/tool-arg-schema-coercion.js +2 -0
  895. package/dist/providers/tool-executor.d.ts +12 -0
  896. package/dist/providers/tool-executor.js +20 -0
  897. package/dist/providers/tool-failure-tracker.d.ts +1 -0
  898. package/dist/providers/tool-failure-tracker.js +2 -0
  899. package/dist/providers/tool-repeat-tracker.d.ts +1 -0
  900. package/dist/providers/tool-repeat-tracker.js +2 -0
  901. package/dist/providers/turn-timeout.d.ts +1 -0
  902. package/dist/providers/turn-timeout.js +1 -0
  903. package/dist/providers/types.d.ts +834 -0
  904. package/dist/providers/types.js +42 -0
  905. package/dist/providers/usage-builder.d.ts +1 -0
  906. package/dist/providers/usage-builder.js +2 -0
  907. package/dist/providers/vision-capability.d.ts +109 -0
  908. package/dist/providers/vision-capability.js +137 -0
  909. package/dist/python/mlx-runtime-status-bus.d.ts +39 -0
  910. package/dist/python/mlx-runtime-status-bus.js +27 -0
  911. package/dist/python/uv-runtime.d.ts +176 -0
  912. package/dist/python/uv-runtime.js +492 -0
  913. package/dist/relevance/install.d.ts +28 -0
  914. package/dist/relevance/install.js +114 -0
  915. package/dist/relevance/manager.d.ts +79 -0
  916. package/dist/relevance/manager.js +211 -0
  917. package/dist/relevance/registry.d.ts +11 -0
  918. package/dist/relevance/registry.js +158 -0
  919. package/dist/relevance/relevance-core.d.ts +67 -0
  920. package/dist/relevance/relevance-core.js +189 -0
  921. package/dist/relevance/relevance-model.d.ts +42 -0
  922. package/dist/relevance/relevance-model.js +292 -0
  923. package/dist/relevance/relevance-worker.d.ts +20 -0
  924. package/dist/relevance/relevance-worker.js +57 -0
  925. package/dist/relevance/settings.d.ts +30 -0
  926. package/dist/relevance/settings.js +81 -0
  927. package/dist/remotes/identity.d.ts +121 -0
  928. package/dist/remotes/identity.js +348 -0
  929. package/dist/remotes/pinned-fetch.d.ts +45 -0
  930. package/dist/remotes/pinned-fetch.js +193 -0
  931. package/dist/remotes/types.d.ts +54 -0
  932. package/dist/remotes/types.js +1 -0
  933. package/dist/runtime-lock.d.ts +29 -0
  934. package/dist/runtime-lock.js +85 -0
  935. package/dist/search/relevance-stage.d.ts +81 -0
  936. package/dist/search/relevance-stage.js +177 -0
  937. package/dist/secrets/types.d.ts +63 -0
  938. package/dist/secrets/types.js +64 -0
  939. package/dist/speech.d.ts +1 -0
  940. package/dist/speech.js +1 -0
  941. package/dist/system/darwin-memory.d.ts +26 -0
  942. package/dist/system/darwin-memory.js +81 -0
  943. package/dist/system/gezel-process-memory.d.ts +55 -0
  944. package/dist/system/gezel-process-memory.js +156 -0
  945. package/dist/system/memory.d.ts +154 -0
  946. package/dist/system/memory.js +501 -0
  947. package/dist/transformers-cache.d.ts +112 -0
  948. package/dist/transformers-cache.js +392 -0
  949. package/dist/utils/disk-space.d.ts +55 -0
  950. package/dist/utils/disk-space.js +72 -0
  951. package/dist/utils/download-common.d.ts +138 -0
  952. package/dist/utils/download-common.js +196 -0
  953. package/dist/utils/download-with-retry.d.ts +85 -0
  954. package/dist/utils/download-with-retry.js +522 -0
  955. package/dist/utils/extract-zip.d.ts +22 -0
  956. package/dist/utils/extract-zip.js +103 -0
  957. package/dist/utils/retire-model-worker.d.ts +15 -0
  958. package/dist/utils/retire-model-worker.js +24 -0
  959. package/dist/utils/service-worker-entry.d.ts +59 -0
  960. package/dist/utils/service-worker-entry.js +69 -0
  961. package/dist/utils/xet-download.d.ts +40 -0
  962. package/dist/utils/xet-download.js +526 -0
  963. package/dist/utils/xet.d.ts +86 -0
  964. package/dist/utils/xet.js +201 -0
  965. package/package.json +103 -3
  966. package/scripts/embedding-packaging.cjs +264 -0
  967. 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
+ }