Skip to content

feat: add facemarket live avatar plugin#5686

Open
wuguangmou wants to merge 4 commits intolivekit:mainfrom
wuguangmou:main
Open

feat: add facemarket live avatar plugin#5686
wuguangmou wants to merge 4 commits intolivekit:mainfrom
wuguangmou:main

Conversation

@wuguangmou
Copy link
Copy Markdown

livekit-plugins-facemarket is a lightweight Avatar Plugin for LiveKit Agents.

It is designed for the narrow integration model confirmed for this project:

  • LiveKit Agents users only
  • caller owns STT / LLM / TTS
  • plugin is responsible for avatar session orchestration and signaling
  • FaceMarket backend is responsible for starting renderer/coordinator participants

devin-ai-integration[bot]

This comment was marked as resolved.

…emarket/api.py


fix code from devin review options

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…emarket/api.py

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…emarket/api.py

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
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 2 new potential issues.

View 8 additional findings in Devin Review.

Open in Devin Review

Comment on lines +133 to +134
except FaceMarketPlatformError:
raise
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.

🟑 HTTP 5xx server errors bypass the retry mechanism entirely

_decode_response raises FaceMarketPlatformError for all HTTP status codes >= 400, including transient server errors like 502/503/504 (api.py:152-160). In the retry loop, FaceMarketPlatformError is caught and immediately re-raised (api.py:133-134), completely bypassing the retry logic. Only aiohttp.ClientError and asyncio.TimeoutError are retried. This means the retry mechanism (configured via DEFAULT_RETRIES = 2) is ineffective for transient server-side failures, which are exactly the kind of errors retries are meant to handle.

Prompt for agents
In api.py _request_json method (lines 119-141), the except FaceMarketPlatformError: raise clause on lines 133-134 immediately re-raises ALL platform errors, including retryable HTTP 5xx errors. The _decode_response method (lines 143-160) converts all HTTP >= 400 responses into FaceMarketPlatformError, making no distinction between 4xx (client errors, non-retryable) and 5xx (server errors, typically retryable).

To fix this, consider one of these approaches:
1. In _decode_response, raise a retryable subclass of FaceMarketPlatformError for 5xx status codes. Then in _request_json, only re-raise the non-retryable subclass immediately.
2. Alternatively, in _request_json, check the HTTP status from the exception before deciding to re-raise or retry. For example, attach the status code to FaceMarketPlatformError and check if status >= 500 before retrying.

The relevant methods are FaceMarketAPI._request_json (line 106) and FaceMarketAPI._decode_response (line 143) in api.py.
Open in Devin Review

Was this helpful? React with πŸ‘ or πŸ‘Ž to provide feedback.

Comment on lines +291 to +292
if participant_identity not in (None, COORDINATOR_IDENTITY):
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.

🟑 Data packet handler processes packets from unidentified participants (identity=None)

The _handle_data_packet method at avatar.py:291 accepts data packets where participant_identity is None (i.e., participant_identity not in (None, COORDINATOR_IDENTITY) passes when identity is None). This means data packets from any source without a resolved participant identity are processed as if they came from the coordinator. Any room participant could craft JSON data packets with events like session.stop (triggering full session shutdown at line 327), system.idleTrigger (switching to prompt mode at line 322), or error (emitting error callbacks at line 331). The filter should require the identity to specifically match COORDINATOR_IDENTITY rather than also accepting None.

Suggested change
if participant_identity not in (None, COORDINATOR_IDENTITY):
return
if participant_identity != COORDINATOR_IDENTITY:
return
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.

1 participant