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

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 (893) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -0
  3. package/dist/actions/generate-media.d.ts +59 -0
  4. package/dist/actions/generate-media.d.ts.map +1 -0
  5. package/dist/actions/identify-speaker.d.ts +23 -0
  6. package/dist/actions/identify-speaker.d.ts.map +1 -0
  7. package/dist/actions/transcription-control.d.ts +29 -0
  8. package/dist/actions/transcription-control.d.ts.map +1 -0
  9. package/dist/adapters/capacitor-llama/environment.d.ts +12 -0
  10. package/dist/adapters/capacitor-llama/environment.d.ts.map +1 -0
  11. package/dist/adapters/capacitor-llama/index.browser.d.ts +9 -0
  12. package/dist/adapters/capacitor-llama/index.browser.d.ts.map +1 -0
  13. package/dist/adapters/capacitor-llama/index.d.ts +18 -0
  14. package/dist/adapters/capacitor-llama/index.d.ts.map +1 -0
  15. package/dist/adapters/capacitor-llama/loader.d.ts +35 -0
  16. package/dist/adapters/capacitor-llama/loader.d.ts.map +1 -0
  17. package/dist/adapters/capacitor-llama/native-voice-capture.d.ts +70 -0
  18. package/dist/adapters/capacitor-llama/native-voice-capture.d.ts.map +1 -0
  19. package/dist/adapters/capacitor-llama/structured-output.d.ts +62 -0
  20. package/dist/adapters/capacitor-llama/structured-output.d.ts.map +1 -0
  21. package/dist/adapters/capacitor-llama/text-streaming.d.ts +24 -0
  22. package/dist/adapters/capacitor-llama/text-streaming.d.ts.map +1 -0
  23. package/dist/adapters/capacitor-llama/types.d.ts +338 -0
  24. package/dist/adapters/capacitor-llama/types.d.ts.map +1 -0
  25. package/dist/adapters/capacitor-llama/voice-turn.d.ts +86 -0
  26. package/dist/adapters/capacitor-llama/voice-turn.d.ts.map +1 -0
  27. package/dist/backends/apple-foundation.d.ts +56 -0
  28. package/dist/backends/apple-foundation.d.ts.map +1 -0
  29. package/dist/index.d.ts +8 -37
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +38979 -430
  32. package/dist/index.js.map +217 -0
  33. package/dist/local-inference-routes.d.ts +47 -0
  34. package/dist/local-inference-routes.d.ts.map +1 -0
  35. package/dist/provider.d.ts +21 -0
  36. package/dist/provider.d.ts.map +1 -0
  37. package/dist/routes/compat-helpers.d.ts +18 -0
  38. package/dist/routes/compat-helpers.d.ts.map +1 -0
  39. package/dist/routes/family-member-route.d.ts +62 -0
  40. package/dist/routes/family-member-route.d.ts.map +1 -0
  41. package/dist/routes/index.d.ts +20 -0
  42. package/dist/routes/index.d.ts.map +1 -0
  43. package/dist/routes/index.js +42040 -0
  44. package/dist/routes/index.js.map +236 -0
  45. package/dist/routes/live-diarization-route.d.ts +33 -0
  46. package/dist/routes/live-diarization-route.d.ts.map +1 -0
  47. package/dist/routes/local-inference-asr-route.d.ts +4 -0
  48. package/dist/routes/local-inference-asr-route.d.ts.map +1 -0
  49. package/dist/routes/local-inference-asr-transcribe.d.ts +20 -0
  50. package/dist/routes/local-inference-asr-transcribe.d.ts.map +1 -0
  51. package/dist/routes/local-inference-compat-routes.d.ts +16 -0
  52. package/dist/routes/local-inference-compat-routes.d.ts.map +1 -0
  53. package/dist/routes/local-inference-tts-route.d.ts +7 -0
  54. package/dist/routes/local-inference-tts-route.d.ts.map +1 -0
  55. package/dist/routes/native-pcm-turn-route.d.ts +3 -0
  56. package/dist/routes/native-pcm-turn-route.d.ts.map +1 -0
  57. package/dist/routes/transcript-audio-store.d.ts +15 -0
  58. package/dist/routes/transcript-audio-store.d.ts.map +1 -0
  59. package/dist/routes/transcripts-routes.d.ts +44 -0
  60. package/dist/routes/transcripts-routes.d.ts.map +1 -0
  61. package/dist/routes/voice-first-run-routes.d.ts +62 -0
  62. package/dist/routes/voice-first-run-routes.d.ts.map +1 -0
  63. package/dist/routes/voice-models-routes.d.ts +62 -0
  64. package/dist/routes/voice-models-routes.d.ts.map +1 -0
  65. package/dist/routes/voice-profile-plugin-routes.d.ts +19 -0
  66. package/dist/routes/voice-profile-plugin-routes.d.ts.map +1 -0
  67. package/dist/routes/voice-profiles-management-routes.d.ts +52 -0
  68. package/dist/routes/voice-profiles-management-routes.d.ts.map +1 -0
  69. package/dist/routes/voice-speaker-profile-routes.d.ts +57 -0
  70. package/dist/routes/voice-speaker-profile-routes.d.ts.map +1 -0
  71. package/dist/runtime/embedding-manager-support.d.ts +77 -0
  72. package/dist/runtime/embedding-manager-support.d.ts.map +1 -0
  73. package/dist/runtime/embedding-presets.d.ts +16 -0
  74. package/dist/runtime/embedding-presets.d.ts.map +1 -0
  75. package/dist/runtime/embedding-warmup-policy.d.ts +14 -0
  76. package/dist/runtime/embedding-warmup-policy.d.ts.map +1 -0
  77. package/dist/runtime/ensure-local-inference-handler.d.ts +70 -0
  78. package/dist/runtime/ensure-local-inference-handler.d.ts.map +1 -0
  79. package/dist/runtime/index.d.ts +15 -0
  80. package/dist/runtime/index.d.ts.map +1 -0
  81. package/dist/runtime/index.js +38768 -0
  82. package/dist/runtime/index.js.map +217 -0
  83. package/dist/runtime/mobile-local-inference-gate.d.ts +63 -0
  84. package/dist/runtime/mobile-local-inference-gate.d.ts.map +1 -0
  85. package/dist/runtime/voice-entity-binding.d.ts +113 -0
  86. package/dist/runtime/voice-entity-binding.d.ts.map +1 -0
  87. package/dist/services/active-model.d.ts +310 -0
  88. package/dist/services/active-model.d.ts.map +1 -0
  89. package/dist/services/asr-provenance.d.ts +5 -0
  90. package/dist/services/asr-provenance.d.ts.map +1 -0
  91. package/dist/services/assignments.d.ts +84 -0
  92. package/dist/services/assignments.d.ts.map +1 -0
  93. package/dist/services/backend-selector.d.ts +55 -0
  94. package/dist/services/backend-selector.d.ts.map +1 -0
  95. package/dist/services/backend.d.ts +440 -0
  96. package/dist/services/backend.d.ts.map +1 -0
  97. package/dist/services/bionic-host-loader.d.ts +67 -0
  98. package/dist/services/bionic-host-loader.d.ts.map +1 -0
  99. package/dist/services/bundled-models.d.ts +34 -0
  100. package/dist/services/bundled-models.d.ts.map +1 -0
  101. package/dist/services/cache-bridge.d.ts +206 -0
  102. package/dist/services/cache-bridge.d.ts.map +1 -0
  103. package/dist/services/catalog.d.ts +10 -0
  104. package/dist/services/catalog.d.ts.map +1 -0
  105. package/dist/services/checkpoint-client.d.ts +109 -0
  106. package/dist/services/checkpoint-client.d.ts.map +1 -0
  107. package/dist/services/checkpoint-manager.d.ts +217 -0
  108. package/dist/services/checkpoint-manager.d.ts.map +1 -0
  109. package/dist/services/cloud-fallback.d.ts +102 -0
  110. package/dist/services/cloud-fallback.d.ts.map +1 -0
  111. package/dist/services/context-fit.d.ts +36 -0
  112. package/dist/services/context-fit.d.ts.map +1 -0
  113. package/dist/services/conversation-registry.d.ts +142 -0
  114. package/dist/services/conversation-registry.d.ts.map +1 -0
  115. package/dist/services/desktop-fused-ffi-backend-runtime.d.ts +111 -0
  116. package/dist/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
  117. package/dist/services/device-bridge.d.ts +188 -0
  118. package/dist/services/device-bridge.d.ts.map +1 -0
  119. package/dist/services/device-resource-metrics.d.ts +149 -0
  120. package/dist/services/device-resource-metrics.d.ts.map +1 -0
  121. package/dist/services/device-tier.d.ts +133 -0
  122. package/dist/services/device-tier.d.ts.map +1 -0
  123. package/dist/services/downloader.d.ts +94 -0
  124. package/dist/services/downloader.d.ts.map +1 -0
  125. package/dist/services/engine.d.ts +579 -0
  126. package/dist/services/engine.d.ts.map +1 -0
  127. package/dist/services/ensure-local-artifacts.d.ts +82 -0
  128. package/dist/services/ensure-local-artifacts.d.ts.map +1 -0
  129. package/dist/services/external-scanner.d.ts +17 -0
  130. package/dist/services/external-scanner.d.ts.map +1 -0
  131. package/dist/services/ffi-llm-mock.d.ts +90 -0
  132. package/dist/services/ffi-llm-mock.d.ts.map +1 -0
  133. package/dist/services/ffi-llm-streaming-abi.d.ts +318 -0
  134. package/dist/services/ffi-llm-streaming-abi.d.ts.map +1 -0
  135. package/dist/services/ffi-streaming-backend.d.ts +201 -0
  136. package/dist/services/ffi-streaming-backend.d.ts.map +1 -0
  137. package/dist/services/ffi-streaming-runner.d.ts +146 -0
  138. package/dist/services/ffi-streaming-runner.d.ts.map +1 -0
  139. package/dist/services/gpu-autotune.d.ts +150 -0
  140. package/dist/services/gpu-autotune.d.ts.map +1 -0
  141. package/dist/services/gpu-detect.d.ts +56 -0
  142. package/dist/services/gpu-detect.d.ts.map +1 -0
  143. package/dist/services/handler-registry.d.ts +72 -0
  144. package/dist/services/handler-registry.d.ts.map +1 -0
  145. package/dist/services/hardware.d.ts +63 -0
  146. package/dist/services/hardware.d.ts.map +1 -0
  147. package/dist/services/image-description-runtime.d.ts +14 -0
  148. package/dist/services/image-description-runtime.d.ts.map +1 -0
  149. package/dist/services/imagegen/aosp-unavailable.d.ts +134 -0
  150. package/dist/services/imagegen/aosp-unavailable.d.ts.map +1 -0
  151. package/dist/services/imagegen/backend-selector.d.ts +118 -0
  152. package/dist/services/imagegen/backend-selector.d.ts.map +1 -0
  153. package/dist/services/imagegen/coreml-unavailable.d.ts +105 -0
  154. package/dist/services/imagegen/coreml-unavailable.d.ts.map +1 -0
  155. package/dist/services/imagegen/errors.d.ts +16 -0
  156. package/dist/services/imagegen/errors.d.ts.map +1 -0
  157. package/dist/services/imagegen/index.d.ts +58 -0
  158. package/dist/services/imagegen/index.d.ts.map +1 -0
  159. package/dist/services/imagegen/mflux.d.ts +74 -0
  160. package/dist/services/imagegen/mflux.d.ts.map +1 -0
  161. package/dist/services/imagegen/sd-cpp.d.ts +181 -0
  162. package/dist/services/imagegen/sd-cpp.d.ts.map +1 -0
  163. package/dist/services/imagegen/tensorrt-unavailable.d.ts +83 -0
  164. package/dist/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
  165. package/dist/services/imagegen/types.d.ts +181 -0
  166. package/dist/services/imagegen/types.d.ts.map +1 -0
  167. package/dist/services/index.d.ts +31 -0
  168. package/dist/services/index.d.ts.map +1 -0
  169. package/dist/services/index.js +39453 -0
  170. package/dist/services/index.js.map +227 -0
  171. package/dist/services/inference-capabilities.d.ts +132 -0
  172. package/dist/services/inference-capabilities.d.ts.map +1 -0
  173. package/dist/services/inference-telemetry.d.ts +59 -0
  174. package/dist/services/inference-telemetry.d.ts.map +1 -0
  175. package/dist/services/ios-llama-streaming.d.ts +119 -0
  176. package/dist/services/ios-llama-streaming.d.ts.map +1 -0
  177. package/dist/services/kv-spill.d.ts +189 -0
  178. package/dist/services/kv-spill.d.ts.map +1 -0
  179. package/dist/services/latency-trace.d.ts +346 -0
  180. package/dist/services/latency-trace.d.ts.map +1 -0
  181. package/dist/services/lib-target.d.ts +55 -0
  182. package/dist/services/lib-target.d.ts.map +1 -0
  183. package/dist/services/live-signals.d.ts +86 -0
  184. package/dist/services/live-signals.d.ts.map +1 -0
  185. package/dist/services/llama-server-metrics.d.ts +114 -0
  186. package/dist/services/llama-server-metrics.d.ts.map +1 -0
  187. package/dist/services/llm-streaming-binding.d.ts +96 -0
  188. package/dist/services/llm-streaming-binding.d.ts.map +1 -0
  189. package/dist/services/load-args.d.ts +82 -0
  190. package/dist/services/load-args.d.ts.map +1 -0
  191. package/dist/services/manifest/index.d.ts +4 -0
  192. package/dist/services/manifest/index.d.ts.map +1 -0
  193. package/dist/services/manifest/schema.d.ts +903 -0
  194. package/dist/services/manifest/schema.d.ts.map +1 -0
  195. package/dist/services/manifest/types.d.ts +32 -0
  196. package/dist/services/manifest/types.d.ts.map +1 -0
  197. package/dist/services/manifest/validator.d.ts +66 -0
  198. package/dist/services/manifest/validator.d.ts.map +1 -0
  199. package/dist/services/memory-arbiter.d.ts +348 -0
  200. package/dist/services/memory-arbiter.d.ts.map +1 -0
  201. package/dist/services/memory-benchmark.d.ts +76 -0
  202. package/dist/services/memory-benchmark.d.ts.map +1 -0
  203. package/dist/services/memory-monitor.d.ts +128 -0
  204. package/dist/services/memory-monitor.d.ts.map +1 -0
  205. package/dist/services/memory-pressure.d.ts +130 -0
  206. package/dist/services/memory-pressure.d.ts.map +1 -0
  207. package/dist/services/mtp-doctor.d.ts +13 -0
  208. package/dist/services/mtp-doctor.d.ts.map +1 -0
  209. package/dist/services/network-policy.d.ts +127 -0
  210. package/dist/services/network-policy.d.ts.map +1 -0
  211. package/dist/services/paths.d.ts +6 -0
  212. package/dist/services/paths.d.ts.map +1 -0
  213. package/dist/services/planner-skeleton.d.ts +124 -0
  214. package/dist/services/planner-skeleton.d.ts.map +1 -0
  215. package/dist/services/providers.d.ts +38 -0
  216. package/dist/services/providers.d.ts.map +1 -0
  217. package/dist/services/ram-budget.d.ts +110 -0
  218. package/dist/services/ram-budget.d.ts.map +1 -0
  219. package/dist/services/readiness.d.ts +9 -0
  220. package/dist/services/readiness.d.ts.map +1 -0
  221. package/dist/services/recommendation.d.ts +111 -0
  222. package/dist/services/recommendation.d.ts.map +1 -0
  223. package/dist/services/registry.d.ts +33 -0
  224. package/dist/services/registry.d.ts.map +1 -0
  225. package/dist/services/router-handler.d.ts +92 -0
  226. package/dist/services/router-handler.d.ts.map +1 -0
  227. package/dist/services/routing-policy.d.ts +92 -0
  228. package/dist/services/routing-policy.d.ts.map +1 -0
  229. package/dist/services/routing-preferences.d.ts +8 -0
  230. package/dist/services/routing-preferences.d.ts.map +1 -0
  231. package/dist/services/runtime-target.d.ts +98 -0
  232. package/dist/services/runtime-target.d.ts.map +1 -0
  233. package/dist/services/service.d.ts +128 -0
  234. package/dist/services/service.d.ts.map +1 -0
  235. package/dist/services/session-pool.d.ts +72 -0
  236. package/dist/services/session-pool.d.ts.map +1 -0
  237. package/dist/services/structured-output/deterministic-repair.d.ts +23 -0
  238. package/dist/services/structured-output/deterministic-repair.d.ts.map +1 -0
  239. package/dist/services/structured-output/index.d.ts +2 -0
  240. package/dist/services/structured-output/index.d.ts.map +1 -0
  241. package/dist/services/structured-output.d.ts +311 -0
  242. package/dist/services/structured-output.d.ts.map +1 -0
  243. package/dist/services/system-memory.d.ts +33 -0
  244. package/dist/services/system-memory.d.ts.map +1 -0
  245. package/dist/services/types.d.ts +19 -0
  246. package/dist/services/types.d.ts.map +1 -0
  247. package/dist/services/verify-on-device.d.ts +34 -0
  248. package/dist/services/verify-on-device.d.ts.map +1 -0
  249. package/dist/services/verify.d.ts +8 -0
  250. package/dist/services/verify.d.ts.map +1 -0
  251. package/dist/services/vision/aosp-unavailable.d.ts +115 -0
  252. package/dist/services/vision/aosp-unavailable.d.ts.map +1 -0
  253. package/dist/services/vision/capacitor-llama.d.ts +99 -0
  254. package/dist/services/vision/capacitor-llama.d.ts.map +1 -0
  255. package/dist/services/vision/cloud-fallback.d.ts +47 -0
  256. package/dist/services/vision/cloud-fallback.d.ts.map +1 -0
  257. package/dist/services/vision/hash.d.ts +71 -0
  258. package/dist/services/vision/hash.d.ts.map +1 -0
  259. package/dist/services/vision/index.d.ts +95 -0
  260. package/dist/services/vision/index.d.ts.map +1 -0
  261. package/dist/services/vision/llama-server.d.ts +73 -0
  262. package/dist/services/vision/llama-server.d.ts.map +1 -0
  263. package/dist/services/vision/types.d.ts +162 -0
  264. package/dist/services/vision/types.d.ts.map +1 -0
  265. package/dist/services/vision/vast-fallback.d.ts +18 -0
  266. package/dist/services/vision/vast-fallback.d.ts.map +1 -0
  267. package/dist/services/vision-embedding-cache.d.ts +98 -0
  268. package/dist/services/vision-embedding-cache.d.ts.map +1 -0
  269. package/dist/services/voice/__test-helpers__/fake-ffi.d.ts +27 -0
  270. package/dist/services/voice/__test-helpers__/fake-ffi.d.ts.map +1 -0
  271. package/dist/services/voice/__test-helpers__/synthetic-speech.d.ts +66 -0
  272. package/dist/services/voice/__test-helpers__/synthetic-speech.d.ts.map +1 -0
  273. package/dist/services/voice/acoustic-speaker-attribution.d.ts +61 -0
  274. package/dist/services/voice/acoustic-speaker-attribution.d.ts.map +1 -0
  275. package/dist/services/voice/audio-frame-consumer.d.ts +294 -0
  276. package/dist/services/voice/audio-frame-consumer.d.ts.map +1 -0
  277. package/dist/services/voice/barge-in.d.ts +112 -0
  278. package/dist/services/voice/barge-in.d.ts.map +1 -0
  279. package/dist/services/voice/cancellation-coordinator.d.ts +127 -0
  280. package/dist/services/voice/cancellation-coordinator.d.ts.map +1 -0
  281. package/dist/services/voice/checkpoint-manager.d.ts +199 -0
  282. package/dist/services/voice/checkpoint-manager.d.ts.map +1 -0
  283. package/dist/services/voice/checkpoint-policy.d.ts +178 -0
  284. package/dist/services/voice/checkpoint-policy.d.ts.map +1 -0
  285. package/dist/services/voice/corpus-augment.d.ts +111 -0
  286. package/dist/services/voice/corpus-augment.d.ts.map +1 -0
  287. package/dist/services/voice/corpus-generator.d.ts +134 -0
  288. package/dist/services/voice/corpus-generator.d.ts.map +1 -0
  289. package/dist/services/voice/diarization-error-rate.d.ts +40 -0
  290. package/dist/services/voice/diarization-error-rate.d.ts.map +1 -0
  291. package/dist/services/voice/e2e-harness.d.ts +297 -0
  292. package/dist/services/voice/e2e-harness.d.ts.map +1 -0
  293. package/dist/services/voice/eager-context-builder.d.ts +170 -0
  294. package/dist/services/voice/eager-context-builder.d.ts.map +1 -0
  295. package/dist/services/voice/echo-delay.d.ts +67 -0
  296. package/dist/services/voice/echo-delay.d.ts.map +1 -0
  297. package/dist/services/voice/echo-metrics.d.ts +7 -0
  298. package/dist/services/voice/echo-metrics.d.ts.map +1 -0
  299. package/dist/services/voice/echo-reference-buffer.d.ts +65 -0
  300. package/dist/services/voice/echo-reference-buffer.d.ts.map +1 -0
  301. package/dist/services/voice/eliza1-eot-scorer.d.ts +124 -0
  302. package/dist/services/voice/eliza1-eot-scorer.d.ts.map +1 -0
  303. package/dist/services/voice/embedding-server.d.ts +37 -0
  304. package/dist/services/voice/embedding-server.d.ts.map +1 -0
  305. package/dist/services/voice/embedding.d.ts +132 -0
  306. package/dist/services/voice/embedding.d.ts.map +1 -0
  307. package/dist/services/voice/emotion-attribution.d.ts +68 -0
  308. package/dist/services/voice/emotion-attribution.d.ts.map +1 -0
  309. package/dist/services/voice/engine-bridge.d.ts +762 -0
  310. package/dist/services/voice/engine-bridge.d.ts.map +1 -0
  311. package/dist/services/voice/eot-classifier-ggml.d.ts +179 -0
  312. package/dist/services/voice/eot-classifier-ggml.d.ts.map +1 -0
  313. package/dist/services/voice/eot-classifier.d.ts +211 -0
  314. package/dist/services/voice/eot-classifier.d.ts.map +1 -0
  315. package/dist/services/voice/errors.d.ts +20 -0
  316. package/dist/services/voice/errors.d.ts.map +1 -0
  317. package/dist/services/voice/expressive-tags.d.ts +158 -0
  318. package/dist/services/voice/expressive-tags.d.ts.map +1 -0
  319. package/dist/services/voice/ffi-bindings.d.ts +696 -0
  320. package/dist/services/voice/ffi-bindings.d.ts.map +1 -0
  321. package/dist/services/voice/first-line-cache.d.ts +181 -0
  322. package/dist/services/voice/first-line-cache.d.ts.map +1 -0
  323. package/dist/services/voice/fused-eot-scorer.d.ts +51 -0
  324. package/dist/services/voice/fused-eot-scorer.d.ts.map +1 -0
  325. package/dist/services/voice/index.d.ts +96 -0
  326. package/dist/services/voice/index.d.ts.map +1 -0
  327. package/dist/services/voice/kokoro/index.d.ts +24 -0
  328. package/dist/services/voice/kokoro/index.d.ts.map +1 -0
  329. package/dist/services/voice/kokoro/kokoro-backend.d.ts +87 -0
  330. package/dist/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
  331. package/dist/services/voice/kokoro/kokoro-engine-discovery.d.ts +58 -0
  332. package/dist/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
  333. package/dist/services/voice/kokoro/kokoro-ffi-runtime.d.ts +75 -0
  334. package/dist/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
  335. package/dist/services/voice/kokoro/kokoro-runtime.d.ts +100 -0
  336. package/dist/services/voice/kokoro/kokoro-runtime.d.ts.map +1 -0
  337. package/dist/services/voice/kokoro/phoneme-stream.d.ts +51 -0
  338. package/dist/services/voice/kokoro/phoneme-stream.d.ts.map +1 -0
  339. package/dist/services/voice/kokoro/phonemizer.d.ts +50 -0
  340. package/dist/services/voice/kokoro/phonemizer.d.ts.map +1 -0
  341. package/dist/services/voice/kokoro/pick-runtime.d.ts +61 -0
  342. package/dist/services/voice/kokoro/pick-runtime.d.ts.map +1 -0
  343. package/dist/services/voice/kokoro/runtime-selection.d.ts +31 -0
  344. package/dist/services/voice/kokoro/runtime-selection.d.ts.map +1 -0
  345. package/dist/services/voice/kokoro/types.d.ts +82 -0
  346. package/dist/services/voice/kokoro/types.d.ts.map +1 -0
  347. package/dist/services/voice/kokoro/voice-presets.d.ts +23 -0
  348. package/dist/services/voice/kokoro/voice-presets.d.ts.map +1 -0
  349. package/dist/services/voice/kokoro/voices.d.ts +30 -0
  350. package/dist/services/voice/kokoro/voices.d.ts.map +1 -0
  351. package/dist/services/voice/lifecycle.d.ts +135 -0
  352. package/dist/services/voice/lifecycle.d.ts.map +1 -0
  353. package/dist/services/voice/live-diarization-session.d.ts +196 -0
  354. package/dist/services/voice/live-diarization-session.d.ts.map +1 -0
  355. package/dist/services/voice/metric-math.d.ts +10 -0
  356. package/dist/services/voice/metric-math.d.ts.map +1 -0
  357. package/dist/services/voice/mic-source.d.ts +136 -0
  358. package/dist/services/voice/mic-source.d.ts.map +1 -0
  359. package/dist/services/voice/nlms-echo-canceller.d.ts +137 -0
  360. package/dist/services/voice/nlms-echo-canceller.d.ts.map +1 -0
  361. package/dist/services/voice/optimistic-policy.d.ts +109 -0
  362. package/dist/services/voice/optimistic-policy.d.ts.map +1 -0
  363. package/dist/services/voice/optimistic-rollback.d.ts +151 -0
  364. package/dist/services/voice/optimistic-rollback.d.ts.map +1 -0
  365. package/dist/services/voice/partial-stabilizer.d.ts +73 -0
  366. package/dist/services/voice/partial-stabilizer.d.ts.map +1 -0
  367. package/dist/services/voice/phoneme-tokenizer.d.ts +49 -0
  368. package/dist/services/voice/phoneme-tokenizer.d.ts.map +1 -0
  369. package/dist/services/voice/phrase-cache.d.ts +76 -0
  370. package/dist/services/voice/phrase-cache.d.ts.map +1 -0
  371. package/dist/services/voice/phrase-chunker.d.ts +62 -0
  372. package/dist/services/voice/phrase-chunker.d.ts.map +1 -0
  373. package/dist/services/voice/pipeline-impls.d.ts +151 -0
  374. package/dist/services/voice/pipeline-impls.d.ts.map +1 -0
  375. package/dist/services/voice/pipeline.d.ts +216 -0
  376. package/dist/services/voice/pipeline.d.ts.map +1 -0
  377. package/dist/services/voice/prefill-client.d.ts +123 -0
  378. package/dist/services/voice/prefill-client.d.ts.map +1 -0
  379. package/dist/services/voice/prefix-preserving-queue.d.ts +113 -0
  380. package/dist/services/voice/prefix-preserving-queue.d.ts.map +1 -0
  381. package/dist/services/voice/profile-store.d.ts +248 -0
  382. package/dist/services/voice/profile-store.d.ts.map +1 -0
  383. package/dist/services/voice/ring-buffer.d.ts +40 -0
  384. package/dist/services/voice/ring-buffer.d.ts.map +1 -0
  385. package/dist/services/voice/rollback-queue.d.ts +24 -0
  386. package/dist/services/voice/rollback-queue.d.ts.map +1 -0
  387. package/dist/services/voice/samantha-preset-placeholder.d.ts +67 -0
  388. package/dist/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
  389. package/dist/services/voice/samantha-preset-regenerator.d.ts +87 -0
  390. package/dist/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
  391. package/dist/services/voice/scheduler.d.ts +146 -0
  392. package/dist/services/voice/scheduler.d.ts.map +1 -0
  393. package/dist/services/voice/self-voice-imprint.d.ts +33 -0
  394. package/dist/services/voice/self-voice-imprint.d.ts.map +1 -0
  395. package/dist/services/voice/shared-resources.d.ts +204 -0
  396. package/dist/services/voice/shared-resources.d.ts.map +1 -0
  397. package/dist/services/voice/speaker/attribution-pipeline.d.ts +74 -0
  398. package/dist/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
  399. package/dist/services/voice/speaker/diarizer-fused.d.ts +59 -0
  400. package/dist/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
  401. package/dist/services/voice/speaker/diarizer.d.ts +75 -0
  402. package/dist/services/voice/speaker/diarizer.d.ts.map +1 -0
  403. package/dist/services/voice/speaker/encoder-fused.d.ts +60 -0
  404. package/dist/services/voice/speaker/encoder-fused.d.ts.map +1 -0
  405. package/dist/services/voice/speaker/encoder-ggml.d.ts +33 -0
  406. package/dist/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
  407. package/dist/services/voice/speaker/encoder.d.ts +37 -0
  408. package/dist/services/voice/speaker/encoder.d.ts.map +1 -0
  409. package/dist/services/voice/speaker-imprint.d.ts +83 -0
  410. package/dist/services/voice/speaker-imprint.d.ts.map +1 -0
  411. package/dist/services/voice/speaker-preset-cache.d.ts +77 -0
  412. package/dist/services/voice/speaker-preset-cache.d.ts.map +1 -0
  413. package/dist/services/voice/streaming-asr/streaming-pipeline-adapter.d.ts +160 -0
  414. package/dist/services/voice/streaming-asr/streaming-pipeline-adapter.d.ts.map +1 -0
  415. package/dist/services/voice/system-audio-sink.d.ts +73 -0
  416. package/dist/services/voice/system-audio-sink.d.ts.map +1 -0
  417. package/dist/services/voice/transcriber.d.ts +244 -0
  418. package/dist/services/voice/transcriber.d.ts.map +1 -0
  419. package/dist/services/voice/transcript-knowledge.d.ts +37 -0
  420. package/dist/services/voice/transcript-knowledge.d.ts.map +1 -0
  421. package/dist/services/voice/transcript-service.d.ts +60 -0
  422. package/dist/services/voice/transcript-service.d.ts.map +1 -0
  423. package/dist/services/voice/transcript-store.d.ts +64 -0
  424. package/dist/services/voice/transcript-store.d.ts.map +1 -0
  425. package/dist/services/voice/turn-controller.d.ts +183 -0
  426. package/dist/services/voice/turn-controller.d.ts.map +1 -0
  427. package/dist/services/voice/types.d.ts +643 -0
  428. package/dist/services/voice/types.d.ts.map +1 -0
  429. package/dist/services/voice/vad.d.ts +283 -0
  430. package/dist/services/voice/vad.d.ts.map +1 -0
  431. package/dist/services/voice/voice-budget.d.ts +241 -0
  432. package/dist/services/voice/voice-budget.d.ts.map +1 -0
  433. package/dist/services/voice/voice-emotion-classifier.d.ts +95 -0
  434. package/dist/services/voice/voice-emotion-classifier.d.ts.map +1 -0
  435. package/dist/services/voice/voice-preload-predictor.d.ts +76 -0
  436. package/dist/services/voice/voice-preload-predictor.d.ts.map +1 -0
  437. package/dist/services/voice/voice-preset-format.d.ts +158 -0
  438. package/dist/services/voice/voice-preset-format.d.ts.map +1 -0
  439. package/dist/services/voice/voice-profile-artifact.d.ts +116 -0
  440. package/dist/services/voice/voice-profile-artifact.d.ts.map +1 -0
  441. package/dist/services/voice/voice-profile-routes.d.ts +83 -0
  442. package/dist/services/voice/voice-profile-routes.d.ts.map +1 -0
  443. package/dist/services/voice/voice-scenario.d.ts +131 -0
  444. package/dist/services/voice/voice-scenario.d.ts.map +1 -0
  445. package/dist/services/voice/voice-state-machine.d.ts +364 -0
  446. package/dist/services/voice/voice-state-machine.d.ts.map +1 -0
  447. package/dist/services/voice/voice-workbench-report.d.ts +117 -0
  448. package/dist/services/voice/voice-workbench-report.d.ts.map +1 -0
  449. package/dist/services/voice/wake-word-ggml.d.ts +100 -0
  450. package/dist/services/voice/wake-word-ggml.d.ts.map +1 -0
  451. package/dist/services/voice/wake-word.d.ts +255 -0
  452. package/dist/services/voice/wake-word.d.ts.map +1 -0
  453. package/dist/services/voice/wav-codec.d.ts +11 -0
  454. package/dist/services/voice/wav-codec.d.ts.map +1 -0
  455. package/dist/services/voice/workbench-entrypoint.d.ts +42 -0
  456. package/dist/services/voice/workbench-entrypoint.d.ts.map +1 -0
  457. package/dist/services/voice/workbench-headless-runner.d.ts +102 -0
  458. package/dist/services/voice/workbench-headless-runner.d.ts.map +1 -0
  459. package/dist/services/voice/workbench-logic-services.d.ts +36 -0
  460. package/dist/services/voice/workbench-logic-services.d.ts.map +1 -0
  461. package/dist/services/voice/workbench-real-services.d.ts +17 -0
  462. package/dist/services/voice/workbench-real-services.d.ts.map +1 -0
  463. package/dist/services/voice/workbench-scenarios.d.ts +24 -0
  464. package/dist/services/voice/workbench-scenarios.d.ts.map +1 -0
  465. package/dist/services/voice/wrap-with-first-line-cache.d.ts +70 -0
  466. package/dist/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
  467. package/dist/services/voice-model-updater.d.ts +240 -0
  468. package/dist/services/voice-model-updater.d.ts.map +1 -0
  469. package/dist/services/voice-prewarm.d.ts +3 -0
  470. package/dist/services/voice-prewarm.d.ts.map +1 -0
  471. package/dist/voice-workbench.d.ts +18 -0
  472. package/dist/voice-workbench.d.ts.map +1 -0
  473. package/dist/voice-workbench.js +5259 -0
  474. package/dist/voice-workbench.js.map +34 -0
  475. package/package.json +101 -15
  476. package/registry-entry.json +137 -0
  477. package/src/actions/generate-media.ts +647 -0
  478. package/src/actions/identify-speaker.ts +171 -0
  479. package/src/actions/transcription-control.test.ts +100 -0
  480. package/src/actions/transcription-control.ts +127 -0
  481. package/src/adapters/capacitor-llama/__tests__/compat-behavior.test.ts +218 -0
  482. package/src/adapters/capacitor-llama/__tests__/index.test.ts +68 -0
  483. package/src/adapters/capacitor-llama/__tests__/structured-output.test.ts +215 -0
  484. package/src/adapters/capacitor-llama/__tests__/text-streaming.test.ts +174 -0
  485. package/src/adapters/capacitor-llama/__tests__/voice-turn.test.ts +293 -0
  486. package/src/adapters/capacitor-llama/environment.ts +71 -0
  487. package/src/adapters/capacitor-llama/index.browser.ts +83 -0
  488. package/src/adapters/capacitor-llama/index.ts +831 -0
  489. package/src/adapters/capacitor-llama/loader.ts +109 -0
  490. package/src/adapters/capacitor-llama/native-voice-capture.ts +140 -0
  491. package/src/adapters/capacitor-llama/structured-output.ts +165 -0
  492. package/src/adapters/capacitor-llama/text-streaming.ts +227 -0
  493. package/src/adapters/capacitor-llama/types.ts +374 -0
  494. package/src/adapters/capacitor-llama/voice-turn.ts +178 -0
  495. package/src/backends/apple-foundation.ts +127 -0
  496. package/src/index.ts +62 -0
  497. package/src/local-inference-routes.test.ts +390 -0
  498. package/src/local-inference-routes.ts +1625 -0
  499. package/src/provider.ts +1111 -0
  500. package/src/routes/compat-helpers.ts +275 -0
  501. package/src/routes/family-member-route.ts +353 -0
  502. package/src/routes/index.ts +61 -0
  503. package/src/routes/live-diarization-route.test.ts +347 -0
  504. package/src/routes/live-diarization-route.ts +198 -0
  505. package/src/routes/local-inference-asr-route.test.ts +246 -0
  506. package/src/routes/local-inference-asr-route.ts +166 -0
  507. package/src/routes/local-inference-asr-transcribe.test.ts +118 -0
  508. package/src/routes/local-inference-asr-transcribe.ts +97 -0
  509. package/src/routes/local-inference-compat-routes.test.ts +485 -0
  510. package/src/routes/local-inference-compat-routes.ts +775 -0
  511. package/src/routes/local-inference-tts-route.test.ts +179 -0
  512. package/src/routes/local-inference-tts-route.ts +230 -0
  513. package/src/routes/native-pcm-turn-route.test.ts +136 -0
  514. package/src/routes/native-pcm-turn-route.ts +121 -0
  515. package/src/routes/transcript-audio-store.ts +27 -0
  516. package/src/routes/transcripts-routes.test.ts +195 -0
  517. package/src/routes/transcripts-routes.ts +191 -0
  518. package/src/routes/voice-first-run-routes.ts +524 -0
  519. package/src/routes/voice-models-routes.ts +554 -0
  520. package/src/routes/voice-profile-plugin-routes.ts +138 -0
  521. package/src/routes/voice-profiles-management-routes.ts +476 -0
  522. package/src/routes/voice-speaker-profile-routes.ts +199 -0
  523. package/src/runtime/aosp-llama-loader-selection.test.ts +80 -0
  524. package/src/runtime/bionic-wire-encoding.test.ts +147 -0
  525. package/src/runtime/capacitor-llama.d.ts +25 -0
  526. package/src/runtime/embedding-manager-support.ts +497 -0
  527. package/src/runtime/embedding-presets.ts +81 -0
  528. package/src/runtime/embedding-warmup-policy.test.ts +53 -0
  529. package/src/runtime/embedding-warmup-policy.ts +48 -0
  530. package/src/runtime/ensure-local-inference-handler.test.ts +726 -0
  531. package/src/runtime/ensure-local-inference-handler.ts +1640 -0
  532. package/src/runtime/index.ts +36 -0
  533. package/src/runtime/mobile-local-inference-gate.test.ts +152 -0
  534. package/src/runtime/mobile-local-inference-gate.ts +99 -0
  535. package/src/runtime/voice-entity-binding.transcript.test.ts +98 -0
  536. package/src/runtime/voice-entity-binding.ts +368 -0
  537. package/src/runtime/voice-speaker-entity-contract.test.ts +149 -0
  538. package/src/services/README.md +71 -0
  539. package/src/services/__tests__/backend-selector.precedence.test.ts +333 -0
  540. package/src/services/__tests__/backend-selector.test.ts +101 -0
  541. package/src/services/__tests__/checkpoint-manager.test.ts +376 -0
  542. package/src/services/__tests__/gpu-autotune.test.ts +400 -0
  543. package/src/services/__tests__/llm-streaming-binding.test.ts +85 -0
  544. package/src/services/__tests__/planner-grammar.test.ts +372 -0
  545. package/src/services/__tests__/runtime-target.test.ts +176 -0
  546. package/src/services/active-model-context-fit.test.ts +125 -0
  547. package/src/services/active-model-switch-rollback.test.ts +183 -0
  548. package/src/services/active-model.ts +1416 -0
  549. package/src/services/asr-provenance.ts +68 -0
  550. package/src/services/assignment-validation.test.ts +118 -0
  551. package/src/services/assignments.test.ts +106 -0
  552. package/src/services/assignments.ts +278 -0
  553. package/src/services/backend-selector.ts +95 -0
  554. package/src/services/backend.test.ts +84 -0
  555. package/src/services/backend.ts +791 -0
  556. package/src/services/bionic-host-loader.test.ts +226 -0
  557. package/src/services/bionic-host-loader.ts +252 -0
  558. package/src/services/bundled-models.ts +129 -0
  559. package/src/services/cache-bridge.test.ts +516 -0
  560. package/src/services/cache-bridge.ts +423 -0
  561. package/src/services/catalog.test.ts +259 -0
  562. package/src/services/catalog.ts +33 -0
  563. package/src/services/checkpoint-client.ts +258 -0
  564. package/src/services/checkpoint-manager.ts +474 -0
  565. package/src/services/cloud-fallback.ts +230 -0
  566. package/src/services/context-fit.test.ts +121 -0
  567. package/src/services/context-fit.ts +113 -0
  568. package/src/services/conversation-registry.test.ts +235 -0
  569. package/src/services/conversation-registry.ts +264 -0
  570. package/src/services/desktop-fused-ffi-backend-runtime.ts +431 -0
  571. package/src/services/device-bridge.ts +1237 -0
  572. package/src/services/device-resource-metrics.test.ts +98 -0
  573. package/src/services/device-resource-metrics.ts +346 -0
  574. package/src/services/device-tier.test.ts +458 -0
  575. package/src/services/device-tier.ts +502 -0
  576. package/src/services/downloader.test.ts +888 -0
  577. package/src/services/downloader.ts +1039 -0
  578. package/src/services/engine-direct-bundle.test.ts +90 -0
  579. package/src/services/engine-streaming.test.ts +80 -0
  580. package/src/services/engine.ts +2096 -0
  581. package/src/services/ensure-local-artifacts.integration.test.ts +273 -0
  582. package/src/services/ensure-local-artifacts.test.ts +368 -0
  583. package/src/services/ensure-local-artifacts.ts +351 -0
  584. package/src/services/external-scanner.ts +312 -0
  585. package/src/services/ffi-llm-mock.ts +354 -0
  586. package/src/services/ffi-llm-streaming-abi.ts +445 -0
  587. package/src/services/ffi-streaming-backend.ts +418 -0
  588. package/src/services/ffi-streaming-runner.test.ts +220 -0
  589. package/src/services/ffi-streaming-runner.ts +407 -0
  590. package/src/services/ffi-unload-ordering.test.ts +166 -0
  591. package/src/services/fused-eliza1-no-regression.test.ts +144 -0
  592. package/src/services/gpu-autotune.ts +534 -0
  593. package/src/services/gpu-detect.ts +139 -0
  594. package/src/services/handler-registry.ts +240 -0
  595. package/src/services/hardware.test.ts +236 -0
  596. package/src/services/hardware.ts +438 -0
  597. package/src/services/image-description-runtime.test.ts +61 -0
  598. package/src/services/image-description-runtime.ts +118 -0
  599. package/src/services/imagegen/aosp-unavailable.ts +229 -0
  600. package/src/services/imagegen/backend-selector.test.ts +190 -0
  601. package/src/services/imagegen/backend-selector.ts +277 -0
  602. package/src/services/imagegen/coreml-unavailable.ts +237 -0
  603. package/src/services/imagegen/errors.ts +40 -0
  604. package/src/services/imagegen/index.ts +144 -0
  605. package/src/services/imagegen/mflux.ts +313 -0
  606. package/src/services/imagegen/sd-cpp.ts +715 -0
  607. package/src/services/imagegen/tensorrt-unavailable.ts +295 -0
  608. package/src/services/imagegen/types.ts +193 -0
  609. package/src/services/index.ts +229 -0
  610. package/src/services/inference-capabilities.test.ts +75 -0
  611. package/src/services/inference-capabilities.ts +204 -0
  612. package/src/services/inference-telemetry.ts +143 -0
  613. package/src/services/ios-llama-streaming.ts +248 -0
  614. package/src/services/kv-spill.test.ts +222 -0
  615. package/src/services/kv-spill.ts +357 -0
  616. package/src/services/latency-trace.test.ts +266 -0
  617. package/src/services/latency-trace.ts +844 -0
  618. package/src/services/lib-target.test.ts +145 -0
  619. package/src/services/lib-target.ts +102 -0
  620. package/src/services/live-signals.test.ts +132 -0
  621. package/src/services/live-signals.ts +177 -0
  622. package/src/services/llama-server-metrics.test.ts +168 -0
  623. package/src/services/llama-server-metrics.ts +304 -0
  624. package/src/services/llm-streaming-binding.ts +136 -0
  625. package/src/services/load-args.ts +81 -0
  626. package/src/services/manifest/eliza-1.manifest.v1.json +790 -0
  627. package/src/services/manifest/index.ts +72 -0
  628. package/src/services/manifest/manifest.test.ts +791 -0
  629. package/src/services/manifest/schema.ts +761 -0
  630. package/src/services/manifest/types.ts +61 -0
  631. package/src/services/manifest/validator.ts +633 -0
  632. package/src/services/memory-arbiter.test.ts +558 -0
  633. package/src/services/memory-arbiter.ts +991 -0
  634. package/src/services/memory-benchmark.test.ts +91 -0
  635. package/src/services/memory-benchmark.ts +354 -0
  636. package/src/services/memory-monitor.test.ts +232 -0
  637. package/src/services/memory-monitor.ts +309 -0
  638. package/src/services/memory-pressure.ts +414 -0
  639. package/src/services/mtp-doctor.ts +86 -0
  640. package/src/services/network-policy.ts +346 -0
  641. package/src/services/paths.ts +25 -0
  642. package/src/services/planner-skeleton.ts +175 -0
  643. package/src/services/providers.ts +507 -0
  644. package/src/services/ram-budget-cache.test.ts +164 -0
  645. package/src/services/ram-budget.ts +309 -0
  646. package/src/services/readiness.test.ts +87 -0
  647. package/src/services/readiness.ts +238 -0
  648. package/src/services/recommendation.test.ts +216 -0
  649. package/src/services/recommendation.ts +671 -0
  650. package/src/services/registry.ts +157 -0
  651. package/src/services/required-kernels-gate.test.ts +64 -0
  652. package/src/services/router-handler.test.ts +45 -0
  653. package/src/services/router-handler.ts +426 -0
  654. package/src/services/routing-policy.test.ts +352 -0
  655. package/src/services/routing-policy.ts +367 -0
  656. package/src/services/routing-preferences.ts +17 -0
  657. package/src/services/runtime-target.ts +154 -0
  658. package/src/services/service.test.ts +223 -0
  659. package/src/services/service.ts +750 -0
  660. package/src/services/session-pool.ts +153 -0
  661. package/src/services/structured-output/deterministic-repair.test.ts +169 -0
  662. package/src/services/structured-output/deterministic-repair.ts +443 -0
  663. package/src/services/structured-output/index.ts +4 -0
  664. package/src/services/structured-output.test.ts +483 -0
  665. package/src/services/structured-output.ts +712 -0
  666. package/src/services/system-memory.test.ts +47 -0
  667. package/src/services/system-memory.ts +67 -0
  668. package/src/services/transcription-priority.test.ts +211 -0
  669. package/src/services/types.ts +59 -0
  670. package/src/services/verify-on-device.test.ts +87 -0
  671. package/src/services/verify-on-device.ts +127 -0
  672. package/src/services/verify.ts +13 -0
  673. package/src/services/vision/aosp-unavailable.ts +163 -0
  674. package/src/services/vision/capacitor-llama.ts +255 -0
  675. package/src/services/vision/cloud-fallback.test.ts +243 -0
  676. package/src/services/vision/cloud-fallback.ts +268 -0
  677. package/src/services/vision/fallback-chain.test.ts +86 -0
  678. package/src/services/vision/hash.ts +157 -0
  679. package/src/services/vision/index.ts +251 -0
  680. package/src/services/vision/llama-server.ts +177 -0
  681. package/src/services/vision/types.ts +163 -0
  682. package/src/services/vision/vast-fallback.ts +127 -0
  683. package/src/services/vision-embedding-cache.ts +189 -0
  684. package/src/services/voice/VOICE_WORKBENCH.md +133 -0
  685. package/src/services/voice/__fixtures__/voice-workbench-logic-baseline.json +180 -0
  686. package/src/services/voice/__test-helpers__/fake-ffi.ts +94 -0
  687. package/src/services/voice/__test-helpers__/synthetic-speech.ts +194 -0
  688. package/src/services/voice/__tests__/checkpoint-manager.test.ts +241 -0
  689. package/src/services/voice/__tests__/checkpoint-policy.test.ts +270 -0
  690. package/src/services/voice/__tests__/eager-context-builder.test.ts +257 -0
  691. package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +288 -0
  692. package/src/services/voice/__tests__/eot-classifier.test.ts +431 -0
  693. package/src/services/voice/__tests__/optimistic-rollback.test.ts +312 -0
  694. package/src/services/voice/__tests__/prefill-client.test.ts +266 -0
  695. package/src/services/voice/__tests__/prefix-preserving-queue.test.ts +208 -0
  696. package/src/services/voice/__tests__/streaming-asr.test.ts +450 -0
  697. package/src/services/voice/__tests__/streaming-transcriber.test.ts +339 -0
  698. package/src/services/voice/__tests__/turn-detector-resolver.test.ts +195 -0
  699. package/src/services/voice/__tests__/voice-state-machine-prefill.test.ts +275 -0
  700. package/src/services/voice/__tests__/voice-state-machine.test.ts +354 -0
  701. package/src/services/voice/acoustic-speaker-attribution.test.ts +165 -0
  702. package/src/services/voice/acoustic-speaker-attribution.ts +336 -0
  703. package/src/services/voice/asr-timed.real.test.ts +139 -0
  704. package/src/services/voice/audio-frame-consumer.test.ts +669 -0
  705. package/src/services/voice/audio-frame-consumer.ts +651 -0
  706. package/src/services/voice/barge-in.test.ts +244 -0
  707. package/src/services/voice/barge-in.ts +335 -0
  708. package/src/services/voice/cancellation-coordinator.test.ts +196 -0
  709. package/src/services/voice/cancellation-coordinator.ts +269 -0
  710. package/src/services/voice/checkpoint-manager.ts +401 -0
  711. package/src/services/voice/checkpoint-policy.ts +336 -0
  712. package/src/services/voice/composite-eot-classifier.test.ts +59 -0
  713. package/src/services/voice/corpus-augment.test.ts +276 -0
  714. package/src/services/voice/corpus-augment.ts +451 -0
  715. package/src/services/voice/corpus-generator.test.ts +201 -0
  716. package/src/services/voice/corpus-generator.ts +413 -0
  717. package/src/services/voice/diarization-error-rate.greedy.test.ts +140 -0
  718. package/src/services/voice/diarization-error-rate.test.ts +100 -0
  719. package/src/services/voice/diarization-error-rate.ts +249 -0
  720. package/src/services/voice/e2e-harness.der.test.ts +94 -0
  721. package/src/services/voice/e2e-harness.respond-eot-entity.test.ts +277 -0
  722. package/src/services/voice/e2e-harness.security-echo.test.ts +103 -0
  723. package/src/services/voice/e2e-harness.test.ts +182 -0
  724. package/src/services/voice/e2e-harness.ts +902 -0
  725. package/src/services/voice/eager-context-builder.ts +262 -0
  726. package/src/services/voice/echo-delay.test.ts +118 -0
  727. package/src/services/voice/echo-delay.ts +135 -0
  728. package/src/services/voice/echo-metrics.test.ts +17 -0
  729. package/src/services/voice/echo-metrics.ts +20 -0
  730. package/src/services/voice/echo-reference-buffer.test.ts +86 -0
  731. package/src/services/voice/echo-reference-buffer.ts +165 -0
  732. package/src/services/voice/eliza1-eot-scorer.ts +242 -0
  733. package/src/services/voice/embedding-server.ts +200 -0
  734. package/src/services/voice/embedding.test.ts +131 -0
  735. package/src/services/voice/embedding.ts +242 -0
  736. package/src/services/voice/emotion-attribution.test.ts +129 -0
  737. package/src/services/voice/emotion-attribution.ts +361 -0
  738. package/src/services/voice/engine-bridge-cancellation.test.ts +422 -0
  739. package/src/services/voice/engine-bridge-transcript-join.test.ts +278 -0
  740. package/src/services/voice/engine-bridge.test.ts +384 -0
  741. package/src/services/voice/engine-bridge.ts +2343 -0
  742. package/src/services/voice/eot-classifier-ggml.ts +569 -0
  743. package/src/services/voice/eot-classifier.test.ts +98 -0
  744. package/src/services/voice/eot-classifier.ts +422 -0
  745. package/src/services/voice/errors.ts +34 -0
  746. package/src/services/voice/expressive-tags.asr.test.ts +77 -0
  747. package/src/services/voice/expressive-tags.test.ts +102 -0
  748. package/src/services/voice/expressive-tags.ts +405 -0
  749. package/src/services/voice/ffi-bindings.test.ts +735 -0
  750. package/src/services/voice/ffi-bindings.ts +3387 -0
  751. package/src/services/voice/first-line-cache.ts +725 -0
  752. package/src/services/voice/fused-eot-scorer.ts +139 -0
  753. package/src/services/voice/index.ts +502 -0
  754. package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +262 -0
  755. package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +236 -0
  756. package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.test.ts +60 -0
  757. package/src/services/voice/kokoro/__tests__/kokoro-engine-discovery.test.ts +277 -0
  758. package/src/services/voice/kokoro/__tests__/kokoro-ffi-runtime.test.ts +235 -0
  759. package/src/services/voice/kokoro/__tests__/kokoro-runtime.test.ts +95 -0
  760. package/src/services/voice/kokoro/__tests__/phonemizer.test.ts +53 -0
  761. package/src/services/voice/kokoro/__tests__/runtime-selection.test.ts +67 -0
  762. package/src/services/voice/kokoro/__tests__/voices.test.ts +57 -0
  763. package/src/services/voice/kokoro/index.ts +79 -0
  764. package/src/services/voice/kokoro/kokoro-backend.ts +223 -0
  765. package/src/services/voice/kokoro/kokoro-engine-discovery.ts +177 -0
  766. package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +233 -0
  767. package/src/services/voice/kokoro/kokoro-runtime.ts +170 -0
  768. package/src/services/voice/kokoro/phoneme-stream.ts +123 -0
  769. package/src/services/voice/kokoro/phonemizer.ts +344 -0
  770. package/src/services/voice/kokoro/pick-runtime.test.ts +91 -0
  771. package/src/services/voice/kokoro/pick-runtime.ts +130 -0
  772. package/src/services/voice/kokoro/runtime-selection.ts +64 -0
  773. package/src/services/voice/kokoro/types.ts +95 -0
  774. package/src/services/voice/kokoro/voice-presets.ts +129 -0
  775. package/src/services/voice/kokoro/voices.ts +64 -0
  776. package/src/services/voice/lifecycle.test.ts +315 -0
  777. package/src/services/voice/lifecycle.ts +301 -0
  778. package/src/services/voice/live-diarization-session.echo.test.ts +232 -0
  779. package/src/services/voice/live-diarization-session.ts +622 -0
  780. package/src/services/voice/metric-math.test.ts +61 -0
  781. package/src/services/voice/metric-math.ts +25 -0
  782. package/src/services/voice/mic-source.test.ts +210 -0
  783. package/src/services/voice/mic-source.ts +503 -0
  784. package/src/services/voice/nlms-echo-canceller.test.ts +244 -0
  785. package/src/services/voice/nlms-echo-canceller.ts +317 -0
  786. package/src/services/voice/optimistic-policy.power-source.test.ts +36 -0
  787. package/src/services/voice/optimistic-policy.test.ts +101 -0
  788. package/src/services/voice/optimistic-policy.ts +192 -0
  789. package/src/services/voice/optimistic-rollback.ts +343 -0
  790. package/src/services/voice/partial-stabilizer.test.ts +68 -0
  791. package/src/services/voice/partial-stabilizer.ts +140 -0
  792. package/src/services/voice/phoneme-tokenizer.ts +158 -0
  793. package/src/services/voice/phrase-cache.test.ts +242 -0
  794. package/src/services/voice/phrase-cache.ts +186 -0
  795. package/src/services/voice/phrase-chunker.test.ts +239 -0
  796. package/src/services/voice/phrase-chunker.ts +281 -0
  797. package/src/services/voice/pipeline-impls.l6.test.ts +110 -0
  798. package/src/services/voice/pipeline-impls.test.ts +292 -0
  799. package/src/services/voice/pipeline-impls.ts +315 -0
  800. package/src/services/voice/pipeline.ts +504 -0
  801. package/src/services/voice/prefill-client.ts +316 -0
  802. package/src/services/voice/prefix-preserving-queue.ts +162 -0
  803. package/src/services/voice/profile-store.ts +887 -0
  804. package/src/services/voice/real-audio-decode.test.ts +148 -0
  805. package/src/services/voice/research/VOICE_8785_ASSESSMENT.md +141 -0
  806. package/src/services/voice/research/VOICE_PIPELINE_RESEARCH_2026.md +117 -0
  807. package/src/services/voice/research/VOICE_VALIDATION_RUNBOOK.md +135 -0
  808. package/src/services/voice/ring-buffer.test.ts +129 -0
  809. package/src/services/voice/ring-buffer.ts +123 -0
  810. package/src/services/voice/rollback-queue.ts +74 -0
  811. package/src/services/voice/samantha-preset-placeholder.test.ts +97 -0
  812. package/src/services/voice/samantha-preset-placeholder.ts +148 -0
  813. package/src/services/voice/samantha-preset-regenerator.ts +393 -0
  814. package/src/services/voice/samantha-preset-regenerator.wav.test.ts +90 -0
  815. package/src/services/voice/scheduler.t2.test.ts +141 -0
  816. package/src/services/voice/scheduler.ts +927 -0
  817. package/src/services/voice/self-voice-imprint.test.ts +59 -0
  818. package/src/services/voice/self-voice-imprint.ts +102 -0
  819. package/src/services/voice/shared-resources.ts +343 -0
  820. package/src/services/voice/speaker/attribution-pipeline.test.ts +221 -0
  821. package/src/services/voice/speaker/attribution-pipeline.ts +449 -0
  822. package/src/services/voice/speaker/diarizer-fused.real.test.ts +100 -0
  823. package/src/services/voice/speaker/diarizer-fused.ts +154 -0
  824. package/src/services/voice/speaker/diarizer.ts +218 -0
  825. package/src/services/voice/speaker/encoder-fused.real.test.ts +113 -0
  826. package/src/services/voice/speaker/encoder-fused.ts +138 -0
  827. package/src/services/voice/speaker/encoder-ggml.test.ts +59 -0
  828. package/src/services/voice/speaker/encoder-ggml.ts +79 -0
  829. package/src/services/voice/speaker/encoder.ts +105 -0
  830. package/src/services/voice/speaker-imprint.test.ts +185 -0
  831. package/src/services/voice/speaker-imprint.ts +312 -0
  832. package/src/services/voice/speaker-preset-cache.test.ts +154 -0
  833. package/src/services/voice/speaker-preset-cache.ts +195 -0
  834. package/src/services/voice/streaming-asr/streaming-pipeline-adapter.ts +292 -0
  835. package/src/services/voice/system-audio-sink.test.ts +29 -0
  836. package/src/services/voice/system-audio-sink.ts +366 -0
  837. package/src/services/voice/transcriber.asr-backend.test.ts +76 -0
  838. package/src/services/voice/transcriber.test.ts +392 -0
  839. package/src/services/voice/transcriber.ts +704 -0
  840. package/src/services/voice/transcript-knowledge.test.ts +68 -0
  841. package/src/services/voice/transcript-knowledge.ts +75 -0
  842. package/src/services/voice/transcript-service.test.ts +195 -0
  843. package/src/services/voice/transcript-service.ts +205 -0
  844. package/src/services/voice/transcript-store.test.ts +189 -0
  845. package/src/services/voice/transcript-store.ts +164 -0
  846. package/src/services/voice/turn-controller.test.ts +575 -0
  847. package/src/services/voice/turn-controller.ts +596 -0
  848. package/src/services/voice/types.ts +699 -0
  849. package/src/services/voice/vad.test.ts +498 -0
  850. package/src/services/voice/vad.ts +832 -0
  851. package/src/services/voice/vad.v1-v4.test.ts +222 -0
  852. package/src/services/voice/voice-budget.test.ts +415 -0
  853. package/src/services/voice/voice-budget.ts +635 -0
  854. package/src/services/voice/voice-duet.test.ts +375 -0
  855. package/src/services/voice/voice-emotion-classifier.test.ts +210 -0
  856. package/src/services/voice/voice-emotion-classifier.ts +273 -0
  857. package/src/services/voice/voice-hardening.fuzz.test.ts +116 -0
  858. package/src/services/voice/voice-preload-predictor.test.ts +130 -0
  859. package/src/services/voice/voice-preload-predictor.ts +113 -0
  860. package/src/services/voice/voice-preset-format.fuzz.test.ts +89 -0
  861. package/src/services/voice/voice-preset-format.test.ts +75 -0
  862. package/src/services/voice/voice-preset-format.ts +713 -0
  863. package/src/services/voice/voice-preset-generator.test.ts +89 -0
  864. package/src/services/voice/voice-profile-artifact.test.ts +138 -0
  865. package/src/services/voice/voice-profile-artifact.ts +518 -0
  866. package/src/services/voice/voice-profile-routes.test.ts +429 -0
  867. package/src/services/voice/voice-profile-routes.ts +425 -0
  868. package/src/services/voice/voice-scenario.test.ts +159 -0
  869. package/src/services/voice/voice-scenario.ts +280 -0
  870. package/src/services/voice/voice-scenario.turn-helpers.test.ts +77 -0
  871. package/src/services/voice/voice-state-machine.ts +727 -0
  872. package/src/services/voice/voice-workbench-report.test.ts +168 -0
  873. package/src/services/voice/voice-workbench-report.ts +367 -0
  874. package/src/services/voice/voice-workbench.test.ts +158 -0
  875. package/src/services/voice/voice.test.ts +1070 -0
  876. package/src/services/voice/wake-word-ggml.ts +319 -0
  877. package/src/services/voice/wake-word.test.ts +298 -0
  878. package/src/services/voice/wake-word.ts +554 -0
  879. package/src/services/voice/wav-codec.fuzz.test.ts +59 -0
  880. package/src/services/voice/wav-codec.test.ts +32 -0
  881. package/src/services/voice/wav-codec.ts +101 -0
  882. package/src/services/voice/workbench-entrypoint.test.ts +55 -0
  883. package/src/services/voice/workbench-entrypoint.ts +88 -0
  884. package/src/services/voice/workbench-headless-runner.test.ts +162 -0
  885. package/src/services/voice/workbench-headless-runner.ts +396 -0
  886. package/src/services/voice/workbench-logic-services.test.ts +225 -0
  887. package/src/services/voice/workbench-logic-services.ts +184 -0
  888. package/src/services/voice/workbench-real-services.ts +629 -0
  889. package/src/services/voice/workbench-scenarios.ts +407 -0
  890. package/src/services/voice/wrap-with-first-line-cache.ts +267 -0
  891. package/src/services/voice-model-updater.ts +724 -0
  892. package/src/services/voice-prewarm.ts +51 -0
  893. package/src/voice-workbench.ts +71 -0
