@elizaos/plugin-local-inference 2.0.0-beta.1 → 2.0.3-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/actions/generate-media.d.ts +59 -0
- package/dist/actions/generate-media.d.ts.map +1 -0
- package/dist/actions/identify-speaker.d.ts +23 -0
- package/dist/actions/identify-speaker.d.ts.map +1 -0
- package/dist/actions/transcription-control.d.ts +29 -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 +8 -37
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38979 -430
- package/dist/index.js.map +217 -0
- package/dist/local-inference-routes.d.ts +47 -0
- package/dist/local-inference-routes.d.ts.map +1 -0
- package/dist/provider.d.ts +21 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/routes/compat-helpers.d.ts +18 -0
- package/dist/routes/compat-helpers.d.ts.map +1 -0
- package/dist/routes/family-member-route.d.ts +62 -0
- package/dist/routes/family-member-route.d.ts.map +1 -0
- package/dist/routes/index.d.ts +20 -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/dist/routes/live-diarization-route.d.ts +33 -0
- package/dist/routes/live-diarization-route.d.ts.map +1 -0
- package/dist/routes/local-inference-asr-route.d.ts +4 -0
- package/dist/routes/local-inference-asr-route.d.ts.map +1 -0
- package/dist/routes/local-inference-asr-transcribe.d.ts +20 -0
- package/dist/routes/local-inference-asr-transcribe.d.ts.map +1 -0
- package/dist/routes/local-inference-compat-routes.d.ts +16 -0
- package/dist/routes/local-inference-compat-routes.d.ts.map +1 -0
- package/dist/routes/local-inference-tts-route.d.ts +7 -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 +15 -0
- package/dist/routes/transcript-audio-store.d.ts.map +1 -0
- package/dist/routes/transcripts-routes.d.ts +44 -0
- package/dist/routes/transcripts-routes.d.ts.map +1 -0
- package/dist/routes/voice-first-run-routes.d.ts +62 -0
- package/dist/routes/voice-first-run-routes.d.ts.map +1 -0
- package/dist/routes/voice-models-routes.d.ts +62 -0
- package/dist/routes/voice-models-routes.d.ts.map +1 -0
- package/dist/routes/voice-profile-plugin-routes.d.ts +19 -0
- package/dist/routes/voice-profile-plugin-routes.d.ts.map +1 -0
- package/dist/routes/voice-profiles-management-routes.d.ts +52 -0
- package/dist/routes/voice-profiles-management-routes.d.ts.map +1 -0
- package/dist/routes/voice-speaker-profile-routes.d.ts +57 -0
- package/dist/routes/voice-speaker-profile-routes.d.ts.map +1 -0
- package/dist/runtime/embedding-manager-support.d.ts +77 -0
- package/dist/runtime/embedding-manager-support.d.ts.map +1 -0
- package/dist/runtime/embedding-presets.d.ts +16 -0
- package/dist/runtime/embedding-presets.d.ts.map +1 -0
- package/dist/runtime/embedding-warmup-policy.d.ts +14 -0
- package/dist/runtime/embedding-warmup-policy.d.ts.map +1 -0
- package/dist/runtime/ensure-local-inference-handler.d.ts +70 -0
- package/dist/runtime/ensure-local-inference-handler.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +15 -0
- 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/dist/runtime/voice-entity-binding.d.ts +113 -0
- package/dist/runtime/voice-entity-binding.d.ts.map +1 -0
- package/dist/services/active-model.d.ts +310 -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/dist/services/assignments.d.ts +84 -0
- 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/dist/services/backend.d.ts +440 -0
- package/dist/services/backend.d.ts.map +1 -0
- package/dist/services/bionic-host-loader.d.ts +67 -0
- package/dist/services/bionic-host-loader.d.ts.map +1 -0
- package/dist/services/bundled-models.d.ts +34 -0
- package/dist/services/bundled-models.d.ts.map +1 -0
- package/dist/services/cache-bridge.d.ts +206 -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 +109 -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 +102 -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 +142 -0
- package/dist/services/conversation-registry.d.ts.map +1 -0
- package/dist/services/desktop-fused-ffi-backend-runtime.d.ts +111 -0
- package/dist/services/desktop-fused-ffi-backend-runtime.d.ts.map +1 -0
- package/dist/services/device-bridge.d.ts +188 -0
- package/dist/services/device-bridge.d.ts.map +1 -0
- package/dist/services/device-resource-metrics.d.ts +149 -0
- package/dist/services/device-resource-metrics.d.ts.map +1 -0
- package/dist/services/device-tier.d.ts +133 -0
- package/dist/services/device-tier.d.ts.map +1 -0
- package/dist/services/downloader.d.ts +94 -0
- package/dist/services/downloader.d.ts.map +1 -0
- package/dist/services/engine.d.ts +579 -0
- 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 +17 -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/dist/services/ffi-streaming-backend.d.ts +201 -0
- package/dist/services/ffi-streaming-backend.d.ts.map +1 -0
- package/dist/services/ffi-streaming-runner.d.ts +146 -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 +56 -0
- package/dist/services/gpu-detect.d.ts.map +1 -0
- package/dist/services/handler-registry.d.ts +72 -0
- package/dist/services/handler-registry.d.ts.map +1 -0
- package/dist/services/hardware.d.ts +63 -0
- package/dist/services/hardware.d.ts.map +1 -0
- package/dist/services/image-description-runtime.d.ts +14 -0
- package/dist/services/image-description-runtime.d.ts.map +1 -0
- package/dist/services/imagegen/aosp-unavailable.d.ts +134 -0
- package/dist/services/imagegen/aosp-unavailable.d.ts.map +1 -0
- package/dist/services/imagegen/backend-selector.d.ts +118 -0
- package/dist/services/imagegen/backend-selector.d.ts.map +1 -0
- package/dist/services/imagegen/coreml-unavailable.d.ts +105 -0
- package/dist/services/imagegen/coreml-unavailable.d.ts.map +1 -0
- package/dist/services/imagegen/errors.d.ts +16 -0
- package/dist/services/imagegen/errors.d.ts.map +1 -0
- package/dist/services/imagegen/index.d.ts +58 -0
- package/dist/services/imagegen/index.d.ts.map +1 -0
- package/dist/services/imagegen/mflux.d.ts +74 -0
- package/dist/services/imagegen/mflux.d.ts.map +1 -0
- package/dist/services/imagegen/sd-cpp.d.ts +181 -0
- package/dist/services/imagegen/sd-cpp.d.ts.map +1 -0
- package/dist/services/imagegen/tensorrt-unavailable.d.ts +83 -0
- package/dist/services/imagegen/tensorrt-unavailable.d.ts.map +1 -0
- package/dist/services/imagegen/types.d.ts +181 -0
- package/dist/services/imagegen/types.d.ts.map +1 -0
- package/dist/services/index.d.ts +31 -0
- 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 +132 -0
- package/dist/services/inference-capabilities.d.ts.map +1 -0
- package/dist/services/inference-telemetry.d.ts +59 -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 +189 -0
- package/dist/services/kv-spill.d.ts.map +1 -0
- package/dist/services/latency-trace.d.ts +346 -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 +96 -0
- package/dist/services/llm-streaming-binding.d.ts.map +1 -0
- package/dist/services/load-args.d.ts +82 -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/dist/services/manifest/schema.d.ts +903 -0
- package/dist/services/manifest/schema.d.ts.map +1 -0
- package/dist/services/manifest/types.d.ts +32 -0
- package/dist/services/manifest/types.d.ts.map +1 -0
- package/dist/services/manifest/validator.d.ts +66 -0
- package/dist/services/manifest/validator.d.ts.map +1 -0
- package/dist/services/memory-arbiter.d.ts +348 -0
- 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/dist/services/memory-monitor.d.ts +128 -0
- package/dist/services/memory-monitor.d.ts.map +1 -0
- package/dist/services/memory-pressure.d.ts +130 -0
- package/dist/services/memory-pressure.d.ts.map +1 -0
- package/dist/services/mtp-doctor.d.ts +13 -0
- package/dist/services/mtp-doctor.d.ts.map +1 -0
- package/dist/services/network-policy.d.ts +127 -0
- package/dist/services/network-policy.d.ts.map +1 -0
- package/dist/services/paths.d.ts +6 -0
- package/dist/services/paths.d.ts.map +1 -0
- package/dist/services/planner-skeleton.d.ts +124 -0
- package/dist/services/planner-skeleton.d.ts.map +1 -0
- package/dist/services/providers.d.ts +38 -0
- package/dist/services/providers.d.ts.map +1 -0
- package/dist/services/ram-budget.d.ts +110 -0
- package/dist/services/ram-budget.d.ts.map +1 -0
- package/dist/services/readiness.d.ts +9 -0
- package/dist/services/readiness.d.ts.map +1 -0
- package/dist/services/recommendation.d.ts +111 -0
- package/dist/services/recommendation.d.ts.map +1 -0
- package/dist/services/registry.d.ts +33 -0
- package/dist/services/registry.d.ts.map +1 -0
- package/dist/services/router-handler.d.ts +92 -0
- package/dist/services/router-handler.d.ts.map +1 -0
- package/dist/services/routing-policy.d.ts +92 -0
- package/dist/services/routing-policy.d.ts.map +1 -0
- package/dist/services/routing-preferences.d.ts +8 -0
- package/dist/services/routing-preferences.d.ts.map +1 -0
- package/dist/services/runtime-target.d.ts +98 -0
- package/dist/services/runtime-target.d.ts.map +1 -0
- package/dist/services/service.d.ts +128 -0
- package/dist/services/service.d.ts.map +1 -0
- package/dist/services/session-pool.d.ts +72 -0
- package/dist/services/session-pool.d.ts.map +1 -0
- package/dist/services/structured-output/deterministic-repair.d.ts +23 -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 +311 -0
- package/dist/services/structured-output.d.ts.map +1 -0
- package/dist/services/system-memory.d.ts +33 -0
- package/dist/services/system-memory.d.ts.map +1 -0
- package/dist/services/types.d.ts +19 -0
- package/dist/services/types.d.ts.map +1 -0
- package/dist/services/verify-on-device.d.ts +34 -0
- package/dist/services/verify-on-device.d.ts.map +1 -0
- package/dist/services/verify.d.ts +8 -0
- package/dist/services/verify.d.ts.map +1 -0
- package/dist/services/vision/aosp-unavailable.d.ts +115 -0
- package/dist/services/vision/aosp-unavailable.d.ts.map +1 -0
- package/dist/services/vision/capacitor-llama.d.ts +99 -0
- package/dist/services/vision/capacitor-llama.d.ts.map +1 -0
- package/dist/services/vision/cloud-fallback.d.ts +47 -0
- package/dist/services/vision/cloud-fallback.d.ts.map +1 -0
- package/dist/services/vision/hash.d.ts +71 -0
- package/dist/services/vision/hash.d.ts.map +1 -0
- package/dist/services/vision/index.d.ts +95 -0
- package/dist/services/vision/index.d.ts.map +1 -0
- package/dist/services/vision/llama-server.d.ts +73 -0
- package/dist/services/vision/llama-server.d.ts.map +1 -0
- package/dist/services/vision/types.d.ts +162 -0
- package/dist/services/vision/types.d.ts.map +1 -0
- package/dist/services/vision/vast-fallback.d.ts +18 -0
- package/dist/services/vision/vast-fallback.d.ts.map +1 -0
- package/dist/services/vision-embedding-cache.d.ts +98 -0
- 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/dist/services/voice/audio-frame-consumer.d.ts +294 -0
- package/dist/services/voice/audio-frame-consumer.d.ts.map +1 -0
- package/dist/services/voice/barge-in.d.ts +112 -0
- package/dist/services/voice/barge-in.d.ts.map +1 -0
- package/dist/services/voice/cancellation-coordinator.d.ts +127 -0
- package/dist/services/voice/cancellation-coordinator.d.ts.map +1 -0
- package/dist/services/voice/checkpoint-manager.d.ts +199 -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 +170 -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/dist/services/voice/eliza1-eot-scorer.d.ts +124 -0
- 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/dist/services/voice/embedding.d.ts +132 -0
- package/dist/services/voice/embedding.d.ts.map +1 -0
- package/dist/services/voice/emotion-attribution.d.ts +68 -0
- package/dist/services/voice/emotion-attribution.d.ts.map +1 -0
- package/dist/services/voice/engine-bridge.d.ts +762 -0
- package/dist/services/voice/engine-bridge.d.ts.map +1 -0
- package/dist/services/voice/eot-classifier-ggml.d.ts +179 -0
- package/dist/services/voice/eot-classifier-ggml.d.ts.map +1 -0
- package/dist/services/voice/eot-classifier.d.ts +211 -0
- package/dist/services/voice/eot-classifier.d.ts.map +1 -0
- package/dist/services/voice/errors.d.ts +20 -0
- package/dist/services/voice/errors.d.ts.map +1 -0
- package/dist/services/voice/expressive-tags.d.ts +158 -0
- package/dist/services/voice/expressive-tags.d.ts.map +1 -0
- package/dist/services/voice/ffi-bindings.d.ts +696 -0
- package/dist/services/voice/ffi-bindings.d.ts.map +1 -0
- package/dist/services/voice/first-line-cache.d.ts +181 -0
- package/dist/services/voice/first-line-cache.d.ts.map +1 -0
- package/dist/services/voice/fused-eot-scorer.d.ts +51 -0
- package/dist/services/voice/fused-eot-scorer.d.ts.map +1 -0
- package/dist/services/voice/index.d.ts +96 -0
- 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/dist/services/voice/kokoro/kokoro-backend.d.ts +87 -0
- package/dist/services/voice/kokoro/kokoro-backend.d.ts.map +1 -0
- package/dist/services/voice/kokoro/kokoro-engine-discovery.d.ts +58 -0
- package/dist/services/voice/kokoro/kokoro-engine-discovery.d.ts.map +1 -0
- package/dist/services/voice/kokoro/kokoro-ffi-runtime.d.ts +75 -0
- package/dist/services/voice/kokoro/kokoro-ffi-runtime.d.ts.map +1 -0
- package/dist/services/voice/kokoro/kokoro-runtime.d.ts +100 -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 +50 -0
- package/dist/services/voice/kokoro/phonemizer.d.ts.map +1 -0
- package/dist/services/voice/kokoro/pick-runtime.d.ts +61 -0
- 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 +82 -0
- package/dist/services/voice/kokoro/types.d.ts.map +1 -0
- package/dist/services/voice/kokoro/voice-presets.d.ts +23 -0
- package/dist/services/voice/kokoro/voice-presets.d.ts.map +1 -0
- package/dist/services/voice/kokoro/voices.d.ts +30 -0
- package/dist/services/voice/kokoro/voices.d.ts.map +1 -0
- package/dist/services/voice/lifecycle.d.ts +135 -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/dist/services/voice/mic-source.d.ts +136 -0
- 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 +109 -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/dist/services/voice/partial-stabilizer.d.ts +73 -0
- package/dist/services/voice/partial-stabilizer.d.ts.map +1 -0
- package/dist/services/voice/phoneme-tokenizer.d.ts +49 -0
- package/dist/services/voice/phoneme-tokenizer.d.ts.map +1 -0
- package/dist/services/voice/phrase-cache.d.ts +76 -0
- package/dist/services/voice/phrase-cache.d.ts.map +1 -0
- package/dist/services/voice/phrase-chunker.d.ts +62 -0
- package/dist/services/voice/phrase-chunker.d.ts.map +1 -0
- package/dist/services/voice/pipeline-impls.d.ts +151 -0
- package/dist/services/voice/pipeline-impls.d.ts.map +1 -0
- package/dist/services/voice/pipeline.d.ts +216 -0
- package/dist/services/voice/pipeline.d.ts.map +1 -0
- package/dist/services/voice/prefill-client.d.ts +123 -0
- package/dist/services/voice/prefill-client.d.ts.map +1 -0
- package/dist/services/voice/prefix-preserving-queue.d.ts +113 -0
- package/dist/services/voice/prefix-preserving-queue.d.ts.map +1 -0
- package/dist/services/voice/profile-store.d.ts +248 -0
- package/dist/services/voice/profile-store.d.ts.map +1 -0
- package/dist/services/voice/ring-buffer.d.ts +40 -0
- package/dist/services/voice/ring-buffer.d.ts.map +1 -0
- package/dist/services/voice/rollback-queue.d.ts +24 -0
- package/dist/services/voice/rollback-queue.d.ts.map +1 -0
- package/dist/services/voice/samantha-preset-placeholder.d.ts +67 -0
- package/dist/services/voice/samantha-preset-placeholder.d.ts.map +1 -0
- package/dist/services/voice/samantha-preset-regenerator.d.ts +87 -0
- package/dist/services/voice/samantha-preset-regenerator.d.ts.map +1 -0
- package/dist/services/voice/scheduler.d.ts +146 -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/dist/services/voice/shared-resources.d.ts +204 -0
- package/dist/services/voice/shared-resources.d.ts.map +1 -0
- package/dist/services/voice/speaker/attribution-pipeline.d.ts +74 -0
- package/dist/services/voice/speaker/attribution-pipeline.d.ts.map +1 -0
- package/dist/services/voice/speaker/diarizer-fused.d.ts +59 -0
- package/dist/services/voice/speaker/diarizer-fused.d.ts.map +1 -0
- package/dist/services/voice/speaker/diarizer.d.ts +75 -0
- package/dist/services/voice/speaker/diarizer.d.ts.map +1 -0
- package/dist/services/voice/speaker/encoder-fused.d.ts +60 -0
- package/dist/services/voice/speaker/encoder-fused.d.ts.map +1 -0
- package/dist/services/voice/speaker/encoder-ggml.d.ts +33 -0
- package/dist/services/voice/speaker/encoder-ggml.d.ts.map +1 -0
- package/dist/services/voice/speaker/encoder.d.ts +37 -0
- package/dist/services/voice/speaker/encoder.d.ts.map +1 -0
- package/dist/services/voice/speaker-imprint.d.ts +83 -0
- package/dist/services/voice/speaker-imprint.d.ts.map +1 -0
- package/dist/services/voice/speaker-preset-cache.d.ts +77 -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 +73 -0
- package/dist/services/voice/system-audio-sink.d.ts.map +1 -0
- package/dist/services/voice/transcriber.d.ts +244 -0
- package/dist/services/voice/transcriber.d.ts.map +1 -0
- package/dist/services/voice/transcript-knowledge.d.ts +37 -0
- package/dist/services/voice/transcript-knowledge.d.ts.map +1 -0
- package/dist/services/voice/transcript-service.d.ts +60 -0
- package/dist/services/voice/transcript-service.d.ts.map +1 -0
- package/dist/services/voice/transcript-store.d.ts +64 -0
- package/dist/services/voice/transcript-store.d.ts.map +1 -0
- package/dist/services/voice/turn-controller.d.ts +183 -0
- package/dist/services/voice/turn-controller.d.ts.map +1 -0
- package/dist/services/voice/types.d.ts +643 -0
- package/dist/services/voice/types.d.ts.map +1 -0
- package/dist/services/voice/vad.d.ts +283 -0
- package/dist/services/voice/vad.d.ts.map +1 -0
- package/dist/services/voice/voice-budget.d.ts +241 -0
- package/dist/services/voice/voice-budget.d.ts.map +1 -0
- package/dist/services/voice/voice-emotion-classifier.d.ts +95 -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/dist/services/voice/voice-preset-format.d.ts +158 -0
- package/dist/services/voice/voice-preset-format.d.ts.map +1 -0
- package/dist/services/voice/voice-profile-artifact.d.ts +116 -0
- package/dist/services/voice/voice-profile-artifact.d.ts.map +1 -0
- package/dist/services/voice/voice-profile-routes.d.ts +83 -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 +364 -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/dist/services/voice/wake-word-ggml.d.ts +100 -0
- package/dist/services/voice/wake-word-ggml.d.ts.map +1 -0
- package/dist/services/voice/wake-word.d.ts +255 -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 +70 -0
- package/dist/services/voice/wrap-with-first-line-cache.d.ts.map +1 -0
- package/dist/services/voice-model-updater.d.ts +240 -0
- package/dist/services/voice-model-updater.d.ts.map +1 -0
- package/dist/services/voice-prewarm.d.ts +3 -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 +101 -15
- package/registry-entry.json +137 -0
- package/src/actions/generate-media.ts +647 -0
- package/src/actions/identify-speaker.ts +171 -0
- package/src/actions/transcription-control.test.ts +100 -0
- package/src/actions/transcription-control.ts +127 -0
- package/src/adapters/capacitor-llama/__tests__/compat-behavior.test.ts +218 -0
- package/src/adapters/capacitor-llama/__tests__/index.test.ts +68 -0
- package/src/adapters/capacitor-llama/__tests__/structured-output.test.ts +215 -0
- package/src/adapters/capacitor-llama/__tests__/text-streaming.test.ts +174 -0
- package/src/adapters/capacitor-llama/__tests__/voice-turn.test.ts +293 -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 +831 -0
- package/src/adapters/capacitor-llama/loader.ts +109 -0
- package/src/adapters/capacitor-llama/native-voice-capture.ts +140 -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/adapters/capacitor-llama/voice-turn.ts +178 -0
- package/src/backends/apple-foundation.ts +127 -0
- package/src/index.ts +62 -0
- package/src/local-inference-routes.test.ts +390 -0
- package/src/local-inference-routes.ts +1625 -0
- package/src/provider.ts +1111 -0
- package/src/routes/compat-helpers.ts +275 -0
- package/src/routes/family-member-route.ts +353 -0
- package/src/routes/index.ts +61 -0
- package/src/routes/live-diarization-route.test.ts +347 -0
- package/src/routes/live-diarization-route.ts +198 -0
- package/src/routes/local-inference-asr-route.test.ts +246 -0
- package/src/routes/local-inference-asr-route.ts +166 -0
- package/src/routes/local-inference-asr-transcribe.test.ts +118 -0
- package/src/routes/local-inference-asr-transcribe.ts +97 -0
- package/src/routes/local-inference-compat-routes.test.ts +485 -0
- package/src/routes/local-inference-compat-routes.ts +775 -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/native-pcm-turn-route.test.ts +136 -0
- package/src/routes/native-pcm-turn-route.ts +121 -0
- package/src/routes/transcript-audio-store.ts +27 -0
- package/src/routes/transcripts-routes.test.ts +195 -0
- package/src/routes/transcripts-routes.ts +191 -0
- package/src/routes/voice-first-run-routes.ts +524 -0
- package/src/routes/voice-models-routes.ts +554 -0
- package/src/routes/voice-profile-plugin-routes.ts +138 -0
- package/src/routes/voice-profiles-management-routes.ts +476 -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/bionic-wire-encoding.test.ts +147 -0
- package/src/runtime/capacitor-llama.d.ts +25 -0
- package/src/runtime/embedding-manager-support.ts +497 -0
- package/src/runtime/embedding-presets.ts +81 -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.test.ts +726 -0
- package/src/runtime/ensure-local-inference-handler.ts +1640 -0
- package/src/runtime/index.ts +36 -0
- package/src/runtime/mobile-local-inference-gate.test.ts +152 -0
- package/src/runtime/mobile-local-inference-gate.ts +99 -0
- package/src/runtime/voice-entity-binding.transcript.test.ts +98 -0
- package/src/runtime/voice-entity-binding.ts +368 -0
- package/src/runtime/voice-speaker-entity-contract.test.ts +149 -0
- package/src/services/README.md +71 -0
- package/src/services/__tests__/backend-selector.precedence.test.ts +333 -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-context-fit.test.ts +125 -0
- package/src/services/active-model-switch-rollback.test.ts +183 -0
- package/src/services/active-model.ts +1416 -0
- package/src/services/asr-provenance.ts +68 -0
- package/src/services/assignment-validation.test.ts +118 -0
- package/src/services/assignments.test.ts +106 -0
- package/src/services/assignments.ts +278 -0
- package/src/services/backend-selector.ts +95 -0
- package/src/services/backend.test.ts +84 -0
- package/src/services/backend.ts +791 -0
- package/src/services/bionic-host-loader.test.ts +226 -0
- package/src/services/bionic-host-loader.ts +252 -0
- package/src/services/bundled-models.ts +129 -0
- package/src/services/cache-bridge.test.ts +516 -0
- package/src/services/cache-bridge.ts +423 -0
- package/src/services/catalog.test.ts +259 -0
- package/src/services/catalog.ts +33 -0
- package/src/services/checkpoint-client.ts +258 -0
- package/src/services/checkpoint-manager.ts +474 -0
- package/src/services/cloud-fallback.ts +230 -0
- package/src/services/context-fit.test.ts +121 -0
- package/src/services/context-fit.ts +113 -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.ts +431 -0
- package/src/services/device-bridge.ts +1237 -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.test.ts +458 -0
- package/src/services/device-tier.ts +502 -0
- package/src/services/downloader.test.ts +888 -0
- package/src/services/downloader.ts +1039 -0
- package/src/services/engine-direct-bundle.test.ts +90 -0
- package/src/services/engine-streaming.test.ts +80 -0
- package/src/services/engine.ts +2096 -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.ts +312 -0
- package/src/services/ffi-llm-mock.ts +354 -0
- package/src/services/ffi-llm-streaming-abi.ts +445 -0
- package/src/services/ffi-streaming-backend.ts +418 -0
- package/src/services/ffi-streaming-runner.test.ts +220 -0
- package/src/services/ffi-streaming-runner.ts +407 -0
- package/src/services/ffi-unload-ordering.test.ts +166 -0
- package/src/services/fused-eliza1-no-regression.test.ts +144 -0
- package/src/services/gpu-autotune.ts +534 -0
- package/src/services/gpu-detect.ts +139 -0
- package/src/services/handler-registry.ts +240 -0
- package/src/services/hardware.test.ts +236 -0
- package/src/services/hardware.ts +438 -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.ts +229 -0
- package/src/services/imagegen/backend-selector.test.ts +190 -0
- package/src/services/imagegen/backend-selector.ts +277 -0
- package/src/services/imagegen/coreml-unavailable.ts +237 -0
- package/src/services/imagegen/errors.ts +40 -0
- package/src/services/imagegen/index.ts +144 -0
- package/src/services/imagegen/mflux.ts +313 -0
- package/src/services/imagegen/sd-cpp.ts +715 -0
- package/src/services/imagegen/tensorrt-unavailable.ts +295 -0
- package/src/services/imagegen/types.ts +193 -0
- package/src/services/index.ts +229 -0
- package/src/services/inference-capabilities.test.ts +75 -0
- package/src/services/inference-capabilities.ts +204 -0
- package/src/services/inference-telemetry.ts +143 -0
- package/src/services/ios-llama-streaming.ts +248 -0
- package/src/services/kv-spill.test.ts +222 -0
- package/src/services/kv-spill.ts +357 -0
- package/src/services/latency-trace.test.ts +266 -0
- package/src/services/latency-trace.ts +844 -0
- 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/llama-server-metrics.ts +304 -0
- package/src/services/llm-streaming-binding.ts +136 -0
- package/src/services/load-args.ts +81 -0
- package/src/services/manifest/eliza-1.manifest.v1.json +790 -0
- package/src/services/manifest/index.ts +72 -0
- package/src/services/manifest/manifest.test.ts +791 -0
- package/src/services/manifest/schema.ts +761 -0
- package/src/services/manifest/types.ts +61 -0
- package/src/services/manifest/validator.ts +633 -0
- package/src/services/memory-arbiter.test.ts +558 -0
- package/src/services/memory-arbiter.ts +991 -0
- package/src/services/memory-benchmark.test.ts +91 -0
- package/src/services/memory-benchmark.ts +354 -0
- package/src/services/memory-monitor.test.ts +232 -0
- package/src/services/memory-monitor.ts +309 -0
- package/src/services/memory-pressure.ts +414 -0
- package/src/services/mtp-doctor.ts +86 -0
- package/src/services/network-policy.ts +346 -0
- package/src/services/paths.ts +25 -0
- package/src/services/planner-skeleton.ts +175 -0
- package/src/services/providers.ts +507 -0
- package/src/services/ram-budget-cache.test.ts +164 -0
- package/src/services/ram-budget.ts +309 -0
- package/src/services/readiness.test.ts +87 -0
- package/src/services/readiness.ts +238 -0
- package/src/services/recommendation.test.ts +216 -0
- package/src/services/recommendation.ts +671 -0
- package/src/services/registry.ts +157 -0
- package/src/services/required-kernels-gate.test.ts +64 -0
- package/src/services/router-handler.test.ts +45 -0
- package/src/services/router-handler.ts +426 -0
- package/src/services/routing-policy.test.ts +352 -0
- package/src/services/routing-policy.ts +367 -0
- package/src/services/routing-preferences.ts +17 -0
- package/src/services/runtime-target.ts +154 -0
- package/src/services/service.test.ts +223 -0
- package/src/services/service.ts +750 -0
- package/src/services/session-pool.ts +153 -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.test.ts +483 -0
- package/src/services/structured-output.ts +712 -0
- package/src/services/system-memory.test.ts +47 -0
- package/src/services/system-memory.ts +67 -0
- package/src/services/transcription-priority.test.ts +211 -0
- package/src/services/types.ts +59 -0
- package/src/services/verify-on-device.test.ts +87 -0
- package/src/services/verify-on-device.ts +127 -0
- package/src/services/verify.ts +13 -0
- package/src/services/vision/aosp-unavailable.ts +163 -0
- package/src/services/vision/capacitor-llama.ts +255 -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.ts +157 -0
- package/src/services/vision/index.ts +251 -0
- package/src/services/vision/llama-server.ts +177 -0
- package/src/services/vision/types.ts +163 -0
- package/src/services/vision/vast-fallback.ts +127 -0
- package/src/services/vision-embedding-cache.ts +189 -0
- package/src/services/voice/VOICE_WORKBENCH.md +133 -0
- package/src/services/voice/__fixtures__/voice-workbench-logic-baseline.json +180 -0
- package/src/services/voice/__test-helpers__/fake-ffi.ts +94 -0
- package/src/services/voice/__test-helpers__/synthetic-speech.ts +194 -0
- package/src/services/voice/__tests__/checkpoint-manager.test.ts +241 -0
- package/src/services/voice/__tests__/checkpoint-policy.test.ts +270 -0
- package/src/services/voice/__tests__/eager-context-builder.test.ts +257 -0
- package/src/services/voice/__tests__/eliza1-eot-scorer.test.ts +288 -0
- package/src/services/voice/__tests__/eot-classifier.test.ts +431 -0
- package/src/services/voice/__tests__/optimistic-rollback.test.ts +312 -0
- package/src/services/voice/__tests__/prefill-client.test.ts +266 -0
- package/src/services/voice/__tests__/prefix-preserving-queue.test.ts +208 -0
- package/src/services/voice/__tests__/streaming-asr.test.ts +450 -0
- package/src/services/voice/__tests__/streaming-transcriber.test.ts +339 -0
- package/src/services/voice/__tests__/turn-detector-resolver.test.ts +195 -0
- package/src/services/voice/__tests__/voice-state-machine-prefill.test.ts +275 -0
- package/src/services/voice/__tests__/voice-state-machine.test.ts +354 -0
- package/src/services/voice/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 +139 -0
- package/src/services/voice/audio-frame-consumer.test.ts +669 -0
- package/src/services/voice/audio-frame-consumer.ts +651 -0
- package/src/services/voice/barge-in.test.ts +244 -0
- package/src/services/voice/barge-in.ts +335 -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.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/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 +182 -0
- package/src/services/voice/e2e-harness.ts +902 -0
- package/src/services/voice/eager-context-builder.ts +262 -0
- 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 +242 -0
- package/src/services/voice/embedding-server.ts +200 -0
- package/src/services/voice/embedding.test.ts +131 -0
- package/src/services/voice/embedding.ts +242 -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-transcript-join.test.ts +278 -0
- package/src/services/voice/engine-bridge.test.ts +384 -0
- package/src/services/voice/engine-bridge.ts +2343 -0
- package/src/services/voice/eot-classifier-ggml.ts +569 -0
- package/src/services/voice/eot-classifier.test.ts +98 -0
- package/src/services/voice/eot-classifier.ts +422 -0
- package/src/services/voice/errors.ts +34 -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 +405 -0
- package/src/services/voice/ffi-bindings.test.ts +735 -0
- package/src/services/voice/ffi-bindings.ts +3387 -0
- package/src/services/voice/first-line-cache.ts +725 -0
- package/src/services/voice/fused-eot-scorer.ts +139 -0
- package/src/services/voice/index.ts +502 -0
- package/src/services/voice/kokoro/__tests__/kokoro-backend.test.ts +262 -0
- package/src/services/voice/kokoro/__tests__/kokoro-engine-bridge.real.test.ts +236 -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 +67 -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.ts +223 -0
- package/src/services/voice/kokoro/kokoro-engine-discovery.ts +177 -0
- package/src/services/voice/kokoro/kokoro-ffi-runtime.ts +233 -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.ts +344 -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.ts +64 -0
- package/src/services/voice/kokoro/types.ts +95 -0
- package/src/services/voice/kokoro/voice-presets.ts +129 -0
- package/src/services/voice/kokoro/voices.ts +64 -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.echo.test.ts +232 -0
- package/src/services/voice/live-diarization-session.ts +622 -0
- 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.test.ts +210 -0
- package/src/services/voice/mic-source.ts +503 -0
- 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/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.test.ts +68 -0
- package/src/services/voice/partial-stabilizer.ts +140 -0
- package/src/services/voice/phoneme-tokenizer.ts +158 -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.test.ts +239 -0
- package/src/services/voice/phrase-chunker.ts +281 -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.ts +504 -0
- package/src/services/voice/prefill-client.ts +316 -0
- package/src/services/voice/prefix-preserving-queue.ts +162 -0
- package/src/services/voice/profile-store.ts +887 -0
- package/src/services/voice/real-audio-decode.test.ts +148 -0
- package/src/services/voice/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/ring-buffer.test.ts +129 -0
- package/src/services/voice/ring-buffer.ts +123 -0
- package/src/services/voice/rollback-queue.ts +74 -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.ts +393 -0
- package/src/services/voice/samantha-preset-regenerator.wav.test.ts +90 -0
- package/src/services/voice/scheduler.t2.test.ts +141 -0
- package/src/services/voice/scheduler.ts +927 -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 +343 -0
- package/src/services/voice/speaker/attribution-pipeline.test.ts +221 -0
- package/src/services/voice/speaker/attribution-pipeline.ts +449 -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.ts +218 -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.test.ts +59 -0
- package/src/services/voice/speaker/encoder-ggml.ts +79 -0
- package/src/services/voice/speaker/encoder.ts +105 -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.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.test.ts +29 -0
- package/src/services/voice/system-audio-sink.ts +366 -0
- package/src/services/voice/transcriber.asr-backend.test.ts +76 -0
- package/src/services/voice/transcriber.test.ts +392 -0
- package/src/services/voice/transcriber.ts +704 -0
- package/src/services/voice/transcript-knowledge.test.ts +68 -0
- package/src/services/voice/transcript-knowledge.ts +75 -0
- package/src/services/voice/transcript-service.test.ts +195 -0
- package/src/services/voice/transcript-service.ts +205 -0
- package/src/services/voice/transcript-store.test.ts +189 -0
- package/src/services/voice/transcript-store.ts +164 -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.ts +699 -0
- package/src/services/voice/vad.test.ts +498 -0
- package/src/services/voice/vad.ts +832 -0
- package/src/services/voice/vad.v1-v4.test.ts +222 -0
- package/src/services/voice/voice-budget.test.ts +415 -0
- package/src/services/voice/voice-budget.ts +635 -0
- package/src/services/voice/voice-duet.test.ts +375 -0
- package/src/services/voice/voice-emotion-classifier.test.ts +210 -0
- package/src/services/voice/voice-emotion-classifier.ts +273 -0
- 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 +713 -0
- package/src/services/voice/voice-preset-generator.test.ts +89 -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.test.ts +429 -0
- package/src/services/voice/voice-profile-routes.ts +425 -0
- package/src/services/voice/voice-scenario.test.ts +159 -0
- package/src/services/voice/voice-scenario.ts +280 -0
- package/src/services/voice/voice-scenario.turn-helpers.test.ts +77 -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 +367 -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.ts +319 -0
- package/src/services/voice/wake-word.test.ts +298 -0
- package/src/services/voice/wake-word.ts +554 -0
- 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/wrap-with-first-line-cache.ts +267 -0
- package/src/services/voice-model-updater.ts +724 -0
- package/src/services/voice-prewarm.ts +51 -0
- package/src/voice-workbench.ts +71 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
export interface CachedPhraseAudio {
|
|
2
|
+
text: string;
|
|
3
|
+
pcm: Float32Array;
|
|
4
|
+
sampleRate: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Canonical seed list for the voice phrase cache: short openers, fillers, and
|
|
9
|
+
* acknowledgements the assistant emits constantly. Pre-synthesizing these and
|
|
10
|
+
* holding their PCM in `PhraseCache` removes the TTS forward pass from the
|
|
11
|
+
* critical path for the most common first utterances — `dispatchPhrase` hits
|
|
12
|
+
* the cache and writes audio to the ring buffer on the same tick.
|
|
13
|
+
*
|
|
14
|
+
* Used by:
|
|
15
|
+
* - the preset generator (`scripts/voice-preset/build-default-voice-preset.mjs`),
|
|
16
|
+
* which synthesizes these against a real OmniVoice TTS backend and writes
|
|
17
|
+
* the PCM into `cache/voice-preset-default.bin` — the seeded source of truth.
|
|
18
|
+
* - `EngineVoiceBridge.start()` indirectly: the bundle's preset ships these
|
|
19
|
+
* phrases with their PCM, which `PhraseCache.seed(...)` loads at startup.
|
|
20
|
+
* - the idle-time auto-prewarm hook (`EngineVoiceBridge.prewarmIdlePhrases`),
|
|
21
|
+
* which only runs when a real TTS backend is present — never against the
|
|
22
|
+
* silent backend (caching zeros is not a phrase cache).
|
|
23
|
+
* - the first-audio filler (`FIRST_AUDIO_FILLERS` is a subset).
|
|
24
|
+
*
|
|
25
|
+
* Entries are kept here in canonical form (lowercase, single-spaced, trimmed)
|
|
26
|
+
* so the preset generator and the runtime agree byte-for-byte on the keys.
|
|
27
|
+
*/
|
|
28
|
+
export const DEFAULT_PHRASE_CACHE_SEED: ReadonlyArray<string> = [
|
|
29
|
+
// Immediate acknowledgements — "I heard you, working on it".
|
|
30
|
+
"okay",
|
|
31
|
+
"got it",
|
|
32
|
+
"sure",
|
|
33
|
+
"right",
|
|
34
|
+
"on it",
|
|
35
|
+
"one sec",
|
|
36
|
+
"one second",
|
|
37
|
+
"let me check",
|
|
38
|
+
"let me see",
|
|
39
|
+
"give me a moment",
|
|
40
|
+
// Conversational openers / fillers — natural sentence starters the planner
|
|
41
|
+
// emits before the substantive answer streams in.
|
|
42
|
+
"okay so",
|
|
43
|
+
"so",
|
|
44
|
+
"hmm",
|
|
45
|
+
"well",
|
|
46
|
+
"alright",
|
|
47
|
+
"sure thing",
|
|
48
|
+
"of course",
|
|
49
|
+
"no problem",
|
|
50
|
+
"good question",
|
|
51
|
+
"let me think",
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The subset of `DEFAULT_PHRASE_CACHE_SEED` suitable to play the instant VAD
|
|
56
|
+
* fires `speech-start`, masking first-token latency (AGENTS.md §4 / H4). Kept
|
|
57
|
+
* short and uncommitted — anything that takes a stance ("of course") is
|
|
58
|
+
* excluded so the filler never contradicts the eventual reply. The first
|
|
59
|
+
* entry found in the phrase cache wins.
|
|
60
|
+
*/
|
|
61
|
+
export const FIRST_AUDIO_FILLERS: ReadonlyArray<string> = [
|
|
62
|
+
"one sec",
|
|
63
|
+
"okay",
|
|
64
|
+
"let me check",
|
|
65
|
+
"hmm",
|
|
66
|
+
"got it",
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
export interface PhraseCacheOptions {
|
|
70
|
+
/** Maximum distinct phrase texts retained. Older non-accessed entries
|
|
71
|
+
* are evicted first. */
|
|
72
|
+
maxEntries?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Opportunistic live-cache guardrail. Voice mode primarily benefits from
|
|
75
|
+
* cached acknowledgements and first sentence fragments; longer text is less
|
|
76
|
+
* likely to repeat and can evict useful hot phrases.
|
|
77
|
+
*/
|
|
78
|
+
maxEstimatedTokensPerEntry?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Guardrail for live opportunistic caching. Long-form direct TTS can be
|
|
81
|
+
* megabytes of PCM and is not a good phrase-cache resident.
|
|
82
|
+
*/
|
|
83
|
+
maxPcmSamplesPerEntry?: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function canonicalizePhraseText(text: string): string {
|
|
87
|
+
return text.trim().toLowerCase().replace(/\s+/g, " ");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function estimatePhraseTokenCount(text: string): number {
|
|
91
|
+
const normalized = canonicalizePhraseText(text);
|
|
92
|
+
if (!normalized) return 0;
|
|
93
|
+
return normalized.split(/\s+/).length;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const DEFAULT_MAX_ENTRIES = 128;
|
|
97
|
+
const DEFAULT_MAX_ESTIMATED_TOKENS_PER_ENTRY = 9;
|
|
98
|
+
const DEFAULT_MAX_PCM_SAMPLES_PER_ENTRY = 24000 * 8;
|
|
99
|
+
|
|
100
|
+
export class PhraseCache {
|
|
101
|
+
private readonly entries = new Map<string, CachedPhraseAudio>();
|
|
102
|
+
private readonly maxEntries: number;
|
|
103
|
+
private readonly maxEstimatedTokensPerEntry: number;
|
|
104
|
+
private readonly maxPcmSamplesPerEntry: number;
|
|
105
|
+
|
|
106
|
+
constructor(opts: PhraseCacheOptions = {}) {
|
|
107
|
+
this.maxEntries = Math.max(
|
|
108
|
+
1,
|
|
109
|
+
Math.floor(opts.maxEntries ?? DEFAULT_MAX_ENTRIES),
|
|
110
|
+
);
|
|
111
|
+
this.maxEstimatedTokensPerEntry = Math.max(
|
|
112
|
+
1,
|
|
113
|
+
Math.floor(
|
|
114
|
+
opts.maxEstimatedTokensPerEntry ??
|
|
115
|
+
DEFAULT_MAX_ESTIMATED_TOKENS_PER_ENTRY,
|
|
116
|
+
),
|
|
117
|
+
);
|
|
118
|
+
this.maxPcmSamplesPerEntry = Math.max(
|
|
119
|
+
1,
|
|
120
|
+
Math.floor(
|
|
121
|
+
opts.maxPcmSamplesPerEntry ?? DEFAULT_MAX_PCM_SAMPLES_PER_ENTRY,
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
put(entry: CachedPhraseAudio): boolean {
|
|
127
|
+
const key = canonicalizePhraseText(entry.text);
|
|
128
|
+
if (!key) return false;
|
|
129
|
+
if (entry.pcm.length > this.maxPcmSamplesPerEntry) return false;
|
|
130
|
+
if (
|
|
131
|
+
estimatePhraseTokenCount(entry.text) > this.maxEstimatedTokensPerEntry
|
|
132
|
+
) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
this.entries.delete(key);
|
|
136
|
+
this.entries.set(key, entry);
|
|
137
|
+
this.evictOverflow();
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Pre-populate the cache from a voice-preset seed list. Texts are stored
|
|
143
|
+
* verbatim — callers (the format reader) are responsible for canonicalizing
|
|
144
|
+
* before serialization, but we re-canonicalize on insert to be safe.
|
|
145
|
+
*/
|
|
146
|
+
seed(
|
|
147
|
+
entries: ReadonlyArray<{
|
|
148
|
+
text: string;
|
|
149
|
+
pcm: Float32Array;
|
|
150
|
+
sampleRate: number;
|
|
151
|
+
}>,
|
|
152
|
+
): void {
|
|
153
|
+
for (const e of entries) {
|
|
154
|
+
this.put({
|
|
155
|
+
text: e.text,
|
|
156
|
+
pcm: e.pcm,
|
|
157
|
+
sampleRate: e.sampleRate,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
get(text: string): CachedPhraseAudio | undefined {
|
|
163
|
+
const key = canonicalizePhraseText(text);
|
|
164
|
+
const entry = this.entries.get(key);
|
|
165
|
+
if (!entry) return undefined;
|
|
166
|
+
this.entries.delete(key);
|
|
167
|
+
this.entries.set(key, entry);
|
|
168
|
+
return entry;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
has(text: string): boolean {
|
|
172
|
+
return this.entries.has(canonicalizePhraseText(text));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
size(): number {
|
|
176
|
+
return this.entries.size;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private evictOverflow(): void {
|
|
180
|
+
while (this.entries.size > this.maxEntries) {
|
|
181
|
+
const oldest = this.entries.keys().next().value;
|
|
182
|
+
if (oldest === undefined) return;
|
|
183
|
+
this.entries.delete(oldest);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { type ClockMs, chunkTokens, PhraseChunker } from "./phrase-chunker";
|
|
3
|
+
import type { TextToken } from "./types";
|
|
4
|
+
|
|
5
|
+
function tokens(parts: string[]): TextToken[] {
|
|
6
|
+
return parts.map((text, index) => ({ index, text }));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe("PhraseChunker punctuation boundaries", () => {
|
|
10
|
+
it("flushes on semicolon and colon boundaries for faster first audio", () => {
|
|
11
|
+
const phrases = chunkTokens(tokens(["First:", " second;", " third"]), {});
|
|
12
|
+
|
|
13
|
+
expect(phrases.map((phrase) => phrase.text)).toEqual([
|
|
14
|
+
"First:",
|
|
15
|
+
" second;",
|
|
16
|
+
" third",
|
|
17
|
+
]);
|
|
18
|
+
expect(phrases.map((phrase) => phrase.terminator)).toEqual([
|
|
19
|
+
"punctuation",
|
|
20
|
+
"punctuation",
|
|
21
|
+
"max-cap",
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("PhraseChunker T3 time-budget flush", () => {
|
|
27
|
+
it("force-flushes once the time budget elapses on a slow producer", () => {
|
|
28
|
+
let now = 0;
|
|
29
|
+
const clock: ClockMs = () => now;
|
|
30
|
+
const chunker = new PhraseChunker(
|
|
31
|
+
// Pin first-phrase budget == full budget so these mechanism tests
|
|
32
|
+
// exercise the uniform 200ms path (first-phrase shortening is
|
|
33
|
+
// covered separately below).
|
|
34
|
+
{
|
|
35
|
+
maxAccumulationMs: 200,
|
|
36
|
+
firstPhraseMaxAccumulationMs: 200,
|
|
37
|
+
maxTokensPerPhrase: 100,
|
|
38
|
+
},
|
|
39
|
+
null,
|
|
40
|
+
clock,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(chunker.push({ index: 0, text: "hello", acceptedAt: 0 })).toBeNull();
|
|
44
|
+
now = 100;
|
|
45
|
+
expect(
|
|
46
|
+
chunker.push({ index: 1, text: " there", acceptedAt: 0 }),
|
|
47
|
+
).toBeNull();
|
|
48
|
+
now = 220;
|
|
49
|
+
const flushed = chunker.push({ index: 2, text: " friend", acceptedAt: 0 });
|
|
50
|
+
expect(flushed).not.toBeNull();
|
|
51
|
+
expect(flushed?.text).toBe("hello there friend");
|
|
52
|
+
expect(flushed?.terminator).toBe("max-cap");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("does not flush before the budget elapses", () => {
|
|
56
|
+
let now = 0;
|
|
57
|
+
const clock: ClockMs = () => now;
|
|
58
|
+
const chunker = new PhraseChunker(
|
|
59
|
+
// Pin first-phrase budget == full budget so these mechanism tests
|
|
60
|
+
// exercise the uniform 200ms path (first-phrase shortening is
|
|
61
|
+
// covered separately below).
|
|
62
|
+
{
|
|
63
|
+
maxAccumulationMs: 200,
|
|
64
|
+
firstPhraseMaxAccumulationMs: 200,
|
|
65
|
+
maxTokensPerPhrase: 100,
|
|
66
|
+
},
|
|
67
|
+
null,
|
|
68
|
+
clock,
|
|
69
|
+
);
|
|
70
|
+
expect(chunker.push({ index: 0, text: "a", acceptedAt: 0 })).toBeNull();
|
|
71
|
+
now = 50;
|
|
72
|
+
expect(chunker.push({ index: 1, text: "b", acceptedAt: 0 })).toBeNull();
|
|
73
|
+
now = 150;
|
|
74
|
+
expect(chunker.push({ index: 2, text: "c", acceptedAt: 0 })).toBeNull();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("flushIfTimeBudgetExceeded triggers on caller poll without a new token", () => {
|
|
78
|
+
let now = 0;
|
|
79
|
+
const clock: ClockMs = () => now;
|
|
80
|
+
const chunker = new PhraseChunker(
|
|
81
|
+
// Pin first-phrase budget == full budget so these mechanism tests
|
|
82
|
+
// exercise the uniform 200ms path (first-phrase shortening is
|
|
83
|
+
// covered separately below).
|
|
84
|
+
{
|
|
85
|
+
maxAccumulationMs: 200,
|
|
86
|
+
firstPhraseMaxAccumulationMs: 200,
|
|
87
|
+
maxTokensPerPhrase: 100,
|
|
88
|
+
},
|
|
89
|
+
null,
|
|
90
|
+
clock,
|
|
91
|
+
);
|
|
92
|
+
chunker.push({ index: 0, text: "x", acceptedAt: 0 });
|
|
93
|
+
now = 100;
|
|
94
|
+
expect(chunker.flushIfTimeBudgetExceeded()).toBeNull();
|
|
95
|
+
now = 250;
|
|
96
|
+
const phrase = chunker.flushIfTimeBudgetExceeded();
|
|
97
|
+
expect(phrase?.text).toBe("x");
|
|
98
|
+
expect(phrase?.terminator).toBe("max-cap");
|
|
99
|
+
expect(chunker.flushIfTimeBudgetExceeded()).toBeNull();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("msUntilTimeBudget reports infinity for an empty buffer or disabled budget", () => {
|
|
103
|
+
let now = 0;
|
|
104
|
+
const clock: ClockMs = () => now;
|
|
105
|
+
const chunker = new PhraseChunker(
|
|
106
|
+
// Pin first-phrase budget == full budget so these mechanism tests
|
|
107
|
+
// exercise the uniform 200ms path (first-phrase shortening is
|
|
108
|
+
// covered separately below).
|
|
109
|
+
{
|
|
110
|
+
maxAccumulationMs: 200,
|
|
111
|
+
firstPhraseMaxAccumulationMs: 200,
|
|
112
|
+
maxTokensPerPhrase: 100,
|
|
113
|
+
},
|
|
114
|
+
null,
|
|
115
|
+
clock,
|
|
116
|
+
);
|
|
117
|
+
expect(chunker.msUntilTimeBudget()).toBe(Number.POSITIVE_INFINITY);
|
|
118
|
+
chunker.push({ index: 0, text: "x", acceptedAt: 0 });
|
|
119
|
+
expect(chunker.msUntilTimeBudget()).toBe(200);
|
|
120
|
+
now = 75;
|
|
121
|
+
expect(chunker.msUntilTimeBudget()).toBe(125);
|
|
122
|
+
|
|
123
|
+
const disabled = new PhraseChunker(
|
|
124
|
+
{ maxAccumulationMs: 0, maxTokensPerPhrase: 100 },
|
|
125
|
+
null,
|
|
126
|
+
clock,
|
|
127
|
+
);
|
|
128
|
+
disabled.push({ index: 0, text: "x", acceptedAt: 0 });
|
|
129
|
+
expect(disabled.msUntilTimeBudget()).toBe(Number.POSITIVE_INFINITY);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("disabled budget never time-flushes", () => {
|
|
133
|
+
let now = 0;
|
|
134
|
+
const clock: ClockMs = () => now;
|
|
135
|
+
const chunker = new PhraseChunker(
|
|
136
|
+
{ maxAccumulationMs: 0, maxTokensPerPhrase: 100 },
|
|
137
|
+
null,
|
|
138
|
+
clock,
|
|
139
|
+
);
|
|
140
|
+
chunker.push({ index: 0, text: "a", acceptedAt: 0 });
|
|
141
|
+
now = 10_000;
|
|
142
|
+
expect(chunker.push({ index: 1, text: " b", acceptedAt: 0 })).toBeNull();
|
|
143
|
+
expect(chunker.flushIfTimeBudgetExceeded()).toBeNull();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("PhraseChunker first-phrase budget (TTFA)", () => {
|
|
148
|
+
it("flushes the first phrase on the shorter budget, later phrases on the full one", () => {
|
|
149
|
+
let now = 0;
|
|
150
|
+
const clock: ClockMs = () => now;
|
|
151
|
+
const chunker = new PhraseChunker(
|
|
152
|
+
{
|
|
153
|
+
maxAccumulationMs: 700,
|
|
154
|
+
firstPhraseMaxAccumulationMs: 300,
|
|
155
|
+
maxTokensPerPhrase: 100,
|
|
156
|
+
},
|
|
157
|
+
null,
|
|
158
|
+
clock,
|
|
159
|
+
);
|
|
160
|
+
// First phrase: silent producer, no punctuation — flushes at 300ms.
|
|
161
|
+
expect(chunker.push({ index: 0, text: "hello", acceptedAt: 0 })).toBeNull();
|
|
162
|
+
expect(chunker.msUntilTimeBudget()).toBe(300);
|
|
163
|
+
now = 300;
|
|
164
|
+
const first = chunker.flushIfTimeBudgetExceeded();
|
|
165
|
+
expect(first?.text).toBe("hello");
|
|
166
|
+
expect(first?.terminator).toBe("max-cap");
|
|
167
|
+
|
|
168
|
+
// Second phrase now uses the FULL 700ms budget (no fragmentation).
|
|
169
|
+
now = 1000;
|
|
170
|
+
expect(
|
|
171
|
+
chunker.push({ index: 1, text: " there", acceptedAt: 0 }),
|
|
172
|
+
).toBeNull();
|
|
173
|
+
expect(chunker.msUntilTimeBudget()).toBe(700);
|
|
174
|
+
now = 1300; // 300ms in — would have flushed the first phrase, not this one
|
|
175
|
+
expect(chunker.flushIfTimeBudgetExceeded()).toBeNull();
|
|
176
|
+
now = 1700; // full 700ms elapsed
|
|
177
|
+
expect(chunker.flushIfTimeBudgetExceeded()?.text).toBe(" there");
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it("derives the first-phrase budget from maxAccumulationMs when unset (half, capped 350)", () => {
|
|
181
|
+
const now = 0;
|
|
182
|
+
const clock: ClockMs = () => now;
|
|
183
|
+
// 700ms full → first-phrase budget = min(350, 350) = 350.
|
|
184
|
+
const chunker = new PhraseChunker(
|
|
185
|
+
{ maxAccumulationMs: 700, maxTokensPerPhrase: 100 },
|
|
186
|
+
null,
|
|
187
|
+
clock,
|
|
188
|
+
);
|
|
189
|
+
chunker.push({ index: 0, text: "x", acceptedAt: 0 });
|
|
190
|
+
expect(chunker.msUntilTimeBudget()).toBe(350);
|
|
191
|
+
|
|
192
|
+
// 400ms full → half = 200 (below the 350 cap).
|
|
193
|
+
const small = new PhraseChunker(
|
|
194
|
+
{ maxAccumulationMs: 400, maxTokensPerPhrase: 100 },
|
|
195
|
+
null,
|
|
196
|
+
clock,
|
|
197
|
+
);
|
|
198
|
+
small.push({ index: 0, text: "x", acceptedAt: 0 });
|
|
199
|
+
expect(small.msUntilTimeBudget()).toBe(200);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it("resets the first-phrase gate on reset() so each reply gets fast first audio", () => {
|
|
203
|
+
let now = 0;
|
|
204
|
+
const clock: ClockMs = () => now;
|
|
205
|
+
const chunker = new PhraseChunker(
|
|
206
|
+
{
|
|
207
|
+
maxAccumulationMs: 700,
|
|
208
|
+
firstPhraseMaxAccumulationMs: 300,
|
|
209
|
+
maxTokensPerPhrase: 100,
|
|
210
|
+
},
|
|
211
|
+
null,
|
|
212
|
+
clock,
|
|
213
|
+
);
|
|
214
|
+
chunker.push({ index: 0, text: "first", acceptedAt: 0 });
|
|
215
|
+
now = 300;
|
|
216
|
+
expect(chunker.flushIfTimeBudgetExceeded()).not.toBeNull(); // phrase #1 flushed
|
|
217
|
+
chunker.reset();
|
|
218
|
+
now = 1000;
|
|
219
|
+
chunker.push({ index: 0, text: "again", acceptedAt: 0 });
|
|
220
|
+
// Back to the short first-phrase budget after reset.
|
|
221
|
+
expect(chunker.msUntilTimeBudget()).toBe(300);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("clamps an explicit first-phrase budget to the full budget", () => {
|
|
225
|
+
const now = 0;
|
|
226
|
+
const clock: ClockMs = () => now;
|
|
227
|
+
const chunker = new PhraseChunker(
|
|
228
|
+
{
|
|
229
|
+
maxAccumulationMs: 200,
|
|
230
|
+
firstPhraseMaxAccumulationMs: 999,
|
|
231
|
+
maxTokensPerPhrase: 100,
|
|
232
|
+
},
|
|
233
|
+
null,
|
|
234
|
+
clock,
|
|
235
|
+
);
|
|
236
|
+
chunker.push({ index: 0, text: "x", acceptedAt: 0 });
|
|
237
|
+
expect(chunker.msUntilTimeBudget()).toBe(200);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import type { PhonemeTokenizer } from "./phoneme-tokenizer";
|
|
2
|
+
import type {
|
|
3
|
+
AcceptedToken,
|
|
4
|
+
Phrase,
|
|
5
|
+
PhraseChunkerConfig,
|
|
6
|
+
TextToken,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default phrase boundaries: end-of-clause punctuation plus the three
|
|
11
|
+
* sentence-final marks. Per `packages/inference/AGENTS.md` §4 / the
|
|
12
|
+
* voice-swarm brief item A6 — "the first segment delimited by punctuation
|
|
13
|
+
* OR the first 30 words, whichever comes first". Cutting a phrase at the
|
|
14
|
+
* first comma/semicolon/colon hands TTS something to say without waiting
|
|
15
|
+
* for a sentence-final mark.
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_TERMINATORS: ReadonlySet<string> = new Set([
|
|
18
|
+
",",
|
|
19
|
+
".",
|
|
20
|
+
"!",
|
|
21
|
+
"?",
|
|
22
|
+
";",
|
|
23
|
+
":",
|
|
24
|
+
]);
|
|
25
|
+
const DEFAULT_PHONEMES_PER_CHUNK = 8;
|
|
26
|
+
/** Default hard word cap when a caller doesn't supply `maxTokensPerPhrase` (the brief's "first 30 words"). */
|
|
27
|
+
const DEFAULT_MAX_TOKENS_PER_PHRASE = 30;
|
|
28
|
+
/**
|
|
29
|
+
* T3 — default time budget in milliseconds for the time-budget phrase
|
|
30
|
+
* flush. When a phrase has been accumulating in the buffer for this long
|
|
31
|
+
* without hitting a punctuation / phoneme / cap boundary, force a flush
|
|
32
|
+
* so the next phrase reaches TTS instead of stalling behind a slow
|
|
33
|
+
* producer. Override via `ELIZA_PHRASE_FLUSH_MS` env var.
|
|
34
|
+
*
|
|
35
|
+
* The default is deliberately phrase-sized. A 200ms budget was fast on paper
|
|
36
|
+
* but split slow token streams into word fragments, which made OmniVoice
|
|
37
|
+
* produce filler-like audio and degraded the downstream ASR loop.
|
|
38
|
+
*/
|
|
39
|
+
function resolveDefaultMaxAccumulationMs(): number {
|
|
40
|
+
const raw = process.env.ELIZA_PHRASE_FLUSH_MS?.trim();
|
|
41
|
+
if (raw) {
|
|
42
|
+
const v = Number.parseInt(raw, 10);
|
|
43
|
+
if (Number.isFinite(v) && v > 0) return v;
|
|
44
|
+
}
|
|
45
|
+
return 700;
|
|
46
|
+
}
|
|
47
|
+
const DEFAULT_MAX_ACCUMULATION_MS = resolveDefaultMaxAccumulationMs();
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* First-audio (TTFA) optimization: the FIRST phrase of a reply uses a shorter
|
|
51
|
+
* time budget than the rest. First-audio latency is the dominant voice-UX
|
|
52
|
+
* metric, and a punctuation-sparse opening otherwise waits the full
|
|
53
|
+
* {@link DEFAULT_MAX_ACCUMULATION_MS} before any sound plays. Once audio is
|
|
54
|
+
* flowing, later phrases keep the full budget so the bulk of the reply is not
|
|
55
|
+
* fragmented into word-sized chunks (the failure mode the 700ms default fixed).
|
|
56
|
+
* Override via `ELIZA_PHRASE_FLUSH_FIRST_MS`; defaults to half the full budget,
|
|
57
|
+
* capped at 350ms. A non-positive full budget disables both.
|
|
58
|
+
*/
|
|
59
|
+
function resolveFirstPhraseMs(fullBudgetMs: number): number {
|
|
60
|
+
if (fullBudgetMs <= 0) return 0;
|
|
61
|
+
const raw = process.env.ELIZA_PHRASE_FLUSH_FIRST_MS?.trim();
|
|
62
|
+
if (raw) {
|
|
63
|
+
const v = Number.parseInt(raw, 10);
|
|
64
|
+
if (Number.isFinite(v) && v > 0) return Math.min(v, fullBudgetMs);
|
|
65
|
+
}
|
|
66
|
+
return Math.min(350, Math.ceil(fullBudgetMs / 2));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Wall-clock source the chunker uses. Tests inject a deterministic clock. */
|
|
70
|
+
export type ClockMs = () => number;
|
|
71
|
+
|
|
72
|
+
const DEFAULT_CLOCK: ClockMs = () => globalThis.performance.now();
|
|
73
|
+
|
|
74
|
+
export class PhraseChunker {
|
|
75
|
+
private buffer: AcceptedToken[] = [];
|
|
76
|
+
private nextPhraseId = 0;
|
|
77
|
+
private readonly terminators: ReadonlySet<string>;
|
|
78
|
+
private readonly chunkOn: "punctuation" | "phoneme-stream";
|
|
79
|
+
private readonly phonemesPerChunk: number;
|
|
80
|
+
private readonly maxTokensPerPhrase: number;
|
|
81
|
+
private readonly tokenizer: PhonemeTokenizer | null;
|
|
82
|
+
private phonemeCount = 0;
|
|
83
|
+
/**
|
|
84
|
+
* T3 — time-budget flush. `firstTokenAtMs` is captured on the first
|
|
85
|
+
* `push()` after an empty buffer; once `clock() - firstTokenAtMs >=
|
|
86
|
+
* maxAccumulationMs` the chunker force-flushes even without a
|
|
87
|
+
* punctuation / phoneme / cap boundary. `maxAccumulationMs <= 0`
|
|
88
|
+
* disables the time budget.
|
|
89
|
+
*/
|
|
90
|
+
private readonly maxAccumulationMs: number;
|
|
91
|
+
/** Shorter budget applied only while no phrase has flushed yet this reply. */
|
|
92
|
+
private readonly firstPhraseMaxAccumulationMs: number;
|
|
93
|
+
private readonly clock: ClockMs;
|
|
94
|
+
private firstTokenAtMs = 0;
|
|
95
|
+
/** Phrases emitted since the last {@link reset}; gates the first-phrase budget. */
|
|
96
|
+
private phrasesEmitted = 0;
|
|
97
|
+
|
|
98
|
+
constructor(
|
|
99
|
+
config: PhraseChunkerConfig,
|
|
100
|
+
tokenizer: PhonemeTokenizer | null = null,
|
|
101
|
+
clock: ClockMs = DEFAULT_CLOCK,
|
|
102
|
+
) {
|
|
103
|
+
this.terminators = config.sentenceTerminators ?? DEFAULT_TERMINATORS;
|
|
104
|
+
this.chunkOn = config.chunkOn ?? "punctuation";
|
|
105
|
+
this.phonemesPerChunk = Math.max(
|
|
106
|
+
1,
|
|
107
|
+
config.phonemesPerChunk ?? DEFAULT_PHONEMES_PER_CHUNK,
|
|
108
|
+
);
|
|
109
|
+
this.maxTokensPerPhrase = Math.max(
|
|
110
|
+
1,
|
|
111
|
+
config.maxTokensPerPhrase ?? DEFAULT_MAX_TOKENS_PER_PHRASE,
|
|
112
|
+
);
|
|
113
|
+
this.maxAccumulationMs =
|
|
114
|
+
config.maxAccumulationMs !== undefined
|
|
115
|
+
? Math.max(0, config.maxAccumulationMs)
|
|
116
|
+
: DEFAULT_MAX_ACCUMULATION_MS;
|
|
117
|
+
this.firstPhraseMaxAccumulationMs =
|
|
118
|
+
config.firstPhraseMaxAccumulationMs !== undefined
|
|
119
|
+
? Math.min(
|
|
120
|
+
this.maxAccumulationMs,
|
|
121
|
+
Math.max(0, config.firstPhraseMaxAccumulationMs),
|
|
122
|
+
)
|
|
123
|
+
: resolveFirstPhraseMs(this.maxAccumulationMs);
|
|
124
|
+
this.clock = clock;
|
|
125
|
+
this.tokenizer = tokenizer;
|
|
126
|
+
if (this.chunkOn === "phoneme-stream" && this.tokenizer === null) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
"PhraseChunker: chunkOn='phoneme-stream' requires a PhonemeTokenizer",
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
push(token: AcceptedToken): Phrase | null {
|
|
134
|
+
if (this.buffer.length === 0) {
|
|
135
|
+
this.firstTokenAtMs = this.clock();
|
|
136
|
+
}
|
|
137
|
+
this.buffer.push(token);
|
|
138
|
+
|
|
139
|
+
// Punctuation always wins — a `, . ! ?` boundary forces a flush even
|
|
140
|
+
// in phoneme-stream mode.
|
|
141
|
+
if (this.endsWithTerminator(token.text)) {
|
|
142
|
+
return this.flushAs("punctuation");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (this.chunkOn === "phoneme-stream" && this.tokenizer !== null) {
|
|
146
|
+
const phonemes = this.tokenizer.tokenize(token.text, token.index);
|
|
147
|
+
this.phonemeCount += phonemes.length;
|
|
148
|
+
if (this.phonemeCount >= this.phonemesPerChunk) {
|
|
149
|
+
return this.flushAs("phoneme-stream");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (this.buffer.length >= this.maxTokensPerPhrase) {
|
|
154
|
+
return this.flushAs("max-cap");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// T3 — time-budget flush. Re-uses the `"max-cap"` terminator because
|
|
158
|
+
// adding a new terminator value would require editing the shared
|
|
159
|
+
// `Phrase` type in `types.ts`. Structurally "the chunker forced a
|
|
160
|
+
// flush" is what max-cap already means.
|
|
161
|
+
const budget = this.currentBudgetMs();
|
|
162
|
+
if (budget > 0 && this.clock() - this.firstTokenAtMs >= budget) {
|
|
163
|
+
return this.flushAs("max-cap");
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Active time budget: the shorter first-phrase budget until the reply's
|
|
169
|
+
* first phrase has flushed, then the full budget. */
|
|
170
|
+
private currentBudgetMs(): number {
|
|
171
|
+
return this.phrasesEmitted === 0
|
|
172
|
+
? this.firstPhraseMaxAccumulationMs
|
|
173
|
+
: this.maxAccumulationMs;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* T3 — caller-driven check. Returns a phrase when the time budget has
|
|
178
|
+
* elapsed for the current buffer, otherwise null. The scheduler polls
|
|
179
|
+
* this from a `setTimeout` so even a producer that goes silent before
|
|
180
|
+
* pushing the next token still gets its in-flight phrase flushed.
|
|
181
|
+
*/
|
|
182
|
+
flushIfTimeBudgetExceeded(): Phrase | null {
|
|
183
|
+
if (this.buffer.length === 0) return null;
|
|
184
|
+
const budget = this.currentBudgetMs();
|
|
185
|
+
if (budget <= 0) return null;
|
|
186
|
+
if (this.clock() - this.firstTokenAtMs < budget) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
return this.flushAs("max-cap");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* T3 — milliseconds remaining until the time budget elapses for the
|
|
194
|
+
* current buffer. Negative when the budget has already been exceeded;
|
|
195
|
+
* `Number.POSITIVE_INFINITY` when the buffer is empty or the budget is
|
|
196
|
+
* disabled. Callers compute their flush timer off this.
|
|
197
|
+
*/
|
|
198
|
+
msUntilTimeBudget(): number {
|
|
199
|
+
if (this.buffer.length === 0) return Number.POSITIVE_INFINITY;
|
|
200
|
+
const budget = this.currentBudgetMs();
|
|
201
|
+
if (budget <= 0) return Number.POSITIVE_INFINITY;
|
|
202
|
+
return this.firstTokenAtMs + budget - this.clock();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
flushPending(): Phrase | null {
|
|
206
|
+
if (this.buffer.length === 0) return null;
|
|
207
|
+
return this.flushAs("max-cap");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Drop buffered tokens that have not flushed whose token index is ≥
|
|
212
|
+
* `fromIndex`. Used by the pipeline's rollback path: when the target
|
|
213
|
+
* verifier rejects a draft tail, any draft tokens still sitting in the
|
|
214
|
+
* chunker's buffer before phrase packing MUST be discarded so
|
|
215
|
+
* the verifier's correction does not get glued onto stale text.
|
|
216
|
+
* Phonemes are recounted from scratch over what remains.
|
|
217
|
+
*/
|
|
218
|
+
dropPendingFrom(fromIndex: number): void {
|
|
219
|
+
const kept = this.buffer.filter((t) => t.index < fromIndex);
|
|
220
|
+
if (kept.length === this.buffer.length) return;
|
|
221
|
+
this.buffer = kept;
|
|
222
|
+
this.phonemeCount = 0;
|
|
223
|
+
if (this.buffer.length === 0) {
|
|
224
|
+
this.firstTokenAtMs = 0;
|
|
225
|
+
}
|
|
226
|
+
if (this.chunkOn === "phoneme-stream" && this.tokenizer !== null) {
|
|
227
|
+
for (const t of this.buffer) {
|
|
228
|
+
this.phonemeCount += this.tokenizer.tokenize(t.text, t.index).length;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
reset(): void {
|
|
234
|
+
this.buffer = [];
|
|
235
|
+
this.phonemeCount = 0;
|
|
236
|
+
this.firstTokenAtMs = 0;
|
|
237
|
+
this.phrasesEmitted = 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private endsWithTerminator(text: string): boolean {
|
|
241
|
+
if (text.length === 0) return false;
|
|
242
|
+
const last = text[text.length - 1];
|
|
243
|
+
return this.terminators.has(last);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private flushAs(terminator: Phrase["terminator"]): Phrase {
|
|
247
|
+
const tokens = this.buffer;
|
|
248
|
+
this.buffer = [];
|
|
249
|
+
this.phonemeCount = 0;
|
|
250
|
+
this.firstTokenAtMs = 0;
|
|
251
|
+
this.phrasesEmitted++;
|
|
252
|
+
const fromIndex = tokens[0].index;
|
|
253
|
+
const toIndex = tokens[tokens.length - 1].index;
|
|
254
|
+
const text = tokens.map((t) => t.text).join("");
|
|
255
|
+
const phrase: Phrase = {
|
|
256
|
+
id: this.nextPhraseId++,
|
|
257
|
+
text,
|
|
258
|
+
fromIndex,
|
|
259
|
+
toIndex,
|
|
260
|
+
terminator,
|
|
261
|
+
};
|
|
262
|
+
return phrase;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function chunkTokens(
|
|
267
|
+
tokens: TextToken[],
|
|
268
|
+
config: PhraseChunkerConfig,
|
|
269
|
+
acceptedAt = 0,
|
|
270
|
+
tokenizer: PhonemeTokenizer | null = null,
|
|
271
|
+
): Phrase[] {
|
|
272
|
+
const chunker = new PhraseChunker(config, tokenizer);
|
|
273
|
+
const phrases: Phrase[] = [];
|
|
274
|
+
for (const t of tokens) {
|
|
275
|
+
const p = chunker.push({ ...t, acceptedAt });
|
|
276
|
+
if (p) phrases.push(p);
|
|
277
|
+
}
|
|
278
|
+
const tail = chunker.flushPending();
|
|
279
|
+
if (tail) phrases.push(tail);
|
|
280
|
+
return phrases;
|
|
281
|
+
}
|