Skip to content

feat(anam): forward output video dimensions via SessionOptions#5935

Open
Smidge wants to merge 2 commits into
livekit:mainfrom
Smidge:feat/anam-session-video-dimensions
Open

feat(anam): forward output video dimensions via SessionOptions#5935
Smidge wants to merge 2 commits into
livekit:mainfrom
Smidge:feat/anam-session-video-dimensions

Conversation

@Smidge
Copy link
Copy Markdown

@Smidge Smidge commented Jun 2, 2026

Closes #5954

What

Adds an optional anam.SessionOptions(video_width, video_height) that the Anam avatar plugin forwards into Anam's session-token request as sessionOptions.videoWidth / videoHeight. The avatar video then publishes at the Anam-resolved output size.

session = anam.AvatarSession(
    persona_config=anam.PersonaConfig(name="avatar", avatarId=ANAM_AVATAR_ID),
    session_options=anam.SessionOptions(video_width=1152, video_height=768),
)

Why

Anam's public session-token API now accepts explicit pixel output dimensions. This lets Agents users choose the avatar's output size without any provider-specific dimensions API.

Design

  • Pixels only, both-or-neither — no portrait/landscape strings.
  • Validation lives in Anam, not the plugin. The plugin is a thin pass-through and doesn't know the per-model allow-list; Anam validates the requested pair against the avatar model and returns HTTP 400 for an unsupported (or half) pair, which the plugin already surfaces as APIStatusError with Anam's descriptive message. No silent downgrade.
  • Mirrors livekit-plugins-avatario (VideoInfo(video_width, video_height)). I named it SessionOptions to match Anam's own sessionOptions API field and leave room for future session-level options — happy to switch to a nested AvatarSession.VideoInfo if you'd prefer consistency with Avatario.
  • Backward compatible: session_options is optional (NOT_GIVEN); when omitted the request body is identical to today and Anam applies the avatar model's default. No behaviour change for existing users.

Scope

5 files — types.py (new SessionOptions dataclass), avatar.py + api.py (thread through + emit camelCase), __init__.py (export), and the anam example. No new dependencies; no change to the LiveKit token / start_engine_session / wait_remote_track flow. ruff format + ruff check clean. Left version.py/changelog to the release bot per CONTRIBUTING.

Happy to add unit tests for the payload construction in whatever harness you prefer.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 2, 2026

CLA assistant check
All committers have signed the CLA.

Add an optional anam.SessionOptions(video_width, video_height) that the plugin
forwards into Anam's session-token request as sessionOptions.videoWidth/videoHeight.
The avatar video then publishes at the Anam-resolved output size.

Pixels only (no portrait/landscape strings), both-or-neither, validated server-side
by Anam as the single source of truth: unsupported pairs return HTTP 400, already
surfaced by the plugin as APIStatusError, with no silent downgrade. Mirrors the
livekit-plugins-avatario VideoInfo dataclass.

Backward compatible: session_options is optional; when omitted the request is
identical to today and Anam applies the avatar model's default output.
@Smidge Smidge force-pushed the feat/anam-session-video-dimensions branch from 6dbba86 to ffbcd53 Compare June 3, 2026 12:29
Comment on lines +105 to +110
if session_options.video_width is not None:
video_options["videoWidth"] = session_options.video_width
if session_options.video_height is not None:
video_options["videoHeight"] = session_options.video_height
if video_options:
payload["sessionOptions"] = video_options
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.

this doesn't match the comment above "Send both or neither"?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch, you're right. It builds video_options from whichever field is non-None, so a lone video_width/video_height still goes out as exactly the half pair the comment says Anam rejects.

Fixing it to send both or neither, and to fail fast locally on a half pair rather than round-tripping a 400:

if session_options is not None and (
    session_options.video_width is not None
    or session_options.video_height is not None
):
    if session_options.video_width is None or session_options.video_height is None:
        raise ValueError(
            "video_width and video_height must be set together (both or neither)"
        )
    payload["sessionOptions"] = {
        "videoWidth": session_options.video_width,
        "videoHeight": session_options.video_height,
    }

Thanks for the review!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 73adbbcsessionOptions now only goes out when both dimensions are present, and raises a ValueError on a lone width/height so it fails fast locally instead of round-tripping a 400.

The previous guard built sessionOptions from whichever of video_width /
video_height was set, so a lone value was forwarded as a half pair, which the
Anam API rejects with a 400. Only send the pair when both are present, and raise
a ValueError on a half pair so it fails fast locally instead of round-tripping.
Addresses review feedback from @longcw.
@Smidge Smidge marked this pull request as ready for review June 5, 2026 15:06
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: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

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.

Anam plugin: support explicit output video dimensions via SessionOptions

3 participants