@bendyline/gezel-inference 1.0.5 → 1.0.7

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 (144) hide show
  1. package/dist/cache/controller.d.ts +2 -0
  2. package/dist/cache/controller.js +38 -5
  3. package/dist/catalog/chat-models/index.json +1 -1
  4. package/dist/catalog/chat-models/lf/lfm3-1.7b-q4/manifest.json +114 -0
  5. package/dist/catalog/chat-models/lf/lfm3-1.7b-q4/versions/1.0.0/manifest.json +15 -0
  6. package/dist/catalog/chat-models/raw-index.json +1 -1
  7. package/dist/catalog/image-loras/index.json +1 -0
  8. package/dist/catalog/image-loras/kr/krea-2-ink-wash/manifest.json +31 -0
  9. package/dist/catalog/image-loras/kr/krea-2-ink-wash/versions/1.0.0/manifest.json +15 -0
  10. package/dist/catalog/image-loras/kr/krea-2-isometric-3d/manifest.json +32 -0
  11. package/dist/catalog/image-loras/kr/krea-2-isometric-3d/versions/1.0.0/manifest.json +15 -0
  12. package/dist/catalog/image-loras/kr/krea-2-kids-drawing/manifest.json +31 -0
  13. package/dist/catalog/image-loras/kr/krea-2-kids-drawing/versions/1.0.0/manifest.json +15 -0
  14. package/dist/catalog/image-loras/kr/krea-2-pixel-art/manifest.json +31 -0
  15. package/dist/catalog/image-loras/kr/krea-2-pixel-art/versions/1.0.0/manifest.json +15 -0
  16. package/dist/catalog/image-loras/kr/krea-2-soft-watercolor/manifest.json +31 -0
  17. package/dist/catalog/image-loras/kr/krea-2-soft-watercolor/versions/1.0.0/manifest.json +15 -0
  18. package/dist/catalog/image-loras/kr/krea-2-turbo-4step/manifest.json +31 -0
  19. package/dist/catalog/image-loras/kr/krea-2-turbo-4step/versions/1.0.0/manifest.json +15 -0
  20. package/dist/catalog/image-loras/mo/moss-image-gouache/manifest.json +29 -0
  21. package/dist/catalog/image-loras/mo/moss-image-gouache/versions/1.0.0/manifest.json +15 -0
  22. package/dist/catalog/image-loras/mo/moss-image-sft-4step/manifest.json +30 -0
  23. package/dist/catalog/image-loras/mo/moss-image-sft-4step/versions/1.0.0/manifest.json +15 -0
  24. package/dist/catalog/image-loras/qw/qwen-image-edit-2511-lightning/manifest.json +31 -0
  25. package/dist/catalog/image-loras/qw/qwen-image-edit-2511-lightning/versions/1.0.0/manifest.json +15 -0
  26. package/dist/catalog/image-loras/raw-index.json +1 -0
  27. package/dist/catalog/image-loras/sd/sdxl-3d-render/manifest.json +29 -0
  28. package/dist/catalog/image-loras/sd/sdxl-3d-render/versions/1.0.0/manifest.json +15 -0
  29. package/dist/catalog/image-loras/sd/sdxl-coloring-book/manifest.json +30 -0
  30. package/dist/catalog/image-loras/sd/sdxl-coloring-book/versions/1.0.0/manifest.json +15 -0
  31. package/dist/catalog/image-loras/sd/sdxl-papercut/manifest.json +29 -0
  32. package/dist/catalog/image-loras/sd/sdxl-papercut/versions/1.0.0/manifest.json +15 -0
  33. package/dist/catalog/image-loras/sd/sdxl-pixel-art/manifest.json +29 -0
  34. package/dist/catalog/image-loras/sd/sdxl-pixel-art/versions/1.0.0/manifest.json +15 -0
  35. package/dist/catalog/image-models/fl/flux-2-klein-4b-q4/manifest.json +3 -0
  36. package/dist/catalog/image-models/index.json +1 -1
  37. package/dist/catalog/image-models/qw/qwen-image-edit-2511-q4/manifest.json +44 -0
  38. package/dist/catalog/image-models/qw/qwen-image-edit-2511-q4/versions/1.0.0/manifest.json +36 -0
  39. package/dist/catalog/image-models/raw-index.json +1 -1
  40. package/dist/catalog/knowledge-catalogs/index.json +1 -1
  41. package/dist/catalog/knowledge-catalogs/raw-index.json +1 -1
  42. package/dist/catalog/knowledge-catalogs/wi/wikipedia-arts/versions/2026.10.2/manifest.json +181 -0
  43. package/dist/catalog/knowledge-catalogs/wi/wikipedia-astronomy/versions/2026.10.2/manifest.json +181 -0
  44. package/dist/catalog/knowledge-catalogs/wi/wikipedia-biology/versions/2026.10.2/manifest.json +217 -0
  45. package/dist/catalog/knowledge-catalogs/wi/wikipedia-business/versions/2026.10.2/manifest.json +197 -0
  46. package/dist/catalog/knowledge-catalogs/wi/wikipedia-film-tv/versions/2026.10.2/manifest.json +197 -0
  47. package/dist/catalog/knowledge-catalogs/wi/wikipedia-food-drink/versions/2026.10.2/manifest.json +185 -0
  48. package/dist/catalog/knowledge-catalogs/wi/wikipedia-games/versions/2026.10.2/manifest.json +181 -0
  49. package/dist/catalog/knowledge-catalogs/wi/wikipedia-general/manifest.json +55 -0
  50. package/dist/catalog/knowledge-catalogs/wi/wikipedia-general/versions/2026.10.2/manifest.json +165 -0
  51. package/dist/catalog/knowledge-catalogs/wi/wikipedia-geography/versions/2026.10.2/manifest.json +217 -0
  52. package/dist/catalog/knowledge-catalogs/wi/wikipedia-history/versions/2026.10.2/manifest.json +217 -0
  53. package/dist/catalog/knowledge-catalogs/wi/wikipedia-language/versions/2026.10.2/manifest.json +181 -0
  54. package/dist/catalog/knowledge-catalogs/wi/wikipedia-law/versions/2026.10.2/manifest.json +185 -0
  55. package/dist/catalog/knowledge-catalogs/wi/wikipedia-literature/versions/2026.10.2/manifest.json +193 -0
  56. package/dist/catalog/knowledge-catalogs/wi/wikipedia-mathematics/versions/2026.10.2/manifest.json +189 -0
  57. package/dist/catalog/knowledge-catalogs/wi/wikipedia-medicine/versions/2026.10.2/manifest.json +185 -0
  58. package/dist/catalog/knowledge-catalogs/wi/wikipedia-military/versions/2026.10.2/manifest.json +189 -0
  59. package/dist/catalog/knowledge-catalogs/wi/wikipedia-music/versions/2026.10.2/manifest.json +197 -0
  60. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-arts/versions/2026.10.2/manifest.json +209 -0
  61. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-business/versions/2026.10.2/manifest.json +189 -0
  62. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-entertainment/versions/2026.10.2/manifest.json +201 -0
  63. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-military/versions/2026.10.2/manifest.json +185 -0
  64. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-other/versions/2026.10.2/manifest.json +165 -0
  65. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-politics/versions/2026.10.2/manifest.json +197 -0
  66. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-religion/versions/2026.10.2/manifest.json +201 -0
  67. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-science/versions/2026.10.2/manifest.json +205 -0
  68. package/dist/catalog/knowledge-catalogs/wi/wikipedia-people-sports/versions/2026.10.2/manifest.json +237 -0
  69. package/dist/catalog/knowledge-catalogs/wi/wikipedia-politics/versions/2026.10.2/manifest.json +197 -0
  70. package/dist/catalog/knowledge-catalogs/wi/wikipedia-religion-philosophy/versions/2026.10.2/manifest.json +189 -0
  71. package/dist/catalog/knowledge-catalogs/wi/wikipedia-science/versions/2026.10.2/manifest.json +185 -0
  72. package/dist/catalog/knowledge-catalogs/wi/wikipedia-sports/versions/2026.10.2/manifest.json +193 -0
  73. package/dist/catalog/knowledge-catalogs/wi/wikipedia-technology/versions/2026.10.2/manifest.json +185 -0
  74. package/dist/catalog/knowledge-catalogs/wi/wikipedia-transportation/versions/2026.10.2/manifest.json +189 -0
  75. package/dist/catalog/provenance.json +2 -1
  76. package/dist/engine-components.js +2 -2
  77. package/dist/engines/electron-native-reuse.d.ts +7 -1
  78. package/dist/engines/electron-native-reuse.js +12 -4
  79. package/dist/engines/native-file-manifest.json +546 -406
  80. package/dist/engines/native-manifest.d.ts +4 -4
  81. package/dist/engines/native-manifest.js +36 -36
  82. package/dist/engines/resolver.d.ts +1 -1
  83. package/dist/engines/resolver.js +48 -51
  84. package/dist/http/auth-context.d.ts +12 -0
  85. package/dist/http/routes/image-ensure-routes.d.ts +4 -0
  86. package/dist/http/routes/image-ensure-routes.js +102 -0
  87. package/dist/http/routes/v1-image-styles.d.ts +5 -0
  88. package/dist/http/routes/v1-image-styles.js +91 -0
  89. package/dist/http/routes/v1-images.d.ts +1 -0
  90. package/dist/http/routes/v1-images.js +15 -93
  91. package/dist/inference-service.js +2 -1
  92. package/dist/knowledge/worker-host.js +2 -0
  93. package/dist/machine-engine/inspect-runtime.js +12 -3
  94. package/dist/memory/embed-core.js +3 -0
  95. package/dist/memory/embeddings.js +2 -0
  96. package/dist/models/image-fit.js +2 -2
  97. package/dist/models/weight-facts.d.ts +5 -0
  98. package/dist/models/weight-facts.js +5 -2
  99. package/dist/providers/ds4/build-provider.js +1 -1
  100. package/dist/providers/ds4/residency.js +3 -3
  101. package/dist/providers/image/img2img-support.d.ts +36 -1
  102. package/dist/providers/image/img2img-support.js +30 -1
  103. package/dist/providers/image/local-engine.d.ts +1 -0
  104. package/dist/providers/image/local-engine.js +8 -2
  105. package/dist/providers/image/local-factory.d.ts +10 -1
  106. package/dist/providers/image/local-factory.js +33 -6
  107. package/dist/providers/image/mock.d.ts +8 -1
  108. package/dist/providers/image/mock.js +46 -1
  109. package/dist/providers/image/pull-registry.d.ts +25 -3
  110. package/dist/providers/image/pull-registry.js +96 -34
  111. package/dist/providers/image/sd-cpp.d.ts +63 -4
  112. package/dist/providers/image/sd-cpp.js +361 -38
  113. package/dist/providers/image/types.d.ts +76 -4
  114. package/dist/providers/image/types.js +8 -0
  115. package/dist/providers/llama-cpp/build-provider.js +3 -2
  116. package/dist/providers/llama-cpp/cache-adapter.d.ts +3 -0
  117. package/dist/providers/llama-cpp/cache-adapter.js +18 -4
  118. package/dist/providers/llama-cpp/devices.js +2 -2
  119. package/dist/providers/llama-cpp/engine-flags.d.ts +5 -0
  120. package/dist/providers/llama-cpp/engine-flags.js +5 -2
  121. package/dist/providers/llama-cpp/provider.js +20 -4
  122. package/dist/providers/mlx/provider.js +13 -4
  123. package/dist/providers/mlx/python/gezel_mlx_server.py +9 -2
  124. package/dist/providers/mlx/python/spec_decode.py +44 -5
  125. package/dist/providers/native/capacity-broker.d.ts +1 -1
  126. package/dist/providers/native/capacity-broker.js +8 -8
  127. package/dist/providers/native/capacity-budget.js +5 -4
  128. package/dist/providers/native/device-capacity-ledger.d.ts +2 -0
  129. package/dist/providers/native/device-capacity-ledger.js +36 -5
  130. package/dist/providers/native/device-capacity.js +4 -3
  131. package/dist/providers/native/local-engine-runtime.js +4 -4
  132. package/dist/providers/native/process-identity.d.ts +2 -0
  133. package/dist/providers/native/process-identity.js +70 -0
  134. package/dist/relevance/relevance-core.js +2 -0
  135. package/dist/relevance/relevance-model.js +2 -0
  136. package/dist/relevance/settings.js +2 -2
  137. package/dist/runtime-lock.d.ts +43 -5
  138. package/dist/runtime-lock.js +189 -26
  139. package/dist/system/host-memory.d.ts +46 -0
  140. package/dist/system/host-memory.js +89 -0
  141. package/dist/system/memory.js +5 -4
  142. package/dist/transformers-cache.js +2 -0
  143. package/dist/utils/download-common.d.ts +1 -1
  144. package/package.json +8 -8
