@elizaos/plugin-local-inference 2.0.0-beta.1 → 2.0.3-beta.2

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 (701) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/package.json +82 -15
  4. package/src/actions/generate-media.d.ts +59 -0
  5. package/src/actions/generate-media.d.ts.map +1 -0
  6. package/src/actions/generate-media.ts +647 -0
  7. package/src/actions/identify-speaker.d.ts +23 -0
  8. package/src/actions/identify-speaker.d.ts.map +1 -0
  9. package/src/actions/identify-speaker.ts +171 -0
  10. package/src/actions/transcription-control.d.ts +29 -0
  11. package/src/actions/transcription-control.d.ts.map +1 -0
  12. package/src/actions/transcription-control.test.ts +100 -0
  13. package/src/actions/transcription-control.ts +127 -0
  14. package/src/adapters/capacitor-llama/__tests__/compat-behavior.test.ts +218 -0
  15. package/src/adapters/capacitor-llama/__tests__/index.test.ts +68 -0
  16. package/src/adapters/capacitor-llama/__tests__/structured-output.test.ts +215 -0
  17. package/src/adapters/capacitor-llama/__tests__/text-streaming.test.ts +174 -0
  18. package/src/adapters/capacitor-llama/environment.ts +71 -0
  19. package/src/adapters/capacitor-llama/index.browser.ts +83 -0
  20. package/src/adapters/capacitor-llama/index.ts +807 -0
  21. package/src/adapters/capacitor-llama/loader.ts +109 -0
  22. package/src/adapters/capacitor-llama/structured-output.ts +165 -0
  23. package/src/adapters/capacitor-llama/text-streaming.ts +227 -0
  24. package/src/adapters/capacitor-llama/types.ts +374 -0
  25. package/src/backends/apple-foundation.ts +127 -0
  26. package/src/index.d.ts +8 -0
  27. package/src/index.d.ts.map +1 -0
  28. package/src/index.ts +62 -0
  29. package/src/local-inference-routes.d.ts +38 -0
  30. package/src/local-inference-routes.d.ts.map +1 -0
  31. package/src/local-inference-routes.test.ts +344 -0
  32. package/src/local-inference-routes.ts +1543 -0
  33. package/src/provider.d.ts +21 -0
  34. package/src/provider.d.ts.map +1 -0
  35. package/src/provider.ts +1082 -0
  36. package/src/routes/compat-helpers.d.ts +18 -0
  37. package/src/routes/compat-helpers.d.ts.map +1 -0
  38. package/src/routes/compat-helpers.ts +274 -0
  39. package/src/routes/family-member-route.d.ts +62 -0
  40. package/src/routes/family-member-route.d.ts.map +1 -0
  41. package/src/routes/family-member-route.ts +353 -0
  42. package/src/routes/index.d.ts +19 -0
  43. package/src/routes/index.d.ts.map +1 -0
  44. package/src/routes/index.ts +60 -0
  45. package/src/routes/live-diarization-route.d.ts +26 -0
  46. package/src/routes/live-diarization-route.d.ts.map +1 -0
  47. package/src/routes/live-diarization-route.test.ts +213 -0
  48. package/src/routes/live-diarization-route.ts +122 -0
  49. package/src/routes/local-inference-asr-route.d.ts +4 -0
  50. package/src/routes/local-inference-asr-route.d.ts.map +1 -0
  51. package/src/routes/local-inference-asr-route.test.ts +205 -0
  52. package/src/routes/local-inference-asr-route.ts +163 -0
  53. package/src/routes/local-inference-asr-transcribe.d.ts +20 -0
  54. package/src/routes/local-inference-asr-transcribe.d.ts.map +1 -0
  55. package/src/routes/local-inference-asr-transcribe.test.ts +118 -0
  56. package/src/routes/local-inference-asr-transcribe.ts +97 -0
  57. package/src/routes/local-inference-compat-routes.d.ts +16 -0
  58. package/src/routes/local-inference-compat-routes.d.ts.map +1 -0
  59. package/src/routes/local-inference-compat-routes.test.ts +485 -0
  60. package/src/routes/local-inference-compat-routes.ts +808 -0
  61. package/src/routes/local-inference-tts-route.d.ts +7 -0
  62. package/src/routes/local-inference-tts-route.d.ts.map +1 -0
  63. package/src/routes/local-inference-tts-route.test.ts +179 -0
  64. package/src/routes/local-inference-tts-route.ts +230 -0
  65. package/src/routes/transcript-audio-store.d.ts +15 -0
  66. package/src/routes/transcript-audio-store.d.ts.map +1 -0
  67. package/src/routes/transcript-audio-store.ts +27 -0
  68. package/src/routes/transcripts-routes.d.ts +36 -0
  69. package/src/routes/transcripts-routes.d.ts.map +1 -0
  70. package/src/routes/transcripts-routes.test.ts +144 -0
  71. package/src/routes/transcripts-routes.ts +159 -0
  72. package/src/routes/voice-first-run-routes.d.ts +62 -0
  73. package/src/routes/voice-first-run-routes.d.ts.map +1 -0
  74. package/src/routes/voice-first-run-routes.ts +524 -0
  75. package/src/routes/voice-models-routes.d.ts +62 -0
  76. package/src/routes/voice-models-routes.d.ts.map +1 -0
  77. package/src/routes/voice-models-routes.ts +554 -0
  78. package/src/routes/voice-profile-plugin-routes.d.ts +19 -0
  79. package/src/routes/voice-profile-plugin-routes.d.ts.map +1 -0
  80. package/src/routes/voice-profile-plugin-routes.ts +138 -0
  81. package/src/routes/voice-profiles-management-routes.d.ts +52 -0
  82. package/src/routes/voice-profiles-management-routes.d.ts.map +1 -0
  83. package/src/routes/voice-profiles-management-routes.ts +476 -0
  84. package/src/routes/voice-speaker-profile-routes.d.ts +57 -0
  85. package/src/routes/voice-speaker-profile-routes.d.ts.map +1 -0
  86. package/src/routes/voice-speaker-profile-routes.ts +199 -0
  87. package/src/runtime/aosp-llama-loader-selection.test.ts +80 -0
  88. package/src/runtime/capacitor-llama.d.ts +25 -0
  89. package/src/runtime/embedding-manager-support.d.ts +77 -0
  90. package/src/runtime/embedding-manager-support.d.ts.map +1 -0
  91. package/src/runtime/embedding-manager-support.ts +497 -0
  92. package/src/runtime/embedding-presets.d.ts +16 -0
  93. package/src/runtime/embedding-presets.d.ts.map +1 -0
  94. package/src/runtime/embedding-presets.ts +81 -0
  95. package/src/runtime/embedding-warmup-policy.d.ts +14 -0
  96. package/src/runtime/embedding-warmup-policy.d.ts.map +1 -0
  97. package/src/runtime/embedding-warmup-policy.test.ts +53 -0
  98. package/src/runtime/embedding-warmup-policy.ts +48 -0
  99. package/src/runtime/ensure-local-inference-handler.d.ts +62 -0
  100. package/src/runtime/ensure-local-inference-handler.d.ts.map +1 -0
  101. package/src/runtime/ensure-local-inference-handler.test.ts +528 -0
  102. package/src/runtime/ensure-local-inference-handler.ts +1448 -0
  103. package/src/runtime/index.d.ts +15 -0
  104. package/src/runtime/index.d.ts.map +1 -0
  105. package/src/runtime/index.ts +33 -0
  106. package/src/runtime/mobile-local-inference-gate.d.ts +31 -0
  107. package/src/runtime/mobile-local-inference-gate.d.ts.map +1 -0
  108. package/src/runtime/mobile-local-inference-gate.test.ts +69 -0
  109. package/src/runtime/mobile-local-inference-gate.ts +44 -0
  110. package/src/runtime/voice-entity-binding.d.ts +103 -0
  111. package/src/runtime/voice-entity-binding.d.ts.map +1 -0
  112. package/src/runtime/voice-entity-binding.transcript.test.ts +69 -0
  113. package/src/runtime/voice-entity-binding.ts +328 -0
  114. package/src/services/README.md +71 -0
  115. package/src/services/__tests__/backend-selector.test.ts +101 -0
  116. package/src/services/__tests__/checkpoint-manager.test.ts +376 -0
  117. package/src/services/__tests__/gpu-autotune.test.ts +400 -0
  118. package/src/services/__tests__/llm-streaming-binding.test.ts +85 -0
  119. package/src/services/__tests__/planner-grammar.test.ts +372 -0
  120. package/src/services/__tests__/runtime-target.test.ts +176 -0
  121. package/src/services/active-model-switch-rollback.test.ts +183 -0
  122. package/src/services/active-model.d.ts +282 -0
  123. package/src/services/active-model.d.ts.map +1 -0
  124. package/src/services/active-model.ts +1213 -0
  125. package/src/services/assignments.d.ts +71 -0
  126. package/src/services/assignments.d.ts.map +1 -0
  127. package/src/services/assignments.test.ts +80 -0
  128. package/src/services/assignments.ts +230 -0
  129. package/src/services/backend-selector.ts +95 -0
  130. package/src/services/backend.d.ts +346 -0
  131. package/src/services/backend.d.ts.map +1 -0
  132. package/src/services/backend.ts +612 -0
  133. package/src/services/bionic-host-loader.d.ts +46 -0
  134. package/src/services/bionic-host-loader.d.ts.map +1 -0
  135. package/src/services/bionic-host-loader.test.ts +133 -0
  136. package/src/services/bionic-host-loader.ts +180 -0
  137. package/src/services/bundled-models.d.ts +34 -0
  138. package/src/services/bundled-models.d.ts.map +1 -0
  139. package/src/services/bundled-models.ts +129 -0
  140. package/src/services/cache-bridge.d.ts +206 -0
  141. package/src/services/cache-bridge.d.ts.map +1 -0
  142. package/src/services/cache-bridge.test.ts +516 -0
  143. package/src/services/cache-bridge.ts +423 -0
  144. package/src/services/catalog.d.ts +10 -0
  145. package/src/services/catalog.d.ts.map +1 -0
  146. package/src/services/catalog.test.ts +238 -0
  147. package/src/services/catalog.ts +27 -0
  148. package/src/services/checkpoint-client.d.ts +109 -0
  149. package/src/services/checkpoint-client.d.ts.map +1 -0
  150. package/src/services/checkpoint-client.ts +258 -0
  151. package/src/services/checkpoint-manager.ts +474 -0
  152. package/src/services/cloud-fallback.d.ts +102 -0
  153. package/src/services/cloud-fallback.d.ts.map +1 -0
  154. package/src/services/cloud-fallback.ts +230 -0
  155. package/src/services/conversation-registry.d.ts +142 -0
  156. package/src/services/conversation-registry.d.ts.map +1 -0
  157. package/src/services/conversation-registry.test.ts +235 -0
  158. package/src/services/conversation-registry.ts +264 -0
  159. package/src/services/desktop-fused-ffi-backend-runtime.d.ts +95 -0
  160. package/src/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
  161. package/src/services/desktop-fused-ffi-backend-runtime.ts +339 -0
  162. package/src/services/device-bridge.d.ts +188 -0
  163. package/src/services/device-bridge.d.ts.map +1 -0
  164. package/src/services/device-bridge.ts +1237 -0
  165. package/src/services/device-resource-metrics.d.ts +149 -0
  166. package/src/services/device-resource-metrics.d.ts.map +1 -0
  167. package/src/services/device-resource-metrics.test.ts +98 -0
  168. package/src/services/device-resource-metrics.ts +346 -0
  169. package/src/services/device-tier.d.ts +115 -0
  170. package/src/services/device-tier.d.ts.map +1 -0
  171. package/src/services/device-tier.test.ts +371 -0
  172. package/src/services/device-tier.ts +410 -0
  173. package/src/services/downloader.d.ts +82 -0
  174. package/src/services/downloader.d.ts.map +1 -0
  175. package/src/services/downloader.test.ts +747 -0
  176. package/src/services/downloader.ts +925 -0
  177. package/src/services/engine-direct-bundle.test.ts +58 -0
  178. package/src/services/engine-streaming.test.ts +80 -0
  179. package/src/services/engine.d.ts +540 -0
  180. package/src/services/engine.d.ts.map +1 -0
  181. package/src/services/engine.ts +1909 -0
  182. package/src/services/ensure-local-artifacts.integration.test.ts +273 -0
  183. package/src/services/ensure-local-artifacts.test.ts +368 -0
  184. package/src/services/ensure-local-artifacts.ts +351 -0
  185. package/src/services/external-scanner.d.ts +17 -0
  186. package/src/services/external-scanner.d.ts.map +1 -0
  187. package/src/services/external-scanner.ts +312 -0
  188. package/src/services/ffi-llm-mock.ts +354 -0
  189. package/src/services/ffi-llm-streaming-abi.ts +442 -0
  190. package/src/services/ffi-streaming-backend.d.ts +180 -0
  191. package/src/services/ffi-streaming-backend.d.ts.map +1 -0
  192. package/src/services/ffi-streaming-backend.ts +382 -0
  193. package/src/services/ffi-streaming-runner.d.ts +122 -0
  194. package/src/services/ffi-streaming-runner.d.ts.map +1 -0
  195. package/src/services/ffi-streaming-runner.test.ts +60 -0
  196. package/src/services/ffi-streaming-runner.ts +354 -0
  197. package/src/services/ffi-unload-ordering.test.ts +162 -0
  198. package/src/services/gpu-autotune.ts +534 -0
  199. package/src/services/gpu-detect.d.ts +56 -0
  200. package/src/services/gpu-detect.d.ts.map +1 -0
  201. package/src/services/gpu-detect.ts +139 -0
  202. package/src/services/handler-registry.d.ts +72 -0
  203. package/src/services/handler-registry.d.ts.map +1 -0
  204. package/src/services/handler-registry.ts +240 -0
  205. package/src/services/hardware.d.ts +63 -0
  206. package/src/services/hardware.d.ts.map +1 -0
  207. package/src/services/hardware.test.ts +231 -0
  208. package/src/services/hardware.ts +410 -0
  209. package/src/services/hf-search.d.ts +26 -0
  210. package/src/services/hf-search.d.ts.map +1 -0
  211. package/src/services/hf-search.test.ts +69 -0
  212. package/src/services/hf-search.ts +420 -0
  213. package/src/services/image-description-runtime.d.ts +14 -0
  214. package/src/services/image-description-runtime.d.ts.map +1 -0
  215. package/src/services/image-description-runtime.test.ts +61 -0
  216. package/src/services/image-description-runtime.ts +118 -0
  217. package/src/services/imagegen/aosp-unavailable.d.ts +134 -0
  218. package/src/services/imagegen/aosp-unavailable.d.ts.map +1 -0
  219. package/src/services/imagegen/aosp-unavailable.ts +229 -0
  220. package/src/services/imagegen/backend-selector.d.ts +118 -0
  221. package/src/services/imagegen/backend-selector.d.ts.map +1 -0
  222. package/src/services/imagegen/backend-selector.ts +277 -0
  223. package/src/services/imagegen/coreml-unavailable.d.ts +105 -0
  224. package/src/services/imagegen/coreml-unavailable.d.ts.map +1 -0
  225. package/src/services/imagegen/coreml-unavailable.ts +237 -0
  226. package/src/services/imagegen/errors.d.ts +16 -0
  227. package/src/services/imagegen/errors.d.ts.map +1 -0
  228. package/src/services/imagegen/errors.ts +40 -0
  229. package/src/services/imagegen/index.d.ts +58 -0
  230. package/src/services/imagegen/index.d.ts.map +1 -0
  231. package/src/services/imagegen/index.ts +144 -0
  232. package/src/services/imagegen/mflux.d.ts +74 -0
  233. package/src/services/imagegen/mflux.d.ts.map +1 -0
  234. package/src/services/imagegen/mflux.ts +313 -0
  235. package/src/services/imagegen/sd-cpp.d.ts +180 -0
  236. package/src/services/imagegen/sd-cpp.d.ts.map +1 -0
  237. package/src/services/imagegen/sd-cpp.ts +718 -0
  238. package/src/services/imagegen/tensorrt-unavailable.d.ts +83 -0
  239. package/src/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
  240. package/src/services/imagegen/tensorrt-unavailable.ts +295 -0
  241. package/src/services/imagegen/types.d.ts +181 -0
  242. package/src/services/imagegen/types.d.ts.map +1 -0
  243. package/src/services/imagegen/types.ts +193 -0
  244. package/src/services/index.d.ts +29 -0
  245. package/src/services/index.d.ts.map +1 -0
  246. package/src/services/index.ts +211 -0
  247. package/src/services/inference-capabilities.d.ts +132 -0
  248. package/src/services/inference-capabilities.d.ts.map +1 -0
  249. package/src/services/inference-capabilities.test.ts +75 -0
  250. package/src/services/inference-capabilities.ts +204 -0
  251. package/src/services/inference-telemetry.d.ts +59 -0
  252. package/src/services/inference-telemetry.d.ts.map +1 -0
  253. package/src/services/inference-telemetry.ts +143 -0
  254. package/src/services/ios-llama-streaming.ts +248 -0
  255. package/src/services/kv-spill.d.ts +189 -0
  256. package/src/services/kv-spill.d.ts.map +1 -0
  257. package/src/services/kv-spill.test.ts +222 -0
  258. package/src/services/kv-spill.ts +356 -0
  259. package/src/services/latency-trace.d.ts +346 -0
  260. package/src/services/latency-trace.d.ts.map +1 -0
  261. package/src/services/latency-trace.test.ts +266 -0
  262. package/src/services/latency-trace.ts +844 -0
  263. package/src/services/llama-server-metrics.ts +304 -0
  264. package/src/services/llm-streaming-binding.d.ts +96 -0
  265. package/src/services/llm-streaming-binding.d.ts.map +1 -0
  266. package/src/services/llm-streaming-binding.ts +136 -0
  267. package/src/services/load-args.d.ts +82 -0
  268. package/src/services/load-args.d.ts.map +1 -0
  269. package/src/services/load-args.ts +81 -0
  270. package/src/services/manifest/eliza-1.manifest.v1.json +708 -0
  271. package/src/services/manifest/index.d.ts +4 -0
  272. package/src/services/manifest/index.d.ts.map +1 -0
  273. package/src/services/manifest/index.ts +66 -0
  274. package/src/services/manifest/manifest.test.ts +689 -0
  275. package/src/services/manifest/schema.d.ts +713 -0
  276. package/src/services/manifest/schema.d.ts.map +1 -0
  277. package/src/services/manifest/schema.ts +653 -0
  278. package/src/services/manifest/types.d.ts +30 -0
  279. package/src/services/manifest/types.d.ts.map +1 -0
  280. package/src/services/manifest/types.ts +55 -0
  281. package/src/services/manifest/validator.d.ts +66 -0
  282. package/src/services/manifest/validator.d.ts.map +1 -0
  283. package/src/services/manifest/validator.ts +567 -0
  284. package/src/services/memory-arbiter.d.ts +318 -0
  285. package/src/services/memory-arbiter.d.ts.map +1 -0
  286. package/src/services/memory-arbiter.test.ts +419 -0
  287. package/src/services/memory-arbiter.ts +925 -0
  288. package/src/services/memory-monitor.d.ts +122 -0
  289. package/src/services/memory-monitor.d.ts.map +1 -0
  290. package/src/services/memory-monitor.test.ts +208 -0
  291. package/src/services/memory-monitor.ts +297 -0
  292. package/src/services/memory-pressure.d.ts +130 -0
  293. package/src/services/memory-pressure.d.ts.map +1 -0
  294. package/src/services/memory-pressure.ts +414 -0
  295. package/src/services/mtp-doctor.d.ts +13 -0
  296. package/src/services/mtp-doctor.d.ts.map +1 -0
  297. package/src/services/mtp-doctor.ts +78 -0
  298. package/src/services/network-policy.d.ts +127 -0
  299. package/src/services/network-policy.d.ts.map +1 -0
  300. package/src/services/network-policy.ts +346 -0
  301. package/src/services/paths.d.ts +6 -0
  302. package/src/services/paths.d.ts.map +1 -0
  303. package/src/services/paths.ts +25 -0
  304. package/src/services/planner-skeleton.d.ts +124 -0
  305. package/src/services/planner-skeleton.d.ts.map +1 -0
  306. package/src/services/planner-skeleton.ts +175 -0
  307. package/src/services/providers.d.ts +38 -0
  308. package/src/services/providers.d.ts.map +1 -0
  309. package/src/services/providers.ts +507 -0
  310. package/src/services/ram-budget-cache.test.ts +163 -0
  311. package/src/services/ram-budget.d.ts +110 -0
  312. package/src/services/ram-budget.d.ts.map +1 -0
  313. package/src/services/ram-budget.ts +0 -0
  314. package/src/services/readiness.d.ts +9 -0
  315. package/src/services/readiness.d.ts.map +1 -0
  316. package/src/services/readiness.test.ts +87 -0
  317. package/src/services/readiness.ts +238 -0
  318. package/src/services/recommendation.d.ts +111 -0
  319. package/src/services/recommendation.d.ts.map +1 -0
  320. package/src/services/recommendation.ts +671 -0
  321. package/src/services/registry.d.ts +35 -0
  322. package/src/services/registry.d.ts.map +1 -0
  323. package/src/services/registry.ts +151 -0
  324. package/src/services/router-handler.d.ts +92 -0
  325. package/src/services/router-handler.d.ts.map +1 -0
  326. package/src/services/router-handler.test.ts +45 -0
  327. package/src/services/router-handler.ts +407 -0
  328. package/src/services/routing-policy.d.ts +69 -0
  329. package/src/services/routing-policy.d.ts.map +1 -0
  330. package/src/services/routing-policy.test.ts +164 -0
  331. package/src/services/routing-policy.ts +297 -0
  332. package/src/services/routing-preferences.d.ts +8 -0
  333. package/src/services/routing-preferences.d.ts.map +1 -0
  334. package/src/services/routing-preferences.ts +17 -0
  335. package/src/services/runtime-target.d.ts +98 -0
  336. package/src/services/runtime-target.d.ts.map +1 -0
  337. package/src/services/runtime-target.ts +154 -0
  338. package/src/services/service.d.ts +128 -0
  339. package/src/services/service.d.ts.map +1 -0
  340. package/src/services/service.test.ts +223 -0
  341. package/src/services/service.ts +735 -0
  342. package/src/services/session-pool.d.ts +72 -0
  343. package/src/services/session-pool.d.ts.map +1 -0
  344. package/src/services/session-pool.ts +153 -0
  345. package/src/services/structured-output/deterministic-repair.d.ts +23 -0
  346. package/src/services/structured-output/deterministic-repair.d.ts.map +1 -0
  347. package/src/services/structured-output/deterministic-repair.test.ts +169 -0
  348. package/src/services/structured-output/deterministic-repair.ts +443 -0
  349. package/src/services/structured-output/index.ts +4 -0
  350. package/src/services/structured-output.d.ts +311 -0
  351. package/src/services/structured-output.d.ts.map +1 -0
  352. package/src/services/structured-output.test.ts +483 -0
  353. package/src/services/structured-output.ts +712 -0
  354. package/src/services/system-memory.d.ts +33 -0
  355. package/src/services/system-memory.d.ts.map +1 -0
  356. package/src/services/system-memory.test.ts +47 -0
  357. package/src/services/system-memory.ts +67 -0
  358. package/src/services/transcription-priority.test.ts +211 -0
  359. package/src/services/types.d.ts +19 -0
  360. package/src/services/types.d.ts.map +1 -0
  361. package/src/services/types.ts +55 -0
  362. package/src/services/verify-on-device.d.ts +34 -0
  363. package/src/services/verify-on-device.d.ts.map +1 -0
  364. package/src/services/verify-on-device.test.ts +87 -0
  365. package/src/services/verify-on-device.ts +127 -0
  366. package/src/services/verify.d.ts +8 -0
  367. package/src/services/verify.d.ts.map +1 -0
  368. package/src/services/verify.ts +13 -0
  369. package/src/services/vision/aosp-unavailable.d.ts +115 -0
  370. package/src/services/vision/aosp-unavailable.d.ts.map +1 -0
  371. package/src/services/vision/aosp-unavailable.ts +163 -0
  372. package/src/services/vision/capacitor-llama.d.ts +99 -0
  373. package/src/services/vision/capacitor-llama.d.ts.map +1 -0
  374. package/src/services/vision/capacitor-llama.ts +255 -0
  375. package/src/services/vision/cloud-fallback.d.ts +47 -0
  376. package/src/services/vision/cloud-fallback.d.ts.map +1 -0
  377. package/src/services/vision/cloud-fallback.test.ts +243 -0
  378. package/src/services/vision/cloud-fallback.ts +268 -0
  379. package/src/services/vision/fallback-chain.test.ts +86 -0
  380. package/src/services/vision/hash.d.ts +71 -0
  381. package/src/services/vision/hash.d.ts.map +1 -0
  382. package/src/services/vision/hash.ts +157 -0
  383. package/src/services/vision/index.d.ts +95 -0
  384. package/src/services/vision/index.d.ts.map +1 -0
  385. package/src/services/vision/index.ts +251 -0
  386. package/src/services/vision/llama-server.d.ts +73 -0
  387. package/src/services/vision/llama-server.d.ts.map +1 -0
  388. package/src/services/vision/llama-server.ts +177 -0
  389. package/src/services/vision/types.d.ts +153 -0
  390. package/src/services/vision/types.d.ts.map +1 -0
  391. package/src/services/vision/types.ts +154 -0
  392. package/src/services/vision/vast-fallback.d.ts +18 -0
  393. package/src/services/vision/vast-fallback.d.ts.map +1 -0
  394. package/src/services/vision/vast-fallback.ts +127 -0
  395. package/src/services/vision-embedding-cache.d.ts +98 -0
  396. package/src/services/vision-embedding-cache.d.ts.map +1 -0
  397. package/src/services/vision-embedding-cache.ts +189 -0
  398. package/src/services/voice/VOICE_WORKBENCH.md +88 -0
  399. package/src/services/voice/__test-helpers__/fake-ffi.ts +94 -0
  400. package/src/services/voice/__test-helpers__/synthetic-speech.ts +124 -0
  401. package/src/services/voice/__tests__/checkpoint-manager.test.ts +241 -0
  402. package/src/services/voice/__tests__/checkpoint-policy.test.ts +270 -0
  403. package/src/services/voice/__tests__/eager-context-builder.test.ts +257 -0
  404. package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +288 -0
  405. package/src/services/voice/__tests__/eot-classifier.test.ts +431 -0
  406. package/src/services/voice/__tests__/optimistic-rollback.test.ts +312 -0
  407. package/src/services/voice/__tests__/prefill-client.test.ts +266 -0
  408. package/src/services/voice/__tests__/prefix-preserving-queue.test.ts +208 -0
  409. package/src/services/voice/__tests__/streaming-asr.test.ts +450 -0
  410. package/src/services/voice/__tests__/streaming-transcriber.test.ts +339 -0
  411. package/src/services/voice/__tests__/turn-detector-resolver.test.ts +195 -0
  412. package/src/services/voice/__tests__/voice-state-machine-prefill.test.ts +275 -0
  413. package/src/services/voice/__tests__/voice-state-machine.test.ts +354 -0
  414. package/src/services/voice/asr-timed.real.test.ts +141 -0
  415. package/src/services/voice/audio-frame-consumer.d.ts +212 -0
  416. package/src/services/voice/audio-frame-consumer.d.ts.map +1 -0
  417. package/src/services/voice/audio-frame-consumer.test.ts +343 -0
  418. package/src/services/voice/audio-frame-consumer.ts +491 -0
  419. package/src/services/voice/barge-in.d.ts +112 -0
  420. package/src/services/voice/barge-in.d.ts.map +1 -0
  421. package/src/services/voice/barge-in.test.ts +244 -0
  422. package/src/services/voice/barge-in.ts +336 -0
  423. package/src/services/voice/cancellation-coordinator.d.ts +127 -0
  424. package/src/services/voice/cancellation-coordinator.d.ts.map +1 -0
  425. package/src/services/voice/cancellation-coordinator.test.ts +196 -0
  426. package/src/services/voice/cancellation-coordinator.ts +269 -0
  427. package/src/services/voice/checkpoint-manager.d.ts +199 -0
  428. package/src/services/voice/checkpoint-manager.d.ts.map +1 -0
  429. package/src/services/voice/checkpoint-manager.ts +401 -0
  430. package/src/services/voice/checkpoint-policy.ts +336 -0
  431. package/src/services/voice/composite-eot-classifier.test.ts +59 -0
  432. package/src/services/voice/e2e-harness.test.ts +182 -0
  433. package/src/services/voice/e2e-harness.ts +743 -0
  434. package/src/services/voice/eager-context-builder.d.ts +170 -0
  435. package/src/services/voice/eager-context-builder.d.ts.map +1 -0
  436. package/src/services/voice/eager-context-builder.ts +262 -0
  437. package/src/services/voice/eliza1-eot-scorer.d.ts +124 -0
  438. package/src/services/voice/eliza1-eot-scorer.d.ts.map +1 -0
  439. package/src/services/voice/eliza1-eot-scorer.ts +242 -0
  440. package/src/services/voice/embedding-server.ts +200 -0
  441. package/src/services/voice/embedding.d.ts +133 -0
  442. package/src/services/voice/embedding.d.ts.map +1 -0
  443. package/src/services/voice/embedding.test.ts +131 -0
  444. package/src/services/voice/embedding.ts +243 -0
  445. package/src/services/voice/emotion-attribution.d.ts +68 -0
  446. package/src/services/voice/emotion-attribution.d.ts.map +1 -0
  447. package/src/services/voice/emotion-attribution.test.ts +129 -0
  448. package/src/services/voice/emotion-attribution.ts +361 -0
  449. package/src/services/voice/engine-bridge-cancellation.test.ts +422 -0
  450. package/src/services/voice/engine-bridge.d.ts +759 -0
  451. package/src/services/voice/engine-bridge.d.ts.map +1 -0
  452. package/src/services/voice/engine-bridge.test.ts +384 -0
  453. package/src/services/voice/engine-bridge.ts +2302 -0
  454. package/src/services/voice/eot-classifier-ggml.d.ts +179 -0
  455. package/src/services/voice/eot-classifier-ggml.d.ts.map +1 -0
  456. package/src/services/voice/eot-classifier-ggml.ts +566 -0
  457. package/src/services/voice/eot-classifier.d.ts +214 -0
  458. package/src/services/voice/eot-classifier.d.ts.map +1 -0
  459. package/src/services/voice/eot-classifier.ts +533 -0
  460. package/src/services/voice/errors.d.ts +20 -0
  461. package/src/services/voice/errors.d.ts.map +1 -0
  462. package/src/services/voice/errors.ts +32 -0
  463. package/src/services/voice/expressive-tags.d.ts +158 -0
  464. package/src/services/voice/expressive-tags.d.ts.map +1 -0
  465. package/src/services/voice/expressive-tags.ts +405 -0
  466. package/src/services/voice/ffi-bindings.d.ts +674 -0
  467. package/src/services/voice/ffi-bindings.d.ts.map +1 -0
  468. package/src/services/voice/ffi-bindings.test.ts +728 -0
  469. package/src/services/voice/ffi-bindings.ts +3225 -0
  470. package/src/services/voice/first-line-cache.d.ts +181 -0
  471. package/src/services/voice/first-line-cache.d.ts.map +1 -0
  472. package/src/services/voice/first-line-cache.ts +725 -0
  473. package/src/services/voice/fused-eot-scorer.d.ts +51 -0
  474. package/src/services/voice/fused-eot-scorer.d.ts.map +1 -0
  475. package/src/services/voice/fused-eot-scorer.ts +135 -0
  476. package/src/services/voice/index.d.ts +91 -0
  477. package/src/services/voice/index.d.ts.map +1 -0
  478. package/src/services/voice/index.ts +481 -0
  479. package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +151 -0
  480. package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +151 -0
  481. package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.test.ts +60 -0
  482. package/src/services/voice/kokoro/__tests__/kokoro-engine-discovery.test.ts +277 -0
  483. package/src/services/voice/kokoro/__tests__/kokoro-ffi-runtime.test.ts +235 -0
  484. package/src/services/voice/kokoro/__tests__/kokoro-runtime.test.ts +95 -0
  485. package/src/services/voice/kokoro/__tests__/phonemizer.test.ts +53 -0
  486. package/src/services/voice/kokoro/__tests__/runtime-selection.test.ts +231 -0
  487. package/src/services/voice/kokoro/__tests__/voices.test.ts +57 -0
  488. package/src/services/voice/kokoro/index.ts +79 -0
  489. package/src/services/voice/kokoro/kokoro-backend.d.ts +72 -0
  490. package/src/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
  491. package/src/services/voice/kokoro/kokoro-backend.ts +207 -0
  492. package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts +58 -0
  493. package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
  494. package/src/services/voice/kokoro/kokoro-engine-discovery.ts +177 -0
  495. package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts +75 -0
  496. package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
  497. package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +233 -0
  498. package/src/services/voice/kokoro/kokoro-runtime.d.ts +100 -0
  499. package/src/services/voice/kokoro/kokoro-runtime.d.ts.map +1 -0
  500. package/src/services/voice/kokoro/kokoro-runtime.ts +170 -0
  501. package/src/services/voice/kokoro/phoneme-stream.ts +123 -0
  502. package/src/services/voice/kokoro/phonemizer.d.ts +50 -0
  503. package/src/services/voice/kokoro/phonemizer.d.ts.map +1 -0
  504. package/src/services/voice/kokoro/phonemizer.ts +344 -0
  505. package/src/services/voice/kokoro/pick-runtime.d.ts +61 -0
  506. package/src/services/voice/kokoro/pick-runtime.d.ts.map +1 -0
  507. package/src/services/voice/kokoro/pick-runtime.test.ts +91 -0
  508. package/src/services/voice/kokoro/pick-runtime.ts +130 -0
  509. package/src/services/voice/kokoro/runtime-selection.d.ts +92 -0
  510. package/src/services/voice/kokoro/runtime-selection.d.ts.map +1 -0
  511. package/src/services/voice/kokoro/runtime-selection.ts +237 -0
  512. package/src/services/voice/kokoro/types.d.ts +82 -0
  513. package/src/services/voice/kokoro/types.d.ts.map +1 -0
  514. package/src/services/voice/kokoro/types.ts +95 -0
  515. package/src/services/voice/kokoro/voice-presets.d.ts +23 -0
  516. package/src/services/voice/kokoro/voice-presets.d.ts.map +1 -0
  517. package/src/services/voice/kokoro/voice-presets.ts +129 -0
  518. package/src/services/voice/kokoro/voices.d.ts +30 -0
  519. package/src/services/voice/kokoro/voices.d.ts.map +1 -0
  520. package/src/services/voice/kokoro/voices.ts +64 -0
  521. package/src/services/voice/lifecycle.d.ts +135 -0
  522. package/src/services/voice/lifecycle.d.ts.map +1 -0
  523. package/src/services/voice/lifecycle.test.ts +315 -0
  524. package/src/services/voice/lifecycle.ts +301 -0
  525. package/src/services/voice/live-diarization-session.d.ts +96 -0
  526. package/src/services/voice/live-diarization-session.d.ts.map +1 -0
  527. package/src/services/voice/live-diarization-session.ts +289 -0
  528. package/src/services/voice/mic-source.d.ts +136 -0
  529. package/src/services/voice/mic-source.d.ts.map +1 -0
  530. package/src/services/voice/mic-source.test.ts +210 -0
  531. package/src/services/voice/mic-source.ts +503 -0
  532. package/src/services/voice/optimistic-policy.d.ts +109 -0
  533. package/src/services/voice/optimistic-policy.d.ts.map +1 -0
  534. package/src/services/voice/optimistic-policy.test.ts +101 -0
  535. package/src/services/voice/optimistic-policy.ts +192 -0
  536. package/src/services/voice/optimistic-rollback.ts +343 -0
  537. package/src/services/voice/partial-stabilizer.d.ts +73 -0
  538. package/src/services/voice/partial-stabilizer.d.ts.map +1 -0
  539. package/src/services/voice/partial-stabilizer.test.ts +68 -0
  540. package/src/services/voice/partial-stabilizer.ts +140 -0
  541. package/src/services/voice/phoneme-tokenizer.d.ts +49 -0
  542. package/src/services/voice/phoneme-tokenizer.d.ts.map +1 -0
  543. package/src/services/voice/phoneme-tokenizer.ts +158 -0
  544. package/src/services/voice/phrase-cache.d.ts +76 -0
  545. package/src/services/voice/phrase-cache.d.ts.map +1 -0
  546. package/src/services/voice/phrase-cache.test.ts +242 -0
  547. package/src/services/voice/phrase-cache.ts +186 -0
  548. package/src/services/voice/phrase-chunker.d.ts +62 -0
  549. package/src/services/voice/phrase-chunker.d.ts.map +1 -0
  550. package/src/services/voice/phrase-chunker.test.ts +239 -0
  551. package/src/services/voice/phrase-chunker.ts +281 -0
  552. package/src/services/voice/pipeline-impls.d.ts +151 -0
  553. package/src/services/voice/pipeline-impls.d.ts.map +1 -0
  554. package/src/services/voice/pipeline-impls.l6.test.ts +110 -0
  555. package/src/services/voice/pipeline-impls.test.ts +292 -0
  556. package/src/services/voice/pipeline-impls.ts +315 -0
  557. package/src/services/voice/pipeline.d.ts +216 -0
  558. package/src/services/voice/pipeline.d.ts.map +1 -0
  559. package/src/services/voice/pipeline.ts +505 -0
  560. package/src/services/voice/prefill-client.d.ts +123 -0
  561. package/src/services/voice/prefill-client.d.ts.map +1 -0
  562. package/src/services/voice/prefill-client.ts +316 -0
  563. package/src/services/voice/prefix-preserving-queue.d.ts +113 -0
  564. package/src/services/voice/prefix-preserving-queue.d.ts.map +1 -0
  565. package/src/services/voice/prefix-preserving-queue.ts +162 -0
  566. package/src/services/voice/profile-store.d.ts +248 -0
  567. package/src/services/voice/profile-store.d.ts.map +1 -0
  568. package/src/services/voice/profile-store.ts +887 -0
  569. package/src/services/voice/real-audio-decode.test.ts +148 -0
  570. package/src/services/voice/ring-buffer.d.ts +40 -0
  571. package/src/services/voice/ring-buffer.d.ts.map +1 -0
  572. package/src/services/voice/ring-buffer.test.ts +129 -0
  573. package/src/services/voice/ring-buffer.ts +123 -0
  574. package/src/services/voice/rollback-queue.d.ts +24 -0
  575. package/src/services/voice/rollback-queue.d.ts.map +1 -0
  576. package/src/services/voice/rollback-queue.ts +74 -0
  577. package/src/services/voice/samantha-preset-placeholder.d.ts +67 -0
  578. package/src/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
  579. package/src/services/voice/samantha-preset-placeholder.test.ts +97 -0
  580. package/src/services/voice/samantha-preset-placeholder.ts +148 -0
  581. package/src/services/voice/samantha-preset-regenerator.d.ts +87 -0
  582. package/src/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
  583. package/src/services/voice/samantha-preset-regenerator.ts +393 -0
  584. package/src/services/voice/scheduler.d.ts +146 -0
  585. package/src/services/voice/scheduler.d.ts.map +1 -0
  586. package/src/services/voice/scheduler.t2.test.ts +141 -0
  587. package/src/services/voice/scheduler.ts +927 -0
  588. package/src/services/voice/shared-resources.d.ts +190 -0
  589. package/src/services/voice/shared-resources.d.ts.map +1 -0
  590. package/src/services/voice/shared-resources.ts +320 -0
  591. package/src/services/voice/speaker/attribution-pipeline.d.ts +74 -0
  592. package/src/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
  593. package/src/services/voice/speaker/attribution-pipeline.ts +386 -0
  594. package/src/services/voice/speaker/diarizer-fused.d.ts +59 -0
  595. package/src/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
  596. package/src/services/voice/speaker/diarizer-fused.real.test.ts +100 -0
  597. package/src/services/voice/speaker/diarizer-fused.ts +154 -0
  598. package/src/services/voice/speaker/diarizer.d.ts +75 -0
  599. package/src/services/voice/speaker/diarizer.d.ts.map +1 -0
  600. package/src/services/voice/speaker/diarizer.ts +218 -0
  601. package/src/services/voice/speaker/encoder-fused.d.ts +60 -0
  602. package/src/services/voice/speaker/encoder-fused.d.ts.map +1 -0
  603. package/src/services/voice/speaker/encoder-fused.real.test.ts +113 -0
  604. package/src/services/voice/speaker/encoder-fused.ts +138 -0
  605. package/src/services/voice/speaker/encoder-ggml.d.ts +33 -0
  606. package/src/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
  607. package/src/services/voice/speaker/encoder-ggml.ts +79 -0
  608. package/src/services/voice/speaker/encoder.d.ts +37 -0
  609. package/src/services/voice/speaker/encoder.d.ts.map +1 -0
  610. package/src/services/voice/speaker/encoder.ts +105 -0
  611. package/src/services/voice/speaker-imprint.d.ts +83 -0
  612. package/src/services/voice/speaker-imprint.d.ts.map +1 -0
  613. package/src/services/voice/speaker-imprint.test.ts +185 -0
  614. package/src/services/voice/speaker-imprint.ts +312 -0
  615. package/src/services/voice/speaker-preset-cache.d.ts +77 -0
  616. package/src/services/voice/speaker-preset-cache.d.ts.map +1 -0
  617. package/src/services/voice/speaker-preset-cache.test.ts +154 -0
  618. package/src/services/voice/speaker-preset-cache.ts +195 -0
  619. package/src/services/voice/streaming-asr/streaming-pipeline-adapter.ts +292 -0
  620. package/src/services/voice/system-audio-sink.d.ts +73 -0
  621. package/src/services/voice/system-audio-sink.d.ts.map +1 -0
  622. package/src/services/voice/system-audio-sink.test.ts +29 -0
  623. package/src/services/voice/system-audio-sink.ts +366 -0
  624. package/src/services/voice/transcriber.d.ts +244 -0
  625. package/src/services/voice/transcriber.d.ts.map +1 -0
  626. package/src/services/voice/transcriber.test.ts +392 -0
  627. package/src/services/voice/transcriber.ts +704 -0
  628. package/src/services/voice/transcript-knowledge.d.ts +37 -0
  629. package/src/services/voice/transcript-knowledge.d.ts.map +1 -0
  630. package/src/services/voice/transcript-knowledge.test.ts +68 -0
  631. package/src/services/voice/transcript-knowledge.ts +75 -0
  632. package/src/services/voice/transcript-service.d.ts +41 -0
  633. package/src/services/voice/transcript-service.d.ts.map +1 -0
  634. package/src/services/voice/transcript-service.test.ts +137 -0
  635. package/src/services/voice/transcript-service.ts +141 -0
  636. package/src/services/voice/transcript-store.d.ts +53 -0
  637. package/src/services/voice/transcript-store.d.ts.map +1 -0
  638. package/src/services/voice/transcript-store.test.ts +153 -0
  639. package/src/services/voice/transcript-store.ts +132 -0
  640. package/src/services/voice/turn-controller.d.ts +183 -0
  641. package/src/services/voice/turn-controller.d.ts.map +1 -0
  642. package/src/services/voice/turn-controller.test.ts +575 -0
  643. package/src/services/voice/turn-controller.ts +596 -0
  644. package/src/services/voice/types.d.ts +643 -0
  645. package/src/services/voice/types.d.ts.map +1 -0
  646. package/src/services/voice/types.ts +699 -0
  647. package/src/services/voice/vad.d.ts +282 -0
  648. package/src/services/voice/vad.d.ts.map +1 -0
  649. package/src/services/voice/vad.test.ts +480 -0
  650. package/src/services/voice/vad.ts +827 -0
  651. package/src/services/voice/vad.v1-v4.test.ts +222 -0
  652. package/src/services/voice/voice-budget.d.ts +241 -0
  653. package/src/services/voice/voice-budget.d.ts.map +1 -0
  654. package/src/services/voice/voice-budget.test.ts +418 -0
  655. package/src/services/voice/voice-budget.ts +635 -0
  656. package/src/services/voice/voice-duet.test.ts +375 -0
  657. package/src/services/voice/voice-emotion-classifier.d.ts +95 -0
  658. package/src/services/voice/voice-emotion-classifier.d.ts.map +1 -0
  659. package/src/services/voice/voice-emotion-classifier.test.ts +210 -0
  660. package/src/services/voice/voice-emotion-classifier.ts +273 -0
  661. package/src/services/voice/voice-preset-format.d.ts +158 -0
  662. package/src/services/voice/voice-preset-format.d.ts.map +1 -0
  663. package/src/services/voice/voice-preset-format.ts +700 -0
  664. package/src/services/voice/voice-preset-generator.test.ts +89 -0
  665. package/src/services/voice/voice-profile-artifact.d.ts +116 -0
  666. package/src/services/voice/voice-profile-artifact.d.ts.map +1 -0
  667. package/src/services/voice/voice-profile-artifact.test.ts +138 -0
  668. package/src/services/voice/voice-profile-artifact.ts +518 -0
  669. package/src/services/voice/voice-profile-routes.d.ts +83 -0
  670. package/src/services/voice/voice-profile-routes.d.ts.map +1 -0
  671. package/src/services/voice/voice-profile-routes.test.ts +429 -0
  672. package/src/services/voice/voice-profile-routes.ts +425 -0
  673. package/src/services/voice/voice-scenario.ts +154 -0
  674. package/src/services/voice/voice-settings.d.ts +82 -0
  675. package/src/services/voice/voice-settings.d.ts.map +1 -0
  676. package/src/services/voice/voice-settings.ts +172 -0
  677. package/src/services/voice/voice-state-machine.d.ts +364 -0
  678. package/src/services/voice/voice-state-machine.d.ts.map +1 -0
  679. package/src/services/voice/voice-state-machine.ts +727 -0
  680. package/src/services/voice/voice-workbench-report.test.ts +168 -0
  681. package/src/services/voice/voice-workbench-report.ts +326 -0
  682. package/src/services/voice/voice-workbench.test.ts +158 -0
  683. package/src/services/voice/voice.test.ts +1070 -0
  684. package/src/services/voice/wake-word-ggml.d.ts +101 -0
  685. package/src/services/voice/wake-word-ggml.d.ts.map +1 -0
  686. package/src/services/voice/wake-word-ggml.ts +320 -0
  687. package/src/services/voice/wake-word.d.ts +255 -0
  688. package/src/services/voice/wake-word.d.ts.map +1 -0
  689. package/src/services/voice/wake-word.test.ts +298 -0
  690. package/src/services/voice/wake-word.ts +554 -0
  691. package/src/services/voice/wrap-with-first-line-cache.d.ts +70 -0
  692. package/src/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
  693. package/src/services/voice/wrap-with-first-line-cache.ts +267 -0
  694. package/src/services/voice-model-updater.d.ts +240 -0
  695. package/src/services/voice-model-updater.d.ts.map +1 -0
  696. package/src/services/voice-model-updater.ts +724 -0
  697. package/src/services/voice-prewarm.d.ts +3 -0
  698. package/src/services/voice-prewarm.d.ts.map +1 -0
  699. package/src/services/voice-prewarm.ts +51 -0
  700. package/dist/index.d.ts +0 -37
  701. package/dist/index.js +0 -1098
