From ebacfaad4ad906c7410c4093c6924e69cf18f5e8 Mon Sep 17 00:00:00 2001 From: Sabiha Khan Date: Tue, 21 Jul 2026 15:48:47 +0530 Subject: [PATCH] fix: save call metadata in gathered context for an api trigger outbound call --- api/routes/public_agent.py | 15 +++++++++++++- api/tests/test_public_agent_routes.py | 30 ++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/api/routes/public_agent.py b/api/routes/public_agent.py index 45263534..4814d6ab 100644 --- a/api/routes/public_agent.py +++ b/api/routes/public_agent.py @@ -320,7 +320,7 @@ async def _execute_resolved_target( # (e.g. Telnyx, Cloudonix); without them the URL contains "None/None" and # the stream connection fails. try: - await provider.initiate_call( + result = await provider.initiate_call( to_number=request.phone_number, webhook_url=webhook_url, workflow_run_id=workflow_run.id, @@ -337,6 +337,19 @@ async def _execute_resolved_target( detail=f"Failed to initiate call: {e}", ) + gathered_context = { + "provider": provider.PROVIDER_NAME, + "triggered_by": "api", + **(result.provider_metadata or {}), + } + if target.identifier_type == "trigger_path": + gathered_context["trigger_uuid"] = target.identifier_value + + await db_client.update_workflow_run( + run_id=workflow_run.id, + gathered_context=gathered_context, + ) + logger.info( f"Call initiated successfully for workflow run {workflow_run.id} " f"via {target.identifier_type}={target.identifier_value}" diff --git a/api/tests/test_public_agent_routes.py b/api/tests/test_public_agent_routes.py index 241f9865..d9336359 100644 --- a/api/tests/test_public_agent_routes.py +++ b/api/tests/test_public_agent_routes.py @@ -45,7 +45,14 @@ def _provider(): PROVIDER_NAME="twilio", WEBHOOK_ENDPOINT="outbound", validate_config=Mock(return_value=True), - initiate_call=AsyncMock(), + initiate_call=AsyncMock( + return_value=SimpleNamespace( + call_id="CA123", + status="queued", + caller_number="+15550000000", + provider_metadata={"call_id": "CA123"}, + ) + ), ) @@ -96,6 +103,7 @@ def test_trigger_route_executes_as_workflow_owner(): return_value=SimpleNamespace(id=55) ) mock_db.create_workflow_run = AsyncMock(return_value=SimpleNamespace(id=501)) + mock_db.update_workflow_run = AsyncMock() response = client.post( "/public/agent/trigger-uuid-123", @@ -135,6 +143,15 @@ def test_trigger_route_executes_as_workflow_owner(): assert initiate_kwargs["workflow_id"] == workflow.id # The media websocket URL is keyed on the org, not the workflow owner. assert initiate_kwargs["organization_id"] == workflow.organization_id + mock_db.update_workflow_run.assert_awaited_once_with( + run_id=501, + gathered_context={ + "provider": "twilio", + "triggered_by": "api", + "call_id": "CA123", + "trigger_uuid": "trigger-uuid-123", + }, + ) def test_workflow_uuid_route_uses_scoped_lookup_and_shared_execution(): @@ -177,6 +194,7 @@ def test_workflow_uuid_route_uses_scoped_lookup_and_shared_execution(): return_value=SimpleNamespace(id=55) ) mock_db.create_workflow_run = AsyncMock(return_value=SimpleNamespace(id=601)) + mock_db.update_workflow_run = AsyncMock() response = client.post( f"/public/agent/workflow/{workflow.workflow_uuid}", @@ -207,6 +225,14 @@ def test_workflow_uuid_route_uses_scoped_lookup_and_shared_execution(): assert create_kwargs["definition_id"] == 77 assert "name" not in create_kwargs["initial_context"] assert not mock_db.get_draft_version.called + mock_db.update_workflow_run.assert_awaited_once_with( + run_id=601, + gathered_context={ + "provider": "twilio", + "triggered_by": "api", + "call_id": "CA123", + }, + ) def test_trigger_test_route_uses_draft_and_template_context_with_api_override(): @@ -262,6 +288,7 @@ def test_trigger_test_route_uses_draft_and_template_context_with_api_override(): return_value=SimpleNamespace(id=55) ) mock_db.create_workflow_run = AsyncMock(return_value=SimpleNamespace(id=501)) + mock_db.update_workflow_run = AsyncMock() response = client.post( "/public/agent/test/trigger-uuid-123", @@ -328,6 +355,7 @@ def test_workflow_uuid_test_route_uses_draft_and_template_context(): return_value=SimpleNamespace(id=55) ) mock_db.create_workflow_run = AsyncMock(return_value=SimpleNamespace(id=501)) + mock_db.update_workflow_run = AsyncMock() response = client.post( f"/public/agent/test/workflow/{workflow.workflow_uuid}",