mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-25 12:01:04 +02:00
fix: move draft and template context handling out of create_workflow_run (#560)
* fix: move draft and template context handling out of create_workflow_run create_workflow_run now only creates the run with the definition_id and initial_context provided by the caller. Test call paths explicitly resolve draft definitions and merge template context variables before creating the run, while production/runtime paths bind the published definition without adding template defaults. * fix: review comments * chore: format and minor cleanups --------- Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
This commit is contained in:
parent
94dce42209
commit
90c5831984
19 changed files with 657 additions and 72 deletions
|
|
@ -24,6 +24,7 @@ from api.services.call_concurrency import (
|
|||
)
|
||||
from api.services.quota_service import authorize_workflow_run_start
|
||||
from api.services.telephony import registry as telephony_registry
|
||||
from api.services.workflow.run_creation import prepare_workflow_run_inputs
|
||||
|
||||
router = APIRouter(prefix="/agent-stream")
|
||||
|
||||
|
|
@ -68,11 +69,11 @@ async def agent_stream_websocket(
|
|||
numeric_suffix = int(str(uuid.uuid4()).replace("-", "")[:8], 16) % 100000000
|
||||
workflow_run_name = f"WR-AGS-{numeric_suffix:08d}"
|
||||
initial_context = {
|
||||
**(workflow.template_context_variables or {}),
|
||||
"provider": provider_name,
|
||||
"direction": "inbound",
|
||||
}
|
||||
try:
|
||||
run_inputs = await prepare_workflow_run_inputs(db_client, workflow)
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
workflow_run_name,
|
||||
workflow.id,
|
||||
|
|
@ -81,6 +82,7 @@ async def agent_stream_websocket(
|
|||
call_type=CallType.INBOUND,
|
||||
initial_context=initial_context,
|
||||
organization_id=workflow.organization_id,
|
||||
definition_id=run_inputs.definition_id,
|
||||
)
|
||||
await call_concurrency.bind_workflow_run(concurrency_slot, workflow_run.id)
|
||||
except Exception:
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from api.services.telephony.factory import (
|
|||
get_default_telephony_provider,
|
||||
get_telephony_provider_by_id,
|
||||
)
|
||||
from api.services.workflow.run_creation import prepare_workflow_run_inputs
|
||||
from api.utils.common import get_backend_endpoints
|
||||
|
||||
router = APIRouter(prefix="/public/agent")
|
||||
|
|
@ -260,14 +261,21 @@ async def _execute_resolved_target(
|
|||
)
|
||||
|
||||
try:
|
||||
run_inputs = await prepare_workflow_run_inputs(
|
||||
db_client,
|
||||
target.workflow,
|
||||
initial_context=initial_context,
|
||||
use_draft=use_draft,
|
||||
include_template_context=use_draft,
|
||||
)
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
name=workflow_run_name,
|
||||
workflow_id=target.workflow.id,
|
||||
mode=workflow_run_mode,
|
||||
initial_context=initial_context,
|
||||
initial_context=run_inputs.initial_context,
|
||||
user_id=execution_user_id,
|
||||
use_draft=use_draft,
|
||||
organization_id=target.organization_id,
|
||||
definition_id=run_inputs.definition_id,
|
||||
)
|
||||
await call_concurrency.bind_workflow_run(concurrency_slot, workflow_run.id)
|
||||
except Exception:
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ from api.routes.turn_credentials import (
|
|||
TurnCredentialsResponse,
|
||||
generate_turn_credentials,
|
||||
)
|
||||
from api.services.workflow.run_creation import prepare_workflow_run_inputs
|
||||
|
||||
router = APIRouter(prefix="/public/embed")
|
||||
|
||||
|
|
@ -304,6 +305,12 @@ async def initialize_embed_session(
|
|||
|
||||
# Create workflow run
|
||||
try:
|
||||
workflow = await db_client.get_workflow(
|
||||
embed_token.workflow_id, organization_id=embed_token.organization_id
|
||||
)
|
||||
if not workflow:
|
||||
raise ValueError("Workflow not found")
|
||||
run_inputs = await prepare_workflow_run_inputs(db_client, workflow)
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
name=f"Embed Run - {datetime.now(UTC).isoformat()}",
|
||||
workflow_id=embed_token.workflow_id,
|
||||
|
|
@ -314,6 +321,7 @@ async def initialize_embed_session(
|
|||
**(init_request.context_variables or {}),
|
||||
"provider": WorkflowRunMode.SMALLWEBRTC.value,
|
||||
},
|
||||
definition_id=run_inputs.definition_id,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create workflow run: {e}")
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ from api.services.telephony.transfer_event_protocol import (
|
|||
TransferEvent,
|
||||
TransferEventType,
|
||||
)
|
||||
from api.services.workflow.run_creation import prepare_workflow_run_inputs
|
||||
from api.utils.common import get_backend_endpoints
|
||||
from api.utils.telephony_helper import (
|
||||
generic_hangup_response,
|
||||
|
|
@ -173,27 +174,29 @@ async def initiate_call(
|
|||
|
||||
try:
|
||||
if not workflow_run_id:
|
||||
# Merge template context variables (e.g. caller_number, called_number
|
||||
# set in workflow settings for testing pre-call data fetch).
|
||||
template_vars = workflow.template_context_variables or {}
|
||||
|
||||
numeric_suffix = int(str(uuid.uuid4()).replace("-", "")[:8], 16) % 100000000
|
||||
workflow_run_name = f"WR-TEL-OUT-{numeric_suffix:08d}"
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
workflow_run_name,
|
||||
workflow.id,
|
||||
workflow_run_mode,
|
||||
user_id=execution_user_id,
|
||||
call_type=CallType.OUTBOUND,
|
||||
run_inputs = await prepare_workflow_run_inputs(
|
||||
db_client,
|
||||
workflow,
|
||||
initial_context={
|
||||
**template_vars,
|
||||
"phone_number": phone_number,
|
||||
"called_number": phone_number,
|
||||
"provider": provider.PROVIDER_NAME,
|
||||
"telephony_configuration_id": telephony_configuration_id,
|
||||
},
|
||||
use_draft=True,
|
||||
include_template_context=True,
|
||||
)
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
workflow_run_name,
|
||||
workflow.id,
|
||||
workflow_run_mode,
|
||||
user_id=execution_user_id,
|
||||
call_type=CallType.OUTBOUND,
|
||||
initial_context=run_inputs.initial_context,
|
||||
organization_id=user.selected_organization_id,
|
||||
definition_id=run_inputs.definition_id,
|
||||
)
|
||||
workflow_run_id = workflow_run.id
|
||||
else:
|
||||
|
|
@ -463,6 +466,12 @@ async def _create_inbound_workflow_run(
|
|||
call_id = normalized_data.call_id
|
||||
numeric_suffix = int(str(uuid.uuid4()).replace("-", "")[:8], 16) % 100000000
|
||||
workflow_run_name = f"WR-TEL-IN-{numeric_suffix:08d}"
|
||||
workflow = await db_client.get_workflow(
|
||||
workflow_id, organization_id=organization_id
|
||||
)
|
||||
if not workflow:
|
||||
raise HTTPException(status_code=404, detail="Workflow not found")
|
||||
run_inputs = await prepare_workflow_run_inputs(db_client, workflow)
|
||||
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
workflow_run_name,
|
||||
|
|
@ -490,6 +499,7 @@ async def _create_inbound_workflow_run(
|
|||
},
|
||||
},
|
||||
organization_id=organization_id,
|
||||
definition_id=run_inputs.definition_id,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ from api.services.workflow.configuration_policy import (
|
|||
from api.services.workflow.dto import ReactFlowDTO, sanitize_workflow_definition
|
||||
from api.services.workflow.duplicate import duplicate_workflow
|
||||
from api.services.workflow.errors import ItemKind, WorkflowError
|
||||
from api.services.workflow.run_creation import prepare_workflow_run_inputs
|
||||
from api.services.workflow.run_usage_response import (
|
||||
format_public_cost_info,
|
||||
format_public_usage_info,
|
||||
|
|
@ -1317,13 +1318,27 @@ async def create_workflow_run(
|
|||
request: The create workflow run request
|
||||
user: The user to create the workflow run for
|
||||
"""
|
||||
workflow = await db_client.get_workflow(
|
||||
workflow_id, organization_id=user.selected_organization_id
|
||||
)
|
||||
if not workflow:
|
||||
raise HTTPException(status_code=404, detail="Workflow not found")
|
||||
|
||||
run_inputs = await prepare_workflow_run_inputs(
|
||||
db_client,
|
||||
workflow,
|
||||
use_draft=True,
|
||||
include_template_context=True,
|
||||
)
|
||||
|
||||
run = await db_client.create_workflow_run(
|
||||
request.name,
|
||||
workflow_id,
|
||||
request.mode,
|
||||
user.id,
|
||||
use_draft=True,
|
||||
organization_id=user.selected_organization_id,
|
||||
definition_id=run_inputs.definition_id,
|
||||
initial_context=run_inputs.initial_context,
|
||||
)
|
||||
return {
|
||||
"id": run.id,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from api.db.models import UserModel, WorkflowRunTextSessionModel
|
|||
from api.enums import WorkflowRunMode
|
||||
from api.services.auth.depends import get_user_with_selected_organization
|
||||
from api.services.quota_service import authorize_workflow_run_start
|
||||
from api.services.workflow.run_creation import prepare_workflow_run_inputs
|
||||
from api.services.workflow.text_chat_session_service import (
|
||||
TextChatPendingTurnLostError,
|
||||
TextChatSessionExecutionError,
|
||||
|
|
@ -164,14 +165,26 @@ async def create_text_chat_session(
|
|||
) -> WorkflowRunTextSessionResponse:
|
||||
session_name = request.name or f"WR-TEXT-{uuid4().hex[:6].upper()}"
|
||||
try:
|
||||
workflow = await db_client.get_workflow(
|
||||
workflow_id, organization_id=user.selected_organization_id
|
||||
)
|
||||
if not workflow:
|
||||
raise ValueError(f"Workflow with ID {workflow_id} not found")
|
||||
run_inputs = await prepare_workflow_run_inputs(
|
||||
db_client,
|
||||
workflow,
|
||||
initial_context=request.initial_context,
|
||||
use_draft=True,
|
||||
include_template_context=True,
|
||||
)
|
||||
workflow_run = await db_client.create_workflow_run(
|
||||
name=session_name,
|
||||
workflow_id=workflow_id,
|
||||
mode=WorkflowRunMode.TEXTCHAT.value,
|
||||
user_id=user.id,
|
||||
initial_context=request.initial_context,
|
||||
use_draft=True,
|
||||
initial_context=run_inputs.initial_context,
|
||||
organization_id=user.selected_organization_id,
|
||||
definition_id=run_inputs.definition_id,
|
||||
)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue