mirror of
https://github.com/Skyvern-AI/skyvern.git
synced 2025-09-17 02:39:40 +00:00
workflow run block description generation (#1482)
This commit is contained in:
parent
60e051eeb5
commit
187c18d83c
7 changed files with 91 additions and 2 deletions
|
@ -0,0 +1,31 @@
|
||||||
|
"""add description to workflow run block
|
||||||
|
|
||||||
|
Revision ID: 32e2f138f7fd
|
||||||
|
Revises: 521241e64aed
|
||||||
|
Create Date: 2025-01-03 23:49:40.290858+00:00
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "32e2f138f7fd"
|
||||||
|
down_revision: Union[str, None] = "521241e64aed"
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column("workflow_run_blocks", sa.Column("description", sa.String(), nullable=True))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column("workflow_run_blocks", "description")
|
||||||
|
# ### end Alembic commands ###
|
|
@ -0,0 +1,10 @@
|
||||||
|
We are building workflow automations. There are many blocks in a workflow. Generate a summary for the following block to help the user understand what the block is planning to do.
|
||||||
|
|
||||||
|
{{ block }}
|
||||||
|
|
||||||
|
Respond with the following JSON format:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"summary": str // Be concise and to the point. Summarize the block in one sentence with no more than 20 words. Use languages like "Will do something", "Planning to do something", "Going to do something" and replace the "do something" with the actual action the block is planning to do.
|
||||||
|
}
|
||||||
|
```
|
|
@ -2146,11 +2146,11 @@ class AgentDB:
|
||||||
async def update_workflow_run_block(
|
async def update_workflow_run_block(
|
||||||
self,
|
self,
|
||||||
workflow_run_block_id: str,
|
workflow_run_block_id: str,
|
||||||
|
organization_id: str | None = None,
|
||||||
status: BlockStatus | None = None,
|
status: BlockStatus | None = None,
|
||||||
output: dict | list | str | None = None,
|
output: dict | list | str | None = None,
|
||||||
failure_reason: str | None = None,
|
failure_reason: str | None = None,
|
||||||
task_id: str | None = None,
|
task_id: str | None = None,
|
||||||
organization_id: str | None = None,
|
|
||||||
loop_values: list | None = None,
|
loop_values: list | None = None,
|
||||||
current_value: str | None = None,
|
current_value: str | None = None,
|
||||||
current_index: int | None = None,
|
current_index: int | None = None,
|
||||||
|
@ -2160,6 +2160,7 @@ class AgentDB:
|
||||||
body: str | None = None,
|
body: str | None = None,
|
||||||
prompt: str | None = None,
|
prompt: str | None = None,
|
||||||
wait_sec: int | None = None,
|
wait_sec: int | None = None,
|
||||||
|
description: str | None = None,
|
||||||
) -> WorkflowRunBlock:
|
) -> WorkflowRunBlock:
|
||||||
async with self.Session() as session:
|
async with self.Session() as session:
|
||||||
workflow_run_block = (
|
workflow_run_block = (
|
||||||
|
@ -2196,6 +2197,8 @@ class AgentDB:
|
||||||
workflow_run_block.prompt = prompt
|
workflow_run_block.prompt = prompt
|
||||||
if wait_sec:
|
if wait_sec:
|
||||||
workflow_run_block.wait_sec = wait_sec
|
workflow_run_block.wait_sec = wait_sec
|
||||||
|
if description:
|
||||||
|
workflow_run_block.description = description
|
||||||
await session.commit()
|
await session.commit()
|
||||||
await session.refresh(workflow_run_block)
|
await session.refresh(workflow_run_block)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -494,6 +494,7 @@ class WorkflowRunBlockModel(Base):
|
||||||
String, ForeignKey("workflow_run_blocks.workflow_run_block_id"), nullable=True
|
String, ForeignKey("workflow_run_blocks.workflow_run_block_id"), nullable=True
|
||||||
)
|
)
|
||||||
organization_id = Column(String, ForeignKey("organizations.organization_id"), nullable=True)
|
organization_id = Column(String, ForeignKey("organizations.organization_id"), nullable=True)
|
||||||
|
description = Column(String, nullable=True)
|
||||||
task_id = Column(String, ForeignKey("tasks.task_id"), nullable=True)
|
task_id = Column(String, ForeignKey("tasks.task_id"), nullable=True)
|
||||||
label = Column(String, nullable=True)
|
label = Column(String, nullable=True)
|
||||||
block_type = Column(String, nullable=False)
|
block_type = Column(String, nullable=False)
|
||||||
|
|
|
@ -382,6 +382,7 @@ def convert_to_workflow_run_block(
|
||||||
workflow_run_id=workflow_run_block_model.workflow_run_id,
|
workflow_run_id=workflow_run_block_model.workflow_run_id,
|
||||||
organization_id=workflow_run_block_model.organization_id,
|
organization_id=workflow_run_block_model.organization_id,
|
||||||
parent_workflow_run_block_id=workflow_run_block_model.parent_workflow_run_block_id,
|
parent_workflow_run_block_id=workflow_run_block_model.parent_workflow_run_block_id,
|
||||||
|
description=workflow_run_block_model.description,
|
||||||
block_type=BlockType(workflow_run_block_model.block_type),
|
block_type=BlockType(workflow_run_block_model.block_type),
|
||||||
label=workflow_run_block_model.label,
|
label=workflow_run_block_model.label,
|
||||||
status=BlockStatus(workflow_run_block_model.status),
|
status=BlockStatus(workflow_run_block_model.status),
|
||||||
|
|
|
@ -15,6 +15,7 @@ class WorkflowRunBlock(BaseModel):
|
||||||
workflow_run_block_id: str
|
workflow_run_block_id: str
|
||||||
workflow_run_id: str
|
workflow_run_id: str
|
||||||
organization_id: str | None = None
|
organization_id: str | None = None
|
||||||
|
description: str | None = None
|
||||||
parent_workflow_run_block_id: str | None = None
|
parent_workflow_run_block_id: str | None = None
|
||||||
block_type: BlockType
|
block_type: BlockType
|
||||||
label: str | None = None
|
label: str | None = None
|
||||||
|
|
|
@ -208,6 +208,49 @@ class Block(BaseModel, abc.ABC):
|
||||||
block_type=self.block_type,
|
block_type=self.block_type,
|
||||||
continue_on_failure=self.continue_on_failure,
|
continue_on_failure=self.continue_on_failure,
|
||||||
)
|
)
|
||||||
|
workflow_run_block_id = workflow_run_block.workflow_run_block_id
|
||||||
|
|
||||||
|
description = None
|
||||||
|
try:
|
||||||
|
block_data = self.model_dump(
|
||||||
|
exclude={
|
||||||
|
"workflow_run_block_id",
|
||||||
|
"organization_id",
|
||||||
|
"task_id",
|
||||||
|
"workflow_run_id",
|
||||||
|
"parent_workflow_run_block_id",
|
||||||
|
"label",
|
||||||
|
"status",
|
||||||
|
"output",
|
||||||
|
"continue_on_failure",
|
||||||
|
"failure_reason",
|
||||||
|
"actions",
|
||||||
|
"created_at",
|
||||||
|
"modified_at",
|
||||||
|
},
|
||||||
|
exclude_none=True,
|
||||||
|
)
|
||||||
|
description_generation_prompt = prompt_engine.load_prompt(
|
||||||
|
"generate_workflow_run_block_description",
|
||||||
|
block=block_data,
|
||||||
|
)
|
||||||
|
json_response = await app.SECONDARY_LLM_API_HANDLER(prompt=description_generation_prompt)
|
||||||
|
description = json_response.get("summary")
|
||||||
|
LOG.info(
|
||||||
|
"Generated description for the workflow run block",
|
||||||
|
description=description,
|
||||||
|
workflow_run_block_id=workflow_run_block.workflow_run_block_id,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("Failed to generate description for the workflow run block", error=e)
|
||||||
|
|
||||||
|
if description:
|
||||||
|
workflow_run_block = await app.DATABASE.update_workflow_run_block(
|
||||||
|
workflow_run_block_id=workflow_run_block.workflow_run_block_id,
|
||||||
|
description=description,
|
||||||
|
organization_id=organization_id,
|
||||||
|
)
|
||||||
|
|
||||||
# create a screenshot
|
# create a screenshot
|
||||||
browser_state = app.BROWSER_MANAGER.get_for_workflow_run(workflow_run_id)
|
browser_state = app.BROWSER_MANAGER.get_for_workflow_run(workflow_run_id)
|
||||||
if not browser_state:
|
if not browser_state:
|
||||||
|
@ -220,7 +263,6 @@ class Block(BaseModel, abc.ABC):
|
||||||
artifact_type=ArtifactType.SCREENSHOT_LLM,
|
artifact_type=ArtifactType.SCREENSHOT_LLM,
|
||||||
data=screenshot,
|
data=screenshot,
|
||||||
)
|
)
|
||||||
workflow_run_block_id = workflow_run_block.workflow_run_block_id
|
|
||||||
return await self.execute(workflow_run_id, workflow_run_block_id, organization_id=organization_id, **kwargs)
|
return await self.execute(workflow_run_id, workflow_run_block_id, organization_id=organization_id, **kwargs)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(
|
LOG.exception(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue