@livekit/agents 1.0.47 → 1.1.0-dev.0
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/dist/beta/index.cjs +29 -0
- package/dist/beta/index.cjs.map +1 -0
- package/dist/beta/index.d.cts +2 -0
- package/dist/beta/index.d.ts +2 -0
- package/dist/beta/index.d.ts.map +1 -0
- package/dist/beta/index.js +7 -0
- package/dist/beta/index.js.map +1 -0
- package/dist/beta/workflows/index.cjs +29 -0
- package/dist/beta/workflows/index.cjs.map +1 -0
- package/dist/beta/workflows/index.d.cts +2 -0
- package/dist/beta/workflows/index.d.ts +2 -0
- package/dist/beta/workflows/index.d.ts.map +1 -0
- package/dist/beta/workflows/index.js +7 -0
- package/dist/beta/workflows/index.js.map +1 -0
- package/dist/beta/workflows/task_group.cjs +162 -0
- package/dist/beta/workflows/task_group.cjs.map +1 -0
- package/dist/beta/workflows/task_group.d.cts +32 -0
- package/dist/beta/workflows/task_group.d.ts +32 -0
- package/dist/beta/workflows/task_group.d.ts.map +1 -0
- package/dist/beta/workflows/task_group.js +138 -0
- package/dist/beta/workflows/task_group.js.map +1 -0
- package/dist/constants.cjs +27 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +9 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +18 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/inference/api_protos.d.cts +12 -12
- package/dist/inference/api_protos.d.ts +12 -12
- package/dist/inference/interruption/defaults.cjs +81 -0
- package/dist/inference/interruption/defaults.cjs.map +1 -0
- package/dist/inference/interruption/defaults.d.cts +19 -0
- package/dist/inference/interruption/defaults.d.ts +19 -0
- package/dist/inference/interruption/defaults.d.ts.map +1 -0
- package/dist/inference/interruption/defaults.js +46 -0
- package/dist/inference/interruption/defaults.js.map +1 -0
- package/dist/inference/interruption/errors.cjs +44 -0
- package/dist/inference/interruption/errors.cjs.map +1 -0
- package/dist/inference/interruption/errors.d.cts +12 -0
- package/dist/inference/interruption/errors.d.ts +12 -0
- package/dist/inference/interruption/errors.d.ts.map +1 -0
- package/dist/inference/interruption/errors.js +20 -0
- package/dist/inference/interruption/errors.js.map +1 -0
- package/dist/inference/interruption/http_transport.cjs +147 -0
- package/dist/inference/interruption/http_transport.cjs.map +1 -0
- package/dist/inference/interruption/http_transport.d.cts +63 -0
- package/dist/inference/interruption/http_transport.d.ts +63 -0
- package/dist/inference/interruption/http_transport.d.ts.map +1 -0
- package/dist/inference/interruption/http_transport.js +121 -0
- package/dist/inference/interruption/http_transport.js.map +1 -0
- package/dist/inference/interruption/interruption_cache_entry.cjs +58 -0
- package/dist/inference/interruption/interruption_cache_entry.cjs.map +1 -0
- package/dist/inference/interruption/interruption_cache_entry.d.cts +30 -0
- package/dist/inference/interruption/interruption_cache_entry.d.ts +30 -0
- package/dist/inference/interruption/interruption_cache_entry.d.ts.map +1 -0
- package/dist/inference/interruption/interruption_cache_entry.js +34 -0
- package/dist/inference/interruption/interruption_cache_entry.js.map +1 -0
- package/dist/inference/interruption/interruption_detector.cjs +181 -0
- package/dist/inference/interruption/interruption_detector.cjs.map +1 -0
- package/dist/inference/interruption/interruption_detector.d.cts +59 -0
- package/dist/inference/interruption/interruption_detector.d.ts +59 -0
- package/dist/inference/interruption/interruption_detector.d.ts.map +1 -0
- package/dist/inference/interruption/interruption_detector.js +147 -0
- package/dist/inference/interruption/interruption_detector.js.map +1 -0
- package/dist/inference/interruption/interruption_stream.cjs +368 -0
- package/dist/inference/interruption/interruption_stream.cjs.map +1 -0
- package/dist/inference/interruption/interruption_stream.d.cts +46 -0
- package/dist/inference/interruption/interruption_stream.d.ts +46 -0
- package/dist/inference/interruption/interruption_stream.d.ts.map +1 -0
- package/dist/inference/interruption/interruption_stream.js +344 -0
- package/dist/inference/interruption/interruption_stream.js.map +1 -0
- package/dist/inference/interruption/types.cjs +17 -0
- package/dist/inference/interruption/types.cjs.map +1 -0
- package/dist/inference/interruption/types.d.cts +66 -0
- package/dist/inference/interruption/types.d.ts +66 -0
- package/dist/inference/interruption/types.d.ts.map +1 -0
- package/dist/inference/interruption/types.js +1 -0
- package/dist/inference/interruption/types.js.map +1 -0
- package/dist/inference/interruption/utils.cjs +130 -0
- package/dist/inference/interruption/utils.cjs.map +1 -0
- package/dist/inference/interruption/utils.d.cts +41 -0
- package/dist/inference/interruption/utils.d.ts +41 -0
- package/dist/inference/interruption/utils.d.ts.map +1 -0
- package/dist/inference/interruption/utils.js +105 -0
- package/dist/inference/interruption/utils.js.map +1 -0
- package/dist/inference/interruption/utils.test.cjs +105 -0
- package/dist/inference/interruption/utils.test.cjs.map +1 -0
- package/dist/inference/interruption/utils.test.js +104 -0
- package/dist/inference/interruption/utils.test.js.map +1 -0
- package/dist/inference/interruption/ws_transport.cjs +329 -0
- package/dist/inference/interruption/ws_transport.cjs.map +1 -0
- package/dist/inference/interruption/ws_transport.d.cts +33 -0
- package/dist/inference/interruption/ws_transport.d.ts +33 -0
- package/dist/inference/interruption/ws_transport.d.ts.map +1 -0
- package/dist/inference/interruption/ws_transport.js +295 -0
- package/dist/inference/interruption/ws_transport.js.map +1 -0
- package/dist/inference/llm.cjs +14 -10
- package/dist/inference/llm.cjs.map +1 -1
- package/dist/inference/llm.d.cts +2 -1
- package/dist/inference/llm.d.ts +2 -1
- package/dist/inference/llm.d.ts.map +1 -1
- package/dist/inference/llm.js +8 -10
- package/dist/inference/llm.js.map +1 -1
- package/dist/inference/stt.cjs +7 -2
- package/dist/inference/stt.cjs.map +1 -1
- package/dist/inference/stt.d.cts +2 -0
- package/dist/inference/stt.d.ts +2 -0
- package/dist/inference/stt.d.ts.map +1 -1
- package/dist/inference/stt.js +8 -3
- package/dist/inference/stt.js.map +1 -1
- package/dist/inference/tts.cjs +7 -2
- package/dist/inference/tts.cjs.map +1 -1
- package/dist/inference/tts.d.cts +2 -0
- package/dist/inference/tts.d.ts +2 -0
- package/dist/inference/tts.d.ts.map +1 -1
- package/dist/inference/tts.js +8 -3
- package/dist/inference/tts.js.map +1 -1
- package/dist/inference/utils.cjs +26 -7
- package/dist/inference/utils.cjs.map +1 -1
- package/dist/inference/utils.d.cts +13 -0
- package/dist/inference/utils.d.ts +13 -0
- package/dist/inference/utils.d.ts.map +1 -1
- package/dist/inference/utils.js +18 -2
- package/dist/inference/utils.js.map +1 -1
- package/dist/llm/chat_context.cjs +108 -2
- package/dist/llm/chat_context.cjs.map +1 -1
- package/dist/llm/chat_context.d.cts +28 -1
- package/dist/llm/chat_context.d.ts +28 -1
- package/dist/llm/chat_context.d.ts.map +1 -1
- package/dist/llm/chat_context.js +108 -2
- package/dist/llm/chat_context.js.map +1 -1
- package/dist/llm/chat_context.test.cjs +43 -0
- package/dist/llm/chat_context.test.cjs.map +1 -1
- package/dist/llm/chat_context.test.js +43 -0
- package/dist/llm/chat_context.test.js.map +1 -1
- package/dist/llm/index.cjs +2 -0
- package/dist/llm/index.cjs.map +1 -1
- package/dist/llm/index.d.cts +2 -2
- package/dist/llm/index.d.ts +2 -2
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +3 -1
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/llm.cjs +16 -1
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.cts +9 -0
- package/dist/llm/llm.d.ts +9 -0
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js +16 -1
- package/dist/llm/llm.js.map +1 -1
- package/dist/llm/provider_format/index.d.cts +1 -1
- package/dist/llm/provider_format/index.d.ts +1 -1
- package/dist/llm/realtime.cjs +3 -0
- package/dist/llm/realtime.cjs.map +1 -1
- package/dist/llm/realtime.d.cts +1 -0
- package/dist/llm/realtime.d.ts +1 -0
- package/dist/llm/realtime.d.ts.map +1 -1
- package/dist/llm/realtime.js +3 -0
- package/dist/llm/realtime.js.map +1 -1
- package/dist/llm/tool_context.cjs +7 -0
- package/dist/llm/tool_context.cjs.map +1 -1
- package/dist/llm/tool_context.d.cts +10 -2
- package/dist/llm/tool_context.d.ts +10 -2
- package/dist/llm/tool_context.d.ts.map +1 -1
- package/dist/llm/tool_context.js +6 -0
- package/dist/llm/tool_context.js.map +1 -1
- package/dist/metrics/base.cjs.map +1 -1
- package/dist/metrics/base.d.cts +45 -1
- package/dist/metrics/base.d.ts +45 -1
- package/dist/metrics/base.d.ts.map +1 -1
- package/dist/metrics/index.cjs +5 -0
- package/dist/metrics/index.cjs.map +1 -1
- package/dist/metrics/index.d.cts +2 -1
- package/dist/metrics/index.d.ts +2 -1
- package/dist/metrics/index.d.ts.map +1 -1
- package/dist/metrics/index.js +6 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/model_usage.cjs +189 -0
- package/dist/metrics/model_usage.cjs.map +1 -0
- package/dist/metrics/model_usage.d.cts +92 -0
- package/dist/metrics/model_usage.d.ts +92 -0
- package/dist/metrics/model_usage.d.ts.map +1 -0
- package/dist/metrics/model_usage.js +164 -0
- package/dist/metrics/model_usage.js.map +1 -0
- package/dist/metrics/model_usage.test.cjs +474 -0
- package/dist/metrics/model_usage.test.cjs.map +1 -0
- package/dist/metrics/model_usage.test.js +476 -0
- package/dist/metrics/model_usage.test.js.map +1 -0
- package/dist/metrics/usage_collector.cjs +3 -0
- package/dist/metrics/usage_collector.cjs.map +1 -1
- package/dist/metrics/usage_collector.d.cts +9 -0
- package/dist/metrics/usage_collector.d.ts +9 -0
- package/dist/metrics/usage_collector.d.ts.map +1 -1
- package/dist/metrics/usage_collector.js +3 -0
- package/dist/metrics/usage_collector.js.map +1 -1
- package/dist/metrics/utils.cjs +9 -0
- package/dist/metrics/utils.cjs.map +1 -1
- package/dist/metrics/utils.d.ts.map +1 -1
- package/dist/metrics/utils.js +9 -0
- package/dist/metrics/utils.js.map +1 -1
- package/dist/stream/multi_input_stream.test.cjs +4 -0
- package/dist/stream/multi_input_stream.test.cjs.map +1 -1
- package/dist/stream/multi_input_stream.test.js +5 -1
- package/dist/stream/multi_input_stream.test.js.map +1 -1
- package/dist/stream/stream_channel.cjs +31 -0
- package/dist/stream/stream_channel.cjs.map +1 -1
- package/dist/stream/stream_channel.d.cts +4 -2
- package/dist/stream/stream_channel.d.ts +4 -2
- package/dist/stream/stream_channel.d.ts.map +1 -1
- package/dist/stream/stream_channel.js +31 -0
- package/dist/stream/stream_channel.js.map +1 -1
- package/dist/stt/stt.cjs +34 -2
- package/dist/stt/stt.cjs.map +1 -1
- package/dist/stt/stt.d.cts +22 -0
- package/dist/stt/stt.d.ts +22 -0
- package/dist/stt/stt.d.ts.map +1 -1
- package/dist/stt/stt.js +34 -2
- package/dist/stt/stt.js.map +1 -1
- package/dist/telemetry/otel_http_exporter.cjs +24 -5
- package/dist/telemetry/otel_http_exporter.cjs.map +1 -1
- package/dist/telemetry/otel_http_exporter.d.cts +1 -0
- package/dist/telemetry/otel_http_exporter.d.ts +1 -0
- package/dist/telemetry/otel_http_exporter.d.ts.map +1 -1
- package/dist/telemetry/otel_http_exporter.js +24 -5
- package/dist/telemetry/otel_http_exporter.js.map +1 -1
- package/dist/telemetry/trace_types.cjs +5 -5
- package/dist/telemetry/trace_types.cjs.map +1 -1
- package/dist/telemetry/trace_types.d.cts +9 -5
- package/dist/telemetry/trace_types.d.ts +9 -5
- package/dist/telemetry/trace_types.d.ts.map +1 -1
- package/dist/telemetry/trace_types.js +5 -5
- package/dist/telemetry/trace_types.js.map +1 -1
- package/dist/telemetry/traces.cjs +47 -8
- package/dist/telemetry/traces.cjs.map +1 -1
- package/dist/telemetry/traces.d.ts.map +1 -1
- package/dist/telemetry/traces.js +47 -8
- package/dist/telemetry/traces.js.map +1 -1
- package/dist/tts/tts.cjs +64 -2
- package/dist/tts/tts.cjs.map +1 -1
- package/dist/tts/tts.d.cts +34 -0
- package/dist/tts/tts.d.ts +34 -0
- package/dist/tts/tts.d.ts.map +1 -1
- package/dist/tts/tts.js +64 -2
- package/dist/tts/tts.js.map +1 -1
- package/dist/utils.cjs +1 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/dist/voice/agent.cjs +34 -4
- package/dist/voice/agent.cjs.map +1 -1
- package/dist/voice/agent.d.cts +11 -2
- package/dist/voice/agent.d.ts +11 -2
- package/dist/voice/agent.d.ts.map +1 -1
- package/dist/voice/agent.js +34 -4
- package/dist/voice/agent.js.map +1 -1
- package/dist/voice/agent_activity.cjs +292 -44
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.cts +27 -6
- package/dist/voice/agent_activity.d.ts +27 -6
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +293 -45
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_session.cjs +105 -48
- package/dist/voice/agent_session.cjs.map +1 -1
- package/dist/voice/agent_session.d.cts +90 -20
- package/dist/voice/agent_session.d.ts +90 -20
- package/dist/voice/agent_session.d.ts.map +1 -1
- package/dist/voice/agent_session.js +105 -46
- package/dist/voice/agent_session.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +287 -6
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.cts +42 -3
- package/dist/voice/audio_recognition.d.ts +42 -3
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +289 -7
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/client_events.cjs +554 -0
- package/dist/voice/client_events.cjs.map +1 -0
- package/dist/voice/client_events.d.cts +195 -0
- package/dist/voice/client_events.d.ts +195 -0
- package/dist/voice/client_events.d.ts.map +1 -0
- package/dist/voice/client_events.js +548 -0
- package/dist/voice/client_events.js.map +1 -0
- package/dist/voice/events.cjs +1 -0
- package/dist/voice/events.cjs.map +1 -1
- package/dist/voice/events.d.cts +8 -5
- package/dist/voice/events.d.ts +8 -5
- package/dist/voice/events.d.ts.map +1 -1
- package/dist/voice/events.js +1 -0
- package/dist/voice/events.js.map +1 -1
- package/dist/voice/generation.cjs +43 -8
- package/dist/voice/generation.cjs.map +1 -1
- package/dist/voice/generation.d.cts +3 -3
- package/dist/voice/generation.d.ts +3 -3
- package/dist/voice/generation.d.ts.map +1 -1
- package/dist/voice/generation.js +43 -8
- package/dist/voice/generation.js.map +1 -1
- package/dist/voice/index.cjs +1 -0
- package/dist/voice/index.cjs.map +1 -1
- package/dist/voice/index.d.cts +1 -0
- package/dist/voice/index.d.ts +1 -0
- package/dist/voice/index.d.ts.map +1 -1
- package/dist/voice/index.js +1 -0
- package/dist/voice/index.js.map +1 -1
- package/dist/voice/report.cjs +20 -8
- package/dist/voice/report.cjs.map +1 -1
- package/dist/voice/report.d.cts +5 -0
- package/dist/voice/report.d.ts +5 -0
- package/dist/voice/report.d.ts.map +1 -1
- package/dist/voice/report.js +20 -8
- package/dist/voice/report.js.map +1 -1
- package/dist/voice/report.test.cjs +106 -0
- package/dist/voice/report.test.cjs.map +1 -0
- package/dist/voice/report.test.js +105 -0
- package/dist/voice/report.test.js.map +1 -0
- package/dist/voice/room_io/room_io.cjs +16 -41
- package/dist/voice/room_io/room_io.cjs.map +1 -1
- package/dist/voice/room_io/room_io.d.cts +4 -9
- package/dist/voice/room_io/room_io.d.ts +4 -9
- package/dist/voice/room_io/room_io.d.ts.map +1 -1
- package/dist/voice/room_io/room_io.js +17 -43
- package/dist/voice/room_io/room_io.js.map +1 -1
- package/dist/voice/testing/fake_llm.cjs +127 -0
- package/dist/voice/testing/fake_llm.cjs.map +1 -0
- package/dist/voice/testing/fake_llm.d.cts +30 -0
- package/dist/voice/testing/fake_llm.d.ts +30 -0
- package/dist/voice/testing/fake_llm.d.ts.map +1 -0
- package/dist/voice/testing/fake_llm.js +103 -0
- package/dist/voice/testing/fake_llm.js.map +1 -0
- package/dist/voice/testing/index.cjs +3 -0
- package/dist/voice/testing/index.cjs.map +1 -1
- package/dist/voice/testing/index.d.cts +1 -0
- package/dist/voice/testing/index.d.ts +1 -0
- package/dist/voice/testing/index.d.ts.map +1 -1
- package/dist/voice/testing/index.js +2 -0
- package/dist/voice/testing/index.js.map +1 -1
- package/dist/voice/turn_config/endpointing.cjs +33 -0
- package/dist/voice/turn_config/endpointing.cjs.map +1 -0
- package/dist/voice/turn_config/endpointing.d.cts +30 -0
- package/dist/voice/turn_config/endpointing.d.ts +30 -0
- package/dist/voice/turn_config/endpointing.d.ts.map +1 -0
- package/dist/voice/turn_config/endpointing.js +9 -0
- package/dist/voice/turn_config/endpointing.js.map +1 -0
- package/dist/voice/turn_config/interruption.cjs +37 -0
- package/dist/voice/turn_config/interruption.cjs.map +1 -0
- package/dist/voice/turn_config/interruption.d.cts +53 -0
- package/dist/voice/turn_config/interruption.d.ts +53 -0
- package/dist/voice/turn_config/interruption.d.ts.map +1 -0
- package/dist/voice/turn_config/interruption.js +13 -0
- package/dist/voice/turn_config/interruption.js.map +1 -0
- package/dist/voice/turn_config/turn_handling.cjs +35 -0
- package/dist/voice/turn_config/turn_handling.cjs.map +1 -0
- package/dist/voice/turn_config/turn_handling.d.cts +36 -0
- package/dist/voice/turn_config/turn_handling.d.ts +36 -0
- package/dist/voice/turn_config/turn_handling.d.ts.map +1 -0
- package/dist/voice/turn_config/turn_handling.js +11 -0
- package/dist/voice/turn_config/turn_handling.js.map +1 -0
- package/dist/voice/turn_config/utils.cjs +97 -0
- package/dist/voice/turn_config/utils.cjs.map +1 -0
- package/dist/voice/turn_config/utils.d.cts +25 -0
- package/dist/voice/turn_config/utils.d.ts +25 -0
- package/dist/voice/turn_config/utils.d.ts.map +1 -0
- package/dist/voice/turn_config/utils.js +73 -0
- package/dist/voice/turn_config/utils.js.map +1 -0
- package/dist/voice/turn_config/utils.test.cjs +86 -0
- package/dist/voice/turn_config/utils.test.cjs.map +1 -0
- package/dist/voice/turn_config/utils.test.js +85 -0
- package/dist/voice/turn_config/utils.test.js.map +1 -0
- package/dist/voice/wire_format.cjs +798 -0
- package/dist/voice/wire_format.cjs.map +1 -0
- package/dist/voice/wire_format.d.cts +5503 -0
- package/dist/voice/wire_format.d.ts +5503 -0
- package/dist/voice/wire_format.d.ts.map +1 -0
- package/dist/voice/wire_format.js +728 -0
- package/dist/voice/wire_format.js.map +1 -0
- package/package.json +2 -1
- package/src/beta/index.ts +9 -0
- package/src/beta/workflows/index.ts +9 -0
- package/src/beta/workflows/task_group.ts +194 -0
- package/src/constants.ts +13 -0
- package/src/index.ts +2 -1
- package/src/inference/interruption/defaults.ts +51 -0
- package/src/inference/interruption/errors.ts +25 -0
- package/src/inference/interruption/http_transport.ts +187 -0
- package/src/inference/interruption/interruption_cache_entry.ts +50 -0
- package/src/inference/interruption/interruption_detector.ts +188 -0
- package/src/inference/interruption/interruption_stream.ts +467 -0
- package/src/inference/interruption/types.ts +84 -0
- package/src/inference/interruption/utils.test.ts +132 -0
- package/src/inference/interruption/utils.ts +137 -0
- package/src/inference/interruption/ws_transport.ts +402 -0
- package/src/inference/llm.ts +9 -12
- package/src/inference/stt.ts +10 -3
- package/src/inference/tts.ts +10 -3
- package/src/inference/utils.ts +29 -1
- package/src/llm/chat_context.test.ts +48 -0
- package/src/llm/chat_context.ts +161 -0
- package/src/llm/index.ts +2 -0
- package/src/llm/llm.ts +16 -0
- package/src/llm/realtime.ts +4 -0
- package/src/llm/tool_context.ts +14 -0
- package/src/metrics/base.ts +48 -1
- package/src/metrics/index.ts +11 -0
- package/src/metrics/model_usage.test.ts +545 -0
- package/src/metrics/model_usage.ts +262 -0
- package/src/metrics/usage_collector.ts +11 -0
- package/src/metrics/utils.ts +11 -0
- package/src/stream/multi_input_stream.test.ts +6 -1
- package/src/stream/stream_channel.ts +34 -2
- package/src/stt/stt.ts +38 -0
- package/src/telemetry/otel_http_exporter.ts +28 -5
- package/src/telemetry/trace_types.ts +11 -8
- package/src/telemetry/traces.ts +111 -54
- package/src/tts/tts.ts +69 -1
- package/src/utils.ts +5 -0
- package/src/voice/agent.ts +41 -3
- package/src/voice/agent_activity.ts +371 -34
- package/src/voice/agent_session.ts +207 -59
- package/src/voice/audio_recognition.ts +385 -9
- package/src/voice/client_events.ts +838 -0
- package/src/voice/events.ts +14 -4
- package/src/voice/generation.ts +52 -9
- package/src/voice/index.ts +1 -0
- package/src/voice/report.test.ts +117 -0
- package/src/voice/report.ts +29 -6
- package/src/voice/room_io/room_io.ts +21 -64
- package/src/voice/testing/fake_llm.ts +138 -0
- package/src/voice/testing/index.ts +2 -0
- package/src/voice/turn_config/endpointing.ts +33 -0
- package/src/voice/turn_config/interruption.ts +56 -0
- package/src/voice/turn_config/turn_handling.ts +45 -0
- package/src/voice/turn_config/utils.test.ts +100 -0
- package/src/voice/turn_config/utils.ts +103 -0
- package/src/voice/wire_format.ts +827 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var ws_transport_exports = {};
|
|
30
|
+
__export(ws_transport_exports, {
|
|
31
|
+
createWsTransport: () => createWsTransport
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(ws_transport_exports);
|
|
34
|
+
var import_web = require("stream/web");
|
|
35
|
+
var import_ws = __toESM(require("ws"), 1);
|
|
36
|
+
var import_zod = require("zod");
|
|
37
|
+
var import_log = require("../../log.cjs");
|
|
38
|
+
var import_utils = require("../utils.cjs");
|
|
39
|
+
var import_defaults = require("./defaults.cjs");
|
|
40
|
+
var import_interruption_cache_entry = require("./interruption_cache_entry.cjs");
|
|
41
|
+
const MSG_SESSION_CREATE = "session.create";
|
|
42
|
+
const MSG_SESSION_CLOSE = "session.close";
|
|
43
|
+
const MSG_SESSION_CREATED = "session.created";
|
|
44
|
+
const MSG_SESSION_CLOSED = "session.closed";
|
|
45
|
+
const MSG_INTERRUPTION_DETECTED = "bargein_detected";
|
|
46
|
+
const MSG_INFERENCE_DONE = "inference_done";
|
|
47
|
+
const MSG_ERROR = "error";
|
|
48
|
+
const wsMessageSchema = import_zod.z.discriminatedUnion("type", [
|
|
49
|
+
import_zod.z.object({
|
|
50
|
+
type: import_zod.z.literal(MSG_SESSION_CREATED)
|
|
51
|
+
}),
|
|
52
|
+
import_zod.z.object({
|
|
53
|
+
type: import_zod.z.literal(MSG_SESSION_CLOSED)
|
|
54
|
+
}),
|
|
55
|
+
import_zod.z.object({
|
|
56
|
+
type: import_zod.z.literal(MSG_INTERRUPTION_DETECTED),
|
|
57
|
+
created_at: import_zod.z.number(),
|
|
58
|
+
probabilities: import_zod.z.array(import_zod.z.number()).default([]),
|
|
59
|
+
prediction_duration: import_zod.z.number().default(0)
|
|
60
|
+
}),
|
|
61
|
+
import_zod.z.object({
|
|
62
|
+
type: import_zod.z.literal(MSG_INFERENCE_DONE),
|
|
63
|
+
created_at: import_zod.z.number(),
|
|
64
|
+
probabilities: import_zod.z.array(import_zod.z.number()).default([]),
|
|
65
|
+
prediction_duration: import_zod.z.number().default(0),
|
|
66
|
+
is_bargein: import_zod.z.boolean().optional()
|
|
67
|
+
}),
|
|
68
|
+
import_zod.z.object({
|
|
69
|
+
type: import_zod.z.literal(MSG_ERROR),
|
|
70
|
+
message: import_zod.z.string(),
|
|
71
|
+
code: import_zod.z.number().optional(),
|
|
72
|
+
session_id: import_zod.z.string().optional()
|
|
73
|
+
})
|
|
74
|
+
]);
|
|
75
|
+
async function connectWebSocket(options) {
|
|
76
|
+
const baseUrl = options.baseUrl.replace(/^http/, "ws");
|
|
77
|
+
const token = await (0, import_utils.createAccessToken)(options.apiKey, options.apiSecret);
|
|
78
|
+
const url = `${baseUrl}/bargein`;
|
|
79
|
+
const ws = new import_ws.default(url, {
|
|
80
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
81
|
+
});
|
|
82
|
+
await new Promise((resolve, reject) => {
|
|
83
|
+
const timeout = setTimeout(() => {
|
|
84
|
+
ws.terminate();
|
|
85
|
+
reject(new Error("WebSocket connection timeout"));
|
|
86
|
+
}, options.timeout);
|
|
87
|
+
ws.once("open", () => {
|
|
88
|
+
clearTimeout(timeout);
|
|
89
|
+
resolve();
|
|
90
|
+
});
|
|
91
|
+
ws.once("error", (err) => {
|
|
92
|
+
clearTimeout(timeout);
|
|
93
|
+
ws.terminate();
|
|
94
|
+
reject(err);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
return ws;
|
|
98
|
+
}
|
|
99
|
+
function createWsTransport(options, getState, setState, updateUserSpeakingSpan, onRequestSent, getAndResetNumRequests) {
|
|
100
|
+
const logger = (0, import_log.log)();
|
|
101
|
+
let ws = null;
|
|
102
|
+
let outputController = null;
|
|
103
|
+
function setupMessageHandler(socket) {
|
|
104
|
+
socket.on("message", (data) => {
|
|
105
|
+
try {
|
|
106
|
+
const message = wsMessageSchema.parse(JSON.parse(data.toString()));
|
|
107
|
+
handleMessage(message);
|
|
108
|
+
} catch {
|
|
109
|
+
logger.warn({ data: data.toString() }, "Failed to parse WebSocket message");
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
socket.on("error", (err) => {
|
|
113
|
+
logger.error({ err }, "WebSocket error");
|
|
114
|
+
});
|
|
115
|
+
socket.on("close", (code, reason) => {
|
|
116
|
+
logger.debug({ code, reason: reason.toString() }, "WebSocket closed");
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
async function ensureConnection() {
|
|
120
|
+
if (ws && ws.readyState === import_ws.default.OPEN) return;
|
|
121
|
+
const maxRetries = options.maxRetries ?? 3;
|
|
122
|
+
let lastError = null;
|
|
123
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
124
|
+
try {
|
|
125
|
+
ws = await connectWebSocket(options);
|
|
126
|
+
setupMessageHandler(ws);
|
|
127
|
+
const sessionCreateMsg = JSON.stringify({
|
|
128
|
+
type: MSG_SESSION_CREATE,
|
|
129
|
+
settings: {
|
|
130
|
+
sample_rate: options.sampleRate,
|
|
131
|
+
num_channels: 1,
|
|
132
|
+
threshold: options.threshold,
|
|
133
|
+
min_frames: options.minFrames,
|
|
134
|
+
encoding: "s16le"
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
ws.send(sessionCreateMsg);
|
|
138
|
+
return;
|
|
139
|
+
} catch (err) {
|
|
140
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
141
|
+
if (attempt < maxRetries) {
|
|
142
|
+
const delay = (0, import_defaults.intervalForRetry)(attempt);
|
|
143
|
+
logger.debug(
|
|
144
|
+
{ attempt, delay, err: lastError.message },
|
|
145
|
+
"WebSocket connection failed, retrying"
|
|
146
|
+
);
|
|
147
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
throw lastError ?? new Error("Failed to connect to WebSocket after retries");
|
|
152
|
+
}
|
|
153
|
+
function handleMessage(message) {
|
|
154
|
+
const state = getState();
|
|
155
|
+
switch (message.type) {
|
|
156
|
+
case MSG_SESSION_CREATED:
|
|
157
|
+
logger.debug("WebSocket session created");
|
|
158
|
+
break;
|
|
159
|
+
case MSG_INTERRUPTION_DETECTED: {
|
|
160
|
+
const createdAt = message.created_at;
|
|
161
|
+
const overlapSpeechStartedAt = state.overlapSpeechStartedAt;
|
|
162
|
+
if (state.overlapSpeechStarted && overlapSpeechStartedAt !== void 0) {
|
|
163
|
+
const existing = state.cache.get(createdAt);
|
|
164
|
+
const totalDurationInS = (existing == null ? void 0 : existing.requestStartedAt) !== void 0 ? (performance.now() - existing.requestStartedAt) / 1e3 : (performance.now() - createdAt) / 1e3;
|
|
165
|
+
const entry = state.cache.setOrUpdate(
|
|
166
|
+
createdAt,
|
|
167
|
+
() => new import_interruption_cache_entry.InterruptionCacheEntry({ createdAt }),
|
|
168
|
+
{
|
|
169
|
+
speechInput: existing == null ? void 0 : existing.speechInput,
|
|
170
|
+
requestStartedAt: existing == null ? void 0 : existing.requestStartedAt,
|
|
171
|
+
totalDurationInS,
|
|
172
|
+
probabilities: message.probabilities,
|
|
173
|
+
isInterruption: true,
|
|
174
|
+
predictionDurationInS: message.prediction_duration,
|
|
175
|
+
detectionDelayInS: (Date.now() - overlapSpeechStartedAt) / 1e3
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
if (updateUserSpeakingSpan) {
|
|
179
|
+
updateUserSpeakingSpan(entry);
|
|
180
|
+
}
|
|
181
|
+
logger.debug(
|
|
182
|
+
{
|
|
183
|
+
totalDuration: entry.totalDurationInS,
|
|
184
|
+
predictionDuration: entry.predictionDurationInS,
|
|
185
|
+
detectionDelay: entry.detectionDelayInS,
|
|
186
|
+
probability: entry.probability
|
|
187
|
+
},
|
|
188
|
+
"interruption detected"
|
|
189
|
+
);
|
|
190
|
+
const event = {
|
|
191
|
+
type: "user_overlapping_speech",
|
|
192
|
+
timestamp: Date.now(),
|
|
193
|
+
isInterruption: true,
|
|
194
|
+
totalDurationInS: entry.totalDurationInS,
|
|
195
|
+
predictionDurationInS: entry.predictionDurationInS,
|
|
196
|
+
overlapStartedAt: overlapSpeechStartedAt,
|
|
197
|
+
speechInput: entry.speechInput,
|
|
198
|
+
probabilities: entry.probabilities,
|
|
199
|
+
detectionDelayInS: entry.detectionDelayInS,
|
|
200
|
+
probability: entry.probability,
|
|
201
|
+
numRequests: (getAndResetNumRequests == null ? void 0 : getAndResetNumRequests()) ?? 0
|
|
202
|
+
};
|
|
203
|
+
outputController == null ? void 0 : outputController.enqueue(event);
|
|
204
|
+
setState({ overlapSpeechStarted: false });
|
|
205
|
+
}
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case MSG_INFERENCE_DONE: {
|
|
209
|
+
const createdAt = message.created_at;
|
|
210
|
+
const overlapSpeechStartedAt = state.overlapSpeechStartedAt;
|
|
211
|
+
if (state.overlapSpeechStarted && overlapSpeechStartedAt !== void 0) {
|
|
212
|
+
const existing = state.cache.get(createdAt);
|
|
213
|
+
const totalDurationInS = (existing == null ? void 0 : existing.requestStartedAt) !== void 0 ? (performance.now() - existing.requestStartedAt) / 1e3 : (performance.now() - createdAt) / 1e3;
|
|
214
|
+
const entry = state.cache.setOrUpdate(
|
|
215
|
+
createdAt,
|
|
216
|
+
() => new import_interruption_cache_entry.InterruptionCacheEntry({ createdAt }),
|
|
217
|
+
{
|
|
218
|
+
speechInput: existing == null ? void 0 : existing.speechInput,
|
|
219
|
+
requestStartedAt: existing == null ? void 0 : existing.requestStartedAt,
|
|
220
|
+
totalDurationInS,
|
|
221
|
+
predictionDurationInS: message.prediction_duration,
|
|
222
|
+
probabilities: message.probabilities,
|
|
223
|
+
isInterruption: message.is_bargein ?? false,
|
|
224
|
+
detectionDelayInS: (Date.now() - overlapSpeechStartedAt) / 1e3
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
logger.debug(
|
|
228
|
+
{
|
|
229
|
+
totalDurationInS: entry.totalDurationInS,
|
|
230
|
+
predictionDurationInS: entry.predictionDurationInS
|
|
231
|
+
},
|
|
232
|
+
"interruption inference done"
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case MSG_SESSION_CLOSED:
|
|
238
|
+
logger.debug("WebSocket session closed");
|
|
239
|
+
break;
|
|
240
|
+
case MSG_ERROR:
|
|
241
|
+
outputController == null ? void 0 : outputController.error(
|
|
242
|
+
new Error(
|
|
243
|
+
`LiveKit Adaptive Interruption error${message.code !== void 0 ? ` (${message.code})` : ""}: ${message.message}`
|
|
244
|
+
)
|
|
245
|
+
);
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function sendAudioData(audioSlice) {
|
|
250
|
+
if (!ws || ws.readyState !== import_ws.default.OPEN) {
|
|
251
|
+
throw new Error("WebSocket not connected");
|
|
252
|
+
}
|
|
253
|
+
const state = getState();
|
|
254
|
+
const createdAt = Math.floor(performance.now());
|
|
255
|
+
state.cache.set(
|
|
256
|
+
createdAt,
|
|
257
|
+
new import_interruption_cache_entry.InterruptionCacheEntry({
|
|
258
|
+
createdAt,
|
|
259
|
+
requestStartedAt: performance.now(),
|
|
260
|
+
speechInput: audioSlice
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
const header = new ArrayBuffer(8);
|
|
264
|
+
const view = new DataView(header);
|
|
265
|
+
view.setUint32(0, createdAt >>> 0, true);
|
|
266
|
+
view.setUint32(4, Math.floor(createdAt / 4294967296) >>> 0, true);
|
|
267
|
+
const audioBytes = new Uint8Array(
|
|
268
|
+
audioSlice.buffer,
|
|
269
|
+
audioSlice.byteOffset,
|
|
270
|
+
audioSlice.byteLength
|
|
271
|
+
);
|
|
272
|
+
const combined = new Uint8Array(8 + audioBytes.length);
|
|
273
|
+
combined.set(new Uint8Array(header), 0);
|
|
274
|
+
combined.set(audioBytes, 8);
|
|
275
|
+
try {
|
|
276
|
+
ws.send(combined);
|
|
277
|
+
onRequestSent == null ? void 0 : onRequestSent();
|
|
278
|
+
} catch (e) {
|
|
279
|
+
logger.error(e, `failed to send audio via websocket`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function close() {
|
|
283
|
+
if ((ws == null ? void 0 : ws.readyState) === import_ws.default.OPEN) {
|
|
284
|
+
const closeMsg = JSON.stringify({ type: MSG_SESSION_CLOSE });
|
|
285
|
+
try {
|
|
286
|
+
ws.send(closeMsg);
|
|
287
|
+
} catch (e) {
|
|
288
|
+
logger.error(e, "failed to send close message");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
ws == null ? void 0 : ws.close(1e3);
|
|
292
|
+
ws = null;
|
|
293
|
+
}
|
|
294
|
+
async function reconnect() {
|
|
295
|
+
close();
|
|
296
|
+
}
|
|
297
|
+
const transport = new import_web.TransformStream(
|
|
298
|
+
{
|
|
299
|
+
async start(controller) {
|
|
300
|
+
outputController = controller;
|
|
301
|
+
await ensureConnection();
|
|
302
|
+
},
|
|
303
|
+
transform(chunk, controller) {
|
|
304
|
+
if (!(chunk instanceof Int16Array)) {
|
|
305
|
+
controller.enqueue(chunk);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const state = getState();
|
|
309
|
+
if (!state.overlapSpeechStartedAt || !state.overlapSpeechStarted) return;
|
|
310
|
+
try {
|
|
311
|
+
sendAudioData(chunk);
|
|
312
|
+
} catch (err) {
|
|
313
|
+
logger.error({ err }, "Failed to send audio data over WebSocket");
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
flush() {
|
|
317
|
+
close();
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
{ highWaterMark: 2 },
|
|
321
|
+
{ highWaterMark: 2 }
|
|
322
|
+
);
|
|
323
|
+
return { transport, reconnect };
|
|
324
|
+
}
|
|
325
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
326
|
+
0 && (module.exports = {
|
|
327
|
+
createWsTransport
|
|
328
|
+
});
|
|
329
|
+
//# sourceMappingURL=ws_transport.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/inference/interruption/ws_transport.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { TransformStream } from 'stream/web';\nimport WebSocket from 'ws';\nimport { z } from 'zod';\nimport { log } from '../../log.js';\nimport { createAccessToken } from '../utils.js';\nimport { intervalForRetry } from './defaults.js';\nimport { InterruptionCacheEntry } from './interruption_cache_entry.js';\nimport type { OverlappingSpeechEvent } from './types.js';\nimport type { BoundedCache } from './utils.js';\n\n// WebSocket message types\nconst MSG_SESSION_CREATE = 'session.create';\nconst MSG_SESSION_CLOSE = 'session.close';\nconst MSG_SESSION_CREATED = 'session.created';\nconst MSG_SESSION_CLOSED = 'session.closed';\nconst MSG_INTERRUPTION_DETECTED = 'bargein_detected';\nconst MSG_INFERENCE_DONE = 'inference_done';\nconst MSG_ERROR = 'error';\n\nexport interface WsTransportOptions {\n baseUrl: string;\n apiKey: string;\n apiSecret: string;\n sampleRate: number;\n threshold: number;\n minFrames: number;\n timeout: number;\n maxRetries?: number;\n}\n\nexport interface WsTransportState {\n overlapSpeechStarted: boolean;\n overlapSpeechStartedAt: number | undefined;\n cache: BoundedCache<number, InterruptionCacheEntry>;\n}\n\nconst wsMessageSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal(MSG_SESSION_CREATED),\n }),\n z.object({\n type: z.literal(MSG_SESSION_CLOSED),\n }),\n z.object({\n type: z.literal(MSG_INTERRUPTION_DETECTED),\n created_at: z.number(),\n probabilities: z.array(z.number()).default([]),\n prediction_duration: z.number().default(0),\n }),\n z.object({\n type: z.literal(MSG_INFERENCE_DONE),\n created_at: z.number(),\n probabilities: z.array(z.number()).default([]),\n prediction_duration: z.number().default(0),\n is_bargein: z.boolean().optional(),\n }),\n z.object({\n type: z.literal(MSG_ERROR),\n message: z.string(),\n code: z.number().optional(),\n session_id: z.string().optional(),\n }),\n]);\n\ntype WsMessage = z.infer<typeof wsMessageSchema>;\n\n/**\n * Creates a WebSocket connection and waits for it to open.\n */\nasync function connectWebSocket(options: WsTransportOptions): Promise<WebSocket> {\n const baseUrl = options.baseUrl.replace(/^http/, 'ws');\n const token = await createAccessToken(options.apiKey, options.apiSecret);\n const url = `${baseUrl}/bargein`;\n\n const ws = new WebSocket(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.terminate();\n reject(new Error('WebSocket connection timeout'));\n }, options.timeout);\n ws.once('open', () => {\n clearTimeout(timeout);\n resolve();\n });\n ws.once('error', (err: Error) => {\n clearTimeout(timeout);\n ws.terminate();\n reject(err);\n });\n });\n\n return ws;\n}\n\nexport interface WsTransportResult {\n transport: TransformStream<Int16Array | OverlappingSpeechEvent, OverlappingSpeechEvent>;\n reconnect: () => Promise<void>;\n}\n\n/**\n * Creates a WebSocket transport TransformStream for interruption detection.\n *\n * This transport receives Int16Array audio slices and outputs InterruptionEvents.\n * It maintains a persistent WebSocket connection with automatic retry on failure.\n * Returns both the transport and a reconnect function for option updates.\n */\nexport function createWsTransport(\n options: WsTransportOptions,\n getState: () => WsTransportState,\n setState: (partial: Partial<WsTransportState>) => void,\n updateUserSpeakingSpan?: (entry: InterruptionCacheEntry) => void,\n onRequestSent?: () => void,\n getAndResetNumRequests?: () => number,\n): WsTransportResult {\n const logger = log();\n let ws: WebSocket | null = null;\n let outputController: TransformStreamDefaultController<OverlappingSpeechEvent> | null = null;\n\n function setupMessageHandler(socket: WebSocket): void {\n socket.on('message', (data: WebSocket.Data) => {\n try {\n const message = wsMessageSchema.parse(JSON.parse(data.toString()));\n handleMessage(message);\n } catch {\n logger.warn({ data: data.toString() }, 'Failed to parse WebSocket message');\n }\n });\n\n socket.on('error', (err: Error) => {\n logger.error({ err }, 'WebSocket error');\n });\n\n socket.on('close', (code: number, reason: Buffer) => {\n logger.debug({ code, reason: reason.toString() }, 'WebSocket closed');\n });\n }\n\n async function ensureConnection(): Promise<void> {\n if (ws && ws.readyState === WebSocket.OPEN) return;\n\n const maxRetries = options.maxRetries ?? 3;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n ws = await connectWebSocket(options);\n setupMessageHandler(ws);\n\n // Send session.create message\n const sessionCreateMsg = JSON.stringify({\n type: MSG_SESSION_CREATE,\n settings: {\n sample_rate: options.sampleRate,\n num_channels: 1,\n threshold: options.threshold,\n min_frames: options.minFrames,\n encoding: 's16le',\n },\n });\n ws.send(sessionCreateMsg);\n return;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n if (attempt < maxRetries) {\n const delay = intervalForRetry(attempt);\n logger.debug(\n { attempt, delay, err: lastError.message },\n 'WebSocket connection failed, retrying',\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError ?? new Error('Failed to connect to WebSocket after retries');\n }\n\n function handleMessage(message: WsMessage): void {\n const state = getState();\n\n switch (message.type) {\n case MSG_SESSION_CREATED:\n logger.debug('WebSocket session created');\n break;\n\n case MSG_INTERRUPTION_DETECTED: {\n const createdAt = message.created_at;\n const overlapSpeechStartedAt = state.overlapSpeechStartedAt;\n if (state.overlapSpeechStarted && overlapSpeechStartedAt !== undefined) {\n const existing = state.cache.get(createdAt);\n\n const totalDurationInS =\n existing?.requestStartedAt !== undefined\n ? (performance.now() - existing.requestStartedAt) / 1000\n : (performance.now() - createdAt) / 1000;\n\n const entry = state.cache.setOrUpdate(\n createdAt,\n () => new InterruptionCacheEntry({ createdAt }),\n {\n speechInput: existing?.speechInput,\n requestStartedAt: existing?.requestStartedAt,\n totalDurationInS,\n probabilities: message.probabilities,\n isInterruption: true,\n predictionDurationInS: message.prediction_duration,\n detectionDelayInS: (Date.now() - overlapSpeechStartedAt) / 1000,\n },\n );\n\n if (updateUserSpeakingSpan) {\n updateUserSpeakingSpan(entry);\n }\n\n logger.debug(\n {\n totalDuration: entry.totalDurationInS,\n predictionDuration: entry.predictionDurationInS,\n detectionDelay: entry.detectionDelayInS,\n probability: entry.probability,\n },\n 'interruption detected',\n );\n\n const event: OverlappingSpeechEvent = {\n type: 'user_overlapping_speech',\n timestamp: Date.now(),\n isInterruption: true,\n totalDurationInS: entry.totalDurationInS,\n predictionDurationInS: entry.predictionDurationInS,\n overlapStartedAt: overlapSpeechStartedAt,\n speechInput: entry.speechInput,\n probabilities: entry.probabilities,\n detectionDelayInS: entry.detectionDelayInS,\n probability: entry.probability,\n numRequests: getAndResetNumRequests?.() ?? 0,\n };\n\n outputController?.enqueue(event);\n setState({ overlapSpeechStarted: false });\n }\n break;\n }\n\n case MSG_INFERENCE_DONE: {\n const createdAt = message.created_at;\n const overlapSpeechStartedAt = state.overlapSpeechStartedAt;\n if (state.overlapSpeechStarted && overlapSpeechStartedAt !== undefined) {\n const existing = state.cache.get(createdAt);\n const totalDurationInS =\n existing?.requestStartedAt !== undefined\n ? (performance.now() - existing.requestStartedAt) / 1000\n : (performance.now() - createdAt) / 1000;\n const entry = state.cache.setOrUpdate(\n createdAt,\n () => new InterruptionCacheEntry({ createdAt }),\n {\n speechInput: existing?.speechInput,\n requestStartedAt: existing?.requestStartedAt,\n totalDurationInS,\n predictionDurationInS: message.prediction_duration,\n probabilities: message.probabilities,\n isInterruption: message.is_bargein ?? false,\n detectionDelayInS: (Date.now() - overlapSpeechStartedAt) / 1000,\n },\n );\n\n logger.debug(\n {\n totalDurationInS: entry.totalDurationInS,\n predictionDurationInS: entry.predictionDurationInS,\n },\n 'interruption inference done',\n );\n }\n break;\n }\n\n case MSG_SESSION_CLOSED:\n logger.debug('WebSocket session closed');\n break;\n\n case MSG_ERROR:\n outputController?.error(\n new Error(\n `LiveKit Adaptive Interruption error${\n message.code !== undefined ? ` (${message.code})` : ''\n }: ${message.message}`,\n ),\n );\n break;\n }\n }\n\n function sendAudioData(audioSlice: Int16Array): void {\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket not connected');\n }\n\n const state = getState();\n // Use truncated timestamp consistently for both cache key and header\n // This ensures the server's response created_at matches our cache key\n const createdAt = Math.floor(performance.now());\n\n // Store the audio data in cache with truncated timestamp\n state.cache.set(\n createdAt,\n new InterruptionCacheEntry({\n createdAt,\n requestStartedAt: performance.now(),\n speechInput: audioSlice,\n }),\n );\n\n // Create header: 8-byte little-endian uint64 timestamp (milliseconds as integer)\n const header = new ArrayBuffer(8);\n const view = new DataView(header);\n view.setUint32(0, createdAt >>> 0, true);\n view.setUint32(4, Math.floor(createdAt / 0x100000000) >>> 0, true);\n\n // Combine header and audio data\n const audioBytes = new Uint8Array(\n audioSlice.buffer,\n audioSlice.byteOffset,\n audioSlice.byteLength,\n );\n const combined = new Uint8Array(8 + audioBytes.length);\n combined.set(new Uint8Array(header), 0);\n combined.set(audioBytes, 8);\n\n try {\n ws.send(combined);\n onRequestSent?.();\n } catch (e: unknown) {\n logger.error(e, `failed to send audio via websocket`);\n }\n }\n\n function close(): void {\n if (ws?.readyState === WebSocket.OPEN) {\n const closeMsg = JSON.stringify({ type: MSG_SESSION_CLOSE });\n try {\n ws.send(closeMsg);\n } catch (e: unknown) {\n logger.error(e, 'failed to send close message');\n }\n }\n ws?.close(1000); // signal normal websocket closure\n ws = null;\n }\n\n /**\n * Reconnect the WebSocket with updated options.\n * This is called when options are updated via updateOptions().\n */\n async function reconnect(): Promise<void> {\n close();\n }\n\n const transport = new TransformStream<\n Int16Array | OverlappingSpeechEvent,\n OverlappingSpeechEvent\n >(\n {\n async start(controller) {\n outputController = controller;\n await ensureConnection();\n },\n\n transform(chunk, controller) {\n if (!(chunk instanceof Int16Array)) {\n controller.enqueue(chunk);\n return;\n }\n\n // Only forwards buffered audio while overlap speech is actively on.\n const state = getState();\n if (!state.overlapSpeechStartedAt || !state.overlapSpeechStarted) return;\n\n try {\n sendAudioData(chunk);\n } catch (err) {\n logger.error({ err }, 'Failed to send audio data over WebSocket');\n }\n },\n\n flush() {\n close();\n },\n },\n { highWaterMark: 2 },\n { highWaterMark: 2 },\n );\n\n return { transport, reconnect };\n}\n"],"mappings":"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","names":["WebSocket"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { TransformStream } from 'stream/web';
|
|
3
|
+
import { InterruptionCacheEntry } from './interruption_cache_entry.js';
|
|
4
|
+
import type { OverlappingSpeechEvent } from './types.js';
|
|
5
|
+
import type { BoundedCache } from './utils.js';
|
|
6
|
+
export interface WsTransportOptions {
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
apiSecret: string;
|
|
10
|
+
sampleRate: number;
|
|
11
|
+
threshold: number;
|
|
12
|
+
minFrames: number;
|
|
13
|
+
timeout: number;
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface WsTransportState {
|
|
17
|
+
overlapSpeechStarted: boolean;
|
|
18
|
+
overlapSpeechStartedAt: number | undefined;
|
|
19
|
+
cache: BoundedCache<number, InterruptionCacheEntry>;
|
|
20
|
+
}
|
|
21
|
+
export interface WsTransportResult {
|
|
22
|
+
transport: TransformStream<Int16Array | OverlappingSpeechEvent, OverlappingSpeechEvent>;
|
|
23
|
+
reconnect: () => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a WebSocket transport TransformStream for interruption detection.
|
|
27
|
+
*
|
|
28
|
+
* This transport receives Int16Array audio slices and outputs InterruptionEvents.
|
|
29
|
+
* It maintains a persistent WebSocket connection with automatic retry on failure.
|
|
30
|
+
* Returns both the transport and a reconnect function for option updates.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createWsTransport(options: WsTransportOptions, getState: () => WsTransportState, setState: (partial: Partial<WsTransportState>) => void, updateUserSpeakingSpan?: (entry: InterruptionCacheEntry) => void, onRequestSent?: () => void, getAndResetNumRequests?: () => number): WsTransportResult;
|
|
33
|
+
//# sourceMappingURL=ws_transport.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { TransformStream } from 'stream/web';
|
|
3
|
+
import { InterruptionCacheEntry } from './interruption_cache_entry.js';
|
|
4
|
+
import type { OverlappingSpeechEvent } from './types.js';
|
|
5
|
+
import type { BoundedCache } from './utils.js';
|
|
6
|
+
export interface WsTransportOptions {
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
apiSecret: string;
|
|
10
|
+
sampleRate: number;
|
|
11
|
+
threshold: number;
|
|
12
|
+
minFrames: number;
|
|
13
|
+
timeout: number;
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface WsTransportState {
|
|
17
|
+
overlapSpeechStarted: boolean;
|
|
18
|
+
overlapSpeechStartedAt: number | undefined;
|
|
19
|
+
cache: BoundedCache<number, InterruptionCacheEntry>;
|
|
20
|
+
}
|
|
21
|
+
export interface WsTransportResult {
|
|
22
|
+
transport: TransformStream<Int16Array | OverlappingSpeechEvent, OverlappingSpeechEvent>;
|
|
23
|
+
reconnect: () => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a WebSocket transport TransformStream for interruption detection.
|
|
27
|
+
*
|
|
28
|
+
* This transport receives Int16Array audio slices and outputs InterruptionEvents.
|
|
29
|
+
* It maintains a persistent WebSocket connection with automatic retry on failure.
|
|
30
|
+
* Returns both the transport and a reconnect function for option updates.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createWsTransport(options: WsTransportOptions, getState: () => WsTransportState, setState: (partial: Partial<WsTransportState>) => void, updateUserSpeakingSpan?: (entry: InterruptionCacheEntry) => void, onRequestSent?: () => void, getAndResetNumRequests?: () => number): WsTransportResult;
|
|
33
|
+
//# sourceMappingURL=ws_transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws_transport.d.ts","sourceRoot":"","sources":["../../../src/inference/interruption/ws_transport.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAM7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAW/C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CACrD;AA+DD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,eAAe,CAAC,UAAU,GAAG,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;IACxF,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,MAAM,gBAAgB,EAChC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,IAAI,EACtD,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,EAChE,aAAa,CAAC,EAAE,MAAM,IAAI,EAC1B,sBAAsB,CAAC,EAAE,MAAM,MAAM,GACpC,iBAAiB,CA0RnB"}
|