mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-22 08:38:13 +02:00
feat: add qa node in workflow builder (#172)
* feat: add qa node in workflow builder * feat: add qa analysis token usage in usage_info * fix: mask the API key in QA node * feat: add advanced configuration in QA node
This commit is contained in:
parent
f1f4830012
commit
a836825b83
30 changed files with 1619 additions and 265 deletions
|
|
@ -45,8 +45,6 @@ class SuperuserWorkflowRunResponse(BaseModel):
|
|||
cost_info: Optional[dict]
|
||||
initial_context: Optional[dict]
|
||||
gathered_context: Optional[dict]
|
||||
admin_comment: Optional[str]
|
||||
admin_comment_ts: Optional[datetime]
|
||||
created_at: datetime
|
||||
|
||||
|
||||
|
|
@ -151,49 +149,3 @@ async def get_workflow_runs(
|
|||
limit=limit,
|
||||
total_pages=total_pages,
|
||||
)
|
||||
|
||||
|
||||
# ------------------ Admin Comment ------------------
|
||||
|
||||
|
||||
class AdminCommentRequest(BaseModel):
|
||||
admin_comment: str
|
||||
|
||||
|
||||
class AdminCommentResponse(BaseModel):
|
||||
success: bool
|
||||
admin_comment: str
|
||||
admin_comment_ts: datetime
|
||||
|
||||
|
||||
# ------------------ Routes ------------------
|
||||
|
||||
|
||||
@router.post("/workflow-runs/{run_id}/comment", response_model=AdminCommentResponse)
|
||||
async def set_admin_comment(
|
||||
run_id: int,
|
||||
request: AdminCommentRequest,
|
||||
user: UserModel = Depends(get_superuser),
|
||||
):
|
||||
"""Add or update an *admin-only* comment for a workflow run.
|
||||
|
||||
The comment is stored inside the ``annotations`` JSON column under the
|
||||
``admin_comment`` key so that it does not interfere with any other
|
||||
annotations recorded by the system.
|
||||
"""
|
||||
|
||||
await db_client.update_admin_comment(
|
||||
run_id=run_id, admin_comment=request.admin_comment
|
||||
)
|
||||
|
||||
# Fetch the updated run to get the timestamp from annotations
|
||||
updated_run = await db_client.get_workflow_run_by_id(run_id)
|
||||
admin_comment_ts = None
|
||||
if updated_run and updated_run.annotations:
|
||||
admin_comment_ts = updated_run.annotations.get("admin_comment_ts")
|
||||
|
||||
return AdminCommentResponse(
|
||||
success=True,
|
||||
admin_comment=request.admin_comment,
|
||||
admin_comment_ts=admin_comment_ts,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ from api.db.workflow_template_client import WorkflowTemplateClient
|
|||
from api.enums import CallType
|
||||
from api.schemas.workflow import WorkflowRunResponseSchema
|
||||
from api.services.auth.depends import get_user
|
||||
from api.services.configuration.masking import (
|
||||
mask_workflow_definition,
|
||||
merge_workflow_api_keys,
|
||||
)
|
||||
from api.services.mps_service_key_client import mps_service_key_client
|
||||
from api.services.workflow.dto import ReactFlowDTO
|
||||
from api.services.workflow.errors import ItemKind, WorkflowError
|
||||
|
|
@ -273,7 +277,9 @@ async def create_workflow(
|
|||
"name": workflow.name,
|
||||
"status": workflow.status,
|
||||
"created_at": workflow.created_at,
|
||||
"workflow_definition": workflow.workflow_definition_with_fallback,
|
||||
"workflow_definition": mask_workflow_definition(
|
||||
workflow.workflow_definition_with_fallback
|
||||
),
|
||||
"current_definition_id": workflow.current_definition_id,
|
||||
"template_context_variables": workflow.template_context_variables,
|
||||
"call_disposition_codes": workflow.call_disposition_codes,
|
||||
|
|
@ -351,7 +357,9 @@ async def create_workflow_from_template(
|
|||
"name": workflow.name,
|
||||
"status": workflow.status,
|
||||
"created_at": workflow.created_at,
|
||||
"workflow_definition": workflow.workflow_definition_with_fallback,
|
||||
"workflow_definition": mask_workflow_definition(
|
||||
workflow.workflow_definition_with_fallback
|
||||
),
|
||||
"current_definition_id": workflow.current_definition_id,
|
||||
"template_context_variables": workflow.template_context_variables,
|
||||
"call_disposition_codes": workflow.call_disposition_codes,
|
||||
|
|
@ -462,7 +470,9 @@ async def get_workflow(
|
|||
"name": workflow.name,
|
||||
"status": workflow.status,
|
||||
"created_at": workflow.created_at,
|
||||
"workflow_definition": workflow.workflow_definition_with_fallback,
|
||||
"workflow_definition": mask_workflow_definition(
|
||||
workflow.workflow_definition_with_fallback
|
||||
),
|
||||
"current_definition_id": workflow.current_definition_id,
|
||||
"template_context_variables": workflow.template_context_variables,
|
||||
"call_disposition_codes": workflow.call_disposition_codes,
|
||||
|
|
@ -512,7 +522,9 @@ async def update_workflow_status(
|
|||
"name": workflow.name,
|
||||
"status": workflow.status,
|
||||
"created_at": workflow.created_at,
|
||||
"workflow_definition": workflow.workflow_definition_with_fallback,
|
||||
"workflow_definition": mask_workflow_definition(
|
||||
workflow.workflow_definition_with_fallback
|
||||
),
|
||||
"current_definition_id": workflow.current_definition_id,
|
||||
"template_context_variables": workflow.template_context_variables,
|
||||
"call_disposition_codes": workflow.call_disposition_codes,
|
||||
|
|
@ -545,18 +557,30 @@ async def update_workflow(
|
|||
HTTPException: If the workflow is not found or if there's a database error
|
||||
"""
|
||||
try:
|
||||
# Restore real API keys where the incoming definition has masked placeholders
|
||||
workflow_definition = request.workflow_definition
|
||||
if workflow_definition:
|
||||
existing_workflow = await db_client.get_workflow(
|
||||
workflow_id, organization_id=user.selected_organization_id
|
||||
)
|
||||
if existing_workflow:
|
||||
workflow_definition = merge_workflow_api_keys(
|
||||
workflow_definition,
|
||||
existing_workflow.workflow_definition_with_fallback,
|
||||
)
|
||||
|
||||
workflow = await db_client.update_workflow(
|
||||
workflow_id=workflow_id,
|
||||
name=request.name,
|
||||
workflow_definition=request.workflow_definition,
|
||||
workflow_definition=workflow_definition,
|
||||
template_context_variables=request.template_context_variables,
|
||||
workflow_configurations=request.workflow_configurations,
|
||||
organization_id=user.selected_organization_id,
|
||||
)
|
||||
|
||||
# Sync agent triggers if workflow definition was updated
|
||||
if request.workflow_definition:
|
||||
trigger_paths = extract_trigger_paths(request.workflow_definition)
|
||||
if workflow_definition:
|
||||
trigger_paths = extract_trigger_paths(workflow_definition)
|
||||
await db_client.sync_triggers_for_workflow(
|
||||
workflow_id=workflow.id,
|
||||
organization_id=user.selected_organization_id,
|
||||
|
|
@ -568,7 +592,9 @@ async def update_workflow(
|
|||
"name": workflow.name,
|
||||
"status": workflow.status,
|
||||
"created_at": workflow.created_at,
|
||||
"workflow_definition": workflow.workflow_definition_with_fallback,
|
||||
"workflow_definition": mask_workflow_definition(
|
||||
workflow.workflow_definition_with_fallback
|
||||
),
|
||||
"current_definition_id": workflow.current_definition_id,
|
||||
"template_context_variables": workflow.template_context_variables,
|
||||
"call_disposition_codes": workflow.call_disposition_codes,
|
||||
|
|
@ -798,7 +824,9 @@ async def duplicate_workflow_template(
|
|||
"name": workflow.name,
|
||||
"status": workflow.status,
|
||||
"created_at": workflow.created_at,
|
||||
"workflow_definition": workflow.workflow_definition_with_fallback,
|
||||
"workflow_definition": mask_workflow_definition(
|
||||
workflow.workflow_definition_with_fallback
|
||||
),
|
||||
"current_definition_id": workflow.current_definition_id,
|
||||
"template_context_variables": workflow.template_context_variables,
|
||||
"call_disposition_codes": workflow.call_disposition_codes,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue