# ๐ญ tracelet
### Local-first DevTools for AI agents
**Diff two runs of your agent step by step โ and watch every LLM and tool call live.**
Any framework. No account, no Docker, zero dependencies. 100% on your machine.
```bash
npx @jnmetacode/tracelet --demo
```
English | [็ฎไฝไธญๆ](https://github.com/jnMetaCode/tracelet/blob/main/README.zh-CN.md)

---
Your agent is a black box. It calls an LLM, the LLM asks for a tool, the tool
returns something weird, the next LLM call does something dumb โ and all you see
in your terminal is the final answer (or a stack trace).
**tracelet** is the missing inspector for that loop. Point any OpenTelemetry
exporter at `localhost:4318`, and watch your agent's execution tree stream in
live: every LLM call, every tool invocation, prompts in, completions out, token
counts, latency, and errors โ in a clean local UI that opens instantly.
And when you change a prompt, swap a model or fix a tool, **Compare** lines two
runs up step by step and shows exactly what changed โ which step, which model,
the prompt diff, and the ฮ in latency, tokens and cost.
Nothing ever leaves your machine.
## Quick start
```bash
# Start with two sample runs of an agent already loaded, then press Compare
npx @jnmetacode/tracelet --demo
```
Or start it plain (`npx @jnmetacode/tracelet`) and click **Load demo runs** on
the empty screen. From a clone, `node examples/demo.js --compare` sends the same
runs over real OTLP/HTTP.
Using the **Vercel AI SDK (v7+)** or **LangChain.js**? One line, no OpenTelemetry packages:
```js
import '@jnmetacode/tracelet/ai-sdk/register'; // AI SDK: top of your entry file
await agent.invoke(input, { callbacks: [tracelet()] }); // LangChain: from '@jnmetacode/tracelet/langchain'
```
Anything else: point your agent's OpenTelemetry exporter at the ingest endpoint:
```
http://localhost:4318/v1/traces
```
That's the standard OTLP/HTTP port โ most setups need only:
```bash
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
```
Both OTLP/HTTP encodings work: **protobuf** (the exporter default) and **JSON**.
No `OTEL_EXPORTER_OTLP_PROTOCOL` needed.
## Compare two runs
Change a prompt, swap a model, fix a tool โ then answer the question that
actually matters: *what changed in the agent's behaviour?* Select a run, press
**Compare** (or `c`), pick a second run:
- **Steps aligned side by side.** Retries, dropped tool calls and new steps
show as `+ added` / `โ removed`; the rest stays lined up instead of shifting.
- **Every changed step flagged** โ `status`, `model`, `input`, `output` โ with
per-step latency, tokens and cost for A, B and ฮ.
- **Prompt and completion diffs** in the inspector, line by line.
- **Headline deltas**: latency, tokens, cost, errors โ B relative to A.
- **Pin a baseline** (`p`): every new run that streams in is compared against
it automatically โ a regression check that runs while you iterate.
The run list searches too (`/`): names, models, tool names, and the full text
of prompts, completions and tool payloads โ matching spans light up in the
waterfall.
In the waterfall, drag across the bars to zoom into a time range (a 40 ms tool
call inside a 30 s run becomes readable); `Esc` or double-click resets.
`npx @jnmetacode/tracelet --demo` loads a before/after pair so you can try it
without wiring an agent. Deep-link a comparison with `#compare=,`.
## Works with what you already use
tracelet speaks the three common tracing vocabularies on the same spans, so it
"just works" no matter who emitted the trace:
| Source | How |
| --- | --- |
| **Vercel AI SDK v7+** | **One line, zero extra packages:** `import '@jnmetacode/tracelet/ai-sdk/register'`. See [`examples/vercel-ai-sdk`](examples/vercel-ai-sdk.md). |
| **Vercel AI SDK v5/v6** | `experimental_telemetry: { isEnabled: true }` โ export OTLP to `localhost:4318`. Same doc. |
| **Python OTel SDK** (LangChain, CrewAI, OpenAI Agents SDKโฆ) | The standard exporter works as-is (protobuf included). See [`examples/python-opentelemetry`](examples/python-opentelemetry.md). |
| **LangChain.js / LangGraph.js** | **One line, zero extra packages:** `{ callbacks: [tracelet()] }` from `@jnmetacode/tracelet/langchain`. See [`examples/langchain`](examples/langchain.md). |
| **Mastra** | `@mastra/otel-exporter` with a `custom` endpoint of `localhost:4318`. See [`examples/mastra`](examples/mastra.md). |
| **OpenInference** (LangChain, LlamaIndex, CrewAIโฆ) | Any OpenInference instrumentor exporting OTLP. |
| **OpenTelemetry GenAI** semconv | Native `gen_ai.*` spans, content as attributes *or* events. |
| **Anything OTel** | Plain spans render too โ you just get less semantic enrichment. |
No SDK lock-in: tracelet is just an OTLP endpoint + a viewer.
## Why another one?
Local agent debuggers exist now โ including good first-party ones. What
tracelet adds is **comparing two runs of an agent step by step, whatever
framework produced them.**
| | local, no account | works across frameworks | reads LLM spans (prompts ยท tokens ยท cost) | compare two runs | start |
| --- | :-: | :-: | :-: | :-: | --- |
| **tracelet** | โ
| โ
any OTLP + one-liners for AI SDK / LangChain.js | โ
| โ
steps aligned, prompt diffs, ฮ latency/tokens/cost | `npx` |
| [AI SDK DevTools](https://ai-sdk.dev/docs/ai-sdk-core/devtools) | โ
| โ AI SDK only | โ
| โ not in its docs | `npx @ai-sdk/devtools` |
| [Mastra Studio](https://mastra.ai/docs/evals/experiments) | โ
| โ Mastra only | โ
| ~ compares *experiment* scores over a dataset | `mastra dev` |
| [otel-front](https://github.com/mesaglio/otel-front) | โ
| โ
any OTLP | โ generic OpenTelemetry | โ
side-by-side traces | Homebrew / Docker / binary |
If you only use the AI SDK and don't need to compare runs, its DevTools is a
fine choice. If your agent mixes frameworks, runs in Python too, or you keep
asking *"what changed since the last run?"*, that's the gap tracelet fills.
It isn't a production analytics platform either. Those โ [Langfuse](https://langfuse.com/self-hosting)
(self-host: Postgres + ClickHouse + Redis + S3, or cloud), Arize Phoenix
(`pip install arize-phoenix` or Docker), LangSmith (cloud) โ bring retention,
evals, dashboards and teams. tracelet is the window you keep open while
*building*, like the Network tab for agent runs.
> Outgrew local? Everything is standard OTLP, so you graduate to any of those
> for production without re-instrumenting.
## How it works
```
your agent โโOTLP/HTTP (pb|json)โโโถ :4318 โโโถ in-memory store โโSSEโโโถ UI :4321
(ring buffer, never persisted off-box)
```
- **Zero dependencies.** Pure Node built-ins, no build step. About 3 000
lines all in โ server, parser, UI and the framework integrations โ readable
in an afternoon.
- **Two ports.** `4318` ingests OTLP (the convention), `4321` serves the UI.
- **In-memory ring buffer.** Last 500 traces. Restart = clean slate โ unless
you opt in to `--persist `, which keeps history in a local JSONL file
(still your disk, still nothing sent anywhere; Clear wipes it too).
- **Cost estimates.** Traces and LLM spans show a `~$` figure computed from
published list prices for common models (Claude/GPT/Gemini); unknown models
simply show none โ it never guesses.
- **Bounded.** 50 MB per request, 64 MB inflated, 10 000 spans per trace
(extras are counted as dropped, not stored), 500 traces in memory. A
runaway agent can't take the tool down with it.
- **Private by default.** Both ports bind to `127.0.0.1` (use `--host 0.0.0.0`
to expose them deliberately). The UI API sends no CORS headers, so a web page
open in the same browser cannot read your traces, and the UI only answers to
`localhost` / `127.0.0.1`, so DNS-rebinding tricks can't either. Only the OTLP
ingest path accepts cross-origin POSTs, for browser-side exporters.
## CLI
```
npx @jnmetacode/tracelet [options]
-p, --port OTLP/HTTP ingest port (default 4318)
--ui-port Web UI port (default 4321)
--persist opt-in local history (JSONL; reloaded on start)
--demo start with two sample agent runs loaded
--host bind address (default 127.0.0.1 โ loopback only;
0.0.0.0 to expose, e.g. inside a container)
--no-open don't auto-open browser
```
### Keyboard
| Key | |
| --- | --- |
| `/` | focus search |
| `j` / `k` (or โ / โ) | next / previous span โ or diff row in Compare |
| `[` / `]` | previous / next run |
| `c` | compare the selected run with another |
| `p` | pin / unpin the selected run as baseline |
| `Esc` | cancel picking ยท reset zoom |
| double-click waterfall | reset zoom |
## Roadmap
- [x] Opt-in local history (`--persist traces.jsonl`) โ done
- [x] Diff two runs side by side (Compare: aligned steps, prompt/output diffs, ฮ latency/tokens/cost) โ done
- [x] Cost estimates per model (list-price `~$` on traces and LLM spans) โ done
- [x] protobuf OTLP ingest (zero-dep decoder) โ done
- [x] Waterfall zoom (drag a time range on the bars; Esc / double-click resets) โ done
- [x] Trace list: search inside prompts/outputs, filter by model/tool โ done
- [x] One-line wrapper for the Vercel AI SDK (`@jnmetacode/tracelet/ai-sdk`, zero deps) โ done
- [x] Mastra: config-only wiring via `@mastra/otel-exporter` (`examples/mastra.md`)
- [x] One-line wrapper for LangChain.js / LangGraph.js (`@jnmetacode/tracelet/langchain`, zero deps) โ done
PRs welcome. This is early โ issues and ideas are the most useful contribution
right now.
## Status
Usable daily: live ingest (protobuf + JSON), waterfall + inspector, Compare /
baseline, search, zoom, cost estimates, opt-in history, and verified one-line
integrations for the Vercel AI SDK, LangChain.js and Mastra. Still small (~3 000
lines, no build step, no dependencies) and still opinionated about staying local.
Issues with a sample OTLP payload are the most useful contribution.
## Sibling projects
Part of a small, local-first, zero-dependency toolkit for building AI agents โ see the [toolkit overview & end-to-end recipe](https://github.com/jnMetaCode/local-agent-toolkit):
- ๐ญ **tracelet** โ local DevTools to debug agent runs *(this repo)*
- ๐ณ **[skillet](https://github.com/jnMetaCode/skillet)** โ a package manager for agent skills
- ๐ง **[engram](https://github.com/jnMetaCode/engram)** โ a local, private memory layer for agents (and you)
Beyond the toolkit, the same author maintains the widerใAIไธๆญข่ฏญใecosystem:
[agency-agents-zh](https://github.com/jnMetaCode/agency-agents-zh) (277 AI expert personas) ยท [superpowers-zh](https://github.com/jnMetaCode/superpowers-zh) (20 skills that teach AI how to work) ยท [agency-orchestrator](https://github.com/jnMetaCode/agency-orchestrator) (one prompt โ 276 specialists collaborate) ยท [openshorts](https://github.com/jnMetaCode/openshorts) (topic in, finished short video out).
## License
MIT โ see [LICENSE](LICENSE).