daari — Architecture & project structure¶
Living overview of the repo layout, runtime flow, and implementation status.
Last updated: 2026-10-05 · Verified at:working tree
For phase tasks and exit criteria, see TRACKING.md. For clone/run/test pickup, see DEVELOPING.md.
What daari is¶
daari is an open-source local execution router — a cost optimizer you run on your machine. Dev agents (Cursor, OpenAI SDK, curl) send chat requests to a localhost daemon; daari routes each request through the cheapest capable tier (exact cache → local model) before any frontier API. It is not a proxy: routing, cache, and policy live in one Python process you own. See PRD v0.4 and ADR-0013 for monorepo rules.
Phase status¶
| Phase | Status | Summary |
|---|---|---|
| A / A.1 — Tracer bullet + install | Done | gateway, L0, L3, router, metrics, evals; install, setup, doctor, L6 escalation, confidence |
| B — Rules, Lt, multi-model | Done | L1, L2, L2-dev, CCS, Lt B.0 + PolicyEngine, L4, setup recipes, ask/confirm UX, evals GP-20 |
| C1/C2/C3 — Clients & providers | Done | Anthropic gateway (+ tool passthrough), MCP ingress, Ollama-compatible facade, browser extension, web UI, MLX backend, Sourcegraph/GHE/GitLab providers, per-project .daari.yaml profiles, gateway API-key auth |
| D — Local learning | Done | feedback store + tuner (D1), example capture + MLX fine-tune (D2), opt-in collective stats export (D3), learn deploy |
| Trust trains 1–5 | Done | cache-trust measurement (false-hit rate, diversity, normalization), prompt-cache passthrough + compaction + compression, latency-aware routing, learned routing, budgets/client attribution/PII scrub |
| E2/E3 — Org shared cache + learning | Done (tracer) | daari org-cache serve, L0-org/L1-org lookup + write-through, metadata feedback + profile sync |
| Roadmap v2 (F1–F5) | Next | OSS launch pack, gateway parity, Prometheus/OTel, enterprise scale-out — ROADMAP-v2 |
Detail and task checklists: TRACKING.md.
Directory tree¶
Concise layout as of main (~3c44a8e). Omitted: __pycache__, .venv, dotfiles.
daari/ # repo root
├── daari/ # Python package — routing brain (pip install -e .)
│ ├── cli/ # Typer commands (serve, stats, report, trace, learn, setup, …)
│ ├── server/ # FastAPI app factory + API-key middleware
│ ├── gateway/ # OpenAI, Anthropic (tool passthrough), MCP, Ollama facade, PII scrub, request log
│ ├── router/ # Tier routing + prompt profile, latency budgets, compression, MLX executor, model profiling
│ ├── cache/ # L0 exact + L1 semantic (normalization, TTLs) + CCS command context
│ ├── learning/ # Phase D: feedback, tuner, examples, dataset, finetune, deploy, collective, router model
│ ├── config/ # Settings + defaults.yaml + per-project .daari.yaml profiles
│ ├── observability/ # Tier metrics, usage ledger (savings), request traces
│ ├── providers/ # IntegrationProvider registry (Sourcegraph, GHE, GitLab)
│ ├── enterprise/ # Org config + shared-cache/learning service and client
│ ├── rules/ # L2 + L2-dev regex/template routing rules
│ ├── tools/ # Lt subprocess executor
│ ├── policy/ # Lt allow/deny/ask policy engine
│ ├── clients/ # One-click setup recipes (Cursor, Claude Code, IntelliJ, VS Code)
│ └── setup/ # doctor, wizard, backup, jsonc, models, openai-compat/context helpers
├── tests/
│ ├── unit/ # cache, router, learning, trust, budgets, settings, …
│ ├── integration/ # gateway flows (OpenAI/Anthropic/MCP/facade/auth); optional live Ollama
│ ├── benchmark/ # L0 vs L3 latency (optional)
│ └── test_*.py # routing evals, setup, doctor
├── evals/routing/ # Golden prompts GP-01–GP-20
├── docs/ # PRDs, ADRs, setup guides, release notes, tracker
├── scripts/ # install.sh, demo.sh, bench.sh, tunnel.sh, autodev-local.sh
├── packages/
│ ├── browser-extension/ # MV3 popup + content-script site profiles → local daemon (jsdom-tested)
│ └── web-ui/ # Stats/savings/traces dashboard (jsdom-tested)
├── pyproject.toml
├── README.md
└── CONTEXT.md # Agent handoff
User runtime paths (not in repo): ~/.daari/config.yaml, ~/.daari/cache/{l0,l1}, ~/.daari/traces/, ~/.daari/usage/, ~/.daari/feedback/, ~/.daari/training/, ~/.daari/backups/<tool>/, ~/.daari/cursor-requests.log (rotated).
Path → purpose → status¶
Runtime code (daari/)¶
| Path | Purpose | Status |
|---|---|---|
daari/__main__.py |
python -m daari entry |
✅ |
daari/cli/app.py |
Typer CLI: serve, stats, doctor, setup |
✅ |
daari/cli/setup_actions.py |
Shared setup apply helpers | ✅ |
daari/server/app.py |
FastAPI factory, lifespan → AppContext |
✅ |
daari/gateway/openai.py |
POST /v1/chat/completions, audio transcriptions, stats, health |
✅ |
daari/gateway/internal.py |
InternalRequest / InternalResponse / DaariMeta (agent_turn per ADR-0004) |
✅ |
daari/router/router.py |
Router: L0/CCS/L1/L2/Lt/L3/L4/L5/L6 + no-frontier + fallback behavior | ✅ |
daari/gateway/base.py |
GatewayAdapter protocol |
✅ |
daari/gateway/anthropic.py |
POST /v1/messages Anthropic-compatible adapter (minimal) |
✅ |
daari/gateway/mcp.py |
MCP JSON-RPC 2.0 at POST /mcp; deprecated /v1/mcp/query alias |
✅ |
daari/cache/exact.py |
L0 exact cache keys + diskcache store | ✅ |
daari/cache/semantic.py |
L1 semantic cache — Ollama embeddings + cosine similarity | ✅ |
daari/config/settings.py |
Merged config (defaults.yaml + ~/.daari/ + profile overlays + skills prefix) |
✅ |
daari/config/defaults.yaml |
Package defaults (host, port, models) | ✅ |
daari/observability/metrics.py |
Tier counters for /v1/daari/stats (soft_warnings / rejects cliff maps, backend_summary, compact_to_fit_applied / compact_to_fit_tokens_dropped) |
✅ |
daari/providers/base.py |
IntegrationProvider protocol (execute, health) |
✅ |
daari/providers/registry.py |
Provider registry used by router | ✅ |
daari/providers/integrations.py |
Sourcegraph GraphQL + GHE repo/issue search providers | ✅ |
daari/enterprise/config.py |
Enterprise org settings schema (OrgSettings) including shared-cache URL/token fields |
✅ |
daari/enterprise/client.py |
Org shared-cache + learning HTTP clients used by router/CLI (L0-org, L1-org, feedback/profile) |
✅ |
daari/enterprise/service.py |
Lightweight shared-cache + learning FastAPI service (/v1/org-cache/*, /v1/org-learning/*) |
✅ |
daari/rules/engine.py |
L2 deterministic transforms (JSON/YAML) | ✅ |
daari/rules/dev_commands.py |
L2-dev developer command detection | ✅ |
daari/cache/command_context.py |
CCS store for command output reuse | ✅ |
daari/tools/shell.py |
Lt shell execution backend | ✅ |
daari/policy/engine.py |
Allow/deny/ask execution policy | ✅ |
daari/clients/base.py |
ClientSetupRecipe protocol |
✅ |
daari/clients/registry.py |
Setup recipe dispatch (cursor, intellij, vscode, claude-code) |
✅ |
daari/clients/cursor/recipe.py |
Cursor settings patch / undo / dry-run | ✅ |
daari/clients/intellij/recipe.py |
IntelliJ helper config patch / undo / dry-run | ✅ minimal |
daari/clients/vscode/recipe.py |
VS Code settings patch / undo / dry-run | ✅ minimal |
daari/clients/claude_code/recipe.py |
claude-code env helper + config pointer dry-run/apply/undo | ✅ minimal |
daari/setup/doctor.py |
Health checks (Python, config, Ollama models including embedding model, org cache, daemon) | ✅ |
daari/setup/wizard.py |
Interactive daari setup |
✅ |
daari/setup/backup.py |
Backup / restore for setup recipes | ✅ |
daari/setup/jsonc.py |
JSONC read/write for Cursor config | ✅ |
daari/setup/models.py |
daari setup models — tier → Ollama model |
✅ |
daari/setup/openai_compat.py |
setup openai-compat + frontier env/profile hints |
✅ |
daari/setup/context.py |
daari context clear cache invalidation helper + daemon cache-handle reload support |
✅ |
daari/gateway/ollama_compat.py |
Ollama-compatible facade (/api/tags, /api/chat, …) for JetBrains & Ollama-speaking clients |
✅ |
daari/gateway/pii.py |
Regex PII scrub before L6 escalation (opt-in) | ✅ |
daari/gateway/request_log.py |
Rotating JSON request log (~/.daari/cursor-requests.log) |
✅ |
daari/router/profile.py |
Prompt profiling: category, complexity, token estimate | ✅ |
daari/router/mlx_executor.py |
MLX backend executor (mlx_lm.server, Apple Silicon) |
✅ |
daari/router/model_profile.py |
daari profile benchmarks + warm-model tracking + latency budgets |
✅ |
daari/router/compress.py |
Frontier context compression (relevance pruning) | ✅ |
daari/cache/normalize.py |
Input normalization before L1 embedding | ✅ |
daari/observability/usage.py |
SQLite usage ledger — savings, budgets, client attribution | ✅ |
daari/observability/spend.py |
Opt-in per-request spend rows + daari spend export |
✅ |
daari/observability/trace.py |
Per-request trace store (daari trace) |
✅ |
daari/learning/feedback.py |
Outcome store + explicit accept/reject + shadow-sampling stats | ✅ |
daari/learning/tuner.py |
Per-category confidence threshold tuner (opt-in) | ✅ |
daari/learning/examples.py · dataset.py · finetune.py · deploy.py |
Opt-in example capture → MLX LoRA fine-tune → adapter deploy | ✅ |
daari/learning/router_model.py |
Learned category/tier classifier (daari learn train-router) |
✅ |
daari/learning/collective.py |
D3 opt-in anonymized stats export (review-first) | ✅ |
daari/config/project.py |
Per-project .daari.yaml profiles (X-Daari-Project) |
✅ |
Not in tree (Roadmap v2): Docker/Helm artifacts, Prometheus exporter, Redis/Postgres backends, virtual keys, guardrails, Responses API adapter.
Docs (docs/)¶
| Path | Purpose | Status |
|---|---|---|
docs/prd/ |
PRD, ROADMAP, routing-spec, setup-spec, glossary | Spec (living) |
docs/adr/ |
Architecture decision records 0001–0014 | Accepted |
docs/plans/phase-a.md |
Phase A implementation plan | Historical + reference |
docs/setup/cursor.md |
Manual Cursor fallback | ✅ |
docs/setup/intellij.md |
IntelliJ setup + helper config behavior | ✅ |
docs/setup/vscode.md |
VS Code setup helper behavior | ✅ |
docs/setup/claude-code.md |
claude-code env helper setup | ✅ |
docs/DEVELOPING.md |
Clone, run, test pickup | ✅ |
docs/TRACKING.md |
Phase task tracker | ✅ |
docs/ARCHITECTURE.md |
This file | ✅ |
Scripts & tests¶
| Path | Purpose | Status |
|---|---|---|
scripts/install.sh |
venv + editable install + Ollama pull hint | ✅ |
scripts/demo.sh |
One-click smoke: serve, curl, stats, setup dry-run | ✅ |
tests/unit/ |
Fast unit tests (CI) | ✅ |
tests/integration/ |
Mocked gateway flow; live Ollama optional | ✅ |
tests/benchmark/ |
Tier latency (@pytest.mark.benchmark) |
✅ optional |
tests/test_routing_eval.py |
GP-01–GP-20 routing evals | ✅ |
tests/test_setup.py, tests/test_doctor.py |
Setup / doctor coverage | ✅ |
.github/workflows/ci.yml |
Python 3.12 pytest on push/PR | ✅ |
Other¶
| Path | Purpose | Status |
|---|---|---|
evals/routing/prompts.jsonl |
Golden prompt fixtures for routing evals | ✅ |
packages/README.md |
Placeholder for future browser ext / web UI | ✅ |
packages/browser-extension/ |
MV3 popup + content-script site profiles → local daemon (:11435); session savings in popup |
✅ |
packages/web-ui/README.md |
Web UI runtime docs (table + chart + auto-refresh controls) | ✅ |
CONTEXT.md |
Agent/session handoff | ✅ |
Request flow¶
Typical chat completion path: client → OpenAI-compat gateway → router → cache/rules/tools/local models/frontier.
flowchart LR
Client["Client\n(Cursor / curl / SDK)"]
Serve["daari serve\nFastAPI :11435"]
GW["gateway/openai.py\nPOST /v1/chat/completions"]
Router["router/router.py"]
L0["L0 ExactCache\ndiskcache"]
L1["L1 SemanticCache\nOllama embeddings"]
L3["L3 OllamaExecutor\n/api/chat"]
Ollama["Ollama\n:11434"]
Client --> Serve
Serve --> GW
GW --> Router
Router -->|"L0 miss"| L1
Router -->|"L1 miss"| L3
Router -->|"L0 hit"| L0
Router -->|"L1 hit"| L1
Router -->|"agent L0 miss"| L3
L1 --> Ollama
L3 --> Ollama
L0 --> GW
L1 --> GW
L3 --> GW
GW --> Client
Routing rules (shipped):
- Agent flows (
toolspresent ortool_callsin history) keep the full tool protocol and skip Lt/L2/L1. Exact L0 is on: an identical full history hits cache; a changed last tool result misses (ADR-0004 / G1). - Try L0 exact cache, then org L0 when configured (unless
X-Daari-No-Cache: trueor the category policy skips cache). - Try CCS for matched dev command context before re-execution.
- Try L1 semantic cache (normalized-input embeddings + cosine threshold, per-category TTLs); near-misses above the draft threshold inject the cached answer as a draft; a sample of hits is shadow-checked to measure false-hit rate.
- Apply L2-dev command rules (
git,pytest,eslint) and policy gate; execute Lt when allowed. - Apply L2 deterministic transforms (JSON/YAML patterns).
- Build the prompt profile (category/complexity; learned router can override the heuristic); pick the initial tier via category policy → tier cap (
X-Daari-Tier-Cap,.daari.yaml) → latency budget step-down (profiled model latency vsrouting.latency_budget_ms/X-Daari-Latency-Budget) with warm-model preference. - Model path L3/L4/L5 with fallback; confidence (per-category tuned when
learning.auto_tune) drives escalation toward L6 — slimmed, optionally compressed and PII-scrubbed, budget-guarded (daily + monthly soft/hard). Opt-inrouting.compact_to_fittrims droppable turns before L6; a successful trim recordstokens_before/tokens_afteron thecompact_to_fittrace step (fail-closed if the remainder still exceeds the cap). X-Daari-No-Frontier: true(or the project profile) prevents L6 escalation.
Entry points¶
CLI (daari)¶
| Command | Purpose |
|---|---|
daari serve [--host] [--port] [--no-frontier] [--org] |
Start HTTP daemon (default 127.0.0.1:11435) |
daari org-cache serve [--org] [--port] [--require-token] |
Start org shared-cache + learning service (default 127.0.0.1:11436) |
daari org-learning stats |
Show aggregated org learning metrics |
daari org-learning sync |
Force the running daemon to refresh org-learning routing profile |
daari org-learning export [-o FILE] |
Export anonymized org learning summary |
daari stats [--host] [--port] |
Fetch tier counters from running daemon |
daari doctor |
Check Python, config, Ollama, model, optional daemon |
daari install [--run-doctor/--no-run-doctor] [--pull-l4] [--pull-l5] |
Run install workflow via scripts/install.sh |
daari setup |
Interactive setup wizard |
daari setup --undo <tool> |
Restore latest backup (e.g. cursor) |
daari setup cursor [--dry-run] [--force] |
Patch Cursor to point at daari |
daari setup intellij [--dry-run] [--force] |
Write IntelliJ helper OpenAI-compatible config |
daari setup vscode [--dry-run] [--force] |
Patch VS Code settings with daari OpenAI-compatible marker |
daari setup claude-code [--dry-run] [--force] |
Write claude-code OPENAI_* env helper + config pointer |
daari setup all [--dry-run] [--force] |
Run setup recipes for all detected clients |
daari setup models [--tier] [--model] [--list] |
Map tier → Ollama model in user config |
daari setup openai-compat |
Print OPENAI_* exports + write ~/.daari/.env.example |
daari setup frontier-key |
Optional shell/profile frontier key hint (no secret persistence) |
daari context clear [--l0/--l1/--ccs] |
Clear L0/L1/CCS caches and auto-refresh running daemon cache handles |
daari report [--days N] [--md FILE] |
Usage, savings, budget state, client breakdown, cache trust |
daari trace [ID] [--md FILE] |
Per-request decision timeline |
daari feedback <trace_id> --accept/--reject |
Explicit outcome feedback |
daari learn stats/recommend/examples/export-dataset/train-router/finetune/deploy/export-stats |
Phase D learning loop |
daari profile [--models ...] |
Benchmark local models (tokens/sec, load) for latency-aware routing |
daari project init/show |
Per-repo .daari.yaml profile management |
daari cache prune |
Remove expired L0/L1 entries. On Redis, prints that expiry is TTL and prune does not scan. |
daari cache invalidate [--model M] [--hash H] |
Drop L0/L1 entries by served model or entry hash. No flags clears both. Uses the daemon when it is up. |
daari web-ui serve |
Local dashboard (stats, savings, traces, cache trust) |
daari setup cursor --tunnel |
Cursor BYOK via cloudflared + auto-generated gateway API key |
Registered in pyproject.toml as daari = "daari.cli.app:app".
HTTP (daemon)¶
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/chat/completions |
OpenAI-compat chat with full SSE streaming (tier fallback, L0/L1, draft injection) |
POST |
/v1/audio/transcriptions |
OpenAI speech-to-text; local asr.base_url, optional frontier fallback (off by default) |
POST |
/v1/responses |
OpenAI Responses API (function calls, previous_response_id, background) |
GET |
/v1/responses/{id} |
Retrieve a stored Responses object |
POST |
/v1/responses/{id}/cancel |
Cancel an in-flight or return the current terminal Responses object |
DELETE |
/v1/responses/{id} |
Delete a stored Responses object |
GET |
/v1/models, /v1/models/{id} |
Model listing for client pickers |
POST |
/v1/messages |
Anthropic-compatible adapter with tool passthrough (non-stream + SSE) |
GET/POST |
/api/tags, /api/chat, /api/version, /api/show, /api/ps |
Ollama-compatible facade (JetBrains AI Assistant, any Ollama client) |
POST |
/mcp |
MCP JSON-RPC 2.0 (initialize, tools/list, tools/call) over streamable HTTP |
POST |
/v1/mcp/query |
Deprecated MCP alias (Deprecation + Link to /mcp) |
POST |
/v1/daari/reload-caches |
Reload in-memory L0/L1/CCS handles from current settings |
GET |
/v1/daari/stats |
Tier metrics snapshot (soft_warnings / rejects maps, backend_summary counts) |
GET |
/v1/daari/report |
Usage/savings/budget/cache-trust report |
GET |
/v1/daari/traces, /v1/daari/traces/{id} |
Request trace list/detail |
POST |
/v1/daari/feedback |
Explicit accept/reject by trace_id |
GET |
/v1/daari/learn/stats |
Learning outcome evidence |
GET |
/v1/daari/cache/diversity |
Semantic-cache diversity stats |
POST |
/introspect |
RFC 7662 token introspection for master / virtual keys |
GET |
/health |
Liveness (open even when API-key auth is on) |
When server.api_key is set (auto-generated by daari setup cursor --tunnel), all non-health endpoints require Authorization: Bearer or x-api-key.
Optional headers on chat: X-Daari-No-Cache, X-Daari-Tier-Override, X-Daari-Tier-Cap, X-Daari-No-Frontier, X-Daari-Latency-Budget, X-Daari-Client-Id, X-Daari-Project, X-Daari-Meta, X-Daari-Tools, X-Daari-Confirm, X-Daari-Confirm-Tool, X-Daari-ReRun-Command.
Org shared-cache service (daari org-cache serve):
| Method | Path | Purpose |
|---|---|---|
GET |
/v1/org-cache/get?key=...&tier=... |
Read org cache entry |
PUT |
/v1/org-cache/put |
Write org cache entry |
GET |
/v1/org-cache/stats |
Show entries and hit/miss/write counters |
Org learning endpoints (same service host):
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/org-learning/feedback |
Ingest anonymized routing feedback metadata |
GET |
/v1/org-learning/profile |
Read aggregated org routing profile |
PUT |
/v1/org-learning/profile |
Admin override for org routing profile (token-gated) |
POST |
/v1/org-learning/sync |
Force profile refresh in running daemon app context |
Scripts¶
| Script | Purpose |
|---|---|
./scripts/install.sh |
Create venv, pip install -e ".[dev]", Ollama model hint |
./scripts/demo.sh |
Full smoke: install, serve, double curl (L0 hit), stats, setup dry-run |
./scripts/bench.sh |
Tier latency benchmark helper (L0/L1/L2/Lt/L3) with robust uncached prompt seeding |
./scripts/smoke-cursor-dry-run.sh |
CI-friendly daari setup cursor --dry-run smoke command |
Implemented vs spec-only¶
| Area | Implemented | Spec only / deferred (Roadmap v2) |
|---|---|---|
| Gateway | OpenAI (+SSE), Anthropic with tool passthrough, MCP ingress, Ollama facade, API-key auth, PII scrub | Responses API, guardrails, virtual keys, MCP egress client |
| Tiers | L0/L1 (TTLs, normalization, draft injection, shadow sampling), CCS, L2/L2-dev, Lt + policy, L3–L5 (Ollama or MLX), L6 with slimming/compression/budgets | multi-provider L6 fallback chains, key rotation, circuit breakers |
| Routing intelligence | Prompt profile, category policies, tier caps, latency budgets + model profiling + warm preference, learned router, tuner | capability catalog, VRAM stack advisor |
| Learning | Feedback → stats/recommend → tuner → examples → fine-tune → deploy; D3 opt-in export | D4 published defaults pipeline |
| Setup | One-click Cursor (tunnel+auth), Claude Code, IntelliJ facade, VS Code, openai-compat, per-project profiles | Homebrew, Docker one-command |
| Providers | Sourcegraph, GHE, GitLab, generic HTTP, L2-live URL fetch | live-source family (Open-Meteo, wttr.in, sources.yaml) |
| Observability | Tier metrics, usage ledger + savings, traces, request log rotation, web dashboard, MD export | Prometheus /metrics, Grafana, OTel |
| Enterprise | Org shared cache + learning sync (tracer), API-key auth | Redis/Postgres backends, stateless replicas, Helm, fleet bootstrap, SSO/RBAC/audit |
| Packages | browser-extension + web-ui (both jsdom-tested in CI) | intellij-plugin (superseded by Ollama facade) |
Source of truth for “done”: TRACKING.md task tables + daari/ tree + pytest.
Suggested walkthrough order¶
Read in this order to follow a request from CLI to response, then setup and tests.
README.md— one-paragraph product + quick startdocs/prd/PRD.md(§ tiers) or routing-spec — tier modeldaari/config/defaults.yaml→daari/config/settings.py— config mergedaari/gateway/internal.py— internal wire modelsdaari/server/app.py— app bootstrapdaari/gateway/openai.py— HTTP → internal requestdaari/router/router.py— L0 / L1 / L3 routingdaari/cache/exact.py— L0 cache keysdaari/cache/semantic.py— L1 semantic cachedaari/observability/metrics.py— statsdaari/cli/app.py— CLI surfacedaari/clients/cursor/recipe.py+daari/setup/— Phase A.1 setuptests/integration/test_gateway_flow.py— end-to-end mocked flowtests/test_routing_eval.py+evals/routing/prompts.jsonl— routing qualitydocs/adr/0013-monorepo-structure.md— where future code goes
Maintenance¶
Update this doc when:
- A new phase ships (or exits) — refresh phase status, path table, implemented vs spec
- A major module is added under
daari/(e.g.tools/, new gateway adapter) - A tier is implemented (L1, L2, L6, Lt, …) — update flow diagram and routing rules
- A CLI command or HTTP endpoint is added or renamed
- Default ports, paths, or entry points change
Also refresh Last updated and Verified at commit when editing. Keep TRACKING.md as the task-level checklist; this file is the structural map.