fix: reject misrouted smallwebrtc runs on the telephony websocket (#468)

* fix: reject misrouted smallwebrtc runs on the telephony websocket

A smallwebrtc (browser/WebRTC) workflow run is established through the WebRTC
signaling endpoint, not the PSTN telephony websocket. When such a run reached
_handle_telephony_websocket it read no "provider" from initial_context and
closed with an opaque "Provider type not found". Detect smallwebrtc runs and
close with a clear reason pointing to the signaling endpoint, without setting
the run to running or invoking a telephony provider. Also store the provider on
smallwebrtc runs at creation so they are self-describing, and make the generic
no-provider close reason include the run id and mode.

Closes #433

* fix: merge workflow run initial context defaults

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
This commit is contained in:
Matt Van Horn 2026-06-26 07:07:40 -07:00 committed by GitHub
parent faa73427c6
commit 3309face2c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 5 deletions

View file

@ -21,7 +21,7 @@ from starlette.websockets import WebSocketDisconnect
from api.db import db_client
from api.db.models import UserModel
from api.enums import CallType, WorkflowRunState
from api.enums import CallType, WorkflowRunMode, WorkflowRunState
from api.errors.telephony_errors import TelephonyError
from api.sdk_expose import sdk_expose
from api.services.auth.depends import get_user
@ -584,12 +584,36 @@ async def _handle_telephony_websocket(
provider_type = workflow_run.initial_context.get("provider")
logger.info(f"Extracted provider_type: {provider_type}")
if (
workflow_run.mode == WorkflowRunMode.SMALLWEBRTC.value
or provider_type == WorkflowRunMode.SMALLWEBRTC.value
):
logger.warning(
f"SmallWebRTC workflow run {workflow_run_id} reached telephony "
f"websocket; mode={workflow_run.mode}, provider={provider_type}"
)
await websocket.close(
code=4400,
reason=(
"smallwebrtc runs connect through the WebRTC signaling endpoint, "
"not the telephony websocket"
),
)
return
if not provider_type:
logger.error(
f"No provider type found in workflow run {workflow_run_id}. "
f"gathered_context: {workflow_run.gathered_context}, mode: {workflow_run.mode}"
)
await websocket.close(code=4400, reason="Provider type not found")
await websocket.close(
code=4400,
reason=(
f"No provider type found for workflow run {workflow_run_id} "
f"(mode: {workflow_run.mode}); telephony websocket requires "
"a telephony provider"
),
)
return
logger.info(