Migrate docs to fern (#1652)

This commit is contained in:
Suchintan
2025-01-27 10:06:11 -05:00
committed by GitHub
parent 2100174a1b
commit bf2d9ef737
101 changed files with 4437 additions and 0 deletions

View File

@@ -0,0 +1,245 @@
---
title: Creating Workflows
subtitle: Creating complex multi-step workflows
slug: workflows/creating-workflows
---
## Building workflows
Workflows represent chaining multiple blocks together. Imagine calling multiple tasks in a row, doing conditional logic, extracting data to a CSV, etc. All of these ideas will be supported within our workflows feature
All of our workflows are defined in **YAML** format, and allow chaining multiple components together to generate some defined output
Today, were building the workflows for most of our customers as we iterate on the specification.
This is a cumbersome experience -- rest assured that we are improving our web application that will offer a significantly enhanced user experience for this process.
## Request - Create Workflow (YAML)
`POST api.skyvern.com/api/v1/workflows`
Use this API to create a workflow. The response of this API is a `workflow_permanent_id`, which can be used to run workflows below
| Parameter | Type | Required? | Sample Value | Description |
| --- | --- | --- | --- | --- |
| title | String | yes | Calculate a product price diff % | A title for a workflow |
| description | String | yes | Compare two products' price diff % on alibaba vs newlabelwholesale | A description for a workflow |
## Workflow Parameters
Workflow parameters are specific parameters youre going to be passing into the workflows to allow execution
| Parameter | Type | Required? | Sample Value | Description |
| --- | --- | --- | --- | --- |
| key | String | yes | alibaba_url | unique key corresponding to a specific parameter |
| parameter_type | Enum | yes | workflow | The type of parameter for the workflow. Meant to indicate whether this parameter is being passed in via the run workflow endpoint (workflow), or whether a parameter is the output of a different workflow step (output). Can be workflow , context, aws_secret, or output |
| workflow_parameter_type | Enum | no? | string | The actual type of the parameter, meant to be used for type-safety reasons.<br/>Supported types:<br/>STRING = "string"<br/>INTEGER = "integer"<br/>FLOAT = "float"<br/>BOOLEAN = "boolean"<br/>JSON = "json”<br/>FILE_URL = "file_url” |
| description | string | yes | Alibaba product URL for checking the price of the product | Description of the parameter |
## Blocks
Blocks are the building block (pun intended) of Skyverns workflows. Each block is one discrete task you want to occur. Multiple blocks may be chained together, with outputs from one block being fed as inputs to the next block.
| Parameter | Type | Required? | Sample Value | Description |
| --- | --- | --- | --- | --- |
| block_type | Enum | yes | Task | Signifying the type of block this is in the workflow |
| label | String | yes | get_alibaba_price | The unique identifier for this block within this workflow |
| parameter_keys | Array | yes | parameter_keys:<br/>- alibaba_price<br/>- NLW_price | The list of parameters this block depends on for execution |
| output_parameter_key | string | yes | output_parameter_key: price_diff_percentage | The optional output of the block, so that it may be used by other blocks |
| \{\{ block specific parameters }} | ?? | yes | | Other parameters, specific to the block_type specified above. These are covered below |
Building blocks supported today:
1. TaskBlock: The **magic** block. Skyvern navigates through the websites to take actions and/or extract information.
2. ForLoopBlock
3. CodeBlock
4. TextPromptBlock
5. DownloadToS3Block
6. UploadToS3Block
7. SendEmailBlock
8. FileParserBlock
To read about specific blocks, check out [the block documentation](/workflows/workflow-blocks)
## Managing Credentials and Sensitive Information
This is something the Skyvern team will need to set you up with today. If you're interested, please [book a call with Suchintan](https://meetings.hubspot.com/skyvern/demo)
## Common concepts
### `continue_on_failure`
`continue_on_failure` flag indicates whether a failed block execution should block subsequent blocks or not
### `error_code_mapping`
Maps errors to specific error codes so you can have deterministic outputs
### `persist_browser_session`
The `persist_browser_session` flag indicates whether the browser session should be retained between different workflow runs. When enabled, it uses the same `user_data_dir` for each run and updates it at the end of each run. This is useful for maintaining the browser state, such as login sessions and cookies, across multiple runs of the same workflow, leading to more efficient and seamless execution.
> **Note:** This flag is set at the workflow level, not the block level, meaning it applies to the entire workflow's session persistence rather than individual blocks.
### `output_parameter_key` (autogenerated)
Specifies the output parameter of a specific block so it can be re-used in a subsequent block
Its format is always: `{label}_output`
ie the output parameter for a block like this (which can be referenced in subsequent blocks) would be: `login_output`
```
- block_type: task
label: login
parameter_keys:
- credentials
url: website_url
navigation_goal: >-
If you're not on the login page, navigate to login page and login using
the credentials given. First, take actions on promotional popups or cookie prompts that could prevent taking other action on the web page. If you fail to login to find the login page or can't login after several trials, terminate. If login is
completed, you're successful.
data_extraction_goal: >-
Extract anything for the sake of this demo
error_code_mapping:
stuck_with_popups: terminate and return this error if you can't close popups after several tries and can't take the necessary actions on the website because there is a blocking popup on the page
failed_to_login: terminate and return this error if you fail logging in to the page
```
## Example workflow
```
title: Invoice Downloading Demo (Jun 13)
description: >-
Login to the website, download all the invoices after a date, email the
invoices
workflow_definition:
parameters:
- key: website_url
parameter_type: workflow
workflow_parameter_type: string
- key: credentials
parameter_type: bitwarden_login_credential
bitwarden_client_id_aws_secret_key: SECRET
bitwarden_client_secret_aws_secret_key: SECRET
bitwarden_master_password_aws_secret_key: SECRET
bitwarden_collection_id: SECRET
url_parameter_key: website_url
- key: invoice_retrieval_start_date
parameter_type: workflow
workflow_parameter_type: string
- key: smtp_host
parameter_type: aws_secret
aws_key: SKYVERN_SMTP_HOST_AWS_SES
- key: smtp_port
parameter_type: aws_secret
aws_key: SKYVERN_SMTP_PORT_AWS_SES
- key: smtp_username
parameter_type: aws_secret
aws_key: SKYVERN_SMTP_USERNAME_SES
- key: smtp_password
parameter_type: aws_secret
aws_key: SKYVERN_SMTP_PASSWORD_SES
- parameter_type: context
key: order_history_url
source_parameter_key: get_order_history_page_url_and_qualifying_order_ids_output
- parameter_type: context
key: order_ids
source_parameter_key: get_order_history_page_url_and_qualifying_order_ids_output
- parameter_type: context
key: order_id
source_parameter_key: order_ids
blocks:
- block_type: task
label: login
parameter_keys:
- credentials
url: website_url
navigation_goal: >-
If you're not on the login page, navigate to login page and login using the credentials given, and then navigate to the personal account page. First, take actions on promotional popups or cookie prompts that could prevent taking other action on the web page. Then, try to login and navigate to the personal account page. If you fail to login to find the login page or can't login after several trials, terminate. If you're on the personal account page, consider the goal is completed.
error_code_mapping:
stuck_with_popups: terminate and return this error if you can't close popups after several tries and can't take the necessary actions on the website because there is a blocking popup on the page
failed_to_login: terminate and return this error if you fail logging in to the page
- block_type: task
label: get_order_history_page_url_and_qualifying_order_ids
parameter_keys:
- invoice_retrieval_start_date
navigation_goal: Find the order history page. If there is no orders after given start date, terminate.
data_extraction_goal: >-
You need to extract the order history page url by looking at the current
page you're on. You need to extract contact emails you see on the page. You also need to extract the order ids for orders that
happened on or after invoice_retrieval_start_date. Make sure to filter
only the orders that happened on or after invoice_retrieval_start_date. You need to compare each order's date with the invoice_download_start_date. You can only include an order in the output if the order's date is after or the same as the invoice_download_start_date.
While comparing dates, first compare year, then month, then day. invoice_retrieval_start_date
is in YYYY-MM-DD format. The dates on the websites may be in different formats, compare accordingly and compare year, date, and month.
error_code_mapping:
failed_to_find_order_history_page: return this error if you can't find the order history page on the website
no_orders_found_after_start_date: return this error if there are no orders after the specified invoice_download_start_date
data_schema:
type: object
properties:
order_history_url:
type: url
description: >-
The exact URL of the order history page. Do not make any
assumptions. Return the URL that's passed along in this context.
contact_emails:
type: array
items:
type: string
description: Contact email for the ecommerce website you're on. If you can't find any return null
date_comparison_scratchpad:
type: string
description: >-
You are supposed to filter the orders that happened on or after the invoice_download_start_date. Think through how you will approach this task step-by-step here. Consider these before starting the comparison:
- What format is the order date in? How can you parse it into a structured format?
- What is the correct way to compare two dates?
- How will you compare the order dates to the invoice_download_start_date?
Write out your thought process before filling out the order_ids field below. Remember, the original date may be in any format, so parse it carefully! The invoice_download_start_date will be an exact date you can directly compare against in the format YYYY-MM-DD.
order_ids:
type: array
items:
type: object
properties:
order_date:
type: iso-8601-date-string
order_id:
type: string
description: >-
Return a list of order id strings. Do not return order ids of
orders that happened before the specified
invoice_retrieval_start_date
- block_type: for_loop
label: iterate_over_order_ids
loop_over_parameter_key: order_ids
continue_on_failure: true
loop_blocks:
- block_type: task
label: download_invoice_for_order
complete_on_download: true
continue_on_failure: true
parameter_keys:
- order_id
url: order_history_url
navigation_goal: Download the invoice of the order with the given order ID. Make sure to download the invoice for the given order id. If the element tree doesn't have a matching order id, check the screenshots. Complete if you have successfully downloaded the invoice according to action history, if you were able to download it, you'll see download_triggered=True for the last step. If you don't see a way to download an invoice, navigate to the order page if possible. If there's no way to download an invoice terminate. If the text suggests printing, you can assume you can download it. Return click action with download=True if you want to trigger a download.
error_code_mapping:
not_possible_to_download_invoice: return this error if the website doesn't allow downloading/viewing invoices
cant_solve_captcha: return this error if captcha isn't solved after multiple retries
- block_type: upload_to_s3
label: upload_downloaded_files_to_s3
path: SKYVERN_DOWNLOAD_DIRECTORY
- block_type: send_email
label: send_email
smtp_host_secret_parameter_key: smtp_host
smtp_port_secret_parameter_key: smtp_port
smtp_username_secret_parameter_key: smtp_username
smtp_password_secret_parameter_key: smtp_password
sender: hello@skyvern.com
recipients:
- founders@skyvern.com
subject: Skyvern - Downloaded Invoices Demo
body: website_url
file_attachments:
- SKYVERN_DOWNLOAD_DIRECTORY
```

View File

@@ -0,0 +1,156 @@
---
title: Getting Existing Workflows
subtitle: ''
slug: workflows/getting-workflows
---
# Workflows API Specification
## Endpoint
### `GET /api/v1/workflows`
This endpoint retrieves a list of workflows.
### Request
* **URL:** `https://api.skyvern.com/api/v1/workflows`
* **Method:** `GET`
* **Query Parameters:**
* `page`: The page number to retrieve (default: `1`).
* `only_workflows`: Set to `true` to only retrieve workflows.
### Headers
* **x-api-key:** `String` `yes` `[your-api-key-here]`
### Example Curl Request
```bash
curl 'https://api.skyvern.com/api/v1/workflows?page=1&only_workflows=true' \
-H 'x-api-key: [your-api-key-here]' \
```
## API Response Structure
The API returns a JSON array where each element represents a workflow object. Below is the structure and documentation for each field.
```json
[
{
"workflow_id": "string",
"organization_id": "string",
"title": "string",
"workflow_permanent_id": "string",
"version": "integer",
"is_saved_task": "boolean",
"description": "string",
"proxy_location": "string | null",
"webhook_callback_url": "string | null",
"totp_verification_url": "string | null",
"workflow_definition": {
"parameters": [
{
"parameter_type": "string",
"key": "string",
"description": "string | null"
}
],
"blocks": [
{
"label": "string",
"block_type": "string"
}
]
}
}
]
```
### Fields
* **workflow_id** (`string`):
* A unique identifier for the workflow. This ID is used to reference the workflow in various operations and tasks.
* **organization_id** (`string`):
* The unique identifier of the organization to which the workflow belongs. This is useful for segregating workflows by different organizations.
* **title** (`string`):
* The human-readable title of the workflow. It typically describes the primary task or purpose of the workflow.
* **workflow_permanent_id** (`string`):
* A permanent and unique identifier for the workflow. Unlike `workflow_id`, this ID remains consistent across different versions of the workflow.
* **version** (`integer`):
* Indicates the version number of the workflow. This is incremented with each update or modification to the workflow.
* **is_saved_task** (`boolean`):
* A flag indicating whether the workflow is saved as a task for future use (`true`) or not (`false`).
* **description** (`string`):
* A brief description of what the workflow does. This may include the primary goal or steps involved in the workflow.
* **proxy_location** (`string | null`):
* The location setting for the proxy, if applicable. It could be `RESIDENTIAL`, `DATACENTER`, or `null` if no proxy is used.
* **webhook_callback_url** (`string | null`):
* The URL to which callbacks will be sent once the workflow completes or if specific events occur during its execution. This field may be `null` if no webhook is configured.
* **totp_verification_url** (`string | null`):
* The URL for TOTP (Time-based One-Time Password) verification, if required. This field is `null` if TOTP verification is not necessary for the workflow.
* **workflow_definition** (`object`):
* Contains the detailed definition of the workflow, including the parameters and blocks that make up the workflow.
* **parameters** (`array`):
* A list of parameters used by the workflow. Each parameter defines a key-value pair that may include the type of parameter, its key, and an optional description. Parameters help in customizing and controlling the workflow's behavior.
* **blocks** (`array`):
* A series of blocks that represent individual tasks or actions within the workflow. Each block includes a label and type, which define the nature and purpose of the task within the workflow. Blocks can range from simple tasks, like logging in, to more complex sequences of actions.
Example Response
Heres an example of what the API might return:
```
[
{
"workflow_id": "w_297763518988864302",
"organization_id": "o_197675547813248794",
"title": "Test Workday Application",
"workflow_permanent_id": "wpid_297751296240552836",
"version": 4,
"is_saved_task": false,
"description": "Login Workday and submit the application",
"proxy_location": "RESIDENTIAL",
"webhook_callback_url": null,
"totp_verification_url": null,
"workflow_definition": {
"parameters": [
{
"parameter_type": "output",
"key": "login_output",
"description": "Output parameter for block login"
},
{
"parameter_type": "workflow",
"key": "website_url",
"description": null
}
],
"blocks": [
{
"label": "login",
"block_type": "task"
},
{
"label": "submit",
"block_type": "task"
}
]
}
}
]
```

View File

@@ -0,0 +1,19 @@
---
title: Introduction
subtitle: Workflows -- chaining multiple tasks together
slug: workflows/introduction
---
Workflows represent chaining multiple blocks together. Imagine calling multiple tasks in a row, doing conditional logic, extracting data to a CSV, etc. All of these ideas will be supported within our workflows feature.
Building blocks supported today:
1. TaskBlock: The **magic** block. Skyvern navigates through the websites to take actions and/or extract information.
2. ForLoopBlock
3. CodeBlock
4. TextPromptBlock
5. DownloadToS3Block
6. UploadToS3Block
7. SendEmailBlock
8. FileParserBlock

View File

@@ -0,0 +1,211 @@
---
title: Running Workflows
subtitle: Executing complex multi-step workflows
slug: workflows/running-workflows
---
## Running workflows
### `POST /workflows/{workflow_permanent_id}/run`
You can see the generic endpoint definition below. Well go into the specifics of the invoice retrieval workflow in the next section.
### Body
| Parameter | Type | Required? | Sample Value | Description |
| --- | --- | --- | --- | --- |
| data | JSON | no | \{ <br/>"website_url": "YOUR_URL",<br/>"invoice_retrieval_start_date": "2024-04-15"<br/> \}, | The data field is used to pass in required and optional parameters that a workflow accepts. For the invoice retrieval workflow, required fields are website_url and invoice_retrieval_start_date |
| webhook_callback_url | String | no | … | Our system will send the webhook once it is finished executing the workflow run. |
| proxy_location | String | no | RESIDENTIAL | Proxy location for the web browser. Please pass RESIDENTIAL. <br /> If we use residential proxies, Skyverns requests to the websites will be less suspicious. |
### Response
| Parameter | Type | Always returned? | Sample Value | Description |
| --- | --- | --- | --- | --- |
| workflow_permanent_id | String | yes | wpid_123456 | The workflow id |
| workflow_run_id | String | yes | wr_123456 | The workflow run id that represents this specific workflow run. <br/> You can use this id to match the webhook response to the initial request. |
### Sample Request & Response - Invoice retrieval
```bash
-- Sample Request
curl --location 'https://api.skyvern.com/api/v1/workflows/wpid_123456/run' \
--header 'x-api-key: <USE_YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"data": {
"website_url": "your_website",
"invoice_retrieval_start_date": "2024-04-15"
},
"proxy_location": "RESIDENTIAL",
"webhook_callback_url": "<your-endpoint>"
}'
-- Sample Response
{
"workflow_id": "wpid_123456",
"workflow_run_id": "wr_123456"
}
```
## Retrieving workflow runs
### `GET /workflows/runs/{workflow_run_id}`
### Response
| Parameter | Type | Sample value | Description |
| --- | --- | --- | --- |
| workflow_id | String | wpid_123456 | |
| workflow_run_id | String | wr_123456 | |
| status | String | completed | Status of the workflow run. Possible values: created, running, failed, terminated, completed |
| proxy_location | JSON | RESIDENTIAL | |
| webhook_callback_url | String | 127.0.0.1:8000/api/v1/webhook | |
| created_at | Timestamp | 2024-05-16T08:35:24.920793 | Timestamp for when the workflow run is created |
| modified_at | Timestamp | 2024-05-16T08:42:32.568908 | Last modified timestamp for the workflow run |
| parameters | JSON | see sample response below | The parameters that the workflow run was triggered with. For the invoice retrieval workflow, this field will have the website_url and invoice_retrieval_start_date values you sent. |
| screenshot_urls | list[String] | see sample response below | Final screenshots for the last 3 tasks in the workflow. |
| recording_url | String | see sample response below | The full browser recording. |
| outputs | JSON | see sample response below | See the explaining outputs section |
### Sample response
```json
{
"workflow_id": "wpid_123456",
"workflow_run_id": "wr_123456",
"status": "completed",
"proxy_location": "RESIDENTIAL",
"webhook_callback_url": "127.0.0.1:8000/api/v1/webhook",
"created_at": "2024-05-16T08:35:24.920793",
"modified_at": "2024-05-16T08:42:32.568908",
"parameters": {
"website_url": "YOUR_WEBSITE_URL",
"invoice_retrieval_start_date": "2024-04-15"
},
"screenshot_urls": [
"https://skyvern-artifacts.s3.amazonaws.com/...",
"https://skyvern-artifacts.s3.amazonaws.com/...",
"https://skyvern-artifacts.s3.amazonaws.com/..."
],
"recording_url": "https://skyvern-artifacts.s3.amazonaws.com/...",
"outputs": {
"login_output": {
"task_id": "tsk_1234",
"status": "completed",
"extracted_information": null,
"failure_reason": null,
"errors": []
},
"get_order_history_page_url_and_qualifying_order_ids_output": {
"task_id": "tsk_258409009008559418",
"status": "completed",
"extracted_information": {
...
},
"failure_reason": null,
"errors": []
},
"iterate_over_order_ids_output": [
[
{
...
}
]
],
"download_invoice_for_order_output": {
"task_id": "tsk_258409361195877732",
"status": "completed",
"extracted_information": null,
"failure_reason": null,
"errors": []
},
"upload_downloaded_files_to_s3_output": [
"s3://skyvern-uploads/..."
],
"send_email_output": {
"success": true
}
}
}
```
## Webhooks
Skyvern always sends webhooks when a workflow run is executed. The status for an executed workflow run can be: `completed, failed, terminated`.
The webhook body is the same as the get workflow run endpoint.
### Webhook Headers
| Parameter | Type | Required? | Sample Value | Description |
| --- | --- | --- | --- | --- |
| x-skyvern-signature | String | yes | v0=a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503 | Authentication token that allows our service to communicate with your backend service via callback / webhook <br/> <br/> Well be using the same strategy slack uses, as defined here: https://api.slack.com/authentication/verifying-requests-from-slack#making__validating-a-request |
| x-skyvern-timestamp | String | yes | 1531420618 | Timestamp used to decode and validate the incoming webhook call
Well be using the same strategy slack uses, as defined here: https://api.slack.com/authentication/verifying-requests-from-slack#making__validating-a-request |
## Explaining `outputs`
If you checked out the sample response, you probably thought “What the heck is this field right here?”.
We previously went over that workflows are essentially a list of building blocks. `outputs` field has the output for every single block that a workflow has. Before we start analyzing the `outputs` from the sample above, lets go over the building blocks for the invoice retrieval workflow.
### Building blocks of invoice retrieval workflow:
| # | Block type | Block label | Purpose |
| --- | --- | --- | --- |
| 1 | TaskBlock | login | Find login page, login to the website |
| 2 | TaskBlock | get_order_history_page_url_and_qualifying_order_ids | Find the order history page, extract order history page url, contact emails, and order details for orders after the start date |
| 3 | ForLoopBlock | iterate_over_order_ids | The contents of the ForLoop is executed for each order id thats extracted from the previous step. |
| 4 | TaskBlock [within ForLoopBlock] | download_invoice_for_order | For a given order id, find a way to download the invoice, download it. |
| 5 | UploadToS3Block | upload_downloaded_files_to_s3 | Upload all downloaded invoices to S3 |
| 6 | SendEmailBlock | send_email | Send an email attaching all the downloaded invoices |
### ⚠️ Still in development, not a blocker
1. The blocks within the ForLoop show up twice: within the ForLoop output and as a root block.
2. UploadToS3Block output is S3 URIs at the moment. Theyll be updated with signed urls instead.
3. Add block type to each object in `outputs`, define the output structure for each block for easier integration.
```json
...
"outputs": {
"login_output": {
"task_id": "tsk_1234",
"status": "completed",
"extracted_information": null,
"failure_reason": null,
"errors": []
},
"get_order_history_page_url_and_qualifying_order_ids_output": {
"task_id": "tsk_1234",
"status": "completed",
"extracted_information": {
...
},
"failure_reason": null,
"errors": []
},
"iterate_over_order_ids_output": [
...
],
"download_invoice_for_order_output": {
"task_id": "tsk_1234",
"status": "completed",
"extracted_information": null,
"failure_reason": null,
"errors": []
},
"upload_downloaded_files_to_s3_output": [
"s3://skyvern-uploads/...",
"s3://skyvern-uploads/..."
],
"send_email_output": {
"success": true
}
}
...
```

View File

@@ -0,0 +1,97 @@
---
title: What the heck is a parameter?
slug: workflows/what-is-a-parameter
---
## What is a Parameter?
Parameters allow you to replace specific values with placeholders that can be customized run by run.
If I have a series of task blocks in a workflow that go to Sephora, search for a specific black mascara, add 100 to my cart and purchase, I would have to go in and manually change those items every time if I wanted to do so for a different website, a different product, and different quantity. For those three values, instead of putting in the fixed Sephora URL, product number, and quantity, I can create placeholders for those string value inputs.
* So, instead of “www.sephora.com” the placeholder parameter would be “website_URL”
* Instead of “ID 123456”, “product_ID”
* And instead of “100”, “quantity”
With these registered as parameters, the user doesnt have to change the values in each node if they want to change the site, product, or quantity, they only have to write them in after pressing “run”. In this case, the “Sephora Purchase Acquisition” becomes a template for more general “Purchase Acquisitions” that can be customized more easily without tampering with the inner workings of the workflow.
## Adding a Parameter
**Step 1.** To create a placeholder value, you must first create one using the “parameters” dropdown in the Workflow Editor
<img src="../images/what_is_a_parameter/p.1.png"/>
**Step 2.** Add a workflow parameter
* Note that if you are looking to add a username or password parameter, you must first contact us
<img src="../images/what_is_a_parameter/p.2.png"/>
<img src="../images/what_is_a_parameter/p.3.png"/>
**Step 3.** Add a key that will act as the name for the parameter. You can also include a description or set a default value if you wish. Note that a default value pre-populates the run parameter, but can be overrode
<img src="../images/what_is_a_parameter/p.4.png"/>
<img src="../images/what_is_a_parameter/p.5.png"/>
<img src="../images/what_is_a_parameter/p.6.png"/>
**Step 4.** Input the parameter. In this case, we are using the website_URL parameter in the URL of the task block (this is considered a “parameterized field”). For other parameters, you might need to link it in the parameters drop down. **Make sure you read the “Using Parameters” section—this is critical!**
<img src="../images/what_is_a_parameter/p.7.png"/>
<img src="../images/what_is_a_parameter/p.8.png"/>
**Step 5.** Press “Run” after you are done configuring your workflow and input values for any parameters you have linked throughout your workflow. Note that if you set a default value, it will automatically populate here.
<img src="../images/what_is_a_parameter/p.9.png"/>
## Using Parameters
There are two ways to use parameters in Skyverns Workflow Agent (Beta):
### 1. Parameterized Fields: certain fields can accept a fixed string value or a parameter
If you are looking to load a parameterized value into the following fields, you can only do so by passing the parameters key, or name, as text into the input:
* Task block: URL, Suffix, TOTP Identifier
* For Loop: loop over value
* File Parser: URL
* Send Email: recipients, body
**Steps**
1. Create the parameter in the parameter dropdown in the menu. In this case, the key is “website_URL”
2. Type the key freeform into the task URL
<img src="../images/what_is_a_parameter/u.1.png"/>
### 2. Block Parameters: any parameter linked in the block that will be passed into the LLM as context Skyvern needs to complete the task. Any other non-parameterized fields accept block parameters this way.
Create this value when you have details that vary from run-to-run:
* For instance, you can parameterize usernames or passwords, how to do something, dates, or uploaded files
* Ask yourself: does this vary run-by-run? If the answer is yes, there might be value in creating a parameter for it
* Examples: start_date, end_date, procurement_list_file, email_recipients, how_to_download_an_invoice
* to load these values, you can add them in the workflow editor using the run parameters tab in the header
* Make sure to check if this value needs to go into a parameterized field, if not, load them into the parameters drop down, you dont need to worry about the placement or order as the LLM pieces together what goes where
**Steps**
1. Create the parameter in the parameter dropdown in the menu. In this case, the parameter keys are start_date, end_date, and how_to_find_invoices_page
2. Link the values in the parameters dropdown menu
<img src="../images/what_is_a_parameter/u.2.png"/>
## Future Plans for Parameters
Our main goal is to make every field a parameterized field and remove block parameters
* We know its confusing, but its only temporary! In the future were headed toward loading parameters directly into each input field.
* One day, your prompt may look like “Find the invoices page using **/how_to_find_invoices_page**, filter the invoices using **/start_date** and **/end_date** provided.” Or perhaps brackets as are traditionally used in code.

View File

@@ -0,0 +1,209 @@
---
title: Workflow Blocks
subtitle: Individual Blocks within Skyvern
slug: workflows/workflow-blocks
---
## TaskBlock
The magic block. Skyvern navigates through the websites to take actions and/or extract information.
Example block:
```
- block_type: task
label: login
parameter_keys:
- credentials
url: website_url
navigation_goal: >-
If you're not on the login page, navigate to login page and login using
the credentials given. First, take actions on promotional popups or cookie prompts that could prevent taking other action on the web page. If you fail to login to find the login page or can't login after several trials, terminate. If login is
completed, you're successful.
data_extraction_goal: >-
Extract anything for the sake of this demo
error_code_mapping:
stuck_with_popups: terminate and return this error if you can't close popups after several tries and can't take the necessary actions on the website because there is a blocking popup on the page
failed_to_login: terminate and return this error if you fail logging in to the page
```
Inputs:
1. **URL *(often required):*** Skyvern Agents starting point. Ideally the website youd like to automate.
- In the workflows interface, if this input is left blank it will continue where the previous node left off. The idea of a navigation goal is to set or reset where the agent starts off.
- If youre logging in to a site using the first task block, you would want to leave URL blank for the second block so that it can continue after logging in
2. **Navigation Goal *(often required):*** details where Skyvern is going and what Skyvern is doing. Clear Navigation Goals will be a single goal, broken down into steps. Avoid supplying multiple goals. You need to specify when the goal is complete, using “COMPLETE”, or when to abandon that goal, using “TERMINATE”
- The navigation goal is not used to load the URL. Asking Skyvern to “go to website A” in this field will not have the intended effect
- Terminations result in Skyvern explaining why it stopped navigating
- This field can be omitted if you only want Skyvern to extract data without navigating anywhere else
3. **Data Extraction Goal *(optional):*** aside from where Skyvern is going and what Skyvern is doing, is there anything that Skyvern is extracting and returning back? A good data extraction goal is specific about what Skyvern is returning to the user
- Note that data extractions only happen after Skyvern is finished navigating
4. **Extracted Information Schema *(optional):*** if you have a data extraction goal, some users need it formatted in a certain way for internal purposes. Navigation payload accepts JSON formatted specifications for how the data should be returned
5. **Max Steps Override *(optional):*** some users want to cap cost through the number of steps the task can take
6. **Max Retries *(optional):*** the number of times a step can be retried if it fails
7. **Complete on Download *(optional):*** Allows Skyvern to complete the task after a file has been downloaded
8. **File Suffix *(optional):*** an identifier attached to the downloaded file
9. **TOTP URL and TOTP Identifier *(optional):*** if you have an internal system where you can store the 2FA TOTP code, this URL calls on this storage space. The identifier allows you to link the code to the task, this is critical if you are running multiple tasks concurrently. [Contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) if you would like to set up 2FA retreival in your workflows.
10. **Parameters *(optional):*** parameters are self-defined placeholders that are specified run-to-run. They can either be workflow parameters, passed in via an API call, or output parameters, extracted from a previous task block. If specified, they are used by Skyvern to assist in the navigation, to fill out forms or further influence what actions to take on a website.
## ForLoopBlock
Iterate over something such as a CSV or the output of a previous block. The blocks nested under `loop_blocks` are the blocks that will be repeated for each entry in the
```
- block_type: for_loop
label: iterate_over_order_ids
loop_over_parameter_key: order_ids
continue_on_failure: true
loop_blocks:
- block_type: task
label: download_invoice_for_order
complete_on_download: true
continue_on_failure: true
parameter_keys:
- order_id
url: order_history_url
navigation_goal: >-
Download the invoice of the order with the given order ID.
Make sure to download the invoice for the given order id.
If the element tree doesn't have a matching order id, check the screenshots.
Complete if you have successfully downloaded the invoice according to action history, if you were able to download it, you'll see download_triggered=True for the last step.
If you don't see a way to download an invoice, navigate to the order page if possible.
If there's no way to download an invoice terminate.
If the text suggests printing, you can assume you can download it.
Return click action with download=True if you want to trigger a download.
error_code_mapping:
not_possible_to_download_invoice: return this error if the website doesn't allow downloading/viewing invoices
cant_solve_captcha: return this error if captcha isn't solved after multiple retries
```
Inputs:
1. **Loop Value *(required):*** This is the value that the loop will iterate over. For instance, if you have for every invoice ID, do X, invoice ID would be the value for this input.
* Please [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) if you would like to add a loop block. Since were in beta, the loop value needs to be parameterized from the backend.
2. **Another block nested within the loop (required)**
## CodeBlock
This block executes user-defined Python code within our execution environment. Its able to take parameters as input and transform them based on a certain specification.
In addition to running simple code snippets, CodeBlock allows you to:
- execute asynchronous code
- control your browser page inside Skyvern
**Example Block**
```json
- block_type: code
label: calculate_percentage_diff
parameter_keys:
- alibaba_price
- amazon_price
code: |
if amazon_price["unitPrice"] and alibaba_price["unitPrice"]:
result = 1.0 * (alibaba_price["unitPrice"] - amazon_price["unitPrice"]) / amazon_price["unitPrice"]
else:
result = None
output_parameter_key: price_diff_percentage
```
**Example Block with Browser Control**
```json
- block_type: code
label: get_tab_details
code: |
print("Getting tab details")
result = {
"url": skyvern_page.url,
"title": await skyvern_page.title()
}
print("Got details:", result)
print("Now I want to see a cat")
await skyvern_page.goto("https://cataas.com/cat")
```
Inputs:
1. **Code *(required):*** Insert your custom Python code so that you can define your own custom block.
## TextPromptBlock
Do a custom OpenAI query as a part of your workflow
```
- block_type: text_prompt
label: generate_new_title
parameter_keys:
- alibaba_title
- amazon_title
llm_key: OPENAI_GPT4O
prompt: >
You're given two e-commerce product titles. Use both and generate a
better one.
Title 1: {{ alibaba_title }}
Title 2: {{ amazon_title }}
output_parameter_key: new_title
```
Inputs:
1. **Prompt *(required):*** Write a natural language prompt to be sent to the LLM to generate a text response
2. **JSON Schema *(optional):*** Craft a JSON input that structures the LLM output for use in another programming task
## DownloadToS3Block / UploadToS3Block
Persists files inside S3
```
- block_type: upload_to_s3
label: upload_downloaded_files_to_s3
path: SKYVERN_DOWNLOAD_DIRECTORY
```
* Since were in beta, this feature is unavailable right now, [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) if you would like to use it.
## SendEmailBlock
Sends an email with some data
```
- block_type: send_email
label: send_email
smtp_host_secret_parameter_key: smtp_host
smtp_port_secret_parameter_key: smtp_port
smtp_username_secret_parameter_key: smtp_username
smtp_password_secret_parameter_key: smtp_password
sender: hello@skyvern.com
recipients:
- founders@skyvern.com
subject: Skyvern - Downloaded Invoices Demo
body: website_url
file_attachments:
- SKYVERN_DOWNLOAD_DIRECTORY
```
Inputs:
1. **Recipients *(required):*** a list of people who will receive the email separated by commas
2. **Subject/Body *(optional):*** the header and body of an email
3. **File attachments *(optional):*** since were still in beta, you will need to [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) to upload attachments to the email
## FileParserBlock
Downloads and parses a file to be used within other workflow blocks.
**Supported types:** CSV
```
- block_type: file_url_parser
label: csv_parser
file_type: csv
file_url: <csv_file_url>
```
Inputs:
1. **File URL *(required):*** This block allows you to use a CSV within your workflow.
* Since were still in beta, you will need to [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) to load a value into this block