chore: push remaining local changes

This commit is contained in:
Yera All
2026-04-16 02:31:57 +05:00
parent 5af47991dc
commit 1206ff91ac
2 changed files with 67 additions and 1 deletions
+17 -1
View File
@@ -213,6 +213,16 @@ def ai_voice_queue_config() -> dict[str, dict[str, Any]]:
return result
def _legacy_voice_start_profile(queue_code: str, *, stage: str | None, agent_profile: str) -> tuple[str | None, str]:
if stage or agent_profile != "voice_support":
return stage, agent_profile
# Backward compatibility for deployed IVR AI queues that predate the
# explicit voice_start stage/profile fields.
if queue_code.startswith("ivr_") and "_ai_" in queue_code:
return "voice_start", "voice_start"
return stage, agent_profile
def ai_voice_config_for_queue(queue_code: str | None) -> dict[str, Any] | None:
key = str(queue_code or "").strip()
if not key or not ai_voice_enabled():
@@ -223,6 +233,12 @@ def ai_voice_config_for_queue(queue_code: str | None) -> dict[str, Any] | None:
if str(item.get("mode") or "ai_first").strip().lower() != "ai_first":
return None
stage = str(item.get("stage") or "").strip() or None
agent_profile = str(item.get("agent_profile") or "voice_support").strip() or "voice_support"
stage, agent_profile = _legacy_voice_start_profile(
key,
stage=stage,
agent_profile=agent_profile,
)
next_queue_code = str(item.get("next_queue_code") or "").strip() or None
next_queue_id = str(item.get("next_queue_id") or "").strip() or None
handoff_queue_code = str(item.get("handoff_queue_code") or next_queue_code or key).strip() or key
@@ -234,7 +250,7 @@ def ai_voice_config_for_queue(queue_code: str | None) -> dict[str, Any] | None:
return {
"queue_code": key,
"mode": "ai_first",
"agent_profile": str(item.get("agent_profile") or "voice_support").strip() or "voice_support",
"agent_profile": agent_profile,
"language": str(item.get("language") or "").strip() or None,
"stage": stage,
"next_queue_code": next_queue_code,
+50
View File
@@ -104,6 +104,56 @@ def test_browser_softphone_config_route_returns_403_when_mapping_missing(monkeyp
assert response.json()["detail"] == "Browser softphone is not configured for this user"
def test_ai_voice_config_for_queue_promotes_legacy_ivr_ai_queues_to_voice_start(monkeypatch):
monkeypatch.setenv("AI_VOICE_ENABLED", "1")
monkeypatch.setenv(
"AI_VOICE_QUEUE_CONFIG_JSON",
json.dumps(
{
"ivr_support_ai_ru": {
"mode": "ai_first",
"agent_profile": "voice_support",
"handoff_queue_code": "ivr_support",
"language": "ru",
}
}
),
)
monkeypatch.setenv("ASTERISK_QUEUE_MAP_JSON", '{"ivr_support":"que_ivr_support"}')
config = bridge_module._ai_voice_config_for_queue("ivr_support_ai_ru")
assert config is not None
assert config["agent_profile"] == "voice_start"
assert config["stage"] == "voice_start"
assert config["handoff_queue_id"] == "que_ivr_support"
def test_ai_voice_config_for_queue_preserves_non_ivr_profiles(monkeypatch):
monkeypatch.setenv("AI_VOICE_ENABLED", "1")
monkeypatch.setenv(
"AI_VOICE_QUEUE_CONFIG_JSON",
json.dumps(
{
"voice_lab_ai": {
"mode": "ai_first",
"agent_profile": "voice_support",
"handoff_queue_code": "voice_lab",
"language": "ru",
}
}
),
)
monkeypatch.setenv("ASTERISK_QUEUE_MAP_JSON", '{"voice_lab":"que_voice_lab"}')
config = bridge_module._ai_voice_config_for_queue("voice_lab_ai")
assert config is not None
assert config["agent_profile"] == "voice_support"
assert config["stage"] is None
assert config["handoff_queue_id"] == "que_voice_lab"
def test_post_json_bearer_first_falls_back_to_legacy(monkeypatch):
class DummyResponse:
def __init__(self, status_code: int, body: dict):