Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/concepts/vendors.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Used with `agent.with_avatar()` in the cascading ASR + LLM + TTS pipeline. Some
| `HeyGenAvatar` | HeyGen (deprecated alias) | `api_key`, `quality`, `agora_uid` | 24000 Hz |
| `LiveAvatarAvatar` | LiveAvatar | `api_key`, `quality`, `agora_uid` | 24000 Hz |
| `AkoolAvatar` | Akool | `api_key` | 16000 Hz |
| `AnamAvatar` | Anam | `api_key` | None |
| `AnamAvatar` | Anam | `api_key`, `avatar_id` | None |
| `GenericAvatar` | Generic Avatar | `api_key`, `api_base_url`, `avatar_id`, `agora_uid` | None |
| `SenseTimeAvatar` | SenseTime (CN) | `agora_uid`, `app_key`, `sceneList` | None |
| `SpatiusAvatar` | Spatius (CN) | `spatius_api_key`, `spatius_app_id`, `spatius_avatar_id`, `agora_uid` | Optional avatar-declared sample rate |
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/vendors.md
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ Same options as `HeyGenAvatar`, but serializes `vendor: "liveavatar"`. `agora_to
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `api_key` | `str` | Yes | — | Anam API key |
| `persona_id` | `str` | No | `None` | Persona ID |
| `avatar_id` | `str` | Yes | | Anam avatar ID |
| `enable` | `bool` | No | `True` | Enable or disable the avatar |

### `GenericAvatar`
Expand Down
2 changes: 2 additions & 0 deletions src/agora_agent/agentkit/avatar_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ def validate_avatar_config(
params = config.get("params", {})
if not params.get("api_key"):
raise ValueError("Anam avatar requires api_key")
if not params.get("avatar_id"):
raise ValueError("Anam avatar requires avatar_id")
elif is_generic_avatar(config):
params = config.get("params", {})
if not params.get("api_key"):
Expand Down
5 changes: 2 additions & 3 deletions src/agora_agent/agentkit/vendors/avatar.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class AnamAvatarOptions(BaseModel):
model_config = ConfigDict(extra="forbid")

api_key: str = Field(..., description="Anam API key")
persona_id: Optional[str] = Field(default=None, description="Anam persona ID")
avatar_id: str = Field(..., description="Anam avatar ID")
enable: Optional[bool] = Field(default=None, description="Enable avatar (default: true)")
additional_params: Optional[Dict[str, Any]] = Field(default=None, description="Additional vendor-specific parameters")

Expand All @@ -197,10 +197,9 @@ def required_sample_rate(self) -> int:
def to_config(self) -> Dict[str, Any]:
params: Dict[str, Any] = {
"api_key": self.options.api_key,
"avatar_id": self.options.avatar_id,
}

if self.options.persona_id is not None:
params["persona_id"] = self.options.persona_id
if self.options.additional_params is not None:
params = {**self.options.additional_params, **params}

Expand Down
22 changes: 22 additions & 0 deletions tests/custom/test_agentkit_vendors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from agora_agent.agentkit import LlmGreetingConfigs
from agora_agent.agentkit.vendors import (
AnamAvatar,
GenericAvatar,
GenericTTS,
OpenAI,
Expand Down Expand Up @@ -70,6 +71,27 @@ def test_generic_avatar_omits_session_enriched_fields_when_unset():
}


def test_anam_avatar_serializes_avatar_id() -> None:
config = AnamAvatar(
api_key="anam-key",
avatar_id="anam-avatar-1",
).to_config()

assert config == {
"enable": True,
"vendor": "anam",
"params": {
"api_key": "anam-key",
"avatar_id": "anam-avatar-1",
},
}


def test_anam_avatar_requires_avatar_id() -> None:
with pytest.raises(ValidationError):
AnamAvatar(api_key="anam-key")


def test_vertex_ai_explicit_fields_override_additional_params():
from agora_agent.agentkit.vendors import VertexAI

Expand Down
36 changes: 36 additions & 0 deletions tests/custom/test_anam_avatar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

from agora_agent.agentkit import validate_avatar_config
from agora_agent.agentkit.avatar_types import is_anam_avatar
from agora_agent.agentkit.vendors import AnamAvatar


def test_anam_avatar_to_config_shape() -> None:
config = AnamAvatar(
api_key="anam-key",
avatar_id="anam-avatar",
).to_config()

assert config == {
"enable": True,
"vendor": "anam",
"params": {
"api_key": "anam-key",
"avatar_id": "anam-avatar",
},
}
assert is_anam_avatar(config)


@pytest.mark.parametrize(
("params", "message"),
[
({}, "Anam avatar requires api_key"),
({"api_key": "key"}, "Anam avatar requires avatar_id"),
],
)
def test_validate_avatar_config_rejects_incomplete_anam(
params: dict, message: str
) -> None:
with pytest.raises(ValueError, match=message):
validate_avatar_config({"vendor": "anam", "params": params})
Loading