@@ -0,0 +1,148 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { describe, expect, it } from "vitest";
5
+ import { decodeMonoPcm16Wav, encodeMonoPcm16Wav } from "./engine-bridge";
6
+
7
+ /**
8
+ * Real-audio coverage for the front of the single FFI pipe: the WAV → PCM
9
+ * decoder every transcription path feeds (`decodeMonoPcm16Wav`), exercised
10
+ * against the committed real WAV files rather than synthetic in-memory buffers.
11
+ *
12
+ * Two real corpora:
13
+ * 1. `native/verify/asr_bench_fixtures/non_publish_structure_5utt/` — five
14
+ * committed mono 16 kHz PCM16 WAVs (deterministic tones, NOT speech — see
15
+ * the corpus manifest; valid for decode/codec validation, NOT for WER).
16
+ * 2. `native/omnivoice.cpp/examples/freeman.wav` — a real 22.05 kHz speech
17
+ * recording. Lives in a git submodule, so the block is skipped when the
18
+ * submodule isn't checked out.
19
+ */
20
+
21
+ const FIXTURE_DIR = fileURLToPath(
22
+ new URL(
23
+ "../../../native/verify/asr_bench_fixtures/non_publish_structure_5utt/",
24
+ import.meta.url,
25
+ ),
26
+ );
27
+
28
+ interface FixtureManifest {
29
+ realRecorded: boolean;
30
+ files: Array<{
31
+ id: string;
32
+ reference: string;
33
+ wav: string;
34
+ txt: string;
35
+ sampleRateHz: number;
36
+ }>;
37
+ }
38
+
39
+ const manifest = JSON.parse(
40
+ readFileSync(join(FIXTURE_DIR, "manifest.json"), "utf8"),
41
+ ) as FixtureManifest;
42
+
43
+ /**
44
+ * Every decoded sample must be a finite mono amplitude in [-1, 1]. Scan in a
45
+ * plain loop and assert the AGGREGATE once — a per-sample `expect()` over a
46
+ * multi-second clip (freeman.wav is ~380k samples) is pathologically slow and
47
+ * trips the test timeout under load.
48
+ */
49
+ function assertInRangePcm(pcm: Float32Array): void {
50
+ expect(pcm.length).toBeGreaterThan(0);
51
+ let allFinite = true;
52
+ let maxAbs = 0;
53
+ for (let i = 0; i < pcm.length; i++) {
54
+ const s = pcm[i] ?? Number.NaN;
55
+ if (!Number.isFinite(s)) {
56
+ allFinite = false;
57
+ break;
58
+ }
59
+ const abs = Math.abs(s);
60
+ if (abs > maxAbs) maxAbs = abs;
61
+ }
62
+ expect(allFinite).toBe(true);
63
+ expect(maxAbs).toBeLessThanOrEqual(1);
64
+ }
65
+
66
+ describe("decodeMonoPcm16Wav — committed fixture corpus (real WAV files)", () => {
67
+ it("decodes every fixture to in-range mono PCM at the manifest sample rate", () => {
68
+ expect(manifest.files.length).toBeGreaterThanOrEqual(5);
69
+ for (const f of manifest.files) {
70
+ const bytes = new Uint8Array(readFileSync(join(FIXTURE_DIR, f.wav)));
71
+ const { pcm, sampleRate } = decodeMonoPcm16Wav(bytes);
72
+
73
+ expect(sampleRate).toBe(f.sampleRateHz);
74
+ assertInRangePcm(pcm);
75
+
76
+ const durationMs = (1000 * pcm.length) / sampleRate;
77
+ expect(durationMs).toBeGreaterThan(0);
78
+ expect(Number.isFinite(durationMs)).toBe(true);
79
+
80
+ // Corpus integrity: the sidecar .txt matches the manifest reference
81
+ // (these are the references a real-speech replacement corpus must hit).
82
+ const txt = readFileSync(join(FIXTURE_DIR, f.txt), "utf8").trim();
83
+ expect(txt).toBe(f.reference);
84
+ }
85
+ });
86
+
87
+ it("round-trips decode → encode → decode losslessly (PCM16 codec)", () => {
88
+ const first = manifest.files[0];
89
+ expect(first).toBeDefined();
90
+ const bytes = new Uint8Array(
91
+ readFileSync(
92
+ join(FIXTURE_DIR, (first as FixtureManifest["files"][0]).wav),
93
+ ),
94
+ );
95
+ const a = decodeMonoPcm16Wav(bytes);
96
+ const reencoded = encodeMonoPcm16Wav(a.pcm, a.sampleRate);
97
+ const b = decodeMonoPcm16Wav(reencoded);
98
+
99
+ expect(b.sampleRate).toBe(a.sampleRate);
100
+ expect(b.pcm.length).toBe(a.pcm.length);
101
+ // PCM16 → float → PCM16 is exact (the float values are k/0x8000).
102
+ for (let i = 0; i < a.pcm.length; i++) {
103
+ expect(b.pcm[i]).toBeCloseTo(a.pcm[i] ?? 0, 6);
104
+ }
105
+ });
106
+
107
+ it("documents that the fixture corpus is non-speech (not WER evidence)", () => {
108
+ // Guards against anyone treating these tones as ASR ground truth.
109
+ expect(manifest.realRecorded).toBe(false);
110
+ });
111
+ });
112
+
113
+ const FREEMAN_WAV = fileURLToPath(
114
+ new URL(
115
+ "../../../native/omnivoice.cpp/examples/freeman.wav",
116
+ import.meta.url,
117
+ ),
118
+ );
119
+ const hasFreeman = existsSync(FREEMAN_WAV);
120
+ const describeFreeman = hasFreeman ? describe : describe.skip;
121
+
122
+ describeFreeman(
123
+ "decodeMonoPcm16Wav — freeman.wav (real 22.05 kHz speech)",
124
+ () => {
125
+ it("decodes to several seconds of bipolar in-range speech PCM", () => {
126
+ const bytes = new Uint8Array(readFileSync(FREEMAN_WAV));
127
+ const { pcm, sampleRate } = decodeMonoPcm16Wav(bytes);
128
+
129
+ expect(sampleRate).toBe(22_050);
130
+ assertInRangePcm(pcm);
131
+
132
+ // Real speech is bipolar, not silence or a DC tone.
133
+ let min = Number.POSITIVE_INFINITY;
134
+ let max = Number.NEGATIVE_INFINITY;
135
+ for (let i = 0; i < pcm.length; i++) {
136
+ const s = pcm[i] ?? 0;
137
+ if (s < min) min = s;
138
+ if (s > max) max = s;
139
+ }
140
+ expect(min).toBeLessThan(0);
141
+ expect(max).toBeGreaterThan(0);
142
+
143
+ const durationSec = pcm.length / sampleRate;
144
+ expect(durationSec).toBeGreaterThan(1);
145
+ expect(durationSec).toBeLessThan(60);
146
+ });
147
+ },
148
+ );
@@ -0,0 +1,40 @@
1
+ import type { AudioSink } from "./types";
2
+ export interface PcmRingBufferOptions {
3
+ /**
4
+ * Fired when the buffer is full and a write overwrites unread samples.
5
+ * Reports the count of dropped samples in this write call. Schedulers
6
+ * should use this signal to apply backpressure upstream — silent
7
+ * overwrites produce audible glitches.
8
+ */
9
+ onOverflow?: (droppedSamples: number) => void;
10
+ }
11
+ export declare class PcmRingBuffer {
12
+ private readonly capacity;
13
+ private readonly sampleRate;
14
+ private readonly sink;
15
+ private readonly buf;
16
+ private readPos;
17
+ private writePos;
18
+ private filled;
19
+ private readonly onOverflow?;
20
+ constructor(capacity: number, sampleRate: number, sink: AudioSink, options?: PcmRingBufferOptions);
21
+ write(pcm: Float32Array): void;
22
+ /** Fill ratio in [0, 1]. Schedulers can throttle TTS dispatches as this approaches 1. */
23
+ pressure(): number;
24
+ flushToSink(): number;
25
+ drain(): void;
26
+ size(): number;
27
+ capacityHint(): number;
28
+ }
29
+ export declare class InMemoryAudioSink implements AudioSink {
30
+ readonly chunks: Array<{
31
+ pcm: Float32Array;
32
+ sampleRate: number;
33
+ }>;
34
+ private buffered;
35
+ write(pcm: Float32Array, sampleRate: number): void;
36
+ drain(): void;
37
+ bufferedSamples(): number;
38
+ totalWritten(): number;
39
+ }
40
+ //# sourceMappingURL=ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,qBAAa,aAAa;IAQxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IATtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAmC;gBAG7C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,EAChC,OAAO,GAAE,oBAAyB;IASnC,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAkC9B,yFAAyF;IACzF,QAAQ,IAAI,MAAM;IAIlB,WAAW,IAAI,MAAM;IAcrB,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,MAAM;IAId,YAAY,IAAI,MAAM;CAGtB;AAED,qBAAa,iBAAkB,YAAW,SAAS;IAClD,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,YAAY,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IACvE,OAAO,CAAC,QAAQ,CAAK;IAErB,KAAK,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAKlD,KAAK,IAAI,IAAI;IAIb,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;CAKtB"}
@@ -0,0 +1,129 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { InMemoryAudioSink, PcmRingBuffer } from "./ring-buffer";
3
+
4
+ function f32(...xs: number[]): Float32Array {
5
+ return Float32Array.from(xs);
6
+ }
7
+
8
+ /** Concatenate everything an InMemoryAudioSink received, in order. */
9
+ function sinkData(sink: InMemoryAudioSink): number[] {
10
+ const out: number[] = [];
11
+ for (const c of sink.chunks) out.push(...c.pcm);
12
+ return out;
13
+ }
14
+
15
+ describe("PcmRingBuffer (bulk-copy)", () => {
16
+ it("writes then flushes in FIFO order", () => {
17
+ const sink = new InMemoryAudioSink();
18
+ const rb = new PcmRingBuffer(8, 16000, sink);
19
+ rb.write(f32(1, 2, 3));
20
+ rb.write(f32(4, 5));
21
+ expect(rb.size()).toBe(5);
22
+ expect(rb.flushToSink()).toBe(5);
23
+ expect(sinkData(sink)).toEqual([1, 2, 3, 4, 5]);
24
+ expect(rb.size()).toBe(0);
25
+ });
26
+
27
+ it("handles a write that wraps the write cursor", () => {
28
+ const sink = new InMemoryAudioSink();
29
+ const rb = new PcmRingBuffer(4, 16000, sink);
30
+ rb.write(f32(1, 2, 3)); // writePos=3
31
+ expect(rb.flushToSink()).toBe(3); // readPos=writePos=3
32
+ rb.write(f32(4, 5, 6)); // wraps: positions 3,0,1
33
+ expect(rb.flushToSink()).toBe(3);
34
+ expect(sinkData(sink)).toEqual([1, 2, 3, 4, 5, 6]);
35
+ });
36
+
37
+ it("drops oldest samples on overflow and reports the count", () => {
38
+ const sink = new InMemoryAudioSink();
39
+ const dropped: number[] = [];
40
+ const rb = new PcmRingBuffer(4, 16000, sink, {
41
+ onOverflow: (n) => dropped.push(n),
42
+ });
43
+ rb.write(f32(1, 2, 3)); // filled=3
44
+ rb.write(f32(4, 5, 6)); // filled would be 6 → drop 2 oldest (1,2)
45
+ expect(dropped).toEqual([2]);
46
+ expect(rb.size()).toBe(4);
47
+ expect(rb.flushToSink()).toBe(4);
48
+ expect(sinkData(sink)).toEqual([3, 4, 5, 6]);
49
+ });
50
+
51
+ it("keeps only the last `capacity` samples when one write exceeds capacity", () => {
52
+ const sink = new InMemoryAudioSink();
53
+ const dropped: number[] = [];
54
+ const rb = new PcmRingBuffer(4, 16000, sink, {
55
+ onOverflow: (n) => dropped.push(n),
56
+ });
57
+ rb.write(f32(1, 2, 3, 4, 5, 6, 7)); // 7 samples into cap-4 → keep 4,5,6,7
58
+ expect(dropped).toEqual([3]);
59
+ expect(rb.size()).toBe(4);
60
+ rb.flushToSink();
61
+ expect(sinkData(sink)).toEqual([4, 5, 6, 7]);
62
+ });
63
+
64
+ it("exact-capacity write fills without dropping", () => {
65
+ const sink = new InMemoryAudioSink();
66
+ const dropped: number[] = [];
67
+ const rb = new PcmRingBuffer(4, 16000, sink, {
68
+ onOverflow: (n) => dropped.push(n),
69
+ });
70
+ rb.write(f32(1, 2, 3, 4));
71
+ expect(dropped).toEqual([]);
72
+ expect(rb.size()).toBe(4);
73
+ rb.flushToSink();
74
+ expect(sinkData(sink)).toEqual([1, 2, 3, 4]);
75
+ });
76
+
77
+ it("partial overflow when already partly filled, with wrap", () => {
78
+ const sink = new InMemoryAudioSink();
79
+ const rb = new PcmRingBuffer(4, 16000, sink);
80
+ rb.write(f32(1, 2)); // writePos=2, filled=2
81
+ rb.write(f32(3, 4, 5)); // 3→pos2, 4→pos3, 5→pos0 (overwrites 1); drop 1
82
+ // logical order now: 2,3,4,5
83
+ expect(rb.size()).toBe(4);
84
+ rb.flushToSink();
85
+ expect(sinkData(sink)).toEqual([2, 3, 4, 5]);
86
+ });
87
+
88
+ it("pressure reflects fill ratio", () => {
89
+ const rb = new PcmRingBuffer(10, 16000, new InMemoryAudioSink());
90
+ expect(rb.pressure()).toBe(0);
91
+ rb.write(f32(1, 2, 3, 4, 5));
92
+ expect(rb.pressure()).toBeCloseTo(0.5);
93
+ });
94
+
95
+ it("drain clears without writing to the sink", () => {
96
+ const sink = new InMemoryAudioSink();
97
+ const rb = new PcmRingBuffer(4, 16000, sink);
98
+ rb.write(f32(1, 2, 3));
99
+ rb.drain();
100
+ expect(rb.size()).toBe(0);
101
+ expect(sinkData(sink)).toEqual([]);
102
+ });
103
+
104
+ it("empty write is a no-op", () => {
105
+ const sink = new InMemoryAudioSink();
106
+ const rb = new PcmRingBuffer(4, 16000, sink);
107
+ rb.write(new Float32Array(0));
108
+ expect(rb.size()).toBe(0);
109
+ expect(rb.flushToSink()).toBe(0);
110
+ });
111
+
112
+ it("matches the reference per-sample model over a randomized-ish sequence", () => {
113
+ // Reference oracle implemented straightforwardly; compare logical contents.
114
+ const cap = 5;
115
+ const sink = new InMemoryAudioSink();
116
+ const rb = new PcmRingBuffer(cap, 16000, sink);
117
+ const ref: number[] = [];
118
+ const writes = [[1, 2], [3, 4, 5, 6], [7], [8, 9, 10, 11, 12, 13]];
119
+ const value = 0;
120
+ for (const w of writes) {
121
+ void value;
122
+ rb.write(Float32Array.from(w));
123
+ ref.push(...w);
124
+ while (ref.length > cap) ref.shift();
125
+ }
126
+ rb.flushToSink();
127
+ expect(sinkData(sink)).toEqual(ref);
128
+ });
129
+ });
@@ -0,0 +1,123 @@
1
+ import type { AudioSink } from "./types";
2
+
3
+ export interface PcmRingBufferOptions {
4
+ /**
5
+ * Fired when the buffer is full and a write overwrites unread samples.
6
+ * Reports the count of dropped samples in this write call. Schedulers
7
+ * should use this signal to apply backpressure upstream — silent
8
+ * overwrites produce audible glitches.
9
+ */
10
+ onOverflow?: (droppedSamples: number) => void;
11
+ }
12
+
13
+ export class PcmRingBuffer {
14
+ private readonly buf: Float32Array;
15
+ private readPos = 0;
16
+ private writePos = 0;
17
+ private filled = 0;
18
+ private readonly onOverflow?: (droppedSamples: number) => void;
19
+
20
+ constructor(
21
+ private readonly capacity: number,
22
+ private readonly sampleRate: number,
23
+ private readonly sink: AudioSink,
24
+ options: PcmRingBufferOptions = {},
25
+ ) {
26
+ if (capacity <= 0) {
27
+ throw new Error("PcmRingBuffer: capacity must be positive");
28
+ }
29
+ this.buf = new Float32Array(capacity);
30
+ this.onOverflow = options.onOverflow;
31
+ }
32
+
33
+ write(pcm: Float32Array): void {
34
+ const n = pcm.length;
35
+ if (n === 0) return;
36
+ // Samples lost to overwrite: everything past capacity once we account for
37
+ // what's already buffered. Matches the per-sample loop's drop accounting.
38
+ const dropped = Math.max(0, this.filled + n - this.capacity);
39
+
40
+ if (n >= this.capacity) {
41
+ // The incoming chunk alone fills (or overfills) the ring — only its last
42
+ // `capacity` samples survive. Bulk-copy them and reset to a full buffer.
43
+ this.buf.set(pcm.subarray(n - this.capacity, n), 0);
44
+ this.readPos = 0;
45
+ this.writePos = 0;
46
+ this.filled = this.capacity;
47
+ } else {
48
+ // Up to two contiguous bulk copies (one before the wrap, one after).
49
+ const firstSpan = Math.min(n, this.capacity - this.writePos);
50
+ this.buf.set(pcm.subarray(0, firstSpan), this.writePos);
51
+ if (n > firstSpan) this.buf.set(pcm.subarray(firstSpan, n), 0);
52
+ this.writePos = (this.writePos + n) % this.capacity;
53
+ if (dropped > 0) {
54
+ // Buffer overran: the read cursor chases the write cursor.
55
+ this.readPos = (this.readPos + dropped) % this.capacity;
56
+ this.filled = this.capacity;
57
+ } else {
58
+ this.filled += n;
59
+ }
60
+ }
61
+
62
+ if (dropped > 0 && this.onOverflow) {
63
+ this.onOverflow(dropped);
64
+ }
65
+ }
66
+
67
+ /** Fill ratio in [0, 1]. Schedulers can throttle TTS dispatches as this approaches 1. */
68
+ pressure(): number {
69
+ return this.filled / this.capacity;
70
+ }
71
+
72
+ flushToSink(): number {
73
+ if (this.filled === 0) return 0;
74
+ const n = this.filled;
75
+ const out = new Float32Array(n);
76
+ // Read `n` samples from readPos with at most one wrap — two bulk copies.
77
+ const firstSpan = Math.min(n, this.capacity - this.readPos);
78
+ out.set(this.buf.subarray(this.readPos, this.readPos + firstSpan), 0);
79
+ if (n > firstSpan) out.set(this.buf.subarray(0, n - firstSpan), firstSpan);
80
+ this.readPos = this.writePos;
81
+ this.filled = 0;
82
+ this.sink.write(out, this.sampleRate);
83
+ return n;
84
+ }
85
+
86
+ drain(): void {
87
+ this.readPos = this.writePos;
88
+ this.filled = 0;
89
+ this.sink.drain();
90
+ }
91
+
92
+ size(): number {
93
+ return this.filled;
94
+ }
95
+
96
+ capacityHint(): number {
97
+ return this.capacity;
98
+ }
99
+ }
100
+
101
+ export class InMemoryAudioSink implements AudioSink {
102
+ readonly chunks: Array<{ pcm: Float32Array; sampleRate: number }> = [];
103
+ private buffered = 0;
104
+
105
+ write(pcm: Float32Array, sampleRate: number): void {
106
+ this.chunks.push({ pcm, sampleRate });
107
+ this.buffered += pcm.length;
108
+ }
109
+
110
+ drain(): void {
111
+ this.buffered = 0;
112
+ }
113
+
114
+ bufferedSamples(): number {
115
+ return this.buffered;
116
+ }
117
+
118
+ totalWritten(): number {
119
+ let n = 0;
120
+ for (const c of this.chunks) n += c.pcm.length;
121
+ return n;
122
+ }
123
+ }
@@ -0,0 +1,24 @@
1
+ import type { Phrase, RejectedTokenRange } from "./types";
2
+ type PhraseState = "queued" | "synthesizing" | "ringbuffered" | "played";
3
+ export interface RollbackEvent {
4
+ phraseId: number;
5
+ reason: "rejected-tokens";
6
+ rejectedRange: RejectedTokenRange;
7
+ }
8
+ export declare class RollbackQueue {
9
+ private readonly tracked;
10
+ track(phrase: Phrase): void;
11
+ markSynthesizing(phraseId: number): void;
12
+ markRingBuffered(phraseId: number): void;
13
+ markPlayed(phraseId: number): void;
14
+ drop(phraseId: number): void;
15
+ onRejected(range: RejectedTokenRange): RollbackEvent[];
16
+ snapshot(): ReadonlyArray<{
17
+ phrase: Phrase;
18
+ state: PhraseState;
19
+ }>;
20
+ private requireEntry;
21
+ private overlaps;
22
+ }
23
+ export {};
24
+ //# sourceMappingURL=rollback-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback-queue.d.ts","sourceRoot":"","sources":["rollback-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE1D,KAAK,WAAW,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,QAAQ,CAAC;AAOzE,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,aAAa,EAAE,kBAAkB,CAAC;CAClC;AAED,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAE5D,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI3B,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKxC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKlC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI5B,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,EAAE;IAetD,QAAQ,IAAI,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,CAAC;IAIjE,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,QAAQ;CAKhB"}
@@ -0,0 +1,74 @@
1
+ import type { Phrase, RejectedTokenRange } from "./types";
2
+
3
+ type PhraseState = "queued" | "synthesizing" | "ringbuffered" | "played";
4
+
5
+ interface TrackedPhrase {
6
+ phrase: Phrase;
7
+ state: PhraseState;
8
+ }
9
+
10
+ export interface RollbackEvent {
11
+ phraseId: number;
12
+ reason: "rejected-tokens";
13
+ rejectedRange: RejectedTokenRange;
14
+ }
15
+
16
+ export class RollbackQueue {
17
+ private readonly tracked = new Map<number, TrackedPhrase>();
18
+
19
+ track(phrase: Phrase): void {
20
+ this.tracked.set(phrase.id, { phrase, state: "queued" });
21
+ }
22
+
23
+ markSynthesizing(phraseId: number): void {
24
+ const entry = this.requireEntry(phraseId);
25
+ entry.state = "synthesizing";
26
+ }
27
+
28
+ markRingBuffered(phraseId: number): void {
29
+ const entry = this.requireEntry(phraseId);
30
+ entry.state = "ringbuffered";
31
+ }
32
+
33
+ markPlayed(phraseId: number): void {
34
+ const entry = this.requireEntry(phraseId);
35
+ entry.state = "played";
36
+ }
37
+
38
+ drop(phraseId: number): void {
39
+ this.tracked.delete(phraseId);
40
+ }
41
+
42
+ onRejected(range: RejectedTokenRange): RollbackEvent[] {
43
+ const events: RollbackEvent[] = [];
44
+ for (const entry of this.tracked.values()) {
45
+ if (entry.state === "played") continue;
46
+ if (this.overlaps(entry.phrase, range)) {
47
+ events.push({
48
+ phraseId: entry.phrase.id,
49
+ reason: "rejected-tokens",
50
+ rejectedRange: range,
51
+ });
52
+ }
53
+ }
54
+ return events;
55
+ }
56
+
57
+ snapshot(): ReadonlyArray<{ phrase: Phrase; state: PhraseState }> {
58
+ return Array.from(this.tracked.values()).map((e) => ({ ...e }));
59
+ }
60
+
61
+ private requireEntry(phraseId: number): TrackedPhrase {
62
+ const entry = this.tracked.get(phraseId);
63
+ if (!entry) {
64
+ throw new Error(`RollbackQueue: unknown phraseId ${phraseId}`);
65
+ }
66
+ return entry;
67
+ }
68
+
69
+ private overlaps(phrase: Phrase, range: RejectedTokenRange): boolean {
70
+ return (
71
+ phrase.toIndex >= range.fromIndex && phrase.fromIndex <= range.toIndex
72
+ );
73
+ }
74
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Samantha-preset placeholder detection + on-the-fly regeneration.
3
+ *
4
+ * Background: the canonical default voice (Samantha, `af_same`) ships with
5
+ * the Eliza-1 bundle as `cache/voice-preset-default.bin` (ELZ1 format).
6
+ * The first I-wave shipped a 1052-byte zero-filled placeholder before the
7
+ * real preset bytes were produced — the runtime treats this placeholder as
8
+ * "not yet generated" and synthesises a fresh preset on first boot via the
9
+ * fused OmniVoice TTS (Path A).
10
+ *
11
+ * The detection rule is intentionally narrow: only an ELZ1 v1/v2 file whose
12
+ * (a) speaker embedding is exactly zero AND (b) ref_audio_tokens / ref_text
13
+ * are empty AND (c) phrase-cache seed is empty counts as a placeholder. Any
14
+ * file that has even one non-zero region is considered real and is left
15
+ * alone — the runtime never silently overwrites operator-supplied presets.
16
+ *
17
+ * The fallback chain executed by `EngineVoiceBridge.start()`:
18
+ *
19
+ * 1. If `cache/voice-preset-default.bin` is missing → throw (existing
20
+ * behaviour, the bundle is malformed).
21
+ * 2. If the file exists and is NOT a placeholder → load it as-is.
22
+ * 3. If it IS a placeholder AND the OmniVoice reference-encode FFI is
23
+ * available → regenerate the preset using the bundled Samantha
24
+ * reference clip + transcript, write the new bytes back to disk,
25
+ * then load.
26
+ * 4. If it IS a placeholder AND OmniVoice reference-encode is unavailable
27
+ * → log a loud warning and fall through to the bundled Kokoro default
28
+ * voice (`kokoro.defaultVoiceId`) by re-pointing the discovery layer.
29
+ */
30
+ /** The exact byte-length the I-wave placeholder shipped at. Used as a fast
31
+ * pre-check before the more expensive structural parse — files of any
32
+ * other size cannot be the placeholder. */
33
+ export declare const SAMANTHA_PLACEHOLDER_BYTE_LENGTH = 1052;
34
+ /** Reasons `detectSamanthaPlaceholder` returns. Each is structurally
35
+ * distinct so the caller can branch without re-parsing. */
36
+ export type SamanthaPlaceholderState = {
37
+ kind: "missing";
38
+ } | {
39
+ kind: "real-preset";
40
+ reason: string;
41
+ } | {
42
+ kind: "placeholder";
43
+ } | {
44
+ kind: "unreadable";
45
+ reason: string;
46
+ };
47
+ /**
48
+ * Inspect `presetPath` and report whether it is the I-wave zero-fill
49
+ * placeholder, a real preset, missing, or unreadable. Pure I/O — no
50
+ * mutation of the file.
51
+ */
52
+ export declare function detectSamanthaPlaceholder(presetPath: string): SamanthaPlaceholderState;
53
+ /**
54
+ * The text the on-the-fly regeneration uses as the Samantha reference
55
+ * transcript. Stable across versions so the produced preset is
56
+ * deterministic — pinning the prompt is part of the cacheability contract
57
+ * (same inputs -> same output bytes for byte-for-byte comparison).
58
+ */
59
+ export declare const SAMANTHA_REFERENCE_TRANSCRIPT = "Hi, I'm Samantha. It's nice to finally talk to you about something real.";
60
+ /**
61
+ * The closed-vocabulary VoiceDesign instruct string baked into the
62
+ * regenerated Samantha preset. Mirrors the publish-time freeze CLI's
63
+ * settings so the runtime regen and a future operator-built preset land on
64
+ * the same surface. Pinned for deterministic regeneration.
65
+ */
66
+ export declare const SAMANTHA_INSTRUCT = "female, american accent, young adult, moderate pitch";
67
+ //# sourceMappingURL=samantha-preset-placeholder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"samantha-preset-placeholder.d.ts","sourceRoot":"","sources":["samantha-preset-placeholder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAaH;;4CAE4C;AAC5C,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD;4DAC4D;AAC5D,MAAM,MAAM,wBAAwB,GACjC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,yBAAyB,CACxC,UAAU,EAAE,MAAM,GAChB,wBAAwB,CAoE1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,6EACiC,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,yDACyB,CAAC"}