@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
package/dist/llm/index.js
CHANGED
|
@@ -2,7 +2,8 @@ import {
|
|
|
2
2
|
handoff,
|
|
3
3
|
isFunctionTool,
|
|
4
4
|
tool,
|
|
5
|
-
ToolError
|
|
5
|
+
ToolError,
|
|
6
|
+
ToolFlag
|
|
6
7
|
} from "./tool_context.js";
|
|
7
8
|
import {
|
|
8
9
|
AgentHandoffItem,
|
|
@@ -46,6 +47,7 @@ export {
|
|
|
46
47
|
RealtimeSession,
|
|
47
48
|
RemoteChatContext,
|
|
48
49
|
ToolError,
|
|
50
|
+
ToolFlag,
|
|
49
51
|
computeChatCtxDiff,
|
|
50
52
|
createAudioContent,
|
|
51
53
|
createImageContent,
|
package/dist/llm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport {\n handoff,\n isFunctionTool,\n tool,\n ToolError,\n type AgentHandoff,\n type FunctionTool,\n type ProviderDefinedTool,\n type Tool,\n type ToolChoice,\n type ToolContext,\n type ToolOptions,\n type ToolType,\n} from './tool_context.js';\n\nexport {\n AgentHandoffItem,\n ChatContext,\n ChatMessage,\n createAudioContent,\n createImageContent,\n FunctionCall,\n FunctionCallOutput,\n type AudioContent,\n type ChatContent,\n type ChatItem,\n type ChatRole,\n type ImageContent,\n} from './chat_context.js';\n\nexport type { ProviderFormat } from './provider_format/index.js';\n\nexport {\n LLM,\n LLMStream,\n type ChatChunk,\n type ChoiceDelta,\n type CompletionUsage,\n type LLMCallbacks,\n} from './llm.js';\n\nexport {\n RealtimeModel,\n RealtimeSession,\n type GenerationCreatedEvent,\n type InputSpeechStartedEvent,\n type InputSpeechStoppedEvent,\n type InputTranscriptionCompleted,\n type MessageGeneration,\n type RealtimeCapabilities,\n type RealtimeModelError,\n type RealtimeSessionReconnectedEvent,\n} from './realtime.js';\n\nexport { RemoteChatContext } from './remote_chat_context.js';\n\nexport {\n computeChatCtxDiff,\n createToolOptions,\n executeToolCall,\n oaiBuildFunctionInfo,\n oaiParams,\n toJsonSchema,\n type OpenAIFunctionParameters,\n} from './utils.js';\n\nexport {\n FallbackAdapter,\n type AvailabilityChangedEvent,\n type FallbackAdapterOptions,\n} from './fallback_adapter.js';\n"],"mappings":"AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OASK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/llm/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport {\n handoff,\n isFunctionTool,\n tool,\n ToolError,\n ToolFlag,\n type AgentHandoff,\n type FunctionTool,\n type ProviderDefinedTool,\n type Tool,\n type ToolChoice,\n type ToolContext,\n type ToolOptions,\n type ToolType,\n} from './tool_context.js';\n\nexport {\n AgentHandoffItem,\n ChatContext,\n ChatMessage,\n createAudioContent,\n createImageContent,\n FunctionCall,\n FunctionCallOutput,\n type AudioContent,\n type ChatContent,\n type ChatItem,\n type ChatRole,\n type ImageContent,\n type MetricsReport,\n} from './chat_context.js';\n\nexport type { ProviderFormat } from './provider_format/index.js';\n\nexport {\n LLM,\n LLMStream,\n type ChatChunk,\n type ChoiceDelta,\n type CompletionUsage,\n type LLMCallbacks,\n} from './llm.js';\n\nexport {\n RealtimeModel,\n RealtimeSession,\n type GenerationCreatedEvent,\n type InputSpeechStartedEvent,\n type InputSpeechStoppedEvent,\n type InputTranscriptionCompleted,\n type MessageGeneration,\n type RealtimeCapabilities,\n type RealtimeModelError,\n type RealtimeSessionReconnectedEvent,\n} from './realtime.js';\n\nexport { RemoteChatContext } from './remote_chat_context.js';\n\nexport {\n computeChatCtxDiff,\n createToolOptions,\n executeToolCall,\n oaiBuildFunctionInfo,\n oaiParams,\n toJsonSchema,\n type OpenAIFunctionParameters,\n} from './utils.js';\n\nexport {\n FallbackAdapter,\n type AvailabilityChangedEvent,\n type FallbackAdapterOptions,\n} from './fallback_adapter.js';\n"],"mappings":"AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OASK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAOK;AAIP;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,OASK;AAEP,SAAS,yBAAyB;AAElC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAEP;AAAA,EACE;AAAA,OAGK;","names":[]}
|
package/dist/llm/llm.cjs
CHANGED
|
@@ -44,6 +44,17 @@ class LLM extends import_node_events.EventEmitter {
|
|
|
44
44
|
get model() {
|
|
45
45
|
return "unknown";
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the provider name for this LLM instance.
|
|
49
|
+
*
|
|
50
|
+
* @returns The provider name if available, "unknown" otherwise.
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* Plugins should override this property to provide their provider information.
|
|
54
|
+
*/
|
|
55
|
+
get provider() {
|
|
56
|
+
return "unknown";
|
|
57
|
+
}
|
|
47
58
|
/**
|
|
48
59
|
* Pre-warm connection to the LLM service
|
|
49
60
|
*/
|
|
@@ -178,7 +189,11 @@ class LLMStream {
|
|
|
178
189
|
return 0;
|
|
179
190
|
}
|
|
180
191
|
return ((usage == null ? void 0 : usage.completionTokens) || 0) / (durationMs / 1e3);
|
|
181
|
-
})()
|
|
192
|
+
})(),
|
|
193
|
+
metadata: {
|
|
194
|
+
modelProvider: this.#llm.provider,
|
|
195
|
+
modelName: this.#llm.model
|
|
196
|
+
}
|
|
182
197
|
};
|
|
183
198
|
if (this.#llmRequestSpan) {
|
|
184
199
|
this.#llmRequestSpan.setAttribute(import_telemetry.traceTypes.ATTR_LLM_METRICS, JSON.stringify(metrics));
|
package/dist/llm/llm.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport type { Span } from '@opentelemetry/api';\nimport { EventEmitter } from 'node:events';\nimport { APIConnectionError, APIError } from '../_exceptions.js';\nimport { log } from '../log.js';\nimport type { LLMMetrics } from '../metrics/base.js';\nimport { recordException, traceTypes, tracer } from '../telemetry/index.js';\nimport { type APIConnectOptions, intervalForRetry } from '../types.js';\nimport { AsyncIterableQueue, delay, startSoon, toError } from '../utils.js';\nimport { type ChatContext, type ChatRole, type FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport interface ChoiceDelta {\n role: ChatRole;\n content?: string;\n toolCalls?: FunctionCall[];\n extra?: Record<string, unknown>;\n}\n\nexport interface CompletionUsage {\n completionTokens: number;\n promptTokens: number;\n promptCachedTokens: number;\n totalTokens: number;\n}\n\nexport interface ChatChunk {\n id: string;\n delta?: ChoiceDelta;\n usage?: CompletionUsage;\n}\n\nexport interface LLMError {\n type: 'llm_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport type LLMCallbacks = {\n ['metrics_collected']: (metrics: LLMMetrics) => void;\n ['error']: (error: LLMError) => void;\n};\n\nexport abstract class LLM extends (EventEmitter as new () => TypedEmitter<LLMCallbacks>) {\n constructor() {\n super();\n }\n\n abstract label(): string;\n\n /**\n * Get the model name/identifier for this LLM instance.\n *\n * @returns The model name if available, \"unknown\" otherwise.\n *\n * @remarks\n * Plugins should override this property to provide their model information.\n */\n get model(): string {\n return 'unknown';\n }\n\n /**\n * Returns a {@link LLMStream} that can be used to push text and receive LLM responses.\n */\n abstract chat({\n chatCtx,\n toolCtx,\n connOptions,\n parallelToolCalls,\n toolChoice,\n extraKwargs,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: ToolChoice;\n extraKwargs?: Record<string, unknown>;\n }): LLMStream;\n\n /**\n * Pre-warm connection to the LLM service\n */\n prewarm(): void {\n // Default implementation - subclasses can override\n }\n\n async aclose(): Promise<void> {\n // Default implementation - subclasses can override\n }\n}\n\nexport abstract class LLMStream implements AsyncIterableIterator<ChatChunk> {\n protected output = new AsyncIterableQueue<ChatChunk>();\n protected queue = new AsyncIterableQueue<ChatChunk>();\n protected closed = false;\n protected abortController = new AbortController();\n protected _connOptions: APIConnectOptions;\n protected logger = log();\n\n #llm: LLM;\n #chatCtx: ChatContext;\n #toolCtx?: ToolContext;\n #llmRequestSpan?: Span;\n\n constructor(\n llm: LLM,\n {\n chatCtx,\n toolCtx,\n connOptions,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions: APIConnectOptions;\n },\n ) {\n this.#llm = llm;\n this.#chatCtx = chatCtx;\n this.#toolCtx = toolCtx;\n this._connOptions = connOptions;\n this.monitorMetrics();\n this.abortController.signal.addEventListener('abort', () => {\n // TODO (AJS-37) clean this up when we refactor with streams\n this.output.close();\n this.closed = true;\n });\n\n // this is a hack to immitate asyncio.create_task so that mainTask\n // is run **after** the constructor has finished. Otherwise we get\n // runtime error when trying to access class variables in the\n // `run` method.\n startSoon(() => this.mainTask().finally(() => this.queue.close()));\n }\n\n private _mainTaskImpl = async (span: Span) => {\n this.#llmRequestSpan = span;\n span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, this.#llm.model);\n\n for (let i = 0; i < this._connOptions.maxRetry + 1; i++) {\n try {\n return await tracer.startActiveSpan(\n async (attemptSpan) => {\n attemptSpan.setAttribute(traceTypes.ATTR_RETRY_COUNT, i);\n try {\n return await this.run();\n } catch (error) {\n recordException(attemptSpan, toError(error));\n throw error;\n }\n },\n { name: 'llm_request_run' },\n );\n } catch (error) {\n if (error instanceof APIError) {\n const retryInterval = intervalForRetry(this._connOptions, i);\n\n if (this._connOptions.maxRetry === 0 || !error.retryable) {\n this.emitError({ error, recoverable: false });\n throw error;\n } else if (i === this._connOptions.maxRetry) {\n this.emitError({ error, recoverable: false });\n throw new APIConnectionError({\n message: `failed to generate LLM completion after ${this._connOptions.maxRetry + 1} attempts`,\n options: { retryable: false },\n });\n } else {\n this.emitError({ error, recoverable: true });\n this.logger.warn(\n { llm: this.#llm.label(), attempt: i + 1, error },\n `failed to generate LLM completion, retrying in ${retryInterval}ms`,\n );\n }\n\n if (retryInterval > 0) {\n await delay(retryInterval);\n }\n } else {\n this.emitError({ error: toError(error), recoverable: false });\n throw error;\n }\n }\n }\n };\n\n private mainTask = async () =>\n tracer.startActiveSpan(async (span) => this._mainTaskImpl(span), {\n name: 'llm_request',\n endOnExit: false,\n });\n\n private emitError({ error, recoverable }: { error: Error; recoverable: boolean }) {\n this.#llm.emit('error', {\n type: 'llm_error',\n timestamp: Date.now(),\n label: this.#llm.label(),\n error,\n recoverable,\n });\n }\n\n protected async monitorMetrics() {\n const startTime = process.hrtime.bigint();\n let ttft: bigint = BigInt(-1);\n let requestId = '';\n let usage: CompletionUsage | undefined;\n let completionStartTime: string | undefined;\n\n for await (const ev of this.queue) {\n if (this.abortController.signal.aborted) {\n break;\n }\n this.output.put(ev);\n requestId = ev.id;\n if (ttft === BigInt(-1)) {\n ttft = process.hrtime.bigint() - startTime;\n completionStartTime = new Date().toISOString();\n }\n if (ev.usage) {\n usage = ev.usage;\n }\n }\n this.output.close();\n\n const duration = process.hrtime.bigint() - startTime;\n const durationMs = Math.trunc(Number(duration / BigInt(1000000)));\n const metrics: LLMMetrics = {\n type: 'llm_metrics',\n timestamp: Date.now(),\n requestId,\n ttftMs: ttft === BigInt(-1) ? -1 : Math.trunc(Number(ttft / BigInt(1000000))),\n durationMs,\n cancelled: this.abortController.signal.aborted,\n label: this.#llm.label(),\n completionTokens: usage?.completionTokens || 0,\n promptTokens: usage?.promptTokens || 0,\n promptCachedTokens: usage?.promptCachedTokens || 0,\n totalTokens: usage?.totalTokens || 0,\n tokensPerSecond: (() => {\n if (durationMs <= 0) {\n return 0;\n }\n return (usage?.completionTokens || 0) / (durationMs / 1000);\n })(),\n };\n\n if (this.#llmRequestSpan) {\n this.#llmRequestSpan.setAttribute(traceTypes.ATTR_LLM_METRICS, JSON.stringify(metrics));\n\n this.#llmRequestSpan.setAttributes({\n [traceTypes.ATTR_GEN_AI_USAGE_INPUT_TOKENS]: metrics.promptTokens,\n [traceTypes.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS]: metrics.completionTokens,\n });\n\n if (completionStartTime) {\n this.#llmRequestSpan.setAttribute(\n traceTypes.ATTR_LANGFUSE_COMPLETION_START_TIME,\n completionStartTime,\n );\n }\n\n // End the span now that metrics are collected\n this.#llmRequestSpan.end();\n }\n\n this.#llm.emit('metrics_collected', metrics);\n }\n\n protected abstract run(): Promise<void>;\n\n /** The function context of this stream. */\n get toolCtx(): ToolContext | undefined {\n return this.#toolCtx;\n }\n\n /** The initial chat context of this stream. */\n get chatCtx(): ChatContext {\n return this.#chatCtx;\n }\n\n /** The connection options for this stream. */\n get connOptions(): APIConnectOptions {\n return this._connOptions;\n }\n\n next(): Promise<IteratorResult<ChatChunk>> {\n return this.output.next();\n }\n\n close() {\n this.abortController.abort();\n }\n\n [Symbol.asyncIterator](): LLMStream {\n return this;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,yBAA6B;AAC7B,wBAA6C;AAC7C,iBAAoB;AAEpB,uBAAoD;AACpD,mBAAyD;AACzD,mBAA8D;AAC9D,0BAAmE;AAoC5D,MAAe,YAAa,gCAAsD;AAAA,EACvF,cAAc;AACZ,UAAM;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,IAAI,QAAgB;AAClB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAwBA,UAAgB;AAAA,EAEhB;AAAA,EAEA,MAAM,SAAwB;AAAA,EAE9B;AACF;AAEO,MAAe,UAAsD;AAAA,EAChE,SAAS,IAAI,gCAA8B;AAAA,EAC3C,QAAQ,IAAI,gCAA8B;AAAA,EAC1C,SAAS;AAAA,EACT,kBAAkB,IAAI,gBAAgB;AAAA,EACtC;AAAA,EACA,aAAS,gBAAI;AAAA,EAEvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YACE,KACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKA;AACA,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,gBAAgB,OAAO,iBAAiB,SAAS,MAAM;AAE1D,WAAK,OAAO,MAAM;AAClB,WAAK,SAAS;AAAA,IAChB,CAAC;AAMD,gCAAU,MAAM,KAAK,SAAS,EAAE,QAAQ,MAAM,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,EACnE;AAAA,EAEQ,gBAAgB,OAAO,SAAe;AAC5C,SAAK,kBAAkB;AACvB,SAAK,aAAa,4BAAW,2BAA2B,KAAK,KAAK,KAAK;AAEvE,aAAS,IAAI,GAAG,IAAI,KAAK,aAAa,WAAW,GAAG,KAAK;AACvD,UAAI;AACF,eAAO,MAAM,wBAAO;AAAA,UAClB,OAAO,gBAAgB;AACrB,wBAAY,aAAa,4BAAW,kBAAkB,CAAC;AACvD,gBAAI;AACF,qBAAO,MAAM,KAAK,IAAI;AAAA,YACxB,SAAS,OAAO;AACd,oDAAgB,iBAAa,sBAAQ,KAAK,CAAC;AAC3C,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,EAAE,MAAM,kBAAkB;AAAA,QAC5B;AAAA,MACF,SAAS,OAAO;AACd,YAAI,iBAAiB,4BAAU;AAC7B,gBAAM,oBAAgB,+BAAiB,KAAK,cAAc,CAAC;AAE3D,cAAI,KAAK,aAAa,aAAa,KAAK,CAAC,MAAM,WAAW;AACxD,iBAAK,UAAU,EAAE,OAAO,aAAa,MAAM,CAAC;AAC5C,kBAAM;AAAA,UACR,WAAW,MAAM,KAAK,aAAa,UAAU;AAC3C,iBAAK,UAAU,EAAE,OAAO,aAAa,MAAM,CAAC;AAC5C,kBAAM,IAAI,qCAAmB;AAAA,cAC3B,SAAS,2CAA2C,KAAK,aAAa,WAAW,CAAC;AAAA,cAClF,SAAS,EAAE,WAAW,MAAM;AAAA,YAC9B,CAAC;AAAA,UACH,OAAO;AACL,iBAAK,UAAU,EAAE,OAAO,aAAa,KAAK,CAAC;AAC3C,iBAAK,OAAO;AAAA,cACV,EAAE,KAAK,KAAK,KAAK,MAAM,GAAG,SAAS,IAAI,GAAG,MAAM;AAAA,cAChD,kDAAkD,aAAa;AAAA,YACjE;AAAA,UACF;AAEA,cAAI,gBAAgB,GAAG;AACrB,sBAAM,oBAAM,aAAa;AAAA,UAC3B;AAAA,QACF,OAAO;AACL,eAAK,UAAU,EAAE,WAAO,sBAAQ,KAAK,GAAG,aAAa,MAAM,CAAC;AAC5D,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,WAAW,YACjB,wBAAO,gBAAgB,OAAO,SAAS,KAAK,cAAc,IAAI,GAAG;AAAA,IAC/D,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AAAA,EAEK,UAAU,EAAE,OAAO,YAAY,GAA2C;AAChF,SAAK,KAAK,KAAK,SAAS;AAAA,MACtB,MAAM;AAAA,MACN,WAAW,KAAK,IAAI;AAAA,MACpB,OAAO,KAAK,KAAK,MAAM;AAAA,MACvB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAgB,iBAAiB;AAC/B,UAAM,YAAY,QAAQ,OAAO,OAAO;AACxC,QAAI,OAAe,OAAO,EAAE;AAC5B,QAAI,YAAY;AAChB,QAAI;AACJ,QAAI;AAEJ,qBAAiB,MAAM,KAAK,OAAO;AACjC,UAAI,KAAK,gBAAgB,OAAO,SAAS;AACvC;AAAA,MACF;AACA,WAAK,OAAO,IAAI,EAAE;AAClB,kBAAY,GAAG;AACf,UAAI,SAAS,OAAO,EAAE,GAAG;AACvB,eAAO,QAAQ,OAAO,OAAO,IAAI;AACjC,+BAAsB,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC/C;AACA,UAAI,GAAG,OAAO;AACZ,gBAAQ,GAAG;AAAA,MACb;AAAA,IACF;AACA,SAAK,OAAO,MAAM;AAElB,UAAM,WAAW,QAAQ,OAAO,OAAO,IAAI;AAC3C,UAAM,aAAa,KAAK,MAAM,OAAO,WAAW,OAAO,GAAO,CAAC,CAAC;AAChE,UAAM,UAAsB;AAAA,MAC1B,MAAM;AAAA,MACN,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,MACA,QAAQ,SAAS,OAAO,EAAE,IAAI,KAAK,KAAK,MAAM,OAAO,OAAO,OAAO,GAAO,CAAC,CAAC;AAAA,MAC5E;AAAA,MACA,WAAW,KAAK,gBAAgB,OAAO;AAAA,MACvC,OAAO,KAAK,KAAK,MAAM;AAAA,MACvB,mBAAkB,+BAAO,qBAAoB;AAAA,MAC7C,eAAc,+BAAO,iBAAgB;AAAA,MACrC,qBAAoB,+BAAO,uBAAsB;AAAA,MACjD,cAAa,+BAAO,gBAAe;AAAA,MACnC,kBAAkB,MAAM;AACtB,YAAI,cAAc,GAAG;AACnB,iBAAO;AAAA,QACT;AACA,iBAAQ,+BAAO,qBAAoB,MAAM,aAAa;AAAA,MACxD,GAAG;AAAA,IACL;AAEA,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,aAAa,4BAAW,kBAAkB,KAAK,UAAU,OAAO,CAAC;AAEtF,WAAK,gBAAgB,cAAc;AAAA,QACjC,CAAC,4BAAW,8BAA8B,GAAG,QAAQ;AAAA,QACrD,CAAC,4BAAW,+BAA+B,GAAG,QAAQ;AAAA,MACxD,CAAC;AAED,UAAI,qBAAqB;AACvB,aAAK,gBAAgB;AAAA,UACnB,4BAAW;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAGA,WAAK,gBAAgB,IAAI;AAAA,IAC3B;AAEA,SAAK,KAAK,KAAK,qBAAqB,OAAO;AAAA,EAC7C;AAAA;AAAA,EAKA,IAAI,UAAmC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,UAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,cAAiC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAA2C;AACzC,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AAAA,EAEA,QAAQ;AACN,SAAK,gBAAgB,MAAM;AAAA,EAC7B;AAAA,EAEA,CAAC,OAAO,aAAa,IAAe;AAClC,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/llm/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport type { Span } from '@opentelemetry/api';\nimport { EventEmitter } from 'node:events';\nimport { APIConnectionError, APIError } from '../_exceptions.js';\nimport { log } from '../log.js';\nimport type { LLMMetrics } from '../metrics/base.js';\nimport { recordException, traceTypes, tracer } from '../telemetry/index.js';\nimport { type APIConnectOptions, intervalForRetry } from '../types.js';\nimport { AsyncIterableQueue, delay, startSoon, toError } from '../utils.js';\nimport { type ChatContext, type ChatRole, type FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport interface ChoiceDelta {\n role: ChatRole;\n content?: string;\n toolCalls?: FunctionCall[];\n extra?: Record<string, unknown>;\n}\n\nexport interface CompletionUsage {\n completionTokens: number;\n promptTokens: number;\n promptCachedTokens: number;\n totalTokens: number;\n}\n\nexport interface ChatChunk {\n id: string;\n delta?: ChoiceDelta;\n usage?: CompletionUsage;\n}\n\nexport interface LLMError {\n type: 'llm_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport type LLMCallbacks = {\n ['metrics_collected']: (metrics: LLMMetrics) => void;\n ['error']: (error: LLMError) => void;\n};\n\nexport abstract class LLM extends (EventEmitter as new () => TypedEmitter<LLMCallbacks>) {\n constructor() {\n super();\n }\n\n abstract label(): string;\n\n /**\n * Get the model name/identifier for this LLM instance.\n *\n * @returns The model name if available, \"unknown\" otherwise.\n *\n * @remarks\n * Plugins should override this property to provide their model information.\n */\n get model(): string {\n return 'unknown';\n }\n\n /**\n * Get the provider name for this LLM instance.\n *\n * @returns The provider name if available, \"unknown\" otherwise.\n *\n * @remarks\n * Plugins should override this property to provide their provider information.\n */\n get provider(): string {\n return 'unknown';\n }\n\n /**\n * Returns a {@link LLMStream} that can be used to push text and receive LLM responses.\n */\n abstract chat({\n chatCtx,\n toolCtx,\n connOptions,\n parallelToolCalls,\n toolChoice,\n extraKwargs,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: ToolChoice;\n extraKwargs?: Record<string, unknown>;\n }): LLMStream;\n\n /**\n * Pre-warm connection to the LLM service\n */\n prewarm(): void {\n // Default implementation - subclasses can override\n }\n\n async aclose(): Promise<void> {\n // Default implementation - subclasses can override\n }\n}\n\nexport abstract class LLMStream implements AsyncIterableIterator<ChatChunk> {\n protected output = new AsyncIterableQueue<ChatChunk>();\n protected queue = new AsyncIterableQueue<ChatChunk>();\n protected closed = false;\n protected abortController = new AbortController();\n protected _connOptions: APIConnectOptions;\n protected logger = log();\n\n #llm: LLM;\n #chatCtx: ChatContext;\n #toolCtx?: ToolContext;\n #llmRequestSpan?: Span;\n\n constructor(\n llm: LLM,\n {\n chatCtx,\n toolCtx,\n connOptions,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions: APIConnectOptions;\n },\n ) {\n this.#llm = llm;\n this.#chatCtx = chatCtx;\n this.#toolCtx = toolCtx;\n this._connOptions = connOptions;\n this.monitorMetrics();\n this.abortController.signal.addEventListener('abort', () => {\n // TODO (AJS-37) clean this up when we refactor with streams\n this.output.close();\n this.closed = true;\n });\n\n // this is a hack to immitate asyncio.create_task so that mainTask\n // is run **after** the constructor has finished. Otherwise we get\n // runtime error when trying to access class variables in the\n // `run` method.\n startSoon(() => this.mainTask().finally(() => this.queue.close()));\n }\n\n private _mainTaskImpl = async (span: Span) => {\n this.#llmRequestSpan = span;\n span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, this.#llm.model);\n\n for (let i = 0; i < this._connOptions.maxRetry + 1; i++) {\n try {\n return await tracer.startActiveSpan(\n async (attemptSpan) => {\n attemptSpan.setAttribute(traceTypes.ATTR_RETRY_COUNT, i);\n try {\n return await this.run();\n } catch (error) {\n recordException(attemptSpan, toError(error));\n throw error;\n }\n },\n { name: 'llm_request_run' },\n );\n } catch (error) {\n if (error instanceof APIError) {\n const retryInterval = intervalForRetry(this._connOptions, i);\n\n if (this._connOptions.maxRetry === 0 || !error.retryable) {\n this.emitError({ error, recoverable: false });\n throw error;\n } else if (i === this._connOptions.maxRetry) {\n this.emitError({ error, recoverable: false });\n throw new APIConnectionError({\n message: `failed to generate LLM completion after ${this._connOptions.maxRetry + 1} attempts`,\n options: { retryable: false },\n });\n } else {\n this.emitError({ error, recoverable: true });\n this.logger.warn(\n { llm: this.#llm.label(), attempt: i + 1, error },\n `failed to generate LLM completion, retrying in ${retryInterval}ms`,\n );\n }\n\n if (retryInterval > 0) {\n await delay(retryInterval);\n }\n } else {\n this.emitError({ error: toError(error), recoverable: false });\n throw error;\n }\n }\n }\n };\n\n private mainTask = async () =>\n tracer.startActiveSpan(async (span) => this._mainTaskImpl(span), {\n name: 'llm_request',\n endOnExit: false,\n });\n\n private emitError({ error, recoverable }: { error: Error; recoverable: boolean }) {\n this.#llm.emit('error', {\n type: 'llm_error',\n timestamp: Date.now(),\n label: this.#llm.label(),\n error,\n recoverable,\n });\n }\n\n protected async monitorMetrics() {\n const startTime = process.hrtime.bigint();\n let ttft: bigint = BigInt(-1);\n let requestId = '';\n let usage: CompletionUsage | undefined;\n let completionStartTime: string | undefined;\n\n for await (const ev of this.queue) {\n if (this.abortController.signal.aborted) {\n break;\n }\n this.output.put(ev);\n requestId = ev.id;\n if (ttft === BigInt(-1)) {\n ttft = process.hrtime.bigint() - startTime;\n completionStartTime = new Date().toISOString();\n }\n if (ev.usage) {\n usage = ev.usage;\n }\n }\n this.output.close();\n\n const duration = process.hrtime.bigint() - startTime;\n const durationMs = Math.trunc(Number(duration / BigInt(1000000)));\n const metrics: LLMMetrics = {\n type: 'llm_metrics',\n timestamp: Date.now(),\n requestId,\n ttftMs: ttft === BigInt(-1) ? -1 : Math.trunc(Number(ttft / BigInt(1000000))),\n durationMs,\n cancelled: this.abortController.signal.aborted,\n label: this.#llm.label(),\n completionTokens: usage?.completionTokens || 0,\n promptTokens: usage?.promptTokens || 0,\n promptCachedTokens: usage?.promptCachedTokens || 0,\n totalTokens: usage?.totalTokens || 0,\n tokensPerSecond: (() => {\n if (durationMs <= 0) {\n return 0;\n }\n return (usage?.completionTokens || 0) / (durationMs / 1000);\n })(),\n metadata: {\n modelProvider: this.#llm.provider,\n modelName: this.#llm.model,\n },\n };\n\n if (this.#llmRequestSpan) {\n this.#llmRequestSpan.setAttribute(traceTypes.ATTR_LLM_METRICS, JSON.stringify(metrics));\n\n this.#llmRequestSpan.setAttributes({\n [traceTypes.ATTR_GEN_AI_USAGE_INPUT_TOKENS]: metrics.promptTokens,\n [traceTypes.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS]: metrics.completionTokens,\n });\n\n if (completionStartTime) {\n this.#llmRequestSpan.setAttribute(\n traceTypes.ATTR_LANGFUSE_COMPLETION_START_TIME,\n completionStartTime,\n );\n }\n\n // End the span now that metrics are collected\n this.#llmRequestSpan.end();\n }\n\n this.#llm.emit('metrics_collected', metrics);\n }\n\n protected abstract run(): Promise<void>;\n\n /** The function context of this stream. */\n get toolCtx(): ToolContext | undefined {\n return this.#toolCtx;\n }\n\n /** The initial chat context of this stream. */\n get chatCtx(): ChatContext {\n return this.#chatCtx;\n }\n\n /** The connection options for this stream. */\n get connOptions(): APIConnectOptions {\n return this._connOptions;\n }\n\n next(): Promise<IteratorResult<ChatChunk>> {\n return this.output.next();\n }\n\n close() {\n this.abortController.abort();\n }\n\n [Symbol.asyncIterator](): LLMStream {\n return this;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/llm/llm.d.cts
CHANGED
|
@@ -45,6 +45,15 @@ export declare abstract class LLM extends LLM_base {
|
|
|
45
45
|
* Plugins should override this property to provide their model information.
|
|
46
46
|
*/
|
|
47
47
|
get model(): string;
|
|
48
|
+
/**
|
|
49
|
+
* Get the provider name for this LLM instance.
|
|
50
|
+
*
|
|
51
|
+
* @returns The provider name if available, "unknown" otherwise.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* Plugins should override this property to provide their provider information.
|
|
55
|
+
*/
|
|
56
|
+
get provider(): string;
|
|
48
57
|
/**
|
|
49
58
|
* Returns a {@link LLMStream} that can be used to push text and receive LLM responses.
|
|
50
59
|
*/
|
package/dist/llm/llm.d.ts
CHANGED
|
@@ -45,6 +45,15 @@ export declare abstract class LLM extends LLM_base {
|
|
|
45
45
|
* Plugins should override this property to provide their model information.
|
|
46
46
|
*/
|
|
47
47
|
get model(): string;
|
|
48
|
+
/**
|
|
49
|
+
* Get the provider name for this LLM instance.
|
|
50
|
+
*
|
|
51
|
+
* @returns The provider name if available, "unknown" otherwise.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* Plugins should override this property to provide their provider information.
|
|
55
|
+
*/
|
|
56
|
+
get provider(): string;
|
|
48
57
|
/**
|
|
49
58
|
* Returns a {@link LLMStream} that can be used to push text and receive LLM responses.
|
|
50
59
|
*/
|
package/dist/llm/llm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/llm/llm.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/llm/llm.ts"],"names":[],"mappings":"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"}
|
package/dist/llm/llm.js
CHANGED
|
@@ -20,6 +20,17 @@ class LLM extends EventEmitter {
|
|
|
20
20
|
get model() {
|
|
21
21
|
return "unknown";
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the provider name for this LLM instance.
|
|
25
|
+
*
|
|
26
|
+
* @returns The provider name if available, "unknown" otherwise.
|
|
27
|
+
*
|
|
28
|
+
* @remarks
|
|
29
|
+
* Plugins should override this property to provide their provider information.
|
|
30
|
+
*/
|
|
31
|
+
get provider() {
|
|
32
|
+
return "unknown";
|
|
33
|
+
}
|
|
23
34
|
/**
|
|
24
35
|
* Pre-warm connection to the LLM service
|
|
25
36
|
*/
|
|
@@ -154,7 +165,11 @@ class LLMStream {
|
|
|
154
165
|
return 0;
|
|
155
166
|
}
|
|
156
167
|
return ((usage == null ? void 0 : usage.completionTokens) || 0) / (durationMs / 1e3);
|
|
157
|
-
})()
|
|
168
|
+
})(),
|
|
169
|
+
metadata: {
|
|
170
|
+
modelProvider: this.#llm.provider,
|
|
171
|
+
modelName: this.#llm.model
|
|
172
|
+
}
|
|
158
173
|
};
|
|
159
174
|
if (this.#llmRequestSpan) {
|
|
160
175
|
this.#llmRequestSpan.setAttribute(traceTypes.ATTR_LLM_METRICS, JSON.stringify(metrics));
|
package/dist/llm/llm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport type { Span } from '@opentelemetry/api';\nimport { EventEmitter } from 'node:events';\nimport { APIConnectionError, APIError } from '../_exceptions.js';\nimport { log } from '../log.js';\nimport type { LLMMetrics } from '../metrics/base.js';\nimport { recordException, traceTypes, tracer } from '../telemetry/index.js';\nimport { type APIConnectOptions, intervalForRetry } from '../types.js';\nimport { AsyncIterableQueue, delay, startSoon, toError } from '../utils.js';\nimport { type ChatContext, type ChatRole, type FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport interface ChoiceDelta {\n role: ChatRole;\n content?: string;\n toolCalls?: FunctionCall[];\n extra?: Record<string, unknown>;\n}\n\nexport interface CompletionUsage {\n completionTokens: number;\n promptTokens: number;\n promptCachedTokens: number;\n totalTokens: number;\n}\n\nexport interface ChatChunk {\n id: string;\n delta?: ChoiceDelta;\n usage?: CompletionUsage;\n}\n\nexport interface LLMError {\n type: 'llm_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport type LLMCallbacks = {\n ['metrics_collected']: (metrics: LLMMetrics) => void;\n ['error']: (error: LLMError) => void;\n};\n\nexport abstract class LLM extends (EventEmitter as new () => TypedEmitter<LLMCallbacks>) {\n constructor() {\n super();\n }\n\n abstract label(): string;\n\n /**\n * Get the model name/identifier for this LLM instance.\n *\n * @returns The model name if available, \"unknown\" otherwise.\n *\n * @remarks\n * Plugins should override this property to provide their model information.\n */\n get model(): string {\n return 'unknown';\n }\n\n /**\n * Returns a {@link LLMStream} that can be used to push text and receive LLM responses.\n */\n abstract chat({\n chatCtx,\n toolCtx,\n connOptions,\n parallelToolCalls,\n toolChoice,\n extraKwargs,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: ToolChoice;\n extraKwargs?: Record<string, unknown>;\n }): LLMStream;\n\n /**\n * Pre-warm connection to the LLM service\n */\n prewarm(): void {\n // Default implementation - subclasses can override\n }\n\n async aclose(): Promise<void> {\n // Default implementation - subclasses can override\n }\n}\n\nexport abstract class LLMStream implements AsyncIterableIterator<ChatChunk> {\n protected output = new AsyncIterableQueue<ChatChunk>();\n protected queue = new AsyncIterableQueue<ChatChunk>();\n protected closed = false;\n protected abortController = new AbortController();\n protected _connOptions: APIConnectOptions;\n protected logger = log();\n\n #llm: LLM;\n #chatCtx: ChatContext;\n #toolCtx?: ToolContext;\n #llmRequestSpan?: Span;\n\n constructor(\n llm: LLM,\n {\n chatCtx,\n toolCtx,\n connOptions,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions: APIConnectOptions;\n },\n ) {\n this.#llm = llm;\n this.#chatCtx = chatCtx;\n this.#toolCtx = toolCtx;\n this._connOptions = connOptions;\n this.monitorMetrics();\n this.abortController.signal.addEventListener('abort', () => {\n // TODO (AJS-37) clean this up when we refactor with streams\n this.output.close();\n this.closed = true;\n });\n\n // this is a hack to immitate asyncio.create_task so that mainTask\n // is run **after** the constructor has finished. Otherwise we get\n // runtime error when trying to access class variables in the\n // `run` method.\n startSoon(() => this.mainTask().finally(() => this.queue.close()));\n }\n\n private _mainTaskImpl = async (span: Span) => {\n this.#llmRequestSpan = span;\n span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, this.#llm.model);\n\n for (let i = 0; i < this._connOptions.maxRetry + 1; i++) {\n try {\n return await tracer.startActiveSpan(\n async (attemptSpan) => {\n attemptSpan.setAttribute(traceTypes.ATTR_RETRY_COUNT, i);\n try {\n return await this.run();\n } catch (error) {\n recordException(attemptSpan, toError(error));\n throw error;\n }\n },\n { name: 'llm_request_run' },\n );\n } catch (error) {\n if (error instanceof APIError) {\n const retryInterval = intervalForRetry(this._connOptions, i);\n\n if (this._connOptions.maxRetry === 0 || !error.retryable) {\n this.emitError({ error, recoverable: false });\n throw error;\n } else if (i === this._connOptions.maxRetry) {\n this.emitError({ error, recoverable: false });\n throw new APIConnectionError({\n message: `failed to generate LLM completion after ${this._connOptions.maxRetry + 1} attempts`,\n options: { retryable: false },\n });\n } else {\n this.emitError({ error, recoverable: true });\n this.logger.warn(\n { llm: this.#llm.label(), attempt: i + 1, error },\n `failed to generate LLM completion, retrying in ${retryInterval}ms`,\n );\n }\n\n if (retryInterval > 0) {\n await delay(retryInterval);\n }\n } else {\n this.emitError({ error: toError(error), recoverable: false });\n throw error;\n }\n }\n }\n };\n\n private mainTask = async () =>\n tracer.startActiveSpan(async (span) => this._mainTaskImpl(span), {\n name: 'llm_request',\n endOnExit: false,\n });\n\n private emitError({ error, recoverable }: { error: Error; recoverable: boolean }) {\n this.#llm.emit('error', {\n type: 'llm_error',\n timestamp: Date.now(),\n label: this.#llm.label(),\n error,\n recoverable,\n });\n }\n\n protected async monitorMetrics() {\n const startTime = process.hrtime.bigint();\n let ttft: bigint = BigInt(-1);\n let requestId = '';\n let usage: CompletionUsage | undefined;\n let completionStartTime: string | undefined;\n\n for await (const ev of this.queue) {\n if (this.abortController.signal.aborted) {\n break;\n }\n this.output.put(ev);\n requestId = ev.id;\n if (ttft === BigInt(-1)) {\n ttft = process.hrtime.bigint() - startTime;\n completionStartTime = new Date().toISOString();\n }\n if (ev.usage) {\n usage = ev.usage;\n }\n }\n this.output.close();\n\n const duration = process.hrtime.bigint() - startTime;\n const durationMs = Math.trunc(Number(duration / BigInt(1000000)));\n const metrics: LLMMetrics = {\n type: 'llm_metrics',\n timestamp: Date.now(),\n requestId,\n ttftMs: ttft === BigInt(-1) ? -1 : Math.trunc(Number(ttft / BigInt(1000000))),\n durationMs,\n cancelled: this.abortController.signal.aborted,\n label: this.#llm.label(),\n completionTokens: usage?.completionTokens || 0,\n promptTokens: usage?.promptTokens || 0,\n promptCachedTokens: usage?.promptCachedTokens || 0,\n totalTokens: usage?.totalTokens || 0,\n tokensPerSecond: (() => {\n if (durationMs <= 0) {\n return 0;\n }\n return (usage?.completionTokens || 0) / (durationMs / 1000);\n })(),\n };\n\n if (this.#llmRequestSpan) {\n this.#llmRequestSpan.setAttribute(traceTypes.ATTR_LLM_METRICS, JSON.stringify(metrics));\n\n this.#llmRequestSpan.setAttributes({\n [traceTypes.ATTR_GEN_AI_USAGE_INPUT_TOKENS]: metrics.promptTokens,\n [traceTypes.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS]: metrics.completionTokens,\n });\n\n if (completionStartTime) {\n this.#llmRequestSpan.setAttribute(\n traceTypes.ATTR_LANGFUSE_COMPLETION_START_TIME,\n completionStartTime,\n );\n }\n\n // End the span now that metrics are collected\n this.#llmRequestSpan.end();\n }\n\n this.#llm.emit('metrics_collected', metrics);\n }\n\n protected abstract run(): Promise<void>;\n\n /** The function context of this stream. */\n get toolCtx(): ToolContext | undefined {\n return this.#toolCtx;\n }\n\n /** The initial chat context of this stream. */\n get chatCtx(): ChatContext {\n return this.#chatCtx;\n }\n\n /** The connection options for this stream. */\n get connOptions(): APIConnectOptions {\n return this._connOptions;\n }\n\n next(): Promise<IteratorResult<ChatChunk>> {\n return this.output.next();\n }\n\n close() {\n this.abortController.abort();\n }\n\n [Symbol.asyncIterator](): LLMStream {\n return this;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/llm/llm.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport type { Span } from '@opentelemetry/api';\nimport { EventEmitter } from 'node:events';\nimport { APIConnectionError, APIError } from '../_exceptions.js';\nimport { log } from '../log.js';\nimport type { LLMMetrics } from '../metrics/base.js';\nimport { recordException, traceTypes, tracer } from '../telemetry/index.js';\nimport { type APIConnectOptions, intervalForRetry } from '../types.js';\nimport { AsyncIterableQueue, delay, startSoon, toError } from '../utils.js';\nimport { type ChatContext, type ChatRole, type FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport interface ChoiceDelta {\n role: ChatRole;\n content?: string;\n toolCalls?: FunctionCall[];\n extra?: Record<string, unknown>;\n}\n\nexport interface CompletionUsage {\n completionTokens: number;\n promptTokens: number;\n promptCachedTokens: number;\n totalTokens: number;\n}\n\nexport interface ChatChunk {\n id: string;\n delta?: ChoiceDelta;\n usage?: CompletionUsage;\n}\n\nexport interface LLMError {\n type: 'llm_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport type LLMCallbacks = {\n ['metrics_collected']: (metrics: LLMMetrics) => void;\n ['error']: (error: LLMError) => void;\n};\n\nexport abstract class LLM extends (EventEmitter as new () => TypedEmitter<LLMCallbacks>) {\n constructor() {\n super();\n }\n\n abstract label(): string;\n\n /**\n * Get the model name/identifier for this LLM instance.\n *\n * @returns The model name if available, \"unknown\" otherwise.\n *\n * @remarks\n * Plugins should override this property to provide their model information.\n */\n get model(): string {\n return 'unknown';\n }\n\n /**\n * Get the provider name for this LLM instance.\n *\n * @returns The provider name if available, \"unknown\" otherwise.\n *\n * @remarks\n * Plugins should override this property to provide their provider information.\n */\n get provider(): string {\n return 'unknown';\n }\n\n /**\n * Returns a {@link LLMStream} that can be used to push text and receive LLM responses.\n */\n abstract chat({\n chatCtx,\n toolCtx,\n connOptions,\n parallelToolCalls,\n toolChoice,\n extraKwargs,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions?: APIConnectOptions;\n parallelToolCalls?: boolean;\n toolChoice?: ToolChoice;\n extraKwargs?: Record<string, unknown>;\n }): LLMStream;\n\n /**\n * Pre-warm connection to the LLM service\n */\n prewarm(): void {\n // Default implementation - subclasses can override\n }\n\n async aclose(): Promise<void> {\n // Default implementation - subclasses can override\n }\n}\n\nexport abstract class LLMStream implements AsyncIterableIterator<ChatChunk> {\n protected output = new AsyncIterableQueue<ChatChunk>();\n protected queue = new AsyncIterableQueue<ChatChunk>();\n protected closed = false;\n protected abortController = new AbortController();\n protected _connOptions: APIConnectOptions;\n protected logger = log();\n\n #llm: LLM;\n #chatCtx: ChatContext;\n #toolCtx?: ToolContext;\n #llmRequestSpan?: Span;\n\n constructor(\n llm: LLM,\n {\n chatCtx,\n toolCtx,\n connOptions,\n }: {\n chatCtx: ChatContext;\n toolCtx?: ToolContext;\n connOptions: APIConnectOptions;\n },\n ) {\n this.#llm = llm;\n this.#chatCtx = chatCtx;\n this.#toolCtx = toolCtx;\n this._connOptions = connOptions;\n this.monitorMetrics();\n this.abortController.signal.addEventListener('abort', () => {\n // TODO (AJS-37) clean this up when we refactor with streams\n this.output.close();\n this.closed = true;\n });\n\n // this is a hack to immitate asyncio.create_task so that mainTask\n // is run **after** the constructor has finished. Otherwise we get\n // runtime error when trying to access class variables in the\n // `run` method.\n startSoon(() => this.mainTask().finally(() => this.queue.close()));\n }\n\n private _mainTaskImpl = async (span: Span) => {\n this.#llmRequestSpan = span;\n span.setAttribute(traceTypes.ATTR_GEN_AI_REQUEST_MODEL, this.#llm.model);\n\n for (let i = 0; i < this._connOptions.maxRetry + 1; i++) {\n try {\n return await tracer.startActiveSpan(\n async (attemptSpan) => {\n attemptSpan.setAttribute(traceTypes.ATTR_RETRY_COUNT, i);\n try {\n return await this.run();\n } catch (error) {\n recordException(attemptSpan, toError(error));\n throw error;\n }\n },\n { name: 'llm_request_run' },\n );\n } catch (error) {\n if (error instanceof APIError) {\n const retryInterval = intervalForRetry(this._connOptions, i);\n\n if (this._connOptions.maxRetry === 0 || !error.retryable) {\n this.emitError({ error, recoverable: false });\n throw error;\n } else if (i === this._connOptions.maxRetry) {\n this.emitError({ error, recoverable: false });\n throw new APIConnectionError({\n message: `failed to generate LLM completion after ${this._connOptions.maxRetry + 1} attempts`,\n options: { retryable: false },\n });\n } else {\n this.emitError({ error, recoverable: true });\n this.logger.warn(\n { llm: this.#llm.label(), attempt: i + 1, error },\n `failed to generate LLM completion, retrying in ${retryInterval}ms`,\n );\n }\n\n if (retryInterval > 0) {\n await delay(retryInterval);\n }\n } else {\n this.emitError({ error: toError(error), recoverable: false });\n throw error;\n }\n }\n }\n };\n\n private mainTask = async () =>\n tracer.startActiveSpan(async (span) => this._mainTaskImpl(span), {\n name: 'llm_request',\n endOnExit: false,\n });\n\n private emitError({ error, recoverable }: { error: Error; recoverable: boolean }) {\n this.#llm.emit('error', {\n type: 'llm_error',\n timestamp: Date.now(),\n label: this.#llm.label(),\n error,\n recoverable,\n });\n }\n\n protected async monitorMetrics() {\n const startTime = process.hrtime.bigint();\n let ttft: bigint = BigInt(-1);\n let requestId = '';\n let usage: CompletionUsage | undefined;\n let completionStartTime: string | undefined;\n\n for await (const ev of this.queue) {\n if (this.abortController.signal.aborted) {\n break;\n }\n this.output.put(ev);\n requestId = ev.id;\n if (ttft === BigInt(-1)) {\n ttft = process.hrtime.bigint() - startTime;\n completionStartTime = new Date().toISOString();\n }\n if (ev.usage) {\n usage = ev.usage;\n }\n }\n this.output.close();\n\n const duration = process.hrtime.bigint() - startTime;\n const durationMs = Math.trunc(Number(duration / BigInt(1000000)));\n const metrics: LLMMetrics = {\n type: 'llm_metrics',\n timestamp: Date.now(),\n requestId,\n ttftMs: ttft === BigInt(-1) ? -1 : Math.trunc(Number(ttft / BigInt(1000000))),\n durationMs,\n cancelled: this.abortController.signal.aborted,\n label: this.#llm.label(),\n completionTokens: usage?.completionTokens || 0,\n promptTokens: usage?.promptTokens || 0,\n promptCachedTokens: usage?.promptCachedTokens || 0,\n totalTokens: usage?.totalTokens || 0,\n tokensPerSecond: (() => {\n if (durationMs <= 0) {\n return 0;\n }\n return (usage?.completionTokens || 0) / (durationMs / 1000);\n })(),\n metadata: {\n modelProvider: this.#llm.provider,\n modelName: this.#llm.model,\n },\n };\n\n if (this.#llmRequestSpan) {\n this.#llmRequestSpan.setAttribute(traceTypes.ATTR_LLM_METRICS, JSON.stringify(metrics));\n\n this.#llmRequestSpan.setAttributes({\n [traceTypes.ATTR_GEN_AI_USAGE_INPUT_TOKENS]: metrics.promptTokens,\n [traceTypes.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS]: metrics.completionTokens,\n });\n\n if (completionStartTime) {\n this.#llmRequestSpan.setAttribute(\n traceTypes.ATTR_LANGFUSE_COMPLETION_START_TIME,\n completionStartTime,\n );\n }\n\n // End the span now that metrics are collected\n this.#llmRequestSpan.end();\n }\n\n this.#llm.emit('metrics_collected', metrics);\n }\n\n protected abstract run(): Promise<void>;\n\n /** The function context of this stream. */\n get toolCtx(): ToolContext | undefined {\n return this.#toolCtx;\n }\n\n /** The initial chat context of this stream. */\n get chatCtx(): ChatContext {\n return this.#chatCtx;\n }\n\n /** The connection options for this stream. */\n get connOptions(): APIConnectOptions {\n return this._connOptions;\n }\n\n next(): Promise<IteratorResult<ChatChunk>> {\n return this.output.next();\n }\n\n close() {\n this.abortController.abort();\n }\n\n [Symbol.asyncIterator](): LLMStream {\n return this;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ChatContext } from '../chat_context.js';
|
|
2
2
|
export type ProviderFormat = 'openai' | 'openai.responses' | 'google';
|
|
3
|
-
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<[Record<string, unknown>[], import("./google.js").GoogleFormatData]
|
|
3
|
+
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<Record<string, any>[] | [Record<string, unknown>[], import("./google.js").GoogleFormatData]>;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ChatContext } from '../chat_context.js';
|
|
2
2
|
export type ProviderFormat = 'openai' | 'openai.responses' | 'google';
|
|
3
|
-
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<[Record<string, unknown>[], import("./google.js").GoogleFormatData]
|
|
3
|
+
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<Record<string, any>[] | [Record<string, unknown>[], import("./google.js").GoogleFormatData]>;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/llm/realtime.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/realtime.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { EventEmitter } from 'events';\nimport type { ReadableStream } from 'node:stream/web';\nimport { DeferredReadableStream } from '../stream/deferred_stream.js';\nimport { Task } from '../utils.js';\nimport type { TimedString } from '../voice/io.js';\nimport type { ChatContext, FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport type InputSpeechStartedEvent = object;\n\nexport interface InputSpeechStoppedEvent {\n userTranscriptionEnabled: boolean;\n}\n\nexport interface MessageGeneration {\n messageId: string;\n /**\n * Text stream that may contain plain strings or TimedString objects with timestamps.\n */\n textStream: ReadableStream<string | TimedString>;\n audioStream: ReadableStream<AudioFrame>;\n modalities?: Promise<('text' | 'audio')[]>;\n}\n\nexport interface GenerationCreatedEvent {\n messageStream: ReadableStream<MessageGeneration>;\n functionStream: ReadableStream<FunctionCall>;\n userInitiated: boolean;\n /** Response ID for correlating metrics with spans */\n responseId?: string;\n}\n\nexport interface RealtimeModelError {\n type: 'realtime_model_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport interface RealtimeCapabilities {\n messageTruncation: boolean;\n turnDetection: boolean;\n userTranscription: boolean;\n autoToolReplyGeneration: boolean;\n audioOutput: boolean;\n manualFunctionCalls: boolean;\n}\n\nexport interface InputTranscriptionCompleted {\n itemId: string;\n transcript: string;\n isFinal: boolean;\n}\n\nexport interface RealtimeSessionReconnectedEvent {}\n\nexport abstract class RealtimeModel {\n private _capabilities: RealtimeCapabilities;\n\n constructor(capabilities: RealtimeCapabilities) {\n this._capabilities = capabilities;\n }\n\n get capabilities() {\n return this._capabilities;\n }\n\n /** The model name/identifier used by this realtime model */\n abstract get model(): string;\n\n abstract session(): RealtimeSession;\n\n abstract close(): Promise<void>;\n}\n\nexport abstract class RealtimeSession extends EventEmitter {\n protected _realtimeModel: RealtimeModel;\n private deferredInputStream = new DeferredReadableStream<AudioFrame>();\n private _mainTask: Task<void>;\n\n constructor(realtimeModel: RealtimeModel) {\n super();\n this._realtimeModel = realtimeModel;\n this._mainTask = Task.from((controller) => this._mainTaskImpl(controller.signal));\n }\n\n get realtimeModel() {\n return this._realtimeModel;\n }\n\n abstract get chatCtx(): ChatContext;\n\n abstract get tools(): ToolContext;\n\n abstract updateInstructions(instructions: string): Promise<void>;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract updateChatCtx(chatCtx: ChatContext): Promise<void>;\n\n abstract updateTools(tools: ToolContext): Promise<void>;\n\n abstract updateOptions(options: { toolChoice?: ToolChoice | null }): void;\n\n abstract pushAudio(frame: AudioFrame): void;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract generateReply(instructions?: string): Promise<GenerationCreatedEvent>;\n\n /**\n * Commit the input audio buffer to the server\n */\n abstract commitAudio(): Promise<void>;\n\n /**\n * Clear the input audio buffer to the server\n */\n abstract clearAudio(): Promise<void>;\n\n /**\n * Cancel the current generation (do nothing if no generation is in progress)\n */\n abstract interrupt(): Promise<void>;\n\n /**\n * Truncate the message at the given audio end time\n */\n abstract truncate(options: {\n messageId: string;\n audioEndMs: number;\n modalities?: ('text' | 'audio')[];\n audioTranscript?: string;\n }): Promise<void>;\n\n async close(): Promise<void> {\n this._mainTask.cancel();\n }\n\n /**\n * Notifies the model that user activity has started\n */\n startUserActivity(): void {\n return;\n }\n\n private async _mainTaskImpl(signal: AbortSignal): Promise<void> {\n const reader = this.deferredInputStream.stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done || signal.aborted) {\n break;\n }\n this.pushAudio(value);\n }\n }\n\n setInputAudioStream(audioStream: ReadableStream<AudioFrame>): void {\n this.deferredInputStream.setSource(audioStream);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,oBAA6B;AAE7B,6BAAuC;AACvC,mBAAqB;AAsDd,MAAe,cAAc;AAAA,EAC1B;AAAA,EAER,YAAY,cAAoC;AAC9C,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK;AAAA,EACd;
|
|
1
|
+
{"version":3,"sources":["../../src/llm/realtime.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { EventEmitter } from 'events';\nimport type { ReadableStream } from 'node:stream/web';\nimport { DeferredReadableStream } from '../stream/deferred_stream.js';\nimport { Task } from '../utils.js';\nimport type { TimedString } from '../voice/io.js';\nimport type { ChatContext, FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport type InputSpeechStartedEvent = object;\n\nexport interface InputSpeechStoppedEvent {\n userTranscriptionEnabled: boolean;\n}\n\nexport interface MessageGeneration {\n messageId: string;\n /**\n * Text stream that may contain plain strings or TimedString objects with timestamps.\n */\n textStream: ReadableStream<string | TimedString>;\n audioStream: ReadableStream<AudioFrame>;\n modalities?: Promise<('text' | 'audio')[]>;\n}\n\nexport interface GenerationCreatedEvent {\n messageStream: ReadableStream<MessageGeneration>;\n functionStream: ReadableStream<FunctionCall>;\n userInitiated: boolean;\n /** Response ID for correlating metrics with spans */\n responseId?: string;\n}\n\nexport interface RealtimeModelError {\n type: 'realtime_model_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport interface RealtimeCapabilities {\n messageTruncation: boolean;\n turnDetection: boolean;\n userTranscription: boolean;\n autoToolReplyGeneration: boolean;\n audioOutput: boolean;\n manualFunctionCalls: boolean;\n}\n\nexport interface InputTranscriptionCompleted {\n itemId: string;\n transcript: string;\n isFinal: boolean;\n}\n\nexport interface RealtimeSessionReconnectedEvent {}\n\nexport abstract class RealtimeModel {\n private _capabilities: RealtimeCapabilities;\n\n constructor(capabilities: RealtimeCapabilities) {\n this._capabilities = capabilities;\n }\n\n get capabilities() {\n return this._capabilities;\n }\n\n /** The model name/identifier used by this realtime model */\n abstract get model(): string;\n\n get provider(): string {\n return 'unknown';\n }\n\n abstract session(): RealtimeSession;\n\n abstract close(): Promise<void>;\n}\n\nexport abstract class RealtimeSession extends EventEmitter {\n protected _realtimeModel: RealtimeModel;\n private deferredInputStream = new DeferredReadableStream<AudioFrame>();\n private _mainTask: Task<void>;\n\n constructor(realtimeModel: RealtimeModel) {\n super();\n this._realtimeModel = realtimeModel;\n this._mainTask = Task.from((controller) => this._mainTaskImpl(controller.signal));\n }\n\n get realtimeModel() {\n return this._realtimeModel;\n }\n\n abstract get chatCtx(): ChatContext;\n\n abstract get tools(): ToolContext;\n\n abstract updateInstructions(instructions: string): Promise<void>;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract updateChatCtx(chatCtx: ChatContext): Promise<void>;\n\n abstract updateTools(tools: ToolContext): Promise<void>;\n\n abstract updateOptions(options: { toolChoice?: ToolChoice | null }): void;\n\n abstract pushAudio(frame: AudioFrame): void;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract generateReply(instructions?: string): Promise<GenerationCreatedEvent>;\n\n /**\n * Commit the input audio buffer to the server\n */\n abstract commitAudio(): Promise<void>;\n\n /**\n * Clear the input audio buffer to the server\n */\n abstract clearAudio(): Promise<void>;\n\n /**\n * Cancel the current generation (do nothing if no generation is in progress)\n */\n abstract interrupt(): Promise<void>;\n\n /**\n * Truncate the message at the given audio end time\n */\n abstract truncate(options: {\n messageId: string;\n audioEndMs: number;\n modalities?: ('text' | 'audio')[];\n audioTranscript?: string;\n }): Promise<void>;\n\n async close(): Promise<void> {\n this._mainTask.cancel();\n }\n\n /**\n * Notifies the model that user activity has started\n */\n startUserActivity(): void {\n return;\n }\n\n private async _mainTaskImpl(signal: AbortSignal): Promise<void> {\n const reader = this.deferredInputStream.stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done || signal.aborted) {\n break;\n }\n this.pushAudio(value);\n }\n }\n\n setInputAudioStream(audioStream: ReadableStream<AudioFrame>): void {\n this.deferredInputStream.setSource(audioStream);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,oBAA6B;AAE7B,6BAAuC;AACvC,mBAAqB;AAsDd,MAAe,cAAc;AAAA,EAC1B;AAAA,EAER,YAAY,cAAoC;AAC9C,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAKA,IAAI,WAAmB;AACrB,WAAO;AAAA,EACT;AAKF;AAEO,MAAe,wBAAwB,2BAAa;AAAA,EAC/C;AAAA,EACF,sBAAsB,IAAI,8CAAmC;AAAA,EAC7D;AAAA,EAER,YAAY,eAA8B;AACxC,UAAM;AACN,SAAK,iBAAiB;AACtB,SAAK,YAAY,kBAAK,KAAK,CAAC,eAAe,KAAK,cAAc,WAAW,MAAM,CAAC;AAAA,EAClF;AAAA,EAEA,IAAI,gBAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAiDA,MAAM,QAAuB;AAC3B,SAAK,UAAU,OAAO;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA0B;AACxB;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,QAAoC;AAC9D,UAAM,SAAS,KAAK,oBAAoB,OAAO,UAAU;AACzD,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,QAAQ,OAAO,SAAS;AAC1B;AAAA,MACF;AACA,WAAK,UAAU,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,oBAAoB,aAA+C;AACjE,SAAK,oBAAoB,UAAU,WAAW;AAAA,EAChD;AACF;","names":[]}
|
package/dist/llm/realtime.d.cts
CHANGED
|
@@ -54,6 +54,7 @@ export declare abstract class RealtimeModel {
|
|
|
54
54
|
get capabilities(): RealtimeCapabilities;
|
|
55
55
|
/** The model name/identifier used by this realtime model */
|
|
56
56
|
abstract get model(): string;
|
|
57
|
+
get provider(): string;
|
|
57
58
|
abstract session(): RealtimeSession;
|
|
58
59
|
abstract close(): Promise<void>;
|
|
59
60
|
}
|
package/dist/llm/realtime.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ export declare abstract class RealtimeModel {
|
|
|
54
54
|
get capabilities(): RealtimeCapabilities;
|
|
55
55
|
/** The model name/identifier used by this realtime model */
|
|
56
56
|
abstract get model(): string;
|
|
57
|
+
get provider(): string;
|
|
57
58
|
abstract session(): RealtimeSession;
|
|
58
59
|
abstract close(): Promise<void>;
|
|
59
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/llm/realtime.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/llm/realtime.ts"],"names":[],"mappings":"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"}
|
package/dist/llm/realtime.js
CHANGED
package/dist/llm/realtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/realtime.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { EventEmitter } from 'events';\nimport type { ReadableStream } from 'node:stream/web';\nimport { DeferredReadableStream } from '../stream/deferred_stream.js';\nimport { Task } from '../utils.js';\nimport type { TimedString } from '../voice/io.js';\nimport type { ChatContext, FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport type InputSpeechStartedEvent = object;\n\nexport interface InputSpeechStoppedEvent {\n userTranscriptionEnabled: boolean;\n}\n\nexport interface MessageGeneration {\n messageId: string;\n /**\n * Text stream that may contain plain strings or TimedString objects with timestamps.\n */\n textStream: ReadableStream<string | TimedString>;\n audioStream: ReadableStream<AudioFrame>;\n modalities?: Promise<('text' | 'audio')[]>;\n}\n\nexport interface GenerationCreatedEvent {\n messageStream: ReadableStream<MessageGeneration>;\n functionStream: ReadableStream<FunctionCall>;\n userInitiated: boolean;\n /** Response ID for correlating metrics with spans */\n responseId?: string;\n}\n\nexport interface RealtimeModelError {\n type: 'realtime_model_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport interface RealtimeCapabilities {\n messageTruncation: boolean;\n turnDetection: boolean;\n userTranscription: boolean;\n autoToolReplyGeneration: boolean;\n audioOutput: boolean;\n manualFunctionCalls: boolean;\n}\n\nexport interface InputTranscriptionCompleted {\n itemId: string;\n transcript: string;\n isFinal: boolean;\n}\n\nexport interface RealtimeSessionReconnectedEvent {}\n\nexport abstract class RealtimeModel {\n private _capabilities: RealtimeCapabilities;\n\n constructor(capabilities: RealtimeCapabilities) {\n this._capabilities = capabilities;\n }\n\n get capabilities() {\n return this._capabilities;\n }\n\n /** The model name/identifier used by this realtime model */\n abstract get model(): string;\n\n abstract session(): RealtimeSession;\n\n abstract close(): Promise<void>;\n}\n\nexport abstract class RealtimeSession extends EventEmitter {\n protected _realtimeModel: RealtimeModel;\n private deferredInputStream = new DeferredReadableStream<AudioFrame>();\n private _mainTask: Task<void>;\n\n constructor(realtimeModel: RealtimeModel) {\n super();\n this._realtimeModel = realtimeModel;\n this._mainTask = Task.from((controller) => this._mainTaskImpl(controller.signal));\n }\n\n get realtimeModel() {\n return this._realtimeModel;\n }\n\n abstract get chatCtx(): ChatContext;\n\n abstract get tools(): ToolContext;\n\n abstract updateInstructions(instructions: string): Promise<void>;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract updateChatCtx(chatCtx: ChatContext): Promise<void>;\n\n abstract updateTools(tools: ToolContext): Promise<void>;\n\n abstract updateOptions(options: { toolChoice?: ToolChoice | null }): void;\n\n abstract pushAudio(frame: AudioFrame): void;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract generateReply(instructions?: string): Promise<GenerationCreatedEvent>;\n\n /**\n * Commit the input audio buffer to the server\n */\n abstract commitAudio(): Promise<void>;\n\n /**\n * Clear the input audio buffer to the server\n */\n abstract clearAudio(): Promise<void>;\n\n /**\n * Cancel the current generation (do nothing if no generation is in progress)\n */\n abstract interrupt(): Promise<void>;\n\n /**\n * Truncate the message at the given audio end time\n */\n abstract truncate(options: {\n messageId: string;\n audioEndMs: number;\n modalities?: ('text' | 'audio')[];\n audioTranscript?: string;\n }): Promise<void>;\n\n async close(): Promise<void> {\n this._mainTask.cancel();\n }\n\n /**\n * Notifies the model that user activity has started\n */\n startUserActivity(): void {\n return;\n }\n\n private async _mainTaskImpl(signal: AbortSignal): Promise<void> {\n const reader = this.deferredInputStream.stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done || signal.aborted) {\n break;\n }\n this.pushAudio(value);\n }\n }\n\n setInputAudioStream(audioStream: ReadableStream<AudioFrame>): void {\n this.deferredInputStream.setSource(audioStream);\n }\n}\n"],"mappings":"AAIA,SAAS,oBAAoB;AAE7B,SAAS,8BAA8B;AACvC,SAAS,YAAY;AAsDd,MAAe,cAAc;AAAA,EAC1B;AAAA,EAER,YAAY,cAAoC;AAC9C,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK;AAAA,EACd;
|
|
1
|
+
{"version":3,"sources":["../../src/llm/realtime.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { EventEmitter } from 'events';\nimport type { ReadableStream } from 'node:stream/web';\nimport { DeferredReadableStream } from '../stream/deferred_stream.js';\nimport { Task } from '../utils.js';\nimport type { TimedString } from '../voice/io.js';\nimport type { ChatContext, FunctionCall } from './chat_context.js';\nimport type { ToolChoice, ToolContext } from './tool_context.js';\n\nexport type InputSpeechStartedEvent = object;\n\nexport interface InputSpeechStoppedEvent {\n userTranscriptionEnabled: boolean;\n}\n\nexport interface MessageGeneration {\n messageId: string;\n /**\n * Text stream that may contain plain strings or TimedString objects with timestamps.\n */\n textStream: ReadableStream<string | TimedString>;\n audioStream: ReadableStream<AudioFrame>;\n modalities?: Promise<('text' | 'audio')[]>;\n}\n\nexport interface GenerationCreatedEvent {\n messageStream: ReadableStream<MessageGeneration>;\n functionStream: ReadableStream<FunctionCall>;\n userInitiated: boolean;\n /** Response ID for correlating metrics with spans */\n responseId?: string;\n}\n\nexport interface RealtimeModelError {\n type: 'realtime_model_error';\n timestamp: number;\n label: string;\n error: Error;\n recoverable: boolean;\n}\n\nexport interface RealtimeCapabilities {\n messageTruncation: boolean;\n turnDetection: boolean;\n userTranscription: boolean;\n autoToolReplyGeneration: boolean;\n audioOutput: boolean;\n manualFunctionCalls: boolean;\n}\n\nexport interface InputTranscriptionCompleted {\n itemId: string;\n transcript: string;\n isFinal: boolean;\n}\n\nexport interface RealtimeSessionReconnectedEvent {}\n\nexport abstract class RealtimeModel {\n private _capabilities: RealtimeCapabilities;\n\n constructor(capabilities: RealtimeCapabilities) {\n this._capabilities = capabilities;\n }\n\n get capabilities() {\n return this._capabilities;\n }\n\n /** The model name/identifier used by this realtime model */\n abstract get model(): string;\n\n get provider(): string {\n return 'unknown';\n }\n\n abstract session(): RealtimeSession;\n\n abstract close(): Promise<void>;\n}\n\nexport abstract class RealtimeSession extends EventEmitter {\n protected _realtimeModel: RealtimeModel;\n private deferredInputStream = new DeferredReadableStream<AudioFrame>();\n private _mainTask: Task<void>;\n\n constructor(realtimeModel: RealtimeModel) {\n super();\n this._realtimeModel = realtimeModel;\n this._mainTask = Task.from((controller) => this._mainTaskImpl(controller.signal));\n }\n\n get realtimeModel() {\n return this._realtimeModel;\n }\n\n abstract get chatCtx(): ChatContext;\n\n abstract get tools(): ToolContext;\n\n abstract updateInstructions(instructions: string): Promise<void>;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract updateChatCtx(chatCtx: ChatContext): Promise<void>;\n\n abstract updateTools(tools: ToolContext): Promise<void>;\n\n abstract updateOptions(options: { toolChoice?: ToolChoice | null }): void;\n\n abstract pushAudio(frame: AudioFrame): void;\n\n /**\n * @throws RealtimeError on Timeout\n */\n abstract generateReply(instructions?: string): Promise<GenerationCreatedEvent>;\n\n /**\n * Commit the input audio buffer to the server\n */\n abstract commitAudio(): Promise<void>;\n\n /**\n * Clear the input audio buffer to the server\n */\n abstract clearAudio(): Promise<void>;\n\n /**\n * Cancel the current generation (do nothing if no generation is in progress)\n */\n abstract interrupt(): Promise<void>;\n\n /**\n * Truncate the message at the given audio end time\n */\n abstract truncate(options: {\n messageId: string;\n audioEndMs: number;\n modalities?: ('text' | 'audio')[];\n audioTranscript?: string;\n }): Promise<void>;\n\n async close(): Promise<void> {\n this._mainTask.cancel();\n }\n\n /**\n * Notifies the model that user activity has started\n */\n startUserActivity(): void {\n return;\n }\n\n private async _mainTaskImpl(signal: AbortSignal): Promise<void> {\n const reader = this.deferredInputStream.stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done || signal.aborted) {\n break;\n }\n this.pushAudio(value);\n }\n }\n\n setInputAudioStream(audioStream: ReadableStream<AudioFrame>): void {\n this.deferredInputStream.setSource(audioStream);\n }\n}\n"],"mappings":"AAIA,SAAS,oBAAoB;AAE7B,SAAS,8BAA8B;AACvC,SAAS,YAAY;AAsDd,MAAe,cAAc;AAAA,EAC1B;AAAA,EAER,YAAY,cAAoC;AAC9C,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAKA,IAAI,WAAmB;AACrB,WAAO;AAAA,EACT;AAKF;AAEO,MAAe,wBAAwB,aAAa;AAAA,EAC/C;AAAA,EACF,sBAAsB,IAAI,uBAAmC;AAAA,EAC7D;AAAA,EAER,YAAY,eAA8B;AACxC,UAAM;AACN,SAAK,iBAAiB;AACtB,SAAK,YAAY,KAAK,KAAK,CAAC,eAAe,KAAK,cAAc,WAAW,MAAM,CAAC;AAAA,EAClF;AAAA,EAEA,IAAI,gBAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAiDA,MAAM,QAAuB;AAC3B,SAAK,UAAU,OAAO;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA0B;AACxB;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,QAAoC;AAC9D,UAAM,SAAS,KAAK,oBAAoB,OAAO,UAAU;AACzD,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,QAAQ,OAAO,SAAS;AAC1B;AAAA,MACF;AACA,WAAK,UAAU,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,oBAAoB,aAA+C;AACjE,SAAK,oBAAoB,UAAU,WAAW;AAAA,EAChD;AACF;","names":[]}
|
|
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var tool_context_exports = {};
|
|
20
20
|
__export(tool_context_exports, {
|
|
21
21
|
ToolError: () => ToolError,
|
|
22
|
+
ToolFlag: () => ToolFlag,
|
|
22
23
|
handoff: () => handoff,
|
|
23
24
|
isAgentHandoff: () => isAgentHandoff,
|
|
24
25
|
isFunctionTool: () => isFunctionTool,
|
|
@@ -45,6 +46,10 @@ class ToolError extends Error {
|
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
const ToolFlag = {
|
|
50
|
+
NONE: 0,
|
|
51
|
+
IGNORE_ON_ENTER: 1 << 0
|
|
52
|
+
};
|
|
48
53
|
function handoff(options) {
|
|
49
54
|
return {
|
|
50
55
|
agent: options.agent,
|
|
@@ -102,6 +107,7 @@ function tool(tool2) {
|
|
|
102
107
|
description: tool2.description,
|
|
103
108
|
parameters,
|
|
104
109
|
execute: tool2.execute,
|
|
110
|
+
flags: tool2.flags ?? ToolFlag.NONE,
|
|
105
111
|
[TOOL_SYMBOL]: true,
|
|
106
112
|
[FUNCTION_TOOL_SYMBOL]: true
|
|
107
113
|
};
|
|
@@ -139,6 +145,7 @@ function isAgentHandoff(handoff2) {
|
|
|
139
145
|
// Annotate the CommonJS export names for ESM import in node:
|
|
140
146
|
0 && (module.exports = {
|
|
141
147
|
ToolError,
|
|
148
|
+
ToolFlag,
|
|
142
149
|
handoff,
|
|
143
150
|
isAgentHandoff,
|
|
144
151
|
isFunctionTool,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/tool_context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JSONSchema7 } from 'json-schema';\nimport { z } from 'zod';\nimport type { Agent } from '../voice/agent.js';\nimport type { RunContext, UnknownUserData } from '../voice/run_context.js';\nimport { isZodObjectSchema, isZodSchema } from './zod-utils.js';\n\n// heavily inspired by Vercel AI's `tool()`:\n// https://github.com/vercel/ai/blob/3b0983b/packages/ai/core/tool/tool.ts\n\nconst TOOL_SYMBOL = Symbol('tool');\nconst FUNCTION_TOOL_SYMBOL = Symbol('function_tool');\nconst PROVIDER_DEFINED_TOOL_SYMBOL = Symbol('provider_defined_tool');\nconst TOOL_ERROR_SYMBOL = Symbol('tool_error');\nconst HANDOFF_SYMBOL = Symbol('handoff');\n\nexport type JSONValue = null | string | number | boolean | JSONObject | JSONArray;\n\nexport type JSONArray = JSONValue[];\n\nexport type JSONObject = {\n [key: string]: JSONValue;\n};\n\n// Supports both Zod v3 and v4 schemas, as well as raw JSON schema\n// Adapted from Vercel AI SDK's FlexibleSchema approach\n// Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L67-L70\n//\n// Vercel uses StandardSchemaV1 from @standard-schema/spec package.\n// We use a simpler approach by directly checking for schema properties:\n// - Zod v3: Has `_output` property\n// - Zod v4: Implements Standard Schema spec with `~standard` property\n// - JSON Schema: Plain object fallback\nexport type ToolInputSchema<T = JSONObject> =\n | {\n // Zod v3 schema - has _output property for type inference\n _output: T;\n }\n | {\n // Zod v4 schema (Standard Schema) - has ~standard property\n '~standard': {\n types?: { output: T };\n };\n }\n | JSONSchema7;\n\n/**\n * Infer the output type from a ToolInputSchema.\n * Adapted from Vercel AI SDK's InferSchema type.\n * Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L72-L79\n */\nexport type InferToolInput<T> = T extends { _output: infer O }\n ? O\n : T extends { '~standard': { types?: { output: infer O } } }\n ? O\n : any; // eslint-disable-line @typescript-eslint/no-explicit-any -- Fallback type for JSON Schema objects without type inference\n\nexport type ToolType = 'function' | 'provider-defined';\n\nexport type ToolChoice =\n | 'auto'\n | 'none'\n | 'required'\n | {\n type: 'function';\n function: {\n name: string;\n };\n };\n\nexport class ToolError extends Error {\n constructor(message: string) {\n super(message);\n\n Object.defineProperty(this, TOOL_ERROR_SYMBOL, {\n value: true,\n });\n }\n}\n\nexport interface AgentHandoff {\n /**\n * The agent to handoff to.\n */\n agent: Agent;\n\n /**\n * The return value of the tool.\n */\n returns?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n [HANDOFF_SYMBOL]: true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function handoff(options: { agent: Agent; returns?: any }): AgentHandoff {\n return {\n agent: options.agent,\n returns: options.returns,\n [HANDOFF_SYMBOL]: true,\n };\n}\n\nexport interface ToolOptions<UserData = UnknownUserData> {\n /**\n * RunContext for the current agent session.\n */\n ctx: RunContext<UserData>;\n\n /**\n * The ID of the tool call.\n */\n toolCallId: string;\n\n /**\n * An optional abort signal that indicates that the overall operation should be aborted.\n */\n abortSignal?: AbortSignal;\n}\n\nexport type ToolExecuteFunction<\n Parameters extends JSONObject,\n UserData = UnknownUserData,\n Result = unknown,\n> = (args: Parameters, opts: ToolOptions<UserData>) => Promise<Result>;\n\nexport interface Tool {\n /**\n * The type of the tool.\n * @internal Either user-defined core tool or provider-defined tool.\n */\n type: ToolType;\n\n [TOOL_SYMBOL]: true;\n}\n\n// TODO(AJS-112): support provider-defined tools\nexport interface ProviderDefinedTool extends Tool {\n type: 'provider-defined';\n\n /**\n * The ID of the tool.\n */\n id: string;\n\n /**\n * The configuration of the tool.\n */\n config: Record<string, unknown>;\n\n [PROVIDER_DEFINED_TOOL_SYMBOL]: true;\n}\n\nexport interface FunctionTool<\n Parameters extends JSONObject,\n UserData = UnknownUserData,\n Result = unknown,\n> extends Tool {\n type: 'function';\n\n /**\n * The description of the tool. Will be used by the language model to decide whether to use the tool.\n */\n description: string;\n\n /**\n * The schema of the input that the tool expects. The language model will use this to generate the input.\n * It is also used to validate the output of the language model.\n * Use descriptions to make the input understandable for the language model.\n */\n parameters: ToolInputSchema<Parameters>;\n\n /**\n * An async function that is called with the arguments from the tool call and produces a result.\n * It also carries context about current session, user-defined data, and the tool call id, etc.\n */\n execute: ToolExecuteFunction<Parameters, UserData, Result>;\n\n [FUNCTION_TOOL_SYMBOL]: true;\n}\n\n// TODO(AJS-112): support provider-defined tools in the future)\nexport type ToolContext<UserData = UnknownUserData> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic tool registry needs to accept any parameter/result types\n [name: string]: FunctionTool<any, UserData, any>;\n};\n\nexport function isSameToolContext(ctx1: ToolContext, ctx2: ToolContext): boolean {\n const toolNames = new Set(Object.keys(ctx1));\n const toolNames2 = new Set(Object.keys(ctx2));\n\n if (toolNames.size !== toolNames2.size) {\n return false;\n }\n\n for (const name of toolNames) {\n if (!toolNames2.has(name)) {\n return false;\n }\n\n const tool1 = ctx1[name];\n const tool2 = ctx2[name];\n\n if (!tool1 || !tool2) {\n return false;\n }\n\n if (tool1.description !== tool2.description) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function isSameToolChoice(choice1: ToolChoice | null, choice2: ToolChoice | null): boolean {\n if (choice1 === choice2) {\n return true;\n }\n if (choice1 === null || choice2 === null) {\n return false;\n }\n if (typeof choice1 === 'string' && typeof choice2 === 'string') {\n return choice1 === choice2;\n }\n if (typeof choice1 === 'object' && typeof choice2 === 'object') {\n return choice1.type === choice2.type && choice1.function.name === choice2.function.name;\n }\n return false;\n}\n\n/**\n * Create a function tool with inferred parameters from the schema.\n */\nexport function tool<\n Schema extends ToolInputSchema<any>, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type\n UserData = UnknownUserData,\n Result = unknown,\n>({\n description,\n parameters,\n execute,\n}: {\n description: string;\n parameters: Schema;\n execute: ToolExecuteFunction<InferToolInput<Schema>, UserData, Result>;\n}): FunctionTool<InferToolInput<Schema>, UserData, Result>;\n\n/**\n * Create a function tool without parameters.\n */\nexport function tool<UserData = UnknownUserData, Result = unknown>({\n description,\n execute,\n}: {\n description: string;\n parameters?: never;\n execute: ToolExecuteFunction<Record<string, never>, UserData, Result>;\n}): FunctionTool<Record<string, never>, UserData, Result>;\n\n/**\n * Create a provider-defined tool.\n *\n * @param id - The ID of the tool.\n * @param config - The configuration of the tool.\n */\nexport function tool({\n id,\n config,\n}: {\n id: string;\n config: Record<string, unknown>;\n}): ProviderDefinedTool;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function tool(tool: any): any {\n if (tool.execute !== undefined) {\n // Default parameters to z.object({}) if not provided\n const parameters = tool.parameters ?? z.object({});\n\n // if parameters is a Zod schema, ensure it's an object schema\n if (isZodSchema(parameters) && !isZodObjectSchema(parameters)) {\n throw new Error('Tool parameters must be a Zod object schema (z.object(...))');\n }\n\n // Ensure parameters is either a Zod schema or a plain object (JSON schema)\n if (!isZodSchema(parameters) && !(typeof parameters === 'object')) {\n throw new Error('Tool parameters must be a Zod object schema or a raw JSON schema');\n }\n\n return {\n type: 'function',\n description: tool.description,\n parameters,\n execute: tool.execute,\n [TOOL_SYMBOL]: true,\n [FUNCTION_TOOL_SYMBOL]: true,\n };\n }\n\n if (tool.config !== undefined && tool.id !== undefined) {\n return {\n type: 'provider-defined',\n id: tool.id,\n config: tool.config,\n [TOOL_SYMBOL]: true,\n [PROVIDER_DEFINED_TOOL_SYMBOL]: true,\n };\n }\n\n throw new Error('Invalid tool');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isTool(tool: any): tool is Tool {\n return tool && tool[TOOL_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isFunctionTool(tool: any): tool is FunctionTool<any, any, any> {\n const isTool = tool && tool[TOOL_SYMBOL] === true;\n const isFunctionTool = tool[FUNCTION_TOOL_SYMBOL] === true;\n return isTool && isFunctionTool;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isProviderDefinedTool(tool: any): tool is ProviderDefinedTool {\n const isTool = tool && tool[TOOL_SYMBOL] === true;\n const isProviderDefinedTool = tool[PROVIDER_DEFINED_TOOL_SYMBOL] === true;\n return isTool && isProviderDefinedTool;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolError(error: any): error is ToolError {\n return error && error[TOOL_ERROR_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAgentHandoff(handoff: any): handoff is AgentHandoff {\n return handoff && handoff[HANDOFF_SYMBOL] === true;\n}\n"],"mappings":"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","names":["tool","isTool","isFunctionTool","isProviderDefinedTool","handoff"]}
|
|
1
|
+
{"version":3,"sources":["../../src/llm/tool_context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JSONSchema7 } from 'json-schema';\nimport { z } from 'zod';\nimport type { Agent } from '../voice/agent.js';\nimport type { RunContext, UnknownUserData } from '../voice/run_context.js';\nimport { isZodObjectSchema, isZodSchema } from './zod-utils.js';\n\n// heavily inspired by Vercel AI's `tool()`:\n// https://github.com/vercel/ai/blob/3b0983b/packages/ai/core/tool/tool.ts\n\nconst TOOL_SYMBOL = Symbol('tool');\nconst FUNCTION_TOOL_SYMBOL = Symbol('function_tool');\nconst PROVIDER_DEFINED_TOOL_SYMBOL = Symbol('provider_defined_tool');\nconst TOOL_ERROR_SYMBOL = Symbol('tool_error');\nconst HANDOFF_SYMBOL = Symbol('handoff');\n\nexport type JSONValue = null | string | number | boolean | JSONObject | JSONArray;\n\nexport type JSONArray = JSONValue[];\n\nexport type JSONObject = {\n [key: string]: JSONValue;\n};\n\n// Supports both Zod v3 and v4 schemas, as well as raw JSON schema\n// Adapted from Vercel AI SDK's FlexibleSchema approach\n// Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L67-L70\n//\n// Vercel uses StandardSchemaV1 from @standard-schema/spec package.\n// We use a simpler approach by directly checking for schema properties:\n// - Zod v3: Has `_output` property\n// - Zod v4: Implements Standard Schema spec with `~standard` property\n// - JSON Schema: Plain object fallback\nexport type ToolInputSchema<T = JSONObject> =\n | {\n // Zod v3 schema - has _output property for type inference\n _output: T;\n }\n | {\n // Zod v4 schema (Standard Schema) - has ~standard property\n '~standard': {\n types?: { output: T };\n };\n }\n | JSONSchema7;\n\n/**\n * Infer the output type from a ToolInputSchema.\n * Adapted from Vercel AI SDK's InferSchema type.\n * Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L72-L79\n */\nexport type InferToolInput<T> = T extends { _output: infer O }\n ? O\n : T extends { '~standard': { types?: { output: infer O } } }\n ? O\n : any; // eslint-disable-line @typescript-eslint/no-explicit-any -- Fallback type for JSON Schema objects without type inference\n\nexport type ToolType = 'function' | 'provider-defined';\n\nexport type ToolChoice =\n | 'auto'\n | 'none'\n | 'required'\n | {\n type: 'function';\n function: {\n name: string;\n };\n };\n\nexport class ToolError extends Error {\n constructor(message: string) {\n super(message);\n\n Object.defineProperty(this, TOOL_ERROR_SYMBOL, {\n value: true,\n });\n }\n}\n\nexport const ToolFlag = {\n NONE: 0,\n IGNORE_ON_ENTER: 1 << 0,\n} as const;\n\nexport type ToolFlag = (typeof ToolFlag)[keyof typeof ToolFlag];\n\nexport interface AgentHandoff {\n /**\n * The agent to handoff to.\n */\n agent: Agent;\n\n /**\n * The return value of the tool.\n */\n returns?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n [HANDOFF_SYMBOL]: true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function handoff(options: { agent: Agent; returns?: any }): AgentHandoff {\n return {\n agent: options.agent,\n returns: options.returns,\n [HANDOFF_SYMBOL]: true,\n };\n}\n\nexport interface ToolOptions<UserData = UnknownUserData> {\n /**\n * RunContext for the current agent session.\n */\n ctx: RunContext<UserData>;\n\n /**\n * The ID of the tool call.\n */\n toolCallId: string;\n\n /**\n * An optional abort signal that indicates that the overall operation should be aborted.\n */\n abortSignal?: AbortSignal;\n}\n\nexport type ToolExecuteFunction<\n Parameters extends JSONObject,\n UserData = UnknownUserData,\n Result = unknown,\n> = (args: Parameters, opts: ToolOptions<UserData>) => Promise<Result>;\n\nexport interface Tool {\n /**\n * The type of the tool.\n * @internal Either user-defined core tool or provider-defined tool.\n */\n type: ToolType;\n\n [TOOL_SYMBOL]: true;\n}\n\n// TODO(AJS-112): support provider-defined tools\nexport interface ProviderDefinedTool extends Tool {\n type: 'provider-defined';\n\n /**\n * The ID of the tool.\n */\n id: string;\n\n /**\n * The configuration of the tool.\n */\n config: Record<string, unknown>;\n\n [PROVIDER_DEFINED_TOOL_SYMBOL]: true;\n}\n\nexport interface FunctionTool<\n Parameters extends JSONObject,\n UserData = UnknownUserData,\n Result = unknown,\n> extends Tool {\n type: 'function';\n\n /**\n * The description of the tool. Will be used by the language model to decide whether to use the tool.\n */\n description: string;\n\n /**\n * The schema of the input that the tool expects. The language model will use this to generate the input.\n * It is also used to validate the output of the language model.\n * Use descriptions to make the input understandable for the language model.\n */\n parameters: ToolInputSchema<Parameters>;\n\n /**\n * An async function that is called with the arguments from the tool call and produces a result.\n * It also carries context about current session, user-defined data, and the tool call id, etc.\n */\n execute: ToolExecuteFunction<Parameters, UserData, Result>;\n\n flags: number;\n\n [FUNCTION_TOOL_SYMBOL]: true;\n}\n\n// TODO(AJS-112): support provider-defined tools in the future)\nexport type ToolContext<UserData = UnknownUserData> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic tool registry needs to accept any parameter/result types\n [name: string]: FunctionTool<any, UserData, any>;\n};\n\nexport function isSameToolContext(ctx1: ToolContext, ctx2: ToolContext): boolean {\n const toolNames = new Set(Object.keys(ctx1));\n const toolNames2 = new Set(Object.keys(ctx2));\n\n if (toolNames.size !== toolNames2.size) {\n return false;\n }\n\n for (const name of toolNames) {\n if (!toolNames2.has(name)) {\n return false;\n }\n\n const tool1 = ctx1[name];\n const tool2 = ctx2[name];\n\n if (!tool1 || !tool2) {\n return false;\n }\n\n if (tool1.description !== tool2.description) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function isSameToolChoice(choice1: ToolChoice | null, choice2: ToolChoice | null): boolean {\n if (choice1 === choice2) {\n return true;\n }\n if (choice1 === null || choice2 === null) {\n return false;\n }\n if (typeof choice1 === 'string' && typeof choice2 === 'string') {\n return choice1 === choice2;\n }\n if (typeof choice1 === 'object' && typeof choice2 === 'object') {\n return choice1.type === choice2.type && choice1.function.name === choice2.function.name;\n }\n return false;\n}\n\n/**\n * Create a function tool with inferred parameters from the schema.\n */\nexport function tool<\n Schema extends ToolInputSchema<any>, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type\n UserData = UnknownUserData,\n Result = unknown,\n>({\n description,\n parameters,\n execute,\n flags,\n}: {\n description: string;\n parameters: Schema;\n execute: ToolExecuteFunction<InferToolInput<Schema>, UserData, Result>;\n flags?: number;\n}): FunctionTool<InferToolInput<Schema>, UserData, Result>;\n\n/**\n * Create a function tool without parameters.\n */\nexport function tool<UserData = UnknownUserData, Result = unknown>({\n description,\n execute,\n flags,\n}: {\n description: string;\n parameters?: never;\n execute: ToolExecuteFunction<Record<string, never>, UserData, Result>;\n flags?: number;\n}): FunctionTool<Record<string, never>, UserData, Result>;\n\n/**\n * Create a provider-defined tool.\n *\n * @param id - The ID of the tool.\n * @param config - The configuration of the tool.\n */\nexport function tool({\n id,\n config,\n}: {\n id: string;\n config: Record<string, unknown>;\n}): ProviderDefinedTool;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function tool(tool: any): any {\n if (tool.execute !== undefined) {\n // Default parameters to z.object({}) if not provided\n const parameters = tool.parameters ?? z.object({});\n\n // if parameters is a Zod schema, ensure it's an object schema\n if (isZodSchema(parameters) && !isZodObjectSchema(parameters)) {\n throw new Error('Tool parameters must be a Zod object schema (z.object(...))');\n }\n\n // Ensure parameters is either a Zod schema or a plain object (JSON schema)\n if (!isZodSchema(parameters) && !(typeof parameters === 'object')) {\n throw new Error('Tool parameters must be a Zod object schema or a raw JSON schema');\n }\n\n return {\n type: 'function',\n description: tool.description,\n parameters,\n execute: tool.execute,\n flags: tool.flags ?? ToolFlag.NONE,\n [TOOL_SYMBOL]: true,\n [FUNCTION_TOOL_SYMBOL]: true,\n };\n }\n\n if (tool.config !== undefined && tool.id !== undefined) {\n return {\n type: 'provider-defined',\n id: tool.id,\n config: tool.config,\n [TOOL_SYMBOL]: true,\n [PROVIDER_DEFINED_TOOL_SYMBOL]: true,\n };\n }\n\n throw new Error('Invalid tool');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isTool(tool: any): tool is Tool {\n return tool && tool[TOOL_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isFunctionTool(tool: any): tool is FunctionTool<any, any, any> {\n const isTool = tool && tool[TOOL_SYMBOL] === true;\n const isFunctionTool = tool[FUNCTION_TOOL_SYMBOL] === true;\n return isTool && isFunctionTool;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isProviderDefinedTool(tool: any): tool is ProviderDefinedTool {\n const isTool = tool && tool[TOOL_SYMBOL] === true;\n const isProviderDefinedTool = tool[PROVIDER_DEFINED_TOOL_SYMBOL] === true;\n return isTool && isProviderDefinedTool;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolError(error: any): error is ToolError {\n return error && error[TOOL_ERROR_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAgentHandoff(handoff: any): handoff is AgentHandoff {\n return handoff && handoff[HANDOFF_SYMBOL] === true;\n}\n"],"mappings":"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","names":["tool","isTool","isFunctionTool","isProviderDefinedTool","handoff"]}
|
|
@@ -43,6 +43,11 @@ export type ToolChoice = 'auto' | 'none' | 'required' | {
|
|
|
43
43
|
export declare class ToolError extends Error {
|
|
44
44
|
constructor(message: string);
|
|
45
45
|
}
|
|
46
|
+
export declare const ToolFlag: {
|
|
47
|
+
readonly NONE: 0;
|
|
48
|
+
readonly IGNORE_ON_ENTER: number;
|
|
49
|
+
};
|
|
50
|
+
export type ToolFlag = (typeof ToolFlag)[keyof typeof ToolFlag];
|
|
46
51
|
export interface AgentHandoff {
|
|
47
52
|
/**
|
|
48
53
|
* The agent to handoff to.
|
|
@@ -110,6 +115,7 @@ export interface FunctionTool<Parameters extends JSONObject, UserData = UnknownU
|
|
|
110
115
|
* It also carries context about current session, user-defined data, and the tool call id, etc.
|
|
111
116
|
*/
|
|
112
117
|
execute: ToolExecuteFunction<Parameters, UserData, Result>;
|
|
118
|
+
flags: number;
|
|
113
119
|
[FUNCTION_TOOL_SYMBOL]: true;
|
|
114
120
|
}
|
|
115
121
|
export type ToolContext<UserData = UnknownUserData> = {
|
|
@@ -121,18 +127,20 @@ export declare function isSameToolChoice(choice1: ToolChoice | null, choice2: To
|
|
|
121
127
|
* Create a function tool with inferred parameters from the schema.
|
|
122
128
|
*/
|
|
123
129
|
export declare function tool<Schema extends ToolInputSchema<any>, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type
|
|
124
|
-
UserData = UnknownUserData, Result = unknown>({ description, parameters, execute, }: {
|
|
130
|
+
UserData = UnknownUserData, Result = unknown>({ description, parameters, execute, flags, }: {
|
|
125
131
|
description: string;
|
|
126
132
|
parameters: Schema;
|
|
127
133
|
execute: ToolExecuteFunction<InferToolInput<Schema>, UserData, Result>;
|
|
134
|
+
flags?: number;
|
|
128
135
|
}): FunctionTool<InferToolInput<Schema>, UserData, Result>;
|
|
129
136
|
/**
|
|
130
137
|
* Create a function tool without parameters.
|
|
131
138
|
*/
|
|
132
|
-
export declare function tool<UserData = UnknownUserData, Result = unknown>({ description, execute, }: {
|
|
139
|
+
export declare function tool<UserData = UnknownUserData, Result = unknown>({ description, execute, flags, }: {
|
|
133
140
|
description: string;
|
|
134
141
|
parameters?: never;
|
|
135
142
|
execute: ToolExecuteFunction<Record<string, never>, UserData, Result>;
|
|
143
|
+
flags?: number;
|
|
136
144
|
}): FunctionTool<Record<string, never>, UserData, Result>;
|
|
137
145
|
/**
|
|
138
146
|
* Create a provider-defined tool.
|
|
@@ -43,6 +43,11 @@ export type ToolChoice = 'auto' | 'none' | 'required' | {
|
|
|
43
43
|
export declare class ToolError extends Error {
|
|
44
44
|
constructor(message: string);
|
|
45
45
|
}
|
|
46
|
+
export declare const ToolFlag: {
|
|
47
|
+
readonly NONE: 0;
|
|
48
|
+
readonly IGNORE_ON_ENTER: number;
|
|
49
|
+
};
|
|
50
|
+
export type ToolFlag = (typeof ToolFlag)[keyof typeof ToolFlag];
|
|
46
51
|
export interface AgentHandoff {
|
|
47
52
|
/**
|
|
48
53
|
* The agent to handoff to.
|
|
@@ -110,6 +115,7 @@ export interface FunctionTool<Parameters extends JSONObject, UserData = UnknownU
|
|
|
110
115
|
* It also carries context about current session, user-defined data, and the tool call id, etc.
|
|
111
116
|
*/
|
|
112
117
|
execute: ToolExecuteFunction<Parameters, UserData, Result>;
|
|
118
|
+
flags: number;
|
|
113
119
|
[FUNCTION_TOOL_SYMBOL]: true;
|
|
114
120
|
}
|
|
115
121
|
export type ToolContext<UserData = UnknownUserData> = {
|
|
@@ -121,18 +127,20 @@ export declare function isSameToolChoice(choice1: ToolChoice | null, choice2: To
|
|
|
121
127
|
* Create a function tool with inferred parameters from the schema.
|
|
122
128
|
*/
|
|
123
129
|
export declare function tool<Schema extends ToolInputSchema<any>, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type
|
|
124
|
-
UserData = UnknownUserData, Result = unknown>({ description, parameters, execute, }: {
|
|
130
|
+
UserData = UnknownUserData, Result = unknown>({ description, parameters, execute, flags, }: {
|
|
125
131
|
description: string;
|
|
126
132
|
parameters: Schema;
|
|
127
133
|
execute: ToolExecuteFunction<InferToolInput<Schema>, UserData, Result>;
|
|
134
|
+
flags?: number;
|
|
128
135
|
}): FunctionTool<InferToolInput<Schema>, UserData, Result>;
|
|
129
136
|
/**
|
|
130
137
|
* Create a function tool without parameters.
|
|
131
138
|
*/
|
|
132
|
-
export declare function tool<UserData = UnknownUserData, Result = unknown>({ description, execute, }: {
|
|
139
|
+
export declare function tool<UserData = UnknownUserData, Result = unknown>({ description, execute, flags, }: {
|
|
133
140
|
description: string;
|
|
134
141
|
parameters?: never;
|
|
135
142
|
execute: ToolExecuteFunction<Record<string, never>, UserData, Result>;
|
|
143
|
+
flags?: number;
|
|
136
144
|
}): FunctionTool<Record<string, never>, UserData, Result>;
|
|
137
145
|
/**
|
|
138
146
|
* Create a provider-defined tool.
|