@bendyline/gezel-inference 1.0.2 → 1.0.4

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 (297) hide show
  1. package/dist/catalog/chat-models/de/deepseek-v4.1-flash-552b-q2/manifest.json +120 -0
  2. package/dist/catalog/chat-models/de/deepseek-v4.1-flash-552b-q2/versions/1.0.0/manifest.json +21 -0
  3. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/manifest.json +6 -5
  4. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.2/manifest.json +27 -0
  5. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.3/manifest.json +27 -0
  6. package/dist/catalog/chat-models/index.json +1 -1
  7. package/dist/catalog/chat-models/na/nanbeige4.2-3b-q4/manifest.json +1 -1
  8. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/manifest.json +157 -0
  9. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/versions/1.0.0/manifest.json +30 -0
  10. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-e4b-q4/manifest.json +142 -0
  11. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-e4b-q4/versions/1.0.0/manifest.json +14 -0
  12. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-e4b-q4/versions/1.0.1/manifest.json +14 -0
  13. package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/manifest.json +156 -0
  14. package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/versions/1.0.0/manifest.json +28 -0
  15. package/dist/catalog/chat-models/raw-index.json +1 -1
  16. package/dist/catalog/image-models/an/animagine-xl-4/manifest.json +40 -0
  17. package/dist/catalog/image-models/an/animagine-xl-4/versions/4.0.0/manifest.json +10 -0
  18. package/dist/catalog/image-models/an/animagine-xl-4/versions/4.0.1/manifest.json +16 -0
  19. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/manifest.json +44 -0
  20. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/versions/1.0.0/manifest.json +23 -0
  21. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/versions/1.0.1/manifest.json +29 -0
  22. package/dist/catalog/image-models/index.json +1 -0
  23. package/dist/catalog/image-models/ir/iris-3b-f32/manifest.json +41 -0
  24. package/dist/catalog/image-models/ir/iris-3b-f32/versions/1.0.0/manifest.json +19 -0
  25. package/dist/catalog/image-models/ir/iris-3b-f32/versions/1.0.1/manifest.json +25 -0
  26. package/dist/catalog/image-models/ir/iris-3b-f32/versions/1.0.2/manifest.json +25 -0
  27. package/dist/catalog/image-models/kr/krea-2-turbo-q4/manifest.json +42 -0
  28. package/dist/catalog/image-models/kr/krea-2-turbo-q4/versions/1.0.0/manifest.json +23 -0
  29. package/dist/catalog/image-models/kr/krea-2-turbo-q4/versions/1.0.1/manifest.json +29 -0
  30. package/dist/catalog/image-models/kr/krea-2-turbo-q6/manifest.json +42 -0
  31. package/dist/catalog/image-models/kr/krea-2-turbo-q6/versions/1.0.0/manifest.json +23 -0
  32. package/dist/catalog/image-models/kr/krea-2-turbo-q6/versions/1.0.1/manifest.json +29 -0
  33. package/dist/catalog/image-models/kr/krea-2-turbo-q8/manifest.json +42 -0
  34. package/dist/catalog/image-models/kr/krea-2-turbo-q8/versions/1.0.0/manifest.json +23 -0
  35. package/dist/catalog/image-models/kr/krea-2-turbo-q8/versions/1.0.1/manifest.json +29 -0
  36. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/manifest.json +41 -0
  37. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.0/manifest.json +31 -0
  38. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.1/manifest.json +50 -0
  39. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.2/manifest.json +50 -0
  40. package/dist/catalog/image-models/mo/moss-image-sft-q4/manifest.json +40 -0
  41. package/dist/catalog/image-models/mo/moss-image-sft-q4/versions/1.0.0/manifest.json +37 -0
  42. package/dist/catalog/image-models/mo/moss-image-sft-q4/versions/1.0.1/manifest.json +37 -0
  43. package/dist/catalog/image-models/raw-index.json +1 -0
  44. package/dist/catalog/image-models/sd/sd-1.5/manifest.json +40 -0
  45. package/dist/catalog/image-models/sd/sd-1.5/versions/1.0.0/manifest.json +10 -0
  46. package/dist/catalog/image-models/sd/sd-1.5/versions/1.0.1/manifest.json +16 -0
  47. package/dist/catalog/image-models/sd/sd-turbo/manifest.json +40 -0
  48. package/dist/catalog/image-models/sd/sd-turbo/versions/1.0.0/manifest.json +10 -0
  49. package/dist/catalog/image-models/sd/sd-turbo/versions/1.0.1/manifest.json +16 -0
  50. package/dist/catalog/image-models/sd/sdxl-base-1.0/manifest.json +39 -0
  51. package/dist/catalog/image-models/sd/sdxl-base-1.0/versions/1.0.0/manifest.json +10 -0
  52. package/dist/catalog/image-models/sd/sdxl-base-1.0/versions/1.0.1/manifest.json +16 -0
  53. package/dist/catalog/image-models/sd/sdxl-lightning-4step/manifest.json +40 -0
  54. package/dist/catalog/image-models/sd/sdxl-lightning-4step/versions/1.0.0/manifest.json +10 -0
  55. package/dist/catalog/image-models/sd/sdxl-lightning-4step/versions/1.0.1/manifest.json +16 -0
  56. package/dist/catalog/image-models/sd/sdxl-turbo/manifest.json +41 -0
  57. package/dist/catalog/image-models/sd/sdxl-turbo/versions/1.0.0/manifest.json +10 -0
  58. package/dist/catalog/image-models/sd/sdxl-turbo/versions/1.0.1/manifest.json +16 -0
  59. package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/keywords.json +56 -0
  60. package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/keywords.json +12 -0
  61. package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/keywords.json +13 -0
  62. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/keywords.json +14 -0
  63. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/keywords.json +17 -0
  64. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/keywords.json +12 -0
  65. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/keywords.json +12 -0
  66. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/keywords.json +12 -0
  67. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/keywords.json +12 -0
  68. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/keywords.json +12 -0
  69. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/keywords.json +12 -0
  70. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/keywords.json +12 -0
  71. package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/keywords.json +12 -0
  72. package/dist/catalog/knowledge-catalogs/index.json +1 -1
  73. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/keywords.json +21 -0
  74. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/keywords.json +27 -0
  75. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/keywords.json +23 -0
  76. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/keywords.json +26 -0
  77. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/keywords.json +28 -0
  78. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/keywords.json +29 -0
  79. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/keywords.json +21 -0
  80. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/keywords.json +14 -0
  81. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/keywords.json +20 -0
  82. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/keywords.json +24 -0
  83. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/keywords.json +27 -0
  84. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/keywords.json +18 -0
  85. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/keywords.json +28 -0
  86. package/dist/catalog/knowledge-catalogs/raw-index.json +1 -1
  87. package/dist/catalog/knowledge-catalogs/re/regional-american-south/keywords.json +1700 -0
  88. package/dist/catalog/knowledge-catalogs/re/regional-american-south/versions/2026.10.5/manifest.json +133 -0
  89. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/keywords.json +750 -0
  90. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/versions/2026.10.5/manifest.json +133 -0
  91. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/keywords.json +1281 -0
  92. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/versions/2026.10.5/manifest.json +133 -0
  93. package/dist/catalog/knowledge-catalogs/re/regional-brazil/keywords.json +1125 -0
  94. package/dist/catalog/knowledge-catalogs/re/regional-brazil/versions/2026.10.5/manifest.json +133 -0
  95. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/keywords.json +3287 -0
  96. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/versions/2026.10.5/manifest.json +133 -0
  97. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/keywords.json +1835 -0
  98. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/versions/2026.10.5/manifest.json +133 -0
  99. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/keywords.json +1184 -0
  100. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/versions/2026.10.5/manifest.json +133 -0
  101. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/keywords.json +1503 -0
  102. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/versions/2026.10.5/manifest.json +133 -0
  103. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/keywords.json +2836 -0
  104. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/versions/2026.10.5/manifest.json +133 -0
  105. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/keywords.json +813 -0
  106. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/versions/2026.10.5/manifest.json +133 -0
  107. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/keywords.json +2082 -0
  108. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/versions/2026.10.5/manifest.json +133 -0
  109. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/keywords.json +1481 -0
  110. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/versions/2026.10.5/manifest.json +133 -0
  111. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/keywords.json +1272 -0
  112. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/versions/2026.10.5/manifest.json +133 -0
  113. package/dist/catalog/knowledge-catalogs/re/regional-midwest/keywords.json +758 -0
  114. package/dist/catalog/knowledge-catalogs/re/regional-midwest/versions/2026.10.5/manifest.json +133 -0
  115. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/keywords.json +896 -0
  116. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/versions/2026.10.5/manifest.json +133 -0
  117. package/dist/catalog/knowledge-catalogs/re/regional-northeast/keywords.json +1281 -0
  118. package/dist/catalog/knowledge-catalogs/re/regional-northeast/versions/2026.10.5/manifest.json +133 -0
  119. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/keywords.json +346 -0
  120. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/versions/2026.10.5/manifest.json +133 -0
  121. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/keywords.json +2688 -0
  122. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/versions/2026.10.5/manifest.json +133 -0
  123. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/keywords.json +973 -0
  124. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/versions/2026.10.5/manifest.json +133 -0
  125. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/keywords.json +937 -0
  126. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/versions/2026.10.5/manifest.json +133 -0
  127. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/keywords.json +608 -0
  128. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/versions/2026.10.5/manifest.json +133 -0
  129. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/keywords.json +633 -0
  130. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/versions/2026.10.5/manifest.json +133 -0
  131. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/keywords.json +2697 -0
  132. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/versions/2026.10.5/manifest.json +133 -0
  133. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/keywords.json +606 -0
  134. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/versions/2026.10.5/manifest.json +133 -0
  135. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/keywords.json +564 -0
  136. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/versions/2026.10.5/manifest.json +133 -0
  137. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/keywords.json +3247 -0
  138. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/manifest.json +47 -0
  139. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/versions/2026.10.5/manifest.json +133 -0
  140. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/manifest.json +47 -0
  141. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/versions/2026.10.5/manifest.json +133 -0
  142. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/keywords.json +5437 -0
  143. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/manifest.json +1 -1
  144. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.10.1/manifest.json +181 -0
  145. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/keywords.json +4009 -0
  146. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/manifest.json +1 -1
  147. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.10.1/manifest.json +181 -0
  148. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/keywords.json +4009 -0
  149. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/manifest.json +1 -1
  150. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.10.1/manifest.json +217 -0
  151. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/keywords.json +5583 -0
  152. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/manifest.json +1 -1
  153. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.10.1/manifest.json +197 -0
  154. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/keywords.json +6386 -0
  155. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/manifest.json +2 -2
  156. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.10.1/manifest.json +197 -0
  157. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/keywords.json +4009 -0
  158. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/manifest.json +1 -1
  159. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.10.1/manifest.json +185 -0
  160. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/keywords.json +5672 -0
  161. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/manifest.json +1 -1
  162. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.10.1/manifest.json +137 -0
  163. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/manifest.json +68 -0
  164. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/versions/2026.10.1/manifest.json +217 -0
  165. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/manifest.json +68 -0
  166. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/versions/2026.10.1/manifest.json +217 -0
  167. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/keywords.json +4009 -0
  168. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/manifest.json +1 -1
  169. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.10.1/manifest.json +141 -0
  170. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/keywords.json +4009 -0
  171. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/manifest.json +1 -1
  172. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.10.1/manifest.json +185 -0
  173. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/keywords.json +5719 -0
  174. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/manifest.json +1 -1
  175. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.10.1/manifest.json +193 -0
  176. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/keywords.json +4009 -0
  177. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/manifest.json +1 -1
  178. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.10.1/manifest.json +189 -0
  179. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/keywords.json +16009 -0
  180. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/manifest.json +1 -1
  181. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.10.1/manifest.json +185 -0
  182. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/keywords.json +5843 -0
  183. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/manifest.json +1 -1
  184. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.10.1/manifest.json +189 -0
  185. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/keywords.json +6264 -0
  186. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/manifest.json +1 -1
  187. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.10.1/manifest.json +197 -0
  188. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/manifest.json +66 -0
  189. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/versions/2026.10.1/manifest.json +209 -0
  190. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/manifest.json +61 -0
  191. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/versions/2026.10.1/manifest.json +189 -0
  192. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/manifest.json +64 -0
  193. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/versions/2026.10.1/manifest.json +201 -0
  194. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/manifest.json +60 -0
  195. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/versions/2026.10.1/manifest.json +185 -0
  196. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/manifest.json +55 -0
  197. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/versions/2026.10.1/manifest.json +165 -0
  198. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/manifest.json +63 -0
  199. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/versions/2026.10.1/manifest.json +197 -0
  200. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/manifest.json +64 -0
  201. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/versions/2026.10.1/manifest.json +201 -0
  202. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/manifest.json +65 -0
  203. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/versions/2026.10.1/manifest.json +205 -0
  204. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/manifest.json +73 -0
  205. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/versions/2026.10.1/manifest.json +237 -0
  206. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/keywords.json +5447 -0
  207. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/manifest.json +1 -1
  208. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.10.1/manifest.json +197 -0
  209. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/keywords.json +4009 -0
  210. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/manifest.json +1 -1
  211. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.10.1/manifest.json +189 -0
  212. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/keywords.json +4009 -0
  213. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/manifest.json +1 -1
  214. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.10.1/manifest.json +185 -0
  215. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/keywords.json +5209 -0
  216. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/manifest.json +1 -1
  217. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.10.1/manifest.json +193 -0
  218. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/keywords.json +6537 -0
  219. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/manifest.json +1 -1
  220. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.10.1/manifest.json +185 -0
  221. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/keywords.json +5989 -0
  222. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/manifest.json +1 -1
  223. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.10.1/manifest.json +189 -0
  224. package/dist/catalog/provenance.json +2 -1
  225. package/dist/engines/native-file-manifest.json +198 -118
  226. package/dist/engines/native-manifest.d.ts +4 -4
  227. package/dist/engines/native-manifest.js +36 -34
  228. package/dist/engines/resolver.js +12 -1
  229. package/dist/fs/atomic.d.ts +4 -1
  230. package/dist/fs/atomic.js +7 -1
  231. package/dist/http/openai-compat/chat-target.d.ts +1 -1
  232. package/dist/http/openai-compat/chat-target.js +1 -1
  233. package/dist/http/openai-compat/engine-failure.js +7 -2
  234. package/dist/http/routes/v1-chat.js +1 -1
  235. package/dist/http/routes/v1-images.d.ts +44 -0
  236. package/dist/http/routes/v1-images.js +370 -0
  237. package/dist/http/routes/v1-knowledge.js +4 -0
  238. package/dist/http/routes/v1-responses.d.ts +1 -1
  239. package/dist/inference-service.d.ts +9 -1
  240. package/dist/inference-service.js +44 -11
  241. package/dist/knowledge/manager.d.ts +7 -0
  242. package/dist/knowledge/manager.js +32 -1
  243. package/dist/kokoro-lexicon/manifest.json +6 -3
  244. package/dist/models/image-fit.d.ts +83 -0
  245. package/dist/models/image-fit.js +163 -0
  246. package/dist/models/weight-facts.d.ts +36 -0
  247. package/dist/models/weight-facts.js +171 -0
  248. package/dist/perf/responsiveness.js +4 -3
  249. package/dist/providers/audio/kokoro-frontend.js +1 -1
  250. package/dist/providers/ds4/build-provider.js +34 -21
  251. package/dist/providers/ds4/dspark.d.ts +23 -5
  252. package/dist/providers/ds4/dspark.js +36 -8
  253. package/dist/providers/image/img2img-support.d.ts +40 -0
  254. package/dist/providers/image/img2img-support.js +74 -0
  255. package/dist/providers/image/local-engine.d.ts +31 -0
  256. package/dist/providers/image/local-engine.js +47 -0
  257. package/dist/providers/image/local-factory.d.ts +95 -0
  258. package/dist/providers/image/local-factory.js +270 -0
  259. package/dist/providers/image/mock.d.ts +23 -0
  260. package/dist/providers/image/mock.js +151 -0
  261. package/dist/providers/image/pull-registry.d.ts +106 -0
  262. package/dist/providers/image/pull-registry.js +227 -0
  263. package/dist/providers/image/sd-cpp.d.ts +200 -0
  264. package/dist/providers/image/sd-cpp.js +845 -0
  265. package/dist/providers/image/types.d.ts +235 -0
  266. package/dist/providers/image/types.js +20 -0
  267. package/dist/providers/llama-cpp/backend-health.d.ts +7 -0
  268. package/dist/providers/llama-cpp/backend-health.js +41 -1
  269. package/dist/providers/llama-cpp/build-provider.js +107 -56
  270. package/dist/providers/llama-cpp/cache-adapter.d.ts +7 -1
  271. package/dist/providers/llama-cpp/cache-adapter.js +9 -0
  272. package/dist/providers/llama-cpp/devices.d.ts +13 -2
  273. package/dist/providers/llama-cpp/devices.js +43 -6
  274. package/dist/providers/llama-cpp/models.js +4 -1
  275. package/dist/providers/llama-cpp/offload-planner.d.ts +23 -0
  276. package/dist/providers/llama-cpp/offload-planner.js +27 -0
  277. package/dist/providers/llama-cpp/provider.d.ts +14 -3
  278. package/dist/providers/llama-cpp/provider.js +35 -2
  279. package/dist/providers/mlx/provider.js +15 -5
  280. package/dist/providers/mlx/reasoning-stream.d.ts +15 -0
  281. package/dist/providers/mlx/reasoning-stream.js +35 -0
  282. package/dist/providers/native/capacity-broker.js +9 -3
  283. package/dist/providers/native/local-engine-runtime.js +15 -12
  284. package/dist/providers/native/supervisor.d.ts +8 -0
  285. package/dist/providers/native/supervisor.js +55 -5
  286. package/dist/providers/project-macro-loop-bail.js +5 -3
  287. package/dist/providers/provider-lifecycle.d.ts +21 -0
  288. package/dist/providers/provider-lifecycle.js +83 -0
  289. package/dist/providers/queue.d.ts +9 -2
  290. package/dist/providers/queue.js +17 -2
  291. package/dist/providers/retirement-gate.d.ts +20 -0
  292. package/dist/providers/retirement-gate.js +55 -0
  293. package/dist/providers/session-hooks.d.ts +4 -1
  294. package/dist/system/memory.js +6 -0
  295. package/dist/utils/image-meta.d.ts +12 -0
  296. package/dist/utils/image-meta.js +77 -0
  297. package/package.json +6 -6
