@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
@@ -22,6 +22,7 @@
22
22
  * lazily respawn its process (see {@link shutdown}).
23
23
  */
24
24
  import { type DisableThinkingRequestShape, LlamaCppSession, type ReasoningEffortRequestShape, type ToolGrammarFallback } from '@bendyline/gezel/local-loop';
25
+ import type { StartupCrashVerdict } from '@bendyline/gezel/native';
25
26
  import type { GpuArbiter } from '../gpu-arbiter.js';
26
27
  import type { NativeEngineLifecycleSnapshot, NativeEngineSupervisor } from '../native/supervisor.js';
27
28
  import { ProviderQueue } from '../queue.js';
@@ -55,6 +56,7 @@ export declare class LlamaCppProvider implements LLMProvider {
55
56
  */
56
57
  private toolGrammarFloor;
57
58
  private readonly supervisor?;
59
+ private readonly startupCrashVerdict?;
58
60
  /** Explicit base URL when no supervisor is managing the process. */
59
61
  private readonly externalBaseUrl?;
60
62
  private readonly defaultModel;
@@ -141,7 +143,9 @@ export declare class LlamaCppProvider implements LLMProvider {
141
143
  /** Request-scoped effort shape for compatible wrappers such as ds4-server. */
142
144
  private readonly reasoningEffortRequestShape;
143
145
  /** Engine batch width; see the `batchMaxConcurrency` constructor opt. */
144
- private readonly batchMaxConcurrency;
146
+ private batchMaxConcurrency;
147
+ /** See the `reserveBackgroundSlot` constructor opt. */
148
+ private readonly reservesBackgroundLane;
145
149
  /**
146
150
  * Number of real llama-server request slots (`--parallel`). The provider
147
151
  * queue can intentionally be wider than this by one reserved background
@@ -150,7 +154,7 @@ export declare class LlamaCppProvider implements LLMProvider {
150
154
  * boundary: cache slot save/restore plus the streamed engine request must
151
155
  * never exceed the slots the native server actually owns.
152
156
  */
153
- private readonly engineRequestWidth;
157
+ private engineRequestWidth;
154
158
  private engineRequestsActive;
155
159
  private readonly engineRequestWaiters;
156
160
  /**
@@ -242,6 +246,12 @@ export declare class LlamaCppProvider implements LLMProvider {
242
246
  * `baseUrl`.
243
247
  */
244
248
  supervisor?: NativeEngineSupervisor;
249
+ /**
250
+ * What a startup crash did to its build's standing (strike or
251
+ * quarantine), looked up by incident id when a start fails, so the error
252
+ * says what the next request will actually do.
253
+ */
254
+ startupCrashVerdict?: (incidentId: string) => StartupCrashVerdict | undefined;
245
255
  /**
246
256
  * Fixed base URL of an already-running llama-server. Used in
247
257
  * dev iteration and LAN-shared setups. Mutually exclusive with
@@ -401,7 +411,7 @@ export declare class LlamaCppProvider implements LLMProvider {
401
411
  */
402
412
  private cacheAdapter;
403
413
  private slotSavePath?;
404
- private readonly launchedSlots;
414
+ private launchedSlots;
405
415
  setCacheAdapter(adapter: import('./cache-adapter.js').LlamaCppCacheAdapter): void;
406
416
  getCacheAdapter(): import('./cache-adapter.js').LlamaCppCacheAdapter | null;
407
417
  /**
@@ -422,6 +432,15 @@ export declare class LlamaCppProvider implements LLMProvider {
422
432
  * would 400 silently, and the debug probe's slot narration was fiction.
423
433
  */
424
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;
425
444
  /**
426
445
  * Claim one physical llama-server request slot.
427
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.
@@ -57,6 +57,7 @@ export class LlamaCppProvider {
57
57
  */
58
58
  toolGrammarFloor = null;
59
59
  supervisor;
60
+ startupCrashVerdict;
60
61
  /** Explicit base URL when no supervisor is managing the process. */
61
62
  externalBaseUrl;
62
63
  defaultModel;
@@ -146,6 +147,8 @@ export class LlamaCppProvider {
146
147
  reasoningEffortRequestShape;
147
148
  /** Engine batch width; see the `batchMaxConcurrency` constructor opt. */
148
149
  batchMaxConcurrency;
150
+ /** See the `reserveBackgroundSlot` constructor opt. */
151
+ reservesBackgroundLane;
149
152
  /**
150
153
  * Number of real llama-server request slots (`--parallel`). The provider
151
154
  * queue can intentionally be wider than this by one reserved background
@@ -247,6 +250,8 @@ export class LlamaCppProvider {
247
250
  }
248
251
  if (opts.supervisor)
249
252
  this.supervisor = opts.supervisor;
253
+ if (opts.startupCrashVerdict)
254
+ this.startupCrashVerdict = opts.startupCrashVerdict;
250
255
  if (opts.baseUrl)
251
256
  this.externalBaseUrl = opts.baseUrl.replace(/\/+$/, '');
252
257
  // Only register an evictor when we own the lifecycle. External-baseUrl
@@ -338,7 +343,10 @@ export class LlamaCppProvider {
338
343
  // mid-turn compaction wedges the turn, the same failure the MLX
339
344
  // single-slot path hit. See the matching note in the MLX provider.
340
345
  const interactiveConcurrency = batchMax;
341
- 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;
342
350
  this.queue = new ProviderQueue({
343
351
  // llama-server is launched with `--parallel ${slots}` (see
344
352
  // `buildLlamaCppProvider` in chat/manager.ts) so the engine has matching
@@ -361,6 +369,9 @@ export class LlamaCppProvider {
361
369
  // a multi-minute chore turn never lands right before their next
362
370
  // move. Applies to ds4 too — its provider wraps this class.
363
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(),
364
375
  });
365
376
  }
366
377
  /**
@@ -455,6 +466,31 @@ export class LlamaCppProvider {
455
466
  getLaunchedSlots() {
456
467
  return this.launchedSlots;
457
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
+ }
458
494
  /**
459
495
  * Claim one physical llama-server request slot.
460
496
  *
@@ -848,7 +884,7 @@ export class LlamaCppProvider {
848
884
  catch (err) {
849
885
  const nativeExit = this.supervisor.lastExitSnapshot?.();
850
886
  if (nativeExit && !nativeExit.expected && nativeExit.exitedAt >= ensureStartedAt) {
851
- throw new NativeEngineCrashedError(nativeExit, err);
887
+ throw new NativeEngineCrashedError(nativeExit, err, this.startupCrashVerdict?.(nativeExit.incidentId));
852
888
  }
853
889
  throw err;
854
890
  }
@@ -27,7 +27,7 @@
27
27
  */
28
28
  import { AsyncLocalStorage } from 'node:async_hooks';
29
29
  import { randomUUID } from 'node:crypto';
30
- import { AwakeBudget, autoCompactedNotice, createAwakeTimeout, createLogger, leaksUntaggedReasoning, turnCancelledMessage, } from '@bendyline/gezel';
30
+ import { AwakeBudget, autoCompactedNotice, createAwakeTimeout, createLogger, isProjectStartingCall, leaksUntaggedReasoning, turnCancelledMessage, } from '@bendyline/gezel';
31
31
  import { leadingSystemMessages, standaloneTurnMessages, toolSurfaceSize, } from '@bendyline/gezel/local-loop';
32
32
  import { computeToolBudgetChars } from '@bendyline/gezel/local-loop';
33
33
  import { extractReasoningWithProfile, profileBehaviorConfig, profileHasBehavior, } from '../../model-profile/runtime.js';
@@ -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';
@@ -2159,7 +2159,7 @@ class MlxSession extends StreamingSessionBase {
2159
2159
  // accumulated into `lastTurnReasoning` so the chat bubble can
2160
2160
  // render it behind a collapsed expander.
2161
2161
  {
2162
- const split = extractReasoningWithProfile(turnContent, this.deps.profile);
2162
+ const split = extractReasoningWithProfile(reopenTemplateReasoning(turnContent, opensInReasoning), this.deps.profile);
2163
2163
  turnContent = split.visible;
2164
2164
  if (split.reasoning) {
2165
2165
  this.lastTurnReasoning =
@@ -2656,7 +2656,7 @@ class MlxSession extends StreamingSessionBase {
2656
2656
  output =
2657
2657
  "You already posted a question card to the user earlier in this turn. The second `ask_user_question` call was suppressed so the user only sees one card. END YOUR TURN NOW — the user's answer to the first question will arrive as the next user message; this turn produces no further visible content.";
2658
2658
  }
2659
- else if ((call.function.name === 'start_project' || call.function.name === 'start_job') &&
2659
+ else if (isProjectStartingCall(call.function.name, args) &&
2660
2660
  startedProjectOrJobThisTurn) {
2661
2661
  // Success-led phrasing — wild-caught on gemma4-26b/MLX,
2662
2662
  // the previous "DO NOT call..." wording got misread by
@@ -2753,8 +2753,7 @@ class MlxSession extends StreamingSessionBase {
2753
2753
  // Successful start_project / start_job → arm the
2754
2754
  // per-turn macro guard so subsequent variants get
2755
2755
  // intercepted above before reaching the bridge.
2756
- if ((call.function.name === 'start_project' || call.function.name === 'start_job') &&
2757
- !output.startsWith('ERROR:')) {
2756
+ if (isProjectStartingCall(call.function.name, args) && !output.startsWith('ERROR:')) {
2758
2757
  startedProjectOrJobThisTurn = { tool: call.function.name, firstResult: output };
2759
2758
  }
2760
2759
  }
@@ -14,7 +14,6 @@ so concurrent replicas cannot observe a half-built view.
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- import fcntl
18
17
  import hashlib
19
18
  import json
20
19
  import os
@@ -23,6 +22,13 @@ import uuid
23
22
  from pathlib import Path
24
23
  from typing import Callable, Optional, Tuple
25
24
 
25
+ try:
26
+ import fcntl
27
+ except ImportError:
28
+ # Windows has no fcntl. The MLX engine never runs there, but this module's
29
+ # stdlib suite does (python-suites.test.ts), so it must still import.
30
+ fcntl = None
31
+
26
32
 
27
33
  PLE_MARKER = ".ple.ple_embedding.ngram_embedding.shards."
28
34
  VIEW_MARKER = "GEZEL_PLE_VIEW.json"
@@ -122,7 +128,8 @@ def prepare_external_ple_view(
122
128
  lock_path = target.parent / f".{target.name}.lock"
123
129
  try:
124
130
  with lock_path.open("a+b") as lock:
125
- fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
131
+ if fcntl is not None:
132
+ fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
126
133
  if _valid_view(target, signature):
127
134
  return str(target), "reused", True
128
135
 
@@ -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
  *
@@ -46,6 +46,14 @@ export interface CapacityBrokerOptions {
46
46
  * {@link computeCapacityBudget}. Omit to read the last published probe.
47
47
  */
48
48
  gpuVramBytes?: number | null;
49
+ /**
50
+ * An integrated GPU's firmware carve-out — see
51
+ * {@link CapacityBudgetInput.reservedGpuBytes}. Travels with
52
+ * `gpuVramBytes`/`unifiedMemory` as one description of the host.
53
+ */
54
+ reservedGpuBytes?: number | null;
55
+ /** What an integrated GPU can reach — see {@link CapacityBudgetInput.gpuAddressableBytes}. */
56
+ gpuAddressableBytes?: number | null;
49
57
  /**
50
58
  * May co-resident models spill into system RAM? `null`/omitted follows
51
59
  * {@link autoAllowRamSpillover} for this host. See
@@ -192,6 +200,8 @@ export declare class CapacityBroker {
192
200
  private readonly systemRamBytes;
193
201
  private readonly unifiedMemory;
194
202
  private readonly gpuVramBytes;
203
+ private readonly reservedGpuBytes;
204
+ private readonly gpuAddressableBytes;
195
205
  private explicitAllowRamSpillover;
196
206
  private readonly reservations;
197
207
  constructor(opts?: CapacityBrokerOptions);
@@ -503,11 +513,9 @@ export declare const MIN_VIABLE_LOCAL_CONTEXT_TOKENS = 65536;
503
513
  /** The same minimum on a host that has to trade context for memory. */
504
514
  export declare const MIN_VIABLE_CONSTRAINED_CONTEXT_TOKENS = 32768;
505
515
  /**
506
- * The most KV cache an automatic choice plans for one llama.cpp engine:
507
- * adaptive growth stops here, and the Gemma `--swa-full` auto-default is
508
- * declined when its full-size cache would pass it. Explicit settings (a
509
- * numeric context, a pinned `swaFull`) are the operator's call and bypass it;
510
- * it never shortens the ladder-settled base window either.
516
+ * The most KV cache adaptive growth plans for one llama.cpp engine. An
517
+ * explicit numeric context is the operator's call and skips growth
518
+ * altogether, and the ceiling never shortens the ladder-settled base window.
511
519
  *
512
520
  * Past this a bigger cache buys nothing: llama.cpp's prefill and decode cost
513
521
  * follows the tokens actually present, not the reservation, so the rest only
@@ -650,10 +658,10 @@ export interface CtxMemoryClampInput {
650
658
  */
651
659
  freeSystemRamBytes?: number;
652
660
  /**
653
- * Usable VRAM on a discrete card; MUST be 0 on unified/shared-pool
654
- * hosts, where the "VRAM" is the same physical RAM `freeSystemRamBytes`
655
- * measures and adding it would double-count. `computeCapacityBudget`
656
- * already reports `vramBytes: 0` for those hosts — pass its value.
661
+ * Usable VRAM on a discrete card. On a unified/shared-pool host it MUST be
662
+ * only an integrated GPU's firmware carve-out, which `freeSystemRamBytes`
663
+ * never sees; any "VRAM" that is the same physical RAM would double-count.
664
+ * `computeCapacityBudget` reports exactly that — pass its value.
657
665
  */
658
666
  vramBytes: number;
659
667
  minPerTurnCtxTokens?: number;
@@ -751,7 +759,7 @@ export interface AdaptiveCtxGrowthInput {
751
759
  fastBudgetBytes: number;
752
760
  committedOtherBytes?: number;
753
761
  budgetKind: CapacityBudget['kind'];
754
- /** Usable VRAM on a discrete card (`liveBudget.vramBytes`); 0 elsewhere. */
762
+ /** Usable VRAM on a discrete card (`liveBudget.vramBytes`); ignored elsewhere. */
755
763
  vramBytes: number;
756
764
  /**
757
765
  * Graphics memory free right now on a discrete card, as device admission
@@ -796,11 +804,9 @@ export interface AdaptiveCtxGrowthResult {
796
804
  * settled slots and granted the un-grown request.
797
805
  *
798
806
  * Deliberately a second clamp pass rather than a bigger first request:
799
- * the first ladder pass sizes slot ceilings, the `--swa-full` fit verdict,
800
- * and RAM-spillover admission, all of which must stay anchored on the
801
- * practical 64K target — growing the request there would decline
802
- * `--swa-full` for models whose full cache fits at 64K and grow KV into
803
- * system-RAM spill on discrete cards.
807
+ * the first ladder pass sizes slot ceilings and RAM-spillover admission,
808
+ * both of which must stay anchored on the practical 64K target — growing
809
+ * the request there would grow KV into system-RAM spill on discrete cards.
804
810
  *
805
811
  * Slot trade: when `allowSlotTrade` is set and the target is out of reach
806
812
  * at the settled slot count, growth walks the count down — taking the
@@ -151,12 +151,16 @@ export class CapacityBroker {
151
151
  systemRamBytes;
152
152
  unifiedMemory;
153
153
  gpuVramBytes;
154
+ reservedGpuBytes;
155
+ gpuAddressableBytes;
154
156
  explicitAllowRamSpillover;
155
157
  reservations = new Map();
156
158
  constructor(opts = {}) {
157
159
  this.systemRamBytes = (opts.systemRamBytes ?? totalmem)();
158
160
  this.unifiedMemory = opts.unifiedMemory;
159
161
  this.gpuVramBytes = opts.gpuVramBytes;
162
+ this.reservedGpuBytes = opts.reservedGpuBytes;
163
+ this.gpuAddressableBytes = opts.gpuAddressableBytes;
160
164
  this.explicitAllowRamSpillover = opts.allowRamSpillover ?? null;
161
165
  this.explicitBudgetBytes = opts.budgetBytes ?? null;
162
166
  // Assigned by applyBudget; the definite-assignment dance TS wants for
@@ -189,6 +193,12 @@ export class CapacityBroker {
189
193
  : {
190
194
  ...(this.unifiedMemory === undefined ? {} : { unifiedMemory: this.unifiedMemory }),
191
195
  ...(this.gpuVramBytes === undefined ? {} : { gpuVramBytes: this.gpuVramBytes }),
196
+ ...(this.reservedGpuBytes === undefined
197
+ ? {}
198
+ : { reservedGpuBytes: this.reservedGpuBytes }),
199
+ ...(this.gpuAddressableBytes === undefined
200
+ ? {}
201
+ : { gpuAddressableBytes: this.gpuAddressableBytes }),
192
202
  }),
193
203
  });
194
204
  }
@@ -714,11 +724,9 @@ function envGrowthCeilingTokens() {
714
724
  return Number.isFinite(tokens) && tokens > 0 ? tokens : null;
715
725
  }
716
726
  /**
717
- * The most KV cache an automatic choice plans for one llama.cpp engine:
718
- * adaptive growth stops here, and the Gemma `--swa-full` auto-default is
719
- * declined when its full-size cache would pass it. Explicit settings (a
720
- * numeric context, a pinned `swaFull`) are the operator's call and bypass it;
721
- * it never shortens the ladder-settled base window either.
727
+ * The most KV cache adaptive growth plans for one llama.cpp engine. An
728
+ * explicit numeric context is the operator's call and skips growth
729
+ * altogether, and the ceiling never shortens the ladder-settled base window.
722
730
  *
723
731
  * Past this a bigger cache buys nothing: llama.cpp's prefill and decode cost
724
732
  * follows the tokens actually present, not the reservation, so the rest only
@@ -806,14 +814,20 @@ export function resolveLlamaCppContextRequirement(opts) {
806
814
  const strictModelMax = opts.contextSizing === 'model-max' && opts.explicitContextWindow === undefined;
807
815
  const requestedContextWindow = opts.explicitContextWindow ??
808
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;
809
825
  const resolved = resolveLocalContextRequirement({
810
826
  ...(opts.modelContextWindow !== undefined
811
827
  ? { modelContextWindow: opts.modelContextWindow }
812
828
  : {}),
813
829
  ...(requestedContextWindow !== undefined ? { requestedContextWindow } : {}),
814
- ...(opts.minViableContextTokens !== undefined
815
- ? { minViableContextTokens: opts.minViableContextTokens }
816
- : {}),
830
+ minViableContextTokens: minimum,
817
831
  });
818
832
  if (strictModelMax) {
819
833
  return {
@@ -959,11 +973,9 @@ export const ADAPTIVE_GROWTH_TRADE_MIN_GAIN = 1.25;
959
973
  * settled slots and granted the un-grown request.
960
974
  *
961
975
  * Deliberately a second clamp pass rather than a bigger first request:
962
- * the first ladder pass sizes slot ceilings, the `--swa-full` fit verdict,
963
- * and RAM-spillover admission, all of which must stay anchored on the
964
- * practical 64K target — growing the request there would decline
965
- * `--swa-full` for models whose full cache fits at 64K and grow KV into
966
- * system-RAM spill on discrete cards.
976
+ * the first ladder pass sizes slot ceilings and RAM-spillover admission,
977
+ * both of which must stay anchored on the practical 64K target — growing
978
+ * the request there would grow KV into system-RAM spill on discrete cards.
967
979
  *
968
980
  * Slot trade: when `allowSlotTrade` is set and the target is out of reach
969
981
  * at the settled slot count, growth walks the count down — taking the
@@ -5,7 +5,13 @@
5
5
  * VRAM and RAM are common on small discrete-GPU machines, so their ratio is
6
6
  * not enough to tell a GeForce from a genuinely shared GB10/iGPU pool.
7
7
  */
8
- export declare function setDetectedGpuVramBytes(bytes: number | null, unifiedMemory?: boolean): void;
8
+ export declare function setDetectedGpuVramBytes(bytes: number | null, unifiedMemory?: boolean, reservedGpuBytes?: number | null, gpuAddressableBytes?: number | null): void;
9
+ /**
10
+ * What engines may hold of memory an integrated GPU owns or can reach — its
11
+ * carve-out, or carve-out plus GTT — after the share the desktop it also
12
+ * drives needs.
13
+ */
14
+ export declare function usableReservedGpuBytes(reservedGpuBytes: number | null | undefined): number;
9
15
  /** The published accelerator-memory figure, or null when none was measured. */
10
16
  export declare function getDetectedGpuVramBytes(): number | null;
11
17
  /**
@@ -26,13 +32,19 @@ export interface CapacityBudget {
26
32
  budgetBytes: number;
27
33
  /**
28
34
  * The FAST pool inside that budget: usable VRAM on a discrete card, the
29
- * whole budget on unified / CPU hosts. Size KV slots and prompt caches
35
+ * whole budget on unified / CPU hosts — except an integrated GPU that can
36
+ * reach less than that (Linux GTT; see
37
+ * {@link CapacityBudgetInput.gpuAddressableBytes}). Size KV slots and prompt caches
30
38
  * against this, not against {@link budgetBytes} — on a discrete card the
31
39
  * rest of the budget is system RAM that weights stream from, and putting
32
40
  * more KV there than the card holds is how a GPU OOMs.
33
41
  */
34
42
  fastBytes: number;
35
- /** Usable VRAM on a discrete card; 0 on unified / CPU-only hosts. */
43
+ /**
44
+ * Usable VRAM on a discrete card. On a unified host, the usable part of an
45
+ * integrated GPU's firmware carve-out — memory the GPU owns that free-RAM
46
+ * readings never include — and 0 when there is none. 0 on CPU-only hosts.
47
+ */
36
48
  vramBytes: number;
37
49
  /** The system-RAM share of the budget. */
38
50
  ramShareBytes: number;
@@ -59,6 +71,26 @@ export interface CapacityBudgetInput {
59
71
  */
60
72
  gpuVramBytes?: number | null;
61
73
  unifiedMemory?: boolean;
74
+ /**
75
+ * Memory firmware sets aside for an integrated GPU (an AMD "UMA frame
76
+ * buffer"): carved out before the OS counts RAM, so it is NOT inside
77
+ * `systemRamBytes`, and only the GPU can use it. Credited on a unified host
78
+ * only — an engine on the CPU build cannot reach it. Without this, raising
79
+ * the carve-out shrank the budget: the bytes left the RAM figure and were
80
+ * counted nowhere. Omit to fall back to the last published probe, under the
81
+ * same rule as `gpuVramBytes`.
82
+ */
83
+ reservedGpuBytes?: number | null;
84
+ /**
85
+ * The most memory an integrated GPU can reach: on Linux amdgpu, its
86
+ * carve-out plus GTT, the window of system RAM the kernel lets it map
87
+ * (half of RAM by default). Caps the FAST pool on a unified host — the GPU
88
+ * cannot hold more KV or weights than this, whatever the RAM share says —
89
+ * while the admission budget keeps the rest for layers the CPU runs. Omit
90
+ * to fall back to the last published probe, under the same rule as
91
+ * `gpuVramBytes`.
92
+ */
93
+ gpuAddressableBytes?: number | null;
62
94
  }
63
95
  /**
64
96
  * Resolve the memory a host can give resident local engines, per pool.
@@ -67,6 +67,13 @@ const VRAM_USABLE_FRACTION = 0.95;
67
67
  * bytes, so those hosts take the unified curve instead.
68
68
  */
69
69
  const UNIFIED_VRAM_RATIO = 0.75;
70
+ /**
71
+ * Held back from an integrated GPU's firmware carve-out (see
72
+ * {@link CapacityBudgetInput.reservedGpuBytes}) for the desktop it also
73
+ * drives. The discrete card's 5% margin is too thin here: on a 512 MiB
74
+ * carve-out it would leave the compositor 25 MiB.
75
+ */
76
+ const CARVE_OUT_DISPLAY_RESERVE_BYTES = 512 * 1024 ** 2;
70
77
  /**
71
78
  * Last accelerator-memory figure `detectMemoryProfile` measured on this host,
72
79
  * or null when nothing has probed yet / no GPU memory figure was published.
@@ -81,6 +88,8 @@ const UNIFIED_VRAM_RATIO = 0.75;
81
88
  */
82
89
  let detectedGpuVramBytes = null;
83
90
  let detectedGpuUnifiedMemory;
91
+ let detectedGpuReservedBytes = null;
92
+ let detectedGpuAddressableBytes = null;
84
93
  /**
85
94
  * Publish the measured accelerator pool. Called by `detectMemoryProfile`.
86
95
  *
@@ -88,10 +97,26 @@ let detectedGpuUnifiedMemory;
88
97
  * VRAM and RAM are common on small discrete-GPU machines, so their ratio is
89
98
  * not enough to tell a GeForce from a genuinely shared GB10/iGPU pool.
90
99
  */
91
- export function setDetectedGpuVramBytes(bytes, unifiedMemory) {
92
- detectedGpuVramBytes =
93
- typeof bytes === 'number' && Number.isFinite(bytes) && bytes > 0 ? bytes : null;
100
+ export function setDetectedGpuVramBytes(bytes, unifiedMemory, reservedGpuBytes, gpuAddressableBytes) {
101
+ detectedGpuVramBytes = positiveOrNull(bytes);
94
102
  detectedGpuUnifiedMemory = unifiedMemory;
103
+ detectedGpuReservedBytes = positiveOrNull(reservedGpuBytes);
104
+ detectedGpuAddressableBytes = positiveOrNull(gpuAddressableBytes);
105
+ }
106
+ function positiveOrNull(bytes) {
107
+ return typeof bytes === 'number' && Number.isFinite(bytes) && bytes > 0 ? bytes : null;
108
+ }
109
+ /**
110
+ * What engines may hold of memory an integrated GPU owns or can reach — its
111
+ * carve-out, or carve-out plus GTT — after the share the desktop it also
112
+ * drives needs.
113
+ */
114
+ export function usableReservedGpuBytes(reservedGpuBytes) {
115
+ const reserved = positiveOrNull(reservedGpuBytes);
116
+ if (reserved === null)
117
+ return 0;
118
+ const display = Math.max(CARVE_OUT_DISPLAY_RESERVE_BYTES, Math.ceil(reserved * (1 - VRAM_USABLE_FRACTION)));
119
+ return Math.max(0, reserved - display);
95
120
  }
96
121
  /** The published accelerator-memory figure, or null when none was measured. */
97
122
  export function getDetectedGpuVramBytes() {
@@ -144,6 +169,16 @@ export function computeCapacityBudget(input = {}) {
144
169
  const sharedPool = hasCard && measuredVram >= systemRamBytes * UNIFIED_VRAM_RATIO;
145
170
  const unified = measuredUnifiedMemory ?? (isUnifiedMemoryHost() || sharedPool);
146
171
  const discrete = hasCard && !unified;
172
+ const reservedGpuBytes = input.reservedGpuBytes !== undefined
173
+ ? input.reservedGpuBytes
174
+ : input.unifiedMemory === undefined && input.gpuVramBytes === undefined
175
+ ? detectedGpuReservedBytes
176
+ : null;
177
+ const gpuAddressableBytes = input.gpuAddressableBytes !== undefined
178
+ ? input.gpuAddressableBytes
179
+ : input.unifiedMemory === undefined && input.gpuVramBytes === undefined
180
+ ? detectedGpuAddressableBytes
181
+ : null;
147
182
  const highMemory = systemRamBytes >= HIGH_MEMORY_THRESHOLD_BYTES;
148
183
  // Whichever bound leaves the host MORE memory wins between the fraction and
149
184
  // the capped reserve, then the 4 GiB floor reserve caps them both. Written
@@ -153,7 +188,11 @@ export function computeCapacityBudget(input = {}) {
153
188
  const unifiedShare = Math.max(0, Math.min(Math.max(unifiedFractionShare, systemRamBytes - UNIFIED_OS_RESERVE_MAX_BYTES), systemRamBytes - UNIFIED_OS_RESERVE_BYTES));
154
189
  const nonUnifiedShare = Math.min(Math.floor(systemRamBytes * (highMemory ? 0.8 : 0.6)), BUDGET_CAP_BYTES);
155
190
  const ramShareBytes = unified ? unifiedShare : nonUnifiedShare;
156
- const vramBytes = discrete ? Math.floor(measuredVram * VRAM_USABLE_FRACTION) : 0;
191
+ const vramBytes = discrete
192
+ ? Math.floor(measuredVram * VRAM_USABLE_FRACTION)
193
+ : unified
194
+ ? usableReservedGpuBytes(reservedGpuBytes)
195
+ : 0;
157
196
  // The pre-cap curve, retained for slot sizing only.
158
197
  const concurrencyRamShare = unified
159
198
  ? Math.max(0, Math.min(unifiedFractionShare, systemRamBytes - UNIFIED_OS_RESERVE_BYTES, BUDGET_CAP_BYTES))
@@ -175,7 +214,12 @@ export function computeCapacityBudget(input = {}) {
175
214
  overriddenByEnv: true,
176
215
  };
177
216
  }
178
- const fastBytes = discrete ? vramBytes : auto;
217
+ const addressable = positiveOrNull(gpuAddressableBytes);
218
+ const fastBytes = discrete
219
+ ? vramBytes
220
+ : unified && addressable !== null
221
+ ? Math.min(auto, usableReservedGpuBytes(addressable))
222
+ : auto;
179
223
  return {
180
224
  budgetBytes: auto,
181
225
  fastBytes,
@@ -73,7 +73,7 @@ export declare function configuredEngineMemoryBytes(config: {
73
73
  * download pages hide is exactly one the launch path refuses. Omit
74
74
  * `configuredBytes` for the machine's automatic ceilings.
75
75
  */
76
- export declare function staticCapacityCeilings(budget: Pick<CapacityBudget, 'budgetBytes' | 'fastBytes' | 'kind'>, ramBytes: number, configuredBytes?: number): {
76
+ export declare function staticCapacityCeilings(budget: Pick<CapacityBudget, 'budgetBytes' | 'fastBytes' | 'kind' | 'vramBytes'>, ramBytes: number, configuredBytes?: number, platform?: NodeJS.Platform): {
77
77
  budgetBytes: number;
78
78
  gpuBudgetBytes: number;
79
79
  };