@livekit/agents 0.7.8 → 1.0.0-next.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/_exceptions.cjs +109 -0
- package/dist/_exceptions.cjs.map +1 -0
- package/dist/_exceptions.d.cts +64 -0
- package/dist/_exceptions.d.ts +64 -0
- package/dist/_exceptions.d.ts.map +1 -0
- package/dist/_exceptions.js +80 -0
- package/dist/_exceptions.js.map +1 -0
- package/dist/audio.cjs +10 -3
- package/dist/audio.cjs.map +1 -1
- package/dist/audio.d.cts +2 -0
- package/dist/audio.d.ts +2 -0
- package/dist/audio.d.ts.map +1 -1
- package/dist/audio.js +8 -2
- package/dist/audio.js.map +1 -1
- package/dist/cli.cjs +25 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +25 -0
- package/dist/cli.js.map +1 -1
- package/dist/constants.cjs +6 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +2 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/http_server.cjs.map +1 -1
- package/dist/http_server.d.cts +1 -0
- package/dist/http_server.d.ts +1 -0
- package/dist/http_server.d.ts.map +1 -1
- package/dist/http_server.js.map +1 -1
- package/dist/index.cjs +27 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -11
- package/dist/index.js.map +1 -1
- package/dist/inference_runner.cjs +0 -1
- package/dist/inference_runner.cjs.map +1 -1
- package/dist/inference_runner.d.cts +2 -3
- package/dist/inference_runner.d.ts +2 -3
- package/dist/inference_runner.d.ts.map +1 -1
- package/dist/inference_runner.js +0 -1
- package/dist/inference_runner.js.map +1 -1
- package/dist/ipc/inference_proc_executor.cjs +2 -2
- package/dist/ipc/inference_proc_executor.cjs.map +1 -1
- package/dist/ipc/inference_proc_executor.js +2 -2
- package/dist/ipc/inference_proc_executor.js.map +1 -1
- package/dist/ipc/job_executor.cjs.map +1 -1
- package/dist/ipc/job_executor.js.map +1 -1
- package/dist/ipc/job_proc_executor.cjs +1 -0
- package/dist/ipc/job_proc_executor.cjs.map +1 -1
- package/dist/ipc/job_proc_executor.js +1 -0
- package/dist/ipc/job_proc_executor.js.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +1 -1
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/ipc/supervised_proc.d.cts +1 -1
- package/dist/ipc/supervised_proc.d.ts +1 -1
- package/dist/ipc/supervised_proc.d.ts.map +1 -1
- package/dist/job.cjs +14 -2
- package/dist/job.cjs.map +1 -1
- package/dist/job.d.cts +8 -0
- package/dist/job.d.ts +8 -0
- package/dist/job.d.ts.map +1 -1
- package/dist/job.js +12 -1
- package/dist/job.js.map +1 -1
- package/dist/llm/chat_context.cjs +332 -82
- package/dist/llm/chat_context.cjs.map +1 -1
- package/dist/llm/chat_context.d.cts +152 -48
- package/dist/llm/chat_context.d.ts +152 -48
- package/dist/llm/chat_context.d.ts.map +1 -1
- package/dist/llm/chat_context.js +327 -81
- package/dist/llm/chat_context.js.map +1 -1
- package/dist/llm/chat_context.test.cjs +380 -0
- package/dist/llm/chat_context.test.cjs.map +1 -0
- package/dist/llm/chat_context.test.js +385 -0
- package/dist/llm/chat_context.test.js.map +1 -0
- package/dist/llm/index.cjs +37 -8
- package/dist/llm/index.cjs.map +1 -1
- package/dist/llm/index.d.cts +7 -3
- package/dist/llm/index.d.ts +7 -3
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +39 -9
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/llm.cjs +98 -33
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.cts +50 -24
- package/dist/llm/llm.d.ts +50 -24
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js +99 -33
- package/dist/llm/llm.js.map +1 -1
- package/dist/llm/provider_format/google.cjs +128 -0
- package/dist/llm/provider_format/google.cjs.map +1 -0
- package/dist/llm/provider_format/google.d.cts +6 -0
- package/dist/llm/provider_format/google.d.ts +6 -0
- package/dist/llm/provider_format/google.d.ts.map +1 -0
- package/dist/llm/provider_format/google.js +104 -0
- package/dist/llm/provider_format/google.js.map +1 -0
- package/dist/llm/provider_format/google.test.cjs +676 -0
- package/dist/llm/provider_format/google.test.cjs.map +1 -0
- package/dist/llm/provider_format/google.test.js +675 -0
- package/dist/llm/provider_format/google.test.js.map +1 -0
- package/dist/llm/provider_format/index.cjs +40 -0
- package/dist/llm/provider_format/index.cjs.map +1 -0
- package/dist/llm/provider_format/index.d.cts +4 -0
- package/dist/llm/provider_format/index.d.ts +4 -0
- package/dist/llm/provider_format/index.d.ts.map +1 -0
- package/dist/llm/provider_format/index.js +16 -0
- package/dist/llm/provider_format/index.js.map +1 -0
- package/dist/llm/provider_format/openai.cjs +116 -0
- package/dist/llm/provider_format/openai.cjs.map +1 -0
- package/dist/llm/provider_format/openai.d.cts +3 -0
- package/dist/llm/provider_format/openai.d.ts +3 -0
- package/dist/llm/provider_format/openai.d.ts.map +1 -0
- package/dist/llm/provider_format/openai.js +92 -0
- package/dist/llm/provider_format/openai.js.map +1 -0
- package/dist/llm/provider_format/openai.test.cjs +490 -0
- package/dist/llm/provider_format/openai.test.cjs.map +1 -0
- package/dist/llm/provider_format/openai.test.js +489 -0
- package/dist/llm/provider_format/openai.test.js.map +1 -0
- package/dist/llm/provider_format/utils.cjs +146 -0
- package/dist/llm/provider_format/utils.cjs.map +1 -0
- package/dist/llm/provider_format/utils.d.cts +38 -0
- package/dist/llm/provider_format/utils.d.ts +38 -0
- package/dist/llm/provider_format/utils.d.ts.map +1 -0
- package/dist/llm/provider_format/utils.js +122 -0
- package/dist/llm/provider_format/utils.js.map +1 -0
- package/dist/llm/realtime.cjs +77 -0
- package/dist/llm/realtime.cjs.map +1 -0
- package/dist/llm/realtime.d.cts +98 -0
- package/dist/llm/realtime.d.ts +98 -0
- package/dist/llm/realtime.d.ts.map +1 -0
- package/dist/llm/realtime.js +52 -0
- package/dist/llm/realtime.js.map +1 -0
- package/dist/llm/remote_chat_context.cjs +112 -0
- package/dist/llm/remote_chat_context.cjs.map +1 -0
- package/dist/llm/remote_chat_context.d.cts +23 -0
- package/dist/llm/remote_chat_context.d.ts +23 -0
- package/dist/llm/remote_chat_context.d.ts.map +1 -0
- package/dist/llm/remote_chat_context.js +88 -0
- package/dist/llm/remote_chat_context.js.map +1 -0
- package/dist/llm/remote_chat_context.test.cjs +225 -0
- package/dist/llm/remote_chat_context.test.cjs.map +1 -0
- package/dist/llm/remote_chat_context.test.js +224 -0
- package/dist/llm/remote_chat_context.test.js.map +1 -0
- package/dist/llm/tool_context.cjs +111 -0
- package/dist/llm/tool_context.cjs.map +1 -0
- package/dist/llm/tool_context.d.cts +125 -0
- package/dist/llm/tool_context.d.ts +125 -0
- package/dist/llm/tool_context.d.ts.map +1 -0
- package/dist/llm/tool_context.js +80 -0
- package/dist/llm/tool_context.js.map +1 -0
- package/dist/llm/tool_context.test.cjs +162 -0
- package/dist/llm/tool_context.test.cjs.map +1 -0
- package/dist/llm/tool_context.test.js +161 -0
- package/dist/llm/tool_context.test.js.map +1 -0
- package/dist/llm/tool_context.type.test.cjs +92 -0
- package/dist/llm/tool_context.type.test.cjs.map +1 -0
- package/dist/llm/tool_context.type.test.js +91 -0
- package/dist/llm/tool_context.type.test.js.map +1 -0
- package/dist/llm/utils.cjs +260 -0
- package/dist/llm/utils.cjs.map +1 -0
- package/dist/llm/utils.d.cts +42 -0
- package/dist/llm/utils.d.ts +42 -0
- package/dist/llm/utils.d.ts.map +1 -0
- package/dist/llm/utils.js +223 -0
- package/dist/llm/utils.js.map +1 -0
- package/dist/llm/utils.test.cjs +513 -0
- package/dist/llm/utils.test.cjs.map +1 -0
- package/dist/llm/utils.test.js +490 -0
- package/dist/llm/utils.test.js.map +1 -0
- package/dist/metrics/base.cjs +0 -27
- package/dist/metrics/base.cjs.map +1 -1
- package/dist/metrics/base.d.cts +105 -63
- package/dist/metrics/base.d.ts +105 -63
- package/dist/metrics/base.d.ts.map +1 -1
- package/dist/metrics/base.js +0 -19
- package/dist/metrics/base.js.map +1 -1
- package/dist/metrics/index.cjs +0 -3
- package/dist/metrics/index.cjs.map +1 -1
- package/dist/metrics/index.d.cts +2 -3
- package/dist/metrics/index.d.ts +2 -3
- package/dist/metrics/index.d.ts.map +1 -1
- package/dist/metrics/index.js +0 -2
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/usage_collector.cjs +17 -12
- package/dist/metrics/usage_collector.cjs.map +1 -1
- package/dist/metrics/usage_collector.d.cts +3 -2
- package/dist/metrics/usage_collector.d.ts +3 -2
- package/dist/metrics/usage_collector.d.ts.map +1 -1
- package/dist/metrics/usage_collector.js +17 -12
- package/dist/metrics/usage_collector.js.map +1 -1
- package/dist/metrics/utils.cjs +22 -59
- package/dist/metrics/utils.cjs.map +1 -1
- package/dist/metrics/utils.d.cts +1 -8
- package/dist/metrics/utils.d.ts +1 -8
- package/dist/metrics/utils.d.ts.map +1 -1
- package/dist/metrics/utils.js +22 -52
- package/dist/metrics/utils.js.map +1 -1
- package/dist/multimodal/index.cjs +0 -2
- package/dist/multimodal/index.cjs.map +1 -1
- package/dist/multimodal/index.d.cts +0 -1
- package/dist/multimodal/index.d.ts +0 -1
- package/dist/multimodal/index.d.ts.map +1 -1
- package/dist/multimodal/index.js +0 -1
- package/dist/multimodal/index.js.map +1 -1
- package/dist/plugin.cjs +24 -8
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +18 -4
- package/dist/plugin.d.ts +18 -4
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +22 -7
- package/dist/plugin.js.map +1 -1
- package/dist/stream/deferred_stream.cjs +98 -0
- package/dist/stream/deferred_stream.cjs.map +1 -0
- package/dist/stream/deferred_stream.d.cts +27 -0
- package/dist/stream/deferred_stream.d.ts +27 -0
- package/dist/stream/deferred_stream.d.ts.map +1 -0
- package/dist/stream/deferred_stream.js +73 -0
- package/dist/stream/deferred_stream.js.map +1 -0
- package/dist/stream/deferred_stream.test.cjs +527 -0
- package/dist/stream/deferred_stream.test.cjs.map +1 -0
- package/dist/stream/deferred_stream.test.js +526 -0
- package/dist/stream/deferred_stream.test.js.map +1 -0
- package/dist/stream/identity_transform.cjs +42 -0
- package/dist/stream/identity_transform.cjs.map +1 -0
- package/dist/stream/identity_transform.d.cts +6 -0
- package/dist/stream/identity_transform.d.ts +6 -0
- package/dist/stream/identity_transform.d.ts.map +1 -0
- package/dist/stream/identity_transform.js +18 -0
- package/dist/stream/identity_transform.js.map +1 -0
- package/dist/stream/identity_transform.test.cjs +125 -0
- package/dist/stream/identity_transform.test.cjs.map +1 -0
- package/dist/stream/identity_transform.test.js +124 -0
- package/dist/stream/identity_transform.test.js.map +1 -0
- package/dist/stream/index.cjs +38 -0
- package/dist/stream/index.cjs.map +1 -0
- package/dist/stream/index.d.cts +5 -0
- package/dist/stream/index.d.ts +5 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream/index.js +11 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/stream/merge_readable_streams.cjs +59 -0
- package/dist/stream/merge_readable_streams.cjs.map +1 -0
- package/dist/stream/merge_readable_streams.d.cts +4 -0
- package/dist/stream/merge_readable_streams.d.ts +4 -0
- package/dist/stream/merge_readable_streams.d.ts.map +1 -0
- package/dist/stream/merge_readable_streams.js +35 -0
- package/dist/stream/merge_readable_streams.js.map +1 -0
- package/dist/stream/stream_channel.cjs +47 -0
- package/dist/stream/stream_channel.cjs.map +1 -0
- package/dist/stream/stream_channel.d.cts +9 -0
- package/dist/stream/stream_channel.d.ts +9 -0
- package/dist/stream/stream_channel.d.ts.map +1 -0
- package/dist/stream/stream_channel.js +23 -0
- package/dist/stream/stream_channel.js.map +1 -0
- package/dist/stream/stream_channel.test.cjs +97 -0
- package/dist/stream/stream_channel.test.cjs.map +1 -0
- package/dist/stream/stream_channel.test.js +96 -0
- package/dist/stream/stream_channel.test.js.map +1 -0
- package/dist/stt/stream_adapter.cjs +3 -4
- package/dist/stt/stream_adapter.cjs.map +1 -1
- package/dist/stt/stream_adapter.d.cts +1 -0
- package/dist/stt/stream_adapter.d.ts +1 -0
- package/dist/stt/stream_adapter.d.ts.map +1 -1
- package/dist/stt/stream_adapter.js +3 -4
- package/dist/stt/stream_adapter.js.map +1 -1
- package/dist/stt/stt.cjs +101 -10
- package/dist/stt/stt.cjs.map +1 -1
- package/dist/stt/stt.d.cts +26 -5
- package/dist/stt/stt.d.ts +26 -5
- package/dist/stt/stt.d.ts.map +1 -1
- package/dist/stt/stt.js +102 -11
- package/dist/stt/stt.js.map +1 -1
- package/dist/tokenize/basic/basic.cjs +10 -5
- package/dist/tokenize/basic/basic.cjs.map +1 -1
- package/dist/tokenize/basic/basic.d.cts +7 -1
- package/dist/tokenize/basic/basic.d.ts +7 -1
- package/dist/tokenize/basic/basic.d.ts.map +1 -1
- package/dist/tokenize/basic/basic.js +10 -5
- package/dist/tokenize/basic/basic.js.map +1 -1
- package/dist/tokenize/basic/sentence.cjs +14 -6
- package/dist/tokenize/basic/sentence.cjs.map +1 -1
- package/dist/tokenize/basic/sentence.d.cts +1 -1
- package/dist/tokenize/basic/sentence.d.ts +1 -1
- package/dist/tokenize/basic/sentence.d.ts.map +1 -1
- package/dist/tokenize/basic/sentence.js +14 -6
- package/dist/tokenize/basic/sentence.js.map +1 -1
- package/dist/tokenize/token_stream.cjs +5 -3
- package/dist/tokenize/token_stream.cjs.map +1 -1
- package/dist/tokenize/token_stream.d.cts +1 -0
- package/dist/tokenize/token_stream.d.ts +1 -0
- package/dist/tokenize/token_stream.d.ts.map +1 -1
- package/dist/tokenize/token_stream.js +6 -4
- package/dist/tokenize/token_stream.js.map +1 -1
- package/dist/transcription.cjs +1 -2
- package/dist/transcription.cjs.map +1 -1
- package/dist/transcription.d.ts.map +1 -1
- package/dist/transcription.js +2 -3
- package/dist/transcription.js.map +1 -1
- package/dist/tts/index.cjs +2 -4
- package/dist/tts/index.cjs.map +1 -1
- package/dist/tts/index.d.cts +1 -1
- package/dist/tts/index.d.ts +1 -1
- package/dist/tts/index.d.ts.map +1 -1
- package/dist/tts/index.js +1 -3
- package/dist/tts/index.js.map +1 -1
- package/dist/tts/stream_adapter.cjs +26 -13
- package/dist/tts/stream_adapter.cjs.map +1 -1
- package/dist/tts/stream_adapter.d.cts +1 -1
- package/dist/tts/stream_adapter.d.ts +1 -1
- package/dist/tts/stream_adapter.d.ts.map +1 -1
- package/dist/tts/stream_adapter.js +27 -14
- package/dist/tts/stream_adapter.js.map +1 -1
- package/dist/tts/tts.cjs +157 -25
- package/dist/tts/tts.cjs.map +1 -1
- package/dist/tts/tts.d.cts +29 -5
- package/dist/tts/tts.d.ts +29 -5
- package/dist/tts/tts.d.ts.map +1 -1
- package/dist/tts/tts.js +157 -24
- package/dist/tts/tts.js.map +1 -1
- package/dist/types.cjs +60 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +13 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.cjs +281 -27
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +134 -9
- package/dist/utils.d.ts +134 -9
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +265 -26
- package/dist/utils.js.map +1 -1
- package/dist/utils.test.cjs +492 -0
- package/dist/utils.test.cjs.map +1 -0
- package/dist/utils.test.js +498 -0
- package/dist/utils.test.js.map +1 -0
- package/dist/vad.cjs +76 -20
- package/dist/vad.cjs.map +1 -1
- package/dist/vad.d.cts +25 -5
- package/dist/vad.d.ts +25 -5
- package/dist/vad.d.ts.map +1 -1
- package/dist/vad.js +76 -20
- package/dist/vad.js.map +1 -1
- package/dist/voice/agent.cjs +245 -0
- package/dist/voice/agent.cjs.map +1 -0
- package/dist/voice/agent.d.cts +78 -0
- package/dist/voice/agent.d.ts +78 -0
- package/dist/voice/agent.d.ts.map +1 -0
- package/dist/voice/agent.js +220 -0
- package/dist/voice/agent.js.map +1 -0
- package/dist/voice/agent.test.cjs +61 -0
- package/dist/voice/agent.test.cjs.map +1 -0
- package/dist/voice/agent.test.js +60 -0
- package/dist/voice/agent.test.js.map +1 -0
- package/dist/voice/agent_activity.cjs +1453 -0
- package/dist/voice/agent_activity.cjs.map +1 -0
- package/dist/voice/agent_activity.d.cts +94 -0
- package/dist/voice/agent_activity.d.ts +94 -0
- package/dist/voice/agent_activity.d.ts.map +1 -0
- package/dist/voice/agent_activity.js +1449 -0
- package/dist/voice/agent_activity.js.map +1 -0
- package/dist/voice/agent_session.cjs +312 -0
- package/dist/voice/agent_session.cjs.map +1 -0
- package/dist/voice/agent_session.d.cts +121 -0
- package/dist/voice/agent_session.d.ts +121 -0
- package/dist/voice/agent_session.d.ts.map +1 -0
- package/dist/voice/agent_session.js +295 -0
- package/dist/voice/agent_session.js.map +1 -0
- package/dist/voice/audio_recognition.cjs +375 -0
- package/dist/voice/audio_recognition.cjs.map +1 -0
- package/dist/voice/audio_recognition.d.cts +80 -0
- package/dist/voice/audio_recognition.d.ts +80 -0
- package/dist/voice/audio_recognition.d.ts.map +1 -0
- package/dist/voice/audio_recognition.js +351 -0
- package/dist/voice/audio_recognition.js.map +1 -0
- package/dist/voice/events.cjs +145 -0
- package/dist/voice/events.cjs.map +1 -0
- package/dist/voice/events.d.cts +124 -0
- package/dist/voice/events.d.ts +124 -0
- package/dist/voice/events.d.ts.map +1 -0
- package/dist/voice/events.js +110 -0
- package/dist/voice/events.js.map +1 -0
- package/dist/voice/generation.cjs +700 -0
- package/dist/voice/generation.cjs.map +1 -0
- package/dist/voice/generation.d.cts +115 -0
- package/dist/voice/generation.d.ts +115 -0
- package/dist/voice/generation.d.ts.map +1 -0
- package/dist/voice/generation.js +672 -0
- package/dist/voice/generation.js.map +1 -0
- package/dist/voice/index.cjs +40 -0
- package/dist/voice/index.cjs.map +1 -0
- package/dist/voice/index.d.cts +5 -0
- package/dist/voice/index.d.ts +5 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +11 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/io.cjs +245 -0
- package/dist/voice/io.cjs.map +1 -0
- package/dist/voice/io.d.cts +101 -0
- package/dist/voice/io.d.ts +101 -0
- package/dist/voice/io.d.ts.map +1 -0
- package/dist/voice/io.js +217 -0
- package/dist/voice/io.js.map +1 -0
- package/dist/voice/room_io/_input.cjs +121 -0
- package/dist/voice/room_io/_input.cjs.map +1 -0
- package/dist/voice/room_io/_input.d.cts +24 -0
- package/dist/voice/room_io/_input.d.ts +24 -0
- package/dist/voice/room_io/_input.d.ts.map +1 -0
- package/dist/voice/room_io/_input.js +102 -0
- package/dist/voice/room_io/_input.js.map +1 -0
- package/dist/voice/room_io/_output.cjs +358 -0
- package/dist/voice/room_io/_output.cjs.map +1 -0
- package/dist/voice/room_io/_output.d.cts +75 -0
- package/dist/voice/room_io/_output.d.ts +75 -0
- package/dist/voice/room_io/_output.d.ts.map +1 -0
- package/dist/voice/room_io/_output.js +342 -0
- package/dist/voice/room_io/_output.js.map +1 -0
- package/dist/voice/room_io/index.cjs +25 -0
- package/dist/voice/room_io/index.cjs.map +1 -0
- package/dist/voice/room_io/index.d.cts +3 -0
- package/dist/voice/room_io/index.d.ts +3 -0
- package/dist/voice/room_io/index.d.ts.map +1 -0
- package/dist/voice/room_io/index.js +3 -0
- package/dist/voice/room_io/index.js.map +1 -0
- package/dist/voice/room_io/room_io.cjs +370 -0
- package/dist/voice/room_io/room_io.cjs.map +1 -0
- package/dist/voice/room_io/room_io.d.cts +73 -0
- package/dist/voice/room_io/room_io.d.ts +73 -0
- package/dist/voice/room_io/room_io.d.ts.map +1 -0
- package/dist/voice/room_io/room_io.js +361 -0
- package/dist/voice/room_io/room_io.js.map +1 -0
- package/dist/{pipeline/index.cjs → voice/run_context.cjs} +16 -11
- package/dist/voice/run_context.cjs.map +1 -0
- package/dist/voice/run_context.d.cts +12 -0
- package/dist/voice/run_context.d.ts +12 -0
- package/dist/voice/run_context.d.ts.map +1 -0
- package/dist/voice/run_context.js +14 -0
- package/dist/voice/run_context.js.map +1 -0
- package/dist/voice/speech_handle.cjs +105 -0
- package/dist/voice/speech_handle.cjs.map +1 -0
- package/dist/voice/speech_handle.d.cts +46 -0
- package/dist/voice/speech_handle.d.ts +46 -0
- package/dist/voice/speech_handle.d.ts.map +1 -0
- package/dist/voice/speech_handle.js +81 -0
- package/dist/voice/speech_handle.js.map +1 -0
- package/dist/voice/transcription/_utils.cjs +45 -0
- package/dist/voice/transcription/_utils.cjs.map +1 -0
- package/dist/voice/transcription/_utils.d.cts +3 -0
- package/dist/voice/transcription/_utils.d.ts +3 -0
- package/dist/voice/transcription/_utils.d.ts.map +1 -0
- package/dist/voice/transcription/_utils.js +21 -0
- package/dist/voice/transcription/_utils.js.map +1 -0
- package/dist/voice/transcription/index.cjs +23 -0
- package/dist/voice/transcription/index.cjs.map +1 -0
- package/dist/voice/transcription/index.d.cts +2 -0
- package/dist/voice/transcription/index.d.ts +2 -0
- package/dist/voice/transcription/index.d.ts.map +1 -0
- package/dist/voice/transcription/index.js +2 -0
- package/dist/voice/transcription/index.js.map +1 -0
- package/dist/voice/transcription/synchronizer.cjs +380 -0
- package/dist/voice/transcription/synchronizer.cjs.map +1 -0
- package/dist/voice/transcription/synchronizer.d.cts +86 -0
- package/dist/voice/transcription/synchronizer.d.ts +86 -0
- package/dist/voice/transcription/synchronizer.d.ts.map +1 -0
- package/dist/voice/transcription/synchronizer.js +355 -0
- package/dist/voice/transcription/synchronizer.js.map +1 -0
- package/dist/worker.cjs +22 -4
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +1 -1
- package/dist/worker.d.ts +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +22 -4
- package/dist/worker.js.map +1 -1
- package/package.json +9 -2
- package/src/_exceptions.ts +137 -0
- package/src/audio.ts +12 -1
- package/src/cli.ts +37 -0
- package/src/constants.ts +2 -0
- package/src/http_server.ts +1 -0
- package/src/index.ts +13 -10
- package/src/inference_runner.ts +2 -3
- package/src/ipc/inference_proc_executor.ts +2 -2
- package/src/ipc/job_executor.ts +1 -1
- package/src/ipc/job_proc_executor.ts +1 -1
- package/src/ipc/job_proc_lazy_main.ts +1 -1
- package/src/job.ts +18 -0
- package/src/llm/__snapshots__/chat_context.test.ts.snap +527 -0
- package/src/llm/__snapshots__/tool_context.test.ts.snap +177 -0
- package/src/llm/__snapshots__/utils.test.ts.snap +65 -0
- package/src/llm/chat_context.test.ts +450 -0
- package/src/llm/chat_context.ts +501 -103
- package/src/llm/index.ts +53 -18
- package/src/llm/llm.ts +149 -50
- package/src/llm/provider_format/google.test.ts +772 -0
- package/src/llm/provider_format/google.ts +130 -0
- package/src/llm/provider_format/index.ts +23 -0
- package/src/llm/provider_format/openai.test.ts +581 -0
- package/src/llm/provider_format/openai.ts +118 -0
- package/src/llm/provider_format/utils.ts +183 -0
- package/src/llm/realtime.ts +151 -0
- package/src/llm/remote_chat_context.test.ts +290 -0
- package/src/llm/remote_chat_context.ts +114 -0
- package/src/llm/tool_context.test.ts +198 -0
- package/src/llm/tool_context.ts +259 -0
- package/src/llm/tool_context.type.test.ts +115 -0
- package/src/llm/utils.test.ts +670 -0
- package/src/llm/utils.ts +324 -0
- package/src/metrics/base.ts +110 -78
- package/src/metrics/index.ts +3 -9
- package/src/metrics/usage_collector.ts +19 -13
- package/src/metrics/utils.ts +24 -69
- package/src/multimodal/index.ts +0 -1
- package/src/plugin.ts +26 -8
- package/src/stream/deferred_stream.test.ts +755 -0
- package/src/stream/deferred_stream.ts +110 -0
- package/src/stream/identity_transform.test.ts +179 -0
- package/src/stream/identity_transform.ts +18 -0
- package/src/stream/index.ts +7 -0
- package/src/stream/merge_readable_streams.ts +40 -0
- package/src/stream/stream_channel.test.ts +129 -0
- package/src/stream/stream_channel.ts +32 -0
- package/src/stt/stream_adapter.ts +3 -5
- package/src/stt/stt.ts +135 -17
- package/src/tokenize/basic/basic.ts +13 -5
- package/src/tokenize/basic/sentence.ts +20 -6
- package/src/tokenize/token_stream.ts +7 -4
- package/src/transcription.ts +2 -3
- package/src/tts/index.ts +0 -1
- package/src/tts/stream_adapter.ts +42 -16
- package/src/tts/tts.ts +203 -21
- package/src/types.ts +42 -0
- package/src/utils.test.ts +658 -0
- package/src/utils.ts +375 -44
- package/src/vad.ts +90 -22
- package/src/voice/agent.test.ts +80 -0
- package/src/voice/agent.ts +332 -0
- package/src/voice/agent_activity.ts +1913 -0
- package/src/voice/agent_session.ts +460 -0
- package/src/voice/audio_recognition.ts +474 -0
- package/src/voice/events.ts +252 -0
- package/src/voice/generation.ts +881 -0
- package/src/voice/index.ts +7 -0
- package/src/voice/io.ts +304 -0
- package/src/voice/room_io/_input.ts +144 -0
- package/src/voice/room_io/_output.ts +436 -0
- package/src/voice/room_io/index.ts +5 -0
- package/src/voice/room_io/room_io.ts +495 -0
- package/src/voice/run_context.ts +20 -0
- package/src/voice/speech_handle.ts +104 -0
- package/src/voice/transcription/_utils.ts +25 -0
- package/src/voice/transcription/index.ts +4 -0
- package/src/voice/transcription/synchronizer.ts +478 -0
- package/src/worker.ts +22 -2
- package/dist/llm/function_context.cjs +0 -103
- package/dist/llm/function_context.cjs.map +0 -1
- package/dist/llm/function_context.d.cts +0 -47
- package/dist/llm/function_context.d.ts +0 -47
- package/dist/llm/function_context.d.ts.map +0 -1
- package/dist/llm/function_context.js +0 -78
- package/dist/llm/function_context.js.map +0 -1
- package/dist/llm/function_context.test.cjs +0 -218
- package/dist/llm/function_context.test.cjs.map +0 -1
- package/dist/llm/function_context.test.js +0 -217
- package/dist/llm/function_context.test.js.map +0 -1
- package/dist/multimodal/multimodal_agent.cjs +0 -451
- package/dist/multimodal/multimodal_agent.cjs.map +0 -1
- package/dist/multimodal/multimodal_agent.d.cts +0 -48
- package/dist/multimodal/multimodal_agent.d.ts +0 -48
- package/dist/multimodal/multimodal_agent.d.ts.map +0 -1
- package/dist/multimodal/multimodal_agent.js +0 -425
- package/dist/multimodal/multimodal_agent.js.map +0 -1
- package/dist/pipeline/agent_output.cjs +0 -197
- package/dist/pipeline/agent_output.cjs.map +0 -1
- package/dist/pipeline/agent_output.d.cts +0 -33
- package/dist/pipeline/agent_output.d.ts +0 -33
- package/dist/pipeline/agent_output.d.ts.map +0 -1
- package/dist/pipeline/agent_output.js +0 -172
- package/dist/pipeline/agent_output.js.map +0 -1
- package/dist/pipeline/agent_playout.cjs +0 -175
- package/dist/pipeline/agent_playout.cjs.map +0 -1
- package/dist/pipeline/agent_playout.d.cts +0 -40
- package/dist/pipeline/agent_playout.d.ts +0 -40
- package/dist/pipeline/agent_playout.d.ts.map +0 -1
- package/dist/pipeline/agent_playout.js +0 -139
- package/dist/pipeline/agent_playout.js.map +0 -1
- package/dist/pipeline/human_input.cjs +0 -171
- package/dist/pipeline/human_input.cjs.map +0 -1
- package/dist/pipeline/human_input.d.cts +0 -30
- package/dist/pipeline/human_input.d.ts +0 -30
- package/dist/pipeline/human_input.d.ts.map +0 -1
- package/dist/pipeline/human_input.js +0 -146
- package/dist/pipeline/human_input.js.map +0 -1
- package/dist/pipeline/index.cjs.map +0 -1
- package/dist/pipeline/index.d.cts +0 -2
- package/dist/pipeline/index.d.ts +0 -2
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline/index.js +0 -11
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/pipeline_agent.cjs +0 -849
- package/dist/pipeline/pipeline_agent.cjs.map +0 -1
- package/dist/pipeline/pipeline_agent.d.cts +0 -150
- package/dist/pipeline/pipeline_agent.d.ts +0 -150
- package/dist/pipeline/pipeline_agent.d.ts.map +0 -1
- package/dist/pipeline/pipeline_agent.js +0 -826
- package/dist/pipeline/pipeline_agent.js.map +0 -1
- package/dist/pipeline/speech_handle.cjs +0 -176
- package/dist/pipeline/speech_handle.cjs.map +0 -1
- package/dist/pipeline/speech_handle.d.cts +0 -37
- package/dist/pipeline/speech_handle.d.ts +0 -37
- package/dist/pipeline/speech_handle.d.ts.map +0 -1
- package/dist/pipeline/speech_handle.js +0 -152
- package/dist/pipeline/speech_handle.js.map +0 -1
- package/src/llm/function_context.test.ts +0 -248
- package/src/llm/function_context.ts +0 -142
- package/src/multimodal/multimodal_agent.ts +0 -555
- package/src/pipeline/agent_output.ts +0 -219
- package/src/pipeline/agent_playout.ts +0 -192
- package/src/pipeline/human_input.ts +0 -188
- package/src/pipeline/index.ts +0 -15
- package/src/pipeline/pipeline_agent.ts +0 -1185
- package/src/pipeline/speech_handle.ts +0 -201
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { log } from '../../log.js';
|
|
5
|
+
import type {
|
|
6
|
+
ChatContext,
|
|
7
|
+
ChatItem,
|
|
8
|
+
ChatMessage,
|
|
9
|
+
FunctionCall,
|
|
10
|
+
FunctionCallOutput,
|
|
11
|
+
} from '../chat_context.js';
|
|
12
|
+
|
|
13
|
+
class ChatItemGroup {
|
|
14
|
+
message?: ChatMessage;
|
|
15
|
+
toolCalls: FunctionCall[];
|
|
16
|
+
toolOutputs: FunctionCallOutput[];
|
|
17
|
+
logger = log();
|
|
18
|
+
|
|
19
|
+
constructor(params: {
|
|
20
|
+
message?: ChatMessage;
|
|
21
|
+
toolCalls: FunctionCall[];
|
|
22
|
+
toolOutputs: FunctionCallOutput[];
|
|
23
|
+
}) {
|
|
24
|
+
this.message = params.message;
|
|
25
|
+
this.toolCalls = params.toolCalls;
|
|
26
|
+
this.toolOutputs = params.toolOutputs;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static create(params?: {
|
|
30
|
+
message?: ChatMessage;
|
|
31
|
+
toolCalls?: FunctionCall[];
|
|
32
|
+
toolOutputs?: FunctionCallOutput[];
|
|
33
|
+
}) {
|
|
34
|
+
const { message, toolCalls = [], toolOutputs = [] } = params ?? {};
|
|
35
|
+
return new ChatItemGroup({ message, toolCalls, toolOutputs });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get isEmpty() {
|
|
39
|
+
return (
|
|
40
|
+
this.message === undefined && this.toolCalls.length === 0 && this.toolOutputs.length === 0
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
add(item: ChatItem) {
|
|
45
|
+
if (item.type === 'message') {
|
|
46
|
+
if (this.message) {
|
|
47
|
+
throw new Error('only one message is allowed in a group');
|
|
48
|
+
}
|
|
49
|
+
this.message = item;
|
|
50
|
+
} else if (item.type === 'function_call') {
|
|
51
|
+
this.toolCalls.push(item);
|
|
52
|
+
} else if (item.type === 'function_call_output') {
|
|
53
|
+
this.toolOutputs.push(item);
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
removeInvalidToolCalls() {
|
|
59
|
+
if (this.toolCalls.length === this.toolOutputs.length) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const toolCallIds = new Set(this.toolCalls.map((call) => call.callId));
|
|
64
|
+
const toolOutputIds = new Set(this.toolOutputs.map((output) => output.callId));
|
|
65
|
+
|
|
66
|
+
// intersection of tool call ids and tool output ids
|
|
67
|
+
const validCallIds = intersection(toolCallIds, toolOutputIds);
|
|
68
|
+
|
|
69
|
+
// filter out tool calls that don't have a corresponding tool output
|
|
70
|
+
this.toolCalls = this.toolCalls.filter((call) => {
|
|
71
|
+
if (validCallIds.has(call.callId)) return true;
|
|
72
|
+
this.logger.warn(
|
|
73
|
+
{
|
|
74
|
+
callId: call.callId,
|
|
75
|
+
toolName: call.name,
|
|
76
|
+
},
|
|
77
|
+
'function call missing the corresponding function output, ignoring',
|
|
78
|
+
);
|
|
79
|
+
return false;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// filter out tool outputs that don't have a corresponding tool call
|
|
83
|
+
this.toolOutputs = this.toolOutputs.filter((output) => {
|
|
84
|
+
if (validCallIds.has(output.callId)) return true;
|
|
85
|
+
this.logger.warn(
|
|
86
|
+
{
|
|
87
|
+
callId: output.callId,
|
|
88
|
+
toolName: output.name,
|
|
89
|
+
},
|
|
90
|
+
'function output missing the corresponding function call, ignoring',
|
|
91
|
+
);
|
|
92
|
+
return false;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
flatten() {
|
|
97
|
+
const items: ChatItem[] = [];
|
|
98
|
+
if (this.message) items.push(this.message);
|
|
99
|
+
items.push(...this.toolCalls, ...this.toolOutputs);
|
|
100
|
+
return items;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function intersection<T>(set1: Set<T>, set2: Set<T>): Set<T> {
|
|
105
|
+
return new Set([...set1].filter((item) => set2.has(item)));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Group chat items (messages, function calls, and function outputs)
|
|
110
|
+
* into coherent groups based on their item IDs and call IDs.
|
|
111
|
+
*
|
|
112
|
+
* Each group will contain:
|
|
113
|
+
* - Zero or one assistant message
|
|
114
|
+
* - Zero or more function/tool calls
|
|
115
|
+
* - The corresponding function/tool outputs matched by call_id
|
|
116
|
+
*
|
|
117
|
+
* User and system messages are placed in their own individual groups.
|
|
118
|
+
*
|
|
119
|
+
* @param chatCtx - The chat context containing all conversation items
|
|
120
|
+
* @returns A list of ChatItemGroup objects representing the grouped conversation
|
|
121
|
+
*/
|
|
122
|
+
export function groupToolCalls(chatCtx: ChatContext) {
|
|
123
|
+
const itemGroups: Record<string, ChatItemGroup> = {};
|
|
124
|
+
const insertionOrder: Record<string, number> = {};
|
|
125
|
+
const toolOutputs: FunctionCallOutput[] = [];
|
|
126
|
+
const logger = log();
|
|
127
|
+
|
|
128
|
+
let insertionIndex = 0;
|
|
129
|
+
for (const item of chatCtx.items) {
|
|
130
|
+
const isAssistantMessage = item.type === 'message' && item.role === 'assistant';
|
|
131
|
+
const isFunctionCall = item.type === 'function_call';
|
|
132
|
+
const isFunctionCallOutput = item.type === 'function_call_output';
|
|
133
|
+
|
|
134
|
+
if (isAssistantMessage || isFunctionCall) {
|
|
135
|
+
// only assistant messages and function calls can be grouped
|
|
136
|
+
const groupId = item.id.split('/')[0]!;
|
|
137
|
+
if (itemGroups[groupId] === undefined) {
|
|
138
|
+
itemGroups[groupId] = ChatItemGroup.create();
|
|
139
|
+
|
|
140
|
+
// we use insertion order to sort the groups as they are added to the context
|
|
141
|
+
// simulating the OrderedDict in python
|
|
142
|
+
insertionOrder[groupId] = insertionIndex;
|
|
143
|
+
insertionIndex++;
|
|
144
|
+
}
|
|
145
|
+
itemGroups[groupId]!.add(item);
|
|
146
|
+
} else if (isFunctionCallOutput) {
|
|
147
|
+
toolOutputs.push(item);
|
|
148
|
+
} else {
|
|
149
|
+
itemGroups[item.id] = ChatItemGroup.create().add(item);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// add tool outputs to their corresponding groups
|
|
154
|
+
const callIdToGroup: Record<string, ChatItemGroup> = {};
|
|
155
|
+
for (const group of Object.values(itemGroups)) {
|
|
156
|
+
for (const toolCall of group.toolCalls) {
|
|
157
|
+
callIdToGroup[toolCall.callId] = group;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
for (const toolOutput of toolOutputs) {
|
|
162
|
+
const group = callIdToGroup[toolOutput.callId];
|
|
163
|
+
if (group === undefined) {
|
|
164
|
+
logger.warn(
|
|
165
|
+
{ callId: toolOutput.callId, toolName: toolOutput.name },
|
|
166
|
+
'function output missing the corresponding function call, ignoring',
|
|
167
|
+
);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
group.add(toolOutput);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// validate that each group and remove invalid tool calls and tool outputs
|
|
174
|
+
for (const group of Object.values(itemGroups)) {
|
|
175
|
+
group.removeInvalidToolCalls();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// sort groups by their item id
|
|
179
|
+
const orderedGroups = Object.entries(itemGroups)
|
|
180
|
+
.sort((a, b) => insertionOrder[a[0]]! - insertionOrder[b[0]]!)
|
|
181
|
+
.map(([, group]) => group);
|
|
182
|
+
return orderedGroups;
|
|
183
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import type { AudioFrame } from '@livekit/rtc-node';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import type { ReadableStream } from 'node:stream/web';
|
|
7
|
+
import { DeferredReadableStream } from '../stream/deferred_stream.js';
|
|
8
|
+
import { Task } from '../utils.js';
|
|
9
|
+
import type { ChatContext, FunctionCall } from './chat_context.js';
|
|
10
|
+
import type { ToolChoice, ToolContext } from './tool_context.js';
|
|
11
|
+
|
|
12
|
+
export type InputSpeechStartedEvent = object;
|
|
13
|
+
|
|
14
|
+
export interface InputSpeechStoppedEvent {
|
|
15
|
+
userTranscriptionEnabled: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface MessageGeneration {
|
|
19
|
+
messageId: string;
|
|
20
|
+
textStream: ReadableStream<string>;
|
|
21
|
+
audioStream: ReadableStream<AudioFrame>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface GenerationCreatedEvent {
|
|
25
|
+
messageStream: ReadableStream<MessageGeneration>;
|
|
26
|
+
functionStream: ReadableStream<FunctionCall>;
|
|
27
|
+
userInitiated: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface RealtimeModelError {
|
|
31
|
+
type: 'realtime_model_error';
|
|
32
|
+
timestamp: number;
|
|
33
|
+
label: string;
|
|
34
|
+
error: Error;
|
|
35
|
+
recoverable: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface RealtimeCapabilities {
|
|
39
|
+
messageTruncation: boolean;
|
|
40
|
+
turnDetection: boolean;
|
|
41
|
+
userTranscription: boolean;
|
|
42
|
+
autoToolReplyGeneration: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface InputTranscriptionCompleted {
|
|
46
|
+
itemId: string;
|
|
47
|
+
transcript: string;
|
|
48
|
+
isFinal: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface RealtimeSessionReconnectedEvent {}
|
|
52
|
+
|
|
53
|
+
export abstract class RealtimeModel {
|
|
54
|
+
private _capabilities: RealtimeCapabilities;
|
|
55
|
+
|
|
56
|
+
constructor(capabilities: RealtimeCapabilities) {
|
|
57
|
+
this._capabilities = capabilities;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get capabilities() {
|
|
61
|
+
return this._capabilities;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
abstract session(): RealtimeSession;
|
|
65
|
+
|
|
66
|
+
abstract close(): Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export abstract class RealtimeSession extends EventEmitter {
|
|
70
|
+
protected _realtimeModel: RealtimeModel;
|
|
71
|
+
private deferredInputStream = new DeferredReadableStream<AudioFrame>();
|
|
72
|
+
private _mainTask: Task<void>;
|
|
73
|
+
|
|
74
|
+
constructor(realtimeModel: RealtimeModel) {
|
|
75
|
+
super();
|
|
76
|
+
this._realtimeModel = realtimeModel;
|
|
77
|
+
this._mainTask = Task.from((controller) => this._mainTaskImpl(controller.signal));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get realtimeModel() {
|
|
81
|
+
return this._realtimeModel;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
abstract get chatCtx(): ChatContext;
|
|
85
|
+
|
|
86
|
+
abstract get tools(): ToolContext;
|
|
87
|
+
|
|
88
|
+
abstract updateInstructions(instructions: string): Promise<void>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @throws RealtimeError on Timeout
|
|
92
|
+
*/
|
|
93
|
+
abstract updateChatCtx(chatCtx: ChatContext): Promise<void>;
|
|
94
|
+
|
|
95
|
+
abstract updateTools(tools: ToolContext): Promise<void>;
|
|
96
|
+
|
|
97
|
+
abstract updateOptions(options: { toolChoice?: ToolChoice | null }): void;
|
|
98
|
+
|
|
99
|
+
abstract pushAudio(frame: AudioFrame): void;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @throws RealtimeError on Timeout
|
|
103
|
+
*/
|
|
104
|
+
abstract generateReply(instructions?: string): Promise<GenerationCreatedEvent>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Commit the input audio buffer to the server
|
|
108
|
+
*/
|
|
109
|
+
abstract commitAudio(): Promise<void>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Clear the input audio buffer to the server
|
|
113
|
+
*/
|
|
114
|
+
abstract clearAudio(): Promise<void>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Cancel the current generation (do nothing if no generation is in progress)
|
|
118
|
+
*/
|
|
119
|
+
abstract interrupt(): Promise<void>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Truncate the message at the given audio end time
|
|
123
|
+
*/
|
|
124
|
+
abstract truncate(options: { messageId: string; audioEndMs: number }): Promise<void>;
|
|
125
|
+
|
|
126
|
+
async close(): Promise<void> {
|
|
127
|
+
this._mainTask.cancel();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Notifies the model that user activity has started
|
|
132
|
+
*/
|
|
133
|
+
startUserActivity(): void {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private async _mainTaskImpl(signal: AbortSignal): Promise<void> {
|
|
138
|
+
const reader = this.deferredInputStream.stream.getReader();
|
|
139
|
+
while (true) {
|
|
140
|
+
const { done, value } = await reader.read();
|
|
141
|
+
if (done || signal.aborted) {
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
this.pushAudio(value);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
setInputAudioStream(audioStream: ReadableStream<AudioFrame>): void {
|
|
149
|
+
this.deferredInputStream.setSource(audioStream);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { ChatMessage } from './chat_context.js';
|
|
6
|
+
import { RemoteChatContext } from './remote_chat_context.js';
|
|
7
|
+
|
|
8
|
+
function createMessage(id: string, content: string): ChatMessage {
|
|
9
|
+
return new ChatMessage({ id, role: 'user', content });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('RemoteChatContext', () => {
|
|
13
|
+
let context: RemoteChatContext;
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
context = new RemoteChatContext();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe('empty context', () => {
|
|
20
|
+
it('should return empty ChatContext', () => {
|
|
21
|
+
const chatCtx = context.toChatCtx();
|
|
22
|
+
expect(chatCtx.items).toHaveLength(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should return null for non-existent item', () => {
|
|
26
|
+
expect(context.get('nonexistent')).toBeNull();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should throw error when deleting non-existent item', () => {
|
|
30
|
+
expect(() => context.delete('nonexistent')).toThrow('Item with ID nonexistent not found');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('single item operations', () => {
|
|
35
|
+
it('should insert single item at head', () => {
|
|
36
|
+
const msg = createMessage('msg1', 'Hello');
|
|
37
|
+
context.insert(undefined, msg);
|
|
38
|
+
|
|
39
|
+
expect(context.get('msg1')).toBeDefined();
|
|
40
|
+
expect(context.get('msg1')!.item).toBe(msg);
|
|
41
|
+
expect(context.toChatCtx().items).toEqual([msg]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should delete single item', () => {
|
|
45
|
+
const msg = createMessage('msg1', 'Hello');
|
|
46
|
+
context.insert(undefined, msg);
|
|
47
|
+
context.delete('msg1');
|
|
48
|
+
|
|
49
|
+
expect(context.get('msg1')).toBeNull();
|
|
50
|
+
expect(context.toChatCtx().items).toHaveLength(0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('multiple item operations', () => {
|
|
55
|
+
it('should insert multiple items at head', () => {
|
|
56
|
+
const msg1 = createMessage('msg1', 'First');
|
|
57
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
58
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
59
|
+
|
|
60
|
+
context.insert(undefined, msg1);
|
|
61
|
+
context.insert(undefined, msg2);
|
|
62
|
+
context.insert(undefined, msg3);
|
|
63
|
+
|
|
64
|
+
expect(context.toChatCtx().items).toEqual([msg3, msg2, msg1]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should insert items after specific nodes', () => {
|
|
68
|
+
const msg1 = createMessage('msg1', 'First');
|
|
69
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
70
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
71
|
+
|
|
72
|
+
context.insert(undefined, msg1);
|
|
73
|
+
context.insert('msg1', msg2);
|
|
74
|
+
context.insert('msg1', msg3);
|
|
75
|
+
|
|
76
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg3, msg2]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should insert at tail', () => {
|
|
80
|
+
const msg1 = createMessage('msg1', 'First');
|
|
81
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
82
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
83
|
+
|
|
84
|
+
context.insert(undefined, msg1);
|
|
85
|
+
context.insert('msg1', msg2);
|
|
86
|
+
context.insert('msg2', msg3);
|
|
87
|
+
|
|
88
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg2, msg3]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('deletion edge cases', () => {
|
|
93
|
+
it('should delete head node from multi-item list', () => {
|
|
94
|
+
const msg1 = createMessage('msg1', 'First');
|
|
95
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
96
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
97
|
+
|
|
98
|
+
context.insert(undefined, msg1);
|
|
99
|
+
context.insert('msg1', msg2);
|
|
100
|
+
context.insert('msg2', msg3);
|
|
101
|
+
|
|
102
|
+
context.delete('msg1');
|
|
103
|
+
expect(context.toChatCtx().items).toEqual([msg2, msg3]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should delete tail node from multi-item list', () => {
|
|
107
|
+
const msg1 = createMessage('msg1', 'First');
|
|
108
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
109
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
110
|
+
|
|
111
|
+
context.insert(undefined, msg1);
|
|
112
|
+
context.insert('msg1', msg2);
|
|
113
|
+
context.insert('msg2', msg3);
|
|
114
|
+
|
|
115
|
+
context.delete('msg3');
|
|
116
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg2]);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should delete middle node from multi-item list', () => {
|
|
120
|
+
const msg1 = createMessage('msg1', 'First');
|
|
121
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
122
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
123
|
+
|
|
124
|
+
context.insert(undefined, msg1);
|
|
125
|
+
context.insert('msg1', msg2);
|
|
126
|
+
context.insert('msg2', msg3);
|
|
127
|
+
|
|
128
|
+
context.delete('msg2');
|
|
129
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg3]);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should handle multiple deletions', () => {
|
|
133
|
+
const msg1 = createMessage('msg1', 'First');
|
|
134
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
135
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
136
|
+
const msg4 = createMessage('msg4', 'Fourth');
|
|
137
|
+
|
|
138
|
+
context.insert(undefined, msg1);
|
|
139
|
+
context.insert('msg1', msg2);
|
|
140
|
+
context.insert('msg2', msg3);
|
|
141
|
+
context.insert('msg3', msg4);
|
|
142
|
+
|
|
143
|
+
context.delete('msg2');
|
|
144
|
+
context.delete('msg4');
|
|
145
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg3]);
|
|
146
|
+
|
|
147
|
+
context.delete('msg1');
|
|
148
|
+
expect(context.toChatCtx().items).toEqual([msg3]);
|
|
149
|
+
|
|
150
|
+
context.delete('msg3');
|
|
151
|
+
expect(context.toChatCtx().items).toHaveLength(0);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('error conditions', () => {
|
|
156
|
+
it('should throw error when inserting duplicate ID', () => {
|
|
157
|
+
const msg1 = createMessage('msg1', 'First');
|
|
158
|
+
const msg2 = createMessage('msg1', 'Duplicate');
|
|
159
|
+
|
|
160
|
+
context.insert(undefined, msg1);
|
|
161
|
+
expect(() => context.insert(undefined, msg2)).toThrow('Item with ID msg1 already exists.');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should throw error when inserting after non-existent ID', () => {
|
|
165
|
+
const msg = createMessage('msg1', 'Hello');
|
|
166
|
+
expect(() => context.insert('nonexistent', msg)).toThrow(
|
|
167
|
+
'previousItemId nonexistent not found',
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should throw error when deleting non-existent ID', () => {
|
|
172
|
+
expect(() => context.delete('nonexistent')).toThrow('Item with ID nonexistent not found');
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe('complex scenarios', () => {
|
|
177
|
+
it('should handle interleaved inserts and deletes', () => {
|
|
178
|
+
const msg1 = createMessage('msg1', 'A');
|
|
179
|
+
const msg2 = createMessage('msg2', 'B');
|
|
180
|
+
const msg3 = createMessage('msg3', 'C');
|
|
181
|
+
const msg4 = createMessage('msg4', 'D');
|
|
182
|
+
|
|
183
|
+
context.insert(undefined, msg1);
|
|
184
|
+
context.insert('msg1', msg2);
|
|
185
|
+
context.delete('msg1');
|
|
186
|
+
context.insert('msg2', msg3);
|
|
187
|
+
context.insert(undefined, msg4);
|
|
188
|
+
|
|
189
|
+
expect(context.toChatCtx().items).toEqual([msg4, msg2, msg3]);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should maintain correct pointers after complex operations', () => {
|
|
193
|
+
const msg1 = createMessage('msg1', 'A');
|
|
194
|
+
const msg2 = createMessage('msg2', 'B');
|
|
195
|
+
const msg3 = createMessage('msg3', 'C');
|
|
196
|
+
const msg4 = createMessage('msg4', 'D');
|
|
197
|
+
const msg5 = createMessage('msg5', 'E');
|
|
198
|
+
|
|
199
|
+
context.insert(undefined, msg1);
|
|
200
|
+
context.insert('msg1', msg2);
|
|
201
|
+
context.insert('msg2', msg3);
|
|
202
|
+
context.insert('msg1', msg4);
|
|
203
|
+
context.insert('msg4', msg5);
|
|
204
|
+
|
|
205
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg4, msg5, msg2, msg3]);
|
|
206
|
+
|
|
207
|
+
context.delete('msg4');
|
|
208
|
+
expect(context.toChatCtx().items).toEqual([msg1, msg5, msg2, msg3]);
|
|
209
|
+
|
|
210
|
+
context.delete('msg1');
|
|
211
|
+
expect(context.toChatCtx().items).toEqual([msg5, msg2, msg3]);
|
|
212
|
+
|
|
213
|
+
context.delete('msg2');
|
|
214
|
+
expect(context.toChatCtx().items).toEqual([msg5, msg3]);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should handle rebuilding from scratch', () => {
|
|
218
|
+
const messages = Array.from({ length: 10 }, (_, i) =>
|
|
219
|
+
createMessage(`msg${i}`, `Content ${i}`),
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
for (const msg of messages) {
|
|
223
|
+
context.insert(undefined, msg);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
expect(context.toChatCtx().items).toEqual([...messages].reverse());
|
|
227
|
+
|
|
228
|
+
for (let i = 0; i < 5; i++) {
|
|
229
|
+
context.delete(`msg${i}`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const remaining = [...messages]
|
|
233
|
+
.reverse()
|
|
234
|
+
.filter((msg) => !['msg0', 'msg1', 'msg2', 'msg3', 'msg4'].includes(msg.id));
|
|
235
|
+
expect(context.toChatCtx().items).toEqual(remaining);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe('get method', () => {
|
|
240
|
+
it('should return correct item for existing ID', () => {
|
|
241
|
+
const msg1 = createMessage('msg1', 'Hello');
|
|
242
|
+
const msg2 = createMessage('msg2', 'World');
|
|
243
|
+
|
|
244
|
+
context.insert(undefined, msg1);
|
|
245
|
+
context.insert('msg1', msg2);
|
|
246
|
+
|
|
247
|
+
const retrieved = context.get('msg2');
|
|
248
|
+
expect(retrieved).toBeDefined();
|
|
249
|
+
expect(retrieved!.item).toBe(msg2);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should return null for non-existent ID', () => {
|
|
253
|
+
const msg = createMessage('msg1', 'Hello');
|
|
254
|
+
context.insert(undefined, msg);
|
|
255
|
+
|
|
256
|
+
expect(context.get('nonexistent')).toBeNull();
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
describe('toChatCtx method', () => {
|
|
261
|
+
it('should preserve order in ChatContext', () => {
|
|
262
|
+
const msg1 = createMessage('msg1', 'First');
|
|
263
|
+
const msg2 = createMessage('msg2', 'Second');
|
|
264
|
+
const msg3 = createMessage('msg3', 'Third');
|
|
265
|
+
|
|
266
|
+
context.insert(undefined, msg1);
|
|
267
|
+
context.insert('msg1', msg2);
|
|
268
|
+
context.insert('msg2', msg3);
|
|
269
|
+
|
|
270
|
+
const chatCtx = context.toChatCtx();
|
|
271
|
+
expect(chatCtx.items).toEqual([msg1, msg2, msg3]);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('should work with empty context', () => {
|
|
275
|
+
const chatCtx = context.toChatCtx();
|
|
276
|
+
expect(chatCtx.items).toHaveLength(0);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('should create new ChatContext instance', () => {
|
|
280
|
+
const msg = createMessage('msg1', 'Hello');
|
|
281
|
+
context.insert(undefined, msg);
|
|
282
|
+
|
|
283
|
+
const chatCtx1 = context.toChatCtx();
|
|
284
|
+
const chatCtx2 = context.toChatCtx();
|
|
285
|
+
|
|
286
|
+
expect(chatCtx1).not.toBe(chatCtx2);
|
|
287
|
+
expect(chatCtx1.items).toEqual(chatCtx2.items);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
});
|