@@ -40,12 +40,12 @@
40
40
  * but logs that it could not anchor to a baked-in digest.
41
41
  */
42
42
  /** Native release version this build pins. Placeholder until first public release. */
43
- export declare const NATIVE_ENGINE_RELEASE = "0.1.54";
43
+ export declare const NATIVE_ENGINE_RELEASE = "0.1.57";
44
44
  /** sha256 of the pinned release's `SHA256SUMS` asset. All-zeros = unpinned. */
45
- export declare const SHA256SUMS_DIGEST = "087215a12096127a779b20e0dcb7d2ed9ce5dda1c81f33fdeb6b6eb730485b20";
46
- /** Exact SHA256 values for every engine archive published by native-v0.1.54. */
45
+ export declare const SHA256SUMS_DIGEST = "977b0ad4cdb8983ed44d7a3223267038b1f35b2806d8a1807d7d15c5c7e94f47";
46
+ /** Exact SHA256 values for every engine archive published by native-v0.1.57. */
47
47
  export declare const NATIVE_ENGINE_ARCHIVE_SHA256: Readonly<Record<string, string>>;
48
- /** Download size in bytes of every engine archive published by native-v0.1.54. */
48
+ /** Download size in bytes of every engine archive published by native-v0.1.57. */
49
49
  export declare const NATIVE_ENGINE_ARCHIVE_BYTES: Readonly<Record<string, number>>;
