scripts gen all block support (#3407)
This commit is contained in:
@@ -33,12 +33,17 @@ from skyvern.services.script_service import ( # noqa: E402
|
|||||||
action, # noqa: E402
|
action, # noqa: E402
|
||||||
download, # noqa: E402
|
download, # noqa: E402
|
||||||
extract, # noqa: E402
|
extract, # noqa: E402
|
||||||
|
http_request, # noqa: E402
|
||||||
generate_text, # noqa: E402
|
generate_text, # noqa: E402
|
||||||
|
goto, # noqa: E402
|
||||||
login, # noqa: E402
|
login, # noqa: E402
|
||||||
|
parse_file, # noqa: E402
|
||||||
|
prompt, # noqa: E402
|
||||||
render_template, # noqa: E402
|
render_template, # noqa: E402
|
||||||
run_code, # noqa: E402
|
run_code, # noqa: E402
|
||||||
run_script, # noqa: E402
|
run_script, # noqa: E402
|
||||||
run_task, # noqa: E402
|
run_task, # noqa: E402
|
||||||
|
send_email, # noqa: E402
|
||||||
wait, # noqa: E402
|
wait, # noqa: E402
|
||||||
) # noqa: E402
|
) # noqa: E402
|
||||||
|
|
||||||
@@ -51,12 +56,17 @@ __all__ = [
|
|||||||
"cached",
|
"cached",
|
||||||
"download",
|
"download",
|
||||||
"extract",
|
"extract",
|
||||||
|
"http_request",
|
||||||
"generate_text",
|
"generate_text",
|
||||||
|
"goto",
|
||||||
"login",
|
"login",
|
||||||
|
"parse_file",
|
||||||
|
"prompt",
|
||||||
"render_template",
|
"render_template",
|
||||||
"run_code",
|
"run_code",
|
||||||
"run_script",
|
"run_script",
|
||||||
"run_task",
|
"run_task",
|
||||||
|
"send_email",
|
||||||
"setup",
|
"setup",
|
||||||
"wait",
|
"wait",
|
||||||
"workflow",
|
"workflow",
|
||||||
|
|||||||
@@ -726,6 +726,14 @@ def _build_send_email_statement(block: dict[str, Any]) -> cst.SimpleStatementLin
|
|||||||
last_line=cst.SimpleWhitespace(INDENT),
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("recipients"),
|
||||||
|
value=_value(block.get("recipients", [])),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
cst.Arg(
|
cst.Arg(
|
||||||
keyword=cst.Name("subject"),
|
keyword=cst.Name("subject"),
|
||||||
value=_value(block.get("subject", "")),
|
value=_value(block.get("subject", "")),
|
||||||
@@ -742,17 +750,18 @@ def _build_send_email_statement(block: dict[str, Any]) -> cst.SimpleStatementLin
|
|||||||
last_line=cst.SimpleWhitespace(INDENT),
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
# TODO: support file attachments?
|
||||||
|
# cst.Arg(
|
||||||
|
# keyword=cst.Name("file_attachments"),
|
||||||
|
# value=_value(block.get("file_attachments", [])),
|
||||||
|
# whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
# indent=True,
|
||||||
|
# last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
# ),
|
||||||
|
# ),
|
||||||
cst.Arg(
|
cst.Arg(
|
||||||
keyword=cst.Name("recipients"),
|
keyword=cst.Name("label"),
|
||||||
value=_value(block.get("recipients", [])),
|
value=_value(block.get("label", "")),
|
||||||
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
|
||||||
indent=True,
|
|
||||||
last_line=cst.SimpleWhitespace(INDENT),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
cst.Arg(
|
|
||||||
keyword=cst.Name("attach_downloaded_files"),
|
|
||||||
value=_value(block.get("attach_downloaded_files", False)),
|
|
||||||
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
indent=True,
|
indent=True,
|
||||||
),
|
),
|
||||||
@@ -861,6 +870,14 @@ def _build_goto_statement(block: dict[str, Any]) -> cst.SimpleStatementLine:
|
|||||||
cst.Arg(
|
cst.Arg(
|
||||||
keyword=cst.Name("url"),
|
keyword=cst.Name("url"),
|
||||||
value=_value(block.get("url", "")),
|
value=_value(block.get("url", "")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("label"),
|
||||||
|
value=_value(block.get("label") or block.get("title") or f"block_{block.get('workflow_run_block_id')}"),
|
||||||
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
indent=True,
|
indent=True,
|
||||||
),
|
),
|
||||||
@@ -937,6 +954,7 @@ def _build_file_upload_statement(block: dict[str, Any]) -> cst.SimpleStatementLi
|
|||||||
value=_value(block.get("parameters", None)),
|
value=_value(block.get("parameters", None)),
|
||||||
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
indent=True,
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
cst.Arg(
|
cst.Arg(
|
||||||
@@ -944,6 +962,7 @@ def _build_file_upload_statement(block: dict[str, Any]) -> cst.SimpleStatementLi
|
|||||||
value=_value(block.get("storage_type", FileStorageType.S3)),
|
value=_value(block.get("storage_type", FileStorageType.S3)),
|
||||||
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
indent=True,
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@@ -964,9 +983,12 @@ def _build_file_upload_statement(block: dict[str, Any]) -> cst.SimpleStatementLi
|
|||||||
value=_value(block.get(key, "")),
|
value=_value(block.get(key, "")),
|
||||||
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
indent=True,
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
_mark_last_arg_as_comma(args)
|
||||||
|
|
||||||
call = cst.Call(
|
call = cst.Call(
|
||||||
func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("upload_file")),
|
func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("upload_file")),
|
||||||
args=args,
|
args=args,
|
||||||
@@ -979,6 +1001,238 @@ def _build_file_upload_statement(block: dict[str, Any]) -> cst.SimpleStatementLi
|
|||||||
return cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
return cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_file_url_parser_statement(block: dict[str, Any]) -> cst.SimpleStatementLine:
|
||||||
|
"""Build a skyvern.parse_file statement."""
|
||||||
|
args = [
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("file_url"),
|
||||||
|
value=_value(block.get("file_url", "")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("file_type"),
|
||||||
|
value=_value(str(block.get("file_type"))),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add optional parameters if they exist
|
||||||
|
if block.get("json_schema") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("schema"),
|
||||||
|
value=_value(block.get("json_schema")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("label") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("label"),
|
||||||
|
value=_value(block.get("label")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_mark_last_arg_as_comma(args)
|
||||||
|
|
||||||
|
call = cst.Call(
|
||||||
|
func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("parse_file")),
|
||||||
|
args=args,
|
||||||
|
whitespace_before_args=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_http_request_statement(block: dict[str, Any]) -> cst.SimpleStatementLine:
|
||||||
|
"""Build a skyvern.http_request statement."""
|
||||||
|
args = [
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("method"),
|
||||||
|
value=_value(block.get("method", "GET")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("url"),
|
||||||
|
value=_value(block.get("url", "")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add optional parameters if they exist
|
||||||
|
if block.get("headers") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("headers"),
|
||||||
|
value=_value(block.get("headers")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("body") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("body"),
|
||||||
|
value=_value(block.get("body")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("timeout") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("timeout"),
|
||||||
|
value=_value(block.get("timeout")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("follow_redirects") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("follow_redirects"),
|
||||||
|
value=_value(block.get("follow_redirects")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("label") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("label"),
|
||||||
|
value=_value(block.get("label")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
_mark_last_arg_as_comma(args)
|
||||||
|
|
||||||
|
call = cst.Call(
|
||||||
|
func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("http_request")),
|
||||||
|
args=args,
|
||||||
|
whitespace_before_args=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_prompt_statement(block: dict[str, Any]) -> cst.SimpleStatementLine:
|
||||||
|
"""Build a skyvern.prompt statement."""
|
||||||
|
args = [
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("prompt"),
|
||||||
|
value=_render_value(block.get("prompt", "")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add optional parameters if they exist
|
||||||
|
if block.get("json_schema") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("schema"),
|
||||||
|
value=_value(block.get("json_schema")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("label") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("label"),
|
||||||
|
value=_value(block.get("label")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if block.get("parameters") is not None:
|
||||||
|
args.append(
|
||||||
|
cst.Arg(
|
||||||
|
keyword=cst.Name("parameters"),
|
||||||
|
value=_value(block.get("parameters")),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
call = cst.Call(
|
||||||
|
func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("prompt")),
|
||||||
|
args=args,
|
||||||
|
whitespace_before_args=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
last_line=cst.SimpleWhitespace(INDENT),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
||||||
|
|
||||||
|
|
||||||
|
def _mark_last_arg_as_comma(args: list[cst.Arg]) -> None:
|
||||||
|
if not args:
|
||||||
|
return
|
||||||
|
|
||||||
|
last_arg = args.pop()
|
||||||
|
new_arg = cst.Arg(
|
||||||
|
keyword=last_arg.keyword,
|
||||||
|
value=last_arg.value,
|
||||||
|
comma=cst.Comma(),
|
||||||
|
whitespace_after_arg=cst.ParenthesizedWhitespace(
|
||||||
|
indent=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
args.append(new_arg)
|
||||||
|
|
||||||
|
|
||||||
def __build_base_task_statement(block_title: str, block: dict[str, Any]) -> list[cst.Arg]:
|
def __build_base_task_statement(block_title: str, block: dict[str, Any]) -> list[cst.Arg]:
|
||||||
args = [
|
args = [
|
||||||
cst.Arg(
|
cst.Arg(
|
||||||
@@ -1081,7 +1335,7 @@ def _build_run_fn(blocks: list[dict[str, Any]], wf_req: dict[str, Any]) -> Funct
|
|||||||
elif block_type == "send_email":
|
elif block_type == "send_email":
|
||||||
stmt = _build_send_email_statement(block)
|
stmt = _build_send_email_statement(block)
|
||||||
elif block_type == "text_prompt":
|
elif block_type == "text_prompt":
|
||||||
stmt = _build_validate_statement(block)
|
stmt = _build_prompt_statement(block)
|
||||||
elif block_type == "wait":
|
elif block_type == "wait":
|
||||||
stmt = _build_wait_statement(block)
|
stmt = _build_wait_statement(block)
|
||||||
elif block_type == "for_loop":
|
elif block_type == "for_loop":
|
||||||
@@ -1092,6 +1346,10 @@ def _build_run_fn(blocks: list[dict[str, Any]], wf_req: dict[str, Any]) -> Funct
|
|||||||
stmt = _build_code_statement(block)
|
stmt = _build_code_statement(block)
|
||||||
elif block_type == "file_upload":
|
elif block_type == "file_upload":
|
||||||
stmt = _build_file_upload_statement(block)
|
stmt = _build_file_upload_statement(block)
|
||||||
|
elif block_type == "file_url_parser":
|
||||||
|
stmt = _build_file_url_parser_statement(block)
|
||||||
|
elif block_type == "http_request":
|
||||||
|
stmt = _build_http_request_statement(block)
|
||||||
else:
|
else:
|
||||||
# Default case for unknown block types
|
# Default case for unknown block types
|
||||||
stmt = cst.SimpleStatementLine([cst.Expr(cst.SimpleString(f"# Unknown block type: {block_type}"))])
|
stmt = cst.SimpleStatementLine([cst.Expr(cst.SimpleString(f"# Unknown block type: {block_type}"))])
|
||||||
@@ -1099,26 +1357,26 @@ def _build_run_fn(blocks: list[dict[str, Any]], wf_req: dict[str, Any]) -> Funct
|
|||||||
body.append(stmt)
|
body.append(stmt)
|
||||||
|
|
||||||
# Add a final validation step if not already present
|
# Add a final validation step if not already present
|
||||||
has_validation = any(block.get("block_type") == "text_prompt" for block in blocks)
|
# has_validation = any(block.get("block_type") == "text_prompt" for block in blocks)
|
||||||
has_task_blocks = any(block.get("block_type") in SCRIPT_TASK_BLOCKS for block in blocks)
|
# has_task_blocks = any(block.get("block_type") in SCRIPT_TASK_BLOCKS for block in blocks)
|
||||||
if not has_validation and not has_task_blocks:
|
# if not has_validation and not has_task_blocks:
|
||||||
# Build the final validation statement using LibCST components
|
# # Build the final validation statement using LibCST components
|
||||||
args = [
|
# args = [
|
||||||
cst.Arg(
|
# cst.Arg(
|
||||||
keyword=cst.Name("prompt"),
|
# keyword=cst.Name("prompt"),
|
||||||
value=cst.SimpleString(
|
# value=cst.SimpleString(
|
||||||
'"Your goal is to validate that the workflow completed successfully. COMPLETE if successful, TERMINATE if there are issues."'
|
# '"Your goal is to validate that the workflow completed successfully. COMPLETE if successful, TERMINATE if there are issues."'
|
||||||
),
|
# ),
|
||||||
),
|
# ),
|
||||||
]
|
# ]
|
||||||
|
|
||||||
call = cst.Call(
|
# call = cst.Call(
|
||||||
func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("validate")),
|
# func=cst.Attribute(value=cst.Name("skyvern"), attr=cst.Name("validate")),
|
||||||
args=args,
|
# args=args,
|
||||||
)
|
# )
|
||||||
|
|
||||||
validation_stmt = cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
# validation_stmt = cst.SimpleStatementLine([cst.Expr(cst.Await(call))])
|
||||||
body.append(validation_stmt)
|
# body.append(validation_stmt)
|
||||||
|
|
||||||
params = cst.Parameters(
|
params = cst.Parameters(
|
||||||
params=[
|
params=[
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ class Workflow(BaseModel):
|
|||||||
return block.output_parameter
|
return block.output_parameter
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_parameter(self, key: str) -> PARAMETER_TYPE | None:
|
||||||
|
for parameter in self.workflow_definition.parameters:
|
||||||
|
if parameter.key == key:
|
||||||
|
return parameter
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class WorkflowRunStatus(StrEnum):
|
class WorkflowRunStatus(StrEnum):
|
||||||
created = "created"
|
created = "created"
|
||||||
|
|||||||
@@ -27,12 +27,21 @@ from skyvern.forge.sdk.core import skyvern_context
|
|||||||
from skyvern.forge.sdk.models import Step, StepStatus
|
from skyvern.forge.sdk.models import Step, StepStatus
|
||||||
from skyvern.forge.sdk.schemas.files import FileInfo
|
from skyvern.forge.sdk.schemas.files import FileInfo
|
||||||
from skyvern.forge.sdk.schemas.tasks import Task, TaskOutput, TaskStatus
|
from skyvern.forge.sdk.schemas.tasks import Task, TaskOutput, TaskStatus
|
||||||
from skyvern.forge.sdk.workflow.models.block import CodeBlock, FileUploadBlock, TaskBlock
|
from skyvern.forge.sdk.workflow.models.block import (
|
||||||
|
CodeBlock,
|
||||||
|
FileParserBlock,
|
||||||
|
FileUploadBlock,
|
||||||
|
HttpRequestBlock,
|
||||||
|
SendEmailBlock,
|
||||||
|
TaskBlock,
|
||||||
|
TextPromptBlock,
|
||||||
|
UrlBlock,
|
||||||
|
)
|
||||||
from skyvern.forge.sdk.workflow.models.parameter import PARAMETER_TYPE, OutputParameter
|
from skyvern.forge.sdk.workflow.models.parameter import PARAMETER_TYPE, OutputParameter
|
||||||
from skyvern.forge.sdk.workflow.models.workflow import Workflow
|
from skyvern.forge.sdk.workflow.models.workflow import Workflow
|
||||||
from skyvern.schemas.runs import RunEngine
|
from skyvern.schemas.runs import RunEngine
|
||||||
from skyvern.schemas.scripts import CreateScriptResponse, FileEncoding, FileNode, ScriptFileCreate
|
from skyvern.schemas.scripts import CreateScriptResponse, FileEncoding, FileNode, ScriptFileCreate
|
||||||
from skyvern.schemas.workflows import BlockStatus, BlockType, FileStorageType
|
from skyvern.schemas.workflows import BlockStatus, BlockType, FileStorageType, FileType
|
||||||
|
|
||||||
LOG = structlog.get_logger(__name__)
|
LOG = structlog.get_logger(__name__)
|
||||||
jinja_sandbox_env = SandboxedEnvironment()
|
jinja_sandbox_env = SandboxedEnvironment()
|
||||||
@@ -1323,7 +1332,7 @@ async def run_script(
|
|||||||
if parameters:
|
if parameters:
|
||||||
await user_script.run_workflow(parameters=parameters)
|
await user_script.run_workflow(parameters=parameters)
|
||||||
else:
|
else:
|
||||||
await user_script.run_workflow()
|
await user_script.run_workflow(parameters={})
|
||||||
else:
|
else:
|
||||||
raise Exception(f"No 'run_workflow' function found in {path}")
|
raise Exception(f"No 'run_workflow' function found in {path}")
|
||||||
|
|
||||||
@@ -1382,6 +1391,7 @@ def render_template(template: str, data: dict[str, Any] | None = None) -> str:
|
|||||||
class BlockValidationOutput:
|
class BlockValidationOutput:
|
||||||
label: str
|
label: str
|
||||||
output_parameter: OutputParameter
|
output_parameter: OutputParameter
|
||||||
|
workflow: Workflow
|
||||||
workflow_id: str
|
workflow_id: str
|
||||||
workflow_run_id: str
|
workflow_run_id: str
|
||||||
organization_id: str
|
organization_id: str
|
||||||
@@ -1410,6 +1420,7 @@ async def _validate_and_get_output_parameter(label: str | None = None) -> BlockV
|
|||||||
return BlockValidationOutput(
|
return BlockValidationOutput(
|
||||||
label=label,
|
label=label,
|
||||||
output_parameter=output_parameter,
|
output_parameter=output_parameter,
|
||||||
|
workflow=workflow,
|
||||||
workflow_id=workflow_id,
|
workflow_id=workflow_id,
|
||||||
workflow_run_id=workflow_run_id,
|
workflow_run_id=workflow_run_id,
|
||||||
organization_id=organization_id,
|
organization_id=organization_id,
|
||||||
@@ -1470,3 +1481,134 @@ async def upload_file(
|
|||||||
organization_id=block_validation_output.organization_id,
|
organization_id=block_validation_output.organization_id,
|
||||||
browser_session_id=block_validation_output.browser_session_id,
|
browser_session_id=block_validation_output.browser_session_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def send_email(
|
||||||
|
sender: str,
|
||||||
|
recipients: list[str],
|
||||||
|
subject: str,
|
||||||
|
body: str,
|
||||||
|
file_attachments: list[str] = [],
|
||||||
|
label: str | None = None,
|
||||||
|
parameters: list[PARAMETER_TYPE] | None = None,
|
||||||
|
) -> None:
|
||||||
|
block_validation_output = await _validate_and_get_output_parameter(label)
|
||||||
|
workflow = block_validation_output.workflow
|
||||||
|
smtp_host_parameter = workflow.get_parameter("smtp_host")
|
||||||
|
smtp_port_parameter = workflow.get_parameter("smtp_port")
|
||||||
|
smtp_username_parameter = workflow.get_parameter("smtp_username")
|
||||||
|
smtp_password_parameter = workflow.get_parameter("smtp_password")
|
||||||
|
if not smtp_host_parameter or not smtp_port_parameter or not smtp_username_parameter or not smtp_password_parameter:
|
||||||
|
raise Exception("SMTP host, port, username, and password parameters are required")
|
||||||
|
send_email_block = SendEmailBlock(
|
||||||
|
smtp_host=smtp_host_parameter,
|
||||||
|
smtp_port=smtp_port_parameter,
|
||||||
|
smtp_username=smtp_username_parameter,
|
||||||
|
smtp_password=smtp_password_parameter,
|
||||||
|
sender=sender,
|
||||||
|
recipients=recipients,
|
||||||
|
subject=subject,
|
||||||
|
body=body,
|
||||||
|
file_attachments=file_attachments,
|
||||||
|
label=block_validation_output.label,
|
||||||
|
output_parameter=block_validation_output.output_parameter,
|
||||||
|
parameters=parameters or [],
|
||||||
|
)
|
||||||
|
await send_email_block.execute_safe(
|
||||||
|
workflow_run_id=block_validation_output.workflow_run_id,
|
||||||
|
organization_id=block_validation_output.organization_id,
|
||||||
|
browser_session_id=block_validation_output.browser_session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def parse_file(
|
||||||
|
file_url: str,
|
||||||
|
file_type: FileType,
|
||||||
|
schema: dict[str, Any] | None = None,
|
||||||
|
label: str | None = None,
|
||||||
|
parameters: list[PARAMETER_TYPE] | None = None,
|
||||||
|
) -> None:
|
||||||
|
block_validation_output = await _validate_and_get_output_parameter(label)
|
||||||
|
file_parser_block = FileParserBlock(
|
||||||
|
file_url=file_url,
|
||||||
|
file_type=file_type,
|
||||||
|
json_schema=schema,
|
||||||
|
label=block_validation_output.label,
|
||||||
|
output_parameter=block_validation_output.output_parameter,
|
||||||
|
parameters=parameters or [],
|
||||||
|
)
|
||||||
|
await file_parser_block.execute_safe(
|
||||||
|
workflow_run_id=block_validation_output.workflow_run_id,
|
||||||
|
organization_id=block_validation_output.organization_id,
|
||||||
|
browser_session_id=block_validation_output.browser_session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def http_request(
|
||||||
|
method: str,
|
||||||
|
url: str,
|
||||||
|
headers: dict[str, str] | None = None,
|
||||||
|
body: dict[str, Any] | None = None,
|
||||||
|
timeout: int = 30,
|
||||||
|
follow_redirects: bool = True,
|
||||||
|
label: str | None = None,
|
||||||
|
parameters: list[PARAMETER_TYPE] | None = None,
|
||||||
|
) -> None:
|
||||||
|
block_validation_output = await _validate_and_get_output_parameter(label)
|
||||||
|
http_request_block = HttpRequestBlock(
|
||||||
|
method=method,
|
||||||
|
url=url,
|
||||||
|
headers=headers,
|
||||||
|
body=body,
|
||||||
|
timeout=timeout,
|
||||||
|
follow_redirects=follow_redirects,
|
||||||
|
label=block_validation_output.label,
|
||||||
|
output_parameter=block_validation_output.output_parameter,
|
||||||
|
parameters=parameters or [],
|
||||||
|
)
|
||||||
|
await http_request_block.execute_safe(
|
||||||
|
workflow_run_id=block_validation_output.workflow_run_id,
|
||||||
|
organization_id=block_validation_output.organization_id,
|
||||||
|
browser_session_id=block_validation_output.browser_session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def goto(
|
||||||
|
url: str,
|
||||||
|
label: str | None = None,
|
||||||
|
parameters: list[PARAMETER_TYPE] | None = None,
|
||||||
|
) -> None:
|
||||||
|
block_validation_output = await _validate_and_get_output_parameter(label)
|
||||||
|
goto_url_block = UrlBlock(
|
||||||
|
url=url,
|
||||||
|
label=block_validation_output.label,
|
||||||
|
output_parameter=block_validation_output.output_parameter,
|
||||||
|
parameters=parameters or [],
|
||||||
|
)
|
||||||
|
await goto_url_block.execute_safe(
|
||||||
|
workflow_run_id=block_validation_output.workflow_run_id,
|
||||||
|
organization_id=block_validation_output.organization_id,
|
||||||
|
browser_session_id=block_validation_output.browser_session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def prompt(
|
||||||
|
prompt: str,
|
||||||
|
schema: dict[str, Any] | None = None,
|
||||||
|
label: str | None = None,
|
||||||
|
parameters: list[PARAMETER_TYPE] | None = None,
|
||||||
|
) -> dict[str, Any] | list | str | None:
|
||||||
|
block_validation_output = await _validate_and_get_output_parameter(label)
|
||||||
|
prompt_block = TextPromptBlock(
|
||||||
|
prompt=prompt,
|
||||||
|
json_schema=schema,
|
||||||
|
label=block_validation_output.label,
|
||||||
|
output_parameter=block_validation_output.output_parameter,
|
||||||
|
parameters=parameters or [],
|
||||||
|
)
|
||||||
|
result = await prompt_block.execute_safe(
|
||||||
|
workflow_run_id=block_validation_output.workflow_run_id,
|
||||||
|
organization_id=block_validation_output.organization_id,
|
||||||
|
browser_session_id=block_validation_output.browser_session_id,
|
||||||
|
)
|
||||||
|
return result.output_parameter_value
|
||||||
|
|||||||
Reference in New Issue
Block a user