@elizaos/plugin-local-inference 2.0.0-beta.1 → 2.0.3-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/package.json +82 -15
- package/src/actions/generate-media.d.ts +59 -0
- package/src/actions/generate-media.d.ts.map +1 -0
- package/src/actions/generate-media.ts +647 -0
- package/src/actions/identify-speaker.d.ts +23 -0
- package/src/actions/identify-speaker.d.ts.map +1 -0
- package/src/actions/identify-speaker.ts +171 -0
- package/src/actions/transcription-control.d.ts +29 -0
- package/src/actions/transcription-control.d.ts.map +1 -0
- package/src/actions/transcription-control.test.ts +100 -0
- package/src/actions/transcription-control.ts +127 -0
- package/src/adapters/capacitor-llama/__tests__/compat-behavior.test.ts +218 -0
- package/src/adapters/capacitor-llama/__tests__/index.test.ts +68 -0
- package/src/adapters/capacitor-llama/__tests__/structured-output.test.ts +215 -0
- package/src/adapters/capacitor-llama/__tests__/text-streaming.test.ts +174 -0
- package/src/adapters/capacitor-llama/environment.ts +71 -0
- package/src/adapters/capacitor-llama/index.browser.ts +83 -0
- package/src/adapters/capacitor-llama/index.ts +807 -0
- package/src/adapters/capacitor-llama/loader.ts +109 -0
- package/src/adapters/capacitor-llama/structured-output.ts +165 -0
- package/src/adapters/capacitor-llama/text-streaming.ts +227 -0
- package/src/adapters/capacitor-llama/types.ts +374 -0
- package/src/backends/apple-foundation.ts +127 -0
- package/src/index.d.ts +8 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +62 -0
- package/src/local-inference-routes.d.ts +38 -0
- package/src/local-inference-routes.d.ts.map +1 -0
- package/src/local-inference-routes.test.ts +344 -0
- package/src/local-inference-routes.ts +1543 -0
- package/src/provider.d.ts +21 -0
- package/src/provider.d.ts.map +1 -0
- package/src/provider.ts +1082 -0
- package/src/routes/compat-helpers.d.ts +18 -0
- package/src/routes/compat-helpers.d.ts.map +1 -0
- package/src/routes/compat-helpers.ts +274 -0
- package/src/routes/family-member-route.d.ts +62 -0
- package/src/routes/family-member-route.d.ts.map +1 -0
- package/src/routes/family-member-route.ts +353 -0
- package/src/routes/index.d.ts +19 -0
- package/src/routes/index.d.ts.map +1 -0
- package/src/routes/index.ts +60 -0
- package/src/routes/live-diarization-route.d.ts +26 -0
- package/src/routes/live-diarization-route.d.ts.map +1 -0
- package/src/routes/live-diarization-route.test.ts +213 -0
- package/src/routes/live-diarization-route.ts +122 -0
- package/src/routes/local-inference-asr-route.d.ts +4 -0
- package/src/routes/local-inference-asr-route.d.ts.map +1 -0
- package/src/routes/local-inference-asr-route.test.ts +205 -0
- package/src/routes/local-inference-asr-route.ts +163 -0
- package/src/routes/local-inference-asr-transcribe.d.ts +20 -0
- package/src/routes/local-inference-asr-transcribe.d.ts.map +1 -0
- package/src/routes/local-inference-asr-transcribe.test.ts +118 -0
- package/src/routes/local-inference-asr-transcribe.ts +97 -0
- package/src/routes/local-inference-compat-routes.d.ts +16 -0
- package/src/routes/local-inference-compat-routes.d.ts.map +1 -0
- package/src/routes/local-inference-compat-routes.test.ts +485 -0
- package/src/routes/local-inference-compat-routes.ts +808 -0
- package/src/routes/local-inference-tts-route.d.ts +7 -0
- package/src/routes/local-inference-tts-route.d.ts.map +1 -0
- package/src/routes/local-inference-tts-route.test.ts +179 -0
- package/src/routes/local-inference-tts-route.ts +230 -0
- package/src/routes/transcript-audio-store.d.ts +15 -0
- package/src/routes/transcript-audio-store.d.ts.map +1 -0
- package/src/routes/transcript-audio-store.ts +27 -0
- package/src/routes/transcripts-routes.d.ts +36 -0
- package/src/routes/transcripts-routes.d.ts.map +1 -0
- package/src/routes/transcripts-routes.test.ts +144 -0
- package/src/routes/transcripts-routes.ts +159 -0
- package/src/routes/voice-first-run-routes.d.ts +62 -0
- package/src/routes/voice-first-run-routes.d.ts.map +1 -0
- package/src/routes/voice-first-run-routes.ts +524 -0
- package/src/routes/voice-models-routes.d.ts +62 -0
- package/src/routes/voice-models-routes.d.ts.map +1 -0
- package/src/routes/voice-models-routes.ts +554 -0
- package/src/routes/voice-profile-plugin-routes.d.ts +19 -0
- package/src/routes/voice-profile-plugin-routes.d.ts.map +1 -0
- package/src/routes/voice-profile-plugin-routes.ts +138 -0
- package/src/routes/voice-profiles-management-routes.d.ts +52 -0
- package/src/routes/voice-profiles-management-routes.d.ts.map +1 -0
- package/src/routes/voice-profiles-management-routes.ts +476 -0
- package/src/routes/voice-speaker-profile-routes.d.ts +57 -0
- package/src/routes/voice-speaker-profile-routes.d.ts.map +1 -0
- package/src/routes/voice-speaker-profile-routes.ts +199 -0
- package/src/runtime/aosp-llama-loader-selection.test.ts +80 -0
- package/src/runtime/capacitor-llama.d.ts +25 -0
- package/src/runtime/embedding-manager-support.d.ts +77 -0
- package/src/runtime/embedding-manager-support.d.ts.map +1 -0
- package/src/runtime/embedding-manager-support.ts +497 -0
- package/src/runtime/embedding-presets.d.ts +16 -0
- package/src/runtime/embedding-presets.d.ts.map +1 -0
- package/src/runtime/embedding-presets.ts +81 -0
- package/src/runtime/embedding-warmup-policy.d.ts +14 -0
- package/src/runtime/embedding-warmup-policy.d.ts.map +1 -0
- package/src/runtime/embedding-warmup-policy.test.ts +53 -0
- package/src/runtime/embedding-warmup-policy.ts +48 -0
- package/src/runtime/ensure-local-inference-handler.d.ts +62 -0
- package/src/runtime/ensure-local-inference-handler.d.ts.map +1 -0
- package/src/runtime/ensure-local-inference-handler.test.ts +528 -0
- package/src/runtime/ensure-local-inference-handler.ts +1448 -0
- package/src/runtime/index.d.ts +15 -0
- package/src/runtime/index.d.ts.map +1 -0
- package/src/runtime/index.ts +33 -0
- package/src/runtime/mobile-local-inference-gate.d.ts +31 -0
- package/src/runtime/mobile-local-inference-gate.d.ts.map +1 -0
- package/src/runtime/mobile-local-inference-gate.test.ts +69 -0
- package/src/runtime/mobile-local-inference-gate.ts +44 -0
- package/src/runtime/voice-entity-binding.d.ts +103 -0
- package/src/runtime/voice-entity-binding.d.ts.map +1 -0
- package/src/runtime/voice-entity-binding.transcript.test.ts +69 -0
- package/src/runtime/voice-entity-binding.ts +328 -0
- package/src/services/README.md +71 -0
- package/src/services/__tests__/backend-selector.test.ts +101 -0
- package/src/services/__tests__/checkpoint-manager.test.ts +376 -0
- package/src/services/__tests__/gpu-autotune.test.ts +400 -0
- package/src/services/__tests__/llm-streaming-binding.test.ts +85 -0
- package/src/services/__tests__/planner-grammar.test.ts +372 -0
- package/src/services/__tests__/runtime-target.test.ts +176 -0
- package/src/services/active-model-switch-rollback.test.ts +183 -0
- package/src/services/active-model.d.ts +282 -0
- package/src/services/active-model.d.ts.map +1 -0
- package/src/services/active-model.ts +1213 -0
- package/src/services/assignments.d.ts +71 -0
- package/src/services/assignments.d.ts.map +1 -0
- package/src/services/assignments.test.ts +80 -0
- package/src/services/assignments.ts +230 -0
- package/src/services/backend-selector.ts +95 -0
- package/src/services/backend.d.ts +346 -0
- package/src/services/backend.d.ts.map +1 -0
- package/src/services/backend.ts +612 -0
- package/src/services/bionic-host-loader.d.ts +46 -0
- package/src/services/bionic-host-loader.d.ts.map +1 -0
- package/src/services/bionic-host-loader.test.ts +133 -0
- package/src/services/bionic-host-loader.ts +180 -0
- package/src/services/bundled-models.d.ts +34 -0
- package/src/services/bundled-models.d.ts.map +1 -0
- package/src/services/bundled-models.ts +129 -0
- package/src/services/cache-bridge.d.ts +206 -0
- package/src/services/cache-bridge.d.ts.map +1 -0
- package/src/services/cache-bridge.test.ts +516 -0
- package/src/services/cache-bridge.ts +423 -0
- package/src/services/catalog.d.ts +10 -0
- package/src/services/catalog.d.ts.map +1 -0
- package/src/services/catalog.test.ts +238 -0
- package/src/services/catalog.ts +27 -0
- package/src/services/checkpoint-client.d.ts +109 -0
- package/src/services/checkpoint-client.d.ts.map +1 -0
- package/src/services/checkpoint-client.ts +258 -0
- package/src/services/checkpoint-manager.ts +474 -0
- package/src/services/cloud-fallback.d.ts +102 -0
- package/src/services/cloud-fallback.d.ts.map +1 -0
- package/src/services/cloud-fallback.ts +230 -0
- package/src/services/conversation-registry.d.ts +142 -0
- package/src/services/conversation-registry.d.ts.map +1 -0
- package/src/services/conversation-registry.test.ts +235 -0
- package/src/services/conversation-registry.ts +264 -0
- package/src/services/desktop-fused-ffi-backend-runtime.d.ts +95 -0
- package/src/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
- package/src/services/desktop-fused-ffi-backend-runtime.ts +339 -0
- package/src/services/device-bridge.d.ts +188 -0
- package/src/services/device-bridge.d.ts.map +1 -0
- package/src/services/device-bridge.ts +1237 -0
- package/src/services/device-resource-metrics.d.ts +149 -0
- package/src/services/device-resource-metrics.d.ts.map +1 -0
- package/src/services/device-resource-metrics.test.ts +98 -0
- package/src/services/device-resource-metrics.ts +346 -0
- package/src/services/device-tier.d.ts +115 -0
- package/src/services/device-tier.d.ts.map +1 -0
- package/src/services/device-tier.test.ts +371 -0
- package/src/services/device-tier.ts +410 -0
- package/src/services/downloader.d.ts +82 -0
- package/src/services/downloader.d.ts.map +1 -0
- package/src/services/downloader.test.ts +747 -0
- package/src/services/downloader.ts +925 -0
- package/src/services/engine-direct-bundle.test.ts +58 -0
- package/src/services/engine-streaming.test.ts +80 -0
- package/src/services/engine.d.ts +540 -0
- package/src/services/engine.d.ts.map +1 -0
- package/src/services/engine.ts +1909 -0
- package/src/services/ensure-local-artifacts.integration.test.ts +273 -0
- package/src/services/ensure-local-artifacts.test.ts +368 -0
- package/src/services/ensure-local-artifacts.ts +351 -0
- package/src/services/external-scanner.d.ts +17 -0
- package/src/services/external-scanner.d.ts.map +1 -0
- package/src/services/external-scanner.ts +312 -0
- package/src/services/ffi-llm-mock.ts +354 -0
- package/src/services/ffi-llm-streaming-abi.ts +442 -0
- package/src/services/ffi-streaming-backend.d.ts +180 -0
- package/src/services/ffi-streaming-backend.d.ts.map +1 -0
- package/src/services/ffi-streaming-backend.ts +382 -0
- package/src/services/ffi-streaming-runner.d.ts +122 -0
- package/src/services/ffi-streaming-runner.d.ts.map +1 -0
- package/src/services/ffi-streaming-runner.test.ts +60 -0
- package/src/services/ffi-streaming-runner.ts +354 -0
- package/src/services/ffi-unload-ordering.test.ts +162 -0
- package/src/services/gpu-autotune.ts +534 -0
- package/src/services/gpu-detect.d.ts +56 -0
- package/src/services/gpu-detect.d.ts.map +1 -0
- package/src/services/gpu-detect.ts +139 -0
- package/src/services/handler-registry.d.ts +72 -0
- package/src/services/handler-registry.d.ts.map +1 -0
- package/src/services/handler-registry.ts +240 -0
- package/src/services/hardware.d.ts +63 -0
- package/src/services/hardware.d.ts.map +1 -0
- package/src/services/hardware.test.ts +231 -0
- package/src/services/hardware.ts +410 -0
- package/src/services/hf-search.d.ts +26 -0
- package/src/services/hf-search.d.ts.map +1 -0
- package/src/services/hf-search.test.ts +69 -0
- package/src/services/hf-search.ts +420 -0
- package/src/services/image-description-runtime.d.ts +14 -0
- package/src/services/image-description-runtime.d.ts.map +1 -0
- package/src/services/image-description-runtime.test.ts +61 -0
- package/src/services/image-description-runtime.ts +118 -0
- package/src/services/imagegen/aosp-unavailable.d.ts +134 -0
- package/src/services/imagegen/aosp-unavailable.d.ts.map +1 -0
- package/src/services/imagegen/aosp-unavailable.ts +229 -0
- package/src/services/imagegen/backend-selector.d.ts +118 -0
- package/src/services/imagegen/backend-selector.d.ts.map +1 -0
- package/src/services/imagegen/backend-selector.ts +277 -0
- package/src/services/imagegen/coreml-unavailable.d.ts +105 -0
- package/src/services/imagegen/coreml-unavailable.d.ts.map +1 -0
- package/src/services/imagegen/coreml-unavailable.ts +237 -0
- package/src/services/imagegen/errors.d.ts +16 -0
- package/src/services/imagegen/errors.d.ts.map +1 -0
- package/src/services/imagegen/errors.ts +40 -0
- package/src/services/imagegen/index.d.ts +58 -0
- package/src/services/imagegen/index.d.ts.map +1 -0
- package/src/services/imagegen/index.ts +144 -0
- package/src/services/imagegen/mflux.d.ts +74 -0
- package/src/services/imagegen/mflux.d.ts.map +1 -0
- package/src/services/imagegen/mflux.ts +313 -0
- package/src/services/imagegen/sd-cpp.d.ts +180 -0
- package/src/services/imagegen/sd-cpp.d.ts.map +1 -0
- package/src/services/imagegen/sd-cpp.ts +718 -0
- package/src/services/imagegen/tensorrt-unavailable.d.ts +83 -0
- package/src/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
- package/src/services/imagegen/tensorrt-unavailable.ts +295 -0
- package/src/services/imagegen/types.d.ts +181 -0
- package/src/services/imagegen/types.d.ts.map +1 -0
- package/src/services/imagegen/types.ts +193 -0
- package/src/services/index.d.ts +29 -0
- package/src/services/index.d.ts.map +1 -0
- package/src/services/index.ts +211 -0
- package/src/services/inference-capabilities.d.ts +132 -0
- package/src/services/inference-capabilities.d.ts.map +1 -0
- package/src/services/inference-capabilities.test.ts +75 -0
- package/src/services/inference-capabilities.ts +204 -0
- package/src/services/inference-telemetry.d.ts +59 -0
- package/src/services/inference-telemetry.d.ts.map +1 -0
- package/src/services/inference-telemetry.ts +143 -0
- package/src/services/ios-llama-streaming.ts +248 -0
- package/src/services/kv-spill.d.ts +189 -0
- package/src/services/kv-spill.d.ts.map +1 -0
- package/src/services/kv-spill.test.ts +222 -0
- package/src/services/kv-spill.ts +356 -0
- package/src/services/latency-trace.d.ts +346 -0
- package/src/services/latency-trace.d.ts.map +1 -0
- package/src/services/latency-trace.test.ts +266 -0
- package/src/services/latency-trace.ts +844 -0
- package/src/services/llama-server-metrics.ts +304 -0
- package/src/services/llm-streaming-binding.d.ts +96 -0
- package/src/services/llm-streaming-binding.d.ts.map +1 -0
- package/src/services/llm-streaming-binding.ts +136 -0
- package/src/services/load-args.d.ts +82 -0
- package/src/services/load-args.d.ts.map +1 -0
- package/src/services/load-args.ts +81 -0
- package/src/services/manifest/eliza-1.manifest.v1.json +708 -0
- package/src/services/manifest/index.d.ts +4 -0
- package/src/services/manifest/index.d.ts.map +1 -0
- package/src/services/manifest/index.ts +66 -0
- package/src/services/manifest/manifest.test.ts +689 -0
- package/src/services/manifest/schema.d.ts +713 -0
- package/src/services/manifest/schema.d.ts.map +1 -0
- package/src/services/manifest/schema.ts +653 -0
- package/src/services/manifest/types.d.ts +30 -0
- package/src/services/manifest/types.d.ts.map +1 -0
- package/src/services/manifest/types.ts +55 -0
- package/src/services/manifest/validator.d.ts +66 -0
- package/src/services/manifest/validator.d.ts.map +1 -0
- package/src/services/manifest/validator.ts +567 -0
- package/src/services/memory-arbiter.d.ts +318 -0
- package/src/services/memory-arbiter.d.ts.map +1 -0
- package/src/services/memory-arbiter.test.ts +419 -0
- package/src/services/memory-arbiter.ts +925 -0
- package/src/services/memory-monitor.d.ts +122 -0
- package/src/services/memory-monitor.d.ts.map +1 -0
- package/src/services/memory-monitor.test.ts +208 -0
- package/src/services/memory-monitor.ts +297 -0
- package/src/services/memory-pressure.d.ts +130 -0
- package/src/services/memory-pressure.d.ts.map +1 -0
- package/src/services/memory-pressure.ts +414 -0
- package/src/services/mtp-doctor.d.ts +13 -0
- package/src/services/mtp-doctor.d.ts.map +1 -0
- package/src/services/mtp-doctor.ts +78 -0
- package/src/services/network-policy.d.ts +127 -0
- package/src/services/network-policy.d.ts.map +1 -0
- package/src/services/network-policy.ts +346 -0
- package/src/services/paths.d.ts +6 -0
- package/src/services/paths.d.ts.map +1 -0
- package/src/services/paths.ts +25 -0
- package/src/services/planner-skeleton.d.ts +124 -0
- package/src/services/planner-skeleton.d.ts.map +1 -0
- package/src/services/planner-skeleton.ts +175 -0
- package/src/services/providers.d.ts +38 -0
- package/src/services/providers.d.ts.map +1 -0
- package/src/services/providers.ts +507 -0
- package/src/services/ram-budget-cache.test.ts +163 -0
- package/src/services/ram-budget.d.ts +110 -0
- package/src/services/ram-budget.d.ts.map +1 -0
- package/src/services/ram-budget.ts +0 -0
- package/src/services/readiness.d.ts +9 -0
- package/src/services/readiness.d.ts.map +1 -0
- package/src/services/readiness.test.ts +87 -0
- package/src/services/readiness.ts +238 -0
- package/src/services/recommendation.d.ts +111 -0
- package/src/services/recommendation.d.ts.map +1 -0
- package/src/services/recommendation.ts +671 -0
- package/src/services/registry.d.ts +35 -0
- package/src/services/registry.d.ts.map +1 -0
- package/src/services/registry.ts +151 -0
- package/src/services/router-handler.d.ts +92 -0
- package/src/services/router-handler.d.ts.map +1 -0
- package/src/services/router-handler.test.ts +45 -0
- package/src/services/router-handler.ts +407 -0
- package/src/services/routing-policy.d.ts +69 -0
- package/src/services/routing-policy.d.ts.map +1 -0
- package/src/services/routing-policy.test.ts +164 -0
- package/src/services/routing-policy.ts +297 -0
- package/src/services/routing-preferences.d.ts +8 -0
- package/src/services/routing-preferences.d.ts.map +1 -0
- package/src/services/routing-preferences.ts +17 -0
- package/src/services/runtime-target.d.ts +98 -0
- package/src/services/runtime-target.d.ts.map +1 -0
- package/src/services/runtime-target.ts +154 -0
- package/src/services/service.d.ts +128 -0
- package/src/services/service.d.ts.map +1 -0
- package/src/services/service.test.ts +223 -0
- package/src/services/service.ts +735 -0
- package/src/services/session-pool.d.ts +72 -0
- package/src/services/session-pool.d.ts.map +1 -0
- package/src/services/session-pool.ts +153 -0
- package/src/services/structured-output/deterministic-repair.d.ts +23 -0
- package/src/services/structured-output/deterministic-repair.d.ts.map +1 -0
- package/src/services/structured-output/deterministic-repair.test.ts +169 -0
- package/src/services/structured-output/deterministic-repair.ts +443 -0
- package/src/services/structured-output/index.ts +4 -0
- package/src/services/structured-output.d.ts +311 -0
- package/src/services/structured-output.d.ts.map +1 -0
- package/src/services/structured-output.test.ts +483 -0
- package/src/services/structured-output.ts +712 -0
- package/src/services/system-memory.d.ts +33 -0
- package/src/services/system-memory.d.ts.map +1 -0
- package/src/services/system-memory.test.ts +47 -0
- package/src/services/system-memory.ts +67 -0
- package/src/services/transcription-priority.test.ts +211 -0
- package/src/services/types.d.ts +19 -0
- package/src/services/types.d.ts.map +1 -0
- package/src/services/types.ts +55 -0
- package/src/services/verify-on-device.d.ts +34 -0
- package/src/services/verify-on-device.d.ts.map +1 -0
- package/src/services/verify-on-device.test.ts +87 -0
- package/src/services/verify-on-device.ts +127 -0
- package/src/services/verify.d.ts +8 -0
- package/src/services/verify.d.ts.map +1 -0
- package/src/services/verify.ts +13 -0
- package/src/services/vision/aosp-unavailable.d.ts +115 -0
- package/src/services/vision/aosp-unavailable.d.ts.map +1 -0
- package/src/services/vision/aosp-unavailable.ts +163 -0
- package/src/services/vision/capacitor-llama.d.ts +99 -0
- package/src/services/vision/capacitor-llama.d.ts.map +1 -0
- package/src/services/vision/capacitor-llama.ts +255 -0
- package/src/services/vision/cloud-fallback.d.ts +47 -0
- package/src/services/vision/cloud-fallback.d.ts.map +1 -0
- package/src/services/vision/cloud-fallback.test.ts +243 -0
- package/src/services/vision/cloud-fallback.ts +268 -0
- package/src/services/vision/fallback-chain.test.ts +86 -0
- package/src/services/vision/hash.d.ts +71 -0
- package/src/services/vision/hash.d.ts.map +1 -0
- package/src/services/vision/hash.ts +157 -0
- package/src/services/vision/index.d.ts +95 -0
- package/src/services/vision/index.d.ts.map +1 -0
- package/src/services/vision/index.ts +251 -0
- package/src/services/vision/llama-server.d.ts +73 -0
- package/src/services/vision/llama-server.d.ts.map +1 -0
- package/src/services/vision/llama-server.ts +177 -0
- package/src/services/vision/types.d.ts +153 -0
- package/src/services/vision/types.d.ts.map +1 -0
- package/src/services/vision/types.ts +154 -0
- package/src/services/vision/vast-fallback.d.ts +18 -0
- package/src/services/vision/vast-fallback.d.ts.map +1 -0
- package/src/services/vision/vast-fallback.ts +127 -0
- package/src/services/vision-embedding-cache.d.ts +98 -0
- package/src/services/vision-embedding-cache.d.ts.map +1 -0
- package/src/services/vision-embedding-cache.ts +189 -0
- package/src/services/voice/VOICE_WORKBENCH.md +88 -0
- package/src/services/voice/__test-helpers__/fake-ffi.ts +94 -0
- package/src/services/voice/__test-helpers__/synthetic-speech.ts +124 -0
- package/src/services/voice/__tests__/checkpoint-manager.test.ts +241 -0
- package/src/services/voice/__tests__/checkpoint-policy.test.ts +270 -0
- package/src/services/voice/__tests__/eager-context-builder.test.ts +257 -0
- package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +288 -0
- package/src/services/voice/__tests__/eot-classifier.test.ts +431 -0
- package/src/services/voice/__tests__/optimistic-rollback.test.ts +312 -0
- package/src/services/voice/__tests__/prefill-client.test.ts +266 -0
- package/src/services/voice/__tests__/prefix-preserving-queue.test.ts +208 -0
- package/src/services/voice/__tests__/streaming-asr.test.ts +450 -0
- package/src/services/voice/__tests__/streaming-transcriber.test.ts +339 -0
- package/src/services/voice/__tests__/turn-detector-resolver.test.ts +195 -0
- package/src/services/voice/__tests__/voice-state-machine-prefill.test.ts +275 -0
- package/src/services/voice/__tests__/voice-state-machine.test.ts +354 -0
- package/src/services/voice/asr-timed.real.test.ts +141 -0
- package/src/services/voice/audio-frame-consumer.d.ts +212 -0
- package/src/services/voice/audio-frame-consumer.d.ts.map +1 -0
- package/src/services/voice/audio-frame-consumer.test.ts +343 -0
- package/src/services/voice/audio-frame-consumer.ts +491 -0
- package/src/services/voice/barge-in.d.ts +112 -0
- package/src/services/voice/barge-in.d.ts.map +1 -0
- package/src/services/voice/barge-in.test.ts +244 -0
- package/src/services/voice/barge-in.ts +336 -0
- package/src/services/voice/cancellation-coordinator.d.ts +127 -0
- package/src/services/voice/cancellation-coordinator.d.ts.map +1 -0
- package/src/services/voice/cancellation-coordinator.test.ts +196 -0
- package/src/services/voice/cancellation-coordinator.ts +269 -0
- package/src/services/voice/checkpoint-manager.d.ts +199 -0
- package/src/services/voice/checkpoint-manager.d.ts.map +1 -0
- package/src/services/voice/checkpoint-manager.ts +401 -0
- package/src/services/voice/checkpoint-policy.ts +336 -0
- package/src/services/voice/composite-eot-classifier.test.ts +59 -0
- package/src/services/voice/e2e-harness.test.ts +182 -0
- package/src/services/voice/e2e-harness.ts +743 -0
- package/src/services/voice/eager-context-builder.d.ts +170 -0
- package/src/services/voice/eager-context-builder.d.ts.map +1 -0
- package/src/services/voice/eager-context-builder.ts +262 -0
- package/src/services/voice/eliza1-eot-scorer.d.ts +124 -0
- package/src/services/voice/eliza1-eot-scorer.d.ts.map +1 -0
- package/src/services/voice/eliza1-eot-scorer.ts +242 -0
- package/src/services/voice/embedding-server.ts +200 -0
- package/src/services/voice/embedding.d.ts +133 -0
- package/src/services/voice/embedding.d.ts.map +1 -0
- package/src/services/voice/embedding.test.ts +131 -0
- package/src/services/voice/embedding.ts +243 -0
- package/src/services/voice/emotion-attribution.d.ts +68 -0
- package/src/services/voice/emotion-attribution.d.ts.map +1 -0
- package/src/services/voice/emotion-attribution.test.ts +129 -0
- package/src/services/voice/emotion-attribution.ts +361 -0
- package/src/services/voice/engine-bridge-cancellation.test.ts +422 -0
- package/src/services/voice/engine-bridge.d.ts +759 -0
- package/src/services/voice/engine-bridge.d.ts.map +1 -0
- package/src/services/voice/engine-bridge.test.ts +384 -0
- package/src/services/voice/engine-bridge.ts +2302 -0
- package/src/services/voice/eot-classifier-ggml.d.ts +179 -0
- package/src/services/voice/eot-classifier-ggml.d.ts.map +1 -0
- package/src/services/voice/eot-classifier-ggml.ts +566 -0
- package/src/services/voice/eot-classifier.d.ts +214 -0
- package/src/services/voice/eot-classifier.d.ts.map +1 -0
- package/src/services/voice/eot-classifier.ts +533 -0
- package/src/services/voice/errors.d.ts +20 -0
- package/src/services/voice/errors.d.ts.map +1 -0
- package/src/services/voice/errors.ts +32 -0
- package/src/services/voice/expressive-tags.d.ts +158 -0
- package/src/services/voice/expressive-tags.d.ts.map +1 -0
- package/src/services/voice/expressive-tags.ts +405 -0
- package/src/services/voice/ffi-bindings.d.ts +674 -0
- package/src/services/voice/ffi-bindings.d.ts.map +1 -0
- package/src/services/voice/ffi-bindings.test.ts +728 -0
- package/src/services/voice/ffi-bindings.ts +3225 -0
- package/src/services/voice/first-line-cache.d.ts +181 -0
- package/src/services/voice/first-line-cache.d.ts.map +1 -0
- package/src/services/voice/first-line-cache.ts +725 -0
- package/src/services/voice/fused-eot-scorer.d.ts +51 -0
- package/src/services/voice/fused-eot-scorer.d.ts.map +1 -0
- package/src/services/voice/fused-eot-scorer.ts +135 -0
- package/src/services/voice/index.d.ts +91 -0
- package/src/services/voice/index.d.ts.map +1 -0
- package/src/services/voice/index.ts +481 -0
- package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +151 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +151 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.test.ts +60 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-discovery.test.ts +277 -0
- package/src/services/voice/kokoro/__tests__/kokoro-ffi-runtime.test.ts +235 -0
- package/src/services/voice/kokoro/__tests__/kokoro-runtime.test.ts +95 -0
- package/src/services/voice/kokoro/__tests__/phonemizer.test.ts +53 -0
- package/src/services/voice/kokoro/__tests__/runtime-selection.test.ts +231 -0
- package/src/services/voice/kokoro/__tests__/voices.test.ts +57 -0
- package/src/services/voice/kokoro/index.ts +79 -0
- package/src/services/voice/kokoro/kokoro-backend.d.ts +72 -0
- package/src/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-backend.ts +207 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts +58 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.ts +177 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts +75 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +233 -0
- package/src/services/voice/kokoro/kokoro-runtime.d.ts +100 -0
- package/src/services/voice/kokoro/kokoro-runtime.d.ts.map +1 -0
- package/src/services/voice/kokoro/kokoro-runtime.ts +170 -0
- package/src/services/voice/kokoro/phoneme-stream.ts +123 -0
- package/src/services/voice/kokoro/phonemizer.d.ts +50 -0
- package/src/services/voice/kokoro/phonemizer.d.ts.map +1 -0
- package/src/services/voice/kokoro/phonemizer.ts +344 -0
- package/src/services/voice/kokoro/pick-runtime.d.ts +61 -0
- package/src/services/voice/kokoro/pick-runtime.d.ts.map +1 -0
- package/src/services/voice/kokoro/pick-runtime.test.ts +91 -0
- package/src/services/voice/kokoro/pick-runtime.ts +130 -0
- package/src/services/voice/kokoro/runtime-selection.d.ts +92 -0
- package/src/services/voice/kokoro/runtime-selection.d.ts.map +1 -0
- package/src/services/voice/kokoro/runtime-selection.ts +237 -0
- package/src/services/voice/kokoro/types.d.ts +82 -0
- package/src/services/voice/kokoro/types.d.ts.map +1 -0
- package/src/services/voice/kokoro/types.ts +95 -0
- package/src/services/voice/kokoro/voice-presets.d.ts +23 -0
- package/src/services/voice/kokoro/voice-presets.d.ts.map +1 -0
- package/src/services/voice/kokoro/voice-presets.ts +129 -0
- package/src/services/voice/kokoro/voices.d.ts +30 -0
- package/src/services/voice/kokoro/voices.d.ts.map +1 -0
- package/src/services/voice/kokoro/voices.ts +64 -0
- package/src/services/voice/lifecycle.d.ts +135 -0
- package/src/services/voice/lifecycle.d.ts.map +1 -0
- package/src/services/voice/lifecycle.test.ts +315 -0
- package/src/services/voice/lifecycle.ts +301 -0
- package/src/services/voice/live-diarization-session.d.ts +96 -0
- package/src/services/voice/live-diarization-session.d.ts.map +1 -0
- package/src/services/voice/live-diarization-session.ts +289 -0
- package/src/services/voice/mic-source.d.ts +136 -0
- package/src/services/voice/mic-source.d.ts.map +1 -0
- package/src/services/voice/mic-source.test.ts +210 -0
- package/src/services/voice/mic-source.ts +503 -0
- package/src/services/voice/optimistic-policy.d.ts +109 -0
- package/src/services/voice/optimistic-policy.d.ts.map +1 -0
- package/src/services/voice/optimistic-policy.test.ts +101 -0
- package/src/services/voice/optimistic-policy.ts +192 -0
- package/src/services/voice/optimistic-rollback.ts +343 -0
- package/src/services/voice/partial-stabilizer.d.ts +73 -0
- package/src/services/voice/partial-stabilizer.d.ts.map +1 -0
- package/src/services/voice/partial-stabilizer.test.ts +68 -0
- package/src/services/voice/partial-stabilizer.ts +140 -0
- package/src/services/voice/phoneme-tokenizer.d.ts +49 -0
- package/src/services/voice/phoneme-tokenizer.d.ts.map +1 -0
- package/src/services/voice/phoneme-tokenizer.ts +158 -0
- package/src/services/voice/phrase-cache.d.ts +76 -0
- package/src/services/voice/phrase-cache.d.ts.map +1 -0
- package/src/services/voice/phrase-cache.test.ts +242 -0
- package/src/services/voice/phrase-cache.ts +186 -0
- package/src/services/voice/phrase-chunker.d.ts +62 -0
- package/src/services/voice/phrase-chunker.d.ts.map +1 -0
- package/src/services/voice/phrase-chunker.test.ts +239 -0
- package/src/services/voice/phrase-chunker.ts +281 -0
- package/src/services/voice/pipeline-impls.d.ts +151 -0
- package/src/services/voice/pipeline-impls.d.ts.map +1 -0
- package/src/services/voice/pipeline-impls.l6.test.ts +110 -0
- package/src/services/voice/pipeline-impls.test.ts +292 -0
- package/src/services/voice/pipeline-impls.ts +315 -0
- package/src/services/voice/pipeline.d.ts +216 -0
- package/src/services/voice/pipeline.d.ts.map +1 -0
- package/src/services/voice/pipeline.ts +505 -0
- package/src/services/voice/prefill-client.d.ts +123 -0
- package/src/services/voice/prefill-client.d.ts.map +1 -0
- package/src/services/voice/prefill-client.ts +316 -0
- package/src/services/voice/prefix-preserving-queue.d.ts +113 -0
- package/src/services/voice/prefix-preserving-queue.d.ts.map +1 -0
- package/src/services/voice/prefix-preserving-queue.ts +162 -0
- package/src/services/voice/profile-store.d.ts +248 -0
- package/src/services/voice/profile-store.d.ts.map +1 -0
- package/src/services/voice/profile-store.ts +887 -0
- package/src/services/voice/real-audio-decode.test.ts +148 -0
- package/src/services/voice/ring-buffer.d.ts +40 -0
- package/src/services/voice/ring-buffer.d.ts.map +1 -0
- package/src/services/voice/ring-buffer.test.ts +129 -0
- package/src/services/voice/ring-buffer.ts +123 -0
- package/src/services/voice/rollback-queue.d.ts +24 -0
- package/src/services/voice/rollback-queue.d.ts.map +1 -0
- package/src/services/voice/rollback-queue.ts +74 -0
- package/src/services/voice/samantha-preset-placeholder.d.ts +67 -0
- package/src/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
- package/src/services/voice/samantha-preset-placeholder.test.ts +97 -0
- package/src/services/voice/samantha-preset-placeholder.ts +148 -0
- package/src/services/voice/samantha-preset-regenerator.d.ts +87 -0
- package/src/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
- package/src/services/voice/samantha-preset-regenerator.ts +393 -0
- package/src/services/voice/scheduler.d.ts +146 -0
- package/src/services/voice/scheduler.d.ts.map +1 -0
- package/src/services/voice/scheduler.t2.test.ts +141 -0
- package/src/services/voice/scheduler.ts +927 -0
- package/src/services/voice/shared-resources.d.ts +190 -0
- package/src/services/voice/shared-resources.d.ts.map +1 -0
- package/src/services/voice/shared-resources.ts +320 -0
- package/src/services/voice/speaker/attribution-pipeline.d.ts +74 -0
- package/src/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
- package/src/services/voice/speaker/attribution-pipeline.ts +386 -0
- package/src/services/voice/speaker/diarizer-fused.d.ts +59 -0
- package/src/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
- package/src/services/voice/speaker/diarizer-fused.real.test.ts +100 -0
- package/src/services/voice/speaker/diarizer-fused.ts +154 -0
- package/src/services/voice/speaker/diarizer.d.ts +75 -0
- package/src/services/voice/speaker/diarizer.d.ts.map +1 -0
- package/src/services/voice/speaker/diarizer.ts +218 -0
- package/src/services/voice/speaker/encoder-fused.d.ts +60 -0
- package/src/services/voice/speaker/encoder-fused.d.ts.map +1 -0
- package/src/services/voice/speaker/encoder-fused.real.test.ts +113 -0
- package/src/services/voice/speaker/encoder-fused.ts +138 -0
- package/src/services/voice/speaker/encoder-ggml.d.ts +33 -0
- package/src/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
- package/src/services/voice/speaker/encoder-ggml.ts +79 -0
- package/src/services/voice/speaker/encoder.d.ts +37 -0
- package/src/services/voice/speaker/encoder.d.ts.map +1 -0
- package/src/services/voice/speaker/encoder.ts +105 -0
- package/src/services/voice/speaker-imprint.d.ts +83 -0
- package/src/services/voice/speaker-imprint.d.ts.map +1 -0
- package/src/services/voice/speaker-imprint.test.ts +185 -0
- package/src/services/voice/speaker-imprint.ts +312 -0
- package/src/services/voice/speaker-preset-cache.d.ts +77 -0
- package/src/services/voice/speaker-preset-cache.d.ts.map +1 -0
- package/src/services/voice/speaker-preset-cache.test.ts +154 -0
- package/src/services/voice/speaker-preset-cache.ts +195 -0
- package/src/services/voice/streaming-asr/streaming-pipeline-adapter.ts +292 -0
- package/src/services/voice/system-audio-sink.d.ts +73 -0
- package/src/services/voice/system-audio-sink.d.ts.map +1 -0
- package/src/services/voice/system-audio-sink.test.ts +29 -0
- package/src/services/voice/system-audio-sink.ts +366 -0
- package/src/services/voice/transcriber.d.ts +244 -0
- package/src/services/voice/transcriber.d.ts.map +1 -0
- package/src/services/voice/transcriber.test.ts +392 -0
- package/src/services/voice/transcriber.ts +704 -0
- package/src/services/voice/transcript-knowledge.d.ts +37 -0
- package/src/services/voice/transcript-knowledge.d.ts.map +1 -0
- package/src/services/voice/transcript-knowledge.test.ts +68 -0
- package/src/services/voice/transcript-knowledge.ts +75 -0
- package/src/services/voice/transcript-service.d.ts +41 -0
- package/src/services/voice/transcript-service.d.ts.map +1 -0
- package/src/services/voice/transcript-service.test.ts +137 -0
- package/src/services/voice/transcript-service.ts +141 -0
- package/src/services/voice/transcript-store.d.ts +53 -0
- package/src/services/voice/transcript-store.d.ts.map +1 -0
- package/src/services/voice/transcript-store.test.ts +153 -0
- package/src/services/voice/transcript-store.ts +132 -0
- package/src/services/voice/turn-controller.d.ts +183 -0
- package/src/services/voice/turn-controller.d.ts.map +1 -0
- package/src/services/voice/turn-controller.test.ts +575 -0
- package/src/services/voice/turn-controller.ts +596 -0
- package/src/services/voice/types.d.ts +643 -0
- package/src/services/voice/types.d.ts.map +1 -0
- package/src/services/voice/types.ts +699 -0
- package/src/services/voice/vad.d.ts +282 -0
- package/src/services/voice/vad.d.ts.map +1 -0
- package/src/services/voice/vad.test.ts +480 -0
- package/src/services/voice/vad.ts +827 -0
- package/src/services/voice/vad.v1-v4.test.ts +222 -0
- package/src/services/voice/voice-budget.d.ts +241 -0
- package/src/services/voice/voice-budget.d.ts.map +1 -0
- package/src/services/voice/voice-budget.test.ts +418 -0
- package/src/services/voice/voice-budget.ts +635 -0
- package/src/services/voice/voice-duet.test.ts +375 -0
- package/src/services/voice/voice-emotion-classifier.d.ts +95 -0
- package/src/services/voice/voice-emotion-classifier.d.ts.map +1 -0
- package/src/services/voice/voice-emotion-classifier.test.ts +210 -0
- package/src/services/voice/voice-emotion-classifier.ts +273 -0
- package/src/services/voice/voice-preset-format.d.ts +158 -0
- package/src/services/voice/voice-preset-format.d.ts.map +1 -0
- package/src/services/voice/voice-preset-format.ts +700 -0
- package/src/services/voice/voice-preset-generator.test.ts +89 -0
- package/src/services/voice/voice-profile-artifact.d.ts +116 -0
- package/src/services/voice/voice-profile-artifact.d.ts.map +1 -0
- package/src/services/voice/voice-profile-artifact.test.ts +138 -0
- package/src/services/voice/voice-profile-artifact.ts +518 -0
- package/src/services/voice/voice-profile-routes.d.ts +83 -0
- package/src/services/voice/voice-profile-routes.d.ts.map +1 -0
- package/src/services/voice/voice-profile-routes.test.ts +429 -0
- package/src/services/voice/voice-profile-routes.ts +425 -0
- package/src/services/voice/voice-scenario.ts +154 -0
- package/src/services/voice/voice-settings.d.ts +82 -0
- package/src/services/voice/voice-settings.d.ts.map +1 -0
- package/src/services/voice/voice-settings.ts +172 -0
- package/src/services/voice/voice-state-machine.d.ts +364 -0
- package/src/services/voice/voice-state-machine.d.ts.map +1 -0
- package/src/services/voice/voice-state-machine.ts +727 -0
- package/src/services/voice/voice-workbench-report.test.ts +168 -0
- package/src/services/voice/voice-workbench-report.ts +326 -0
- package/src/services/voice/voice-workbench.test.ts +158 -0
- package/src/services/voice/voice.test.ts +1070 -0
- package/src/services/voice/wake-word-ggml.d.ts +101 -0
- package/src/services/voice/wake-word-ggml.d.ts.map +1 -0
- package/src/services/voice/wake-word-ggml.ts +320 -0
- package/src/services/voice/wake-word.d.ts +255 -0
- package/src/services/voice/wake-word.d.ts.map +1 -0
- package/src/services/voice/wake-word.test.ts +298 -0
- package/src/services/voice/wake-word.ts +554 -0
- package/src/services/voice/wrap-with-first-line-cache.d.ts +70 -0
- package/src/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
- package/src/services/voice/wrap-with-first-line-cache.ts +267 -0
- package/src/services/voice-model-updater.d.ts +240 -0
- package/src/services/voice-model-updater.d.ts.map +1 -0
- package/src/services/voice-model-updater.ts +724 -0
- package/src/services/voice-prewarm.d.ts +3 -0
- package/src/services/voice-prewarm.d.ts.map +1 -0
- package/src/services/voice-prewarm.ts +51 -0
- package/dist/index.d.ts +0 -37
- package/dist/index.js +0 -1098
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text → phoneme-id adapter for Kokoro-82M.
|
|
3
|
+
*
|
|
4
|
+
* Kokoro is trained against espeak-ng IPA tokens with a small fixed vocab
|
|
5
|
+
* (~178 entries: IPA symbols + stress/punct markers + special <s>/<pad>).
|
|
6
|
+
* Production deployments should bring real espeak-ng phonemization
|
|
7
|
+
* (`phonemizer` is the pure-JS eSpeak NG package); the bundled fallback here is a
|
|
8
|
+
* deterministic letter-to-pseudo-phoneme adapter that produces audible
|
|
9
|
+
* speech for ASCII English text but loses prosodic accuracy.
|
|
10
|
+
*
|
|
11
|
+
* Resolution order:
|
|
12
|
+
* 1. Caller-provided `KokoroPhonemizer` (preferred — bring your own).
|
|
13
|
+
* 2. Dynamically-imported `phonemizer`/`phonemize` npm package, if installed.
|
|
14
|
+
* 3. Bundled `FallbackG2PPhonemizer` (degrades gracefully, never throws on
|
|
15
|
+
* ASCII input).
|
|
16
|
+
*
|
|
17
|
+
* Non-ASCII text with no real phonemizer raises `KokoroPhonemizerError` —
|
|
18
|
+
* silent garbage out is worse than a surfaced error (AGENTS.md §3).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
type KokoroPhonemeSequence,
|
|
23
|
+
type KokoroPhonemizer,
|
|
24
|
+
KokoroPhonemizerError,
|
|
25
|
+
} from "./types";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Kokoro v1.0 phoneme vocabulary. These ids must match the bundled
|
|
29
|
+
* `tts/kokoro/tokenizer.json` asset. The boundary token is `$` (id 0);
|
|
30
|
+
* feeding invented `<s>` / `</s>` ids shifts the whole utterance and produces
|
|
31
|
+
* plausible-sounding but lexically wrong audio.
|
|
32
|
+
*/
|
|
33
|
+
const VOCAB: Readonly<Record<string, number>> = {
|
|
34
|
+
$: 0,
|
|
35
|
+
";": 1,
|
|
36
|
+
":": 2,
|
|
37
|
+
",": 3,
|
|
38
|
+
".": 4,
|
|
39
|
+
"!": 5,
|
|
40
|
+
"?": 6,
|
|
41
|
+
"—": 9,
|
|
42
|
+
"…": 10,
|
|
43
|
+
'"': 11,
|
|
44
|
+
"(": 12,
|
|
45
|
+
")": 13,
|
|
46
|
+
"“": 14,
|
|
47
|
+
"”": 15,
|
|
48
|
+
" ": 16,
|
|
49
|
+
"̃": 17,
|
|
50
|
+
ʣ: 18,
|
|
51
|
+
ʥ: 19,
|
|
52
|
+
ʦ: 20,
|
|
53
|
+
ʨ: 21,
|
|
54
|
+
ᵝ: 22,
|
|
55
|
+
ꭧ: 23,
|
|
56
|
+
A: 24,
|
|
57
|
+
I: 25,
|
|
58
|
+
O: 31,
|
|
59
|
+
Q: 33,
|
|
60
|
+
S: 35,
|
|
61
|
+
T: 36,
|
|
62
|
+
W: 39,
|
|
63
|
+
Y: 41,
|
|
64
|
+
ᵊ: 42,
|
|
65
|
+
a: 43,
|
|
66
|
+
b: 44,
|
|
67
|
+
c: 45,
|
|
68
|
+
d: 46,
|
|
69
|
+
e: 47,
|
|
70
|
+
f: 48,
|
|
71
|
+
h: 50,
|
|
72
|
+
i: 51,
|
|
73
|
+
j: 52,
|
|
74
|
+
k: 53,
|
|
75
|
+
l: 54,
|
|
76
|
+
m: 55,
|
|
77
|
+
n: 56,
|
|
78
|
+
o: 57,
|
|
79
|
+
p: 58,
|
|
80
|
+
q: 59,
|
|
81
|
+
r: 60,
|
|
82
|
+
s: 61,
|
|
83
|
+
t: 62,
|
|
84
|
+
u: 63,
|
|
85
|
+
v: 64,
|
|
86
|
+
w: 65,
|
|
87
|
+
x: 66,
|
|
88
|
+
y: 67,
|
|
89
|
+
z: 68,
|
|
90
|
+
ɑ: 69,
|
|
91
|
+
ɐ: 70,
|
|
92
|
+
ɒ: 71,
|
|
93
|
+
æ: 72,
|
|
94
|
+
β: 75,
|
|
95
|
+
ɔ: 76,
|
|
96
|
+
ɕ: 77,
|
|
97
|
+
ç: 78,
|
|
98
|
+
ɖ: 80,
|
|
99
|
+
ð: 81,
|
|
100
|
+
ʤ: 82,
|
|
101
|
+
ə: 83,
|
|
102
|
+
ɚ: 85,
|
|
103
|
+
ɛ: 86,
|
|
104
|
+
ɜ: 87,
|
|
105
|
+
ɟ: 90,
|
|
106
|
+
ɡ: 92,
|
|
107
|
+
ɥ: 99,
|
|
108
|
+
ɨ: 101,
|
|
109
|
+
ɪ: 102,
|
|
110
|
+
ʝ: 103,
|
|
111
|
+
ɯ: 110,
|
|
112
|
+
ɰ: 111,
|
|
113
|
+
ŋ: 112,
|
|
114
|
+
ɳ: 113,
|
|
115
|
+
ɲ: 114,
|
|
116
|
+
ɴ: 115,
|
|
117
|
+
ø: 116,
|
|
118
|
+
ɸ: 118,
|
|
119
|
+
θ: 119,
|
|
120
|
+
œ: 120,
|
|
121
|
+
ɹ: 123,
|
|
122
|
+
ɾ: 125,
|
|
123
|
+
ɻ: 126,
|
|
124
|
+
ʁ: 128,
|
|
125
|
+
ɽ: 129,
|
|
126
|
+
ʂ: 130,
|
|
127
|
+
ʃ: 131,
|
|
128
|
+
ʈ: 132,
|
|
129
|
+
ʧ: 133,
|
|
130
|
+
ʊ: 135,
|
|
131
|
+
ʋ: 136,
|
|
132
|
+
ʌ: 138,
|
|
133
|
+
ɣ: 139,
|
|
134
|
+
ɤ: 140,
|
|
135
|
+
χ: 142,
|
|
136
|
+
ʎ: 143,
|
|
137
|
+
ʒ: 147,
|
|
138
|
+
ʔ: 148,
|
|
139
|
+
ˈ: 156,
|
|
140
|
+
ˌ: 157,
|
|
141
|
+
ː: 158,
|
|
142
|
+
ʰ: 162,
|
|
143
|
+
ʲ: 164,
|
|
144
|
+
"↓": 169,
|
|
145
|
+
"→": 171,
|
|
146
|
+
"↗": 172,
|
|
147
|
+
"↘": 173,
|
|
148
|
+
ᵻ: 177,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const PAD = VOCAB.$;
|
|
152
|
+
const BOS = VOCAB.$;
|
|
153
|
+
const EOS = VOCAB.$;
|
|
154
|
+
|
|
155
|
+
const FALLBACK_WORD_IPA: Readonly<Record<string, string>> = {
|
|
156
|
+
a: "ə",
|
|
157
|
+
am: "æm",
|
|
158
|
+
and: "ænd",
|
|
159
|
+
are: "ɑɹ",
|
|
160
|
+
cal: "kæl",
|
|
161
|
+
capital: "kæpɪtəl",
|
|
162
|
+
can: "kæn",
|
|
163
|
+
france: "fɹæns",
|
|
164
|
+
hello: "hɛloʊ",
|
|
165
|
+
hear: "hiɹ",
|
|
166
|
+
is: "ɪz",
|
|
167
|
+
me: "mi",
|
|
168
|
+
meeting: "mitɪŋ",
|
|
169
|
+
of: "ʌv",
|
|
170
|
+
the: "ðə",
|
|
171
|
+
there: "ðɛɹ",
|
|
172
|
+
to: "tu",
|
|
173
|
+
you: "ju",
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const FALLBACK_DIGRAPH_IPA: Readonly<Record<string, string>> = {
|
|
177
|
+
ch: "ʧ",
|
|
178
|
+
ng: "ŋ",
|
|
179
|
+
sh: "ʃ",
|
|
180
|
+
th: "θ",
|
|
181
|
+
wh: "w",
|
|
182
|
+
zh: "ʒ",
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
function fallbackWordToIpa(word: string): string {
|
|
186
|
+
const known = FALLBACK_WORD_IPA[word];
|
|
187
|
+
if (known) return known;
|
|
188
|
+
let out = "";
|
|
189
|
+
for (let i = 0; i < word.length; i += 1) {
|
|
190
|
+
const pair = word.slice(i, i + 2);
|
|
191
|
+
const digraph = FALLBACK_DIGRAPH_IPA[pair];
|
|
192
|
+
if (digraph) {
|
|
193
|
+
out += digraph;
|
|
194
|
+
i += 1;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
out += word[i];
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function fallbackTextToIpa(cleaned: string): string {
|
|
203
|
+
return cleaned.replace(/[a-z]+|[^a-z]+/g, (part) =>
|
|
204
|
+
/^[a-z]+$/.test(part) ? fallbackWordToIpa(part) : part,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Deterministic ASCII-only G2P used when no real phonemizer is installed.
|
|
210
|
+
* Lossy by design — this exists so dev environments without espeak-ng still
|
|
211
|
+
* produce lexically useful smoke output for common English phrases, not to
|
|
212
|
+
* replace a production Misaki/espeak phonemizer.
|
|
213
|
+
*/
|
|
214
|
+
export class FallbackG2PPhonemizer implements KokoroPhonemizer {
|
|
215
|
+
readonly id = "fallback-g2p";
|
|
216
|
+
|
|
217
|
+
async phonemize(text: string, _lang: string): Promise<KokoroPhonemeSequence> {
|
|
218
|
+
const cleaned = text.normalize("NFKD").toLowerCase();
|
|
219
|
+
for (const ch of cleaned) {
|
|
220
|
+
const cp = ch.codePointAt(0);
|
|
221
|
+
if (cp === undefined) continue;
|
|
222
|
+
// Allow ASCII printable + whitespace; refuse anything else so we
|
|
223
|
+
// surface non-English text rather than emit silence.
|
|
224
|
+
if (cp > 127) {
|
|
225
|
+
throw new KokoroPhonemizerError(
|
|
226
|
+
`[kokoro] fallback phonemizer cannot handle non-ASCII character '${ch}' (U+${cp.toString(16).padStart(4, "0")}). Install the 'phonemizer' npm package or pass a custom KokoroPhonemizer for full Unicode coverage.`,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const phonemes = fallbackTextToIpa(cleaned);
|
|
231
|
+
const ids: number[] = [BOS];
|
|
232
|
+
for (const ch of phonemes) {
|
|
233
|
+
const id = VOCAB[ch];
|
|
234
|
+
if (id !== undefined) ids.push(id);
|
|
235
|
+
// Unknown char: skip (acts as a pad). The model's training data did
|
|
236
|
+
// not contain raw graphemes anyway — best effort.
|
|
237
|
+
}
|
|
238
|
+
ids.push(EOS);
|
|
239
|
+
return {
|
|
240
|
+
ids: Int32Array.from(ids),
|
|
241
|
+
phonemes,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface PhonemizeMod {
|
|
247
|
+
// The `phonemizer` / legacy `phonemize` npm package typing varies between
|
|
248
|
+
// packages and versions; treat it structurally so minor updates do not break
|
|
249
|
+
// mobile TTS.
|
|
250
|
+
phonemize?: (
|
|
251
|
+
text: string,
|
|
252
|
+
langOrOpts?: unknown,
|
|
253
|
+
) => string | string[] | Promise<string | string[]>;
|
|
254
|
+
default?: { phonemize?: PhonemizeMod["phonemize"] };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Wraps the npm `phonemizer` package when present. It returns an IPA string
|
|
259
|
+
* which we tokenise with the same VOCAB above. Real Kokoro inference should
|
|
260
|
+
* use a proper espeak tokenizer — production deployments bring their own;
|
|
261
|
+
* this is the "install npm and it works" middle ground.
|
|
262
|
+
*/
|
|
263
|
+
export class NpmPhonemizePhonemizer implements KokoroPhonemizer {
|
|
264
|
+
readonly id: string;
|
|
265
|
+
private constructor(
|
|
266
|
+
private readonly mod: PhonemizeMod,
|
|
267
|
+
id = "phonemizer",
|
|
268
|
+
private readonly callStyle: "language" | "options" = "language",
|
|
269
|
+
) {
|
|
270
|
+
this.id = id;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
static async tryLoad(): Promise<NpmPhonemizePhonemizer | null> {
|
|
274
|
+
try {
|
|
275
|
+
const mod = (await import("phonemizer")) as PhonemizeMod;
|
|
276
|
+
const phon = mod.phonemize ?? mod.default?.phonemize;
|
|
277
|
+
if (typeof phon !== "function") return null;
|
|
278
|
+
return new NpmPhonemizePhonemizer(mod);
|
|
279
|
+
} catch {
|
|
280
|
+
// Older local installs used a package named `phonemize`. Keep it as a
|
|
281
|
+
// secondary, deliberately non-bundled fallback for developer machines.
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
const spec = "phonemize";
|
|
285
|
+
const mod = (await import(/* @vite-ignore */ spec)) as PhonemizeMod;
|
|
286
|
+
const phon = mod.phonemize ?? mod.default?.phonemize;
|
|
287
|
+
if (typeof phon !== "function") return null;
|
|
288
|
+
return new NpmPhonemizePhonemizer(mod, "phonemize", "options");
|
|
289
|
+
} catch {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async phonemize(text: string, lang: string): Promise<KokoroPhonemeSequence> {
|
|
295
|
+
const phon = this.mod.phonemize ?? this.mod.default?.phonemize;
|
|
296
|
+
if (!phon) {
|
|
297
|
+
throw new KokoroPhonemizerError(
|
|
298
|
+
"[kokoro] 'phonemize' module loaded but does not export a phonemize() function",
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
const out = await phon(
|
|
302
|
+
text,
|
|
303
|
+
this.callStyle === "language"
|
|
304
|
+
? kokoroLangToPhonemizerLanguage(lang)
|
|
305
|
+
: { lang },
|
|
306
|
+
);
|
|
307
|
+
const phonemes = Array.isArray(out)
|
|
308
|
+
? out.join(" ")
|
|
309
|
+
: typeof out === "string"
|
|
310
|
+
? out
|
|
311
|
+
: String(out);
|
|
312
|
+
const ids: number[] = [BOS];
|
|
313
|
+
for (const ch of phonemes.toLowerCase()) {
|
|
314
|
+
const id = VOCAB[ch];
|
|
315
|
+
if (id !== undefined) ids.push(id);
|
|
316
|
+
}
|
|
317
|
+
ids.push(EOS);
|
|
318
|
+
return { ids: Int32Array.from(ids), phonemes };
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function kokoroLangToPhonemizerLanguage(lang: string): string {
|
|
323
|
+
switch (lang.trim().toLowerCase()) {
|
|
324
|
+
case "a":
|
|
325
|
+
return "en-us";
|
|
326
|
+
case "b":
|
|
327
|
+
return "en-gb";
|
|
328
|
+
default:
|
|
329
|
+
return lang || "en-us";
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Lazy resolver: caller override → npm `phonemizer` → bundled fallback. */
|
|
334
|
+
export async function resolvePhonemizer(
|
|
335
|
+
override?: KokoroPhonemizer,
|
|
336
|
+
): Promise<KokoroPhonemizer> {
|
|
337
|
+
if (override) return override;
|
|
338
|
+
const npm = await NpmPhonemizePhonemizer.tryLoad();
|
|
339
|
+
if (npm) return npm;
|
|
340
|
+
return new FallbackG2PPhonemizer();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** Exported for tests and bench-time diagnostics. */
|
|
344
|
+
export const KOKORO_PAD_ID = PAD;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kokoro runtime selector — picks the resolved-runtime path.
|
|
3
|
+
*
|
|
4
|
+
* The env knob is `KOKORO_BACKEND`:
|
|
5
|
+
*
|
|
6
|
+
* ffi (default) → KokoroFfiRuntime → in-process synthesis through the
|
|
7
|
+
* fused `libelizainference` handle (the
|
|
8
|
+
* `eliza_inference_kokoro_*` exports, introduced at ABI
|
|
9
|
+
* v10; the fused library is currently ABI v11). This is
|
|
10
|
+
* the SOLE synthesis path on every platform.
|
|
11
|
+
* mock → KokoroMockRuntime. Tests only.
|
|
12
|
+
*
|
|
13
|
+
* The legacy `fork` / `server` value (POST `/v1/audio/speech` on a running
|
|
14
|
+
* llama-server) was removed — Kokoro is folded into the fused lib, so there is
|
|
15
|
+
* one runtime, not a duplicate HTTP transport. The "onnx" value was removed
|
|
16
|
+
* earlier with `onnxruntime-node`.
|
|
17
|
+
*/
|
|
18
|
+
import { type KokoroFfiRuntimeOptions } from "./kokoro-ffi-runtime";
|
|
19
|
+
import { type KokoroMockRuntimeOptions, type KokoroRuntime } from "./kokoro-runtime";
|
|
20
|
+
export type KokoroBackendId = "ffi" | "mock";
|
|
21
|
+
export interface KokoroBackendInputs {
|
|
22
|
+
/** Override the env-resolved backend (tests / programmatic selection). */
|
|
23
|
+
backend?: KokoroBackendId;
|
|
24
|
+
/** Default backend derived from the discovered model layout. Used when no
|
|
25
|
+
* explicit backend and no `KOKORO_BACKEND` env override are set. When
|
|
26
|
+
* omitted the selector defaults to the in-process `ffi` path. */
|
|
27
|
+
defaultBackend?: KokoroBackendId;
|
|
28
|
+
/** Construction options for the in-process FFI path. Used iff backend === "ffi". */
|
|
29
|
+
ffi?: KokoroFfiRuntimeOptions;
|
|
30
|
+
/** Construction options for the mock path. */
|
|
31
|
+
mock?: KokoroMockRuntimeOptions;
|
|
32
|
+
/** Override the process.env source. */
|
|
33
|
+
env?: NodeJS.ProcessEnv;
|
|
34
|
+
}
|
|
35
|
+
export interface KokoroBackendDecision {
|
|
36
|
+
backend: KokoroBackendId;
|
|
37
|
+
/** One-line reason — surfaced to telemetry. */
|
|
38
|
+
reason: string;
|
|
39
|
+
runtime: KokoroRuntime;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the `KOKORO_BACKEND` env variable. Throws on an unrecognized value
|
|
43
|
+
* — silent fallback would hide a misconfiguration (AGENTS.md §3 "no silent
|
|
44
|
+
* fallback"). The legacy `fork` / `server` (HTTP) value is rejected with a
|
|
45
|
+
* pointer to the in-process path.
|
|
46
|
+
*/
|
|
47
|
+
export declare function readKokoroBackendFromEnv(env?: NodeJS.ProcessEnv): KokoroBackendId | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Pick the Kokoro runtime backend.
|
|
50
|
+
*
|
|
51
|
+
* 1. Explicit `inputs.backend` wins.
|
|
52
|
+
* 2. Else env (`KOKORO_BACKEND`).
|
|
53
|
+
* 3. Else `inputs.defaultBackend`.
|
|
54
|
+
* 4. Else default → `ffi` (in-process fused handle, the only mobile-safe path).
|
|
55
|
+
*
|
|
56
|
+
* If the chosen backend's options block is missing the call throws a
|
|
57
|
+
* structured error (no silent downgrade). Callers must wire the options
|
|
58
|
+
* for the backends they enable.
|
|
59
|
+
*/
|
|
60
|
+
export declare function pickKokoroRuntimeBackend(inputs: KokoroBackendInputs): KokoroBackendDecision;
|
|
61
|
+
//# sourceMappingURL=pick-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pick-runtime.d.ts","sourceRoot":"","sources":["pick-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAEN,KAAK,uBAAuB,EAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEN,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EAClB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IACnC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B;;sEAEkE;IAClE,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,oFAAoF;IACpF,GAAG,CAAC,EAAE,uBAAuB,CAAC;IAC9B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,wBAAwB,CAAC;IAChC,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,eAAe,CAAC;IACzB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACvC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAClC,eAAe,GAAG,SAAS,CAc7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,mBAAmB,GACzB,qBAAqB,CAuCvB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { ElizaInferenceFfi } from "../ffi-bindings";
|
|
4
|
+
import { pickKokoroRuntimeBackend } from "./pick-runtime";
|
|
5
|
+
import type { KokoroModelLayout } from "./types";
|
|
6
|
+
|
|
7
|
+
const LAYOUT: KokoroModelLayout = {
|
|
8
|
+
root: "/tmp/kokoro",
|
|
9
|
+
modelFile: "kokoro-82m-v1_0.gguf",
|
|
10
|
+
voicesDir: "/tmp/kokoro/voices",
|
|
11
|
+
sampleRate: 24_000,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Minimal FFI stand-in for the in-process Kokoro path: only the symbols
|
|
16
|
+
* `KokoroFfiRuntime`'s constructor touches (`kokoroSupported`, `create`) are
|
|
17
|
+
* non-trivial. Synthesis itself is exercised in the runtime test; here we only
|
|
18
|
+
* need a handle that constructs.
|
|
19
|
+
*/
|
|
20
|
+
function fakeKokoroFfi(supported = true): ElizaInferenceFfi {
|
|
21
|
+
return {
|
|
22
|
+
libraryPath: "/fake/libelizainference.so",
|
|
23
|
+
libraryAbiVersion: "10",
|
|
24
|
+
create: () => 1n,
|
|
25
|
+
destroy: () => {},
|
|
26
|
+
kokoroSupported: () => supported,
|
|
27
|
+
kokoroLoad: () => {},
|
|
28
|
+
kokoroSynthesize: () => new Float32Array(0),
|
|
29
|
+
kokoroSampleRate: () => 24_000,
|
|
30
|
+
} as unknown as ElizaInferenceFfi;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe("pickKokoroRuntimeBackend", () => {
|
|
34
|
+
it("defaults to the in-process ffi runtime when no backend or env override is set", () => {
|
|
35
|
+
const decision = pickKokoroRuntimeBackend({
|
|
36
|
+
env: {},
|
|
37
|
+
ffi: { layout: LAYOUT, ffi: fakeKokoroFfi(), ctx: 1n },
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(decision.backend).toBe("ffi");
|
|
41
|
+
expect(decision.runtime.id).toBe("gguf");
|
|
42
|
+
expect(decision.reason).toMatch(/default/);
|
|
43
|
+
expect(decision.reason).toMatch(/in-process/);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("uses ffi when KOKORO_BACKEND=ffi is set via env", () => {
|
|
47
|
+
const decision = pickKokoroRuntimeBackend({
|
|
48
|
+
env: { KOKORO_BACKEND: "ffi" },
|
|
49
|
+
ffi: { layout: LAYOUT, ffi: fakeKokoroFfi(), ctx: 1n },
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
expect(decision.backend).toBe("ffi");
|
|
53
|
+
expect(decision.reason).toMatch(/KOKORO_BACKEND=ffi/);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("rejects the removed HTTP fork/server backend with an actionable error", () => {
|
|
57
|
+
for (const value of ["fork", "server"]) {
|
|
58
|
+
expect(() =>
|
|
59
|
+
pickKokoroRuntimeBackend({
|
|
60
|
+
env: { KOKORO_BACKEND: value },
|
|
61
|
+
ffi: { layout: LAYOUT, ffi: fakeKokoroFfi(), ctx: 1n },
|
|
62
|
+
}),
|
|
63
|
+
).toThrow(/llama-server HTTP\) was removed/);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("uses mock when KOKORO_BACKEND=mock is set via env", () => {
|
|
68
|
+
const decision = pickKokoroRuntimeBackend({
|
|
69
|
+
env: { KOKORO_BACKEND: "mock" },
|
|
70
|
+
mock: { sampleRate: 24_000 },
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(decision.backend).toBe("mock");
|
|
74
|
+
expect(decision.runtime.id).toBe("mock");
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("throws on unrecognized KOKORO_BACKEND value", () => {
|
|
78
|
+
expect(() =>
|
|
79
|
+
pickKokoroRuntimeBackend({
|
|
80
|
+
env: { KOKORO_BACKEND: "bogus" },
|
|
81
|
+
ffi: { layout: LAYOUT, ffi: fakeKokoroFfi(), ctx: 1n },
|
|
82
|
+
}),
|
|
83
|
+
).toThrow(/KOKORO_BACKEND must be one of/);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("throws when the ffi backend is selected without its options block", () => {
|
|
87
|
+
expect(() =>
|
|
88
|
+
pickKokoroRuntimeBackend({ env: { KOKORO_BACKEND: "ffi" } }),
|
|
89
|
+
).toThrow(/requires `inputs.ffi`/);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kokoro runtime selector — picks the resolved-runtime path.
|
|
3
|
+
*
|
|
4
|
+
* The env knob is `KOKORO_BACKEND`:
|
|
5
|
+
*
|
|
6
|
+
* ffi (default) → KokoroFfiRuntime → in-process synthesis through the
|
|
7
|
+
* fused `libelizainference` handle (the
|
|
8
|
+
* `eliza_inference_kokoro_*` exports, introduced at ABI
|
|
9
|
+
* v10; the fused library is currently ABI v11). This is
|
|
10
|
+
* the SOLE synthesis path on every platform.
|
|
11
|
+
* mock → KokoroMockRuntime. Tests only.
|
|
12
|
+
*
|
|
13
|
+
* The legacy `fork` / `server` value (POST `/v1/audio/speech` on a running
|
|
14
|
+
* llama-server) was removed — Kokoro is folded into the fused lib, so there is
|
|
15
|
+
* one runtime, not a duplicate HTTP transport. The "onnx" value was removed
|
|
16
|
+
* earlier with `onnxruntime-node`.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
KokoroFfiRuntime,
|
|
21
|
+
type KokoroFfiRuntimeOptions,
|
|
22
|
+
} from "./kokoro-ffi-runtime";
|
|
23
|
+
import {
|
|
24
|
+
KokoroMockRuntime,
|
|
25
|
+
type KokoroMockRuntimeOptions,
|
|
26
|
+
type KokoroRuntime,
|
|
27
|
+
} from "./kokoro-runtime";
|
|
28
|
+
|
|
29
|
+
export type KokoroBackendId = "ffi" | "mock";
|
|
30
|
+
|
|
31
|
+
export interface KokoroBackendInputs {
|
|
32
|
+
/** Override the env-resolved backend (tests / programmatic selection). */
|
|
33
|
+
backend?: KokoroBackendId;
|
|
34
|
+
/** Default backend derived from the discovered model layout. Used when no
|
|
35
|
+
* explicit backend and no `KOKORO_BACKEND` env override are set. When
|
|
36
|
+
* omitted the selector defaults to the in-process `ffi` path. */
|
|
37
|
+
defaultBackend?: KokoroBackendId;
|
|
38
|
+
/** Construction options for the in-process FFI path. Used iff backend === "ffi". */
|
|
39
|
+
ffi?: KokoroFfiRuntimeOptions;
|
|
40
|
+
/** Construction options for the mock path. */
|
|
41
|
+
mock?: KokoroMockRuntimeOptions;
|
|
42
|
+
/** Override the process.env source. */
|
|
43
|
+
env?: NodeJS.ProcessEnv;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface KokoroBackendDecision {
|
|
47
|
+
backend: KokoroBackendId;
|
|
48
|
+
/** One-line reason — surfaced to telemetry. */
|
|
49
|
+
reason: string;
|
|
50
|
+
runtime: KokoroRuntime;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the `KOKORO_BACKEND` env variable. Throws on an unrecognized value
|
|
55
|
+
* — silent fallback would hide a misconfiguration (AGENTS.md §3 "no silent
|
|
56
|
+
* fallback"). The legacy `fork` / `server` (HTTP) value is rejected with a
|
|
57
|
+
* pointer to the in-process path.
|
|
58
|
+
*/
|
|
59
|
+
export function readKokoroBackendFromEnv(
|
|
60
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
61
|
+
): KokoroBackendId | undefined {
|
|
62
|
+
const raw = env.KOKORO_BACKEND?.trim().toLowerCase();
|
|
63
|
+
if (!raw) return undefined;
|
|
64
|
+
if (raw === "ffi" || raw === "mock") return raw;
|
|
65
|
+
if (raw === "fork" || raw === "server") {
|
|
66
|
+
throw new Error(
|
|
67
|
+
"[voice/kokoro] KOKORO_BACKEND='fork'/'server' (llama-server HTTP) was " +
|
|
68
|
+
"removed — Kokoro runs in-process through the fused libelizainference. " +
|
|
69
|
+
"Use 'ffi' (default).",
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
throw new Error(
|
|
73
|
+
`[voice/kokoro] KOKORO_BACKEND must be one of 'ffi', 'mock' (got '${raw}')`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Pick the Kokoro runtime backend.
|
|
79
|
+
*
|
|
80
|
+
* 1. Explicit `inputs.backend` wins.
|
|
81
|
+
* 2. Else env (`KOKORO_BACKEND`).
|
|
82
|
+
* 3. Else `inputs.defaultBackend`.
|
|
83
|
+
* 4. Else default → `ffi` (in-process fused handle, the only mobile-safe path).
|
|
84
|
+
*
|
|
85
|
+
* If the chosen backend's options block is missing the call throws a
|
|
86
|
+
* structured error (no silent downgrade). Callers must wire the options
|
|
87
|
+
* for the backends they enable.
|
|
88
|
+
*/
|
|
89
|
+
export function pickKokoroRuntimeBackend(
|
|
90
|
+
inputs: KokoroBackendInputs,
|
|
91
|
+
): KokoroBackendDecision {
|
|
92
|
+
const fromEnv = readKokoroBackendFromEnv(inputs.env);
|
|
93
|
+
const fromDefault = inputs.backend === undefined && fromEnv === undefined;
|
|
94
|
+
const backend: KokoroBackendId =
|
|
95
|
+
inputs.backend ?? fromEnv ?? inputs.defaultBackend ?? "ffi";
|
|
96
|
+
|
|
97
|
+
if (backend === "ffi") {
|
|
98
|
+
if (!inputs.ffi) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
"[voice/kokoro] KOKORO_BACKEND=ffi requires `inputs.ffi` " +
|
|
101
|
+
"(layout). Pass the resolved Kokoro layout so the in-process " +
|
|
102
|
+
"fused engine can load the GGUF + voice .bin.",
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
backend,
|
|
107
|
+
reason: inputs.backend
|
|
108
|
+
? "explicit backend=ffi (in-process fused libelizainference)"
|
|
109
|
+
: fromEnv
|
|
110
|
+
? `KOKORO_BACKEND=${fromEnv} → ffi (in-process fused libelizainference)`
|
|
111
|
+
: fromDefault && inputs.defaultBackend === "ffi"
|
|
112
|
+
? "model layout default → ffi (in-process fused libelizainference)"
|
|
113
|
+
: "default → ffi (in-process fused libelizainference)",
|
|
114
|
+
runtime: new KokoroFfiRuntime(inputs.ffi),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// backend === "mock"
|
|
119
|
+
if (!inputs.mock) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
"[voice/kokoro] KOKORO_BACKEND=mock requires `inputs.mock` " +
|
|
122
|
+
"(sampleRate). Construct the runtime with explicit test options.",
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
backend,
|
|
127
|
+
reason: "explicit backend=mock (test fixture)",
|
|
128
|
+
runtime: new KokoroMockRuntime(inputs.mock),
|
|
129
|
+
};
|
|
130
|
+
}
|