Skip to content

Conversation

@Saksham209
Copy link
Contributor

@Saksham209 Saksham209 commented Nov 28, 2025

Summary by CodeRabbit

  • New Features

    • Avatario virtual-avatar plugin for LiveKit Agents with avatar session support, API client, and automatic plugin registration.
    • Example agent that starts an avatar session, joins a room, and triggers an initial greeting.
  • Documentation

    • Added README docs for the Avatario plugin and example agent, including required environment variables and run instructions.
  • Chores

    • Packaging/configuration, typing marker, and workspace registration for the Avatario plugin.

✏️ Tip: You can customize this high-level summary in your review settings.

@CLAassistant
Copy link

CLAassistant commented Nov 28, 2025

CLA assistant check
All committers have signed the CLA.

@Saksham209 Saksham209 changed the title avatario avatar plugin feat: avatario avatar plugin Dec 1, 2025
@i25959341
Copy link

i25959341 commented Jan 8, 2026

@Saksham209 is it possible get a loom recording as a demo for this avatar plugin please?

you can also add an example here

@Saksham209
Copy link
Contributor Author

Saksham209 commented Jan 9, 2026

Hi @i25959341. I have added the example file in the specified folder. Here is the loom link for our product:

loom

@Saksham209
Copy link
Contributor Author

@i25959341 please let me know if there is anything required from our end.

@karlsonlee-livekit
Copy link

karlsonlee-livekit commented Jan 20, 2026

Hi @Saksham209, apology on this, can you show your plugin is working by running your example script and do a conversation on the agent playground? similar to this loom video on this PR.

@Saksham209
Copy link
Contributor Author

Saksham209 commented Jan 20, 2026

Hi @karlsonlee-livekit would this demo work: loom ?

I removed this line from my experiment script for this demo :
session.generate_reply(instructions="say hello to the user")

as it was generating speech in a different language

@tinalenguyen
Copy link
Member

Hi, thank you for creating this PR! Could you also edit these files and add the plugin:
https://github.com/livekit/agents/blob/main/examples/avatar_agents/README.md

https://github.com/livekit/agents/blob/main/pyproject.toml

@tinalenguyen
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

📝 Walkthrough

Walkthrough

Adds a new Avatario LiveKit plugin and example integration: async Avatario API client, AvatarSession that builds JWTs and starts remote avatar sessions, package metadata/typing, logging, docs, and an example agent worker that composes AvatarSession with AgentSession to join LiveKit rooms.

Changes

Cohort / File(s) Summary
Avatario Plugin - Core Implementation
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/__init__.py, .../api.py, .../avatar.py, .../log.py, .../version.py, .../py.typed
New package exposing AvatarioPlugin; adds AvatarioAPI async client (session management, retry/timeout, POST start-session), AvatarioException, and AvatarSession (VideoInfo dataclass, env fallbacks, JWT creation, start flow, DataStreamAudioOutput wiring); logger, __version__, and typing marker.
Plugin Packaging & Config
livekit-plugins/livekit-plugins-avatario/pyproject.toml
New package pyproject using Hatchling with metadata and dependency on livekit-agents>=1.3.12; version sourced from version.py.
Example Agent & Docs
examples/avatar_agents/avatario/agent_worker.py, examples/avatar_agents/avatario/README.md, livekit-plugins/livekit-plugins-avatario/README.md, examples/README.md, examples/avatar_agents/README.md
Adds an example agent worker that composes AgentSession + AvatarSession, READMEs describing required env vars and run command, and adds Avatario to example provider lists.
Workspace / Repo Config
pyproject.toml
Adds livekit-plugins-avatario to workspace packages/sources, updates dev deps (pytest-xdist), and adds mypy overrides for new modules.

Sequence Diagram(s)

sequenceDiagram
    participant Client as RTC Client
    participant Agent as Agent Worker
    participant Avatar as AvatarSession
    participant AvatarioAPI as Avatario API
    participant LiveKit as LiveKit Server

    Client->>Agent: Connect RTC session
    Agent->>Avatar: Instantiate AvatarSession (avatar_id, video_info)
    Avatar->>Avatar: _ensure_http_session()
    Avatar->>Avatar: Build JWT (identity, grants, publish-on-behalf)
    Avatar->>AvatarioAPI: POST /start-session (payload: avatar_id, token, livekit_url, video_info)
    AvatarioAPI-->>Avatar: Session started (response)
    Avatar->>Agent: Configure DataStreamAudioOutput (route audio to avatar)
    Agent->>LiveKit: Join room / publish tracks
    LiveKit-->>Agent: Room joined / participant events
    Agent->>Client: Agent/Avatar audio/video streams active
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • tinalenguyen

Poem

