send webhook when task or workflow run is canceled (#1374)
This commit is contained in:
@@ -285,7 +285,7 @@ class ForgeAgent:
|
|||||||
task=task,
|
task=task,
|
||||||
last_step=step,
|
last_step=step,
|
||||||
api_key=api_key,
|
api_key=api_key,
|
||||||
need_call_webhook=False,
|
need_call_webhook=True,
|
||||||
)
|
)
|
||||||
return step, None, None
|
return step, None, None
|
||||||
|
|
||||||
@@ -1543,7 +1543,7 @@ class ForgeAgent:
|
|||||||
async def execute_task_webhook(
|
async def execute_task_webhook(
|
||||||
self,
|
self,
|
||||||
task: Task,
|
task: Task,
|
||||||
last_step: Step,
|
last_step: Step | None,
|
||||||
api_key: str | None,
|
api_key: str | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not api_key:
|
if not api_key:
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ async def get_task(
|
|||||||
async def cancel_task(
|
async def cancel_task(
|
||||||
task_id: str,
|
task_id: str,
|
||||||
current_org: Organization = Depends(org_auth_service.get_current_org),
|
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||||
|
x_api_key: Annotated[str | None, Header()] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
analytics.capture("skyvern-oss-agent-task-get")
|
analytics.capture("skyvern-oss-agent-task-get")
|
||||||
task_obj = await app.DATABASE.get_task(task_id, organization_id=current_org.organization_id)
|
task_obj = await app.DATABASE.get_task(task_id, organization_id=current_org.organization_id)
|
||||||
@@ -292,7 +293,11 @@ async def cancel_task(
|
|||||||
status_code=status.HTTP_404_NOT_FOUND,
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Task not found {task_id}",
|
detail=f"Task not found {task_id}",
|
||||||
)
|
)
|
||||||
await app.agent.update_task(task_obj, status=TaskStatus.canceled)
|
task = await app.agent.update_task(task_obj, status=TaskStatus.canceled)
|
||||||
|
# get latest step
|
||||||
|
latest_step = await app.DATABASE.get_latest_step(task_id, organization_id=current_org.organization_id)
|
||||||
|
# retry the webhook
|
||||||
|
await app.agent.execute_task_webhook(task=task, last_step=latest_step, api_key=x_api_key)
|
||||||
|
|
||||||
|
|
||||||
@base_router.post("/workflows/runs/{workflow_run_id}/cancel")
|
@base_router.post("/workflows/runs/{workflow_run_id}/cancel")
|
||||||
@@ -300,8 +305,16 @@ async def cancel_task(
|
|||||||
async def cancel_workflow_run(
|
async def cancel_workflow_run(
|
||||||
workflow_run_id: str,
|
workflow_run_id: str,
|
||||||
current_org: Organization = Depends(org_auth_service.get_current_org),
|
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||||
|
x_api_key: Annotated[str | None, Header()] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
workflow_run = await app.DATABASE.get_workflow_run(workflow_run_id=workflow_run_id)
|
||||||
|
if not workflow_run:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Workflow run not found {workflow_run_id}",
|
||||||
|
)
|
||||||
await app.WORKFLOW_SERVICE.mark_workflow_run_as_canceled(workflow_run_id)
|
await app.WORKFLOW_SERVICE.mark_workflow_run_as_canceled(workflow_run_id)
|
||||||
|
await app.WORKFLOW_SERVICE.execute_workflow_webhook(workflow_run, api_key=x_api_key)
|
||||||
|
|
||||||
|
|
||||||
@base_router.post(
|
@base_router.post(
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class WorkflowService:
|
|||||||
workflow=workflow,
|
workflow=workflow,
|
||||||
workflow_run=workflow_run,
|
workflow_run=workflow_run,
|
||||||
api_key=api_key,
|
api_key=api_key,
|
||||||
need_call_webhook=False,
|
need_call_webhook=True,
|
||||||
)
|
)
|
||||||
return workflow_run
|
return workflow_run
|
||||||
parameters = block.get_all_parameters(workflow_run_id)
|
parameters = block.get_all_parameters(workflow_run_id)
|
||||||
@@ -881,10 +881,18 @@ class WorkflowService:
|
|||||||
if not need_call_webhook:
|
if not need_call_webhook:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
await self.execute_workflow_webhook(workflow_run, api_key)
|
||||||
|
|
||||||
|
async def execute_workflow_webhook(
|
||||||
|
self,
|
||||||
|
workflow_run: WorkflowRun,
|
||||||
|
api_key: str | None = None,
|
||||||
|
) -> None:
|
||||||
|
workflow_id = workflow_run.workflow_id
|
||||||
workflow_run_status_response = await self.build_workflow_run_status_response(
|
workflow_run_status_response = await self.build_workflow_run_status_response(
|
||||||
workflow_permanent_id=workflow.workflow_permanent_id,
|
workflow_permanent_id=workflow_run.workflow_permanent_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
organization_id=workflow.organization_id,
|
organization_id=workflow_run.organization_id,
|
||||||
)
|
)
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"Built workflow run status response",
|
"Built workflow run status response",
|
||||||
@@ -894,7 +902,7 @@ class WorkflowService:
|
|||||||
if not workflow_run.webhook_callback_url:
|
if not workflow_run.webhook_callback_url:
|
||||||
LOG.warning(
|
LOG.warning(
|
||||||
"Workflow has no webhook callback url. Not sending workflow response",
|
"Workflow has no webhook callback url. Not sending workflow response",
|
||||||
workflow_id=workflow.workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -902,7 +910,7 @@ class WorkflowService:
|
|||||||
if not api_key:
|
if not api_key:
|
||||||
LOG.warning(
|
LOG.warning(
|
||||||
"Request has no api key. Not sending workflow response",
|
"Request has no api key. Not sending workflow response",
|
||||||
workflow_id=workflow.workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -921,7 +929,7 @@ class WorkflowService:
|
|||||||
}
|
}
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"Sending webhook run status to webhook callback url",
|
"Sending webhook run status to webhook callback url",
|
||||||
workflow_id=workflow.workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
webhook_callback_url=workflow_run.webhook_callback_url,
|
webhook_callback_url=workflow_run.webhook_callback_url,
|
||||||
payload=payload,
|
payload=payload,
|
||||||
@@ -934,7 +942,7 @@ class WorkflowService:
|
|||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"Webhook sent successfully",
|
"Webhook sent successfully",
|
||||||
workflow_id=workflow.workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
resp_code=resp.status_code,
|
resp_code=resp.status_code,
|
||||||
resp_text=resp.text,
|
resp_text=resp.text,
|
||||||
@@ -942,7 +950,7 @@ class WorkflowService:
|
|||||||
else:
|
else:
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"Webhook failed",
|
"Webhook failed",
|
||||||
workflow_id=workflow.workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
webhook_data=payload,
|
webhook_data=payload,
|
||||||
resp=resp,
|
resp=resp,
|
||||||
@@ -951,7 +959,7 @@ class WorkflowService:
|
|||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise FailedToSendWebhook(
|
raise FailedToSendWebhook(
|
||||||
workflow_id=workflow.workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run.workflow_run_id,
|
workflow_run_id=workflow_run.workflow_run_id,
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user