Skip to content

feat: add Ojin avatar plugin - #7162

Open
php-workx wants to merge 3 commits into
livekit:mainfrom
ojinai:feat/ojin-stv-avatar
Open

feat: add Ojin avatar plugin#7162
php-workx wants to merge 3 commits into
livekit:mainfrom
ojinai:feat/ojin-stv-avatar

Conversation

@php-workx

@php-workx php-workx commented Sep 8, 2026

Copy link
Copy Markdown

Ojin · Docs

This PR adds the Ojin avatar plugin, driving Ojin's Speech-To-Video models from an AgentSession.

from livekit.plugins import ojin

avatar = ojin.AvatarSession()          # OJIN_API_KEY, OJIN_CONFIG_ID
await avatar.start(session, room=ctx.room)

@php-workx
php-workx requested a review from a team as a code owner September 8, 2026 03:45

@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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 8 potential issues.

2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py Outdated
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py Outdated
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
@php-workx
php-workx force-pushed the feat/ojin-stv-avatar branch from 3e654ed to 167ac0f Compare September 8, 2026 04:46

@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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 4 new potential issues.

3 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py Outdated
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Comment thread livekit-plugins/livekit-plugins-ojin/livekit/plugins/ojin/avatar.py
Adds livekit-plugins-ojin, driving Ojin's Speech-To-Video models from an
AgentSession.

Ojin renders in-process through its SDK rather than joining the room as its own
participant, so the plugin runs on the local-runner path (AvatarSession ->
AvatarRunner -> VideoGenerator) alongside bithuman, and owns the media path
itself rather than being a thin API client.

The subtle part is segment accounting. Ojin's playback clock emits an audio
frame on every tick - zero-filled while idle - whereas AvatarRunner reports
playback-finished only when the generator yields an AudioSegmentEnd, and
AgentSession blocks on that after every utterance. A missing marker wedges the
conversation permanently, so the decision about when an utterance is actually
over lives in its own module with its own tests.

Ships 92 hermetic tests driven by a fake STV client - no network, no
credentials - covering the frame conversions, the frame sink, the turn state
machine, barge-in, the frame watchdog and the degradation path, plus an
end-to-end suite over the real QueueAudioOutput.

Registered as the `ojin` extra alongside the other avatar plugins.
@php-workx
php-workx force-pushed the feat/ojin-stv-avatar branch from 167ac0f to 3099740 Compare September 8, 2026 05:02
devin-ai-integration[bot]

This comment was marked as resolved.

owes_segment_end only asked the tracker, which lets go of a segment the
moment the marker is queued. Turning that marker into a playback report is
the runner's job, so a fatal landing between the two discarded it and left
the session waiting in wait_for_playout(). Treat a marker still sitting in
the queue as owed.
_on_fatal schedules the degrade only once a runner exists to tear down. A
fatal between the first-frame check and that assignment therefore scheduled
nothing, while its first-wins guard stopped any later event or the watchdog
from scheduling one - and startup went on to install an avatar that could
never report playback. Re-check after the runner starts and fail the start,
which rolls back through the existing path.
php-workx added a commit to ojinai/livekit-demo that referenced this pull request Sep 9, 2026
The branch pin resolved to whatever feat/ojin-stv-avatar pointed at, and
upstream review keeps rebasing that branch - which orphaned the pinned commit
twice, leaving `uv sync` unable to resolve the plugin at all. The tag cannot
move. Bugfixes arrive as a new preview tag, and PyPI takes over once
livekit/agents#7162 merges.
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