@@ -16,7 +16,7 @@
16
16
  * `backend.json` pattern in `core/native/llama-backend.ts`.
17
17
  */
18
18
  import { execFile } from 'node:child_process';
19
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
19
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
20
20
  import { totalmem } from 'node:os';
21
21
  import { delimiter, dirname, join } from 'node:path';
22
22
  import { promisify } from 'node:util';
@@ -122,11 +122,34 @@ export function pickBestGpuDevice(devices) {
122
122
  function cachePath(home) {
123
123
  return join(home, 'engines', 'llama-cpp', 'devices.json');
124
124
  }
125
+ /**
126
+ * An empty listing is re-asked after this long. A CPU build always answers
127
+ * "(none)", but so can a GPU build whose driver was mid-update, and a cached
128
+ * "no GPU" sizes every model against system RAM.
129
+ */
130
+ const EMPTY_DEVICES_RETRY_MS = 60 * 60 * 1000;
131
+ /**
132
+ * Which build a cached listing came from: its path (the backend) and its
133
+ * size and mtime (the release, since a native update rewrites the files).
134
+ * A listing taken from the CPU build, or from the build an update replaced,
135
+ * said "no GPU" about a 32 GB Radeon and was served for the rest of the day
136
+ * (2026-10-19).
137
+ */
138
+ export function llamaBinaryFingerprint(binaryPath) {
139
+ try {
140
+ const { size, mtimeMs } = statSync(binaryPath);
141
+ return `${binaryPath}|${size}|${Math.floor(mtimeMs)}`;
142
+ }
143
+ catch {
144
+ return binaryPath;
145
+ }
146
+ }
125
147
  /**
126
148
  * Probe device memory by running `<binaryPath> --list-devices`, caching
127
149
  * the result. Reads the cache when present (VRAM capacity is stable per
128
- * machine) and the OS still reports the RAM it was probed with; pass
129
- * `force` to re-probe. Any failure (spawn error, no
150
+ * machine), the OS still reports the RAM it was probed with, and the same
151
+ * build answered it; an empty listing is re-asked hourly. Pass `force` to
152
+ * re-probe. Any failure (spawn error, no
130
153
  * cache, unparseable output) resolves to an empty device list — the
131
154
  * planner then simply does nothing and the engine's own `--fit`/`-ngl
132
155
  * auto` takes over. `nowIso` and `systemRamBytes` are injectable for
@@ -137,11 +160,19 @@ export async function probeLlamaDevices(opts) {
137
160
  const now = opts.nowIso ?? (() => new Date().toISOString());
138
161
  const systemRamBytes = opts.systemRamBytes ?? totalmem();
139
162
  const path = cachePath(home);
163
+ const binary = llamaBinaryFingerprint(binaryPath);
140
164
  if (!force && existsSync(path)) {
141
165
  try {
142
166
  const cached = JSON.parse(readFileSync(path, 'utf8'));
143
- // A cache without the RAM figure predates the check and re-probes once.
144
- if (Array.isArray(cached.devices) && cached.systemRamBytes === systemRamBytes) {
167
+ // A cache without the RAM figure or the binary predates that check and
168
+ // re-probes once.
169
+ const emptyExpired = Array.isArray(cached.devices) &&
170
+ cached.devices.length === 0 &&
171
+ !(Date.parse(now()) - Date.parse(cached.probedAt) < EMPTY_DEVICES_RETRY_MS);
172
+ if (Array.isArray(cached.devices) &&
173
+ cached.systemRamBytes === systemRamBytes &&
174
+ cached.binary === binary &&
175
+ !emptyExpired) {
145
176
  return { ...cached, cached: true };
146
177
  }
147
178
  }
@@ -171,7 +202,13 @@ export async function probeLlamaDevices(opts) {
171
202
  // Leave devices empty — caller treats "no devices" as "no offload target".
172
203
  return { devices, probedAt: now(), cached: false };
173
204
  }
174
- const probe = { devices, probedAt: now(), cached: false, systemRamBytes };
205
+ const probe = {
206
+ devices,
207
+ probedAt: now(),
208
+ cached: false,
209
+ systemRamBytes,
210
+ binary,
211
+ };
175
212
  try {
176
213
  mkdirSync(dirname(path), { recursive: true });
177
214
  writeFileSync(path, JSON.stringify(probe, null, 2), 'utf8');
@@ -748,7 +748,10 @@ export class LlamaCppModelManager {
748
748
  installed.fileSha256 = await hashModelPayloadFiles(itemDir, verifiedDigests);
749
749
  await writeFile(join(itemDir, 'manifest.json'), JSON.stringify(installed, null, 2), 'utf8');
750
750
  await makeSharedModelReadable(itemDir);
751
- const warning = summary.chatTemplateMissing
751
+ // ds4-server renders each family's prompt itself and never reads
752
+ // tokenizer.chat_template; DeepSeek V4.1 ships no Jinja template at all,
753
+ // and its first install warned that replies "may be incoherent".
754
+ const warning = summary.chatTemplateMissing && this.engine === 'llama-cpp'
752
755
  ? '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.'
753
756
  : undefined;
754
757
  try {
@@ -166,6 +166,29 @@ export declare function planMoeOffload(input: MoeOffloadInput): MoeOffloadDecisi
166
166
  export declare function degradeMoeOffloadDecision(decision: MoeOffloadDecision | undefined): MoeOffloadDecision | null;
167
167
  /** Dense counterpart of {@link degradeMoeOffloadDecision}. */
168
168
  export declare function degradeDenseFfnOffloadDecision(decision: MoeOffloadDecision | undefined, blockCount: number | undefined): MoeOffloadDecision | null;
169
+ /**
170
+ * Room an extra engine slot must leave on the card. Other programs' graphics
171
+ * memory moves while a model runs (a browser, a video, the desktop), and a
172
+ * two-slot launch planned to within a gigabyte or two died with a Vulkan
173
+ * out-of-memory when they took more (2026-10-19, a 32 GB card).
174
+ */
175
+ export declare const EXTRA_SLOT_GPU_CUSHION_BYTES: number;
176
+ /**
177
+ * Fewer slots before system RAM. Keep `slots` only when the model stays
178
+ * fully on the GPU with {@link EXTRA_SLOT_GPU_CUSHION_BYTES} to spare;
179
+ * otherwise drop to one slot when that alone keeps it fully on the GPU. A
180
+ * model that needs system RAM even at one slot keeps its slots and the
181
+ * planner's split. `plan` prices one slot count against one VRAM pool.
182
+ */
183
+ export declare function shedSlotsForGpuResidency(input: {
184
+ slots: number;
185
+ vramBytes: number;
186
+ plan: (slots: number, vramBytes: number) => MoeOffloadDecision;
187
+ }): {
188
+ slots: number;
189
+ decision: MoeOffloadDecision;
190
+ shed: boolean;
191
+ };
169
192
  export interface KvReserveInput {
170
193
  blockCount?: number | undefined;
171
194
  embeddingLength?: number | undefined;
@@ -272,6 +272,33 @@ export function degradeDenseFfnOffloadDecision(decision, blockCount) {
272
272
  }
273
273
  return null;
274
274
  }
275
+ /**
276
+ * Room an extra engine slot must leave on the card. Other programs' graphics
277
+ * memory moves while a model runs (a browser, a video, the desktop), and a
278
+ * two-slot launch planned to within a gigabyte or two died with a Vulkan
279
+ * out-of-memory when they took more (2026-10-19, a 32 GB card).
280
+ */
281
+ export const EXTRA_SLOT_GPU_CUSHION_BYTES = 2 * 1024 ** 3;
282
+ /**
283
+ * Fewer slots before system RAM. Keep `slots` only when the model stays
284
+ * fully on the GPU with {@link EXTRA_SLOT_GPU_CUSHION_BYTES} to spare;
285
+ * otherwise drop to one slot when that alone keeps it fully on the GPU. A
286
+ * model that needs system RAM even at one slot keeps its slots and the
287
+ * planner's split. `plan` prices one slot count against one VRAM pool.
288
+ */
289
+ export function shedSlotsForGpuResidency(input) {
290
+ const decision = input.plan(input.slots, input.vramBytes);
291
+ const keep = { slots: input.slots, decision, shed: false };
292
+ if (input.slots <= 1 || input.vramBytes <= 0)
293
+ return keep;
294
+ const roomy = input.plan(input.slots, Math.max(0, input.vramBytes - EXTRA_SLOT_GPU_CUSHION_BYTES));
295
+ if (roomy.fullGpuResidency)
296
+ return keep;
297
+ const single = input.plan(1, input.vramBytes);
298
+ if (!single.fullGpuResidency)
299
+ return keep;
300
+ return { slots: 1, decision: single, shed: true };
301
+ }
275
302
  /** Bytes per KV element for llama-server's `--cache-type-k/v` values. */
276
303
  const KV_BYTES_PER_ELEMENT = {
277
304
  f32: 4,
@@ -143,7 +143,9 @@ export declare class LlamaCppProvider implements LLMProvider {
143
143
  /** Request-scoped effort shape for compatible wrappers such as ds4-server. */
144
144
  private readonly reasoningEffortRequestShape;
145
145
  /** Engine batch width; see the `batchMaxConcurrency` constructor opt. */
146
- private readonly batchMaxConcurrency;
146
+ private batchMaxConcurrency;
147
+ /** See the `reserveBackgroundSlot` constructor opt. */
148
+ private readonly reservesBackgroundLane;
147
149
  /**
148
150
  * Number of real llama-server request slots (`--parallel`). The provider
149
151
  * queue can intentionally be wider than this by one reserved background
@@ -152,7 +154,7 @@ export declare class LlamaCppProvider implements LLMProvider {
152
154
  * boundary: cache slot save/restore plus the streamed engine request must
153
155
  * never exceed the slots the native server actually owns.
154
156
  */
155
- private readonly engineRequestWidth;
157
+ private engineRequestWidth;
156
158
  private engineRequestsActive;
157
159
  private readonly engineRequestWaiters;
158
160
  /**
@@ -409,7 +411,7 @@ export declare class LlamaCppProvider implements LLMProvider {
409
411
  */
410
412
  private cacheAdapter;
411
413
  private slotSavePath?;
412
- private readonly launchedSlots;
414
+ private launchedSlots;
413
415
  setCacheAdapter(adapter: import('./cache-adapter.js').LlamaCppCacheAdapter): void;
414
416
  getCacheAdapter(): import('./cache-adapter.js').LlamaCppCacheAdapter | null;
415
417
  /**
@@ -430,6 +432,15 @@ export declare class LlamaCppProvider implements LLMProvider {
430
432
  * would 400 silently, and the debug probe's slot narration was fiction.
431
433
  */
432
434
  getLaunchedSlots(): number;
435
+ /**
436
+ * Follow a supervised engine that is relaunching with fewer `--parallel`
437
+ * slots because the wider launch ran the GPU out of memory. Runs between
438
+ * the failed start and the retry, while the request that asked for the
439
+ * engine still holds its lease. Refused when more requests hold leases
440
+ * than the narrower engine has slots: two turns on one slot would save and
441
+ * restore it under each other.
442
+ */
443
+ narrowEngineSlots(slots: number): boolean;
433
444
  /**
434
445
  * Claim one physical llama-server request slot.
435
446
  *
@@ -25,7 +25,7 @@ import * as os from 'node:os';
25
25
  import { createLogger } from '@bendyline/gezel';
26
26
  import { DEFAULT_NUM_CTX, LlamaCppSession, NativeEngineCrashedError, TOOL_GRAMMAR_FALLBACK_ORDER, constrainedToolNoSignalMsForModel, engineRequestAbortError, parseEnvMs, } from '@bendyline/gezel/local-loop';
27
27
  import { ProviderDisposedError } from '../provider-disposal.js';
28
- import { ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, defaultAmbientQuietMs, } from '../queue.js';
28
+ import { ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, defaultAmbientQuietMs, defaultQueueYieldQuantumMs, } from '../queue.js';
29
29
  import { createToolExecutor } from '../tool-executor.js';
30
30
  import { classifyStartupLine } from './stdout-parser.js';
31
31
  // The session and its helpers live in core so a phone runs the same loop.
@@ -147,6 +147,8 @@ export class LlamaCppProvider {
147
147
  reasoningEffortRequestShape;
148
148
  /** Engine batch width; see the `batchMaxConcurrency` constructor opt. */
149
149
  batchMaxConcurrency;
150
+ /** See the `reserveBackgroundSlot` constructor opt. */
151
+ reservesBackgroundLane;
150
152
  /**
151
153
  * Number of real llama-server request slots (`--parallel`). The provider
152
154
  * queue can intentionally be wider than this by one reserved background
@@ -341,7 +343,10 @@ export class LlamaCppProvider {
341
343
  // mid-turn compaction wedges the turn, the same failure the MLX
342
344
  // single-slot path hit. See the matching note in the MLX provider.
343
345
  const interactiveConcurrency = batchMax;
344
- const queueConcurrency = opts.reserveBackgroundSlot === false ? slots : Math.max(slots, interactiveConcurrency + 1);
346
+ this.reservesBackgroundLane = opts.reserveBackgroundSlot !== false;
347
+ const queueConcurrency = this.reservesBackgroundLane
348
+ ? Math.max(slots, interactiveConcurrency + 1)
349
+ : slots;
345
350
  this.queue = new ProviderQueue({
346
351
  // llama-server is launched with `--parallel ${slots}` (see
347
352
  // `buildLlamaCppProvider` in chat/manager.ts) so the engine has matching
@@ -364,6 +369,9 @@ export class LlamaCppProvider {
364
369
  // a multi-minute chore turn never lands right before their next
365
370
  // move. Applies to ds4 too — its provider wraps this class.
366
371
  ambientQuietMs: defaultAmbientQuietMs(),
372
+ // A tool loop hands the slot to a waiting conversation between
373
+ // iterations once it has held it this long (see `QueueLease`).
374
+ yieldQuantumMs: defaultQueueYieldQuantumMs(),
367
375
  });
368
376
  }
369
377
  /**
@@ -458,6 +466,31 @@ export class LlamaCppProvider {
458
466
  getLaunchedSlots() {
459
467
  return this.launchedSlots;
460
468
  }
469
+ /**
470
+ * Follow a supervised engine that is relaunching with fewer `--parallel`
471
+ * slots because the wider launch ran the GPU out of memory. Runs between
472
+ * the failed start and the retry, while the request that asked for the
473
+ * engine still holds its lease. Refused when more requests hold leases
474
+ * than the narrower engine has slots: two turns on one slot would save and
475
+ * restore it under each other.
476
+ */
477
+ narrowEngineSlots(slots) {
478
+ const next = Math.max(1, Math.floor(slots));
479
+ if (next >= this.launchedSlots || this.engineRequestsActive > next)
480
+ return false;
481
+ this.launchedSlots = next;
482
+ this.engineRequestWidth = next;
483
+ this.batchMaxConcurrency = Math.min(this.batchMaxConcurrency, next);
484
+ this.queue.narrow({
485
+ concurrency: this.reservesBackgroundLane
486
+ ? Math.max(next, this.batchMaxConcurrency + 1)
487
+ : next,
488
+ interactiveConcurrency: this.batchMaxConcurrency,
489
+ backgroundConcurrency: backgroundLaneCap(next),
490
+ });
491
+ this.cacheAdapter?.setSlotCount(next);
492
+ return true;
493
+ }
461
494
  /**
462
495
  * Claim one physical llama-server request slot.
463
496
  *
@@ -58,7 +58,7 @@ import { MlxEngineGate } from './engine-gate.js';
58
58
  import { EngineHold, engineHoldLabelFor } from './engine-hold.js';
59
59
  import { EngineLogRouter } from './engine-log-router.js';
60
60
  import { MlxEngineStatsSampler } from './engine-stats-sampler.js';
61
- import { REASONING_OPEN_HEADER, StreamingReasoningSplit, engineOpensReasoning, requestOpensReasoning, } from './reasoning-stream.js';
61
+ import { REASONING_OPEN_HEADER, StreamingReasoningSplit, engineOpensReasoning, reopenTemplateReasoning, requestOpensReasoning, } from './reasoning-stream.js';
62
62
  import { applyMlxRequestShape } from './request-shape.js';
63
63
  import { PRE_FIRST_BYTE_BASE_MS, buildMidStreamDropMessage, buildPreFirstByteAbortMessage, computePreFirstByteBudgetMs, estimatePromptTokens, formatTps, isMidStreamConnectionDrop, mlxHttpError, } from './runtime-diagnostics.js';
64
64
  import { classifyMlxFatalErrorLine, classifyMlxStartupLine, } from './stdout-parser.js';
@@ -1497,11 +1497,21 @@ class MlxSession extends StreamingSessionBase {
1497
1497
  // Paused mid-reply: the stream stops until the chat ahead is
1498
1498
  // served. The reply so far stays on screen; the pill says why.
1499
1499
  const detail = engineHoldLabelFor(queue);
1500
- this.emitEnginePhase({ provider: 'mlx', phase: 'generating', detail });
1500
+ this.emitEnginePhase({
1501
+ provider: 'mlx',
1502
+ phase: 'generating',
1503
+ detail,
1504
+ hold: 'yielding',
1505
+ });
1501
1506
  return;
1502
1507
  }
1503
1508
  const detail = this.engineHold.begin(queue, opts?.queue?.onQueueWait);
1504
- this.emitEnginePhase({ provider: 'mlx', phase: 'prefill', detail });
1509
+ this.emitEnginePhase({
1510
+ provider: 'mlx',
1511
+ phase: 'prefill',
1512
+ detail,
1513
+ hold: queue.state === 'paused' ? 'yielding' : 'behind',
1514
+ });
1505
1515
  };
1506
1516
  // Anchored at request dispatch: only work the engine did while THIS
1507
1517
  // turn was already waiting can explain why it never got a first byte.
@@ -2159,7 +2169,7 @@ class MlxSession extends StreamingSessionBase {
2159
2169
  // accumulated into `lastTurnReasoning` so the chat bubble can
2160
2170
  // render it behind a collapsed expander.
2161
2171
  {
2162
- const split = extractReasoningWithProfile(turnContent, this.deps.profile);
2172
+ const split = extractReasoningWithProfile(reopenTemplateReasoning(turnContent, opensInReasoning), this.deps.profile);
2163
2173
  turnContent = split.visible;
2164
2174
  if (split.reasoning) {
2165
2175
  this.lastTurnReasoning =
@@ -2666,7 +2676,7 @@ class MlxSession extends StreamingSessionBase {
2666
2676
  // tool result makes the success unambiguous; the STOP
2667
2677
  // instruction is the closing emphasis, not the framing.
2668
2678
  projectMacroInterceptCount++;
2669
- output = `✓ The project was successfully created on your earlier \`${startedProjectOrJobThisTurn.tool}\` call this turn — kickoff is complete and the lead is on it.\n\nOriginal result:\n${startedProjectOrJobThisTurn.firstResult}\n\nSTOP — do NOT emit any more tool calls this turn. Each project-start call creates a real project, lead, and kickoff task; repeating the macro would create duplicates. END YOUR TURN NOW with a one-sentence summary to the user (e.g. "Project is on it — the voorman is leading"). The lead handles the work from here.`;
2679
+ output = `✓ The project was successfully created on your earlier \`${startedProjectOrJobThisTurn.tool}\` call this turn — kickoff is complete and the lead is on it.\n\nOriginal result:\n${startedProjectOrJobThisTurn.firstResult}\n\nSTOP — do NOT emit any more tool calls this turn. Each project-start call creates a real project, lead, and kickoff task; repeating the macro would create duplicates. END YOUR TURN NOW with a one-sentence summary to the user (e.g. "Project is underway — the crew lead is on it"). The lead handles the work from here.`;
2670
2680
  if (projectMacroInterceptCount >= PROJECT_MACRO_INTERCEPT_CAP) {
2671
2681
  forceProjectMacroBail = {
2672
2682
  closingText: deriveProjectMacroClosing(startedProjectOrJobThisTurn.firstResult),
@@ -56,6 +56,21 @@ export declare function templateTextOpensReasoning(template: string): TemplateRe
56
56
  * into the reasoning pane. Absent means on, matching the engine's default.
57
57
  */
58
58
  export declare function requestOpensReasoning(templateOpen: TemplateReasoningOpen | undefined, body: Record<string, unknown>): boolean;
59
+ /**
60
+ * Restore the reasoning opener the chat template supplied, before the
61
+ * end-of-turn reasoning pass.
62
+ *
63
+ * When the rendered prompt left generation inside a reasoning block, the
64
+ * model's text starts mid-thought and carries only the closer. The live split
65
+ * knows that, but `extractReasoning` reads a lone `<channel|>` as stray and
66
+ * keeps the thoughts as the reply: Gemma 4 E4B, after a tool response, saved
67
+ * "The user wants to know…I need to answer in one sentence.The launch is on
68
+ * Friday…", and the stall check then asked it to answer again.
69
+ *
70
+ * Unchanged when the turn did not open in reasoning, when the model opened a
71
+ * block itself, or when no closer arrived.
72
+ */
73
+ export declare function reopenTemplateReasoning(text: string, opensInReasoning: boolean): string;
59
74
  export interface ReasoningSplitChunk {
60
75
  visible: string;
61
76
  reasoning: string;
@@ -112,6 +112,41 @@ export function requestOpensReasoning(templateOpen, body) {
112
112
  return true;
113
113
  return kwargs.enable_thinking !== false;
114
114
  }
115
+ /** The opener `extractReasoning` pairs with each closer a template-opened turn emits. */
116
+ const OPENER_FOR_CLOSER = [
117
+ ['</think>', '<think>'],
118
+ ['</reasoning>', '<reasoning>'],
119
+ ['[/THINK]', '[THINK]'],
120
+ ['<channel|>', '<|channel>thought\n'],
121
+ ['<|end|>', '<|channel|>analysis<|message|>'],
122
+ ];
123
+ /**
124
+ * Restore the reasoning opener the chat template supplied, before the
125
+ * end-of-turn reasoning pass.
126
+ *
127
+ * When the rendered prompt left generation inside a reasoning block, the
128
+ * model's text starts mid-thought and carries only the closer. The live split
129
+ * knows that, but `extractReasoning` reads a lone `<channel|>` as stray and
130
+ * keeps the thoughts as the reply: Gemma 4 E4B, after a tool response, saved
131
+ * "The user wants to know…I need to answer in one sentence.The launch is on
132
+ * Friday…", and the stall check then asked it to answer again.
133
+ *
134
+ * Unchanged when the turn did not open in reasoning, when the model opened a
135
+ * block itself, or when no closer arrived.
136
+ */
137
+ export function reopenTemplateReasoning(text, opensInReasoning) {
138
+ if (!opensInReasoning || /^\s*(?:<think>|<reasoning>|\[THINK\]|<\|?channel\|?>)/i.test(text)) {
139
+ return text;
140
+ }
141
+ const lower = text.toLowerCase();
142
+ let first = null;
143
+ for (const [closer, opener] of OPENER_FOR_CLOSER) {
144
+ const index = lower.indexOf(closer.toLowerCase());
145
+ if (index !== -1 && (first === null || index < first.index))
146
+ first = { index, opener };
147
+ }
148
+ return first ? `${first.opener}${text}` : text;
149
+ }
115
150
  /**
116
151
  * Incremental reasoning splitter for a streamed MLX turn.
117
152
  *
@@ -814,14 +814,20 @@ export function resolveLlamaCppContextRequirement(opts) {
814
814
  const strictModelMax = opts.contextSizing === 'model-max' && opts.explicitContextWindow === undefined;
815
815
  const requestedContextWindow = opts.explicitContextWindow ??
816
816
  (strictModelMax ? opts.modelContextWindow : opts.adaptiveContextWindow);
817
+ // Env, per-model and machine-wide numeric settings all express deliberate
818
+ // operator intent. The automatic host floor must not silently turn a 32K
819
+ // memory-saving request back into 64K. Resolve this here so launch and
820
+ // preview cannot apply different floors to the same explicit request.
821
+ const hostFloor = opts.minViableContextTokens ?? minViableLocalContextTokens();
822
+ const minimum = opts.explicitContextWindow !== undefined && opts.explicitContextWindow > 0
823
+ ? Math.min(hostFloor, opts.explicitContextWindow)
824
+ : hostFloor;
817
825
  const resolved = resolveLocalContextRequirement({
818
826
  ...(opts.modelContextWindow !== undefined
819
827
  ? { modelContextWindow: opts.modelContextWindow }
820
828
  : {}),
821
829
  ...(requestedContextWindow !== undefined ? { requestedContextWindow } : {}),
822
- ...(opts.minViableContextTokens !== undefined
823
- ? { minViableContextTokens: opts.minViableContextTokens }
824
- : {}),
830
+ minViableContextTokens: minimum,
825
831
  });
826
832
  if (strictModelMax) {
827
833
  return {
@@ -223,11 +223,19 @@ export class LocalEngineRuntime {
223
223
  return null;
224
224
  if (this.engineRouterInitPromise)
225
225
  return this.engineRouterInitPromise;
226
- this.engineRouterInitPromise = this.buildEngineRouter().then((r) => {
226
+ const pending = this.buildEngineRouter().then((r) => {
227
227
  this.engineRouterCache = r;
228
228
  return r;
229
+ }, (err) => {
230
+ // A failed build must not be cached. One that ran while a dev rebuild
231
+ // had emptied dist/ failed every later local turn with "Cannot find
232
+ // module …engine-router.js" until the app restarted (2026-10-19).
233
+ if (this.engineRouterInitPromise === pending)
234
+ this.engineRouterInitPromise = null;
235
+ throw err;
229
236
  });
230
- return this.engineRouterInitPromise;
237
+ this.engineRouterInitPromise = pending;
238
+ return pending;
231
239
  }
232
240
  async buildEngineRouter() {
233
241
  const { EngineRouter } = await import('./engine-router.js');
@@ -1136,17 +1144,12 @@ export class LocalEngineRuntime {
1136
1144
  const manifestEngineConfig = await resolveCatalogLlamaCppEngineConfig(this.catalog, modelId);
1137
1145
  const perModelCtxOverride = config.modelContextOverrides?.[`llama-cpp:${modelId}`];
1138
1146
  const explicitContextWindow = envNumCtx ?? perModelCtxOverride ?? config.llamaCppNumCtx;
1139
- // A per-model override below the host floor is deliberate user intent —
1140
- // lower the admission floor to the override instead of silently raising
1141
- // the request back to 64K. Env / machine-wide values keep their
1142
- // historical floor semantics. Mirrors buildLlamaCppProvider.
1147
+ // The shared resolver honors every explicit numeric context below the
1148
+ // host floor. Keep per-model override state for the Settings auto marker.
1143
1149
  const overrideActive = perModelCtxOverride !== undefined && explicitContextWindow === perModelCtxOverride;
1144
- const minViableTokens = overrideActive
1145
- ? Math.min(contextFloor, perModelCtxOverride)
1146
- : contextFloor;
1147
1150
  const contextRequirement = resolveLlamaCppContextRequirement({
1148
1151
  modelContextWindow: installed.contextWindow,
1149
- minViableContextTokens: minViableTokens,
1152
+ minViableContextTokens: contextFloor,
1150
1153
  ...(explicitContextWindow !== undefined ? { explicitContextWindow } : {}),
1151
1154
  ...(manifestEngineConfig?.contextSize !== undefined
1152
1155
  ? {
@@ -1162,7 +1165,7 @@ export class LocalEngineRuntime {
1162
1165
  // per-model override deliberately does NOT short-circuit on a resident
1163
1166
  // engine: the full plan must run so a stale resident window surfaces as
1164
1167
  // restart-required instead of masquerading as the applied setting.
1165
- const shortCircuit = (residentContextWindow !== undefined && !overrideActive) || envNumCtx !== undefined;
1168
+ const shortCircuit = residentContextWindow !== undefined && !overrideActive;
1166
1169
  const { defaultLocalEngineSlots, estimatePerSlotKvBytes, kvQuantScale, llamaCppSlotCeiling, planAdaptiveContextGrowth, planCtxTokensForMemory, plannedLocalEngineSlots, } = await import('./capacity-broker.js');
1167
1170
  const capacity = await this.previewCapacityInputs('llama-cpp', modelId, capacityOpts);
1168
1171
  const { budgetBytes: admissionBudgetBytes, fastBudgetBytes, committedOtherBytes } = capacity;
@@ -1587,7 +1590,7 @@ export class LocalEngineRuntime {
1587
1590
  }
1588
1591
  return { grantedCtx, slots, kvCacheType: kv, plannedFieldsOk: true };
1589
1592
  };
1590
- const plan = llamaPlanPass(explicitContextWindow, minViableTokens);
1593
+ const plan = llamaPlanPass(explicitContextWindow, contextFloor);
1591
1594
  let autoContextWindow;
1592
1595
  if (overrideActive) {
1593
1596
  try {
@@ -289,6 +289,14 @@ export declare class NativeEngineSupervisor {
289
289
  private currentOomKills;
290
290
  private readonly logListeners;
291
291
  private recentStarts;
292
+ /**
293
+ * The {@link recentStarts} entry for the child running now. A child that
294
+ * became ready and was then stopped on purpose (idle, memory pressure, a
295
+ * model swap) was not a crash, so its start is returned to the budget.
296
+ * Otherwise an engine asked to swap models or yield memory three times in
297
+ * a minute would refuse the fourth start as a crash loop.
298
+ */
299
+ private currentStartAt;
292
300
  private lastUsedAt;
293
301
  /**
294
302
  * The same mark on the awake clock. Every idle/pressure DECISION reads this
@@ -25,7 +25,7 @@ import { readFileSync } from 'node:fs';
25
25
  import { basename } from 'node:path';
26
26
  import { awakeNow, createLogger } from '@bendyline/gezel';
27
27
  import { listProcessSnapshots } from '@bendyline/gezel-client/node';
28
- import { windowsHeadlessSpawnOptions } from '@bendyline/gezel/native';
28
+ import { diagnoseDllLoadFailure, windowsHeadlessSpawnOptions } from '@bendyline/gezel/native';
29
29
  import { acquireNativeCapacity, } from './device-capacity.js';
30
30
  const log = createLogger('native');
31
31
  /**
@@ -55,7 +55,9 @@ const RESTART_WINDOW_MS = 60_000;
55
55
  /**
56
56
  * Ceiling on `recoverStartup` retries within one start. Two covers the
57
57
  * full MoE degradation ladder (partial split → all experts to RAM →
58
- * engine-owned fit); a hook that keeps asking past that is looping.
58
+ * engine-owned fit), or one slot and one offload rung; a hook that keeps
59
+ * asking past that is looping. Every failed start also spends the restart
60
+ * budget, which refuses a fourth start inside its window anyway.
59
61
  */
60
62
  const MAX_STARTUP_RECOVERIES = 2;
61
63
  const HEALTH_FAIL_THRESHOLD = 3;
@@ -202,6 +204,14 @@ export class NativeEngineSupervisor {
202
204
  // swallowed so a buggy parser can't take down the supervisor.
203
205
  logListeners = new Set();
204
206
  recentStarts = [];
207
+ /**
208
+ * The {@link recentStarts} entry for the child running now. A child that
209
+ * became ready and was then stopped on purpose (idle, memory pressure, a
210
+ * model swap) was not a crash, so its start is returned to the budget.
211
+ * Otherwise an engine asked to swap models or yield memory three times in
212
+ * a minute would refuse the fourth start as a crash loop.
213
+ */
214
+ currentStartAt;
205
215
  lastUsedAt = 0;
206
216
  /**
207
217
  * The same mark on the awake clock. Every idle/pressure DECISION reads this
@@ -483,7 +493,11 @@ export class NativeEngineSupervisor {
483
493
  const { child } = this.state;
484
494
  if (this.state.kind === 'running' && reason !== 'health-restart') {
485
495
  await this.runBeforeStop(reason, this.state.launch.baseUrl);
496
+ const index = this.currentStartAt === undefined ? -1 : this.recentStarts.indexOf(this.currentStartAt);
497
+ if (index >= 0)
498
+ this.recentStarts.splice(index, 1);
486
499
  }
500
+ this.currentStartAt = undefined;
487
501
  this.pressureDeadlineAt = undefined;
488
502
  this.expectedExitReason = reason;
489
503
  this.state = { kind: 'stopped' };
@@ -579,7 +593,9 @@ export class NativeEngineSupervisor {
579
593
  }
580
594
  });
581
595
  }
582
- this.recentStarts.push(Date.now());
596
+ const startedAt = Date.now();
597
+ this.recentStarts.push(startedAt);
598
+ this.currentStartAt = startedAt;
583
599
  let child;
584
600
  try {
585
601
  child = this.spawn(launch.command, launch.args, {
@@ -1019,6 +1035,21 @@ export class NativeEngineSupervisor {
1019
1035
  // shortage, and the GPU-to-RAM ladder those lines trigger cannot help
1020
1036
  // when RAM is what ran out.
1021
1037
  const oomKilled = signal === 'SIGKILL' && !expected ? this.oomKillsSince(this.currentOomKills) : null;
1038
+ // Windows reports a DLL the engine could not load only as a status, before
1039
+ // the engine prints a word. Name the DLL. A missing machine-wide runtime is
1040
+ // a panic of its own, so no build is quarantined for it (missing-dll.ts).
1041
+ const dllFailure = process.platform === 'win32' &&
1042
+ priorState.kind === 'starting' &&
1043
+ !expected &&
1044
+ !this.currentReachedReady &&
1045
+ !this.currentPanic
1046
+ ? diagnoseDllLoadFailure(code, priorState.launch.command, {
1047
+ ...process.env,
1048
+ ...(priorState.launch.env ?? {}),
1049
+ })
1050
+ : null;
1051
+ if (dllFailure)
1052
+ this.onLog(`${this.logPrefix} startup DLL check: ${dllFailure.reason}`);
1022
1053
  const panic = oomKilled
1023
1054
  ? {
1024
1055
  kind: 'host-out-of-memory',
@@ -1030,7 +1061,9 @@ export class NativeEngineSupervisor {
1030
1061
  kind: 'illegal-instruction',
1031
1062
  line: 'engine terminated by SIGILL (illegal instruction) with no diagnostic output',
1032
1063
  }
1033
- : undefined));
1064
+ : dllFailure?.machineWide
1065
+ ? { kind: 'missing-runtime', line: dllFailure.summary }
1066
+ : undefined));
1034
1067
  const snapshot = {
1035
1068
  incidentId: `native-${pid ?? 'unknown'}-${exitedAt}`,
1036
1069
  ...(pid !== undefined ? { pid } : {}),
@@ -1043,6 +1076,15 @@ export class NativeEngineSupervisor {
1043
1076
  reachedReady: this.currentReachedReady,
1044
1077
  ...(expectedReason ? { expectedReason } : {}),
1045
1078
  ...(panic ? { panicKind: panic.kind, panicLine: panic.line } : {}),
1079
+ ...(dllFailure
1080
+ ? {
1081
+ dllLoadFailure: {
1082
+ kind: dllFailure.kind,
1083
+ ...(dllFailure.dll ? { dll: dllFailure.dll } : {}),
1084
+ summary: dllFailure.summary,
1085
+ },
1086
+ }
1087
+ : {}),
1046
1088
  outputTail: this.currentOutput,
1047
1089
  ...(this.currentDiagnostics ? { diagnostics: { ...this.currentDiagnostics } } : {}),
1048
1090
  };
@@ -1103,7 +1145,15 @@ export class NativeEngineSupervisor {
1103
1145
  // call wins because it lands first (the classifier sees the leaf
1104
1146
  // exception line slightly before the kernel reports the exit).
1105
1147
  if (this.startupAbort && priorState.kind === 'starting') {
1106
- this.startupAbort.abort(new Error(`${this.logPrefix} child exited (code=${code} signal=${signal ?? 'none'}) before becoming ready`));
1148
+ this.startupAbort.abort(dllFailure
1149
+ ? Object.assign(new Error(`${this.logPrefix} could not start: ${dllFailure.summary}`), {
1150
+ // The engine never came up, and the summary says what to do, so
1151
+ // callers pass it through unchanged.
1152
+ code: ENGINE_LAUNCH_ERROR_CODE,
1153
+ isActionable: true,
1154
+ ...(panic?.kind === 'missing-runtime' ? { panicKind: panic.kind } : {}),
1155
+ })
1156
+ : new Error(`${this.logPrefix} child exited (code=${code} signal=${signal ?? 'none'}) before becoming ready`));
1107
1157
  }
1108
1158
  this.state = { kind: 'stopped' };
1109
1159
  }
@@ -6,12 +6,14 @@ export const PROJECT_MACRO_FAILURE_CAP = 2;
6
6
  /** Derive a concise user-facing closing from a successful kickoff result. */
7
7
  export function deriveProjectMacroClosing(firstResult) {
8
8
  const projectMatch = firstResult.match(/Started (?:project|job) "([^"]+)"/);
9
- const leadMatch = firstResult.match(/Recruited (\S+) as (voorman|builder|lead)/i);
9
+ // "voorman" is what results said before the crew lead was renamed.
10
+ const leadMatch = firstResult.match(/Recruited (\S+) as (crew lead|voorman|builder|lead)/i);
10
11
  const projectName = projectMatch?.[1];
11
12
  const leadName = leadMatch?.[1];
12
- const leadRole = leadMatch?.[2];
13
+ const leadRole = leadMatch?.[2]?.toLowerCase();
13
14
  if (projectName && leadName) {
14
- const trailer = leadRole === 'voorman' ? ' is leading the crew' : ' is on it';
15
+ const crewLead = leadRole === 'crew lead' || leadRole === 'voorman';
16
+ const trailer = crewLead ? ' is leading the crew' : ' is on it';
15
17
  return `Project "${projectName}" is kicked off — ${leadName}${trailer}. You can watch their work surface in this thread.`;
16
18
  }
17
19
  if (projectName) {