50
50
  /**
51
51
  * True only when the pinned release's standalone macOS archives were
@@ -40,47 +40,47 @@
40
40
  * but logs that it could not anchor to a baked-in digest.
41
41
  */
42
42
  /** Native release version this build pins. Placeholder until first public release. */
43
- export const NATIVE_ENGINE_RELEASE = '0.1.54';
43
+ export const NATIVE_ENGINE_RELEASE = '0.1.57';
44
44
  /** sha256 of the pinned release's `SHA256SUMS` asset. All-zeros = unpinned. */
45
- export const SHA256SUMS_DIGEST = '087215a12096127a779b20e0dcb7d2ed9ce5dda1c81f33fdeb6b6eb730485b20';
45
+ export const SHA256SUMS_DIGEST = '977b0ad4cdb8983ed44d7a3223267038b1f35b2806d8a1807d7d15c5c7e94f47';
46
46
  // BEGIN PINNED NATIVE ARCHIVE HASHES
47
- /** Exact SHA256 values for every engine archive published by native-v0.1.54. */
47
+ /** Exact SHA256 values for every engine archive published by native-v0.1.57. */
48
48
  export const NATIVE_ENGINE_ARCHIVE_SHA256 = Object.freeze({
49
- 'gezel-native-0.1.54-darwin-arm64-metal.tar.gz': 'f2990970303b954af2fd2e2bd31efef7d1c231bea16e026e0cdc0a7f9cc17842',
50
- 'gezel-native-0.1.54-darwin-arm64.tar.gz': '850f28338c52f945996c55edd77cf14d451c9bc4a09f719f6608885ddab99687',
51
- 'gezel-native-0.1.54-linux-arm64-cpu.tar.gz': '7dac7fed45c46b591cd6d597d639c385f54a3a367ac15d6097d3ad04d9c3c6e6',
52
- 'gezel-native-0.1.54-linux-arm64-cuda.tar.gz': 'f73c4569c356c4584199513c6c1f1f0bd3f0151fb1845696e2fa43f2b3626803',
53
- 'gezel-native-0.1.54-linux-arm64.tar.gz': 'f034ad2d3d12165c979d2fff2d34752c8d4f8ff836d3c416c9c64535f3bb652b',
54
- 'gezel-native-0.1.54-linux-x64-cpu.tar.gz': '57de7d52b0e95e3886bf4ffad7e015b98ba8bbea96b95d8cb3e26bc1ff309e99',
55
- 'gezel-native-0.1.54-linux-x64-cuda.tar.gz': 'c2d8616410f72b8bb217194f7c71d5175ed1c94ac6d9d94f660e0f535a3cff22',
56
- 'gezel-native-0.1.54-linux-x64-vulkan.tar.gz': '89f3233f41861404db082219962eb25d1b2c3f6e42bbc2696fda122ce845371d',
57
- 'gezel-native-0.1.54-linux-x64.tar.gz': 'f42e42d71187c6ef5af9685ebb65511bb7ac638815105f09f3df22cfdb9e6bce',
58
- 'gezel-native-0.1.54-win32-arm64-cpu.zip': 'e482e2af92f28135aea2e21ae97290e231b0dc77eadc8cc532d2506304d27575',
59
- 'gezel-native-0.1.54-win32-arm64-cuda.zip': 'ff6eaf7f070e9aba7fc087a155896f73b12664d867e0374af5546e941c153b82',
60
- 'gezel-native-0.1.54-win32-arm64.zip': '9b854d824117fe56d7d532ab83c01693a97cf6b45752e69cb895aa183c8cff35',
61
- 'gezel-native-0.1.54-win32-x64-cpu.zip': '93c8f22b47831ba8e0808033e87ce91cdb0d481890602857b6b8b5295cc7d50b',
62
- 'gezel-native-0.1.54-win32-x64-cuda.zip': '84da0b362e502d0bb6e3509528e7a4ccff50c2b9fcaa2fa1a62b3d9b0ad9f5d2',
63
- 'gezel-native-0.1.54-win32-x64-vulkan.zip': '1a3c99ce8343552fb17af80c36ba8ebb7c13ac8d6b4966f3aa3054018d41fa11',
64
- 'gezel-native-0.1.54-win32-x64.zip': 'f224fcdea6945ce574d32bee6ace345f82847f317c40cfa9059feba9b87ac0ca',
49
+ 'gezel-native-0.1.57-darwin-arm64-metal.tar.gz': '6b97be648b032980cf73663db4424140f4cc04577972dc283b956af677ce884a',
50
+ 'gezel-native-0.1.57-darwin-arm64.tar.gz': 'e8ca070c4d3961e95946ed32fe7376ddbc97e407dd3f5b78e26cab20c8fb286a',
51
+ 'gezel-native-0.1.57-linux-arm64-cpu.tar.gz': 'cc87822123602a0024c63a0d65789232a665140cb2fe37b106d5bd680d12f795',
52
+ 'gezel-native-0.1.57-linux-arm64-cuda.tar.gz': '315a441e5698800945f7030e9da961e20f3cf379a4b75c98e1d6ba88c8fee1c5',
53
+ 'gezel-native-0.1.57-linux-arm64.tar.gz': '0684b77d23f008f8a2aa0d9d8931437bacd8569fb6c10d3ddab61a5fb25b6a06',
54
+ 'gezel-native-0.1.57-linux-x64-cpu.tar.gz': 'b2100842f51c393b92667535798e49932173d52626f5ae72c40005b3408f1201',
55
+ 'gezel-native-0.1.57-linux-x64-cuda.tar.gz': '2fca7720614687e8491be17366060c604551257199d395f795b27a87216bcde9',
56
+ 'gezel-native-0.1.57-linux-x64-vulkan.tar.gz': 'c1014a1fe1d241ad1ee9abfa5badafcce208cbff8d38b4b4deb4779f31a95bef',
57
+ 'gezel-native-0.1.57-linux-x64.tar.gz': 'a7f3dbe1941c3d03ed121c32be1bdd199aea47080b03d89989590a0f5d13c5ff',
58
+ 'gezel-native-0.1.57-win32-arm64-cpu.zip': '12d66681cec1872f23b015c7d0bd45a25ed262342da6b0ecea8bea303adf2105',
59
+ 'gezel-native-0.1.57-win32-arm64-cuda.zip': 'b437a9f0894673179f91a1af75d5d7d058dafa1b4f48a57eab123596f1c21ca4',
60
+ 'gezel-native-0.1.57-win32-arm64.zip': '21cddb8b733f9a2669d64b1ada18002f60bb2779f2d5e2aacfb88214db00da7e',
61
+ 'gezel-native-0.1.57-win32-x64-cpu.zip': 'a81f7c6754f1954a0ed5de1efc47d6194dc60d912138a9d2b8e4f992168b12c6',
62
+ 'gezel-native-0.1.57-win32-x64-cuda.zip': '9e3f21713fe77c23536dd4124244ac3834f90c82d6e470cb6836a73bb4f7c592',
63
+ 'gezel-native-0.1.57-win32-x64-vulkan.zip': '0d473300317b4f6cb072bdd7875ce1536a85fe50e781c435e1aef1c4cbdb08e5',
64
+ 'gezel-native-0.1.57-win32-x64.zip': '89a073abcfc97e50b9a0c39f56862b51ac21139b7ca4a3e7a75105dca56292a2',
65
65
  });
