Jon/backend hitl buffs (#3826)

This commit is contained in:
Jonathan Dobson
2025-10-27 14:50:17 -04:00
committed by GitHub
parent be2ceb31a8
commit 353358ee17
6 changed files with 92 additions and 14 deletions

View File

@@ -3289,6 +3289,10 @@ class AgentDB:
http_request_timeout: int | None = None,
http_request_follow_redirects: bool | None = None,
ai_fallback_triggered: bool | None = None,
# human interaction block
instructions: str | None = None,
positive_descriptor: str | None = None,
negative_descriptor: str | None = None,
) -> WorkflowRunBlock:
async with self.Session() as session:
workflow_run_block = (
@@ -3348,6 +3352,13 @@ class AgentDB:
workflow_run_block.http_request_follow_redirects = http_request_follow_redirects
if ai_fallback_triggered is not None:
workflow_run_block.script_run = {"ai_fallback_triggered": ai_fallback_triggered}
# human interaction block fields
if instructions:
workflow_run_block.instructions = instructions
if positive_descriptor:
workflow_run_block.positive_descriptor = positive_descriptor
if negative_descriptor:
workflow_run_block.negative_descriptor = negative_descriptor
await session.commit()
await session.refresh(workflow_run_block)
else:

View File

@@ -680,6 +680,11 @@ class WorkflowRunBlockModel(Base):
http_request_timeout = Column(Integer, nullable=True)
http_request_follow_redirects = Column(Boolean, nullable=True)
# human interaction block
instructions = Column(String, nullable=True)
positive_descriptor = Column(String, nullable=True)
negative_descriptor = Column(String, nullable=True)
created_at = Column(DateTime, default=datetime.datetime.utcnow, nullable=False)
modified_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, nullable=False)

View File

@@ -523,6 +523,9 @@ def convert_to_workflow_run_block(
body=workflow_run_block_model.body,
created_at=workflow_run_block_model.created_at,
modified_at=workflow_run_block_model.modified_at,
instructions=workflow_run_block_model.instructions,
positive_descriptor=workflow_run_block_model.positive_descriptor,
negative_descriptor=workflow_run_block_model.negative_descriptor,
)
if task:
if task.finished_at and task.started_at:

View File

@@ -53,6 +53,11 @@ class WorkflowRunBlock(BaseModel):
subject: str | None = None
body: str | None = None
# human interaction block
instructions: str | None = None
positive_descriptor: str | None = None
negative_descriptor: str | None = None
class WorkflowRunTimelineType(StrEnum):
thought = "thought"

View File

@@ -3099,6 +3099,14 @@ class HumanInteractionBlock(BaseTaskBlock):
self.recipients = formatted
self.negative_descriptor = self.format_block_parameter_template_from_workflow_run_context(
self.negative_descriptor, workflow_run_context
)
self.positive_descriptor = self.format_block_parameter_template_from_workflow_run_context(
self.positive_descriptor, workflow_run_context
)
async def execute(
self,
workflow_run_id: str,
@@ -3110,6 +3118,31 @@ class HumanInteractionBlock(BaseTaskBlock):
# avoid circular import
from skyvern.forge.sdk.workflow.models.workflow import WorkflowRunStatus # noqa: PLC0415
workflow_run_context = self.get_workflow_run_context(workflow_run_id)
try:
self.format_potential_template_parameters(workflow_run_context)
except Exception as e:
return await self.build_block_result(
success=False,
failure_reason=f"Failed to format jinja template: {str(e)}",
output_parameter_value=None,
status=BlockStatus.failed,
workflow_run_block_id=workflow_run_block_id,
organization_id=organization_id,
)
await app.DATABASE.update_workflow_run_block(
workflow_run_block_id=workflow_run_block_id,
organization_id=organization_id,
recipients=self.recipients,
subject=self.subject,
body=self.body,
instructions=self.instructions,
positive_descriptor=self.positive_descriptor,
negative_descriptor=self.negative_descriptor,
)
LOG.info(
"Pausing workflow for human interaction",
workflow_run_id=workflow_run_id,
@@ -3138,20 +3171,6 @@ class HumanInteractionBlock(BaseTaskBlock):
organization_id=organization_id,
)
workflow_run_context = self.get_workflow_run_context(workflow_run_id)
try:
self.format_potential_template_parameters(workflow_run_context)
except Exception as e:
return await self.build_block_result(
success=False,
failure_reason=f"Failed to format jinja template: {str(e)}",
output_parameter_value=None,
status=BlockStatus.failed,
workflow_run_block_id=workflow_run_block_id,
organization_id=organization_id,
)
workflow_permanent_id = workflow_run.workflow_permanent_id
app_url = f"{settings.SKYVERN_APP_URL}/workflows/{workflow_permanent_id}/{workflow_run_id}/overview"
body = f"{self.body}\n\nKindly visit {app_url}\n\n{self.instructions}\n\n"