spb/search-box Public
Agentic web research engine — hypotheses, verbatim evidence, contradictions, sourced answers streamed live. Claude Opus 5 + Firecrawl + PostgreSQL.
TypeScript 76.9%
CSS 18.7%
SQL 2.1%
JavaScript 1.8%
Shell 0.5%
1<!--2Search-box.ai3Author: Simon-Pierre Boucher4Contact: contact@spboucher.ai5File: docs/architecture.md6Description: System architecture overview.7-->89# Architecture1011## Flow1213```14question ─▶ POST /api/research ─▶ createSession ─▶ runSession (in-process)15 │16 ┌─────────────────────────────────────────┤17 │ orchestrator loop (packages/agent) │18 │ Claude decides: search / fetch / │19 │ read_source / claims / evidence / │20 │ contradictions / finish │21 │ App enforces: budgets, schemas, SSRF │22 └───────────────┬─────────────────────────┘23 ▼24 ResearchState (packages/research)25 every mutation = 1 DB write + 1 event26 ▼27 PostgreSQL (packages/db)28 ▼29 GET /api/research/:id/stream (SSE, Last-Event-ID replay)30 ▼31 event-sourced UI (apps/web)32```3334## Key decisions3536- **No fixed pipeline.** The model chooses strategy via tool use; the app owns safety37 (budgets in `packages/shared/src/budgets.ts`, zod-validated tool inputs, SSRF guard).38- **ResearchState is durable** and lives in PostgreSQL, outside the model's context window.39 The `ResearchState` service is the single mutation path: state write and event append40 always happen together, so the UI can never show fabricated progress.41- **Event-sourced UI.** The client rebuilds its entire view by replaying the event stream42 from seq 0 — the same mechanism gives live streaming, reconnection (`Last-Event-ID`),43 and full session replay for debugging.44- **Citations are mechanical.** At synthesis time, sources carrying evidence receive stable45 indices (`sources.assignCitationIndices`, ordered by first evidence use). The synthesis46 model may only use the `[n]` markers provided; the UI links them back to sources.47- **In-process runner** (`apps/web/lib/runner.ts`): sessions run inside the Next.js server48 process for the MVP. A queue (e.g. Redis-backed) only gets added when scale demands it.4950## Model roles5152Configured via env (`CLAUDE_ORCHESTRATOR_MODEL`, `CLAUDE_SYNTHESIS_MODEL`, …), all defaulting53to `claude-opus-5`. The researcher/verifier roles are reserved for the post-MVP multi-agent54phase (Explorer, Skeptic, Verifier, …) which only begins once the single-orchestrator engine55is demonstrably reliable.56