🐇
I hopped through code with nimble feet,
Spun JWTs so avatars could meet,
I whispered "hello" across the stream,
Agents woke and joined the dream,
Come listen — the avatar says hi!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: avatario avatar plugin' clearly summarizes the main change: introduction of a new Avatario avatar plugin for LiveKit agents with full implementation and examples.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)

98-149: Good error handling and retry logic.

The implementation correctly handles APIStatusError by checking retryable before deciding to retry, and preserves the original exception when re-raising. The runtime check for uninitialized session provides a clear error message.

Minor docstring gap: The Raises section documents APIConnectionError but omits APIStatusError (raised on non-retryable errors) and RuntimeError (raised when session is not initialized).

📝 Suggested docstring update
         Raises:
             APIConnectionError: If the request fails after all retries
+            APIStatusError: If the server returns a non-retryable error
+            RuntimeError: If the API is used without async context manager
📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 522a33f and f424094.

📒 Files selected for processing (1)
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
🧠 Learnings (1)
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Applies to **/*.py : Ensure Python 3.9+ compatibility

Applied to files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.9)
🔇 Additional comments (5)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (5)

1-19: LGTM!

The from __future__ import annotations import correctly enables Python 3.9+ compatibility for union type syntax. Imports are well-organized and all appear necessary.


21-25: LGTM!

Exception class and API URL constant are properly defined.


35-53: LGTM!

Session ownership tracking is properly implemented with self._owns_session, addressing the previous review feedback. The initialization correctly stores configuration without creating the session until __aenter__ is called.


55-64: LGTM!

Async context manager correctly creates and cleans up the session based on ownership. The conditional logic ensures externally provided sessions are not inadvertently closed.


66-96: LGTM!

The method properly validates livekit_agent_identity and handles properties using utils.is_given(). The Google-style docstring accurately describes the parameters.

Note: The response from _post is discarded (return type is None). If the Avatario API's start-session response contains useful data (e.g., session ID, status), consider returning it to callers.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@examples/avatar_agents/avatario/README.md`:
- Around line 1-3: Replace the incorrect phrase "a animated" in the README
header/intro with the grammatically correct "an animated"; locate the string "a
animated avatar" in the README content (under the "LiveKit Avatario Avatar
Agent" title) and update it to "an animated avatar".

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py`:
- Around line 28-48: The __init__ currently uses Python 3.10 union types,
mis-handles the NOT_GIVEN sentinel, and leaks aiohttp sessions; update the
signature to use Optional[aiohttp.ClientSession] for Python 3.9 compatibility,
replace truthy checks with utils.is_given(...) when handling api_key and
avatar_id so the NOT_GIVEN sentinel isn't lost (e.g., in AvatarioAPI.__init__
check utils.is_given(avatar_id) and utils.is_given(api_key) before falling back
to env), and track session ownership by adding a boolean like self._owns_session
when you create a new aiohttp.ClientSession so you can implement an async
aclose(self) method that closes the session only if owned and not already
closed.

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py`:
- Around line 69-85: The start method currently uses "livekit_url = livekit_url
or os.getenv(...)" which fails when the sentinel NOT_GIVEN is truthy; update the
fallback logic to explicitly check for the NOT_GIVEN sentinel for livekit_url,
livekit_api_key, and livekit_api_secret (e.g., if livekit_url is NOT_GIVEN then
set it from os.getenv, otherwise keep the provided value), then validate and
raise AvatarioException if any final value is missing; reference the start
method and the variables livekit_url, livekit_api_key, livekit_api_secret and
the AvatarioException to locate where to change the assignments.
🧹 Nitpick comments (1)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)

73-113: Tighten retry semantics and fix docstring drift.
The docstring mentions an endpoint arg that doesn’t exist. Also, if max_retry represents “number of retries,” the loop should attempt max_retry + 1 total tries and honor an immediate first retry per APIConnectOptions docs.

♻️ Suggested refactor
-            endpoint: API endpoint path (without leading slash)
             payload: JSON payload for the request
@@
-        for i in range(self._conn_options.max_retry):
+        for i in range(self._conn_options.max_retry + 1):
@@
-                if i < self._conn_options.max_retry - 1:
-                    await asyncio.sleep(self._conn_options.retry_interval)
+                if i < self._conn_options.max_retry:
+                    await asyncio.sleep(0.1 if i == 0 else self._conn_options.retry_interval)
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13580b3 and 5acb543.

📒 Files selected for processing (10)
  • examples/avatar_agents/avatario/README.md
  • examples/avatar_agents/avatario/agent_worker.py
  • livekit-plugins/livekit-plugins-avatario/README.md
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/__init__.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/log.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/py.typed
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/version.py
  • livekit-plugins/livekit-plugins-avatario/pyproject.toml
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/log.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/version.py
  • examples/avatar_agents/avatario/agent_worker.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/__init__.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
🧬 Code graph analysis (4)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (6)
livekit-agents/livekit/agents/job.py (2)
  • api (276-284)
  • get_job_context (56-63)
livekit-agents/livekit/agents/types.py (1)
  • APIConnectOptions (54-88)
livekit-agents/livekit/agents/voice/avatar/_datastream_io.py (1)
  • DataStreamAudioOutput (23-260)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (3)
  • AvatarioAPI (27-113)
  • AvatarioException (20-21)
  • start_session (49-71)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
livekit-agents/livekit/agents/utils/http_context.py (1)
  • http_session (40-51)
examples/avatar_agents/avatario/agent_worker.py (4)
livekit-agents/livekit/agents/voice/agent.py (2)
  • Agent (40-638)
  • instructions (105-110)
livekit-agents/livekit/agents/worker.py (1)
  • AgentServer (253-1310)
livekit-agents/livekit/agents/voice/agent_session.py (1)
  • AgentSession (135-1314)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)
  • VideoInfo (33-36)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/__init__.py (3)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)
  • AvatarioException (20-21)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)
  • AvatarSession (29-113)
livekit-agents/livekit/agents/plugin.py (2)
  • Plugin (13-56)
  • register_plugin (31-36)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (4)
livekit-agents/livekit/agents/_exceptions.py (2)
  • APIConnectionError (84-88)
  • APIStatusError (45-81)
livekit-agents/livekit/agents/types.py (1)
  • APIConnectOptions (54-88)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
livekit-agents/livekit/agents/utils/aio/sleep.py (1)
  • sleep (68-69)
🔇 Additional comments (17)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/log.py (1)

1-3: LGTM — consistent module-level logger.

livekit-plugins/livekit-plugins-avatario/README.md (1)

1-3: LGTM — concise README intro.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/py.typed (1)

1-1: LGTM — PEP 561 marker included.

livekit-plugins/livekit-plugins-avatario/pyproject.toml (1)

1-39: LGTM — clean packaging metadata.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/version.py (1)

1-15: LGTM — version constant defined.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/__init__.py (3)

1-9: Exports look correct.
__all__ cleanly exposes the intended public API for the plugin.


16-18: AvatarioPlugin wrapper is clean.
The thin wrapper around Plugin is straightforward and clear.


21-21: Auto-registration matches the plugin pattern.
Import-time registration aligns with how plugins are typically surfaced.

examples/avatar_agents/avatario/agent_worker.py (4)

1-15: Example setup is straightforward.
Logger, dotenv load, and server init are clear and minimal.


17-39: Entrypoint flow looks sensible.
Starting the avatar session before the agent session is a clear, workable sequence.


44-45: CLI entrypoint is fine.
Standard __main__ guard and cli.run_app usage.


41-41: Remove this suggestion. session.generate_reply() is a synchronous method that returns a SpeechHandle immediately; it does not need to be awaited. The method signature at livekit-agents/livekit/agents/voice/agent_session.py:906 confirms def generate_reply(...) -> SpeechHandle: is non-async. While SpeechHandle contains internal asyncio state, it is not an awaitable object, and the current code is correct.

Likely an incorrect or invalid review comment.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (2)

20-25: Exception type + default URL are fine.
Clear, simple definitions for the public API surface.


49-71: The review comment is incorrect. The current code already properly handles NOT_GIVEN values and does not need the proposed fix.

Why the current code is correct:

  1. Line 55 (if not livekit_agent_identity): The NotGiven class defines __bool__() to return False, so not NOT_GIVEN evaluates to True. This condition correctly catches and rejects NOT_GIVEN.

  2. Line 61 (properties = properties or {}): Python's or operator evaluates NOT_GIVEN as False (via __bool__()), so it returns the right operand {}. The sentinel value is never used.

  3. Line 69 (if utils.is_given(self._video_info)): This properly guards the code, preventing NOT_GIVEN from being added to the payload.

  4. JSON serialization: Sentinel values never reach the payload. They are either caught by conditionals (raising exceptions) or converted to default values before payload construction.

The proposed fix introduces unnecessary complexity and redundancy without addressing a real issue.

Likely an incorrect or invalid review comment.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (3)

29-37: VideoInfo defaults look good.
Simple, sensible defaults for avatar video parameters.


63-67: HTTP session retrieval is fine.
Using the job-context HTTP session is consistent with other plugins.


38-62: The current implementation correctly handles the sentinel value without issues.

avatar_participant_identity or _AVATAR_AGENT_IDENTITY works as intended because NOT_GIVEN is falsy (its __bool__() method returns False). The or operator will correctly use the default value when NOT_GIVEN is passed, so sentinel values cannot leak into token creation. The proposed fix is unnecessary for the stated concern.

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Fix all issues with AI agents
In `@examples/avatar_agents/README.md`:
- Line 12: The markdown list item for Avatario contains a formatting typo:
change the substring "-[Platform]" to " - [Platform]" in the Avatario entry (the
line containing "**[Avatario](./avatario/)** -[Platform](https://avatario.ai/) |
[Integration Guide](https://avatario.ai/docs/integrations/livekit)") so it
matches the other entries' " - " spacing.

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py`:
- Line 29: Remove the trailing whitespace on the blank module-level line in the
avatario API module (livekit.plugins.avatario.api) flagged by ruff: delete the
stray spaces on the empty line near the top of the file so the line is truly
empty (or run a whitespace-trimming/save to strip trailing spaces).
- Line 57: Remove the trailing whitespace that ruff flagged in
livekit.plugins.avatario.api (a blank line in api.py); open the file and delete
the extra space characters at the end of the empty line so the file contains a
true blank line without trailing spaces, then save and run the linter again to
confirm the warning is gone.
- Line 84: The code uses "properties = properties or {}" which fails when the
sentinel NOT_GIVEN (truthy) is passed; change this to detect the sentinel using
utils.is_given and only set an empty dict when properties was not given (e.g.,
if not utils.is_given(properties): properties = {}), keeping the rest of the
function logic the same and using the existing utils.is_given() helper
referenced elsewhere in the file.
- Around line 58-59: The union type in the async context manager signature
(__aexit__) uses Python 3.10+ syntax (e.g., "type | None") which breaks 3.9; fix
by either adding "from __future__ import annotations" at the top of the module
to enable postponed evaluation of annotations, or change the annotation in the
__aexit__ definition to use typing.Optional/Union (e.g., Optional[type] and
Optional[Exception]) and import Optional from typing so the code remains Python
3.9 compatible.
- Around line 110-120: The start_session method (inside AvatarioAPI) can call
self._session.post when self._session is None if the instance wasn't entered via
__aenter__; add a runtime guard at the start of start_session (and any other
public methods that use self._session like _post) that checks if self._session
is not None and raises a clear RuntimeError (or ValueError) instructing users to
use the class as an async context manager (or call the initializer), or
alternatively lazily create the aiohttp session; reference the
attributes/methods self._session, start_session, __aenter__, and _post when
applying the check so the error is raised early with a descriptive message.

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py`:
- Around line 71-79: The NOT_GIVEN sentinel is handled incorrectly and checks
are inconsistent: ensure both avatar_id and avatario_api_key use the
utils.is_given() helper when resolving inputs and environment variables (replace
the `a or (os.getenv(...) or NOT_GIVEN)` pattern with explicit resolution that
prefers the provided argument, then falls back to os.getenv(...), and finally
NOT_GIVEN), and then validate with utils.is_given() before raising
AvatarioException for missing AVATARIO_AVATAR_ID and AVATARIO_API_KEY; finally
assign to self._avatar_id and self._api_key only after those validated resolved
values.

In `@pyproject.toml`:
- Line 29: The dependency declaration for livekit-plugins-lemonslice in
pyproject.toml has a formatting inconsistency (missing space before the closing
brace); update the entry for livekit-plugins-lemonslice = { workspace = true} to
follow the project style by adding a space before the closing brace so it reads
with consistent spacing around braces for that dependency declaration.
♻️ Duplicate comments (1)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

101-110: NOT_GIVEN handling still incorrect for LiveKit credentials.

Same issue as the __init__ method—the pattern livekit_url = livekit_url or (os.getenv(...) or NOT_GIVEN) doesn't work because NOT_GIVEN is truthy. This was flagged in a previous review but the fix appears incomplete.

🛠️ Proposed fix
-        livekit_url = livekit_url or (os.getenv("LIVEKIT_URL") or NOT_GIVEN)
-        livekit_api_key = livekit_api_key or (os.getenv("LIVEKIT_API_KEY") or NOT_GIVEN)
-        livekit_api_secret = livekit_api_secret or (
-            os.getenv("LIVEKIT_API_SECRET") or NOT_GIVEN
-        )
-        if not livekit_url or not livekit_api_key or not livekit_api_secret:
+        livekit_url = (
+            livekit_url if utils.is_given(livekit_url) else os.getenv("LIVEKIT_URL")
+        )
+        livekit_api_key = (
+            livekit_api_key
+            if utils.is_given(livekit_api_key)
+            else os.getenv("LIVEKIT_API_KEY")
+        )
+        livekit_api_secret = (
+            livekit_api_secret
+            if utils.is_given(livekit_api_secret)
+            else os.getenv("LIVEKIT_API_SECRET")
+        )
+        if not livekit_url or not livekit_api_key or not livekit_api_secret:
             raise AvatarioException(
                 "livekit_url, livekit_api_key, and livekit_api_secret must be set "
                 "by arguments or environment variables"
             )
🧹 Nitpick comments (2)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)

129-138: Retry logic retries all exceptions, including non-retryable ones.

The current implementation catches all exceptions and retries, but APIStatusError from 4xx responses has retryable=False. Consider checking e.retryable before retrying to avoid wasting retries on client errors like 401 Unauthorized or 400 Bad Request.

♻️ Proposed improvement
             except Exception as e:
-                if isinstance(e, APIConnectionError):
+                if isinstance(e, (APIConnectionError, APIStatusError)):
+                    if not e.retryable:
+                        raise
                     logger.warning(
                         "failed to call Avatario API", extra={"error": str(e)}
                     )
                 else:
                     logger.exception("failed to call avatario api")
+                    raise  # Don't retry unexpected exceptions

                 if i < self._conn_options.max_retry - 1:
                     await asyncio.sleep(self._conn_options.retry_interval)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

81-84: NOT_GIVEN handling for participant identity/name is inconsistent.

Using or works here because these fall back to string constants (which are truthy), but it's inconsistent with the utils.is_given() pattern used elsewhere. If NOT_GIVEN is passed, the or short-circuits correctly only because the fallback is truthy.

♻️ Suggested improvement for consistency
         self._avatar_participant_identity = (
-            avatar_participant_identity or _AVATAR_AGENT_IDENTITY
+            avatar_participant_identity
+            if utils.is_given(avatar_participant_identity)
+            else _AVATAR_AGENT_IDENTITY
         )
-        self._avatar_participant_name = avatar_participant_name or _AVATAR_AGENT_NAME
+        self._avatar_participant_name = (
+            avatar_participant_name
+            if utils.is_given(avatar_participant_name)
+            else _AVATAR_AGENT_NAME
+        )
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5acb543 and 3584bfb.

📒 Files selected for processing (8)
  • examples/README.md
  • examples/avatar_agents/README.md
  • examples/avatar_agents/avatario/README.md
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/version.py
  • livekit-plugins/livekit-plugins-avatario/pyproject.toml
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (3)
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/version.py
  • livekit-plugins/livekit-plugins-avatario/pyproject.toml
  • examples/avatar_agents/avatario/README.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Follow the Plugin System pattern where plugins in livekit-plugins/ are separate packages registered via the Plugin base class
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Follow the Plugin System pattern where plugins in livekit-plugins/ are separate packages registered via the Plugin base class

Applied to files:

  • pyproject.toml
🧬 Code graph analysis (1)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (4)
livekit-agents/livekit/agents/_exceptions.py (2)
  • APIConnectionError (84-88)
  • APIStatusError (45-81)
livekit-agents/livekit/agents/types.py (1)
  • APIConnectOptions (54-88)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
livekit-agents/livekit/agents/utils/aio/sleep.py (1)
  • sleep (68-69)
🪛 GitHub Check: ruff
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py

[failure] 57-57: Ruff (W293)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:57:1: W293 Blank line contains whitespace


[failure] 29-29: Ruff (W293)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:29:1: W293 Blank line contains whitespace

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.9)
🔇 Additional comments (3)
examples/README.md (1)

13-13: LGTM — clear provider list update.

pyproject.toml (1)

9-9: LGTM!

The Avatario plugin workspace entry follows the established pattern and is correctly placed in alphabetical order.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

139-144: LGTM!

The DataStreamAudioOutput configuration correctly routes audio to the avatar participant with the appropriate sample rate and video track synchronization.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

livekit-plugins-hume = { workspace = true }
livekit-plugins-inworld = { workspace = true }
livekit-plugins-langchain = { workspace = true }
livekit-plugins-lemonslice = { workspace = true}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor formatting inconsistency: missing space before closing brace.

📝 Proposed fix
-livekit-plugins-lemonslice = { workspace = true}
+livekit-plugins-lemonslice = { workspace = true }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
livekit-plugins-lemonslice = { workspace = true}
livekit-plugins-lemonslice = { workspace = true }
🤖 Prompt for AI Agents
In `@pyproject.toml` at line 29, The dependency declaration for
livekit-plugins-lemonslice in pyproject.toml has a formatting inconsistency
(missing space before the closing brace); update the entry for
livekit-plugins-lemonslice = { workspace = true} to follow the project style by
adding a space before the closing brace so it reads with consistent spacing
around braces for that dependency declaration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py`:
- Line 149: The file ends without a trailing newline causing ruff W292; update
the function that raises APIConnectionError (the line containing raise
APIConnectionError("Failed to call Avatario API after all retries")) to ensure
the file ends with a single trailing newline character (add a newline at EOF).

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py`:
- Around line 85-88: The current assignments for _avatar_participant_identity
and _avatar_participant_name use "or" which treats the NOT_GIVEN sentinel as
truthy and can pass the sentinel through; change them to use utils.is_given() so
the defaults (_AVATAR_AGENT_IDENTITY and _AVATAR_AGENT_NAME) are applied only
when avatar_participant_identity / avatar_participant_name are not given. Locate
the assignments to self._avatar_participant_identity and
self._avatar_participant_name in avatar.py and replace the "or" logic with a
conditional that calls utils.is_given(avatar_participant_identity) and
utils.is_given(avatar_participant_name) respectively, setting the default only
when is_given returns False.
♻️ Duplicate comments (2)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

105-110: Correct LiveKit env fallback when args are NOT_GIVEN.

NOT_GIVEN is truthy, so the current or chain skips env vars and the subsequent falsy check won’t catch missing values, leading to invalid token construction.

🛠️ Proposed fix
-        livekit_url = livekit_url or (os.getenv("LIVEKIT_URL") or NOT_GIVEN)
-        livekit_api_key = livekit_api_key or (os.getenv("LIVEKIT_API_KEY") or NOT_GIVEN)
-        livekit_api_secret = livekit_api_secret or (
-            os.getenv("LIVEKIT_API_SECRET") or NOT_GIVEN
-        )
+        livekit_url = (
+            livekit_url if utils.is_given(livekit_url) and livekit_url else os.getenv("LIVEKIT_URL")
+        )
+        livekit_api_key = (
+            livekit_api_key
+            if utils.is_given(livekit_api_key) and livekit_api_key
+            else os.getenv("LIVEKIT_API_KEY")
+        )
+        livekit_api_secret = (
+            livekit_api_secret
+            if utils.is_given(livekit_api_secret) and livekit_api_secret
+            else os.getenv("LIVEKIT_API_SECRET")
+        )
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)

60-64: Avoid X | None syntax to keep Python 3.9 compatibility.

Python 3.9 can’t parse union types with |, even with from __future__ import annotations. Use Optional[...] instead. As per coding guidelines, Python 3.9+ compatibility is required.

🛠️ Proposed fix
     async def __aexit__(
-        self, exc_type: type | None, exc_val: Exception | None, exc_tb: Any
+        self,
+        exc_type: Optional[type],
+        exc_val: Optional[Exception],
+        exc_tb: Any,
     ) -> None:
#!/bin/bash
# Verify declared Python version requirements in packaging metadata.
rg -n "requires-python|python_requires" -g 'pyproject.toml' -g 'setup.cfg' -g 'setup.py'
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3584bfb and 2fb48ed.

📒 Files selected for processing (2)
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Follow the Plugin System pattern where plugins in livekit-plugins/ are separate packages registered via the Plugin base class
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Applies to **/*.py : Ensure Python 3.9+ compatibility

