@tangle-network/traces 0.8.19 → 0.8.21
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 +55 -25
- package/dist/cli.js +14 -14
- package/docs/stream-findings.svg +39 -0
- package/package.json +2 -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
|
|
|
@@ -118,7 +118,7 @@ traces upload --since 24h # upload last day to the Inte
|
|
|
118
118
|
| `--last <n>` | Most-recent N sessions |
|
|
119
119
|
| `--session <path>` | One explicit session file |
|
|
120
120
|
| `--cwd <dir>` | Filter by working directory |
|
|
121
|
-
| `--since <t>` | `upload`: window
|
|
121
|
+
| `--since <t>` | `upload`: window, `30m`/`2h`/`7d` or ISO (default 24h); `analyze`: ISO cutoff |
|
|
122
122
|
| `--out <path>` | Write the report to a file |
|
|
123
123
|
| `--dir <path>` | `improve`: write the full artifact pack to this directory |
|
|
124
124
|
| `--otlp <path>` | OTLP artifact path (also evidence provenance / dry-run upload preview) |
|
|
@@ -130,7 +130,7 @@ traces upload --since 24h # upload last day to the Inte
|
|
|
130
130
|
| `--mode <kind>` | `stream`: `visualizer` (spans + findings), `findings` (low-volume), or `agent` (findings + reports) |
|
|
131
131
|
| `--replay` / `--once` | `stream`: scan once, then exit |
|
|
132
132
|
| `--no-spans` / `--no-findings` | `stream`: suppress raw span rows / finding rows |
|
|
133
|
-
| `--no-content` | `upload`: send metadata only
|
|
133
|
+
| `--no-content` | `upload`: send metadata only; strip all prompt/response text |
|
|
134
134
|
| `--dry-run` / `--yes` | `upload`: preview without sending / skip the confirm prompt |
|
|
135
135
|
|
|
136
136
|
## Live stream
|
|
@@ -152,6 +152,36 @@ Live streaming emits `session`, `span`, `analysis_batch`, `finding`, and `tick`
|
|
|
152
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.
|
|
153
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
154
|
Use `--mode agent` when another agent needs deterministic loop/tool-use reports alongside the findings.
|
|
155
|
+
The same JSONL shape is used for live sessions and replayed trace files:
|
|
156
|
+
|
|
157
|
+

