@bendyline/gezel-inference 1.0.1 → 1.0.3

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 (264) 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/ne/nemotron3.5-bolt-74b-iq2/manifest.json +157 -0
  8. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/versions/1.0.0/manifest.json +30 -0
  9. package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/manifest.json +156 -0
  10. package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/versions/1.0.0/manifest.json +28 -0
  11. package/dist/catalog/chat-models/raw-index.json +1 -1
  12. package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/keywords.json +56 -0
  13. package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/keywords.json +12 -0
  14. package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/keywords.json +13 -0
  15. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/keywords.json +14 -0
  16. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/keywords.json +17 -0
  17. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/keywords.json +12 -0
  18. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/keywords.json +12 -0
  19. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/keywords.json +12 -0
  20. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/keywords.json +12 -0
  21. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/keywords.json +12 -0
  22. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/keywords.json +12 -0
  23. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/keywords.json +12 -0
  24. package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/keywords.json +12 -0
  25. package/dist/catalog/knowledge-catalogs/index.json +1 -1
  26. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/keywords.json +21 -0
  27. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/keywords.json +27 -0
  28. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/keywords.json +23 -0
  29. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/keywords.json +26 -0
  30. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/keywords.json +28 -0
  31. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/keywords.json +29 -0
  32. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/keywords.json +21 -0
  33. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/keywords.json +14 -0
  34. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/keywords.json +20 -0
  35. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/keywords.json +24 -0
  36. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/keywords.json +27 -0
  37. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/keywords.json +18 -0
  38. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/keywords.json +28 -0
  39. package/dist/catalog/knowledge-catalogs/raw-index.json +1 -1
  40. package/dist/catalog/knowledge-catalogs/re/regional-american-south/keywords.json +1700 -0
  41. package/dist/catalog/knowledge-catalogs/re/regional-american-south/versions/2026.10.5/manifest.json +133 -0
  42. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/keywords.json +750 -0
  43. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/versions/2026.10.5/manifest.json +133 -0
  44. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/keywords.json +1281 -0
  45. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/versions/2026.10.5/manifest.json +133 -0
  46. package/dist/catalog/knowledge-catalogs/re/regional-brazil/keywords.json +1125 -0
  47. package/dist/catalog/knowledge-catalogs/re/regional-brazil/versions/2026.10.5/manifest.json +133 -0
  48. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/keywords.json +3287 -0
  49. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/versions/2026.10.5/manifest.json +133 -0
  50. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/keywords.json +1835 -0
  51. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/versions/2026.10.5/manifest.json +133 -0
  52. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/keywords.json +1184 -0
  53. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/versions/2026.10.5/manifest.json +133 -0
  54. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/keywords.json +1503 -0
  55. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/versions/2026.10.5/manifest.json +133 -0
  56. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/keywords.json +2836 -0
  57. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/versions/2026.10.5/manifest.json +133 -0
  58. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/keywords.json +813 -0
  59. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/versions/2026.10.5/manifest.json +133 -0
  60. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/keywords.json +2082 -0
  61. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/versions/2026.10.5/manifest.json +133 -0
  62. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/keywords.json +1481 -0
  63. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/versions/2026.10.5/manifest.json +133 -0
  64. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/keywords.json +1272 -0
  65. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/versions/2026.10.5/manifest.json +133 -0
  66. package/dist/catalog/knowledge-catalogs/re/regional-midwest/keywords.json +758 -0
  67. package/dist/catalog/knowledge-catalogs/re/regional-midwest/versions/2026.10.5/manifest.json +133 -0
  68. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/keywords.json +896 -0
  69. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/versions/2026.10.5/manifest.json +133 -0
  70. package/dist/catalog/knowledge-catalogs/re/regional-northeast/keywords.json +1281 -0
  71. package/dist/catalog/knowledge-catalogs/re/regional-northeast/versions/2026.10.5/manifest.json +133 -0
  72. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/keywords.json +346 -0
  73. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/versions/2026.10.5/manifest.json +133 -0
  74. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/keywords.json +2688 -0
  75. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/versions/2026.10.5/manifest.json +133 -0
  76. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/keywords.json +973 -0
  77. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/versions/2026.10.5/manifest.json +133 -0
  78. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/keywords.json +937 -0
  79. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/versions/2026.10.5/manifest.json +133 -0
  80. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/keywords.json +608 -0
  81. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/versions/2026.10.5/manifest.json +133 -0
  82. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/keywords.json +633 -0
  83. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/versions/2026.10.5/manifest.json +133 -0
  84. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/keywords.json +2697 -0
  85. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/versions/2026.10.5/manifest.json +133 -0
  86. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/keywords.json +606 -0
  87. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/versions/2026.10.5/manifest.json +133 -0
  88. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/keywords.json +564 -0
  89. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/versions/2026.10.5/manifest.json +133 -0
  90. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/keywords.json +3247 -0
  91. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/manifest.json +47 -0
  92. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/versions/2026.10.5/manifest.json +133 -0
  93. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/manifest.json +47 -0
  94. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/versions/2026.10.5/manifest.json +133 -0
  95. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/keywords.json +5437 -0
  96. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/manifest.json +1 -1
  97. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.10.1/manifest.json +181 -0
  98. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/keywords.json +4009 -0
  99. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/manifest.json +1 -1
  100. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.10.1/manifest.json +181 -0
  101. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/keywords.json +4009 -0
  102. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/manifest.json +1 -1
  103. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.10.1/manifest.json +217 -0
  104. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/keywords.json +5583 -0
  105. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/manifest.json +1 -1
  106. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.10.1/manifest.json +197 -0
  107. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/keywords.json +6386 -0
  108. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/manifest.json +2 -2
  109. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.10.1/manifest.json +197 -0
  110. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/keywords.json +4009 -0
  111. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/manifest.json +1 -1
  112. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.10.1/manifest.json +185 -0
  113. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/keywords.json +5672 -0
  114. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/manifest.json +1 -1
  115. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.10.1/manifest.json +137 -0
  116. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/manifest.json +68 -0
  117. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/versions/2026.10.1/manifest.json +217 -0
  118. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/manifest.json +68 -0
  119. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/versions/2026.10.1/manifest.json +217 -0
  120. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/keywords.json +4009 -0
  121. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/manifest.json +1 -1
  122. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.10.1/manifest.json +141 -0
  123. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/keywords.json +4009 -0
  124. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/manifest.json +1 -1
  125. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.10.1/manifest.json +185 -0
  126. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/keywords.json +5719 -0
  127. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/manifest.json +1 -1
  128. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.10.1/manifest.json +193 -0
  129. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/keywords.json +4009 -0
  130. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/manifest.json +1 -1
  131. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.10.1/manifest.json +189 -0
  132. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/keywords.json +16009 -0
  133. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/manifest.json +1 -1
  134. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.10.1/manifest.json +185 -0
  135. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/keywords.json +5843 -0
  136. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/manifest.json +1 -1
  137. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.10.1/manifest.json +189 -0
  138. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/keywords.json +6264 -0
  139. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/manifest.json +1 -1
  140. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.10.1/manifest.json +197 -0
  141. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/manifest.json +66 -0
  142. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/versions/2026.10.1/manifest.json +209 -0
  143. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/manifest.json +61 -0
  144. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/versions/2026.10.1/manifest.json +189 -0
  145. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/manifest.json +64 -0
  146. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/versions/2026.10.1/manifest.json +201 -0
  147. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/manifest.json +60 -0
  148. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/versions/2026.10.1/manifest.json +185 -0
  149. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/manifest.json +55 -0
  150. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/versions/2026.10.1/manifest.json +165 -0
  151. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/manifest.json +63 -0
  152. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/versions/2026.10.1/manifest.json +197 -0
  153. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/manifest.json +64 -0
  154. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/versions/2026.10.1/manifest.json +201 -0
  155. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/manifest.json +65 -0
  156. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/versions/2026.10.1/manifest.json +205 -0
  157. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/manifest.json +73 -0
  158. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/versions/2026.10.1/manifest.json +237 -0
  159. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/keywords.json +5447 -0
  160. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/manifest.json +1 -1
  161. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.10.1/manifest.json +197 -0
  162. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/keywords.json +4009 -0
  163. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/manifest.json +1 -1
  164. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.10.1/manifest.json +189 -0
  165. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/keywords.json +4009 -0
  166. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/manifest.json +1 -1
  167. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.10.1/manifest.json +185 -0
  168. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/keywords.json +5209 -0
  169. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/manifest.json +1 -1
  170. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.10.1/manifest.json +193 -0
  171. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/keywords.json +6537 -0
  172. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/manifest.json +1 -1
  173. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.10.1/manifest.json +185 -0
  174. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/keywords.json +5989 -0
  175. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/manifest.json +1 -1
  176. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.10.1/manifest.json +189 -0
  177. package/dist/catalog/provenance.json +1 -1
  178. package/dist/engines/native-file-manifest.json +483 -413
  179. package/dist/engines/native-manifest.d.ts +4 -4
  180. package/dist/engines/native-manifest.js +36 -34
  181. package/dist/engines/resolver.js +3 -1
  182. package/dist/fs/atomic.d.ts +4 -1
  183. package/dist/fs/atomic.js +7 -1
  184. package/dist/http/openai-compat/chat-target.d.ts +1 -1
  185. package/dist/http/openai-compat/chat-target.js +1 -1
  186. package/dist/http/openai-compat/engine-failure.d.ts +25 -0
  187. package/dist/http/openai-compat/engine-failure.js +76 -0
  188. package/dist/http/openai-compat/responses-streaming.js +2 -1
  189. package/dist/http/openai-compat/responses-translate.d.ts +1 -1
  190. package/dist/http/openai-compat/translate.d.ts +1 -1
  191. package/dist/http/routes/engines.js +35 -0
  192. package/dist/http/routes/v1-chat.js +11 -2
  193. package/dist/http/routes/v1-knowledge.js +4 -0
  194. package/dist/http/routes/v1-models.js +6 -4
  195. package/dist/http/routes/v1-responses.d.ts +1 -1
  196. package/dist/http/routes/v1-responses.js +7 -1
  197. package/dist/inference-service.d.ts +6 -1
  198. package/dist/inference-service.js +20 -9
  199. package/dist/knowledge/catalog-host.d.ts +9 -1
  200. package/dist/knowledge/catalog-host.js +2 -0
  201. package/dist/knowledge/manager.d.ts +21 -0
  202. package/dist/knowledge/manager.js +85 -7
  203. package/dist/knowledge/search-worker.d.ts +1 -1
  204. package/dist/knowledge/spatial-query.d.ts +2 -3
  205. package/dist/knowledge/spatial-query.js +12 -6
  206. package/dist/knowledge/worker-host.js +2 -0
  207. package/dist/memory/embed-core.d.ts +16 -0
  208. package/dist/memory/embed-core.js +31 -0
  209. package/dist/memory/embed-worker.d.ts +7 -3
  210. package/dist/memory/embed-worker.js +13 -4
  211. package/dist/memory/embeddings.d.ts +17 -2
  212. package/dist/memory/embeddings.js +36 -7
  213. package/dist/models/ensure.d.ts +2 -0
  214. package/dist/models/ensure.js +9 -0
  215. package/dist/perf/responsiveness.d.ts +14 -1
  216. package/dist/perf/responsiveness.js +81 -10
  217. package/dist/providers/audio/kokoro-frontend.js +1 -1
  218. package/dist/providers/ds4/build-provider.js +6 -0
  219. package/dist/providers/llama-cpp/backend-health.d.ts +30 -0
  220. package/dist/providers/llama-cpp/backend-health.js +64 -0
  221. package/dist/providers/llama-cpp/backend-quarantine.d.ts +40 -0
  222. package/dist/providers/llama-cpp/backend-quarantine.js +100 -0
  223. package/dist/providers/llama-cpp/build-provider.js +247 -199
  224. package/dist/providers/llama-cpp/cache-adapter.d.ts +7 -1
  225. package/dist/providers/llama-cpp/cache-adapter.js +11 -1
  226. package/dist/providers/llama-cpp/devices.d.ts +22 -2
  227. package/dist/providers/llama-cpp/devices.js +48 -5
  228. package/dist/providers/llama-cpp/engine-flags.d.ts +0 -18
  229. package/dist/providers/llama-cpp/engine-flags.js +12 -18
  230. package/dist/providers/llama-cpp/gguf-metadata.js +20 -3
  231. package/dist/providers/llama-cpp/gpu-startup-watch.d.ts +41 -0
  232. package/dist/providers/llama-cpp/gpu-startup-watch.js +58 -0
  233. package/dist/providers/llama-cpp/models.d.ts +6 -0
  234. package/dist/providers/llama-cpp/models.js +23 -2
  235. package/dist/providers/llama-cpp/offload-planner.d.ts +26 -18
  236. package/dist/providers/llama-cpp/offload-planner.js +30 -14
  237. package/dist/providers/llama-cpp/provider.d.ts +22 -3
  238. package/dist/providers/llama-cpp/provider.js +39 -3
  239. package/dist/providers/mlx/provider.js +5 -6
  240. package/dist/providers/mlx/python/qwen4_ple.py +9 -2
  241. package/dist/providers/mlx/reasoning-stream.d.ts +15 -0
  242. package/dist/providers/mlx/reasoning-stream.js +35 -0
  243. package/dist/providers/native/capacity-broker.d.ts +21 -15
  244. package/dist/providers/native/capacity-broker.js +25 -13
  245. package/dist/providers/native/capacity-budget.d.ts +35 -3
  246. package/dist/providers/native/capacity-budget.js +49 -5
  247. package/dist/providers/native/device-capacity.d.ts +1 -1
  248. package/dist/providers/native/device-capacity.js +23 -5
  249. package/dist/providers/native/local-engine-runtime.js +31 -31
  250. package/dist/providers/native/measured-budget.js +2 -0
  251. package/dist/providers/native/supervisor.d.ts +25 -0
  252. package/dist/providers/native/supervisor.js +62 -8
  253. package/dist/providers/queue.d.ts +9 -2
  254. package/dist/providers/queue.js +17 -2
  255. package/dist/providers/session-hooks.d.ts +4 -1
  256. package/dist/system/amdgpu-adapters.d.ts +18 -0
  257. package/dist/system/amdgpu-adapters.js +55 -0
  258. package/dist/system/gpu-carve-out.d.ts +84 -0
  259. package/dist/system/gpu-carve-out.js +111 -0
  260. package/dist/system/memory.d.ts +17 -1
  261. package/dist/system/memory.js +94 -13
  262. package/dist/transformers-cache.d.ts +2 -0
  263. package/dist/transformers-cache.js +6 -3
  264. package/package.json +5 -5