Applied to files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
🧬 Code graph analysis (1)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (6)
livekit-agents/livekit/agents/job.py (3)
  • api (276-284)
  • get_job_context (56-63)
  • local_participant_identity (315-319)
livekit-agents/livekit/agents/voice/agent_session.py (4)
  • AgentSession (135-1314)
  • room_io (721-727)
  • conn_options (399-400)
  • output (391-392)
livekit-agents/livekit/agents/voice/avatar/_datastream_io.py (1)
  • DataStreamAudioOutput (23-260)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (3)
  • AvatarioAPI (28-149)
  • AvatarioException (21-22)
  • start_session (66-96)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
livekit-agents/livekit/agents/utils/http_context.py (1)
  • http_session (40-51)
🪛 GitHub Check: ruff
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py

[failure] 149-149: Ruff (W292)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:149:82: W292 No newline at end of file


[failure] 42-42: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:42:18: UP007 Use X | Y for type annotations

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests
  • GitHub Check: type-check (3.9)
  • GitHub Check: type-check (3.13)
🔇 Additional comments (3)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

90-94: Lazy HTTP session initialization looks good.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (2)

35-54: Session ownership tracking is clean and readable.


66-96: Input validation and payload assembly look good.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py`:
- Around line 118-149: The loop currently catches all exceptions and converts
APIStatusError into a generic APIConnectionError and always retries; change the
error handling to first catch APIStatusError (the one raised when response.ok is
false) and re-raise it immediately so callers keep status/body, then in the
broader exception handler inspect retryability (check for a .retryable attribute
or treat APIConnectionError as retryable) and only sleep/retry when the
exception is retryable; if not retryable, re-raise the exception. Update the
try/except around the _session.post block (referencing _conn_options.max_retry,
self._session.post, APIStatusError, APIConnectionError) to implement this flow
and preserve original error details when re-raising.

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py`:
- Around line 32-36: Replace all PEP 604 union annotations with typing.Optional
to restore Python 3.9 compatibility: change VideoInfo fields using "str | None"
to "Optional[str]" and any usages like "aiohttp.ClientSession | None" to
"Optional[aiohttp.ClientSession]"; add "from typing import Optional" to the
imports if missing. Update the annotations in the VideoInfo dataclass and in the
class/attribute where the aiohttp.ClientSession is declared (refer to VideoInfo
and the attribute using ClientSession) so all None-able types use Optional[...]
instead of the "|" syntax.
♻️ Duplicate comments (2)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)

