@qvac/harness 0.4.0 → 0.6.0

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 (299) hide show
  1. package/CHANGELOG.md +740 -141
  2. package/README.md +75 -7
  3. package/dist/harness.bundle +72 -50
  4. package/dist-lib/index.d.ts +49 -39
  5. package/dist-lib/index.js +448 -161
  6. package/dist-lib/lib/audio-transcode-bare.d.ts +2 -2
  7. package/dist-lib/lib/audio-transcode-bare.js +28 -18
  8. package/dist-lib/lib/audio-transcode-node.d.ts +2 -2
  9. package/dist-lib/lib/capabilities/audio-resample.d.ts +7 -6
  10. package/dist-lib/lib/capabilities/audio-resample.js +30 -18
  11. package/dist-lib/lib/capabilities/completion.d.ts +20 -19
  12. package/dist-lib/lib/capabilities/completion.js +193 -132
  13. package/dist-lib/lib/capabilities/download.d.ts +6 -6
  14. package/dist-lib/lib/capabilities/download.js +15 -8
  15. package/dist-lib/lib/capabilities/embed.js +2 -1
  16. package/dist-lib/lib/capabilities/enhance.d.ts +6 -1
  17. package/dist-lib/lib/capabilities/enhance.js +7 -4
  18. package/dist-lib/lib/capabilities/invoke.js +7 -4
  19. package/dist-lib/lib/capabilities/kv-cache.js +2 -1
  20. package/dist-lib/lib/capabilities/preview-model-source.d.ts +9 -7
  21. package/dist-lib/lib/capabilities/preview-model-source.js +80 -28
  22. package/dist-lib/lib/capabilities/speech-text.js +5 -4
  23. package/dist-lib/lib/capabilities/tool-selection.js +10 -9
  24. package/dist-lib/lib/capabilities/tool-turns.js +30 -16
  25. package/dist-lib/lib/capabilities/usage-breakdown.js +2 -1
  26. package/dist-lib/lib/capabilities/voice.d.ts +5 -1
  27. package/dist-lib/lib/capabilities/voice.js +22 -12
  28. package/dist-lib/lib/connect.d.ts +13 -32
  29. package/dist-lib/lib/connect.js +170 -112
  30. package/dist-lib/lib/context-window.js +25 -21
  31. package/dist-lib/lib/contract-types.d.ts +35 -15
  32. package/dist-lib/lib/diagram-repair.d.ts +4 -4
  33. package/dist-lib/lib/diagram-repair.js +6 -3
  34. package/dist-lib/lib/docx/index.d.ts +3 -2
  35. package/dist-lib/lib/{error-fields.d.ts → guards.d.ts} +1 -0
  36. package/dist-lib/lib/{error-fields.js → guards.js} +3 -0
  37. package/dist-lib/lib/hardware/capability-probe.js +20 -10
  38. package/dist-lib/lib/hardware/gpu-classify.js +6 -3
  39. package/dist-lib/lib/hardware/gpu-probe-addon.js +8 -4
  40. package/dist-lib/lib/hardware/gpu-probe.js +4 -2
  41. package/dist-lib/lib/hardware/gpu-stats.native.cjs +8 -9
  42. package/dist-lib/lib/hardware/parsers.js +8 -4
  43. package/dist-lib/lib/helpers/buffer-burst.js +4 -2
  44. package/dist-lib/lib/helpers/control-tokens.js +4 -2
  45. package/dist-lib/lib/helpers/join-guard.d.ts +2 -2
  46. package/dist-lib/lib/helpers/join-guard.js +4 -2
  47. package/dist-lib/lib/helpers/load-stall.js +4 -2
  48. package/dist-lib/lib/helpers/markup-stream-filter.d.ts +2 -2
  49. package/dist-lib/lib/helpers/markup-stream-filter.js +6 -3
  50. package/dist-lib/lib/helpers/race-abort.js +2 -1
  51. package/dist-lib/lib/helpers/race-timeout.d.ts +5 -0
  52. package/dist-lib/lib/helpers/race-timeout.js +14 -0
  53. package/dist-lib/lib/helpers/run-outcome.d.ts +6 -8
  54. package/dist-lib/lib/helpers/run-outcome.js +36 -20
  55. package/dist-lib/lib/helpers/spawn-path.js +6 -3
  56. package/dist-lib/lib/helpers/text-coalescer.js +6 -3
  57. package/dist-lib/lib/helpers/thinking.js +38 -45
  58. package/dist-lib/lib/helpers/tool-call-markup.d.ts +9 -7
  59. package/dist-lib/lib/helpers/tool-call-markup.js +36 -20
  60. package/dist-lib/lib/helpers/tool-intent.d.ts +3 -2
  61. package/dist-lib/lib/helpers/tool-intent.js +4 -2
  62. package/dist-lib/lib/helpers/tool-label.js +18 -9
  63. package/dist-lib/lib/hooks/built-in/arg-repair.js +23 -13
  64. package/dist-lib/lib/hooks/built-in/egress.js +2 -1
  65. package/dist-lib/lib/hooks/built-in/skill-catalog.js +2 -1
  66. package/dist-lib/lib/hooks/pipeline.d.ts +5 -4
  67. package/dist-lib/lib/hooks/pipeline.js +6 -3
  68. package/dist-lib/lib/hooks/run.js +12 -8
  69. package/dist-lib/lib/model-download-progress.js +10 -8
  70. package/dist-lib/lib/models/context.d.ts +1 -1
  71. package/dist-lib/lib/models/context.js +5 -1
  72. package/dist-lib/lib/models/custom-model-cache.d.ts +10 -1
  73. package/dist-lib/lib/models/custom-model-cache.js +43 -15
  74. package/dist-lib/lib/models/gguf-header.d.ts +3 -2
  75. package/dist-lib/lib/models/gguf-header.js +44 -22
  76. package/dist-lib/lib/models/idle-unload.d.ts +14 -0
  77. package/dist-lib/lib/models/idle-unload.js +51 -0
  78. package/dist-lib/lib/models/kv-cache.d.ts +3 -2
  79. package/dist-lib/lib/models/kv-cache.js +4 -3
  80. package/dist-lib/lib/models/llm-presets.d.ts +2 -2
  81. package/dist-lib/lib/models/llm-presets.js +4 -2
  82. package/dist-lib/lib/models/model-catalog-constants.js +3 -2
  83. package/dist-lib/lib/models/model-catalog.d.ts +15 -20
  84. package/dist-lib/lib/models/model-catalog.js +66 -31
  85. package/dist-lib/lib/models/model-delete.js +18 -8
  86. package/dist-lib/lib/models/model-handle.js +2 -1
  87. package/dist-lib/lib/models/model-list.d.ts +8 -3
  88. package/dist-lib/lib/models/model-list.js +11 -6
  89. package/dist-lib/lib/models/model-pool.d.ts +48 -10
  90. package/dist-lib/lib/models/model-pool.js +106 -45
  91. package/dist-lib/lib/models/model-source.js +10 -5
  92. package/dist-lib/lib/models/music-catalog.d.ts +2 -2
  93. package/dist-lib/lib/models/nmt-catalog.d.ts +4 -3
  94. package/dist-lib/lib/models/nmt-catalog.js +10 -5
  95. package/dist-lib/lib/models/opencl-cache.d.ts +6 -1
  96. package/dist-lib/lib/models/opencl-cache.js +5 -3
  97. package/dist-lib/lib/models/sdk-faults.d.ts +11 -8
  98. package/dist-lib/lib/models/sdk-faults.js +9 -6
  99. package/dist-lib/lib/models/shards.d.ts +11 -0
  100. package/dist-lib/lib/models/shards.js +15 -0
  101. package/dist-lib/lib/models/tool-dialect.js +10 -5
  102. package/dist-lib/lib/no-redirect-fetch-bare.d.ts +3 -3
  103. package/dist-lib/lib/no-redirect-fetch-bare.js +1 -1
  104. package/dist-lib/lib/no-redirect-fetch-impl.js +6 -3
  105. package/dist-lib/lib/no-redirect-fetch-node.d.ts +1 -1
  106. package/dist-lib/lib/no-redirect-fetch-node.js +9 -9
  107. package/dist-lib/lib/office/index.d.ts +3 -2
  108. package/dist-lib/lib/office/python.d.ts +3 -2
  109. package/dist-lib/lib/office/python.js +2 -1
  110. package/dist-lib/lib/prompt.d.ts +5 -4
  111. package/dist-lib/lib/prompt.js +8 -4
  112. package/dist-lib/lib/queue.js +10 -5
  113. package/dist-lib/lib/resolution-detector.js +21 -11
  114. package/dist-lib/lib/rpc-session.js +2 -1
  115. package/dist-lib/lib/sdk-loader.js +2 -1
  116. package/dist-lib/lib/sdk-storage.js +4 -2
  117. package/dist-lib/lib/serve.js +122 -66
  118. package/dist-lib/lib/spawn.js +7 -4
  119. package/dist-lib/lib/tmp-path.d.ts +7 -6
  120. package/dist-lib/lib/tool-call-display.d.ts +2 -2
  121. package/dist-lib/lib/tools/create-documents.js +18 -10
  122. package/dist-lib/lib/tools/edit-documents.js +23 -13
  123. package/dist-lib/lib/tools/edit-image.d.ts +2 -2
  124. package/dist-lib/lib/tools/edit-image.js +60 -36
  125. package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +10 -10
  126. package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +17 -11
  127. package/dist-lib/lib/tools/exec/adapters/python/attachments.js +53 -40
  128. package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +2 -2
  129. package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +60 -32
  130. package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.d.ts +33 -22
  131. package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.js +58 -29
  132. package/dist-lib/lib/tools/exec/adapters/python/interrupt-timer.d.ts +2 -2
  133. package/dist-lib/lib/tools/exec/adapters/python/loader.js +23 -12
  134. package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +13 -11
  135. package/dist-lib/lib/tools/exec/adapters/python/memfs.js +10 -5
  136. package/dist-lib/lib/tools/exec/adapters/python/net-shim.js +3 -1
  137. package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +6 -4
  138. package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +20 -10
  139. package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +2 -2
  140. package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +14 -7
  141. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +41 -34
  142. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +316 -166
  143. package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +9 -8
  144. package/dist-lib/lib/tools/exec/adapters/python/run-session.js +56 -28
  145. package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +8 -10
  146. package/dist-lib/lib/tools/exec/adapters/python/wheels.js +22 -11
  147. package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +3 -2
  148. package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +41 -26
  149. package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +27 -18
  150. package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +2 -2
  151. package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +14 -13
  152. package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +4 -4
  153. package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +10 -5
  154. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +4 -4
  155. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +2 -1
  156. package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +6 -1
  157. package/dist-lib/lib/tools/exec/obsidian/cli-process.js +8 -5
  158. package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +6 -6
  159. package/dist-lib/lib/tools/exec/obsidian/cli.js +4 -4
  160. package/dist-lib/lib/tools/exec/obsidian/command.d.ts +3 -2
  161. package/dist-lib/lib/tools/exec/obsidian/command.js +6 -3
  162. package/dist-lib/lib/tools/exec/obsidian/output.js +2 -1
  163. package/dist-lib/lib/tools/exec/obsidian/route.d.ts +4 -6
  164. package/dist-lib/lib/tools/exec/obsidian/route.js +17 -11
  165. package/dist-lib/lib/tools/exec/obsidian/safe-path.js +2 -1
  166. package/dist-lib/lib/tools/exec/obsidian/vault-create.js +15 -7
  167. package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +2 -2
  168. package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +20 -10
  169. package/dist-lib/lib/tools/exec/obsidian/vault-read.js +20 -13
  170. package/dist-lib/lib/tools/exec/obsidian/vault-write.js +24 -12
  171. package/dist-lib/lib/tools/exec/runner.d.ts +14 -14
  172. package/dist-lib/lib/tools/exec/runner.js +5 -3
  173. package/dist-lib/lib/tools/exec/scope.js +52 -28
  174. package/dist-lib/lib/tools/exec/shell-argv.js +31 -18
  175. package/dist-lib/lib/tools/exec/shell-guidance.d.ts +6 -1
  176. package/dist-lib/lib/tools/exec/shell-guidance.js +35 -20
  177. package/dist-lib/lib/tools/exec/video-tools.js +2 -2
  178. package/dist-lib/lib/tools/exec.d.ts +6 -8
  179. package/dist-lib/lib/tools/exec.js +113 -54
  180. package/dist-lib/lib/tools/file-glob.d.ts +4 -5
  181. package/dist-lib/lib/tools/file-glob.js +16 -11
  182. package/dist-lib/lib/tools/fs/glob.js +13 -18
  183. package/dist-lib/lib/tools/fs/remote-protocol.d.ts +10 -10
  184. package/dist-lib/lib/tools/fs/remote.d.ts +3 -2
  185. package/dist-lib/lib/tools/fs/remote.js +13 -7
  186. package/dist-lib/lib/tools/fs/scope.d.ts +8 -3
  187. package/dist-lib/lib/tools/fs/scope.js +20 -12
  188. package/dist-lib/lib/tools/fs/walk.js +6 -3
  189. package/dist-lib/lib/tools/fs/write.d.ts +3 -2
  190. package/dist-lib/lib/tools/generate-image.d.ts +11 -9
  191. package/dist-lib/lib/tools/generate-image.js +73 -37
  192. package/dist-lib/lib/tools/generate-music.d.ts +22 -11
  193. package/dist-lib/lib/tools/generate-music.js +79 -48
  194. package/dist-lib/lib/tools/grep.js +66 -41
  195. package/dist-lib/lib/tools/http-request/encode-fields.js +18 -9
  196. package/dist-lib/lib/tools/http-request/{utils.js → request.js} +20 -11
  197. package/dist-lib/lib/tools/http-request/truncate-response.js +57 -46
  198. package/dist-lib/lib/tools/http-request.d.ts +1 -1
  199. package/dist-lib/lib/tools/http-request.js +33 -18
  200. package/dist-lib/lib/tools/mcp/protocol.d.ts +53 -0
  201. package/dist-lib/lib/tools/mcp/{utils.js → protocol.js} +45 -23
  202. package/dist-lib/lib/tools/mcp-call.d.ts +1 -1
  203. package/dist-lib/lib/tools/mcp-call.js +37 -16
  204. package/dist-lib/lib/tools/operations/builders.js +10 -6
  205. package/dist-lib/lib/tools/operations/compile.js +20 -10
  206. package/dist-lib/lib/tools/operations/decoders.js +12 -6
  207. package/dist-lib/lib/tools/operations/gmail-message.js +3 -2
  208. package/dist-lib/lib/tools/outbound-guard.d.ts +4 -3
  209. package/dist-lib/lib/tools/outbound-guard.js +14 -8
  210. package/dist-lib/lib/tools/private-ip.js +8 -7
  211. package/dist-lib/lib/tools/rag-search.js +14 -7
  212. package/dist-lib/lib/tools/read-files.js +23 -20
  213. package/dist-lib/lib/tools/skill.js +19 -10
  214. package/dist-lib/lib/tools/skills/auth-resolver.d.ts +11 -18
  215. package/dist-lib/lib/tools/skills/auth-resolver.js +30 -18
  216. package/dist-lib/lib/tools/skills/bin-check.d.ts +3 -2
  217. package/dist-lib/lib/tools/skills/bin-check.js +10 -3
  218. package/dist-lib/lib/tools/skills/bundled-dir.js +20 -10
  219. package/dist-lib/lib/tools/skills/bundled-hash.d.ts +3 -2
  220. package/dist-lib/lib/tools/skills/bundled-hash.js +6 -1
  221. package/dist-lib/lib/tools/skills/catalog.d.ts +3 -2
  222. package/dist-lib/lib/tools/skills/catalog.js +33 -28
  223. package/dist-lib/lib/tools/skills/cli-argv.d.ts +3 -2
  224. package/dist-lib/lib/tools/skills/cli-argv.js +55 -52
  225. package/dist-lib/lib/tools/skills/cli-schema-check.js +21 -10
  226. package/dist-lib/lib/tools/skills/cli-schema-load.js +28 -20
  227. package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +6 -6
  228. package/dist-lib/lib/tools/skills/cli-schema.js +2 -1
  229. package/dist-lib/lib/tools/skills/credential-check.d.ts +6 -3
  230. package/dist-lib/lib/tools/skills/credential-check.js +24 -12
  231. package/dist-lib/lib/tools/skills/credential-grants.js +1 -6
  232. package/dist-lib/lib/tools/skills/credential-health.d.ts +5 -1
  233. package/dist-lib/lib/tools/skills/credential-health.js +5 -3
  234. package/dist-lib/lib/tools/skills/frontmatter-parser.js +10 -5
  235. package/dist-lib/lib/tools/skills/manifest-parse.js +84 -64
  236. package/dist-lib/lib/tools/skills/mention.js +7 -6
  237. package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +2 -2
  238. package/dist-lib/lib/tools/skills/obsidian-readiness.js +11 -3
  239. package/dist-lib/lib/tools/skills/overlay-crud.d.ts +6 -4
  240. package/dist-lib/lib/tools/skills/overlay-crud.js +12 -6
  241. package/dist-lib/lib/tools/skills/overlay-dir.js +4 -2
  242. package/dist-lib/lib/tools/skills/overlay-watch.d.ts +3 -2
  243. package/dist-lib/lib/tools/skills/overlay-watch.js +8 -4
  244. package/dist-lib/lib/tools/skills/setup-routes.js +1 -3
  245. package/dist-lib/lib/tools/skills/skill-settings.js +4 -1
  246. package/dist-lib/lib/tools/skills/skill-state.d.ts +6 -11
  247. package/dist-lib/lib/tools/skills/skill-state.js +48 -29
  248. package/dist-lib/lib/tools/skills/tool-grants.js +6 -3
  249. package/dist-lib/lib/tools/toolsets.js +2 -1
  250. package/dist-lib/lib/tools/translate.d.ts +4 -5
  251. package/dist-lib/lib/tools/translate.js +31 -14
  252. package/dist-lib/lib/tools/url-guard.js +2 -1
  253. package/dist-lib/lib/tools/weather-lookup/place.js +8 -4
  254. package/dist-lib/lib/tools/weather-lookup/report.d.ts +7 -1
  255. package/dist-lib/lib/tools/weather-lookup/report.js +46 -9
  256. package/dist-lib/lib/tools/weather-lookup.js +18 -12
  257. package/dist-lib/lib/tools/web-fetch.js +47 -24
  258. package/dist-lib/lib/tools/web-search.js +8 -3
  259. package/dist-lib/lib/validating-lookup.d.ts +4 -4
  260. package/dist-lib/lib/wav-encode.d.ts +1 -1
  261. package/dist-lib/lib/wav-encode.js +11 -10
  262. package/dist-lib/lib/web-fetch/embedded-state.js +24 -12
  263. package/dist-lib/lib/web-fetch/extract.js +4 -2
  264. package/dist-lib/lib/web-fetch/images.js +8 -4
  265. package/dist-lib/lib/web-fetch/video.d.ts +2 -2
  266. package/dist-lib/lib/web-fetch/video.js +8 -4
  267. package/dist-lib/lib/web-search/engine-registry.d.ts +2 -2
  268. package/dist-lib/lib/web-search/engines/aol.js +1 -1
  269. package/dist-lib/lib/web-search/engines/bing.js +1 -1
  270. package/dist-lib/lib/web-search/engines/brave.js +4 -1
  271. package/dist-lib/lib/web-search/engines/duckduckgo.js +3 -2
  272. package/dist-lib/lib/web-search/engines/google.js +7 -3
  273. package/dist-lib/lib/web-search/engines/wikipedia.js +5 -4
  274. package/dist-lib/lib/web-search/engines/yahoo.js +1 -1
  275. package/dist-lib/lib/web-search/fetch-html.d.ts +5 -4
  276. package/dist-lib/lib/web-search/fetch-html.js +13 -7
  277. package/dist-lib/lib/web-search/orchestrator.d.ts +9 -5
  278. package/dist-lib/lib/web-search/orchestrator.js +3 -3
  279. package/dist-lib/lib/wire.d.ts +3 -2
  280. package/dist-lib/lib/wire.js +23 -15
  281. package/dist-lib/schema/baseline.js +10 -5
  282. package/dist-lib/schema/build.js +2 -1
  283. package/dist-lib/schema/harness.d.ts +15 -2
  284. package/dist-lib/schema/harness.js +39 -2
  285. package/dist-lib/schema/release-tags.d.ts +3 -2
  286. package/dist-lib/schema/release-tags.js +6 -3
  287. package/dist-lib/spec/bind.js +9 -0
  288. package/dist-lib/spec/calls.js +3 -0
  289. package/dist-lib/spec/hrpc/hrpc.json +39 -0
  290. package/dist-lib/spec/hrpc/index.js +39 -3
  291. package/dist-lib/spec/hrpc/messages.js +105 -8
  292. package/dist-lib/spec/hyperschema/index.js +105 -8
  293. package/dist-lib/spec/hyperschema/schema.json +77 -1
  294. package/dist-lib/spec/hyperschema/types.d.ts +25 -1
  295. package/package.json +14 -14
  296. package/worker/harness-sidecar.mjs +15 -22
  297. package/worker/stow-entry.mjs +7 -4
  298. package/dist-lib/lib/tools/mcp/utils.d.ts +0 -47
  299. /package/dist-lib/lib/tools/http-request/{utils.d.ts → request.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- export type LlmGenerationParams = {
1
+ export interface LlmGenerationParams {
2
2
  temp?: number;
3
3
  top_p?: number;
4
4
  top_k?: number;
@@ -6,5 +6,5 @@ export type LlmGenerationParams = {
6
6
  repeat_penalty?: number;
7
7
  frequency_penalty?: number;
8
8
  reasoning_budget: -1 | 0;
9
- };
9
+ }
10
10
  export declare function resolveLlmGenerationParams(modelName: string | undefined, reasoningEnabled: boolean | undefined, deviceDefault?: boolean): LlmGenerationParams | undefined;
@@ -31,11 +31,13 @@ export function resolveLlmGenerationParams(modelName, reasoningEnabled, deviceDe
31
31
  const resolver = modelName
32
32
  ? PRESET_RESOLVERS.find((entry) => modelName.startsWith(entry.prefix))
33
33
  : undefined;
34
- if (resolver)
34
+ if (resolver) {
35
35
  return resolver.resolve(reasoningEnabled);
36
+ }
36
37
  const effective = reasoningEnabled ?? deviceDefault;
37
- if (effective === undefined)
38
+ if (effective === undefined) {
38
39
  return undefined;
40
+ }
39
41
  return { reasoning_budget: effective ? -1 : 0 };
40
42
  }
41
43
  function qwen08BPreset(reasoningEnabled) {
@@ -14,7 +14,7 @@ export const QWEN_38_27B = 'Qwen3.8-27B-UD-Q4_K_XL';
14
14
  export const MEDPSY_1_7B = 'medpsy-1.7b-q4_k_m-imat';
15
15
  export const MEDPSY_4B = 'medpsy-4b-q4_k_m-imat';
16
16
  export function isCapabilityProfile(value) {
17
- return CAPABILITY_PROFILE_ORDER.includes(value);
17
+ return CAPABILITY_PROFILE_ORDER.some((profile) => profile === value);
18
18
  }
19
19
  export function meetsMinCapabilityProfile(active, required) {
20
20
  return CAPABILITY_PROFILE_ORDER.indexOf(active) >= CAPABILITY_PROFILE_ORDER.indexOf(required);
@@ -41,8 +41,9 @@ const PROFILE_TO_MODEL_NAME = new Map([
41
41
  ]);
42
42
  export function capabilityProfileToModelName(profile) {
43
43
  const name = PROFILE_TO_MODEL_NAME.get(profile);
44
- if (!name)
44
+ if (!name) {
45
45
  throw new Error(`no model for capability profile ${profile}`);
46
+ }
46
47
  return name;
47
48
  }
48
49
  export const AGENT_MODEL_NAMES = [
@@ -1,4 +1,6 @@
1
1
  import type { ModelRegistryEntry, ToolDialect } from '@qvac/sdk';
2
+ import type { ImageModelSet } from '../tools/generate-image.ts';
3
+ import type { MusicModelStages } from '../tools/generate-music.ts';
2
4
  import type { ModelAddon } from './model-source.ts';
3
5
  export interface SdkModelAsset extends ModelRegistryEntry {
4
6
  readonly src: string;
@@ -24,10 +26,11 @@ export interface CategoryDefault {
24
26
  export declare const CATEGORY_DEFAULTS: ReadonlyArray<CategoryDefault>;
25
27
  export declare function defaultVoiceModel(category: ModelCategory): string;
26
28
  export declare function defaultTtsFor(profile: CapabilityProfile): CategoryDefault;
27
- export declare function infraModelsFor(profile: CapabilityProfile): Array<{
28
- name: string;
29
- addon: ModelAddon;
30
- }>;
29
+ export interface CatalogModel {
30
+ readonly name: string;
31
+ readonly addon: ModelAddon;
32
+ }
33
+ export declare function infraModelsFor(profile: CapabilityProfile): CatalogModel[];
31
34
  export declare function mediaModelNameFor(category: ModelCategory, profile: CapabilityProfile): string;
32
35
  export interface DiffusionCatalogEntry {
33
36
  readonly choice: ImageModelChoice;
@@ -62,12 +65,7 @@ export declare const AUDIOGEN_CATALOG: ReadonlyArray<AudioGenCatalogEntry>;
62
65
  export declare function musicDefaultSteps(choice: string | undefined): number | undefined;
63
66
  export declare function musicChoiceForDit(dit: string): MusicModelChoice | undefined;
64
67
  export declare function musicSizeBytes(entry: AudioGenCatalogEntry): number;
65
- export declare function musicModelSet(choice: string | undefined): {
66
- dit: string;
67
- textEnc: string;
68
- lm: string;
69
- vae: string;
70
- } | null;
68
+ export declare function musicModelSet(choice: string | undefined): MusicModelStages | null;
71
69
  export interface AudioGenDownloadMetadata {
72
70
  readonly companions: ReadonlyArray<string>;
73
71
  readonly assetSizes: Readonly<Record<string, number>>;
@@ -80,17 +78,9 @@ export interface AgentSkillModelInput {
80
78
  readonly imageModelChoice?: ImageModelChoice | null;
81
79
  readonly musicModelChoice?: MusicModelChoice | null;
82
80
  }
83
- export declare function skillModelsForAgent(agent: AgentSkillModelInput): ReadonlyArray<{
84
- readonly name: string;
85
- readonly addon: ModelAddon;
86
- }>;
81
+ export declare function skillModelsForAgent(agent: AgentSkillModelInput): ReadonlyArray<CatalogModel>;
87
82
  export declare function diffusionSizeBytes(entry: DiffusionCatalogEntry): number;
88
- export declare function imageModelFor(choice: string | undefined): {
89
- model: string;
90
- llmModel?: string | undefined;
91
- vaeModel?: string | undefined;
92
- prediction?: 'flux2_flow' | undefined;
93
- } | null;
83
+ export declare function imageModelFor(choice: string | undefined): ImageModelSet | null;
94
84
  export interface ImageClamps {
95
85
  maxDim?: number;
96
86
  maxSteps?: number;
@@ -105,6 +95,8 @@ export interface CuratedListable {
105
95
  }
106
96
  export declare function curatedListables(): CuratedListable[];
107
97
  export declare function curatedModelAsset(name: string, addon: ModelRegistryEntry['addon']): SdkModelAsset | undefined;
98
+ export declare function modelAddonOf(model: string): ModelRegistryEntry['addon'];
99
+ export declare function residentSrc(model: string, addon: ModelRegistryEntry['addon']): string;
108
100
  export declare const CUSTOM_TASK_TYPES: readonly ['llm'];
109
101
  export type CustomTaskType = (typeof CUSTOM_TASK_TYPES)[number];
110
102
  export interface CustomModelEntry {
@@ -113,9 +105,12 @@ export interface CustomModelEntry {
113
105
  readonly projectionSrc?: string;
114
106
  readonly taskType?: CustomTaskType;
115
107
  readonly expectedSize?: number;
108
+ readonly label?: string;
109
+ readonly contextLength?: number;
116
110
  }
117
111
  export declare function setCustomModels(entries: ReadonlyArray<CustomModelEntry>): void;
118
112
  export declare function customModels(): ReadonlyArray<CustomModelEntry>;
113
+ export declare function customContextLength(name: string): number | undefined;
119
114
  export declare function customModelSrc(name: string, addon: ModelRegistryEntry['addon']): string | undefined;
120
115
  export declare function customToolDialect(name: string): ToolDialect | undefined;
121
116
  export declare function customProjectionMap(): Record<string, string>;
@@ -56,8 +56,9 @@ export const LLM_CATALOG = [
56
56
  export function defaultProjectionMap() {
57
57
  const map = {};
58
58
  for (const entry of LLM_CATALOG) {
59
- if (entry.projection)
59
+ if (entry.projection) {
60
60
  map[entry.name] = entry.projection.src;
61
+ }
61
62
  }
62
63
  return map;
63
64
  }
@@ -73,13 +74,18 @@ export const CATEGORY_DEFAULTS = [
73
74
  ];
74
75
  export function defaultVoiceModel(category) {
75
76
  const entry = CATEGORY_DEFAULTS.find((candidate) => candidate.category === category);
76
- if (!entry)
77
+ if (!entry) {
77
78
  throw new Error(`no default model for category ${category}`);
79
+ }
78
80
  return entry.asset.src;
79
81
  }
80
82
  export function defaultTtsFor(profile) {
81
83
  const name = defaultTtsModelName(profile);
82
- return CATEGORY_DEFAULTS.find((entry) => entry.name === name);
84
+ const entry = CATEGORY_DEFAULTS.find((candidate) => candidate.name === name);
85
+ if (!entry) {
86
+ throw new Error(`no default tts model named ${name}`);
87
+ }
88
+ return entry;
83
89
  }
84
90
  export function infraModelsFor(profile) {
85
91
  const tts = defaultTtsFor(profile);
@@ -87,11 +93,13 @@ export function infraModelsFor(profile) {
87
93
  return [tts, ...rest].map((entry) => ({ name: entry.name, addon: entry.asset.addon }));
88
94
  }
89
95
  export function mediaModelNameFor(category, profile) {
90
- if (category === 'tts')
96
+ if (category === 'tts') {
91
97
  return defaultTtsFor(profile).name;
98
+ }
92
99
  const entry = CATEGORY_DEFAULTS.find((candidate) => candidate.category === category);
93
- if (!entry)
100
+ if (!entry) {
94
101
  throw new Error(`no default model for category ${category}`);
102
+ }
95
103
  return entry.name;
96
104
  }
97
105
  const IMAGE_GENERATION_SKILL = 'image-generation';
@@ -123,10 +131,12 @@ export const DIFFUSION_CATALOG = [
123
131
  ];
124
132
  function diffusionAssets(entry) {
125
133
  const assets = [entry.model];
126
- if (entry.llmModel)
134
+ if (entry.llmModel) {
127
135
  assets.push(entry.llmModel);
128
- if (entry.vaeModel)
136
+ }
137
+ if (entry.vaeModel) {
129
138
  assets.push(entry.vaeModel);
139
+ }
130
140
  return assets;
131
141
  }
132
142
  function diffusionCatalogEntry(model) {
@@ -142,12 +152,14 @@ export function diffusionDownloadMetadata(model, addon) {
142
152
  if (addon !== 'diffusion')
143
153
  return undefined;
144
154
  const entry = diffusionCatalogEntry(model);
145
- if (!entry)
155
+ if (!entry) {
146
156
  return undefined;
157
+ }
147
158
  const assets = diffusionAssets(entry);
148
159
  const assetSizes = {};
149
- for (const asset of assets)
160
+ for (const asset of assets) {
150
161
  assetSizes[asset.src] = asset.expectedSize;
162
+ }
151
163
  return {
152
164
  companions: assets.slice(1).map((asset) => asset.src),
153
165
  assetSizes
@@ -202,8 +214,9 @@ export function musicSizeBytes(entry) {
202
214
  }
203
215
  export function musicModelSet(choice) {
204
216
  const entry = AUDIOGEN_CATALOG.find((candidate) => candidate.choice === choice);
205
- if (!entry)
217
+ if (!entry) {
206
218
  return null;
219
+ }
207
220
  return {
208
221
  dit: entry.dit.src,
209
222
  textEnc: entry.textEnc.src,
@@ -215,12 +228,14 @@ export function audioGenDownloadMetadata(model, addon) {
215
228
  if (addon !== 'audiogen')
216
229
  return undefined;
217
230
  const entry = AUDIOGEN_CATALOG.find((candidate) => candidate.name === model || candidate.dit.name === model || candidate.dit.src === model);
218
- if (!entry)
231
+ if (!entry) {
219
232
  return undefined;
233
+ }
220
234
  const stages = audioGenStages(entry);
221
235
  const assetSizes = {};
222
- for (const asset of stages)
236
+ for (const asset of stages) {
223
237
  assetSizes[asset.src] = asset.expectedSize;
238
+ }
224
239
  return {
225
240
  companions: stages.slice(1).map((asset) => asset.src),
226
241
  assetSizes
@@ -235,14 +250,16 @@ export function skillModelsForAgent(agent) {
235
250
  if (agentHasSkill(agent, IMAGE_GENERATION_SKILL)) {
236
251
  const choice = agent.imageModelChoice ?? DEFAULT_IMAGE_MODEL_CHOICE;
237
252
  const entry = DIFFUSION_CATALOG.find((candidate) => candidate.choice === choice);
238
- if (entry)
253
+ if (entry) {
239
254
  models.push({ name: entry.name, addon: entry.model.addon });
255
+ }
240
256
  }
241
257
  if (agentHasSkill(agent, MUSIC_GENERATION_SKILL)) {
242
258
  const choice = agent.musicModelChoice ?? DEFAULT_MUSIC_MODEL_CHOICE;
243
259
  const entry = AUDIOGEN_CATALOG.find((candidate) => candidate.choice === choice);
244
- if (entry)
260
+ if (entry) {
245
261
  models.push({ name: entry.name, addon: entry.dit.addon });
262
+ }
246
263
  }
247
264
  return models;
248
265
  }
@@ -251,13 +268,14 @@ export function diffusionSizeBytes(entry) {
251
268
  }
252
269
  export function imageModelFor(choice) {
253
270
  const entry = DIFFUSION_CATALOG.find((candidate) => candidate.choice === choice);
254
- if (!entry)
271
+ if (!entry) {
255
272
  return null;
273
+ }
256
274
  return {
257
275
  model: entry.model.src,
258
- ...(entry.llmModel ? { llmModel: entry.llmModel.src } : {}),
259
- ...(entry.vaeModel ? { vaeModel: entry.vaeModel.src } : {}),
260
- ...(entry.prediction ? { prediction: entry.prediction } : {})
276
+ llmModel: entry.llmModel?.src,
277
+ vaeModel: entry.vaeModel?.src,
278
+ prediction: entry.prediction
261
279
  };
262
280
  }
263
281
  export function imageClampsFromEnv(env) {
@@ -267,9 +285,10 @@ export function imageClampsFromEnv(env) {
267
285
  };
268
286
  const maxDim = positive(env.QVAC_IMAGE_MAX_DIM);
269
287
  const maxSteps = positive(env.QVAC_IMAGE_MAX_STEPS);
270
- if (!maxDim && !maxSteps)
288
+ if (!maxDim && !maxSteps) {
271
289
  return undefined;
272
- return { ...(maxDim ? { maxDim } : {}), ...(maxSteps ? { maxSteps } : {}) };
290
+ }
291
+ return { maxDim, maxSteps };
273
292
  }
274
293
  export function imageModelFromEnv(env, onIgnoredCompanions, onIgnoredPrediction) {
275
294
  const catalog = imageModelFor(env.QVAC_IMAGE_MODEL);
@@ -279,12 +298,14 @@ export function imageModelFromEnv(env, onIgnoredCompanions, onIgnoredPrediction)
279
298
  }
280
299
  return catalog;
281
300
  }
282
- if (!env.QVAC_IMAGE_MODEL)
301
+ if (!env.QVAC_IMAGE_MODEL) {
283
302
  return undefined;
303
+ }
284
304
  const prediction = env.QVAC_IMAGE_PREDICTION || undefined;
285
305
  const fluxSet = Boolean(env.QVAC_IMAGE_LLM && env.QVAC_IMAGE_VAE);
286
- if (prediction && !fluxSet)
306
+ if (prediction && !fluxSet) {
287
307
  onIgnoredPrediction?.();
308
+ }
288
309
  return {
289
310
  model: env.QVAC_IMAGE_MODEL,
290
311
  llmModel: env.QVAC_IMAGE_LLM || undefined,
@@ -304,13 +325,20 @@ export function curatedListables() {
304
325
  ...DIFFUSION_CATALOG.map((entry) => ({
305
326
  name: entry.name,
306
327
  asset: entry.model,
307
- companions: [entry.llmModel, entry.vaeModel].filter(Boolean)
328
+ companions: [entry.llmModel, entry.vaeModel].filter((asset) => asset !== undefined)
308
329
  }))
309
330
  ];
310
331
  }
311
332
  export function curatedModelAsset(name, addon) {
312
333
  return curatedListables().find((entry) => entry.asset.addon === addon && (entry.name === name || entry.asset.name === name))?.asset;
313
334
  }
335
+ export function modelAddonOf(model) {
336
+ const known = [...curatedListables(), ...musicListables()].find((entry) => entry.name === model || entry.asset.name === model || entry.asset.src === model);
337
+ return known?.asset.addon ?? 'llm';
338
+ }
339
+ export function residentSrc(model, addon) {
340
+ return curatedModelAsset(model, addon)?.src ?? model;
341
+ }
314
342
  export const CUSTOM_TASK_TYPES = ['llm'];
315
343
  let CUSTOM_MODELS = new Map();
316
344
  export function setCustomModels(entries) {
@@ -319,34 +347,40 @@ export function setCustomModels(entries) {
319
347
  export function customModels() {
320
348
  return [...CUSTOM_MODELS.values()];
321
349
  }
350
+ export function customContextLength(name) {
351
+ return CUSTOM_MODELS.get(name)?.contextLength;
352
+ }
322
353
  export function customModelSrc(name, addon) {
323
354
  const entry = CUSTOM_MODELS.get(name);
324
355
  return entry && (entry.taskType ?? 'llm') === addon ? entry.src : undefined;
325
356
  }
326
357
  export function customToolDialect(name) {
327
358
  const entry = CUSTOM_MODELS.get(name);
328
- return entry ? detectToolDialect(entry.src, entry.name) : undefined;
359
+ return entry
360
+ ? detectToolDialect(entry.src, entry.label?.replace(/\s+/g, '-') ?? entry.name)
361
+ : undefined;
329
362
  }
330
363
  export function customProjectionMap() {
331
364
  const map = {};
332
365
  for (const entry of CUSTOM_MODELS.values()) {
333
- if (entry.projectionSrc)
366
+ if (entry.projectionSrc) {
334
367
  map[entry.name] = entry.projectionSrc;
368
+ }
335
369
  }
336
370
  return map;
337
371
  }
338
372
  export function companionRegistryPaths() {
339
373
  const map = new Map();
340
374
  for (const entry of LLM_CATALOG) {
341
- if (entry.projection)
375
+ if (entry.projection) {
342
376
  map.set(entry.weight.registryPath, [entry.projection.registryPath]);
377
+ }
343
378
  }
344
379
  for (const entry of DIFFUSION_CATALOG) {
345
- const companions = [entry.llmModel, entry.vaeModel]
346
- .filter(Boolean)
347
- .map((asset) => asset.registryPath);
348
- if (companions.length)
380
+ const companions = [entry.llmModel, entry.vaeModel].flatMap((asset) => asset ? [asset.registryPath] : []);
381
+ if (companions.length) {
349
382
  map.set(entry.model.registryPath, companions);
383
+ }
350
384
  }
351
385
  for (const entry of AUDIOGEN_CATALOG) {
352
386
  map.set(entry.dit.registryPath, [
@@ -360,8 +394,9 @@ export function companionRegistryPaths() {
360
394
  export function audioGenModelByName(name) {
361
395
  for (const entry of AUDIOGEN_CATALOG) {
362
396
  for (const stage of [entry.dit, entry.textEnc, entry.lm, entry.vae]) {
363
- if (stage.name === name || entry.name === name)
397
+ if (stage.name === name || entry.name === name) {
364
398
  return name === entry.name ? entry.dit : stage;
399
+ }
365
400
  }
366
401
  }
367
402
  return undefined;
@@ -1,30 +1,38 @@
1
1
  import fs from 'fs';
2
- import { downloadedCustomFiles } from './custom-model-cache.js';
2
+ import { customDownloads } from './custom-model-cache.js';
3
3
  import { curatedListables, customModels, musicListables } from './model-catalog.js';
4
4
  export function summarizeDelete(result) {
5
5
  return { name: result.name, removed: result.removed.length, freedBytes: result.freedBytes };
6
6
  }
7
7
  export async function deleteModelFiles(sdk, name, { modelsDir } = {}) {
8
8
  const custom = customModels().find((entry) => entry.name === name);
9
- const paths = custom ? downloadedCustomFiles(custom, modelsDir) : await catalogFiles(sdk, name);
9
+ const { files, dirs } = custom
10
+ ? await customDownloads(custom, modelsDir)
11
+ : { files: await catalogFiles(sdk, name), dirs: [] };
10
12
  const removed = [];
11
- for (const filePath of new Set(paths)) {
13
+ for (const filePath of new Set(files)) {
12
14
  const bytes = await onDiskSize(filePath);
13
- if (bytes === null)
15
+ if (bytes === null) {
14
16
  continue;
17
+ }
15
18
  await fs.promises.rm(filePath, { force: true });
16
19
  removed.push({ path: filePath, bytes });
17
20
  }
21
+ for (const dir of dirs) {
22
+ await fs.promises.rm(dir, { recursive: true, force: true });
23
+ }
18
24
  return { name, removed, freedBytes: removed.reduce((sum, file) => sum + file.bytes, 0) };
19
25
  }
20
26
  async function catalogFiles(sdk, name) {
21
27
  const paths = [];
22
28
  for (const catalogName of namesToPurge(name)) {
23
29
  const info = await sdk.getModelInfo({ name: catalogName }).catch(() => null);
24
- if (!info)
30
+ if (!info) {
25
31
  continue;
26
- for (const file of info.cacheFiles)
32
+ }
33
+ for (const file of info.cacheFiles) {
27
34
  paths.push(file.path);
35
+ }
28
36
  }
29
37
  return paths;
30
38
  }
@@ -41,12 +49,14 @@ function namesToPurge(name) {
41
49
  const curated = curatedListables().find((entry) => entry.name === name || entry.asset.name === name);
42
50
  if (curated) {
43
51
  const names = [curated.asset.name, ...curated.companions.map((companion) => companion.name)];
44
- if (curated.projection)
52
+ if (curated.projection) {
45
53
  names.push(curated.projection.name);
54
+ }
46
55
  return names;
47
56
  }
48
57
  const music = musicListables().find((entry) => entry.name === name || entry.asset.name === name);
49
- if (music)
58
+ if (music) {
50
59
  return [music.asset.name, ...music.companions.map((stage) => stage.name)];
60
+ }
51
61
  return [name];
52
62
  }
@@ -16,8 +16,9 @@ export class ModelHandle {
16
16
  this._tracked = attempt;
17
17
  this._loading = true;
18
18
  const settled = () => {
19
- if (this._tracked === attempt)
19
+ if (this._tracked === attempt) {
20
20
  this._loading = false;
21
+ }
21
22
  };
22
23
  attempt.then(settled, settled);
23
24
  }
@@ -18,6 +18,7 @@ export interface ModelInfo {
18
18
  supportsImages: boolean;
19
19
  expectedSize: number;
20
20
  actualSize?: number;
21
+ label?: string;
21
22
  }
22
23
  export interface ListModelsOptions {
23
24
  type?: ModelType;
@@ -31,14 +32,18 @@ interface ModelStatus {
31
32
  expectedSize?: number;
32
33
  actualSize?: number;
33
34
  }
34
- export type ModelStatusCache = {
35
+ export interface ModelStatusCache {
35
36
  readonly entries: Map<string, ModelStatus>;
36
37
  epoch: number;
37
- };
38
+ }
38
39
  export declare const MODEL_STATUS_TTL_MS = 30000;
39
40
  export declare function createModelStatusCache(): ModelStatusCache;
40
41
  export declare function invalidateModelStatusCache(cache: ModelStatusCache): void;
41
- export declare function listModels(sdk: ModelListSdk, { type, cachedOnly, fullRegistry }?: ListModelsOptions, cache?: ModelStatusCache, projectionFor?: (name: string) => string | undefined): Promise<ModelInfo[]>;
42
+ export interface ListModelsRuntime {
43
+ cache?: ModelStatusCache | undefined;
44
+ projectionFor?: ((name: string) => string | undefined) | undefined;
45
+ }
46
+ export declare function listModels(sdk: ModelListSdk, { type, cachedOnly, fullRegistry }?: ListModelsOptions, { cache, projectionFor }?: ListModelsRuntime): Promise<ModelInfo[]>;
42
47
  export interface CustomModelRowsContext {
43
48
  readonly modelsDir?: string;
44
49
  readonly loaded: ReadonlySet<string>;
@@ -15,8 +15,9 @@ async function mapPool(items, limit, fn) {
15
15
  const worker = async () => {
16
16
  while (true) {
17
17
  const i = cursor++;
18
- if (i >= items.length)
18
+ if (i >= items.length) {
19
19
  return;
20
+ }
20
21
  results[i] = await fn(items[i]);
21
22
  }
22
23
  };
@@ -46,13 +47,14 @@ async function musicRows(hydrate) {
46
47
  }
47
48
  return rows;
48
49
  }
49
- export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, cache, projectionFor) {
50
+ export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, { cache, projectionFor } = {}) {
50
51
  const now = Date.now();
51
52
  const seesImages = (name, addon) => addon === 'llm' && Boolean(projectionFor?.(name));
52
53
  const hydrate = async (registryPath, catalogName) => {
53
54
  const hit = cache?.entries.get(registryPath);
54
- if (hit && now - hit.at < MODEL_STATUS_TTL_MS)
55
+ if (hit && now - hit.at < MODEL_STATUS_TTL_MS) {
55
56
  return hit;
57
+ }
56
58
  const epoch = cache?.epoch;
57
59
  const info = catalogName
58
60
  ? await sdk.getModelInfo({ name: catalogName }).catch(() => null)
@@ -64,8 +66,9 @@ export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, c
64
66
  expectedSize: info?.expectedSize,
65
67
  actualSize: info?.actualSize
66
68
  };
67
- if (cache && cache.epoch === epoch)
69
+ if (cache && cache.epoch === epoch) {
68
70
  cache.entries.set(registryPath, status);
71
+ }
69
72
  return status;
70
73
  };
71
74
  if (!fullRegistry) {
@@ -99,8 +102,9 @@ export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, c
99
102
  }
100
103
  const entries = await sdk.modelRegistrySearch(type ? { addon: type } : {});
101
104
  const catalog = new Map();
102
- for (const c of sdk.models)
105
+ for (const c of sdk.models) {
103
106
  catalog.set(c.registryPath, c.name);
107
+ }
104
108
  const rows = await mapPool(entries, STATUS_CONCURRENCY, async (entry) => {
105
109
  const status = await hydrate(entry.registryPath, catalog.get(entry.registryPath));
106
110
  const companions = COMPANIONS_BY_WEIGHT.get(entry.registryPath) ?? [];
@@ -134,7 +138,8 @@ export async function customModelRows({ type, cachedOnly }, { modelsDir, loaded
134
138
  isCached: await isCustomModelCached(entry, modelsDir),
135
139
  isLoaded: loaded.has(entry.name),
136
140
  supportsImages: addon === 'llm' && Boolean(entry.projectionSrc),
137
- expectedSize: entry.expectedSize ?? 0
141
+ expectedSize: entry.expectedSize ?? 0,
142
+ label: entry.label
138
143
  };
139
144
  }));
140
145
  return cachedOnly ? rows.filter((row) => row.isCached) : rows;
@@ -66,7 +66,16 @@ export interface LoadedModel {
66
66
  model: string;
67
67
  refs: number;
68
68
  }
69
- type PoolLike = ReturnType<typeof createModelPool>;
69
+ interface PuddleEntry {
70
+ readonly id: string;
71
+ readonly refs: number;
72
+ readonly value: ModelHandle;
73
+ }
74
+ declare class ModelPuddle extends ResourcePuddle<string, ModelHandle> {
75
+ readonly resources: Map<string, PuddleEntry>;
76
+ }
77
+ type PoolLike = ModelPuddle;
78
+ export declare function modelOf(key: string): string;
70
79
  export declare function releaseModel(pool: PoolLike, key: string): void;
71
80
  export declare function loadedModels(pool: PoolLike): LoadedModel[];
72
81
  export interface ResidentLease {
@@ -78,10 +87,21 @@ export declare function leaseResidentModel(pool: PoolLike, wanted?: (model: stri
78
87
  export declare function isResident(pool: PoolLike, key: string): boolean;
79
88
  export declare function leaseCount(pool: PoolLike, key: string): number;
80
89
  export declare function evictIdle(pool: PoolLike): Promise<void>;
81
- export declare function awaitModelCapacity(pool: PoolLike, cap: number, deadlineMs: number, tickMs?: number, signal?: {
82
- aborted?: boolean;
83
- }): Promise<boolean>;
84
- export declare function evictModelWithin(pool: PoolLike, key: string, deadlineMs: number, tickMs?: number): Promise<boolean>;
90
+ export declare function evictIdleWhere(pool: PoolLike, wanted: (key: string) => boolean): Promise<void>;
91
+ export interface DeadlineOptions {
92
+ deadlineMs: number;
93
+ tickMs?: number;
94
+ }
95
+ export interface ModelCapacityOptions extends DeadlineOptions {
96
+ cap: number;
97
+ signal?: {
98
+ aborted?: boolean;
99
+ } | undefined;
100
+ evictable?: (key: string) => boolean;
101
+ }
102
+ export declare function awaitModelCapacity(pool: PoolLike, { cap, deadlineMs, tickMs, signal, evictable }: ModelCapacityOptions): Promise<boolean>;
103
+ export declare function evictModelWithin(pool: PoolLike, key: string, options: DeadlineOptions): Promise<boolean>;
104
+ export declare function evictModel(pool: PoolLike, model: string, options: DeadlineOptions): Promise<boolean>;
85
105
  export type LoadSdk = () => Promise<ModelLifecycleSdk>;
86
106
  export type EmbedLifecycleSdk = Pick<SdkModule, 'unloadModel' | 'modelRegistrySearch'> & Partial<CancelSdk> & {
87
107
  loadModel(params: {
@@ -104,11 +124,22 @@ interface LoadClockGuardOptions {
104
124
  sampleMs?: number;
105
125
  jumpMs?: number;
106
126
  }
107
- export declare function loadClockGuard(model: string, sdk: Partial<CancelSdk>, { now, monoMs, sampleMs, jumpMs }?: LoadClockGuardOptions): {
127
+ interface LoadClockGuard {
108
128
  race: (pending: TrackedLoad) => Promise<string>;
109
- };
110
- export declare function createModelPool(loadSdk: LoadSdk, notify: NotifyFn, deviceConfig?: LlmDeviceConfig, loads?: LoadTracker): ResourcePuddle<string, ModelHandle>;
111
- export declare function createEmbedPool(loadSdk: LoadEmbedSdk, notify: NotifyFn, faults: GpuFaultState, batchSize?: number, openclCacheDir?: () => string | undefined, loads?: LoadTracker): ResourcePuddle<string, ModelHandle>;
129
+ }
130
+ export declare function loadClockGuard(model: string, sdk: Partial<CancelSdk>, { now, monoMs, sampleMs, jumpMs }?: LoadClockGuardOptions): LoadClockGuard;
131
+ export interface ModelPoolOptions {
132
+ deviceConfig?: LlmDeviceConfig;
133
+ loads?: LoadTracker;
134
+ }
135
+ export declare function createModelPool(loadSdk: LoadSdk, notify: NotifyFn, { deviceConfig, loads }?: ModelPoolOptions): ModelPuddle;
136
+ export interface EmbedPoolOptions {
137
+ faults: GpuFaultState;
138
+ batchSize?: number;
139
+ openclCacheDir?: (() => string | undefined) | undefined;
140
+ loads?: LoadTracker;
141
+ }
142
+ export declare function createEmbedPool(loadSdk: LoadEmbedSdk, notify: NotifyFn, { faults, batchSize, openclCacheDir, loads }: EmbedPoolOptions): ModelPuddle;
112
143
  export type VoiceLifecycleSdk = Pick<SdkModule, 'unloadModel' | 'modelRegistrySearch'> & Partial<CancelSdk> & {
113
144
  loadModel(params: {
114
145
  modelSrc: ModelSrc;
@@ -118,5 +149,12 @@ export type VoiceLifecycleSdk = Pick<SdkModule, 'unloadModel' | 'modelRegistrySe
118
149
  }): TrackedLoad;
119
150
  };
120
151
  export type LoadVoiceSdk = () => Promise<VoiceLifecycleSdk>;
121
- export declare function createVoicePool(loadSdk: LoadVoiceSdk, notify: NotifyFn, modelType: string, addon: ModelAddon, modelConfig?: Record<string, unknown>, openclCacheDir?: () => string | undefined, loads?: LoadTracker): ResourcePuddle<string, ModelHandle>;
152
+ export interface VoicePoolOptions {
153
+ modelType: string;
154
+ addon: ModelAddon;
155
+ modelConfig?: Record<string, unknown> | undefined;
156
+ openclCacheDir?: (() => string | undefined) | undefined;
157
+ loads?: LoadTracker;
158
+ }
159
+ export declare function createVoicePool(loadSdk: LoadVoiceSdk, notify: NotifyFn, { modelType, addon, modelConfig, openclCacheDir, loads }: VoicePoolOptions): ModelPuddle;
122
160
  export {};