@elizaos/plugin-local-inference 2.0.0-beta.1 → 2.0.11-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (676) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/package.json +81 -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/adapters/capacitor-llama/__tests__/compat-behavior.test.ts +218 -0
  11. package/src/adapters/capacitor-llama/__tests__/index.test.ts +68 -0
  12. package/src/adapters/capacitor-llama/__tests__/structured-output.test.ts +215 -0
  13. package/src/adapters/capacitor-llama/__tests__/text-streaming.test.ts +174 -0
  14. package/src/adapters/capacitor-llama/environment.ts +71 -0
  15. package/src/adapters/capacitor-llama/index.browser.ts +83 -0
  16. package/src/adapters/capacitor-llama/index.ts +807 -0
  17. package/src/adapters/capacitor-llama/loader.ts +109 -0
  18. package/src/adapters/capacitor-llama/structured-output.ts +165 -0
  19. package/src/adapters/capacitor-llama/text-streaming.ts +227 -0
  20. package/src/adapters/capacitor-llama/types.ts +374 -0
  21. package/src/backends/apple-foundation.ts +127 -0
  22. package/src/index.d.ts +7 -0
  23. package/src/index.d.ts.map +1 -0
  24. package/src/index.ts +54 -0
  25. package/src/local-inference-routes.d.ts +38 -0
  26. package/src/local-inference-routes.d.ts.map +1 -0
  27. package/src/local-inference-routes.test.ts +344 -0
  28. package/src/local-inference-routes.ts +1543 -0
  29. package/src/provider.d.ts +21 -0
  30. package/src/provider.d.ts.map +1 -0
  31. package/src/provider.ts +1171 -0
  32. package/src/routes/compat-helpers.d.ts +18 -0
  33. package/src/routes/compat-helpers.d.ts.map +1 -0
  34. package/src/routes/compat-helpers.ts +274 -0
  35. package/src/routes/family-member-route.d.ts +62 -0
  36. package/src/routes/family-member-route.d.ts.map +1 -0
  37. package/src/routes/family-member-route.ts +353 -0
  38. package/src/routes/index.d.ts +19 -0
  39. package/src/routes/index.d.ts.map +1 -0
  40. package/src/routes/index.ts +60 -0
  41. package/src/routes/live-diarization-route.d.ts +26 -0
  42. package/src/routes/live-diarization-route.d.ts.map +1 -0
  43. package/src/routes/live-diarization-route.test.ts +213 -0
  44. package/src/routes/live-diarization-route.ts +122 -0
  45. package/src/routes/local-inference-asr-route.d.ts +4 -0
  46. package/src/routes/local-inference-asr-route.d.ts.map +1 -0
  47. package/src/routes/local-inference-asr-route.test.ts +190 -0
  48. package/src/routes/local-inference-asr-route.ts +213 -0
  49. package/src/routes/local-inference-compat-routes.d.ts +16 -0
  50. package/src/routes/local-inference-compat-routes.d.ts.map +1 -0
  51. package/src/routes/local-inference-compat-routes.test.ts +423 -0
  52. package/src/routes/local-inference-compat-routes.ts +782 -0
  53. package/src/routes/local-inference-tts-route.d.ts +7 -0
  54. package/src/routes/local-inference-tts-route.d.ts.map +1 -0
  55. package/src/routes/local-inference-tts-route.test.ts +179 -0
  56. package/src/routes/local-inference-tts-route.ts +230 -0
  57. package/src/routes/voice-first-run-routes.d.ts +62 -0
  58. package/src/routes/voice-first-run-routes.d.ts.map +1 -0
  59. package/src/routes/voice-first-run-routes.ts +524 -0
  60. package/src/routes/voice-models-routes.d.ts +62 -0
  61. package/src/routes/voice-models-routes.d.ts.map +1 -0
  62. package/src/routes/voice-models-routes.ts +554 -0
  63. package/src/routes/voice-profile-plugin-routes.d.ts +19 -0
  64. package/src/routes/voice-profile-plugin-routes.d.ts.map +1 -0
  65. package/src/routes/voice-profile-plugin-routes.ts +138 -0
  66. package/src/routes/voice-profiles-management-routes.d.ts +52 -0
  67. package/src/routes/voice-profiles-management-routes.d.ts.map +1 -0
  68. package/src/routes/voice-profiles-management-routes.ts +476 -0
  69. package/src/routes/voice-speaker-profile-routes.d.ts +57 -0
  70. package/src/routes/voice-speaker-profile-routes.d.ts.map +1 -0
  71. package/src/routes/voice-speaker-profile-routes.ts +199 -0
  72. package/src/runtime/aosp-llama-loader-selection.test.ts +80 -0
  73. package/src/runtime/capacitor-llama.d.ts +25 -0
  74. package/src/runtime/embedding-manager-support.d.ts +77 -0
  75. package/src/runtime/embedding-manager-support.d.ts.map +1 -0
  76. package/src/runtime/embedding-manager-support.ts +497 -0
  77. package/src/runtime/embedding-presets.d.ts +16 -0
  78. package/src/runtime/embedding-presets.d.ts.map +1 -0
  79. package/src/runtime/embedding-presets.ts +81 -0
  80. package/src/runtime/embedding-warmup-policy.d.ts +14 -0
  81. package/src/runtime/embedding-warmup-policy.d.ts.map +1 -0
  82. package/src/runtime/embedding-warmup-policy.test.ts +53 -0
  83. package/src/runtime/embedding-warmup-policy.ts +48 -0
  84. package/src/runtime/ensure-local-inference-handler.d.ts +53 -0
  85. package/src/runtime/ensure-local-inference-handler.d.ts.map +1 -0
  86. package/src/runtime/ensure-local-inference-handler.test.ts +528 -0
  87. package/src/runtime/ensure-local-inference-handler.ts +1398 -0
  88. package/src/runtime/index.d.ts +14 -0
  89. package/src/runtime/index.d.ts.map +1 -0
  90. package/src/runtime/index.ts +27 -0
  91. package/src/runtime/mobile-local-inference-gate.d.ts +31 -0
  92. package/src/runtime/mobile-local-inference-gate.d.ts.map +1 -0
  93. package/src/runtime/mobile-local-inference-gate.test.ts +69 -0
  94. package/src/runtime/mobile-local-inference-gate.ts +44 -0
  95. package/src/runtime/voice-entity-binding.d.ts +103 -0
  96. package/src/runtime/voice-entity-binding.d.ts.map +1 -0
  97. package/src/runtime/voice-entity-binding.transcript.test.ts +69 -0
  98. package/src/runtime/voice-entity-binding.ts +328 -0
  99. package/src/services/README.md +71 -0
  100. package/src/services/__tests__/backend-selector.test.ts +101 -0
  101. package/src/services/__tests__/checkpoint-manager.test.ts +376 -0
  102. package/src/services/__tests__/gpu-autotune.test.ts +400 -0
  103. package/src/services/__tests__/llm-streaming-binding.test.ts +85 -0
  104. package/src/services/__tests__/planner-grammar.test.ts +372 -0
  105. package/src/services/__tests__/runtime-target.test.ts +176 -0
  106. package/src/services/active-model-switch-rollback.test.ts +183 -0
  107. package/src/services/active-model.d.ts +282 -0
  108. package/src/services/active-model.d.ts.map +1 -0
  109. package/src/services/active-model.ts +1213 -0
  110. package/src/services/asr/errors.d.ts +21 -0
  111. package/src/services/asr/errors.d.ts.map +1 -0
  112. package/src/services/asr/errors.ts +50 -0
  113. package/src/services/asr/hash.d.ts +28 -0
  114. package/src/services/asr/hash.d.ts.map +1 -0
  115. package/src/services/asr/hash.ts +49 -0
  116. package/src/services/asr/index.d.ts +76 -0
  117. package/src/services/asr/index.d.ts.map +1 -0
  118. package/src/services/asr/index.ts +178 -0
  119. package/src/services/asr/types.d.ts +91 -0
  120. package/src/services/asr/types.d.ts.map +1 -0
  121. package/src/services/asr/types.ts +95 -0
  122. package/src/services/assignments.d.ts +71 -0
  123. package/src/services/assignments.d.ts.map +1 -0
  124. package/src/services/assignments.test.ts +80 -0
  125. package/src/services/assignments.ts +230 -0
  126. package/src/services/backend-selector.ts +95 -0
  127. package/src/services/backend.d.ts +346 -0
  128. package/src/services/backend.d.ts.map +1 -0
  129. package/src/services/backend.ts +612 -0
  130. package/src/services/bundled-models.d.ts +34 -0
  131. package/src/services/bundled-models.d.ts.map +1 -0
  132. package/src/services/bundled-models.ts +129 -0
  133. package/src/services/cache-bridge.d.ts +206 -0
  134. package/src/services/cache-bridge.d.ts.map +1 -0
  135. package/src/services/cache-bridge.test.ts +516 -0
  136. package/src/services/cache-bridge.ts +423 -0
  137. package/src/services/catalog.d.ts +10 -0
  138. package/src/services/catalog.d.ts.map +1 -0
  139. package/src/services/catalog.test.ts +240 -0
  140. package/src/services/catalog.ts +27 -0
  141. package/src/services/checkpoint-client.d.ts +109 -0
  142. package/src/services/checkpoint-client.d.ts.map +1 -0
  143. package/src/services/checkpoint-client.ts +258 -0
  144. package/src/services/checkpoint-manager.ts +474 -0
  145. package/src/services/cloud-fallback.d.ts +102 -0
  146. package/src/services/cloud-fallback.d.ts.map +1 -0
  147. package/src/services/cloud-fallback.ts +230 -0
  148. package/src/services/conversation-registry.d.ts +142 -0
  149. package/src/services/conversation-registry.d.ts.map +1 -0
  150. package/src/services/conversation-registry.test.ts +235 -0
  151. package/src/services/conversation-registry.ts +264 -0
  152. package/src/services/desktop-fused-ffi-backend-runtime.d.ts +92 -0
  153. package/src/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
  154. package/src/services/desktop-fused-ffi-backend-runtime.ts +333 -0
  155. package/src/services/device-bridge.d.ts +188 -0
  156. package/src/services/device-bridge.d.ts.map +1 -0
  157. package/src/services/device-bridge.ts +1237 -0
  158. package/src/services/device-resource-metrics.d.ts +149 -0
  159. package/src/services/device-resource-metrics.d.ts.map +1 -0
  160. package/src/services/device-resource-metrics.test.ts +98 -0
  161. package/src/services/device-resource-metrics.ts +346 -0
  162. package/src/services/device-tier.d.ts +115 -0
  163. package/src/services/device-tier.d.ts.map +1 -0
  164. package/src/services/device-tier.test.ts +371 -0
  165. package/src/services/device-tier.ts +410 -0
  166. package/src/services/downloader.d.ts +82 -0
  167. package/src/services/downloader.d.ts.map +1 -0
  168. package/src/services/downloader.test.ts +724 -0
  169. package/src/services/downloader.ts +899 -0
  170. package/src/services/engine-direct-bundle.test.ts +58 -0
  171. package/src/services/engine-streaming.test.ts +80 -0
  172. package/src/services/engine.d.ts +534 -0
  173. package/src/services/engine.d.ts.map +1 -0
  174. package/src/services/engine.ts +1891 -0
  175. package/src/services/ensure-local-artifacts.integration.test.ts +273 -0
  176. package/src/services/ensure-local-artifacts.test.ts +368 -0
  177. package/src/services/ensure-local-artifacts.ts +351 -0
  178. package/src/services/external-scanner.d.ts +17 -0
  179. package/src/services/external-scanner.d.ts.map +1 -0
  180. package/src/services/external-scanner.ts +312 -0
  181. package/src/services/ffi-llm-mock.ts +354 -0
  182. package/src/services/ffi-llm-streaming-abi.ts +442 -0
  183. package/src/services/ffi-streaming-backend.d.ts +180 -0
  184. package/src/services/ffi-streaming-backend.d.ts.map +1 -0
  185. package/src/services/ffi-streaming-backend.ts +382 -0
  186. package/src/services/ffi-streaming-runner.d.ts +122 -0
  187. package/src/services/ffi-streaming-runner.d.ts.map +1 -0
  188. package/src/services/ffi-streaming-runner.test.ts +60 -0
  189. package/src/services/ffi-streaming-runner.ts +354 -0
  190. package/src/services/ffi-unload-ordering.test.ts +162 -0
  191. package/src/services/gpu-autotune.ts +534 -0
  192. package/src/services/gpu-detect.ts +139 -0
  193. package/src/services/handler-registry.d.ts +72 -0
  194. package/src/services/handler-registry.d.ts.map +1 -0
  195. package/src/services/handler-registry.ts +240 -0
  196. package/src/services/hardware.d.ts +63 -0
  197. package/src/services/hardware.d.ts.map +1 -0
  198. package/src/services/hardware.test.ts +183 -0
  199. package/src/services/hardware.ts +404 -0
  200. package/src/services/hf-search.d.ts +26 -0
  201. package/src/services/hf-search.d.ts.map +1 -0
  202. package/src/services/hf-search.test.ts +69 -0
  203. package/src/services/hf-search.ts +420 -0
  204. package/src/services/image-description-runtime.d.ts +14 -0
  205. package/src/services/image-description-runtime.d.ts.map +1 -0
  206. package/src/services/image-description-runtime.test.ts +61 -0
  207. package/src/services/image-description-runtime.ts +118 -0
  208. package/src/services/imagegen/aosp-unavailable.d.ts +134 -0
  209. package/src/services/imagegen/aosp-unavailable.d.ts.map +1 -0
  210. package/src/services/imagegen/aosp-unavailable.ts +229 -0
  211. package/src/services/imagegen/backend-selector.d.ts +118 -0
  212. package/src/services/imagegen/backend-selector.d.ts.map +1 -0
  213. package/src/services/imagegen/backend-selector.ts +281 -0
  214. package/src/services/imagegen/coreml-unavailable.d.ts +105 -0
  215. package/src/services/imagegen/coreml-unavailable.d.ts.map +1 -0
  216. package/src/services/imagegen/coreml-unavailable.ts +237 -0
  217. package/src/services/imagegen/errors.d.ts +16 -0
  218. package/src/services/imagegen/errors.d.ts.map +1 -0
  219. package/src/services/imagegen/errors.ts +40 -0
  220. package/src/services/imagegen/index.d.ts +58 -0
  221. package/src/services/imagegen/index.d.ts.map +1 -0
  222. package/src/services/imagegen/index.ts +144 -0
  223. package/src/services/imagegen/mflux.d.ts +74 -0
  224. package/src/services/imagegen/mflux.d.ts.map +1 -0
  225. package/src/services/imagegen/mflux.ts +313 -0
  226. package/src/services/imagegen/sd-cpp.d.ts +180 -0
  227. package/src/services/imagegen/sd-cpp.d.ts.map +1 -0
  228. package/src/services/imagegen/sd-cpp.ts +718 -0
  229. package/src/services/imagegen/tensorrt-unavailable.d.ts +83 -0
  230. package/src/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
  231. package/src/services/imagegen/tensorrt-unavailable.ts +295 -0
  232. package/src/services/imagegen/types.d.ts +181 -0
  233. package/src/services/imagegen/types.d.ts.map +1 -0
  234. package/src/services/imagegen/types.ts +193 -0
  235. package/src/services/index.d.ts +30 -0
  236. package/src/services/index.d.ts.map +1 -0
  237. package/src/services/index.ts +225 -0
  238. package/src/services/inference-capabilities.d.ts +132 -0
  239. package/src/services/inference-capabilities.d.ts.map +1 -0
  240. package/src/services/inference-capabilities.test.ts +75 -0
  241. package/src/services/inference-capabilities.ts +204 -0
  242. package/src/services/inference-telemetry.d.ts +59 -0
  243. package/src/services/inference-telemetry.d.ts.map +1 -0
  244. package/src/services/inference-telemetry.ts +143 -0
  245. package/src/services/ios-llama-streaming.ts +248 -0
  246. package/src/services/kv-spill.d.ts +189 -0
  247. package/src/services/kv-spill.d.ts.map +1 -0
  248. package/src/services/kv-spill.test.ts +222 -0
  249. package/src/services/kv-spill.ts +356 -0
  250. package/src/services/latency-trace.d.ts +346 -0
  251. package/src/services/latency-trace.d.ts.map +1 -0
  252. package/src/services/latency-trace.test.ts +266 -0
  253. package/src/services/latency-trace.ts +844 -0
  254. package/src/services/llama-server-metrics.ts +304 -0
  255. package/src/services/llm-streaming-binding.d.ts +96 -0
  256. package/src/services/llm-streaming-binding.d.ts.map +1 -0
  257. package/src/services/llm-streaming-binding.ts +136 -0
  258. package/src/services/load-args.d.ts +82 -0
  259. package/src/services/load-args.d.ts.map +1 -0
  260. package/src/services/load-args.ts +81 -0
  261. package/src/services/manifest/eliza-1.manifest.v1.json +708 -0
  262. package/src/services/manifest/index.d.ts +4 -0
  263. package/src/services/manifest/index.d.ts.map +1 -0
  264. package/src/services/manifest/index.ts +66 -0
  265. package/src/services/manifest/manifest.test.ts +693 -0
  266. package/src/services/manifest/schema.d.ts +715 -0
  267. package/src/services/manifest/schema.d.ts.map +1 -0
  268. package/src/services/manifest/schema.ts +655 -0
  269. package/src/services/manifest/types.d.ts +30 -0
  270. package/src/services/manifest/types.d.ts.map +1 -0
  271. package/src/services/manifest/types.ts +55 -0
  272. package/src/services/manifest/validator.d.ts +66 -0
  273. package/src/services/manifest/validator.d.ts.map +1 -0
  274. package/src/services/manifest/validator.ts +569 -0
  275. package/src/services/memory-arbiter.d.ts +343 -0
  276. package/src/services/memory-arbiter.d.ts.map +1 -0
  277. package/src/services/memory-arbiter.test.ts +419 -0
  278. package/src/services/memory-arbiter.ts +1000 -0
  279. package/src/services/memory-monitor.d.ts +119 -0
  280. package/src/services/memory-monitor.d.ts.map +1 -0
  281. package/src/services/memory-monitor.test.ts +208 -0
  282. package/src/services/memory-monitor.ts +296 -0
  283. package/src/services/memory-pressure.d.ts +127 -0
  284. package/src/services/memory-pressure.d.ts.map +1 -0
  285. package/src/services/memory-pressure.ts +413 -0
  286. package/src/services/mtp-doctor.d.ts +13 -0
  287. package/src/services/mtp-doctor.d.ts.map +1 -0
  288. package/src/services/mtp-doctor.ts +78 -0
  289. package/src/services/network-policy.d.ts +127 -0
  290. package/src/services/network-policy.d.ts.map +1 -0
  291. package/src/services/network-policy.ts +346 -0
  292. package/src/services/paths.d.ts +6 -0
  293. package/src/services/paths.d.ts.map +1 -0
  294. package/src/services/paths.ts +25 -0
  295. package/src/services/planner-skeleton.d.ts +124 -0
  296. package/src/services/planner-skeleton.d.ts.map +1 -0
  297. package/src/services/planner-skeleton.ts +175 -0
  298. package/src/services/providers.d.ts +38 -0
  299. package/src/services/providers.d.ts.map +1 -0
  300. package/src/services/providers.ts +507 -0
  301. package/src/services/ram-budget-cache.test.ts +163 -0
  302. package/src/services/ram-budget.d.ts +110 -0
  303. package/src/services/ram-budget.d.ts.map +1 -0
  304. package/src/services/ram-budget.ts +0 -0
  305. package/src/services/readiness.d.ts +9 -0
  306. package/src/services/readiness.d.ts.map +1 -0
  307. package/src/services/readiness.test.ts +87 -0
  308. package/src/services/readiness.ts +238 -0
  309. package/src/services/recommendation.d.ts +111 -0
  310. package/src/services/recommendation.d.ts.map +1 -0
  311. package/src/services/recommendation.ts +672 -0
  312. package/src/services/registry.d.ts +35 -0
  313. package/src/services/registry.d.ts.map +1 -0
  314. package/src/services/registry.ts +151 -0
  315. package/src/services/router-handler.d.ts +92 -0
  316. package/src/services/router-handler.d.ts.map +1 -0
  317. package/src/services/router-handler.test.ts +45 -0
  318. package/src/services/router-handler.ts +376 -0
  319. package/src/services/routing-policy.d.ts +55 -0
  320. package/src/services/routing-policy.d.ts.map +1 -0
  321. package/src/services/routing-policy.ts +228 -0
  322. package/src/services/routing-preferences.d.ts +8 -0
  323. package/src/services/routing-preferences.d.ts.map +1 -0
  324. package/src/services/routing-preferences.ts +15 -0
  325. package/src/services/runtime-target.d.ts +98 -0
  326. package/src/services/runtime-target.d.ts.map +1 -0
  327. package/src/services/runtime-target.ts +154 -0
  328. package/src/services/service.d.ts +128 -0
  329. package/src/services/service.d.ts.map +1 -0
  330. package/src/services/service.test.ts +223 -0
  331. package/src/services/service.ts +735 -0
  332. package/src/services/session-pool.d.ts +72 -0
  333. package/src/services/session-pool.d.ts.map +1 -0
  334. package/src/services/session-pool.ts +153 -0
  335. package/src/services/structured-output/deterministic-repair.d.ts +23 -0
  336. package/src/services/structured-output/deterministic-repair.d.ts.map +1 -0
  337. package/src/services/structured-output/deterministic-repair.test.ts +169 -0
  338. package/src/services/structured-output/deterministic-repair.ts +443 -0
  339. package/src/services/structured-output/index.ts +4 -0
  340. package/src/services/structured-output.d.ts +311 -0
  341. package/src/services/structured-output.d.ts.map +1 -0
  342. package/src/services/structured-output.test.ts +483 -0
  343. package/src/services/structured-output.ts +712 -0
  344. package/src/services/transcription-priority.test.ts +211 -0
  345. package/src/services/tts/errors.ts +46 -0
  346. package/src/services/tts/index.ts +214 -0
  347. package/src/services/tts/tts-audio-cache.ts +235 -0
  348. package/src/services/tts/types.ts +157 -0
  349. package/src/services/types.d.ts +19 -0
  350. package/src/services/types.d.ts.map +1 -0
  351. package/src/services/types.ts +55 -0
  352. package/src/services/verify-on-device.d.ts +34 -0
  353. package/src/services/verify-on-device.d.ts.map +1 -0
  354. package/src/services/verify-on-device.test.ts +87 -0
  355. package/src/services/verify-on-device.ts +127 -0
  356. package/src/services/verify.d.ts +8 -0
  357. package/src/services/verify.d.ts.map +1 -0
  358. package/src/services/verify.ts +13 -0
  359. package/src/services/vision/aosp-unavailable.d.ts +115 -0
  360. package/src/services/vision/aosp-unavailable.d.ts.map +1 -0
  361. package/src/services/vision/aosp-unavailable.ts +163 -0
  362. package/src/services/vision/capacitor-llama.d.ts +99 -0
  363. package/src/services/vision/capacitor-llama.d.ts.map +1 -0
  364. package/src/services/vision/capacitor-llama.ts +255 -0
  365. package/src/services/vision/cloud-fallback.d.ts +47 -0
  366. package/src/services/vision/cloud-fallback.d.ts.map +1 -0
  367. package/src/services/vision/cloud-fallback.test.ts +243 -0
  368. package/src/services/vision/cloud-fallback.ts +268 -0
  369. package/src/services/vision/fallback-chain.test.ts +86 -0
  370. package/src/services/vision/hash.d.ts +71 -0
  371. package/src/services/vision/hash.d.ts.map +1 -0
  372. package/src/services/vision/hash.ts +157 -0
  373. package/src/services/vision/index.d.ts +95 -0
  374. package/src/services/vision/index.d.ts.map +1 -0
  375. package/src/services/vision/index.ts +251 -0
  376. package/src/services/vision/llama-server.d.ts +73 -0
  377. package/src/services/vision/llama-server.d.ts.map +1 -0
  378. package/src/services/vision/llama-server.ts +177 -0
  379. package/src/services/vision/types.d.ts +153 -0
  380. package/src/services/vision/types.d.ts.map +1 -0
  381. package/src/services/vision/types.ts +154 -0
  382. package/src/services/vision/vast-fallback.d.ts +18 -0
  383. package/src/services/vision/vast-fallback.d.ts.map +1 -0
  384. package/src/services/vision/vast-fallback.ts +127 -0
  385. package/src/services/vision-embedding-cache.d.ts +98 -0
  386. package/src/services/vision-embedding-cache.d.ts.map +1 -0
  387. package/src/services/vision-embedding-cache.ts +189 -0
  388. package/src/services/voice/VOICE_WORKBENCH.md +88 -0
  389. package/src/services/voice/__test-helpers__/fake-ffi.ts +92 -0
  390. package/src/services/voice/__test-helpers__/synthetic-speech.ts +124 -0
  391. package/src/services/voice/__tests__/checkpoint-manager.test.ts +241 -0
  392. package/src/services/voice/__tests__/checkpoint-policy.test.ts +270 -0
  393. package/src/services/voice/__tests__/eager-context-builder.test.ts +257 -0
  394. package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +288 -0
  395. package/src/services/voice/__tests__/eot-classifier.test.ts +431 -0
  396. package/src/services/voice/__tests__/optimistic-rollback.test.ts +312 -0
  397. package/src/services/voice/__tests__/prefill-client.test.ts +266 -0
  398. package/src/services/voice/__tests__/prefix-preserving-queue.test.ts +208 -0
  399. package/src/services/voice/__tests__/streaming-asr.test.ts +450 -0
  400. package/src/services/voice/__tests__/streaming-transcriber.test.ts +339 -0
  401. package/src/services/voice/__tests__/turn-detector-resolver.test.ts +197 -0
  402. package/src/services/voice/__tests__/voice-state-machine-prefill.test.ts +275 -0
  403. package/src/services/voice/__tests__/voice-state-machine.test.ts +354 -0
  404. package/src/services/voice/audio-frame-consumer.d.ts +212 -0
  405. package/src/services/voice/audio-frame-consumer.d.ts.map +1 -0
  406. package/src/services/voice/audio-frame-consumer.test.ts +343 -0
  407. package/src/services/voice/audio-frame-consumer.ts +491 -0
  408. package/src/services/voice/barge-in.d.ts +112 -0
  409. package/src/services/voice/barge-in.d.ts.map +1 -0
  410. package/src/services/voice/barge-in.test.ts +244 -0
  411. package/src/services/voice/barge-in.ts +336 -0
  412. package/src/services/voice/cancellation-coordinator.d.ts +127 -0
  413. package/src/services/voice/cancellation-coordinator.d.ts.map +1 -0
  414. package/src/services/voice/cancellation-coordinator.test.ts +196 -0
  415. package/src/services/voice/cancellation-coordinator.ts +269 -0
  416. package/src/services/voice/checkpoint-manager.d.ts +199 -0
  417. package/src/services/voice/checkpoint-manager.d.ts.map +1 -0
  418. package/src/services/voice/checkpoint-manager.ts +401 -0
  419. package/src/services/voice/checkpoint-policy.ts +336 -0
  420. package/src/services/voice/composite-eot-classifier.test.ts +59 -0
  421. package/src/services/voice/e2e-harness.test.ts +182 -0
  422. package/src/services/voice/e2e-harness.ts +743 -0
  423. package/src/services/voice/eager-context-builder.d.ts +170 -0
  424. package/src/services/voice/eager-context-builder.d.ts.map +1 -0
  425. package/src/services/voice/eager-context-builder.ts +262 -0
  426. package/src/services/voice/eliza1-eot-scorer.d.ts +124 -0
  427. package/src/services/voice/eliza1-eot-scorer.d.ts.map +1 -0
  428. package/src/services/voice/eliza1-eot-scorer.ts +242 -0
  429. package/src/services/voice/embedding-server.ts +200 -0
  430. package/src/services/voice/embedding.d.ts +133 -0
  431. package/src/services/voice/embedding.d.ts.map +1 -0
  432. package/src/services/voice/embedding.test.ts +148 -0
  433. package/src/services/voice/embedding.ts +244 -0
  434. package/src/services/voice/emotion-attribution.d.ts +68 -0
  435. package/src/services/voice/emotion-attribution.d.ts.map +1 -0
  436. package/src/services/voice/emotion-attribution.test.ts +129 -0
  437. package/src/services/voice/emotion-attribution.ts +361 -0
  438. package/src/services/voice/engine-bridge-cancellation.test.ts +422 -0
  439. package/src/services/voice/engine-bridge.d.ts +746 -0
  440. package/src/services/voice/engine-bridge.d.ts.map +1 -0
  441. package/src/services/voice/engine-bridge.test.ts +384 -0
  442. package/src/services/voice/engine-bridge.ts +2226 -0
  443. package/src/services/voice/eot-classifier-ggml.d.ts +179 -0
  444. package/src/services/voice/eot-classifier-ggml.d.ts.map +1 -0
  445. package/src/services/voice/eot-classifier-ggml.ts +566 -0
  446. package/src/services/voice/eot-classifier.d.ts +214 -0
  447. package/src/services/voice/eot-classifier.d.ts.map +1 -0
  448. package/src/services/voice/eot-classifier.ts +533 -0
  449. package/src/services/voice/errors.d.ts +20 -0
  450. package/src/services/voice/errors.d.ts.map +1 -0
  451. package/src/services/voice/errors.ts +32 -0
  452. package/src/services/voice/expressive-tags.d.ts +158 -0
  453. package/src/services/voice/expressive-tags.d.ts.map +1 -0
  454. package/src/services/voice/expressive-tags.ts +405 -0
  455. package/src/services/voice/ffi-bindings.d.ts +636 -0
  456. package/src/services/voice/ffi-bindings.d.ts.map +1 -0
  457. package/src/services/voice/ffi-bindings.test.ts +671 -0
  458. package/src/services/voice/ffi-bindings.ts +3050 -0
  459. package/src/services/voice/first-line-cache.d.ts +181 -0
  460. package/src/services/voice/first-line-cache.d.ts.map +1 -0
  461. package/src/services/voice/first-line-cache.ts +725 -0
  462. package/src/services/voice/fused-eot-scorer.d.ts +51 -0
  463. package/src/services/voice/fused-eot-scorer.d.ts.map +1 -0
  464. package/src/services/voice/fused-eot-scorer.ts +135 -0
  465. package/src/services/voice/index.d.ts +91 -0
  466. package/src/services/voice/index.d.ts.map +1 -0
  467. package/src/services/voice/index.ts +481 -0
  468. package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +151 -0
  469. package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +151 -0
  470. package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.test.ts +60 -0
  471. package/src/services/voice/kokoro/__tests__/kokoro-engine-discovery.test.ts +277 -0
  472. package/src/services/voice/kokoro/__tests__/kokoro-ffi-runtime.test.ts +235 -0
  473. package/src/services/voice/kokoro/__tests__/kokoro-runtime.test.ts +95 -0
  474. package/src/services/voice/kokoro/__tests__/phonemizer.test.ts +53 -0
  475. package/src/services/voice/kokoro/__tests__/runtime-selection.test.ts +231 -0
  476. package/src/services/voice/kokoro/__tests__/voices.test.ts +57 -0
  477. package/src/services/voice/kokoro/index.ts +79 -0
  478. package/src/services/voice/kokoro/kokoro-backend.d.ts +72 -0
  479. package/src/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
  480. package/src/services/voice/kokoro/kokoro-backend.ts +207 -0
  481. package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts +58 -0
  482. package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
  483. package/src/services/voice/kokoro/kokoro-engine-discovery.ts +177 -0
  484. package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts +75 -0
  485. package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
  486. package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +233 -0
  487. package/src/services/voice/kokoro/kokoro-runtime.d.ts +100 -0
  488. package/src/services/voice/kokoro/kokoro-runtime.d.ts.map +1 -0
  489. package/src/services/voice/kokoro/kokoro-runtime.ts +170 -0
  490. package/src/services/voice/kokoro/phoneme-stream.ts +123 -0
  491. package/src/services/voice/kokoro/phonemizer.d.ts +50 -0
  492. package/src/services/voice/kokoro/phonemizer.d.ts.map +1 -0
  493. package/src/services/voice/kokoro/phonemizer.ts +344 -0
  494. package/src/services/voice/kokoro/pick-runtime.d.ts +61 -0
  495. package/src/services/voice/kokoro/pick-runtime.d.ts.map +1 -0
  496. package/src/services/voice/kokoro/pick-runtime.test.ts +91 -0
  497. package/src/services/voice/kokoro/pick-runtime.ts +130 -0
  498. package/src/services/voice/kokoro/runtime-selection.d.ts +92 -0
  499. package/src/services/voice/kokoro/runtime-selection.d.ts.map +1 -0
  500. package/src/services/voice/kokoro/runtime-selection.ts +237 -0
  501. package/src/services/voice/kokoro/types.d.ts +82 -0
  502. package/src/services/voice/kokoro/types.d.ts.map +1 -0
  503. package/src/services/voice/kokoro/types.ts +95 -0
  504. package/src/services/voice/kokoro/voice-presets.d.ts +23 -0
  505. package/src/services/voice/kokoro/voice-presets.d.ts.map +1 -0
  506. package/src/services/voice/kokoro/voice-presets.ts +129 -0
  507. package/src/services/voice/kokoro/voices.d.ts +30 -0
  508. package/src/services/voice/kokoro/voices.d.ts.map +1 -0
  509. package/src/services/voice/kokoro/voices.ts +64 -0
  510. package/src/services/voice/lifecycle.d.ts +135 -0
  511. package/src/services/voice/lifecycle.d.ts.map +1 -0
  512. package/src/services/voice/lifecycle.test.ts +315 -0
  513. package/src/services/voice/lifecycle.ts +301 -0
  514. package/src/services/voice/live-diarization-session.d.ts +96 -0
  515. package/src/services/voice/live-diarization-session.d.ts.map +1 -0
  516. package/src/services/voice/live-diarization-session.ts +289 -0
  517. package/src/services/voice/mic-source.d.ts +136 -0
  518. package/src/services/voice/mic-source.d.ts.map +1 -0
  519. package/src/services/voice/mic-source.test.ts +210 -0
  520. package/src/services/voice/mic-source.ts +503 -0
  521. package/src/services/voice/optimistic-policy.d.ts +109 -0
  522. package/src/services/voice/optimistic-policy.d.ts.map +1 -0
  523. package/src/services/voice/optimistic-policy.test.ts +101 -0
  524. package/src/services/voice/optimistic-policy.ts +192 -0
  525. package/src/services/voice/optimistic-rollback.ts +343 -0
  526. package/src/services/voice/partial-stabilizer.d.ts +73 -0
  527. package/src/services/voice/partial-stabilizer.d.ts.map +1 -0
  528. package/src/services/voice/partial-stabilizer.test.ts +68 -0
  529. package/src/services/voice/partial-stabilizer.ts +140 -0
  530. package/src/services/voice/phoneme-tokenizer.d.ts +49 -0
  531. package/src/services/voice/phoneme-tokenizer.d.ts.map +1 -0
  532. package/src/services/voice/phoneme-tokenizer.ts +158 -0
  533. package/src/services/voice/phrase-cache.d.ts +76 -0
  534. package/src/services/voice/phrase-cache.d.ts.map +1 -0
  535. package/src/services/voice/phrase-cache.test.ts +242 -0
  536. package/src/services/voice/phrase-cache.ts +186 -0
  537. package/src/services/voice/phrase-chunker.d.ts +62 -0
  538. package/src/services/voice/phrase-chunker.d.ts.map +1 -0
  539. package/src/services/voice/phrase-chunker.test.ts +239 -0
  540. package/src/services/voice/phrase-chunker.ts +281 -0
  541. package/src/services/voice/pipeline-impls.d.ts +151 -0
  542. package/src/services/voice/pipeline-impls.d.ts.map +1 -0
  543. package/src/services/voice/pipeline-impls.l6.test.ts +110 -0
  544. package/src/services/voice/pipeline-impls.test.ts +292 -0
  545. package/src/services/voice/pipeline-impls.ts +315 -0
  546. package/src/services/voice/pipeline.d.ts +216 -0
  547. package/src/services/voice/pipeline.d.ts.map +1 -0
  548. package/src/services/voice/pipeline.ts +505 -0
  549. package/src/services/voice/prefill-client.d.ts +123 -0
  550. package/src/services/voice/prefill-client.d.ts.map +1 -0
  551. package/src/services/voice/prefill-client.ts +316 -0
  552. package/src/services/voice/prefix-preserving-queue.d.ts +113 -0
  553. package/src/services/voice/prefix-preserving-queue.d.ts.map +1 -0
  554. package/src/services/voice/prefix-preserving-queue.ts +162 -0
  555. package/src/services/voice/profile-store.d.ts +248 -0
  556. package/src/services/voice/profile-store.d.ts.map +1 -0
  557. package/src/services/voice/profile-store.ts +887 -0
  558. package/src/services/voice/ring-buffer.d.ts +40 -0
  559. package/src/services/voice/ring-buffer.d.ts.map +1 -0
  560. package/src/services/voice/ring-buffer.ts +105 -0
  561. package/src/services/voice/rollback-queue.d.ts +24 -0
  562. package/src/services/voice/rollback-queue.d.ts.map +1 -0
  563. package/src/services/voice/rollback-queue.ts +74 -0
  564. package/src/services/voice/samantha-preset-placeholder.d.ts +67 -0
  565. package/src/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
  566. package/src/services/voice/samantha-preset-placeholder.test.ts +97 -0
  567. package/src/services/voice/samantha-preset-placeholder.ts +148 -0
  568. package/src/services/voice/samantha-preset-regenerator.d.ts +87 -0
  569. package/src/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
  570. package/src/services/voice/samantha-preset-regenerator.ts +393 -0
  571. package/src/services/voice/scheduler.d.ts +146 -0
  572. package/src/services/voice/scheduler.d.ts.map +1 -0
  573. package/src/services/voice/scheduler.t2.test.ts +141 -0
  574. package/src/services/voice/scheduler.ts +927 -0
  575. package/src/services/voice/shared-resources.d.ts +190 -0
  576. package/src/services/voice/shared-resources.d.ts.map +1 -0
  577. package/src/services/voice/shared-resources.ts +320 -0
  578. package/src/services/voice/speaker/attribution-pipeline.d.ts +74 -0
  579. package/src/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
  580. package/src/services/voice/speaker/attribution-pipeline.ts +386 -0
  581. package/src/services/voice/speaker/diarizer-fused.d.ts +59 -0
  582. package/src/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
  583. package/src/services/voice/speaker/diarizer-fused.real.test.ts +100 -0
  584. package/src/services/voice/speaker/diarizer-fused.ts +154 -0
  585. package/src/services/voice/speaker/diarizer.d.ts +75 -0
  586. package/src/services/voice/speaker/diarizer.d.ts.map +1 -0
  587. package/src/services/voice/speaker/diarizer.ts +218 -0
  588. package/src/services/voice/speaker/encoder-fused.d.ts +60 -0
  589. package/src/services/voice/speaker/encoder-fused.d.ts.map +1 -0
  590. package/src/services/voice/speaker/encoder-fused.real.test.ts +113 -0
  591. package/src/services/voice/speaker/encoder-fused.ts +138 -0
  592. package/src/services/voice/speaker/encoder-ggml.d.ts +33 -0
  593. package/src/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
  594. package/src/services/voice/speaker/encoder-ggml.ts +79 -0
  595. package/src/services/voice/speaker/encoder.d.ts +37 -0
  596. package/src/services/voice/speaker/encoder.d.ts.map +1 -0
  597. package/src/services/voice/speaker/encoder.ts +105 -0
  598. package/src/services/voice/speaker-imprint.d.ts +83 -0
  599. package/src/services/voice/speaker-imprint.d.ts.map +1 -0
  600. package/src/services/voice/speaker-imprint.test.ts +185 -0
  601. package/src/services/voice/speaker-imprint.ts +312 -0
  602. package/src/services/voice/speaker-preset-cache.d.ts +77 -0
  603. package/src/services/voice/speaker-preset-cache.d.ts.map +1 -0
  604. package/src/services/voice/speaker-preset-cache.test.ts +154 -0
  605. package/src/services/voice/speaker-preset-cache.ts +195 -0
  606. package/src/services/voice/streaming-asr/streaming-pipeline-adapter.ts +292 -0
  607. package/src/services/voice/system-audio-sink.d.ts +73 -0
  608. package/src/services/voice/system-audio-sink.d.ts.map +1 -0
  609. package/src/services/voice/system-audio-sink.test.ts +29 -0
  610. package/src/services/voice/system-audio-sink.ts +366 -0
  611. package/src/services/voice/transcriber.d.ts +244 -0
  612. package/src/services/voice/transcriber.d.ts.map +1 -0
  613. package/src/services/voice/transcriber.test.ts +392 -0
  614. package/src/services/voice/transcriber.ts +704 -0
  615. package/src/services/voice/turn-controller.d.ts +183 -0
  616. package/src/services/voice/turn-controller.d.ts.map +1 -0
  617. package/src/services/voice/turn-controller.test.ts +575 -0
  618. package/src/services/voice/turn-controller.ts +596 -0
  619. package/src/services/voice/types.d.ts +643 -0
  620. package/src/services/voice/types.d.ts.map +1 -0
  621. package/src/services/voice/types.ts +699 -0
  622. package/src/services/voice/vad.d.ts +282 -0
  623. package/src/services/voice/vad.d.ts.map +1 -0
  624. package/src/services/voice/vad.test.ts +480 -0
  625. package/src/services/voice/vad.ts +827 -0
  626. package/src/services/voice/vad.v1-v4.test.ts +222 -0
  627. package/src/services/voice/voice-budget.d.ts +241 -0
  628. package/src/services/voice/voice-budget.d.ts.map +1 -0
  629. package/src/services/voice/voice-budget.test.ts +420 -0
  630. package/src/services/voice/voice-budget.ts +656 -0
  631. package/src/services/voice/voice-duet.test.ts +375 -0
  632. package/src/services/voice/voice-emotion-classifier.d.ts +95 -0
  633. package/src/services/voice/voice-emotion-classifier.d.ts.map +1 -0
  634. package/src/services/voice/voice-emotion-classifier.test.ts +210 -0
  635. package/src/services/voice/voice-emotion-classifier.ts +273 -0
  636. package/src/services/voice/voice-preset-format.d.ts +158 -0
  637. package/src/services/voice/voice-preset-format.d.ts.map +1 -0
  638. package/src/services/voice/voice-preset-format.ts +700 -0
  639. package/src/services/voice/voice-preset-generator.test.ts +89 -0
  640. package/src/services/voice/voice-profile-artifact.d.ts +116 -0
  641. package/src/services/voice/voice-profile-artifact.d.ts.map +1 -0
  642. package/src/services/voice/voice-profile-artifact.test.ts +138 -0
  643. package/src/services/voice/voice-profile-artifact.ts +518 -0
  644. package/src/services/voice/voice-profile-routes.d.ts +83 -0
  645. package/src/services/voice/voice-profile-routes.d.ts.map +1 -0
  646. package/src/services/voice/voice-profile-routes.test.ts +429 -0
  647. package/src/services/voice/voice-profile-routes.ts +425 -0
  648. package/src/services/voice/voice-scenario.ts +154 -0
  649. package/src/services/voice/voice-settings.d.ts +82 -0
  650. package/src/services/voice/voice-settings.d.ts.map +1 -0
  651. package/src/services/voice/voice-settings.ts +172 -0
  652. package/src/services/voice/voice-state-machine.d.ts +364 -0
  653. package/src/services/voice/voice-state-machine.d.ts.map +1 -0
  654. package/src/services/voice/voice-state-machine.ts +727 -0
  655. package/src/services/voice/voice-workbench-report.test.ts +168 -0
  656. package/src/services/voice/voice-workbench-report.ts +326 -0
  657. package/src/services/voice/voice-workbench.test.ts +158 -0
  658. package/src/services/voice/voice.test.ts +1070 -0
  659. package/src/services/voice/wake-word-ggml.d.ts +101 -0
  660. package/src/services/voice/wake-word-ggml.d.ts.map +1 -0
  661. package/src/services/voice/wake-word-ggml.ts +320 -0
  662. package/src/services/voice/wake-word.d.ts +255 -0
  663. package/src/services/voice/wake-word.d.ts.map +1 -0
  664. package/src/services/voice/wake-word.test.ts +298 -0
  665. package/src/services/voice/wake-word.ts +554 -0
  666. package/src/services/voice/wrap-with-first-line-cache.d.ts +70 -0
  667. package/src/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
  668. package/src/services/voice/wrap-with-first-line-cache.ts +267 -0
  669. package/src/services/voice-model-updater.d.ts +240 -0
  670. package/src/services/voice-model-updater.d.ts.map +1 -0
  671. package/src/services/voice-model-updater.ts +724 -0
  672. package/src/services/voice-prewarm.d.ts +3 -0
  673. package/src/services/voice-prewarm.d.ts.map +1 -0
  674. package/src/services/voice-prewarm.ts +51 -0
  675. package/dist/index.d.ts +0 -37
  676. package/dist/index.js +0 -1098