66
- /** Download size in bytes of every engine archive published by native-v0.1.54. */
66
+ /** Download size in bytes of every engine archive published by native-v0.1.57. */
67
67
  export const NATIVE_ENGINE_ARCHIVE_BYTES = Object.freeze({
68
- 'gezel-native-0.1.54-darwin-arm64-metal.tar.gz': 7056387,
69
- 'gezel-native-0.1.54-darwin-arm64.tar.gz': 42224129,
70
- 'gezel-native-0.1.54-linux-arm64-cpu.tar.gz': 8838944,
71
- 'gezel-native-0.1.54-linux-arm64-cuda.tar.gz': 620429935,
72
- 'gezel-native-0.1.54-linux-arm64.tar.gz': 42037092,
73
- 'gezel-native-0.1.54-linux-x64-cpu.tar.gz': 12914025,
74
- 'gezel-native-0.1.54-linux-x64-cuda.tar.gz': 993587032,
75
- 'gezel-native-0.1.54-linux-x64-vulkan.tar.gz': 25672135,
76
- 'gezel-native-0.1.54-linux-x64.tar.gz': 57185943,
77
- 'gezel-native-0.1.54-win32-arm64-cpu.zip': 5623741,
78
- 'gezel-native-0.1.54-win32-arm64-cuda.zip': 242341587,
79
- 'gezel-native-0.1.54-win32-arm64.zip': 42236457,
80
- 'gezel-native-0.1.54-win32-x64-cpu.zip': 8719660,
81
- 'gezel-native-0.1.54-win32-x64-cuda.zip': 749849595,
82
- 'gezel-native-0.1.54-win32-x64-vulkan.zip': 21128362,
83
- 'gezel-native-0.1.54-win32-x64.zip': 55668353,
68
+ 'gezel-native-0.1.57-darwin-arm64-metal.tar.gz': 7387963,
69
+ 'gezel-native-0.1.57-darwin-arm64.tar.gz': 42223786,
70
+ 'gezel-native-0.1.57-linux-arm64-cpu.tar.gz': 9223249,
71
+ 'gezel-native-0.1.57-linux-arm64-cuda.tar.gz': 621626283,
72
+ 'gezel-native-0.1.57-linux-arm64.tar.gz': 42040003,
73
+ 'gezel-native-0.1.57-linux-x64-cpu.tar.gz': 13398337,
74
+ 'gezel-native-0.1.57-linux-x64-cuda.tar.gz': 1000325316,
75
+ 'gezel-native-0.1.57-linux-x64-vulkan.tar.gz': 26290440,
76
+ 'gezel-native-0.1.57-linux-x64.tar.gz': 57190295,
77
+ 'gezel-native-0.1.57-win32-arm64-cpu.zip': 6049234,
78
+ 'gezel-native-0.1.57-win32-arm64-cuda.zip': 243595554,
79
+ 'gezel-native-0.1.57-win32-arm64.zip': 42236484,
80
+ 'gezel-native-0.1.57-win32-x64-cpu.zip': 9131460,
81
+ 'gezel-native-0.1.57-win32-x64-cuda.zip': 756439338,
82
+ 'gezel-native-0.1.57-win32-x64-vulkan.zip': 21673895,
83
+ 'gezel-native-0.1.57-win32-x64.zip': 55668381,
84
84
  });
