# 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. BLAST in action ## 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`. BLAST in action 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)