Skip to content

Architecture

LoopLens is a single local process plus a tiny SDK. Everything stays on 127.0.0.1 — no login, no cloud, no API key.

Your agent app ──(looplens SDK / OTel / adapter)──▶ Local FastAPI server ──▶ SQLite
                                                            └──(live stream)──▶ React UI

Components

  • SDK (looplens): trace() + event() + @observe, a background HTTP sender, and a JSONL fallback. Zero third-party dependencies; fail-silent.
  • Server (looplens[server]): FastAPI + SQLite + Pydantic. Hosts the ingest API, the loop detectors, metrics, the SSE live stream, and the OpenTelemetry receiver at /v1/traces.
  • UI: React + Vite + TypeScript + Tailwind, prebuilt and bundled into the wheel so installing the [server] extra needs no Node.

Ingestion pipeline

Every event — whether it came from the SDK (POST /api/events), an OTel exporter (POST /v1/traces), or a JSONL import — funnels through one shared store_event path. That path writes the event, updates run totals and lifecycle, runs the loop detectors, and feeds the live stream. So detection, scoring, and the UI behave identically no matter how an agent was instrumented.

Storage

SQLite with three tables — runs, events, warnings — opened per operation with WAL enabled. Metrics and health are computed on demand from the stored events and warnings, so there's no derived state to keep in sync.

Data flow characteristics

  • Near-real-time, not push: the SSE stream polls SQLite every ~0.5s.
  • Single local user, no auth — local-first by design, not a production service.
  • Fail-silent SDK: if the server is down, events buffer to JSONL and the SDK never raises into your agent.