@atomic-chat/core 0.19.1 → 0.20.6

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 (335) hide show
  1. package/dist/app-daemon.js +5 -0
  2. package/dist/app-daemon.js.map +1 -1
  3. package/dist/audio/args.d.ts +19 -0
  4. package/dist/audio/args.js +39 -0
  5. package/dist/audio/args.js.map +1 -0
  6. package/dist/audio/capabilities.d.ts +24 -0
  7. package/dist/audio/capabilities.js +96 -0
  8. package/dist/audio/capabilities.js.map +1 -0
  9. package/dist/audio/config.d.ts +40 -0
  10. package/dist/audio/config.js +57 -0
  11. package/dist/audio/config.js.map +1 -0
  12. package/dist/audio/errors.d.ts +23 -0
  13. package/dist/audio/errors.js +52 -0
  14. package/dist/audio/errors.js.map +1 -0
  15. package/dist/audio/gallery.d.ts +30 -0
  16. package/dist/audio/gallery.js +152 -0
  17. package/dist/audio/gallery.js.map +1 -0
  18. package/dist/audio/http.d.ts +26 -0
  19. package/dist/audio/http.js +56 -0
  20. package/dist/audio/http.js.map +1 -0
  21. package/dist/audio/idle.d.ts +22 -0
  22. package/dist/audio/idle.js +44 -0
  23. package/dist/audio/idle.js.map +1 -0
  24. package/dist/audio/index.d.ts +26 -0
  25. package/dist/audio/index.js +27 -0
  26. package/dist/audio/index.js.map +1 -0
  27. package/dist/audio/install.d.ts +57 -0
  28. package/dist/audio/install.js +196 -0
  29. package/dist/audio/install.js.map +1 -0
  30. package/dist/audio/jobs.d.ts +77 -0
  31. package/dist/audio/jobs.js +340 -0
  32. package/dist/audio/jobs.js.map +1 -0
  33. package/dist/audio/model-files.d.ts +12 -0
  34. package/dist/audio/model-files.js +42 -0
  35. package/dist/audio/model-files.js.map +1 -0
  36. package/dist/audio/output.d.ts +32 -0
  37. package/dist/audio/output.js +93 -0
  38. package/dist/audio/output.js.map +1 -0
  39. package/dist/audio/parse.d.ts +15 -0
  40. package/dist/audio/parse.js +149 -0
  41. package/dist/audio/parse.js.map +1 -0
  42. package/dist/audio/recipe.d.ts +22 -0
  43. package/dist/audio/recipe.js +92 -0
  44. package/dist/audio/recipe.js.map +1 -0
  45. package/dist/audio/request.d.ts +24 -0
  46. package/dist/audio/request.js +86 -0
  47. package/dist/audio/request.js.map +1 -0
  48. package/dist/audio/server-process.d.ts +51 -0
  49. package/dist/audio/server-process.js +202 -0
  50. package/dist/audio/server-process.js.map +1 -0
  51. package/dist/audio/service.d.ts +107 -0
  52. package/dist/audio/service.js +402 -0
  53. package/dist/audio/service.js.map +1 -0
  54. package/dist/audio/session.d.ts +73 -0
  55. package/dist/audio/session.js +216 -0
  56. package/dist/audio/session.js.map +1 -0
  57. package/dist/audio/state.d.ts +68 -0
  58. package/dist/audio/state.js +88 -0
  59. package/dist/audio/state.js.map +1 -0
  60. package/dist/audio/types.d.ts +52 -0
  61. package/dist/audio/types.js +8 -0
  62. package/dist/audio/types.js.map +1 -0
  63. package/dist/audio/wav.d.ts +22 -0
  64. package/dist/audio/wav.js +56 -0
  65. package/dist/audio/wav.js.map +1 -0
  66. package/dist/audio/wiring.d.ts +31 -0
  67. package/dist/audio/wiring.js +41 -0
  68. package/dist/audio/wiring.js.map +1 -0
  69. package/dist/backend/install/service.js +4 -2
  70. package/dist/backend/install/service.js.map +1 -1
  71. package/dist/cli/launch.js +2 -0
  72. package/dist/cli/launch.js.map +1 -1
  73. package/dist/cli/main.d.ts +1 -1
  74. package/dist/cli/main.js +5 -0
  75. package/dist/cli/main.js.map +1 -1
  76. package/dist/client/control-client.d.ts +21 -1
  77. package/dist/client/control-client.js +50 -0
  78. package/dist/client/control-client.js.map +1 -1
  79. package/dist/client/index.d.ts +1 -0
  80. package/dist/client/index.js +1 -0
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/client/model-catalog.d.ts +40 -0
  83. package/dist/client/model-catalog.js +149 -0
  84. package/dist/client/model-catalog.js.map +1 -0
  85. package/dist/cloud/registry.js +1 -0
  86. package/dist/cloud/registry.js.map +1 -1
  87. package/dist/config/paths.d.ts +22 -1
  88. package/dist/config/paths.js +24 -0
  89. package/dist/config/paths.js.map +1 -1
  90. package/dist/contracts/audio.d.ts +290 -0
  91. package/dist/contracts/audio.js +24 -0
  92. package/dist/contracts/audio.js.map +1 -0
  93. package/dist/contracts/embedding.js +1 -0
  94. package/dist/contracts/embedding.js.map +1 -1
  95. package/dist/contracts/engine-builds.d.ts +10 -4
  96. package/dist/contracts/engine-builds.js +10 -2
  97. package/dist/contracts/engine-builds.js.map +1 -1
  98. package/dist/contracts/engines.d.ts +1 -1
  99. package/dist/contracts/engines.js +4 -0
  100. package/dist/contracts/engines.js.map +1 -1
  101. package/dist/contracts/errors.d.ts +14 -2
  102. package/dist/contracts/errors.js +29 -0
  103. package/dist/contracts/errors.js.map +1 -1
  104. package/dist/contracts/events.d.ts +10 -0
  105. package/dist/contracts/geniex.d.ts +98 -0
  106. package/dist/contracts/geniex.js +15 -0
  107. package/dist/contracts/geniex.js.map +1 -0
  108. package/dist/contracts/index.d.ts +2 -0
  109. package/dist/contracts/index.js +2 -0
  110. package/dist/contracts/index.js.map +1 -1
  111. package/dist/contracts/model-yml.d.ts +40 -0
  112. package/dist/contracts/model-yml.js +7 -0
  113. package/dist/contracts/model-yml.js.map +1 -1
  114. package/dist/contracts/session.d.ts +6 -1
  115. package/dist/contracts/session.js.map +1 -1
  116. package/dist/contracts/settings.d.ts +12 -1
  117. package/dist/contracts/settings.js.map +1 -1
  118. package/dist/core/atomic-core.d.ts +6 -1
  119. package/dist/core/atomic-core.js +7 -1
  120. package/dist/core/atomic-core.js.map +1 -1
  121. package/dist/core/create.js +105 -6
  122. package/dist/core/create.js.map +1 -1
  123. package/dist/core/gpu-residency.d.ts +8 -2
  124. package/dist/core/gpu-residency.js +9 -1
  125. package/dist/core/gpu-residency.js.map +1 -1
  126. package/dist/core/types.d.ts +3 -0
  127. package/dist/core/types.js.map +1 -1
  128. package/dist/diffusion/install.d.ts +6 -3
  129. package/dist/diffusion/install.js +5 -4
  130. package/dist/diffusion/install.js.map +1 -1
  131. package/dist/embedding/index.js +1 -0
  132. package/dist/embedding/index.js.map +1 -1
  133. package/dist/engine-builds/engines.d.ts +31 -8
  134. package/dist/engine-builds/engines.js +118 -14
  135. package/dist/engine-builds/engines.js.map +1 -1
  136. package/dist/engine-builds/geniex.d.ts +35 -0
  137. package/dist/engine-builds/geniex.js +111 -0
  138. package/dist/engine-builds/geniex.js.map +1 -0
  139. package/dist/engine-builds/index.d.ts +3 -2
  140. package/dist/engine-builds/index.js +3 -2
  141. package/dist/engine-builds/index.js.map +1 -1
  142. package/dist/engine-builds/manifest.d.ts +95 -5
  143. package/dist/engine-builds/manifest.js +152 -9
  144. package/dist/engine-builds/manifest.js.map +1 -1
  145. package/dist/engine-builds/order.d.ts +7 -1
  146. package/dist/engine-builds/order.js +13 -0
  147. package/dist/engine-builds/order.js.map +1 -1
  148. package/dist/engine-builds/select.d.ts +43 -11
  149. package/dist/engine-builds/select.js +64 -16
  150. package/dist/engine-builds/select.js.map +1 -1
  151. package/dist/engine-builds/service.d.ts +19 -11
  152. package/dist/engine-builds/service.js +31 -9
  153. package/dist/engine-builds/service.js.map +1 -1
  154. package/dist/engines/service.d.ts +4 -3
  155. package/dist/engines/service.js +5 -3
  156. package/dist/engines/service.js.map +1 -1
  157. package/dist/engines/versions.js +3 -0
  158. package/dist/engines/versions.js.map +1 -1
  159. package/dist/integrations/catalog.d.ts +3 -1
  160. package/dist/integrations/catalog.js +8 -2
  161. package/dist/integrations/catalog.js.map +1 -1
  162. package/dist/integrations/config-io.d.ts +45 -4
  163. package/dist/integrations/config-io.js +91 -6
  164. package/dist/integrations/config-io.js.map +1 -1
  165. package/dist/integrations/configure/codex-repair.d.ts +75 -0
  166. package/dist/integrations/configure/codex-repair.js +254 -0
  167. package/dist/integrations/configure/codex-repair.js.map +1 -0
  168. package/dist/integrations/configure/codex.d.ts +48 -10
  169. package/dist/integrations/configure/codex.js +126 -32
  170. package/dist/integrations/configure/codex.js.map +1 -1
  171. package/dist/integrations/configure/registry.d.ts +4 -1
  172. package/dist/integrations/configure/registry.js +1 -0
  173. package/dist/integrations/configure/registry.js.map +1 -1
  174. package/dist/lock/process-journal.d.ts +3 -3
  175. package/dist/models/compatibility/rules-baseline.js +1 -0
  176. package/dist/models/compatibility/rules-baseline.js.map +1 -1
  177. package/dist/models/compatibility/rules.js +1 -0
  178. package/dist/models/compatibility/rules.js.map +1 -1
  179. package/dist/models/gguf/kv-cache.d.ts +5 -0
  180. package/dist/models/gguf/kv-cache.js +35 -2
  181. package/dist/models/gguf/kv-cache.js.map +1 -1
  182. package/dist/models/gguf/reader.d.ts +5 -0
  183. package/dist/models/gguf/reader.js +15 -3
  184. package/dist/models/gguf/reader.js.map +1 -1
  185. package/dist/models/hf.d.ts +3 -0
  186. package/dist/models/hf.js +11 -4
  187. package/dist/models/hf.js.map +1 -1
  188. package/dist/router/resolve.d.ts +3 -2
  189. package/dist/router/resolve.js +3 -1
  190. package/dist/router/resolve.js.map +1 -1
  191. package/dist/runtime/geniex/accelerators.d.ts +20 -0
  192. package/dist/runtime/geniex/accelerators.js +53 -0
  193. package/dist/runtime/geniex/accelerators.js.map +1 -0
  194. package/dist/runtime/geniex/check.d.ts +34 -0
  195. package/dist/runtime/geniex/check.js +117 -0
  196. package/dist/runtime/geniex/check.js.map +1 -0
  197. package/dist/runtime/geniex/chip.d.ts +29 -0
  198. package/dist/runtime/geniex/chip.js +35 -0
  199. package/dist/runtime/geniex/chip.js.map +1 -0
  200. package/dist/runtime/geniex/devices.d.ts +13 -0
  201. package/dist/runtime/geniex/devices.js +32 -0
  202. package/dist/runtime/geniex/devices.js.map +1 -0
  203. package/dist/runtime/geniex/geniex-host.d.ts +17 -0
  204. package/dist/runtime/geniex/geniex-host.js +26 -0
  205. package/dist/runtime/geniex/geniex-host.js.map +1 -0
  206. package/dist/runtime/geniex/host/args.d.ts +56 -0
  207. package/dist/runtime/geniex/host/args.js +115 -0
  208. package/dist/runtime/geniex/host/args.js.map +1 -0
  209. package/dist/runtime/geniex/host/engine.d.ts +76 -0
  210. package/dist/runtime/geniex/host/engine.js +122 -0
  211. package/dist/runtime/geniex/host/engine.js.map +1 -0
  212. package/dist/runtime/geniex/host/ffi-bun.d.ts +15 -0
  213. package/dist/runtime/geniex/host/ffi-bun.js +415 -0
  214. package/dist/runtime/geniex/host/ffi-bun.js.map +1 -0
  215. package/dist/runtime/geniex/host/grammar.d.ts +11 -0
  216. package/dist/runtime/geniex/host/grammar.js +223 -0
  217. package/dist/runtime/geniex/host/grammar.js.map +1 -0
  218. package/dist/runtime/geniex/host/inspect.d.ts +25 -0
  219. package/dist/runtime/geniex/host/inspect.js +177 -0
  220. package/dist/runtime/geniex/host/inspect.js.map +1 -0
  221. package/dist/runtime/geniex/host/library.d.ts +117 -0
  222. package/dist/runtime/geniex/host/library.js +38 -0
  223. package/dist/runtime/geniex/host/library.js.map +1 -0
  224. package/dist/runtime/geniex/host/openai.d.ts +62 -0
  225. package/dist/runtime/geniex/host/openai.js +458 -0
  226. package/dist/runtime/geniex/host/openai.js.map +1 -0
  227. package/dist/runtime/geniex/host/run.d.ts +48 -0
  228. package/dist/runtime/geniex/host/run.js +208 -0
  229. package/dist/runtime/geniex/host/run.js.map +1 -0
  230. package/dist/runtime/geniex/host/server.d.ts +39 -0
  231. package/dist/runtime/geniex/host/server.js +232 -0
  232. package/dist/runtime/geniex/host/server.js.map +1 -0
  233. package/dist/runtime/geniex/host/worker-protocol.d.ts +76 -0
  234. package/dist/runtime/geniex/host/worker-protocol.js +116 -0
  235. package/dist/runtime/geniex/host/worker-protocol.js.map +1 -0
  236. package/dist/runtime/geniex/host/worker-source.generated.d.ts +1 -0
  237. package/dist/runtime/geniex/host/worker-source.generated.js +4 -0
  238. package/dist/runtime/geniex/host/worker-source.generated.js.map +1 -0
  239. package/dist/runtime/geniex/host/worker.d.ts +7 -0
  240. package/dist/runtime/geniex/host/worker.js +19 -0
  241. package/dist/runtime/geniex/host/worker.js.map +1 -0
  242. package/dist/runtime/geniex/host-process.d.ts +48 -0
  243. package/dist/runtime/geniex/host-process.js +104 -0
  244. package/dist/runtime/geniex/host-process.js.map +1 -0
  245. package/dist/runtime/geniex/index.d.ts +11 -0
  246. package/dist/runtime/geniex/index.js +12 -0
  247. package/dist/runtime/geniex/index.js.map +1 -0
  248. package/dist/runtime/geniex/model-yml.d.ts +8 -0
  249. package/dist/runtime/geniex/model-yml.js +98 -0
  250. package/dist/runtime/geniex/model-yml.js.map +1 -0
  251. package/dist/runtime/geniex/runtime.d.ts +94 -0
  252. package/dist/runtime/geniex/runtime.js +366 -0
  253. package/dist/runtime/geniex/runtime.js.map +1 -0
  254. package/dist/runtime/litert-lm/host/openai.d.ts +4 -37
  255. package/dist/runtime/litert-lm/host/openai.js +11 -96
  256. package/dist/runtime/litert-lm/host/openai.js.map +1 -1
  257. package/dist/runtime/litert-lm/host/pool.d.ts +1 -7
  258. package/dist/runtime/litert-lm/host/pool.js +1 -17
  259. package/dist/runtime/litert-lm/host/pool.js.map +1 -1
  260. package/dist/runtime/litert-lm/host/server.js +11 -53
  261. package/dist/runtime/litert-lm/host/server.js.map +1 -1
  262. package/dist/runtime/llamacpp/args.d.ts +5 -0
  263. package/dist/runtime/llamacpp/args.js +2 -0
  264. package/dist/runtime/llamacpp/args.js.map +1 -1
  265. package/dist/runtime/llamacpp/fit-margin.d.ts +44 -0
  266. package/dist/runtime/llamacpp/fit-margin.js +50 -0
  267. package/dist/runtime/llamacpp/fit-margin.js.map +1 -1
  268. package/dist/runtime/llamacpp/load-plan.d.ts +5 -0
  269. package/dist/runtime/llamacpp/load-plan.js +57 -22
  270. package/dist/runtime/llamacpp/load-plan.js.map +1 -1
  271. package/dist/runtime/llamacpp/runtime.d.ts +2 -1
  272. package/dist/runtime/llamacpp/runtime.js +3 -1
  273. package/dist/runtime/llamacpp/runtime.js.map +1 -1
  274. package/dist/runtime/shared/external-sessions.js +1 -0
  275. package/dist/runtime/shared/external-sessions.js.map +1 -1
  276. package/dist/runtime/shared/fifo-lock.d.ts +10 -0
  277. package/dist/runtime/shared/fifo-lock.js +21 -0
  278. package/dist/runtime/shared/fifo-lock.js.map +1 -0
  279. package/dist/runtime/shared/index.d.ts +2 -0
  280. package/dist/runtime/shared/index.js +2 -0
  281. package/dist/runtime/shared/index.js.map +1 -1
  282. package/dist/runtime/shared/openai-sse.d.ts +112 -0
  283. package/dist/runtime/shared/openai-sse.js +178 -0
  284. package/dist/runtime/shared/openai-sse.js.map +1 -0
  285. package/dist/server/control/index.d.ts +1 -1
  286. package/dist/server/control/router.js +4 -0
  287. package/dist/server/control/router.js.map +1 -1
  288. package/dist/server/control/routes/audio.d.ts +15 -0
  289. package/dist/server/control/routes/audio.js +59 -0
  290. package/dist/server/control/routes/audio.js.map +1 -0
  291. package/dist/server/control/routes/geniex.d.ts +7 -0
  292. package/dist/server/control/routes/geniex.js +22 -0
  293. package/dist/server/control/routes/geniex.js.map +1 -0
  294. package/dist/server/control/types.d.ts +36 -2
  295. package/dist/server/control/types.js.map +1 -1
  296. package/dist/server/http.js +4 -0
  297. package/dist/server/http.js.map +1 -1
  298. package/dist/server/public/audio-speech-params.d.ts +47 -0
  299. package/dist/server/public/audio-speech-params.js +177 -0
  300. package/dist/server/public/audio-speech-params.js.map +1 -0
  301. package/dist/server/public/audio-speech.d.ts +14 -0
  302. package/dist/server/public/audio-speech.js +118 -0
  303. package/dist/server/public/audio-speech.js.map +1 -0
  304. package/dist/server/public/embedding.d.ts +8 -7
  305. package/dist/server/public/embedding.js +15 -7
  306. package/dist/server/public/embedding.js.map +1 -1
  307. package/dist/server/public/forward.js +15 -1
  308. package/dist/server/public/forward.js.map +1 -1
  309. package/dist/server/public/index.d.ts +1 -1
  310. package/dist/server/public/index.js +7 -0
  311. package/dist/server/public/index.js.map +1 -1
  312. package/dist/server/public/listing.js +1 -0
  313. package/dist/server/public/listing.js.map +1 -1
  314. package/dist/server/public/responses.js +9 -0
  315. package/dist/server/public/responses.js.map +1 -1
  316. package/dist/server/public/trace.js +2 -0
  317. package/dist/server/public/trace.js.map +1 -1
  318. package/dist/server/public/types.d.ts +29 -1
  319. package/dist/server/public/validate.d.ts +32 -0
  320. package/dist/server/public/validate.js +146 -0
  321. package/dist/server/public/validate.js.map +1 -0
  322. package/dist/settings/schema/geniex.json +63 -0
  323. package/dist/settings/schema/mlx.json +1 -1
  324. package/dist/settings/schema.js +11 -0
  325. package/dist/settings/schema.js.map +1 -1
  326. package/dist/telemetry/reports.d.ts +12 -0
  327. package/dist/telemetry/reports.js +38 -0
  328. package/dist/telemetry/reports.js.map +1 -1
  329. package/dist/telemetry/subscribe.d.ts +3 -3
  330. package/dist/telemetry/subscribe.js +8 -3
  331. package/dist/telemetry/subscribe.js.map +1 -1
  332. package/dist/telemetry/types.d.ts +1 -1
  333. package/dist/version.d.ts +1 -1
  334. package/dist/version.js +1 -1
  335. package/package.json +11 -2
