diff --git a/docs/concepts/vendors.md b/docs/concepts/vendors.md index b82c2d7..86a7630 100644 --- a/docs/concepts/vendors.md +++ b/docs/concepts/vendors.md @@ -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 | diff --git a/docs/reference/vendors.md b/docs/reference/vendors.md index 697109e..8e9801f 100644 --- a/docs/reference/vendors.md +++ b/docs/reference/vendors.md @@ -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` diff --git a/src/agora_agent/agentkit/avatar_types.py b/src/agora_agent/agentkit/avatar_types.py index 9d565fa..2c362d3 100644 --- a/src/agora_agent/agentkit/avatar_types.py +++ b/src/agora_agent/agentkit/avatar_types.py @@ -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"): diff --git a/src/agora_agent/agentkit/vendors/avatar.py b/src/agora_agent/agentkit/vendors/avatar.py index 50bdd08..7bbd8dc 100644 --- a/src/agora_agent/agentkit/vendors/avatar.py +++ b/src/agora_agent/agentkit/vendors/avatar.py @@ -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") @@ -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} diff --git a/tests/custom/test_agentkit_vendors.py b/tests/custom/test_agentkit_vendors.py index c78f32b..8dd79c4 100644 --- a/tests/custom/test_agentkit_vendors.py +++ b/tests/custom/test_agentkit_vendors.py @@ -3,6 +3,7 @@ from agora_agent.agentkit import LlmGreetingConfigs from agora_agent.agentkit.vendors import ( + AnamAvatar, GenericAvatar, GenericTTS, OpenAI, @@ -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 diff --git a/tests/custom/test_anam_avatar.py b/tests/custom/test_anam_avatar.py new file mode 100644 index 0000000..a4fa395 --- /dev/null +++ b/tests/custom/test_anam_avatar.py @@ -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})