@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,138 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import type { ChatContext } from '../../llm/chat_context.js';
|
|
5
|
+
import { FunctionCall } from '../../llm/chat_context.js';
|
|
6
|
+
import { LLMStream as BaseLLMStream, LLM, type LLMStream } from '../../llm/llm.js';
|
|
7
|
+
import type { ToolChoice, ToolContext } from '../../llm/tool_context.js';
|
|
8
|
+
import { type APIConnectOptions, DEFAULT_API_CONNECT_OPTIONS } from '../../types.js';
|
|
9
|
+
import { delay } from '../../utils.js';
|
|
10
|
+
|
|
11
|
+
export interface FakeLLMResponse {
|
|
12
|
+
input: string;
|
|
13
|
+
type?: 'llm';
|
|
14
|
+
content?: string;
|
|
15
|
+
ttft?: number;
|
|
16
|
+
duration?: number;
|
|
17
|
+
toolCalls?: Array<{ name: string; args: Record<string, unknown> }>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class FakeLLM extends LLM {
|
|
21
|
+
private readonly responseMap = new Map<string, FakeLLMResponse>();
|
|
22
|
+
|
|
23
|
+
constructor(responses: FakeLLMResponse[] = []) {
|
|
24
|
+
super();
|
|
25
|
+
for (const response of responses) {
|
|
26
|
+
this.responseMap.set(response.input, {
|
|
27
|
+
type: 'llm',
|
|
28
|
+
ttft: 0,
|
|
29
|
+
duration: 0,
|
|
30
|
+
...response,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
label(): string {
|
|
36
|
+
return 'fake-llm';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
chat({
|
|
40
|
+
chatCtx,
|
|
41
|
+
toolCtx,
|
|
42
|
+
connOptions = DEFAULT_API_CONNECT_OPTIONS,
|
|
43
|
+
}: {
|
|
44
|
+
chatCtx: ChatContext;
|
|
45
|
+
toolCtx?: ToolContext;
|
|
46
|
+
connOptions?: APIConnectOptions;
|
|
47
|
+
parallelToolCalls?: boolean;
|
|
48
|
+
toolChoice?: ToolChoice;
|
|
49
|
+
extraKwargs?: Record<string, unknown>;
|
|
50
|
+
}): LLMStream {
|
|
51
|
+
return new FakeLLMStream(this, {
|
|
52
|
+
chatCtx,
|
|
53
|
+
toolCtx,
|
|
54
|
+
connOptions,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
lookup(input: string): FakeLLMResponse | undefined {
|
|
59
|
+
return this.responseMap.get(input);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class FakeLLMStream extends BaseLLMStream {
|
|
64
|
+
private readonly fake: FakeLLM;
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
fake: FakeLLM,
|
|
68
|
+
params: { chatCtx: ChatContext; toolCtx?: ToolContext; connOptions: APIConnectOptions },
|
|
69
|
+
) {
|
|
70
|
+
super(fake, params);
|
|
71
|
+
this.fake = fake;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected async run(): Promise<void> {
|
|
75
|
+
const input = this.getInputText();
|
|
76
|
+
const decision = this.fake.lookup(input);
|
|
77
|
+
if (!decision) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const startedAt = Date.now();
|
|
82
|
+
if ((decision.ttft ?? 0) > 0) {
|
|
83
|
+
await delay(decision.ttft!);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const content = decision.content ?? '';
|
|
87
|
+
const chunkSize = 3;
|
|
88
|
+
for (let i = 0; i < content.length; i += chunkSize) {
|
|
89
|
+
this.queue.put({
|
|
90
|
+
id: 'fake',
|
|
91
|
+
delta: { role: 'assistant', content: content.slice(i, i + chunkSize) },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (decision.toolCalls && decision.toolCalls.length > 0) {
|
|
96
|
+
const calls = decision.toolCalls.map((tc, index) =>
|
|
97
|
+
FunctionCall.create({
|
|
98
|
+
callId: `fake_call_${index}`,
|
|
99
|
+
name: tc.name,
|
|
100
|
+
args: JSON.stringify(tc.args),
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
103
|
+
this.queue.put({
|
|
104
|
+
id: 'fake',
|
|
105
|
+
delta: { role: 'assistant', toolCalls: calls },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const elapsed = Date.now() - startedAt;
|
|
110
|
+
const waitMs = Math.max(0, (decision.duration ?? 0) - elapsed);
|
|
111
|
+
if (waitMs > 0) {
|
|
112
|
+
await delay(waitMs);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private getInputText(): string {
|
|
117
|
+
const items = this.chatCtx.items;
|
|
118
|
+
if (items.length === 0) {
|
|
119
|
+
throw new Error('No input text found');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (const item of items) {
|
|
123
|
+
if (item.type === 'message' && item.role === 'system') {
|
|
124
|
+
const text = item.textContent ?? '';
|
|
125
|
+
const lines = text.split('\n');
|
|
126
|
+
const tail = lines[lines.length - 1] ?? '';
|
|
127
|
+
if (lines.length > 1 && tail.startsWith('instructions:')) {
|
|
128
|
+
return tail;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const last = items[items.length - 1]!;
|
|
134
|
+
if (last.type === 'message' && last.role === 'user') return last.textContent ?? '';
|
|
135
|
+
if (last.type === 'function_call_output') return last.output;
|
|
136
|
+
throw new Error('No input text found');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for endpointing, which determines when the user's turn is complete.
|
|
6
|
+
*/
|
|
7
|
+
export interface EndpointingOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Endpointing mode. `"fixed"` uses a fixed delay, `"dynamic"` adjusts delay based on
|
|
10
|
+
* end-of-utterance prediction.
|
|
11
|
+
* @defaultValue "fixed"
|
|
12
|
+
*/
|
|
13
|
+
mode: 'fixed' | 'dynamic';
|
|
14
|
+
/**
|
|
15
|
+
* Minimum time in milliseconds since the last detected speech before the agent declares the user's
|
|
16
|
+
* turn complete. In VAD mode this effectively behaves like `max(VAD silence, minDelay)`;
|
|
17
|
+
* in STT mode it is applied after the STT end-of-speech signal, so it can be additive with
|
|
18
|
+
* the STT provider's endpointing delay.
|
|
19
|
+
* @defaultValue 500
|
|
20
|
+
*/
|
|
21
|
+
minDelay: number;
|
|
22
|
+
/**
|
|
23
|
+
* Maximum time in milliseconds the agent will wait before terminating the turn.
|
|
24
|
+
* @defaultValue 3000
|
|
25
|
+
*/
|
|
26
|
+
maxDelay: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const defaultEndpointingOptions = {
|
|
30
|
+
mode: 'fixed',
|
|
31
|
+
minDelay: 500,
|
|
32
|
+
maxDelay: 3000,
|
|
33
|
+
} as const satisfies EndpointingOptions;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for interruption handling.
|
|
6
|
+
*/
|
|
7
|
+
export interface InterruptionOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Whether interruptions are enabled.
|
|
10
|
+
* @defaultValue true
|
|
11
|
+
*/
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Interruption handling strategy. `"adaptive"` for ML-based detection, `"vad"` for simple
|
|
15
|
+
* voice-activity detection. `undefined` means auto-detect.
|
|
16
|
+
* @defaultValue undefined
|
|
17
|
+
*/
|
|
18
|
+
mode: 'adaptive' | 'vad' | false | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* When `true`, buffered audio is dropped while the agent is speaking and cannot be interrupted.
|
|
21
|
+
* @defaultValue true
|
|
22
|
+
*/
|
|
23
|
+
discardAudioIfUninterruptible: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Minimum speech length in milliseconds to register as an interruption.
|
|
26
|
+
* @defaultValue 500
|
|
27
|
+
*/
|
|
28
|
+
minDuration: number;
|
|
29
|
+
/**
|
|
30
|
+
* Minimum number of words to consider an interruption, only used if STT is enabled.
|
|
31
|
+
* @defaultValue 0
|
|
32
|
+
*/
|
|
33
|
+
minWords: number;
|
|
34
|
+
/**
|
|
35
|
+
* If set, emit an `agentFalseInterruption` event after this amount of time if the user is
|
|
36
|
+
* silent and no user transcript is detected after the interruption. Set to `undefined` to
|
|
37
|
+
* disable. The value is in milliseconds.
|
|
38
|
+
* @defaultValue 2000
|
|
39
|
+
*/
|
|
40
|
+
falseInterruptionTimeout: number;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to resume the false interruption after the `falseInterruptionTimeout`.
|
|
43
|
+
* @defaultValue true
|
|
44
|
+
*/
|
|
45
|
+
resumeFalseInterruption: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const defaultInterruptionOptions = {
|
|
49
|
+
enabled: true,
|
|
50
|
+
mode: undefined,
|
|
51
|
+
discardAudioIfUninterruptible: true,
|
|
52
|
+
minDuration: 500,
|
|
53
|
+
minWords: 0,
|
|
54
|
+
falseInterruptionTimeout: 2000,
|
|
55
|
+
resumeFalseInterruption: true,
|
|
56
|
+
} as const satisfies InterruptionOptions;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import type { TurnDetectionMode } from '../agent_session.js';
|
|
5
|
+
import { type EndpointingOptions, defaultEndpointingOptions } from './endpointing.js';
|
|
6
|
+
import { type InterruptionOptions, defaultInterruptionOptions } from './interruption.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for the turn handling system. Used to configure the turn taking behavior of the
|
|
10
|
+
* session.
|
|
11
|
+
*/
|
|
12
|
+
export interface TurnHandlingOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Strategy for deciding when the user has finished speaking.
|
|
15
|
+
*
|
|
16
|
+
* - `"stt"` – rely on speech-to-text end-of-utterance cues
|
|
17
|
+
* - `"vad"` – rely on Voice Activity Detection start/stop cues
|
|
18
|
+
* - `"realtime_llm"` – use server-side detection from a realtime LLM
|
|
19
|
+
* - `"manual"` – caller controls turn boundaries explicitly
|
|
20
|
+
*
|
|
21
|
+
* If not set, the session chooses the best available mode in priority order
|
|
22
|
+
* `realtime_llm → vad → stt → manual`; it automatically falls back if the necessary model
|
|
23
|
+
* is missing.
|
|
24
|
+
*/
|
|
25
|
+
turnDetection: TurnDetectionMode | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for endpointing.
|
|
28
|
+
*/
|
|
29
|
+
endpointing: Partial<EndpointingOptions>;
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for interruption handling.
|
|
32
|
+
*/
|
|
33
|
+
interruption: Partial<InterruptionOptions>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface InternalTurnHandlingOptions extends TurnHandlingOptions {
|
|
37
|
+
endpointing: EndpointingOptions;
|
|
38
|
+
interruption: InterruptionOptions;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const defaultTurnHandlingOptions: InternalTurnHandlingOptions = {
|
|
42
|
+
turnDetection: undefined,
|
|
43
|
+
interruption: defaultInterruptionOptions,
|
|
44
|
+
endpointing: defaultEndpointingOptions,
|
|
45
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { beforeAll, describe, expect, it } from 'vitest';
|
|
5
|
+
import { initializeLogger } from '../../log.js';
|
|
6
|
+
import { defaultEndpointingOptions } from './endpointing.js';
|
|
7
|
+
import { defaultInterruptionOptions } from './interruption.js';
|
|
8
|
+
import { defaultTurnHandlingOptions } from './turn_handling.js';
|
|
9
|
+
import { migrateLegacyOptions } from './utils.js';
|
|
10
|
+
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
initializeLogger({ pretty: true, level: 'info' });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('migrateLegacyOptions', () => {
|
|
16
|
+
it('should return all defaults when no options are provided', () => {
|
|
17
|
+
const result = migrateLegacyOptions({});
|
|
18
|
+
|
|
19
|
+
expect(result.options.turnHandling).toEqual({
|
|
20
|
+
turnDetection: defaultTurnHandlingOptions.turnDetection,
|
|
21
|
+
endpointing: defaultEndpointingOptions,
|
|
22
|
+
interruption: defaultInterruptionOptions,
|
|
23
|
+
});
|
|
24
|
+
expect(result.options.maxToolSteps).toBe(3);
|
|
25
|
+
expect(result.options.preemptiveGeneration).toBe(false);
|
|
26
|
+
expect(result.options.userAwayTimeout).toBe(15.0);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should migrate legacy flat fields into nested turnHandling config', () => {
|
|
30
|
+
const result = migrateLegacyOptions({
|
|
31
|
+
voiceOptions: {
|
|
32
|
+
minInterruptionDuration: 1000,
|
|
33
|
+
minInterruptionWords: 3,
|
|
34
|
+
discardAudioIfUninterruptible: false,
|
|
35
|
+
minEndpointingDelay: 800,
|
|
36
|
+
maxEndpointingDelay: 5000,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(result.options.turnHandling.interruption!.minDuration).toBe(1000);
|
|
41
|
+
expect(result.options.turnHandling.interruption!.minWords).toBe(3);
|
|
42
|
+
expect(result.options.turnHandling.interruption!.discardAudioIfUninterruptible).toBe(false);
|
|
43
|
+
expect(result.options.turnHandling.endpointing!.minDelay).toBe(800);
|
|
44
|
+
expect(result.options.turnHandling.endpointing!.maxDelay).toBe(5000);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should set interruption.enabled to false when allowInterruptions is false', () => {
|
|
48
|
+
const result = migrateLegacyOptions({
|
|
49
|
+
options: {
|
|
50
|
+
allowInterruptions: false,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
expect(result.options.turnHandling.interruption!.enabled).toBe(false);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should give options precedence over voiceOptions when both are provided', () => {
|
|
58
|
+
const result = migrateLegacyOptions({
|
|
59
|
+
voiceOptions: {
|
|
60
|
+
minInterruptionDuration: 1000,
|
|
61
|
+
maxEndpointingDelay: 5000,
|
|
62
|
+
maxToolSteps: 10,
|
|
63
|
+
},
|
|
64
|
+
options: {
|
|
65
|
+
minInterruptionDuration: 2000,
|
|
66
|
+
maxEndpointingDelay: 8000,
|
|
67
|
+
maxToolSteps: 5,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(result.options.turnHandling.interruption!.minDuration).toBe(2000);
|
|
72
|
+
expect(result.options.turnHandling.endpointing!.maxDelay).toBe(8000);
|
|
73
|
+
expect(result.options.maxToolSteps).toBe(5);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should let explicit turnHandling override legacy flat fields', () => {
|
|
77
|
+
const result = migrateLegacyOptions({
|
|
78
|
+
options: {
|
|
79
|
+
minInterruptionDuration: 1000,
|
|
80
|
+
minEndpointingDelay: 800,
|
|
81
|
+
turnHandling: {
|
|
82
|
+
interruption: { minDuration: 3000 },
|
|
83
|
+
endpointing: { minDelay: 2000 },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(result.options.turnHandling.interruption!.minDuration).toBe(3000);
|
|
89
|
+
expect(result.options.turnHandling.endpointing!.minDelay).toBe(2000);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should preserve top-level turnDetection in the result', () => {
|
|
93
|
+
const result = migrateLegacyOptions({
|
|
94
|
+
turnDetection: 'vad',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(result.turnDetection).toBe('vad');
|
|
98
|
+
expect(result.options.turnHandling.turnDetection).toBe('vad');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { log } from '../../log.js';
|
|
5
|
+
import {
|
|
6
|
+
type AgentSessionOptions,
|
|
7
|
+
type InternalSessionOptions,
|
|
8
|
+
defaultSessionOptions,
|
|
9
|
+
} from '../agent_session.js';
|
|
10
|
+
import { defaultEndpointingOptions } from './endpointing.js';
|
|
11
|
+
import { defaultInterruptionOptions } from './interruption.js';
|
|
12
|
+
import { type TurnHandlingOptions, defaultTurnHandlingOptions } from './turn_handling.js';
|
|
13
|
+
|
|
14
|
+
export function migrateLegacyOptions<UserData>(
|
|
15
|
+
legacyOptions: AgentSessionOptions<UserData>,
|
|
16
|
+
): AgentSessionOptions<UserData> & { options: InternalSessionOptions } {
|
|
17
|
+
const logger = log();
|
|
18
|
+
const { voiceOptions, turnDetection, options: sessionOptions, ...rest } = legacyOptions;
|
|
19
|
+
|
|
20
|
+
if (voiceOptions !== undefined && sessionOptions !== undefined) {
|
|
21
|
+
logger.warn(
|
|
22
|
+
'Both voiceOptions and options have been supplied as part of the AgentSessionOptions, voiceOptions will be merged with options taking precedence',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Preserve turnDetection before cloning since structuredClone converts class instances to plain objects
|
|
27
|
+
const originalTurnDetection =
|
|
28
|
+
sessionOptions?.turnHandling?.turnDetection ??
|
|
29
|
+
voiceOptions?.turnHandling?.turnDetection ??
|
|
30
|
+
turnDetection;
|
|
31
|
+
|
|
32
|
+
// Exclude potentially non-cloneable turnDetection objects before structuredClone.
|
|
33
|
+
// They are restored from originalTurnDetection below.
|
|
34
|
+
const cloneableVoiceOptions = voiceOptions
|
|
35
|
+
? {
|
|
36
|
+
...voiceOptions,
|
|
37
|
+
turnHandling: voiceOptions.turnHandling
|
|
38
|
+
? { ...voiceOptions.turnHandling, turnDetection: undefined }
|
|
39
|
+
: voiceOptions.turnHandling,
|
|
40
|
+
}
|
|
41
|
+
: voiceOptions;
|
|
42
|
+
const cloneableSessionOptions = sessionOptions
|
|
43
|
+
? {
|
|
44
|
+
...sessionOptions,
|
|
45
|
+
turnHandling: sessionOptions.turnHandling
|
|
46
|
+
? { ...sessionOptions.turnHandling, turnDetection: undefined }
|
|
47
|
+
: sessionOptions.turnHandling,
|
|
48
|
+
}
|
|
49
|
+
: sessionOptions;
|
|
50
|
+
|
|
51
|
+
const mergedOptions = structuredClone({ ...cloneableVoiceOptions, ...cloneableSessionOptions });
|
|
52
|
+
|
|
53
|
+
const turnHandling: TurnHandlingOptions = {
|
|
54
|
+
interruption: {
|
|
55
|
+
discardAudioIfUninterruptible: mergedOptions?.discardAudioIfUninterruptible,
|
|
56
|
+
minDuration: mergedOptions?.minInterruptionDuration,
|
|
57
|
+
minWords: mergedOptions?.minInterruptionWords,
|
|
58
|
+
},
|
|
59
|
+
endpointing: {
|
|
60
|
+
minDelay: mergedOptions?.minEndpointingDelay,
|
|
61
|
+
maxDelay: mergedOptions?.maxEndpointingDelay,
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
...mergedOptions.turnHandling,
|
|
65
|
+
// Restore original turnDetection after spread to preserve class instance with methods
|
|
66
|
+
// (structuredClone converts class instances to plain objects, losing prototype methods)
|
|
67
|
+
turnDetection: originalTurnDetection,
|
|
68
|
+
} as const;
|
|
69
|
+
|
|
70
|
+
if (mergedOptions?.allowInterruptions === false) {
|
|
71
|
+
turnHandling.interruption.enabled = false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const optionsWithDefaults = {
|
|
75
|
+
...defaultSessionOptions,
|
|
76
|
+
...mergedOptions,
|
|
77
|
+
turnHandling: mergeWithDefaults(turnHandling),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const newAgentSessionOptions: AgentSessionOptions<UserData> & {
|
|
81
|
+
options: InternalSessionOptions;
|
|
82
|
+
} = {
|
|
83
|
+
...rest,
|
|
84
|
+
options: optionsWithDefaults,
|
|
85
|
+
voiceOptions: optionsWithDefaults,
|
|
86
|
+
turnDetection: turnHandling.turnDetection,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return newAgentSessionOptions;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Remove keys whose value is `undefined` so they don't shadow defaults when spread. */
|
|
93
|
+
export function stripUndefined<T extends object>(obj: T): Partial<T> {
|
|
94
|
+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function mergeWithDefaults(config: TurnHandlingOptions) {
|
|
98
|
+
return {
|
|
99
|
+
turnDetection: config.turnDetection ?? defaultTurnHandlingOptions.turnDetection,
|
|
100
|
+
endpointing: { ...defaultEndpointingOptions, ...stripUndefined(config.endpointing) },
|
|
101
|
+
interruption: { ...defaultInterruptionOptions, ...stripUndefined(config.interruption) },
|
|
102
|
+
} as const;
|
|
103
|
+
}
|