42-43: Align typing syntax with the supported Python version

type | None is Python 3.10+ syntax and will be a SyntaxError on 3.9, while UP007 asks for X | Y (also 3.10+). Please confirm the minimum Python version; if 3.9 is still supported, keep Optional[...] and update __aexit__ accordingly (and adjust UP007/target-version in lint config). As per coding guidelines, please confirm 3.9 compatibility.

🛠️ Suggested 3.9-safe adjustment
     async def __aexit__(
-        self, exc_type: type | None, exc_val: Exception | None, exc_tb: Any
+        self, exc_type: Optional[type], exc_val: Optional[Exception], exc_tb: Any
     ) -> None:

Also applies to: 60-61

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

103-113: Fix NOT_GIVEN fallbacks for LiveKit credentials

NOT_GIVEN is truthy, so the current or defaults can short‑circuit and skip env fallbacks, and the subsequent if not ... checks won’t catch missing values. Use utils.is_given() to resolve values before validation.

🛠️ Proposed fix
-        livekit_url = livekit_url or (os.getenv("LIVEKIT_URL") or NOT_GIVEN)
-        livekit_api_key = livekit_api_key or (os.getenv("LIVEKIT_API_KEY") or NOT_GIVEN)
-        livekit_api_secret = livekit_api_secret or (
-            os.getenv("LIVEKIT_API_SECRET") or NOT_GIVEN
-        )
+        livekit_url = (
+            livekit_url
+            if utils.is_given(livekit_url) and livekit_url
+            else os.getenv("LIVEKIT_URL")
+        )
+        livekit_api_key = (
+            livekit_api_key
+            if utils.is_given(livekit_api_key) and livekit_api_key
+            else os.getenv("LIVEKIT_API_KEY")
+        )
+        livekit_api_secret = (
+            livekit_api_secret
+            if utils.is_given(livekit_api_secret) and livekit_api_secret
+            else os.getenv("LIVEKIT_API_SECRET")
+        )
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fb48ed and dde4de8.

