A sophisticated multi-agent web automation system powered by Google Gemini 2.5 Pro
Featuring visual perception via OmniParser, intelligent task planning, and autonomous self-supervised execution.
Features • Installation • Quick Start • Architecture • Documentation
| Feature | Description |
|---|---|
| 🏗️ Multi-Agent Architecture | Hierarchical system with Master orchestrator, Supervisor monitors, and Worker executors for scalable automation |
| 👁️ Visual Perception | OmniParser (Qwen2-VL + EasyOCR) enables accurate element detection without brittle DOM selectors |
| 🧠 AI-Driven Planning | Gemini 2.5 Pro decomposes complex goals into executable TaskDAGs with dependency management |
| ✅ Self-Verification | Agents verify task completion with confidence scoring and request replanning when needed |
| 🔄 Adaptive Replanning | Automatic recovery from failures with AI-driven RETRY/SKIP/REPLAN decisions |
| 💾 Persistent Memory | Shared AccomplishmentStore prevents redundant work across parallel workers |
| 🔒 Type Safety | LangChain + Pydantic structured outputs eliminate JSON parsing errors |
| ⚡ Performance | 80%+ cache hit rate, parallel execution, and smart resource management |
- Architecture
- System Requirements
- Installation
- Quick Start
- Configuration
- Usage Examples
- Project Structure
- How It Works
- Troubleshooting
- License
For detailed architecture documentation, see README_ARCHITECTURE.md
The system follows a 3-tier hierarchical multi-agent architecture:
graph TD
subgraph Master["🎯 MasterAgent (Singleton Orchestrator)"]
M1[Goal Decomposition]
M2[Plan → TaskDAG Conversion]
M3[Supervisor Coordination]
M4[Decision-driven Continuation]
M5[Final Verification]
M1 --> M2 --> M3 --> M4 --> M5
end
subgraph Shared["🔧 Shared Resources (Singleton)"]
SR1[GeminiAgent - LLM]
SR2[ScreenParser - OmniParser]
SR3[BrowserController]
SR4[ConversationManager]
SR5[AccomplishmentStore]
end
subgraph Supervisor["👁️ AISupervisorAgent (Per-DAG)"]
S1[Health Monitoring]
S2[Worker Lifecycle Management]
S3[AI-Driven Recovery]
S4[Automatic Replanning]
S1 --> S2 --> S3 --> S4
end
subgraph Worker["⚙️ WorkerAgent (Per-Task)"]
W1[Observe - Screenshot + Parse]
W2[Decide - AI Action Selection]
W3[Act - Execute via Playwright]
W4[Verify - Check Completion]
W1 --> W2 --> W3 --> W4 --> W1
end
Master -->|Spawns per DAG| Supervisor
Supervisor -->|Spawns per Task| Worker
Master -.Uses.-> Shared
Supervisor -.Uses.-> Shared
Worker -.Uses.-> Shared
style Master fill:#e1f5ff,stroke:#0066cc,stroke-width:3px
style Supervisor fill:#fff4e1,stroke:#ff9900,stroke-width:3px
style Worker fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px
style Shared fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
sequenceDiagram
participant User
participant Master as MasterAgent
participant Planner
participant Supervisor as AISupervisor
participant Worker as WorkerAgent
participant Browser
participant Gemini as Gemini 2.5 Pro
participant OmniParser
User->>Master: execute_goal(goal, url)
Master->>Browser: Navigate to URL
Master->>Planner: Create plan for goal
Planner->>OmniParser: Parse current page
OmniParser-->>Planner: Elements & layout
Planner->>Gemini: Generate StructuredPlan
Gemini-->>Planner: Task breakdown
Planner-->>Master: TaskDAG with dependencies
Master->>Supervisor: Execute DAG
loop For each ready task
Supervisor->>Worker: Spawn worker(task)
loop Action Loop (max 50 iterations)
Worker->>OmniParser: Screenshot → Parse elements
OmniParser-->>Worker: Interactive elements
Worker->>Gemini: Decide next action
Gemini-->>Worker: Action (click/type/scroll)
Worker->>Browser: Execute action
Browser-->>Worker: Page state
Worker->>Worker: Verify completion
alt Task Complete
Worker-->>Supervisor: SUCCESS
else Task Failed
Worker-->>Supervisor: FAILED
else Needs Replan
Worker-->>Supervisor: REQUEST_REPLAN
end
end
alt Failure Detected
Supervisor->>Gemini: Analyze failure
Gemini-->>Supervisor: Decision (RETRY/SKIP/REPLAN)
alt REPLAN
Supervisor->>Planner: Create recovery plan
Planner-->>Supervisor: Updated DAG
end
end
end
Supervisor-->>Master: DAG execution result
Master->>Gemini: Verify goal achievement
Gemini-->>Master: Verification result
Master->>Gemini: Decide continuation
Gemini-->>Master: CONTINUE / STOP
alt CONTINUE
Master->>Planner: Create next plan
Note over Master,Supervisor: Loop continues
end
Master-->>User: ExecutionResult
1. MasterAgent (Singleton)
- Purpose: Top-level orchestrator coordinating entire session
- Flow: Navigate → Plan → DAG → Supervise → Verify → Loop
- Shared Resources: Single GeminiAgent, ScreenParser, Browser, Redis store
- Memory: Aggressive cleanup (CUDA cache, GC, singleton reset)
2. AISupervisorAgent (Per-DAG)
- Purpose: Monitors task execution & recovers from failures
- Loop: Health check → Ready tasks → Spawn workers → Handle results
- AI Decisions: RETRY (reset task), SKIP (unblock deps), REPLAN (add recovery), ABORT (exit)
- Protection: 30s cooldown, max 3 consecutive skips, worker requests bypass
3. WorkerAgent (Per-Task)
- Purpose: Executes single task with observe-decide-act loop
- Feasibility: Detects task-screen mismatches → requests replan
- Thread ID:
worker_worker_{task_id}_sup{N}_{uuid}(isolation) - Limits: Max 50 iterations per task
4. ActionLoop (Worker Core)
- OBSERVE: Screenshot → OmniParser (cached) → DOM enrichment
- DECIDE: Gemini structured output → tool call (click/type/etc)
- ACT: ActionHandler executes with delays (prevents mis-clicks)
5. Supporting Systems
- ScreenParser: OmniParser wrapper with SQLite cache (80%+ hit rate)
- GeminiAgent: gemini-2.5-pro with structured outputs (planning, actions, decisions, verification)
- ConversationManager: Conversation storage with Redis + in-memory fallback
- AccomplishmentStore: Session-scoped shared cache (work deduplication)
- DecisionEngine: AI-driven recovery & continuation decisions
- HealthMonitor: Tracks success rate, detects deadlocks, stuck situations
- Separation of Concerns: Master orchestrates, Supervisor monitors, Worker executes
- Resource Sharing: Single expensive resources (OmniParser, Gemini, Browser)
- Context Isolation: Unique thread_ids prevent Gemini pollution, enable parallelism
- AI-Driven Recovery: No hardcoded rules - AI analyzes failures & decides actions
- Memory Efficiency: Aggressive caching, cleanup, immediate object deletion
- Type Safety: Pydantic models + LangChain structured outputs (no JSON parsing)
Resource Usage (with GPU):
- RAM: ~6-8 GB (OmniParser + Qwen2-VL + Browser)
- VRAM: ~4-6 GB (Vision models)
- Latency: 1-2s per action (cache hit), 4-6s (cache miss)
Optimizations:
- Screen caching: 80%+ hit rate → 3-4x speedup
- Accomplishment sharing: 30-50% fewer redundant actions
- Parallel execution: Up to 4x workers → 2-3x speedup
- Early feasibility: Saves 5-10 wasted iterations per mismatch
| Component | Minimum | Recommended |
|---|---|---|
| RAM | 8 GB | 16+ GB |
| GPU | None (CPU inference) | NVIDIA GPU with 6GB+ VRAM for faster OmniParser |
| Storage | 8+ GB free space | 16+ GB free space |
Note: Tested on Python 3.9-3.13 • Linux, macOS, and Windows (WSL2)
git clone https://github.com/spoloxs/automata.git
cd automata/web-agentRepository: https://github.com/spoloxs/automata
It's recommended to use a virtual environment to avoid dependency conflicts.
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activatepip install --upgrade pip
pip install -r requirements.txtplaywright install chromiumIMPORTANT: This project includes a customized OmniParser implementation in the OmniParser/ directory. Do NOT use the original Microsoft OmniParser repository - always use the included version which has been optimized for this project.
Download the required pre-trained model weights:
# Download weights to the included OmniParser directory
cd OmniParser/weights
# Download icon detection model
wget https://huggingface.co/microsoft/OmniParser/resolve/main/icon_detect/model.safetensors -P icon_detect/
# Download caption model (choose one based on your preference if not using Qwen or EasyOCR for OCR):
# Option 1: Florence (recommended for better accuracy)
wget https://huggingface.co/microsoft/OmniParser/resolve/main/icon_caption_florence/model.safetensors -P icon_caption_florence/
# Option 2: BLIP2 (lighter alternative)
wget https://huggingface.co/microsoft/OmniParser/resolve/main/icon_caption_blip2/model.safetensors -P icon_caption_blip2/Required files structure:
OmniParser/weights/
├── icon_detect/
│ └── model.safetensors
└── icon_caption_florence/ (or icon_caption_blip2/)
└── model.safetensors
cp .env.example .envEdit .env and add your Gemini API key:
GEMINI_API_KEY=your_gemini_api_key_hereNote: Some environment variables are still being migrated to use .env configuration. Most settings can be found in src/web_agent/config/settings.py.
Get Gemini API Key: https://aistudio.google.com/app/apikey
Redis is used for persistent conversation storage and caching:
Ubuntu/Debian:
sudo apt-get install redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-servermacOS:
brew install redis
brew services start redisWindows (WSL2):
sudo apt-get install redis-server
sudo service redis-server startVerify Redis is running:
redis-cli ping # Should return "PONG"python -c "import torch; print(f'PyTorch: {torch.__version__}')"
python -c "from playwright.async_api import async_playwright; print('Playwright OK')"
python -c "import redis; print(f'Redis: {redis.__version__}')"
python scripts/verify_setup.pyThe easiest and most user-friendly way to use the agent:
# Start the web interface
python app.py
# Or use the startup script
./start_gui.shThen open your browser to http://localhost:7860
Features:
- 📎 Upload Documents: Drag & drop PDFs (resumes, forms, etc.)
- 🤖 AI-Powered: Gemini uses your documents to fill forms automatically
- 📊 Real-time Progress: Watch the automation happen live
- 💡 Examples: Pre-loaded examples to get started quickly
Example Use Case:
- Upload your resume (PDF)
- Enter URL:
https://company.com/careers/apply - Task:
Fill the job application using my resume - Click "Run Automation" ✨
For command-line enthusiasts:
# Run the CLI tool
python cli.py
# Or use the wrapper script
./automateThe CLI will prompt you for:
- Target URL: The website to automate (e.g.,
https://www.google.com) - Task: What you want to accomplish (e.g.,
Search for 'Python' and click first result) - Workers: Number of parallel workers (default: 2)
Example session:
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 🤖 AI Web Automation Agent CLI v0.1.0 ║
║ ║
║ Powered by Gemini 2.5 Pro + OmniParser ║
║ ║
╚═══════════════════════════════════════════════════════════╝
Enter automation details:
Target URL: https://www.google.com
Task: Search for 'Python asyncio tutorial' and click first result
Max parallel workers [2]: 2
✓ Automation completed successfully! ✨
For automation scripts or CI/CD:
# Direct execution with arguments
python cli.py --url "https://www.google.com" \
--task "Search for 'Python' and click first result"
# With custom settings
python cli.py --url "https://example.com" \
--task "Fill contact form" \
--workers 4 \
--headless
# Show help
python cli.py --helpCLI Options:
| Option | Short | Description | Default |
|---|---|---|---|
--url |
-u |
Target URL to automate | Interactive prompt |
--task |
-t |
Task description | Interactive prompt |
--workers |
-w |
Max parallel workers | 2 |
--headless |
- | Run browser in headless mode | Visible |
--version |
-v |
Show version | - |
--help |
-h |
Show help message | - |
For integration into your own scripts:
import asyncio
from web_agent.core.master_agent import MasterAgent
async def main():
# Initialize the master agent
master = MasterAgent(max_parallel_workers=2)
await master.initialize()
try:
# Execute the automation goal
result = await master.execute_goal(
goal="Search for 'Python asyncio tutorial' and click the first result",
starting_url="https://www.google.com"
)
# Check results
print(f"Success: {result.success}")
print(f"Tasks completed: {result.completed_tasks}/{result.total_tasks}")
finally:
# Always cleanup resources
await master.cleanup()
if __name__ == "__main__":
asyncio.run(main())# Simple search example
python examples/simple_search.py
# Form filling
python examples/form_filling.py
# Data extraction
python examples/data_extraction.py
# Interactive mode
python main.py# Gemini API
GEMINI_API_KEY=your_key_here
# Model is hardcoded to gemini-2.5-pro in gemini_agent.py
# Browser Settings
BROWSER_HEADLESS=false
BROWSER_TIMEOUT=30000 # milliseconds
BROWSER_WINDOW_SIZE=1440,900
# Agent Limits
MAX_WORKER_DEPTH=3
WORKER_TOKEN_LIMIT=100000
MAX_ACTION_ITERATIONS=50
# Memory & Caching
ENABLE_SCREEN_CACHE=true
CACHE_TTL_SECONDS=3600
ENABLE_ACCOMPLISHMENT_STORE=true
# Logging
LOG_LEVEL=INFO # DEBUG, INFO, WARN, ERRORKey configuration options:
# Vision Model Settings
OMNIPARSER_DEVICE = "cuda" # or "cpu"
OMNIPARSER_BATCH_SIZE = 8
# LLM Settings
GEMINI_TEMPERATURE = 0.7
GEMINI_MAX_TOKENS = 8192
# Supervisor Settings
REPLAN_COOLDOWN_SECONDS = 30
MAX_CONSECUTIVE_SKIPS = 3
SUPERVISION_INTERVAL = 2.0 # seconds
# Worker Settings
ACTION_DELAY_BEFORE = 0.3 # seconds before click/type
ACTION_DELAY_AFTER = 0.7 # seconds after click/typeresult = await master.execute_goal(
goal="Search for 'machine learning' on Google and click the Wikipedia result",
starting_url="https://www.google.com"
)result = await master.execute_goal(
goal="Fill out the contact form with name 'John Doe' and email 'john@example.com', then submit",
starting_url="https://example.com/contact"
)result = await master.execute_goal(
goal="Extract the top 5 news headlines from the homepage",
starting_url="https://news.ycombinator.com"
)
# Access extracted data
if result.success:
print(result.extracted_data)result = await master.execute_goal(
goal="""
1. Go to GitHub
2. Search for 'web automation'
3. Click on the first repository
4. Star the repository
5. Navigate to the Issues tab
""",
starting_url="https://github.com"
)web-agent/
├── config/ # Configuration
│ └── settings.py # Global settings
├── src/web_agent/ # Main source code
│ ├── core/ # Core agents
│ │ ├── master_agent.py # Orchestrator
│ │ ├── supervisor_agent.py # Task monitor
│ │ └── worker_agent.py # Task executor
│ ├── planning/ # Task planning
│ │ ├── planner.py # Goal decomposition
│ │ └── dag_converter.py # Plan to DAG
│ ├── scheduling/ # Worker management
│ │ └── scheduler.py # Worker pool
│ ├── execution/ # Action execution
│ │ ├── action_loop.py # Observe-decide-act
│ │ ├── action_handler.py # Action execution
│ │ └── browser_controller.py # Playwright wrapper
│ ├── perception/ # Visual perception
│ │ ├── screen_parser.py # OmniParser integration
│ │ ├── omniparser_wrapper.py
│ │ └── element_formatter.py
│ ├── intelligence/ # LLM integration
│ │ ├── gemini_agent.py # Gemini wrapper
│ │ ├── prompt_builder.py # Prompt generation
│ │ └── tool_definitions.py # Action schemas
│ ├── verification/ # Task verification
│ │ └── verifier.py # Completion checking
│ ├── supervision/ # Health monitoring
│ │ ├── health_monitor.py # Health tracking
│ │ └── decision_engine.py # AI recovery
│ └── storage/ # Memory & caching
│ ├── screen_cache.py # Screenshot cache
│ ├── accomplishment_store.py
│ └── worker_memory.py
├── OmniParser/ # Vision model (submodule)
├── examples/ # Usage examples
├── tests/ # Unit & integration tests
├── scripts/ # Utility scripts
├── .env.example # Example environment file
├── requirements.txt # Python dependencies
├── pyproject.toml # Project metadata
└── README.md # This file
stateDiagram-v2
[*] --> Observe
Observe --> Decide
Decide --> Act
Act --> Verify
Verify --> TaskComplete: Success
Verify --> CheckIterations: Not Complete
CheckIterations --> Observe: < 50 iterations
CheckIterations --> TaskFailed: >= 50 iterations
TaskComplete --> [*]
TaskFailed --> [*]
state Observe {
[*] --> CaptureScreen
CaptureScreen --> CheckCache
CheckCache --> ParseWithOmniParser: Cache Miss
CheckCache --> UseCachedResult: Cache Hit
ParseWithOmniParser --> EnrichWithDOM
UseCachedResult --> EnrichWithDOM
EnrichWithDOM --> [*]
}
state Decide {
[*] --> BuildPrompt
BuildPrompt --> CallGemini
CallGemini --> ParseStructuredOutput
ParseStructuredOutput --> [*]
}
state Act {
[*] --> ValidateAction
ValidateAction --> ExecuteDelay
ExecuteDelay --> PerformAction
PerformAction --> WaitAfterAction
WaitAfterAction --> [*]
}
mindmap
root((Web Agent<br/>Design))
Separation of Concerns
Master → Orchestration
Supervisor → Monitoring
Worker → Execution
Context Isolation
Unique thread_id per worker
Prevents pollution
Enables parallelism
Token Management
Disposable workers
Persistent master
Structured outputs
AI-Driven Recovery
Failure analysis
Auto retry/skip/replan
Health monitoring
Visual-First
OmniParser detection
DOM enrichment
Shadow DOM support
Performance
Screen caching 80%+
Parallel workers 4x
Shared accomplishments
Issue: "OmniParser weights not found"
# Download weights manually
cd OmniParser/weights
wget https://huggingface.co/microsoft/OmniParser/resolve/main/icon_detect/model.safetensorsIssue: "Gemini API rate limit exceeded"
- Wait 60 seconds between retries
- Reduce
max_parallel_workersin MasterAgent - Check API quota: https://aistudio.google.com/app/apikey
Issue: "Browser timeout"
- Increase
BROWSER_TIMEOUTin .env - Check internet connection
- Try headless mode:
BROWSER_HEADLESS=true
Issue: "CUDA out of memory"
# Use CPU for OmniParser
OMNIPARSER_DEVICE = "cpu" # in config/settings.pyIssue: "Worker stuck in infinite loop"
- Check logs for "max iterations reached"
- Supervisor will auto-replan after cooldown
- Reduce
MAX_ACTION_ITERATIONSif needed
Enable detailed logging:
export LOG_LEVEL=DEBUG
python main.pyOr in code:
import logging
logging.basicConfig(level=logging.DEBUG)-
Enable GPU acceleration (if available)
OMNIPARSER_DEVICE = "cuda"
-
Use screen caching
ENABLE_SCREEN_CACHE = True
-
Reduce parallel workers (if memory constrained)
master = MasterAgent(max_parallel_workers=1)
-
Use headless mode (faster)
BROWSER_HEADLESS=true
Current Version: 0.1.0 (Alpha) • Last Updated: December 2024
The following improvements are currently under development:
- Faster execution - Optimizing action delays and caching strategies
- Reduced latency - Streamlining observe-decide-act cycle
- Better resource usage - Memory management improvements
- Cross-origin iframe handling - Working on seamless iframe context switching
- Complex nested iframes - Support for deeply nested iframe structures
- Crossword puzzles - Specialized handling for iframe-based games and puzzles
- Optimizing visual analysis - Currently, when OmniParser can't detect elements, the system falls back to Gemini Vision API (sends full screenshots). Future improvements include:
- Better OmniParser tuning and configuration
- Enhanced DOM-based fallback strategies
- Hybrid detection methods to reduce API calls
- Improved element detection for complex UIs
gantt
title Development Roadmap
dateFormat YYYY-MM
section Core Features
iframe Support Enhancement :2025-01, 2025-02
Vision System Optimization :2025-01, 2025-03
Multi-LLM Support :2025-02, 2025-04
section Performance
Faster Execution :2025-01, 2025-02
Advanced Caching :2025-02, 2025-03
section Integrations
API Server :2025-03, 2025-04
CLI Tool :2025-03, 2025-04
Upcoming Enhancements:
- 🔧 Enhanced error recovery with smarter retry logic
- 📱 Better handling of dynamic content and lazy-loaded elements
- 🌐 Multi-page workflow optimization
- ⚡ Faster plan generation and execution
- 🤖 Support for additional LLM providers (Claude Opus 4, GPT-4, etc.)
- 🔌 REST API server for integration
- 💻 Standalone CLI tool
- Architecture Guide - Detailed system architecture and design
- Micro Agents - Micro-agent architecture documentation
- OmniParser Guide - Vision model setup and customization
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
- Google Gemini - Powering our AI planning and decision making
- Microsoft OmniParser - Visual element detection foundation
- Playwright - Browser automation framework
- LangChain - LLM integration framework
- Issues: GitHub Issues
- Discussions: GitHub Discussions
⭐ Star this repo if you find it useful!
Made with ❤️ by the community