Skip to content

fix(voice): disable AEC warmup for outbound SIP calls - #2202

Merged
chenghao-mou merged 1 commit into
mainfrom
rattler-crabbily-shockers
Aug 2, 2026
Merged

fix(voice): disable AEC warmup for outbound SIP calls#2202
chenghao-mou merged 1 commit into
mainfrom
rattler-crabbily-shockers

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Ports livekit/agents#6608.

Outbound SIP callers can speak before the greeting, but the default AEC warmup suppresses those initial interruptions. Detect outbound SIP participants through the empty sip.ruleID attribute and disable warmup only when aecWarmupDuration is omitted; explicit settings and the 3000 ms default for other calls remain unchanged.

Validation

  • pnpm test agents (111 files, 1551 passed, 5 skipped)
  • pnpm build
  • pnpm lint (passes with existing warnings)
  • pnpm exec prettier --check ... on changed files
  • cue-cli voice-mode run: observed AS_SPEAKING followed by committed assistant greeting
Source diff coverage

Source diff coverage

  • Adapted: livekit-agents/livekit/agents/voice/agent_session.py -> agents/src/voice/agent_session.ts. Preserves omitted-vs-explicit AEC configuration, adapts the 3.0-second Python default to 3000 ms, detects outbound SIP via rtc-node participant.info.kind plus an empty sip.ruleID, updates remaining warmup, and clears an active Node timer.
  • Ported: livekit-agents/livekit/agents/voice/room_io/room_io.py -> agents/src/voice/room_io/room_io.ts. Notifies AgentSession immediately after resolving the linked participant.
  • Adapted: tests/test_agent_session.py -> agents/src/voice/agent_session.test.ts. Ports the source parameterized coverage for call-type defaults, explicit overrides, and active timer cancellation using Vitest and rtc-node conventions.
  • Not applicable: none. All source files have target counterparts and all behavior is ported; no infrastructure gap remains.

Ported from livekit/agents#6608

Original PR description

Outbound SIP callers can speak before the greeting, but the default AEC warmup suppresses those initial interruptions. Detect outbound SIP participants through the empty sip.ruleID attribute and disable warmup only when the option is omitted; explicit settings and the three-second default for other calls remain unchanged.

Tested with a SIP outbound call.

Fixes AGT-3199

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner August 1, 2026 18:55
@changeset-bot

changeset-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2a88a3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 39 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-azure Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-krisp Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-protoface Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

}

this.participantAvailableFuture.resolve(participant);
this.agentSession._onRoomIOParticipantLinked(participant);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Echo-cancellation warmup is not disabled for outbound phone calls when the caller is already in the room

The session is only told about the linked caller from the connect path (this.agentSession._onRoomIOParticipantLinked(participant) at agents/src/voice/room_io/room_io.ts:262) and not from the path that switches to a caller that has already joined, so those outbound phone calls keep the 3-second interruption block.
Impact: For outbound calls where the callee is already present when the agent focuses on them, early speech from the callee is still ignored during the greeting.

Two code paths resolve the linked participant, only one notifies the session

RoomIO.setParticipant() also resolves participantAvailableFuture directly when the target participant is already in room.remoteParticipants (agents/src/voice/room_io/room_io.ts:473-483) and never calls _onRoomIOParticipantLinked. This public method is the documented way to focus the session on a SIP callee (see examples/src/telephony_amd.ts:75). If the SIP participant is created before setParticipant is called, the linked-participant hook never runs and sessionOptions.aecWarmupDuration stays at the 3000 ms default even for an outbound SIP call, which is exactly the case this PR aims to fix.

Prompt for agents
RoomIO has two places where the linked participant future gets resolved: onParticipantConnected (agents/src/voice/room_io/room_io.ts:261) and setParticipant (around agents/src/voice/room_io/room_io.ts:473-483, when the target participant is already connected). The PR only notifies AgentSession from the first one, so outbound SIP detection is skipped when the session is switched onto an already-connected SIP participant (a supported flow, see examples/src/telephony_amd.ts). Consider extracting a single helper that resolves the future and notifies the session, and use it in both places.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is unclear why you would have another participant before a SIP call and have the callee waiting on the line? In that case, it is almost like an inbound call.

@chenghao-mou

Copy link
Copy Markdown
Member

Filed AGT-3217 as a follow-up to make AEC warmup re-arming participant-aware. It covers same-participant reconnects vs. genuinely new acoustic endpoints, plus the Python/JS timer-lifecycle difference when relinking while the agent is already speaking. Treating this as non-blocking for this PR so the outbound SIP fix can merge first.

@chenghao-mou
chenghao-mou merged commit 8260fa1 into main Aug 2, 2026
6 checks passed
@chenghao-mou
chenghao-mou deleted the rattler-crabbily-shockers branch August 2, 2026 18:49
@github-actions github-actions Bot mentioned this pull request Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant