Skip to content

Commit be39ea4

Browse files
plutolessclaude
andcommitted
feat: export global vendor types at top-level; add agora_agent.cn module
Global vendor classes now resolve to real types via the top-level TYPE_CHECKING block, so `from agora_agent import DeepgramSTT` gives IDE autocomplete (was Any). CN vendors get a dedicated `agora_agent.cn` module (natural names), which also resolves the MicrosoftSTT/MicrosoftTTS/MiniMaxTTS collisions. SpatiusAvatar (CN) is now cn-only; XaiGrok/GenericAvatar demoted to TYPE_CHECKING-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent d7304ea commit be39ea4

5 files changed

Lines changed: 119 additions & 16 deletions

File tree

.fernignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Specify files that shouldn't be modified by Fern
22
src/agora_agent/pool_client.py
33
src/agora_agent/__init__.py
4+
src/agora_agent/cn.py
45
src/agora_agent/core/domain.py
56
changelog.md
67

docs/guides/avatars.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ agent = (
132132
`SpatiusAvatar` is available for `Area.CN` sessions. Provide `spatius_api_key`, `spatius_app_id`, `spatius_avatar_id`, and `agora_uid` when constructing the avatar. `agora_token` is optional and is generated at session start when omitted, like SenseTime and Generic avatars.
133133

134134
```python
135-
from agora_agent import Agora, Area, CNAgent, GenericTTS, SpatiusAvatar, TencentSTT
135+
from agora_agent import Agora, Area, CNAgent, GenericTTS
136+
from agora_agent.cn import SpatiusAvatar, TencentSTT
136137

137138
client = Agora(
138139
area=Area.CN,

src/agora_agent/__init__.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,57 @@
2020
AgentSessionOptions,
2121
CNAgent,
2222
GlobalAgent,
23-
GenericAvatar,
24-
SpatiusAvatar,
2523
RegionalAgent,
26-
XaiGrok,
2724
generate_rtc_token,
2825
GenerateTokenOptions,
26+
# Global (non-CN) vendor classes — re-exported from agentkit for static typing so
27+
# `from agora_agent import DeepgramSTT` autocompletes. Runtime resolution and
28+
# `__all__` membership come from the `__getattr__` fallback + the `__all__` union
29+
# below, so these need no `_dynamic_imports` / `_ROOT_ALL` entries.
30+
# CN vendors are intentionally not here — import them from `agora_agent.cn`.
31+
AkoolAvatar,
32+
AmazonBedrock,
33+
AmazonSTT,
34+
AmazonTTS,
35+
AnamAvatar,
36+
Anthropic,
37+
AresSTT,
38+
AssemblyAISTT,
39+
AzureOpenAI,
40+
CartesiaTTS,
41+
CustomLLM,
42+
DeepgramSTT,
43+
DeepgramTTS,
44+
Dify,
45+
ElevenLabsTTS,
46+
FishAudioTTS,
47+
Gemini,
48+
GeminiLive,
49+
GenericAvatar,
50+
GenericTTS,
51+
GoogleSTT,
52+
GoogleTTS,
53+
Groq,
54+
HeyGenAvatar,
55+
HumeAITTS,
56+
LiveAvatarAvatar,
57+
MicrosoftSTT,
58+
MicrosoftTTS,
59+
MiniMaxTTS,
60+
MurfTTS,
61+
OpenAI,
62+
OpenAIRealtime,
63+
OpenAISTT,
64+
OpenAITTS,
65+
RimeTTS,
66+
SarvamSTT,
67+
SarvamTTS,
68+
SpeechmaticsSTT,
69+
VertexAI,
70+
VertexAILLM,
71+
XaiGrok,
72+
XaiSTT,
73+
XaiTTS,
2974
)
3075
from .agentkit.agent_session import AsyncAgentSession
3176

@@ -39,9 +84,6 @@
3984
"AsyncAgentSession": ".agentkit.agent_session",
4085
"AsyncAgora": ".pool_client",
4186
"AsyncAgentClient": ".pool_client",
42-
"GenericAvatar": ".agentkit",
43-
"SpatiusAvatar": ".agentkit",
44-
"XaiGrok": ".agentkit",
4587
"GenerateTokenOptions": ".agentkit",
4688
"__version__": ".version",
4789
"agentkit": ".agentkit",
@@ -63,9 +105,6 @@
63105
"AsyncAgentSession",
64106
"AsyncAgora",
65107
"AsyncAgentClient",
66-
"GenericAvatar",
67-
"SpatiusAvatar",
68-
"XaiGrok",
69108
"GenerateTokenOptions",
70109
"Pool",
71110
"__version__",

src/agora_agent/cn.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# isort: skip_file
2+
"""China (CN) vendor classes for the Agora Conversational AI SDK.
3+
4+
Import CN vendors explicitly from this module so they stay separate from the global
5+
top-level namespace::
6+
7+
from agora_agent.cn import AliyunLLM, MiniMaxTTS, TencentSTT
8+
9+
``MicrosoftSTT`` / ``MicrosoftTTS`` / ``MiniMaxTTS`` here are the CN variants; the
10+
global variants of those names are available from the top-level package
11+
(e.g. ``from agora_agent import MiniMaxTTS``).
12+
"""
13+
14+
from .agentkit.vendors.cn import (
15+
AliyunLLM,
16+
BytedanceDuplexTTS,
17+
BytedanceLLM,
18+
BytedanceTTS,
19+
CosyVoiceTTS,
20+
DeepSeekLLM,
21+
FengmingSTT,
22+
MicrosoftSTT,
23+
MicrosoftTTS,
24+
MiniMaxTTS,
25+
SenseTimeAvatar,
26+
SpatiusAvatar,
27+
StepFunTTS,
28+
TencentLLM,
29+
TencentSTT,
30+
TencentTTS,
31+
XfyunBigModelSTT,
32+
XfyunDialectSTT,
33+
XfyunSTT,
34+
)
35+
36+
__all__ = [
37+
# STT
38+
"FengmingSTT",
39+
"MicrosoftSTT",
40+
"TencentSTT",
41+
"XfyunBigModelSTT",
42+
"XfyunDialectSTT",
43+
"XfyunSTT",
44+
# TTS
45+
"BytedanceDuplexTTS",
46+
"BytedanceTTS",
47+
"CosyVoiceTTS",
48+
"MicrosoftTTS",
49+
"MiniMaxTTS",
50+
"StepFunTTS",
51+
"TencentTTS",
52+
# LLM
53+
"AliyunLLM",
54+
"BytedanceLLM",
55+
"DeepSeekLLM",
56+
"TencentLLM",
57+
# Avatar
58+
"SenseTimeAvatar",
59+
"SpatiusAvatar",
60+
]

tests/custom/test_llm_vendors.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,28 +128,30 @@ def test_dify_serializes_conversation_fields() -> None:
128128

129129

130130
def test_llm_vendors_reject_missing_required_models() -> None:
131+
# These intentionally omit the required `model` to assert it raises; the top-level
132+
# vendor types are now real, so mypy needs the call-arg ignores.
131133
with pytest.raises(Exception, match="model"):
132-
OpenAI(api_key="openai-key", base_url="https://api.openai.com/v1/chat/completions")
134+
OpenAI(api_key="openai-key", base_url="https://api.openai.com/v1/chat/completions") # type: ignore[call-arg]
133135

134136
with pytest.raises(Exception, match="model"):
135-
Anthropic(
137+
Anthropic( # type: ignore[call-arg]
136138
api_key="anthropic-key",
137139
url="https://api.anthropic.com/v1/messages",
138140
headers={"anthropic-version": "2023-06-01"},
139141
max_tokens=1024,
140142
)
141143

142144
with pytest.raises(Exception, match="model"):
143-
Gemini(api_key="google-key")
145+
Gemini(api_key="google-key") # type: ignore[call-arg]
144146

145147
with pytest.raises(Exception, match="model"):
146-
Groq(api_key="groq-key", base_url="https://api.groq.com/openai/v1/chat/completions")
148+
Groq(api_key="groq-key", base_url="https://api.groq.com/openai/v1/chat/completions") # type: ignore[call-arg]
147149

148150
with pytest.raises(Exception, match="model"):
149-
VertexAILLM(api_key="vertex-token", project_id="project", location="us-central1")
151+
VertexAILLM(api_key="vertex-token", project_id="project", location="us-central1") # type: ignore[call-arg]
150152

151153
with pytest.raises(Exception, match="model"):
152-
AmazonBedrock(access_key="aws-access", secret_key="aws-secret", region="us-east-1")
154+
AmazonBedrock(access_key="aws-access", secret_key="aws-secret", region="us-east-1") # type: ignore[call-arg]
153155

154156

155157
def test_openai_managed_mode_is_restricted_to_supported_models() -> None:

0 commit comments

Comments
 (0)