Skip to content

Latest commit

 

History

History
87 lines (73 loc) · 5.91 KB

File metadata and controls

87 lines (73 loc) · 5.91 KB

Architecture (scaffold)

The template's runtime architecture is intentionally small — one backend service, one frontend app, one tracing collector. The point of the scaffold is to exercise the harness, not to ship features.

Components

                                        ┌────────────────────┐
                                        │   Browser          │
                                        │   (React 19.2)     │
                                        └─────────┬──────────┘
                                                  │
                                                  │ http://localhost:5173
                                                  │ (Vite dev server, HMR)
                                                  ▼
                                        ┌────────────────────┐
                                        │   frontend/        │
                                        │   Vite + React +TS │
                                        │   • App.tsx        │
                                        │   • lib/api/       │
                                        │     client.ts (SSE)│
                                        └─────────┬──────────┘
                                                  │
                                                  │ /api/v1/* (proxied)
                                                  ▼
       ┌──────────────────────────────────────────────────────────┐
       │                     src/api/                             │
       │  ┌──────────┐   ┌─────────────┐   ┌──────────────────┐   │
       │  │ main.py  │ ─►│ routes.py   │   │ sessions.py      │   │
       │  │ FastAPI  │   │ /v1/health  │   │ in-memory store  │   │
       │  │ lifespan │   │ /v1/echo    │   │                  │   │
       │  └────┬─────┘   └─────────────┘   └──────────────────┘   │
       │       │                                                   │
       │       │ setup_tracing → setup_logging → instrument_*       │
       │       ▼                                                   │
       │  ┌─────────────────────────────────────────────────────┐  │
       │  │              src/observability/                     │  │
       │  │  tracing.py · logging.py · spans.py                 │  │
       │  └─────────────────────┬───────────────────────────────┘  │
       └────────────────────────┼──────────────────────────────────┘
                                │ OTLP gRPC :4317
                                ▼
                       ┌─────────────────────┐
                       │  Jaeger all-in-one  │   :16686 (UI)
                       │                     │   :4317  (OTLP gRPC)
                       │                     │   :4318  (OTLP HTTP)
                       └─────────────────────┘

Slots that fill in as the project grows

Slot Today Eventual
src/agent/ Empty package LLM tool-calling loop
src/tools/ registry.py + echo_tool Real domain tools
src/data/ Empty package DB / file / API clients
src/api/sessions.py In-memory dict Redis or DB-backed store
eval/golden_qa.json One echo case 15-50 cases by category

The layered import-linter contract lets each slot grow without coordination — adding src/data/db_client.py doesn't trigger any change in src/models/ or src/api/.

Request lifecycle (scaffold)

  1. Browser hits GET /api/v1/health (or /echo?msg=...).
  2. FastAPI routes to src/api/routes.py:health / routes.py:echo.
  3. The handler builds a typed response (HealthResponse / EchoResponse — both StrictModel).
  4. OpenTelemetry's FastAPI instrumentation produces a span; OTLP exporter ships it to Jaeger.
  5. The structured logger writes one JSON record per request, correlated by trace_id / span_id.
  6. Response returns to the browser as JSON.

Frontend lifecycle (scaffold)

  1. Vite dev server serves index.htmlsrc/main.tsxApp.tsx.
  2. App.tsx runs useEffect once, fetching /api/v1/health via the browser's fetch (proxied through Vite to :8000 in dev, served same-origin in a real deployment).
  3. The component renders one of three states (loading | ok | error) using semantic ARIA roles + data-testid hooks for the Vitest suite.
  4. CSS variables in src/styles/palette.css drive the visual; [data-theme='dark'] flips palette tokens.

The typed SSE client at src/lib/api/client.ts is unused by the scaffold's hello page but ships ready: any backend that returns text/event-stream from a POST endpoint can be consumed via sendMessage<TEvent>(...).

Out of scope at the scaffold level

  • Persistence (real DB / queue / cache).
  • Auth (OIDC, sessions, API keys).
  • Rate limiting.
  • Real production observability backend (Jaeger is the local dev choice; production typically uses a managed OTLP collector / vendor).

Each of these earns a section in this document when the project decides on its concrete shape.