run scripts with workflow run paramters (#3219)

This commit is contained in:
Shuchang Zheng
2025-08-17 20:27:53 -07:00
committed by GitHub
parent c1b676f85e
commit 35313508d0
3 changed files with 59 additions and 34 deletions

View File

@@ -37,7 +37,7 @@ LOG = structlog.get_logger(__name__)
ACTION_MAP = {
"click": "click",
"input_text": "input_text",
"input_text": "fill",
"upload_file": "upload_file",
"select_option": "select_option",
"goto": "goto",
@@ -54,6 +54,8 @@ ACTION_MAP = {
ACTIONS_WITH_XPATH = [
"click",
"input_text",
"type",
"fill",
"upload_file",
"select_option",
]
@@ -170,7 +172,7 @@ def _action_to_stmt(act: dict[str, Any]) -> cst.BaseStatement:
)
)
if method == "input_text":
if method in ["type", "fill"]:
args.append(
cst.Arg(
keyword=cst.Name("text"),
@@ -203,6 +205,17 @@ def _action_to_stmt(act: dict[str, Any]) -> cst.BaseStatement:
),
)
)
elif method == "extract":
args.append(
cst.Arg(
keyword=cst.Name("data_extraction_goal"),
value=_value(act["data_extraction_goal"]),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
)
)
args.extend(
[
@@ -415,14 +428,6 @@ def _build_download_statement(block_title: str, block: dict[str, Any]) -> cst.Si
def _build_action_statement(block_title: str, block: dict[str, Any]) -> cst.SimpleStatementLine:
"""Build a skyvern.action statement."""
args = [
cst.Arg(
keyword=cst.Name("title"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")),
@@ -434,6 +439,14 @@ def _build_action_statement(block_title: str, block: dict[str, Any]) -> cst.Simp
cst.Arg(
keyword=cst.Name("max_steps"),
value=_value(block.get("max_steps_per_run", 30)),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("cache_key"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
),
@@ -483,6 +496,14 @@ def _build_login_statement(block_title: str, block: dict[str, Any]) -> cst.Simpl
cst.Arg(
keyword=cst.Name("webhook_callback_url"),
value=_value(block.get("webhook_callback_url", "")),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("cache_key"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
),
@@ -506,16 +527,16 @@ def _build_extract_statement(block_title: str, block: dict[str, Any]) -> cst.Sim
"""Build a skyvern.extract statement."""
args = [
cst.Arg(
keyword=cst.Name("title"),
value=_value(block_title),
keyword=cst.Name("prompt"),
value=_value(block.get("data_extraction_goal", "")),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")),
keyword=cst.Name("cache_key"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
),
@@ -538,14 +559,6 @@ def _build_extract_statement(block_title: str, block: dict[str, Any]) -> cst.Sim
def _build_navigate_statement(block_title: str, block: dict[str, Any]) -> cst.SimpleStatementLine:
"""Build a skyvern.navigate statement."""
args = [
cst.Arg(
keyword=cst.Name("title"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")),
@@ -565,6 +578,14 @@ def _build_navigate_statement(block_title: str, block: dict[str, Any]) -> cst.Si
cst.Arg(
keyword=cst.Name("max_steps"),
value=_value(block.get("max_steps_per_run", 30)),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("cache_key"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
),
@@ -694,14 +715,6 @@ def _build_wait_statement(block: dict[str, Any]) -> cst.SimpleStatementLine:
def _build_for_loop_statement(block_title: str, block: dict[str, Any]) -> cst.SimpleStatementLine:
"""Build a skyvern.for_loop statement."""
args = [
cst.Arg(
keyword=cst.Name("title"),
value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True,
last_line=cst.SimpleWhitespace(INDENT),
),
),
cst.Arg(
keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")),

View File

@@ -1,4 +1,5 @@
import abc
from typing import Any
import structlog
from fastapi import BackgroundTasks, Request
@@ -67,7 +68,9 @@ class AsyncExecutor(abc.ABC):
request: Request | None,
script_id: str,
organization_id: str,
background_tasks: BackgroundTasks | None,
parameters: dict[str, Any] | None = None,
workflow_run_id: str | None = None,
background_tasks: BackgroundTasks | None = None,
**kwargs: dict,
) -> None:
pass
@@ -214,7 +217,9 @@ class BackgroundTaskExecutor(AsyncExecutor):
request: Request | None,
script_id: str,
organization_id: str,
background_tasks: BackgroundTasks | None,
parameters: dict[str, Any] | None = None,
workflow_run_id: str | None = None,
background_tasks: BackgroundTasks | None = None,
**kwargs: dict,
) -> None:
if background_tasks:
@@ -222,5 +227,7 @@ class BackgroundTaskExecutor(AsyncExecutor):
script_service.execute_script,
script_id=script_id,
organization_id=organization_id,
parameters=parameters,
workflow_run_id=workflow_run_id,
background_tasks=background_tasks,
)

View File

@@ -3,7 +3,6 @@ import base64
import hashlib
import importlib.util
import os
import subprocess
from datetime import datetime
from typing import Any
@@ -150,6 +149,8 @@ async def create_script(
async def execute_script(
script_id: str,
organization_id: str,
parameters: dict[str, Any] | None = None,
workflow_run_id: str | None = None,
background_tasks: BackgroundTasks | None = None,
) -> None:
# TODO: assume the script only has one ScriptFile called main.py
@@ -207,7 +208,11 @@ async def execute_script(
# step 4: execute the script
if background_tasks:
background_tasks.add_task(subprocess.run, ["python", f"{script.script_id}/main.py"])
if workflow_run_id and not parameters:
parameter_tuples = await app.DATABASE.get_workflow_run_parameters(workflow_run_id=workflow_run_id)
parameters = {wf_param.key: run_param.value for wf_param, run_param in parameter_tuples}
LOG.info("Script run Parameters is using workflow run parameters", parameters=parameters)
background_tasks.add_task(run_script, parameters=parameters)
LOG.info("Script executed successfully", script_id=script_id)