@@ -0,0 +1,340 @@
1
+ /**
2
+ * Jobs: validate, send to `audiocpp_server`, save, and the cancel path. One job at a time; the
3
+ * request is synchronous (audio.cpp has no job API), so a job moves through phases only —
4
+ * `queued`, `loading` while a server stopped by a cancel or a crash comes back, `generating` while
5
+ * the engine runs, `saving` while the clip is written — each one an `audio:job` event.
6
+ *
7
+ * Cancel: audio.cpp cannot interrupt a running request and goes on generating after a JSON client
8
+ * hangs up, so a cancel aborts the request and stops the process, keeping the spec; the next job
9
+ * respawns the server from it. A job not generating yet just ends.
10
+ */
11
+ import { randomInt, randomUUID } from 'node:crypto';
12
+ import { readFile, stat } from 'node:fs/promises';
13
+ import { audioError, audioErrorBody, audioInternalError } from './errors.js';
14
+ import { AudioTimeoutError } from './http.js';
15
+ import { audioCrashError, engineErrorMessage, engineRejection } from './output.js';
16
+ import { buildAudioRecipe } from './recipe.js';
17
+ import { buildSpeechBody, buildTaskBody, decodeTaskAudio, extraOptions, SPEECH_PATH, TASK_PATH, } from './request.js';
18
+ import { emitAudioError, loadFromSpec, modelNotLoadedError, stopKeepingSpec, takeDownSession, } from './session.js';
19
+ import { isTerminalAudioJobState } from './state.js';
20
+ import { MAX_VOICE_REF_BYTES } from './types.js';
21
+ import { parseWav, stripAudioDataUrl } from './wav.js';
22
+ export const DEFAULT_AUDIO_JOB_TIMINGS = {
23
+ generationCeilingMs: 6 * 60 * 60 * 1000,
24
+ exitWaitMs: 1_000,
25
+ };
26
+ export function drawAudioSeed() {
27
+ return randomInt(0, 0x8000_0000);
28
+ }
29
+ const cancelledError = () => audioError('CANCELLED', 'The job was cancelled.');
30
+ /** A reference voice file, read whole once it is known to be small enough. */
31
+ export async function readVoiceRefFile(path, maxBytes) {
32
+ const meta = await stat(path).catch(() => undefined);
33
+ if (!meta || !meta.isFile())
34
+ throw audioError('INVALID_REQUEST', 'The reference voice file was not found.', path);
35
+ if (meta.size > maxBytes)
36
+ throw audioError('INVALID_REQUEST', 'The reference voice is larger than 5 MiB.', `${meta.size} bytes`);
37
+ return readFile(path).catch((error) => {
38
+ throw audioError('INVALID_REQUEST', 'The reference voice file could not be read.', error instanceof Error ? error.message : String(error));
39
+ });
40
+ }
41
+ /** The reference voice as the engine takes it: a WAV of at most 5 MiB, base64. */
42
+ export async function resolveVoiceRef(source, readSource) {
43
+ let bytes;
44
+ if ('path' in source)
45
+ bytes = await readSource(source.path, MAX_VOICE_REF_BYTES);
46
+ else {
47
+ const payload = stripAudioDataUrl(source.base64);
48
+ // Refused before it is decoded: four characters carry three bytes.
49
+ if (Math.floor((payload.length * 3) / 4) > MAX_VOICE_REF_BYTES + 2)
50
+ throw audioError('INVALID_REQUEST', 'The reference voice is larger than 5 MiB.', `${payload.length} base64 characters`);
51
+ bytes = Buffer.from(payload, 'base64');
52
+ if (bytes.length > MAX_VOICE_REF_BYTES)
53
+ throw audioError('INVALID_REQUEST', 'The reference voice is larger than 5 MiB.', `${bytes.length} bytes`);
54
+ }
55
+ if (!parseWav(bytes))
56
+ throw audioError('INVALID_REQUEST', 'The reference voice is not a WAV file.');
57
+ return bytes.toString('base64');
58
+ }
59
+ /** The request as the job record keeps it: inline audio bytes blanked, file paths kept. */
60
+ export function withoutInlineAudio(request) {
61
+ const copy = structuredClone(request);
62
+ if (copy.voiceRef && 'base64' in copy.voiceRef)
63
+ copy.voiceRef = { base64: '' };
64
+ return copy;
65
+ }
66
+ const MODE_WORDS = {
67
+ speech: 'speech',
68
+ music: 'music',
69
+ effects: 'sound effects',
70
+ };
71
+ // ---------------------------------------------------------------------------
72
+ // Job bookkeeping
73
+ // ---------------------------------------------------------------------------
74
+ function emitJob(deps, id) {
75
+ const job = deps.state.job(id);
76
+ if (job)
77
+ deps.emit('audio:job', { job });
78
+ }
79
+ /** Move a job to `phase` (and to `generating` with it), never out of a terminal state. */
80
+ export function setJobPhase(deps, id, phase) {
81
+ let changed = false;
82
+ deps.state.updateJob(id, (job) => {
83
+ if (isTerminalAudioJobState(job.state))
84
+ return;
85
+ const now = deps.now();
86
+ job.progress = { phase, elapsedMs: now - job.createdAtMs };
87
+ if ((phase === 'generating' || phase === 'saving') && job.state === 'queued') {
88
+ job.state = 'generating';
89
+ job.startedAtMs = now;
90
+ }
91
+ changed = true;
92
+ });
93
+ if (changed)
94
+ emitJob(deps, id);
95
+ }
96
+ /** Move a job to a terminal state exactly once. Whether this call made the transition. */
97
+ export function finishAudioJob(deps, id, result) {
98
+ let transitioned = false;
99
+ deps.state.updateJob(id, (job) => {
100
+ if (isTerminalAudioJobState(job.state))
101
+ return;
102
+ transitioned = true;
103
+ const now = deps.now();
104
+ job.finishedAtMs = now;
105
+ if (job.progress)
106
+ job.progress = { ...job.progress, elapsedMs: now - job.createdAtMs };
107
+ if (result.ok) {
108
+ job.state = 'completed';
109
+ job.output = result.item;
110
+ delete job.error;
111
+ }
112
+ else {
113
+ job.state = result.error.code === 'CANCELLED' ? 'cancelled' : 'failed';
114
+ job.error = result.error;
115
+ }
116
+ });
117
+ if (transitioned) {
118
+ if (deps.state.activeJobId === id)
119
+ deps.state.activeJobId = undefined;
120
+ emitJob(deps, id);
121
+ }
122
+ return transitioned;
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Entry points
126
+ // ---------------------------------------------------------------------------
127
+ /** Validate, register and start a job in `mode` on the loaded model. */
128
+ export async function startAudioJob(deps, mode, request) {
129
+ const { state } = deps;
130
+ if (state.closing)
131
+ throw audioError('ENGINE_CRASHED', 'The audio engine is shutting down.');
132
+ const spec = state.spec;
133
+ if (!spec)
134
+ throw modelNotLoadedError();
135
+ if (spec.mode !== mode)
136
+ throw audioError('UNSUPPORTED_MODE', `The loaded model makes ${MODE_WORDS[spec.mode]}, not ${MODE_WORDS[mode]}.`, `${spec.modelId}: ${spec.mode}`);
137
+ if (request.text.trim() === '')
138
+ throw audioError('INVALID_REQUEST', 'Say what to make.');
139
+ const busy = () => {
140
+ if (state.activeJobId !== undefined)
141
+ throw audioError('JOB_BUSY', 'Another clip is being made. Wait for it, or stop it.', state.activeJobId);
142
+ };
143
+ busy();
144
+ const speech = mode === 'speech';
145
+ if (speech && request.voiceRef === undefined && state.capabilities?.requiresVoiceRef === true)
146
+ throw audioError('INVALID_REQUEST', 'This voice model speaks only in a cloned voice: add a reference voice.');
147
+ const voiceRef = speech && request.voiceRef !== undefined
148
+ ? await resolveVoiceRef(request.voiceRef, deps.readSource)
149
+ : undefined;
150
+ // Reading the reference took a moment: another job may have started meanwhile.
151
+ busy();
152
+ const id = randomUUID().replaceAll('-', '');
153
+ state.activeJobId = id;
154
+ state.clearIdle();
155
+ const createdAtMs = deps.now();
156
+ const record = {
157
+ job: {
158
+ id,
159
+ state: 'queued',
160
+ mode,
161
+ modelId: spec.modelId,
162
+ request: withoutInlineAudio(request),
163
+ createdAtMs,
164
+ progress: { phase: 'queued', elapsedMs: 0 },
165
+ output: null,
166
+ },
167
+ cancel: { requested: false, abort: new AbortController() },
168
+ };
169
+ state.insertJob(record);
170
+ emitJob(deps, id);
171
+ const done = execute(deps, id, mode, request, voiceRef, record).then((outcome) => {
172
+ finishAudioJob(deps, id, { ok: true, item: outcome.item });
173
+ state.touchIdle();
174
+ const job = state.job(id);
175
+ return { ok: true, outcome: { job, item: outcome.item, wav: outcome.wav } };
176
+ }, (raw) => {
177
+ const error = audioErrorBody(raw);
178
+ finishAudioJob(deps, id, { ok: false, error });
179
+ state.touchIdle();
180
+ if (error.code !== 'CANCELLED')
181
+ emitAudioError(deps, id, error);
182
+ // The record is authoritative: a cancel that raced the runner may already have marked it.
183
+ return { ok: false, error: state.job(id)?.error ?? error };
184
+ });
185
+ record.done = done;
186
+ return { job: state.job(id), done };
187
+ }
188
+ /** Run one job to completion; the path a caller that awaits the clip takes. */
189
+ export async function runAudioJob(deps, mode, request) {
190
+ const { done } = await startAudioJob(deps, mode, request);
191
+ const result = await done;
192
+ if (result.ok)
193
+ return result.outcome;
194
+ throw audioError(result.error.code, result.error.message, result.error.details);
195
+ }
196
+ /** The resident session, respawned from the kept spec when a cancel or a crash took the server down. */
197
+ async function ensureSession(deps, id, record) {
198
+ const { state } = deps;
199
+ const view = () => {
200
+ const session = state.session;
201
+ return session && session.server.exitStatus() === undefined
202
+ ? { baseUrl: session.baseUrl, spec: session.spec, server: session.server }
203
+ : undefined;
204
+ };
205
+ const alive = view();
206
+ if (alive)
207
+ return alive;
208
+ if (record.cancel.requested)
209
+ throw cancelledError();
210
+ setJobPhase(deps, id, 'loading');
211
+ await deps.loadLock.run(async () => {
212
+ // Once the lock is held the job may be cancelled, the model unloaded or replaced, or the server
213
+ // already back: the spec is read only now.
214
+ if (record.cancel.requested)
215
+ throw cancelledError();
216
+ if (state.closing)
217
+ throw audioError('ENGINE_CRASHED', 'The audio engine is shutting down.');
218
+ if (view())
219
+ return;
220
+ const current = state.spec;
221
+ if (!current)
222
+ throw modelNotLoadedError();
223
+ await takeDownSession(deps);
224
+ await loadFromSpec(deps, current, 'respawn', record.cancel.abort.signal);
225
+ });
226
+ const back = view();
227
+ if (!back)
228
+ throw audioError('ENGINE_CRASHED', 'The audio engine went away right after starting.');
229
+ return back;
230
+ }
231
+ async function execute(deps, id, mode, request, voiceRef, record) {
232
+ const { state, timings } = deps;
233
+ const seed = request.seed !== undefined && request.seed >= 0 ? request.seed : deps.drawSeed();
234
+ const view = await ensureSession(deps, id, record);
235
+ if (record.cancel.requested)
236
+ throw cancelledError();
237
+ const speech = mode === 'speech';
238
+ const body = speech
239
+ ? buildSpeechBody(view.spec.modelId, request, seed, voiceRef)
240
+ : buildTaskBody(view.spec.modelId, request, seed);
241
+ setJobPhase(deps, id, 'generating');
242
+ const started = deps.now();
243
+ let response;
244
+ try {
245
+ response = await deps.http.post(`${view.baseUrl}${speech ? SPEECH_PATH : TASK_PATH}`, body, {
246
+ timeoutMs: timings.generationCeilingMs,
247
+ signal: record.cancel.abort.signal,
248
+ });
249
+ }
250
+ catch (error) {
251
+ return afterTransportError(deps, record, view, error);
252
+ }
253
+ const durationMs = deps.now() - started;
254
+ if (record.cancel.requested)
255
+ throw cancelledError();
256
+ if (response.status === 503)
257
+ throw audioError('JOB_BUSY', 'The audio engine is busy with another request.', engineErrorMessage(response.body.toString('utf8')));
258
+ if (response.status !== 200)
259
+ throw engineRejection(response.status, response.body.toString('utf8'));
260
+ const wav = speech ? response.body : decodeTaskAudio(response.body);
261
+ if (!parseWav(wav))
262
+ throw audioError('INVALID_OUTPUT', 'The audio engine returned something that is not a WAV.', response.contentType);
263
+ setJobPhase(deps, id, 'saving');
264
+ if (record.cancel.requested)
265
+ throw cancelledError();
266
+ const options = extraOptions(mode, request);
267
+ if (speech && request.instruct !== undefined)
268
+ options['instruct'] = request.instruct;
269
+ const recipe = buildAudioRecipe({
270
+ jobId: id,
271
+ request,
272
+ spec: view.spec,
273
+ seed,
274
+ options,
275
+ createdAtMs: record.job.createdAtMs,
276
+ durationMs,
277
+ });
278
+ const item = await deps.gallery.save(state.outputDir(), recipe, wav);
279
+ return { item, wav };
280
+ }
281
+ /**
282
+ * The request to the engine failed without an answer. A cancel is a cancel; past the ceiling the
283
+ * server is stopped; otherwise the server crashed or dropped the connection, and is stopped too —
284
+ * keeping the spec, so the next job brings it back.
285
+ */
286
+ async function afterTransportError(deps, record, view, raw) {
287
+ if (record.cancel.requested)
288
+ throw cancelledError();
289
+ const reason = raw instanceof Error ? raw.message : String(raw);
290
+ const ours = () => deps.state.session?.server === view.server;
291
+ if (raw instanceof AudioTimeoutError) {
292
+ const error = audioInternalError(`Generation exceeded ${Math.round(deps.timings.generationCeilingMs / 3_600_000)} hours and was stopped.`, reason);
293
+ if (ours())
294
+ await stopKeepingSpec(deps, 'timeout', audioErrorBody(error));
295
+ throw error;
296
+ }
297
+ const exit = view.server.exitStatus() ??
298
+ (await Promise.race([view.server.exited, deps.sleep(deps.timings.exitWaitMs).then(() => undefined)]));
299
+ const error = exit
300
+ ? audioCrashError(exit, view.server.tail())
301
+ : audioError('ENGINE_CRASHED', 'The audio engine dropped the connection while generating.', reason);
302
+ deps.log('warn', `audio job failed: ${error.message} (${error.details ?? reason})`);
303
+ if (ours())
304
+ await stopKeepingSpec(deps, 'crashed', audioErrorBody(error));
305
+ throw error;
306
+ }
307
+ // ---------------------------------------------------------------------------
308
+ // Cancel
309
+ // ---------------------------------------------------------------------------
310
+ /**
311
+ * Cancel a job. While the engine generates, the request is aborted and the server stopped (the spec
312
+ * stays, so the next job respawns it); a clip already being saved is kept. Before that the job ends
313
+ * here and now: its runner may be waiting for the load lock to respawn the server, and the caller may
314
+ * hold that lock (a load, an unload, an engine update), so nothing here waits for the runner then.
315
+ */
316
+ export async function cancelAudioJob(deps, id) {
317
+ const { state } = deps;
318
+ const record = state.record(id);
319
+ if (!record)
320
+ throw audioError('JOB_NOT_FOUND', 'That job no longer exists.');
321
+ if (isTerminalAudioJobState(record.job.state))
322
+ return { cancelled: record.job.state === 'cancelled', serverStopped: false };
323
+ record.cancel.requested = true;
324
+ const generating = record.job.progress?.phase === 'generating';
325
+ record.cancel.abort.abort();
326
+ if (generating) {
327
+ deps.log('info', 'cancelling an audio job: stopping audiocpp_server, which cannot interrupt a request');
328
+ await stopKeepingSpec(deps, 'cancelled');
329
+ finishAudioJob(deps, id, { ok: false, error: audioErrorBody(cancelledError()) });
330
+ return { cancelled: true, serverStopped: true };
331
+ }
332
+ if (record.job.progress?.phase === 'saving') {
333
+ // The engine has answered and the clip is being written, which needs no lock.
334
+ await record.done;
335
+ return { cancelled: state.job(id)?.state === 'cancelled', serverStopped: false };
336
+ }
337
+ finishAudioJob(deps, id, { ok: false, error: audioErrorBody(cancelledError()) });
338
+ return { cancelled: true, serverStopped: false };
339
+ }
340
+ //# sourceMappingURL=jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/audio/jobs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The models the client downloads into `<data>/audio/models` (the core never downloads one: ADR
3
+ * 2026-10-15-core-does-not-download-models): listed recursively without in-flight downloads, and
4
+ * deleted one file at a time by their path relative to that folder. The listing is image generation's.
5
+ */
6
+ import type { AudioModelFile } from '../contracts/index.js';
7
+ /** Regular files under the models root, recursively, with `/`-separated relative paths. */
8
+ export declare function listAudioModelFiles(modelsRoot: string): Promise<AudioModelFile[]>;
9
+ /** The absolute path of a file named relative to the models root; anything that leaves it is refused. */
10
+ export declare function audioModelFilePath(modelsRoot: string, relativePath: string, platform?: NodeJS.Platform): Promise<string>;
11
+ /** Delete one file under the models root, and the folders it leaves empty. A file already gone is not an error. */
12
+ export declare function deleteAudioModelFile(modelsRoot: string, path: string, platform?: NodeJS.Platform): Promise<void>;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The models the client downloads into `<data>/audio/models` (the core never downloads one: ADR
3
+ * 2026-10-15-core-does-not-download-models): listed recursively without in-flight downloads, and
4
+ * deleted one file at a time by their path relative to that folder. The listing is image generation's.
5
+ */
6
+ import { readdir, rm, rmdir, stat } from 'node:fs/promises';
7
+ import { dirname, isAbsolute, join } from 'node:path';
8
+ import { listModelFiles, locate } from '../diffusion/index.js';
9
+ import { audioError, audioIoError } from './errors.js';
10
+ /** Regular files under the models root, recursively, with `/`-separated relative paths. */
11
+ export function listAudioModelFiles(modelsRoot) {
12
+ return listModelFiles(modelsRoot);
13
+ }
14
+ /** The absolute path of a file named relative to the models root; anything that leaves it is refused. */
15
+ export async function audioModelFilePath(modelsRoot, relativePath, platform = process.platform) {
16
+ const segments = relativePath.split(/[\\/]/).filter(Boolean);
17
+ if (relativePath.trim() === '' || isAbsolute(relativePath) || /^[A-Za-z]:/.test(relativePath))
18
+ throw audioError('INVALID_REQUEST', 'Name the model file relative to the audio models folder.', relativePath);
19
+ const path = join(modelsRoot, ...segments);
20
+ if ((await locate(path, modelsRoot, platform)) !== 'inside')
21
+ throw audioError('INVALID_REQUEST', 'That file is not in the audio models folder.', relativePath);
22
+ return path;
23
+ }
24
+ const isEmptyDir = (dir) => readdir(dir).then((names) => names.length === 0, () => false);
25
+ /** Delete one file under the models root, and the folders it leaves empty. A file already gone is not an error. */
26
+ export async function deleteAudioModelFile(modelsRoot, path, platform = process.platform) {
27
+ const meta = await stat(path).catch(() => undefined);
28
+ if (!meta)
29
+ return;
30
+ if (meta.isDirectory())
31
+ throw audioError('INVALID_REQUEST', 'That path is a folder, not a model file.', path);
32
+ await rm(path).catch((error) => {
33
+ throw audioIoError('Could not delete the model file.', error);
34
+ });
35
+ // Prune empty folders on the way up, never the root itself.
36
+ for (let dir = dirname(path);; dir = dirname(dir)) {
37
+ if ((await locate(dir, modelsRoot, platform)) !== 'inside' || !(await isEmptyDir(dir)))
38
+ break;
39
+ await rmdir(dir).catch(() => { });
40
+ }
41
+ }
42
+ //# sourceMappingURL=model-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-files.js","sourceRoot":"","sources":["../../src/audio/model-files.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEtD,2FAA2F;AAC3F,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,OAAO,cAAc,CAAC,UAAU,CAAC,CAAA;AACnC,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB,EAClB,YAAoB,EACpB,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC5D,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;QAC3F,MAAM,UAAU,CACd,iBAAiB,EACjB,0DAA0D,EAC1D,YAAY,CACb,CAAA;IACH,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC,CAAA;IAC1C,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,QAAQ;QACzD,MAAM,UAAU,CAAC,iBAAiB,EAAE,8CAA8C,EAAE,YAAY,CAAC,CAAA;IACnG,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAoB,EAAE,CACnD,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CACf,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAC7B,GAAG,EAAE,CAAC,KAAK,CACZ,CAAA;AAEH,mHAAmH;AACnH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,IAAY,EACZ,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IACpD,IAAI,CAAC,IAAI;QAAE,OAAM;IACjB,IAAI,IAAI,CAAC,WAAW,EAAE;QACpB,MAAM,UAAU,CAAC,iBAAiB,EAAE,0CAA0C,EAAE,IAAI,CAAC,CAAA;IACvF,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACtC,MAAM,YAAY,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IACF,4DAA4D;IAC5D,KAAK,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,MAAK;QAC7F,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAClC,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * What `audiocpp_server --log` prints, read: the model facts it traces while it loads, why it died,
3
+ * and the engine's own error message in an HTTP answer. Pure.
4
+ *
5
+ * audio.cpp reports no progress while it generates (only family-specific `[TIMING …]` lines), so
6
+ * nothing here tracks a job: a job moves through phases only.
7
+ */
8
+ import type { AtomicCoreError } from '../contracts/index.js';
9
+ import type { ExitInfo } from '../runtime/llamacpp/index.js';
10
+ /** What the loader said about the model: `runtime.model.variant` and `supports_speaker_reference`. */
11
+ export interface AudioModelFacts {
12
+ /** e.g. `0b6-base` (Qwen3-TTS Base), `Kokoro 82M`, `small` (Stable Audio). */
13
+ variant?: string;
14
+ supportsSpeakerReference?: boolean;
15
+ }
16
+ /** Fold one output line into `facts`; lines that say nothing about the model leave it as it is. */
17
+ export declare function readModelFact(facts: AudioModelFacts, line: string): void;
18
+ /** Whether a server that exited while starting did so because its port was taken. */
19
+ export declare function exitedOnTakenAudioPort(details: string | undefined): boolean;
20
+ /** How an exit reads in a message: `code 1`, `signal SIGKILL`, or `unknown status`. */
21
+ export declare function describeAudioExit(exit: ExitInfo): string;
22
+ /** The error for a server that died before it listened: out of memory when ggml said so. */
23
+ export declare function audioEarlyExitError(exit: ExitInfo, tail: readonly string[]): AtomicCoreError;
24
+ /** The error for a server that died while it generated. */
25
+ export declare function audioCrashError(exit: ExitInfo, tail: readonly string[]): AtomicCoreError;
26
+ /**
27
+ * The engine's words in an error answer: `{"error":{"message"}}` as audio.cpp writes it, a bare
28
+ * `{"error":"…"}`, or the body itself when it is not JSON. At most 1000 characters.
29
+ */
30
+ export declare function engineErrorMessage(body: string): string;
31
+ /** A refusal the engine sent while it ran a job, on the closest code: out of memory, or rejected. */
32
+ export declare function engineRejection(status: number, body: string): AtomicCoreError;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * What `audiocpp_server --log` prints, read: the model facts it traces while it loads, why it died,
3
+ * and the engine's own error message in an HTTP answer. Pure.
4
+ *
5
+ * audio.cpp reports no progress while it generates (only family-specific `[TIMING …]` lines), so
6
+ * nothing here tracks a job: a job moves through phases only.
7
+ */
8
+ import { classifyExit, diagnosticTail } from '../diffusion/index.js';
9
+ import { audioError } from './errors.js';
10
+ /** `[TRACE ts=…] runtime.model.<key> <value>`: the facts the loader traces about the model. */
11
+ const MODEL_FACT = /\]\s+runtime\.model\.(variant|supports_speaker_reference)\s+(.*)$/;
12
+ /** What `audiocpp_server` prints when its port was taken before it could bind it. */
13
+ const PORT_TAKEN = /could not bind|address already in use|EADDRINUSE/i;
14
+ /** Fold one output line into `facts`; lines that say nothing about the model leave it as it is. */
15
+ export function readModelFact(facts, line) {
16
+ const match = MODEL_FACT.exec(line);
17
+ if (!match)
18
+ return;
19
+ const value = (match[2] ?? '').trim();
20
+ if (match[1] === 'variant')
21
+ facts.variant = value;
22
+ else
23
+ facts.supportsSpeakerReference = value === '1' || value.toLowerCase() === 'true';
24
+ }
25
+ /** Whether a server that exited while starting did so because its port was taken. */
26
+ export function exitedOnTakenAudioPort(details) {
27
+ return details !== undefined && PORT_TAKEN.test(details);
28
+ }
29
+ /** How an exit reads in a message: `code 1`, `signal SIGKILL`, or `unknown status`. */
30
+ export function describeAudioExit(exit) {
31
+ if (exit.code !== null)
32
+ return `code ${exit.code}`;
33
+ if (exit.signal !== null)
34
+ return `signal ${String(exit.signal)}`;
35
+ return 'unknown status';
36
+ }
37
+ /** The exit code, or `128 + signal` for a signal the classifier knows by number (SIGKILL → 137). */
38
+ function exitCodeOf(exit) {
39
+ if (exit.code !== null)
40
+ return exit.code;
41
+ if (typeof exit.signal === 'number')
42
+ return 128 + exit.signal;
43
+ if (exit.signal === 'SIGKILL')
44
+ return 137;
45
+ return undefined;
46
+ }
47
+ /** The error for a server that died before it listened: out of memory when ggml said so. */
48
+ export function audioEarlyExitError(exit, tail) {
49
+ const text = diagnosticTail(tail);
50
+ if (classifyExit(text, exitCodeOf(exit)) === 'OUT_OF_MEMORY')
51
+ return audioError('OUT_OF_MEMORY', 'The audio model ran out of memory while loading.', text);
52
+ return audioError('MODEL_LOAD_FAILED', `audiocpp_server exited with ${describeAudioExit(exit)} while loading.`, text);
53
+ }
54
+ /** The error for a server that died while it generated. */
55
+ export function audioCrashError(exit, tail) {
56
+ const text = diagnosticTail(tail);
57
+ if (classifyExit(text, exitCodeOf(exit)) === 'OUT_OF_MEMORY')
58
+ return audioError('OUT_OF_MEMORY', 'The audio engine ran out of memory while generating.', text);
59
+ return audioError('ENGINE_CRASHED', `The audio engine stopped while generating (${describeAudioExit(exit)}).`, text);
60
+ }
61
+ /**
62
+ * The engine's words in an error answer: `{"error":{"message"}}` as audio.cpp writes it, a bare
63
+ * `{"error":"…"}`, or the body itself when it is not JSON. At most 1000 characters.
64
+ */
65
+ export function engineErrorMessage(body) {
66
+ let message;
67
+ try {
68
+ const parsed = JSON.parse(body);
69
+ const error = parsed?.error;
70
+ if (typeof error === 'string')
71
+ message = error;
72
+ else if (error !== null && typeof error === 'object') {
73
+ const inner = error.message;
74
+ if (typeof inner === 'string')
75
+ message = inner;
76
+ }
77
+ else if (typeof parsed?.message === 'string')
78
+ message = parsed.message;
79
+ }
80
+ catch {
81
+ // Not JSON: the body is the message.
82
+ }
83
+ return [...(message ?? body).trim()].slice(0, 1000).join('');
84
+ }
85
+ /** A refusal the engine sent while it ran a job, on the closest code: out of memory, or rejected. */
86
+ export function engineRejection(status, body) {
87
+ const message = engineErrorMessage(body);
88
+ const details = message === '' ? `HTTP ${status}` : message;
89
+ if (classifyExit(message, undefined) === 'OUT_OF_MEMORY')
90
+ return audioError('OUT_OF_MEMORY', 'The audio engine ran out of memory while generating.', details);
91
+ return audioError('REQUEST_REJECTED', 'The audio engine refused the request.', details);
92
+ }
93
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/audio/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Request bodies of the audio routes, read strictly: closed enums, finite numbers, `null` taken as
3
+ * absent for anything optional, unknown fields ignored. A body that does not fit is `INVALID_REQUEST`,
4
+ * and nothing downstream has to doubt a type again (as image generation's `parse.ts`).
5
+ */
6
+ import type { AudioConfig, AudioGalleryListOptions, AudioGenerateRequest, AudioJobSubmission, AudioMode, LoadAudioModelRequest } from '../contracts/index.js';
7
+ export declare function parseAudioMode(value: unknown): AudioMode;
8
+ export declare function parseAudioConfig(body: unknown): AudioConfig;
9
+ export declare function parseLoadAudioModelRequest(body: unknown): LoadAudioModelRequest;
10
+ export declare function parseAudioGenerateRequest(body: unknown): AudioGenerateRequest;
11
+ /** `POST /audio/jobs`: `{mode, request}`. */
12
+ export declare function parseAudioJobSubmission(body: unknown): AudioJobSubmission;
13
+ export declare function parseAudioGalleryListOptions(body: unknown): AudioGalleryListOptions;
14
+ /** One required string out of a body, for the routes that take nothing else (`path`, `relativePath`). */
15
+ export declare function requireAudioString(body: unknown, key: string): string;