@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,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kokoro-82M voice catalog.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the bundled `KOKORO_VOICE_PACKS` table from `voice-presets.ts`
|
|
5
|
+
* under the canonical filename the integration spec calls out, and adds a few
|
|
6
|
+
* search helpers used by the runtime-selection layer and the picker UI.
|
|
7
|
+
*
|
|
8
|
+
* Each voice pack ships as a small (~256 fp32 values × 4 bytes ≈ 1 KB) style
|
|
9
|
+
* tensor under `<modelRoot>/voices/<file>`. Adding voices is cheap (download
|
|
10
|
+
* a single .bin), and a hot ONNX session can swap voices per-utterance with
|
|
11
|
+
* no re-init cost — the model is the same.
|
|
12
|
+
*
|
|
13
|
+
* Upstream registry: https://huggingface.co/hexgrad/Kokoro-82M/tree/main/voices
|
|
14
|
+
*/
|
|
15
|
+
import type { KokoroVoiceId, KokoroVoicePack } from "./types";
|
|
16
|
+
export { findKokoroVoice, KOKORO_DEFAULT_VOICE_ID, KOKORO_VOICE_PACKS, } from "./voice-presets";
|
|
17
|
+
/** All voice ids that ship with the upstream Kokoro v1.0 release. */
|
|
18
|
+
export declare function listKokoroVoiceIds(): ReadonlyArray<KokoroVoiceId>;
|
|
19
|
+
/** Filter voice packs by language tag (`a` US, `b` UK, etc.). */
|
|
20
|
+
export declare function listKokoroVoicesByLang(lang: string): ReadonlyArray<KokoroVoicePack>;
|
|
21
|
+
/** Filter by an exact tag (`female`, `male`, `british`, `breathy`, ...). */
|
|
22
|
+
export declare function listKokoroVoicesByTag(tag: string): ReadonlyArray<KokoroVoicePack>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a caller-supplied voice id against the registry. Returns the
|
|
25
|
+
* matching pack, or the default pack when the id is not bundled. Never
|
|
26
|
+
* throws — runtime selection treats this as a graceful fallback because the
|
|
27
|
+
* caller's `SpeakerPreset.voiceId` may have been authored for OmniVoice.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveKokoroVoiceOrDefault(id: string): KokoroVoicePack;
|
|
30
|
+
//# sourceMappingURL=voices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voices.d.ts","sourceRoot":"","sources":["voices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO9D,OAAO,EACN,eAAe,EACf,uBAAuB,EACvB,kBAAkB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,qEAAqE;AACrE,wBAAgB,kBAAkB,IAAI,aAAa,CAAC,aAAa,CAAC,CAEjE;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,MAAM,GACV,aAAa,CAAC,eAAe,CAAC,CAEhC;AAED,4EAA4E;AAC5E,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,MAAM,GACT,aAAa,CAAC,eAAe,CAAC,CAEhC;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CAUvE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kokoro-82M voice catalog.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the bundled `KOKORO_VOICE_PACKS` table from `voice-presets.ts`
|
|
5
|
+
* under the canonical filename the integration spec calls out, and adds a few
|
|
6
|
+
* search helpers used by the runtime-selection layer and the picker UI.
|
|
7
|
+
*
|
|
8
|
+
* Each voice pack ships as a small (~256 fp32 values × 4 bytes ≈ 1 KB) style
|
|
9
|
+
* tensor under `<modelRoot>/voices/<file>`. Adding voices is cheap (download
|
|
10
|
+
* a single .bin), and a hot ONNX session can swap voices per-utterance with
|
|
11
|
+
* no re-init cost — the model is the same.
|
|
12
|
+
*
|
|
13
|
+
* Upstream registry: https://huggingface.co/hexgrad/Kokoro-82M/tree/main/voices
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { KokoroVoiceId, KokoroVoicePack } from "./types";
|
|
17
|
+
import {
|
|
18
|
+
findKokoroVoice,
|
|
19
|
+
KOKORO_DEFAULT_VOICE_ID,
|
|
20
|
+
KOKORO_VOICE_PACKS,
|
|
21
|
+
} from "./voice-presets";
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
findKokoroVoice,
|
|
25
|
+
KOKORO_DEFAULT_VOICE_ID,
|
|
26
|
+
KOKORO_VOICE_PACKS,
|
|
27
|
+
} from "./voice-presets";
|
|
28
|
+
|
|
29
|
+
/** All voice ids that ship with the upstream Kokoro v1.0 release. */
|
|
30
|
+
export function listKokoroVoiceIds(): ReadonlyArray<KokoroVoiceId> {
|
|
31
|
+
return KOKORO_VOICE_PACKS.map((v) => v.id);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Filter voice packs by language tag (`a` US, `b` UK, etc.). */
|
|
35
|
+
export function listKokoroVoicesByLang(
|
|
36
|
+
lang: string,
|
|
37
|
+
): ReadonlyArray<KokoroVoicePack> {
|
|
38
|
+
return KOKORO_VOICE_PACKS.filter((v) => v.lang === lang);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Filter by an exact tag (`female`, `male`, `british`, `breathy`, ...). */
|
|
42
|
+
export function listKokoroVoicesByTag(
|
|
43
|
+
tag: string,
|
|
44
|
+
): ReadonlyArray<KokoroVoicePack> {
|
|
45
|
+
return KOKORO_VOICE_PACKS.filter((v) => v.tags?.includes(tag) === true);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Resolve a caller-supplied voice id against the registry. Returns the
|
|
50
|
+
* matching pack, or the default pack when the id is not bundled. Never
|
|
51
|
+
* throws — runtime selection treats this as a graceful fallback because the
|
|
52
|
+
* caller's `SpeakerPreset.voiceId` may have been authored for OmniVoice.
|
|
53
|
+
*/
|
|
54
|
+
export function resolveKokoroVoiceOrDefault(id: string): KokoroVoicePack {
|
|
55
|
+
const match = findKokoroVoice(id);
|
|
56
|
+
if (match) return match;
|
|
57
|
+
const fallback = findKokoroVoice(KOKORO_DEFAULT_VOICE_ID);
|
|
58
|
+
if (!fallback) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`[kokoro] default voice id ${KOKORO_DEFAULT_VOICE_ID} is missing from KOKORO_VOICE_PACKS — registry is corrupted`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return fallback;
|
|
64
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice on/off state machine.
|
|
3
|
+
*
|
|
4
|
+
* Per `packages/inference/AGENTS.md` §4 + this scope's design goals,
|
|
5
|
+
* voice is OFF by default. Text + native MTP are hot; TTS, ASR, the
|
|
6
|
+
* speaker preset cache and phrase cache, the chunker, the rollback
|
|
7
|
+
* queue, the barge-in controller, and the ring buffer are NOT in RAM.
|
|
8
|
+
*
|
|
9
|
+
* Transitions are explicit. Illegal transitions throw — no
|
|
10
|
+
* "log-and-continue" (AGENTS.md §9). The transition to `voice-off`
|
|
11
|
+
* MUST issue a real page-eviction call on the TTS/ASR mmap regions
|
|
12
|
+
* (see `MmapRegionHandle.evictPages()` in `shared-resources.ts`) so
|
|
13
|
+
* the OS can reclaim those pages.
|
|
14
|
+
*
|
|
15
|
+
* ┌──────────┐ start() ┌──────────────┐ armed ┌──────────┐
|
|
16
|
+
* │ voice-off│─────────▶│ voice-arming │────────▶│ voice-on │
|
|
17
|
+
* └──────────┘ └──────────────┘ └──────────┘
|
|
18
|
+
* ▲ │ start fails │ stop()
|
|
19
|
+
* │ disarmed ▼ ▼
|
|
20
|
+
* ┌──────────────────┐ ┌──────────────┐ ┌────────────────────┐
|
|
21
|
+
* │ voice-disarming │◀───│ voice-error │ │ voice-disarming │
|
|
22
|
+
* └──────────────────┘ └──────────────┘ └────────────────────┘
|
|
23
|
+
* │ │
|
|
24
|
+
* └────────────────── disarmed ◀───────────────┘
|
|
25
|
+
*
|
|
26
|
+
* `voice-error` is terminal until `reset()` is called. There is no
|
|
27
|
+
* automatic retry: a missing kernel, mmap fail, or RAM-pressure
|
|
28
|
+
* refusal MUST surface to the caller.
|
|
29
|
+
*/
|
|
30
|
+
import type { KernelSet, MmapRegionHandle, MtpDraftHandle, RefCountedResource, SchedulerSlot, SharedResourceRegistry, SharedTokenizer } from "./shared-resources";
|
|
31
|
+
/**
|
|
32
|
+
* Discriminated union — never widened to `string`. Each state may carry
|
|
33
|
+
* payload (the `armed` payload includes the loaded mmap regions so the
|
|
34
|
+
* disarm path can call `evictPages()` on them).
|
|
35
|
+
*/
|
|
36
|
+
export type VoiceLifecycleState = {
|
|
37
|
+
readonly kind: "voice-off";
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: "voice-arming";
|
|
40
|
+
} | {
|
|
41
|
+
readonly kind: "voice-on";
|
|
42
|
+
readonly resources: ArmedResources;
|
|
43
|
+
} | {
|
|
44
|
+
readonly kind: "voice-disarming";
|
|
45
|
+
readonly resources: ArmedResources;
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: "voice-error";
|
|
48
|
+
readonly error: VoiceLifecycleError;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Resources held while voice is armed. Released in reverse order on
|
|
52
|
+
* disarm; the mmap regions get an explicit `evictPages()` call before
|
|
53
|
+
* `release()` so the OS reclaims pages even if the FFI keeps the file
|
|
54
|
+
* descriptor open for the next re-arm.
|
|
55
|
+
*/
|
|
56
|
+
export interface ArmedResources {
|
|
57
|
+
readonly tts: MmapRegionHandle;
|
|
58
|
+
readonly asr: MmapRegionHandle;
|
|
59
|
+
/** Speaker preset + phrase cache — kept in a small LRU after disarm. */
|
|
60
|
+
readonly voiceCaches: RefCountedResource;
|
|
61
|
+
/** Voice-specific scheduler nodes (chunker, rollback, ring buffer, barge-in). */
|
|
62
|
+
readonly voiceSchedulerNodes: RefCountedResource;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resources held while text is up. Acquired by the engine when the
|
|
66
|
+
* bundle is activated; voice piggy-backs on these without re-loading.
|
|
67
|
+
*/
|
|
68
|
+
export interface TextResources {
|
|
69
|
+
readonly tokenizer: SharedTokenizer;
|
|
70
|
+
readonly textWeights: MmapRegionHandle;
|
|
71
|
+
readonly kernels: KernelSet;
|
|
72
|
+
readonly scheduler: SchedulerSlot;
|
|
73
|
+
readonly mtp: MtpDraftHandle;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Structured failure surfaced to the caller. Never a generic `Error` —
|
|
77
|
+
* the caller (engine + UI) needs to distinguish RAM pressure from a
|
|
78
|
+
* missing kernel from a manifest mismatch (AGENTS.md §3).
|
|
79
|
+
*/
|
|
80
|
+
export declare class VoiceLifecycleError extends Error {
|
|
81
|
+
readonly code: "ram-pressure" | "mmap-fail" | "kernel-missing" | "illegal-transition" | "arm-failed" | "disarm-failed";
|
|
82
|
+
constructor(code: VoiceLifecycleError["code"], message: string);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Loader functions injected at construction. Splitting these out keeps
|
|
86
|
+
* `VoiceLifecycle` independent of FFI specifics — the engine wires real
|
|
87
|
+
* loaders at runtime; tests inject mocks. Each loader MUST throw on
|
|
88
|
+
* failure (AGENTS.md §3 — no silent fallback).
|
|
89
|
+
*/
|
|
90
|
+
export interface VoiceLifecycleLoaders {
|
|
91
|
+
loadTtsRegion(): Promise<MmapRegionHandle>;
|
|
92
|
+
loadAsrRegion(): Promise<MmapRegionHandle>;
|
|
93
|
+
loadVoiceCaches(): Promise<RefCountedResource>;
|
|
94
|
+
loadVoiceSchedulerNodes(): Promise<RefCountedResource>;
|
|
95
|
+
}
|
|
96
|
+
export interface VoiceLifecycleEvents {
|
|
97
|
+
onTransition?(prev: VoiceLifecycleState, next: VoiceLifecycleState): void;
|
|
98
|
+
}
|
|
99
|
+
export declare class VoiceLifecycle {
|
|
100
|
+
private state;
|
|
101
|
+
private readonly registry;
|
|
102
|
+
private readonly loaders;
|
|
103
|
+
private readonly events;
|
|
104
|
+
constructor(args: {
|
|
105
|
+
registry: SharedResourceRegistry;
|
|
106
|
+
loaders: VoiceLifecycleLoaders;
|
|
107
|
+
events?: VoiceLifecycleEvents;
|
|
108
|
+
});
|
|
109
|
+
current(): VoiceLifecycleState;
|
|
110
|
+
/**
|
|
111
|
+
* Transition `voice-off → voice-arming → voice-on`. Loads TTS + ASR
|
|
112
|
+
* mmap regions, voice caches, voice scheduler nodes. Each load throws
|
|
113
|
+
* on failure; a thrown loader transitions the state to `voice-error`
|
|
114
|
+
* and re-throws so the caller sees the structured cause. No partial
|
|
115
|
+
* arm: either all four resources are held or none are.
|
|
116
|
+
*/
|
|
117
|
+
arm(): Promise<ArmedResources>;
|
|
118
|
+
/**
|
|
119
|
+
* Transition `voice-on → voice-disarming → voice-off`. Calls
|
|
120
|
+
* `evictPages()` on the TTS + ASR mmap regions before releasing them
|
|
121
|
+
* so the OS reclaims the pages even if another consumer keeps the
|
|
122
|
+
* file descriptor open. The voice caches stay in the registry as
|
|
123
|
+
* tiny (KB-scale) entries — only the heavy mmap regions get evicted.
|
|
124
|
+
*/
|
|
125
|
+
disarm(): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Reset from `voice-error` back to `voice-off`. Required because
|
|
128
|
+
* `voice-error` is terminal — the engine must explicitly acknowledge
|
|
129
|
+
* the failure before the user can re-attempt voice. There is no
|
|
130
|
+
* automatic retry path.
|
|
131
|
+
*/
|
|
132
|
+
reset(): void;
|
|
133
|
+
private transition;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EACX,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GACjE;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GACxE;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,iFAAiF;IACjF,QAAQ,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EACV,cAAc,GACd,WAAW,GACX,gBAAgB,GAChB,oBAAoB,GACpB,YAAY,GACZ,eAAe,CAAC;gBAEP,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;CAK9D;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,eAAe,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/C,uBAAuB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,oBAAoB;IACpC,YAAY,CAAC,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC1E;AAED,qBAAa,cAAc;IAC1B,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,IAAI,EAAE;QACjB,QAAQ,EAAE,sBAAsB,CAAC;QACjC,OAAO,EAAE,qBAAqB,CAAC;QAC/B,MAAM,CAAC,EAAE,oBAAoB,CAAC;KAC9B;IAMD,OAAO,IAAI,mBAAmB;IAI9B;;;;;;OAMG;IACG,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;IAqDpC;;;;;;OAMG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAqD7B;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAUb,OAAO,CAAC,UAAU;CAKlB"}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice lifecycle state-machine tests.
|
|
3
|
+
*
|
|
4
|
+
* Exercises every documented transition in `lifecycle.ts`:
|
|
5
|
+
* - default state is `voice-off`
|
|
6
|
+
* - `arm()` transitions through `voice-arming` → `voice-on`
|
|
7
|
+
* - `disarm()` transitions through `voice-disarming` → `voice-off`
|
|
8
|
+
* and invokes `evictPages()` on the TTS + ASR mmap regions
|
|
9
|
+
* - illegal transitions throw `VoiceLifecycleError`
|
|
10
|
+
* - 100x arm/disarm cycles do not leak refs in the registry
|
|
11
|
+
* - mmap failure surfaces as `voice-error` with the right code,
|
|
12
|
+
* not a silent fallback (AGENTS.md §3 + §9)
|
|
13
|
+
* - `reset()` is the only way out of `voice-error`
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { describe, expect, it, vi } from "vitest";
|
|
17
|
+
import {
|
|
18
|
+
VoiceLifecycle,
|
|
19
|
+
VoiceLifecycleError,
|
|
20
|
+
type VoiceLifecycleLoaders,
|
|
21
|
+
type VoiceLifecycleState,
|
|
22
|
+
} from "./lifecycle";
|
|
23
|
+
import {
|
|
24
|
+
type MmapRegionHandle,
|
|
25
|
+
type RefCountedResource,
|
|
26
|
+
SharedResourceRegistry,
|
|
27
|
+
} from "./shared-resources";
|
|
28
|
+
|
|
29
|
+
interface FakeMmap extends MmapRegionHandle {
|
|
30
|
+
evictCalls: number;
|
|
31
|
+
releaseCalls: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function fakeMmap(id: string, opts: { evictThrows?: Error } = {}): FakeMmap {
|
|
35
|
+
const region: FakeMmap = {
|
|
36
|
+
id,
|
|
37
|
+
path: `/tmp/${id}`,
|
|
38
|
+
sizeBytes: 1024,
|
|
39
|
+
evictCalls: 0,
|
|
40
|
+
releaseCalls: 0,
|
|
41
|
+
async evictPages() {
|
|
42
|
+
region.evictCalls++;
|
|
43
|
+
if (opts.evictThrows) throw opts.evictThrows;
|
|
44
|
+
},
|
|
45
|
+
async release() {
|
|
46
|
+
region.releaseCalls++;
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
return region;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function fakeResource(
|
|
53
|
+
id: string,
|
|
54
|
+
): RefCountedResource & { releaseCalls: number } {
|
|
55
|
+
const r = {
|
|
56
|
+
id,
|
|
57
|
+
releaseCalls: 0,
|
|
58
|
+
async release() {
|
|
59
|
+
r.releaseCalls++;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function loadersOk(): VoiceLifecycleLoaders & {
|
|
66
|
+
tts: FakeMmap;
|
|
67
|
+
asr: FakeMmap;
|
|
68
|
+
caches: ReturnType<typeof fakeResource>;
|
|
69
|
+
nodes: ReturnType<typeof fakeResource>;
|
|
70
|
+
} {
|
|
71
|
+
const tts = fakeMmap("tts:omnivoice-default");
|
|
72
|
+
const asr = fakeMmap("asr:default");
|
|
73
|
+
const caches = fakeResource("voice-caches");
|
|
74
|
+
const nodes = fakeResource("voice-scheduler-nodes");
|
|
75
|
+
return {
|
|
76
|
+
tts,
|
|
77
|
+
asr,
|
|
78
|
+
caches,
|
|
79
|
+
nodes,
|
|
80
|
+
loadTtsRegion: async () => tts,
|
|
81
|
+
loadAsrRegion: async () => asr,
|
|
82
|
+
loadVoiceCaches: async () => caches,
|
|
83
|
+
loadVoiceSchedulerNodes: async () => nodes,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
describe("VoiceLifecycle", () => {
|
|
88
|
+
it("defaults to voice-off", () => {
|
|
89
|
+
const reg = new SharedResourceRegistry();
|
|
90
|
+
const lc = new VoiceLifecycle({ registry: reg, loaders: loadersOk() });
|
|
91
|
+
expect(lc.current().kind).toBe("voice-off");
|
|
92
|
+
expect(reg.size()).toBe(0);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("arm() transitions voice-off → voice-arming → voice-on with all resources held", async () => {
|
|
96
|
+
const reg = new SharedResourceRegistry();
|
|
97
|
+
const loaders = loadersOk();
|
|
98
|
+
const transitions: VoiceLifecycleState["kind"][] = [];
|
|
99
|
+
const lc = new VoiceLifecycle({
|
|
100
|
+
registry: reg,
|
|
101
|
+
loaders,
|
|
102
|
+
events: {
|
|
103
|
+
onTransition: (_prev, next) => transitions.push(next.kind),
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
const armed = await lc.arm();
|
|
107
|
+
expect(transitions).toEqual(["voice-arming", "voice-on"]);
|
|
108
|
+
expect(lc.current().kind).toBe("voice-on");
|
|
109
|
+
expect(armed.tts.id).toBe(loaders.tts.id);
|
|
110
|
+
// All four resources tracked at refcount 1.
|
|
111
|
+
expect(reg.refCount(loaders.tts.id)).toBe(1);
|
|
112
|
+
expect(reg.refCount(loaders.asr.id)).toBe(1);
|
|
113
|
+
expect(reg.refCount(loaders.caches.id)).toBe(1);
|
|
114
|
+
expect(reg.refCount(loaders.nodes.id)).toBe(1);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("disarm() transitions voice-on → voice-disarming → voice-off and invokes evictPages on tts+asr", async () => {
|
|
118
|
+
const reg = new SharedResourceRegistry();
|
|
119
|
+
const loaders = loadersOk();
|
|
120
|
+
const transitions: VoiceLifecycleState["kind"][] = [];
|
|
121
|
+
const lc = new VoiceLifecycle({
|
|
122
|
+
registry: reg,
|
|
123
|
+
loaders,
|
|
124
|
+
events: {
|
|
125
|
+
onTransition: (_prev, next) => transitions.push(next.kind),
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
await lc.arm();
|
|
129
|
+
transitions.length = 0;
|
|
130
|
+
await lc.disarm();
|
|
131
|
+
expect(transitions).toEqual(["voice-disarming", "voice-off"]);
|
|
132
|
+
expect(lc.current().kind).toBe("voice-off");
|
|
133
|
+
// madvise was called on both heavy regions.
|
|
134
|
+
expect(loaders.tts.evictCalls).toBe(1);
|
|
135
|
+
expect(loaders.asr.evictCalls).toBe(1);
|
|
136
|
+
// Underlying release ran for every resource.
|
|
137
|
+
expect(loaders.tts.releaseCalls).toBe(1);
|
|
138
|
+
expect(loaders.asr.releaseCalls).toBe(1);
|
|
139
|
+
expect(loaders.caches.releaseCalls).toBe(1);
|
|
140
|
+
expect(loaders.nodes.releaseCalls).toBe(1);
|
|
141
|
+
// Registry empty post-disarm.
|
|
142
|
+
expect(reg.size()).toBe(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("arm() in voice-on throws illegal-transition", async () => {
|
|
146
|
+
const reg = new SharedResourceRegistry();
|
|
147
|
+
const lc = new VoiceLifecycle({ registry: reg, loaders: loadersOk() });
|
|
148
|
+
await lc.arm();
|
|
149
|
+
let thrown: unknown;
|
|
150
|
+
try {
|
|
151
|
+
await lc.arm();
|
|
152
|
+
} catch (e) {
|
|
153
|
+
thrown = e;
|
|
154
|
+
}
|
|
155
|
+
expect(thrown).toBeInstanceOf(VoiceLifecycleError);
|
|
156
|
+
if (thrown instanceof VoiceLifecycleError) {
|
|
157
|
+
expect(thrown.code).toBe("illegal-transition");
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("disarm() in voice-off throws illegal-transition", async () => {
|
|
162
|
+
const reg = new SharedResourceRegistry();
|
|
163
|
+
const lc = new VoiceLifecycle({ registry: reg, loaders: loadersOk() });
|
|
164
|
+
let thrown: unknown;
|
|
165
|
+
try {
|
|
166
|
+
await lc.disarm();
|
|
167
|
+
} catch (e) {
|
|
168
|
+
thrown = e;
|
|
169
|
+
}
|
|
170
|
+
expect(thrown).toBeInstanceOf(VoiceLifecycleError);
|
|
171
|
+
if (thrown instanceof VoiceLifecycleError) {
|
|
172
|
+
expect(thrown.code).toBe("illegal-transition");
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("100x arm/disarm cycles do not leak resources in the registry", async () => {
|
|
177
|
+
const reg = new SharedResourceRegistry();
|
|
178
|
+
// Build loaders that emit fresh handles on every call so refcount
|
|
179
|
+
// accounting actually exercises acquire/release rather than alias
|
|
180
|
+
// dedup.
|
|
181
|
+
let counter = 0;
|
|
182
|
+
const loaders: VoiceLifecycleLoaders = {
|
|
183
|
+
loadTtsRegion: async () => fakeMmap(`tts-${counter++}`),
|
|
184
|
+
loadAsrRegion: async () => fakeMmap(`asr-${counter++}`),
|
|
185
|
+
loadVoiceCaches: async () => fakeResource(`caches-${counter++}`),
|
|
186
|
+
loadVoiceSchedulerNodes: async () => fakeResource(`nodes-${counter++}`),
|
|
187
|
+
};
|
|
188
|
+
const lc = new VoiceLifecycle({ registry: reg, loaders });
|
|
189
|
+
for (let i = 0; i < 100; i++) {
|
|
190
|
+
await lc.arm();
|
|
191
|
+
await lc.disarm();
|
|
192
|
+
}
|
|
193
|
+
expect(lc.current().kind).toBe("voice-off");
|
|
194
|
+
expect(reg.size()).toBe(0);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("simulated mmap failure surfaces as voice-error (no silent fallback)", async () => {
|
|
198
|
+
const reg = new SharedResourceRegistry();
|
|
199
|
+
const tts = fakeMmap("tts");
|
|
200
|
+
const ttsLoad = vi.fn(async () => tts);
|
|
201
|
+
const asrLoad = vi.fn(async () => {
|
|
202
|
+
throw new Error("mmap MAP_FAILED: cannot allocate memory");
|
|
203
|
+
});
|
|
204
|
+
const lc = new VoiceLifecycle({
|
|
205
|
+
registry: reg,
|
|
206
|
+
loaders: {
|
|
207
|
+
loadTtsRegion: ttsLoad,
|
|
208
|
+
loadAsrRegion: asrLoad,
|
|
209
|
+
loadVoiceCaches: async () => fakeResource("caches"),
|
|
210
|
+
loadVoiceSchedulerNodes: async () => fakeResource("nodes"),
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
let thrown: unknown;
|
|
214
|
+
try {
|
|
215
|
+
await lc.arm();
|
|
216
|
+
} catch (e) {
|
|
217
|
+
thrown = e;
|
|
218
|
+
}
|
|
219
|
+
expect(thrown).toBeInstanceOf(VoiceLifecycleError);
|
|
220
|
+
if (thrown instanceof VoiceLifecycleError) {
|
|
221
|
+
// The error message matched both /mmap|MAP_FAILED/ and
|
|
222
|
+
// /ENOMEM|out of memory|RAM/. The mmap branch comes second in the
|
|
223
|
+
// mapper — but the RAM regex matches "memory" first. Either is a
|
|
224
|
+
// structured code; the contract is "not silent fallback".
|
|
225
|
+
expect(["ram-pressure", "mmap-fail"]).toContain(thrown.code);
|
|
226
|
+
}
|
|
227
|
+
expect(lc.current().kind).toBe("voice-error");
|
|
228
|
+
// Partial acquisition rolled back — mapped pages are evicted first
|
|
229
|
+
// and registry refs are released.
|
|
230
|
+
expect(tts.evictCalls).toBe(1);
|
|
231
|
+
expect(reg.size()).toBe(0);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it("RAM-pressure error code is preferred when message says ENOMEM", async () => {
|
|
235
|
+
const reg = new SharedResourceRegistry();
|
|
236
|
+
const lc = new VoiceLifecycle({
|
|
237
|
+
registry: reg,
|
|
238
|
+
loaders: {
|
|
239
|
+
loadTtsRegion: async () => {
|
|
240
|
+
throw new Error("ENOMEM: out of memory while mapping TTS weights");
|
|
241
|
+
},
|
|
242
|
+
loadAsrRegion: async () => fakeMmap("asr"),
|
|
243
|
+
loadVoiceCaches: async () => fakeResource("caches"),
|
|
244
|
+
loadVoiceSchedulerNodes: async () => fakeResource("nodes"),
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
let thrown: unknown;
|
|
248
|
+
try {
|
|
249
|
+
await lc.arm();
|
|
250
|
+
} catch (e) {
|
|
251
|
+
thrown = e;
|
|
252
|
+
}
|
|
253
|
+
expect(thrown).toBeInstanceOf(VoiceLifecycleError);
|
|
254
|
+
if (thrown instanceof VoiceLifecycleError) {
|
|
255
|
+
expect(thrown.code).toBe("ram-pressure");
|
|
256
|
+
}
|
|
257
|
+
expect(lc.current().kind).toBe("voice-error");
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it("voice-error is terminal until reset()", async () => {
|
|
261
|
+
const reg = new SharedResourceRegistry();
|
|
262
|
+
const lc = new VoiceLifecycle({
|
|
263
|
+
registry: reg,
|
|
264
|
+
loaders: {
|
|
265
|
+
loadTtsRegion: async () => {
|
|
266
|
+
throw new Error("kernel missing: turboquant_q4 unavailable");
|
|
267
|
+
},
|
|
268
|
+
loadAsrRegion: async () => fakeMmap("asr"),
|
|
269
|
+
loadVoiceCaches: async () => fakeResource("caches"),
|
|
270
|
+
loadVoiceSchedulerNodes: async () => fakeResource("nodes"),
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
await expect(lc.arm()).rejects.toBeInstanceOf(VoiceLifecycleError);
|
|
274
|
+
expect(lc.current().kind).toBe("voice-error");
|
|
275
|
+
// Cannot arm again from voice-error.
|
|
276
|
+
await expect(lc.arm()).rejects.toMatchObject({
|
|
277
|
+
code: "illegal-transition",
|
|
278
|
+
});
|
|
279
|
+
// Cannot disarm from voice-error.
|
|
280
|
+
await expect(lc.disarm()).rejects.toMatchObject({
|
|
281
|
+
code: "illegal-transition",
|
|
282
|
+
});
|
|
283
|
+
lc.reset();
|
|
284
|
+
expect(lc.current().kind).toBe("voice-off");
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it("reset() in voice-off throws illegal-transition", () => {
|
|
288
|
+
const reg = new SharedResourceRegistry();
|
|
289
|
+
const lc = new VoiceLifecycle({ registry: reg, loaders: loadersOk() });
|
|
290
|
+
expect(() => lc.reset()).toThrow(VoiceLifecycleError);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe("SharedResourceRegistry", () => {
|
|
295
|
+
it("dedupes by id and refcounts acquire/release", async () => {
|
|
296
|
+
const reg = new SharedResourceRegistry();
|
|
297
|
+
const a = fakeResource("foo");
|
|
298
|
+
const aliased = fakeResource("foo");
|
|
299
|
+
const first = reg.acquire(a);
|
|
300
|
+
const second = reg.acquire(aliased);
|
|
301
|
+
expect(second).toBe(first);
|
|
302
|
+
expect(reg.refCount("foo")).toBe(2);
|
|
303
|
+
await reg.release("foo");
|
|
304
|
+
expect(reg.refCount("foo")).toBe(1);
|
|
305
|
+
expect(a.releaseCalls).toBe(0);
|
|
306
|
+
await reg.release("foo");
|
|
307
|
+
expect(a.releaseCalls).toBe(1);
|
|
308
|
+
expect(reg.size()).toBe(0);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("release of unknown id throws — no silent leak", async () => {
|
|
312
|
+
const reg = new SharedResourceRegistry();
|
|
313
|
+
await expect(reg.release("ghost")).rejects.toThrow(/unknown resource/);
|
|
314
|
+
});
|
|
315
|
+
});
|