ResearchOS is an open-source, local-first research operating system. Unlike traditional research agents that run in a black box, ResearchOS is designed to expose every discrete step of the research pipeline—from query planning to search, content scraping, fact extraction, and report verification.
This architecture prioritizes total transparency, traceability (linking claims back to specific URLs and generated queries), and offline execution.
- Python 3.12+
- FastAPI — Async REST API framework
- SQLModel — Combined SQLAlchemy & Pydantic ORM
- SQLite — Local-first transactional database
- Ollama — Local LLM runner (llama3 / mistral)
- SearXNG — Self-hosted privacy-focused search engine
- Playwright & Trafilatura — Dynamic browser automation & content extraction
The project follows a Clean Architecture / Service-Oriented structure to ensure modularity and separation of concerns:
app/
├── core/
│ ├── config.py # Settings using Pydantic Settings
│ └── db.py # SQLite SQLModel engine and DB session setup
├── models/
│ ├── base.py # Database base utilities
│ ├── research.py # Planner DTO schemas (ResearchQuestion/Queries)
│ └── session.py # ResearchSession database entities & schemas
├── repositories/
│ └── session.py # Session CRUD operations
├── services/
│ └── planner.py # Ollama query planning service
├── api/
│ ├── deps.py # Dependency Injection providers
│ └── v1/
│ ├── router.py # Registers API V1 routes
│ └── endpoints/
│ ├── health.py # Heartbeat status endpoint
│ ├── research.py # Planner endpoint
│ └── sessions.py # Research Session CRUD endpoints
├── main.py # FastAPI Application Entrypoint
tests/ # Automated unit & integration tests
pytest.ini # Pytest configuration
requirements.txt # Production and development dependencies
.env # Local environment variables
.gitignore # Version control ignore rules
Ensure Python 3.12+ is installed. Create a virtual environment and install the package requirements:
# Create virtual environment
python -m venv .venv
# Activate virtual environment
# On Windows (PowerShell):
.venv\Scripts\Activate.ps1
# On Linux / macOS:
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txtCreate a local .env file at the root directory (this is excluded from git):
PROJECT_NAME="ResearchOS"
API_V1_STR="/api/v1"
DATABASE_URL="sqlite+aiosqlite:///./research_os.db"
OLLAMA_API_URL="http://localhost:11434"
LLM_MODEL="llama3"Execute the pytest suite using pytest-asyncio:
python -m pytestLaunch the development server using Uvicorn:
uvicorn app.main:app --reloadOnce the server is running, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- GET
/health(or/api/v1/health)- Returns core API health:
{"status": "healthy"}
- Returns core API health:
- GET
/api/v1/health/llm- Checks if local Ollama model is online.
- POST
/api/v1/sessions- Payload:
{"question": "Best vector databases for RAG"} - Initializes a session tracking database record.
- Payload:
- GET
/api/v1/sessions- Lists all sessions.
- GET
/api/v1/sessions/{session_id}/events- Retrieves a chronological history of EventBus pipeline events published for the session.
- POST
/research- Payload:
{"question": "Best vector databases for RAG"} - Converts the question into optimized search queries via local Ollama.
- Payload:
- POST
/research/search- Payload:
{"question": "Best vector databases for RAG"} - Runs generated queries through SearXNG, deduplicates URL search results, and saves them.
- Payload:
- POST
/research/fetch- Payload:
{"session_id": "<session-uuid>"} - Opens unique URLs concurrently using Chromium tabs, extracts clean text, saves raw HTML, and scores extraction quality.
- Payload:
- POST
/api/v1/research/claims- Payload:
{"session_id": "<session-uuid>"} - Chunks text into 4000 char blocks, extracts factual claims using Ollama, hashes claims to prevent duplicates, and links to source queries and chunks.
- Payload: