feat(voice): add admin-configurable elevenlabs tts
This commit is contained in:
@@ -9,13 +9,25 @@ import services.ai_voice_runtime_service.app as runtime_module
|
||||
from services.shared.core import utc_now_iso
|
||||
from services.shared.db import get_session
|
||||
from services.shared.models import VoiceAIStartIn
|
||||
from services.shared.sql_models import VoiceAISessionRow, VoiceTranscriptSegmentRow
|
||||
from services.shared.sql_models import VoiceAISessionRow, VoiceTranscriptSegmentRow, VoiceTTSSettingsRow
|
||||
from services.shared.voice_tts_config import save_voice_tts_config, voice_tts_default_config
|
||||
|
||||
|
||||
def _admin_headers() -> dict[str, str]:
|
||||
return {"X-User": "admin", "X-Role": "admin"}
|
||||
|
||||
|
||||
def _reset_voice_tts_settings() -> None:
|
||||
session = get_session()
|
||||
try:
|
||||
row = session.execute(select(VoiceTTSSettingsRow)).scalar_one_or_none()
|
||||
if row is not None:
|
||||
session.delete(row)
|
||||
session.commit()
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
def test_create_voice_ai_session_records_greeting_without_blocking_on_orchestrator(monkeypatch):
|
||||
allow_start = threading.Event()
|
||||
|
||||
@@ -194,6 +206,60 @@ def test_create_voice_ai_session_records_greeting_without_blocking_on_orchestrat
|
||||
raise AssertionError("background voice-session start did not finish in time")
|
||||
|
||||
|
||||
def test_create_voice_ai_session_uses_database_selected_tts_provider(monkeypatch):
|
||||
_reset_voice_tts_settings()
|
||||
|
||||
session = get_session()
|
||||
try:
|
||||
payload = voice_tts_default_config().model_dump()
|
||||
payload["provider"] = "elevenlabs"
|
||||
save_voice_tts_config(session, payload)
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
def _fake_orchestrator_request(method: str, path: str, *, payload=None, timeout=10.0):
|
||||
assert method == "POST"
|
||||
assert path.endswith("/start")
|
||||
return {
|
||||
"session_id": "ais_voice_tts_runtime",
|
||||
"language": "ru",
|
||||
"greeting_text": "Здравствуйте. Чем помочь?",
|
||||
"disclosure_required": False,
|
||||
}
|
||||
|
||||
monkeypatch.setattr(runtime_module, "_orchestrator_request", _fake_orchestrator_request)
|
||||
|
||||
client = TestClient(runtime_module.app)
|
||||
response = client.post(
|
||||
"/internal/voice-ai/sessions",
|
||||
headers=_admin_headers(),
|
||||
json={
|
||||
"call_id": "call_voice_runtime_tts_provider",
|
||||
"linked_id": "linked_voice_runtime_tts_provider",
|
||||
"interaction_id": "int_voice_runtime_tts_provider",
|
||||
"queue_id": "que_voice_runtime_tts_provider",
|
||||
"caller_number": "+77010000032",
|
||||
"caller_name": "Runtime Caller",
|
||||
"agent_profile": "voice_support",
|
||||
"language_hint": "ru",
|
||||
"handoff_queue_id": "que_voice_runtime_tts_provider",
|
||||
"metadata": {"queue_code": "voice_lab_ai"},
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
session = get_session()
|
||||
try:
|
||||
voice_session = session.execute(
|
||||
select(VoiceAISessionRow).where(VoiceAISessionRow.call_id == "call_voice_runtime_tts_provider")
|
||||
).scalar_one()
|
||||
assert voice_session.tts_provider == "elevenlabs"
|
||||
finally:
|
||||
session.close()
|
||||
_reset_voice_tts_settings()
|
||||
|
||||
|
||||
def test_mark_reply_delivered_finalizes_only_matching_pending_assistant_segment():
|
||||
now = utc_now_iso()
|
||||
session = get_session()
|
||||
|
||||
Reference in New Issue
Block a user