@livekit/agents 0.7.9 → 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 -3
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +2 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -2
- 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 -1
- 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 -486
- 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 -461
- 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 -859
- 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 -837
- 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 -592
- 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 -1197
- package/src/pipeline/speech_handle.ts +0 -201
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import type {
|
|
5
|
+
ReadableStream,
|
|
6
|
+
ReadableStreamDefaultReader,
|
|
7
|
+
WritableStreamDefaultWriter,
|
|
8
|
+
} from 'node:stream/web';
|
|
9
|
+
import { IdentityTransform } from './identity_transform.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Check if error is related to reader.read after release lock
|
|
13
|
+
*
|
|
14
|
+
* Invalid state: Releasing reader
|
|
15
|
+
* Invalid state: The reader is not attached to a stream
|
|
16
|
+
*/
|
|
17
|
+
export function isStreamReaderReleaseError(e: unknown) {
|
|
18
|
+
const allowedMessages = [
|
|
19
|
+
'Invalid state: Releasing reader',
|
|
20
|
+
'Invalid state: The reader is not attached to a stream',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
if (e instanceof TypeError) {
|
|
24
|
+
return allowedMessages.some((message) => e.message.includes(message));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
export class DeferredReadableStream<T> {
|
|
30
|
+
private transform: IdentityTransform<T>;
|
|
31
|
+
private writer: WritableStreamDefaultWriter<T>;
|
|
32
|
+
private sourceReader?: ReadableStreamDefaultReader<T>;
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
this.transform = new IdentityTransform<T>();
|
|
36
|
+
this.writer = this.transform.writable.getWriter();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get stream() {
|
|
40
|
+
return this.transform.readable;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get isSourceSet() {
|
|
44
|
+
return !!this.sourceReader;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Call once the actual source is ready.
|
|
49
|
+
*/
|
|
50
|
+
setSource(source: ReadableStream<T>) {
|
|
51
|
+
if (this.isSourceSet) {
|
|
52
|
+
throw new Error('Stream source already set');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.sourceReader = source.getReader();
|
|
56
|
+
this.pump();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private async pump() {
|
|
60
|
+
let sourceError: unknown;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
while (true) {
|
|
64
|
+
const { done, value } = await this.sourceReader!.read();
|
|
65
|
+
if (done) break;
|
|
66
|
+
await this.writer.write(value);
|
|
67
|
+
}
|
|
68
|
+
} catch (e) {
|
|
69
|
+
// skip source detach related errors
|
|
70
|
+
if (isStreamReaderReleaseError(e)) return;
|
|
71
|
+
sourceError = e;
|
|
72
|
+
} finally {
|
|
73
|
+
// any other error from source will be propagated to the consumer
|
|
74
|
+
if (sourceError) {
|
|
75
|
+
this.writer.abort(sourceError);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// release lock so this.stream.getReader().read() will terminate with done: true
|
|
80
|
+
this.writer.releaseLock();
|
|
81
|
+
|
|
82
|
+
// we only close the writable stream after done
|
|
83
|
+
try {
|
|
84
|
+
await this.transform.writable.close();
|
|
85
|
+
// NOTE: we do not cancel this.transform.readable as there might be access to
|
|
86
|
+
// this.transform.readable.getReader() outside that blocks this cancellation
|
|
87
|
+
// hence, user is responsible for canceling reader on their own
|
|
88
|
+
} catch (e) {
|
|
89
|
+
// ignore TypeError: Invalid state: WritableStream is closed
|
|
90
|
+
// in case stream reader is already closed, this will throw
|
|
91
|
+
// but we ignore it as we are closing the stream anyway
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Detach the source stream and clean up resources.
|
|
98
|
+
*/
|
|
99
|
+
async detachSource() {
|
|
100
|
+
if (!this.isSourceSet) {
|
|
101
|
+
throw new Error('Source not set');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// release lock will make any pending read() throw TypeError
|
|
105
|
+
// which are expected, and we intentionally catch those error
|
|
106
|
+
// using isStreamReaderReleaseError
|
|
107
|
+
// this will unblock any pending read() inside the async for loop
|
|
108
|
+
this.sourceReader!.releaseLock();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { IdentityTransform } from './identity_transform.js';
|
|
6
|
+
|
|
7
|
+
describe('IdentityTransform', () => {
|
|
8
|
+
it('should handle stream with one value', async () => {
|
|
9
|
+
const transform = new IdentityTransform<string>();
|
|
10
|
+
const writer = transform.writable.getWriter();
|
|
11
|
+
const reader = transform.readable.getReader();
|
|
12
|
+
|
|
13
|
+
const inputValue = 'single value';
|
|
14
|
+
|
|
15
|
+
await writer.write(inputValue);
|
|
16
|
+
await writer.close();
|
|
17
|
+
|
|
18
|
+
const result = await reader.read();
|
|
19
|
+
expect(result.done).toBe(false);
|
|
20
|
+
expect(result.value).toBe(inputValue);
|
|
21
|
+
|
|
22
|
+
const nextResult = await reader.read();
|
|
23
|
+
expect(nextResult.done).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should handle multiple values in sequence', async () => {
|
|
27
|
+
const transform = new IdentityTransform<string>();
|
|
28
|
+
const writer = transform.writable.getWriter();
|
|
29
|
+
const reader = transform.readable.getReader();
|
|
30
|
+
|
|
31
|
+
const inputValues = ['first', 'second', 'third'];
|
|
32
|
+
|
|
33
|
+
// Write all values
|
|
34
|
+
for (const value of inputValues) {
|
|
35
|
+
await writer.write(value);
|
|
36
|
+
}
|
|
37
|
+
await writer.close();
|
|
38
|
+
|
|
39
|
+
// Read all values
|
|
40
|
+
const results: string[] = [];
|
|
41
|
+
let result = await reader.read();
|
|
42
|
+
while (!result.done) {
|
|
43
|
+
results.push(result.value);
|
|
44
|
+
result = await reader.read();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
expect(results).toEqual(inputValues);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should handle null and undefined values', async () => {
|
|
51
|
+
const transform = new IdentityTransform<string | null | undefined>();
|
|
52
|
+
const writer = transform.writable.getWriter();
|
|
53
|
+
const reader = transform.readable.getReader();
|
|
54
|
+
|
|
55
|
+
const inputValues = ['test', null, undefined, 'another'];
|
|
56
|
+
|
|
57
|
+
// Write all values
|
|
58
|
+
for (const value of inputValues) {
|
|
59
|
+
await writer.write(value);
|
|
60
|
+
}
|
|
61
|
+
await writer.close();
|
|
62
|
+
|
|
63
|
+
// Read all values
|
|
64
|
+
const results: (string | null | undefined)[] = [];
|
|
65
|
+
let result = await reader.read();
|
|
66
|
+
while (!result.done) {
|
|
67
|
+
results.push(result.value);
|
|
68
|
+
result = await reader.read();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
expect(results).toEqual(inputValues);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should handle arrays', async () => {
|
|
75
|
+
const transform = new IdentityTransform<number[]>();
|
|
76
|
+
const writer = transform.writable.getWriter();
|
|
77
|
+
const reader = transform.readable.getReader();
|
|
78
|
+
|
|
79
|
+
const inputValue = [1, 2, 3, 4, 5];
|
|
80
|
+
|
|
81
|
+
await writer.write(inputValue);
|
|
82
|
+
await writer.close();
|
|
83
|
+
|
|
84
|
+
const result = await reader.read();
|
|
85
|
+
|
|
86
|
+
expect(result.done).toBe(false);
|
|
87
|
+
expect(result.value).toEqual(inputValue);
|
|
88
|
+
expect(result.value).toBe(inputValue); // Should be the same reference
|
|
89
|
+
|
|
90
|
+
const nextResult = await reader.read();
|
|
91
|
+
expect(nextResult.done).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should work with streamed data', async () => {
|
|
95
|
+
const transform = new IdentityTransform<string>();
|
|
96
|
+
const writer = transform.writable.getWriter();
|
|
97
|
+
const reader = transform.readable.getReader();
|
|
98
|
+
|
|
99
|
+
const testData = ['chunk1', 'chunk2', 'chunk3'];
|
|
100
|
+
|
|
101
|
+
// Write data asynchronously to simulate streaming
|
|
102
|
+
const writePromise = (async () => {
|
|
103
|
+
for (const chunk of testData) {
|
|
104
|
+
await writer.write(chunk);
|
|
105
|
+
}
|
|
106
|
+
await writer.close();
|
|
107
|
+
})();
|
|
108
|
+
|
|
109
|
+
// Read data as it comes through
|
|
110
|
+
const results: string[] = [];
|
|
111
|
+
let result = await reader.read();
|
|
112
|
+
while (!result.done) {
|
|
113
|
+
results.push(result.value);
|
|
114
|
+
result = await reader.read();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
await writePromise;
|
|
118
|
+
expect(results).toEqual(testData);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should handle empty stream', async () => {
|
|
122
|
+
const transform = new IdentityTransform<string>();
|
|
123
|
+
const writer = transform.writable.getWriter();
|
|
124
|
+
const reader = transform.readable.getReader();
|
|
125
|
+
|
|
126
|
+
// Close immediately without writing anything
|
|
127
|
+
await writer.close();
|
|
128
|
+
|
|
129
|
+
// Should immediately be done
|
|
130
|
+
const result = await reader.read();
|
|
131
|
+
expect(result.done).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should handle writer closing while reading is in progress', async () => {
|
|
135
|
+
const transform = new IdentityTransform<string>();
|
|
136
|
+
const writer = transform.writable.getWriter();
|
|
137
|
+
const reader = transform.readable.getReader();
|
|
138
|
+
|
|
139
|
+
const testData = ['chunk1', 'chunk2', 'chunk3'];
|
|
140
|
+
const results: string[] = [];
|
|
141
|
+
|
|
142
|
+
// Start writing some data
|
|
143
|
+
await writer.write(testData[0]);
|
|
144
|
+
await writer.write(testData[1]);
|
|
145
|
+
|
|
146
|
+
// Start reading concurrently
|
|
147
|
+
const readPromise = (async () => {
|
|
148
|
+
let result = await reader.read();
|
|
149
|
+
while (!result.done) {
|
|
150
|
+
results.push(result.value);
|
|
151
|
+
result = await reader.read();
|
|
152
|
+
}
|
|
153
|
+
})();
|
|
154
|
+
|
|
155
|
+
// Write one more chunk and then close the writer while reading
|
|
156
|
+
await writer.write(testData[2]);
|
|
157
|
+
await writer.close();
|
|
158
|
+
|
|
159
|
+
// Wait for reading to complete
|
|
160
|
+
await readPromise;
|
|
161
|
+
|
|
162
|
+
// Should have received all the data
|
|
163
|
+
expect(results).toEqual(testData);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should handle a pending read when the writer is closed', async () => {
|
|
167
|
+
const transform = new IdentityTransform<string>();
|
|
168
|
+
const writer = transform.writable.getWriter();
|
|
169
|
+
const reader = transform.readable.getReader();
|
|
170
|
+
|
|
171
|
+
const readPromise = reader.read();
|
|
172
|
+
|
|
173
|
+
await writer.close();
|
|
174
|
+
|
|
175
|
+
const result = await readPromise;
|
|
176
|
+
expect(result.done).toBe(true);
|
|
177
|
+
expect(result.value).toBeUndefined();
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { TransformStream } from 'node:stream/web';
|
|
5
|
+
|
|
6
|
+
export class IdentityTransform<T> extends TransformStream<T, T> {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(
|
|
9
|
+
{
|
|
10
|
+
transform: (chunk, controller) => controller.enqueue(chunk),
|
|
11
|
+
},
|
|
12
|
+
// By default the transfor stream will buffer only one chunk at a time.
|
|
13
|
+
// In order to follow the python agents channel.py, we set set the capaciy to be effectively infinite.
|
|
14
|
+
{ highWaterMark: Number.MAX_SAFE_INTEGER },
|
|
15
|
+
{ highWaterMark: Number.MAX_SAFE_INTEGER },
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
export { DeferredReadableStream } from './deferred_stream.js';
|
|
5
|
+
export { IdentityTransform } from './identity_transform.js';
|
|
6
|
+
export { mergeReadableStreams } from './merge_readable_streams.js';
|
|
7
|
+
export { createStreamChannel, type StreamChannel } from './stream_channel.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { ReadableStream } from 'node:stream/web';
|
|
5
|
+
import { withResolvers } from '../utils.js';
|
|
6
|
+
|
|
7
|
+
// Adapted from https://github.com/denoland/std/blob/main/streams/merge_readable_streams.ts
|
|
8
|
+
// we manually adapted to make ReadableStream<T> typing compatible with our current node
|
|
9
|
+
// version as well as typescript configuration
|
|
10
|
+
export function mergeReadableStreams<T>(...streams: ReadableStream<T>[]): ReadableStream<T> {
|
|
11
|
+
const resolvePromises = streams.map(() => withResolvers<void>());
|
|
12
|
+
return new ReadableStream<T>({
|
|
13
|
+
start(controller) {
|
|
14
|
+
let mustClose = false;
|
|
15
|
+
Promise.all(resolvePromises.map(({ promise }) => promise))
|
|
16
|
+
.then(() => {
|
|
17
|
+
controller.close();
|
|
18
|
+
})
|
|
19
|
+
.catch((error) => {
|
|
20
|
+
mustClose = true;
|
|
21
|
+
controller.error(error);
|
|
22
|
+
});
|
|
23
|
+
for (const [index, stream] of streams.entries()) {
|
|
24
|
+
(async () => {
|
|
25
|
+
try {
|
|
26
|
+
for await (const data of stream) {
|
|
27
|
+
if (mustClose) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
controller.enqueue(data);
|
|
31
|
+
}
|
|
32
|
+
resolvePromises[index]!.resolve();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
resolvePromises[index]!.reject(error);
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { createStreamChannel } from './stream_channel.js';
|
|
6
|
+
|
|
7
|
+
describe('StreamChannel', () => {
|
|
8
|
+
it('should write and read a single value', async () => {
|
|
9
|
+
const channel = createStreamChannel<string>();
|
|
10
|
+
const reader = channel.stream().getReader();
|
|
11
|
+
|
|
12
|
+
await channel.write('test value');
|
|
13
|
+
await channel.close();
|
|
14
|
+
|
|
15
|
+
const result = await reader.read();
|
|
16
|
+
expect(result.done).toBe(false);
|
|
17
|
+
expect(result.value).toBe('test value');
|
|
18
|
+
|
|
19
|
+
const nextResult = await reader.read();
|
|
20
|
+
expect(nextResult.done).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should write and read multiple values in sequence', async () => {
|
|
24
|
+
const channel = createStreamChannel<string>();
|
|
25
|
+
const reader = channel.stream().getReader();
|
|
26
|
+
|
|
27
|
+
const testValues = ['first', 'second', 'third'];
|
|
28
|
+
|
|
29
|
+
for (const value of testValues) {
|
|
30
|
+
await channel.write(value);
|
|
31
|
+
}
|
|
32
|
+
await channel.close();
|
|
33
|
+
|
|
34
|
+
const results: string[] = [];
|
|
35
|
+
let result = await reader.read();
|
|
36
|
+
while (!result.done) {
|
|
37
|
+
results.push(result.value);
|
|
38
|
+
result = await reader.read();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
expect(results).toEqual(testValues);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should handle arrays', async () => {
|
|
45
|
+
const channel = createStreamChannel<number[]>();
|
|
46
|
+
const reader = channel.stream().getReader();
|
|
47
|
+
|
|
48
|
+
const testArray = [1, 2, 3, 4, 5];
|
|
49
|
+
await channel.write(testArray);
|
|
50
|
+
await channel.close();
|
|
51
|
+
|
|
52
|
+
const result = await reader.read();
|
|
53
|
+
expect(result.value).toEqual(testArray);
|
|
54
|
+
expect(result.value).toBe(testArray);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should work with concurrent writing and reading', async () => {
|
|
58
|
+
const channel = createStreamChannel<string>();
|
|
59
|
+
const reader = channel.stream().getReader();
|
|
60
|
+
|
|
61
|
+
const testData = ['chunk1', 'chunk2', 'chunk3'];
|
|
62
|
+
const results: string[] = [];
|
|
63
|
+
|
|
64
|
+
const readPromise = (async () => {
|
|
65
|
+
let result = await reader.read();
|
|
66
|
+
while (!result.done) {
|
|
67
|
+
results.push(result.value);
|
|
68
|
+
result = await reader.read();
|
|
69
|
+
}
|
|
70
|
+
})();
|
|
71
|
+
|
|
72
|
+
for (const chunk of testData) {
|
|
73
|
+
await channel.write(chunk);
|
|
74
|
+
}
|
|
75
|
+
await channel.close();
|
|
76
|
+
|
|
77
|
+
await readPromise;
|
|
78
|
+
expect(results).toEqual(testData);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should handle empty stream', async () => {
|
|
82
|
+
const channel = createStreamChannel<string>();
|
|
83
|
+
const reader = channel.stream().getReader();
|
|
84
|
+
|
|
85
|
+
await channel.close();
|
|
86
|
+
|
|
87
|
+
const result = await reader.read();
|
|
88
|
+
expect(result.done).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should handle non-awaited sequential writes', async () => {
|
|
92
|
+
const channel = createStreamChannel<number>();
|
|
93
|
+
const reader = channel.stream().getReader();
|
|
94
|
+
|
|
95
|
+
const testNumbers = Array.from({ length: 100 }, (_, i) => i);
|
|
96
|
+
|
|
97
|
+
for (const num of testNumbers) {
|
|
98
|
+
channel.write(num);
|
|
99
|
+
}
|
|
100
|
+
channel.close();
|
|
101
|
+
|
|
102
|
+
const results: number[] = [];
|
|
103
|
+
let result = await reader.read();
|
|
104
|
+
while (!result.done) {
|
|
105
|
+
results.push(result.value);
|
|
106
|
+
result = await reader.read();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
expect(results).toEqual(testNumbers);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should handle double closing without error', async () => {
|
|
113
|
+
const channel = createStreamChannel<string>();
|
|
114
|
+
const reader = channel.stream().getReader();
|
|
115
|
+
|
|
116
|
+
await channel.write('test');
|
|
117
|
+
|
|
118
|
+
await channel.close();
|
|
119
|
+
// Close again - should not throw
|
|
120
|
+
await expect(channel.close()).resolves.toBeUndefined();
|
|
121
|
+
|
|
122
|
+
const result = await reader.read();
|
|
123
|
+
expect(result.done).toBe(false);
|
|
124
|
+
expect(result.value).toBe('test');
|
|
125
|
+
|
|
126
|
+
const nextResult = await reader.read();
|
|
127
|
+
expect(nextResult.done).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import type { ReadableStream } from 'node:stream/web';
|
|
5
|
+
import { IdentityTransform } from './identity_transform.js';
|
|
6
|
+
|
|
7
|
+
export interface StreamChannel<T> {
|
|
8
|
+
write(chunk: T): Promise<void>;
|
|
9
|
+
close(): Promise<void>;
|
|
10
|
+
stream(): ReadableStream<T>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createStreamChannel<T>(): StreamChannel<T> {
|
|
14
|
+
const transform = new IdentityTransform<T>();
|
|
15
|
+
const writer = transform.writable.getWriter();
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
write: (chunk: T) => writer.write(chunk),
|
|
19
|
+
stream: () => transform.readable,
|
|
20
|
+
close: async () => {
|
|
21
|
+
try {
|
|
22
|
+
return await writer.close();
|
|
23
|
+
} catch (e) {
|
|
24
|
+
if (e instanceof Error && e.name === 'TypeError') {
|
|
25
|
+
// Ignore error if the stream is already closed
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -19,8 +19,8 @@ export class StreamAdapter extends STT {
|
|
|
19
19
|
this.#vad = vad;
|
|
20
20
|
this.label = `stt.StreamAdapter<${this.#stt.label}>`;
|
|
21
21
|
|
|
22
|
-
this.#stt.on(
|
|
23
|
-
this.emit(
|
|
22
|
+
this.#stt.on('metrics_collected', (metrics) => {
|
|
23
|
+
this.emit('metrics_collected', metrics);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -43,15 +43,13 @@ export class StreamAdapterWrapper extends SpeechStream {
|
|
|
43
43
|
this.#stt = stt;
|
|
44
44
|
this.#vadStream = vad.stream();
|
|
45
45
|
this.label = `stt.StreamAdapterWrapper<${this.#stt.label}>`;
|
|
46
|
-
|
|
47
|
-
this.#run();
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
async monitorMetrics() {
|
|
51
49
|
return; // do nothing
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
async
|
|
52
|
+
protected async run() {
|
|
55
53
|
const forwardInput = async () => {
|
|
56
54
|
for await (const input of this.input) {
|
|
57
55
|
if (input === SpeechStream.FLUSH_SENTINEL) {
|