85
85
  // END PINNED NATIVE ARCHIVE HASHES
86
86
  /**
@@ -32,7 +32,7 @@ export interface ResolveEngineOptions {
32
32
  signaturePolicy?: SignaturePolicy;
33
33
  fetchImpl?: typeof fetch;
34
34
  signal?: AbortSignal;
35
- /** Pre-resolved token: `undefined` = auto-resolve; `null` = explicitly none. */
35
+ /** Pre-resolved token: `undefined` = from the environment; `null` = explicitly none. */
36
36
  token?: string | null;
37
37
  /** Override the source-pinned SHA256SUMS digest (tests). */
38
38
  expectedSha256sumsDigest?: string;
@@ -3,7 +3,7 @@ import { createReadStream, existsSync, readdirSync } from 'node:fs';
3
3
  import { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
4
4
  import { dirname, join } from 'node:path';
5
5
  import { HttpStatusError, createLogger, nowIso, resolveDistributionProfile, retryTransient, } from '@bendyline/gezel';
6
- import { DUCKDB_APPLE_TEAM_ID, DUCKDB_ARCHIVE_SHA256, DUCKDB_ASSET, DUCKDB_BINARY_SHA256, DUCKDB_VERSION, DUCKDB_WINDOWS_PUBLISHER, MXC_EXECUTOR_NAME, MXC_EXECUTOR_SHA256, MXC_LICENSE_SHA256, MXC_TARBALL_INTEGRITY, MXC_TARBALL_LICENSE_ENTRY, MXC_TARBALL_SHA256, MXC_TARBALL_URL, MXC_VERIFIED_SENTINEL, MXC_VERSION, MXC_WINDOWS_PUBLISHER, duckdbAssetUrl, duckdbBinaryName, duckdbInstallDir, duckdbPlatformKey, mxcArch, mxcInstallDir, mxcTarballEntry, resolvePlatformKey, windowsHeadlessSpawnOptions, } from '@bendyline/gezel/native';
6
+ import { DUCKDB_APPLE_TEAM_ID, DUCKDB_ARCHIVE_SHA256, DUCKDB_ASSET, DUCKDB_BINARY_SHA256, DUCKDB_VERSION, DUCKDB_WINDOWS_PUBLISHER, MXC_EXECUTOR_NAME, MXC_EXECUTOR_SHA256, MXC_LICENSE_SHA256, MXC_TARBALL_INTEGRITY, MXC_TARBALL_LICENSE_ENTRY, MXC_TARBALL_SHA256, MXC_TARBALL_URL, MXC_VERIFIED_SENTINEL, MXC_VERSION, MXC_WINDOWS_PUBLISHER, duckdbAssetUrl, duckdbBinaryName, duckdbInstallDir, duckdbPlatformKey, mxcArch, mxcInstallDir, mxcTarballEntry, resolvePlatformKey, } from '@bendyline/gezel/native';
7
7
  import * as tar from 'tar';
8
8
  import { downloadWithRetry, friendlyErrors, } from '../utils/download-with-retry.js';
9
9
  import { extractZip } from '../utils/extract-zip.js';
@@ -33,6 +33,7 @@ const ENGINE_ENV_VAR = {
33
33
  uv: 'GEZEL_UV_BIN',
34
34
  duckdb: 'GEZEL_DUCKDB_BIN',
35
35
  'apple-fm': 'GEZEL_APPLE_FM_BIN',
36
+ sandbox: 'GEZEL_SANDBOX_BIN',
36
37
  };
37
38
  /**
38
39
  * Thrown for the "can't resolve, and that's expected/actionable" cases:
@@ -541,14 +542,16 @@ export async function* resolveEngine(opts) {
541
542
  // `bendyline/gezel` is public, so release metadata and assets are readable
542
543
  // anonymously. A token stays OPTIONAL and is used when present purely to
543
544
  // lift GitHub's 60-request/hour unauthenticated API rate limit. Do not
544
- // reinstate a hard gate here: users who install from npm have no `gh`
545
- // login, and requiring one would make on-device engines unreachable for
546
- // every consumer outside this repo.
547
- const token = opts.token !== undefined ? opts.token : await resolveGitHubToken();
545
+ // reinstate a hard gate here: users who install from npm have no token,
546
+ // and requiring one would make on-device engines unreachable for every
547
+ // consumer outside this repo.
548
+ const auth = {
549
+ token: opts.token !== undefined ? opts.token : resolveGitHubToken(),
550
+ };
548
551
  const baseFetch = opts.fetchImpl ?? globalThis.fetch;
549
552
  const tag = `native-v${version}`;
550
553
  // ── 1. Resolve release + assets ──
551
- const release = await ghJson(`${apiBase}/repos/${REPO}/releases/tags/${tag}`, baseFetch, token);
554
+ const release = await ghJson(`${apiBase}/repos/${REPO}/releases/tags/${tag}`, baseFetch, auth);
552
555
  const archiveAsset = release.assets?.find((a) => a.name === archiveName);
553
556
  const sumsAsset = release.assets?.find((a) => a.name === 'SHA256SUMS');
554
557
  if (!archiveAsset) {
@@ -558,7 +561,7 @@ export async function* resolveEngine(opts) {
558
561
  yield* fail(`release ${tag} is missing its SHA256SUMS manifest — refusing to install unverified`);
559
562
  }
560
563
  // ── 2. SHA256SUMS: verify own digest against the source pin, then parse ──
561
- const sumsBytes = await ghBytes(sumsAsset.url, baseFetch, token);
564
+ const sumsBytes = await ghBytes(sumsAsset.url, baseFetch, auth);
562
565
  const sumsDigest = createHash('sha256').update(sumsBytes).digest('hex');
563
566
  if (!unpinned && sumsDigest !== expectedDigest) {
564
567
  yield* fail(`SHA256SUMS digest mismatch for ${tag}: this build pins ${expectedDigest.slice(0, 16)}… but the release served ${sumsDigest.slice(0, 16)}…. Refusing — the release may have been tampered with or re-cut.`);
@@ -584,7 +587,7 @@ export async function* resolveEngine(opts) {
584
587
  url: archiveAsset.url,
585
588
  destPath: archivePath,
586
589
  approxSizeBytes: archiveAsset.size ?? 0,
587
- fetchImpl: makeAuthedFetch(baseFetch, token),
590
+ fetchImpl: gitHubFetch(baseFetch, auth, 'application/octet-stream'),
588
591
  ...(opts.signal ? { signal: opts.signal } : {}),
589
592
  });
590
593
  let outcome;
@@ -765,35 +768,37 @@ function stampEnv(engine, binPath, variant, versionDir) {
765
768
  process.env.GEZEL_SQLITE_VEC_PATH = sqliteVec;
766
769
  }
767
770
  }
768
- async function resolveGitHubToken() {
769
- if (process.env.GEZEL_GITHUB_TOKEN)
770
- return process.env.GEZEL_GITHUB_TOKEN;
771
- if (process.env.GITHUB_TOKEN)
772
- return process.env.GITHUB_TOKEN;
773
- try {
774
- const { execFileSync } = await import('node:child_process');
775
- // Named host: a bare `gh auth token` answers for gh's default host, which
776
- // can be a GitHub Enterprise server whose token must not go to github.com.
777
- const out = execFileSync('gh', ['auth', 'token', '--hostname', 'github.com'], {
778
- encoding: 'utf8',
779
- stdio: ['ignore', 'pipe', 'ignore'],
780
- ...windowsHeadlessSpawnOptions(),
781
- });
782
- return out.trim() || null;
783
- }
784
- catch {
785
- return null;
786
- }
771
+ /**
772
+ * An optional token, from the environment only. This module runs inside apps
773
+ * that embed Gezel, so it never borrows the user's GitHub CLI login: `gh` is
774
+ * not its credential to use, and a stale one used to fail public downloads.
775
+ */
776
+ function resolveGitHubToken() {
777
+ return process.env.GEZEL_GITHUB_TOKEN || process.env.GITHUB_TOKEN || null;
787
778
  }
788
- function makeAuthedFetch(base, token) {
789
- return ((input, init) => base(input, {
790
- ...init,
791
- headers: {
792
- ...init?.headers,
793
- Accept: 'application/octet-stream',
794
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
795
- },
796
- }));
779
+ /**
780
+ * Fetch from GitHub with the optional token. The release is public, so a token
781
+ * GitHub rejects (expired, revoked) is dropped for the rest of the resolve and
782
+ * the request repeats anonymously instead of failing the install.
783
+ */
784
+ function gitHubFetch(base, auth, accept) {
785
+ return (async (input, init) => {
786
+ const send = () => base(input, {
787
+ ...init,
788
+ headers: {
789
+ ...init?.headers,
790
+ Accept: accept,
791
+ ...(auth.token ? { Authorization: `Bearer ${auth.token}` } : {}),
792
+ },
793
+ });
794
+ const res = await send();
795
+ if (res.status !== 401 || !auth.token)
796
+ return res;
797
+ await res.body?.cancel().catch(() => { });
798
+ log.warn('[engine-resolver] GitHub rejected the token from GEZEL_GITHUB_TOKEN / GITHUB_TOKEN (401); continuing anonymously');
799
+ auth.token = null;
800
+ return send();
801
+ });
797
802
  }
798
803
  /**
799
804
  * The archive itself goes through `downloadWithRetry`, but the two small
@@ -808,31 +813,23 @@ function ghRetryLog(what) {
808
813
  log.warn(`[engine-resolver] ${what} failed (${info.reason}); retrying in ${info.delayMs}ms (attempt ${info.attempt}/${info.maxAttempts})`);
809
814
  };
810
815
  }
811
- async function ghJson(url, fetchImpl, token) {
816
+ async function ghJson(url, fetchImpl, auth) {
817
+ const get = gitHubFetch(fetchImpl, auth, 'application/vnd.github+json');
812
818
  return retryTransient(async () => {
813
- const res = await fetchImpl(url, {
814
- headers: {
815
- Accept: 'application/vnd.github+json',
816
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
817
- },
818
- });
819
+ const res = await get(url);
819
820
  if (!res.ok) {
820
821
  await res.body?.cancel().catch(() => { });
821
822
  // A transient status is thrown as HttpStatusError so retryTransient
822
823
  // takes another pass; 4xx becomes the terminal EngineUnavailableError.
823
- throw new HttpStatusError(res.status, `GitHub API returned ${res.status} for ${url}${res.status === 404 ? ' (release not found — or no access while private)' : ''}`);
824
+ throw new HttpStatusError(res.status, `GitHub API returned ${res.status} for ${url}${res.status === 404 ? ' (release not found)' : ''}`);
824
825
  }
825
826
  return (await res.json());
826
827
  }, { attempts: GH_METADATA_ATTEMPTS, onRetry: ghRetryLog('GitHub release lookup') }).catch(rethrowAsEngineUnavailable);
827
828
  }
828
- async function ghBytes(assetApiUrl, fetchImpl, token) {
829
+ async function ghBytes(assetApiUrl, fetchImpl, auth) {
830
+ const get = gitHubFetch(fetchImpl, auth, 'application/octet-stream');
829
831
  return retryTransient(async () => {
830
- const res = await fetchImpl(assetApiUrl, {
831
- headers: {
832
- Accept: 'application/octet-stream',
833
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
834
- },
835
- });
832
+ const res = await get(assetApiUrl);
836
833
  if (!res.ok) {
837
834
  await res.body?.cancel().catch(() => { });
838
835
  throw new HttpStatusError(res.status, `asset download returned ${res.status} for ${assetApiUrl}`);
@@ -18,6 +18,18 @@ declare module 'hono' {
18
18
  projectId?: string;
19
19
  gezelId?: string;
20
20
  team?: boolean;
21
+ /**
22
+ * The signed-in account behind an account session (ADR 0029, the
23
+ * principal from ADR 0004). Absent for app, device and owner
24
+ * credentials.
25
+ */
26
+ account?: {
27
+ id: string;
28
+ source: 'password' | 'device' | 'os';
29
+ label: string;
30
+ };
31
+ /** The account session this request came in on, for "sign out this browser". */
32
+ accountSessionId?: string;
21
33
  };
22
34
  }
