@bendyline/gezel-inference 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/dist/catalog/chat-models/de/deepseek-v4.1-flash-552b-q2/manifest.json +120 -0
  2. package/dist/catalog/chat-models/de/deepseek-v4.1-flash-552b-q2/versions/1.0.0/manifest.json +21 -0
  3. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/manifest.json +6 -5
  4. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.2/manifest.json +27 -0
  5. package/dist/catalog/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.3/manifest.json +27 -0
  6. package/dist/catalog/chat-models/index.json +1 -1
  7. package/dist/catalog/chat-models/na/nanbeige4.2-3b-q4/manifest.json +1 -1
  8. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/manifest.json +157 -0
  9. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-74b-iq2/versions/1.0.0/manifest.json +30 -0
  10. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-e4b-q4/manifest.json +142 -0
  11. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-e4b-q4/versions/1.0.0/manifest.json +14 -0
  12. package/dist/catalog/chat-models/ne/nemotron3.5-bolt-e4b-q4/versions/1.0.1/manifest.json +14 -0
  13. package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/manifest.json +156 -0
  14. package/dist/catalog/chat-models/ne/nemotron3.5-super-vl-120b-nvfp4/versions/1.0.0/manifest.json +28 -0
  15. package/dist/catalog/chat-models/raw-index.json +1 -1
  16. package/dist/catalog/image-models/an/animagine-xl-4/manifest.json +40 -0
  17. package/dist/catalog/image-models/an/animagine-xl-4/versions/4.0.0/manifest.json +10 -0
  18. package/dist/catalog/image-models/an/animagine-xl-4/versions/4.0.1/manifest.json +16 -0
  19. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/manifest.json +44 -0
  20. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/versions/1.0.0/manifest.json +23 -0
  21. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/versions/1.0.1/manifest.json +29 -0
  22. package/dist/catalog/image-models/index.json +1 -0
  23. package/dist/catalog/image-models/ir/iris-3b-f32/manifest.json +41 -0
  24. package/dist/catalog/image-models/ir/iris-3b-f32/versions/1.0.0/manifest.json +19 -0
  25. package/dist/catalog/image-models/ir/iris-3b-f32/versions/1.0.1/manifest.json +25 -0
  26. package/dist/catalog/image-models/ir/iris-3b-f32/versions/1.0.2/manifest.json +25 -0
  27. package/dist/catalog/image-models/kr/krea-2-turbo-q4/manifest.json +42 -0
  28. package/dist/catalog/image-models/kr/krea-2-turbo-q4/versions/1.0.0/manifest.json +23 -0
  29. package/dist/catalog/image-models/kr/krea-2-turbo-q4/versions/1.0.1/manifest.json +29 -0
  30. package/dist/catalog/image-models/kr/krea-2-turbo-q6/manifest.json +42 -0
  31. package/dist/catalog/image-models/kr/krea-2-turbo-q6/versions/1.0.0/manifest.json +23 -0
  32. package/dist/catalog/image-models/kr/krea-2-turbo-q6/versions/1.0.1/manifest.json +29 -0
  33. package/dist/catalog/image-models/kr/krea-2-turbo-q8/manifest.json +42 -0
  34. package/dist/catalog/image-models/kr/krea-2-turbo-q8/versions/1.0.0/manifest.json +23 -0
  35. package/dist/catalog/image-models/kr/krea-2-turbo-q8/versions/1.0.1/manifest.json +29 -0
  36. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/manifest.json +41 -0
  37. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.0/manifest.json +31 -0
  38. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.1/manifest.json +50 -0
  39. package/dist/catalog/image-models/mi/ming-image-0.1-design-bf16/versions/1.0.2/manifest.json +50 -0
  40. package/dist/catalog/image-models/mo/moss-image-sft-q4/manifest.json +40 -0
  41. package/dist/catalog/image-models/mo/moss-image-sft-q4/versions/1.0.0/manifest.json +37 -0
  42. package/dist/catalog/image-models/mo/moss-image-sft-q4/versions/1.0.1/manifest.json +37 -0
  43. package/dist/catalog/image-models/raw-index.json +1 -0
  44. package/dist/catalog/image-models/sd/sd-1.5/manifest.json +40 -0
  45. package/dist/catalog/image-models/sd/sd-1.5/versions/1.0.0/manifest.json +10 -0
  46. package/dist/catalog/image-models/sd/sd-1.5/versions/1.0.1/manifest.json +16 -0
  47. package/dist/catalog/image-models/sd/sd-turbo/manifest.json +40 -0
  48. package/dist/catalog/image-models/sd/sd-turbo/versions/1.0.0/manifest.json +10 -0
  49. package/dist/catalog/image-models/sd/sd-turbo/versions/1.0.1/manifest.json +16 -0
  50. package/dist/catalog/image-models/sd/sdxl-base-1.0/manifest.json +39 -0
  51. package/dist/catalog/image-models/sd/sdxl-base-1.0/versions/1.0.0/manifest.json +10 -0
  52. package/dist/catalog/image-models/sd/sdxl-base-1.0/versions/1.0.1/manifest.json +16 -0
  53. package/dist/catalog/image-models/sd/sdxl-lightning-4step/manifest.json +40 -0
  54. package/dist/catalog/image-models/sd/sdxl-lightning-4step/versions/1.0.0/manifest.json +10 -0
  55. package/dist/catalog/image-models/sd/sdxl-lightning-4step/versions/1.0.1/manifest.json +16 -0
  56. package/dist/catalog/image-models/sd/sdxl-turbo/manifest.json +41 -0
  57. package/dist/catalog/image-models/sd/sdxl-turbo/versions/1.0.0/manifest.json +10 -0
  58. package/dist/catalog/image-models/sd/sdxl-turbo/versions/1.0.1/manifest.json +16 -0
  59. package/dist/catalog/knowledge-catalogs/be/bendyline-how-to-books/keywords.json +56 -0
  60. package/dist/catalog/knowledge-catalogs/ca/caselaw-alaska-part-0001/keywords.json +12 -0
  61. package/dist/catalog/knowledge-catalogs/ca/caselaw-nevada-part-0001/keywords.json +13 -0
  62. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-300-399-part-0001/keywords.json +14 -0
  63. package/dist/catalog/knowledge-catalogs/ca/caselaw-us-347-349/keywords.json +17 -0
  64. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0001/keywords.json +12 -0
  65. package/dist/catalog/knowledge-catalogs/ca/caselaw-utah-part-0002/keywords.json +12 -0
  66. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0001/keywords.json +12 -0
  67. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0002/keywords.json +12 -0
  68. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0003/keywords.json +12 -0
  69. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0004/keywords.json +12 -0
  70. package/dist/catalog/knowledge-catalogs/ca/caselaw-washington-part-0005/keywords.json +12 -0
  71. package/dist/catalog/knowledge-catalogs/ca/caselaw-wyoming-part-0001/keywords.json +12 -0
  72. package/dist/catalog/knowledge-catalogs/index.json +1 -1
  73. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-aspnet-core-en/keywords.json +21 -0
  74. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-ai-platform-en/keywords.json +27 -0
  75. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-apps-compute-en/keywords.json +23 -0
  76. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-data-aiot-en/keywords.json +26 -0
  77. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-management-hybrid-en/keywords.json +28 -0
  78. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-azure-network-security-en/keywords.json +29 -0
  79. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-dotnet-en/keywords.json +21 -0
  80. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-entity-framework-en/keywords.json +14 -0
  81. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-microsoft-365-en/keywords.json +20 -0
  82. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-powershell-en/keywords.json +24 -0
  83. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-sql-server-en/keywords.json +27 -0
  84. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-apps-en/keywords.json +18 -0
  85. package/dist/catalog/knowledge-catalogs/mi/microsoftdocs-windows-server-en/keywords.json +28 -0
  86. package/dist/catalog/knowledge-catalogs/raw-index.json +1 -1
  87. package/dist/catalog/knowledge-catalogs/re/regional-american-south/keywords.json +1700 -0
  88. package/dist/catalog/knowledge-catalogs/re/regional-american-south/versions/2026.10.5/manifest.json +133 -0
  89. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/keywords.json +750 -0
  90. package/dist/catalog/knowledge-catalogs/re/regional-andes-amazon/versions/2026.10.5/manifest.json +133 -0
  91. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/keywords.json +1281 -0
  92. package/dist/catalog/knowledge-catalogs/re/regional-australia-nz/versions/2026.10.5/manifest.json +133 -0
  93. package/dist/catalog/knowledge-catalogs/re/regional-brazil/keywords.json +1125 -0
  94. package/dist/catalog/knowledge-catalogs/re/regional-brazil/versions/2026.10.5/manifest.json +133 -0
  95. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/keywords.json +3287 -0
  96. package/dist/catalog/knowledge-catalogs/re/regional-britain-ireland/versions/2026.10.5/manifest.json +133 -0
  97. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/keywords.json +1835 -0
  98. package/dist/catalog/knowledge-catalogs/re/regional-california-southwest/versions/2026.10.5/manifest.json +133 -0
  99. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/keywords.json +1184 -0
  100. package/dist/catalog/knowledge-catalogs/re/regional-canada-alaska/versions/2026.10.5/manifest.json +133 -0
  101. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/keywords.json +1503 -0
  102. package/dist/catalog/knowledge-catalogs/re/regional-central-eastern-europe/versions/2026.10.5/manifest.json +133 -0
  103. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/keywords.json +2836 -0
  104. package/dist/catalog/knowledge-catalogs/re/regional-east-asia/versions/2026.10.5/manifest.json +133 -0
  105. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/keywords.json +813 -0
  106. package/dist/catalog/knowledge-catalogs/re/regional-east-southern-africa/versions/2026.10.5/manifest.json +133 -0
  107. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/keywords.json +2082 -0
  108. package/dist/catalog/knowledge-catalogs/re/regional-mediterranean/versions/2026.10.5/manifest.json +133 -0
  109. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/keywords.json +1481 -0
  110. package/dist/catalog/knowledge-catalogs/re/regional-mexico-central-america/versions/2026.10.5/manifest.json +133 -0
  111. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/keywords.json +1272 -0
  112. package/dist/catalog/knowledge-catalogs/re/regional-middle-east/versions/2026.10.5/manifest.json +133 -0
  113. package/dist/catalog/knowledge-catalogs/re/regional-midwest/keywords.json +758 -0
  114. package/dist/catalog/knowledge-catalogs/re/regional-midwest/versions/2026.10.5/manifest.json +133 -0
  115. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/keywords.json +896 -0
  116. package/dist/catalog/knowledge-catalogs/re/regional-north-africa/versions/2026.10.5/manifest.json +133 -0
  117. package/dist/catalog/knowledge-catalogs/re/regional-northeast/keywords.json +1281 -0
  118. package/dist/catalog/knowledge-catalogs/re/regional-northeast/versions/2026.10.5/manifest.json +133 -0
  119. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/keywords.json +346 -0
  120. package/dist/catalog/knowledge-catalogs/re/regional-northern-eurasia/versions/2026.10.5/manifest.json +133 -0
  121. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/keywords.json +2688 -0
  122. package/dist/catalog/knowledge-catalogs/re/regional-northern-europe/versions/2026.10.5/manifest.json +133 -0
  123. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/keywords.json +973 -0
  124. package/dist/catalog/knowledge-catalogs/re/regional-pacific-islands/versions/2026.10.5/manifest.json +133 -0
  125. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/keywords.json +937 -0
  126. package/dist/catalog/knowledge-catalogs/re/regional-pacific-northwest/versions/2026.10.5/manifest.json +133 -0
  127. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/keywords.json +608 -0
  128. package/dist/catalog/knowledge-catalogs/re/regional-rockies-plains/versions/2026.10.5/manifest.json +133 -0
  129. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/keywords.json +633 -0
  130. package/dist/catalog/knowledge-catalogs/re/regional-south-asia/versions/2026.10.5/manifest.json +133 -0
  131. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/keywords.json +2697 -0
  132. package/dist/catalog/knowledge-catalogs/re/regional-southeast-asia/versions/2026.10.5/manifest.json +133 -0
  133. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/keywords.json +606 -0
  134. package/dist/catalog/knowledge-catalogs/re/regional-southern-cone/versions/2026.10.5/manifest.json +133 -0
  135. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/keywords.json +564 -0
  136. package/dist/catalog/knowledge-catalogs/re/regional-west-central-africa/versions/2026.10.5/manifest.json +133 -0
  137. package/dist/catalog/knowledge-catalogs/re/regional-western-europe/keywords.json +3247 -0
  138. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/manifest.json +47 -0
  139. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-east/versions/2026.10.5/manifest.json +133 -0
  140. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/manifest.json +47 -0
  141. package/dist/catalog/knowledge-catalogs/re/regional-western-europe-west/versions/2026.10.5/manifest.json +133 -0
  142. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/keywords.json +5437 -0
  143. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/manifest.json +1 -1
  144. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.10.1/manifest.json +181 -0
  145. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/keywords.json +4009 -0
  146. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/manifest.json +1 -1
  147. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.10.1/manifest.json +181 -0
  148. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/keywords.json +4009 -0
  149. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/manifest.json +1 -1
  150. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.10.1/manifest.json +217 -0
  151. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/keywords.json +5583 -0
  152. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/manifest.json +1 -1
  153. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.10.1/manifest.json +197 -0
  154. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/keywords.json +6386 -0
  155. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/manifest.json +2 -2
  156. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.10.1/manifest.json +197 -0
  157. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/keywords.json +4009 -0
  158. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/manifest.json +1 -1
  159. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.10.1/manifest.json +185 -0
  160. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/keywords.json +5672 -0
  161. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/manifest.json +1 -1
  162. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.10.1/manifest.json +137 -0
  163. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/manifest.json +68 -0
  164. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/versions/2026.10.1/manifest.json +217 -0
  165. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/manifest.json +68 -0
  166. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/versions/2026.10.1/manifest.json +217 -0
  167. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/keywords.json +4009 -0
  168. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/manifest.json +1 -1
  169. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.10.1/manifest.json +141 -0
  170. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/keywords.json +4009 -0
  171. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/manifest.json +1 -1
  172. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.10.1/manifest.json +185 -0
  173. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/keywords.json +5719 -0
  174. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/manifest.json +1 -1
  175. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.10.1/manifest.json +193 -0
  176. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/keywords.json +4009 -0
  177. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/manifest.json +1 -1
  178. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.10.1/manifest.json +189 -0
  179. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/keywords.json +16009 -0
  180. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/manifest.json +1 -1
  181. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.10.1/manifest.json +185 -0
  182. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/keywords.json +5843 -0
  183. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/manifest.json +1 -1
  184. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.10.1/manifest.json +189 -0
  185. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/keywords.json +6264 -0
  186. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/manifest.json +1 -1
  187. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.10.1/manifest.json +197 -0
  188. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/manifest.json +66 -0
  189. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/versions/2026.10.1/manifest.json +209 -0
  190. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/manifest.json +61 -0
  191. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/versions/2026.10.1/manifest.json +189 -0
  192. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/manifest.json +64 -0
  193. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/versions/2026.10.1/manifest.json +201 -0
  194. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/manifest.json +60 -0
  195. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/versions/2026.10.1/manifest.json +185 -0
  196. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/manifest.json +55 -0
  197. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/versions/2026.10.1/manifest.json +165 -0
  198. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/manifest.json +63 -0
  199. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/versions/2026.10.1/manifest.json +197 -0
  200. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/manifest.json +64 -0
  201. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/versions/2026.10.1/manifest.json +201 -0
  202. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/manifest.json +65 -0
  203. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/versions/2026.10.1/manifest.json +205 -0
  204. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/manifest.json +73 -0
  205. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/versions/2026.10.1/manifest.json +237 -0
  206. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/keywords.json +5447 -0
  207. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/manifest.json +1 -1
  208. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.10.1/manifest.json +197 -0
  209. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/keywords.json +4009 -0
  210. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/manifest.json +1 -1
  211. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.10.1/manifest.json +189 -0
  212. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/keywords.json +4009 -0
  213. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/manifest.json +1 -1
  214. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.10.1/manifest.json +185 -0
  215. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/keywords.json +5209 -0
  216. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/manifest.json +1 -1
  217. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.10.1/manifest.json +193 -0
  218. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/keywords.json +6537 -0
  219. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/manifest.json +1 -1
  220. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.10.1/manifest.json +185 -0
  221. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/keywords.json +5989 -0
  222. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/manifest.json +1 -1
  223. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.10.1/manifest.json +189 -0
  224. package/dist/catalog/provenance.json +2 -1
  225. package/dist/engines/native-file-manifest.json +198 -118
  226. package/dist/engines/native-manifest.d.ts +4 -4
  227. package/dist/engines/native-manifest.js +36 -34
  228. package/dist/engines/resolver.js +12 -1
  229. package/dist/fs/atomic.d.ts +4 -1
  230. package/dist/fs/atomic.js +7 -1
  231. package/dist/http/openai-compat/chat-target.d.ts +1 -1
  232. package/dist/http/openai-compat/chat-target.js +1 -1
  233. package/dist/http/openai-compat/engine-failure.js +7 -2
  234. package/dist/http/routes/v1-chat.js +1 -1
  235. package/dist/http/routes/v1-images.d.ts +44 -0
  236. package/dist/http/routes/v1-images.js +370 -0
  237. package/dist/http/routes/v1-knowledge.js +4 -0
  238. package/dist/http/routes/v1-responses.d.ts +1 -1
  239. package/dist/inference-service.d.ts +9 -1
  240. package/dist/inference-service.js +44 -11
  241. package/dist/knowledge/manager.d.ts +7 -0
  242. package/dist/knowledge/manager.js +32 -1
  243. package/dist/kokoro-lexicon/manifest.json +6 -3
  244. package/dist/models/image-fit.d.ts +83 -0
  245. package/dist/models/image-fit.js +163 -0
  246. package/dist/models/weight-facts.d.ts +36 -0
  247. package/dist/models/weight-facts.js +171 -0
  248. package/dist/perf/responsiveness.js +4 -3
  249. package/dist/providers/audio/kokoro-frontend.js +1 -1
  250. package/dist/providers/ds4/build-provider.js +34 -21
  251. package/dist/providers/ds4/dspark.d.ts +23 -5
  252. package/dist/providers/ds4/dspark.js +36 -8
  253. package/dist/providers/image/img2img-support.d.ts +40 -0
  254. package/dist/providers/image/img2img-support.js +74 -0
  255. package/dist/providers/image/local-engine.d.ts +31 -0
  256. package/dist/providers/image/local-engine.js +47 -0
  257. package/dist/providers/image/local-factory.d.ts +95 -0
  258. package/dist/providers/image/local-factory.js +270 -0
  259. package/dist/providers/image/mock.d.ts +23 -0
  260. package/dist/providers/image/mock.js +151 -0
  261. package/dist/providers/image/pull-registry.d.ts +106 -0
  262. package/dist/providers/image/pull-registry.js +227 -0
  263. package/dist/providers/image/sd-cpp.d.ts +200 -0
  264. package/dist/providers/image/sd-cpp.js +845 -0
  265. package/dist/providers/image/types.d.ts +235 -0
  266. package/dist/providers/image/types.js +20 -0
  267. package/dist/providers/llama-cpp/backend-health.d.ts +7 -0
  268. package/dist/providers/llama-cpp/backend-health.js +41 -1
  269. package/dist/providers/llama-cpp/build-provider.js +107 -56
  270. package/dist/providers/llama-cpp/cache-adapter.d.ts +7 -1
  271. package/dist/providers/llama-cpp/cache-adapter.js +9 -0
  272. package/dist/providers/llama-cpp/devices.d.ts +13 -2
  273. package/dist/providers/llama-cpp/devices.js +43 -6
  274. package/dist/providers/llama-cpp/models.js +4 -1
  275. package/dist/providers/llama-cpp/offload-planner.d.ts +23 -0
  276. package/dist/providers/llama-cpp/offload-planner.js +27 -0
  277. package/dist/providers/llama-cpp/provider.d.ts +14 -3
  278. package/dist/providers/llama-cpp/provider.js +35 -2
  279. package/dist/providers/mlx/provider.js +15 -5
  280. package/dist/providers/mlx/reasoning-stream.d.ts +15 -0
  281. package/dist/providers/mlx/reasoning-stream.js +35 -0
  282. package/dist/providers/native/capacity-broker.js +9 -3
  283. package/dist/providers/native/local-engine-runtime.js +15 -12
  284. package/dist/providers/native/supervisor.d.ts +8 -0
  285. package/dist/providers/native/supervisor.js +55 -5
  286. package/dist/providers/project-macro-loop-bail.js +5 -3
  287. package/dist/providers/provider-lifecycle.d.ts +21 -0
  288. package/dist/providers/provider-lifecycle.js +83 -0
  289. package/dist/providers/queue.d.ts +9 -2
  290. package/dist/providers/queue.js +17 -2
  291. package/dist/providers/retirement-gate.d.ts +20 -0
  292. package/dist/providers/retirement-gate.js +55 -0
  293. package/dist/providers/session-hooks.d.ts +4 -1
  294. package/dist/system/memory.js +6 -0
  295. package/dist/utils/image-meta.d.ts +12 -0
  296. package/dist/utils/image-meta.js +77 -0
  297. package/package.json +6 -6