📒 Files selected for processing (3)
  • examples/avatar_agents/README.md
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/avatar_agents/README.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Follow the Plugin System pattern where plugins in livekit-plugins/ are separate packages registered via the Plugin base class
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Applies to **/*.py : Ensure Python 3.9+ compatibility

Applied to files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
🧬 Code graph analysis (1)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (3)
livekit-agents/livekit/agents/_exceptions.py (2)
  • APIConnectionError (84-88)
  • APIStatusError (45-81)
livekit-agents/livekit/agents/types.py (1)
  • APIConnectOptions (54-88)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
🪛 GitHub Check: ruff
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py

[failure] 42-42: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:42:18: UP007 Use X | Y for type annotations

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: type-check (3.9)
  • GitHub Check: type-check (3.13)
  • GitHub Check: unit-tests
🔇 Additional comments (2)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (1)

66-97: LGTM: start_session payload assembly and validation

The utils.is_given checks and payload construction look solid.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

92-96: LGTM: lazy session initialization

Using the shared http_context session here is clean and consistent.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py`:
- Around line 98-152: The _post method's docstring incorrectly references an
endpoint argument that doesn't exist; update the docstring in async def
_post(self, payload: dict[str, Any]) to remove the "endpoint" entry and document
only the actual parameters (payload), return value, and raised exceptions (e.g.
APIConnectionError, APIStatusError) so the doc matches the function signature
and behavior.
- Around line 66-96: In start_session, validate self._avatar_id before
constructing payload: check utils.is_given(self._avatar_id) (or equivalent) and
raise AvatarioException with a clear message if it's NOT_GIVEN so the default
sentinel is not included in the JSON request; reference the start_session method
and self._avatar_id to locate the change and ensure the payload only uses a real
avatar id.

In `@livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py`:
- Around line 1-23: Reorder the imports at the top of the module to satisfy ruff
I001: group and sort standard library imports (from __future__, os, typing,
dataclasses), then third-party packages (aiohttp, livekit and its submodules),
then local package imports (from .api import AvatarioAPI, AvatarioException and
from .log import logger); ensure related symbol imports like
DataStreamAudioOutput and ATTRIBUTE_PUBLISH_ON_BEHALF remain with their livekit
package imports, and run ruff/format (or apply the project's import sorting
tool) to automatically fix ordering.
♻️ Duplicate comments (1)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (1)

99-152: Fix NOT_GIVEN handling for LiveKit credentials.
NOT_GIVEN is truthy, so the current or chain skips env fallbacks and can pass the sentinel into AccessToken, which breaks auth. Use utils.is_given() to decide when to fall back.

🛠️ Proposed fix
-        livekit_url = livekit_url or (os.getenv("LIVEKIT_URL") or NOT_GIVEN)
-        livekit_api_key = livekit_api_key or (os.getenv("LIVEKIT_API_KEY") or NOT_GIVEN)
-        livekit_api_secret = livekit_api_secret or (
-            os.getenv("LIVEKIT_API_SECRET") or NOT_GIVEN
-        )
+        livekit_url = (
+            livekit_url
+            if utils.is_given(livekit_url) and livekit_url
+            else os.getenv("LIVEKIT_URL")
+        )
+        livekit_api_key = (
+            livekit_api_key
+            if utils.is_given(livekit_api_key) and livekit_api_key
+            else os.getenv("LIVEKIT_API_KEY")
+        )
+        livekit_api_secret = (
+            livekit_api_secret
+            if utils.is_given(livekit_api_secret) and livekit_api_secret
+            else os.getenv("LIVEKIT_API_SECRET")
+        )
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dde4de8 and 8f66e31.

📒 Files selected for processing (2)
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Format code with ruff
Run ruff linter and auto-fix issues
Run mypy type checker in strict mode
Maintain line length of 100 characters maximum
Ensure Python 3.9+ compatibility
Use Google-style docstrings

Files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🧠 Learnings (1)
📚 Learning: 2026-01-16T07:44:56.353Z
Learnt from: CR
Repo: livekit/agents PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-16T07:44:56.353Z
Learning: Applies to **/*.py : Ensure Python 3.9+ compatibility