23
35
  }
@@ -0,0 +1,4 @@
1
+ import type { Hono } from 'hono';
2
+ import type { ImageModelPullRegistry } from '../../providers/image/pull-registry.js';
3
+ /** One resumable download protocol, with separate registries for models and styles. */
4
+ export declare function registerImageEnsureRoutes(app: Hono, prefix: string, pulls: ImageModelPullRegistry, qualified: (id: string) => string): void;
@@ -0,0 +1,102 @@
1
+ import { streamSSE } from 'hono/streaming';
2
+ function apiError(code, message) {
3
+ return { error: { message, type: 'invalid_request_error', code } };
4
+ }
5
+ function ensureEvent(jobId, event, totalBytes, qualified) {
6
+ const job = { jobId, modelId: qualified(jobId) };
7
+ switch (event.type) {
8
+ case 'progress':
9
+ return {
10
+ ...job,
11
+ type: 'progress',
12
+ bytesWritten: event.bytesWritten,
13
+ totalBytes: event.totalBytes ?? totalBytes,
14
+ };
15
+ case 'retrying':
16
+ return {
17
+ ...job,
18
+ type: 'retrying',
19
+ attempt: event.attempt,
20
+ maxAttempts: event.maxAttempts,
21
+ delayMs: event.delayMs,
22
+ reason: event.reason,
23
+ };
24
+ case 'error':
25
+ return { ...job, type: 'error', error: event.error };
26
+ case 'done':
27
+ return { ...job, type: 'done' };
28
+ }
29
+ }
30
+ function pullStatus(pull) {
31
+ if (!pull.finished)
32
+ return 'running';
33
+ return pull.error ? 'error' : 'done';
34
+ }
35
+ /** One resumable download protocol, with separate registries for models and styles. */
36
+ export function registerImageEnsureRoutes(app, prefix, pulls, qualified) {
37
+ app.get(`${prefix}/:jobId`, (c) => {
38
+ const pull = pulls.get(c.req.param('jobId'));
39
+ if (!pull)
40
+ return c.json(apiError('job_not_found', 'job not found'), 404);
41
+ return c.json({
42
+ job_id: pull.id,
43
+ model_id: qualified(pull.id),
44
+ status: pullStatus(pull),
45
+ started_at: Date.parse(pull.startedAt),
46
+ bytes_written: pull.bytesWritten,
47
+ total_bytes: pull.totalBytes,
48
+ ...(pull.error ? { error: pull.error } : {}),
49
+ });
50
+ });
51
+ app.get(`${prefix}/:jobId/events`, (c) => {
52
+ const jobId = c.req.param('jobId');
53
+ const snapshot = pulls.get(jobId);
54
+ if (!snapshot)
55
+ return c.json(apiError('job_not_found', 'job not found'), 404);
56
+ return streamSSE(c, async (stream) => {
57
+ let closed = false;
58
+ let sawError = false;
59
+ const unsubscribe = pulls.subscribe(jobId, (event) => {
60
+ // A failed pull ends with an error and then its done; the error is terminal.
61
+ if (sawError)
62
+ return;
63
+ if (event.type === 'error')
64
+ sawError = true;
65
+ const terminal = event.type === 'done' || event.type === 'error';
66
+ void stream
67
+ .writeSSE({
68
+ data: JSON.stringify(ensureEvent(jobId, event, snapshot.totalBytes, qualified)),
69
+ })
70
+ .then(() => {
71
+ if (terminal)
72
+ closed = true;
73
+ })
74
+ .catch(() => {
75
+ closed = true;
76
+ });
77
+ });
78
+ if (!unsubscribe)
79
+ return;
80
+ stream.onAbort(() => {
81
+ closed = true;
82
+ unsubscribe();
83
+ });
84
+ while (!closed) {
85
+ await stream.sleep(1000);
86
+ try {
87
+ await stream.writeSSE({ event: 'ping', data: '' });
88
+ }
89
+ catch {
90
+ closed = true;
91
+ }
92
+ }
93
+ unsubscribe();
94
+ });
95
+ });
96
+ app.delete(`${prefix}/:jobId`, (c) => {
97
+ if (!pulls.cancel(c.req.param('jobId'))) {
98
+ return c.json(apiError('job_not_found', 'No download in progress for that job'), 404);
99
+ }
100
+ return c.json({ cancelled: true });
101
+ });
102
+ }
@@ -0,0 +1,5 @@
1
+ import { Hono } from 'hono';
2
+ import type { ImageModelPullRegistry } from '../../providers/image/pull-registry.js';
3
+ import type { ImagesRouteContext } from './v1-images.js';
4
+ /** App-scoped access to catalog LoRAs; no paths, URLs or engine arguments from callers. */
5
+ export declare function v1ImageStylesRoutes(ctx: ImagesRouteContext, pulls: ImageModelPullRegistry): Hono;
@@ -0,0 +1,91 @@
1
+ import { Hono } from 'hono';
2
+ import { z } from 'zod';
3
+ import { isSafeModelId } from '../../models/model-id.js';
4
+ import { registerImageEnsureRoutes } from './image-ensure-routes.js';
5
+ const styleId = z.string().min(1).max(512).refine(isSafeModelId);
6
+ const ensureRequest = z.object({ style: styleId }).strict();
7
+ const apiError = (code, message) => ({
8
+ error: { code, message, type: 'invalid_request_error' },
9
+ });
10
+ /** App-scoped access to catalog LoRAs; no paths, URLs or engine arguments from callers. */
11
+ export function v1ImageStylesRoutes(ctx, pulls) {
12
+ const app = new Hono();
13
+ app.get('/', async (c) => {
14
+ const provider = await ctx.images.current();
15
+ if (!provider.listLoras || !provider.pullLora || !provider.deleteLora) {
16
+ return c.json(apiError('styles_unsupported', 'Update Gezel to add image styles.'), 409);
17
+ }
18
+ const [installed, catalog] = await Promise.all([
19
+ provider.listLoras(),
20
+ ctx.catalog.list('image-lora'),
21
+ ]);
22
+ const data = [];
23
+ for (const item of catalog) {
24
+ const m = item.manifest;
25
+ if (m.kind !== 'image-lora' || m.purpose !== 'style')
26
+ continue;
27
+ data.push({
28
+ id: m.id,
29
+ object: 'image_style',
30
+ name: m.name,
31
+ description: m.description,
32
+ availability: installed.some((l) => l.id === m.id)
33
+ ? 'available'
34
+ : pulls.get(m.id)?.finished === false
35
+ ? 'downloading'
36
+ : 'download-required',
37
+ base_models: m.baseModels.map((id) => `sd-cpp:${id}`),
38
+ download_bytes: m.approxSizeBytes,
39
+ ...((m.licenseShortName ?? m.license) ? { license: m.licenseShortName ?? m.license } : {}),
40
+ commercial_use: m.commercialUse,
41
+ ...(m.licenseUrl ? { license_url: m.licenseUrl } : {}),
42
+ });
43
+ }
44
+ for (const l of installed) {
45
+ if (l.purpose !== 'style' || data.some((s) => s.id === l.id))
46
+ continue;
47
+ data.push({
48
+ id: l.id,
49
+ object: 'image_style',
50
+ name: l.name,
51
+ availability: 'available',
52
+ download_bytes: l.approxSizeBytes,
53
+ base_models: l.baseModels.map((id) => `sd-cpp:${id}`),
54
+ });
55
+ }
56
+ return c.json({ object: 'list', data });
57
+ });
58
+ app.post('/ensure', async (c) => {
59
+ const { style } = ensureRequest.parse(await c.req.json());
60
+ const provider = await ctx.images.current();
61
+ if (!provider.listLoras || !provider.pullLora)
62
+ return c.json(apiError('styles_unsupported', 'Update Gezel to add image styles.'), 409);
63
+ const installed = await provider.listLoras();
64
+ if (installed.some((l) => l.id === style && l.purpose === 'style'))
65
+ return c.json({ status: 'ready', model_id: style });
66
+ const item = await ctx.catalog.get('image-lora', style);
67
+ if (item?.manifest.kind !== 'image-lora' || item.manifest.purpose !== 'style')
68
+ return c.json(apiError('unknown_style', 'That style is not in the catalog.'), 404);
69
+ const models = await provider.listInstalledModels();
70
+ if (!models.some((model) => item.manifest.kind === 'image-lora' && item.manifest.baseModels.includes(model.id))) {
71
+ return c.json(apiError('style_model_required', 'Download a compatible image model before adding this style.'), 409);
72
+ }
73
+ await pulls.start(style);
74
+ return c.json({ status: 'downloading', model_id: style, job_id: style }, 202);
75
+ });
76
+ registerImageEnsureRoutes(app, '/ensure', pulls, (id) => id);
77
+ app.delete('/:id', async (c) => {
78
+ const id = styleId.parse(c.req.param('id'));
79
+ if (pulls.get(id)?.finished === false)
80
+ return c.json(apiError('style_downloading', 'Cancel the style download before removing it.'), 409);
81
+ await ctx.images.reset();
82
+ const provider = await ctx.images.current();
83
+ if (!provider.deleteLora || !provider.listLoras)
84
+ return c.json(apiError('styles_unsupported', 'Update Gezel to manage image styles.'), 409);
85
+ if (!(await provider.listLoras()).some((l) => l.id === id && l.purpose === 'style'))
86
+ return c.json(apiError('unknown_style', 'That style is not installed.'), 404);
87
+ await provider.deleteLora(id);
88
+ return c.body(null, 204);
89
+ });
90
+ return app;
91
+ }
@@ -16,6 +16,7 @@ export interface ImagesRouteContext {
16
16
  /** Stop the engine, draining renders, before its model files change. */
17
17
  reset(): Promise<void>;
18
18
  pulls: ImageModelPullRegistry;
19
+ loraPulls?: ImageModelPullRegistry;
19
20
  };
20
21
  }
21
22
  /**