@bendyline/gezel-inference 0.0.0-stage → 0.1.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,1011 @@
1
+ /**
2
+ * Local llama.cpp model storage + install pipeline.
3
+ *
4
+ * Storage layout:
5
+ *
6
+ * <home>/engines/llama-cpp/
7
+ * └── models/
8
+ * └── <model-id>/
9
+ * ├── manifest.json (snapshot of catalog metadata + install info)
10
+ * └── <weights>.gguf (the actual weights, original filename preserved)
11
+ *
12
+ * Install flow:
13
+ * 1. Look up the chat-model entry in the catalog.
14
+ * 2. Stream the GGUF from
15
+ * `huggingface.co/<repo>/resolve/<revision>/<filename>` (the pinned
16
+ * commit SHA, or `main` for legacy manifests) to a `.partial`
17
+ * file, hashing as we go.
18
+ * 3. Verify the computed sha256 against the manifest's expected value.
19
+ * 4. Run the GGUF header parser to extract context window + chat-template
20
+ * presence. Surface a non-fatal warning when `tokenizer.chat_template`
21
+ * is missing — llama-server otherwise silently uses the wrong
22
+ * template (the gemma4 footgun the Phase-0 spike caught).
23
+ * 5. Atomically rename `.partial` → final filename and write
24
+ * `manifest.json`.
25
+ *
26
+ * Delete flow:
27
+ * - Remove the per-model directory in one shot.
28
+ *
29
+ * Resolve-current flow:
30
+ * - Pick the first installed model (alphabetical) when ChatManager
31
+ * wants a default model path. Phase 2 keeps "current" implicit; a
32
+ * proper picker lives in the UI.
33
+ */
34
+ import { createHash } from 'node:crypto';
35
+ import { createReadStream } from 'node:fs';
36
+ import { mkdir, readFile, readdir, rename, rm, stat, writeFile } from 'node:fs/promises';
37
+ import { basename, join, resolve } from 'node:path';
38
+ import { createLogger } from '@bendyline/gezel';
39
+ import { listBundleModelFiles, publishStagedModel, safeBundleModelPath, } from '../../models/bundle-storage.js';
40
+ import { evaluateCatalogDrift } from '../../models/catalog-drift.js';
41
+ import { catalogPayloadFingerprint, describeCatalogPayload, } from '../../models/catalog-payload-identity.js';
42
+ import { MODEL_HASH_READ_BUFFER_BYTES, assertModelStorePathSafe, findModelRoot, findRenamedModelId, hashModelPayloadFiles, inspectModelDirectory, listIncompleteModelDownloads, listOverlayModelIds, makeSharedModelReadable, modelExistsOnlyReadOnly, modelStorageRoots, pruneModelPayloadFiles, readOnlyModelError, removeModelDir, verifyReadOnlyModelPayload, } from '../../models/storage-roots.js';
43
+ import { checkDiskSpace, describeDiskShortfall } from '../../utils/disk-space.js';
44
+ import { downloadWithRetry } from '../../utils/download-with-retry.js';
45
+ import { ggufQuantizationTag, readGgufSummary } from './gguf-metadata.js';
46
+ import { backfillGgufQuantization } from './gguf-quantization-backfill.js';
47
+ /**
48
+ * How often to emit a `progress` event during a download. Anything
49
+ * shorter than 250ms wastes CPU on JSON serialization for the SSE
50
+ * stream; anything longer feels laggy in the UI's progress bar.
51
+ */
52
+ const PROGRESS_INTERVAL_MS = 250;
53
+ const log = createLogger('models');
54
+ export class LlamaCppModelManager {
55
+ modelsRoot;
56
+ storageRoots;
57
+ catalog;
58
+ fetchImpl;
59
+ engine;
60
+ onInstalled;
61
+ /**
62
+ * In-flight installs. `install()` registers an entry on first yield
63
+ * and clears it in the iterator's `finally` block, so consumers
64
+ * (HTTP `/active-installs`, polling React UI) always see the live
65
+ * subset regardless of which code path drove the install.
66
+ */
67
+ activeInstalls = new Map();
68
+ /**
69
+ * Model directories we've already warned about skipping. `listInstalled`
70
+ * runs on every picker/settings poll; a broken directory should be loud
71
+ * exactly once per process, not once per poll.
72
+ */
73
+ skipWarned = new Set();
74
+ constructor(opts) {
75
+ this.engine = opts.engine ?? 'llama-cpp';
76
+ this.storageRoots = modelStorageRoots({ home: opts.home, engine: this.engine });
77
+ this.modelsRoot = this.storageRoots.writableRoot;
78
+ this.catalog = opts.catalog;
79
+ this.fetchImpl = opts.fetchImpl ?? fetch;
80
+ this.onInstalled = opts.onInstalled;
81
+ }
82
+ /**
83
+ * The catalog source block this manager downloads from — `ds4` for the
84
+ * DwarfStar engine, `llamaCpp` otherwise. Cast to the llama.cpp source
85
+ * shape. The common downloader accepts the union directly so engine-specific
86
+ * sidecars (`mmproj` versus `visionEncoder`) keep their honest catalog names.
87
+ */
88
+ srcBlock(manifest) {
89
+ return this.engine === 'ds4' ? manifest.ds4 : manifest.llamaCpp;
90
+ }
91
+ /**
92
+ * Snapshot of installs currently running. Used by the Settings UI to
93
+ * mirror background bootstrap installs into its progress view — the
94
+ * first-run download fires server-side via direct method call (not
95
+ * the HTTP install route), so the React component has no live SSE
96
+ * stream to consume; polling this surface fills the gap.
97
+ */
98
+ getActiveInstalls() {
99
+ // Return shallow copies so the caller can't mutate our state.
100
+ return Array.from(this.activeInstalls.values()).map((entry) => ({ ...entry }));
101
+ }
102
+ /**
103
+ * List installed models in alphabetical order. Tolerates malformed or
104
+ * partial directories — they're skipped, not surfaced as errors.
105
+ */
106
+ async listInstalled() {
107
+ const entries = await listOverlayModelIds(this.storageRoots);
108
+ const out = [];
109
+ for (const id of entries) {
110
+ const summary = await this.loadInstalled(id);
111
+ if (!summary) {
112
+ this.warnSkip(id, 'no readable manifest.json (incomplete or interrupted download?)');
113
+ continue;
114
+ }
115
+ // Drift flag: does the catalog now describe different weights than the
116
+ // ones on disk? Best-effort — a catalog miss (third-party / removed
117
+ // entry) leaves it un-flagged.
118
+ const status = await this.evaluateDrift(id, summary).catch(() => null);
119
+ if (status?.updateAvailable) {
120
+ summary.updateAvailable = true;
121
+ if (status.availableVersion)
122
+ summary.availableVersion = status.availableVersion;
123
+ if (status.reason)
124
+ summary.updateReason = status.reason;
125
+ }
126
+ out.push(summary);
127
+ }
128
+ out.sort((a, b) => a.name.localeCompare(b.name));
129
+ return out;
130
+ }
131
+ /**
132
+ * List incomplete downloads for this engine — interrupted or unverified
133
+ * downloads that hold bytes on disk but have no `manifest.json`, so they
134
+ * never appear in {@link listInstalled}. Each is tagged `resumable` when
135
+ * its id still resolves to a catalog entry this engine can source, so the
136
+ * UI can offer resume (re-install picks up from the `.partial`) vs
137
+ * delete-only for stale ids. In-flight installs are excluded.
138
+ */
139
+ async listIncomplete() {
140
+ const activeIds = new Set(this.activeInstalls.keys());
141
+ const rows = await listIncompleteModelDownloads({ writableRoot: this.modelsRoot, activeIds });
142
+ const out = [];
143
+ for (const row of rows) {
144
+ let resumable = false;
145
+ let name;
146
+ if (isSafeId(row.id)) {
147
+ const detail = await this.catalog.get('chat-model', row.id).catch(() => null);
148
+ if (detail && detail.manifest.kind === 'chat-model' && this.srcBlock(detail.manifest)) {
149
+ resumable = true;
150
+ name = detail.manifest.name;
151
+ }
152
+ }
153
+ out.push({ ...row, resumable, ...(name ? { name } : {}) });
154
+ }
155
+ return out;
156
+ }
157
+ /**
158
+ * Model directories that do have a manifest, but whose metadata cannot be
159
+ * loaded by this build. These used to disappear from every inventory
160
+ * surface: `listInstalled()` correctly refused to run them, while the
161
+ * incomplete-download scan correctly ignored anything with a manifest.
162
+ * Keep that safety boundary, but return a management-only row so Settings
163
+ * can update a known catalog id or explicitly remove the held bytes.
164
+ */
165
+ async listUnrecognized() {
166
+ const rows = [];
167
+ for (const id of await listOverlayModelIds(this.storageRoots)) {
168
+ if (!isSafeId(id))
169
+ continue;
170
+ const root = await findModelRoot(this.storageRoots, id);
171
+ // Manifestless directories belong to listIncomplete(), not this state.
172
+ if (!root)
173
+ continue;
174
+ if (await this.loadInstalled(id))
175
+ continue;
176
+ const profile = await inspectModelDirectory(join(root, id));
177
+ if (!profile || profile.bytes === 0)
178
+ continue;
179
+ const raw = await readFile(join(root, id, 'manifest.json'), 'utf8').catch(() => null);
180
+ let legacyName;
181
+ let reason = "Gezel couldn't read this model's metadata.";
182
+ if (raw !== null) {
183
+ try {
184
+ const parsed = JSON.parse(raw);
185
+ if (typeof parsed.name === 'string' && parsed.name.trim())
186
+ legacyName = parsed.name;
187
+ reason =
188
+ typeof parsed.filename === 'string' && typeof parsed.weightsFilename !== 'string'
189
+ ? 'This model was installed by an older version of Gezel and its metadata needs updating.'
190
+ : 'This model metadata is incomplete or does not match the current format.';
191
+ }
192
+ catch {
193
+ reason = "This model's metadata file is not valid JSON.";
194
+ }
195
+ }
196
+ const detail = await this.catalog.get('chat-model', id).catch(() => null);
197
+ const catalogManifest = detail?.manifest.kind === 'chat-model' ? detail.manifest : undefined;
198
+ const canUpdate = Boolean(catalogManifest && this.srcBlock(catalogManifest));
199
+ const name = catalogManifest?.name ?? legacyName;
200
+ rows.push({
201
+ id,
202
+ ...(name ? { name } : {}),
203
+ bytes: profile.bytes,
204
+ updatedAt: profile.updatedAt,
205
+ reason,
206
+ canUpdate,
207
+ ...(resolve(root) !== resolve(this.storageRoots.writableRoot) ? { readOnly: true } : {}),
208
+ });
209
+ }
210
+ rows.sort((a, b) => b.bytes - a.bytes);
211
+ return rows;
212
+ }
213
+ /**
214
+ * Path of the first installed model, or null when none exist. Phase 2
215
+ * uses this to pick a default `--model` arg for the supervised
216
+ * llama-server when the user hasn't explicitly chosen one. A "default
217
+ * model" UI lives in Phase 3.
218
+ */
219
+ async resolveDefaultModelPath() {
220
+ const model = await this.resolveDefaultModel();
221
+ return model?.weightsPath ?? null;
222
+ }
223
+ /**
224
+ * Summary of the first installed model (or null). Same fall-through
225
+ * rule as {@link resolveDefaultModelPath}; returns the full summary
226
+ * so callers like `buildLlamaCppProvider` can pick up the manifest's
227
+ * `contextWindow` along with the path.
228
+ */
229
+ async resolveDefaultModel() {
230
+ const models = await this.listInstalled();
231
+ return models[0] ?? null;
232
+ }
233
+ /**
234
+ * Path of a specific installed model, or null when not installed.
235
+ * Used by ChatManager when the user has picked a model explicitly.
236
+ */
237
+ async resolveModelPath(id) {
238
+ const summary = await this.loadInstalled(id);
239
+ return summary?.weightsPath ?? null;
240
+ }
241
+ /**
242
+ * Full summary for a specific installed model, or null when not
243
+ * installed. Used when the user has pinned a default model via
244
+ * `config.defaultModel['llama-cpp']` — `buildLlamaCppProvider`
245
+ * needs the `contextWindow` to set `--ctx-size` correctly.
246
+ */
247
+ async resolveModel(id) {
248
+ return this.loadInstalled(id);
249
+ }
250
+ /**
251
+ * Whether a genuinely newer build of one installed model exists. Null when
252
+ * the id isn't installed for this engine. Shared with the chat manager's
253
+ * per-session staleness notice so a user is never told to re-download for a
254
+ * change that only touched metadata.
255
+ */
256
+ async getUpdateStatus(id) {
257
+ const summary = await this.loadInstalled(id);
258
+ if (!summary)
259
+ return null;
260
+ return this.evaluateDrift(id, summary).catch(() => ({ updateAvailable: false }));
261
+ }
262
+ /**
263
+ * Compare one installed copy against the live catalog. The catalog lookup
264
+ * runs for every model on every inventory poll; the manifest re-read only
265
+ * happens for the few whose version actually moved.
266
+ */
267
+ async evaluateDrift(id, summary) {
268
+ const installedVersion = summary.catalogVersion;
269
+ if (!installedVersion)
270
+ return { updateAvailable: false };
271
+ const detail = await this.catalog.get('chat-model', id).catch(() => null);
272
+ if (!detail || detail.manifest.kind !== 'chat-model')
273
+ return { updateAvailable: false };
274
+ if (detail.manifest.version === installedVersion)
275
+ return { updateAvailable: false };
276
+ const root = await findModelRoot(this.storageRoots, id);
277
+ if (!root)
278
+ return { updateAvailable: false };
279
+ const modelDir = join(root, id);
280
+ const parsed = await readFile(join(modelDir, 'manifest.json'), 'utf8')
281
+ .then((raw) => JSON.parse(raw))
282
+ .catch(() => null);
283
+ if (!parsed)
284
+ return { updateAvailable: false };
285
+ return evaluateCatalogDrift({
286
+ engine: this.engine,
287
+ id,
288
+ modelDir,
289
+ manifest: detail.manifest,
290
+ installedVersion,
291
+ installed: {
292
+ ...(parsed.huggingfaceRepo ? { huggingfaceRepo: parsed.huggingfaceRepo } : {}),
293
+ ...(parsed.payloadFingerprint ? { payloadFingerprint: parsed.payloadFingerprint } : {}),
294
+ ...(parsed.fileSha256 ? { fileSha256: parsed.fileSha256 } : {}),
295
+ },
296
+ healable: !summary.readOnly && !this.activeInstalls.has(id),
297
+ });
298
+ }
299
+ async delete(id) {
300
+ if (!isSafeId(id))
301
+ throw new Error(`refusing to delete with unsafe id: ${id}`);
302
+ if (await modelExistsOnlyReadOnly(this.storageRoots, id)) {
303
+ throw readOnlyModelError(id);
304
+ }
305
+ await removeModelDir(join(this.modelsRoot, id), this.modelsRoot);
306
+ }
307
+ /** Provider-owned snapshot used by the streaming `.gezmodel` exporter. */
308
+ async getModelBundleSource(id) {
309
+ if (!isSafeId(id))
310
+ throw new Error(`unsafe model id: ${id}`);
311
+ const summary = await this.loadInstalled(id);
312
+ if (!summary)
313
+ throw new Error(`model "${id}" is not available locally for ${this.engine}`);
314
+ const root = await findModelRoot(this.storageRoots, id);
315
+ if (!root)
316
+ throw new Error(`model "${id}" is not available locally for ${this.engine}`);
317
+ const modelDir = join(root, id);
318
+ const installedManifest = JSON.parse(await readFile(join(modelDir, 'manifest.json'), 'utf8'));
319
+ return {
320
+ id,
321
+ name: summary.name,
322
+ modelDir,
323
+ installedManifest,
324
+ modelFiles: await listBundleModelFiles(modelDir),
325
+ ...(summary.catalogVersion ? { catalogVersion: summary.catalogVersion } : {}),
326
+ };
327
+ }
328
+ /**
329
+ * Validate provider-specific invariants, write the local install manifest,
330
+ * and atomically publish a security-scanned staged bundle.
331
+ */
332
+ async importModelBundle(opts) {
333
+ if (!isSafeId(opts.id))
334
+ throw new Error(`unsafe model id: ${opts.id}`);
335
+ const parsed = opts.installedManifest;
336
+ if (parsed.id !== opts.id || !parsed.name || !parsed.weightsFilename || !parsed.installedAt) {
337
+ throw new Error('installed manifest does not describe the bundled model');
338
+ }
339
+ const files = await listBundleModelFiles(opts.stagedModelDir);
340
+ if (files.length === 0 || files.some((file) => !file.toLowerCase().endsWith('.gguf'))) {
341
+ throw new Error(`${this.engine} bundles may contain only GGUF model files`);
342
+ }
343
+ if (!files.includes(parsed.weightsFilename)) {
344
+ throw new Error(`installed manifest references missing weights: ${parsed.weightsFilename}`);
345
+ }
346
+ if (parsed.shards?.some((shard) => !files.includes(shard.filename))) {
347
+ throw new Error('installed manifest references a missing GGUF shard');
348
+ }
349
+ if (parsed.mmprojFilename && !files.includes(parsed.mmprojFilename)) {
350
+ throw new Error('installed manifest references a missing multimodal projector');
351
+ }
352
+ if (parsed.visionEncoderFilename && !files.includes(parsed.visionEncoderFilename)) {
353
+ throw new Error('installed manifest references a missing ds4 vision encoder');
354
+ }
355
+ if (parsed.draftModelFilename && !files.includes(parsed.draftModelFilename)) {
356
+ throw new Error('installed manifest references a missing speculative draft model');
357
+ }
358
+ // Parsing the GGUF header is the same final usability check a network
359
+ // install performs after checksum verification.
360
+ readGgufSummary(safeBundleModelPath(opts.stagedModelDir, parsed.weightsFilename));
361
+ const importedManifest = {
362
+ ...parsed,
363
+ fileSha256: await hashModelPayloadFiles(opts.stagedModelDir),
364
+ };
365
+ await writeFile(join(opts.stagedModelDir, 'manifest.json'), `${JSON.stringify(importedManifest, null, 2)}\n`, 'utf8');
366
+ await publishStagedModel({
367
+ modelsRoot: this.modelsRoot,
368
+ id: opts.id,
369
+ stagedModelDir: opts.stagedModelDir,
370
+ replace: opts.replace,
371
+ });
372
+ await makeSharedModelReadable(join(this.modelsRoot, opts.id));
373
+ try {
374
+ this.onInstalled?.({ engine: this.engine, id: opts.id });
375
+ }
376
+ catch {
377
+ // A post-install fitness hook is best-effort, as in the download path.
378
+ }
379
+ }
380
+ /**
381
+ * Install a model from the catalog. Yields progress / verifying /
382
+ * extracting-metadata / done events. Yields exactly one terminal
383
+ * event (`done` or `error`) and is safe to consume to completion.
384
+ *
385
+ * Existing weights at the target id are atomically replaced — the
386
+ * download writes to a `.partial` sibling and renames into place
387
+ * only after sha256 verification passes. Failed installs leave the
388
+ * previous weights untouched.
389
+ */
390
+ async *install(catalogId, options) {
391
+ const skipSha = options?.skipSha === true;
392
+ // Default ON — see `planDownloads`. ds4 passes `false` because it has no
393
+ // llama.cpp mmproj; its own `visionEncoder` remains mandatory and is not
394
+ // governed by this flag.
395
+ const includeMmproj = options?.includeMmproj !== false;
396
+ if (!isSafeId(catalogId)) {
397
+ yield { type: 'error', error: `unsafe catalog id: ${catalogId}` };
398
+ return;
399
+ }
400
+ // Two concurrent installs of the same catalog id would both write
401
+ // to the same `weights.gguf.partial` and produce a corrupt
402
+ // (sha-mismatched) file. Claim the slot SYNCHRONOUSLY (before any
403
+ // `await`) so a parallel call observing `has(...) === false` and
404
+ // entering the same window can't slip in between our check and
405
+ // set. The placeholder snapshot is filled in once the catalog
406
+ // lookup succeeds. Hits when the first-run bootstrap and the
407
+ // Home banner's limbo recovery fire on the same boot.
408
+ if (this.activeInstalls.has(catalogId)) {
409
+ yield {
410
+ type: 'error',
411
+ error: `install for "${catalogId}" is already in progress`,
412
+ };
413
+ return;
414
+ }
415
+ const tracked = {
416
+ catalogId,
417
+ bytesWritten: 0,
418
+ totalBytes: 0,
419
+ phase: 'downloading',
420
+ startedAt: new Date().toISOString(),
421
+ };
422
+ this.activeInstalls.set(catalogId, tracked);
423
+ try {
424
+ const detail = await this.catalog.get('chat-model', catalogId);
425
+ if (!detail || detail.manifest.kind !== 'chat-model') {
426
+ yield { type: 'error', error: `chat-model "${catalogId}" not in catalog` };
427
+ return;
428
+ }
429
+ const manifest = detail.manifest;
430
+ const installSrc = this.srcBlock(manifest);
431
+ if (!installSrc) {
432
+ yield {
433
+ type: 'error',
434
+ error: `chat-model "${catalogId}" has no ${this.engine} source`,
435
+ };
436
+ return;
437
+ }
438
+ tracked.totalBytes = installSrc.approxSizeBytes;
439
+ yield* this.runInstall(catalogId, manifest, tracked, skipSha, includeMmproj);
440
+ }
441
+ finally {
442
+ this.activeInstalls.delete(catalogId);
443
+ }
444
+ }
445
+ /**
446
+ * Inner install loop. Splitting it out lets {@link install} wrap the
447
+ * generator in a `try/finally` that clears the active-install
448
+ * registration on every exit path, including caller break/throw —
449
+ * the equivalent inline construction would require interleaving the
450
+ * cleanup with each early `return` and silently rot.
451
+ */
452
+ async *runInstall(catalogId, manifest, tracked, skipSha, includeMmproj) {
453
+ const src = this.srcBlock(manifest);
454
+ if (!src) {
455
+ yield { type: 'error', error: `chat-model "${catalogId}" has no ${this.engine} source` };
456
+ return;
457
+ }
458
+ const itemDir = join(this.modelsRoot, catalogId);
459
+ await mkdir(this.modelsRoot, { recursive: true });
460
+ await assertModelStorePathSafe(this.modelsRoot, itemDir);
461
+ await mkdir(itemDir, { recursive: true });
462
+ await assertModelStorePathSafe(this.modelsRoot, itemDir);
463
+ const plan = planDownloads(src, includeMmproj);
464
+ if (plan.length === 0) {
465
+ yield {
466
+ type: 'error',
467
+ error: `chat-model "${catalogId}" ${this.engine} source has neither filename nor shards`,
468
+ };
469
+ return;
470
+ }
471
+ const totalPlanned = plan.reduce((sum, e) => sum + e.sizeBytes, 0) || src.approxSizeBytes;
472
+ tracked.totalBytes = totalPlanned;
473
+ // sha256 of each verified file, keyed by its final relative path (flat,
474
+ // since planDownloads uses basename). Reused to build the fileSha256 map
475
+ // after publish so we don't re-hash the whole payload from disk a second
476
+ // time. `actual` (not the catalog hash) is stored so the skipSha path
477
+ // still records the true on-disk identity.
478
+ const verifiedDigests = {};
479
+ // Files this update doesn't have to fetch because the copy on disk is
480
+ // already the copy the catalog pins. They count as completed bytes from
481
+ // the start, keep their digests, and are left untouched by the publish
482
+ // rename below.
483
+ const reusable = await this.planReusableFiles(itemDir, plan);
484
+ let bytesCompleted = 0;
485
+ for (const entry of plan) {
486
+ const sha = reusable.get(entry.destFilename);
487
+ if (!sha)
488
+ continue;
489
+ verifiedDigests[entry.destFilename] = sha;
490
+ bytesCompleted += entry.sizeBytes;
491
+ }
492
+ if (reusable.size > 0) {
493
+ log.info(`[models] [${this.engine}] "${catalogId}": ${reusable.size} of ${plan.length} file(s) already match the catalog and will not be downloaded`);
494
+ tracked.bytesWritten = bytesCompleted;
495
+ }
496
+ const toFetch = plan.filter((entry) => !reusable.has(entry.destFilename));
497
+ // Preflight the disk before writing a byte. ds4 GGUFs run to 200+ GiB, so
498
+ // discovering ENOSPC at 95% costs hours and leaves a `.partial` occupying
499
+ // the disk it just filled. Only what we actually have to fetch is charged,
500
+ // less any `.partial` already holding part of it, so a resumed install
501
+ // isn't refused for space it already holds. A file being REPLACED is
502
+ // charged in full: its `.partial` lives beside the old copy and the old
503
+ // copy is only deleted at publish, so the update transiently needs room
504
+ // for both.
505
+ const remainingBytes = Math.max(0, toFetch.reduce((sum, e) => sum + e.sizeBytes, 0) -
506
+ (await partialBytesOnDisk(itemDir, toFetch)));
507
+ const space = await checkDiskSpace(itemDir, remainingBytes);
508
+ if (!space.ok) {
509
+ yield { type: 'error', error: describeDiskShortfall(space, manifest.name) };
510
+ return;
511
+ }
512
+ for (let i = 0; i < plan.length; i++) {
513
+ const entry = plan[i];
514
+ if (!entry)
515
+ continue;
516
+ if (reusable.has(entry.destFilename)) {
517
+ yield { type: 'progress', bytesWritten: bytesCompleted, totalBytes: totalPlanned };
518
+ continue;
519
+ }
520
+ const destPath = join(itemDir, entry.destFilename);
521
+ const tmpPath = `${destPath}.partial`;
522
+ // Pin to this payload's catalog revision when present. A model-matched
523
+ // vision encoder may live in a different repository from the language
524
+ // GGUF and therefore carries its own repo + revision. Fall back to the
525
+ // parent source and finally `main` for legacy manifests.
526
+ const repo = entry.huggingfaceRepo ?? src.huggingfaceRepo;
527
+ const ref = entry.revision ?? src.revision ?? 'main';
528
+ const url = `https://huggingface.co/${repo}/resolve/${encodeURIComponent(ref)}/${entry.repoPath.split('/').map(encodeURIComponent).join('/')}?download=true`;
529
+ const dlGen = downloadWithRetry({
530
+ url,
531
+ destPath,
532
+ approxSizeBytes: entry.sizeBytes,
533
+ fetchImpl: this.fetchImpl,
534
+ });
535
+ let entryBytesWritten = 0;
536
+ let inlineSha;
537
+ while (true) {
538
+ const step = await dlGen.next();
539
+ if (step.done) {
540
+ if (step.value.kind === 'aborted') {
541
+ yield { type: 'error', error: 'download aborted' };
542
+ return;
543
+ }
544
+ if (step.value.kind === 'error') {
545
+ yield {
546
+ type: 'error',
547
+ error: plan.length > 1
548
+ ? `shard ${i + 1}/${plan.length} (${entry.destFilename}): ${step.value.error}`
549
+ : step.value.error,
550
+ };
551
+ return;
552
+ }
553
+ entryBytesWritten = step.value.bytesWritten || entryBytesWritten;
554
+ inlineSha = step.value.sha256;
555
+ break;
556
+ }
557
+ const ev = step.value;
558
+ if (ev.type === 'progress') {
559
+ entryBytesWritten = ev.bytesWritten;
560
+ tracked.bytesWritten = bytesCompleted + entryBytesWritten;
561
+ yield {
562
+ type: 'progress',
563
+ bytesWritten: bytesCompleted + entryBytesWritten,
564
+ totalBytes: totalPlanned,
565
+ };
566
+ }
567
+ else if (ev.type === 'retrying') {
568
+ yield {
569
+ type: 'retrying',
570
+ attempt: ev.attempt,
571
+ maxAttempts: ev.maxAttempts,
572
+ delayMs: ev.delayMs,
573
+ reason: ev.reason,
574
+ };
575
+ }
576
+ }
577
+ tracked.phase = 'verifying';
578
+ yield { type: 'verifying' };
579
+ // Prefer the digest the downloader computed inline while streaming —
580
+ // a clean single-pass (HTTP 200) transfer already hashed every byte,
581
+ // so re-reading a multi-GB file off disk just to hash it again is pure
582
+ // waste. Only fall back to the read-back pass when the inline digest
583
+ // is absent (a resumed/appended download, or the Xet path, where the
584
+ // hasher never saw the earlier bytes).
585
+ let actual = inlineSha;
586
+ if (!actual) {
587
+ const hasher = createHash('sha256');
588
+ await new Promise((resolve, reject) => {
589
+ // Big read buffer: a 64 KB stream starves inside the busy daemon
590
+ // event loop (~110k turns for a 7 GB file → 15+ min). See
591
+ // MODEL_HASH_READ_BUFFER_BYTES.
592
+ const stream = createReadStream(tmpPath, {
593
+ highWaterMark: MODEL_HASH_READ_BUFFER_BYTES,
594
+ });
595
+ stream.on('data', (chunk) => hasher.update(chunk));
596
+ stream.on('end', () => resolve());
597
+ stream.on('error', reject);
598
+ });
599
+ actual = hasher.digest('hex');
600
+ }
601
+ verifiedDigests[entry.destFilename] = actual;
602
+ if (actual !== entry.sha256.toLowerCase()) {
603
+ if (skipSha) {
604
+ // User opted in after a previous mismatch surfaced. Keep the
605
+ // `.partial` so the post-loop rename still has something to
606
+ // commit; just stop treating the catalog sha as authoritative.
607
+ }
608
+ else {
609
+ await rm(tmpPath, { force: true });
610
+ yield {
611
+ type: 'error',
612
+ error: `The file '${entry.destFilename}' on Hugging Face has changed since this version of Gezel was published. Expected sha256 ${entry.sha256}, got ${actual}.`,
613
+ mismatch: { file: entry.destFilename, expected: entry.sha256, actual },
614
+ };
615
+ return;
616
+ }
617
+ }
618
+ bytesCompleted += entryBytesWritten;
619
+ tracked.bytesWritten = bytesCompleted;
620
+ // Reset phase back to downloading for the next shard (or stays as
621
+ // verifying if this was the last; the next yielded phase is
622
+ // extracting-metadata below). Keeps the UI's phase pill accurate
623
+ // mid-iteration.
624
+ if (i < plan.length - 1)
625
+ tracked.phase = 'downloading';
626
+ }
627
+ // Parse metadata from the first weights entry (first shard for a
628
+ // sharded install, or the only file for single-file). Sidecars have
629
+ // their own GGUF headers but aren't what llama-server probes for the
630
+ // target model's context length / chat template.
631
+ tracked.phase = 'extracting-metadata';
632
+ yield { type: 'extracting-metadata' };
633
+ const firstWeights = plan.find((e) => e.role === 'weights');
634
+ if (!firstWeights) {
635
+ // Unreachable: planDownloads always emits at least one weights
636
+ // entry when the source is well-formed, and we already errored
637
+ // above when it returned [].
638
+ yield { type: 'error', error: 'internal: download plan has no weights entry' };
639
+ return;
640
+ }
641
+ // A reused file was never re-downloaded, so it has no `.partial` — read
642
+ // the published copy instead.
643
+ const firstWeightsPath = join(itemDir, firstWeights.destFilename);
644
+ const firstTmpPath = reusable.has(firstWeights.destFilename)
645
+ ? firstWeightsPath
646
+ : `${firstWeightsPath}.partial`;
647
+ let summary = null;
648
+ try {
649
+ summary = readGgufSummary(firstTmpPath);
650
+ }
651
+ catch (err) {
652
+ // Hash matched but the parser couldn't read the metadata — this
653
+ // should not happen with a real GGUF, but we don't want to leave
654
+ // downloaded-but-unusable files around. Bail loudly.
655
+ for (const entry of plan) {
656
+ await rm(`${join(itemDir, entry.destFilename)}.partial`, { force: true });
657
+ }
658
+ yield {
659
+ type: 'error',
660
+ error: `GGUF metadata parse failed (file is unusable): ${describeError(err)}`,
661
+ };
662
+ return;
663
+ }
664
+ // Atomic publish: rename each .partial into place. If a rename
665
+ // fails partway through, the renamed-already weights stay, the
666
+ // remaining .partials stay; the next install attempt resumes the
667
+ // rest. We bail loudly rather than try to roll back, because
668
+ // partial state is what we already accept on download failure.
669
+ try {
670
+ for (const entry of plan) {
671
+ if (reusable.has(entry.destFilename))
672
+ continue;
673
+ const finalPath = join(itemDir, entry.destFilename);
674
+ await rm(finalPath, { force: true });
675
+ await rename(`${finalPath}.partial`, finalPath);
676
+ }
677
+ }
678
+ catch (err) {
679
+ yield { type: 'error', error: `rename failed: ${describeError(err)}` };
680
+ return;
681
+ }
682
+ // Drop weights left behind by a previous install of this id that used a
683
+ // different quant/filename — otherwise the old GGUF lingers alongside the
684
+ // new one (tens of GB for one slot). Runs before the fileSha256 map is
685
+ // built so the map describes exactly the current payload.
686
+ const pruned = await pruneModelPayloadFiles(itemDir, new Set(plan.map((entry) => entry.destFilename)));
687
+ if (pruned.length > 0) {
688
+ log.info(`[models] [${this.engine}] pruned ${pruned.length} stale file(s) from "${catalogId}": ${pruned.join(', ')}`);
689
+ }
690
+ const weightsShards = plan.filter((e) => e.role === 'weights' || e.role === 'weights-shard');
691
+ const mmprojEntry = plan.find((e) => e.role === 'mmproj');
692
+ const visionEncoderEntry = plan.find((e) => e.role === 'vision-encoder');
693
+ const draftModelEntry = plan.find((e) => e.role === 'draft-model');
694
+ // Snapshot what the catalog said this payload IS, so a later version bump
695
+ // that only edits metadata can be recognized as such without re-reading a
696
+ // byte. Skipped for a skipSha install: those bytes are knowingly not the
697
+ // ones the catalog describes.
698
+ const catalogPayload = describeCatalogPayload(manifest, this.engine);
699
+ const payloadFingerprint = catalogPayload && !skipSha ? catalogPayloadFingerprint(catalogPayload) : undefined;
700
+ // Recorded next to the catalog's tag, never instead of it: the catalog
701
+ // names the build a user chose, the header names what the bytes are.
702
+ const declaredQuantization = ggufQuantizationTag(summary);
703
+ const installed = {
704
+ id: catalogId,
705
+ name: manifest.name,
706
+ // Language weights only. Sidecars are surfaced and budgeted separately;
707
+ // folding them in here makes every vision launch count the encoder twice.
708
+ approxSizeBytes: src.approxSizeBytes,
709
+ weightsFilename: firstWeights.destFilename,
710
+ sha256: firstWeights.sha256.toLowerCase(),
711
+ installedAt: new Date().toISOString(),
712
+ catalogId,
713
+ catalogVersion: manifest.version,
714
+ huggingfaceRepo: src.huggingfaceRepo,
715
+ ...(weightsShards.length > 1
716
+ ? {
717
+ shards: weightsShards.map((entry) => ({
718
+ filename: entry.destFilename,
719
+ sha256: entry.sha256.toLowerCase(),
720
+ sizeBytes: entry.sizeBytes,
721
+ })),
722
+ }
723
+ : {}),
724
+ ...(mmprojEntry ? { mmprojFilename: mmprojEntry.destFilename } : {}),
725
+ ...(visionEncoderEntry ? { visionEncoderFilename: visionEncoderEntry.destFilename } : {}),
726
+ ...(draftModelEntry ? { draftModelFilename: draftModelEntry.destFilename } : {}),
727
+ ...(src.quantization ? { quantization: src.quantization } : {}),
728
+ ...(declaredQuantization ? { ggufQuantization: declaredQuantization } : {}),
729
+ ...(summary.contextLength ? { contextWindow: Number(summary.contextLength) } : {}),
730
+ ...(summary.architecture ? { architecture: summary.architecture } : {}),
731
+ chatTemplatePresent: !summary.chatTemplateMissing,
732
+ ...(payloadFingerprint ? { payloadFingerprint } : {}),
733
+ };
734
+ installed.fileSha256 = await hashModelPayloadFiles(itemDir, verifiedDigests);
735
+ await writeFile(join(itemDir, 'manifest.json'), JSON.stringify(installed, null, 2), 'utf8');
736
+ await makeSharedModelReadable(itemDir);
737
+ const warning = summary.chatTemplateMissing
738
+ ? 'Model has no embedded chat template (tokenizer.chat_template is missing). llama-server will fall back to a generic template that may not match this model — replies may be incoherent. Consider a different quant of the same model.'
739
+ : undefined;
740
+ try {
741
+ this.onInstalled?.({ engine: this.engine, id: catalogId });
742
+ }
743
+ catch {
744
+ // Fire-and-forget: a hook failure must never fail a completed install.
745
+ }
746
+ yield { type: 'done', id: catalogId, ...(warning ? { warning } : {}) };
747
+ }
748
+ /**
749
+ * Files the plan asks for that are already on disk as exactly the bytes the
750
+ * catalog pins, keyed by filename with the digest to carry forward.
751
+ *
752
+ * An update usually rotates one thing — a quant, one shard, an added draft
753
+ * companion — and re-fetching the rest is pure waste. The install manifest
754
+ * records a sha256 for every file it published, each verified against the
755
+ * catalog when it landed; where that digest equals the pin we are about to
756
+ * download and the file is still its full length, the bytes on disk ARE the
757
+ * bytes we would fetch. Same trust model as the shared-store adoption cache:
758
+ * a recorded digest plus an unchanged stat is identity.
759
+ */
760
+ async planReusableFiles(itemDir, plan) {
761
+ const reusable = new Map();
762
+ const parsed = await readFile(join(itemDir, 'manifest.json'), 'utf8')
763
+ .then((raw) => JSON.parse(raw))
764
+ .catch(() => null);
765
+ const recorded = parsed?.fileSha256;
766
+ if (!recorded)
767
+ return reusable;
768
+ for (const entry of plan) {
769
+ const sha = recorded[entry.destFilename]?.toLowerCase();
770
+ if (!sha || sha !== entry.sha256.toLowerCase())
771
+ continue;
772
+ const size = await stat(join(itemDir, entry.destFilename))
773
+ .then((info) => (info.isFile() ? info.size : -1))
774
+ .catch(() => -1);
775
+ if (size !== entry.sizeBytes)
776
+ continue;
777
+ reusable.set(entry.destFilename, sha);
778
+ }
779
+ return reusable;
780
+ }
781
+ /** Warn once per model directory per process, then stay quiet. */
782
+ warnSkip(id, reason) {
783
+ if (this.skipWarned.has(id))
784
+ return;
785
+ this.skipWarned.add(id);
786
+ log.warn(`[${this.engine}] model directory "${id}" is not runnable: ${reason}`);
787
+ }
788
+ async loadInstalled(requestedId) {
789
+ let id = requestedId;
790
+ let root = await findModelRoot(this.storageRoots, id);
791
+ if (!root) {
792
+ // A pin written before the quant-suffix rename still names the old id.
793
+ // Config, gezel frontmatter, eval caches, and session records all hold
794
+ // whatever id was current when they were written.
795
+ const renamed = await findRenamedModelId(this.storageRoots, requestedId);
796
+ if (!renamed)
797
+ return null;
798
+ id = renamed;
799
+ root = await findModelRoot(this.storageRoots, id);
800
+ if (!root)
801
+ return null;
802
+ }
803
+ const metaPath = join(root, id, 'manifest.json');
804
+ let raw;
805
+ try {
806
+ raw = await readFile(metaPath, 'utf8');
807
+ }
808
+ catch {
809
+ this.warnSkip(id, `manifest.json is unreadable at ${metaPath}`);
810
+ return null;
811
+ }
812
+ let parsed;
813
+ try {
814
+ parsed = JSON.parse(raw);
815
+ }
816
+ catch {
817
+ this.warnSkip(id, `manifest.json is not valid JSON at ${metaPath}`);
818
+ return null;
819
+ }
820
+ if (!parsed.id || !parsed.name || !parsed.weightsFilename || !parsed.installedAt) {
821
+ this.warnSkip(id, 'manifest.json is missing required fields (id/name/weightsFilename/installedAt)');
822
+ return null;
823
+ }
824
+ if (!(await verifyReadOnlyModelPayload(this.storageRoots, root, id, parsed.fileSha256, (reason) => this.warnSkip(id, reason)))) {
825
+ return null;
826
+ }
827
+ // Read from disk, not the manifest: `approxSizeBytes` recorded at install
828
+ // is the weights alone whenever the payload was adopted or resumed rather
829
+ // than freshly downloaded, so it cannot be trusted to include the projector.
830
+ const mmprojSizeBytes = parsed.mmprojFilename
831
+ ? await stat(join(root, id, parsed.mmprojFilename))
832
+ .then((s) => s.size)
833
+ .catch(() => 0)
834
+ : 0;
835
+ const visionEncoderSizeBytes = parsed.visionEncoderFilename
836
+ ? await stat(join(root, id, parsed.visionEncoderFilename))
837
+ .then((s) => s.size)
838
+ .catch(() => 0)
839
+ : 0;
840
+ // Absent on every copy installed before the field existed, and on those
841
+ // the catalog tag is the only thing the table has to show.
842
+ const ggufQuantization = parsed.ggufQuantization ??
843
+ (await backfillGgufQuantization({
844
+ engine: this.engine,
845
+ id,
846
+ modelDir: join(root, id),
847
+ weightsFilename: parsed.weightsFilename,
848
+ ...(parsed.quantization ? { catalogQuantization: parsed.quantization } : {}),
849
+ writable: resolve(root) === resolve(this.storageRoots.writableRoot),
850
+ }));
851
+ return {
852
+ id: parsed.id,
853
+ name: parsed.name,
854
+ approxSizeBytes: parsed.approxSizeBytes ?? 0,
855
+ installedAt: parsed.installedAt,
856
+ weightsPath: join(root, id, parsed.weightsFilename),
857
+ ...(parsed.mmprojFilename
858
+ ? {
859
+ mmprojPath: join(root, id, parsed.mmprojFilename),
860
+ ...(mmprojSizeBytes > 0 ? { mmprojSizeBytes } : {}),
861
+ }
862
+ : {}),
863
+ ...(parsed.visionEncoderFilename
864
+ ? {
865
+ visionEncoderPath: join(root, id, parsed.visionEncoderFilename),
866
+ ...(visionEncoderSizeBytes > 0 ? { visionEncoderSizeBytes } : {}),
867
+ }
868
+ : {}),
869
+ ...(parsed.draftModelFilename
870
+ ? { draftModelPath: join(root, id, parsed.draftModelFilename) }
871
+ : {}),
872
+ ...(parsed.contextWindow ? { contextWindow: parsed.contextWindow } : {}),
873
+ ...(parsed.quantization ? { quantization: parsed.quantization } : {}),
874
+ ...(ggufQuantization ? { ggufQuantization } : {}),
875
+ chatTemplatePresent: parsed.chatTemplatePresent ?? true,
876
+ ...(parsed.architecture ? { architecture: parsed.architecture } : {}),
877
+ ...(parsed.catalogVersion ? { catalogVersion: parsed.catalogVersion } : {}),
878
+ ...(parsed.sha256 ? { sha256: parsed.sha256 } : {}),
879
+ // Read-only when it lives in a machine/shared overlay rather than this
880
+ // daemon's writable root — the delete endpoint refuses it, so the UI
881
+ // must not offer a Delete action that can only 400.
882
+ ...(resolve(root) !== resolve(this.storageRoots.writableRoot) ? { readOnly: true } : {}),
883
+ };
884
+ }
885
+ }
886
+ function describeError(err) {
887
+ return err instanceof Error ? err.message : String(err);
888
+ }
889
+ /**
890
+ * Translate a catalog `llamaCpp` source into the ordered list of files
891
+ * to download. Single-file sources collapse to one entry. Sharded
892
+ * sources expand to one entry per shard, flattening any subdirectory
893
+ * in the HF tree to a basename on disk (so `Q4_K_M/foo-00001-of-NNN.gguf`
894
+ * lands as `foo-00001-of-NNN.gguf` next to its siblings — llama-server
895
+ * needs them all in the same directory to auto-discover splits).
896
+ */
897
+ function planDownloads(src,
898
+ /**
899
+ * Whether to also fetch the vision projector. On by default: fetch what the
900
+ * catalog ships, and let the *runtime* decide whether to load it.
901
+ *
902
+ * This used to be off, on the reasoning that an mmproj-backed server 501s
903
+ * on slot save/restore and so shouldn't be imposed by an install. But the
904
+ * cost is paid at `--mmproj` on the command line, not at download — so
905
+ * withholding the file bought nothing and cost a lot: a user who enabled
906
+ * vision got a model that silently could not see, because the projector
907
+ * had never been fetched and nothing re-fetched it. Turning the toggle on
908
+ * now works immediately instead of requiring a re-install nobody knew to
909
+ * run.
910
+ *
911
+ * This option only governs llama.cpp's `mmproj`; a declared ds4
912
+ * `visionEncoder` is part of that model's install and is always fetched.
913
+ */
914
+ includeMmproj = true) {
915
+ const out = [];
916
+ if (src.shards && src.shards.length > 0) {
917
+ src.shards.forEach((shard, i) => {
918
+ out.push({
919
+ repoPath: shard.name,
920
+ destFilename: basename(shard.name),
921
+ sha256: shard.sha256,
922
+ sizeBytes: shard.sizeBytes,
923
+ role: i === 0 ? 'weights' : 'weights-shard',
924
+ });
925
+ });
926
+ }
927
+ else if (src.filename && src.sha256) {
928
+ out.push({
929
+ repoPath: src.filename,
930
+ destFilename: basename(src.filename),
931
+ sha256: src.sha256,
932
+ sizeBytes: src.approxSizeBytes,
933
+ role: 'weights',
934
+ });
935
+ }
936
+ else {
937
+ return [];
938
+ }
939
+ if (src.mmproj && includeMmproj) {
940
+ out.push({
941
+ repoPath: src.mmproj.filename,
942
+ destFilename: basename(src.mmproj.filename),
943
+ sha256: src.mmproj.sha256,
944
+ sizeBytes: src.mmproj.sizeBytes,
945
+ role: 'mmproj',
946
+ });
947
+ }
948
+ if (src.visionEncoder) {
949
+ out.push({
950
+ ...(src.visionEncoder.huggingfaceRepo
951
+ ? { huggingfaceRepo: src.visionEncoder.huggingfaceRepo }
952
+ : {}),
953
+ ...(src.visionEncoder.revision ? { revision: src.visionEncoder.revision } : {}),
954
+ repoPath: src.visionEncoder.filename,
955
+ destFilename: basename(src.visionEncoder.filename),
956
+ sha256: src.visionEncoder.sha256,
957
+ sizeBytes: src.visionEncoder.sizeBytes,
958
+ role: 'vision-encoder',
959
+ });
960
+ }
961
+ // Draft companions are part of the model's selected decoding path, not
962
+ // an optional modality. Download them whenever the catalog ships one so
963
+ // an explicitly selected `draft-mtp`/other draft mode can work immediately
964
+ // after install without a second download.
965
+ if (src.draftModel) {
966
+ out.push({
967
+ repoPath: src.draftModel.filename,
968
+ destFilename: basename(src.draftModel.filename),
969
+ sha256: src.draftModel.sha256,
970
+ sizeBytes: src.draftModel.sizeBytes,
971
+ role: 'draft-model',
972
+ });
973
+ }
974
+ return out;
975
+ }
976
+ /**
977
+ * Bytes of a still-to-fetch download that a `.partial` already holds — resume
978
+ * credit, so retrying a 200 GiB download that's 90% done isn't refused for
979
+ * space it is already occupying.
980
+ *
981
+ * Deliberately blind to finished files. A previous install's copy of the same
982
+ * filename is NOT credit: the new bytes stream into a `.partial` beside it and
983
+ * the old copy is only removed at publish, so both are on disk at once. (This
984
+ * counted the finished file, which meant an in-place replacement was preflighted
985
+ * as needing nothing at all, and a half-full disk failed with ENOSPC deep into
986
+ * the transfer instead of being refused up front.) Files that don't need
987
+ * fetching at all are excluded by the caller, not credited here.
988
+ */
989
+ async function partialBytesOnDisk(itemDir, plan) {
990
+ let total = 0;
991
+ for (const entry of plan) {
992
+ const size = await stat(`${join(itemDir, entry.destFilename)}.partial`)
993
+ .then((st) => st.size)
994
+ .catch(() => 0);
995
+ if (size > 0)
996
+ total += Math.min(size, entry.sizeBytes);
997
+ }
998
+ return total;
999
+ }
1000
+ /**
1001
+ * Permissive id check — must be a relative single-segment id, no
1002
+ * traversal. Catalog ids match `[a-z0-9][a-z0-9.\-:]{1,63}` per the
1003
+ * core schema, so anything that flunks this is malicious.
1004
+ */
1005
+ function isSafeId(id) {
1006
+ if (id.length === 0 || id.length > 64)
1007
+ return false;
1008
+ if (id.includes('/') || id.includes('\\') || id.startsWith('.'))
1009
+ return false;
1010
+ return /^[a-z0-9][a-z0-9.\-:]{0,63}$/i.test(id);
1011
+ }