Applied to files:

  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py
  • livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py
🧬 Code graph analysis (2)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (3)
livekit-agents/livekit/agents/_exceptions.py (2)
  • APIConnectionError (84-88)
  • APIStatusError (45-81)
livekit-agents/livekit/agents/types.py (1)
  • APIConnectOptions (54-88)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (4)
livekit-agents/livekit/agents/job.py (2)
  • api (276-284)
  • get_job_context (56-63)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (3)
  • AvatarioAPI (28-152)
  • AvatarioException (21-22)
  • start_session (66-96)
livekit-agents/livekit/agents/utils/misc.py (1)
  • is_given (25-26)
livekit-agents/livekit/agents/utils/http_context.py (1)
  • http_session (40-51)
🪛 GitHub Check: ruff
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py

[failure] 117-117: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:117:19: UP007 Use X | Y for type annotations


[failure] 61-61: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:61:50: UP007 Use X | Y for type annotations


[failure] 61-61: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:61:25: UP007 Use X | Y for type annotations


[failure] 42-42: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py:42:18: UP007 Use X | Y for type annotations

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py

[failure] 67-67: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py:67:29: UP007 Use X | Y for type annotations


[failure] 37-37: Ruff (UP007)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py:37:32: UP007 Use X | Y for type annotations


