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 = { ACTION_MAP = {
"click": "click", "click": "click",
"input_text": "input_text", "input_text": "fill",
"upload_file": "upload_file", "upload_file": "upload_file",
"select_option": "select_option", "select_option": "select_option",
"goto": "goto", "goto": "goto",
@@ -54,6 +54,8 @@ ACTION_MAP = {
ACTIONS_WITH_XPATH = [ ACTIONS_WITH_XPATH = [
"click", "click",
"input_text", "input_text",
"type",
"fill",
"upload_file", "upload_file",
"select_option", "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( args.append(
cst.Arg( cst.Arg(
keyword=cst.Name("text"), 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( 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: def _build_action_statement(block_title: str, block: dict[str, Any]) -> cst.SimpleStatementLine:
"""Build a skyvern.action statement.""" """Build a skyvern.action statement."""
args = [ 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( cst.Arg(
keyword=cst.Name("prompt"), keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")), 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( cst.Arg(
keyword=cst.Name("max_steps"), keyword=cst.Name("max_steps"),
value=_value(block.get("max_steps_per_run", 30)), 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( whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True, indent=True,
), ),
@@ -483,6 +496,14 @@ def _build_login_statement(block_title: str, block: dict[str, Any]) -> cst.Simpl
cst.Arg( cst.Arg(
keyword=cst.Name("webhook_callback_url"), keyword=cst.Name("webhook_callback_url"),
value=_value(block.get("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( whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True, indent=True,
), ),
@@ -506,16 +527,16 @@ def _build_extract_statement(block_title: str, block: dict[str, Any]) -> cst.Sim
"""Build a skyvern.extract statement.""" """Build a skyvern.extract statement."""
args = [ args = [
cst.Arg( cst.Arg(
keyword=cst.Name("title"), keyword=cst.Name("prompt"),
value=_value(block_title), value=_value(block.get("data_extraction_goal", "")),
whitespace_after_arg=cst.ParenthesizedWhitespace( whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True, indent=True,
last_line=cst.SimpleWhitespace(INDENT), last_line=cst.SimpleWhitespace(INDENT),
), ),
), ),
cst.Arg( cst.Arg(
keyword=cst.Name("prompt"), keyword=cst.Name("cache_key"),
value=_value(block.get("navigation_goal", "")), value=_value(block_title),
whitespace_after_arg=cst.ParenthesizedWhitespace( whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True, 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: def _build_navigate_statement(block_title: str, block: dict[str, Any]) -> cst.SimpleStatementLine:
"""Build a skyvern.navigate statement.""" """Build a skyvern.navigate statement."""
args = [ 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( cst.Arg(
keyword=cst.Name("prompt"), keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")), 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( cst.Arg(
keyword=cst.Name("max_steps"), keyword=cst.Name("max_steps"),
value=_value(block.get("max_steps_per_run", 30)), 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( whitespace_after_arg=cst.ParenthesizedWhitespace(
indent=True, 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: def _build_for_loop_statement(block_title: str, block: dict[str, Any]) -> cst.SimpleStatementLine:
"""Build a skyvern.for_loop statement.""" """Build a skyvern.for_loop statement."""
args = [ 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( cst.Arg(
keyword=cst.Name("prompt"), keyword=cst.Name("prompt"),
value=_value(block.get("navigation_goal", "")), value=_value(block.get("navigation_goal", "")),

View File

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

View File

@@ -3,7 +3,6 @@ import base64
import hashlib import hashlib
import importlib.util import importlib.util
import os import os
import subprocess
from datetime import datetime from datetime import datetime
from typing import Any from typing import Any
@@ -150,6 +149,8 @@ async def create_script(
async def execute_script( async def execute_script(
script_id: str, script_id: str,
organization_id: str, organization_id: str,
parameters: dict[str, Any] | None = None,
workflow_run_id: str | None = None,
background_tasks: BackgroundTasks | None = None, background_tasks: BackgroundTasks | None = None,
) -> None: ) -> None:
# TODO: assume the script only has one ScriptFile called main.py # TODO: assume the script only has one ScriptFile called main.py
@@ -207,7 +208,11 @@ async def execute_script(
# step 4: execute the script # step 4: execute the script
if background_tasks: 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) LOG.info("Script executed successfully", script_id=script_id)