@elizaos/plugin-local-inference 2.0.3-beta.2 → 2.0.3-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -10
- package/dist/actions/generate-media.d.ts.map +1 -0
- package/dist/actions/identify-speaker.d.ts.map +1 -0
- package/dist/actions/transcription-control.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/environment.d.ts +12 -0
- package/dist/adapters/capacitor-llama/environment.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/index.browser.d.ts +9 -0
- package/dist/adapters/capacitor-llama/index.browser.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/index.d.ts +18 -0
- package/dist/adapters/capacitor-llama/index.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/loader.d.ts +35 -0
- package/dist/adapters/capacitor-llama/loader.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/native-voice-capture.d.ts +70 -0
- package/dist/adapters/capacitor-llama/native-voice-capture.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/structured-output.d.ts +62 -0
- package/dist/adapters/capacitor-llama/structured-output.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/text-streaming.d.ts +24 -0
- package/dist/adapters/capacitor-llama/text-streaming.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/types.d.ts +338 -0
- package/dist/adapters/capacitor-llama/types.d.ts.map +1 -0
- package/dist/adapters/capacitor-llama/voice-turn.d.ts +86 -0
- package/dist/adapters/capacitor-llama/voice-turn.d.ts.map +1 -0
- package/dist/backends/apple-foundation.d.ts +56 -0
- package/dist/backends/apple-foundation.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39647 -0
- package/dist/index.js.map +217 -0
- package/{src → dist}/local-inference-routes.d.ts +9 -0
- package/dist/local-inference-routes.d.ts.map +1 -0
- package/dist/provider.d.ts.map +1 -0
- package/{src → dist}/routes/compat-helpers.d.ts +1 -1
- package/dist/routes/compat-helpers.d.ts.map +1 -0
- package/dist/routes/family-member-route.d.ts.map +1 -0
- package/{src → dist}/routes/index.d.ts +1 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +42040 -0
- package/dist/routes/index.js.map +236 -0
- package/{src → dist}/routes/live-diarization-route.d.ts +7 -0
- package/dist/routes/live-diarization-route.d.ts.map +1 -0
- package/dist/routes/local-inference-asr-route.d.ts.map +1 -0
- package/dist/routes/local-inference-asr-transcribe.d.ts.map +1 -0
- package/dist/routes/local-inference-compat-routes.d.ts.map +1 -0
- package/dist/routes/local-inference-tts-route.d.ts.map +1 -0
- package/dist/routes/native-pcm-turn-route.d.ts +3 -0
- package/dist/routes/native-pcm-turn-route.d.ts.map +1 -0
- package/dist/routes/transcript-audio-store.d.ts.map +1 -0
- package/{src → dist}/routes/transcripts-routes.d.ts +8 -0
- package/dist/routes/transcripts-routes.d.ts.map +1 -0
- package/dist/routes/voice-first-run-routes.d.ts.map +1 -0
- package/dist/routes/voice-models-routes.d.ts.map +1 -0
- package/dist/routes/voice-profile-plugin-routes.d.ts.map +1 -0
- package/dist/routes/voice-profiles-management-routes.d.ts.map +1 -0
- package/dist/routes/voice-speaker-profile-routes.d.ts.map +1 -0
- package/dist/runtime/embedding-manager-support.d.ts.map +1 -0
- package/dist/runtime/embedding-presets.d.ts.map +1 -0
- package/dist/runtime/embedding-warmup-policy.d.ts.map +1 -0
- package/{src → dist}/runtime/ensure-local-inference-handler.d.ts +8 -0
- package/dist/runtime/ensure-local-inference-handler.d.ts.map +1 -0
- package/{src → dist}/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +38768 -0
- package/dist/runtime/index.js.map +217 -0
- package/dist/runtime/mobile-local-inference-gate.d.ts +63 -0
- package/dist/runtime/mobile-local-inference-gate.d.ts.map +1 -0
- package/{src → dist}/runtime/voice-entity-binding.d.ts +10 -0
- package/dist/runtime/voice-entity-binding.d.ts.map +1 -0
- package/{src → dist}/services/active-model.d.ts +28 -0
- package/dist/services/active-model.d.ts.map +1 -0
- package/dist/services/asr-provenance.d.ts +5 -0
- package/dist/services/asr-provenance.d.ts.map +1 -0
- package/{src → dist}/services/assignments.d.ts +16 -3
- package/dist/services/assignments.d.ts.map +1 -0
- package/dist/services/backend-selector.d.ts +55 -0
- package/dist/services/backend-selector.d.ts.map +1 -0
- package/{src → dist}/services/backend.d.ts +110 -16
- package/dist/services/backend.d.ts.map +1 -0
- package/{src → dist}/services/bionic-host-loader.d.ts +21 -0
- package/dist/services/bionic-host-loader.d.ts.map +1 -0
- package/dist/services/bundled-models.d.ts.map +1 -0
- package/dist/services/cache-bridge.d.ts.map +1 -0
- package/dist/services/catalog.d.ts +10 -0
- package/dist/services/catalog.d.ts.map +1 -0
- package/dist/services/checkpoint-client.d.ts.map +1 -0
- package/dist/services/checkpoint-manager.d.ts +217 -0
- package/dist/services/checkpoint-manager.d.ts.map +1 -0
- package/dist/services/cloud-fallback.d.ts.map +1 -0
- package/dist/services/context-fit.d.ts +36 -0
- package/dist/services/context-fit.d.ts.map +1 -0
- package/dist/services/conversation-registry.d.ts.map +1 -0
- package/{src → dist}/services/desktop-fused-ffi-backend-runtime.d.ts +22 -6
- package/dist/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
- package/dist/services/device-bridge.d.ts.map +1 -0
- package/dist/services/device-resource-metrics.d.ts.map +1 -0
- package/{src → dist}/services/device-tier.d.ts +19 -1
- package/dist/services/device-tier.d.ts.map +1 -0
- package/{src → dist}/services/downloader.d.ts +16 -4
- package/dist/services/downloader.d.ts.map +1 -0
- package/{src → dist}/services/engine.d.ts +43 -4
- package/dist/services/engine.d.ts.map +1 -0
- package/dist/services/ensure-local-artifacts.d.ts +82 -0
- package/dist/services/ensure-local-artifacts.d.ts.map +1 -0
- package/dist/services/external-scanner.d.ts.map +1 -0
- package/dist/services/ffi-llm-mock.d.ts +90 -0
- package/dist/services/ffi-llm-mock.d.ts.map +1 -0
- package/dist/services/ffi-llm-streaming-abi.d.ts +318 -0
- package/dist/services/ffi-llm-streaming-abi.d.ts.map +1 -0
- package/{src → dist}/services/ffi-streaming-backend.d.ts +28 -7
- package/dist/services/ffi-streaming-backend.d.ts.map +1 -0
- package/{src → dist}/services/ffi-streaming-runner.d.ts +24 -0
- package/dist/services/ffi-streaming-runner.d.ts.map +1 -0
- package/dist/services/gpu-autotune.d.ts +150 -0
- package/dist/services/gpu-autotune.d.ts.map +1 -0
- package/dist/services/gpu-detect.d.ts.map +1 -0
- package/dist/services/handler-registry.d.ts.map +1 -0
- package/dist/services/hardware.d.ts.map +1 -0
- package/dist/services/image-description-runtime.d.ts.map +1 -0
- package/dist/services/imagegen/aosp-unavailable.d.ts.map +1 -0
- package/dist/services/imagegen/backend-selector.d.ts.map +1 -0
- package/dist/services/imagegen/coreml-unavailable.d.ts.map +1 -0
- package/dist/services/imagegen/errors.d.ts.map +1 -0
- package/dist/services/imagegen/index.d.ts.map +1 -0
- package/dist/services/imagegen/mflux.d.ts.map +1 -0
- package/{src → dist}/services/imagegen/sd-cpp.d.ts +1 -0
- package/dist/services/imagegen/sd-cpp.d.ts.map +1 -0
- package/dist/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
- package/dist/services/imagegen/types.d.ts.map +1 -0
- package/{src → dist}/services/index.d.ts +3 -1
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +39453 -0
- package/dist/services/index.js.map +227 -0
- package/dist/services/inference-capabilities.d.ts.map +1 -0
- package/dist/services/inference-telemetry.d.ts.map +1 -0
- package/dist/services/ios-llama-streaming.d.ts +119 -0
- package/dist/services/ios-llama-streaming.d.ts.map +1 -0
- package/dist/services/kv-spill.d.ts.map +1 -0
- package/dist/services/latency-trace.d.ts.map +1 -0
- package/dist/services/lib-target.d.ts +55 -0
- package/dist/services/lib-target.d.ts.map +1 -0
- package/dist/services/live-signals.d.ts +86 -0
- package/dist/services/live-signals.d.ts.map +1 -0
- package/dist/services/llama-server-metrics.d.ts +114 -0
- package/dist/services/llama-server-metrics.d.ts.map +1 -0
- package/dist/services/llm-streaming-binding.d.ts.map +1 -0
- package/dist/services/load-args.d.ts.map +1 -0
- package/dist/services/manifest/index.d.ts +4 -0
- package/dist/services/manifest/index.d.ts.map +1 -0
- package/{src → dist}/services/manifest/schema.d.ts +196 -6
- package/dist/services/manifest/schema.d.ts.map +1 -0
- package/{src → dist}/services/manifest/types.d.ts +3 -1
- package/dist/services/manifest/types.d.ts.map +1 -0
- package/dist/services/manifest/validator.d.ts.map +1 -0
- package/{src → dist}/services/memory-arbiter.d.ts +33 -3
- package/dist/services/memory-arbiter.d.ts.map +1 -0
- package/dist/services/memory-benchmark.d.ts +76 -0
- package/dist/services/memory-benchmark.d.ts.map +1 -0
- package/{src → dist}/services/memory-monitor.d.ts +6 -0
- package/dist/services/memory-monitor.d.ts.map +1 -0
- package/dist/services/memory-pressure.d.ts.map +1 -0
- package/dist/services/mtp-doctor.d.ts.map +1 -0
- package/dist/services/network-policy.d.ts.map +1 -0
- package/dist/services/paths.d.ts.map +1 -0
- package/dist/services/planner-skeleton.d.ts.map +1 -0
- package/dist/services/providers.d.ts.map +1 -0
- package/dist/services/ram-budget.d.ts.map +1 -0
- package/dist/services/readiness.d.ts.map +1 -0
- package/dist/services/recommendation.d.ts.map +1 -0
- package/{src → dist}/services/registry.d.ts +11 -13
- package/dist/services/registry.d.ts.map +1 -0
- package/{src → dist}/services/router-handler.d.ts +2 -2
- package/dist/services/router-handler.d.ts.map +1 -0
- package/{src → dist}/services/routing-policy.d.ts +32 -9
- package/dist/services/routing-policy.d.ts.map +1 -0
- package/dist/services/routing-preferences.d.ts.map +1 -0
- package/dist/services/runtime-target.d.ts.map +1 -0
- package/{src → dist}/services/service.d.ts +1 -1
- package/dist/services/service.d.ts.map +1 -0
- package/dist/services/session-pool.d.ts.map +1 -0
- package/dist/services/structured-output/deterministic-repair.d.ts.map +1 -0
- package/dist/services/structured-output/index.d.ts +2 -0
- package/dist/services/structured-output/index.d.ts.map +1 -0
- package/dist/services/structured-output.d.ts.map +1 -0
- package/dist/services/system-memory.d.ts.map +1 -0
- package/{src → dist}/services/types.d.ts +1 -1
- package/dist/services/types.d.ts.map +1 -0
- package/dist/services/verify-on-device.d.ts.map +1 -0
- package/dist/services/verify.d.ts.map +1 -0
- package/dist/services/vision/aosp-unavailable.d.ts.map +1 -0
- package/dist/services/vision/capacitor-llama.d.ts.map +1 -0
- package/dist/services/vision/cloud-fallback.d.ts.map +1 -0
- package/dist/services/vision/hash.d.ts.map +1 -0
- package/{src → dist}/services/vision/index.d.ts +1 -1
- package/dist/services/vision/index.d.ts.map +1 -0
- package/dist/services/vision/llama-server.d.ts.map +1 -0
- package/{src → dist}/services/vision/types.d.ts +13 -4
- package/dist/services/vision/types.d.ts.map +1 -0
- package/dist/services/vision/vast-fallback.d.ts.map +1 -0
- package/{src → dist}/services/vision-embedding-cache.d.ts +1 -1
- package/dist/services/vision-embedding-cache.d.ts.map +1 -0
- package/dist/services/voice/__test-helpers__/fake-ffi.d.ts +27 -0
- package/dist/services/voice/__test-helpers__/fake-ffi.d.ts.map +1 -0
- package/dist/services/voice/__test-helpers__/synthetic-speech.d.ts +66 -0
- package/dist/services/voice/__test-helpers__/synthetic-speech.d.ts.map +1 -0
- package/dist/services/voice/acoustic-speaker-attribution.d.ts +61 -0
- package/dist/services/voice/acoustic-speaker-attribution.d.ts.map +1 -0
- package/{src → dist}/services/voice/audio-frame-consumer.d.ts +82 -0
- package/dist/services/voice/audio-frame-consumer.d.ts.map +1 -0
- package/dist/services/voice/barge-in.d.ts.map +1 -0
- package/dist/services/voice/cancellation-coordinator.d.ts.map +1 -0
- package/dist/services/voice/checkpoint-manager.d.ts.map +1 -0
- package/dist/services/voice/checkpoint-policy.d.ts +178 -0
- package/dist/services/voice/checkpoint-policy.d.ts.map +1 -0
- package/dist/services/voice/corpus-augment.d.ts +111 -0
- package/dist/services/voice/corpus-augment.d.ts.map +1 -0
- package/dist/services/voice/corpus-generator.d.ts +134 -0
- package/dist/services/voice/corpus-generator.d.ts.map +1 -0
- package/dist/services/voice/diarization-error-rate.d.ts +40 -0
- package/dist/services/voice/diarization-error-rate.d.ts.map +1 -0
- package/dist/services/voice/e2e-harness.d.ts +297 -0
- package/dist/services/voice/e2e-harness.d.ts.map +1 -0
- package/dist/services/voice/eager-context-builder.d.ts.map +1 -0
- package/dist/services/voice/echo-delay.d.ts +67 -0
- package/dist/services/voice/echo-delay.d.ts.map +1 -0
- package/dist/services/voice/echo-metrics.d.ts +7 -0
- package/dist/services/voice/echo-metrics.d.ts.map +1 -0
- package/dist/services/voice/echo-reference-buffer.d.ts +65 -0
- package/dist/services/voice/echo-reference-buffer.d.ts.map +1 -0
- package/{src → dist}/services/voice/eliza1-eot-scorer.d.ts +8 -8
- package/dist/services/voice/eliza1-eot-scorer.d.ts.map +1 -0
- package/dist/services/voice/embedding-server.d.ts +37 -0
- package/dist/services/voice/embedding-server.d.ts.map +1 -0
- package/{src → dist}/services/voice/embedding.d.ts +2 -3
- package/dist/services/voice/embedding.d.ts.map +1 -0
- package/dist/services/voice/emotion-attribution.d.ts.map +1 -0
- package/{src → dist}/services/voice/engine-bridge.d.ts +8 -5
- package/dist/services/voice/engine-bridge.d.ts.map +1 -0
- package/{src → dist}/services/voice/eot-classifier-ggml.d.ts +22 -22
- package/dist/services/voice/eot-classifier-ggml.d.ts.map +1 -0
- package/{src → dist}/services/voice/eot-classifier.d.ts +9 -12
- package/dist/services/voice/eot-classifier.d.ts.map +1 -0
- package/{src → dist}/services/voice/errors.d.ts +1 -1
- package/dist/services/voice/errors.d.ts.map +1 -0
- package/{src → dist}/services/voice/expressive-tags.d.ts +5 -5
- package/dist/services/voice/expressive-tags.d.ts.map +1 -0
- package/{src → dist}/services/voice/ffi-bindings.d.ts +26 -4
- package/dist/services/voice/ffi-bindings.d.ts.map +1 -0
- package/dist/services/voice/first-line-cache.d.ts.map +1 -0
- package/{src → dist}/services/voice/fused-eot-scorer.d.ts +6 -6
- package/dist/services/voice/fused-eot-scorer.d.ts.map +1 -0
- package/{src → dist}/services/voice/index.d.ts +8 -3
- package/dist/services/voice/index.d.ts.map +1 -0
- package/dist/services/voice/kokoro/index.d.ts +24 -0
- package/dist/services/voice/kokoro/index.d.ts.map +1 -0
- package/{src → dist}/services/voice/kokoro/kokoro-backend.d.ts +15 -0
- package/dist/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
- package/{src → dist}/services/voice/kokoro/kokoro-engine-discovery.d.ts +1 -1
- package/dist/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
- package/{src → dist}/services/voice/kokoro/kokoro-ffi-runtime.d.ts +3 -3
- package/dist/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
- package/dist/services/voice/kokoro/kokoro-runtime.d.ts.map +1 -0
- package/dist/services/voice/kokoro/phoneme-stream.d.ts +51 -0
- package/dist/services/voice/kokoro/phoneme-stream.d.ts.map +1 -0
- package/dist/services/voice/kokoro/phonemizer.d.ts.map +1 -0
- package/{src → dist}/services/voice/kokoro/pick-runtime.d.ts +1 -1
- package/dist/services/voice/kokoro/pick-runtime.d.ts.map +1 -0
- package/dist/services/voice/kokoro/runtime-selection.d.ts +31 -0
- package/dist/services/voice/kokoro/runtime-selection.d.ts.map +1 -0
- package/dist/services/voice/kokoro/types.d.ts.map +1 -0
- package/dist/services/voice/kokoro/voice-presets.d.ts.map +1 -0
- package/dist/services/voice/kokoro/voices.d.ts.map +1 -0
- package/dist/services/voice/lifecycle.d.ts.map +1 -0
- package/dist/services/voice/live-diarization-session.d.ts +196 -0
- package/dist/services/voice/live-diarization-session.d.ts.map +1 -0
- package/dist/services/voice/metric-math.d.ts +10 -0
- package/dist/services/voice/metric-math.d.ts.map +1 -0
- package/{src → dist}/services/voice/mic-source.d.ts +1 -1
- package/dist/services/voice/mic-source.d.ts.map +1 -0
- package/dist/services/voice/nlms-echo-canceller.d.ts +137 -0
- package/dist/services/voice/nlms-echo-canceller.d.ts.map +1 -0
- package/dist/services/voice/optimistic-policy.d.ts.map +1 -0
- package/dist/services/voice/optimistic-rollback.d.ts +151 -0
- package/dist/services/voice/optimistic-rollback.d.ts.map +1 -0
- package/{src → dist}/services/voice/partial-stabilizer.d.ts +1 -1
- package/dist/services/voice/partial-stabilizer.d.ts.map +1 -0
- package/dist/services/voice/phoneme-tokenizer.d.ts.map +1 -0
- package/dist/services/voice/phrase-cache.d.ts.map +1 -0
- package/dist/services/voice/phrase-chunker.d.ts.map +1 -0
- package/dist/services/voice/pipeline-impls.d.ts.map +1 -0
- package/dist/services/voice/pipeline.d.ts.map +1 -0
- package/dist/services/voice/prefill-client.d.ts.map +1 -0
- package/dist/services/voice/prefix-preserving-queue.d.ts.map +1 -0
- package/dist/services/voice/profile-store.d.ts.map +1 -0
- package/dist/services/voice/ring-buffer.d.ts.map +1 -0
- package/dist/services/voice/rollback-queue.d.ts.map +1 -0
- package/dist/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
- package/dist/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
- package/dist/services/voice/scheduler.d.ts.map +1 -0
- package/dist/services/voice/self-voice-imprint.d.ts +33 -0
- package/dist/services/voice/self-voice-imprint.d.ts.map +1 -0
- package/{src → dist}/services/voice/shared-resources.d.ts +14 -0
- package/dist/services/voice/shared-resources.d.ts.map +1 -0
- package/dist/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
- package/dist/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
- package/dist/services/voice/speaker/diarizer.d.ts.map +1 -0
- package/dist/services/voice/speaker/encoder-fused.d.ts.map +1 -0
- package/dist/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
- package/dist/services/voice/speaker/encoder.d.ts.map +1 -0
- package/dist/services/voice/speaker-imprint.d.ts.map +1 -0
- package/dist/services/voice/speaker-preset-cache.d.ts.map +1 -0
- package/dist/services/voice/streaming-asr/streaming-pipeline-adapter.d.ts +160 -0
- package/dist/services/voice/streaming-asr/streaming-pipeline-adapter.d.ts.map +1 -0
- package/dist/services/voice/system-audio-sink.d.ts.map +1 -0
- package/{src → dist}/services/voice/transcriber.d.ts +4 -4
- package/dist/services/voice/transcriber.d.ts.map +1 -0
- package/dist/services/voice/transcript-knowledge.d.ts.map +1 -0
- package/{src → dist}/services/voice/transcript-service.d.ts +20 -1
- package/dist/services/voice/transcript-service.d.ts.map +1 -0
- package/{src → dist}/services/voice/transcript-store.d.ts +12 -1
- package/dist/services/voice/transcript-store.d.ts.map +1 -0
- package/dist/services/voice/turn-controller.d.ts.map +1 -0
- package/{src → dist}/services/voice/types.d.ts +6 -6
- package/dist/services/voice/types.d.ts.map +1 -0
- package/{src → dist}/services/voice/vad.d.ts +6 -5
- package/dist/services/voice/vad.d.ts.map +1 -0
- package/dist/services/voice/voice-budget.d.ts.map +1 -0
- package/dist/services/voice/voice-emotion-classifier.d.ts.map +1 -0
- package/dist/services/voice/voice-preload-predictor.d.ts +76 -0
- package/dist/services/voice/voice-preload-predictor.d.ts.map +1 -0
- package/{src → dist}/services/voice/voice-preset-format.d.ts +2 -2
- package/dist/services/voice/voice-preset-format.d.ts.map +1 -0
- package/dist/services/voice/voice-profile-artifact.d.ts.map +1 -0
- package/dist/services/voice/voice-profile-routes.d.ts.map +1 -0
- package/dist/services/voice/voice-scenario.d.ts +131 -0
- package/dist/services/voice/voice-scenario.d.ts.map +1 -0
- package/dist/services/voice/voice-state-machine.d.ts.map +1 -0
- package/dist/services/voice/voice-workbench-report.d.ts +117 -0
- package/dist/services/voice/voice-workbench-report.d.ts.map +1 -0
- package/{src → dist}/services/voice/wake-word-ggml.d.ts +8 -9
- package/dist/services/voice/wake-word-ggml.d.ts.map +1 -0
- package/dist/services/voice/wake-word.d.ts.map +1 -0
- package/dist/services/voice/wav-codec.d.ts +11 -0
- package/dist/services/voice/wav-codec.d.ts.map +1 -0
- package/dist/services/voice/workbench-entrypoint.d.ts +42 -0
- package/dist/services/voice/workbench-entrypoint.d.ts.map +1 -0
- package/dist/services/voice/workbench-headless-runner.d.ts +102 -0
- package/dist/services/voice/workbench-headless-runner.d.ts.map +1 -0
- package/dist/services/voice/workbench-logic-services.d.ts +36 -0
- package/dist/services/voice/workbench-logic-services.d.ts.map +1 -0
- package/dist/services/voice/workbench-real-services.d.ts +17 -0
- package/dist/services/voice/workbench-real-services.d.ts.map +1 -0
- package/dist/services/voice/workbench-scenarios.d.ts +24 -0
- package/dist/services/voice/workbench-scenarios.d.ts.map +1 -0
- package/dist/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
- package/dist/services/voice-model-updater.d.ts.map +1 -0
- package/dist/services/voice-prewarm.d.ts.map +1 -0
- package/dist/voice-workbench.d.ts +18 -0
- package/dist/voice-workbench.d.ts.map +1 -0
- package/dist/voice-workbench.js +5259 -0
- package/dist/voice-workbench.js.map +34 -0
- package/package.json +28 -9
- package/registry-entry.json +137 -0
- package/src/adapters/capacitor-llama/__tests__/voice-turn.test.ts +293 -0
- package/src/adapters/capacitor-llama/environment.ts +1 -1
- package/src/adapters/capacitor-llama/index.ts +28 -4
- package/src/adapters/capacitor-llama/native-voice-capture.ts +140 -0
- package/src/adapters/capacitor-llama/text-streaming.ts +2 -2
- package/src/adapters/capacitor-llama/voice-turn.ts +178 -0
- package/src/backends/apple-foundation.ts +1 -1
- package/src/local-inference-routes.test.ts +57 -11
- package/src/local-inference-routes.ts +90 -8
- package/src/provider.ts +32 -3
- package/src/routes/compat-helpers.ts +2 -1
- package/src/routes/index.ts +1 -0
- package/src/routes/live-diarization-route.test.ts +134 -0
- package/src/routes/live-diarization-route.ts +79 -3
- package/src/routes/local-inference-asr-route.test.ts +43 -2
- package/src/routes/local-inference-asr-route.ts +7 -4
- package/src/routes/local-inference-asr-transcribe.test.ts +4 -4
- package/src/routes/local-inference-asr-transcribe.ts +1 -1
- package/src/routes/local-inference-compat-routes.test.ts +3 -3
- package/src/routes/local-inference-compat-routes.ts +23 -56
- package/src/routes/native-pcm-turn-route.test.ts +136 -0
- package/src/routes/native-pcm-turn-route.ts +121 -0
- package/src/routes/transcripts-routes.test.ts +51 -0
- package/src/routes/transcripts-routes.ts +35 -3
- package/src/runtime/bionic-wire-encoding.test.ts +147 -0
- package/src/runtime/ensure-local-inference-handler.test.ts +203 -5
- package/src/runtime/ensure-local-inference-handler.ts +203 -11
- package/src/runtime/index.ts +4 -1
- package/src/runtime/mobile-local-inference-gate.test.ts +85 -2
- package/src/runtime/mobile-local-inference-gate.ts +60 -5
- package/src/runtime/voice-entity-binding.transcript.test.ts +29 -0
- package/src/runtime/voice-entity-binding.ts +46 -6
- package/src/runtime/voice-speaker-entity-contract.test.ts +149 -0
- package/src/services/README.md +2 -2
- package/src/services/__tests__/backend-selector.precedence.test.ts +333 -0
- package/src/services/active-model-context-fit.test.ts +125 -0
- package/src/services/active-model.ts +211 -8
- package/src/services/asr-provenance.ts +68 -0
- package/src/services/assignment-validation.test.ts +118 -0
- package/src/services/assignments.test.ts +26 -0
- package/src/services/assignments.ts +52 -4
- package/src/services/backend.test.ts +84 -0
- package/src/services/backend.ts +198 -19
- package/src/services/bionic-host-loader.test.ts +94 -1
- package/src/services/bionic-host-loader.ts +72 -0
- package/src/services/cache-bridge.test.ts +7 -7
- package/src/services/catalog.test.ts +32 -11
- package/src/services/catalog.ts +6 -0
- package/src/services/cloud-fallback.ts +1 -1
- package/src/services/context-fit.test.ts +121 -0
- package/src/services/context-fit.ts +113 -0
- package/src/services/desktop-fused-ffi-backend-runtime.ts +99 -7
- package/src/services/device-tier.test.ts +89 -2
- package/src/services/device-tier.ts +103 -11
- package/src/services/downloader.test.ts +199 -58
- package/src/services/downloader.ts +141 -27
- package/src/services/engine-direct-bundle.test.ts +38 -6
- package/src/services/engine.ts +291 -104
- package/src/services/ensure-local-artifacts.ts +1 -1
- package/src/services/ffi-llm-streaming-abi.ts +6 -3
- package/src/services/ffi-streaming-backend.ts +44 -8
- package/src/services/ffi-streaming-runner.test.ts +163 -3
- package/src/services/ffi-streaming-runner.ts +54 -1
- package/src/services/ffi-unload-ordering.test.ts +5 -1
- package/src/services/fused-eliza1-no-regression.test.ts +144 -0
- package/src/services/hardware.test.ts +7 -2
- package/src/services/hardware.ts +28 -0
- package/src/services/imagegen/backend-selector.test.ts +190 -0
- package/src/services/imagegen/sd-cpp.ts +6 -9
- package/src/services/index.ts +18 -0
- package/src/services/ios-llama-streaming.ts +1 -1
- package/src/services/kv-spill.ts +6 -5
- package/src/services/lib-target.test.ts +145 -0
- package/src/services/lib-target.ts +102 -0
- package/src/services/live-signals.test.ts +132 -0
- package/src/services/live-signals.ts +177 -0
- package/src/services/llama-server-metrics.test.ts +168 -0
- package/src/services/manifest/eliza-1.manifest.v1.json +84 -2
- package/src/services/manifest/index.ts +6 -0
- package/src/services/manifest/manifest.test.ts +156 -54
- package/src/services/manifest/schema.ts +160 -52
- package/src/services/manifest/types.ts +6 -0
- package/src/services/manifest/validator.ts +91 -25
- package/src/services/memory-arbiter.test.ts +139 -0
- package/src/services/memory-arbiter.ts +81 -15
- package/src/services/memory-benchmark.test.ts +91 -0
- package/src/services/memory-benchmark.ts +354 -0
- package/src/services/memory-monitor.test.ts +24 -0
- package/src/services/memory-monitor.ts +12 -0
- package/src/services/mtp-doctor.ts +10 -2
- package/src/services/network-policy.ts +5 -5
- package/src/services/ram-budget-cache.test.ts +2 -1
- package/src/services/ram-budget.ts +0 -0
- package/src/services/recommendation.test.ts +216 -0
- package/src/services/registry.ts +25 -19
- package/src/services/required-kernels-gate.test.ts +64 -0
- package/src/services/router-handler.ts +43 -24
- package/src/services/routing-policy.test.ts +211 -23
- package/src/services/routing-policy.ts +92 -22
- package/src/services/service.test.ts +3 -3
- package/src/services/service.ts +22 -7
- package/src/services/transcription-priority.test.ts +2 -2
- package/src/services/types.ts +4 -0
- package/src/services/verify-on-device.test.ts +2 -2
- package/src/services/vision/hash.ts +1 -1
- package/src/services/vision/index.ts +2 -2
- package/src/services/vision/llama-server.ts +1 -1
- package/src/services/vision/types.ts +13 -4
- package/src/services/vision-embedding-cache.ts +1 -1
- package/src/services/voice/VOICE_WORKBENCH.md +71 -26
- package/src/services/voice/__fixtures__/voice-workbench-logic-baseline.json +180 -0
- package/src/services/voice/__test-helpers__/synthetic-speech.ts +72 -2
- package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +29 -29
- package/src/services/voice/__tests__/streaming-asr.test.ts +1 -1
- package/src/services/voice/acoustic-speaker-attribution.test.ts +165 -0
- package/src/services/voice/acoustic-speaker-attribution.ts +336 -0
- package/src/services/voice/asr-timed.real.test.ts +6 -8
- package/src/services/voice/audio-frame-consumer.test.ts +327 -1
- package/src/services/voice/audio-frame-consumer.ts +165 -5
- package/src/services/voice/barge-in.ts +2 -3
- package/src/services/voice/corpus-augment.test.ts +276 -0
- package/src/services/voice/corpus-augment.ts +451 -0
- package/src/services/voice/corpus-generator.test.ts +201 -0
- package/src/services/voice/corpus-generator.ts +413 -0
- package/src/services/voice/diarization-error-rate.greedy.test.ts +140 -0
- package/src/services/voice/diarization-error-rate.test.ts +100 -0
- package/src/services/voice/diarization-error-rate.ts +249 -0
- package/src/services/voice/e2e-harness.der.test.ts +94 -0
- package/src/services/voice/e2e-harness.respond-eot-entity.test.ts +277 -0
- package/src/services/voice/e2e-harness.security-echo.test.ts +103 -0
- package/src/services/voice/e2e-harness.test.ts +2 -2
- package/src/services/voice/e2e-harness.ts +175 -16
- package/src/services/voice/echo-delay.test.ts +118 -0
- package/src/services/voice/echo-delay.ts +135 -0
- package/src/services/voice/echo-metrics.test.ts +17 -0
- package/src/services/voice/echo-metrics.ts +20 -0
- package/src/services/voice/echo-reference-buffer.test.ts +86 -0
- package/src/services/voice/echo-reference-buffer.ts +165 -0
- package/src/services/voice/eliza1-eot-scorer.ts +22 -22
- package/src/services/voice/embedding.ts +2 -3
- package/src/services/voice/engine-bridge-transcript-join.test.ts +278 -0
- package/src/services/voice/engine-bridge.ts +151 -110
- package/src/services/voice/eot-classifier-ggml.ts +42 -39
- package/src/services/voice/eot-classifier.test.ts +98 -0
- package/src/services/voice/eot-classifier.ts +11 -122
- package/src/services/voice/errors.ts +2 -0
- package/src/services/voice/expressive-tags.asr.test.ts +77 -0
- package/src/services/voice/expressive-tags.test.ts +102 -0
- package/src/services/voice/expressive-tags.ts +8 -8
- package/src/services/voice/ffi-bindings.test.ts +10 -3
- package/src/services/voice/ffi-bindings.ts +177 -15
- package/src/services/voice/fused-eot-scorer.ts +17 -13
- package/src/services/voice/index.ts +33 -12
- package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +112 -1
- package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +88 -3
- package/src/services/voice/kokoro/__tests__/runtime-selection.test.ts +37 -201
- package/src/services/voice/kokoro/kokoro-backend.ts +16 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.ts +1 -1
- package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +3 -3
- package/src/services/voice/kokoro/pick-runtime.ts +1 -1
- package/src/services/voice/kokoro/runtime-selection.ts +28 -201
- package/src/services/voice/live-diarization-session.echo.test.ts +232 -0
- package/src/services/voice/live-diarization-session.ts +335 -2
- package/src/services/voice/metric-math.test.ts +61 -0
- package/src/services/voice/metric-math.ts +25 -0
- package/src/services/voice/mic-source.ts +1 -1
- package/src/services/voice/nlms-echo-canceller.test.ts +244 -0
- package/src/services/voice/nlms-echo-canceller.ts +317 -0
- package/src/services/voice/optimistic-policy.power-source.test.ts +36 -0
- package/src/services/voice/partial-stabilizer.ts +1 -1
- package/src/services/voice/pipeline.ts +3 -4
- package/src/services/voice/research/VOICE_8785_ASSESSMENT.md +141 -0
- package/src/services/voice/research/VOICE_PIPELINE_RESEARCH_2026.md +117 -0
- package/src/services/voice/research/VOICE_VALIDATION_RUNBOOK.md +135 -0
- package/src/services/voice/samantha-preset-regenerator.wav.test.ts +90 -0
- package/src/services/voice/self-voice-imprint.test.ts +59 -0
- package/src/services/voice/self-voice-imprint.ts +102 -0
- package/src/services/voice/shared-resources.ts +23 -0
- package/src/services/voice/speaker/attribution-pipeline.test.ts +221 -0
- package/src/services/voice/speaker/attribution-pipeline.ts +85 -22
- package/src/services/voice/speaker/encoder-ggml.test.ts +59 -0
- package/src/services/voice/transcriber.asr-backend.test.ts +76 -0
- package/src/services/voice/transcriber.ts +4 -4
- package/src/services/voice/transcript-service.test.ts +58 -0
- package/src/services/voice/transcript-service.ts +64 -0
- package/src/services/voice/transcript-store.test.ts +36 -0
- package/src/services/voice/transcript-store.ts +32 -0
- package/src/services/voice/types.ts +7 -7
- package/src/services/voice/vad.test.ts +33 -15
- package/src/services/voice/vad.ts +25 -20
- package/src/services/voice/voice-budget.test.ts +0 -3
- package/src/services/voice/voice-budget.ts +6 -6
- package/src/services/voice/voice-duet.test.ts +1 -1
- package/src/services/voice/voice-hardening.fuzz.test.ts +116 -0
- package/src/services/voice/voice-preload-predictor.test.ts +130 -0
- package/src/services/voice/voice-preload-predictor.ts +113 -0
- package/src/services/voice/voice-preset-format.fuzz.test.ts +89 -0
- package/src/services/voice/voice-preset-format.test.ts +75 -0
- package/src/services/voice/voice-preset-format.ts +17 -4
- package/src/services/voice/voice-scenario.test.ts +159 -0
- package/src/services/voice/voice-scenario.ts +133 -7
- package/src/services/voice/voice-scenario.turn-helpers.test.ts +77 -0
- package/src/services/voice/voice-workbench-report.ts +58 -17
- package/src/services/voice/wake-word-ggml.ts +12 -13
- package/src/services/voice/wav-codec.fuzz.test.ts +59 -0
- package/src/services/voice/wav-codec.test.ts +32 -0
- package/src/services/voice/wav-codec.ts +101 -0
- package/src/services/voice/workbench-entrypoint.test.ts +55 -0
- package/src/services/voice/workbench-entrypoint.ts +88 -0
- package/src/services/voice/workbench-headless-runner.test.ts +162 -0
- package/src/services/voice/workbench-headless-runner.ts +396 -0
- package/src/services/voice/workbench-logic-services.test.ts +225 -0
- package/src/services/voice/workbench-logic-services.ts +184 -0
- package/src/services/voice/workbench-real-services.ts +629 -0
- package/src/services/voice/workbench-scenarios.ts +407 -0
- package/src/services/voice-prewarm.ts +1 -1
- package/src/voice-workbench.ts +71 -0
- package/src/actions/generate-media.d.ts.map +0 -1
- package/src/actions/identify-speaker.d.ts.map +0 -1
- package/src/actions/transcription-control.d.ts.map +0 -1
- package/src/index.d.ts.map +0 -1
- package/src/local-inference-routes.d.ts.map +0 -1
- package/src/provider.d.ts.map +0 -1
- package/src/routes/compat-helpers.d.ts.map +0 -1
- package/src/routes/family-member-route.d.ts.map +0 -1
- package/src/routes/index.d.ts.map +0 -1
- package/src/routes/live-diarization-route.d.ts.map +0 -1
- package/src/routes/local-inference-asr-route.d.ts.map +0 -1
- package/src/routes/local-inference-asr-transcribe.d.ts.map +0 -1
- package/src/routes/local-inference-compat-routes.d.ts.map +0 -1
- package/src/routes/local-inference-tts-route.d.ts.map +0 -1
- package/src/routes/transcript-audio-store.d.ts.map +0 -1
- package/src/routes/transcripts-routes.d.ts.map +0 -1
- package/src/routes/voice-first-run-routes.d.ts.map +0 -1
- package/src/routes/voice-models-routes.d.ts.map +0 -1
- package/src/routes/voice-profile-plugin-routes.d.ts.map +0 -1
- package/src/routes/voice-profiles-management-routes.d.ts.map +0 -1
- package/src/routes/voice-speaker-profile-routes.d.ts.map +0 -1
- package/src/runtime/embedding-manager-support.d.ts.map +0 -1
- package/src/runtime/embedding-presets.d.ts.map +0 -1
- package/src/runtime/embedding-warmup-policy.d.ts.map +0 -1
- package/src/runtime/ensure-local-inference-handler.d.ts.map +0 -1
- package/src/runtime/index.d.ts.map +0 -1
- package/src/runtime/mobile-local-inference-gate.d.ts +0 -31
- package/src/runtime/mobile-local-inference-gate.d.ts.map +0 -1
- package/src/runtime/voice-entity-binding.d.ts.map +0 -1
- package/src/services/active-model.d.ts.map +0 -1
- package/src/services/assignments.d.ts.map +0 -1
- package/src/services/backend.d.ts.map +0 -1
- package/src/services/bionic-host-loader.d.ts.map +0 -1
- package/src/services/bundled-models.d.ts.map +0 -1
- package/src/services/cache-bridge.d.ts.map +0 -1
- package/src/services/catalog.d.ts +0 -10
- package/src/services/catalog.d.ts.map +0 -1
- package/src/services/checkpoint-client.d.ts.map +0 -1
- package/src/services/cloud-fallback.d.ts.map +0 -1
- package/src/services/conversation-registry.d.ts.map +0 -1
- package/src/services/desktop-fused-ffi-backend-runtime.d.ts.map +0 -1
- package/src/services/device-bridge.d.ts.map +0 -1
- package/src/services/device-resource-metrics.d.ts.map +0 -1
- package/src/services/device-tier.d.ts.map +0 -1
- package/src/services/downloader.d.ts.map +0 -1
- package/src/services/engine.d.ts.map +0 -1
- package/src/services/external-scanner.d.ts.map +0 -1
- package/src/services/ffi-streaming-backend.d.ts.map +0 -1
- package/src/services/ffi-streaming-runner.d.ts.map +0 -1
- package/src/services/gpu-detect.d.ts.map +0 -1
- package/src/services/handler-registry.d.ts.map +0 -1
- package/src/services/hardware.d.ts.map +0 -1
- package/src/services/hf-search.d.ts +0 -26
- package/src/services/hf-search.d.ts.map +0 -1
- package/src/services/hf-search.test.ts +0 -69
- package/src/services/hf-search.ts +0 -420
- package/src/services/image-description-runtime.d.ts.map +0 -1
- package/src/services/imagegen/aosp-unavailable.d.ts.map +0 -1
- package/src/services/imagegen/backend-selector.d.ts.map +0 -1
- package/src/services/imagegen/coreml-unavailable.d.ts.map +0 -1
- package/src/services/imagegen/errors.d.ts.map +0 -1
- package/src/services/imagegen/index.d.ts.map +0 -1
- package/src/services/imagegen/mflux.d.ts.map +0 -1
- package/src/services/imagegen/sd-cpp.d.ts.map +0 -1
- package/src/services/imagegen/tensorrt-unavailable.d.ts.map +0 -1
- package/src/services/imagegen/types.d.ts.map +0 -1
- package/src/services/index.d.ts.map +0 -1
- package/src/services/inference-capabilities.d.ts.map +0 -1
- package/src/services/inference-telemetry.d.ts.map +0 -1
- package/src/services/kv-spill.d.ts.map +0 -1
- package/src/services/latency-trace.d.ts.map +0 -1
- package/src/services/llm-streaming-binding.d.ts.map +0 -1
- package/src/services/load-args.d.ts.map +0 -1
- package/src/services/manifest/index.d.ts +0 -4
- package/src/services/manifest/index.d.ts.map +0 -1
- package/src/services/manifest/schema.d.ts.map +0 -1
- package/src/services/manifest/types.d.ts.map +0 -1
- package/src/services/manifest/validator.d.ts.map +0 -1
- package/src/services/memory-arbiter.d.ts.map +0 -1
- package/src/services/memory-monitor.d.ts.map +0 -1
- package/src/services/memory-pressure.d.ts.map +0 -1
- package/src/services/mtp-doctor.d.ts.map +0 -1
- package/src/services/network-policy.d.ts.map +0 -1
- package/src/services/paths.d.ts.map +0 -1
- package/src/services/planner-skeleton.d.ts.map +0 -1
- package/src/services/providers.d.ts.map +0 -1
- package/src/services/ram-budget.d.ts.map +0 -1
- package/src/services/readiness.d.ts.map +0 -1
- package/src/services/recommendation.d.ts.map +0 -1
- package/src/services/registry.d.ts.map +0 -1
- package/src/services/router-handler.d.ts.map +0 -1
- package/src/services/routing-policy.d.ts.map +0 -1
- package/src/services/routing-preferences.d.ts.map +0 -1
- package/src/services/runtime-target.d.ts.map +0 -1
- package/src/services/service.d.ts.map +0 -1
- package/src/services/session-pool.d.ts.map +0 -1
- package/src/services/structured-output/deterministic-repair.d.ts.map +0 -1
- package/src/services/structured-output.d.ts.map +0 -1
- package/src/services/system-memory.d.ts.map +0 -1
- package/src/services/types.d.ts.map +0 -1
- package/src/services/verify-on-device.d.ts.map +0 -1
- package/src/services/verify.d.ts.map +0 -1
- package/src/services/vision/aosp-unavailable.d.ts.map +0 -1
- package/src/services/vision/capacitor-llama.d.ts.map +0 -1
- package/src/services/vision/cloud-fallback.d.ts.map +0 -1
- package/src/services/vision/hash.d.ts.map +0 -1
- package/src/services/vision/index.d.ts.map +0 -1
- package/src/services/vision/llama-server.d.ts.map +0 -1
- package/src/services/vision/types.d.ts.map +0 -1
- package/src/services/vision/vast-fallback.d.ts.map +0 -1
- package/src/services/vision-embedding-cache.d.ts.map +0 -1
- package/src/services/voice/audio-frame-consumer.d.ts.map +0 -1
- package/src/services/voice/barge-in.d.ts.map +0 -1
- package/src/services/voice/cancellation-coordinator.d.ts.map +0 -1
- package/src/services/voice/checkpoint-manager.d.ts.map +0 -1
- package/src/services/voice/eager-context-builder.d.ts.map +0 -1
- package/src/services/voice/eliza1-eot-scorer.d.ts.map +0 -1
- package/src/services/voice/embedding.d.ts.map +0 -1
- package/src/services/voice/emotion-attribution.d.ts.map +0 -1
- package/src/services/voice/engine-bridge.d.ts.map +0 -1
- package/src/services/voice/eot-classifier-ggml.d.ts.map +0 -1
- package/src/services/voice/eot-classifier.d.ts.map +0 -1
- package/src/services/voice/errors.d.ts.map +0 -1
- package/src/services/voice/expressive-tags.d.ts.map +0 -1
- package/src/services/voice/ffi-bindings.d.ts.map +0 -1
- package/src/services/voice/first-line-cache.d.ts.map +0 -1
- package/src/services/voice/fused-eot-scorer.d.ts.map +0 -1
- package/src/services/voice/index.d.ts.map +0 -1
- package/src/services/voice/kokoro/kokoro-backend.d.ts.map +0 -1
- package/src/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +0 -1
- package/src/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +0 -1
- package/src/services/voice/kokoro/kokoro-runtime.d.ts.map +0 -1
- package/src/services/voice/kokoro/phonemizer.d.ts.map +0 -1
- package/src/services/voice/kokoro/pick-runtime.d.ts.map +0 -1
- package/src/services/voice/kokoro/runtime-selection.d.ts +0 -92
- package/src/services/voice/kokoro/runtime-selection.d.ts.map +0 -1
- package/src/services/voice/kokoro/types.d.ts.map +0 -1
- package/src/services/voice/kokoro/voice-presets.d.ts.map +0 -1
- package/src/services/voice/kokoro/voices.d.ts.map +0 -1
- package/src/services/voice/lifecycle.d.ts.map +0 -1
- package/src/services/voice/live-diarization-session.d.ts +0 -96
- package/src/services/voice/live-diarization-session.d.ts.map +0 -1
- package/src/services/voice/mic-source.d.ts.map +0 -1
- package/src/services/voice/optimistic-policy.d.ts.map +0 -1
- package/src/services/voice/partial-stabilizer.d.ts.map +0 -1
- package/src/services/voice/phoneme-tokenizer.d.ts.map +0 -1
- package/src/services/voice/phrase-cache.d.ts.map +0 -1
- package/src/services/voice/phrase-chunker.d.ts.map +0 -1
- package/src/services/voice/pipeline-impls.d.ts.map +0 -1
- package/src/services/voice/pipeline.d.ts.map +0 -1
- package/src/services/voice/prefill-client.d.ts.map +0 -1
- package/src/services/voice/prefix-preserving-queue.d.ts.map +0 -1
- package/src/services/voice/profile-store.d.ts.map +0 -1
- package/src/services/voice/ring-buffer.d.ts.map +0 -1
- package/src/services/voice/rollback-queue.d.ts.map +0 -1
- package/src/services/voice/samantha-preset-placeholder.d.ts.map +0 -1
- package/src/services/voice/samantha-preset-regenerator.d.ts.map +0 -1
- package/src/services/voice/scheduler.d.ts.map +0 -1
- package/src/services/voice/shared-resources.d.ts.map +0 -1
- package/src/services/voice/speaker/attribution-pipeline.d.ts.map +0 -1
- package/src/services/voice/speaker/diarizer-fused.d.ts.map +0 -1
- package/src/services/voice/speaker/diarizer.d.ts.map +0 -1
- package/src/services/voice/speaker/encoder-fused.d.ts.map +0 -1
- package/src/services/voice/speaker/encoder-ggml.d.ts.map +0 -1
- package/src/services/voice/speaker/encoder.d.ts.map +0 -1
- package/src/services/voice/speaker-imprint.d.ts.map +0 -1
- package/src/services/voice/speaker-preset-cache.d.ts.map +0 -1
- package/src/services/voice/system-audio-sink.d.ts.map +0 -1
- package/src/services/voice/transcriber.d.ts.map +0 -1
- package/src/services/voice/transcript-knowledge.d.ts.map +0 -1
- package/src/services/voice/transcript-service.d.ts.map +0 -1
- package/src/services/voice/transcript-store.d.ts.map +0 -1
- package/src/services/voice/turn-controller.d.ts.map +0 -1
- package/src/services/voice/types.d.ts.map +0 -1
- package/src/services/voice/vad.d.ts.map +0 -1
- package/src/services/voice/voice-budget.d.ts.map +0 -1
- package/src/services/voice/voice-emotion-classifier.d.ts.map +0 -1
- package/src/services/voice/voice-preset-format.d.ts.map +0 -1
- package/src/services/voice/voice-profile-artifact.d.ts.map +0 -1
- package/src/services/voice/voice-profile-routes.d.ts.map +0 -1
- package/src/services/voice/voice-settings.d.ts +0 -82
- package/src/services/voice/voice-settings.d.ts.map +0 -1
- package/src/services/voice/voice-settings.ts +0 -172
- package/src/services/voice/voice-state-machine.d.ts.map +0 -1
- package/src/services/voice/wake-word-ggml.d.ts.map +0 -1
- package/src/services/voice/wake-word.d.ts.map +0 -1
- package/src/services/voice/wrap-with-first-line-cache.d.ts.map +0 -1
- package/src/services/voice-model-updater.d.ts.map +0 -1
- package/src/services/voice-prewarm.d.ts.map +0 -1
- /package/{src → dist}/actions/generate-media.d.ts +0 -0
- /package/{src → dist}/actions/identify-speaker.d.ts +0 -0
- /package/{src → dist}/actions/transcription-control.d.ts +0 -0
- /package/{src → dist}/index.d.ts +0 -0
- /package/{src → dist}/provider.d.ts +0 -0
- /package/{src → dist}/routes/family-member-route.d.ts +0 -0
- /package/{src → dist}/routes/local-inference-asr-route.d.ts +0 -0
- /package/{src → dist}/routes/local-inference-asr-transcribe.d.ts +0 -0
- /package/{src → dist}/routes/local-inference-compat-routes.d.ts +0 -0
- /package/{src → dist}/routes/local-inference-tts-route.d.ts +0 -0
- /package/{src → dist}/routes/transcript-audio-store.d.ts +0 -0
- /package/{src → dist}/routes/voice-first-run-routes.d.ts +0 -0
- /package/{src → dist}/routes/voice-models-routes.d.ts +0 -0
- /package/{src → dist}/routes/voice-profile-plugin-routes.d.ts +0 -0
- /package/{src → dist}/routes/voice-profiles-management-routes.d.ts +0 -0
- /package/{src → dist}/routes/voice-speaker-profile-routes.d.ts +0 -0
- /package/{src → dist}/runtime/embedding-manager-support.d.ts +0 -0
- /package/{src → dist}/runtime/embedding-presets.d.ts +0 -0
- /package/{src → dist}/runtime/embedding-warmup-policy.d.ts +0 -0
- /package/{src → dist}/services/bundled-models.d.ts +0 -0
- /package/{src → dist}/services/cache-bridge.d.ts +0 -0
- /package/{src → dist}/services/checkpoint-client.d.ts +0 -0
- /package/{src → dist}/services/cloud-fallback.d.ts +0 -0
- /package/{src → dist}/services/conversation-registry.d.ts +0 -0
- /package/{src → dist}/services/device-bridge.d.ts +0 -0
- /package/{src → dist}/services/device-resource-metrics.d.ts +0 -0
- /package/{src → dist}/services/external-scanner.d.ts +0 -0
- /package/{src → dist}/services/gpu-detect.d.ts +0 -0
- /package/{src → dist}/services/handler-registry.d.ts +0 -0
- /package/{src → dist}/services/hardware.d.ts +0 -0
- /package/{src → dist}/services/image-description-runtime.d.ts +0 -0
- /package/{src → dist}/services/imagegen/aosp-unavailable.d.ts +0 -0
- /package/{src → dist}/services/imagegen/backend-selector.d.ts +0 -0
- /package/{src → dist}/services/imagegen/coreml-unavailable.d.ts +0 -0
- /package/{src → dist}/services/imagegen/errors.d.ts +0 -0
- /package/{src → dist}/services/imagegen/index.d.ts +0 -0
- /package/{src → dist}/services/imagegen/mflux.d.ts +0 -0
- /package/{src → dist}/services/imagegen/tensorrt-unavailable.d.ts +0 -0
- /package/{src → dist}/services/imagegen/types.d.ts +0 -0
- /package/{src → dist}/services/inference-capabilities.d.ts +0 -0
- /package/{src → dist}/services/inference-telemetry.d.ts +0 -0
- /package/{src → dist}/services/kv-spill.d.ts +0 -0
- /package/{src → dist}/services/latency-trace.d.ts +0 -0
- /package/{src → dist}/services/llm-streaming-binding.d.ts +0 -0
- /package/{src → dist}/services/load-args.d.ts +0 -0
- /package/{src → dist}/services/manifest/validator.d.ts +0 -0
- /package/{src → dist}/services/memory-pressure.d.ts +0 -0
- /package/{src → dist}/services/mtp-doctor.d.ts +0 -0
- /package/{src → dist}/services/network-policy.d.ts +0 -0
- /package/{src → dist}/services/paths.d.ts +0 -0
- /package/{src → dist}/services/planner-skeleton.d.ts +0 -0
- /package/{src → dist}/services/providers.d.ts +0 -0
- /package/{src → dist}/services/ram-budget.d.ts +0 -0
- /package/{src → dist}/services/readiness.d.ts +0 -0
- /package/{src → dist}/services/recommendation.d.ts +0 -0
- /package/{src → dist}/services/routing-preferences.d.ts +0 -0
- /package/{src → dist}/services/runtime-target.d.ts +0 -0
- /package/{src → dist}/services/session-pool.d.ts +0 -0
- /package/{src → dist}/services/structured-output/deterministic-repair.d.ts +0 -0
- /package/{src → dist}/services/structured-output.d.ts +0 -0
- /package/{src → dist}/services/system-memory.d.ts +0 -0
- /package/{src → dist}/services/verify-on-device.d.ts +0 -0
- /package/{src → dist}/services/verify.d.ts +0 -0
- /package/{src → dist}/services/vision/aosp-unavailable.d.ts +0 -0
- /package/{src → dist}/services/vision/capacitor-llama.d.ts +0 -0
- /package/{src → dist}/services/vision/cloud-fallback.d.ts +0 -0
- /package/{src → dist}/services/vision/hash.d.ts +0 -0
- /package/{src → dist}/services/vision/llama-server.d.ts +0 -0
- /package/{src → dist}/services/vision/vast-fallback.d.ts +0 -0
- /package/{src → dist}/services/voice/barge-in.d.ts +0 -0
- /package/{src → dist}/services/voice/cancellation-coordinator.d.ts +0 -0
- /package/{src → dist}/services/voice/checkpoint-manager.d.ts +0 -0
- /package/{src → dist}/services/voice/eager-context-builder.d.ts +0 -0
- /package/{src → dist}/services/voice/emotion-attribution.d.ts +0 -0
- /package/{src → dist}/services/voice/first-line-cache.d.ts +0 -0
- /package/{src → dist}/services/voice/kokoro/kokoro-runtime.d.ts +0 -0
- /package/{src → dist}/services/voice/kokoro/phonemizer.d.ts +0 -0
- /package/{src → dist}/services/voice/kokoro/types.d.ts +0 -0
- /package/{src → dist}/services/voice/kokoro/voice-presets.d.ts +0 -0
- /package/{src → dist}/services/voice/kokoro/voices.d.ts +0 -0
- /package/{src → dist}/services/voice/lifecycle.d.ts +0 -0
- /package/{src → dist}/services/voice/optimistic-policy.d.ts +0 -0
- /package/{src → dist}/services/voice/phoneme-tokenizer.d.ts +0 -0
- /package/{src → dist}/services/voice/phrase-cache.d.ts +0 -0
- /package/{src → dist}/services/voice/phrase-chunker.d.ts +0 -0
- /package/{src → dist}/services/voice/pipeline-impls.d.ts +0 -0
- /package/{src → dist}/services/voice/pipeline.d.ts +0 -0
- /package/{src → dist}/services/voice/prefill-client.d.ts +0 -0
- /package/{src → dist}/services/voice/prefix-preserving-queue.d.ts +0 -0
- /package/{src → dist}/services/voice/profile-store.d.ts +0 -0
- /package/{src → dist}/services/voice/ring-buffer.d.ts +0 -0
- /package/{src → dist}/services/voice/rollback-queue.d.ts +0 -0
- /package/{src → dist}/services/voice/samantha-preset-placeholder.d.ts +0 -0
- /package/{src → dist}/services/voice/samantha-preset-regenerator.d.ts +0 -0
- /package/{src → dist}/services/voice/scheduler.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker/attribution-pipeline.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker/diarizer-fused.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker/diarizer.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker/encoder-fused.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker/encoder-ggml.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker/encoder.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker-imprint.d.ts +0 -0
- /package/{src → dist}/services/voice/speaker-preset-cache.d.ts +0 -0
- /package/{src → dist}/services/voice/system-audio-sink.d.ts +0 -0
- /package/{src → dist}/services/voice/transcript-knowledge.d.ts +0 -0
- /package/{src → dist}/services/voice/turn-controller.d.ts +0 -0
- /package/{src → dist}/services/voice/voice-budget.d.ts +0 -0
- /package/{src → dist}/services/voice/voice-emotion-classifier.d.ts +0 -0
- /package/{src → dist}/services/voice/voice-profile-artifact.d.ts +0 -0
- /package/{src → dist}/services/voice/voice-profile-routes.d.ts +0 -0
- /package/{src → dist}/services/voice/voice-state-machine.d.ts +0 -0
- /package/{src → dist}/services/voice/wake-word.d.ts +0 -0
- /package/{src → dist}/services/voice/wrap-with-first-line-cache.d.ts +0 -0
- /package/{src → dist}/services/voice-model-updater.d.ts +0 -0
- /package/{src → dist}/services/voice-prewarm.d.ts +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { EchoReferenceBuffer } from "./echo-reference-buffer.ts";
|
|
3
|
+
|
|
4
|
+
/** Ramp where sample i has value i+1 (so 0 = "not filled"). */
|
|
5
|
+
function ramp(from: number, count: number): Float32Array {
|
|
6
|
+
const out = new Float32Array(count);
|
|
7
|
+
for (let i = 0; i < count; i++) out[i] = from + i + 1;
|
|
8
|
+
return out;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe("EchoReferenceBuffer (#9583)", () => {
|
|
12
|
+
it("returns the last `length` samples at zero delay", () => {
|
|
13
|
+
const buf = new EchoReferenceBuffer({ capacitySamples: 1000 });
|
|
14
|
+
buf.push(ramp(0, 500)); // values 1..500
|
|
15
|
+
const ref = buf.referenceFor(4, 0);
|
|
16
|
+
expect(Array.from(ref)).toEqual([497, 498, 499, 500]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("shifts the window back by the delay", () => {
|
|
20
|
+
const buf = new EchoReferenceBuffer({ capacitySamples: 1000 });
|
|
21
|
+
buf.push(ramp(0, 500)); // values 1..500
|
|
22
|
+
// delay 10 → window ends at sample (500-10)=490 → [487,488,489,490]
|
|
23
|
+
expect(Array.from(buf.referenceFor(4, 10))).toEqual([487, 488, 489, 490]);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("zero-fills samples not yet pushed (delay+length exceeds stream)", () => {
|
|
27
|
+
const buf = new EchoReferenceBuffer({ capacitySamples: 1000 });
|
|
28
|
+
buf.push(ramp(0, 3)); // values 1,2,3
|
|
29
|
+
// length 5, delay 0 → window [-2,3): two leading zeros then 1,2,3
|
|
30
|
+
expect(Array.from(buf.referenceFor(5, 0))).toEqual([0, 0, 1, 2, 3]);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("zero-fills the part evicted past capacity", () => {
|
|
34
|
+
const buf = new EchoReferenceBuffer({ capacitySamples: 8 });
|
|
35
|
+
buf.push(ramp(0, 12)); // values 1..12; only the last 8 (5..12) retained
|
|
36
|
+
// delay 0, length 8 → the retained window is values 5..12
|
|
37
|
+
expect(Array.from(buf.referenceFor(8, 0))).toEqual([
|
|
38
|
+
5, 6, 7, 8, 9, 10, 11, 12,
|
|
39
|
+
]);
|
|
40
|
+
// Asking for 10 reaches before the retained window → 2 leading zeros.
|
|
41
|
+
expect(Array.from(buf.referenceFor(10, 0))).toEqual([
|
|
42
|
+
0, 0, 5, 6, 7, 8, 9, 10, 11, 12,
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("accumulates across multiple pushes and tracks position", () => {
|
|
47
|
+
const buf = new EchoReferenceBuffer({ capacitySamples: 1000 });
|
|
48
|
+
buf.push(ramp(0, 100));
|
|
49
|
+
buf.push(ramp(100, 100)); // values 101..200, position now 200
|
|
50
|
+
expect(buf.position).toBe(200);
|
|
51
|
+
expect(Array.from(buf.referenceFor(3, 0))).toEqual([198, 199, 200]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("reset clears the buffer", () => {
|
|
55
|
+
const buf = new EchoReferenceBuffer({ capacitySamples: 1000 });
|
|
56
|
+
buf.push(ramp(0, 50));
|
|
57
|
+
buf.reset();
|
|
58
|
+
expect(buf.position).toBe(0);
|
|
59
|
+
expect(Array.from(buf.referenceFor(3, 0))).toEqual([0, 0, 0]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("preserves timestamp gaps between playback bursts", () => {
|
|
63
|
+
const buf = new EchoReferenceBuffer({
|
|
64
|
+
capacitySamples: 4000,
|
|
65
|
+
sampleRateHz: 16_000,
|
|
66
|
+
});
|
|
67
|
+
buf.pushAt(1000, ramp(0, 4)); // samples 0..3
|
|
68
|
+
buf.pushAt(1100, ramp(100, 4)); // samples 1600..1603
|
|
69
|
+
|
|
70
|
+
expect(Array.from(buf.referenceAt(1000, 4, 0))).toEqual([1, 2, 3, 4]);
|
|
71
|
+
expect(Array.from(buf.referenceAt(1050, 4, 0))).toEqual([0, 0, 0, 0]);
|
|
72
|
+
expect(Array.from(buf.referenceAt(1100, 4, 0))).toEqual([
|
|
73
|
+
101, 102, 103, 104,
|
|
74
|
+
]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("applies delay to timestamp-aligned reads", () => {
|
|
78
|
+
const buf = new EchoReferenceBuffer({
|
|
79
|
+
capacitySamples: 1000,
|
|
80
|
+
sampleRateHz: 16_000,
|
|
81
|
+
});
|
|
82
|
+
buf.pushAt(0, ramp(0, 10));
|
|
83
|
+
|
|
84
|
+
expect(Array.from(buf.referenceAt(0.25, 4, 2))).toEqual([3, 4, 5, 6]);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Echo-reference alignment buffer (#9583, follow-up to #9455/#9586).
|
|
3
|
+
*
|
|
4
|
+
* The NLMS echo canceller's `process(nearEnd, farEnd)` needs the far-end
|
|
5
|
+
* (the agent's TTS playback) **time-aligned** to the current mic frame: the
|
|
6
|
+
* echo in `nearEnd[t]` is the room-filtered playback from `t − delay`, where
|
|
7
|
+
* `delay` is the bulk playback→mic transport delay (estimated by
|
|
8
|
+
* {@link estimateEchoDelaySamples} in `echo-delay.ts`).
|
|
9
|
+
*
|
|
10
|
+
* The caller renders playback PCM in real time and `push()`es it here as it goes;
|
|
11
|
+
* per mic frame it then asks for the aligned far-end slice. This is the
|
|
12
|
+
* "caller must supply the reference" primitive the consumer seam was missing —
|
|
13
|
+
* a fixed-capacity delay line, pure logic (no FFI, no device, no audio I/O).
|
|
14
|
+
* Samples not yet rendered, or already evicted past capacity, are zero-filled
|
|
15
|
+
* (no echo reference ⇒ the adaptive filter simply has nothing to cancel there).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export interface EchoReferenceBufferOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Ring-buffer capacity in samples. Must comfortably exceed
|
|
21
|
+
* `maxDelaySamples + frameLength`. Default 24000 (1.5 s @ 16 kHz).
|
|
22
|
+
*/
|
|
23
|
+
capacitySamples?: number;
|
|
24
|
+
/** Sample rate for timestamp-based push/read helpers. Default 16000. */
|
|
25
|
+
sampleRateHz?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class EchoReferenceBuffer {
|
|
29
|
+
private readonly buffer: Float32Array;
|
|
30
|
+
private readonly valid: Uint8Array;
|
|
31
|
+
private readonly capacity: number;
|
|
32
|
+
private readonly sampleRateHz: number;
|
|
33
|
+
/** Total samples ever pushed (monotonic); the logical "now" cursor. */
|
|
34
|
+
private pushed = 0;
|
|
35
|
+
/** Timestamp mapped to absolute sample 0 for timestamp-aware playback. */
|
|
36
|
+
private originMs: number | null = null;
|
|
37
|
+
|
|
38
|
+
constructor(options: EchoReferenceBufferOptions = {}) {
|
|
39
|
+
this.capacity = Math.max(1, Math.floor(options.capacitySamples ?? 24000));
|
|
40
|
+
this.sampleRateHz = Math.max(1, Math.floor(options.sampleRateHz ?? 16_000));
|
|
41
|
+
this.buffer = new Float32Array(this.capacity);
|
|
42
|
+
this.valid = new Uint8Array(this.capacity);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Append rendered playback (far-end) PCM as it is produced. */
|
|
46
|
+
push(playback: Float32Array): void {
|
|
47
|
+
this.writeAt(this.pushed, playback);
|
|
48
|
+
this.pushed += playback.length;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Store rendered playback at its capture/render timestamp. This preserves
|
|
53
|
+
* real gaps between playback bursts instead of treating chunks as contiguous.
|
|
54
|
+
*/
|
|
55
|
+
pushAt(timestampMs: number, playback: Float32Array): void {
|
|
56
|
+
if (!Number.isFinite(timestampMs)) {
|
|
57
|
+
this.push(playback);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (this.originMs === null) this.originMs = timestampMs;
|
|
61
|
+
let start = this.sampleIndexFor(timestampMs);
|
|
62
|
+
if (start < 0) {
|
|
63
|
+
this.reset();
|
|
64
|
+
this.originMs = timestampMs;
|
|
65
|
+
start = 0;
|
|
66
|
+
}
|
|
67
|
+
this.writeAt(start, playback);
|
|
68
|
+
this.pushed = Math.max(this.pushed, start + playback.length);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The far-end reference frame aligned to a mic frame of `length` samples
|
|
73
|
+
* captured `delaySamples` after the corresponding playback. Returns the
|
|
74
|
+
* playback window `[pushed − delaySamples − length, pushed − delaySamples)`.
|
|
75
|
+
* Indices before the retained window (not yet pushed, or evicted past
|
|
76
|
+
* capacity) are zero-filled.
|
|
77
|
+
*/
|
|
78
|
+
referenceFor(length: number, delaySamples: number): Float32Array {
|
|
79
|
+
const out = new Float32Array(Math.max(0, Math.floor(length)));
|
|
80
|
+
const delay = Math.max(0, Math.floor(delaySamples));
|
|
81
|
+
// Absolute index (in the monotonic stream) of the first output sample.
|
|
82
|
+
const start = this.pushed - delay - out.length;
|
|
83
|
+
return this.readWindow(start, out.length);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Reference aligned to a mic frame starting at `timestampMs`.
|
|
88
|
+
* Returns playback `[timestampMs - delay, timestampMs - delay + length)`.
|
|
89
|
+
*/
|
|
90
|
+
referenceAt(
|
|
91
|
+
timestampMs: number,
|
|
92
|
+
length: number,
|
|
93
|
+
delaySamples: number,
|
|
94
|
+
): Float32Array {
|
|
95
|
+
const outLength = Math.max(0, Math.floor(length));
|
|
96
|
+
if (this.originMs === null || !Number.isFinite(timestampMs)) {
|
|
97
|
+
return new Float32Array(outLength);
|
|
98
|
+
}
|
|
99
|
+
const delay = Math.max(0, Math.floor(delaySamples));
|
|
100
|
+
const start = this.sampleIndexFor(timestampMs) - delay;
|
|
101
|
+
return this.readWindow(start, outLength);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Samples pushed so far (the monotonic stream position). */
|
|
105
|
+
get position(): number {
|
|
106
|
+
return this.pushed;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Drop all buffered playback (e.g. on a new turn / barge-in flush). */
|
|
110
|
+
reset(): void {
|
|
111
|
+
this.buffer.fill(0);
|
|
112
|
+
this.valid.fill(0);
|
|
113
|
+
this.pushed = 0;
|
|
114
|
+
this.originMs = null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private sampleIndexFor(timestampMs: number): number {
|
|
118
|
+
if (this.originMs === null) return 0;
|
|
119
|
+
return Math.round(
|
|
120
|
+
((timestampMs - this.originMs) / 1000) * this.sampleRateHz,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private writeAt(start: number, playback: Float32Array): void {
|
|
125
|
+
const safeStart = Math.max(0, Math.floor(start));
|
|
126
|
+
const end = safeStart + playback.length;
|
|
127
|
+
if (safeStart > this.pushed) this.clearRange(this.pushed, safeStart);
|
|
128
|
+
const oldest = Math.max(0, this.pushed - this.capacity);
|
|
129
|
+
if (end <= oldest) return;
|
|
130
|
+
for (let i = 0; i < playback.length; i++) {
|
|
131
|
+
const abs = safeStart + i;
|
|
132
|
+
if (abs < oldest) continue;
|
|
133
|
+
const slot = abs % this.capacity;
|
|
134
|
+
this.buffer[slot] = playback[i] ?? 0;
|
|
135
|
+
this.valid[slot] = 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private clearRange(from: number, to: number): void {
|
|
140
|
+
if (to <= from) return;
|
|
141
|
+
if (to - from >= this.capacity) {
|
|
142
|
+
this.buffer.fill(0);
|
|
143
|
+
this.valid.fill(0);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
for (let abs = Math.max(0, Math.floor(from)); abs < to; abs++) {
|
|
147
|
+
const slot = abs % this.capacity;
|
|
148
|
+
this.buffer[slot] = 0;
|
|
149
|
+
this.valid[slot] = 0;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private readWindow(start: number, length: number): Float32Array {
|
|
154
|
+
const out = new Float32Array(length);
|
|
155
|
+
const oldest = Math.max(0, this.pushed - this.capacity);
|
|
156
|
+
for (let i = 0; i < out.length; i++) {
|
|
157
|
+
const abs = start + i;
|
|
158
|
+
if (abs >= oldest && abs >= 0 && abs < this.pushed) {
|
|
159
|
+
const slot = abs % this.capacity;
|
|
160
|
+
if (this.valid[slot] === 1) out[i] = this.buffer[slot];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Eliza-1 EOT scorer — reuses the already-loaded text model to compute
|
|
3
|
-
* P(
|
|
3
|
+
* P(`<end_of_turn>` next | conversation_so_far) without shipping a separate
|
|
4
4
|
* detector ONNX.
|
|
5
5
|
*
|
|
6
6
|
* The runtime keeps a `LlamaModel` resident for chat generation. Voice
|
|
7
|
-
* EOT scoring is a single forward pass over the formatted
|
|
8
|
-
* prompt with the trailing
|
|
7
|
+
* EOT scoring is a single forward pass over the formatted Gemma chat
|
|
8
|
+
* prompt with the trailing `<end_of_turn>` removed. `capacitor-llama`'s
|
|
9
9
|
* `LlamaContextSequence.controlledEvaluate()` returns the next-token
|
|
10
10
|
* probability distribution, so we simply read the entry for the
|
|
11
|
-
*
|
|
11
|
+
* `<end_of_turn>` token id — no sampling loop, no KV-cache growth on the
|
|
12
12
|
* chat session.
|
|
13
13
|
*
|
|
14
14
|
* A dedicated `LlamaContext` is held just for this scorer so we do not
|
|
@@ -70,8 +70,8 @@ export interface ControlledEvaluateOutputLike {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
const
|
|
74
|
-
const
|
|
73
|
+
const END_OF_TURN_TOKEN = "<end_of_turn>";
|
|
74
|
+
const START_OF_TURN_USER_PREFIX = "<start_of_turn>user\n";
|
|
75
75
|
|
|
76
76
|
export interface Eliza1EotScorerOptions {
|
|
77
77
|
/** The already-loaded text model (eliza-1 drafter). */
|
|
@@ -89,7 +89,7 @@ export interface Eliza1EotScorerOptions {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
export interface Eliza1EotScoreResult {
|
|
92
|
-
/** Probability of
|
|
92
|
+
/** Probability of `<end_of_turn>` as the next token, ∈ [0, 1]. */
|
|
93
93
|
probability: number;
|
|
94
94
|
/** Wall-clock model latency for this scoring call. */
|
|
95
95
|
latencyMs: number;
|
|
@@ -112,7 +112,7 @@ export class Eliza1EotScorer {
|
|
|
112
112
|
|
|
113
113
|
private context: LlamaContextLike | null = null;
|
|
114
114
|
private sequence: LlamaContextSequenceLike | null = null;
|
|
115
|
-
private
|
|
115
|
+
private endOfTurnTokenId: number | null = null;
|
|
116
116
|
private initPromise: Promise<void> | null = null;
|
|
117
117
|
/** Serializes concurrent calls — controlledEvaluate is not thread-safe per-sequence. */
|
|
118
118
|
private inflight: Promise<unknown> = Promise.resolve();
|
|
@@ -133,15 +133,15 @@ export class Eliza1EotScorer {
|
|
|
133
133
|
async score(partialTranscript: string): Promise<Eliza1EotScoreResult> {
|
|
134
134
|
await this.ensureReady();
|
|
135
135
|
const sequence = this.sequence;
|
|
136
|
-
const
|
|
137
|
-
if (!sequence ||
|
|
136
|
+
const endOfTurnId = this.endOfTurnTokenId;
|
|
137
|
+
if (!sequence || endOfTurnId === null) {
|
|
138
138
|
throw new Error("[voice] Eliza1EotScorer not initialized.");
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
const tokens = this.tokenizePrompt(partialTranscript);
|
|
142
142
|
const start = performance.now();
|
|
143
143
|
const next = this.inflight.then(() =>
|
|
144
|
-
this.runOnce(sequence, tokens,
|
|
144
|
+
this.runOnce(sequence, tokens, endOfTurnId),
|
|
145
145
|
);
|
|
146
146
|
this.inflight = next.catch(() => undefined);
|
|
147
147
|
const probability = await next;
|
|
@@ -156,25 +156,25 @@ export class Eliza1EotScorer {
|
|
|
156
156
|
const ctx = this.context;
|
|
157
157
|
this.context = null;
|
|
158
158
|
this.sequence = null;
|
|
159
|
-
this.
|
|
159
|
+
this.endOfTurnTokenId = null;
|
|
160
160
|
this.initPromise = null;
|
|
161
161
|
if (ctx) await ctx.dispose();
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
private async ensureReady(): Promise<void> {
|
|
165
|
-
if (this.context && this.sequence && this.
|
|
165
|
+
if (this.context && this.sequence && this.endOfTurnTokenId !== null) return;
|
|
166
166
|
if (!this.initPromise) this.initPromise = this.initialize();
|
|
167
167
|
await this.initPromise;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
private async initialize(): Promise<void> {
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
171
|
+
const endOfTurnIds = this.model.tokenize(END_OF_TURN_TOKEN, true);
|
|
172
|
+
if (endOfTurnIds.length !== 1 || !Number.isInteger(endOfTurnIds[0])) {
|
|
173
173
|
throw new Error(
|
|
174
|
-
`[voice] Eliza1EotScorer: model tokenizer did not resolve
|
|
174
|
+
`[voice] Eliza1EotScorer: model tokenizer did not resolve <end_of_turn> to a single special token (got ${JSON.stringify(endOfTurnIds)}). The base model must be Gemma-template compatible.`,
|
|
175
175
|
);
|
|
176
176
|
}
|
|
177
|
-
this.
|
|
177
|
+
this.endOfTurnTokenId = endOfTurnIds[0];
|
|
178
178
|
|
|
179
179
|
const contextOptions: Parameters<LlamaModelLike["createContext"]>[0] = {
|
|
180
180
|
contextSize: this.contextSize,
|
|
@@ -206,7 +206,7 @@ export class Eliza1EotScorer {
|
|
|
206
206
|
private async runOnce(
|
|
207
207
|
sequence: LlamaContextSequenceLike,
|
|
208
208
|
tokens: number[],
|
|
209
|
-
|
|
209
|
+
endOfTurnId: number,
|
|
210
210
|
): Promise<number> {
|
|
211
211
|
if (tokens.length === 0) return 0.5;
|
|
212
212
|
await sequence.clearHistory();
|
|
@@ -219,15 +219,15 @@ export class Eliza1EotScorer {
|
|
|
219
219
|
const last = out[tokens.length - 1];
|
|
220
220
|
const probs = last?.next.probabilities;
|
|
221
221
|
if (!probs) return 0.5;
|
|
222
|
-
const p = probs.get(
|
|
222
|
+
const p = probs.get(endOfTurnId);
|
|
223
223
|
if (typeof p !== "number" || !Number.isFinite(p)) return 0.5;
|
|
224
224
|
return Math.max(0, Math.min(1, p));
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
/**
|
|
229
|
-
* Format the partial transcript using the
|
|
230
|
-
* trailing
|
|
229
|
+
* Format the partial transcript using the Gemma chat template, with the
|
|
230
|
+
* trailing `<end_of_turn>` removed so the next predicted token *is* the
|
|
231
231
|
* EOT signal we want to measure.
|
|
232
232
|
*
|
|
233
233
|
* Matches the formatting LiveKit's turn-detector uses (single user turn,
|
|
@@ -238,5 +238,5 @@ export class Eliza1EotScorer {
|
|
|
238
238
|
*/
|
|
239
239
|
export function formatEotPrompt(transcript: string): string {
|
|
240
240
|
const cleaned = transcript.trim();
|
|
241
|
-
return `${
|
|
241
|
+
return `${START_OF_TURN_USER_PREFIX}${cleaned}`;
|
|
242
242
|
}
|
|
@@ -110,9 +110,8 @@ export type LocalEmbeddingSource =
|
|
|
110
110
|
/**
|
|
111
111
|
* The dedicated model already ships a contrastive `last`-token
|
|
112
112
|
* pooling head — `--pooling last` is still passed so llama-server
|
|
113
|
-
* doesn't fall back to the GGUF's metadata default
|
|
114
|
-
*
|
|
115
|
-
* this just pins the read.
|
|
113
|
+
* doesn't fall back to the GGUF's metadata default. The model's own
|
|
114
|
+
* pooling layer dominates; this just pins the read.
|
|
116
115
|
*/
|
|
117
116
|
readonly poolingType: "last";
|
|
118
117
|
};
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for the #8786 in-process transcript join.
|
|
3
|
+
*
|
|
4
|
+
* `runVoiceTurn` runs speaker-attribution in parallel with the ASR pipeline.
|
|
5
|
+
* The attribution result drives `handleLiveVoiceAttribution`, which emits
|
|
6
|
+
* `VOICE_TURN_OBSERVED` so the merge engine can fold the turn into the entity
|
|
7
|
+
* graph. Historically the emit carried an empty `text` because the in-process
|
|
8
|
+
* engine never threaded the turn's ASR transcript into the attribution call —
|
|
9
|
+
* so the merge engine knew *who* spoke but never *what* they said, and live
|
|
10
|
+
* name extraction (`VoiceObserver.ingestTurn`) could not fire.
|
|
11
|
+
*
|
|
12
|
+
* These tests assert the join: the transcript produced inside the pipeline
|
|
13
|
+
* (`onAsrComplete`) rides on `VOICE_TURN_OBSERVED` for the same turn. They mock
|
|
14
|
+
* the attribution + pipeline seams (no model, no FFI, no live voice loop) so the
|
|
15
|
+
* correlation logic is exercised in isolation.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { tmpdir } from "node:os";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import type { IAgentRuntime } from "@elizaos/core";
|
|
22
|
+
import { EventType } from "@elizaos/core";
|
|
23
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
24
|
+
import { EngineVoiceBridge } from "./engine-bridge";
|
|
25
|
+
import type { VoiceLifecycleLoaders } from "./lifecycle";
|
|
26
|
+
import type { MtpTextRunner } from "./pipeline-impls";
|
|
27
|
+
import type { MmapRegionHandle, RefCountedResource } from "./shared-resources";
|
|
28
|
+
import type { VoiceAttributionOutput } from "./speaker/attribution-pipeline";
|
|
29
|
+
import { writeVoicePresetFile } from "./voice-preset-format";
|
|
30
|
+
|
|
31
|
+
function writePresetBundle(root: string): void {
|
|
32
|
+
mkdirSync(path.join(root, "cache"), { recursive: true });
|
|
33
|
+
const embedding = new Float32Array(16);
|
|
34
|
+
for (let i = 0; i < embedding.length; i++) embedding[i] = (i + 1) / 100;
|
|
35
|
+
writeFileSync(
|
|
36
|
+
path.join(root, "cache", "voice-preset-default.bin"),
|
|
37
|
+
Buffer.from(writeVoicePresetFile({ embedding, phrases: [] })),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function lifecycleLoadersOk(): VoiceLifecycleLoaders {
|
|
42
|
+
const region: MmapRegionHandle = {
|
|
43
|
+
id: "region-ok",
|
|
44
|
+
path: "/tmp/tts-ok",
|
|
45
|
+
sizeBytes: 1024,
|
|
46
|
+
async evictPages() {},
|
|
47
|
+
async release() {},
|
|
48
|
+
};
|
|
49
|
+
const refc: RefCountedResource = { id: "refc-ok", async release() {} };
|
|
50
|
+
return {
|
|
51
|
+
loadTtsRegion: async () => region,
|
|
52
|
+
loadAsrRegion: async () => region,
|
|
53
|
+
loadVoiceCaches: async () => refc,
|
|
54
|
+
loadVoiceSchedulerNodes: async () => refc,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function unitEmbedding(index = 0): Float32Array {
|
|
59
|
+
const out = new Float32Array(256);
|
|
60
|
+
out[index] = 1;
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Attribution output with a bound speaker (drives the VOICE_TURN_OBSERVED emit). */
|
|
65
|
+
function attributionOutput(
|
|
66
|
+
embedding: Float32Array = unitEmbedding(),
|
|
67
|
+
): VoiceAttributionOutput {
|
|
68
|
+
return {
|
|
69
|
+
turnId: "t1",
|
|
70
|
+
primarySpeaker: { entityId: "entity-jill", confidence: 0.6 },
|
|
71
|
+
observation: {
|
|
72
|
+
imprintClusterId: "cluster-1",
|
|
73
|
+
confidence: 0.6,
|
|
74
|
+
entityId: "entity-jill",
|
|
75
|
+
embedding,
|
|
76
|
+
},
|
|
77
|
+
turn: { metadata: {} },
|
|
78
|
+
segments: [],
|
|
79
|
+
} as unknown as VoiceAttributionOutput;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Capture `VOICE_TURN_OBSERVED` emits and expose a promise that resolves once the
|
|
84
|
+
* first one lands (attribution is fire-and-forget, so the test must wait for it).
|
|
85
|
+
*/
|
|
86
|
+
function captureRuntime(): {
|
|
87
|
+
runtime: IAgentRuntime;
|
|
88
|
+
observed: Promise<Record<string, unknown>>;
|
|
89
|
+
} {
|
|
90
|
+
let resolveObserved: (payload: Record<string, unknown>) => void = () => {};
|
|
91
|
+
const observed = new Promise<Record<string, unknown>>((resolve) => {
|
|
92
|
+
resolveObserved = resolve;
|
|
93
|
+
});
|
|
94
|
+
const runtime = {
|
|
95
|
+
emitEvent: async (type: unknown, payload: Record<string, unknown>) => {
|
|
96
|
+
if (type === EventType.VOICE_TURN_OBSERVED) resolveObserved(payload);
|
|
97
|
+
},
|
|
98
|
+
} as unknown as IAgentRuntime;
|
|
99
|
+
return { runtime, observed };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Build a minimal bridge, then inject the attribution + pipeline mocks onto its
|
|
104
|
+
* private seams. `buildPipeline` is overridden to a fake pipeline that fires
|
|
105
|
+
* `onAsrComplete` (the in-pipeline transcript source) on `run`.
|
|
106
|
+
*/
|
|
107
|
+
function bridgeWithJoin(opts: {
|
|
108
|
+
bundleRoot: string;
|
|
109
|
+
runtime: IAgentRuntime;
|
|
110
|
+
asrTokens: ReadonlyArray<{ index: number; text: string }>;
|
|
111
|
+
/** When true, the fake pipeline never fires onAsrComplete (cancelled/no-ASR). */
|
|
112
|
+
skipAsr?: boolean;
|
|
113
|
+
/** Resolve the fake attribution only after this promise (timing control). */
|
|
114
|
+
attributionGate?: Promise<void>;
|
|
115
|
+
attributionEmbedding?: Float32Array;
|
|
116
|
+
}): EngineVoiceBridge {
|
|
117
|
+
const bridge = EngineVoiceBridge.start({
|
|
118
|
+
bundleRoot: opts.bundleRoot,
|
|
119
|
+
useFfiBackend: false,
|
|
120
|
+
lifecycleLoaders: lifecycleLoadersOk(),
|
|
121
|
+
});
|
|
122
|
+
const internals = bridge as unknown as {
|
|
123
|
+
attributionPipeline: {
|
|
124
|
+
attribute(req: unknown): Promise<VoiceAttributionOutput>;
|
|
125
|
+
};
|
|
126
|
+
eventRuntime: IAgentRuntime;
|
|
127
|
+
buildPipeline(
|
|
128
|
+
runner: unknown,
|
|
129
|
+
config: unknown,
|
|
130
|
+
events?: {
|
|
131
|
+
onAsrComplete?(
|
|
132
|
+
tokens: ReadonlyArray<{ index: number; text: string }>,
|
|
133
|
+
): void;
|
|
134
|
+
},
|
|
135
|
+
): { run(audio: unknown): Promise<"done">; cancel(): void };
|
|
136
|
+
};
|
|
137
|
+
internals.eventRuntime = opts.runtime;
|
|
138
|
+
internals.attributionPipeline = {
|
|
139
|
+
async attribute() {
|
|
140
|
+
if (opts.attributionGate) await opts.attributionGate;
|
|
141
|
+
return attributionOutput(opts.attributionEmbedding);
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
internals.buildPipeline = (_runner, _config, events) => ({
|
|
145
|
+
async run() {
|
|
146
|
+
if (!opts.skipAsr) events?.onAsrComplete?.(opts.asrTokens);
|
|
147
|
+
return "done";
|
|
148
|
+
},
|
|
149
|
+
cancel() {},
|
|
150
|
+
});
|
|
151
|
+
return bridge;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const TEXT_RUNNER = {} as MtpTextRunner;
|
|
155
|
+
const AUDIO = { pcm: new Float32Array(16_000), sampleRate: 16_000 };
|
|
156
|
+
const CONFIG = { maxDraftTokens: 4 };
|
|
157
|
+
|
|
158
|
+
describe("EngineVoiceBridge runVoiceTurn — transcript join (#8786)", () => {
|
|
159
|
+
let bundleRoot: string;
|
|
160
|
+
|
|
161
|
+
beforeEach(() => {
|
|
162
|
+
bundleRoot = mkdtempSync(path.join(tmpdir(), "eliza-transcript-join-"));
|
|
163
|
+
writePresetBundle(bundleRoot);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
afterEach(() => {
|
|
167
|
+
rmSync(bundleRoot, { recursive: true, force: true });
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("rides the turn's ASR transcript on VOICE_TURN_OBSERVED (not '')", async () => {
|
|
171
|
+
const { runtime, observed } = captureRuntime();
|
|
172
|
+
const bridge = bridgeWithJoin({
|
|
173
|
+
bundleRoot,
|
|
174
|
+
runtime,
|
|
175
|
+
asrTokens: [
|
|
176
|
+
{ index: 0, text: "I'm " },
|
|
177
|
+
{ index: 1, text: "Jill" },
|
|
178
|
+
],
|
|
179
|
+
});
|
|
180
|
+
await bridge.arm();
|
|
181
|
+
|
|
182
|
+
await bridge.runVoiceTurn(AUDIO, TEXT_RUNNER, CONFIG);
|
|
183
|
+
const payload = await observed;
|
|
184
|
+
|
|
185
|
+
// The whole point of #8786: the merge engine needs the words, not just
|
|
186
|
+
// the speaker. Previously this was hardcoded "".
|
|
187
|
+
expect(payload.text).toBe("I'm Jill");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("joins even when attribution resolves before ASR completes", async () => {
|
|
191
|
+
// Force the attribution to resolve first; the `.then` must still await the
|
|
192
|
+
// transcript (resolved later, inside the pipeline run) rather than emit "".
|
|
193
|
+
let openGate: () => void = () => {};
|
|
194
|
+
const attributionGate = new Promise<void>((r) => {
|
|
195
|
+
openGate = r;
|
|
196
|
+
});
|
|
197
|
+
const { runtime, observed } = captureRuntime();
|
|
198
|
+
const bridge = bridgeWithJoin({
|
|
199
|
+
bundleRoot,
|
|
200
|
+
runtime,
|
|
201
|
+
asrTokens: [{ index: 0, text: "hello there" }],
|
|
202
|
+
attributionGate,
|
|
203
|
+
});
|
|
204
|
+
await bridge.arm();
|
|
205
|
+
// Let attribution resolve immediately on the next microtask.
|
|
206
|
+
openGate();
|
|
207
|
+
|
|
208
|
+
await bridge.runVoiceTurn(AUDIO, TEXT_RUNNER, CONFIG);
|
|
209
|
+
const payload = await observed;
|
|
210
|
+
expect(payload.text).toBe("hello there");
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("emits with text='' for a turn whose ASR never completes (no hang)", async () => {
|
|
214
|
+
const { runtime, observed } = captureRuntime();
|
|
215
|
+
const bridge = bridgeWithJoin({
|
|
216
|
+
bundleRoot,
|
|
217
|
+
runtime,
|
|
218
|
+
asrTokens: [{ index: 0, text: "unused" }],
|
|
219
|
+
skipAsr: true,
|
|
220
|
+
});
|
|
221
|
+
await bridge.arm();
|
|
222
|
+
|
|
223
|
+
await bridge.runVoiceTurn(AUDIO, TEXT_RUNNER, CONFIG);
|
|
224
|
+
// The pipeline `finally` settles the transcript promise, so attribution
|
|
225
|
+
// resolves (with "") rather than hanging the await forever.
|
|
226
|
+
const payload = await observed;
|
|
227
|
+
expect(payload.text).toBe("");
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("folds live self-voice similarity into the emitted turn signal", async () => {
|
|
231
|
+
const { runtime, observed } = captureRuntime();
|
|
232
|
+
const attributionEmbedding = unitEmbedding();
|
|
233
|
+
const bridge = bridgeWithJoin({
|
|
234
|
+
bundleRoot,
|
|
235
|
+
runtime,
|
|
236
|
+
asrTokens: [{ index: 0, text: "hey eliza" }],
|
|
237
|
+
attributionEmbedding,
|
|
238
|
+
});
|
|
239
|
+
const internals = bridge as unknown as {
|
|
240
|
+
scheduler: { bargeIn: { setAgentSpeaking(speaking: boolean): void } };
|
|
241
|
+
selfVoiceImprint: {
|
|
242
|
+
similarity(embedding: Float32Array): Promise<number | null>;
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
internals.scheduler.bargeIn.setAgentSpeaking(true);
|
|
246
|
+
internals.selfVoiceImprint = {
|
|
247
|
+
async similarity(embedding) {
|
|
248
|
+
expect(embedding).toBe(attributionEmbedding);
|
|
249
|
+
return 0.91;
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
let resolveAttribution: (output: VoiceAttributionOutput) => void = () => {};
|
|
253
|
+
const attributed = new Promise<VoiceAttributionOutput>((resolve) => {
|
|
254
|
+
resolveAttribution = resolve;
|
|
255
|
+
});
|
|
256
|
+
await bridge.arm();
|
|
257
|
+
|
|
258
|
+
await bridge.runVoiceTurn(AUDIO, TEXT_RUNNER, CONFIG, {
|
|
259
|
+
onAttribution(output) {
|
|
260
|
+
resolveAttribution(output);
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
await observed;
|
|
264
|
+
const attributedOutput = await attributed;
|
|
265
|
+
|
|
266
|
+
const signal = attributedOutput.turn.metadata.voiceTurnSignal as
|
|
267
|
+
| {
|
|
268
|
+
agentShouldSpeak: boolean | null;
|
|
269
|
+
nextSpeaker: string;
|
|
270
|
+
metadata?: { provenance?: string; selfVoiceSimilarity?: number };
|
|
271
|
+
}
|
|
272
|
+
| undefined;
|
|
273
|
+
expect(signal?.agentShouldSpeak).toBe(false);
|
|
274
|
+
expect(signal?.nextSpeaker).toBe("user");
|
|
275
|
+
expect(signal?.metadata?.provenance).toBe("voice-bridge+self-voice");
|
|
276
|
+
expect(signal?.metadata?.selfVoiceSimilarity).toBeCloseTo(0.91);
|
|
277
|
+
});
|
|
278
|
+
});
|