This is the backend for WebSeek, a research prototype presented at ACM CHI 2026. Paper: Facilitating Proactive and Reactive Guidance for Decision Making on the Web: A Design Probe with WebSeek · arXiv:2601.15100
FastAPI-based multi-agent backend for the WebSeek Chrome extension. It orchestrates Google ADK agents, calls LLMs via OpenRouter, renders Vega-Lite charts server-side, and persists canvas snapshots in SQLite.
Chrome Extension ──HTTP/WebSocket──▶ FastAPI (main.py)
├─ MainAgent (Google ADK)
│ ├─ ContextAgent (WebSocket back to extension)
│ └─ ExecutorAgent (LLM + data tools)
├─ /api/render-vega-lite (vl-convert-python)
└─ /api/snapshots (aiosqlite)
- Python 3.10+
pipor a virtual environment tool
git clone https://github.com/your-org/webseek_backend.git
cd webseek_backend
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activatepip install -r requirements.txtcp .env.example .envEdit .env:
| Variable | Required | Description |
|---|---|---|
OPENROUTER_API_KEY |
Yes | OpenRouter API key |
OPENROUTER_BASE_URL |
Yes | https://openrouter.ai/api/v1 |
GOOGLE_API_KEY |
Yes | Google AI Studio key for ADK |
HOST |
No | Bind address (default 0.0.0.0) |
PORT |
No | Port (default 8000) |
DEBUG |
No | False in production |
Security:
.envis gitignored. Never commit it. Rotate any keys that were previously exposed.
python main.pyThe server starts at http://0.0.0.0:8000.
Interactive API docs: http://localhost:8000/docs
| Method | Path | Description |
|---|---|---|
GET |
/ |
Health check |
GET |
/health |
Detailed health status |
POST |
/api/process-task |
Submit a task for the agent pipeline |
GET |
/ws |
WebSocket for context exchange with the extension |
POST |
/api/render-vega-lite/ |
Render a Vega-Lite spec to SVG |
POST |
/api/snapshots |
Save a canvas snapshot |
GET |
/api/snapshots |
List all snapshots |
GET |
/api/snapshots/{id} |
Load a specific snapshot |
DELETE |
/api/snapshots/{id} |
Delete a snapshot |
webseek_backend/
├── agents/
│ ├── main/
│ │ └── main_agent.py # Orchestrator (Google ADK)
│ ├── context/
│ │ └── context_agent.py # Pulls context from the extension via WebSocket
│ └── executor/
│ └── executor_agent.py # LLM-driven task execution
├── config/
│ └── settings.py # Pydantic settings (reads .env)
├── utils/
│ ├── data_models.py # Pydantic request/response models
│ ├── database.py # SQLite snapshot persistence
│ ├── llm_client.py # OpenRouter client wrapper
│ └── websocket_manager.py # WebSocket connection pool
├── main.py # FastAPI app entry point
├── requirements.txt
├── .env.example # Environment variable template
└── DEPLOYMENT.md # Lab server deployment guide
See DEPLOYMENT.md for step-by-step instructions covering:
- systemd service setup
- Nginx reverse proxy with WebSocket support
- HTTPS via Let's Encrypt
- CORS restriction to the extension origin
- Database backups
- Set
DEBUG=Falsein.env. - Restrict CORS in
main.py— replaceallow_origins=["*"]with["chrome-extension://<your-extension-id>"]. snapshots.dbcan grow large if users save many image-rich snapshots. Monitor disk usage and schedule regular backups.
If you use WebSeek in your research, please cite:
@inproceedings{huang2026webseek,
title = {Facilitating Proactive and Reactive Guidance for Decision Making on the Web: A Design Probe with WebSeek},
author = {Huang, Yanwei and Narechania, Arpit},
booktitle = {Proceedings of the 2026 CHI Conference on Human Factors in Computing Systems},
year = {2026},
publisher = {ACM},
url = {https://arxiv.org/abs/2601.15100}
}MIT