Add Claude 4.5 Opus support and improve SDK documentation (#4633)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
288
README.md
288
README.md
@@ -23,7 +23,7 @@
|
|||||||
<a href="https://www.linkedin.com/company/95726232"><img src="https://img.shields.io/badge/Follow%20 on%20LinkedIn-8A2BE2?logo=linkedin"/></a>
|
<a href="https://www.linkedin.com/company/95726232"><img src="https://img.shields.io/badge/Follow%20 on%20LinkedIn-8A2BE2?logo=linkedin"/></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[Skyvern](https://www.skyvern.com) automates browser-based workflows using LLMs and computer vision. It provides a simple API endpoint to fully automate manual workflows on a large number of websites, replacing brittle or unreliable automation solutions.
|
[Skyvern](https://www.skyvern.com) automates browser-based workflows using LLMs and computer vision. It provides a Playwright-compatible SDK that adds AI functionality on top of playwright, as well as a no-code workflow builder to help both technical and non-technical users automate manual workflows on any website, replacing brittle or unreliable automation solutions.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="fern/images/geico_shu_recording_cropped.gif"/>
|
<img src="fern/images/geico_shu_recording_cropped.gif"/>
|
||||||
@@ -48,32 +48,12 @@ This approach has a few advantages:
|
|||||||
1. Skyvern can operate on websites it's never seen before, as it's able to map visual elements to actions necessary to complete a workflow, without any customized code
|
1. Skyvern can operate on websites it's never seen before, as it's able to map visual elements to actions necessary to complete a workflow, without any customized code
|
||||||
1. Skyvern is resistant to website layout changes, as there are no pre-determined XPaths or other selectors our system is looking for while trying to navigate
|
1. Skyvern is resistant to website layout changes, as there are no pre-determined XPaths or other selectors our system is looking for while trying to navigate
|
||||||
1. Skyvern is able to take a single workflow and apply it to a large number of websites, as it's able to reason through the interactions necessary to complete the workflow
|
1. Skyvern is able to take a single workflow and apply it to a large number of websites, as it's able to reason through the interactions necessary to complete the workflow
|
||||||
1. Skyvern leverages LLMs to reason through interactions to ensure we can cover complex situations. Examples include:
|
|
||||||
1. If you wanted to get an auto insurance quote from Geico, the answer to a common question "Were you eligible to drive at 18?" could be inferred from the driver receiving their license at age 16
|
|
||||||
1. If you were doing competitor analysis, it's understanding that an Arnold Palmer 22 oz can at 7/11 is almost definitely the same product as a 23 oz can at Gopuff (even though the sizes are slightly different, which could be a rounding error!)
|
|
||||||
|
|
||||||
A detailed technical report can be found [here](https://www.skyvern.com/blog/skyvern-2-0-state-of-the-art-web-navigation-with-85-8-on-webvoyager-eval/).
|
A detailed technical report can be found [here](https://www.skyvern.com/blog/skyvern-2-0-state-of-the-art-web-navigation-with-85-8-on-webvoyager-eval/).
|
||||||
|
|
||||||
# Demo
|
# Demo
|
||||||
<!-- Redo demo -->
|
<!-- Redo demo -->
|
||||||
https://github.com/user-attachments/assets/5cab4668-e8e2-4982-8551-aab05ff73a7f
|
https://github.com/user-attachments/assets/5cab4668-e8e2-4982-8551-aab05ff73a7f
|
||||||
|
|
||||||
# Performance & Evaluation
|
|
||||||
|
|
||||||
Skyvern has SOTA performance on the [WebBench benchmark](webbench.ai) with a 64.4% accuracy. The technical report + evaluation can be found [here](https://www.skyvern.com/blog/web-bench-a-new-way-to-compare-ai-browser-agents/)
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="fern/images/performance/webbench_overall.png"/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## Performance on WRITE tasks (eg filling out forms, logging in, downloading files, etc)
|
|
||||||
|
|
||||||
Skyvern is the best performing agent on WRITE tasks (eg filling out forms, logging in, downloading files, etc), which is primarily used for RPA (Robotic Process Automation) adjacent tasks.
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="fern/images/performance/webbench_write.png"/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# Quickstart
|
# Quickstart
|
||||||
|
|
||||||
## Skyvern Cloud
|
## Skyvern Cloud
|
||||||
@@ -81,7 +61,11 @@ Skyvern is the best performing agent on WRITE tasks (eg filling out forms, loggi
|
|||||||
|
|
||||||
If you'd like to try it out, navigate to [app.skyvern.com](https://app.skyvern.com) and create an account.
|
If you'd like to try it out, navigate to [app.skyvern.com](https://app.skyvern.com) and create an account.
|
||||||
|
|
||||||
## Install & Run
|
## Run Locally (UI + Server)
|
||||||
|
|
||||||
|
Choose your preferred setup method:
|
||||||
|
|
||||||
|
### Option A: pip install (Recommended)
|
||||||
|
|
||||||
Dependencies needed:
|
Dependencies needed:
|
||||||
- [Python 3.11.x](https://www.python.org/downloads/), works with 3.12, not ready yet for 3.13
|
- [Python 3.11.x](https://www.python.org/downloads/), works with 3.12, not ready yet for 3.13
|
||||||
@@ -91,14 +75,13 @@ Additionally, for Windows:
|
|||||||
- [Rust](https://rustup.rs/)
|
- [Rust](https://rustup.rs/)
|
||||||
- VS Code with C++ dev tools and Windows SDK
|
- VS Code with C++ dev tools and Windows SDK
|
||||||
|
|
||||||
### 1. Install Skyvern
|
#### 1. Install Skyvern
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install skyvern
|
pip install skyvern
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Run Skyvern
|
#### 2. Run Skyvern
|
||||||
This is most helpful for first time run (db setup, db migrations etc).
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
skyvern quickstart
|
skyvern quickstart
|
||||||
@@ -111,20 +94,140 @@ local Docker PostgreSQL setup:
|
|||||||
skyvern quickstart --database-string "postgresql+psycopg://user:password@localhost:5432/skyvern"
|
skyvern quickstart --database-string "postgresql+psycopg://user:password@localhost:5432/skyvern"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Run task
|
### Option B: Docker Compose
|
||||||
|
|
||||||
#### UI (Recommended)
|
1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
|
||||||
|
2. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/skyvern-ai/skyvern.git && cd skyvern
|
||||||
|
```
|
||||||
|
3. Run quickstart with Docker Compose:
|
||||||
|
```bash
|
||||||
|
pip install skyvern && skyvern quickstart
|
||||||
|
```
|
||||||
|
When prompted, choose "Docker Compose" for the full containerized setup.
|
||||||
|
4. Navigate to http://localhost:8080
|
||||||
|
|
||||||
Start the Skyvern service and UI (when DB is up and running)
|
## SDK
|
||||||
|
|
||||||
|
**Skyvern is a Playwright extension that adds AI-powered browser automation.** It gives you the full power of Playwright with additional AI capabilities—use natural language prompts to interact with elements, extract data, and automate complex multi-step workflows.
|
||||||
|
|
||||||
|
**Installation:**
|
||||||
|
- Python: `pip install skyvern` then run `skyvern quickstart` for local setup
|
||||||
|
- TypeScript: `npm install @skyvern/client`
|
||||||
|
|
||||||
|
### AI-Powered Page Commands
|
||||||
|
|
||||||
|
Skyvern adds four core AI commands directly on the page object:
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `page.act(prompt)` | Perform actions using natural language (e.g., "Click the login button") |
|
||||||
|
| `page.extract(prompt, schema)` | Extract structured data from the page with optional JSON schema |
|
||||||
|
| `page.validate(prompt)` | Validate page state, returns `bool` (e.g., "Check if user is logged in") |
|
||||||
|
| `page.prompt(prompt, schema)` | Send arbitrary prompts to the LLM with optional response schema |
|
||||||
|
|
||||||
|
Additionally, `page.agent` provides higher-level workflow commands:
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `page.agent.run_task(prompt)` | Execute complex multi-step tasks |
|
||||||
|
| `page.agent.login(credential_type, credential_id)` | Authenticate with stored credentials (Skyvern, Bitwarden, 1Password) |
|
||||||
|
| `page.agent.download_files(prompt)` | Navigate and download files |
|
||||||
|
| `page.agent.run_workflow(workflow_id)` | Execute pre-built workflows |
|
||||||
|
|
||||||
|
### AI-Augmented Playwright Actions
|
||||||
|
|
||||||
|
All standard Playwright actions support an optional `prompt` parameter for AI-powered element location:
|
||||||
|
|
||||||
|
| Action | Playwright | AI-Augmented |
|
||||||
|
|--------|------------|--------------|
|
||||||
|
| Click | `page.click("#btn")` | `page.click(prompt="Click login button")` |
|
||||||
|
| Fill | `page.fill("#email", "a@b.com")` | `page.fill(prompt="Email field", value="a@b.com")` |
|
||||||
|
| Select | `page.select_option("#country", "US")` | `page.select_option(prompt="Country dropdown", value="US")` |
|
||||||
|
| Upload | `page.upload_file("#file", "doc.pdf")` | `page.upload_file(prompt="Upload area", files="doc.pdf")` |
|
||||||
|
|
||||||
|
**Three interaction modes:**
|
||||||
|
```python
|
||||||
|
# 1. Traditional Playwright - CSS/XPath selectors
|
||||||
|
await page.click("#submit-button")
|
||||||
|
|
||||||
|
# 2. AI-powered - natural language
|
||||||
|
await page.click(prompt="Click the green Submit button")
|
||||||
|
|
||||||
|
# 3. AI fallback - tries selector first, falls back to AI if it fails
|
||||||
|
await page.click("#submit-btn", prompt="Click the Submit button")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Core AI Commands - Examples
|
||||||
|
|
||||||
|
```python
|
||||||
|
# act - Perform actions using natural language
|
||||||
|
await page.act("Click the login button and wait for the dashboard to load")
|
||||||
|
|
||||||
|
# extract - Extract structured data with optional JSON schema
|
||||||
|
result = await page.extract("Get the product name and price")
|
||||||
|
result = await page.extract(
|
||||||
|
prompt="Extract order details",
|
||||||
|
schema={"order_id": "string", "total": "number", "items": "array"}
|
||||||
|
)
|
||||||
|
|
||||||
|
# validate - Check page state (returns bool)
|
||||||
|
is_logged_in = await page.validate("Check if the user is logged in")
|
||||||
|
|
||||||
|
# prompt - Send arbitrary prompts to the LLM
|
||||||
|
summary = await page.prompt("Summarize what's on this page")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Quick Start Examples
|
||||||
|
|
||||||
|
**Run via UI:**
|
||||||
```bash
|
```bash
|
||||||
skyvern run all
|
skyvern run all
|
||||||
```
|
```
|
||||||
|
Navigate to http://localhost:8080 to run tasks through the web interface.
|
||||||
|
|
||||||
Go to http://localhost:8080 and use the UI to run a task
|
**Python SDK:**
|
||||||
|
```python
|
||||||
|
from skyvern import Skyvern
|
||||||
|
|
||||||
#### Code
|
# Local mode
|
||||||
|
skyvern = Skyvern.local()
|
||||||
|
|
||||||
|
# Or connect to Skyvern Cloud
|
||||||
|
skyvern = Skyvern(api_key="your-api-key")
|
||||||
|
|
||||||
|
# Launch browser and get page
|
||||||
|
browser = await skyvern.launch_cloud_browser()
|
||||||
|
page = await browser.get_working_page()
|
||||||
|
|
||||||
|
# Mix Playwright with AI-powered actions
|
||||||
|
await page.goto("https://example.com")
|
||||||
|
await page.click("#login-button") # Traditional Playwright
|
||||||
|
await page.agent.login(credential_type="skyvern", credential_id="cred_123") # AI login
|
||||||
|
await page.click(prompt="Add first item to cart") # AI-augmented click
|
||||||
|
await page.agent.run_task("Complete checkout with: John Snow, 12345") # AI task
|
||||||
|
```
|
||||||
|
|
||||||
|
**TypeScript SDK:**
|
||||||
|
```typescript
|
||||||
|
import { Skyvern } from "@skyvern/client";
|
||||||
|
|
||||||
|
const skyvern = new Skyvern({ apiKey: "your-api-key" });
|
||||||
|
const browser = await skyvern.launchCloudBrowser();
|
||||||
|
const page = await browser.getWorkingPage();
|
||||||
|
|
||||||
|
// Mix Playwright with AI-powered actions
|
||||||
|
await page.goto("https://example.com");
|
||||||
|
await page.click("#login-button"); // Traditional Playwright
|
||||||
|
await page.agent.login("skyvern", { credentialId: "cred_123" }); // AI login
|
||||||
|
await page.click({ prompt: "Add first item to cart" }); // AI-augmented click
|
||||||
|
await page.agent.runTask("Complete checkout with: John Snow, 12345"); // AI task
|
||||||
|
|
||||||
|
await browser.close();
|
||||||
|
```
|
||||||
|
|
||||||
|
**Simple task execution:**
|
||||||
```python
|
```python
|
||||||
from skyvern import Skyvern
|
from skyvern import Skyvern
|
||||||
|
|
||||||
@@ -132,88 +235,6 @@ skyvern = Skyvern()
|
|||||||
task = await skyvern.run_task(prompt="Find the top post on hackernews today")
|
task = await skyvern.run_task(prompt="Find the top post on hackernews today")
|
||||||
print(task)
|
print(task)
|
||||||
```
|
```
|
||||||
Skyvern starts running the task in a browser that pops up and closes it when the task is done. You will be able to view the task from http://localhost:8080/history
|
|
||||||
|
|
||||||
You can also run a task on different targets:
|
|
||||||
```python
|
|
||||||
from skyvern import Skyvern
|
|
||||||
|
|
||||||
# Run on Skyvern Cloud
|
|
||||||
skyvern = Skyvern(api_key="SKYVERN API KEY")
|
|
||||||
|
|
||||||
# Local Skyvern service
|
|
||||||
skyvern = Skyvern(base_url="http://localhost:8000", api_key="LOCAL SKYVERN API KEY")
|
|
||||||
|
|
||||||
task = await skyvern.run_task(prompt="Find the top post on hackernews today")
|
|
||||||
print(task)
|
|
||||||
```
|
|
||||||
|
|
||||||
## SDK
|
|
||||||
|
|
||||||
**Installation:**
|
|
||||||
- Python: `pip install skyvern` then run `skyvern quickstart` for local setup
|
|
||||||
- TypeScript: `npm install @skyvern/client`
|
|
||||||
|
|
||||||
Skyvern provides SDKs for both Python and TypeScript to integrate browser automation into your applications.
|
|
||||||
|
|
||||||
### Python SDK
|
|
||||||
|
|
||||||
```python
|
|
||||||
from skyvern import Skyvern
|
|
||||||
|
|
||||||
# Connect to Skyvern Cloud
|
|
||||||
skyvern = Skyvern(api_key="your-api-key")
|
|
||||||
|
|
||||||
# Or run locally
|
|
||||||
skyvern = Skyvern.local()
|
|
||||||
|
|
||||||
# Launch a cloud browser
|
|
||||||
browser = await skyvern.launch_cloud_browser()
|
|
||||||
page = await browser.get_working_page()
|
|
||||||
|
|
||||||
# Use AI-powered actions for complex workflows
|
|
||||||
await page.agent.run_task("Navigate to the most recent invoice and download it")
|
|
||||||
|
|
||||||
# Or mix with Playwright actions
|
|
||||||
await page.goto("https://example.com")
|
|
||||||
await page.click("#button")
|
|
||||||
```
|
|
||||||
|
|
||||||
### TypeScript SDK
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { Skyvern } from "@skyvern/client";
|
|
||||||
|
|
||||||
// Connect to Skyvern Cloud
|
|
||||||
const skyvern = new Skyvern({ apiKey: "your-api-key" });
|
|
||||||
|
|
||||||
// Launch a cloud browser
|
|
||||||
const browser = await skyvern.launchCloudBrowser();
|
|
||||||
const page = await browser.getWorkingPage();
|
|
||||||
|
|
||||||
// Use AI-powered actions for complex workflows
|
|
||||||
await page.agent.runTask("Navigate to the most recent invoice and download it");
|
|
||||||
|
|
||||||
// Or mix with Playwright actions
|
|
||||||
await page.goto("https://example.com");
|
|
||||||
await page.click("#button");
|
|
||||||
```
|
|
||||||
|
|
||||||
Skyvern enhances Playwright methods with AI capabilities. Use regular Playwright syntax with a `prompt` parameter to make any action AI-powered:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Traditional Playwright - uses selectors
|
|
||||||
await page.click("#submit-button")
|
|
||||||
|
|
||||||
# AI-augmented Playwright - uses natural language
|
|
||||||
await page.click(prompt="Click on the Submit button")
|
|
||||||
await page.fill(prompt="Enter email address", value="user@example.com")
|
|
||||||
|
|
||||||
# Mix both approaches in the same workflow
|
|
||||||
await page.goto("https://example.com/dashboard")
|
|
||||||
await page.click(prompt="Click on the most recent unpaid invoice")
|
|
||||||
await page.click("#download-button")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Advanced Usage
|
## Advanced Usage
|
||||||
|
|
||||||
@@ -311,28 +332,21 @@ skyvern stop ui
|
|||||||
skyvern stop server
|
skyvern stop server
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker Compose setup
|
# Performance & Evaluation
|
||||||
|
|
||||||
1. Make sure you have [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed and running on your machine
|
Skyvern has SOTA performance on the [WebBench benchmark](webbench.ai) with a 64.4% accuracy. The technical report + evaluation can be found [here](https://www.skyvern.com/blog/web-bench-a-new-way-to-compare-ai-browser-agents/)
|
||||||
1. Make sure you don't have postgres running locally (Run `docker ps` to check)
|
|
||||||
1. Clone the repository and navigate to the root directory
|
|
||||||
1. Run `skyvern init llm` to generate a `.env` file. This will be copied into the Docker image.
|
|
||||||
1. Fill in the LLM provider key on the [docker-compose.yml](./docker-compose.yml). *If you want to run Skyvern on a remote server, make sure you set the correct server ip for the UI container in [docker-compose.yml](./docker-compose.yml).*
|
|
||||||
2. Run the following command via the commandline:
|
|
||||||
```bash
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
3. Navigate to `http://localhost:8080` in your browser to start using the UI
|
|
||||||
|
|
||||||
> [!Important]
|
<p align="center">
|
||||||
> Only one Postgres container can run on port 5432 at a time. If you switch from the CLI-managed Postgres to Docker Compose, you must first remove the original container:
|
<img src="fern/images/performance/webbench_overall.png"/>
|
||||||
> ```bash
|
</p>
|
||||||
> docker rm -f postgresql-container
|
|
||||||
> ```
|
|
||||||
|
|
||||||
If you encounter any database related errors while using Docker to run Skyvern, check which Postgres container is running with `docker ps`.
|
## Performance on WRITE tasks (eg filling out forms, logging in, downloading files, etc)
|
||||||
|
|
||||||
|
Skyvern is the best performing agent on WRITE tasks (eg filling out forms, logging in, downloading files, etc), which is primarily used for RPA (Robotic Process Automation) adjacent tasks.
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="fern/images/performance/webbench_write.png"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
# Skyvern Features
|
# Skyvern Features
|
||||||
|
|
||||||
@@ -494,11 +508,11 @@ More extensive documentation can be found on our [📕 docs page](https://www.sk
|
|||||||
# Supported LLMs
|
# Supported LLMs
|
||||||
| Provider | Supported Models |
|
| Provider | Supported Models |
|
||||||
| -------- | ------- |
|
| -------- | ------- |
|
||||||
| OpenAI | gpt4-turbo, gpt-4o, gpt-4o-mini |
|
| OpenAI | GPT-5, GPT-5.2, GPT-4.1, o3, o4-mini |
|
||||||
| Anthropic | Claude 3 (Haiku, Sonnet, Opus), Claude 3.5 (Sonnet) |
|
| Anthropic | Claude 4 (Sonnet, Opus), Claude 4.5 (Haiku, Sonnet, Opus) |
|
||||||
| Azure OpenAI | Any GPT models. Better performance with a multimodal llm (azure/gpt4-o) |
|
| Azure OpenAI | Any GPT models. Better performance with a multimodal llm (azure/gpt4-o) |
|
||||||
| AWS Bedrock | Anthropic Claude 3 (Haiku, Sonnet, Opus), Claude 3.5 (Sonnet) |
|
| AWS Bedrock | Claude 3.5, Claude 3.7, Claude 4 (Sonnet, Opus), Claude 4.5 (Sonnet, Opus) |
|
||||||
| Gemini | Gemini 2.5 Pro and flash, Gemini 2.0 |
|
| Gemini | Gemini 3 Pro/Flash, Gemini 2.5 Pro/Flash |
|
||||||
| Ollama | Run any locally hosted model via [Ollama](https://github.com/ollama/ollama) |
|
| Ollama | Run any locally hosted model via [Ollama](https://github.com/ollama/ollama) |
|
||||||
| OpenRouter | Access models through [OpenRouter](https://openrouter.ai) |
|
| OpenRouter | Access models through [OpenRouter](https://openrouter.ai) |
|
||||||
| OpenAI-compatible | Any custom API endpoint that follows OpenAI's API format (via [liteLLM](https://docs.litellm.ai/docs/providers/openai_compatible)) |
|
| OpenAI-compatible | Any custom API endpoint that follows OpenAI's API format (via [liteLLM](https://docs.litellm.ai/docs/providers/openai_compatible)) |
|
||||||
@@ -513,7 +527,7 @@ More extensive documentation can be found on our [📕 docs page](https://www.sk
|
|||||||
| `OPENAI_API_BASE` | OpenAI API Base, optional | String | `https://openai.api.base` |
|
| `OPENAI_API_BASE` | OpenAI API Base, optional | String | `https://openai.api.base` |
|
||||||
| `OPENAI_ORGANIZATION` | OpenAI Organization ID, optional | String | `your-org-id` |
|
| `OPENAI_ORGANIZATION` | OpenAI Organization ID, optional | String | `your-org-id` |
|
||||||
|
|
||||||
Recommended `LLM_KEY`: `OPENAI_GPT4O`, `OPENAI_GPT4O_MINI`, `OPENAI_GPT4_1`, `OPENAI_O4_MINI`, `OPENAI_O3`
|
Recommended `LLM_KEY`: `OPENAI_GPT5`, `OPENAI_GPT5_2`, `OPENAI_GPT4_1`, `OPENAI_O3`, `OPENAI_O4_MINI`
|
||||||
|
|
||||||
##### Anthropic
|
##### Anthropic
|
||||||
| Variable | Description| Type | Sample Value|
|
| Variable | Description| Type | Sample Value|
|
||||||
@@ -521,7 +535,7 @@ Recommended `LLM_KEY`: `OPENAI_GPT4O`, `OPENAI_GPT4O_MINI`, `OPENAI_GPT4_1`, `OP
|
|||||||
| `ENABLE_ANTHROPIC` | Register Anthropic models| Boolean | `true`, `false` |
|
| `ENABLE_ANTHROPIC` | Register Anthropic models| Boolean | `true`, `false` |
|
||||||
| `ANTHROPIC_API_KEY` | Anthropic API key| String | `sk-1234567890` |
|
| `ANTHROPIC_API_KEY` | Anthropic API key| String | `sk-1234567890` |
|
||||||
|
|
||||||
Recommended`LLM_KEY`: `ANTHROPIC_CLAUDE3.5_SONNET`, `ANTHROPIC_CLAUDE3.7_SONNET`, `ANTHROPIC_CLAUDE4_OPUS`, `ANTHROPIC_CLAUDE4_SONNET`
|
Recommended `LLM_KEY`: `ANTHROPIC_CLAUDE4.5_OPUS`, `ANTHROPIC_CLAUDE4.5_SONNET`, `ANTHROPIC_CLAUDE4_OPUS`, `ANTHROPIC_CLAUDE4_SONNET`
|
||||||
|
|
||||||
##### Azure OpenAI
|
##### Azure OpenAI
|
||||||
| Variable | Description| Type | Sample Value|
|
| Variable | Description| Type | Sample Value|
|
||||||
@@ -539,7 +553,7 @@ Recommended `LLM_KEY`: `AZURE_OPENAI`
|
|||||||
| -------- | ------- | ------- | ------- |
|
| -------- | ------- | ------- | ------- |
|
||||||
| `ENABLE_BEDROCK` | Register AWS Bedrock models. To use AWS Bedrock, you need to make sure your [AWS configurations](https://github.com/boto/boto3?tab=readme-ov-file#using-boto3) are set up correctly first. | Boolean | `true`, `false` |
|
| `ENABLE_BEDROCK` | Register AWS Bedrock models. To use AWS Bedrock, you need to make sure your [AWS configurations](https://github.com/boto/boto3?tab=readme-ov-file#using-boto3) are set up correctly first. | Boolean | `true`, `false` |
|
||||||
|
|
||||||
Recommended `LLM_KEY`: `BEDROCK_ANTHROPIC_CLAUDE3.7_SONNET_INFERENCE_PROFILE`, `BEDROCK_ANTHROPIC_CLAUDE4_OPUS_INFERENCE_PROFILE`, `BEDROCK_ANTHROPIC_CLAUDE4_SONNET_INFERENCE_PROFILE`
|
Recommended `LLM_KEY`: `BEDROCK_ANTHROPIC_CLAUDE4.5_OPUS_INFERENCE_PROFILE`, `BEDROCK_ANTHROPIC_CLAUDE4.5_SONNET_INFERENCE_PROFILE`, `BEDROCK_ANTHROPIC_CLAUDE4_OPUS_INFERENCE_PROFILE`
|
||||||
|
|
||||||
##### Gemini
|
##### Gemini
|
||||||
| Variable | Description| Type | Sample Value|
|
| Variable | Description| Type | Sample Value|
|
||||||
@@ -547,7 +561,7 @@ Recommended `LLM_KEY`: `BEDROCK_ANTHROPIC_CLAUDE3.7_SONNET_INFERENCE_PROFILE`, `
|
|||||||
| `ENABLE_GEMINI` | Register Gemini models| Boolean | `true`, `false` |
|
| `ENABLE_GEMINI` | Register Gemini models| Boolean | `true`, `false` |
|
||||||
| `GEMINI_API_KEY` | Gemini API Key| String | `your_google_gemini_api_key`|
|
| `GEMINI_API_KEY` | Gemini API Key| String | `your_google_gemini_api_key`|
|
||||||
|
|
||||||
Recommended `LLM_KEY`: `GEMINI_2.5_PRO_PREVIEW`, `GEMINI_2.5_FLASH_PREVIEW`
|
Recommended `LLM_KEY`: `GEMINI_2.5_PRO`, `GEMINI_2.5_FLASH`, `GEMINI_2.5_PRO_PREVIEW`, `GEMINI_2.5_FLASH_PREVIEW`
|
||||||
|
|
||||||
##### Ollama
|
##### Ollama
|
||||||
| Variable | Description| Type | Sample Value|
|
| Variable | Description| Type | Sample Value|
|
||||||
|
|||||||
@@ -74,12 +74,12 @@ def setup_llm_providers() -> None:
|
|||||||
update_or_add_env_var("ENABLE_OPENAI", "true")
|
update_or_add_env_var("ENABLE_OPENAI", "true")
|
||||||
model_options.extend(
|
model_options.extend(
|
||||||
[
|
[
|
||||||
|
"OPENAI_GPT5",
|
||||||
|
"OPENAI_GPT5_2",
|
||||||
"OPENAI_GPT4_1",
|
"OPENAI_GPT4_1",
|
||||||
"OPENAI_GPT4_1_MINI",
|
|
||||||
"OPENAI_GPT4_1_NANO",
|
|
||||||
"OPENAI_GPT4O",
|
|
||||||
"OPENAI_O4_MINI",
|
|
||||||
"OPENAI_O3",
|
"OPENAI_O3",
|
||||||
|
"OPENAI_O4_MINI",
|
||||||
|
"OPENAI_GPT4O",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -97,13 +97,11 @@ def setup_llm_providers() -> None:
|
|||||||
update_or_add_env_var("ENABLE_ANTHROPIC", "true")
|
update_or_add_env_var("ENABLE_ANTHROPIC", "true")
|
||||||
model_options.extend(
|
model_options.extend(
|
||||||
[
|
[
|
||||||
"ANTHROPIC_CLAUDE3.5_SONNET",
|
"ANTHROPIC_CLAUDE4.5_OPUS",
|
||||||
"ANTHROPIC_CLAUDE3.7_SONNET",
|
"ANTHROPIC_CLAUDE4.5_SONNET",
|
||||||
"ANTHROPIC_CLAUDE3.5_HAIKU",
|
|
||||||
"ANTHROPIC_CLAUDE4_OPUS",
|
"ANTHROPIC_CLAUDE4_OPUS",
|
||||||
"ANTHROPIC_CLAUDE4_SONNET",
|
"ANTHROPIC_CLAUDE4_SONNET",
|
||||||
"ANTHROPIC_CLAUDE4.5_HAIKU",
|
"ANTHROPIC_CLAUDE4.5_HAIKU",
|
||||||
"ANTHROPIC_CLAUDE4.5_SONNET",
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -2,14 +2,17 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import typer
|
import typer
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
from rich.progress import Progress, SpinnerColumn, TextColumn
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
||||||
|
from rich.prompt import Confirm
|
||||||
|
|
||||||
# Import console after skyvern.cli to ensure proper initialization
|
# Import console after skyvern.cli to ensure proper initialization
|
||||||
from skyvern.cli.console import console
|
from skyvern.cli.console import console
|
||||||
from skyvern.cli.init_command import init_env # init is used directly
|
from skyvern.cli.init_command import init_env # init is used directly
|
||||||
|
from skyvern.cli.llm_setup import setup_llm_providers
|
||||||
from skyvern.cli.utils import start_services
|
from skyvern.cli.utils import start_services
|
||||||
|
|
||||||
quickstart_app = typer.Typer(help="Quickstart command to set up and run Skyvern with one command.")
|
quickstart_app = typer.Typer(help="Quickstart command to set up and run Skyvern with one command.")
|
||||||
@@ -29,6 +32,78 @@ def check_docker() -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_docker_compose_file() -> bool:
|
||||||
|
"""Check if docker-compose.yml exists in the current directory."""
|
||||||
|
return Path("docker-compose.yml").exists() or Path("docker-compose.yaml").exists()
|
||||||
|
|
||||||
|
|
||||||
|
def check_postgres_container_conflict() -> bool:
|
||||||
|
"""Check if postgresql-container exists and is using port 5432."""
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["docker", "ps", "-a", "--filter", "name=postgresql-container", "--format", "{{.Names}}"],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
return "postgresql-container" in result.stdout
|
||||||
|
except (FileNotFoundError, subprocess.SubprocessError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def run_docker_compose_setup() -> None:
|
||||||
|
"""Run the Docker Compose setup for Skyvern."""
|
||||||
|
console.print("\n[bold blue]Setting up Skyvern with Docker Compose...[/bold blue]")
|
||||||
|
|
||||||
|
# Check for postgres container conflict
|
||||||
|
if check_postgres_container_conflict():
|
||||||
|
console.print(
|
||||||
|
Panel(
|
||||||
|
"[bold yellow]Warning: Existing PostgreSQL container detected![/bold yellow]\n\n"
|
||||||
|
"A container named 'postgresql-container' already exists, which may conflict\n"
|
||||||
|
"with the PostgreSQL service in Docker Compose (both use port 5432).\n\n"
|
||||||
|
"To avoid conflicts, remove the existing container first:\n"
|
||||||
|
"[cyan]docker rm -f postgresql-container[/cyan]",
|
||||||
|
border_style="yellow",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
proceed = Confirm.ask("Do you want to continue anyway?", default=False)
|
||||||
|
if not proceed:
|
||||||
|
console.print("[yellow]Aborting Docker Compose setup. Please remove the container and try again.[/yellow]")
|
||||||
|
raise typer.Exit(0)
|
||||||
|
|
||||||
|
# Configure LLM provider
|
||||||
|
console.print("\n[bold blue]Step 1: Configure LLM Provider[/bold blue]")
|
||||||
|
setup_llm_providers()
|
||||||
|
|
||||||
|
# Run docker compose up
|
||||||
|
console.print("\n[bold blue]Step 2: Starting Docker Compose...[/bold blue]")
|
||||||
|
with Progress(
|
||||||
|
SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True, console=console
|
||||||
|
) as progress:
|
||||||
|
progress.add_task("[bold blue]Starting Docker containers...", total=None)
|
||||||
|
try:
|
||||||
|
subprocess.run(
|
||||||
|
["docker", "compose", "up", "-d"],
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
console.print("✅ [green]Docker Compose started successfully.[/green]")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
console.print(f"[bold red]Error starting Docker Compose: {e.stderr}[/bold red]")
|
||||||
|
raise typer.Exit(1)
|
||||||
|
|
||||||
|
console.print(
|
||||||
|
Panel(
|
||||||
|
"[bold green]Skyvern is now running![/bold green]\n\n"
|
||||||
|
"Navigate to [link]http://localhost:8080[/link] to start using the UI.\n\n"
|
||||||
|
"To stop Skyvern, run: [cyan]docker compose down[/cyan]",
|
||||||
|
border_style="green",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@quickstart_app.callback(invoke_without_command=True)
|
@quickstart_app.callback(invoke_without_command=True)
|
||||||
def quickstart(
|
def quickstart(
|
||||||
ctx: typer.Context,
|
ctx: typer.Context,
|
||||||
@@ -42,12 +117,16 @@ def quickstart(
|
|||||||
False, "--skip-browser-install", help="Skip Chromium browser installation"
|
False, "--skip-browser-install", help="Skip Chromium browser installation"
|
||||||
),
|
),
|
||||||
server_only: bool = typer.Option(False, "--server-only", help="Only start the server, not the UI"),
|
server_only: bool = typer.Option(False, "--server-only", help="Only start the server, not the UI"),
|
||||||
|
docker_compose: bool = typer.Option(False, "--docker-compose", help="Use Docker Compose for full setup"),
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Quickstart command to set up and run Skyvern with one command."""
|
"""Quickstart command to set up and run Skyvern with one command."""
|
||||||
# Check Docker only if not using custom database
|
# Check Docker
|
||||||
if not database_string:
|
with console.status("Checking Docker installation...") as status:
|
||||||
with console.status("Checking Docker installation...") as status:
|
docker_available = check_docker()
|
||||||
if not check_docker():
|
if docker_available:
|
||||||
|
status.update("✅ Docker is installed and running")
|
||||||
|
else:
|
||||||
|
if not database_string:
|
||||||
console.print(
|
console.print(
|
||||||
Panel(
|
Panel(
|
||||||
"[bold red]Docker is not installed or not running.[/bold red]\n"
|
"[bold red]Docker is not installed or not running.[/bold red]\n"
|
||||||
@@ -57,13 +136,45 @@ def quickstart(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
raise typer.Exit(1)
|
raise typer.Exit(1)
|
||||||
status.update("✅ Docker is installed and running")
|
|
||||||
|
|
||||||
# Run initialization
|
# Run initialization
|
||||||
console.print(Panel("[bold green]🚀 Starting Skyvern Quickstart[/bold green]", border_style="green"))
|
console.print(Panel("[bold green]🚀 Starting Skyvern Quickstart[/bold green]", border_style="green"))
|
||||||
|
|
||||||
|
# Check if Docker Compose option was explicitly requested or offer choice
|
||||||
|
docker_compose_available = check_docker_compose_file()
|
||||||
|
|
||||||
|
if docker_compose:
|
||||||
|
if not docker_compose_available:
|
||||||
|
console.print(
|
||||||
|
Panel(
|
||||||
|
"[bold red]docker-compose.yml not found in current directory.[/bold red]\n"
|
||||||
|
"Please clone the Skyvern repository first:\n"
|
||||||
|
"[cyan]git clone https://github.com/skyvern-ai/skyvern.git && cd skyvern[/cyan]",
|
||||||
|
border_style="red",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
raise typer.Exit(1)
|
||||||
|
run_docker_compose_setup()
|
||||||
|
return
|
||||||
|
|
||||||
|
# If Docker Compose file exists, offer the choice
|
||||||
|
if docker_compose_available and docker_available and not database_string:
|
||||||
|
console.print("\n[bold blue]Setup Method[/bold blue]")
|
||||||
|
console.print("Docker Compose file detected. Choose your setup method:\n")
|
||||||
|
console.print(" [cyan]1.[/cyan] [green]Docker Compose (Recommended)[/green] - Full containerized setup")
|
||||||
|
console.print(" [cyan]2.[/cyan] pip install - Local Python setup with Docker for PostgreSQL only\n")
|
||||||
|
|
||||||
|
use_docker_compose = Confirm.ask(
|
||||||
|
"Would you like to use Docker Compose for the full setup?",
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if use_docker_compose:
|
||||||
|
run_docker_compose_setup()
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Initialize Skyvern
|
# Initialize Skyvern (pip install path)
|
||||||
console.print("\n[bold blue]Initializing Skyvern...[/bold blue]")
|
console.print("\n[bold blue]Initializing Skyvern...[/bold blue]")
|
||||||
run_local = init_env(no_postgres=no_postgres, database_string=database_string)
|
run_local = init_env(no_postgres=no_postgres, database_string=database_string)
|
||||||
|
|
||||||
|
|||||||
@@ -377,6 +377,16 @@ if settings.ENABLE_ANTHROPIC:
|
|||||||
max_completion_tokens=64000,
|
max_completion_tokens=64000,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
LLMConfigRegistry.register_config(
|
||||||
|
"ANTHROPIC_CLAUDE4.5_OPUS",
|
||||||
|
LLMConfig(
|
||||||
|
"anthropic/claude-opus-4-5-20251101",
|
||||||
|
["ANTHROPIC_API_KEY"],
|
||||||
|
supports_vision=True,
|
||||||
|
add_assistant_prefix=True,
|
||||||
|
max_completion_tokens=64000,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if settings.ENABLE_BEDROCK:
|
if settings.ENABLE_BEDROCK:
|
||||||
# Supported through AWS IAM authentication
|
# Supported through AWS IAM authentication
|
||||||
@@ -494,6 +504,26 @@ if settings.ENABLE_BEDROCK:
|
|||||||
max_completion_tokens=32000,
|
max_completion_tokens=32000,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
LLMConfigRegistry.register_config(
|
||||||
|
"BEDROCK_ANTHROPIC_CLAUDE4.5_SONNET_INFERENCE_PROFILE",
|
||||||
|
LLMConfig(
|
||||||
|
"bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||||
|
["AWS_REGION"],
|
||||||
|
supports_vision=True,
|
||||||
|
add_assistant_prefix=True,
|
||||||
|
max_completion_tokens=64000,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
LLMConfigRegistry.register_config(
|
||||||
|
"BEDROCK_ANTHROPIC_CLAUDE4.5_OPUS_INFERENCE_PROFILE",
|
||||||
|
LLMConfig(
|
||||||
|
"bedrock/us.anthropic.claude-opus-4-5-20251101-v1:0",
|
||||||
|
["AWS_REGION"],
|
||||||
|
supports_vision=True,
|
||||||
|
add_assistant_prefix=True,
|
||||||
|
max_completion_tokens=64000,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if settings.ENABLE_AZURE:
|
if settings.ENABLE_AZURE:
|
||||||
|
|||||||
Reference in New Issue
Block a user