# Contributing
Source: https://docs.blastproject.org/development/contributing
Let's build BLAST together!
## Getting Started
1. **Fork the Repository**
* Visit [BLAST on GitHub](https://github.com/calebwin/blast)
* Fork
2. **Set Up Development Environment**
* Follow our [Setup Guide](/development/setup)
* Discuss on [Discord](https://discord.gg/NqrkJwYYh4)
## Checklist
* [ ] Make a feature
* [ ] Create a test for it
* [ ] (if applicable) write Docs
* [ ] Submit a pull request
## Project Structure
```
blastai/
├── blastai/ # Python package
├── tests/ # Test suite
└── examples/ # Example code
```
## Getting Help
* Open an issue
* Read [Internals](/development/internals)
* Discuss in the [Discord](https://discord.gg/NqrkJwYYh4)
## Next Steps
* Review [Roadmap](/development/roadmap)
* Read [Internals](/development/internals)
* Set up [Development Environment](/development/setup)
# Internals
Source: https://docs.blastproject.org/development/internals
What's under the hood
## Core Components
### Engine
The Engine is the central component that:
* Manages task execution
* Coordinates resources
* Handles caching
* Controls parallelism
```python theme={null}
from blastai import Engine
engine = await Engine.create(
settings=settings,
constraints=constraints
)
```
### Scheduler
The Scheduler manages task execution:
* Tracks task states
* Handles task dependencies
* Manages execution order
* Coordinates parallel tasks
Task priorities:
1. Tasks with cached results
2. Tasks with cached plans
3. Subtasks of running tasks
4. Tasks with paused executors
5. Remaining tasks (FIFO)
Tasks can be in different states:
* **Scheduled**: Task is queued for execution
* **Running**: Task is currently executing
* **Completed**: Task has finished execution
### Resource Manager
Handles system resources:
* Browser instances
* Memory usage
* Cost tracking
* Resource cleanup
### Cache Manager
Manages two types of caches both in memory and on disk:
* Results cache (task outputs)
* Plans cache (execution plans generated by LLM)
### Planner
Generates natural language execution plans given user-provided task description.
## Data Flow
1. **Task Creation**
```python theme={null}
task_id = scheduler.schedule_task(
description="Search Python docs",
cache_control=""
)
```
2. **Cache Check**
* Check results cache
* Check plans cache
* Return cached result if available
3. **Resource Allocation**
* Wait for prerequisites
* Allocate browser if needed
* Assign executor
4. **Execution**
* Run task via executor
* Stream progress updates
* Cache results
5. **Cleanup**
* Release resources
* Update cache
* Handle errors
## Code Structure
```
blastai/
├── __init__.py # Package initialization
├── engine.py # Main engine implementation
├── scheduler.py # Task scheduling
├── cache.py # Caching system
├── config.py # Configuration
├── planner.py # Task planning
├── executor.py # Task execution
├── tools.py # Tools for parallelism
└── utils.py # Utilities
```
## Configuration
Settings and constraints control behavior:
```yaml theme={null}
settings:
persist_cache: true
logs_dir: "blast-logs/" # Log to files (null for terminal-only)
blastai_log_level: "info" # BLAST engine log level
browser_use_log_level: "info" # Browser operations log level
constraints:
# Resource limits
max_memory: "4GB"
max_concurrent_browsers: 4
# Model configuration
llm_model: "openai:gpt-4.1" # Main model for complex tasks
llm_model_mini: "openai:gpt-4.1-mini" # Model for simpler tasks
# Parallelism settings
allow_parallelism:
task: true
data: true
```
Environment variables for API keys:
```env theme={null}
# OpenAI configuration
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://your-endpoint.com # Optional
# Google Gemini configuration
GOOGLE_API_KEY=AIza... # From aistudio.google.com
```
## Error Handling
BLAST handles various error types:
* Browser errors
* Resource limits
* Task failures
* Cache issues
Error recovery:
1. Log error details
2. Clean up resources
3. Retry if possible
4. Report to user
## Extending BLAST
You can extend BLAST by:
1. Adding tools for further optimization
2. Creating custom executors
3. Tune better scheduling policy
## Next Steps
* Read the [Setup Guide](/development/setup)
* Learn how to [Contribute](/development/contributing)
* Check the [Roadmap](/development/roadmap)
# null
Source: https://docs.blastproject.org/development/roadmap
# Roadmap
BLAST is actively being developed by a team at Stanford University, with a focus on building a lightning-fast and cost-effective serving engine for browser-augmented LLMs. The moonshot goal is to complete tasks that previously took months of research and human collaboration in seconds. It's hard to imagine how much society would be transformed by such a drastic reduction in latency. As an analog, I would think about how much the world changed when we went from library trips to Google searches. BLAST is a similar step towards a future where we humans can be far more creative and inventive.
## Focus
* **Stability** gotta catch dem bugs
* **Cost** optimize under constraints
* **Performance** need to get way faster
* **Human-Teaming** should allow maximally natural human-AI interaction
* **Reliability** benchmarking
What we're not focusing on is building a better Browser-Use, Notte, Steel, or other vision LLM. Our focus is serving these systems in a way that is optimized under constraints
## Contributing
Please do! See our [Contributing Guide](/development/contributing).
# Setup
Source: https://docs.blastproject.org/development/setup
For BLAST contributors
## Prerequisites
1. **Python Environment**
```bash theme={null}
# Create virtual environment
python -m venv blast-venv
source blast-venv/bin/activate # Linux/macOS
# or
blast-venv\Scripts\activate # Windows
```
2. **Node.js and npm** (for web UI)
* Install from [nodejs.org](https://nodejs.org)
* Required for web frontend development
3. **Browser Requirements**
```bash theme={null}
# Install browser dependencies
python -m playwright install chromium
```
## Installation
1. **Clone Repository**
```bash theme={null}
git clone https://github.com/stanford-mast/blast.git
cd blast
```
2. **Install Dependencies**
```bash theme={null}
# Install Python dependencies
pip install -e ".[dev]"
# Install frontend dependencies
cd blastai/frontend
npm install
```
## Development Server
Just run `blastai serve`.
## Configuration
Create a development config file:
```yaml theme={null}
# dev_config.yaml
settings:
persist_cache: false # Disable cache persistence on disk (also use "no-cache" to disable in memory)
blastai_log_level: "debug"
browser_use_log_level: "debug"
constraints:
max_concurrent_browsers: 2
allow_parallelism:
task: true
data: true
```
## Testing
```bash theme={null}
# Run all tests (probably don't since our test suite needs to be distilled a bit)
pytest
# Run specific test file
pytest tests/test_engine.py
# Run with coverage
pytest --cov=blastai
```
## Debugging
1. **Backend Debugging**
```yaml theme={null}
settings:
persist_cache: false
blastai_log_level: "debug"
browser_use_log_level: "debug"
```
2. **Frontend Debugging**
* Use browser dev tools
* Check browser console
* Monitor network requests
3. **Browser Debugging**
```python theme={null}
# Enable browser debugging
constraints = Constraints(require_headless=False)
```
## Documentation
Go to the [GitHub repo for docs](github.com/stanford-mast/blast-docs).
## Next Steps
* Read [Internals](/development/internals)
* Check [Contributing Guide](/development/contributing)
* Review [Roadmap](/development/roadmap)
# Introduction
Source: https://docs.blastproject.org/get-started/introduction
We make deploying web browsing AI easy, fast, and cost-manageable.
## Well... what is it?
BLAST is a high-performance serving engine for browser-augmented LLMs.
## Use Cases
1. **I want to add web browsing AI to my app...** BLAST serves web browsing AI with an OpenAI-compatible API and concurrency and streaming baked in.
2. **I need to automate workflows...** BLAST will automatically cache and parallelize to keep costs down and enable interactive-level latencies.
3. **Just want to use web browsing AI locally...** BLAST makes sure you stay under budget and not hog your computer's memory.
## Getting Started
Check out our [Quickstart Guide](/get-started/quickstart) to get BLAST up and running!
# Quickstart
Source: https://docs.blastproject.org/get-started/quickstart
Get started with BLAST in a minute.
## Install
```bash theme={null}
pip install blastai
```
## Get an OpenAI API Key
```bash theme={null}
echo "OPENAI_API_KEY=sk-..." > .env
```
## Start the Server
```bash theme={null}
blastai serve
```
## Try the UI
Open `http://localhost:3000` in your browser and try asking BLAST something totally normal like `compare the weight of the 10 heaviest gorillas and the 10 heaviest bench presses and squats ever`.
This frontend is a lightweight Next.js app that is simply calling the OpenAI Node.js API and reading the returned stream for screenshots and text results.
## Use the API
BLAST provides an OpenAI-compatible API. Here's a simple example using the Python OpenAI client:
```python theme={null}
from openai import OpenAI
# Initialize client pointing to local BLAST server
client = OpenAI(
api_key="not-needed",
base_url="http://127.0.0.1:8000"
)
# Create a streaming response
stream = client.responses.create(
model="not-needed",
input="Compare the r/protectandserve and r/securityguard subreddits",
stream=True
)
# Process the stream
for event in stream:
if event.type == "response.output_text.delta":
# Print real-time thoughts/actions
if ' ' in event.delta: # Skip screenshots
print(event.delta, end='', flush=True)
```
## Next Steps
* Learn about the [OpenAI-Compatible API](/guides/openai-compatible-api)
* Understand [Concurrency](/guides/concurrency), [Caching](/guides/caching), [Parallelism](/guides/parallelism)
* Configure [Settings](/guides/settings) and [Constraints](/guides/constraints)
* Check out our [Roadmap](/development/roadmap)
# Caching
Source: https://docs.blastproject.org/guides/caching
Avoid re-computing
## Why is this needed?
BLAST automatically maintains a prefix cache, similar to most LLM serving engines. The difference is
that browser-augmented LLM prefix cache must be aware of the underlying browser resources required to
reuse cache and continue execution.
## Caching Options
```python theme={null}
"" # Cache everything (default)
"no-cache" # Skip results cache lookup
"no-store" # Don't store results in cache
"no-cache-plan" # Skip plan cache lookup
"no-store-plan" # Don't store plan in cache
```
Options can be combined:
```python theme={null}
"no-cache,no-store" # Skip all caching
"no-cache-plan,no-store-plan" # Skip plan cache but use result cache
"no-store,no-store-plan" # Skip storing but check cache
```
## Using Cache Control
### 1. OpenAI-Compatible API
Using `/chat/completions`:
```python theme={null}
from openai import OpenAI
client = OpenAI(
api_key="not-needed",
base_url="http://127.0.0.1:8000"
)
# With cache control
response = client.chat.completions.create(
model="not-needed",
messages=[{
"role": "user",
"content": "Search Python docs",
"cache_control": "no-cache,no-store" # Skip all caching
}]
)
# Default caching
response = client.chat.completions.create(
model="not-needed",
messages=[{
"role": "user",
"content": "Search Python docs"
}]
)
```
Using `/responses`:
```python theme={null}
# With cache control
response = client.responses.create(
model="not-needed",
input="Search Python docs",
cache_control="no-cache-plan" # Skip plan cache
)
# Clear specific response cache
client.responses.delete("resp_")
# Clear by task description
client.responses.delete("Search Python docs")
```
### 2. Engine API
```python theme={null}
from blastai import Engine
async with Engine() as engine:
# With cache control
result = await engine.run(
"Search Python docs",
cache_control="no-cache,no-store"
)
# Multiple tasks with different cache settings
results = await engine.run([
"Search Python docs", # Uses default caching
"Click Documentation" # Uses default caching
], cache_control=["no-cache", ""]) # Different settings per task
```
## Cache Persistence
Enable cache persistence in settings:
```yaml theme={null}
# config.yaml
settings:
persist_cache: true # Keep cache between engine sessions
```
When persistence is enabled:
* Results are stored in `/cache/results/`
* Plans are stored in `/cache/plans/`
* Cache survives between engine restarts
## Clearing Cache
### 1. Through API
```python theme={null}
# Clear by response ID
client.responses.delete("resp_")
client.responses.delete("chatcmpl-")
# Clear by task description
client.responses.delete("Search Python docs")
```
### 2. Through Engine
Clear all caches:
```python theme={null}
engine = await Engine.create()
await engine.cache_manager.clear()
```
### 3. Manually
Remove cache directories:
```bash theme={null}
# Remove all cache
rm -rf ~/.local/share/blast/cache/*
# Remove specific caches
rm -rf ~/.local/share/blast/cache/results/* # Clear results
rm -rf ~/.local/share/blast/cache/plans/* # Clear plans
```
## Next Steps
* Configure [Settings](/guides/settings)
* Learn about [Parallelism](/guides/parallelism)
* Understand [Constraints](/guides/constraints) for resource management
# Concurrency
Source: https://docs.blastproject.org/guides/concurrency
BLAST is "multi-tenant"
**What you need to know**
Since BLAST automatically runs tasks concurrently, the only thing you may need to set is constraints:
```python theme={null}
from blastai import Engine, Constraints
engine = await Engine.create(
constraints=Constraints(
allow_parallelism=True, # Enable/disable parallel execution
max_concurrent_browsers=4 # Maximum number of parallel browsers
)
)
```
## Task Lifecycle
Every task in BLAST goes through several stages:
1. **Creation**: Task is scheduled and assigned a unique ID
2. **Resource Allocation**: Browser and other resources are assigned
3. **Execution**: Task runs and streams progress updates
4. **Completion**: Results are stored and resources are freed
## Task Relationships
BLAST supports two types of task relationships:
### Prerequisites
Tasks can depend on other tasks completing first:
```python theme={null}
from blastai import Engine
async with Engine() as engine:
# Task B won't start until Task A completes
task_a = await engine.run("Go to python.org")
task_b = await engine.run(
"Click on Documentation",
previous_response_id=task_a.id # Set prerequisite
)
```
### Parent/Child Tasks
Tasks can spawn subtasks that run concurrently:
```python theme={null}
# Parent task can create multiple subtasks
results = await engine.run("Launch subtasks to visit each of these websites: bloomberg.com, wsj.com, and nytimes.com")
```
## Task Priorities
BLAST prioritizes tasks in this order:
1. Tasks with cached results
2. Tasks with cached execution plans
3. Subtasks of running tasks
4. Tasks with paused executors
5. Remaining tasks (FIFO order)
## Concurrent Execution
BLAST can execute multiple tasks concurrently when resources allow:
```python theme={null}
async with Engine(
constraints=Constraints(
max_concurrent_browsers=4, # Allow 4 parallel browsers
allow_parallelism=True # Enable parallel execution
)
) as engine:
# These tasks will run in parallel
task1 = engine.run("Search Python docs", stream=True)
task2 = engine.run("Search JavaScript docs", stream=True)
task3 = engine.run("Search Rust docs", stream=True)
# Process streams concurrently
async def process_stream(stream):
async for update in stream:
if isinstance(update, AgentReasoning):
print(update.content)
await asyncio.gather(
process_stream(task1),
process_stream(task2),
process_stream(task3)
)
```
## Resource Management
BLAST automatically manages resources for concurrent tasks:
* Limits concurrent browser instances
* Reuses browsers when possible
* Manages memory usage
* Handles cleanup on task completion
Monitor resource usage:
```python theme={null}
metrics = await engine.get_metrics()
print(f"Running tasks: {metrics['tasks']['running']}")
print(f"Active browsers: {metrics['concurrent_browsers']}")
print(f"Memory usage: {metrics['memory_usage_gb']} GB")
```
## Task State Management
Track task states through the API:
```python theme={null}
metrics = await engine.get_metrics()
task_states = metrics['tasks']
print(f"Scheduled: {task_states['scheduled']}") # Waiting to start
print(f"Running: {task_states['running']}") # Currently executing
print(f"Completed: {task_states['completed']}") # Finished tasks
```
## Next Steps
* Learn about how BLAST [automatically parallelizes](/guides/parallelism)
* Explore [Caching](/guides/caching) to optimize task execution
* Configure [Settings](/guides/settings) and [Constraints](/guides/constraints)
# Constraints
Source: https://docs.blastproject.org/guides/constraints
Tell BLAST its limits
**Quickstart**
```yaml theme={null}
# config.yaml
constraints:
max_concurrent_browsers: 4 # Limit concurrent browsers
max_memory: "4GB" # Limit memory usage
allow_parallelism:
task: true # Enable parallel tasks
data: true # Enable parallel data processing
# Start the BLAST server with your config
blastai serve --config config.yaml
```
## Resources
### Memory Usage
```yaml theme={null}
constraints:
max_memory: "4GB" # Accepts B, KB, MB, GB, TB units
```
### Browser Instances
```yaml theme={null}
constraints:
max_concurrent_browsers: 4 # Maximum concurrent browsers
share_browser_process: true # Share browser process between contexts
```
### Cost Limits
```yaml theme={null}
constraints:
max_cost_per_minute: 0.10 # $0.10 per minute
max_cost_per_hour: 5.00 # $5.00 per hour
```
## Parallelism
BLAST supports different types of parallelism:
```yaml theme={null}
constraints:
allow_parallelism:
task: true # Enable parallel subtasks
data: true # Enable parallel web browser content extraction
first_of_n: false # Disable first-result parallelism
max_parallelism_nesting_depth: 1 # Maximum depth of nested parallel tasks
```
## LLM
```yaml theme={null}
constraints:
llm_model: "gpt-4.1" # Primary model
llm_model_mini: "gpt-4.1-mini" # Model for parallel processing
allow_vision: true # Enable vision capabilities
```
## Browser
```yaml theme={null}
constraints:
require_headless: true # Force headless mode
share_browser_process: true # Share browser process
```
## Programmatic Configuration
While YAML configuration is recommended, you can also set constraints programmatically using the Engine API (see [Engine API](/guides/engine-api) for details):
```python theme={null}
from blastai import Engine, Constraints
engine = await Engine.create(
constraints=Constraints(
max_memory="4GB",
max_concurrent_browsers=4,
allow_parallelism={"task": True, "data": True}
)
)
```
## Next Steps
* Understand [Concurrency](/guides/concurrency)
* Learn about automatic [Parallelism](/guides/parallelism)
* Explore configuring [Settings](/guides/settings)
# Engine API
Source: https://docs.blastproject.org/guides/engine-api
Library for programmatic access to BLAST's core functionality.
## Create an Engine
```python theme={null}
from blastai import Engine, Settings, Constraints
# Create with default settings
engine = await Engine.create()
# Create with custom settings
settings = Settings(
persist_cache=True, # Persist cache between sessions
blastai_log_level="INFO" # Set logging level
)
constraints = Constraints(
max_memory=8, # Max memory in GB
max_concurrent_browsers=4, # Max concurrent browser instances
allow_parallelism=True # Enable parallel task execution
)
engine = await Engine.create(
settings=settings,
constraints=constraints
)
```
## Run Tasks
### Single Task
```python theme={null}
result = await engine.run(
"Search for Python documentation",
stream=False # Get final result only
)
print(result.final_result())
```
### Streaming Task
```python theme={null}
async for update in engine.run(
"Search for Python documentation",
stream=True # Get real-time updates
):
if isinstance(update, AgentReasoning):
print(update.content) # Print thoughts/actions
elif isinstance(update, AgentHistoryListResponse):
print("Final result:", update.final_result())
```
### Sequence of Tasks
```python theme={null}
results = await engine.run([
"Go to python.org",
"Click on Documentation",
"Search for 'asyncio'"
])
```
## Caching
BLAST by default caches results and LLM-generated steps to optimize performance. You can control caching behavior using the `cache_control` option:
```python theme={null}
# Skip cache lookup and storage
result = await engine.run(
"Search for Python documentation",
cache_control="no-cache,no-store"
)
# Skip plan cache but store result
result = await engine.run(
"Search for Python documentation",
cache_control="no-cache-plan"
)
```
## Resource Management
The engine automatically manages system resources:
* Monitors memory usage
* Limits concurrent browser instances
* Tracks LLM costs
* Handles browser reuse and cleanup
Get current resource metrics:
```python theme={null}
metrics = await engine.get_metrics()
print(f"Active browsers: {metrics['concurrent_browsers']}")
print(f"Memory usage: {metrics['memory_usage_gb']} GB")
print(f"Total cost: ${metrics['total_cost']}")
print(f"Tasks:", metrics['tasks'])
```
Monitor task states:
```python theme={null}
metrics = await engine.get_metrics()
task_states = metrics['tasks']
print(f"Scheduled: {task_states['scheduled']}")
print(f"Running: {task_states['running']}")
print(f"Completed: {task_states['completed']}")
```
The Engine can be used as an async context manager for automatic cleanup:
```python theme={null}
async with Engine() as engine:
result = await engine.run("Search for Python documentation")
print(result.final_result())
# Engine automatically stops and cleans up
```
Or stop the engine when done to clean up resources:
```python theme={null}
await engine.stop() # Clean up resources
```
## When to Use the Engine API
The Engine API is useful if you don't want to "run a server". For most use cases, prefer using `blastai serve`.
## Next Steps
* Learn about [Concurrency](/guides/concurrency) and [Parallelism](/guides/parallelism)
* Configure [Settings](/guides/settings) and [Constraints](/guides/constraints)
# OpenAI-Compatible API
Source: https://docs.blastproject.org/guides/openai-compatible-api
BLAST provides an OpenAI-compatible API for web browsing AI.
## Start the Server
```bash theme={null}
# Run the engine + web UI
blastai serve
# Run only the engine
blastai serve engine
# Run only the web UI
blastai serve web
# Run the CLI
blastai serve cli
```
You can then use any OpenAI API client:
```python theme={null}
from openai import OpenAI
client = OpenAI(
api_key="not-needed",
base_url="http://127.0.0.1:8000"
)
```
## Chat Completions API
### 1. Basic Usage
```python theme={null}
response = client.chat.completions.create(
model="not-needed",
messages=[
{"role": "user", "content": "Find the 10 heaviest gorillas"}
]
)
print(response.choices[0].message.content)
```
### 2. Streaming
Enable streaming to receive real-time updates:
```python theme={null}
response = client.chat.completions.create(
model="not-needed",
messages=[
{"role": "user", "content": "Find the 10 heaviest gorillas"}
],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
```
The streaming response includes:
1. Initial role message (`role: "assistant"`)
2. Each chunk's `delta.content` contains either:
* Thought (if the string contains `" "`)
* Screenshot (no spaces in content)
* Final result
3. Final chunk with `finish_reason: "stop"`
### 3. Conversation
BLAST lets you run multi-turn conversations. The engine's prefix caching ensures that already-computed browser actions are not repeated unless needed.
```python theme={null}
response = client.chat.completions.create(
model="not-needed",
messages=[
{"role": "user", "content": "Go to python.org"},
{"role": "assistant", "content": "I've navigated to python.org"},
{"role": "user", "content": "Click on Documentation"}
]
)
```
### 4. Caching
BLAST will by default cache both results and the LLM-generated steps to create those results (in the case of queries that have results that change but the steps to access to new result value doesn't).
Control caching behavior with `cache_control` options:
```python theme={null}
response = client.chat.completions.create(
model="not-needed",
messages=[
{
"role": "user",
"content": "Find the 10 heaviest gorillas",
"cache_control": "no-cache,no-store"
}
]
)
```
Available cache control options:
* `no-cache` - Skip results cache lookup
* `no-store` - Don't store in results cache
* `no-cache-plan` - Skip plan cache lookup
* `no-store-plan` - Don't store plan in cache
## Responses API
### 1. Basic Usage
```python theme={null}
response = client.responses.create(
model="not-needed",
input="Find the 10 heaviest gorillas"
)
print(response.output[0].content[0].text)
```
### 2. Streaming
Enable streaming to receive detailed event updates:
```python theme={null}
stream = client.responses.create(
model="not-needed",
input="Find the 10 heaviest gorillas",
stream=True
)
for event in stream:
if event.type == "response.output_text.delta":
# Skip screenshots (no spaces in delta)
if ' ' in event.delta:
print(event.delta, end="", flush=True)
```
BLAST emits a sequence of events during streaming:
1. `response.created` - Initial event when the response is created
2. `response.in_progress` - Task processing has started
3. `response.output_text.delta` - Each streaming event's delta is either:
* Thought (if the content contains `" "`)
* Screenshot (no spaces in content)
4. `response.output_text.done` - An event is complete
5. `response.completed` - Indicates all events are sent.
### 3. Conversation
Support for stateful conversations using previous response IDs:
```python theme={null}
# First response
response1 = client.responses.create(
model="not-needed",
input="Go to python.org"
)
# Follow-up using previous response ID
response2 = client.responses.create(
model="not-needed",
input="Click on Documentation",
previous_response_id=response1.id
)
```
### 4. Caching
```python theme={null}
response = client.responses.create(
model="not-needed",
input="Find the 10 heaviest gorillas",
cache_control="no-cache,no-store"
)
```
## Next Steps
* Learn about the [Engine API](/guides/engine-api) for direct access
* Understand [Concurrency](/guides/concurrency) and [Parallelism](/guides/parallelism)
* Configure [Settings](/guides/settings) and [Constraints](/guides/constraints)
# Parallelism
Source: https://docs.blastproject.org/guides/parallelism
BLAST is automatically parallel
**Enable Parallelism**
```yaml theme={null}
# config.yaml
constraints:
allow_parallelism:
task: true # Enable parallel subtasks
data: true # Enable parallel data extraction
first_of_n: false # First-result parallelism
max_parallelism_nesting_depth: 1 # Maximum nesting depth
```
```bash theme={null}
blastai serve --config config.yaml
```
## Types of Parallelism
BLAST automates four types of parallelism:
### 1. Task Parallelism
Run multiple subtasks in parallel:
```python theme={null}
from openai import OpenAI
client = OpenAI(
api_key="not-needed",
base_url="http://127.0.0.1:8000"
)
# This will launch subtasks that run in parallel
response = await client.responses.create(
model="not-needed",
input="Look up the largest gorilla in each continent",
stream=True
)
```
### 2. Data Parallelism
One of the most time-consuming steps in web browsing AI is reading and summarizing content from the web. We parallelize this by chunking and and running a smaller LLM on each chunk. Our unscientific testing shows a 5x speedup with the parallelization and 2x speedup with smaller LLM without degrading the quality of the results.
### 3. First-of-N Parallelism
When enabled, BLAST runs multiple copies of each task in parallel and takes the first result that returns, early exiting the other tasks. This helps because browser-augmented LLMs have high variability in latency.
```yaml theme={null}
constraints:
allow_parallelism:
first_of_n: true # Enable first-result parallelism
```
### 4. Nested Parallelism
Control how deep parallel tasks can nest:
```yaml theme={null}
constraints:
max_parallelism_nesting_depth: 2 # Allow nested parallel tasks
```
Example nesting structure:
```
Parent Task (launched by user)
├── Subtask 1 (parallel)
│ ├── Sub-subtask 1.1 (parallel)
│ └── Sub-subtask 1.2 (parallel)
└── Subtask 2 (parallel)
├── Sub-subtask 2.1 (parallel)
└── Sub-subtask 2.2 (parallel)
```
## Monitor Parallel Execution
```python theme={null}
metrics = await engine.get_metrics()
print(f"Running tasks: {metrics['tasks']['running']}")
print(f"Active browsers: {metrics['concurrent_browsers']}")
print(f"Memory usage: {metrics['memory_usage_gb']} GB")
```
## Model Selection
BLAST automatically selects between different models for parallel processing:
```yaml theme={null}
constraints:
llm_model: "gpt-4.1" # Primary model
llm_model_mini: "gpt-4.1-mini" # Model for data parallelism
```
## Next Steps
* Configure [Settings](/guides/settings) for optimal performance
* Learn about [Caching](/guides/caching)
* Understand [Constraints](/guides/constraints) for resource management
# Settings
Source: https://docs.blastproject.org/guides/settings
As you like it
**Quickstart**
```yaml theme={null}
# config.yaml
settings:
persist_cache: true
logs_dir: "blast-logs/" # Log to files (null for terminal-only)
blastai_log_level: "info" # BLAST engine log level
browser_use_log_level: "info" # Browser operations log level
# Start BLAST with your config
blastai serve --config config.yaml
```
### LLM Provider
Configure which models to use and their API keys:
```yaml theme={null}
constraints:
# For OpenAI models:
llm_model: "openai:gpt-4.1" # Main model for complex tasks
llm_model_mini: "openai:gpt-4.1-mini" # Model for simpler tasks
# For Google Gemini models:
llm_model: "google_genai:gemini-2.0-flash-exp"
llm_model_mini: "google_genai:gemini-2.0-flash-exp"
```
API keys can be provided in three ways:
1. Environment variables:
```bash theme={null}
export OPENAI_API_KEY=sk-...
export OPENAI_BASE_URL=https://your-endpoint.com # Optional
export GOOGLE_API_KEY=AIza... # Get from aistudio.google.com
```
2. `.env` file:
```env theme={null}
# For OpenAI models
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://your-endpoint.com # Optional
# For Google Gemini models
GOOGLE_API_KEY=AIza... # Get from aistudio.google.com
```
3. Command line:
```bash theme={null}
blastai serve --env="OPENAI_API_KEY=sk-..."
blastai serve --env="GOOGLE_API_KEY=AIza..."
```
The system automatically detects the model provider from the prefix (`openai:` or `google_genai:`) and uses the appropriate API key.
### Secrets
```yaml theme={null}
settings:
secrets_file_path: "secrets.env" # Path to secrets file
```
The secrets file can contain usernames and passwords for web apps BLAST may need to access:
```env theme={null}
jira_username=calebwin
jira_password=akjgvowi
```
### Browser
```yaml theme={null}
settings:
local_browser_path: "none" # Path to Chrome/Chromium binary
```
The `local_browser_path` setting accepts these values:
* `"none"` (default) - Use system-installed browser
* `"auto"` - Auto-detect browser location
* `"/path/to/browser"` - Specific browser binary path
### Caching
```yaml theme={null}
settings:
persist_cache: false # Persist cache between serving sessions
```
### Logging
Control logging behavior and verbosity:
```yaml theme={null}
settings:
# Log file directory (set to null to log to terminal only)
logs_dir: "blast-logs/"
# Component log levels
blastai_log_level: "debug" # Logging level for BLAST
browser_use_log_level: "info" # Logging level for browser_use
```
When `logs_dir` is set (default: "blast-logs/"):
* All logs go to files based on their levels
* Only engine metrics shown in terminal
* Log file paths shown in endpoint messages
When `logs_dir` is null:
* All logs go to terminal based on their levels
* Engine metrics are not shown
Available log levels (from most to least verbose):
* `"debug"` - Detailed debugging information
* `"info"` - General information
* `"warning"` - Warning messages
* `"error"` - Error messages only
* `"critical"` - Critical errors only
## Next Steps
* Configure [Constraints](/guides/constraints) for resource management
* Learn about automatic [Parallelism](/guides/parallelism)
* Explore [Caching](/guides/caching)
# Streaming
Source: https://docs.blastproject.org/guides/streaming
Show what the AI is thinking and browsing
## Stream Event Types
### 1. Thoughts and Actions
```python theme={null}
from openai import OpenAI
client = OpenAI(
api_key="not-needed",
base_url="http://127.0.0.1:8000"
)
stream = client.responses.create(
model="not-needed",
input="Search for Python documentation",
stream=True
)
for event in stream:
if event.type == "response.output_text.delta":
# Real-time thoughts and actions (contains spaces)
if ' ' in event.delta:
print(event.delta, end="", flush=True)
elif event.type == "response.completed":
# Final result
print("\nTask completed:", event.response.output[0].content[0].text)
```
### 2. Screenshots
```python theme={null}
for event in stream:
if event.type == "response.output_text.delta":
# Screenshot data (no spaces)
if ' ' not in event.delta:
print("Screenshot data received:", event.delta)
```
### 3. Task Progress
```python theme={null}
for event in stream:
match event.type:
case "response.created":
print("Task created")
case "response.in_progress":
print("Task started")
case "response.output_text.delta":
# Process updates
pass
case "response.output_text.done":
print("Intermediate result completed")
case "response.completed":
print("Task finished")
```
## Next Steps
* Learn about [Concurrency](/guides/concurrency) for handling multiple streams
* Explore [Caching](/guides/caching)
* Configure [Settings](/guides/settings) and [Constraints](/guides/constraints)