Skip to content

feat(voice/avatar): add waitForJoin helper#1594

Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
mainfrom
guiltily-mayoral-implode
Open

feat(voice/avatar): add waitForJoin helper#1594
rosetta-livekit-bot[bot] wants to merge 1 commit into
mainfrom
guiltily-mayoral-implode

Conversation

@rosetta-livekit-bot
Copy link
Copy Markdown
Contributor

@rosetta-livekit-bot rosetta-livekit-bot Bot commented May 25, 2026

No description provided.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 25, 2026

🦋 Changeset detected

Latest commit: a4a25e7

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

This PR includes changesets to release 33 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-assemblyai 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-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-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-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-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

Copy link
Copy Markdown
Contributor

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

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 4 additional findings in Devin Review.

Open in Devin Review

* @param timeout - Timeout in milliseconds. Pass `null` to wait indefinitely.
*/
async waitForJoin({ timeout = 30000 }: { timeout?: number | null } = {}): Promise<void> {
if (!this.#waitAvatarJoinPromise) return;
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.

🔴 waitForJoin() silently resolves immediately when room is not yet connected at start() time

When start() is called while the room is not yet connected, #waitAvatarJoinPromise is not set — instead, only a ConnectionStateChanged listener is registered (avatar_session.ts:87), and #startWaitAvatarJoin() runs later when the room connects. However, waitForJoin() at line 98 checks if (!this.#waitAvatarJoinPromise) return; and returns immediately (resolves successfully) if the promise hasn't been created yet.

This means the typical usage pattern await avatarSession.start(agentSession, room); await avatarSession.waitForJoin(); will silently succeed without actually waiting for the avatar to join whenever the room isn't connected at start() time. Callers will proceed under the false assumption that the avatar participant is present in the room.

Prompt for agents
The problem is in `waitForJoin()` at line 98 of `agents/src/voice/avatar/avatar_session.ts`. When `start()` is called with a room that is not yet connected, `#waitAvatarJoinPromise` is not set until the `ConnectionStateChanged` event fires (see `start()` lines 84-88 and `#onConnectionStateChanged` at line 221). But `waitForJoin()` returns immediately if `#waitAvatarJoinPromise` is falsy.

To fix this, `waitForJoin` needs to handle the case where the join promise hasn't been created yet. One approach: always create `#waitAvatarJoinPromise` eagerly in `start()` (even when the room isn't connected yet), and have it internally wait for the connection first before waiting for the participant. Another approach: in `waitForJoin`, if `#waitAvatarJoinPromise` is not yet set but `start()` has been called (i.e. `#room` is set), wait for the promise to be created (e.g. using a Future/deferred that resolves when `#startWaitAvatarJoin` runs) before proceeding with the timeout race.
Open in Devin Review

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

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.

0 participants