Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
b736575
fix(core): clean up variables when committing a user turn manually (#…
chenghao-mou May 8, 2026
05e0858
(deepgram stt): add redact param (#5692)
tinalenguyen May 8, 2026
617228e
fix(agents): persist _speech_start_time across intra-turn VAD bursts …
AlessandroElyos May 9, 2026
9255c91
fix: pass API key via header in Neuphonic and Murf WebSocket TTS (#5691)
u9g May 10, 2026
ff7a393
fix(core): make default user span time explicit (#5699)
chenghao-mou May 11, 2026
2de7aa0
require CanManageAgentSession grant for remote session (#5487)
theomonnom May 11, 2026
8bc32ad
test(examples/survey): add TaskGroup testing reference (DOCS-1225) (#…
kath0la May 12, 2026
4bb4696
fix(anthropic): raise default httpx read timeout for streaming; add c…
SuperMarioYL May 12, 2026
e260ac8
fix(examples): consistent CSV schema in survey_agent (#5689)
u9g May 12, 2026
6aa92d3
Adding fine-grained VAD params to Sarvam saaras:v3 STT plugin (#5563)
dhruvladia-sarvam May 12, 2026
59abab4
Update codec config, MIME mapping, and interruption handling (#5561)
dhruvladia-sarvam May 12, 2026
689314e
(gradium): update endpoint (#5722)
tinalenguyen May 12, 2026
66725a8
Revert "require CanManageAgentSession grant for remote session (#5487…
chenghao-mou May 12, 2026
7b2b57e
feat(gemini llm): add media resolution option to LLM and RealtimeMode…
csanz91 May 13, 2026
51be60e
(inworld tts): add language param (#5723)
tinalenguyen May 13, 2026
b01a645
fix(core): surface real http_context error from STT streams (#5709)
longcw May 13, 2026
b8b8bac
docs: clarify function tools executed event pairing (#5701)
nightcityblade May 13, 2026
e06a544
feat(workflows): expose dtmf and ringing_timeout on WarmTransferTask …
a-gasior May 13, 2026
3078382
fix(agents): await realtime auto tool reply in RunResult (#5702)
longcw May 13, 2026
e2e0fe9
chore(amd): update default models and default behavior (#5713)
chenghao-mou May 13, 2026
763d6f5
Add Perplexity LLM plugin (#5610)
jliounis May 13, 2026
37131a3
fix: raise on unexpected ElevenLabs websocket close (#5729)
nightcityblade May 13, 2026
3c488cf
fix(agents): clear pending auto tool reply future on timeout (#5725)
u9g May 13, 2026
95c4640
(azure + perplexity): bump versions (#5731)
tinalenguyen May 13, 2026
4d6835e
fix: do not republish tracks on reconnect (#5698)
davidzhao May 13, 2026
b5c33cc
chore(amd): add default amd prediction log (#5732)
chenghao-mou May 13, 2026
65c686d
feat(rime): add WebSocket streaming TTS support (#5663)
mcullan May 13, 2026
ef9d8fb
livekit-agents@1.5.9 (#5733)
github-actions[bot] May 13, 2026
e4f0c58
fix: surface Deepgram TTS websocket errors (#5728)
nightcityblade May 14, 2026
09ca0cd
fix(voice): cancel realtime generation when speech is interrupted (#5…
longcw May 14, 2026
461a934
improve should_discard check (#5676)
chenghao-mou May 14, 2026
ccc5896
(examples revamp): add example walkthroughs (#5613)
tinalenguyen May 14, 2026
66fda6a
chore(deps): update dependency langchain-core to v1.3.3 [security] (#…
renovate[bot] May 14, 2026
78a0b84
(inference stt): add speechmatics (#5740)
tinalenguyen May 14, 2026
b285573
fix(ipc): run shutdown callbacks when entrypoint raises (#5741)
longcw May 15, 2026
d3ea8ed
fix(dep): pin bithuman (#5743)
chenghao-mou May 15, 2026
9077c24
fix(barge-in): suppress session-level barge-in errors (#5727)
chenghao-mou May 15, 2026
75e4a37
feat: support python -m livekit.agents.download for asset fetching (#…
davidzhao May 16, 2026
a23d923
feat(rime): add coda model support (#5748)
MaCaki May 17, 2026
a3df48f
(speechmatics + inference): add VAD (#5750)
tinalenguyen May 18, 2026
7675da6
inference.LLM: add update_options for live model swaps (#5757)
theomonnom May 18, 2026
89e9a9d
fix(deepgram): add per-message recv timeout to TTS WebSocket (#5756)
longcw May 18, 2026
7bb6f22
livekit-agents@1.5.10 (#5758)
github-actions[bot] May 18, 2026
c063e85
feat(examples): publish examples manifest to agents-jukebox (#5751)
theomonnom May 18, 2026
3c6197f
deploy-examples: open a PR (with auto-merge) for the manifest refresh…
theomonnom May 18, 2026
666eac5
frontdesk: fix tz crash on deploy + survive failed startup (#5761)
theomonnom May 18, 2026
df18648
deploy-examples: fix manifest publishing (\u escapes + --force push) …
theomonnom May 18, 2026
ac70d19
chore(deps): update actions/setup-python action to v6 (#5759)
renovate[bot] May 18, 2026
d687d94
deprecate mcp_servers param on Agent and AgentSession (#5667)
longcw May 18, 2026
c4daef3
feat(voice): add UserTurnLimitOptions to interrupt long user speech (…
longcw May 18, 2026
391c08f
feat(avatar): add AvatarMetrics for join latency and playback latency…
longcw May 18, 2026
22030f0
docs(inference): fix stale RPC method names and LLM swap description …
detail-app[bot] May 18, 2026
c611eea
(speechmatics stt): update default mode to external (#5765)
tinalenguyen May 18, 2026
13cc998
docs: fix misquoted greeting punctuation in frontdesk README (#5746)
detail-app[bot] May 18, 2026
ae4df8d
fix(cerebras): require openai>=2.16.0 for FinalRequestOptions.content…
u9g May 19, 2026
955a7fc
livekit-agents@1.5.11 (#5774)
github-actions[bot] May 19, 2026
7366c2b
fix(soniox): plugin reliability fixes (#5770)
mihafabcic-soniox May 19, 2026
2a01968
(gemini): add gemini-3.5-flash model str (#5775)
tinalenguyen May 19, 2026
b4781c8
Add Perplexity Agent API (Responses) LLM (#5772)
jliounis May 19, 2026
22d41a4
examples(inference): editable system prompt + "Open in Builder" + Son…
JackNDwyer May 19, 2026
187433c
feat(realtime): support multi-message generation per response (#5763)
longcw May 20, 2026
e2df0d7
feat(openai stt): support gpt-realtime-whisper (#5779)
longcw May 20, 2026
80e284a
feat(rime): add time_scale_factor parameter for arcana, mistv3, and c…
MaCaki May 20, 2026
a155b73
(perplexity responses): update default model (#5780)
tinalenguyen May 20, 2026
ad1c684
fix(interruption): incorrect guard skips true interruptions (#5787)
chenghao-mou May 20, 2026
22e24c2
docs(perplexity): fix stale default model in responses.LLM example (#…
detail-app[bot] May 21, 2026
0c094ad
add new bulbul:v3 speaker voices (#5782)
amlesh-dev May 21, 2026
2992996
livekit-agents@1.5.12 (#5789)
github-actions[bot] May 21, 2026
a245c80
(openai realtime): add gpt-realtime-2 model str (#5791)
tinalenguyen May 21, 2026
5826309
(healthcare example): remove filesearch and pdf (#5795)
tinalenguyen May 21, 2026
d5feb9d
chore(worker): update worker warnings AGT-2909 (#5771)
chenghao-mou May 21, 2026
350e516
fix(voice): race between flush and clear_buffer on interrupt leaks un…
longcw May 21, 2026
f81f2f8
fix(vad): add support for vad reset directly without stream close (#5…
chenghao-mou May 21, 2026
09424f1
feat(inworld tts): add delivery_mode parameter for inworld-tts-2 (#5801)
chrisackermann May 21, 2026
6a2ff03
fix(voice): wait for end-of-turn task when waiting for user inactivit…
longcw May 22, 2026
1ecbc39
Adding GnaniAI STT plugin (#5769)
Gnani-AI-Mintlify May 22, 2026
5d53ac4
(gnani): fix py.typed and remove changesets (#5816)
tinalenguyen May 22, 2026
fcac691
fix(voice): propagate ChatMessage.interrupted through proto serialize…
toubatbrian May 23, 2026
546ace4
fix(anthropic): recreate stream on retry (#5820)
he-yufeng May 24, 2026
1445a44
fix(llm): convert per-turn instructions on the very first turn too (#…
theomonnom May 24, 2026
4a34632
feat(background_audio): add fade_in / fade_out to AudioConfig (#5832)
theomonnom May 25, 2026
cea762d
fix(plugins/sarvam): thread language_probability into SpeechData.conf…
hashirventhodi May 25, 2026
d9a9466
fix(lemonslice): bind avatar audio output before the upstream session…
theomonnom May 25, 2026
69a626f
feat(voice/avatar): kick avatar participant on aclose + wait_for_join…
theomonnom May 25, 2026
d872421
feat(examples): add LemonSlice avatar with switchable personas (#5834)
theomonnom May 25, 2026
0d92542
chore(playground): list frontdesk first (#5838)
theomonnom May 25, 2026
575cc0a
fix: 4xx errors should not be retryable (#5831)
davidzhao May 25, 2026
1912b67
livekit-agents@1.5.13 (#5835)
github-actions[bot] May 25, 2026
ace4856
feat(assemblyai): add continuous_partials and interruption_delay stre…
dlange-aai May 25, 2026
fb36062
ci(deploy-examples): include avatar in matrix + wire LEMONSLICE_API_K…
theomonnom May 25, 2026
c453974
docs: clarify MCP support bullet (#5822)
scosemicolon May 25, 2026
f6a5a00
fix(core): replace frame drop with silence frame AGT-2914 (#5815)
chenghao-mou May 25, 2026
1d2a25c
feat(plugins-soniox): surface per-run language segments end-to-end (#…
MSameerAbbas May 25, 2026
ebd3000
use stt timestamps as last speaking time (#5672)
chenghao-mou May 25, 2026
f011fb0
docs: fix Gemini model version in avatar example README (#5842)
detail-app[bot] May 25, 2026
8111744
handle leaked chat-template tokens in function call args (#5840)
davidzhao May 25, 2026
a38b233
fix(voice): restrict stt pipeline reuse to default stt_node (#5803)
longcw May 26, 2026
c03ed17
feat(google): integration for AI Platform LLMs (#5843)
davidzhao May 26, 2026
c22bade
fix: return function argument errors (ToolError) to LLM (#5846)
davidzhao May 26, 2026
ccdf2e0
refactor(llm): unified ToolError contract for tool arg validation (#5…
longcw May 26, 2026
541d844
feat(openai): stream input_audio_transcription delta events (#5859)
longcw May 27, 2026
7b7d131
fix(voice): block on_user_turn_exceeded during agent handoff (#5858)
longcw May 27, 2026
f9b68de
fix(voice): reset user turn tracker on clear_user_turn (#5857)
longcw May 27, 2026
9ec3373
fix(elevenlabs): always close TTS stream context on cancellation (#5845)
longcw May 27, 2026
1744afe
Update download-files deprecation message (#5781)
bcherry May 27, 2026
5879e35
fix(llm): preserve Field() constraints on function tool arguments (#5…
theomonnom May 27, 2026
ef60a1b
fix(soniox): surface STT server errors (#5864)
he-yufeng May 27, 2026
dbdf14f
Fix ElevenLabs websocket context id handling (#5813)
flynn-hamming May 27, 2026
6df4785
livekit-agents@1.5.14 (#5870)
github-actions[bot] May 27, 2026
e3e992f
(openai realtime): add status_details to incomplete response logs (#5…
tinalenguyen May 28, 2026
99d81a1
feat(cartesia): add ink-2 stt (#5827)
charlotte-zhuang May 28, 2026
ab6e8a1
fix(ipc): bound AgentSession.aclose() during job shutdown (#5875)
longcw May 29, 2026
204e70a
fix(amd): defer no-speech timer until SIP call is answered (#5848)
chenghao-mou May 29, 2026
c64f75a
chore(tests): update tests to use Inference whenever possible AGT-230…
chenghao-mou May 29, 2026
e76344d
fix(llm): sort function tools to make order an invariant (#5884)
u9g May 29, 2026
a10a34e
fix(deps): relax bithuman pin to <3 for SDK 2.x compatibility (#5882)
sgu-bithuman May 29, 2026
ceba456
fix(aws): flatten tool blocks when toolConfig is omitted (#5850)
u9g May 29, 2026
6d50c5d
fix(llm): serialize all provider tools for the Responses API + log se…
u9g May 29, 2026
b903849
fix(llm): make to_responses_fnc_ctx.provider_tool_type optional (#5892)
toubatbrian May 29, 2026
983f0ab
internal(voice): wire DebugMessage over remote-session wire (#5855)
toubatbrian May 29, 2026
5c256ad
Add respeecher tts plugin (#3233)
mitrushchienkova May 29, 2026
2fcbb62
feat(plugins-google): add cached_content option for explicit context …
kamil-bidus May 29, 2026
5319009
(google llm): ruff and add cache warnings (#5893)
tinalenguyen May 29, 2026
d0b8d81
feat(smallestai): update TTS plugin for Lightning v3.1 Pro and WebSoc…
harshitajain165 May 29, 2026
fd32911
fix(openai realtime): honor OPENAI_BASE_URL env var fallback (#5895)
chenghao-mou May 29, 2026
1dcdb94
livekit-agents@1.5.15 (#5896)
github-actions[bot] May 29, 2026
b1058ce
feat(gradium STT): add language option to gradium.STT (#5878)
FLoppix May 29, 2026
e26ac12
fix(workflows): bind GetDtmfTask user-state handler to user_state_cha…
u9g May 30, 2026
4241c47
fix(examples): check anam_avatar_id in ANAM_AVATAR_ID guard (#5901)
u9g May 30, 2026
49f8d96
test(openai realtime): fix process_base_url assertion that was always…
u9g May 30, 2026
2de09f9
fix(examples): raise ToolError instead of returning it in realtime_jo…
u9g May 30, 2026
c6a678d
docs(readme): fix syntax errors in StoryAgent and test snippets (#5905)
u9g May 30, 2026
84f9144
feat(voice): add AgentSession.claim_user_turn (#5806)
longcw Jun 1, 2026
cb99ab2
make claim_user_turn private (#5911)
longcw Jun 1, 2026
d008e67
fix(ipc): retry proc acquisition when all in-flight spawns fail (#5874)
longcw Jun 1, 2026
f759c2a
feat(inference): update model literals for LLM, STT, and TTS, adding …
russellmartin-livekit Jun 1, 2026
064c6a5
feat(worker): send deployment environment in worker registration (#5920)
theomonnom Jun 1, 2026
23aea13
Dispatch downstream version bumps on stable publish (#5817)
Topherhindman Jun 1, 2026
ddb1a20
livekit-agents@1.5.16 (#5922)
github-actions[bot] Jun 1, 2026
982ae50
fix(job): close RecorderIO at session end if session close was interr…
longcw Jun 2, 2026
c126741
fix(recorder): prevent close hang and fix corrupt frame splits (#5926)
chenghao-mou Jun 2, 2026
48e1ccb
feat(examples/avatar): added animation triggers and trimmed personas …
brycedli Jun 2, 2026
0d7f553
fix examples deploy (#5939)
tinalenguyen Jun 2, 2026
9494c2f
revert alphabetized tool ordering (#5941)
tinalenguyen Jun 2, 2026
14bdf4d
fix(amd): start listening on lost publisher, forward realtime transcr…
chenghao-mou Jun 2, 2026
96e199c
feat(inference): Add agent ID header to inference requests (#5937)
adrian-cowham Jun 2, 2026
6f6d007
feat(worker): add WORKER_PROTOCOL_VERSION and return WorkerInfo from …
theomonnom Jun 2, 2026
7515a6f
fix(inference): don't leak mock participant sid into request headers …
adrian-cowham Jun 2, 2026
f43c040
(speechmatics): remove hard coded confidence (#5942)
tinalenguyen Jun 2, 2026
22c884f
(openai realtime): add reasoning param (#5944)
tinalenguyen Jun 2, 2026
5f029b9
fix(inference): guard agent sid header against unconnected room (#5947)
adrian-cowham Jun 3, 2026
04567b9
livekit-agents@1.5.17 (#5949)
github-actions[bot] Jun 3, 2026
daeacfe
test: categorize tests and select via `pytest --unit`/`--plugin opena…
Bobronium Jun 3, 2026
523492d
hamming plugin: add customer_metadata, external_links, and session_mo…
sumanyu Jun 3, 2026
7ce37f0
fix(job): log unhandled exceptions in fire-and-forget tasks (#5961)
theomonnom Jun 3, 2026
b99f3d4
ci(deploy-examples): drop manifest publishing job (#5963)
theomonnom Jun 4, 2026
5c0a3c1
ci(deploy-examples): deploy from the dispatched branch instead of har…
theomonnom Jun 4, 2026
2814436
feat(voice): flush audio and text output per FlushSentinel (#5956)
longcw Jun 4, 2026
3bc0a5c
add ctx.with_filler() for acoustic fillers during long tools (#5885)
longcw Jun 4, 2026
0b68f96
first-class async tools via ctx.update() (#5841)
longcw Jun 4, 2026
d0e7c5b
Deploy examples against the deployed git ref instead of PyPI (#5969)
theomonnom Jun 4, 2026
a713c37
feat(job): expose single_peer_connection in JobContext.connect (#5966)
renal128 Jun 4, 2026
2f55ff7
docs: add filler_agent.py to examples README table of contents (#5967)
detail-app[bot] Jun 4, 2026
7037a05
docs: update test commands to use pytest category flags (#5958)
detail-app[bot] Jun 4, 2026
a3829d3
Enable git-lfs in example images so git-installed deps get real LFS b…
theomonnom Jun 4, 2026
1c4bfa4
fix(ipc): rate-limit and contextualize high-memory warnings (#5962)
Bobronium Jun 4, 2026
8548325
(examples deploy): fix lfs (#5973)
tinalenguyen Jun 4, 2026
0c5f4bf
(openai responses): surface phase field (#5975)
tinalenguyen Jun 5, 2026
f5d0e38
fix(openai): skip empty messages in realtime chat updates (#5952)
nightcityblade Jun 5, 2026
4a475ab
fix quick reconnect participant keyerror (#5979)
tinalenguyen Jun 5, 2026
afa2203
livekit-agents@1.5.18 (#5981)
github-actions[bot] Jun 5, 2026
7ecc6c0
fix(google): require compatible google-genai version (#5988)
nightcityblade Jun 6, 2026
a7212bc
Hotel Receptionist example (#5983)
theomonnom Jun 7, 2026
78597d0
feat(simulation): scenario yaml + on_simulation_end verdict override
theomonnom Jun 7, 2026
c08004f
Merge branch 'main' into theo/1.6.0-v2
theomonnom Jun 7, 2026
00fb125
simulation: 60s finalize timeout
theomonnom Jun 7, 2026
91330b9
simulation: rename SimulationFinalize -> FinalizeSimulation
theomonnom Jun 7, 2026
dd5098b
simulation: veto-only SimulationVerdict, hotel benchmark grading
theomonnom Jun 8, 2026
d913d82
fix(openai): handle string realtime status details (#5994)
he-yufeng Jun 8, 2026
35819bb
Merge remote-tracking branch 'origin/main' into theo/simulation-1.6.0-v2
theomonnom Jun 8, 2026
3463a56
cli: keep rich CLI as run_app (deprecated), add thin CLI to __main__
theomonnom Jun 8, 2026
50471d6
fix: resolve bad-merge artifacts and CI blockers from main merge
theomonnom Jun 8, 2026
16e83c6
testing: add fake_job_context for running an agent in-process
theomonnom Jun 8, 2026
6e3e3aa
fix(tests): repair branch-only RemoteSession / run-input tests
theomonnom Jun 8, 2026
03dd534
fix(voice): propagate LLM inference errors to RunResult / session.run()
theomonnom Jun 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 0 additions & 6 deletions .github/next-release/changeset-9584d6ff.md

This file was deleted.

5 changes: 0 additions & 5 deletions .github/next-release/changeset-filter-markdown-punctuation.md

This file was deleted.

6 changes: 0 additions & 6 deletions .github/next-release/changeset-gpt-5-4-mini.md

This file was deleted.

6 changes: 0 additions & 6 deletions .github/next-release/changeset-service-tier-response.md

This file was deleted.

12 changes: 12 additions & 0 deletions .github/next-release/changeset-soniox-target-segments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"livekit-agents": patch
"livekit-plugins-soniox": patch
---

Surface per-run language segments end-to-end in the Soniox STT plugin, fixing two symmetric symptoms of the same underlying bug where `_TokenAccumulator._lang_segments` was computed but discarded in `send_endpoint_transcript` (and in the interim path). Both fixes live in the same block.

- Add `target_languages` and `target_texts` to `stt.SpeechData`, mirroring the existing `source_languages` / `source_texts` source-side fields.
- In translation mode, the Soniox plugin now populates `target_*` on `FINAL_TRANSCRIPT` and `INTERIM_TRANSCRIPT` / `PREFLIGHT_TRANSCRIPT` events, exposing per-run target-language breakdowns for code-switched two-way translation (e.g. `target_languages=["en", "es"]` / `target_texts=["Hello, how are you?", " Estoy bien, gracias."]` for the translation of `"Hello, ¿cómo estás? I'm doing fine, gracias."`).
- In non-translation mode, the plugin now populates `source_languages` / `source_texts` from the same accumulator (previously these were left `None`, making code-switched dictation look monolingual to consumers). For a Japanese-then-English utterance, consumers now see `source_languages=["ja", "en"]` instead of `None`.

`SpeechData.text` and `SpeechData.language` are unchanged for back-compat (still the full concatenation and the first translated/detected language, respectively). Fixes #5685.
106 changes: 98 additions & 8 deletions .github/workflows/deploy-examples.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
name: Deploy Examples

on:
# Manual runs deploy from the branch picked in the Actions "Use workflow
# from" selector — no input needed.
workflow_dispatch:
inputs:
ref:
description: "Branch or ref to deploy from (default: main)"
type: string
required: false
default: "main"
# Called by publish.yml after a release to deploy the published commit.
workflow_call:
inputs:
ref:
description: "Commit/branch/tag to deploy. Defaults to the triggering ref."
type: string
required: false

Expand All @@ -24,11 +22,18 @@ jobs:
strategy:
fail-fast: false
matrix:
example: [healthcare, survey, frontdesk, drive-thru]
example: [healthcare, survey, frontdesk, drive-thru, inference, avatar]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ inputs.ref || 'main' }}
ref: ${{ inputs.ref || github.ref }}
# Fetch Git-LFS assets (e.g. examples/drive-thru/bg_noise.mp3) so the
# real binaries — not pointer files — get uploaded as the build context
# and copied into the image via `COPY . .`. This checkout authenticates
# with GITHUB_TOKEN, so its LFS fetch is allowed (unlike pip's anonymous
# git clone). Without this the agent crashes at runtime decoding a
# 131-byte pointer as audio.
lfs: true

- name: Install LiveKit CLI
run: |
Expand All @@ -47,16 +52,101 @@ jobs:
--api-secret "$LIVEKIT_API_SECRET" \
--default

- name: Regenerate livekit.toml from playground.yaml
run: |
python3 -m pip install --quiet pyyaml
python3 <<'PY'
import yaml
from pathlib import Path
data = yaml.safe_load(Path("examples/playground.yaml").read_text())
subdomain = data["project"]["subdomain"]
slug = "${{ matrix.example }}"
entry = data["examples"][slug]
toml = (
"[project]\n"
f' subdomain = "{subdomain}"\n'
"\n"
"[agent]\n"
f' id = "{entry["agent_id"]}"\n'
)
Path(f"examples/{slug}/livekit.toml").write_text(toml)
print(f"wrote examples/{slug}/livekit.toml")
PY

- name: Pin livekit-* requirements to the deployed ref
working-directory: examples/${{ matrix.example }}
env:
# Build the agent against the code at the ref we're deploying,
# not the latest release on PyPI. Without this, a branch deploy
# would silently run against the published livekit-agents instead
# of the branch's own SDK changes. Mirror the checkout ref above,
# using ref_name so it's a plain branch/tag pip can resolve.
DEPLOY_REF: ${{ inputs.ref || github.ref_name }}
run: |
python3 <<'PY'
import os, re
from pathlib import Path

REF = os.environ["DEPLOY_REF"]
REPO = "git+https://github.com/livekit/agents.git"
REPO_ROOT = Path(os.environ["GITHUB_WORKSPACE"])

# The package name (and optional [extras]) at the start of a
# requirement, e.g. "livekit-agents[evals]>=1.5.7".
REQUIREMENT = re.compile(r"^(?P<name>[A-Za-z0-9._-]+)(?P<extras>\[.*\])?")

def monorepo_path(name):
"""Path of `name` within this repo, or None if it lives elsewhere.

We only pin packages that actually exist in the checkout. The
directory basename is the distribution name for every package
here (livekit-agents at the root, everything else under
livekit-plugins/ — including the irregular ones like
livekit-blingfire). Anything not found (livekit rtc,
livekit-local-inference, …) keeps its PyPI pin.
"""
for rel in (name, f"livekit-plugins/{name}"):
if (REPO_ROOT / rel).is_dir():
return rel
return None

def pin_to_ref(line):
"""Repoint an in-repo requirement at the deployed git ref.

External requirements, comments and blanks pass through
untouched (the regex doesn't match a leading '#' or '').
"""
match = REQUIREMENT.match(line.strip())
path = monorepo_path(match["name"]) if match else None
if path is None:
return line
return f"{match['name']}{match['extras'] or ''} @ {REPO}@{REF}#subdirectory={path}"

requirements = Path("requirements.txt")
pinned = [pin_to_ref(line) for line in requirements.read_text().splitlines()]
requirements.write_text("\n".join(pinned) + "\n")

print(f"--- requirements.txt pinned to {REF} ---")
print(requirements.read_text())
PY

- name: Build secrets file
working-directory: examples/${{ matrix.example }}
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LEMONSLICE_API_KEY: ${{ secrets.LEMONSLICE_API_KEY }}
run: |
: > .env.deploy
# Register the agent under a deterministic name so the playground
# can dispatch to it explicitly. Matches the slug in playground.yaml.
echo "LIVEKIT_AGENT_NAME=${{ matrix.example }}" >> .env.deploy
case "${{ matrix.example }}" in
healthcare)
keys="OPENAI_API_KEY"
;;
avatar)
keys="LEMONSLICE_API_KEY"
;;
*)
keys=""
;;
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,41 @@ jobs:
with:
ref: ${{ inputs.branch || github.event.pull_request.merge_commit_sha }}
secrets: inherit

dispatch-downstream-bumps:
name: Bump livekit-agents in downstream repos
needs: [publish]
# Only fire for stable releases merged via a release/vX.Y.Z PR.
# RC head refs look like release/v1.5.13rc1 and won't match the regex below.
# Republish retries should use internal-actions' workflow_dispatch fallback.
if: |
always()
&& needs.publish.result == 'success'
&& github.event_name == 'pull_request'
&& github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Resolve stable version from head ref
id: version
env:
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
version="${HEAD_REF#release/v}"
if ! echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::notice::Head ref '$HEAD_REF' is not a stable release — skipping downstream bump."
exit 0
fi
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Dispatch to internal-actions
if: steps.version.outputs.version != ''
env:
GH_TOKEN: ${{ secrets.SYNC_DISPATCH_TOKEN }}
TARGET_REPO: ${{ vars.TARGET_REPO }}
VERSION: ${{ steps.version.outputs.version }}
run: |
gh api -X POST "repos/${TARGET_REPO}/dispatches" \
-f event_type="livekit-agents-published" \
-f client_payload[version]="$VERSION" \
-f client_payload[source_repo]="${{ github.repository }}" \
-f client_payload[source_sha]="${{ github.event.pull_request.merge_commit_sha }}"
2 changes: 1 addition & 1 deletion .github/workflows/test-realtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ jobs:
AZURE_OPENAI_API_VERSION: ${{ secrets.AZURE_OPENAI_API_VERSION }}
# XAI_API_KEY not set — xAI rate-limits GitHub Actions IPs (429 on ws handshake)
run: |
uv run pytest -v tests/test_realtime/ -s --tb=long -p no:xdist
uv run pytest --realtime -v -s --tb=long -p no:xdist
2 changes: 1 addition & 1 deletion .github/workflows/test-stt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ jobs:
# AWS_REGION: ${{ secrets.AWS_REGION }}
SARVAM_API_KEY: ${{ secrets.SARVAM_API_KEY }}
run: |
uv run pytest -n 3 -v tests/test_stt.py --tb=long --junitxml=test-results.xml 2>&1 | tee test-output.txt || true
uv run pytest -n 3 -v --stt --tb=long --junitxml=test-results.xml 2>&1 | tee test-output.txt || true

- name: Cleanup Google credentials
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}

run: uv run pytest tests/test_workflows.py tests/test_evals.py
run: uv run pytest --evals

tests:
# don't run tests for PRs on forks
Expand Down
33 changes: 30 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,39 @@ make check # Run all checks (format-check, lint, type-check)

### Testing
```bash
uv run pytest # Run all tests
uv run pytest --unit # Run all unit tests
uv run pytest tests/test_tools.py # Run a single test file
uv run pytest tests/test_tools.py -k "test_name" # Run specific test
cd tests && make unit-tests # Run unit tests that doesn't require cloud accounts
make unit-tests # Run unit tests that don't require cloud accounts
```

#### Test categories

Every test module declares exactly one category via a module-level marker, and
each category has a matching `--<category>` selection flag. Selection happens
*before* import, so a category run never imports (or fails on) modules outside
it.

| Marker | Flag | Meaning |
|--------|------|---------|
| `pytest.mark.unit` | `--unit` | fast, hermetic, no external providers/credentials/network |
| `pytest.mark.plugin("name")` | `--plugin [name]` | provider integration test (needs that provider's deps/keys) |
| `pytest.mark.stt` | `--stt` | cross-provider speech-to-text suite (`tests/test_stt.py`) |
| `pytest.mark.tts` | `--tts` | cross-provider text-to-speech suite (`tests/test_tts.py`) |
| `pytest.mark.realtime("name")` | `--realtime [name]` | realtime-model test |
| `pytest.mark.evals` | `--evals` | behavioral evals against the LiveKit inference gateway |
| `pytest.mark.docs` | `--docs` | tests for the docs-build tooling under `.github/` |

```bash
uv run pytest --unit # the CI unit gate (no cloud accounts)
uv run pytest --plugin openai # only the openai provider tests
uv run pytest --list-categories # list every module grouped by category, then exit
```

**Adding a test:** give the new module a category marker (`pytestmark =
pytest.mark.unit`, etc.) — collection fails with a hint if it lacks one. Run
pytest with the `--allow-uncategorized` option to temporarily disable this rule
(CI keeps it on by default).

### Running Agents
```bash
python myagent.py console # Terminal mode with local audio I/O (no server needed)
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ agents that can see, hear, and understand.
- **Telephony integration**: Works seamlessly with LiveKit's [telephony stack](https://docs.livekit.io/sip/), allowing your agent to make calls to or receive calls from phones.
- **Exchange data with clients**: Use [RPCs](https://docs.livekit.io/home/client/data/rpc/) and other [Data APIs](https://docs.livekit.io/home/client/data/) to seamlessly exchange data with clients.
- **Semantic turn detection**: Uses a transformer model to detect when a user is done with their turn, helps to reduce interruptions.
- **MCP support**: Native support for MCP. Integrate tools provided by MCP servers with one loc.
- **MCP support**: Native support for MCP. Integrate tools provided by MCP servers with one line of code.
- **Builtin test framework**: Write tests and use judges to ensure your agent is performing as expected.
- **Open-source**: Fully open-source, allowing you to run the entire stack on your own servers, including [LiveKit server](https://github.com/livekit/livekit), one of the most widely used WebRTC media servers.

Expand Down Expand Up @@ -186,7 +186,7 @@ class StoryAgent(Agent):
def __init__(self, name: str, location: str) -> None:
super().__init__(
instructions=f"You are a storyteller. Use the user's information in order to make the story personalized."
f"The user's name is {name}, from {location}"
f"The user's name is {name}, from {location}",
# override the default model, switching to Realtime API from standard LLMs
llm=openai.realtime.RealtimeModel(voice="echo"),
chat_ctx=chat_ctx,
Expand Down Expand Up @@ -222,7 +222,7 @@ Automated tests are essential for building reliable agents, especially with the
@pytest.mark.asyncio
async def test_no_availability() -> None:
llm = google.LLM()
async AgentSession(llm=llm) as sess:
async with AgentSession(llm=llm) as sess:
await sess.start(MyAgent())
result = await sess.run(
user_input="Hello, I need to place an order."
Expand Down Expand Up @@ -409,7 +409,7 @@ For more information, see the [examples README](examples/README.md).
Unit tests are in the `tests` directory and can be run with:

```shell
uv run pytest tests/test_tools.py
uv run pytest --unit
```

Integration tests for each plugin require various API credentials and run automatically in GitHub CI for PRs submitted by project maintainers. See the [tests workflow](.github/workflows/tests.yml) for details.
Expand Down
6 changes: 3 additions & 3 deletions examples/Dockerfile-example
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ WORKDIR /home/appuser
COPY requirements.txt .
RUN python -m pip install --user --no-cache-dir -r requirements.txt

COPY . .

# ensure that any dependent models are downloaded at build-time
RUN python myagent.py download-files
RUN python -m livekit.agents download-files

COPY . .

# Run the application.
ENTRYPOINT ["python", "myagent.py"]
Expand Down
46 changes: 46 additions & 0 deletions examples/avatar/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# syntax=docker/dockerfile:1
#
# Shared Dockerfile for every example under examples/. Byte-identical
# across the tree — each example's entry script is named `agent.py`,
# so there's no per-example variation left.
ARG PYTHON_VERSION=3.13
FROM python:${PYTHON_VERSION}-slim AS base

ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1

ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/app" \
--shell "/sbin/nologin" \
--uid "${UID}" \
appuser

RUN apt-get update && apt-get install -y \
git \
git-lfs \
gcc \
g++ \
python3-dev \
&& rm -rf /var/lib/apt/lists/*

# Enable git-lfs so pip's git installs smudge LFS-tracked binaries
# (e.g. silero's bundled VAD onnx) instead of leaving pointer files.
# --system so the unprivileged appuser below inherits the filters.
RUN git lfs install --system

WORKDIR /app
USER appuser

COPY requirements.txt ./
RUN pip install --user --no-cache-dir -r requirements.txt

# Pre-download model weights plugins ship (silero VAD, turn-detector, …)
# so the container is ready to take traffic without a cold-download stall.
RUN python -m livekit.agents download-files

COPY . .

CMD ["python", "agent.py", "start"]
Loading
Loading