@elizaos/plugin-local-inference 2.0.0-beta.1 → 2.0.11-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/package.json +81 -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/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 +7 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +54 -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 +1171 -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 +190 -0
- package/src/routes/local-inference-asr-route.ts +213 -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 +423 -0
- package/src/routes/local-inference-compat-routes.ts +782 -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/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 +53 -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 +1398 -0
- package/src/runtime/index.d.ts +14 -0
- package/src/runtime/index.d.ts.map +1 -0
- package/src/runtime/index.ts +27 -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/asr/errors.d.ts +21 -0
- package/src/services/asr/errors.d.ts.map +1 -0
- package/src/services/asr/errors.ts +50 -0
- package/src/services/asr/hash.d.ts +28 -0
- package/src/services/asr/hash.d.ts.map +1 -0
- package/src/services/asr/hash.ts +49 -0
- package/src/services/asr/index.d.ts +76 -0
- package/src/services/asr/index.d.ts.map +1 -0
- package/src/services/asr/index.ts +178 -0
- package/src/services/asr/types.d.ts +91 -0
- package/src/services/asr/types.d.ts.map +1 -0
- package/src/services/asr/types.ts +95 -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/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 +240 -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 +92 -0
- package/src/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
- package/src/services/desktop-fused-ffi-backend-runtime.ts +333 -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 +724 -0
- package/src/services/downloader.ts +899 -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 +534 -0
- package/src/services/engine.d.ts.map +1 -0
- package/src/services/engine.ts +1891 -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.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 +183 -0
- package/src/services/hardware.ts +404 -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 +281 -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 +30 -0
- package/src/services/index.d.ts.map +1 -0
- package/src/services/index.ts +225 -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 +693 -0
- package/src/services/manifest/schema.d.ts +715 -0
- package/src/services/manifest/schema.d.ts.map +1 -0
- package/src/services/manifest/schema.ts +655 -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 +569 -0
- package/src/services/memory-arbiter.d.ts +343 -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 +1000 -0
- package/src/services/memory-monitor.d.ts +119 -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 +296 -0
- package/src/services/memory-pressure.d.ts +127 -0
- package/src/services/memory-pressure.d.ts.map +1 -0
- package/src/services/memory-pressure.ts +413 -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 +672 -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 +376 -0
- package/src/services/routing-policy.d.ts +55 -0
- package/src/services/routing-policy.d.ts.map +1 -0
- package/src/services/routing-policy.ts +228 -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 +15 -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/transcription-priority.test.ts +211 -0
- package/src/services/tts/errors.ts +46 -0
- package/src/services/tts/index.ts +214 -0
- package/src/services/tts/tts-audio-cache.ts +235 -0
- package/src/services/tts/types.ts +157 -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 +92 -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 +197 -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/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 +148 -0
- package/src/services/voice/embedding.ts +244 -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 +746 -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 +2226 -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 +636 -0
- package/src/services/voice/ffi-bindings.d.ts.map +1 -0
- package/src/services/voice/ffi-bindings.test.ts +671 -0
- package/src/services/voice/ffi-bindings.ts +3050 -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/ring-buffer.d.ts +40 -0
- package/src/services/voice/ring-buffer.d.ts.map +1 -0
- package/src/services/voice/ring-buffer.ts +105 -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/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 +420 -0
- package/src/services/voice/voice-budget.ts +656 -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 @@
|
|
|
1
|
+
{"version":3,"file":"cancellation-coordinator.d.ts","sourceRoot":"","sources":["cancellation-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EACN,KAAK,uBAAuB,EAC5B,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,eAAe,EAAE;QAChB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACnD,OAAO,CACN,QAAQ,EAAE,CAAC,KAAK,EAAE;YACjB,IAAI,EACD,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,iBAAiB,CAAC;YACrB,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,CAAC,EAAE,MAAM,CAAC;SAChB,KAAK,IAAI,GACR,MAAM,IAAI,CAAC;KACd,CAAC;CACF;AAED,MAAM,WAAW,mCAAmC;IACnD,8BAA8B;IAC9B,OAAO,EAAE,kBAAkB,CAAC;IAC5B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACtE;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACpD;;;OAGG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;CACrC;AAgBD,qBAAa,4BAA4B;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmD;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiD;IACzE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;gBAE1C,IAAI,EAAE,mCAAmC;IAOrD;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,sBAAsB;IA8D1B,2DAA2D;IAC3D,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAItD,kCAAkC;IAClC,YAAY,IAAI,MAAM,EAAE;IAIxB;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO;IAI/D;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIhC;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC;;;;;;;;;OASG;IACH,qBAAqB,CACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE;QACX,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;KACnE,GACC,MAAM,IAAI;IAQb;;;OAGG;IACH,OAAO,IAAI,IAAI;CASf"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { BargeInController } from "./barge-in";
|
|
3
|
+
import {
|
|
4
|
+
type CoordinatorRuntime,
|
|
5
|
+
VoiceCancellationCoordinator,
|
|
6
|
+
} from "./cancellation-coordinator";
|
|
7
|
+
|
|
8
|
+
type RuntimeEvent = Parameters<
|
|
9
|
+
Parameters<CoordinatorRuntime["turnControllers"]["onEvent"]>[0]
|
|
10
|
+
>[0];
|
|
11
|
+
|
|
12
|
+
/** Tiny fake matching the runtime structural surface. */
|
|
13
|
+
function makeFakeRuntime(): CoordinatorRuntime & {
|
|
14
|
+
emitEvent(event: RuntimeEvent): void;
|
|
15
|
+
abortCalls: Array<{ roomId: string; reason: string }>;
|
|
16
|
+
} {
|
|
17
|
+
const listeners = new Set<(e: RuntimeEvent) => void>();
|
|
18
|
+
const abortCalls: Array<{ roomId: string; reason: string }> = [];
|
|
19
|
+
return {
|
|
20
|
+
turnControllers: {
|
|
21
|
+
abortTurn(roomId, reason) {
|
|
22
|
+
abortCalls.push({ roomId, reason });
|
|
23
|
+
return true;
|
|
24
|
+
},
|
|
25
|
+
onEvent(listener) {
|
|
26
|
+
listeners.add(listener);
|
|
27
|
+
return () => listeners.delete(listener);
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
emitEvent(event) {
|
|
31
|
+
for (const l of listeners) l(event);
|
|
32
|
+
},
|
|
33
|
+
abortCalls,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe("VoiceCancellationCoordinator — barge-in fan-out", () => {
|
|
38
|
+
it("arming a turn returns a live token tied to the room", () => {
|
|
39
|
+
const rt = makeFakeRuntime();
|
|
40
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
41
|
+
const token = c.armTurn({ roomId: "r1", runId: "t1" });
|
|
42
|
+
expect(token.aborted).toBe(false);
|
|
43
|
+
expect(c.current("r1")).toBe(token);
|
|
44
|
+
expect(c.armedRoomIds()).toEqual(["r1"]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("bargeIn aborts the token, fires runtime.abortTurn, slotAbort, ttsStop", () => {
|
|
48
|
+
const rt = makeFakeRuntime();
|
|
49
|
+
const slotAbort = vi.fn();
|
|
50
|
+
const ttsStop = vi.fn();
|
|
51
|
+
const c = new VoiceCancellationCoordinator({
|
|
52
|
+
runtime: rt,
|
|
53
|
+
slotAbort,
|
|
54
|
+
ttsStop,
|
|
55
|
+
});
|
|
56
|
+
const token = c.armTurn({ roomId: "r1", runId: "t1", slot: 3 });
|
|
57
|
+
|
|
58
|
+
const ok = c.bargeIn("r1");
|
|
59
|
+
expect(ok).toBe(true);
|
|
60
|
+
expect(token.aborted).toBe(true);
|
|
61
|
+
expect(token.reason).toBe("barge-in");
|
|
62
|
+
expect(rt.abortCalls).toEqual([{ roomId: "r1", reason: "barge-in" }]);
|
|
63
|
+
expect(slotAbort).toHaveBeenCalledWith(3, "barge-in");
|
|
64
|
+
expect(ttsStop).toHaveBeenCalledWith("barge-in");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("does NOT call slotAbort when no slot was registered on the turn", () => {
|
|
68
|
+
const rt = makeFakeRuntime();
|
|
69
|
+
const slotAbort = vi.fn();
|
|
70
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt, slotAbort });
|
|
71
|
+
c.armTurn({ roomId: "r1", runId: "t1" });
|
|
72
|
+
c.bargeIn("r1");
|
|
73
|
+
expect(slotAbort).not.toHaveBeenCalled();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("revokeEot aborts with reason=eot-revoked", () => {
|
|
77
|
+
const rt = makeFakeRuntime();
|
|
78
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
79
|
+
const token = c.armTurn({ roomId: "r1", runId: "t1" });
|
|
80
|
+
c.revokeEot("r1");
|
|
81
|
+
expect(token.reason).toBe("eot-revoked");
|
|
82
|
+
expect(rt.abortCalls).toEqual([{ roomId: "r1", reason: "eot-revoked" }]);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("re-arming a room aborts the previous token (reason=external)", () => {
|
|
86
|
+
const rt = makeFakeRuntime();
|
|
87
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
88
|
+
const first = c.armTurn({ roomId: "r1", runId: "t1" });
|
|
89
|
+
const second = c.armTurn({ roomId: "r1", runId: "t2" });
|
|
90
|
+
expect(first.aborted).toBe(true);
|
|
91
|
+
expect(first.reason).toBe("external");
|
|
92
|
+
expect(second.aborted).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("propagates runtime-driven aborts into the voice token", () => {
|
|
96
|
+
const rt = makeFakeRuntime();
|
|
97
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
98
|
+
const token = c.armTurn({ roomId: "r1", runId: "t1" });
|
|
99
|
+
rt.emitEvent({ type: "aborted", roomId: "r1", reason: "app-pause" });
|
|
100
|
+
expect(token.aborted).toBe(true);
|
|
101
|
+
expect(token.reason).toBe("external");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("propagates runtime aborts with known voice reasons preserving the reason", () => {
|
|
105
|
+
const rt = makeFakeRuntime();
|
|
106
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
107
|
+
const token = c.armTurn({ roomId: "r1", runId: "t1" });
|
|
108
|
+
rt.emitEvent({ type: "aborted", roomId: "r1", reason: "voice-barge-in" });
|
|
109
|
+
expect(token.reason).toBe("barge-in");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("ignores runtime aborts for other rooms", () => {
|
|
113
|
+
const rt = makeFakeRuntime();
|
|
114
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
115
|
+
const tokenA = c.armTurn({ roomId: "rA", runId: "tA" });
|
|
116
|
+
const tokenB = c.armTurn({ roomId: "rB", runId: "tB" });
|
|
117
|
+
rt.emitEvent({ type: "aborted", roomId: "rA", reason: "x" });
|
|
118
|
+
expect(tokenA.aborted).toBe(true);
|
|
119
|
+
expect(tokenB.aborted).toBe(false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("dispose tears down every active turn", () => {
|
|
123
|
+
const rt = makeFakeRuntime();
|
|
124
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt });
|
|
125
|
+
const a = c.armTurn({ roomId: "rA", runId: "tA" });
|
|
126
|
+
const b = c.armTurn({ roomId: "rB", runId: "tB" });
|
|
127
|
+
c.dispose();
|
|
128
|
+
expect(a.aborted).toBe(true);
|
|
129
|
+
expect(b.aborted).toBe(true);
|
|
130
|
+
expect(c.armedRoomIds()).toEqual([]);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("idempotent abort — second bargeIn is a no-op", () => {
|
|
134
|
+
const rt = makeFakeRuntime();
|
|
135
|
+
const slotAbort = vi.fn();
|
|
136
|
+
const c = new VoiceCancellationCoordinator({ runtime: rt, slotAbort });
|
|
137
|
+
c.armTurn({ roomId: "r1", runId: "t1", slot: 0 });
|
|
138
|
+
expect(c.bargeIn("r1")).toBe(true);
|
|
139
|
+
expect(c.bargeIn("r1")).toBe(false);
|
|
140
|
+
// slotAbort called exactly once for the first abort
|
|
141
|
+
expect(slotAbort).toHaveBeenCalledTimes(1);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("bindBargeInController translates hard-stop into coordinator.bargeIn", () => {
|
|
145
|
+
const rt = makeFakeRuntime();
|
|
146
|
+
const slotAbort = vi.fn();
|
|
147
|
+
const ttsStop = vi.fn();
|
|
148
|
+
const c = new VoiceCancellationCoordinator({
|
|
149
|
+
runtime: rt,
|
|
150
|
+
slotAbort,
|
|
151
|
+
ttsStop,
|
|
152
|
+
});
|
|
153
|
+
const bic = new BargeInController();
|
|
154
|
+
const token = c.armTurn({ roomId: "r1", runId: "t1", slot: 9 });
|
|
155
|
+
const unsub = c.bindBargeInController("r1", bic);
|
|
156
|
+
|
|
157
|
+
// Simulate the agent speaking + an authoritative ASR word event so the
|
|
158
|
+
// controller's onWordsDetected promotes pause-tts into hard-stop.
|
|
159
|
+
bic.setAgentSpeaking(true);
|
|
160
|
+
// Pretend VAD just reported speech-active (sets the deadline window).
|
|
161
|
+
// We dispatch directly via `hardStop` for a deterministic test —
|
|
162
|
+
// barge-in.test.ts covers the VAD→words ladder.
|
|
163
|
+
bic.hardStop("barge-in-words");
|
|
164
|
+
expect(token.aborted).toBe(true);
|
|
165
|
+
expect(token.reason).toBe("barge-in");
|
|
166
|
+
expect(rt.abortCalls).toEqual([{ roomId: "r1", reason: "barge-in" }]);
|
|
167
|
+
expect(slotAbort).toHaveBeenCalledWith(9, "barge-in");
|
|
168
|
+
expect(ttsStop).toHaveBeenCalledWith("barge-in");
|
|
169
|
+
|
|
170
|
+
unsub();
|
|
171
|
+
// Subsequent hard-stops on a torn-down binding are inert.
|
|
172
|
+
const second = c.armTurn({ roomId: "r1", runId: "t2", slot: 9 });
|
|
173
|
+
bic.reset();
|
|
174
|
+
bic.hardStop("manual");
|
|
175
|
+
expect(second.aborted).toBe(false);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("listener errors do not block fan-out", () => {
|
|
179
|
+
const rt = makeFakeRuntime();
|
|
180
|
+
// First fan-out callback throws; ttsStop must still fire.
|
|
181
|
+
const ttsStop = vi.fn();
|
|
182
|
+
const slotAbort = vi.fn(() => {
|
|
183
|
+
throw new Error("slot-abort transport failed");
|
|
184
|
+
});
|
|
185
|
+
const c = new VoiceCancellationCoordinator({
|
|
186
|
+
runtime: rt,
|
|
187
|
+
slotAbort,
|
|
188
|
+
ttsStop,
|
|
189
|
+
});
|
|
190
|
+
c.armTurn({ roomId: "r1", runId: "t1", slot: 4 });
|
|
191
|
+
c.bargeIn("r1");
|
|
192
|
+
expect(slotAbort).toHaveBeenCalled();
|
|
193
|
+
expect(ttsStop).toHaveBeenCalled();
|
|
194
|
+
expect(rt.abortCalls.length).toBe(1);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice cancellation coordinator — Wave 3 W3-9.
|
|
3
|
+
*
|
|
4
|
+
* Single brain that owns one `VoiceCancellationToken` per active voice turn
|
|
5
|
+
* and binds every cancellation source into it:
|
|
6
|
+
*
|
|
7
|
+
* 1. VAD start-of-speech while the agent is speaking (barge-in).
|
|
8
|
+
* 2. `BargeInController.hardStop` (ASR-confirmed barge-in words).
|
|
9
|
+
* 3. Turn-detector EOT revocation (user resumed mid-tentative-pause).
|
|
10
|
+
* 4. Runtime turn abort (`TurnControllerRegistry` "aborted" event).
|
|
11
|
+
*
|
|
12
|
+
* On any cancel, it fans out to:
|
|
13
|
+
*
|
|
14
|
+
* 1. The voice token's `AbortSignal` — every fetch / model call wired to
|
|
15
|
+
* `signal` aborts at the next yield point.
|
|
16
|
+
* 2. `runtime.turnControllers.abortTurn(roomId, reason)` — the runtime's
|
|
17
|
+
* planner-loop / action handlers see the abort within one tick
|
|
18
|
+
* (between model calls / between actions / between provider calls).
|
|
19
|
+
* 3. Optional `slotAbort(slotId)` — invokes the registered LM
|
|
20
|
+
* slot-abort callback (typically `MtpLlamaServer.abortSlot` which
|
|
21
|
+
* either aborts in-flight HTTP fetches against that slot or, on a
|
|
22
|
+
* capable fork, calls the slot-cancel REST route).
|
|
23
|
+
* 4. Optional `ttsStop()` — invokes the registered TTS-stop callback
|
|
24
|
+
* (typically `EngineVoiceBridge.triggerBargeIn` which drains the
|
|
25
|
+
* audio sink + cancels the FFI/HTTP synthesis path).
|
|
26
|
+
*
|
|
27
|
+
* The coordinator is intentionally a plain class — no engine coupling. The
|
|
28
|
+
* engine bridge (and tests) construct one with the structural runtime + the
|
|
29
|
+
* appropriate callbacks.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
type VoiceCancellationReason,
|
|
34
|
+
VoiceCancellationRegistry,
|
|
35
|
+
type VoiceCancellationToken,
|
|
36
|
+
} from "@elizaos/shared";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Minimum runtime surface this coordinator needs. Matches a subset of
|
|
40
|
+
* `AgentRuntime.turnControllers`. Structural so unit tests can pass a fake.
|
|
41
|
+
*/
|
|
42
|
+
export interface CoordinatorRuntime {
|
|
43
|
+
turnControllers: {
|
|
44
|
+
abortTurn(roomId: string, reason: string): boolean;
|
|
45
|
+
onEvent(
|
|
46
|
+
listener: (event: {
|
|
47
|
+
type:
|
|
48
|
+
| "started"
|
|
49
|
+
| "completed"
|
|
50
|
+
| "errored"
|
|
51
|
+
| "aborted"
|
|
52
|
+
| "aborted-cleanup";
|
|
53
|
+
roomId: string;
|
|
54
|
+
reason?: string;
|
|
55
|
+
}) => void,
|
|
56
|
+
): () => void;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface VoiceCancellationCoordinatorOptions {
|
|
61
|
+
/** The runtime to bind to. */
|
|
62
|
+
runtime: CoordinatorRuntime;
|
|
63
|
+
/**
|
|
64
|
+
* Abort the inference server slot. Wired to `MtpLlamaServer.abortSlot`
|
|
65
|
+
* in production. Async — the coordinator does NOT await it (the slot
|
|
66
|
+
* abort path is best-effort; the AbortSignal closure on the fetch is the
|
|
67
|
+
* authoritative cancel).
|
|
68
|
+
*/
|
|
69
|
+
slotAbort?: (slotId: number, reason: VoiceCancellationReason) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Hard-stop the TTS pipeline (audio sink drain + FFI/HTTP synthesis
|
|
72
|
+
* cancel). Wired to `EngineVoiceBridge.triggerBargeIn`. Synchronous —
|
|
73
|
+
* the audio sink drain MUST happen within one tick of `abort()`.
|
|
74
|
+
*/
|
|
75
|
+
ttsStop?: (reason: VoiceCancellationReason) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Optional pre-existing registry. Tests inject one to inspect token
|
|
78
|
+
* lifecycle directly. Production creates a fresh registry per session.
|
|
79
|
+
*/
|
|
80
|
+
registry?: VoiceCancellationRegistry;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Per-turn metadata. Recorded when `armTurn` is called so that the
|
|
85
|
+
* coordinator can map a generic `runtime.turnControllers` "aborted" event
|
|
86
|
+
* for a room back to the voice token (and so the slot-abort path knows
|
|
87
|
+
* which slot to target).
|
|
88
|
+
*/
|
|
89
|
+
interface ArmedTurn {
|
|
90
|
+
roomId: string;
|
|
91
|
+
runId: string;
|
|
92
|
+
slot?: number;
|
|
93
|
+
token: VoiceCancellationToken;
|
|
94
|
+
unsubRuntime: () => void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class VoiceCancellationCoordinator {
|
|
98
|
+
private readonly runtime: CoordinatorRuntime;
|
|
99
|
+
private readonly slotAbort: VoiceCancellationCoordinatorOptions["slotAbort"];
|
|
100
|
+
private readonly ttsStop: VoiceCancellationCoordinatorOptions["ttsStop"];
|
|
101
|
+
private readonly registry: VoiceCancellationRegistry;
|
|
102
|
+
/** Active turns keyed by roomId. One per room. */
|
|
103
|
+
private readonly armed = new Map<string, ArmedTurn>();
|
|
104
|
+
|
|
105
|
+
constructor(opts: VoiceCancellationCoordinatorOptions) {
|
|
106
|
+
this.runtime = opts.runtime;
|
|
107
|
+
this.slotAbort = opts.slotAbort;
|
|
108
|
+
this.ttsStop = opts.ttsStop;
|
|
109
|
+
this.registry = opts.registry ?? new VoiceCancellationRegistry();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Begin a new voice turn for `roomId`. If a previous turn was active,
|
|
114
|
+
* it is aborted with `"external"` (the regular replace-on-arm semantics
|
|
115
|
+
* inherited from `VoiceCancellationRegistry`).
|
|
116
|
+
*/
|
|
117
|
+
armTurn(args: {
|
|
118
|
+
roomId: string;
|
|
119
|
+
runId: string;
|
|
120
|
+
slot?: number;
|
|
121
|
+
}): VoiceCancellationToken {
|
|
122
|
+
// Tear down any previous arming for the same room before reusing it.
|
|
123
|
+
const prior = this.armed.get(args.roomId);
|
|
124
|
+
if (prior) {
|
|
125
|
+
prior.unsubRuntime();
|
|
126
|
+
this.armed.delete(args.roomId);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const token = this.registry.arm(args.roomId, {
|
|
130
|
+
runId: args.runId,
|
|
131
|
+
...(args.slot !== undefined ? { slot: args.slot } : {}),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Fan out: when the token aborts, abort the runtime turn + slot + TTS.
|
|
135
|
+
token.onAbort((reason) => {
|
|
136
|
+
// Runtime turn abort — fires the planner-loop / action-handler
|
|
137
|
+
// abort signal merged into StreamingContext.
|
|
138
|
+
try {
|
|
139
|
+
this.runtime.turnControllers.abortTurn(args.roomId, reason);
|
|
140
|
+
} catch {
|
|
141
|
+
// Telemetry shouldn't fail cancellation.
|
|
142
|
+
}
|
|
143
|
+
if (args.slot !== undefined && this.slotAbort) {
|
|
144
|
+
try {
|
|
145
|
+
this.slotAbort(args.slot, reason);
|
|
146
|
+
} catch {
|
|
147
|
+
// Slot abort is best-effort.
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (this.ttsStop) {
|
|
151
|
+
try {
|
|
152
|
+
this.ttsStop(reason);
|
|
153
|
+
} catch {
|
|
154
|
+
// TTS hard-stop is best-effort; the audio sink owns the SIGKILL.
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Reverse direction: when the runtime aborts the turn (e.g. APP_PAUSE,
|
|
160
|
+
// orchestrator-initiated cancel), trip the voice token. This is the
|
|
161
|
+
// "runtime → voice" leg the R11 audit called out as missing.
|
|
162
|
+
const unsubRuntime = this.runtime.turnControllers.onEvent((event) => {
|
|
163
|
+
if (event.roomId !== args.roomId) return;
|
|
164
|
+
if (event.type === "aborted" || event.type === "aborted-cleanup") {
|
|
165
|
+
const reason = mapRuntimeReason(event.reason);
|
|
166
|
+
if (!token.aborted) {
|
|
167
|
+
token.abort(reason);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
this.armed.set(args.roomId, {
|
|
173
|
+
roomId: args.roomId,
|
|
174
|
+
runId: args.runId,
|
|
175
|
+
...(args.slot !== undefined ? { slot: args.slot } : {}),
|
|
176
|
+
token,
|
|
177
|
+
unsubRuntime,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return token;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Fetch the current voice token for `roomId`, or null. */
|
|
184
|
+
current(roomId: string): VoiceCancellationToken | null {
|
|
185
|
+
return this.registry.current(roomId);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Snapshot of armed room ids. */
|
|
189
|
+
armedRoomIds(): string[] {
|
|
190
|
+
return Array.from(this.armed.keys());
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Abort the active turn for `roomId` with the given reason. Idempotent.
|
|
195
|
+
* Returns true when a live token was aborted.
|
|
196
|
+
*/
|
|
197
|
+
abort(roomId: string, reason: VoiceCancellationReason): boolean {
|
|
198
|
+
return this.registry.abort(roomId, reason);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Trip the active token because VAD reported start-of-speech while the
|
|
203
|
+
* agent was speaking. Equivalent to `abort(roomId, "barge-in")` but
|
|
204
|
+
* keeps the call-site grep-able as the canonical barge-in entry point.
|
|
205
|
+
*/
|
|
206
|
+
bargeIn(roomId: string): boolean {
|
|
207
|
+
return this.abort(roomId, "barge-in");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Trip the active token because the turn detector revoked the previous
|
|
212
|
+
* EOT decision (user resumed within the rollback window).
|
|
213
|
+
*/
|
|
214
|
+
revokeEot(roomId: string): boolean {
|
|
215
|
+
return this.abort(roomId, "eot-revoked");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Wire a `BargeInController.onSignal` listener into this coordinator.
|
|
220
|
+
* The controller emits `hard-stop` when ASR confirms barge-in words;
|
|
221
|
+
* this glue translates it into `coordinator.bargeIn(roomId)` so the
|
|
222
|
+
* canonical token (and every downstream consumer) sees the abort.
|
|
223
|
+
*
|
|
224
|
+
* Returns the unsubscribe function from `onSignal`. Production callers
|
|
225
|
+
* (the engine bridge) call this once per `BargeInController` per
|
|
226
|
+
* room and keep the handle until session teardown.
|
|
227
|
+
*/
|
|
228
|
+
bindBargeInController(
|
|
229
|
+
roomId: string,
|
|
230
|
+
controller: {
|
|
231
|
+
onSignal(listener: (signal: { type: string }) => void): () => void;
|
|
232
|
+
},
|
|
233
|
+
): () => void {
|
|
234
|
+
return controller.onSignal((signal) => {
|
|
235
|
+
if (signal.type === "hard-stop") {
|
|
236
|
+
this.bargeIn(roomId);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Tear down. Cancels every armed turn and unsubscribes from the
|
|
243
|
+
* runtime. Safe to call multiple times.
|
|
244
|
+
*/
|
|
245
|
+
dispose(): void {
|
|
246
|
+
for (const arm of Array.from(this.armed.values())) {
|
|
247
|
+
arm.unsubRuntime();
|
|
248
|
+
if (!arm.token.aborted) {
|
|
249
|
+
arm.token.abort("external");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
this.armed.clear();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Map a freeform runtime-abort reason string into a `VoiceCancellationReason`.
|
|
258
|
+
* Conservative: anything that looks like a known voice reason stays as-is,
|
|
259
|
+
* everything else is `"external"` (the runtime decided independently of the
|
|
260
|
+
* voice loop).
|
|
261
|
+
*/
|
|
262
|
+
function mapRuntimeReason(reason: string | undefined): VoiceCancellationReason {
|
|
263
|
+
if (!reason) return "external";
|
|
264
|
+
if (reason === "barge-in" || reason === "voice-barge-in") return "barge-in";
|
|
265
|
+
if (reason === "eot-revoked") return "eot-revoked";
|
|
266
|
+
if (reason === "user-cancel") return "user-cancel";
|
|
267
|
+
if (reason === "timeout") return "timeout";
|
|
268
|
+
return "external";
|
|
269
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckpointManager — high-level slot-agnostic KV-cache checkpoint primitive
|
|
3
|
+
* used by the voice state machine (`voice-state-machine.ts`) to implement the
|
|
4
|
+
* optimistic-rollback path described in `docs/eliza-1-optimistic-rollback.md`.
|
|
5
|
+
*
|
|
6
|
+
* Why a manager on top of `CheckpointClient`?
|
|
7
|
+
*
|
|
8
|
+
* - `CheckpointClient` (in `checkpoint-client.ts`) is a thin REST
|
|
9
|
+
* adapter. It is keyed by `(slotId, filename)` because that is what the
|
|
10
|
+
* fork's `POST /slots/<id>/save?filename=<n>` REST API expects.
|
|
11
|
+
* - Callers (the voice state machine, voice-bench drivers) don't want to
|
|
12
|
+
* mint filenames, track active handles, or know about the upstream URL
|
|
13
|
+
* scheme. They want `save("pre-draft") → handle`, `restore(handle)`,
|
|
14
|
+
* `discard(handle)` and an in-memory mock for unit tests.
|
|
15
|
+
* - Backend reference shape is isolated here: the voice state machine keeps
|
|
16
|
+
* the same public interface (`saveCheckpoint`, `restoreCheckpoint`,
|
|
17
|
+
* `discardCheckpoint`) while this module owns how the REST backend stores
|
|
18
|
+
* and addresses the snapshot.
|
|
19
|
+
*
|
|
20
|
+
* The handle returned from `saveCheckpoint` carries enough information to
|
|
21
|
+
* `restore` and `discard` the same snapshot later even after the underlying
|
|
22
|
+
* URL scheme changes. The current backend reference points at
|
|
23
|
+
* `(slotId, filename)` and can evolve without changing callers.
|
|
24
|
+
*
|
|
25
|
+
* **MockCheckpointManager** stores a caller-supplied snapshot (token sequence
|
|
26
|
+
* + arbitrary metadata) in memory keyed by the handle. Tests use it to drive
|
|
27
|
+
* the voice state machine deterministically without spinning up a real
|
|
28
|
+
* checkpoint runtime.
|
|
29
|
+
*/
|
|
30
|
+
import { type CheckpointFetch, type CheckpointHandle as RestCheckpointHandle } from "../checkpoint-client";
|
|
31
|
+
/**
|
|
32
|
+
* Opaque-to-callers handle returned by `saveCheckpoint`. The fields are
|
|
33
|
+
* exposed so tests can assert on them but callers should treat the handle
|
|
34
|
+
* as an opaque blob.
|
|
35
|
+
*/
|
|
36
|
+
export interface CheckpointHandle {
|
|
37
|
+
/**
|
|
38
|
+
* Caller-supplied conversation/turn-scoped slot id. Maps onto the REST
|
|
39
|
+
* `slotId` today; on v1 it maps onto the upstream checkpoint-server's
|
|
40
|
+
* session id.
|
|
41
|
+
*/
|
|
42
|
+
slotId: string;
|
|
43
|
+
/**
|
|
44
|
+
* Human-readable name passed to `saveCheckpoint`. Used as part of the
|
|
45
|
+
* REST filename today (`C1-<slotId>-<name>`).
|
|
46
|
+
*/
|
|
47
|
+
name: string;
|
|
48
|
+
/**
|
|
49
|
+
* Monotonically increasing per-manager id. Lets tests assert that two
|
|
50
|
+
* checkpoints from the same `(slotId, name)` are distinct.
|
|
51
|
+
*/
|
|
52
|
+
id: number;
|
|
53
|
+
/** ISO timestamp of the save call. */
|
|
54
|
+
createdAt: string;
|
|
55
|
+
/**
|
|
56
|
+
* Backend-specific reference. For the REST-backed manager this is the
|
|
57
|
+
* `CheckpointClient` handle (`{slotId: number, filename: string,
|
|
58
|
+
* createdAt: string}`). For the mock manager this is `null` (the mock
|
|
59
|
+
* is keyed by the handle's `id` field).
|
|
60
|
+
*/
|
|
61
|
+
readonly backendRef: RestCheckpointHandle | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Common interface implemented by both `CheckpointManager` (REST-backed)
|
|
65
|
+
* and `MockCheckpointManager` (in-memory). The voice state machine accepts
|
|
66
|
+
* this interface so tests can substitute the mock.
|
|
67
|
+
*/
|
|
68
|
+
export interface CheckpointManagerLike {
|
|
69
|
+
/**
|
|
70
|
+
* Snapshot the slot's KV state. Returns a handle the caller passes back
|
|
71
|
+
* to `restoreCheckpoint` / `discardCheckpoint`. Each call returns a new
|
|
72
|
+
* handle; identical `(slotId, name)` pairs do NOT alias.
|
|
73
|
+
*/
|
|
74
|
+
saveCheckpoint(slotId: string, name: string): Promise<CheckpointHandle>;
|
|
75
|
+
/**
|
|
76
|
+
* Restore a previously-saved snapshot. After `restore`, the handle is
|
|
77
|
+
* still valid — the same checkpoint can be restored again (e.g. for two
|
|
78
|
+
* consecutive barge-ins against the same C1).
|
|
79
|
+
*/
|
|
80
|
+
restoreCheckpoint(handle: CheckpointHandle): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Free server-side storage for `handle`. After `discard`, the handle is
|
|
83
|
+
* invalid; subsequent restore/discard calls reject with
|
|
84
|
+
* `CheckpointHandleInvalidError`.
|
|
85
|
+
*/
|
|
86
|
+
discardCheckpoint(handle: CheckpointHandle): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Raised when a caller passes a handle that this manager did not create,
|
|
90
|
+
* or that has already been `discardCheckpoint`-ed. Distinct from REST
|
|
91
|
+
* errors (which surface as `CheckpointHttpError` from the client).
|
|
92
|
+
*/
|
|
93
|
+
export declare class CheckpointHandleInvalidError extends Error {
|
|
94
|
+
constructor(message: string);
|
|
95
|
+
}
|
|
96
|
+
export interface CheckpointManagerOptions {
|
|
97
|
+
/**
|
|
98
|
+
* Base URL of the checkpoint runtime. Same shape as
|
|
99
|
+
* `CheckpointClient` — `http://host:port`.
|
|
100
|
+
*/
|
|
101
|
+
baseUrl: string;
|
|
102
|
+
/**
|
|
103
|
+
* Slot-id-string → numeric slot-id mapping. The REST layer takes a
|
|
104
|
+
* non-negative integer; voice callers prefer string ids that travel
|
|
105
|
+
* with the conversation/turn id. Defaults to a hash of the string.
|
|
106
|
+
*/
|
|
107
|
+
resolveSlotId?: (slotIdString: string) => number;
|
|
108
|
+
/** Optional custom fetch (mostly for unit-testing the REST surface). */
|
|
109
|
+
fetchImpl?: CheckpointFetch;
|
|
110
|
+
/**
|
|
111
|
+
* Default per-request timeout (ms). Forwarded to `CheckpointClient`. The
|
|
112
|
+
* REST checkpoint REST surface is latency-critical on the restore path —
|
|
113
|
+
* keep this short.
|
|
114
|
+
*/
|
|
115
|
+
requestTimeoutMs?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Source of monotonically increasing ids. Injected for deterministic
|
|
118
|
+
* tests; defaults to a per-manager counter.
|
|
119
|
+
*/
|
|
120
|
+
now?: () => Date;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* REST-backed `CheckpointManager`. Wraps `CheckpointClient` and exposes
|
|
124
|
+
* the slot-agnostic save/restore/discard contract. The class is stateful
|
|
125
|
+
* only in so far as it tracks which handles are still live so a double-
|
|
126
|
+
* `discard` is detected; the actual snapshot lives in the runtime's
|
|
127
|
+
* `--slot-save-path` directory.
|
|
128
|
+
*/
|
|
129
|
+
export declare class CheckpointManager implements CheckpointManagerLike {
|
|
130
|
+
private readonly client;
|
|
131
|
+
private readonly resolveSlotId;
|
|
132
|
+
private readonly now;
|
|
133
|
+
private nextId;
|
|
134
|
+
private readonly live;
|
|
135
|
+
constructor(opts: CheckpointManagerOptions);
|
|
136
|
+
saveCheckpoint(slotId: string, name: string): Promise<CheckpointHandle>;
|
|
137
|
+
restoreCheckpoint(handle: CheckpointHandle): Promise<void>;
|
|
138
|
+
discardCheckpoint(handle: CheckpointHandle): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Probe the underlying runtime for checkpoint support. Forwarded
|
|
141
|
+
* from `CheckpointClient.probeSupported`. Callers gate the feature flag
|
|
142
|
+
* on this.
|
|
143
|
+
*/
|
|
144
|
+
probeSupported(signal?: AbortSignal): Promise<boolean>;
|
|
145
|
+
private assertLive;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Caller-supplied snapshot the mock stores against a handle. The voice
|
|
149
|
+
* state machine tests use this to record the token sequence at the
|
|
150
|
+
* `speech-pause` instant and assert that a barge-in restores the same
|
|
151
|
+
* sequence.
|
|
152
|
+
*/
|
|
153
|
+
export interface MockCheckpointSnapshot {
|
|
154
|
+
/** Token ids at the time of `saveCheckpoint`. */
|
|
155
|
+
tokens: readonly number[];
|
|
156
|
+
/** Free-form metadata (partial transcript, turn id, etc.). */
|
|
157
|
+
metadata?: Record<string, unknown>;
|
|
158
|
+
}
|
|
159
|
+
export type MockSnapshotSource = (slotId: string, name: string) => MockCheckpointSnapshot;
|
|
160
|
+
/**
|
|
161
|
+
* In-memory `CheckpointManager` for tests. Records every save / restore /
|
|
162
|
+
* discard call so tests can assert on them, and stores a snapshot of the
|
|
163
|
+
* token sequence keyed by handle.
|
|
164
|
+
*/
|
|
165
|
+
export declare class MockCheckpointManager implements CheckpointManagerLike {
|
|
166
|
+
private readonly snapshotSource?;
|
|
167
|
+
private nextId;
|
|
168
|
+
private readonly snapshots;
|
|
169
|
+
/**
|
|
170
|
+
* Operations recorded in arrival order. Useful for assertions like
|
|
171
|
+
* "discard happened after restore".
|
|
172
|
+
*/
|
|
173
|
+
readonly operations: Array<{
|
|
174
|
+
kind: "save";
|
|
175
|
+
slotId: string;
|
|
176
|
+
name: string;
|
|
177
|
+
handleId: number;
|
|
178
|
+
} | {
|
|
179
|
+
kind: "restore";
|
|
180
|
+
handleId: number;
|
|
181
|
+
} | {
|
|
182
|
+
kind: "discard";
|
|
183
|
+
handleId: number;
|
|
184
|
+
}>;
|
|
185
|
+
/**
|
|
186
|
+
* Token sequence the active "slot" most recently restored to. Lets
|
|
187
|
+
* tests assert that a restore actually replayed the saved tokens.
|
|
188
|
+
*/
|
|
189
|
+
currentTokens: readonly number[];
|
|
190
|
+
constructor(snapshotSource?: MockSnapshotSource | undefined);
|
|
191
|
+
saveCheckpoint(slotId: string, name: string): Promise<CheckpointHandle>;
|
|
192
|
+
restoreCheckpoint(handle: CheckpointHandle): Promise<void>;
|
|
193
|
+
discardCheckpoint(handle: CheckpointHandle): Promise<void>;
|
|
194
|
+
/** Live handles count — for leak assertions. */
|
|
195
|
+
liveHandleCount(): number;
|
|
196
|
+
/** Look up the snapshot saved against `handle.id`. */
|
|
197
|
+
snapshotFor(handle: CheckpointHandle): MockCheckpointSnapshot | undefined;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=checkpoint-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-manager.d.ts","sourceRoot":"","sources":["checkpoint-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,gBAAgB,IAAI,oBAAoB,EAC7C,MAAM,sBAAsB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACjD;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxE;;;;OAIG;IACH,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D;;;;OAIG;IACH,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;gBAC1C,OAAO,EAAE,MAAM;CAI3B;AAMD,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,wEAAwE;IACxE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACjB;AAID;;;;;;GAMG;AACH,qBAAa,iBAAkB,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAE9B,IAAI,EAAE,wBAAwB;IAYpC,cAAc,CACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,CAAC;IAmBtB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1D,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAchE;;;;OAIG;IACG,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5D,OAAO,CAAC,UAAU;CAOlB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACtC,iDAAiD;IACjD,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,kBAAkB,GAAG,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,KACR,sBAAsB,CAAC;AAE5B;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,qBAAqB;IAkBtD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAjB5C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6C;IACvE;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,KAAK,CACvB;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAChE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACrC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CACvC,CAAM;IACP;;;OAGG;IACH,aAAa,EAAE,SAAS,MAAM,EAAE,CAAM;gBAET,cAAc,CAAC,EAAE,kBAAkB,YAAA;IAE1D,cAAc,CACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,CAAC;IAkBtB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1D,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhE,gDAAgD;IAChD,eAAe,IAAI,MAAM;IAIzB,sDAAsD;IACtD,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,SAAS;CAGzE"}
|