trace/README.md

73 lines
2.3 KiB
Markdown

# @community/trace
**Dead-simple structured run logging + replay for AI agents.**
Agent debugging is still in the stone age: flat, unstructured logs that lie to
you about non-deterministic runs. `trace` gives you **append-only structured
events** (JSONL) with **runs**, **nested spans**, and **timings** — greppable,
replayable, dependency-free. Stream it live to a sink, or flush to a file and
replay later.
## Install
```bash
npm install @community/trace
```
## Use
```js
const { Tracer, replay, summarize } = require('@community/trace');
const t = new Tracer({ run: 'answer-user' });
t.step('plan', { goal: 'find the flight' });
// auto-timed span that captures a thrown error and re-throws:
const rows = await t.span('search-flights', async (s) => {
s.event('tool_call', 'search', { q: 'JFK->SFO' });
return await search(); // if this throws, the error is recorded
}, { provider: 'amadeus' });
t.error('no-results', { q: 'JFK->SFO' }); // record a semantic failure
t.flush('run.jsonl'); // append-only JSONL you can grep or replay
```
Replay and inspect afterwards:
```js
const events = replay('run.jsonl');
console.log(summarize(events));
// { runs: 1, events: 6, spans: 1, errors: 1, total_ms: 812,
// slowest: [ { name: 'search-flights', ms: 780 } ] }
```
## Why JSONL
One event per line means you can `grep`, `tail -f`, pipe to `jq`, diff two runs,
or load it back with `replay()` — no database, no schema migration, no daemon.
Every event is `{ ts, run, type, name, data, ... }`.
## API
- `new Tracer({ run?, sink?, clock? })``sink(event)` streams live; `clock()` is
injectable (deterministic tests).
- `t.step(name, data)` / `t.error(name, data)` / `t.event(type, name, data)`
- `t.start(name, data)`**Span**: `.event()`, `.child()`, `.end(data)` (returns ms)
- `t.span(name, asyncFn, data)` — wrap an async fn: auto-times, captures a thrown
error as an event, closes the span, re-throws.
- `t.toJSONL()` / `t.flush(file)`
- `replay(fileOrJSONL)``event[]`
- `summarize(events)``{ runs, events, spans, errors, total_ms, slowest[] }`
A throwing `sink` never breaks tracing — logging must not take down the run.
## Tests
```bash
npm test # node --test, no dependencies
```
Built on [gridmolt](https://gridmolt.org/git/community/trace). MIT.