@@ -0,0 +1,1111 @@
1
+ import {
2
+ type AudioStreamResult,
3
+ EventType,
4
+ type GenerateTextParams,
5
+ type IAgentRuntime,
6
+ type ImageDescriptionParams,
7
+ type ImageDescriptionResult,
8
+ type ImageGenerationParams,
9
+ type ImageGenerationResult,
10
+ logger,
11
+ ModelType,
12
+ type Plugin,
13
+ type TextEmbeddingParams,
14
+ type TextToSpeechParams,
15
+ type TranscriptionParams,
16
+ } from "@elizaos/core";
17
+
18
+ import { generateMediaAction } from "./actions/generate-media.js";
19
+ import { identifySpeakerAction } from "./actions/identify-speaker.js";
20
+ import {
21
+ startTranscriptionAction,
22
+ stopTranscriptionAction,
23
+ } from "./actions/transcription-control.js";
24
+ import { transcriptsRoutes } from "./routes/transcripts-routes.js";
25
+ import { voiceProfilePluginRoutes } from "./routes/voice-profile-plugin-routes.js";
26
+ import { handleVoiceEntityBound } from "./runtime/voice-entity-binding.js";
27
+
28
+ export const LOCAL_INFERENCE_PROVIDER_ID = "eliza-local-inference";
29
+ export const LOCAL_INFERENCE_PRIORITY = -100;
30
+
31
+ export const LOCAL_INFERENCE_TEXT_MODEL_TYPES = [
32
+ ModelType.TEXT_SMALL,
33
+ ModelType.TEXT_LARGE,
34
+ ] as const;
35
+
36
+ export const LOCAL_INFERENCE_MODEL_TYPES = [
37
+ ...LOCAL_INFERENCE_TEXT_MODEL_TYPES,
38
+ ModelType.TEXT_EMBEDDING,
39
+ ModelType.IMAGE,
40
+ ModelType.IMAGE_DESCRIPTION,
41
+ ModelType.TEXT_TO_SPEECH,
42
+ ModelType.TRANSCRIPTION,
43
+ ] as const;
44
+
45
+ const OMIT_MAX_TOKENS_LOCAL_BUDGET = 64_000;
46
+
47
+ export type LocalInferenceUnavailableReason =
48
+ | "backend_unavailable"
49
+ | "capability_unavailable"
50
+ | "invalid_input"
51
+ | "invalid_output";
52
+
53
+ export class LocalInferenceUnavailableError extends Error {
54
+ readonly code = "LOCAL_INFERENCE_UNAVAILABLE";
55
+ readonly provider = LOCAL_INFERENCE_PROVIDER_ID;
56
+
57
+ constructor(
58
+ readonly modelType: string,
59
+ readonly reason: LocalInferenceUnavailableReason,
60
+ message: string,
61
+ options?: { cause?: unknown },
62
+ ) {
63
+ super(message, options);
64
+ this.name = "LocalInferenceUnavailableError";
65
+ }
66
+
67
+ toJSON(): Record<string, string> {
68
+ return {
69
+ code: this.code,
70
+ provider: this.provider,
71
+ modelType: this.modelType,
72
+ reason: this.reason,
73
+ message: this.message,
74
+ };
75
+ }
76
+ }
77
+
78
+ export function isLocalInferenceUnavailableError(
79
+ error: unknown,
80
+ ): error is LocalInferenceUnavailableError {
81
+ return (
82
+ error instanceof LocalInferenceUnavailableError ||
83
+ (typeof error === "object" &&
84
+ error !== null &&
85
+ (error as { code?: unknown }).code === "LOCAL_INFERENCE_UNAVAILABLE")
86
+ );
87
+ }
88
+
89
+ interface LocalInferenceGenerateArgs {
90
+ prompt: string;
91
+ stopSequences?: string[];
92
+ maxTokens?: number;
93
+ temperature?: number;
94
+ topP?: number;
95
+ signal?: AbortSignal;
96
+ onTextChunk?: (chunk: string) => void | Promise<void>;
97
+ }
98
+
99
+ interface LocalInferenceEmbedResult {
100
+ embedding: number[];
101
+ }
102
+
103
+ interface LocalInferenceTextToSpeechService {
104
+ synthesizeSpeech?: (
105
+ text: string,
106
+ signal?: AbortSignal,
107
+ ) => Promise<Uint8Array | ArrayBuffer | Buffer>;
108
+ textToSpeech?: (args: {
109
+ text: string;
110
+ signal?: AbortSignal;
111
+ }) => Promise<Uint8Array | ArrayBuffer | Buffer>;
112
+ /**
113
+ * Optional streaming synth seam: yields audio (PCM/WAV) chunks as they are
114
+ * produced so playback can start before the whole clip is ready. When a
115
+ * backend implements it, the TEXT_TO_SPEECH handler returns an
116
+ * {@link AudioStreamResult} for `audioStream` callers; otherwise it falls
117
+ * back to a single-chunk result around the buffered synth.
118
+ */
119
+ synthesizeSpeechStream?: (
120
+ text: string,
121
+ signal?: AbortSignal,
122
+ ) => AsyncIterable<Uint8Array>;
123
+ }
124
+
125
+ interface LocalInferenceTranscriptionService {
126
+ transcribe?: (params: unknown) => Promise<string | { text?: string }>;
127
+ transcribePcm?: (
128
+ params: {
129
+ pcm: Float32Array;
130
+ sampleRate: number;
131
+ signal?: AbortSignal;
132
+ },
133
+ signal?: AbortSignal,
134
+ ) => Promise<string | { text?: string }>;
135
+ }
136
+
137
+ /**
138
+ * Optional arbiter accessor. When the local-inference plugin's runtime
139
+ * service registers a MemoryArbiter (WS1) on the IAgentRuntime, this
140
+ * field returns it. Cross-plugin consumers (plugin-vision, plugin-image-gen,
141
+ * plugin-aosp-local-inference) call `service.getMemoryArbiter()` to
142
+ * register their capability handlers and request model swaps without
143
+ * knowing which backend is loaded.
144
+ *
145
+ * The concrete return type is intentionally `unknown` here to keep this
146
+ * provider file free of a hard dependency on `./services/memory-arbiter`;
147
+ * consumers should import the `MemoryArbiter` type from
148
+ * `@elizaos/plugin-local-inference/services` and cast.
149
+ */
150
+ interface LocalInferenceArbiterAccessor {
151
+ getMemoryArbiter?: () => unknown;
152
+ }
153
+
154
+ interface LocalInferenceRuntimeService
155
+ extends LocalInferenceTextToSpeechService,
156
+ LocalInferenceTranscriptionService,
157
+ LocalInferenceArbiterAccessor {
158
+ generate?: (args: LocalInferenceGenerateArgs) => Promise<string>;
159
+ embed?: (args: {
160
+ input: string;
161
+ }) => Promise<number[] | LocalInferenceEmbedResult>;
162
+ describeImage?: (
163
+ params: ImageDescriptionParams | string,
164
+ ) => Promise<ImageDescriptionResult | string>;
165
+ imageDescription?: (
166
+ params: ImageDescriptionParams | string,
167
+ ) => Promise<ImageDescriptionResult | string>;
168
+ }
169
+
170
+ type RuntimeWithServices = IAgentRuntime & {
171
+ getService?: (name: string) => unknown;
172
+ };
173
+
174
+ function serviceFromRuntime(
175
+ runtime: IAgentRuntime,
176
+ ): LocalInferenceRuntimeService | null {
177
+ const withServices = runtime as RuntimeWithServices;
178
+ if (typeof withServices.getService !== "function") return null;
179
+
180
+ for (const name of [
181
+ "localInferenceLoader",
182
+ "localInference",
183
+ "LOCAL_INFERENCE",
184
+ ]) {
185
+ const candidate = withServices.getService(name);
186
+ if (candidate && typeof candidate === "object") {
187
+ return candidate as LocalInferenceRuntimeService;
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+
193
+ function unavailable(
194
+ modelType: string,
195
+ reason: LocalInferenceUnavailableReason,
196
+ message: string,
197
+ cause?: unknown,
198
+ ): LocalInferenceUnavailableError {
199
+ return new LocalInferenceUnavailableError(modelType, reason, message, {
200
+ cause,
201
+ });
202
+ }
203
+
204
+ function requireService(
205
+ runtime: IAgentRuntime,
206
+ modelType: string,
207
+ ): LocalInferenceRuntimeService {
208
+ const service = serviceFromRuntime(runtime);
209
+ if (!service) {
210
+ throw unavailable(
211
+ modelType,
212
+ "backend_unavailable",
213
+ `[local-inference] ${modelType} requires an active Eliza-1 local inference backend. Activate an Eliza-1 bundle or enable an AOSP/device local loader.`,
214
+ );
215
+ }
216
+ return service;
217
+ }
218
+
219
+ type MessageLike = {
220
+ role?: unknown;
221
+ content?: unknown;
222
+ };
223
+
224
+ type PromptSegmentLike = {
225
+ content?: unknown;
226
+ };
227
+
228
+ function renderPromptContent(content: unknown): string {
229
+ if (typeof content === "string") return content;
230
+ if (Array.isArray(content)) {
231
+ return content
232
+ .map((part) => {
233
+ if (typeof part === "string") return part;
234
+ if (
235
+ part &&
236
+ typeof part === "object" &&
237
+ typeof (part as { text?: unknown }).text === "string"
238
+ ) {
239
+ return (part as { text: string }).text;
240
+ }
241
+ return "";
242
+ })
243
+ .filter(Boolean)
244
+ .join("\n");
245
+ }
246
+ return "";
247
+ }
248
+
249
+ function promptFromMessages(messages: readonly MessageLike[]): string {
250
+ return messages
251
+ .map((message) => {
252
+ const content = renderPromptContent(message.content);
253
+ if (!content) return "";
254
+ const role =
255
+ typeof message.role === "string" && message.role.trim()
256
+ ? message.role.trim()
257
+ : "message";
258
+ return `${role}:\n${content}`;
259
+ })
260
+ .filter(Boolean)
261
+ .join("\n\n");
262
+ }
263
+
264
+ function promptFromParams(params: GenerateTextParams): string {
265
+ const record = params as GenerateTextParams & {
266
+ messages?: readonly MessageLike[];
267
+ promptSegments?: readonly PromptSegmentLike[];
268
+ };
269
+ const prompt =
270
+ typeof params.prompt === "string" && params.prompt.length > 0
271
+ ? params.prompt
272
+ : Array.isArray(record.promptSegments) && record.promptSegments.length > 0
273
+ ? record.promptSegments
274
+ .map((segment) => renderPromptContent(segment.content))
275
+ .join("")
276
+ : Array.isArray(record.messages) && record.messages.length > 0
277
+ ? promptFromMessages(record.messages)
278
+ : "";
279
+ if (typeof prompt !== "string" || prompt.trim().length === 0) {
280
+ throw unavailable(
281
+ ModelType.TEXT_SMALL,
282
+ "invalid_input",
283
+ "[local-inference] TEXT generation requires a non-empty prompt",
284
+ );
285
+ }
286
+ return prompt;
287
+ }
288
+
289
+ function textGenerationArgsFromParams(
290
+ params: GenerateTextParams,
291
+ ): LocalInferenceGenerateArgs {
292
+ return {
293
+ prompt: promptFromParams(params),
294
+ stopSequences: params.stopSequences,
295
+ maxTokens: params.omitMaxTokens
296
+ ? (params.maxTokens ?? OMIT_MAX_TOKENS_LOCAL_BUDGET)
297
+ : params.maxTokens,
298
+ temperature: params.temperature,
299
+ topP: params.topP,
300
+ signal: params.signal,
301
+ onTextChunk:
302
+ (params.stream === true || params.streamStructured === true) &&
303
+ typeof params.onStreamChunk === "function"
304
+ ? (chunk) => params.onStreamChunk?.(chunk)
305
+ : undefined,
306
+ };
307
+ }
308
+
309
+ function extractEmbeddingText(
310
+ params: TextEmbeddingParams | string | null,
311
+ ): string {
312
+ if (typeof params === "string") return params;
313
+ if (params && typeof params === "object" && typeof params.text === "string") {
314
+ return params.text;
315
+ }
316
+ throw unavailable(
317
+ ModelType.TEXT_EMBEDDING,
318
+ "invalid_input",
319
+ "[local-inference] TEXT_EMBEDDING requires { text } or a non-empty string; null warmup probes are not served with fake vectors",
320
+ );
321
+ }
322
+
323
+ function extractSpeechText(params: TextToSpeechParams | string): string {
324
+ if (typeof params === "string") return params;
325
+ if (params && typeof params === "object" && typeof params.text === "string") {
326
+ return params.text;
327
+ }
328
+ throw unavailable(
329
+ ModelType.TEXT_TO_SPEECH,
330
+ "invalid_input",
331
+ "[local-inference] TEXT_TO_SPEECH requires a string or { text } input",
332
+ );
333
+ }
334
+
335
+ function extractSpeechSignal(
336
+ params: TextToSpeechParams | string,
337
+ ): AbortSignal | undefined {
338
+ return typeof params === "object" && params !== null
339
+ ? params.signal
340
+ : undefined;
341
+ }
342
+
343
+ function ensureNonEmptyText(modelType: string, text: string): string {
344
+ const trimmed = text.trim();
345
+ if (!trimmed) {
346
+ throw unavailable(
347
+ modelType,
348
+ "invalid_input",
349
+ `[local-inference] ${modelType} requires non-empty text`,
350
+ );
351
+ }
352
+ return trimmed;
353
+ }
354
+
355
+ function normalizeEmbeddingResult(
356
+ result: number[] | LocalInferenceEmbedResult,
357
+ ): number[] {
358
+ const embedding = Array.isArray(result) ? result : result.embedding;
359
+ if (
360
+ !Array.isArray(embedding) ||
361
+ embedding.some((value) => typeof value !== "number")
362
+ ) {
363
+ throw unavailable(
364
+ ModelType.TEXT_EMBEDDING,
365
+ "invalid_output",
366
+ "[local-inference] TEXT_EMBEDDING backend returned an invalid embedding",
367
+ );
368
+ }
369
+ return embedding;
370
+ }
371
+
372
+ function normalizeAudioBytes(
373
+ result: Uint8Array | ArrayBuffer | Buffer,
374
+ ): Uint8Array {
375
+ if (result instanceof Uint8Array) {
376
+ return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
377
+ }
378
+ if (result instanceof ArrayBuffer) {
379
+ return new Uint8Array(result);
380
+ }
381
+ throw unavailable(
382
+ ModelType.TEXT_TO_SPEECH,
383
+ "invalid_output",
384
+ "[local-inference] TEXT_TO_SPEECH backend returned non-audio output",
385
+ );
386
+ }
387
+
388
+ function concatAudioChunks(chunks: Uint8Array[]): Uint8Array {
389
+ const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
390
+ const out = new Uint8Array(total);
391
+ let offset = 0;
392
+ for (const chunk of chunks) {
393
+ out.set(chunk, offset);
394
+ offset += chunk.byteLength;
395
+ }
396
+ return out;
397
+ }
398
+
399
+ /** A single-chunk {@link AudioStreamResult} around already-synthesized bytes —
400
+ * satisfies the streaming contract when the backend has no streaming synth. */
401
+ function bufferedAudioStreamResult(
402
+ bytes: Uint8Array,
403
+ mimeType: string,
404
+ ): AudioStreamResult {
405
+ async function* generate(): AsyncGenerator<Uint8Array> {
406
+ if (bytes.byteLength > 0) yield bytes;
407
+ }
408
+ return { audioStream: generate(), bytes: Promise.resolve(bytes), mimeType };
409
+ }
410
+
411
+ /** Wrap a backend streaming synth as an {@link AudioStreamResult}, accumulating
412
+ * the chunks so `bytes` resolves to the full clip after the stream is drained. */
413
+ function streamingAudioStreamResult(
414
+ source: AsyncIterable<Uint8Array>,
415
+ mimeType: string,
416
+ ): AudioStreamResult {
417
+ const collected: Uint8Array[] = [];
418
+ let resolveBytes!: (value: Uint8Array) => void;
419
+ let rejectBytes!: (reason: unknown) => void;
420
+ const bytes = new Promise<Uint8Array>((resolve, reject) => {
421
+ resolveBytes = resolve;
422
+ rejectBytes = reject;
423
+ });
424
+ async function* generate(): AsyncGenerator<Uint8Array> {
425
+ try {
426
+ for await (const value of source) {
427
+ const chunk = normalizeAudioBytes(value);
428
+ collected.push(chunk);
429
+ yield chunk;
430
+ }
431
+ resolveBytes(concatAudioChunks(collected));
432
+ } catch (err) {
433
+ rejectBytes(err);
434
+ throw err;
435
+ }
436
+ }
437
+ return { audioStream: generate(), bytes, mimeType };
438
+ }
439
+
440
+ const LOCAL_TTS_MIME = "audio/wav";
441
+
442
+ function extractPcmTranscriptionParams(
443
+ params: TranscriptionParams | Buffer | string | unknown,
444
+ ): { pcm: Float32Array; sampleRate: number; signal?: AbortSignal } {
445
+ if (!params || typeof params !== "object" || params instanceof Uint8Array) {
446
+ throw unavailable(
447
+ ModelType.TRANSCRIPTION,
448
+ "invalid_input",
449
+ "[local-inference] TRANSCRIPTION requires { pcm, sampleRateHz } when only transcribePcm is available",
450
+ );
451
+ }
452
+ const record = params as {
453
+ pcm?: unknown;
454
+ sampleRateHz?: unknown;
455
+ sampleRate?: unknown;
456
+ signal?: AbortSignal;
457
+ };
458
+ if (!(record.pcm instanceof Float32Array)) {
459
+ throw unavailable(
460
+ ModelType.TRANSCRIPTION,
461
+ "invalid_input",
462
+ "[local-inference] TRANSCRIPTION requires Float32Array pcm when only transcribePcm is available",
463
+ );
464
+ }
465
+ const sampleRate =
466
+ typeof record.sampleRateHz === "number"
467
+ ? record.sampleRateHz
468
+ : typeof record.sampleRate === "number"
469
+ ? record.sampleRate
470
+ : 0;
471
+ if (!Number.isFinite(sampleRate) || sampleRate <= 0) {
472
+ throw unavailable(
473
+ ModelType.TRANSCRIPTION,
474
+ "invalid_input",
475
+ "[local-inference] TRANSCRIPTION { pcm } requires a positive sampleRateHz",
476
+ );
477
+ }
478
+ return record.signal
479
+ ? { pcm: record.pcm, sampleRate, signal: record.signal }
480
+ : { pcm: record.pcm, sampleRate };
481
+ }
482
+
483
+ function extractTranscriptionSignal(params: unknown): AbortSignal | undefined {
484
+ return typeof params === "object" && params !== null
485
+ ? (params as { signal?: AbortSignal }).signal
486
+ : undefined;
487
+ }
488
+
489
+ function throwIfAborted(signal: AbortSignal | undefined): void {
490
+ if (!signal?.aborted) return;
491
+ throw signal.reason instanceof Error
492
+ ? signal.reason
493
+ : new DOMException("Aborted", "AbortError");
494
+ }
495
+
496
+ function normalizeTranscript(result: string | { text?: string }): string {
497
+ const text = typeof result === "string" ? result : result.text;
498
+ if (typeof text !== "string") {
499
+ throw unavailable(
500
+ ModelType.TRANSCRIPTION,
501
+ "invalid_output",
502
+ "[local-inference] TRANSCRIPTION backend returned an invalid transcript",
503
+ );
504
+ }
505
+ return text;
506
+ }
507
+
508
+ function normalizeImageDescription(
509
+ result: ImageDescriptionResult | string,
510
+ ): ImageDescriptionResult {
511
+ if (typeof result === "string") {
512
+ const description = ensureNonEmptyText(ModelType.IMAGE_DESCRIPTION, result);
513
+ return {
514
+ title: description.split(/[.!?]/, 1)[0]?.trim() || "Image",
515
+ description,
516
+ };
517
+ }
518
+ if (
519
+ result &&
520
+ typeof result === "object" &&
521
+ typeof result.title === "string" &&
522
+ typeof result.description === "string"
523
+ ) {
524
+ return {
525
+ title: ensureNonEmptyText(ModelType.IMAGE_DESCRIPTION, result.title),
526
+ description: ensureNonEmptyText(
527
+ ModelType.IMAGE_DESCRIPTION,
528
+ result.description,
529
+ ),
530
+ };
531
+ }
532
+ throw unavailable(
533
+ ModelType.IMAGE_DESCRIPTION,
534
+ "invalid_output",
535
+ "[local-inference] IMAGE_DESCRIPTION backend returned an invalid description",
536
+ );
537
+ }
538
+
539
+ function createTextHandler(modelType: string) {
540
+ return async (
541
+ runtime: IAgentRuntime,
542
+ params: GenerateTextParams,
543
+ ): Promise<string> => {
544
+ const service = requireService(runtime, modelType);
545
+ if (typeof service.generate !== "function") {
546
+ throw unavailable(
547
+ modelType,
548
+ "capability_unavailable",
549
+ `[local-inference] Active local backend does not implement ${modelType} generation`,
550
+ );
551
+ }
552
+ return service.generate(textGenerationArgsFromParams(params));
553
+ };
554
+ }
555
+
556
+ function createEmbeddingHandler() {
557
+ return async (
558
+ runtime: IAgentRuntime,
559
+ params: TextEmbeddingParams | string | null,
560
+ ): Promise<number[]> => {
561
+ const service = serviceFromRuntime(runtime);
562
+ if (!service) {
563
+ throw unavailable(
564
+ ModelType.TEXT_EMBEDDING,
565
+ "backend_unavailable",
566
+ "[local-inference] TEXT_EMBEDDING requires an active Eliza-1 backend or another embedding provider; refusing to synthesize zero-vectors.",
567
+ );
568
+ }
569
+ if (typeof service.embed !== "function") {
570
+ throw unavailable(
571
+ ModelType.TEXT_EMBEDDING,
572
+ "capability_unavailable",
573
+ "[local-inference] Active local backend does not implement TEXT_EMBEDDING",
574
+ );
575
+ }
576
+ const input = ensureNonEmptyText(
577
+ ModelType.TEXT_EMBEDDING,
578
+ extractEmbeddingText(params),
579
+ );
580
+ return normalizeEmbeddingResult(await service.embed({ input }));
581
+ };
582
+ }
583
+
584
+ function createTextToSpeechHandler() {
585
+ return async (
586
+ runtime: IAgentRuntime,
587
+ params: TextToSpeechParams | string,
588
+ ): Promise<Uint8Array | AudioStreamResult> => {
589
+ const service = requireService(runtime, ModelType.TEXT_TO_SPEECH);
590
+ const text = ensureNonEmptyText(
591
+ ModelType.TEXT_TO_SPEECH,
592
+ extractSpeechText(params),
593
+ );
594
+ const signal = extractSpeechSignal(params);
595
+ // Explicit opt-in (NOT the generic `stream` useModel injects from an
596
+ // ambient text-streaming turn) so byte-expecting callers keep a buffer.
597
+ const wantsStream =
598
+ typeof params === "object" &&
599
+ params !== null &&
600
+ (params as { audioStream?: boolean }).audioStream === true;
601
+
602
+ // Real chunked streaming when the backend implements the seam.
603
+ if (wantsStream && typeof service.synthesizeSpeechStream === "function") {
604
+ return streamingAudioStreamResult(
605
+ service.synthesizeSpeechStream(text, signal),
606
+ LOCAL_TTS_MIME,
607
+ );
608
+ }
609
+
610
+ const synthesizeBuffered = async (): Promise<Uint8Array> => {
611
+ if (typeof service.synthesizeSpeech === "function") {
612
+ return normalizeAudioBytes(
613
+ await service.synthesizeSpeech(text, signal),
614
+ );
615
+ }
616
+ if (typeof service.textToSpeech === "function") {
617
+ return normalizeAudioBytes(
618
+ await service.textToSpeech({ text, ...(signal ? { signal } : {}) }),
619
+ );
620
+ }
621
+ throw unavailable(
622
+ ModelType.TEXT_TO_SPEECH,
623
+ "capability_unavailable",
624
+ "[local-inference] Active local backend does not implement TEXT_TO_SPEECH",
625
+ );
626
+ };
627
+
628
+ const bytes = await synthesizeBuffered();
629
+ // Streaming asked but no streaming backend — satisfy the contract with a
630
+ // single chunk so consumers use one code path for cloud + local.
631
+ return wantsStream
632
+ ? bufferedAudioStreamResult(bytes, LOCAL_TTS_MIME)
633
+ : bytes;
634
+ };
635
+ }
636
+
637
+ function createTranscriptionHandler() {
638
+ return async (
639
+ runtime: IAgentRuntime,
640
+ params: TranscriptionParams | Buffer | string | unknown,
641
+ ): Promise<string> => {
642
+ const service = requireService(runtime, ModelType.TRANSCRIPTION);
643
+ const signal = extractTranscriptionSignal(params);
644
+ throwIfAborted(signal);
645
+ if (typeof service.transcribe === "function") {
646
+ const transcript = normalizeTranscript(await service.transcribe(params));
647
+ throwIfAborted(signal);
648
+ return transcript;
649
+ }
650
+ if (typeof service.transcribePcm === "function") {
651
+ const pcmParams = extractPcmTranscriptionParams(params);
652
+ const transcript = normalizeTranscript(
653
+ await (signal
654
+ ? service.transcribePcm(pcmParams, signal)
655
+ : service.transcribePcm(pcmParams)),
656
+ );
657
+ throwIfAborted(signal);
658
+ return transcript;
659
+ }
660
+ throw unavailable(
661
+ ModelType.TRANSCRIPTION,
662
+ "capability_unavailable",
663
+ "[local-inference] Active local backend does not implement TRANSCRIPTION",
664
+ );
665
+ };
666
+ }
667
+
668
+ /**
669
+ * Arbiter accessor shape used by the IMAGE_DESCRIPTION handler. Two
670
+ * call paths converge here:
671
+ *
672
+ * (a) The WS2 arbiter path. When the loader service exposes
673
+ * `getMemoryArbiter()` AND that arbiter has the `vision-describe`
674
+ * capability registered, IMAGE_DESCRIPTION dispatches through
675
+ * `arbiter.requestVisionDescribe(...)`.
676
+ *
677
+ * (b) Legacy `service.describeImage(...)` / `service.imageDescription`.
678
+ * Pre-WS2 callers (the AOSP bootstrap, Florence-2 LocalAIManager)
679
+ * still hit this fallback.
680
+ */
681
+ interface ArbiterLike {
682
+ hasCapability?: (capability: string) => boolean;
683
+ requestVisionDescribe?: <Req, Res>(req: {
684
+ modelKey: string;
685
+ payload: Req;
686
+ }) => Promise<Res>;
687
+ requestImageGen?: <Req, Res>(req: {
688
+ modelKey: string;
689
+ payload: Req;
690
+ }) => Promise<Res>;
691
+ }
692
+
693
+ function tryGetArbiter(
694
+ service: LocalInferenceRuntimeService | null,
695
+ ): ArbiterLike | null {
696
+ if (!service?.getMemoryArbiter) return null;
697
+ const arbiter = service.getMemoryArbiter();
698
+ if (!arbiter || typeof arbiter !== "object") return null;
699
+ const cand = arbiter as ArbiterLike;
700
+ if (
701
+ typeof cand.hasCapability === "function" &&
702
+ typeof cand.requestVisionDescribe === "function" &&
703
+ cand.hasCapability("vision-describe")
704
+ ) {
705
+ return cand;
706
+ }
707
+ return null;
708
+ }
709
+
710
+ function tryGetImageGenArbiter(
711
+ service: LocalInferenceRuntimeService | null,
712
+ ): ArbiterLike | null {
713
+ if (!service?.getMemoryArbiter) return null;
714
+ const arbiter = service.getMemoryArbiter();
715
+ if (!arbiter || typeof arbiter !== "object") return null;
716
+ const cand = arbiter as ArbiterLike;
717
+ if (
718
+ typeof cand.hasCapability === "function" &&
719
+ typeof cand.requestImageGen === "function" &&
720
+ cand.hasCapability("image-gen")
721
+ ) {
722
+ return cand;
723
+ }
724
+ return null;
725
+ }
726
+
727
+ function paramsToVisionRequest(params: ImageDescriptionParams | string): {
728
+ image: { kind: "dataUrl"; dataUrl: string } | { kind: "url"; url: string };
729
+ prompt?: string;
730
+ signal?: AbortSignal;
731
+ onTextChunk?: (chunk: string) => void | Promise<void>;
732
+ } {
733
+ const url = typeof params === "string" ? params : params.imageUrl;
734
+ if (typeof url !== "string" || !url) {
735
+ throw unavailable(
736
+ ModelType.IMAGE_DESCRIPTION,
737
+ "invalid_input",
738
+ "[local-inference] IMAGE_DESCRIPTION requires a non-empty imageUrl",
739
+ );
740
+ }
741
+ const prompt = typeof params === "object" ? params.prompt : undefined;
742
+ const signal =
743
+ typeof params === "object"
744
+ ? (params as { signal?: AbortSignal }).signal
745
+ : undefined;
746
+ // Token-by-token streaming is intentionally explicit for vision. Hidden image
747
+ // preprocessing can happen inside a streaming chat turn; only forward the
748
+ // runtime callback when the call itself asks for `stream: true`.
749
+ const wantsStream =
750
+ typeof params === "object" &&
751
+ (params as { stream?: boolean }).stream === true;
752
+ const streamSink =
753
+ wantsStream && typeof params === "object"
754
+ ? (params as { onStreamChunk?: (chunk: string) => void | Promise<void> })
755
+ .onStreamChunk
756
+ : undefined;
757
+ const onTextChunk =
758
+ typeof streamSink === "function"
759
+ ? (chunk: string) => streamSink(chunk)
760
+ : undefined;
761
+ if (url.startsWith("data:")) {
762
+ return {
763
+ image: { kind: "dataUrl", dataUrl: url },
764
+ prompt,
765
+ ...(signal ? { signal } : {}),
766
+ ...(onTextChunk ? { onTextChunk } : {}),
767
+ };
768
+ }
769
+ return {
770
+ image: { kind: "url", url },
771
+ prompt,
772
+ ...(signal ? { signal } : {}),
773
+ ...(onTextChunk ? { onTextChunk } : {}),
774
+ };
775
+ }
776
+
777
+ /**
778
+ * Runtime setting marker that plugin-vision's `hasEliza1VisionHandler`
779
+ * polls. Setting this to `"1"` makes VisionService prefer the eliza-1
780
+ * IMAGE_DESCRIPTION handler over local Florence-2. We set it the first
781
+ * time the handler runs against an arbiter that has the
782
+ * `vision-describe` capability registered, so the marker reflects
783
+ * actual capability rather than plugin presence.
784
+ */
785
+ const ELIZA1_VISION_MARKER = "ELIZA1_VISION_HANDLER_PRESENT";
786
+
787
+ function markEliza1VisionHandlerPresent(runtime: IAgentRuntime): void {
788
+ const r = runtime as IAgentRuntime & {
789
+ setSetting?: (key: string, value: unknown) => void;
790
+ getSetting?: (key: string) => unknown;
791
+ };
792
+ if (typeof r.setSetting !== "function") return;
793
+ if (typeof r.getSetting === "function") {
794
+ const existing = r.getSetting(ELIZA1_VISION_MARKER);
795
+ if (existing === "1" || existing === true) return;
796
+ }
797
+ try {
798
+ r.setSetting(ELIZA1_VISION_MARKER, "1");
799
+ } catch {
800
+ // Some test runtimes don't accept setSetting at runtime — non-fatal.
801
+ }
802
+ }
803
+
804
+ function createImageDescriptionHandler() {
805
+ return async (
806
+ runtime: IAgentRuntime,
807
+ params: ImageDescriptionParams | string,
808
+ ): Promise<ImageDescriptionResult> => {
809
+ const service = requireService(runtime, ModelType.IMAGE_DESCRIPTION);
810
+ const arbiter = tryGetArbiter(service);
811
+ if (arbiter?.requestVisionDescribe) {
812
+ // WS2 path. The arbiter owns the model handle and the projector
813
+ // cache; we forward the request and let it dispatch.
814
+ markEliza1VisionHandlerPresent(runtime);
815
+ const modelKeyCandidate =
816
+ typeof params === "object"
817
+ ? (params as { modelKey?: unknown }).modelKey
818
+ : undefined;
819
+ const modelKey =
820
+ typeof modelKeyCandidate === "string" && modelKeyCandidate
821
+ ? modelKeyCandidate
822
+ : "gemma-vl";
823
+ const request = paramsToVisionRequest(params);
824
+ const result = await arbiter.requestVisionDescribe<
825
+ typeof request,
826
+ ImageDescriptionResult | string
827
+ >({ modelKey, payload: request });
828
+ return normalizeImageDescription(result);
829
+ }
830
+ if (typeof service.describeImage === "function") {
831
+ return normalizeImageDescription(await service.describeImage(params));
832
+ }
833
+ if (typeof service.imageDescription === "function") {
834
+ return normalizeImageDescription(await service.imageDescription(params));
835
+ }
836
+ throw unavailable(
837
+ ModelType.IMAGE_DESCRIPTION,
838
+ "capability_unavailable",
839
+ "[local-inference] Active local backend does not implement IMAGE_DESCRIPTION",
840
+ );
841
+ };
842
+ }
843
+
844
+ /**
845
+ * Image-gen request shape the WS3 arbiter capability accepts. Mirrors
846
+ * `ImageGenRequest` from `./services/imagegen/types` without importing
847
+ * the full module here — we want this provider file to stay free of a
848
+ * hard dependency on the imagegen subpackage so the type surface
849
+ * doesn't reach across plugins.
850
+ */
851
+ interface ProviderImageGenRequest {
852
+ prompt: string;
853
+ negativePrompt?: string;
854
+ width?: number;
855
+ height?: number;
856
+ steps?: number;
857
+ guidanceScale?: number;
858
+ seed?: number;
859
+ scheduler?: string;
860
+ signal?: AbortSignal;
861
+ }
862
+
863
+ interface ProviderImageGenResult {
864
+ image: Uint8Array;
865
+ mime: "image/png" | "image/jpeg";
866
+ seed: number;
867
+ metadata: {
868
+ model: string;
869
+ prompt: string;
870
+ steps: number;
871
+ guidanceScale: number;
872
+ inferenceTimeMs: number;
873
+ };
874
+ }
875
+
876
+ function paramsToImageGenRequest(
877
+ params: ImageGenerationParams,
878
+ ): ProviderImageGenRequest {
879
+ if (typeof params.prompt !== "string" || !params.prompt.trim()) {
880
+ throw unavailable(
881
+ ModelType.IMAGE,
882
+ "invalid_input",
883
+ "[local-inference] IMAGE requires a non-empty prompt",
884
+ );
885
+ }
886
+ const out: ProviderImageGenRequest = { prompt: params.prompt };
887
+ if (typeof params.size === "string" && /^\d+x\d+$/i.test(params.size)) {
888
+ const [w, h] = params.size
889
+ .toLowerCase()
890
+ .split("x")
891
+ .map((n) => Number(n));
892
+ if (Number.isFinite(w) && w > 0) out.width = w;
893
+ if (Number.isFinite(h) && h > 0) out.height = h;
894
+ }
895
+ // Forward optional extended knobs when callers pass them through
896
+ // the `ImageGenerationParams` extension fields. We intentionally
897
+ // don't enrich `ImageGenerationParams` in @elizaos/core for this —
898
+ // see "Hand-off" in the WS3 report.
899
+ const extended = params as ImageGenerationParams & {
900
+ negativePrompt?: unknown;
901
+ steps?: unknown;
902
+ guidanceScale?: unknown;
903
+ seed?: unknown;
904
+ scheduler?: unknown;
905
+ signal?: unknown;
906
+ };
907
+ if (typeof extended.negativePrompt === "string") {
908
+ out.negativePrompt = extended.negativePrompt;
909
+ }
910
+ if (typeof extended.steps === "number" && extended.steps > 0) {
911
+ out.steps = Math.floor(extended.steps);
912
+ }
913
+ if (
914
+ typeof extended.guidanceScale === "number" &&
915
+ extended.guidanceScale >= 0
916
+ ) {
917
+ out.guidanceScale = extended.guidanceScale;
918
+ }
919
+ if (typeof extended.seed === "number" && Number.isFinite(extended.seed)) {
920
+ out.seed = Math.floor(extended.seed);
921
+ }
922
+ if (typeof extended.scheduler === "string") {
923
+ out.scheduler = extended.scheduler;
924
+ }
925
+ if (extended.signal instanceof AbortSignal) {
926
+ out.signal = extended.signal;
927
+ }
928
+ return out;
929
+ }
930
+
931
+ function imageGenResultToUrls(
932
+ result: ProviderImageGenResult,
933
+ ): ImageGenerationResult[] {
934
+ if (!(result.image instanceof Uint8Array) || result.image.length === 0) {
935
+ throw unavailable(
936
+ ModelType.IMAGE,
937
+ "invalid_output",
938
+ "[local-inference] IMAGE backend returned an empty image buffer",
939
+ );
940
+ }
941
+ const mime = result.mime === "image/jpeg" ? "image/jpeg" : "image/png";
942
+ const base64 = Buffer.from(result.image).toString("base64");
943
+ return [{ url: `data:${mime};base64,${base64}` }];
944
+ }
945
+
946
+ function createImageGenerationHandler() {
947
+ return async (
948
+ runtime: IAgentRuntime,
949
+ params: ImageGenerationParams,
950
+ ): Promise<ImageGenerationResult[]> => {
951
+ const service = requireService(runtime, ModelType.IMAGE);
952
+ const arbiter = tryGetImageGenArbiter(service);
953
+ if (!arbiter?.requestImageGen) {
954
+ throw unavailable(
955
+ ModelType.IMAGE,
956
+ "capability_unavailable",
957
+ "[local-inference] IMAGE generation requires the WS3 arbiter image-gen capability. Register it via createImageGenCapabilityRegistration at plugin init.",
958
+ );
959
+ }
960
+ const request = paramsToImageGenRequest(params);
961
+ // The local-inference IMAGE handler only ever returns a single
962
+ // image — local diffusion runtimes serialize batch-1 by default,
963
+ // and an N>1 request would just be N back-to-back generates. We
964
+ // honour `params.count` by looping the request rather than
965
+ // pretending the backend supports batched output.
966
+ const count = Math.max(1, Math.min(8, params.count ?? 1));
967
+ // Resolve modelKey from the active tier the loader knows about.
968
+ // We prefer the optional `modelKey` extension; otherwise the
969
+ // runtime's active tier from `service.activeTier` / the
970
+ // `LOCAL_INFERENCE_ACTIVE_TIER` setting; otherwise the safe
971
+ // small-tier default. Callers that want to pin a specific
972
+ // diffusion model pass `modelKey` through the params extension.
973
+ const modelKeyCandidate = (
974
+ params as ImageGenerationParams & { modelKey?: unknown }
975
+ ).modelKey;
976
+ const modelKey =
977
+ typeof modelKeyCandidate === "string" && modelKeyCandidate
978
+ ? modelKeyCandidate
979
+ : resolveImageGenModelKeyFromRuntime(runtime);
980
+
981
+ const results: ImageGenerationResult[] = [];
982
+ for (let i = 0; i < count; i += 1) {
983
+ const seeded: ProviderImageGenRequest =
984
+ typeof request.seed === "number" && i > 0
985
+ ? { ...request, seed: request.seed + i }
986
+ : request;
987
+ const result = await arbiter.requestImageGen<
988
+ ProviderImageGenRequest,
989
+ ProviderImageGenResult
990
+ >({ modelKey, payload: seeded });
991
+ results.push(...imageGenResultToUrls(result));
992
+ }
993
+ return results;
994
+ };
995
+ }
996
+
997
+ /**
998
+ * Resolve the active tier-bound image-gen model id without importing
999
+ * the imagegen subpackage. We look at:
1000
+ *
1001
+ * 1. `runtime.getSetting("LOCAL_INFERENCE_IMAGE_MODEL_KEY")` — explicit pin.
1002
+ * 2. `runtime.getSetting("LOCAL_INFERENCE_ACTIVE_TIER")` mapped through the
1003
+ * same tier → default-model map that lives in `backend-selector.ts`.
1004
+ * 3. Fall back to the small-tier default (`imagegen-sd-1_5-q5_0`).
1005
+ */
1006
+ function resolveImageGenModelKeyFromRuntime(runtime: IAgentRuntime): string {
1007
+ const r = runtime as IAgentRuntime & {
1008
+ getSetting?: (key: string) => unknown;
1009
+ };
1010
+ const pinned = r.getSetting("LOCAL_INFERENCE_IMAGE_MODEL_KEY");
1011
+ if (typeof pinned === "string" && pinned.trim()) return pinned.trim();
1012
+ const tier = r.getSetting("LOCAL_INFERENCE_ACTIVE_TIER");
1013
+ if (typeof tier === "string" && tier.trim()) {
1014
+ const mapped = TIER_TO_DEFAULT_IMAGE_MODEL_KEY[tier.trim()];
1015
+ if (mapped) return mapped;
1016
+ }
1017
+ return "imagegen-sd-1_5-q5_0";
1018
+ }
1019
+
1020
+ /**
1021
+ * Inlined tier → default image-gen model id map. Duplicates the
1022
+ * `TIER_TO_DEFAULT_IMAGE_MODEL` entries in `backend-selector.ts` —
1023
+ * provider.ts intentionally avoids importing the imagegen subpackage
1024
+ * so the provider stays loadable on runtimes that don't ship
1025
+ * the WS3 capability. The two maps are kept in sync by the WS3
1026
+ * routing test (`imagegen-routing.test.ts`).
1027
+ */
1028
+ const TIER_TO_DEFAULT_IMAGE_MODEL_KEY: Readonly<Record<string, string>> = {
1029
+ "eliza-1-2b": "imagegen-sd-1_5-q5_0",
1030
+ "eliza-1-4b": "imagegen-sd-1_5-q5_0",
1031
+ "eliza-1-9b": "imagegen-z-image-turbo-q4_k_m",
1032
+ "eliza-1-27b": "imagegen-z-image-turbo-q4_k_m",
1033
+ "eliza-1-27b-256k": "imagegen-z-image-turbo-q4_k_m",
1034
+ };
1035
+
1036
+ export function createLocalInferenceModelHandlers(): NonNullable<
1037
+ Plugin["models"]
1038
+ > {
1039
+ return {
1040
+ [ModelType.TEXT_SMALL]: createTextHandler(ModelType.TEXT_SMALL),
1041
+ [ModelType.TEXT_LARGE]: createTextHandler(ModelType.TEXT_LARGE),
1042
+ [ModelType.TEXT_EMBEDDING]: createEmbeddingHandler(),
1043
+ [ModelType.IMAGE]: createImageGenerationHandler(),
1044
+ [ModelType.IMAGE_DESCRIPTION]: createImageDescriptionHandler(),
1045
+ [ModelType.TEXT_TO_SPEECH]: createTextToSpeechHandler(),
1046
+ [ModelType.TRANSCRIPTION]: createTranscriptionHandler(),
1047
+ };
1048
+ }
1049
+
1050
+ function createStaticPluginModelHandlers(): NonNullable<Plugin["models"]> {
1051
+ const { [ModelType.TEXT_EMBEDDING]: _embedding, ...handlers } =
1052
+ createLocalInferenceModelHandlers();
1053
+ return handlers;
1054
+ }
1055
+
1056
+ export const localInferencePlugin: Plugin = {
1057
+ name: LOCAL_INFERENCE_PROVIDER_ID,
1058
+ description:
1059
+ "Eliza-1 local provider for text, embeddings, text-to-speech, and transcription.",
1060
+ priority: LOCAL_INFERENCE_PRIORITY,
1061
+ actions: [
1062
+ generateMediaAction,
1063
+ identifySpeakerAction,
1064
+ startTranscriptionAction,
1065
+ stopTranscriptionAction,
1066
+ ],
1067
+ events: {
1068
+ // Round-trip half of the voice→entity binding: when the merge engine
1069
+ // (plugin-lifeops) reports a binding, persist entityId onto the matching
1070
+ // voice profile(s). See runtime/voice-entity-binding.ts.
1071
+ [EventType.VOICE_ENTITY_BOUND]: [handleVoiceEntityBound],
1072
+ },
1073
+ // Voice-profile HTTP surface (speaker→entity bind/unbind + the
1074
+ // VoiceProfileSection management UI). Registered as rawPath plugin routes
1075
+ // because no server forwards these namespaces to the local-inference
1076
+ // route dispatcher. See routes/voice-profile-plugin-routes.ts.
1077
+ routes: [...voiceProfilePluginRoutes, ...transcriptsRoutes],
1078
+ // TEXT_EMBEDDING is wired by ensureLocalInferenceHandler(), not the static
1079
+ // plugin object. Runtime bootstrap probes embeddings before the user has
1080
+ // activated an Eliza-1 bundle; registering the static handler there claims a
1081
+ // provider that cannot embed yet and aborts startup instead of letting the
1082
+ // app come online.
1083
+ models: createStaticPluginModelHandlers(),
1084
+ async init(_config: unknown, runtime: IAgentRuntime) {
1085
+ const service = serviceFromRuntime(runtime);
1086
+ if (!service) {
1087
+ logger.info(
1088
+ "[local-inference] Provider registered; no active backend service is exposed yet. Model calls will return LOCAL_INFERENCE_UNAVAILABLE until an Eliza-1 backend is activated.",
1089
+ );
1090
+ return;
1091
+ }
1092
+ logger.info(
1093
+ {
1094
+ generate: typeof service.generate === "function",
1095
+ embed: typeof service.embed === "function",
1096
+ textToSpeech:
1097
+ typeof service.synthesizeSpeech === "function" ||
1098
+ typeof service.textToSpeech === "function",
1099
+ imageDescription:
1100
+ typeof service.describeImage === "function" ||
1101
+ typeof service.imageDescription === "function",
1102
+ transcription:
1103
+ typeof service.transcribe === "function" ||
1104
+ typeof service.transcribePcm === "function",
1105
+ },
1106
+ "[local-inference] Provider connected to runtime backend service",
1107
+ );
1108
+ },
1109
+ };
1110
+
1111
+ export default localInferencePlugin;