|
|
158
|
+
|
|
159
|
+
Custom online analysts use the same config file as `investigate` and `improve`:
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
export default {
|
|
163
|
+
liveAnalysts: [{
|
|
164
|
+
id: 'my-live-rule',
|
|
165
|
+
analyze(context) {
|
|
166
|
+
return context.actions.some((action) => action.kind === 'claim') ? [{
|
|
167
|
+
schemaVersion: 1,
|
|
168
|
+
kind: 'traces.live_finding',
|
|
169
|
+
id: `live.my-live-rule.${context.session.sessionId}`,
|
|
170
|
+
ruleId: 'my-live-rule',
|
|
171
|
+
fingerprint: `my-live-rule.${context.session.sessionId}`,
|
|
172
|
+
severity: 'info',
|
|
173
|
+
title: 'Completion claim seen',
|
|
174
|
+
claim: 'A claim-like assistant message appeared in the live trace.',
|
|
175
|
+
action: 'Require the next stream batch to include a verification action.',
|
|
176
|
+
check: 'A later finding or batch should show a test/build/typecheck action.',
|
|
177
|
+
evidence: [{ kind: 'metric', label: 'actions', value: String(context.actions.length) }],
|
|
178
|
+
session: context.session,
|
|
179
|
+
observedAt: context.generatedAt,
|
|
180
|
+
}] : []
|
|
181
|
+
},
|
|
182
|
+
}],
|
|
183
|
+
}
|
|
184
|
+
```
|
|
155
185
|
|
|
156
186
|
## Improvement engine
|
|
157
187
|
|
|
@@ -229,7 +259,7 @@ That boundary matters. `agent-lab` campaign `cells.jsonl` says "arm X beat arm Y
|
|
|
229
259
|
|
|
230
260
|
### Export existing evidence/events to OpenInference
|
|
231
261
|
|
|
232
|
-
If you already have compact evidence or
|
|
262
|
+
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:
|
|
233
263
|
|
|
234
264
|
```bash
|
|
235
265
|
traces export policy-evidence.jsonl --out spans.openinference.jsonl
|
|
@@ -240,7 +270,7 @@ halo spans.openinference.jsonl --prompt "Analyze this trace slice" --max-turns 1
|
|
|
240
270
|
`traces export` accepts:
|
|
241
271
|
|
|
242
272
|
- compact `traces.policy_evidence.session` JSONL from `traces evidence`
|
|
243
|
-
-
|
|
273
|
+
- JSON arrays with `start`, `raw`, `result`, `done`, and `error` events
|
|
244
274
|
- existing OpenInference JSONL, rewritten through the local redaction path
|
|
245
275
|
|
|
246
276
|
Run `traces export --help` for the full command reference.
|
|
@@ -250,28 +280,28 @@ Run `traces export --help` for the full command reference.
|
|
|
250
280
|
`upload` **redacts locally before anything leaves the machine**, dedups against already-uploaded sessions, and tags each with metadata (harness, cwd, git branch, host).
|
|
251
281
|
|
|
252
282
|
```bash
|
|
253
|
-
traces upload --since 24h --dry-run # see exactly what would be sent
|
|
254
|
-
traces upload --since 24h --no-content # send metadata only
|
|
283
|
+
traces upload --since 24h --dry-run # see exactly what would be sent; no network
|
|
284
|
+
traces upload --since 24h --no-content # send metadata only; drop all prompt/response text
|
|
255
285
|
traces upload --since 24h # send it
|
|
256
286
|
```
|
|
257
287
|
|
|
258
288
|
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.
|
|
259
289
|
|
|
260
|
-
### Redaction scope
|
|
290
|
+
### Redaction scope: read this before uploading prose
|
|
261
291
|
|
|
262
292
|
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.
|
|
263
293
|
|
|
264
|
-
It does **not** catch free-form PII
|
|
294
|
+
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:
|
|
265
295
|
|
|
266
|
-
1. **`--no-content
|
|
296
|
+
1. **`--no-content`**: upload metadata only (tool calls, tokens, timing, loop signal); no prose leaves the machine.
|
|
267
297
|
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.
|
|
268
|
-
3. Default
|
|
298
|
+
3. Default: regex redaction of structured secrets.
|
|
269
299
|
|
|
270
300
|
Always `--dry-run` first to see exactly what would be sent.
|
|
271
301
|
|
|
272
302
|
## External engines (bring your own)
|
|
273
303
|
|
|
274
|
-
`traces` hosts analysis engines and PII scrubbers it does **not** bundle
|
|
304
|
+
`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.
|
|
275
305
|
|
|
276
306
|
**Analyzers** run over the emitted OTLP artifact as peers to the built-in analysts:
|
|
277
307
|
|
|
@@ -281,7 +311,7 @@ traces analyze --last 1 --analyzer halo --analyzer-prompt "find token waste"
|
|
|
281
311
|
traces analyze --last 1 --analyzer halo --analyzer my-engine # repeatable
|
|
282
312
|
```
|
|
283
313
|
|
|
284
|
-
Our OTLP artifact is **canonical OpenInference** (top-level `kind`, `resource`, `scope`), so HALO reads it directly
|
|
314
|
+
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.
|
|
285
315
|
|
|
286
316
|
**Redactors** scrub prompt/response prose with an external PII model (catching names/addresses the regex pass can't), running *after* the built-in redaction:
|
|
287
317
|
|
|
@@ -292,7 +322,7 @@ traces upload --since 24h --dry-run --redactor "my-pii-scrubber"
|
|
|
292
322
|
|
|
293
323
|
In the SDK these are the `ExternalAnalyzer` and `Redactor` interfaces (`haloAnalyzer`, `commandAnalyzer`, `commandRedactor`, `applyRedactor`, `runExternalAnalyzers`). See [`examples/external-engines.ts`](./examples/external-engines.ts).
|
|
294
324
|
|
|
295
|
-
> For the built-in agentic analysts (`--llm`), set `OPENAI_API_KEY
|
|
325
|
+
> 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.
|
|
296
326
|
|
|
297
327
|
## Release automation
|
|
298
328
|
|
|
@@ -312,7 +342,7 @@ The CLI is a thin consumer of these exports.
|
|
|
312
342
|
|
|
313
343
|
| Export | Signature | Use |
|
|
314
344
|
|---|---|---|
|
|
315
|
-
| `analyzeSpans` | `(spans, { registry?, ai?, budgetUsd? }) → AnalyzeResult` | run
|
|
345
|
+
| `analyzeSpans` | `(spans, { registry?, ai?, budgetUsd? }) → AnalyzeResult` | run built-in analysts, or **your own** via `registry` |
|
|
316
346
|
| `runTraceInvestigation` | `(TraceInvestigationOptions) → TraceInvestigationResult` | typed findings, recommendations, claims, external analyzer output, and report |
|
|
317
347
|
| `runTraceImprovementLoop` | `(TraceImprovementOptions) → TraceImprovementResult` | writes the full improvement artifact pack and optional proposal output |
|
|
318
348
|
| `buildTraceFindingPacket` | `({ findings }) → TraceFindingPacket` | turn any `AnalystFinding[]` into recommendations, claims, and a report |
|
|
@@ -366,7 +396,7 @@ Runnable, in [`examples/`](./examples):
|
|
|
366
396
|
|---|---|
|
|
367
397
|
| [`observe-and-alert.ts`](./examples/observe-and-alert.ts) | tail live sessions and alert on stuck loops |
|
|
368
398
|
| [`custom-analyst.ts`](./examples/custom-analyst.ts) | register and run your own analyst |
|
|
369
|
-
| [`improvement-config.mjs`](./examples/improvement-config.mjs) | plug in BYO analysts
|
|
399
|
+
| [`improvement-config.mjs`](./examples/improvement-config.mjs) | plug in BYO analysts for `traces stream` / `traces improve` |
|
|
370
400
|
| [`custom-backend.ts`](./examples/custom-backend.ts) | redact + dedup + upload to your own sink |
|
|
371
401
|
| [`register-harness.ts`](./examples/register-harness.ts) | add a new harness by implementing `HarnessTraceAdapter` |
|
|
372
402
|
| [`external-engines.ts`](./examples/external-engines.ts) | drive HALO + an external PII scrubber you install yourself |
|
|
@@ -378,5 +408,5 @@ pnpm install
|
|
|
378
408
|
pnpm dev analyze --harness claude-code --last 1 # run from source via tsx
|
|
379
409
|
pnpm test
|
|
380
410
|
pnpm typecheck
|
|
381
|
-
pnpm build #
|
|
411
|
+
pnpm build # dist/index.js (SDK) + dist/cli.js (bin) + .d.ts
|
|
382
412
|
```
|
package/dist/cli.js
CHANGED
|
@@ -215,7 +215,7 @@ async function buildAxService() {
|
|
|
215
215
|
const apiKey = process.env.OPENAI_API_KEY;
|
|
216
216
|
if (!apiKey) {
|
|
217
217
|
throw new Error(
|
|
218
|
-
"--llm needs OPENAI_API_KEY
|
|
218
|
+
"--llm needs OPENAI_API_KEY: an OpenAI key, or a router/gateway key with OPENAI_BASE_URL set to an OpenAI-compatible endpoint (e.g. the Tangle router). Deterministic analysis needs no key."
|
|
219
219
|
);
|
|
220
220
|
}
|
|
221
221
|
const apiURL = process.env.OPENAI_BASE_URL || void 0;
|
|
@@ -226,7 +226,7 @@ async function cmdList(args) {
|
|
|
226
226
|
const groups = await discover({ ...args, last: args.last || 20 });
|
|
227
227
|
for (const { adapter, refs } of groups) {
|
|
228
228
|
console.log(`
|
|
229
|
-
${adapter.harness}
|
|
229
|
+
${adapter.harness}: ${refs.length} session(s)`);
|
|
230
230
|
for (const r of refs) {
|
|
231
231
|
console.log(` ${new Date(r.mtimeMs).toISOString()} ${r.sessionId} ${r.cwd ?? ""}`);
|
|
232
232
|
}
|
|
@@ -516,7 +516,7 @@ function formatLiveFinding(finding) {
|
|
|
516
516
|
const where = `[${finding.session.harness}] ${finding.session.sessionId.slice(0, 8)}`;
|
|
517
517
|
const cwd = finding.session.cwd ? ` \xB7 ${finding.session.cwd}` : "";
|
|
518
518
|
return [
|
|
519
|
-
`${ts} ${finding.severity.toUpperCase()} ${where}
|
|
519
|
+
`${ts} ${finding.severity.toUpperCase()} ${where}: ${finding.title}${cwd}`,
|
|
520
520
|
` evidence: ${summarizeFindingEvidence(finding)}`,
|
|
521
521
|
` action: ${finding.action}`,
|
|
522
522
|
` check: ${finding.check}`
|
|
@@ -591,7 +591,7 @@ async function cmdStream(args) {
|
|
|
591
591
|
process.once("SIGINT", () => controller.abort());
|
|
592
592
|
if (!args.replay) {
|
|
593
593
|
process.stderr.write(
|
|
594
|
-
`traces stream
|
|
594
|
+
`traces stream: ${preset.mode} JSONL feed for ${all ? "all harnesses" : args.harness}, last ${args.window}m, every ${args.interval}s. Ctrl-C to stop.
|
|
595
595
|
`
|
|
596
596
|
);
|
|
597
597
|
}
|
|
@@ -624,7 +624,7 @@ async function cmdWatch(args) {
|
|
|
624
624
|
const controller = new AbortController();
|
|
625
625
|
process.once("SIGINT", () => controller.abort());
|
|
626
626
|
process.stderr.write(
|
|
627
|
-
`traces watch
|
|
627
|
+
`traces watch: observing ${all ? "all harnesses" : args.harness}, sessions active in the last ${args.window}m, every ${args.interval}s. Loop + semantic live findings; read-only; Ctrl-C to stop.
|
|
628
628
|
`
|
|
629
629
|
);
|
|
630
630
|
await watchSessions({
|
|
@@ -638,7 +638,7 @@ async function cmdWatch(args) {
|
|
|
638
638
|
onLoop: (l) => {
|
|
639
639
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
640
640
|
process.stdout.write(
|
|
641
|
-
`${ts} LOOP [${l.harness}] ${l.sessionId.slice(0, 8)}
|
|
641
|
+
`${ts} LOOP [${l.harness}] ${l.sessionId.slice(0, 8)}: \`${l.toolName}\` repeated \xD7${l.occurrences} with identical args (${(l.windowMs / 1e3).toFixed(0)}s)${l.cwd ? ` \xB7 ${l.cwd}` : ""}
|
|
642
642
|
`
|
|
643
643
|
);
|
|
644
644
|
},
|
|
@@ -686,7 +686,7 @@ Window: since ${new Date(sinceMs).toISOString()}
|
|
|
686
686
|
}
|
|
687
687
|
if (args.dryRun) {
|
|
688
688
|
const res2 = await executeUpload(plan, { dryRun: true, otlpOut: args.otlp, stripContent: args.noContent, redactor });
|
|
689
|
-
console.log(`dry run
|
|
689
|
+
console.log(`dry run: ${newItems.length} session(s), ${totalRedactions} redaction(s). Redacted OTLP -> ${res2.otlpPath}`);
|
|
690
690
|
console.log("No upload performed. Set TANGLE_INGEST_URL / TANGLE_INGEST_API_KEY / TANGLE_TENANT_ID and drop --dry-run to send.");
|
|
691
691
|
return;
|
|
692
692
|
}
|
|
@@ -704,7 +704,7 @@ Window: since ${new Date(sinceMs).toISOString()}
|
|
|
704
704
|
);
|
|
705
705
|
}
|
|
706
706
|
function usageExport() {
|
|
707
|
-
console.log(`traces export
|
|
707
|
+
console.log(`traces export: convert trace evidence files to OpenInference JSONL
|
|
708
708
|
|
|
709
709
|
Usage:
|
|
710
710
|
traces export <input.jsonl|input.json> --out <spans.jsonl> [--format auto]
|
|
@@ -714,7 +714,7 @@ Usage:
|
|
|
714
714
|
|
|
715
715
|
Input formats:
|
|
716
716
|
policy-evidence Compact JSONL rows from \`traces evidence --out policy-evidence.jsonl\`
|
|
717
|
-
sandbox-events
|
|
717
|
+
sandbox-events JSON arrays with start/raw/result/done/error events
|
|
718
718
|
openinference Existing OpenInference JSONL; rewrites through traces redaction
|
|
719
719
|
intelligence-spans JSONL rows exported from Tangle Intelligence trace spans
|
|
720
720
|
auto Detect the format from the file contents (default)
|
|
@@ -732,7 +732,7 @@ Safety:
|
|
|
732
732
|
--metadata must be a JSON object; --attr key=value is repeatable and overrides matching metadata keys.`);
|
|
733
733
|
}
|
|
734
734
|
function usage() {
|
|
735
|
-
console.log(`traces
|
|
735
|
+
console.log(`traces: analyze, observe & upload coding-agent sessions
|
|
736
736
|
|
|
737
737
|
Commands:
|
|
738
738
|
list List discovered sessions
|
|
@@ -754,7 +754,7 @@ Options:
|
|
|
754
754
|
--last <n> Most-recent N sessions
|
|
755
755
|
--session <path> Analyze/stream one explicit harness session file
|
|
756
756
|
--cwd <dir> Filter sessions by working directory
|
|
757
|
-
--since <t> upload: window
|
|
757
|
+
--since <t> upload: window, 30m / 2h / 7d or an ISO date (default 24h); analyze: ISO cutoff
|
|
758
758
|
--out <path> Write report to a file
|
|
759
759
|
--dir <path> improve: write artifacts to this directory
|
|
760
760
|
--otlp <path> OTLP artifact path (also evidence provenance / dry-run upload preview)
|
|
@@ -771,11 +771,11 @@ Options:
|
|
|
771
771
|
--budget <usd> USD cap for agentic analysts
|
|
772
772
|
--analyzer <cmd> analyze: also run an external engine over the OTLP (repeatable; "halo" or any command)
|
|
773
773
|
--analyzer-prompt <p> analyze: prompt passed to external analyzers (default: diagnose)
|
|
774
|
-
--interval <s> watch: poll interval seconds (default 5)
|
|
775
|
-
--window <m> watch: only sessions active in the last N minutes (default 30)
|
|
774
|
+
--interval <s> watch/stream: poll interval seconds (default 5)
|
|
775
|
+
--window <m> watch/stream: only sessions active in the last N minutes (default 30)
|
|
776
776
|
--min-loop <n> Min identical repeated calls to flag a loop (default 3)
|
|
777
777
|
--dry-run upload: redact + dedup + preview, write OTLP, but do NOT send
|
|
778
|
-
--no-content upload: strip prompt/response text
|
|
778
|
+
--no-content upload: strip prompt/response text; send metadata only
|
|
779
779
|
--redactor <cmd> upload: external PII scrubber (JSON array stdin\u2192stdout) after the regex pass
|
|
780
780
|
--yes, -y upload: skip the confirmation prompt
|
|
781
781
|
--version, -v Print the installed traces version
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 1100 540">
|
|
2
|
+
<title>traces stream findings mode terminal capture</title>
|
|
3
|
+
<desc>A terminal preview of traces stream findings mode showing session, batch, and finding JSONL rows.</desc>
|
|
4
|
+
<rect width="1100" height="540" fill="#f6f7f9"/>
|
|
5
|
+
<rect x="50" y="44" width="1000" height="452" rx="8" fill="#111827"/>
|
|
6
|
+
<rect x="50" y="44" width="1000" height="42" rx="8" fill="#202938"/>
|
|
7
|
+
<circle cx="78" cy="65" r="7" fill="#ff5f57"/>
|
|
8
|
+
<circle cx="100" cy="65" r="7" fill="#febc2e"/>
|
|
9
|
+
<circle cx="122" cy="65" r="7" fill="#28c840"/>
|
|
10
|
+
<text x="550" y="70" text-anchor="middle" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="14" fill="#cbd5e1">traces stream --mode findings</text>
|
|
11
|
+
|
|
12
|
+
<text x="78" y="124" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="18" fill="#8bd5ff">$ traces stream spans.openinference.jsonl --format openinference --mode findings</text>
|
|
13
|
+
|
|
14
|
+
<g font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="16">
|
|
15
|
+
<text x="78" y="174" fill="#e5e7eb">{"event":"session",</text>
|
|
16
|
+
<text x="313" y="174" fill="#a7f3d0">"spanCount":5,</text>
|
|
17
|
+
<text x="458" y="174" fill="#e5e7eb">"sessionId":"spans.openinference.jsonl"}</text>
|
|
18
|
+
|
|
19
|
+
<text x="78" y="224" fill="#e5e7eb">{"event":"analysis_batch",</text>
|
|
20
|
+
<text x="352" y="224" fill="#a7f3d0">"findingCount":3,</text>
|
|
21
|
+
<text x="536" y="224" fill="#fcd34d">"toolCallCount":3,</text>
|
|
22
|
+
<text x="732" y="224" fill="#fca5a5">"erroredToolCallCount":3}</text>
|
|
23
|
+
|
|
24
|
+
<text x="78" y="274" fill="#e5e7eb">{"event":"finding", "finding":{</text>
|
|
25
|
+
<text x="407" y="274" fill="#fca5a5">"severity":"high",</text>
|
|
26
|
+
<text x="608" y="274" fill="#c4b5fd">"ruleId":"same-failing-command"}}</text>
|
|
27
|
+
<text x="102" y="304" fill="#94a3b8">action: Stop rerunning it; inspect the first failure before another retry.</text>
|
|
28
|
+
|
|
29
|
+
<text x="78" y="354" fill="#e5e7eb">{"event":"finding", "finding":{</text>
|
|
30
|
+
<text x="407" y="354" fill="#fca5a5">"severity":"high",</text>
|
|
31
|
+
<text x="608" y="354" fill="#c4b5fd">"ruleId":"verification-without-change"}}</text>
|
|
32
|
+
<text x="102" y="384" fill="#94a3b8">evidence: 3 verification calls since the last detected code/config change.</text>
|
|
33
|
+
|
|
34
|
+
<text x="78" y="434" fill="#e5e7eb">{"event":"finding", "finding":{</text>
|
|
35
|
+
<text x="407" y="434" fill="#fcd34d">"severity":"medium",</text>
|
|
36
|
+
<text x="627" y="434" fill="#c4b5fd">"ruleId":"completion-claim-without-verification"}}</text>
|
|
37
|
+
<text x="102" y="464" fill="#94a3b8">check: a later test/build/typecheck/lint/smoke command should appear.</text>
|
|
38
|
+
</g>
|
|
39
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/traces",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.21",
|
|
4
4
|
"description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
39
|
+
"docs/stream-findings.svg",
|
|
39
40
|
"install.sh",
|
|
40
41
|
"README.md"
|
|
41
42
|
],
|