@@ -1,4 +1,5 @@
1
- import { type ProviderName } from '@bendyline/gezel';
1
+ import { type LogOutput, type ProviderName } from '@bendyline/gezel';
2
+ import type { ImageProvider } from './providers/image/types.js';
2
3
  import type { LLMProvider } from './providers/types.js';
3
4
  import './http/auth-context.js';
4
5
  /** Same shape the full service reports, so one handler serves either host. */
@@ -14,7 +15,14 @@ export interface InferenceServiceOptions {
14
15
  home?: string;
15
16
  /** Host-provided local providers, useful for testing without downloading weights. */
16
17
  providers?: ReadonlyMap<ProviderName, LLMProvider>;
18
+ /** Host-provided image provider in place of the local engine, for tests. */
19
+ imageProvider?: ImageProvider;
17
20
  onUnexpectedHttpError?: (event: InferenceHttpErrorEvent) => void;
21
+ /**
22
+ * Where log records go while this host runs; restored on `stop()`. An app
23
+ * embedding the host passes `'stderr'` so its own stdout stays its own.
24
+ */
25
+ logOutput?: LogOutput;
18
26
  }
19
27
  export interface RunningInferenceService {
20
28
  readonly profile: 'embedded-inference';
@@ -1,6 +1,6 @@
1
1
  import { randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
2
2
  import { join } from 'node:path';
3
- import { GEZEL_API_GENERATION, GEZEL_API_GENERATION_FLOOR, GEZEL_VERSION, GezelConfigSchema, createLogger, nowIso, startSuspendMonitor, stopSuspendMonitor, } from '@bendyline/gezel';
3
+ import { GEZEL_API_GENERATION, GEZEL_API_GENERATION_FLOOR, GEZEL_VERSION, GezelConfigSchema, createLogger, getLogOutput, nowIso, setLogOutput, startSuspendMonitor, stopSuspendMonitor, } from '@bendyline/gezel';
4
4
  import { BundledSource, CatalogService } from '@bendyline/gezel-catalog';
5
5
  import { discoverNativeBinaries } from '@bendyline/gezel/native';
6
6
  import { gezelHome } from '@bendyline/gezel/paths';
@@ -14,6 +14,7 @@ import { enginesRoutes } from './http/routes/engines.js';
14
14
  import { modelBundleRoutes } from './http/routes/model-bundles.js';
15
15
  import { v1ChatRoutes } from './http/routes/v1-chat.js';
16
16
  import { v1EmbeddingsRoutes } from './http/routes/v1-embeddings.js';
17
+ import { v1ImagesRoutes } from './http/routes/v1-images.js';
17
18
  import { v1KnowledgeRoutes } from './http/routes/v1-knowledge.js';
18
19
  import { v1ModelsEnsureRoutes } from './http/routes/v1-models-ensure.js';
19
20
  import { v1ModelsRoutes } from './http/routes/v1-models.js';
@@ -23,6 +24,7 @@ import { KnowledgeManager } from './knowledge/manager.js';
23
24
  import { createWorkerCatalogHost } from './knowledge/worker-host.js';
24
25
  import { embeddingsHealth, openEmbeddings, shutdownEmbeddings } from './memory/embeddings.js';
25
26
  import { AppleFoundationModelsProvider } from './providers/apple-foundation-models/provider.js';
27
+ import { LocalImageEngine } from './providers/image/local-engine.js';
26
28
  import { EngineInference } from './providers/native/inference.js';
27
29
  import { resolveModelSessionDefaults } from './providers/session-defaults.js';
28
30
  import { MlxRuntimeStatusBus } from './python/mlx-runtime-status-bus.js';
@@ -35,16 +37,27 @@ import './http/auth-context.js';
35
37
  const log = createLogger('inference');
36
38
  /** Direct Fetch host: no listener, product store, background downloads or daemon discovery. */
37
39
  export async function startService(options = {}) {
40
+ const previousLogOutput = getLogOutput();
41
+ const restoreLogOutput = () => setLogOutput(previousLogOutput);
42
+ if (options.logOutput)
43
+ setLogOutput(options.logOutput);
38
44
  const home = options.home ?? gezelHome();
39
- await ensurePrivateUserHome(home);
40
- // Model files must land in this home's managed cache: unset, transformers.js
41
- // falls back to a module-relative cache that is read-only inside a packaged
42
- // app, and the embed worker (which reads this env) has no other view of home.
43
- process.env[HF_CACHE_DIR_ENV] ??= transformersCacheDir(home);
44
- const startedAt = nowIso();
45
45
  const runtimeDir = join(home, 'runtime');
46
- const lock = await acquireSingleInstanceLock({ runtimeDir, lockPath: join(runtimeDir, 'lock') });
47
- const cleanup = [() => lock.release()];
46
+ let lock;
47
+ try {
48
+ await ensurePrivateUserHome(home);
49
+ // Model files must land in this home's managed cache: unset, transformers.js
50
+ // falls back to a module-relative cache that is read-only inside a packaged
51
+ // app, and the embed worker (which reads this env) has no other view of home.
52
+ process.env[HF_CACHE_DIR_ENV] ??= transformersCacheDir(home);
53
+ lock = await acquireSingleInstanceLock({ runtimeDir, lockPath: join(runtimeDir, 'lock') });
54
+ }
55
+ catch (error) {
56
+ restoreLogOutput();
57
+ throw error;
58
+ }
59
+ const startedAt = nowIso();
60
+ const cleanup = [restoreLogOutput, () => lock.release()];
48
61
  const requests = new InFlightRequests();
49
62
  let stopping;
50
63
  let closed = false;
@@ -146,7 +159,25 @@ export async function startService(options = {}) {
146
159
  await knowledge.start();
147
160
  const relevance = new RelevanceModelManager({ home, readConfig: () => store.readConfig() });
148
161
  cleanup.push(() => relevanceScorer().dispose());
149
- const context = { home, store, catalog, chat, knowledge, relevance, ...components };
162
+ const images = new LocalImageEngine({
163
+ home,
164
+ catalog,
165
+ arbiter: components.gpuArbiter,
166
+ readConfig: () => store.readConfig(),
167
+ ...(options.imageProvider ? { provider: options.imageProvider } : {}),
168
+ });
169
+ cleanup.push(() => images.shutdown());
170
+ const context = {
171
+ home,
172
+ store,
173
+ catalog,
174
+ chat,
175
+ knowledge,
176
+ relevance,
177
+ images,
178
+ imageProvider: images,
179
+ ...components,
180
+ };
150
181
  const clientToken = randomBytes(32).toString('base64url');
151
182
  const tokenBytes = Buffer.from(clientToken);
152
183
  const app = new Hono();
@@ -180,12 +211,13 @@ export async function startService(options = {}) {
180
211
  nodeVersion: process.versions.node,
181
212
  platform: process.platform,
182
213
  embeddings: embeddingsHealth(),
214
+ images: { available: images.available() },
183
215
  }));
184
216
  app.use('*', async (c, next) => {
185
217
  const candidate = Buffer.from(c.req.header('authorization')?.replace(/^Bearer /, '') ?? '');
186
218
  if (candidate.length !== tokenBytes.length || !timingSafeEqual(candidate, tokenBytes))
187
219
  return c.json({ error: 'Unauthorized' }, 401);
188
- c.set('auth', { appId: 'host', scopes: ['openai', 'knowledge'] });
220
+ c.set('auth', { appId: 'host', scopes: ['openai', 'knowledge', 'images'] });
189
221
  return next();
190
222
  });
191
223
  const allowedProviders = ['llama-cpp', 'mlx', 'ds4', 'apple-foundation-models'];
@@ -196,6 +228,7 @@ export async function startService(options = {}) {
196
228
  app.route('/v1/models/ensure', v1ModelsEnsureRoutes(context));
197
229
  app.route('/v1/models', v1ModelsRoutes(context, { localOnly: true }));
198
230
  app.route('/v1/knowledge', v1KnowledgeRoutes(context));
231
+ app.route('/v1/images', v1ImagesRoutes(context));
199
232
  app.route('/api/engines', enginesRoutes(context));
200
233
  app.route('/api/model-bundles', modelBundleRoutes(context));
201
234
  for (const [engine, manager] of [
@@ -260,6 +260,13 @@ export declare class KnowledgeManager {
260
260
  * their own. Explicit search asks; proactive injection does not.
261
261
  */
262
262
  media?: boolean;
263
+ /**
264
+ * Also return up to this many of a document's other passages that the
265
+ * search found, after its best one. Fusion otherwise keeps one passage
266
+ * per document, chosen by vector similarity alone, so an article's name-
267
+ * dense infobox can stand in for the section a reranker would choose.
268
+ */
269
+ chunksPerDocument?: number;
263
270
  }): Promise<UnifiedSearchResult[]>;
264
271
  /** A document the lexical arms named but no chunk carries: cite it with its lead paragraph. */
265
272
  private toDocumentResult;
@@ -1315,6 +1315,20 @@ export class KnowledgeManager {
1315
1315
  }
1316
1316
  fused.set(key, entry);
1317
1317
  };
1318
+ // Every text passage the arms found, per document, best vector match first,
1319
+ // for `chunksPerDocument`. Fusion still ranks documents, not passages.
1320
+ const passagesByDocument = new Map();
1321
+ if ((opts.chunksPerDocument ?? 1) > 1) {
1322
+ for (const hit of response.chunks
1323
+ .filter((h) => !h.media)
1324
+ .sort((a, b) => (b.cosine ?? -1) - (a.cosine ?? -1))) {
1325
+ const key = `${hit.catalogKey}\u0000${hit.documentId}`;
1326
+ const passages = passagesByDocument.get(key) ?? [];
1327
+ if (!passages.some((known) => known.chunkUid === hit.chunkUid))
1328
+ passages.push(hit);
1329
+ passagesByDocument.set(key, passages);
1330
+ }
1331
+ }
1318
1332
  // Vector arm: one rank per document, in rerank-cosine order. A hit under
1319
1333
  // its profile's floor is not evidence at all — KNN always returns its
1320
1334
  // nearest rows, and a rank-0 row fuses to relevance 1.0 however far away
@@ -1446,7 +1460,24 @@ export class KnowledgeManager {
1446
1460
  continue;
1447
1461
  perCatalogCount.set(entry.catalogKey, count + 1);
1448
1462
  seenSpatial.add(spatialIdentity);
1449
- out.push({ ...result, ...matches.get(`${entry.catalogKey}\u0000${entry.documentId}`) });
1463
+ const docKey = `${entry.catalogKey}\u0000${entry.documentId}`;
1464
+ out.push({ ...result, ...matches.get(docKey) });
1465
+ if (out.length >= Math.max(10, opts.maxResults))
1466
+ break;
1467
+ // The document's other passages, each labelled by its own evidence: a
1468
+ // sibling is vector evidence only if it clears the floor by itself.
1469
+ const siblings = (passagesByDocument.get(docKey) ?? [])
1470
+ .filter((hit) => hit.chunkUid !== entry.chunk?.chunkUid)
1471
+ .slice(0, Math.max(0, (opts.chunksPerDocument ?? 1) - 1));
1472
+ const floor = this.vectorFloorFor(entry.catalogKey);
1473
+ for (const sibling of siblings) {
1474
+ const own = floor !== null && sibling.cosine !== undefined && sibling.cosine >= floor
1475
+ ? { arm: 'vector', similarity: sibling.cosine }
1476
+ : { arm: 'fts' };
1477
+ out.push(this.toResult(info, sibling, fusedRankRelevance(out.length), own));
1478
+ if (out.length >= Math.max(10, opts.maxResults))
1479
+ break;
1480
+ }
1450
1481
  if (out.length >= Math.max(10, opts.maxResults))
1451
1482
  break;
1452
1483
  }
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "source": {
3
- "url": "https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/kokoro-int8-multi-lang-v1_0.tar.bz2",
4
- "sha256": "4c3052abaa60943a341f193888cf6abd68787dae6ab8ae5c925a706caa247e4e",
5
- "file": "kokoro-model.tar.bz2"
3
+ "url": "https://huggingface.co/csukuangfj/kokoro-int8-multi-lang-v1_0/resolve/57adb37fc0e8d4bd430cfc1b8f8c2294945b9af2/",
4
+ "files": {
5
+ "lexicon-us-en.txt": "7daaab53a181be9885b853a8582bf1838186317e5dadacbcef9c426d6fa0da14",
6
+ "lexicon-gb-en.txt": "c4cbb37316f62210dff52718a7afcaae24f50c032cc75ab47ae67b831d1049e7",
7
+ "LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30"
8
+ }
6
9
  },
7
10
  "license": {
8
11
  "file": "LICENSE",
@@ -0,0 +1,83 @@
1
+ /**
2
+ * "Can this machine run that image model?" for the image catalog.
3
+ *
4
+ * Prices each catalog entry from the weight facts its gilde entry pins (core
5
+ * `media-memory.ts`) — never the network — and checks it against the same
6
+ * static ceilings the device ledger refuses at, so `wont-run` here means the
7
+ * launch path would refuse the model on this machine whatever else is
8
+ * running. The download pages hide those models and the pull routes refuse
9
+ * them. Contract: docs/media-model-memory.md.
10
+ *
11
+ * The video half lives with the video engine in the service, which shares
12
+ * the helpers here.
13
+ */
14
+ import { type GezelConfig, type ImageModelManifest, type ImageQuality, type MediaCapacity, type MediaFitAssessment, type MediaMemoryPool, type MediaMemoryRequirement, type MediaModelFit, type MediaModelFitResponse, type MediaWeightFile } from '@bendyline/gezel';
15
+ import type { CatalogService } from '@bendyline/gezel-catalog';
16
+ import type { CapacityBudgetKind } from '../providers/native/capacity-budget.js';
17
+ export interface MediaFitContext {
18
+ catalog: CatalogService;
19
+ readConfig: () => Promise<Pick<GezelConfig, 'localEngineMemoryGb'>>;
20
+ }
21
+ /**
22
+ * The 409 body a pull route answers with when the model cannot run here, or
23
+ * null to let the pull start. A failure to assess never blocks a download:
24
+ * the launch path still applies the same check.
25
+ */
26
+ export declare function wontRunRefusal(assess: () => Promise<MediaFitAssessment | null>): Promise<{
27
+ error: string;
28
+ code: string;
29
+ } | null>;
30
+ /**
31
+ * Where sd-server keeps weights: Metal on Apple Silicon, CPU on Intel Macs,
32
+ * CUDA or Vulkan elsewhere, falling back to the processor when no GPU
33
+ * answers. Windows on Arm runs on the processor unless discovery picked its
34
+ * CUDA build, which only an RTX Spark gets.
35
+ */
36
+ export declare function imageMediaPool(kind: CapacityBudgetKind, host?: {
37
+ platform: NodeJS.Platform;
38
+ arch: string;
39
+ sdServerBin?: string | undefined;
40
+ }): MediaMemoryPool;
41
+ /** The ceilings the device ledger applies on this machine, automatic and under the person's limit. */
42
+ export declare function mediaCapacity(pool: MediaMemoryPool, readConfig: MediaFitContext['readConfig']): Promise<MediaCapacity>;
43
+ /** The memory sd-server needs for one model, from its weight files and its launch profile. */
44
+ export declare function sdServerRequirement(input: {
45
+ modelId: string;
46
+ weightsKind: 'checkpoint' | 'diffusion-model';
47
+ files: readonly MediaWeightFile[];
48
+ pool: MediaMemoryPool;
49
+ /** The render size to price; the model's default size when absent. */
50
+ megapixels?: number;
51
+ }): MediaMemoryRequirement;
52
+ /**
53
+ * What a launched sd-server claims on the device ledger.
54
+ *
55
+ * On a discrete card the fit figures charge graphics memory for weights only,
56
+ * because sd-server can stream components from RAM, and the download page
57
+ * must not call a model that offloads "won't run". A running render holds its
58
+ * compute buffers on the card too, though: FLUX.2 Klein at 1024px held
59
+ * 9.4 GiB of a 12 GiB card's dedicated memory against 4.9 GiB of weights
60
+ * (RTX 5070 Ti Laptop, Vulkan, M0 spike 2026-10-25). Claiming weights only
61
+ * let a resident chat model keep its memory, and the render then failed at
62
+ * its first step. The claim is the estimated peak, capped at the card so a
63
+ * model that must offload is admitted once the card is otherwise free.
64
+ */
65
+ export declare function sdServerLedgerClaim(requirement: MediaMemoryRequirement, cardBytes: number): {
66
+ bytes: number;
67
+ gpuBytes: number;
68
+ };
69
+ /** Megapixels a model renders at a quality tier, inside its range. */
70
+ export declare function imageRenderMegapixels(manifest: Pick<ImageModelManifest, 'id' | 'widthRange' | 'heightRange'>, quality: ImageQuality): number;
71
+ export interface FitPlan {
72
+ pool: MediaMemoryPool;
73
+ capacity: MediaCapacity;
74
+ }
75
+ export declare function mediaFitResponse(plan: FitPlan, models: MediaModelFit[]): MediaModelFitResponse;
76
+ /**
77
+ * Every catalog image model's fit. With `quality`, each is priced at the size
78
+ * it renders at that tier rather than its default, which is how the direct
79
+ * image gezel's settings know whether High will fit.
80
+ */
81
+ export declare function imageCatalogFits(ctx: MediaFitContext, quality?: ImageQuality): Promise<MediaModelFitResponse>;
82
+ /** One catalog image model's fit, or null when the id is not in the catalog. */
83
+ export declare function imageModelFit(ctx: MediaFitContext, id: string): Promise<MediaFitAssessment | null>;
@@ -0,0 +1,163 @@
1
+ /**
2
+ * "Can this machine run that image model?" for the image catalog.
3
+ *
4
+ * Prices each catalog entry from the weight facts its gilde entry pins (core
5
+ * `media-memory.ts`) — never the network — and checks it against the same
6
+ * static ceilings the device ledger refuses at, so `wont-run` here means the
7
+ * launch path would refuse the model on this machine whatever else is
8
+ * running. The download pages hide those models and the pull routes refuse
9
+ * them. Contract: docs/media-model-memory.md.
10
+ *
11
+ * The video half lives with the video engine in the service, which shares
12
+ * the helpers here.
13
+ */
14
+ import { totalmem } from 'node:os';
15
+ import { MEDIA_MODEL_WONT_RUN_CODE, assessMediaFit, createLogger, imageMemoryRequirement, imageModelDefaultSide, resolveImageSize, } from '@bendyline/gezel';
16
+ import { isCudaArchivePath } from '@bendyline/gezel/native';
17
+ import { sdServerLoadProfile } from '../providers/image/sd-cpp.js';
18
+ import { configuredEngineMemoryBytes, staticCapacityCeilings, } from '../providers/native/device-capacity.js';
19
+ import { measuredCapacityBudget } from '../providers/native/measured-budget.js';
20
+ import { detectMemoryProfileCached } from '../system/memory.js';
21
+ import { imageCatalogWeightFiles, sdCppMainComponent } from './weight-facts.js';
22
+ const log = createLogger('media-fit');
23
+ /**
24
+ * The 409 body a pull route answers with when the model cannot run here, or
25
+ * null to let the pull start. A failure to assess never blocks a download:
26
+ * the launch path still applies the same check.
27
+ */
28
+ export async function wontRunRefusal(assess) {
29
+ try {
30
+ const fit = await assess();
31
+ if (fit?.verdict !== 'wont-run')
32
+ return null;
33
+ return {
34
+ error: `This model is too large for this machine. ${fit.reason}`,
35
+ code: MEDIA_MODEL_WONT_RUN_CODE,
36
+ };
37
+ }
38
+ catch (error) {
39
+ log.warn(`[media-fit] could not assess a pull, letting it start: ${error instanceof Error ? error.message : String(error)}`);
40
+ return null;
41
+ }
42
+ }
43
+ /**
44
+ * Where sd-server keeps weights: Metal on Apple Silicon, CPU on Intel Macs,
45
+ * CUDA or Vulkan elsewhere, falling back to the processor when no GPU
46
+ * answers. Windows on Arm runs on the processor unless discovery picked its
47
+ * CUDA build, which only an RTX Spark gets.
48
+ */
49
+ export function imageMediaPool(kind, host = {
50
+ platform: process.platform,
51
+ arch: process.arch,
52
+ sdServerBin: process.env.GEZEL_SD_SERVER_BIN,
53
+ }) {
54
+ if (host.platform === 'darwin')
55
+ return host.arch === 'arm64' ? 'unified' : 'cpu';
56
+ if (host.platform === 'win32' &&
57
+ host.arch === 'arm64' &&
58
+ !(host.sdServerBin && isCudaArchivePath(host.sdServerBin))) {
59
+ return 'cpu';
60
+ }
61
+ return kind === 'discrete-gpu' ? 'discrete' : kind === 'unified' ? 'unified' : 'cpu';
62
+ }
63
+ /** The ceilings the device ledger applies on this machine, automatic and under the person's limit. */
64
+ export async function mediaCapacity(pool, readConfig) {
65
+ const budget = await measuredCapacityBudget();
66
+ const ram = totalmem();
67
+ const auto = staticCapacityCeilings(budget, ram);
68
+ const configured = configuredEngineMemoryBytes(await readConfig().catch(() => ({})));
69
+ const limited = configured === undefined ? undefined : staticCapacityCeilings(budget, ram, configured);
70
+ const profile = pool === 'discrete' ? await detectMemoryProfileCached().catch(() => null) : null;
71
+ return {
72
+ pool,
73
+ ...auto,
74
+ ...(limited && limited.budgetBytes < auto.budgetBytes ? { limit: limited } : {}),
75
+ totalRamBytes: ram,
76
+ ...(profile?.gpuLargestDeviceBytes ? { gpuDeviceBytes: profile.gpuLargestDeviceBytes } : {}),
77
+ };
78
+ }
79
+ /** The memory sd-server needs for one model, from its weight files and its launch profile. */
80
+ export function sdServerRequirement(input) {
81
+ const profile = sdServerLoadProfile(input.modelId);
82
+ return imageMemoryRequirement({
83
+ files: input.files,
84
+ pool: input.pool,
85
+ vaeDecode: profile.vaeDecode,
86
+ // The rule names the diffusion weights, which are the main file.
87
+ bf16Components: profile.bf16TensorPattern ? [sdCppMainComponent(input.weightsKind)] : [],
88
+ megapixels: input.megapixels ?? profile.defaultSidePx ** 2 / 1024 ** 2,
89
+ });
90
+ }
91
+ /**
92
+ * What a launched sd-server claims on the device ledger.
93
+ *
94
+ * On a discrete card the fit figures charge graphics memory for weights only,
95
+ * because sd-server can stream components from RAM, and the download page
96
+ * must not call a model that offloads "won't run". A running render holds its
97
+ * compute buffers on the card too, though: FLUX.2 Klein at 1024px held
98
+ * 9.4 GiB of a 12 GiB card's dedicated memory against 4.9 GiB of weights
99
+ * (RTX 5070 Ti Laptop, Vulkan, M0 spike 2026-10-25). Claiming weights only
100
+ * let a resident chat model keep its memory, and the render then failed at
101
+ * its first step. The claim is the estimated peak, capped at the card so a
102
+ * model that must offload is admitted once the card is otherwise free.
103
+ */
104
+ export function sdServerLedgerClaim(requirement, cardBytes) {
105
+ if (requirement.pool !== 'discrete') {
106
+ return { bytes: requirement.bytes, gpuBytes: requirement.gpuBytes };
107
+ }
108
+ const gpuBytes = Math.min(Math.max(requirement.gpuPeakBytes, requirement.gpuBytes), cardBytes);
109
+ return { bytes: Math.max(requirement.bytes, gpuBytes), gpuBytes };
110
+ }
111
+ /** Megapixels a model renders at a quality tier, inside its range. */
112
+ export function imageRenderMegapixels(manifest, quality) {
113
+ const { width, height } = resolveImageSize({ quality }, {
114
+ defaultSidePx: imageModelDefaultSide(manifest.id),
115
+ widthRange: manifest.widthRange,
116
+ heightRange: manifest.heightRange,
117
+ });
118
+ return (width * height) / 1024 ** 2;
119
+ }
120
+ async function imagePlan(ctx) {
121
+ const budget = await measuredCapacityBudget();
122
+ const pool = imageMediaPool(budget.kind);
123
+ return { pool, capacity: await mediaCapacity(pool, ctx.readConfig) };
124
+ }
125
+ function assessImageManifest(plan, manifest, quality) {
126
+ return assessMediaFit(sdServerRequirement({
127
+ modelId: manifest.id,
128
+ weightsKind: manifest.weightsKind,
129
+ files: imageCatalogWeightFiles(manifest),
130
+ pool: plan.pool,
131
+ ...(quality ? { megapixels: imageRenderMegapixels(manifest, quality) } : {}),
132
+ }), plan.capacity);
133
+ }
134
+ export function mediaFitResponse(plan, models) {
135
+ return {
136
+ pool: plan.pool,
137
+ budgetBytes: plan.capacity.budgetBytes,
138
+ gpuBudgetBytes: plan.capacity.gpuBudgetBytes,
139
+ totalRamBytes: plan.capacity.totalRamBytes,
140
+ models,
141
+ };
142
+ }
143
+ /**
144
+ * Every catalog image model's fit. With `quality`, each is priced at the size
145
+ * it renders at that tier rather than its default, which is how the direct
146
+ * image gezel's settings know whether High will fit.
147
+ */
148
+ export async function imageCatalogFits(ctx, quality) {
149
+ const plan = await imagePlan(ctx);
150
+ const items = await ctx.catalog.list('image-model');
151
+ const models = items
152
+ .map((item) => item.manifest)
153
+ .filter((m) => m.kind === 'image-model')
154
+ .map((m) => ({ id: m.id, ...assessImageManifest(plan, m, quality) }));
155
+ return mediaFitResponse(plan, models);
156
+ }
157
+ /** One catalog image model's fit, or null when the id is not in the catalog. */
158
+ export async function imageModelFit(ctx, id) {
159
+ const item = await ctx.catalog.get('image-model', id);
160
+ if (!item || item.manifest.kind !== 'image-model')
161
+ return null;
162
+ return assessImageManifest(await imagePlan(ctx), item.manifest);
163
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Weight facts for media-model memory pricing: each weight file's size and
3
+ * how many elements it stores at every precision. Core `media-memory.ts`
4
+ * turns them into a requirement.
5
+ *
6
+ * Two sources that must agree. A catalog entry carries the facts as
7
+ * `tensors` beside each file's sha256, written by gilde's `pin-weight-tensors`
8
+ * tool when the model was authored; the launch path reads the same facts
9
+ * from the header of the file on disk. Files are pinned by sha256, so both
10
+ * describe the same bytes. Nothing here touches the network: an entry
11
+ * without the facts is priced by its plausible range instead.
12
+ */
13
+ import { type ImageModelManifest, type MediaWeightFile, type VideoModelManifest, type WeightTensors } from '@bendyline/gezel';
14
+ /** Length of the JSON header from a safetensors file's first 8 bytes, or null when implausible. */
15
+ export declare function safetensorsHeaderLength(prefix: Uint8Array, fileBytes: number): number | null;
16
+ /** The `tensors` facts of a safetensors file on disk; undefined when it cannot be read as one. */
17
+ export declare function readLocalWeightTensors(path: string): Promise<WeightTensors | undefined>;
18
+ export declare function videoCatalogWeightFiles(manifest: VideoModelManifest): MediaWeightFile[];
19
+ /**
20
+ * The weight files of an installed diffusers tree, headers read from disk.
21
+ * diffusers loads only the shards a directory's index names, so an unsharded
22
+ * duplicate beside them is never resident and is left out.
23
+ */
24
+ export declare function localDiffusersWeightFiles(modelDir: string): Promise<MediaWeightFile[]>;
25
+ /** The sd-cpp component the main weights load as: the flag they ride on. */
26
+ export declare function sdCppMainComponent(weightsKind: 'checkpoint' | 'diffusion-model'): string;
27
+ export declare function imageCatalogWeightFiles(manifest: ImageModelManifest): MediaWeightFile[];
28
+ /** The weight files of an installed sd-cpp model, headers read from disk. */
29
+ export declare function localSdCppWeightFiles(model: {
30
+ weightsPath: string;
31
+ weightsKind: 'checkpoint' | 'diffusion-model';
32
+ auxiliaryFiles: ReadonlyArray<{
33
+ role: string;
34
+ path: string;
35
+ }>;
36
+ }): Promise<MediaWeightFile[]>;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Weight facts for media-model memory pricing: each weight file's size and
3
+ * how many elements it stores at every precision. Core `media-memory.ts`
4
+ * turns them into a requirement.
5
+ *
6
+ * Two sources that must agree. A catalog entry carries the facts as
7
+ * `tensors` beside each file's sha256, written by gilde's `pin-weight-tensors`
8
+ * tool when the model was authored; the launch path reads the same facts
9
+ * from the header of the file on disk. Files are pinned by sha256, so both
10
+ * describe the same bytes. Nothing here touches the network: an entry
11
+ * without the facts is priced by its plausible range instead.
12
+ */
13
+ import { open, readFile, readdir, stat } from 'node:fs/promises';
14
+ import { join } from 'node:path';
15
+ import { tallySafetensorsHeader, weightFileFormat, } from '@bendyline/gezel';
16
+ /** A header larger than this is not a safetensors header. */
17
+ const MAX_HEADER_BYTES = 100 * 1024 * 1024;
18
+ /** Length of the JSON header from a safetensors file's first 8 bytes, or null when implausible. */
19
+ export function safetensorsHeaderLength(prefix, fileBytes) {
20
+ if (prefix.byteLength < 8)
21
+ return null;
22
+ const view = new DataView(prefix.buffer, prefix.byteOffset, 8);
23
+ const length = Number(view.getBigUint64(0, true));
24
+ if (!Number.isSafeInteger(length) || length <= 0 || length > MAX_HEADER_BYTES)
25
+ return null;
26
+ if (length + 8 > fileBytes)
27
+ return null;
28
+ return length;
29
+ }
30
+ /** The `tensors` facts of a safetensors file on disk; undefined when it cannot be read as one. */
31
+ export async function readLocalWeightTensors(path) {
32
+ let handle;
33
+ try {
34
+ handle = await open(path, 'r');
35
+ const size = (await handle.stat()).size;
36
+ const prefix = Buffer.alloc(8);
37
+ const { bytesRead } = await handle.read(prefix, 0, 8, 0);
38
+ const length = safetensorsHeaderLength(prefix.subarray(0, bytesRead), size);
39
+ if (length === null)
40
+ return undefined;
41
+ const header = Buffer.alloc(length);
42
+ await handle.read(header, 0, length, 8);
43
+ return tallySafetensorsHeader(JSON.parse(header.toString('utf8')));
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ finally {
49
+ await handle?.close();
50
+ }
51
+ }
52
+ function catalogFile(component, fileName, sizeBytes, tensors) {
53
+ const format = weightFileFormat(fileName);
54
+ if (!format)
55
+ return null;
56
+ return { component, sizeBytes, format, ...(tensors ? { tensors } : {}) };
57
+ }
58
+ // ─ Video: diffusers trees ───────────────────────────────────────────
59
+ /** The diffusers component a repo-relative file belongs to: its top-level folder. */
60
+ function diffusersComponent(name) {
61
+ const slash = name.indexOf('/');
62
+ return slash < 0 ? '' : name.slice(0, slash);
63
+ }
64
+ export function videoCatalogWeightFiles(manifest) {
65
+ return manifest.source.files.flatMap((file) => {
66
+ const priced = catalogFile(diffusersComponent(file.name), file.name, file.sizeBytes, file.tensors);
67
+ return priced ? [priced] : [];
68
+ });
69
+ }
70
+ /**
71
+ * The weight files of an installed diffusers tree, headers read from disk.
72
+ * diffusers loads only the shards a directory's index names, so an unsharded
73
+ * duplicate beside them is never resident and is left out.
74
+ */
75
+ export async function localDiffusersWeightFiles(modelDir) {
76
+ const out = [];
77
+ const walk = async (dir, component, depth) => {
78
+ if (depth > 6)
79
+ return;
80
+ const entries = await readdir(dir, { withFileTypes: true });
81
+ const indexed = await indexedShards(dir, entries.map((e) => e.name));
82
+ for (const entry of entries) {
83
+ const path = join(dir, entry.name);
84
+ if (entry.isDirectory()) {
85
+ await walk(path, component || entry.name, depth + 1);
86
+ continue;
87
+ }
88
+ if (!entry.isFile())
89
+ continue;
90
+ const format = weightFileFormat(entry.name);
91
+ if (!format)
92
+ continue;
93
+ if (format === 'safetensors' && indexed && !indexed.has(entry.name))
94
+ continue;
95
+ const sizeBytes = (await stat(path)).size;
96
+ const tensors = format === 'safetensors' ? await readLocalWeightTensors(path) : undefined;
97
+ out.push({ component, sizeBytes, format, ...(tensors ? { tensors } : {}) });
98
+ }
99
+ };
100
+ await walk(modelDir, '', 0);
101
+ return out;
102
+ }
103
+ async function indexedShards(dir, names) {
104
+ const index = names.find((n) => n.endsWith('.safetensors.index.json'));
105
+ if (!index)
106
+ return null;
107
+ try {
108
+ const parsed = JSON.parse(await readFile(join(dir, index), 'utf8'));
109
+ const shards = new Set(Object.values(parsed.weight_map ?? {}));
110
+ return shards.size > 0 ? shards : null;
111
+ }
112
+ catch {
113
+ return null;
114
+ }
115
+ }
116
+ // ─ Image: stable-diffusion.cpp files ────────────────────────────────
117
+ /** The sd-cpp component the main weights load as: the flag they ride on. */
118
+ export function sdCppMainComponent(weightsKind) {
119
+ return weightsKind === 'diffusion-model' ? 'diffusion_model' : 'model';
120
+ }
121
+ function urlFileName(url) {
122
+ try {
123
+ return decodeURIComponent(new URL(url).pathname.split('/').pop() ?? '');
124
+ }
125
+ catch {
126
+ return '';
127
+ }
128
+ }
129
+ export function imageCatalogWeightFiles(manifest) {
130
+ const entries = [
131
+ {
132
+ component: sdCppMainComponent(manifest.weightsKind),
133
+ url: manifest.downloadUrl,
134
+ sizeBytes: manifest.approxSizeBytes,
135
+ tensors: manifest.tensors,
136
+ },
137
+ ...manifest.auxiliaryFiles.map((aux) => ({
138
+ component: aux.role,
139
+ url: aux.downloadUrl,
140
+ sizeBytes: aux.approxSizeBytes,
141
+ tensors: aux.tensors,
142
+ })),
143
+ ];
144
+ return entries.flatMap((e) => {
145
+ const priced = catalogFile(e.component, urlFileName(e.url), e.sizeBytes, e.tensors);
146
+ return priced ? [priced] : [];
147
+ });
148
+ }
149
+ /** The weight files of an installed sd-cpp model, headers read from disk. */
150
+ export async function localSdCppWeightFiles(model) {
151
+ const entries = [
152
+ { component: sdCppMainComponent(model.weightsKind), path: model.weightsPath },
153
+ ...model.auxiliaryFiles.map((a) => ({ component: a.role, path: a.path })),
154
+ ];
155
+ const out = [];
156
+ for (const entry of entries) {
157
+ const format = weightFileFormat(entry.path);
158
+ if (!format)
159
+ continue;
160
+ let sizeBytes;
161
+ try {
162
+ sizeBytes = (await stat(entry.path)).size;
163
+ }
164
+ catch {
165
+ continue;
166
+ }
167
+ const tensors = format === 'safetensors' ? await readLocalWeightTensors(entry.path) : undefined;
168
+ out.push({ component: entry.component, sizeBytes, format, ...(tensors ? { tensors } : {}) });
169
+ }
170
+ return out;
171
+ }