@tangle-network/traces 0.8.18 → 0.8.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -30
- package/dist/{chunk-G3OBZSWY.js → chunk-FCTZLWP7.js} +234 -180
- package/dist/cli.js +51 -24
- package/dist/index.d.ts +172 -135
- package/dist/index.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# traces
|
|
2
2
|
|
|
3
|
-
> Point `traces` at the session logs your coding agent already writes to disk
|
|
3
|
+
> Point `traces` at the session logs your coding agent already writes to disk: Claude Code, Codex, OpenCode, Gemini, and more. Get failure-mode and efficiency findings with zero instrumentation. A CLI *and* an SDK.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](./LICENSE)
|
|
9
9
|
[](https://nodejs.org)
|
|
10
10
|
|
|
11
|
-
It reads the transcripts your harness leaves on disk, reconstructs the run as spans, and reports where the agent got stuck, burned tokens, or stopped checking its own work
|
|
11
|
+
It reads the transcripts your harness leaves on disk, reconstructs the run as spans, and reports where the agent got stuck, burned tokens, or stopped checking its own work. The deterministic pass runs locally, with no API key and no cost.
|
|
12
12
|
|
|
13
13
|
## Contents
|
|
14
14
|
|
|
@@ -46,16 +46,16 @@ Requires Node ≥ 22.
|
|
|
46
46
|
traces analyze --harness claude-code --last 1
|
|
47
47
|
traces improve --harness claude-code --last 5 --dir .traces/improvement
|
|
48
48
|
traces watch --all
|
|
49
|
-
traces stream --all --
|
|
49
|
+
traces stream --all --mode findings
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
That's the command in the demo above. The **deterministic pass**
|
|
52
|
+
That's the command in the demo above. The **deterministic pass** checks stuck loops, token growth, output decay, missing self-verification, and tool monoculture. It needs no API key and costs nothing.
|
|
53
53
|
|
|
54
54
|
Add `--llm` for the **agentic analysts** (failure-mode / knowledge-gap / knowledge-poisoning / improvement); they call OpenAI and respect `--budget <usd>`.
|
|
55
55
|
|
|
56
|
-
Every run also writes a **canonical OpenInference JSONL artifact**, so you can run external engines like [HALO](https://github.com/context-labs/halo) over it directly with `--analyzer halo
|
|
56
|
+
Every run also writes a **canonical OpenInference JSONL artifact**, so you can run external engines like [HALO](https://github.com/context-labs/halo) over it directly with `--analyzer halo`. See [External engines](#external-engines-bring-your-own). Analysis is never locked to one engine.
|
|
57
57
|
|
|
58
|
-
`traces improve` is the reviewable action path. It writes typed artifacts
|
|
58
|
+
`traces improve` is the reviewable action path. It writes typed artifacts: findings, recommendations, evidence rows, claims, report, and before/after replay metadata. Another agent, CI job, or hosted product can consume the result without scraping prose.
|
|
59
59
|
|
|
60
60
|
## What it finds
|
|
61
61
|
|
|
@@ -64,10 +64,10 @@ The deterministic pass (free, no key) surfaces:
|
|
|
64
64
|
| Finding | Meaning |
|
|
65
65
|
|---|---|
|
|
66
66
|
| **Stuck loops** | the same tool called N× with identical args and no state change |
|
|
67
|
-
| **Monotonic input growth** | full history re-sent every step
|
|
67
|
+
| **Monotonic input growth** | full history re-sent every step; context never compressed |
|
|
68
68
|
| **Output-length decay** | planning/reasoning per step shrinking as context grows |
|
|
69
69
|
| **No self-verification** | state-mutating actions never followed by an eval/inspect/check |
|
|
70
|
-
| **Tool
|
|
70
|
+
| **Tool mix / retry / error rates** | repeated, retried, and failed tool calls |
|
|
71
71
|
|
|
72
72
|
`--llm` adds agentic analysts that read the conversation and cluster higher-order failure and improvement signals.
|
|
73
73
|
|
|
@@ -88,7 +88,7 @@ The deterministic pass (free, no key) surfaces:
|
|
|
88
88
|
| `github-copilot` (`copilot`) | `~/.copilot/session-state/<id>/events.jsonl` | fixture |
|
|
89
89
|
| `forge` (`forgecode`) | `/dump` JSON exports | fixture |
|
|
90
90
|
|
|
91
|
-
Every adapter captures the full conversation
|
|
91
|
+
Every adapter captures the full conversation: the **user's prompt** and the **assistant's response** text, plus tool calls/results and token usage. (`github-copilot` is the one exception: its log format carries no user prompt.) Factory stores token totals in `.settings.json`, not per turn. Forge reads `/dump` JSON exports (live SQLite is a follow-up). ACP-only bridges may not persist a local transcript.
|
|
92
92
|
|
|
93
93
|
## CLI reference
|
|
94
94
|
|
|
@@ -104,7 +104,8 @@ traces inspect session-index.json --out inspection-report.md
|
|
|
104
104
|
traces evidence --harness codex --last 20 --out policy-evidence.jsonl
|
|
105
105
|
traces export policy-evidence.jsonl --out spans.openinference.jsonl
|
|
106
106
|
traces watch --all # live observer; loops + semantic findings
|
|
107
|
-
traces stream --all --
|
|
107
|
+
traces stream --all --mode findings # low-volume semantic feed
|
|
108
|
+
traces stream --all --mode agent # findings + deterministic report events
|
|
108
109
|
traces stream spans.openinference.jsonl --format openinference --no-spans
|
|
109
110
|
traces upload --since 1h --dry-run # redact + dedup + preview, no network
|
|
110
111
|
traces upload --since 24h # upload last day to the Intelligence Platform
|
|
@@ -117,18 +118,19 @@ traces upload --since 24h # upload last day to the Inte
|
|
|
117
118
|
| `--last <n>` | Most-recent N sessions |
|
|
118
119
|
| `--session <path>` | One explicit session file |
|
|
119
120
|
| `--cwd <dir>` | Filter by working directory |
|
|
120
|
-
| `--since <t>` | `upload`: window
|
|
121
|
+
| `--since <t>` | `upload`: window, `30m`/`2h`/`7d` or ISO (default 24h); `analyze`: ISO cutoff |
|
|
121
122
|
| `--out <path>` | Write the report to a file |
|
|
122
123
|
| `--dir <path>` | `improve`: write the full artifact pack to this directory |
|
|
123
124
|
| `--otlp <path>` | OTLP artifact path (also evidence provenance / dry-run upload preview) |
|
|
124
125
|
| `--format <kind>` | `export` / file `stream`: `auto`, `policy-evidence`, `sandbox-events`, or `openinference` |
|
|
125
126
|
| `--llm` / `--budget <usd>` | Enable agentic analysts (needs `OPENAI_API_KEY`) / cap their spend |
|
|
126
|
-
| `--config <path>` | `investigate` / `improve`: load BYO analysts, external analyzers, and proposal adapters |
|
|
127
|
+
| `--config <path>` | `investigate` / `improve` / `stream`: load BYO analysts, live analysts, external analyzers, and proposal adapters |
|
|
127
128
|
| `--interval <s>` / `--window <m>` | `watch` / live `stream`: poll seconds (default 5) / active-session window minutes (default 30) |
|
|
128
129
|
| `--min-loop <n>` | Identical repeated calls before flagging a loop (default 3) |
|
|
130
|
+
| `--mode <kind>` | `stream`: `visualizer` (spans + findings), `findings` (low-volume), or `agent` (findings + reports) |
|
|
129
131
|
| `--replay` / `--once` | `stream`: scan once, then exit |
|
|
130
132
|
| `--no-spans` / `--no-findings` | `stream`: suppress raw span rows / finding rows |
|
|
131
|
-
| `--no-content` | `upload`: send metadata only
|
|
133
|
+
| `--no-content` | `upload`: send metadata only; strip all prompt/response text |
|
|
132
134
|
| `--dry-run` / `--yes` | `upload`: preview without sending / skip the confirm prompt |
|
|
133
135
|
|
|
134
136
|
## Live stream
|
|
@@ -141,13 +143,42 @@ It emits newline-delimited JSON events that a dashboard, art visualizer, local w
|
|
|
141
143
|
|
|
142
144
|
```bash
|
|
143
145
|
traces stream --all
|
|
144
|
-
traces stream --all --
|
|
146
|
+
traces stream --all --mode findings
|
|
147
|
+
traces stream --all --mode agent --config traces.config.mjs
|
|
145
148
|
traces stream spans.openinference.jsonl --format openinference --no-spans
|
|
146
149
|
```
|
|
147
150
|
|
|
148
|
-
|
|
151
|
+
Live streaming emits `session`, `span`, `analysis_batch`, `finding`, and `tick` events; `--mode agent` also emits `report` events.
|
|
149
152
|
The semantic findings currently cover repeated failing commands, verification churn without code/config changes, completion claims without later verification, and high tool-error rates.
|
|
150
|
-
Use `--
|
|
153
|
+
Use `--mode findings` when you want the low-volume meaning layer; keep `visualizer` for real-time views that need motion, timing, and tool-call texture.
|
|
154
|
+
Use `--mode agent` when another agent needs deterministic loop/tool-use reports alongside the findings.
|
|
155
|
+
|
|
156
|
+
Custom online analysts use the same config file as `investigate` and `improve`:
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
export default {
|
|
160
|
+
liveAnalysts: [{
|
|
161
|
+
id: 'my-live-rule',
|
|
162
|
+
analyze(context) {
|
|
163
|
+
return context.actions.some((action) => action.kind === 'claim') ? [{
|
|
164
|
+
schemaVersion: 1,
|
|
165
|
+
kind: 'traces.live_finding',
|
|
166
|
+
id: `live.my-live-rule.${context.session.sessionId}`,
|
|
167
|
+
ruleId: 'my-live-rule',
|
|
168
|
+
fingerprint: `my-live-rule.${context.session.sessionId}`,
|
|
169
|
+
severity: 'info',
|
|
170
|
+
title: 'Completion claim seen',
|
|
171
|
+
claim: 'A claim-like assistant message appeared in the live trace.',
|
|
172
|
+
action: 'Require the next stream batch to include a verification action.',
|
|
173
|
+
check: 'A later finding or batch should show a test/build/typecheck action.',
|
|
174
|
+
evidence: [{ kind: 'metric', label: 'actions', value: String(context.actions.length) }],
|
|
175
|
+
session: context.session,
|
|
176
|
+
observedAt: context.generatedAt,
|
|
177
|
+
}] : []
|
|
178
|
+
},
|
|
179
|
+
}],
|
|
180
|
+
}
|
|
181
|
+
```
|
|
151
182
|
|
|
152
183
|
## Improvement engine
|
|
153
184
|
|
|
@@ -177,6 +208,7 @@ traces improve --last 5 --config examples/improvement-config.mjs --dir .traces/i
|
|
|
177
208
|
The config can export:
|
|
178
209
|
|
|
179
210
|
- `analysts`: deterministic or LLM analysts that implement the `agent-eval` `Analyst` contract
|
|
211
|
+
- `liveAnalysts`: deterministic online analysts that implement the `TraceLiveAnalyst` contract for `traces stream`
|
|
180
212
|
- `registry`: a prebuilt `AnalystRegistry`
|
|
181
213
|
- `externalAnalyzers`: HALO or any command/model adapter that reads the OTLP artifact
|
|
182
214
|
- `improvementAdapter`: a proposal writer that maps recommendations to patches, profile edits, prompts, or validation commands
|
|
@@ -224,7 +256,7 @@ That boundary matters. `agent-lab` campaign `cells.jsonl` says "arm X beat arm Y
|
|
|
224
256
|
|
|
225
257
|
### Export existing evidence/events to OpenInference
|
|
226
258
|
|
|
227
|
-
If you already have compact evidence or
|
|
259
|
+
If you already have compact evidence or event captures on disk, convert them to the same OpenInference JSONL shape that `traces analyze --analyzer halo` uses:
|
|
228
260
|
|
|
229
261
|
```bash
|
|
230
262
|
traces export policy-evidence.jsonl --out spans.openinference.jsonl
|
|
@@ -235,7 +267,7 @@ halo spans.openinference.jsonl --prompt "Analyze this trace slice" --max-turns 1
|
|
|
235
267
|
`traces export` accepts:
|
|
236
268
|
|
|
237
269
|
- compact `traces.policy_evidence.session` JSONL from `traces evidence`
|
|
238
|
-
-
|
|
270
|
+
- JSON arrays with `start`, `raw`, `result`, `done`, and `error` events
|
|
239
271
|
- existing OpenInference JSONL, rewritten through the local redaction path
|
|
240
272
|
|
|
241
273
|
Run `traces export --help` for the full command reference.
|
|
@@ -245,28 +277,28 @@ Run `traces export --help` for the full command reference.
|
|
|
245
277
|
`upload` **redacts locally before anything leaves the machine**, dedups against already-uploaded sessions, and tags each with metadata (harness, cwd, git branch, host).
|
|
246
278
|
|
|
247
279
|
```bash
|
|
248
|
-
traces upload --since 24h --dry-run # see exactly what would be sent
|
|
249
|
-
traces upload --since 24h --no-content # send metadata only
|
|
280
|
+
traces upload --since 24h --dry-run # see exactly what would be sent; no network
|
|
281
|
+
traces upload --since 24h --no-content # send metadata only; drop all prompt/response text
|
|
250
282
|
traces upload --since 24h # send it
|
|
251
283
|
```
|
|
252
284
|
|
|
253
285
|
It needs `TANGLE_INGEST_URL` (or `TANGLE_ORCHESTRATOR_URL`), `TANGLE_INGEST_API_KEY` (or `TANGLE_API_KEY`), and `TANGLE_TENANT_ID`. Without them, `--dry-run` still works fully.
|
|
254
286
|
|
|
255
|
-
### Redaction scope
|
|
287
|
+
### Redaction scope: read this before uploading prose
|
|
256
288
|
|
|
257
289
|
Redaction is **best-effort regex** for *structured* secrets and credentials: API keys, GitHub/cloud tokens, JWTs, bearer headers, private-key blocks, `KEY=secret` assignments, and credentials embedded in URLs. It runs over every span attribute, including the captured prompt/response text.
|
|
258
290
|
|
|
259
|
-
It does **not** catch free-form PII
|
|
291
|
+
It does **not** catch free-form PII such as names, postal addresses, or phone numbers in prose. Those need a context-aware model. Three postures, strongest first:
|
|
260
292
|
|
|
261
|
-
1. **`--no-content
|
|
293
|
+
1. **`--no-content`**: upload metadata only (tool calls, tokens, timing, loop signal); no prose leaves the machine.
|
|
262
294
|
2. Run an ML PII scrubber (e.g. [`openai/privacy-filter`](https://github.com/openai/privacy-filter)) on the platform ingest side as defense-in-depth.
|
|
263
|
-
3. Default
|
|
295
|
+
3. Default: regex redaction of structured secrets.
|
|
264
296
|
|
|
265
297
|
Always `--dry-run` first to see exactly what would be sent.
|
|
266
298
|
|
|
267
299
|
## External engines (bring your own)
|
|
268
300
|
|
|
269
|
-
`traces` hosts analysis engines and PII scrubbers it does **not** bundle
|
|
301
|
+
`traces` hosts analysis engines and PII scrubbers it does **not** bundle. You install the tool; `traces` drives it over a thin command adapter. Same pattern for any future engine or model.
|
|
270
302
|
|
|
271
303
|
**Analyzers** run over the emitted OTLP artifact as peers to the built-in analysts:
|
|
272
304
|
|
|
@@ -276,7 +308,7 @@ traces analyze --last 1 --analyzer halo --analyzer-prompt "find token waste"
|
|
|
276
308
|
traces analyze --last 1 --analyzer halo --analyzer my-engine # repeatable
|
|
277
309
|
```
|
|
278
310
|
|
|
279
|
-
Our OTLP artifact is **canonical OpenInference** (top-level `kind`, `resource`, `scope`), so HALO reads it directly
|
|
311
|
+
Our OTLP artifact is **canonical OpenInference** (top-level `kind`, `resource`, `scope`), so HALO reads it directly with no conversion. HALO runs its *own* LLM. Set `OPENAI_BASE_URL` / `OPENAI_API_KEY`, or use HALO's provider; `--model` is forwarded to it. `traces` supplies the trace and drives the CLI; it does not pay for or configure HALO's model.
|
|
280
312
|
|
|
281
313
|
**Redactors** scrub prompt/response prose with an external PII model (catching names/addresses the regex pass can't), running *after* the built-in redaction:
|
|
282
314
|
|
|
@@ -287,7 +319,7 @@ traces upload --since 24h --dry-run --redactor "my-pii-scrubber"
|
|
|
287
319
|
|
|
288
320
|
In the SDK these are the `ExternalAnalyzer` and `Redactor` interfaces (`haloAnalyzer`, `commandAnalyzer`, `commandRedactor`, `applyRedactor`, `runExternalAnalyzers`). See [`examples/external-engines.ts`](./examples/external-engines.ts).
|
|
289
321
|
|
|
290
|
-
> For the built-in agentic analysts (`--llm`), set `OPENAI_API_KEY
|
|
322
|
+
> For the built-in agentic analysts (`--llm`), set `OPENAI_API_KEY`, or point at any OpenAI-compatible gateway with `OPENAI_BASE_URL` (e.g. an internal router) to use a non-OpenAI key.
|
|
291
323
|
|
|
292
324
|
## Release automation
|
|
293
325
|
|
|
@@ -307,7 +339,7 @@ The CLI is a thin consumer of these exports.
|
|
|
307
339
|
|
|
308
340
|
| Export | Signature | Use |
|
|
309
341
|
|---|---|---|
|
|
310
|
-
| `analyzeSpans` | `(spans, { registry?, ai?, budgetUsd? }) → AnalyzeResult` | run
|
|
342
|
+
| `analyzeSpans` | `(spans, { registry?, ai?, budgetUsd? }) → AnalyzeResult` | run built-in analysts, or **your own** via `registry` |
|
|
311
343
|
| `runTraceInvestigation` | `(TraceInvestigationOptions) → TraceInvestigationResult` | typed findings, recommendations, claims, external analyzer output, and report |
|
|
312
344
|
| `runTraceImprovementLoop` | `(TraceImprovementOptions) → TraceImprovementResult` | writes the full improvement artifact pack and optional proposal output |
|
|
313
345
|
| `buildTraceFindingPacket` | `({ findings }) → TraceFindingPacket` | turn any `AnalystFinding[]` into recommendations, claims, and a report |
|
|
@@ -317,6 +349,8 @@ The CLI is a thin consumer of these exports.
|
|
|
317
349
|
| `streamSessions` | `(TraceStreamOptions) → Promise<void>` | live JSONL-ready event stream over active sessions |
|
|
318
350
|
| `traceStreamEventsFromSpans` | `(spans, opts?) → TraceStreamEvent[]` | replay an existing span list as stream events |
|
|
319
351
|
| `analyzeLiveBatch` | `(spans, opts?) → TraceLiveBatch` | compute semantic online findings for one batch |
|
|
352
|
+
| `classifyLiveActions` | `(spans) → TraceLiveAction[]` | classify spans once as read/edit/verify/claim/tool/other |
|
|
353
|
+
| `defaultTraceLiveAnalysts` | `TraceLiveAnalyst[]` | the built-in online analysts; extend or replace them |
|
|
320
354
|
| `collectSessionIndex` | `(ScanOptions) → TraceSessionIndex` | scan sessions and return a reusable JSON-ready catalog |
|
|
321
355
|
| `inspectSessionIndex` | `(TraceSessionIndex) → TraceInspectionReport` | rank improvement findings from an index without rescanning sessions |
|
|
322
356
|
| `buildPolicyEvidenceRecord` | `(ref, spans, opts?) → PolicyEvidenceRecord` | summarize one session for downstream policy mining |
|
|
@@ -359,7 +393,7 @@ Runnable, in [`examples/`](./examples):
|
|
|
359
393
|
|---|---|
|
|
360
394
|
| [`observe-and-alert.ts`](./examples/observe-and-alert.ts) | tail live sessions and alert on stuck loops |
|
|
361
395
|
| [`custom-analyst.ts`](./examples/custom-analyst.ts) | register and run your own analyst |
|
|
362
|
-
| [`improvement-config.mjs`](./examples/improvement-config.mjs) | plug in BYO analysts
|
|
396
|
+
| [`improvement-config.mjs`](./examples/improvement-config.mjs) | plug in BYO analysts for `traces stream` / `traces improve` |
|
|
363
397
|
| [`custom-backend.ts`](./examples/custom-backend.ts) | redact + dedup + upload to your own sink |
|
|
364
398
|
| [`register-harness.ts`](./examples/register-harness.ts) | add a new harness by implementing `HarnessTraceAdapter` |
|
|
365
399
|
| [`external-engines.ts`](./examples/external-engines.ts) | drive HALO + an external PII scrubber you install yourself |
|
|
@@ -371,5 +405,5 @@ pnpm install
|
|
|
371
405
|
pnpm dev analyze --harness claude-code --last 1 # run from source via tsx
|
|
372
406
|
pnpm test
|
|
373
407
|
pnpm typecheck
|
|
374
|
-
pnpm build #
|
|
408
|
+
pnpm build # dist/index.js (SDK) + dist/cli.js (bin) + .d.ts
|
|
375
409
|
```
|