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/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ agent = Agent(client=client).with_llm(
| `rtc` | `RtcConfig` | No | RTC media encryption |
| `filler_words` | `FillerWordsConfig` | No | Filler words while waiting for LLM |

When `client` is provided, `Agent(client=...)` returns `CNAgent` for `Area.CN` and `GlobalAgent` for global areas.
When `client` is provided, `Agent(client=...)` returns `CNAgent` for `Area.CN` and `GlobalAgent` for global areas. If `with_stt()` is omitted, the bound client also determines the default ASR vendor: `Fengming` for `Area.CN`, otherwise `Ares`.

## Builder Methods

Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/vendors.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ tts = ElevenLabsTTS(

Used with `agent.with_stt()`.

Use `turn_detection.language` for Agora interaction language; it defaults to `en-US`. STT vendor `language` options are serialized under `asr.params` using each provider's own format. Ares does not take a provider language option; AgentKit uses `turn_detection.language` for REST `asr.language`.
Use `turn_detection.language` for Agora interaction language; it defaults to `en-US`. STT vendor `language` options are serialized under `asr.params` using each provider's own format. If `with_stt()` is omitted, AgentKit defaults to `AresSTT` for global clients and `FengmingSTT` for `Area.CN` clients. Ares does not take a provider language option; AgentKit uses `turn_detection.language` for REST `asr.language`.

| Class | Provider | Required Parameters |
|---|---|---|
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/regional-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ client = Agora(
## Recommended vendors by area

Bind `client` into `Agent(client=client, ...)` and construct vendors directly with SDK classes. The bound client selects `CNAgent` or `GlobalAgent` for IDE hints based on `area`, but does not restrict which vendor classes you can configure.
If you omit `with_stt()`, AgentKit uses `FengmingSTT` by default for `Area.CN` clients and `AresSTT` for global clients.

| Client area | STT classes | LLM classes | TTS classes | Avatar classes |
|---|---|---|---|---|
Expand Down Expand Up @@ -125,6 +126,7 @@ agent = Agent(client=client, turn_detection={"language": "zh-CN"})
```

`Agent(client=...)` returns `CNAgent` for `Area.CN` and `GlobalAgent` for global areas. A bound `client` is required. The SDK does not reject mismatched vendor classes at build time or session start.
The same bound client also controls the default ASR vendor when `with_stt()` is omitted.

## How the domain pool works

Expand Down
1 change: 1 addition & 0 deletions docs/reference/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ description: Full API reference for the Python Agent builder class.
**Import:** `from agora_agent import Agent, CNAgent, GlobalAgent`

Bind the client on every `Agent` builder via `Agent(client=client, ...)`, then pass vendor classes directly. The bound client sets the API routing region and provides area-specific IDE hints via `CNAgent` / `GlobalAgent`:
it also selects the default ASR vendor when `with_stt()` is omitted (`Fengming` for `Area.CN`, otherwise `Ares`).

> **`client` is required.** `create_session()` and `create_async_session()` raise `ValueError` if no client was bound on the agent.

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/vendors.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ The SDK also includes named helpers for the remaining Agora-supported LLM provid

## STT Vendors

Use `turn_detection.language` for Agora interaction language; it defaults to `en-US`. Provider-specific language values remain under `asr.params` and may use a different format. AgentKit populates REST `asr.language` from `turn_detection.language`.
Use `turn_detection.language` for Agora interaction language; it defaults to `en-US`. Provider-specific language values remain under `asr.params` and may use a different format. If `with_stt()` is omitted, AgentKit defaults to `AresSTT` for global clients and `FengmingSTT` for `Area.CN` clients. AgentKit populates REST `asr.language` from `turn_detection.language`.

### `SpeechmaticsSTT`

Expand Down
3 changes: 2 additions & 1 deletion src/agora_agent/agentkit/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,8 @@ def _resolve_llm_config(self) -> typing.Dict[str, typing.Any]:
def _resolve_asr_config(self, turn_detection_config: TurnDetectionInput) -> typing.Dict[str, typing.Any]:
asr_config = dict(self._stt or {})
if not asr_config:
asr_config["vendor"] = "ares"
area_scope = getattr(self._client, "area_scope", None)
asr_config["vendor"] = "fengming" if area_scope == "cn" else "ares"
asr_config["language"] = self._field_value(turn_detection_config, "language")
return asr_config

Expand Down
22 changes: 22 additions & 0 deletions tests/custom/test_regional_vendors.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,28 @@ def test_agent_constructor_auto_selects_area_aware_subclass() -> None:
assert global_agent.__class__.__name__ == "GlobalAgent"


def test_default_asr_vendor_is_area_aware_when_with_stt_is_omitted() -> None:
cn_properties = Agent(client=_client(Area.CN)).to_properties(
channel="room",
agent_uid="1",
remote_uids=["100"],
token="rtc-token",
allow_missing_vendor_categories={"llm", "tts"},
)
global_properties = Agent(client=_client(Area.US)).to_properties(
channel="room",
agent_uid="1",
remote_uids=["100"],
token="rtc-token",
allow_missing_vendor_categories={"llm", "tts"},
)

assert cn_properties.asr is not None
assert cn_properties.asr.vendor == "fengming"
assert global_properties.asr is not None
assert global_properties.asr.vendor == "ares"


def test_cn_client_allows_global_only_vendor() -> None:
client = _client(Area.CN)
agent = Agent(client=client).with_stt(
Expand Down
13 changes: 13 additions & 0 deletions tests/custom/test_stt_language.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from agora_agent import (
Agent,
Area,
AmazonSTT,
AssemblyAISTT,
DeepgramSTT,
Expand Down Expand Up @@ -85,6 +86,18 @@ def test_default_turn_detection_language_is_sent_without_stt() -> None:
assert props["turn_detection"] == {"language": "en-US"}


def test_default_stt_vendor_depends_on_client_area_when_stt_is_omitted() -> None:
global_props = properties(base_agent())
cn_props = properties(
Agent(test_client(area=Area.CN))
.with_llm(OpenAI(api_key="llm-key", model="gpt-4o-mini", base_url="https://api.openai.com/v1/chat/completions"))
.with_tts(ElevenLabsTTS(key="tts-key", voice_id="voice", model_id="eleven_flash_v2_5", base_url="wss://api.elevenlabs.io/v1"))
)

assert global_props["asr"] == {"vendor": "ares", "language": "en-US"}
assert cn_props["asr"] == {"vendor": "fengming", "language": "en-US"}


def test_stt_vendor_params_match_documented_shapes() -> None:
deepgram_managed = DeepgramSTT(model="nova-3", language="en-US").to_config()
assert "language" not in deepgram_managed
Expand Down
Loading