Python 3.14 Support & Python 3.9 Dropped
This release adds Python 3.14 support and drops Python 3.9. The minimum supported version is now Python 3.10.
Tool Improvements
Tools and toolsets now have stable unique IDs, making it possible to reference and filter tools programmatically. Changes to agent configuration (instructions, tools) are now tracked in conversation history via AgentConfigUpdate.
LLMStream.collect() API
A new LLMStream.collect() API makes it significantly easier to use LLMs outside of AgentSession. You can now call an LLM, collect the full response, and execute tool calls with a straightforward API — useful for background tasks, pre-processing, or any workflow where you need LLM capabilities without the full voice agent pipeline.
from livekit.agents import llm
response = await my_llm.chat(chat_ctx=ctx, tools=tools).collect()
for tc in response.tool_calls:
result = await llm.execute_function_call(tc, tool_ctx)
ctx.insert(result.fnc_call)
if result.fnc_call_out:
ctx.insert(result.fnc_call_out)Manual Turn Detection for Realtime Models
Realtime models now support commit_user_turn, enabling turn_detection="manual" mode. This gives you full control over when user turns are committed — useful for push-to-talk interfaces or scenarios where automatic VAD-based turn detection isn't ideal.
@ctx.room.local_participant.register_rpc_method("end_turn")
async def end_turn(data: rtc.RpcInvocationData):
session.input.set_audio_enabled(False)
session.commit_user_turn(
transcript_timeout=10.0,
stt_flush_duration=2.0,
)Job Migration on Reconnection
When the agent server temporarily loses connection and reconnects, active jobs are now automatically migrated rather than being dropped. This significantly improves reliability during transient network issues.
False Interruption Fix
Fixed a bug where late end-of-speech events could trigger duplicate false interruption timers, causing the agent to incorrectly stop speaking. The agent now properly deduplicates these events and tracks STT completion state more reliably.
New Providers & Plugins
- xAI Responses LLM — Use xAI's Responses API via
xai.responses.LLM() - Azure OpenAI Responses — Azure-hosted Responses API via
azure.responses.LLM(), with support for deployments and Azure auth - Camb.ai TTS — New TTS plugin powered by the MARS model family (mars-flash, mars-pro, mars-instruct), with voice selection, language control, and style instructions
- Avatario Avatar — Virtual avatar plugin with session management and API client
What's Changed
- feat(azure/stt): TrueText post processing option added to STTOptions by @rafallezanko in #4557
- chore(README): remove STT and LLM API key configuration from LemonSlice example as not needed. by @codeSTACKr in #4589
- fix: Add thread-safe initialization to _DefaultLoadCalc singleton by @darshankparmar in #4585
- add missing plugins to dependencies by @tinalenguyen in #4593
- _setup_cloud_tracer still overrides TracerProviders due to checking the wrong base class by @hudson-worden in #4584
- fix(google): add thought_signature support for Gemini 2.5 models by @gdoermann in #4595
- remove shortcut inference STT model name by @longcw in #4594
- Increase read_bufsize in minimax tts plugin by @jose-speak in #4590
- refactor(rtzr): FlushSentinel-based segment control and type safety improvements by @kimdwkimdw in #4565
- improve EndCallTool by @longcw in #4563
- Fix: Add 'required' field to function_tool schema for Groq compatibility by @VinayJogani14 in #4613
- fix: avoid modifying original raw tool description by @davidzhao in #4616
- continue instead of return in InferenceProcExecutor loop by @chenghao-mou in #4612
- add xai responses llm by @tinalenguyen in #4618
- move xAI tools to separate file by @tinalenguyen in #4624
- (xAI): backward compatibility for tools by @tinalenguyen in #4625
- update inference models to match the latest by @davidzhao in #4597
- AssemblyAI added EU streaming endpoint option by @ftsef in #4571
- feat: Add Camb.ai TTS plugin by @eRuaro in #4442
- prevent duplicate false interruption due to late end of speech by @chenghao-mou in #4621
- feat: add customization bithuman gpu avatar endpoint handling by @CathyL0 in #4390
- plugin/liveavatar implement sandbox on liveavatar by @arthurnumen in #4635
- add asyncai to pyproject by @tinalenguyen in #4636
- feat: avatario avatar plugin by @Saksham209 in #4114
- add azure openai responses by @tinalenguyen in #4619
- (openai realtime): add truncation param by @tinalenguyen in #4642
- fix: 11Labs Scribe v2 model not working with EOT prediction model by @Ludobaka in #4601
- (taskgroup): support on_complete callback functions by @tinalenguyen in #4628
- add
idto tools by @theomonnom in #4653 - allow 499 retry by @chenghao-mou in #4637
- AGT-2474: add commit user turn support for realtime models by @chenghao-mou in #4622
- fix(liveavatar): emit playback_finished on AudioSegmentEnd by @MSameerAbbas in #4669
- add
AgentConfigUpdate& initial judges by @theomonnom in #4547 - fix tests & ruff by @theomonnom in #4672
- (minimax): add language boost param by @tinalenguyen in #4667
- remove accidentally committed files by @theomonnom in #4673
- fix duplicated openai realtime remote content by @longcw in #4657
- use text streams & custom rpc logic by @theomonnom in #4677
- remove chat_ctx size limit by @theomonnom in #4678
- clean up metrics export from traces by @davidzhao in #4679
LLMStream.collectAPI & external easier tool executions by @theomonnom in #4680- update openai responses default model by @tinalenguyen in #4681
- fix(google): improve error message for model/API mismatch in Realtime API by @cdutr in #4611
- fix keyterm in Deepgram by @chenghao-mou in #4684
- Expose ws close code and error messages by @chenghao-mou in #4683
- fix: improve handling of 499 status code by @davidzhao in #4685
- support wrapped tools with a warning message by @longcw in #4674
- fix(transcription): prevent stale synchronizer impls (#4486) by @furious-luke in #4686
- Add rtzr plugin to optional dependencies by @zach-iee in #4631
- feat(langgraph): add custom stream mode support in LangChain LLMAdapter by @keenranger in #4511
- Add room deletion timeout and cancellation by @chenghao-mou in #4638
- add TaskCompletedEvent import by @tinalenguyen in #4688
- prevent tool cancellation when AgentTask is called inside it by @longcw in #4586
- fix gemini live tool execution interrupted by generation_complete event by @longcw in #4699
- add STT usage for google by @chenghao-mou in #4599
- fix: commit user turn with STT and realtime by @chenghao-mou in #4663
- add exclude_config_update to ChatContext copy by @longcw in #4700
- add require_confirmation param for built-in tasks by @tinalenguyen in #4698
- Fix wrong "timestamp" parameter in livekit-plugins-spitch stt.py by @pabloFuente in #4702
- Update readme and examples to use deepgram nova-3 by @bcherry in #4697
- set exclude_config_update by @longcw in #4709
- Restore Python 3.14 support by updating livekit-blingfire to 1.1 by @Abivarman123 in #4710
- add ChatContext.messages() by @theomonnom in #4712
- migrate jobs on reconnection by @theomonnom in #4711
- use ChatMessage.messages() where applicable by @theomonnom in #4713
- chore(docs): ditch the v0 docs and promote v1 docs to main path by @rektdeckard in #4695
- filter tools by id by @tinalenguyen in #4723
- support python 3.14 by @theomonnom in #4727
- Fix: Added stt lang parsing and tts voice parsing to the constructors by @adrian-cowham in #4726
- fix (liveavatar): restore interruption handling and track avatar speaking state by @tinalenguyen in #4725
- update padding warning message and silence subsequent ones by @chenghao-mou in #4733
- fix: Add default google tts model selection for backward compatibility by @chenghao-mou in #4731
- fix uv lock file & drop python 3.9 support & upgrade dependencies by @theomonnom in #4728
- automatically close openai client by @theomonnom in #4735
- update gitignore by @theomonnom in #4737
- fix speaking_rate inference by @theomonnom in #4738
- livekit-agents 1.4.0 by @theomonnom in #4739
New Contributors
- @codeSTACKr made their first contribution in #4589
- @hudson-worden made their first contribution in #4584
- @gdoermann made their first contribution in #4595
- @jose-speak made their first contribution in #4590
- @VinayJogani14 made their first contribution in #4613
- @ftsef made their first contribution in #4571
- @eRuaro made their first contribution in #4442
- @arthurnumen made their first contribution in #4635
- @Saksham209 made their first contribution in #4114
- @Ludobaka made their first contribution in #4601
- @cdutr made their first contribution in #4611
- @keenranger made their first contribution in #4511
- @Abivarman123 made their first contribution in #4710
Full Changelog: https://github.com/livekit/agents/compare/livekit-agents@1.3.12...livekit-agents@1.4.0