@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,295 @@
|
|
|
1
|
+
import { TransformStream } from "stream/web";
|
|
2
|
+
import WebSocket from "ws";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { log } from "../../log.js";
|
|
5
|
+
import { createAccessToken } from "../utils.js";
|
|
6
|
+
import { intervalForRetry } from "./defaults.js";
|
|
7
|
+
import { InterruptionCacheEntry } from "./interruption_cache_entry.js";
|
|
8
|
+
const MSG_SESSION_CREATE = "session.create";
|
|
9
|
+
const MSG_SESSION_CLOSE = "session.close";
|
|
10
|
+
const MSG_SESSION_CREATED = "session.created";
|
|
11
|
+
const MSG_SESSION_CLOSED = "session.closed";
|
|
12
|
+
const MSG_INTERRUPTION_DETECTED = "bargein_detected";
|
|
13
|
+
const MSG_INFERENCE_DONE = "inference_done";
|
|
14
|
+
const MSG_ERROR = "error";
|
|
15
|
+
const wsMessageSchema = z.discriminatedUnion("type", [
|
|
16
|
+
z.object({
|
|
17
|
+
type: z.literal(MSG_SESSION_CREATED)
|
|
18
|
+
}),
|
|
19
|
+
z.object({
|
|
20
|
+
type: z.literal(MSG_SESSION_CLOSED)
|
|
21
|
+
}),
|
|
22
|
+
z.object({
|
|
23
|
+
type: z.literal(MSG_INTERRUPTION_DETECTED),
|
|
24
|
+
created_at: z.number(),
|
|
25
|
+
probabilities: z.array(z.number()).default([]),
|
|
26
|
+
prediction_duration: z.number().default(0)
|
|
27
|
+
}),
|
|
28
|
+
z.object({
|
|
29
|
+
type: z.literal(MSG_INFERENCE_DONE),
|
|
30
|
+
created_at: z.number(),
|
|
31
|
+
probabilities: z.array(z.number()).default([]),
|
|
32
|
+
prediction_duration: z.number().default(0),
|
|
33
|
+
is_bargein: z.boolean().optional()
|
|
34
|
+
}),
|
|
35
|
+
z.object({
|
|
36
|
+
type: z.literal(MSG_ERROR),
|
|
37
|
+
message: z.string(),
|
|
38
|
+
code: z.number().optional(),
|
|
39
|
+
session_id: z.string().optional()
|
|
40
|
+
})
|
|
41
|
+
]);
|
|
42
|
+
async function connectWebSocket(options) {
|
|
43
|
+
const baseUrl = options.baseUrl.replace(/^http/, "ws");
|
|
44
|
+
const token = await createAccessToken(options.apiKey, options.apiSecret);
|
|
45
|
+
const url = `${baseUrl}/bargein`;
|
|
46
|
+
const ws = new WebSocket(url, {
|
|
47
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
48
|
+
});
|
|
49
|
+
await new Promise((resolve, reject) => {
|
|
50
|
+
const timeout = setTimeout(() => {
|
|
51
|
+
ws.terminate();
|
|
52
|
+
reject(new Error("WebSocket connection timeout"));
|
|
53
|
+
}, options.timeout);
|
|
54
|
+
ws.once("open", () => {
|
|
55
|
+
clearTimeout(timeout);
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
ws.once("error", (err) => {
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
ws.terminate();
|
|
61
|
+
reject(err);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
return ws;
|
|
65
|
+
}
|
|
66
|
+
function createWsTransport(options, getState, setState, updateUserSpeakingSpan, onRequestSent, getAndResetNumRequests) {
|
|
67
|
+
const logger = log();
|
|
68
|
+
let ws = null;
|
|
69
|
+
let outputController = null;
|
|
70
|
+
function setupMessageHandler(socket) {
|
|
71
|
+
socket.on("message", (data) => {
|
|
72
|
+
try {
|
|
73
|
+
const message = wsMessageSchema.parse(JSON.parse(data.toString()));
|
|
74
|
+
handleMessage(message);
|
|
75
|
+
} catch {
|
|
76
|
+
logger.warn({ data: data.toString() }, "Failed to parse WebSocket message");
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
socket.on("error", (err) => {
|
|
80
|
+
logger.error({ err }, "WebSocket error");
|
|
81
|
+
});
|
|
82
|
+
socket.on("close", (code, reason) => {
|
|
83
|
+
logger.debug({ code, reason: reason.toString() }, "WebSocket closed");
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async function ensureConnection() {
|
|
87
|
+
if (ws && ws.readyState === WebSocket.OPEN) return;
|
|
88
|
+
const maxRetries = options.maxRetries ?? 3;
|
|
89
|
+
let lastError = null;
|
|
90
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
91
|
+
try {
|
|
92
|
+
ws = await connectWebSocket(options);
|
|
93
|
+
setupMessageHandler(ws);
|
|
94
|
+
const sessionCreateMsg = JSON.stringify({
|
|
95
|
+
type: MSG_SESSION_CREATE,
|
|
96
|
+
settings: {
|
|
97
|
+
sample_rate: options.sampleRate,
|
|
98
|
+
num_channels: 1,
|
|
99
|
+
threshold: options.threshold,
|
|
100
|
+
min_frames: options.minFrames,
|
|
101
|
+
encoding: "s16le"
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
ws.send(sessionCreateMsg);
|
|
105
|
+
return;
|
|
106
|
+
} catch (err) {
|
|
107
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
108
|
+
if (attempt < maxRetries) {
|
|
109
|
+
const delay = intervalForRetry(attempt);
|
|
110
|
+
logger.debug(
|
|
111
|
+
{ attempt, delay, err: lastError.message },
|
|
112
|
+
"WebSocket connection failed, retrying"
|
|
113
|
+
);
|
|
114
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
throw lastError ?? new Error("Failed to connect to WebSocket after retries");
|
|
119
|
+
}
|
|
120
|
+
function handleMessage(message) {
|
|
121
|
+
const state = getState();
|
|
122
|
+
switch (message.type) {
|
|
123
|
+
case MSG_SESSION_CREATED:
|
|
124
|
+
logger.debug("WebSocket session created");
|
|
125
|
+
break;
|
|
126
|
+
case MSG_INTERRUPTION_DETECTED: {
|
|
127
|
+
const createdAt = message.created_at;
|
|
128
|
+
const overlapSpeechStartedAt = state.overlapSpeechStartedAt;
|
|
129
|
+
if (state.overlapSpeechStarted && overlapSpeechStartedAt !== void 0) {
|
|
130
|
+
const existing = state.cache.get(createdAt);
|
|
131
|
+
const totalDurationInS = (existing == null ? void 0 : existing.requestStartedAt) !== void 0 ? (performance.now() - existing.requestStartedAt) / 1e3 : (performance.now() - createdAt) / 1e3;
|
|
132
|
+
const entry = state.cache.setOrUpdate(
|
|
133
|
+
createdAt,
|
|
134
|
+
() => new InterruptionCacheEntry({ createdAt }),
|
|
135
|
+
{
|
|
136
|
+
speechInput: existing == null ? void 0 : existing.speechInput,
|
|
137
|
+
requestStartedAt: existing == null ? void 0 : existing.requestStartedAt,
|
|
138
|
+
totalDurationInS,
|
|
139
|
+
probabilities: message.probabilities,
|
|
140
|
+
isInterruption: true,
|
|
141
|
+
predictionDurationInS: message.prediction_duration,
|
|
142
|
+
detectionDelayInS: (Date.now() - overlapSpeechStartedAt) / 1e3
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
if (updateUserSpeakingSpan) {
|
|
146
|
+
updateUserSpeakingSpan(entry);
|
|
147
|
+
}
|
|
148
|
+
logger.debug(
|
|
149
|
+
{
|
|
150
|
+
totalDuration: entry.totalDurationInS,
|
|
151
|
+
predictionDuration: entry.predictionDurationInS,
|
|
152
|
+
detectionDelay: entry.detectionDelayInS,
|
|
153
|
+
probability: entry.probability
|
|
154
|
+
},
|
|
155
|
+
"interruption detected"
|
|
156
|
+
);
|
|
157
|
+
const event = {
|
|
158
|
+
type: "user_overlapping_speech",
|
|
159
|
+
timestamp: Date.now(),
|
|
160
|
+
isInterruption: true,
|
|
161
|
+
totalDurationInS: entry.totalDurationInS,
|
|
162
|
+
predictionDurationInS: entry.predictionDurationInS,
|
|
163
|
+
overlapStartedAt: overlapSpeechStartedAt,
|
|
164
|
+
speechInput: entry.speechInput,
|
|
165
|
+
probabilities: entry.probabilities,
|
|
166
|
+
detectionDelayInS: entry.detectionDelayInS,
|
|
167
|
+
probability: entry.probability,
|
|
168
|
+
numRequests: (getAndResetNumRequests == null ? void 0 : getAndResetNumRequests()) ?? 0
|
|
169
|
+
};
|
|
170
|
+
outputController == null ? void 0 : outputController.enqueue(event);
|
|
171
|
+
setState({ overlapSpeechStarted: false });
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case MSG_INFERENCE_DONE: {
|
|
176
|
+
const createdAt = message.created_at;
|
|
177
|
+
const overlapSpeechStartedAt = state.overlapSpeechStartedAt;
|
|
178
|
+
if (state.overlapSpeechStarted && overlapSpeechStartedAt !== void 0) {
|
|
179
|
+
const existing = state.cache.get(createdAt);
|
|
180
|
+
const totalDurationInS = (existing == null ? void 0 : existing.requestStartedAt) !== void 0 ? (performance.now() - existing.requestStartedAt) / 1e3 : (performance.now() - createdAt) / 1e3;
|
|
181
|
+
const entry = state.cache.setOrUpdate(
|
|
182
|
+
createdAt,
|
|
183
|
+
() => new InterruptionCacheEntry({ createdAt }),
|
|
184
|
+
{
|
|
185
|
+
speechInput: existing == null ? void 0 : existing.speechInput,
|
|
186
|
+
requestStartedAt: existing == null ? void 0 : existing.requestStartedAt,
|
|
187
|
+
totalDurationInS,
|
|
188
|
+
predictionDurationInS: message.prediction_duration,
|
|
189
|
+
probabilities: message.probabilities,
|
|
190
|
+
isInterruption: message.is_bargein ?? false,
|
|
191
|
+
detectionDelayInS: (Date.now() - overlapSpeechStartedAt) / 1e3
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
logger.debug(
|
|
195
|
+
{
|
|
196
|
+
totalDurationInS: entry.totalDurationInS,
|
|
197
|
+
predictionDurationInS: entry.predictionDurationInS
|
|
198
|
+
},
|
|
199
|
+
"interruption inference done"
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
case MSG_SESSION_CLOSED:
|
|
205
|
+
logger.debug("WebSocket session closed");
|
|
206
|
+
break;
|
|
207
|
+
case MSG_ERROR:
|
|
208
|
+
outputController == null ? void 0 : outputController.error(
|
|
209
|
+
new Error(
|
|
210
|
+
`LiveKit Adaptive Interruption error${message.code !== void 0 ? ` (${message.code})` : ""}: ${message.message}`
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function sendAudioData(audioSlice) {
|
|
217
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
218
|
+
throw new Error("WebSocket not connected");
|
|
219
|
+
}
|
|
220
|
+
const state = getState();
|
|
221
|
+
const createdAt = Math.floor(performance.now());
|
|
222
|
+
state.cache.set(
|
|
223
|
+
createdAt,
|
|
224
|
+
new InterruptionCacheEntry({
|
|
225
|
+
createdAt,
|
|
226
|
+
requestStartedAt: performance.now(),
|
|
227
|
+
speechInput: audioSlice
|
|
228
|
+
})
|
|
229
|
+
);
|
|
230
|
+
const header = new ArrayBuffer(8);
|
|
231
|
+
const view = new DataView(header);
|
|
232
|
+
view.setUint32(0, createdAt >>> 0, true);
|
|
233
|
+
view.setUint32(4, Math.floor(createdAt / 4294967296) >>> 0, true);
|
|
234
|
+
const audioBytes = new Uint8Array(
|
|
235
|
+
audioSlice.buffer,
|
|
236
|
+
audioSlice.byteOffset,
|
|
237
|
+
audioSlice.byteLength
|
|
238
|
+
);
|
|
239
|
+
const combined = new Uint8Array(8 + audioBytes.length);
|
|
240
|
+
combined.set(new Uint8Array(header), 0);
|
|
241
|
+
combined.set(audioBytes, 8);
|
|
242
|
+
try {
|
|
243
|
+
ws.send(combined);
|
|
244
|
+
onRequestSent == null ? void 0 : onRequestSent();
|
|
245
|
+
} catch (e) {
|
|
246
|
+
logger.error(e, `failed to send audio via websocket`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function close() {
|
|
250
|
+
if ((ws == null ? void 0 : ws.readyState) === WebSocket.OPEN) {
|
|
251
|
+
const closeMsg = JSON.stringify({ type: MSG_SESSION_CLOSE });
|
|
252
|
+
try {
|
|
253
|
+
ws.send(closeMsg);
|
|
254
|
+
} catch (e) {
|
|
255
|
+
logger.error(e, "failed to send close message");
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
ws == null ? void 0 : ws.close(1e3);
|
|
259
|
+
ws = null;
|
|
260
|
+
}
|
|
261
|
+
async function reconnect() {
|
|
262
|
+
close();
|
|
263
|
+
}
|
|
264
|
+
const transport = new TransformStream(
|
|
265
|
+
{
|
|
266
|
+
async start(controller) {
|
|
267
|
+
outputController = controller;
|
|
268
|
+
await ensureConnection();
|
|
269
|
+
},
|
|
270
|
+
transform(chunk, controller) {
|
|
271
|
+
if (!(chunk instanceof Int16Array)) {
|
|
272
|
+
controller.enqueue(chunk);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const state = getState();
|
|
276
|
+
if (!state.overlapSpeechStartedAt || !state.overlapSpeechStarted) return;
|
|
277
|
+
try {
|
|
278
|
+
sendAudioData(chunk);
|
|
279
|
+
} catch (err) {
|
|
280
|
+
logger.error({ err }, "Failed to send audio data over WebSocket");
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
flush() {
|
|
284
|
+
close();
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
{ highWaterMark: 2 },
|
|
288
|
+
{ highWaterMark: 2 }
|
|
289
|
+
);
|
|
290
|
+
return { transport, reconnect };
|
|
291
|
+
}
|
|
292
|
+
export {
|
|
293
|
+
createWsTransport
|
|
294
|
+
};
|
|
295
|
+
//# sourceMappingURL=ws_transport.js.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":[]}
|
package/dist/inference/llm.cjs
CHANGED
|
@@ -33,10 +33,11 @@ __export(llm_exports, {
|
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(llm_exports);
|
|
35
35
|
var import_openai = __toESM(require("openai"), 1);
|
|
36
|
-
var
|
|
36
|
+
var import_exceptions = require("../_exceptions.cjs");
|
|
37
37
|
var llm = __toESM(require("../llm/index.cjs"), 1);
|
|
38
|
-
var
|
|
39
|
-
|
|
38
|
+
var import_types = require("../types.cjs");
|
|
39
|
+
var import_utils = require("../utils.cjs");
|
|
40
|
+
var import_utils2 = require("./utils.cjs");
|
|
40
41
|
class LLM extends llm.LLM {
|
|
41
42
|
client;
|
|
42
43
|
opts;
|
|
@@ -51,7 +52,7 @@ class LLM extends llm.LLM {
|
|
|
51
52
|
modelOptions,
|
|
52
53
|
strictToolSchema = false
|
|
53
54
|
} = opts;
|
|
54
|
-
const lkBaseURL = baseURL ||
|
|
55
|
+
const lkBaseURL = baseURL || (0, import_utils2.getDefaultInferenceUrl)();
|
|
55
56
|
const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;
|
|
56
57
|
if (!lkApiKey) {
|
|
57
58
|
throw new Error("apiKey is required: pass apiKey or set LIVEKIT_API_KEY");
|
|
@@ -81,13 +82,16 @@ class LLM extends llm.LLM {
|
|
|
81
82
|
get model() {
|
|
82
83
|
return this.opts.model;
|
|
83
84
|
}
|
|
85
|
+
get provider() {
|
|
86
|
+
return "livekit";
|
|
87
|
+
}
|
|
84
88
|
static fromModelString(modelString) {
|
|
85
89
|
return new LLM({ model: modelString });
|
|
86
90
|
}
|
|
87
91
|
chat({
|
|
88
92
|
chatCtx,
|
|
89
93
|
toolCtx,
|
|
90
|
-
connOptions =
|
|
94
|
+
connOptions = import_types.DEFAULT_API_CONNECT_OPTIONS,
|
|
91
95
|
parallelToolCalls,
|
|
92
96
|
toolChoice,
|
|
93
97
|
// TODO(AJS-270): Add response_format parameter support
|
|
@@ -186,7 +190,7 @@ class LLMStream extends llm.LLMStream {
|
|
|
186
190
|
delete requestOptions.tool_choice;
|
|
187
191
|
}
|
|
188
192
|
if (this.gatewayOptions) {
|
|
189
|
-
this.client.apiKey = await (0,
|
|
193
|
+
this.client.apiKey = await (0, import_utils2.createAccessToken)(
|
|
190
194
|
this.gatewayOptions.apiKey,
|
|
191
195
|
this.gatewayOptions.apiSecret
|
|
192
196
|
);
|
|
@@ -236,9 +240,9 @@ class LLMStream extends llm.LLMStream {
|
|
|
236
240
|
}
|
|
237
241
|
} catch (error) {
|
|
238
242
|
if (error instanceof import_openai.default.APIConnectionTimeoutError) {
|
|
239
|
-
throw new
|
|
243
|
+
throw new import_exceptions.APITimeoutError({ options: { retryable } });
|
|
240
244
|
} else if (error instanceof import_openai.default.APIError) {
|
|
241
|
-
throw new
|
|
245
|
+
throw new import_exceptions.APIStatusError({
|
|
242
246
|
message: error.message,
|
|
243
247
|
options: {
|
|
244
248
|
statusCode: error.status,
|
|
@@ -248,8 +252,8 @@ class LLMStream extends llm.LLMStream {
|
|
|
248
252
|
}
|
|
249
253
|
});
|
|
250
254
|
} else {
|
|
251
|
-
throw new
|
|
252
|
-
message: (0,
|
|
255
|
+
throw new import_exceptions.APIConnectionError({
|
|
256
|
+
message: (0, import_utils.toError)(error).message,
|
|
253
257
|
options: { retryable }
|
|
254
258
|
});
|
|
255
259
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/inference/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport OpenAI from 'openai';\nimport {\n APIConnectionError,\n APIStatusError,\n APITimeoutError,\n DEFAULT_API_CONNECT_OPTIONS,\n type Expand,\n toError,\n} from '../index.js';\nimport * as llm from '../llm/index.js';\nimport type { APIConnectOptions } from '../types.js';\nimport { type AnyString, createAccessToken } from './utils.js';\n\nconst DEFAULT_BASE_URL = 'https://agent-gateway.livekit.cloud/v1';\n\nexport type OpenAIModels =\n | 'openai/gpt-5.2'\n | 'openai/gpt-5.2-chat-latest'\n | 'openai/gpt-5.1'\n | 'openai/gpt-5.1-chat-latest'\n | 'openai/gpt-5'\n | 'openai/gpt-5-mini'\n | 'openai/gpt-5-nano'\n | 'openai/gpt-4.1'\n | 'openai/gpt-4.1-mini'\n | 'openai/gpt-4.1-nano'\n | 'openai/gpt-4o'\n | 'openai/gpt-4o-mini'\n | 'openai/gpt-oss-120b';\n\nexport type GoogleModels =\n | 'google/gemini-3-pro'\n | 'google/gemini-3-flash'\n | 'google/gemini-2.5-pro'\n | 'google/gemini-2.5-flash'\n | 'google/gemini-2.5-flash-lite'\n | 'google/gemini-2.0-flash'\n | 'google/gemini-2.0-flash-lite';\n\nexport type MoonshotModels = 'moonshotai/kimi-k2-instruct';\n\nexport type DeepSeekModels = 'deepseek-ai/deepseek-v3' | 'deepseek-ai/deepseek-v3.2';\n\ntype ChatCompletionPredictionContentParam =\n Expand<OpenAI.Chat.Completions.ChatCompletionPredictionContent>;\ntype WebSearchOptions = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams.WebSearchOptions>;\ntype ToolChoice = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams['tool_choice']>;\ntype Verbosity = 'low' | 'medium' | 'high';\n\nexport interface ChatCompletionOptions extends Record<string, unknown> {\n frequency_penalty?: number;\n logit_bias?: Record<string, number>;\n logprobs?: boolean;\n max_completion_tokens?: number;\n max_tokens?: number;\n metadata?: Record<string, string>;\n modalities?: Array<'text' | 'audio'>;\n n?: number;\n parallel_tool_calls?: boolean;\n prediction?: ChatCompletionPredictionContentParam | null;\n presence_penalty?: number;\n prompt_cache_key?: string;\n reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';\n safety_identifier?: string;\n seed?: number;\n service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';\n stop?: string | string[];\n store?: boolean;\n temperature?: number;\n top_logprobs?: number;\n top_p?: number;\n user?: string;\n verbosity?: Verbosity;\n web_search_options?: WebSearchOptions;\n\n // livekit-typed arguments\n tool_choice?: ToolChoice;\n // TODO(brian): support response format\n // response_format?: OpenAI.Chat.Completions.ChatCompletionCreateParams['response_format']\n}\n\nexport type LLMModels = OpenAIModels | GoogleModels | MoonshotModels | DeepSeekModels | AnyString;\n\nexport interface InferenceLLMOptions {\n model: LLMModels;\n provider?: string;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: ChatCompletionOptions;\n strictToolSchema?: boolean;\n}\n\nexport interface GatewayOptions {\n apiKey: string;\n apiSecret: string;\n}\n\n/**\n * Livekit Cloud Inference LLM\n */\nexport class LLM extends llm.LLM {\n private client: OpenAI;\n private opts: InferenceLLMOptions;\n\n constructor(opts: {\n model: LLMModels;\n provider?: string;\n baseURL?: string;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: InferenceLLMOptions['modelOptions'];\n strictToolSchema?: boolean;\n }) {\n super();\n\n const {\n model,\n provider,\n baseURL,\n apiKey,\n apiSecret,\n modelOptions,\n strictToolSchema = false,\n } = opts;\n\n const lkBaseURL = baseURL || process.env.LIVEKIT_INFERENCE_URL || DEFAULT_BASE_URL;\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n provider,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions: modelOptions || {},\n strictToolSchema,\n };\n\n this.client = new OpenAI({\n baseURL: this.opts.baseURL,\n apiKey: '', // leave a temporary empty string to avoid OpenAI complain about missing key\n });\n }\n\n label(): string {\n return 'inference.LLM';\n }\n\n get model(): string {\n return this.opts.model;\n }\n\n static fromModelString(modelString: string): LLM {\n return new LLM({ model: modelString });\n }\n\n chat({\n chatCtx,\n toolCtx,\n connOptions = DEFAULT_API_CONNECT_OPTIONS,\n parallelToolCalls,\n toolChoice,\n // TODO(AJS-270): Add response_format parameter support\n extraKwargs,\n }: {\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: llm.ToolChoice;\n // TODO(AJS-270): Add responseFormat parameter\n extraKwargs?: Record<string, unknown>;\n }): LLMStream {\n let modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };\n\n parallelToolCalls =\n parallelToolCalls !== undefined\n ? parallelToolCalls\n : this.opts.modelOptions.parallel_tool_calls;\n\n if (toolCtx && Object.keys(toolCtx).length > 0 && parallelToolCalls !== undefined) {\n modelOptions.parallel_tool_calls = parallelToolCalls;\n }\n\n toolChoice =\n toolChoice !== undefined\n ? toolChoice\n : (this.opts.modelOptions.tool_choice as llm.ToolChoice | undefined);\n\n if (toolChoice) {\n modelOptions.tool_choice = toolChoice as ToolChoice;\n }\n\n // TODO(AJS-270): Add response_format support here\n\n modelOptions = { ...modelOptions, ...this.opts.modelOptions };\n\n return new LLMStream(this, {\n model: this.opts.model,\n provider: this.opts.provider,\n client: this.client,\n chatCtx,\n toolCtx,\n connOptions,\n modelOptions,\n strictToolSchema: this.opts.strictToolSchema ?? false, // default to false if not set\n gatewayOptions: {\n apiKey: this.opts.apiKey,\n apiSecret: this.opts.apiSecret,\n },\n });\n }\n}\n\nexport class LLMStream extends llm.LLMStream {\n private model: LLMModels;\n private provider?: string;\n private providerFmt: llm.ProviderFormat;\n private client: OpenAI;\n private modelOptions: Record<string, unknown>;\n private strictToolSchema: boolean;\n\n private gatewayOptions?: GatewayOptions;\n private toolCallId?: string;\n private toolIndex?: number;\n private fncName?: string;\n private fncRawArguments?: string;\n private toolExtra?: Record<string, unknown>;\n\n constructor(\n llm: LLM,\n {\n model,\n provider,\n client,\n chatCtx,\n toolCtx,\n gatewayOptions,\n connOptions,\n modelOptions,\n providerFmt,\n strictToolSchema,\n }: {\n model: LLMModels;\n provider?: string;\n client: OpenAI;\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n gatewayOptions?: GatewayOptions;\n connOptions: APIConnectOptions;\n modelOptions: Record<string, unknown>;\n providerFmt?: llm.ProviderFormat;\n strictToolSchema: boolean;\n },\n ) {\n super(llm, { chatCtx, toolCtx, connOptions });\n this.client = client;\n this.gatewayOptions = gatewayOptions;\n this.provider = provider;\n this.providerFmt = providerFmt || 'openai';\n this.modelOptions = modelOptions;\n this.model = model;\n this.strictToolSchema = strictToolSchema;\n }\n\n protected async run(): Promise<void> {\n // current function call that we're waiting for full completion (args are streamed)\n // (defined inside the run method to make sure the state is reset for each run/attempt)\n let retryable = true;\n this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = undefined;\n this.toolExtra = undefined;\n\n try {\n const messages = (await this.chatCtx.toProviderFormat(\n this.providerFmt,\n )) as OpenAI.ChatCompletionMessageParam[];\n\n const tools = this.toolCtx\n ? Object.entries(this.toolCtx).map(([name, func]) => {\n const oaiParams = {\n type: 'function' as const,\n function: {\n name,\n description: func.description,\n parameters: llm.toJsonSchema(\n func.parameters,\n true,\n this.strictToolSchema,\n ) as unknown as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function']['parameters'],\n } as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function'],\n };\n\n if (this.strictToolSchema) {\n oaiParams.function.strict = true;\n }\n\n return oaiParams;\n })\n : undefined;\n\n const requestOptions: Record<string, unknown> = { ...this.modelOptions };\n if (!tools) {\n delete requestOptions.tool_choice;\n }\n\n // Dynamically set the access token for the LiveKit Agent Gateway API\n if (this.gatewayOptions) {\n this.client.apiKey = await createAccessToken(\n this.gatewayOptions.apiKey,\n this.gatewayOptions.apiSecret,\n );\n }\n\n if (this.provider) {\n const extraHeaders = requestOptions.extra_headers\n ? (requestOptions.extra_headers as Record<string, string>)\n : {};\n extraHeaders['X-LiveKit-Inference-Provider'] = this.provider;\n requestOptions.extra_headers = extraHeaders;\n }\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n stream: true,\n stream_options: { include_usage: true },\n ...requestOptions,\n },\n {\n timeout: this.connOptions.timeoutMs,\n },\n );\n\n for await (const chunk of stream) {\n for (const choice of chunk.choices) {\n if (this.abortController.signal.aborted) {\n break;\n }\n const chatChunk = this.parseChoice(chunk.id, choice);\n if (chatChunk) {\n retryable = false;\n this.queue.put(chatChunk);\n }\n }\n\n if (chunk.usage) {\n const usage = chunk.usage;\n retryable = false;\n this.queue.put({\n id: chunk.id,\n usage: {\n completionTokens: usage.completion_tokens,\n promptTokens: usage.prompt_tokens,\n promptCachedTokens: usage.prompt_tokens_details?.cached_tokens || 0,\n totalTokens: usage.total_tokens,\n },\n });\n }\n }\n } catch (error) {\n if (error instanceof OpenAI.APIConnectionTimeoutError) {\n throw new APITimeoutError({ options: { retryable } });\n } else if (error instanceof OpenAI.APIError) {\n throw new APIStatusError({\n message: error.message,\n options: {\n statusCode: error.status,\n body: error.error,\n requestId: error.requestID,\n retryable,\n },\n });\n } else {\n throw new APIConnectionError({\n message: toError(error).message,\n options: { retryable },\n });\n }\n }\n }\n\n private parseChoice(\n id: string,\n choice: OpenAI.ChatCompletionChunk.Choice,\n ): llm.ChatChunk | undefined {\n const delta = choice.delta;\n\n // https://github.com/livekit/agents/issues/688\n // the delta can be None when using Azure OpenAI (content filtering)\n if (delta === undefined) return undefined;\n\n if (delta.tool_calls) {\n // check if we have functions to calls\n for (const tool of delta.tool_calls) {\n if (!tool.function) {\n continue; // oai may add other tools in the future\n }\n\n /**\n * The way OpenAI streams tool calls is a bit tricky.\n *\n * For any new tool call, it first emits a delta tool call with id, and function name,\n * the rest of the delta chunks will only stream the remaining arguments string,\n * until a new tool call is started or the tool call is finished.\n * See below for an example.\n *\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)\n * [ChoiceDeltaToolCall(index=0, id='call_LaVeHWUHpef9K1sd5UO8TtLg', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"P', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='aris\\}', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id='call_ThU4OmMdQXnnVmpXGOCknXIB', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"T', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='okyo', name=None), type=None)]\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None), finish_reason='tool_calls', index=0, logprobs=None)\n */\n let callChunk: llm.ChatChunk | undefined;\n // If we have a previous tool call and this is a new one, emit the previous\n if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {\n callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n // Note: We intentionally do NOT reset toolExtra here.\n // For Gemini 3+, the thought_signature is only provided on the first tool call\n // in a parallel batch, but must be applied to ALL tool calls in the batch.\n // We preserve toolExtra so subsequent tool calls inherit the thought_signature.\n }\n\n // Start or continue building the current tool call\n if (tool.function.name) {\n this.toolIndex = tool.index;\n this.toolCallId = tool.id;\n this.fncName = tool.function.name;\n this.fncRawArguments = tool.function.arguments || '';\n // Extract extra from tool call (e.g., Google thought signatures)\n // Only update toolExtra if this tool call has extra_content.\n // Otherwise, inherit from previous tool call (for parallel Gemini tool calls).\n const newToolExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((tool as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n if (newToolExtra) {\n this.toolExtra = newToolExtra;\n }\n } else if (tool.function.arguments) {\n this.fncRawArguments = (this.fncRawArguments || '') + tool.function.arguments;\n }\n\n if (callChunk) {\n return callChunk;\n }\n }\n }\n\n // If we're done with tool calls, emit the final one\n if (\n choice.finish_reason &&\n ['tool_calls', 'stop'].includes(choice.finish_reason) &&\n this.toolCallId !== undefined\n ) {\n const callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n // Reset toolExtra at the end of the response (not between parallel tool calls)\n this.toolExtra = undefined;\n return callChunk;\n }\n\n // Extract extra from delta (e.g., Google thought signatures on text parts)\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n // Regular content message\n if (!delta.content && !deltaExtra) {\n return undefined;\n }\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n },\n };\n }\n\n private createRunningToolCallChunk(\n id: string,\n delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta,\n ): llm.ChatChunk {\n const toolExtra = this.toolExtra ? { ...this.toolExtra } : {};\n const thoughtSignature = this.extractThoughtSignature(toolExtra);\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n toolCalls: [\n llm.FunctionCall.create({\n callId: this.toolCallId || '',\n name: this.fncName || '',\n args: this.fncRawArguments || '',\n extra: toolExtra,\n thoughtSignature,\n }),\n ],\n },\n };\n }\n\n private extractThoughtSignature(extra?: Record<string, unknown>): string | undefined {\n const googleExtra = extra?.google;\n if (googleExtra && typeof googleExtra === 'object') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (googleExtra as any).thoughtSignature || (googleExtra as any).thought_signature;\n }\n return undefined;\n }\n}\n"],"mappings":"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","names":["OpenAI","llm"]}
|
|
1
|
+
{"version":3,"sources":["../../src/inference/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport OpenAI from 'openai';\nimport { APIConnectionError, APIStatusError, APITimeoutError } from '../_exceptions.js';\nimport * as llm from '../llm/index.js';\nimport { DEFAULT_API_CONNECT_OPTIONS } from '../types.js';\nimport type { APIConnectOptions } from '../types.js';\nimport { type Expand, toError } from '../utils.js';\nimport { type AnyString, createAccessToken, getDefaultInferenceUrl } from './utils.js';\n\nexport type OpenAIModels =\n | 'openai/gpt-5.2'\n | 'openai/gpt-5.2-chat-latest'\n | 'openai/gpt-5.1'\n | 'openai/gpt-5.1-chat-latest'\n | 'openai/gpt-5'\n | 'openai/gpt-5-mini'\n | 'openai/gpt-5-nano'\n | 'openai/gpt-4.1'\n | 'openai/gpt-4.1-mini'\n | 'openai/gpt-4.1-nano'\n | 'openai/gpt-4o'\n | 'openai/gpt-4o-mini'\n | 'openai/gpt-oss-120b';\n\nexport type GoogleModels =\n | 'google/gemini-3-pro'\n | 'google/gemini-3-flash'\n | 'google/gemini-2.5-pro'\n | 'google/gemini-2.5-flash'\n | 'google/gemini-2.5-flash-lite'\n | 'google/gemini-2.0-flash'\n | 'google/gemini-2.0-flash-lite';\n\nexport type MoonshotModels = 'moonshotai/kimi-k2-instruct';\n\nexport type DeepSeekModels = 'deepseek-ai/deepseek-v3' | 'deepseek-ai/deepseek-v3.2';\n\ntype ChatCompletionPredictionContentParam =\n Expand<OpenAI.Chat.Completions.ChatCompletionPredictionContent>;\ntype WebSearchOptions = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams.WebSearchOptions>;\ntype ToolChoice = Expand<OpenAI.Chat.Completions.ChatCompletionCreateParams['tool_choice']>;\ntype Verbosity = 'low' | 'medium' | 'high';\n\nexport interface ChatCompletionOptions extends Record<string, unknown> {\n frequency_penalty?: number;\n logit_bias?: Record<string, number>;\n logprobs?: boolean;\n max_completion_tokens?: number;\n max_tokens?: number;\n metadata?: Record<string, string>;\n modalities?: Array<'text' | 'audio'>;\n n?: number;\n parallel_tool_calls?: boolean;\n prediction?: ChatCompletionPredictionContentParam | null;\n presence_penalty?: number;\n prompt_cache_key?: string;\n reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high';\n safety_identifier?: string;\n seed?: number;\n service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';\n stop?: string | string[];\n store?: boolean;\n temperature?: number;\n top_logprobs?: number;\n top_p?: number;\n user?: string;\n verbosity?: Verbosity;\n web_search_options?: WebSearchOptions;\n\n // livekit-typed arguments\n tool_choice?: ToolChoice;\n // TODO(brian): support response format\n // response_format?: OpenAI.Chat.Completions.ChatCompletionCreateParams['response_format']\n}\n\nexport type LLMModels = OpenAIModels | GoogleModels | MoonshotModels | DeepSeekModels | AnyString;\n\nexport interface InferenceLLMOptions {\n model: LLMModels;\n provider?: string;\n baseURL: string;\n apiKey: string;\n apiSecret: string;\n modelOptions: ChatCompletionOptions;\n strictToolSchema?: boolean;\n}\n\nexport interface GatewayOptions {\n apiKey: string;\n apiSecret: string;\n}\n\n/**\n * Livekit Cloud Inference LLM\n */\nexport class LLM extends llm.LLM {\n private client: OpenAI;\n private opts: InferenceLLMOptions;\n\n constructor(opts: {\n model: LLMModels;\n provider?: string;\n baseURL?: string;\n apiKey?: string;\n apiSecret?: string;\n modelOptions?: InferenceLLMOptions['modelOptions'];\n strictToolSchema?: boolean;\n }) {\n super();\n\n const {\n model,\n provider,\n baseURL,\n apiKey,\n apiSecret,\n modelOptions,\n strictToolSchema = false,\n } = opts;\n\n const lkBaseURL = baseURL || getDefaultInferenceUrl();\n const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;\n if (!lkApiKey) {\n throw new Error('apiKey is required: pass apiKey or set LIVEKIT_API_KEY');\n }\n\n const lkApiSecret =\n apiSecret || process.env.LIVEKIT_INFERENCE_API_SECRET || process.env.LIVEKIT_API_SECRET;\n if (!lkApiSecret) {\n throw new Error('apiSecret is required: pass apiSecret or set LIVEKIT_API_SECRET');\n }\n\n this.opts = {\n model,\n provider,\n baseURL: lkBaseURL,\n apiKey: lkApiKey,\n apiSecret: lkApiSecret,\n modelOptions: modelOptions || {},\n strictToolSchema,\n };\n\n this.client = new OpenAI({\n baseURL: this.opts.baseURL,\n apiKey: '', // leave a temporary empty string to avoid OpenAI complain about missing key\n });\n }\n\n label(): string {\n return 'inference.LLM';\n }\n\n get model(): string {\n return this.opts.model;\n }\n\n get provider(): string {\n return 'livekit';\n }\n\n static fromModelString(modelString: string): LLM {\n return new LLM({ model: modelString });\n }\n\n chat({\n chatCtx,\n toolCtx,\n connOptions = DEFAULT_API_CONNECT_OPTIONS,\n parallelToolCalls,\n toolChoice,\n // TODO(AJS-270): Add response_format parameter support\n extraKwargs,\n }: {\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: llm.ToolChoice;\n // TODO(AJS-270): Add responseFormat parameter\n extraKwargs?: Record<string, unknown>;\n }): LLMStream {\n let modelOptions: Record<string, unknown> = { ...(extraKwargs || {}) };\n\n parallelToolCalls =\n parallelToolCalls !== undefined\n ? parallelToolCalls\n : this.opts.modelOptions.parallel_tool_calls;\n\n if (toolCtx && Object.keys(toolCtx).length > 0 && parallelToolCalls !== undefined) {\n modelOptions.parallel_tool_calls = parallelToolCalls;\n }\n\n toolChoice =\n toolChoice !== undefined\n ? toolChoice\n : (this.opts.modelOptions.tool_choice as llm.ToolChoice | undefined);\n\n if (toolChoice) {\n modelOptions.tool_choice = toolChoice as ToolChoice;\n }\n\n // TODO(AJS-270): Add response_format support here\n\n modelOptions = { ...modelOptions, ...this.opts.modelOptions };\n\n return new LLMStream(this, {\n model: this.opts.model,\n provider: this.opts.provider,\n client: this.client,\n chatCtx,\n toolCtx,\n connOptions,\n modelOptions,\n strictToolSchema: this.opts.strictToolSchema ?? false, // default to false if not set\n gatewayOptions: {\n apiKey: this.opts.apiKey,\n apiSecret: this.opts.apiSecret,\n },\n });\n }\n}\n\nexport class LLMStream extends llm.LLMStream {\n private model: LLMModels;\n private provider?: string;\n private providerFmt: llm.ProviderFormat;\n private client: OpenAI;\n private modelOptions: Record<string, unknown>;\n private strictToolSchema: boolean;\n\n private gatewayOptions?: GatewayOptions;\n private toolCallId?: string;\n private toolIndex?: number;\n private fncName?: string;\n private fncRawArguments?: string;\n private toolExtra?: Record<string, unknown>;\n\n constructor(\n llm: LLM,\n {\n model,\n provider,\n client,\n chatCtx,\n toolCtx,\n gatewayOptions,\n connOptions,\n modelOptions,\n providerFmt,\n strictToolSchema,\n }: {\n model: LLMModels;\n provider?: string;\n client: OpenAI;\n chatCtx: llm.ChatContext;\n toolCtx?: llm.ToolContext;\n gatewayOptions?: GatewayOptions;\n connOptions: APIConnectOptions;\n modelOptions: Record<string, unknown>;\n providerFmt?: llm.ProviderFormat;\n strictToolSchema: boolean;\n },\n ) {\n super(llm, { chatCtx, toolCtx, connOptions });\n this.client = client;\n this.gatewayOptions = gatewayOptions;\n this.provider = provider;\n this.providerFmt = providerFmt || 'openai';\n this.modelOptions = modelOptions;\n this.model = model;\n this.strictToolSchema = strictToolSchema;\n }\n\n protected async run(): Promise<void> {\n // current function call that we're waiting for full completion (args are streamed)\n // (defined inside the run method to make sure the state is reset for each run/attempt)\n let retryable = true;\n this.toolCallId = this.fncName = this.fncRawArguments = this.toolIndex = undefined;\n this.toolExtra = undefined;\n\n try {\n const messages = (await this.chatCtx.toProviderFormat(\n this.providerFmt,\n )) as OpenAI.ChatCompletionMessageParam[];\n\n const tools = this.toolCtx\n ? Object.entries(this.toolCtx).map(([name, func]) => {\n const oaiParams = {\n type: 'function' as const,\n function: {\n name,\n description: func.description,\n parameters: llm.toJsonSchema(\n func.parameters,\n true,\n this.strictToolSchema,\n ) as unknown as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function']['parameters'],\n } as OpenAI.Chat.Completions.ChatCompletionFunctionTool['function'],\n };\n\n if (this.strictToolSchema) {\n oaiParams.function.strict = true;\n }\n\n return oaiParams;\n })\n : undefined;\n\n const requestOptions: Record<string, unknown> = { ...this.modelOptions };\n if (!tools) {\n delete requestOptions.tool_choice;\n }\n\n // Dynamically set the access token for the LiveKit Agent Gateway API\n if (this.gatewayOptions) {\n this.client.apiKey = await createAccessToken(\n this.gatewayOptions.apiKey,\n this.gatewayOptions.apiSecret,\n );\n }\n\n if (this.provider) {\n const extraHeaders = requestOptions.extra_headers\n ? (requestOptions.extra_headers as Record<string, string>)\n : {};\n extraHeaders['X-LiveKit-Inference-Provider'] = this.provider;\n requestOptions.extra_headers = extraHeaders;\n }\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n stream: true,\n stream_options: { include_usage: true },\n ...requestOptions,\n },\n {\n timeout: this.connOptions.timeoutMs,\n },\n );\n\n for await (const chunk of stream) {\n for (const choice of chunk.choices) {\n if (this.abortController.signal.aborted) {\n break;\n }\n const chatChunk = this.parseChoice(chunk.id, choice);\n if (chatChunk) {\n retryable = false;\n this.queue.put(chatChunk);\n }\n }\n\n if (chunk.usage) {\n const usage = chunk.usage;\n retryable = false;\n this.queue.put({\n id: chunk.id,\n usage: {\n completionTokens: usage.completion_tokens,\n promptTokens: usage.prompt_tokens,\n promptCachedTokens: usage.prompt_tokens_details?.cached_tokens || 0,\n totalTokens: usage.total_tokens,\n },\n });\n }\n }\n } catch (error) {\n if (error instanceof OpenAI.APIConnectionTimeoutError) {\n throw new APITimeoutError({ options: { retryable } });\n } else if (error instanceof OpenAI.APIError) {\n throw new APIStatusError({\n message: error.message,\n options: {\n statusCode: error.status,\n body: error.error,\n requestId: error.requestID,\n retryable,\n },\n });\n } else {\n throw new APIConnectionError({\n message: toError(error).message,\n options: { retryable },\n });\n }\n }\n }\n\n private parseChoice(\n id: string,\n choice: OpenAI.ChatCompletionChunk.Choice,\n ): llm.ChatChunk | undefined {\n const delta = choice.delta;\n\n // https://github.com/livekit/agents/issues/688\n // the delta can be None when using Azure OpenAI (content filtering)\n if (delta === undefined) return undefined;\n\n if (delta.tool_calls) {\n // check if we have functions to calls\n for (const tool of delta.tool_calls) {\n if (!tool.function) {\n continue; // oai may add other tools in the future\n }\n\n /**\n * The way OpenAI streams tool calls is a bit tricky.\n *\n * For any new tool call, it first emits a delta tool call with id, and function name,\n * the rest of the delta chunks will only stream the remaining arguments string,\n * until a new tool call is started or the tool call is finished.\n * See below for an example.\n *\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role='assistant', tool_calls=None), finish_reason=None, index=0, logprobs=None)\n * [ChoiceDeltaToolCall(index=0, id='call_LaVeHWUHpef9K1sd5UO8TtLg', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"P', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=0, id=None, function=ChoiceDeltaToolCallFunction(arguments='aris\\}', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id='call_ThU4OmMdQXnnVmpXGOCknXIB', function=ChoiceDeltaToolCallFunction(arguments='', name='get_weather'), type='function')]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='\\{\"location\": \"T', name=None), type=None)]\n * [ChoiceDeltaToolCall(index=1, id=None, function=ChoiceDeltaToolCallFunction(arguments='okyo', name=None), type=None)]\n * Choice(delta=ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None), finish_reason='tool_calls', index=0, logprobs=None)\n */\n let callChunk: llm.ChatChunk | undefined;\n // If we have a previous tool call and this is a new one, emit the previous\n if (this.toolCallId && tool.id && tool.index !== this.toolIndex) {\n callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n // Note: We intentionally do NOT reset toolExtra here.\n // For Gemini 3+, the thought_signature is only provided on the first tool call\n // in a parallel batch, but must be applied to ALL tool calls in the batch.\n // We preserve toolExtra so subsequent tool calls inherit the thought_signature.\n }\n\n // Start or continue building the current tool call\n if (tool.function.name) {\n this.toolIndex = tool.index;\n this.toolCallId = tool.id;\n this.fncName = tool.function.name;\n this.fncRawArguments = tool.function.arguments || '';\n // Extract extra from tool call (e.g., Google thought signatures)\n // Only update toolExtra if this tool call has extra_content.\n // Otherwise, inherit from previous tool call (for parallel Gemini tool calls).\n const newToolExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((tool as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n if (newToolExtra) {\n this.toolExtra = newToolExtra;\n }\n } else if (tool.function.arguments) {\n this.fncRawArguments = (this.fncRawArguments || '') + tool.function.arguments;\n }\n\n if (callChunk) {\n return callChunk;\n }\n }\n }\n\n // If we're done with tool calls, emit the final one\n if (\n choice.finish_reason &&\n ['tool_calls', 'stop'].includes(choice.finish_reason) &&\n this.toolCallId !== undefined\n ) {\n const callChunk = this.createRunningToolCallChunk(id, delta);\n this.toolCallId = this.fncName = this.fncRawArguments = undefined;\n // Reset toolExtra at the end of the response (not between parallel tool calls)\n this.toolExtra = undefined;\n return callChunk;\n }\n\n // Extract extra from delta (e.g., Google thought signatures on text parts)\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n // Regular content message\n if (!delta.content && !deltaExtra) {\n return undefined;\n }\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n },\n };\n }\n\n private createRunningToolCallChunk(\n id: string,\n delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta,\n ): llm.ChatChunk {\n const toolExtra = this.toolExtra ? { ...this.toolExtra } : {};\n const thoughtSignature = this.extractThoughtSignature(toolExtra);\n const deltaExtra =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((delta as any).extra_content as Record<string, unknown> | undefined) ?? undefined;\n\n return {\n id,\n delta: {\n role: 'assistant',\n content: delta.content || undefined,\n extra: deltaExtra,\n toolCalls: [\n llm.FunctionCall.create({\n callId: this.toolCallId || '',\n name: this.fncName || '',\n args: this.fncRawArguments || '',\n extra: toolExtra,\n thoughtSignature,\n }),\n ],\n },\n };\n }\n\n private extractThoughtSignature(extra?: Record<string, unknown>): string | undefined {\n const googleExtra = extra?.google;\n if (googleExtra && typeof googleExtra === 'object') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (googleExtra as any).thoughtSignature || (googleExtra as any).thought_signature;\n }\n return undefined;\n }\n}\n"],"mappings":"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","names":["import_utils","OpenAI","llm"]}
|
package/dist/inference/llm.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { type Expand } from '../index.js';
|
|
3
2
|
import * as llm from '../llm/index.js';
|
|
4
3
|
import type { APIConnectOptions } from '../types.js';
|
|
4
|
+
import { type Expand } from '../utils.js';
|
|
5
5
|
import { type AnyString } from './utils.js';
|
|
6
6
|
export type OpenAIModels = 'openai/gpt-5.2' | 'openai/gpt-5.2-chat-latest' | 'openai/gpt-5.1' | 'openai/gpt-5.1-chat-latest' | 'openai/gpt-5' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-4.1' | 'openai/gpt-4.1-mini' | 'openai/gpt-4.1-nano' | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-oss-120b';
|
|
7
7
|
export type GoogleModels = 'google/gemini-3-pro' | 'google/gemini-3-flash' | 'google/gemini-2.5-pro' | 'google/gemini-2.5-flash' | 'google/gemini-2.5-flash-lite' | 'google/gemini-2.0-flash' | 'google/gemini-2.0-flash-lite';
|
|
@@ -69,6 +69,7 @@ export declare class LLM extends llm.LLM {
|
|
|
69
69
|
});
|
|
70
70
|
label(): string;
|
|
71
71
|
get model(): string;
|
|
72
|
+
get provider(): string;
|
|
72
73
|
static fromModelString(modelString: string): LLM;
|
|
73
74
|
chat({ chatCtx, toolCtx, connOptions, parallelToolCalls, toolChoice, extraKwargs, }: {
|
|
74
75
|
chatCtx: llm.ChatContext;
|
package/dist/inference/llm.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { type Expand } from '../index.js';
|
|
3
2
|
import * as llm from '../llm/index.js';
|
|
4
3
|
import type { APIConnectOptions } from '../types.js';
|
|
4
|
+
import { type Expand } from '../utils.js';
|
|
5
5
|
import { type AnyString } from './utils.js';
|
|
6
6
|
export type OpenAIModels = 'openai/gpt-5.2' | 'openai/gpt-5.2-chat-latest' | 'openai/gpt-5.1' | 'openai/gpt-5.1-chat-latest' | 'openai/gpt-5' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-4.1' | 'openai/gpt-4.1-mini' | 'openai/gpt-4.1-nano' | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-oss-120b';
|
|
7
7
|
export type GoogleModels = 'google/gemini-3-pro' | 'google/gemini-3-flash' | 'google/gemini-2.5-pro' | 'google/gemini-2.5-flash' | 'google/gemini-2.5-flash-lite' | 'google/gemini-2.0-flash' | 'google/gemini-2.0-flash-lite';
|
|
@@ -69,6 +69,7 @@ export declare class LLM extends llm.LLM {
|
|
|
69
69
|
});
|
|
70
70
|
label(): string;
|
|
71
71
|
get model(): string;
|
|
72
|
+
get provider(): string;
|
|
72
73
|
static fromModelString(modelString: string): LLM;
|
|
73
74
|
chat({ chatCtx, toolCtx, connOptions, parallelToolCalls, toolChoice, extraKwargs, }: {
|
|
74
75
|
chatCtx: llm.ChatContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/inference/llm.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/inference/llm.ts"],"names":[],"mappings":"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"}
|
package/dist/inference/llm.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
|
-
import {
|
|
3
|
-
APIConnectionError,
|
|
4
|
-
APIStatusError,
|
|
5
|
-
APITimeoutError,
|
|
6
|
-
DEFAULT_API_CONNECT_OPTIONS,
|
|
7
|
-
toError
|
|
8
|
-
} from "../index.js";
|
|
2
|
+
import { APIConnectionError, APIStatusError, APITimeoutError } from "../_exceptions.js";
|
|
9
3
|
import * as llm from "../llm/index.js";
|
|
10
|
-
import {
|
|
11
|
-
|
|
4
|
+
import { DEFAULT_API_CONNECT_OPTIONS } from "../types.js";
|
|
5
|
+
import { toError } from "../utils.js";
|
|
6
|
+
import { createAccessToken, getDefaultInferenceUrl } from "./utils.js";
|
|
12
7
|
class LLM extends llm.LLM {
|
|
13
8
|
client;
|
|
14
9
|
opts;
|
|
@@ -23,7 +18,7 @@ class LLM extends llm.LLM {
|
|
|
23
18
|
modelOptions,
|
|
24
19
|
strictToolSchema = false
|
|
25
20
|
} = opts;
|
|
26
|
-
const lkBaseURL = baseURL ||
|
|
21
|
+
const lkBaseURL = baseURL || getDefaultInferenceUrl();
|
|
27
22
|
const lkApiKey = apiKey || process.env.LIVEKIT_INFERENCE_API_KEY || process.env.LIVEKIT_API_KEY;
|
|
28
23
|
if (!lkApiKey) {
|
|
29
24
|
throw new Error("apiKey is required: pass apiKey or set LIVEKIT_API_KEY");
|
|
@@ -53,6 +48,9 @@ class LLM extends llm.LLM {
|
|
|
53
48
|
get model() {
|
|
54
49
|
return this.opts.model;
|
|
55
50
|
}
|
|
51
|
+
get provider() {
|
|
52
|
+
return "livekit";
|
|
53
|
+
}
|
|
56
54
|
static fromModelString(modelString) {
|
|
57
55
|
return new LLM({ model: modelString });
|
|
58
56
|
}
|