[failure] 1-23: Ruff (I001)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py:1:1: I001 Import block is un-sorted or un-formatted

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: type-check (3.9)
  • GitHub Check: type-check (3.13)
  • GitHub Check: unit-tests
🔇 Additional comments (6)
livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/api.py (3)

21-25: Clear exception type and default endpoint constant.


35-54: Initialization wiring looks good.


55-64: Context manager lifecycle is clean.

livekit-plugins/livekit-plugins-avatario/livekit/plugins/avatario/avatar.py (3)

33-37: VideoInfo defaults look good.


39-92: Initialization and env fallbacks are clean.


93-97: HTTP session initialization is straightforward.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@Saksham209
Copy link
Contributor Author

Hi @tinalenguyen I have made the required changes you requested. Please let me know if there is anything else needed

@tinalenguyen
Copy link
Member

thanks for iterating, can you run ruff format and ruff check --fix for the edited files

@Saksham209
Copy link
Contributor Author

Saksham209 commented Jan 23, 2026

The ruff checks that are failing are in places where CodeRabbit is identifying them as a problem. For example it mentions using Optional[str] instead of str | None and ruff expects the latter causing a conflict. Should i ignore this warning from CodeRabbit and stick with ruff based instead?

@Saksham209
Copy link
Contributor Author

@tinalenguyen I have merged the ruff based changes and its passing, can we merge this PR now?

Copy link
Member

@tinalenguyen tinalenguyen left a comment

Choose a reason for hiding this comment

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

thank you for creating this PR and iterating! looks good to me, could you just commit the typo fix? and then this plugin can be included in the next release. if possible, do you have a smaller logo to be included in our docs website?

Co-authored-by: Tina Nguyen <[email protected]>
@tinalenguyen tinalenguyen merged commit 537310b into livekit:main Jan 28, 2026
10 checks passed
@Saksham209
Copy link
Contributor Author

Saksham209 commented Jan 29, 2026

avatario_logo

@tinalenguyen this is the logo for avatario

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.

5 participants