Four specialized agents run in sequence. The Fact Checker scores every claim. If confidence is too low, CWIR identifies the single weakest upstream agent and re-runs only from that point β never from scratch. The final score is the harmonic mean of all four agents, so one bad agent pulls the entire score down and forces revision.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β React 19 + TypeScript + Vite β
β βββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββββ β
β β Research β β Pipeline (Live β β Graph Explorer β β
β β Tab β β DAG animation) β β (force-directed) β β
β βββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββββ β
ββββββββββββββββββββββββ€ββββββββββββββββββββββββββββββββββββββββββββ
β REST + WebSocket
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI (asyncpg pool) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β CWIR Pipeline Orchestrator β β
β β QueryAnalyst β SourceValidator β Synthesizer β FC β β
β β β_______ backward refinement arc ________________β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β LLM Router β β Hybrid RAG β β KG Upsert Engine β β
β β Ollama β β β pgvector + β β ON CONFLICT UPDATE β β
β β Claude API β β tsvector β β GREATEST(conf) β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
ββββββββββββ€ββββββββββββββββββββββ€βββββββββββββββββββββββββββββββββ
β β
ββββββββββΌβββββββββ ββββββββββΌβββββββββββββββββββββββββββββββ
β Ollama Server β β PostgreSQL 16 + pgvector β
β gemma3:4b β β βββββββββββββββββββββββββββββββββββ β
β nomic-embed β β β chunks(vector(768)) HNSW index β β
βββββββββββββββββββ β β chunks(tsvector) GIN index β β
β β knowledge_edges UNIQUE index β β
β β research_tasks JSONB results β β
β βββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββ
# Confidence-Weighted Iterative Refinement
def run_cwir(query, max_depth=2):
state = forward_pass(ALL_AGENTS) # 1st pass
for depth in range(max_depth):
fc = state["fact_checker"]
if fc.verdict != "needs_revision":
break # done β
# Find weakest non-FC agent
weakest = argmin([qa, sv, syn])
# Re-run ONLY from weakest node
state = forward_pass(
agents[weakest:], # O(k) not O(n)
state
)
# Harmonic mean β one weak agent β low final score
return harmonic_mean(qa, sv, syn, fc) |
Why harmonic mean? The harmonic mean is bounded above by its minimum value. A single agent scoring
The second row forces a revision. This is by design β the system should never report high confidence when one agent failed. |
| Feature | Description |
|---|---|
| π¨ Animated DAG Canvas | Live pipeline visualization using raw Canvas 2D API. Agent nodes pulse while running, CWIR revision arcs draw as dashed amber beziers |
| πΈ Force-Directed KG | Verlet spring simulation (350 iterations) renders a draggable knowledge graph. Click any node for entity detail: all incoming/outgoing edges with confidence |
| π‘ Live WebSocket Streaming | Agent traces stream in real-time as each agent completes. Frontend state machine transitions idle β running β complete |
| π Hybrid RAG | 0.7 Γ cosine_similarity(pgvector HNSW) + 0.3 Γ BM25(tsvector) merged in Python for precision + recall balance |
| π‘ Agent Resilience | Every agent runs inside asyncio.wait_for() with timeout. Crashes and timeouts produce confidence=0.1 degraded output β pipeline always completes |
| π Workspace Stats | Live stat chips: documents, chunks, queries, avg confidence, entity count, KG edge count |
| π Smart Retry | Exponential backoff on both Ollama and Claude API paths. TTL-cached health probe avoids repeated Ollama checks |
| π¦ Rate Limiting | Sliding-window per-IP limiter (20 req/min) as a FastAPI Depends β no external Redis needed |
ResearchOS/
βββ π³ docker-compose.yml PostgreSQL 16 + pgvector
βββ βοΈ Makefile up / dev / migrate / test
βββ π .env.example
β
βββ backend/
β βββ π main.py FastAPI app β 15 routes + WS endpoint
β βββ π§ pipeline/cwir.py CWIR orchestrator + backward propagation
β βββ agents/
β β βββ base.py timeout + error wrapping (asyncio.wait_for)
β β βββ query_analyst.py query decomposition + clarity scoring
β β βββ source_validator.py RAG retrieval + confidence blending
β β βββ synthesizer.py chunk-grounded synthesis + KG extraction
β β βββ fact_checker.py claim verification + revision trigger
β βββ rag/
β β βββ chunk.py NLTK sentence-boundary chunker
β β βββ embed.py Ollama embedding calls
β β βββ search.py hybrid cosine+BM25 search
β β βββ ingest.py document β chunks β vectors
β βββ tests/
β βββ test_agents.py all 4 agents, JSON fences, fallbacks
β βββ test_resilience.py timeout, crash, retry, rate limit
β βββ test_rag.py chunking, hybrid search
β βββ test_cwir.py full pipeline, CWIR loop, harmonic mean
β
βββ frontend/src/
βββ App.tsx 4-tab routing + workspace state
βββ api.ts typed REST + WebSocket client
βββ hooks/useResearch.ts WS lifecycle, phase state machine
βββ components/
βββ π¨ DAGCanvas.tsx animated pipeline (Canvas 2D)
βββ πΈ KnowledgeGraph.tsx force-directed KG (Canvas 2D)
βββ π GraphExplorer.tsx full-page KG tab with analytics
βββ π WorkspaceStats.tsx stat chip bar
βββ π ResearchHistory.tsx past queries list
# 1. Clone & start the database
git clone https://github.com/devhemanthac-commits/ResearchOS -b master
cd ResearchOS
docker compose up -d
# 2. Backend
cp .env.example .env # add ANTHROPIC_API_KEY
pip install -r backend/requirements.txt
python -c "import asyncio; from backend.database import init_db; asyncio.run(init_db())"
uvicorn backend.main:app --reload --port 8000
# 3. Frontend
cd frontend && npm install
echo "VITE_API_URL=http://localhost:8000" > .env.local
npm run dev # β http://localhost:5173
# 4. Pull models
ollama pull gemma3:4b
ollama pull nomic-embed-textFull setup guide, environment variables, and API reference in the master branch README
| Path | Contents |
|---|---|
backend/ |
FastAPI app, CWIR pipeline, all 4 agents, RAG engine |
backend/agents/ |
QueryAnalyst, SourceValidator, Synthesizer, FactChecker |
backend/pipeline/ |
CWIR orchestrator with backward propagation |
backend/rag/ |
Chunker, embedder, hybrid search |
backend/tests/ |
Full test suite (agents, resilience, RAG, CWIR) |
frontend/src/components/ |
All React components including Canvas 2D visualizations |
frontend/src/hooks/ |
useResearch (WebSocket), useWorkspaces |