@@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { readdir, stat } from 'node:fs/promises';
3
3
  import { homedir, totalmem } from 'node:os';
4
4
  import { join } from 'node:path';
5
- import { GEZEL_VERSION, NativeCapacityCommandSchema, NativeCapacityReplySchema, awakeNow, createLogger, isUnstampedDevBuild, } from '@bendyline/gezel';
5
+ import { DS4_FULL_RESIDENCY_HEADROOM_BYTES, GEZEL_VERSION, NativeCapacityCommandSchema, NativeCapacityReplySchema, awakeNow, createLogger, isUnstampedDevBuild, } from '@bendyline/gezel';
6
6
  import { readSystemServiceRuntime, systemServiceHome } from '@bendyline/gezel-client/node';
7
7
  import { ConfigStore } from '../../fs/config-store.js';
8
8
  import { createPinnedFetch } from '../../remotes/pinned-fetch.js';
@@ -119,21 +119,39 @@ export function configuredEngineMemoryBytes(config) {
119
119
  ? config.localEngineMemoryGb * GIB
120
120
  : undefined;
121
121
  }
122
+ /**
123
+ * GPU bytes a unified host may commit to one launch. macOS keeps 0.75 × RAM,
124
+ * near where Metal's recommended GPU working set sits. Linux unified hosts
125
+ * (DGX Spark GB10) have no such limit, so a large one may commit all but the
126
+ * OS reserve ds4's residency gate keeps: on a 121.6 GiB Spark, 0.75 × RAM
127
+ * (91.2 GiB) refused a GLM 5.3 Q2 launch that runs at 105 GiB with ~9 GiB to
128
+ * spare. Smaller Linux hosts stay on the 0.75 curve, which is the larger one there.
129
+ */
130
+ function unifiedGpuCeilingBytes(ramBytes, platform) {
131
+ const curve = ramBytes * 0.75;
132
+ return platform === 'linux'
133
+ ? Math.max(curve, ramBytes - DS4_FULL_RESIDENCY_HEADROOM_BYTES)
134
+ : curve;
135
+ }
122
136
  /**
123
137
  * The ledger's static ceilings: a request above either is refused at acquire,
124
138
  * whatever else is running. Shared with the media fit check so a model the
125
139
  * download pages hide is exactly one the launch path refuses. Omit
126
140
  * `configuredBytes` for the machine's automatic ceilings.
127
141
  */
128
- export function staticCapacityCeilings(budget, ramBytes, configuredBytes) {
142
+ export function staticCapacityCeilings(budget, ramBytes, configuredBytes, platform = process.platform) {
129
143
  const budgetBytes = configuredBytes === undefined
130
144
  ? budget.budgetBytes
131
145
  : Math.min(configuredBytes, budget.budgetBytes);
132
146
  return {
133
147
  budgetBytes,
134
- // Keep non-reclaimable accelerator commitments on the conservative curve;
135
- // a larger RAM budget is not permission to wire the whole machine.
136
- gpuBudgetBytes: Math.min(budgetBytes, budget.kind === 'unified' ? Math.min(budget.fastBytes, ramBytes * 0.75) : budget.fastBytes),
148
+ // Non-reclaimable accelerator commitments get their own ceiling: a larger
149
+ // RAM budget is not permission to wire the whole machine. An integrated
150
+ // GPU's carve-out (`vramBytes` on a unified host) is already the GPU's,
151
+ // and sits outside `ramBytes`.
152
+ gpuBudgetBytes: Math.min(budgetBytes, budget.kind === 'unified'
153
+ ? Math.min(budget.fastBytes, unifiedGpuCeilingBytes(ramBytes, platform) + budget.vramBytes)
154
+ : budget.fastBytes),
137
155
  };
138
156
  }
139
157
  export async function sampleDeviceCapacity(home) {
@@ -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');
@@ -260,6 +268,8 @@ export class LocalEngineRuntime {
260
268
  ? {
261
269
  unifiedMemory: memoryProfile.gpuMemoryKind === 'integrated' ||
262
270
  memoryProfile.gpuMemoryKind === 'unified',
271
+ reservedGpuBytes: memoryProfile.gpuReservedBytes ?? null,
272
+ gpuAddressableBytes: memoryProfile.gpuAddressableBytes ?? null,
263
273
  }
264
274
  : {}),
265
275
  allowRamSpillover: config.allowRamSpillover ?? null,
@@ -1134,17 +1144,12 @@ export class LocalEngineRuntime {
1134
1144
  const manifestEngineConfig = await resolveCatalogLlamaCppEngineConfig(this.catalog, modelId);
1135
1145
  const perModelCtxOverride = config.modelContextOverrides?.[`llama-cpp:${modelId}`];
1136
1146
  const explicitContextWindow = envNumCtx ?? perModelCtxOverride ?? config.llamaCppNumCtx;
1137
- // A per-model override below the host floor is deliberate user intent —
1138
- // lower the admission floor to the override instead of silently raising
1139
- // the request back to 64K. Env / machine-wide values keep their
1140
- // 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.
1141
1149
  const overrideActive = perModelCtxOverride !== undefined && explicitContextWindow === perModelCtxOverride;
1142
- const minViableTokens = overrideActive
1143
- ? Math.min(contextFloor, perModelCtxOverride)
1144
- : contextFloor;
1145
1150
  const contextRequirement = resolveLlamaCppContextRequirement({
1146
1151
  modelContextWindow: installed.contextWindow,
1147
- minViableContextTokens: minViableTokens,
1152
+ minViableContextTokens: contextFloor,
1148
1153
  ...(explicitContextWindow !== undefined ? { explicitContextWindow } : {}),
1149
1154
  ...(manifestEngineConfig?.contextSize !== undefined
1150
1155
  ? {
@@ -1160,8 +1165,8 @@ export class LocalEngineRuntime {
1160
1165
  // per-model override deliberately does NOT short-circuit on a resident
1161
1166
  // engine: the full plan must run so a stale resident window surfaces as
1162
1167
  // restart-required instead of masquerading as the applied setting.
1163
- const shortCircuit = (residentContextWindow !== undefined && !overrideActive) || envNumCtx !== undefined;
1164
- const { autoKvCacheMaxBytes, defaultLocalEngineSlots, estimatePerSlotKvBytes, kvQuantScale, llamaCppSlotCeiling, planAdaptiveContextGrowth, planCtxTokensForMemory, plannedLocalEngineSlots, } = await import('./capacity-broker.js');
1168
+ const shortCircuit = residentContextWindow !== undefined && !overrideActive;
1169
+ const { defaultLocalEngineSlots, estimatePerSlotKvBytes, kvQuantScale, llamaCppSlotCeiling, planAdaptiveContextGrowth, planCtxTokensForMemory, plannedLocalEngineSlots, } = await import('./capacity-broker.js');
1165
1170
  const capacity = await this.previewCapacityInputs('llama-cpp', modelId, capacityOpts);
1166
1171
  const { budgetBytes: admissionBudgetBytes, fastBudgetBytes, committedOtherBytes } = capacity;
1167
1172
  const configuredSlots = config.providerConcurrency?.['llama-cpp'];
@@ -1481,27 +1486,18 @@ export class LocalEngineRuntime {
1481
1486
  vramBytes: capacity.vramBytes,
1482
1487
  });
1483
1488
  // Mirror the launch path's windowed-cache admission (see
1484
- // buildLlamaCppProvider): when the launch will decline the Gemma
1485
- // `--swa-full` auto-default (or the windowed cache is pinned), the
1486
- // full-attention plan above overstates the real allocation — re-plan
1487
- // with the windowed linearization so the previewed window matches
1488
- // what the engine will actually grant.
1489
+ // buildLlamaCppProvider): unless `swaFull` is pinned, a
1490
+ // sliding-window model runs the windowed cache, which the
1491
+ // full-attention plan above overstates — re-plan with the windowed
1492
+ // linearization so the previewed window matches what the engine will
1493
+ // actually grant.
1489
1494
  // Strict model-max deliberately does NOT gate this: for SWA models
1490
1495
  // the windowed cache is the only layout whose native-window KV can
1491
1496
  // fit real machines, and the strict minimum rides inside
1492
1497
  // `requirement.minimumPerTurnCtxTokens`, so the windowed
1493
1498
  // re-plan sheds slots or denies but never shortens the window.
1494
1499
  const explicitSwaFull = config.llamaCppSwaFull ?? manifestEngineConfig?.swaFull;
1495
- const fullCacheOverCeiling = exactKvAtReference !== undefined &&
1496
- (exactKvAtReference / referenceCtx) * grantedCtx * slots > autoKvCacheMaxBytes();
1497
- const windowedCacheWillRun = (!admission.minimumSatisfied ||
1498
- admission.clamped ||
1499
- admission.slots < slots ||
1500
- fullCacheOverCeiling) &&
1501
- (explicitSwaFull === false ||
1502
- (explicitSwaFull === undefined &&
1503
- isGemmaModel({ architecture: installed.architecture, modelId })));
1504
- if (windowedCacheWillRun) {
1500
+ if (explicitSwaFull !== true) {
1505
1501
  const windowed = estimateWindowedKvLinearization({
1506
1502
  blockCount: summary.blockCount,
1507
1503
  embeddingLength: summary.embeddingLength,
@@ -1541,9 +1537,13 @@ export class LocalEngineRuntime {
1541
1537
  fixedPerSlotBytes: windowed.fixedBytes,
1542
1538
  };
1543
1539
  }
1544
- else if ((summary.slidingWindow ?? 0) > 0 || explicitSwaFull === undefined) {
1545
- // SWA model without a readable layout: the launch path leaves
1546
- // such a launch untouched — preview the requested window.
1540
+ else if ((!admission.minimumSatisfied || admission.clamped || admission.slots < slots) &&
1541
+ (explicitSwaFull === false
1542
+ ? (summary.slidingWindow ?? 0) > 0
1543
+ : isGemmaModel({ architecture: installed.architecture, modelId }))) {
1544
+ // SWA model without a readable layout, over budget on full
1545
+ // math: the launch path leaves such a launch untouched — preview
1546
+ // the requested window.
1547
1547
  return { grantedCtx, slots, kvCacheType: kv, plannedFieldsOk: false };
1548
1548
  }
1549
1549
  }
@@ -1590,7 +1590,7 @@ export class LocalEngineRuntime {
1590
1590
  }
1591
1591
  return { grantedCtx, slots, kvCacheType: kv, plannedFieldsOk: true };
1592
1592
  };
1593
- const plan = llamaPlanPass(explicitContextWindow, minViableTokens);
1593
+ const plan = llamaPlanPass(explicitContextWindow, contextFloor);
1594
1594
  let autoContextWindow;
1595
1595
  if (overrideActive) {
1596
1596
  try {
@@ -50,5 +50,7 @@ export async function measuredCapacityBudget() {
50
50
  systemRamBytes: profile.totalRamBytes,
51
51
  gpuVramBytes: profile.gpuVramBytes,
52
52
  unifiedMemory: profile.gpuMemoryKind === 'integrated' || profile.gpuMemoryKind === 'unified',
53
+ reservedGpuBytes: profile.gpuReservedBytes ?? null,
54
+ gpuAddressableBytes: profile.gpuAddressableBytes ?? null,
53
55
  });
54
56
  }
@@ -158,6 +158,11 @@ export interface NativeEngineSupervisorOptions {
158
158
  onLog?: (line: string) => void;
159
159
  /** Called for both expected and unexpected exits after a snapshot is sealed. */
160
160
  onExit?: (snapshot: NativeEngineExitSnapshot) => void | Promise<void>;
161
+ /**
162
+ * Called each time a start reaches readiness. Errors are caught and logged;
163
+ * a failing hook never fails the start.
164
+ */
165
+ onReady?: (launch: NativeEngineLaunch) => void;
161
166
  /**
162
167
  * Consulted after a start attempt fails (child died or never became
163
168
  * ready — not spawn errors, and not crashes after readiness). Return
@@ -214,6 +219,13 @@ export interface NativeEngineSupervisorOptions {
214
219
  psRunner?: () => Promise<NativeProcessSnapshot[]>;
215
220
  /** Platform seam for Windows owner-liveness semantics in orphan tests. */
216
221
  platform?: NodeJS.Platform;
222
+ /**
223
+ * The kernel's running count of out-of-memory kills, or null when it
224
+ * cannot be read. Compared across a child's life to tell Linux's
225
+ * out-of-memory killer from any other SIGKILL. Defaults to `oom_kill` in
226
+ * `/proc/vmstat` on Linux (any account can read it) and null elsewhere.
227
+ */
228
+ readOomKillCount?: () => number | null;
217
229
  /**
218
230
  * Test seam paired with `psRunner` — invoked instead of
219
231
  * `process.kill(pid, 'SIGKILL')`. Lets unit tests assert which pids
@@ -263,6 +275,7 @@ export declare class NativeEngineSupervisor {
263
275
  private readonly fetchImpl;
264
276
  private readonly onLog;
265
277
  private readonly onExit?;
278
+ private readonly onReady?;
266
279
  private readonly recoverStartup?;
267
280
  private readonly onRawLine?;
268
281
  private readonly logPrefix;
@@ -271,6 +284,9 @@ export declare class NativeEngineSupervisor {
271
284
  private readonly psRunner;
272
285
  private readonly killProcess;
273
286
  private readonly platform;
287
+ private readonly readOomKillCount;
288
+ /** `oom_kill` when the current child spawned; null where it cannot be read. */
289
+ private currentOomKills;
274
290
  private readonly logListeners;
275
291
  private recentStarts;
276
292
  private lastUsedAt;
@@ -482,6 +498,13 @@ export declare class NativeEngineSupervisor {
482
498
  */
483
499
  private runFreeze;
484
500
  private clearIdleTimer;
501
+ /**
502
+ * The counter's movement since `before`, when it rose. Another process
503
+ * killed in the same window would also move it, but a child that died by a
504
+ * SIGKILL this supervisor did not send while the counter rose is, in
505
+ * practice, the one the killer chose.
506
+ */
507
+ private oomKillsSince;
485
508
  private clearFreezeTimer;
486
509
  private clearHealthTimer;
487
510
  }
@@ -490,6 +513,8 @@ export declare function classifyNativeEnginePanic(line: string): {
490
513
  kind: NativeEnginePanicKind;
491
514
  line: string;
492
515
  } | undefined;
516
+ /** `oom_kill` from `/proc/vmstat` (Linux 4.13+), or null when it cannot be read. */
517
+ export declare function readLinuxOomKillCount(): number | null;
493
518
  /** Parse the portable `ps -axo pid=,ppid=,command=` shape. */
494
519
  export declare function parseNativeProcessSnapshot(stdout: string): NativeProcessSnapshot[];
495
520
  /** `code` stamped on every engine-launch failure. See {@link isEngineLaunchError}. */
@@ -21,6 +21,7 @@
21
21
  * so we can drive the lifecycle without a real binary.
22
22
  */
23
23
  import { spawn as nodeSpawn } from 'node:child_process';
24
+ import { readFileSync } from 'node:fs';
24
25
  import { basename } from 'node:path';
25
26
  import { awakeNow, createLogger } from '@bendyline/gezel';
26
27
  import { listProcessSnapshots } from '@bendyline/gezel-client/node';
@@ -54,7 +55,9 @@ const RESTART_WINDOW_MS = 60_000;
54
55
  /**
55
56
  * Ceiling on `recoverStartup` retries within one start. Two covers the
56
57
  * full MoE degradation ladder (partial split → all experts to RAM →
57
- * 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.
58
61
  */
59
62
  const MAX_STARTUP_RECOVERIES = 2;
60
63
  const HEALTH_FAIL_THRESHOLD = 3;
@@ -179,6 +182,7 @@ export class NativeEngineSupervisor {
179
182
  fetchImpl;
180
183
  onLog;
181
184
  onExit;
185
+ onReady;
182
186
  recoverStartup;
183
187
  onRawLine;
184
188
  logPrefix;
@@ -187,6 +191,9 @@ export class NativeEngineSupervisor {
187
191
  psRunner;
188
192
  killProcess;
189
193
  platform;
194
+ readOomKillCount;
195
+ /** `oom_kill` when the current child spawned; null where it cannot be read. */
196
+ currentOomKills = null;
190
197
  // Ad-hoc log listeners attached at runtime (vs. the construction-time
191
198
  // `onLog` / `onRawLine` hooks). Used by the owning provider to
192
199
  // subscribe to engine log lines for the duration of a single request
@@ -274,6 +281,8 @@ export class NativeEngineSupervisor {
274
281
  this.onLog = opts.onLog ?? ((line) => log.info(line));
275
282
  if (opts.onExit)
276
283
  this.onExit = opts.onExit;
284
+ if (opts.onReady)
285
+ this.onReady = opts.onReady;
277
286
  if (opts.recoverStartup)
278
287
  this.recoverStartup = opts.recoverStartup;
279
288
  if (opts.onRawLine)
@@ -282,6 +291,8 @@ export class NativeEngineSupervisor {
282
291
  this.readinessPath = opts.readinessPath ?? '/health';
283
292
  this.readyOnAnyResponse = opts.readyOnAnyResponse ?? false;
284
293
  this.platform = opts.platform ?? process.platform;
294
+ this.readOomKillCount =
295
+ opts.readOomKillCount ?? (this.platform === 'linux' ? readLinuxOomKillCount : () => null);
285
296
  this.psRunner = opts.psRunner ?? (() => defaultPsRunner(this.platform));
286
297
  this.killProcess = opts.killProcess ?? ((pid, sig) => process.kill(pid, sig));
287
298
  }
@@ -600,6 +611,7 @@ export class NativeEngineSupervisor {
600
611
  this.currentDiagnostics = launch.diagnostics ? { ...launch.diagnostics } : undefined;
601
612
  this.currentOutput = '';
602
613
  this.currentPanic = undefined;
614
+ this.currentOomKills = this.readOomKillCount();
603
615
  this.expectedExitReason = undefined;
604
616
  this.onLog(`${this.logPrefix} launch ${JSON.stringify({
605
617
  pid: this.currentPid ?? null,
@@ -698,6 +710,12 @@ export class NativeEngineSupervisor {
698
710
  this.state = { kind: 'running', launch, child, healthFails: 0 };
699
711
  this.resetIdleTimer();
700
712
  this.startHealthWatch();
713
+ try {
714
+ this.onReady?.(launch);
715
+ }
716
+ catch (hookErr) {
717
+ this.onLog(`${this.logPrefix} onReady hook threw: ${hookErr instanceof Error ? hookErr.message : hookErr}`);
718
+ }
701
719
  }
702
720
  catch (err) {
703
721
  // The panic classifier state is cleared by handleExit — read it now,
@@ -998,13 +1016,23 @@ export class NativeEngineSupervisor {
998
1016
  // the output didn't already explain the death more precisely: an
999
1017
  // engine that printed `CUDA error: …` and then took SIGILL on the
1000
1018
  // way down is a CUDA fault, not an unrunnable build.
1001
- const panic = this.currentPanic ??
1002
- (signal === 'SIGILL'
1003
- ? {
1004
- kind: 'illegal-instruction',
1005
- line: 'engine terminated by SIGILL (illegal instruction) with no diagnostic output',
1006
- }
1007
- : undefined);
1019
+ // An out-of-memory kill outranks anything the engine printed: a CUDA or
1020
+ // Vulkan allocation line on the way there is a symptom of the same
1021
+ // shortage, and the GPU-to-RAM ladder those lines trigger cannot help
1022
+ // when RAM is what ran out.
1023
+ const oomKilled = signal === 'SIGKILL' && !expected ? this.oomKillsSince(this.currentOomKills) : null;
1024
+ const panic = oomKilled
1025
+ ? {
1026
+ kind: 'host-out-of-memory',
1027
+ line: `engine killed by the Linux out-of-memory killer (oom_kill ${oomKilled.before} -> ${oomKilled.after})`,
1028
+ }
1029
+ : (this.currentPanic ??
1030
+ (signal === 'SIGILL'
1031
+ ? {
1032
+ kind: 'illegal-instruction',
1033
+ line: 'engine terminated by SIGILL (illegal instruction) with no diagnostic output',
1034
+ }
1035
+ : undefined));
1008
1036
  const snapshot = {
1009
1037
  incidentId: `native-${pid ?? 'unknown'}-${exitedAt}`,
1010
1038
  ...(pid !== undefined ? { pid } : {}),
@@ -1062,6 +1090,7 @@ export class NativeEngineSupervisor {
1062
1090
  this.currentDiagnostics = undefined;
1063
1091
  this.currentOutput = '';
1064
1092
  this.currentPanic = undefined;
1093
+ this.currentOomKills = null;
1065
1094
  this.expectedExitReason = undefined;
1066
1095
  if (priorState.kind === 'stopped')
1067
1096
  return;
@@ -1313,6 +1342,18 @@ export class NativeEngineSupervisor {
1313
1342
  this.idleTimer = undefined;
1314
1343
  }
1315
1344
  }
1345
+ /**
1346
+ * The counter's movement since `before`, when it rose. Another process
1347
+ * killed in the same window would also move it, but a child that died by a
1348
+ * SIGKILL this supervisor did not send while the counter rose is, in
1349
+ * practice, the one the killer chose.
1350
+ */
1351
+ oomKillsSince(before) {
1352
+ if (before === null)
1353
+ return null;
1354
+ const after = this.readOomKillCount();
1355
+ return after !== null && after > before ? { before, after } : null;
1356
+ }
1316
1357
  clearFreezeTimer() {
1317
1358
  if (this.freezeTimer) {
1318
1359
  clearTimeout(this.freezeTimer);
@@ -1346,6 +1387,9 @@ export function classifyNativeEnginePanic(line) {
1346
1387
  if (/CUDA error:.*device-side assert/i.test(line)) {
1347
1388
  return { kind: 'cuda-device-assert', line: clipped };
1348
1389
  }
1390
+ if (/CUDA error:\s*(?:no kernel image is available|the provided PTX was compiled with an unsupported toolchain)/i.test(line)) {
1391
+ return { kind: 'cuda-unsupported-device', line: clipped };
1392
+ }
1349
1393
  if (/CUDA error:/i.test(line))
1350
1394
  return { kind: 'cuda-error', line: clipped };
1351
1395
  if (/assert(?:ion)? failed|GGML_ASSERT/i.test(line)) {
@@ -1353,6 +1397,16 @@ export function classifyNativeEnginePanic(line) {
1353
1397
  }
1354
1398
  return undefined;
1355
1399
  }
1400
+ /** `oom_kill` from `/proc/vmstat` (Linux 4.13+), or null when it cannot be read. */
1401
+ export function readLinuxOomKillCount() {
1402
+ try {
1403
+ const match = /^oom_kill (\d+)$/m.exec(readFileSync('/proc/vmstat', 'utf8'));
1404
+ return match?.[1] ? Number(match[1]) : null;
1405
+ }
1406
+ catch {
1407
+ return null;
1408
+ }
1409
+ }
1356
1410
  function panicPriority(kind) {
1357
1411
  if (kind === 'cuda-error')
1358
1412
  return 1;
@@ -5,11 +5,18 @@
5
5
  * service's import point and keeps the one piece that reads the process
6
6
  * environment.
7
7
  */
8
- export { AbortedWhileQueuedError, DEFAULT_AMBIENT_QUIET_MS, ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, runInQueue, } from '@bendyline/gezel/runtime';
9
- export type { EnqueueRequest, Lane, ProviderQueueOptions, QueueSnapshot, QueueWaitOpts, } from '@bendyline/gezel/runtime';
8
+ export { AbortedWhileQueuedError, DEFAULT_AMBIENT_QUIET_MS, DEFAULT_LOCAL_YIELD_QUANTUM_MS, ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, runInQueue, } from '@bendyline/gezel/runtime';
9
+ export type { EnqueueRequest, Lane, ProviderQueueOptions, QueueLease, QueueSnapshot, QueueWaitOpts, } from '@bendyline/gezel/runtime';
10
10
  /**
11
11
  * Ambient quiet window for local engine queues. Override with
12
12
  * `GEZEL_AMBIENT_QUIET_MS` (milliseconds; `0` disables ambient gating
13
13
  * entirely).
14
14
  */
15
15
  export declare function defaultAmbientQuietMs(): number;
16
+ /**
17
+ * How long a local turn holds its queue slot before it hands the slot to
18
+ * another conversation that is waiting. Override with
19
+ * `GEZEL_QUEUE_YIELD_QUANTUM_MS` (milliseconds; `0` keeps a slot for the
20
+ * whole turn).
21
+ */
22
+ export declare function defaultQueueYieldQuantumMs(): number;
@@ -5,8 +5,8 @@
5
5
  * service's import point and keeps the one piece that reads the process
6
6
  * environment.
7
7
  */
8
- import { DEFAULT_AMBIENT_QUIET_MS } from '@bendyline/gezel/runtime';
9
- export { AbortedWhileQueuedError, DEFAULT_AMBIENT_QUIET_MS, ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, runInQueue, } from '@bendyline/gezel/runtime';
8
+ import { DEFAULT_AMBIENT_QUIET_MS, DEFAULT_LOCAL_YIELD_QUANTUM_MS } from '@bendyline/gezel/runtime';
9
+ export { AbortedWhileQueuedError, DEFAULT_AMBIENT_QUIET_MS, DEFAULT_LOCAL_YIELD_QUANTUM_MS, ProviderQueue, QUEUE_WAIT_NOTICE_DELAY_MS, QUEUE_WAIT_NOTICE_REPEAT_MS, backgroundLaneCap, runInQueue, } from '@bendyline/gezel/runtime';
10
10
  /**
11
11
  * Ambient quiet window for local engine queues. Override with
12
12
  * `GEZEL_AMBIENT_QUIET_MS` (milliseconds; `0` disables ambient gating
@@ -21,3 +21,18 @@ export function defaultAmbientQuietMs() {
21
21
  }
22
22
  return DEFAULT_AMBIENT_QUIET_MS;
23
23
  }
24
+ /**
25
+ * How long a local turn holds its queue slot before it hands the slot to
26
+ * another conversation that is waiting. Override with
27
+ * `GEZEL_QUEUE_YIELD_QUANTUM_MS` (milliseconds; `0` keeps a slot for the
28
+ * whole turn).
29
+ */
30
+ export function defaultQueueYieldQuantumMs() {
31
+ const raw = process.env.GEZEL_QUEUE_YIELD_QUANTUM_MS;
32
+ if (raw !== undefined) {
33
+ const parsed = Number.parseInt(raw, 10);
34
+ if (Number.isFinite(parsed) && parsed >= 0)
35
+ return parsed;
36
+ }
37
+ return DEFAULT_LOCAL_YIELD_QUANTUM_MS;
38
+ }
@@ -22,5 +22,8 @@ export interface ToolGroundingHooks {
22
22
  kind: 'allow';
23
23
  args: Record<string, unknown>;
24
24
  } | null;
25
- labelEvidence(toolName: string, args: Record<string, unknown>, text: string): string | null;
25
+ /** `source.thirdParty` is true for a tool served by any server but gezel's own. */
26
+ labelEvidence(toolName: string, args: Record<string, unknown>, text: string, source?: {
27
+ thirdParty: boolean;
28
+ }): string | null;
26
29
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The amdgpu devices Linux describes in sysfs, for the carve-out decision in
3
+ * gpu-carve-out.ts — the Linux counterpart of the DXCore adapter listing the
4
+ * device-health helper reads on Windows. Everything read here is
5
+ * world-readable, so the machine service's unprivileged account sees it too.
6
+ */
7
+ import type { GpuAdapterFacts } from './gpu-carve-out.js';
8
+ export interface SysfsIo {
9
+ readFile?: (path: string) => string;
10
+ readDir?: (path: string) => string[];
11
+ }
12
+ /**
13
+ * One entry per amdgpu device: `dedicatedBytes` from `mem_info_vram_total`,
14
+ * `sharedSystemBytes` from `mem_info_gtt_total` (the system RAM the kernel
15
+ * lets it map). Connector entries (`card0-HDMI-A-1`) and render nodes are
16
+ * skipped. Empty off Linux, without amdgpu, or when sysfs cannot be read.
17
+ */
18
+ export declare function readAmdgpuAdapters(io?: SysfsIo): GpuAdapterFacts[];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The amdgpu devices Linux describes in sysfs, for the carve-out decision in
3
+ * gpu-carve-out.ts — the Linux counterpart of the DXCore adapter listing the
4
+ * device-health helper reads on Windows. Everything read here is
5
+ * world-readable, so the machine service's unprivileged account sees it too.
6
+ */
7
+ import { readFileSync, readdirSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ const DRM_ROOT = '/sys/class/drm';
10
+ const AMD_PCI_VENDOR = 0x1002;
11
+ /**
12
+ * One entry per amdgpu device: `dedicatedBytes` from `mem_info_vram_total`,
13
+ * `sharedSystemBytes` from `mem_info_gtt_total` (the system RAM the kernel
14
+ * lets it map). Connector entries (`card0-HDMI-A-1`) and render nodes are
15
+ * skipped. Empty off Linux, without amdgpu, or when sysfs cannot be read.
16
+ */
17
+ export function readAmdgpuAdapters(io = {}) {
18
+ const readFile = io.readFile ?? ((path) => readFileSync(path, 'utf8'));
19
+ const readDir = io.readDir ?? ((path) => readdirSync(path));
20
+ const read = (path) => {
21
+ try {
22
+ return readFile(path).trim();
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ };
28
+ let cards;
29
+ try {
30
+ cards = readDir(DRM_ROOT).filter((entry) => /^card\d+$/.test(entry));
31
+ }
32
+ catch {
33
+ return [];
34
+ }
35
+ const adapters = [];
36
+ for (const card of cards) {
37
+ const device = join(DRM_ROOT, card, 'device');
38
+ if (Number.parseInt(read(join(device, 'vendor')) ?? '', 16) !== AMD_PCI_VENDOR)
39
+ continue;
40
+ const vram = byteCount(read(join(device, 'mem_info_vram_total')));
41
+ if (vram === undefined)
42
+ continue;
43
+ const gtt = byteCount(read(join(device, 'mem_info_gtt_total')));
44
+ adapters.push({
45
+ vendorId: AMD_PCI_VENDOR,
46
+ dedicatedBytes: vram,
47
+ ...(gtt !== undefined ? { sharedSystemBytes: gtt } : {}),
48
+ });
49
+ }
50
+ return adapters;
51
+ }
52
+ function byteCount(raw) {
53
+ const value = raw ? Number(raw) : Number.NaN;
54
+ return Number.isSafeInteger(value) && value >= 0 ? value : undefined;
55
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * How much memory firmware set aside for an integrated GPU, if any.
3
+ *
4
+ * Two kinds of integrated GPU report "VRAM" through Vulkan, and they mean
5
+ * opposite things:
6
+ *
7
+ * - A **shared view** (Intel, Snapdragon, most iGPUs): the number is a slice
8
+ * of the same RAM the OS already counts. Adding it double-counts, which is
9
+ * why integrated hosts budget from system RAM alone.
10
+ * - A **carve-out** (an AMD APU's "UMA frame buffer", set in firmware or by
11
+ * AMD's Variable Graphics Memory): memory removed before the OS ever counts
12
+ * RAM. It sits in neither `os.totalmem()` nor any free-RAM reading, and only
13
+ * the GPU can use it. Budgeting from system RAM alone loses it entirely, so
14
+ * on a 16 GB laptop raising the carve-out from 3 GB to 8 GB cut the budget
15
+ * from ~9 GB to ~4 GB.
16
+ *
17
+ * Windows answers directly when the device-health helper can list adapters
18
+ * (DXCore): an integrated adapter's dedicated memory IS its carve-out. Where
19
+ * installed RAM is known too, the two must agree — the carve-out has to fit
20
+ * in the memory that is installed but missing from the OS's count — so one
21
+ * odd driver figure cannot inflate the budget.
22
+ *
23
+ * Without an adapter listing, the GPU's Vulkan-reported memory stands in: a
24
+ * carve-out fits inside that same gap, a shared view is far larger than it
25
+ * (a few hundred MB of firmware reservations is the usual gap without one).
26
+ *
27
+ * Linux answers through the amdgpu driver instead (see
28
+ * {@link linuxGpuCarveOutBytes}). Installed RAM is not readable there without
29
+ * root, and the Vulkan figure cannot stand in: llama.cpp sums every heap of an
30
+ * integrated GPU, and RADV reports an APU's GTT — borrowed system RAM — beside
31
+ * the carve-out.
32
+ *
33
+ * Anything uncertain answers null — integrated GPUs budgeted from system RAM
34
+ * alone, as before.
35
+ */
36
+ export declare function gpuCarveOutBytes(input: {
37
+ /** Physically installed RAM, or null when it could not be read. */
38
+ installedRamBytes: number | null;
39
+ /** RAM the OS reports (`os.totalmem()`). */
40
+ visibleRamBytes: number;
41
+ /** Memory the integrated GPU reports for itself through Vulkan. */
42
+ deviceBytes: number;
43
+ /** Windows' figure for the integrated adapter's own memory, when listed. */
44
+ adapterDedicatedBytes?: number | null;
45
+ }): number | null;
46
+ /**
47
+ * An AMD APU's carve-out on Linux: amdgpu's `mem_info_vram_total`, which on an
48
+ * APU is the frame buffer firmware reserved before the kernel counted RAM, so
49
+ * it is absent from MemTotal. Read only for the one amdgpu device there is —
50
+ * sysfs does not say which of two is integrated — and only when it fits in
51
+ * what Vulkan reports, which for an integrated GPU is the carve-out plus GTT.
52
+ * The caller has already decided the GPU llama.cpp picked is integrated.
53
+ */
54
+ export declare function linuxGpuCarveOutBytes(input: {
55
+ /** amdgpu devices from sysfs (`readAmdgpuAdapters`). */
56
+ adapters: readonly GpuAdapterFacts[];
57
+ visibleRamBytes: number;
58
+ /** Memory the integrated GPU reports for itself through Vulkan. */
59
+ deviceBytes: number;
60
+ }): number | null;
61
+ /**
62
+ * Everything an AMD APU can reach on Linux: its carve-out plus GTT, the
63
+ * window of system RAM amdgpu lets it map (half of RAM on recent kernels
64
+ * unless `ttm.pages_limit` raises it). Past that, allocations fail however
65
+ * much RAM is free. Null without both figures for the one amdgpu device.
66
+ */
67
+ export declare function linuxGpuAddressableBytes(adapters: readonly GpuAdapterFacts[]): number | null;
68
+ /** The part of a helper adapter record (`DeviceGpuAdapter`) this module reads. */
69
+ export interface GpuAdapterFacts {
70
+ name?: string;
71
+ vendorId: number;
72
+ integrated?: boolean;
73
+ dedicatedBytes?: number;
74
+ /** System RAM the adapter may borrow on top of its own (Linux: GTT). */
75
+ sharedSystemBytes?: number;
76
+ }
77
+ /**
78
+ * The adapter Windows lists for the GPU llama.cpp picked: the one with the
79
+ * same name, else the only adapter there is. Null when that is ambiguous —
80
+ * the name-based guesses then stand.
81
+ */
82
+ export declare function matchGpuAdapter<T extends GpuAdapterFacts>(adapters: readonly T[], deviceName: string): T | null;
83
+ /** GPU maker from its PCI vendor id. */
84
+ export declare function gpuVendorFromPciId(vendorId: number): 'amd' | 'intel' | 'nvidia' | undefined;