@@ -0,0 +1,524 @@
1
+ /**
2
+ * Voice first-run HTTP routes.
3
+ *
4
+ * The flow (R2-speaker.md §6):
5
+ *
6
+ * POST /api/voice/first-run/profile/start
7
+ * → { sessionId, script: ScriptStep[], embeddingModel }
8
+ *
9
+ * POST /api/voice/first-run/profile/append?id=<sessionId>
10
+ * Content-Type: application/octet-stream
11
+ * Body: PCM (Float32, 16 kHz, mono) for one capture window
12
+ * → { sessionId, samplesReceived, totalSamples, durationMs }
13
+ *
14
+ * POST /api/voice/first-run/profile/finalize?id=<sessionId>&entityId=<id>
15
+ * → { profileId, entityId, samples, durationMs }
16
+ *
17
+ * POST /api/voice/first-run/complete
18
+ * Body: { entityId: string }
19
+ * → { ownerEntityId, settingsWritten: ["ELIZA_ADMIN_ENTITY_ID"] }
20
+ *
21
+ * Sessions are in-memory. They expire after 30 minutes of inactivity.
22
+ * The encoder is loaded lazily; the route handlers return a structured
23
+ * 503 if the native GGML library is missing.
24
+ *
25
+ * Audio storage: when the user grants `audioRefs` consent, sample WAVs
26
+ * land under `$ELIZA_STATE_DIR/voice-profiles/audio/<profileId>/...`.
27
+ * Otherwise nothing is written to disk except the centroid + variance.
28
+ */
29
+
30
+ import crypto from "node:crypto";
31
+ import type * as http from "node:http";
32
+ import path from "node:path";
33
+ import {
34
+ logger,
35
+ readJsonBody,
36
+ resolveStateDir,
37
+ sendJson,
38
+ sendJsonError,
39
+ } from "@elizaos/core";
40
+ import { resolveFusedLibraryPath } from "../services/desktop-fused-ffi-backend-runtime";
41
+ import { loadElizaInferenceFfi } from "../services/voice/ffi-bindings";
42
+ import { VoiceProfileStore } from "../services/voice/profile-store";
43
+ import {
44
+ averageEmbeddings,
45
+ type SpeakerEncoder,
46
+ SpeakerEncoderUnavailableError,
47
+ WESPEAKER_EMBEDDING_DIM,
48
+ WESPEAKER_MIN_SAMPLES,
49
+ WESPEAKER_RESNET34_LM_INT8_MODEL_ID,
50
+ WESPEAKER_SAMPLE_RATE,
51
+ } from "../services/voice/speaker/encoder";
52
+ import { FusedSpeakerEncoder } from "../services/voice/speaker/encoder-fused";
53
+
54
+ /** Verbatim first-run script (R2-speaker.md §6.2). */
55
+ export interface FirstRunScriptStep {
56
+ id: string;
57
+ role: "consent" | "calibration" | "phonetic" | "prosody" | "quiet" | "open";
58
+ prompt: string;
59
+ expectedDurationMs: number;
60
+ requiresUserSpeech: boolean;
61
+ }
62
+
63
+ export const FIRST_RUN_SCRIPT: ReadonlyArray<FirstRunScriptStep> = [
64
+ {
65
+ id: "consent-1",
66
+ role: "consent",
67
+ prompt:
68
+ "Before we start, I'd like to record a short voice sample so I can recognize you when you talk to me. The recording stays on this device. Is that okay?",
69
+ expectedDurationMs: 4_000,
70
+ requiresUserSpeech: true,
71
+ },
72
+ {
73
+ id: "consent-2",
74
+ role: "consent",
75
+ prompt:
76
+ "One more — do you want me to also be able to imitate your voice for outgoing messages? You can change this any time.",
77
+ expectedDurationMs: 4_000,
78
+ requiresUserSpeech: true,
79
+ },
80
+ {
81
+ id: "calibration",
82
+ role: "calibration",
83
+ prompt: 'Please say "Hello, my name is" and then your full name.',
84
+ expectedDurationMs: 5_000,
85
+ requiresUserSpeech: true,
86
+ },
87
+ {
88
+ id: "phonetic-1",
89
+ role: "phonetic",
90
+ prompt: '"The quick brown fox jumps over the lazy dog."',
91
+ expectedDurationMs: 10_000,
92
+ requiresUserSpeech: true,
93
+ },
94
+ {
95
+ id: "phonetic-2",
96
+ role: "phonetic",
97
+ prompt: '"Pack my box with five dozen liquor jugs."',
98
+ expectedDurationMs: 10_000,
99
+ requiresUserSpeech: true,
100
+ },
101
+ {
102
+ id: "phonetic-3",
103
+ role: "phonetic",
104
+ prompt: '"How razorback-jumping frogs can level six piqued gymnasts."',
105
+ expectedDurationMs: 10_000,
106
+ requiresUserSpeech: true,
107
+ },
108
+ {
109
+ id: "prosody-1",
110
+ role: "prosody",
111
+ prompt: '"Did you remember to lock the back door?"',
112
+ expectedDurationMs: 7_500,
113
+ requiresUserSpeech: true,
114
+ },
115
+ {
116
+ id: "prosody-2",
117
+ role: "prosody",
118
+ prompt:
119
+ '"I left the keys on the kitchen counter, near the coffee machine."',
120
+ expectedDurationMs: 7_500,
121
+ requiresUserSpeech: true,
122
+ },
123
+ {
124
+ id: "quiet",
125
+ role: "quiet",
126
+ prompt:
127
+ 'Now read this one as if someone next to you is sleeping: "Just checking in quickly — everything\'s fine, talk to you tomorrow."',
128
+ expectedDurationMs: 10_000,
129
+ requiresUserSpeech: true,
130
+ },
131
+ {
132
+ id: "open",
133
+ role: "open",
134
+ prompt:
135
+ "Last one — tell me, in your own words, what you'd like me to help with most in the next few weeks.",
136
+ expectedDurationMs: 15_000,
137
+ requiresUserSpeech: true,
138
+ },
139
+ ];
140
+
141
+ const SESSION_TIMEOUT_MS = 30 * 60 * 1000;
142
+
143
+ interface FirstRunSession {
144
+ id: string;
145
+ createdAt: number;
146
+ lastAccessedAt: number;
147
+ embeddings: Float32Array[];
148
+ totalSamples: number;
149
+ totalDurationMs: number;
150
+ consent: {
151
+ attributionAuthorized: boolean;
152
+ synthesisAuthorized: boolean;
153
+ };
154
+ }
155
+
156
+ const sessions = new Map<string, FirstRunSession>();
157
+
158
+ function pruneExpiredSessions(now: number): void {
159
+ for (const [id, session] of sessions.entries()) {
160
+ if (now - session.lastAccessedAt > SESSION_TIMEOUT_MS) {
161
+ sessions.delete(id);
162
+ }
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Encoder factory. By default the route handlers load the WeSpeaker
168
+ * ResNet34-LM speaker encoder through the fused `libelizainference`
169
+ * `eliza_inference_speaker_*` ABI — the sole on-device speaker runtime.
170
+ * Tests inject a fake encoder via `setVoiceFirstRunEncoderFactory()`.
171
+ */
172
+ export type EncoderFactory = () => Promise<SpeakerEncoder>;
173
+
174
+ let encoderFactoryOverride: EncoderFactory | null = null;
175
+ let cachedEncoder: SpeakerEncoder | null = null;
176
+
177
+ export function setVoiceFirstRunEncoderFactory(
178
+ factory: EncoderFactory | null,
179
+ ): void {
180
+ encoderFactoryOverride = factory;
181
+ cachedEncoder = null;
182
+ }
183
+
184
+ async function loadEncoder(): Promise<SpeakerEncoder> {
185
+ if (cachedEncoder) return cachedEncoder;
186
+ if (encoderFactoryOverride) {
187
+ cachedEncoder = await encoderFactoryOverride();
188
+ return cachedEncoder;
189
+ }
190
+ cachedEncoder = await loadFusedSpeakerEncoder();
191
+ return cachedEncoder;
192
+ }
193
+
194
+ /**
195
+ * Load the fused speaker encoder. Resolves the fused `libelizainference`,
196
+ * creates a context anchored at the voice-profiles dir, and probes the speaker
197
+ * ABI up front: a build that lacks `eliza_inference_speaker_*` raises a
198
+ * structured `SpeakerEncoderUnavailableError` (the route surfaces it as a 503)
199
+ * instead of silently degrading. There is no standalone-lib fallback.
200
+ */
201
+ async function loadFusedSpeakerEncoder(): Promise<SpeakerEncoder> {
202
+ const bundleRoot = path.join(resolveStateDir(), "voice-profiles");
203
+ const libPath = resolveFusedLibraryPath(bundleRoot);
204
+ if (!libPath) {
205
+ throw new SpeakerEncoderUnavailableError(
206
+ "library-missing",
207
+ "[voice-first-run] fused libelizainference not found. Set $ELIZA_INFERENCE_LIBRARY (exact path) or $ELIZA_INFERENCE_LIB_DIR, or build it via packages/app-core/scripts/build-llama-cpp-mtp.mjs.",
208
+ );
209
+ }
210
+ const ffi = loadElizaInferenceFfi(libPath);
211
+ if (!FusedSpeakerEncoder.isSupported(ffi)) {
212
+ throw new SpeakerEncoderUnavailableError(
213
+ "native-missing",
214
+ `[voice-first-run] the fused libelizainference at ${libPath} (ABI v${ffi.libraryAbiVersion}) lacks the speaker ABI (eliza_inference_speaker_supported() == 0). Rebuild with the WeSpeaker forward graph linked in.`,
215
+ );
216
+ }
217
+ const ctx = ffi.create(bundleRoot);
218
+ return FusedSpeakerEncoder.load({ ffi, ctx });
219
+ }
220
+
221
+ let profileStoreOverride: VoiceProfileStore | null = null;
222
+
223
+ export function setVoiceFirstRunProfileStore(
224
+ store: VoiceProfileStore | null,
225
+ ): void {
226
+ profileStoreOverride = store;
227
+ }
228
+
229
+ async function getProfileStore(): Promise<VoiceProfileStore> {
230
+ if (profileStoreOverride) return profileStoreOverride;
231
+ const store = new VoiceProfileStore({
232
+ rootDir: path.join(resolveStateDir(), "voice-profiles"),
233
+ });
234
+ await store.init();
235
+ return store;
236
+ }
237
+
238
+ /** Settings-write hook. The runtime overrides this with `runtime.setSetting`. */
239
+ type SettingsWriter = (key: string, value: string) => void | Promise<void>;
240
+ let settingsWriter: SettingsWriter | null = null;
241
+
242
+ export function setVoiceFirstRunSettingsWriter(
243
+ writer: SettingsWriter | null,
244
+ ): void {
245
+ settingsWriter = writer;
246
+ }
247
+
248
+ function startSession(consent: FirstRunSession["consent"]): FirstRunSession {
249
+ const id = `obs_${crypto.randomUUID()}`;
250
+ const now = Date.now();
251
+ const session: FirstRunSession = {
252
+ id,
253
+ createdAt: now,
254
+ lastAccessedAt: now,
255
+ embeddings: [],
256
+ totalSamples: 0,
257
+ totalDurationMs: 0,
258
+ consent,
259
+ };
260
+ sessions.set(id, session);
261
+ return session;
262
+ }
263
+
264
+ function decodeFloat32(buf: Buffer): Float32Array {
265
+ if (buf.byteLength % 4 !== 0) {
266
+ throw new Error(
267
+ `[voice-first-run] PCM buffer length ${buf.byteLength} is not a multiple of 4`,
268
+ );
269
+ }
270
+ // Copy into an owned Float32Array (Buffer.buffer may have an offset).
271
+ const out = new Float32Array(buf.byteLength / 4);
272
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
273
+ for (let i = 0; i < out.length; i += 1) {
274
+ out[i] = view.getFloat32(i * 4, true);
275
+ }
276
+ return out;
277
+ }
278
+
279
+ async function readBinaryBody(req: http.IncomingMessage): Promise<Buffer> {
280
+ const chunks: Buffer[] = [];
281
+ for await (const chunk of req) {
282
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
283
+ }
284
+ return Buffer.concat(chunks);
285
+ }
286
+
287
+ /**
288
+ * Mount-point: returns `true` if the request was handled, `false` if
289
+ * the path is not one of the voice-first-run routes (so the caller
290
+ * can fall through to the next handler).
291
+ */
292
+ export async function handleVoiceFirstRunRoutes(
293
+ req: http.IncomingMessage,
294
+ res: http.ServerResponse,
295
+ ): Promise<boolean> {
296
+ const method = (req.method ?? "GET").toUpperCase();
297
+ const url = new URL(req.url ?? "/", "http://localhost");
298
+ const pathname = url.pathname;
299
+ if (!pathname.startsWith("/api/voice/first-run/")) return false;
300
+
301
+ pruneExpiredSessions(Date.now());
302
+
303
+ if (method === "POST" && pathname === "/api/voice/first-run/profile/start") {
304
+ // Empty body is valid here (the consent flags default to a safe
305
+ // "attribution-yes / synthesis-no" pair). We read the body only when
306
+ // the caller has actually sent one — otherwise `readJsonBody` would
307
+ // emit a 400 for the empty string and then we'd double-write below.
308
+ const hasJsonBody =
309
+ (req.headers["content-type"] ?? "").includes("application/json") &&
310
+ req.headers["content-length"] !== "0";
311
+ const body = hasJsonBody
312
+ ? await readJsonBody<Record<string, unknown>>(req, res, {
313
+ requireObject: false,
314
+ })
315
+ : null;
316
+ // If the body read failed, `readJsonBody` already sent a 4xx.
317
+ if (hasJsonBody && body === null) return true;
318
+ const consent = {
319
+ attributionAuthorized:
320
+ typeof body?.attributionAuthorized === "boolean"
321
+ ? body.attributionAuthorized
322
+ : true,
323
+ synthesisAuthorized:
324
+ typeof body?.synthesisAuthorized === "boolean"
325
+ ? body.synthesisAuthorized
326
+ : false,
327
+ };
328
+ const session = startSession(consent);
329
+ sendJson(res, {
330
+ sessionId: session.id,
331
+ script: FIRST_RUN_SCRIPT,
332
+ embeddingModel: WESPEAKER_RESNET34_LM_INT8_MODEL_ID,
333
+ expectedSampleRate: WESPEAKER_SAMPLE_RATE,
334
+ minSamplesPerCapture: WESPEAKER_MIN_SAMPLES,
335
+ });
336
+ return true;
337
+ }
338
+
339
+ if (method === "POST" && pathname === "/api/voice/first-run/profile/append") {
340
+ const sessionId = url.searchParams.get("id");
341
+ if (!sessionId) {
342
+ sendJsonError(res, "id query parameter is required");
343
+ return true;
344
+ }
345
+ const session = sessions.get(sessionId);
346
+ if (!session) {
347
+ sendJsonError(res, "session not found", 404);
348
+ return true;
349
+ }
350
+ let buffer: Buffer;
351
+ try {
352
+ buffer = await readBinaryBody(req);
353
+ } catch (err) {
354
+ sendJsonError(
355
+ res,
356
+ err instanceof Error ? err.message : "failed to read body",
357
+ 400,
358
+ );
359
+ return true;
360
+ }
361
+ let pcm: Float32Array;
362
+ try {
363
+ pcm = decodeFloat32(buffer);
364
+ } catch (err) {
365
+ sendJsonError(
366
+ res,
367
+ err instanceof Error ? err.message : "invalid PCM body",
368
+ 400,
369
+ );
370
+ return true;
371
+ }
372
+ if (pcm.length < WESPEAKER_MIN_SAMPLES) {
373
+ sendJsonError(
374
+ res,
375
+ `capture too short: ${pcm.length} samples (< ${WESPEAKER_MIN_SAMPLES})`,
376
+ 400,
377
+ );
378
+ return true;
379
+ }
380
+ let encoder: SpeakerEncoder;
381
+ try {
382
+ encoder = await loadEncoder();
383
+ } catch (err) {
384
+ if (err instanceof SpeakerEncoderUnavailableError) {
385
+ sendJsonError(res, err.message, 503);
386
+ return true;
387
+ }
388
+ throw err;
389
+ }
390
+ try {
391
+ const embedding = await encoder.encode(pcm);
392
+ session.embeddings.push(embedding);
393
+ session.totalSamples += pcm.length;
394
+ session.totalDurationMs += Math.round(
395
+ (pcm.length / WESPEAKER_SAMPLE_RATE) * 1000,
396
+ );
397
+ session.lastAccessedAt = Date.now();
398
+ sendJson(res, {
399
+ sessionId: session.id,
400
+ samplesReceived: session.embeddings.length,
401
+ totalSamples: session.totalSamples,
402
+ durationMs: session.totalDurationMs,
403
+ });
404
+ } catch (err) {
405
+ if (err instanceof SpeakerEncoderUnavailableError) {
406
+ sendJsonError(
407
+ res,
408
+ err.message,
409
+ err.code === "invalid-input" ? 400 : 503,
410
+ );
411
+ return true;
412
+ }
413
+ throw err;
414
+ }
415
+ return true;
416
+ }
417
+
418
+ if (
419
+ method === "POST" &&
420
+ pathname === "/api/voice/first-run/profile/finalize"
421
+ ) {
422
+ const sessionId = url.searchParams.get("id");
423
+ const entityId = url.searchParams.get("entityId");
424
+ if (!sessionId) {
425
+ sendJsonError(res, "id query parameter is required");
426
+ return true;
427
+ }
428
+ const session = sessions.get(sessionId);
429
+ if (!session) {
430
+ sendJsonError(res, "session not found", 404);
431
+ return true;
432
+ }
433
+ if (session.embeddings.length === 0) {
434
+ sendJsonError(res, "no embeddings captured yet", 400);
435
+ return true;
436
+ }
437
+ let centroid: Float32Array;
438
+ try {
439
+ centroid = averageEmbeddings(session.embeddings);
440
+ } catch (err) {
441
+ sendJsonError(
442
+ res,
443
+ err instanceof Error ? err.message : "failed to compute centroid",
444
+ 400,
445
+ );
446
+ return true;
447
+ }
448
+ if (centroid.length !== WESPEAKER_EMBEDDING_DIM) {
449
+ sendJsonError(
450
+ res,
451
+ `centroid dim mismatch: ${centroid.length} != ${WESPEAKER_EMBEDDING_DIM}`,
452
+ 500,
453
+ );
454
+ return true;
455
+ }
456
+ const store = await getProfileStore();
457
+ const profile = await store.createProfile({
458
+ centroid,
459
+ embeddingModel: WESPEAKER_RESNET34_LM_INT8_MODEL_ID,
460
+ entityId: entityId ?? null,
461
+ confidence: 0.95,
462
+ durationMs: session.totalDurationMs,
463
+ consent: {
464
+ attributionAuthorized: session.consent.attributionAuthorized,
465
+ synthesisAuthorized: session.consent.synthesisAuthorized,
466
+ grantedAt: new Date().toISOString(),
467
+ grantedBy: entityId ?? undefined,
468
+ },
469
+ });
470
+ sessions.delete(sessionId);
471
+ sendJson(res, {
472
+ profileId: profile.profileId,
473
+ entityId: profile.entityId,
474
+ samples: profile.sampleCount,
475
+ durationMs: profile.totalDurationMs,
476
+ });
477
+ return true;
478
+ }
479
+
480
+ if (method === "POST" && pathname === "/api/voice/first-run/complete") {
481
+ const body = await readJsonBody<Record<string, unknown>>(req, res);
482
+ if (!body) return true;
483
+ const entityId =
484
+ typeof body.entityId === "string" ? body.entityId.trim() : "";
485
+ if (!entityId) {
486
+ sendJsonError(res, "entityId is required", 400);
487
+ return true;
488
+ }
489
+ if (!settingsWriter) {
490
+ sendJsonError(
491
+ res,
492
+ "voice first-run settings writer not configured; runtime must call setVoiceFirstRunSettingsWriter()",
493
+ 503,
494
+ );
495
+ return true;
496
+ }
497
+ try {
498
+ await settingsWriter("ELIZA_ADMIN_ENTITY_ID", entityId);
499
+ } catch (err) {
500
+ logger.error(
501
+ { err },
502
+ "[voice-first-run] failed to write ELIZA_ADMIN_ENTITY_ID",
503
+ );
504
+ sendJsonError(
505
+ res,
506
+ err instanceof Error ? err.message : "failed to write owner entity id",
507
+ 500,
508
+ );
509
+ return true;
510
+ }
511
+ sendJson(res, {
512
+ ownerEntityId: entityId,
513
+ settingsWritten: ["ELIZA_ADMIN_ENTITY_ID"],
514
+ });
515
+ return true;
516
+ }
517
+
518
+ return false;
519
+ }
520
+
521
+ /** Test helper: clear in-memory sessions so a test starts clean. */
522
+ export function __resetVoiceFirstRunSessions(): void {
523
+ sessions.clear();
524
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Local-runtime compat routes for the voice sub-model auto-updater
3
+ * (R5-versioning §3 + §4 + §5).
4
+ *
5
+ * Mirrors the signed Cloud catalog endpoint
6
+ * (`cloud/apps/api/v1/voice-models/catalog/route.ts`) for the on-device
7
+ * surface so the UI can talk to the local runtime without depending on
8
+ * Cloud being reachable. The endpoints expose:
9
+ *
10
+ * GET /api/local-inference/voice-models
11
+ * → { installations: VoiceModelInstallationView[] }
12
+ * Resolves currently-installed versions by reading the bundle voice
13
+ * directory (`<state-dir>/models/voice/`) and matching filenames
14
+ * against `VOICE_MODEL_VERSIONS`.
15
+ *
16
+ * GET /api/local-inference/voice-models/check
17
+ * → { lastCheckedAt, statuses: VoiceModelStatus[] }
18
+ * Invokes `VoiceModelUpdater.check()` which walks the cascade
19
+ * (Cloud → GitHub → HF) and returns a per-id decision.
20
+ *
21
+ * POST /api/local-inference/voice-models/:id/update
22
+ * → { ok: true, finalPath, sha256, sizeBytes }
23
+ * Triggers `downloadVoiceModel()` for the named id, gated on
24
+ * `NetworkPolicy` evaluation per R5 §4. Refuses when the policy
25
+ * decision is not `allow=true`.
26
+ *
27
+ * POST /api/local-inference/voice-models/:id/pin
28
+ * Body: { pinned: boolean }
29
+ * → { ok: true, id, pinned }
30
+ * Toggles the on-disk pin file so the auto-updater skips this id.
31
+ *
32
+ * GET /api/local-inference/voice-models/preferences
33
+ * → { preferences: NetworkPolicyPreferences, isOwner: boolean }
34
+ *
35
+ * POST /api/local-inference/voice-models/preferences
36
+ * Body: Partial<NetworkPolicyPreferences>
37
+ * → { ok: true, preferences }
38
+ * Writes the user's Wi-Fi/cellular/metered policy preferences.
39
+ * Per R5 §5.4 the cellular + metered toggles are OWNER-only — the
40
+ * route returns 403 if a non-OWNER caller tries to flip them.
41
+ *
42
+ * Preferences land at
43
+ * `<state-dir>/local-inference/voice-update-prefs.json`; the pin set is
44
+ * stored as a sibling `voice-update-pins.json`.
45
+ */
46
+ import type * as http from "node:http";
47
+ import { type VoiceModelId } from "@elizaos/shared";
48
+ import { downloadVoiceModel, VoiceModelUpdater } from "../services/voice-model-updater";
49
+ export interface VoiceModelInstallationView {
50
+ readonly id: VoiceModelId;
51
+ readonly installedVersion: string | null;
52
+ readonly pinned: boolean;
53
+ readonly lastError: string | null;
54
+ }
55
+ export declare function resolveInstalledVersions(dir?: string): Promise<Map<VoiceModelId, string>>;
56
+ export declare function setVoiceModelsUpdater(updater: VoiceModelUpdater | null): void;
57
+ type DownloadFn = typeof downloadVoiceModel;
58
+ export declare function setVoiceModelDownloader(fn: DownloadFn | null): void;
59
+ export declare function setVoiceModelsBundleVersionForTest(bundleVersion: string | null): void;
60
+ export declare function handleVoiceModelsRoutes(req: http.IncomingMessage, res: http.ServerResponse): Promise<boolean>;
61
+ export {};
62
+ //# sourceMappingURL=voice-models-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-models-routes.d.ts","sourceRoot":"","sources":["voice-models-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAQvC,OAAO,EAIN,KAAK,YAAY,EAEjB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,kBAAkB,EAGlB,iBAAiB,EACjB,MAAM,iCAAiC,CAAC;AAUzC,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAgKD,wBAAsB,wBAAwB,CAC7C,GAAG,GAAE,MAAyB,GAC5B,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAmBpC;AAQD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAE7E;AAYD,KAAK,UAAU,GAAG,OAAO,kBAAkB,CAAC;AAG5C,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAEnE;AAYD,wBAAgB,kCAAkC,CACjD,aAAa,EAAE,MAAM,GAAG,IAAI,GAC1B,IAAI,CAEN;AAWD,wBAAsB,uBAAuB,CAC5C,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAsNlB"}