Overview
OpenTelemetry-native trace explorer for AI agents.
Theo Traces is an OpenTelemetry-native trace explorer for AI agents — "Jaeger
for agents." Instrument a TypeScript/Node agent in a few lines and it emits OTLP
gen_ai spans to an API that persists them to Postgres and serves a React trace
explorer with session replay, cost, and tool analytics. Spans are the source of
truth; traces and sessions are aggregates recomputed from them.
Pre-1.0 (0.0.0). Apache-2.0 and Docker-first. The SDK @usetheo/lens-sdk is
not yet published to npm — run the stack with Docker and install the SDK from
a local tarball for now. Not claimed production-ready.
Run the stack
git clone https://github.com/usetheodev/theo-lens.git
cd theo-lens
docker compose up -d # Postgres + API + UI on http://localhost:4318Instrument your agent
import { initTheoLens, startAgent, recordToolCall } from '@usetheo/lens-sdk';
const theo = initTheoLens({ endpoint: 'http://localhost:4318', serviceName: 'checkout-agent' });
await startAgent(theo.tracer, 'checkout', async (span) => {
span.setModel('gpt-4o').setProvider('openai').setUsage({ inputTokens: 12, outputTokens: 8 });
recordToolCall(span, 'search-products', { query: 'running shoes' });
});
await theo.shutdown();Instrumentation is fail-open: a telemetry-backend problem never crashes the
instrumented app, and shutdown() resolves even if the flush fails. Refresh
http://localhost:4318 to see the trace.
What you get
OpenTelemetry `gen_ai` spans
A thin facade over the OTel JS SDK — `initTheoLens` wires a tracer provider + OTLP HTTP exporter + batch processor. Standard spans, standard tooling.
Typed agent-span helpers
`startAgent` runs your function inside a `gen_ai` agent span (records exceptions + ends the span); `recordToolCall` nests a tool child span. Chainable setters for model, provider, usage.
Trace explorer UI
Execution list, span tree, session replay, cost view, and tool analytics — same-origin, one port, no CORS.
Cost + tool analytics
Per-trace and aggregate cost and token analytics, plus a tool-call breakdown (`GET /v1/analytics/cost`, `/v1/analytics/tools`).
External-agent adapters
Pluggable adapters selected by `service.name` map a foreign agent's attributes onto Theo's typed fields — Claude Code telemetry shows up as first-class executions.
Self-host, your Postgres
Configure via `THEOLENS_PG_URI` / `THEOLENS_PORT`; the API ingests OTLP at `POST /v1/traces` (JSON + protobuf).