Architecture

Architecture

Reason → Plan → Tool Use → Complete, mapped onto code.

Section

The loop

Data Question → Reason → Plan → Execute (tools) → Complete (answer + Miro board)
                  ↑                    │
                  └──── Replan ────────┘

If a step fails ≤ 2 times, the planner replans from the failure point. Max 3 retries per step, 10 steps per plan. A doom-loop guard injects a corrective system prompt on [A,B,A,B] patterns.

Section

Layers

LayerComponents
User surfaceBrowser, MCP client (Claude Code, Codex, Cursor)
EdgeVercel — /, /q, /datasets/[id], /api/agent (SSE)
Agent loopCodex (gpt-4o), replanner, synthesizer, doom-loop guard
Tool dispatchdiscover · describe · query · summarize · cite · render_to_miro
Data + I/OSocrata SODA APIs (live), local YAML catalog, Miro REST API
Bound + safetySkill doc · 5000-row cap · 30s timeout · 429 backoff · citation enforced

Section

What Codex does

Five distinct LLM-driven roles. Each is a real OpenAI API call with structured outputs (response_format={"type": "json_schema"}).

StepPromptOutput
Reasonprompts/planner.md{intent, data_domain, geography, time_range, analysis_type}
Planprompts/planner.mdOrdered list of {tool, args} steps
Execute(no LLM)Deterministic dispatch
Recoverprompts/planner.md (replan mode)New plan if a step failed
Completeprompts/writer.mdSummary + Miro board layout JSON

Section

Where Codex calls live

  • agent/planner.py — Reason + Plan + Replan.
  • agent/executor.py — Tool dispatch. Not an LLM call.
  • agent/synthesizer.py — Complete.
  • agent/main.py — Orchestrator. Manages the loop, tracks tool history, runs the doom-loop guard, surfaces phase events.

Section

Why this isn't a wrapper

  • Routing decisions live in the agent. The planner picks dataset, columns, time range, and SoQL given a fuzzy question. Nothing is hardcoded.
  • Real external systems. Socrata (6+ datasets, 4 cities + state), Miro (live board generation), local YAML catalog.
  • Multi-step structured output. The plan is a typed (tool, args) list validated against a JSON schema. The dispatcher is deterministic TypeScript.
  • Failure recovery. Bad SoQL, HTTP 429, timeouts, infinite loops — all handled defensively.
  • Policy + safety bounds. The skill document enforces attribution, no-PII, no-auth-walled, rate-limit ethics — at four layers.
  • Verifiable answers. Every reply carries the exact SODA URL it ran. Click to replay.

Section

See also