Skip to content

[M5b] Agent Forge: persisted trace history in the Trace tab - #301

Merged
LinuxDevil merged 4 commits into
mainfrom
lou-m5b-forge-trace-history
Oct 2, 2026
Merged

LinuxDevil merged 4 commits into
mainfrom
lou-m5b-forge-trace-history

Conversation

@LinuxDevil

Copy link
Copy Markdown
Owner

What

Agent Forge keeps the trace of every run and the Trace tab can reopen any of them. Closes #227.

  • Server: RunManager.makeTraceExporter() now fans out to the WebSocket exporter and to M5a's fileTraceExporter({ dir: <baseDir>/.lousho/agents/<agentId>/traces }). Both AgentExecutor.execute call sites share that one helper. New server/traceStore.ts (directory, fan-out exporter, list/read through listTraces / readTrace from @lousho/build-ai-agent/traces).
  • Routes: GET /agents/:id/traces?limit=N (summaries, newest first, default 20, max 200, no file paths) and GET /agents/:id/traces/:traceId (spans). 404 for an unknown agent or trace, 400 for an invalid id (and for an id prefix that matches several runs).
  • Wire: emitSpan forwards kind and status; SpanEvent gains both (optional), plus TraceSummaryPayload / TraceDetailPayload.
  • Client: the Trace tab has a left list (time, duration, model calls, tokens in/out, cost, status; a column layout at narrow widths) with a "Live" entry on top while a run is active. Choosing a past trace loads its spans into the existing waterfall via orderSpansForWaterfall; spans show their kind and failed spans use the existing --danger colour. The list reloads when the agent changes and when a run ends. The canvas node mapping is unchanged.
  • Docs/CHANGELOG: paragraph "Trace history" in the Agent Forge walkthrough (what the tab shows, where the files are, that they hold prompt and tool content), two rows in the ### Routes table, CHANGELOG entry. No heading changes. llms*.txt regenerated.

Security

Trace files hold prompt and tool content by default. The server only reads under <baseDir>/.lousho/agents/<agentId>/traces: the agent id passes the existing isValidAgentId guard, the trace id must match [A-Za-z0-9-]{1,128} and is only matched against file names found in that folder (never joined into a path), and the absolute file path is stripped from the response.

Verification

Run on the branch after merging the latest origin/main:

  • npx tsc --noEmit, npm run lint (zero warnings), npm run build, npm run build --workspace=packages/create-lousho-agent, npm run test:types (64 passed), npm run docs:verify-snippets -- --skip-build (210 type-check, 8 run), npm run docs:llms:check: all pass.
  • npm run test:coverage: first run had one failure, src/tools/built-in/http.test.ts ("rejects near the configured timeout", 4.7 s against a 2 s bound) under machine load; it passes alone (23/23). The coverage run on the merged tree (--coverage.reportOnFailure config): 230 files passed, 3288 tests passed, 6 skipped.
  • npm run fallow: exit 0. It first flagged my SpanRow (cyclomatic 12, CRAP 43); split into helpers, now 0 above threshold.
  • Agent Forge: typecheck clean, typecheck:server clean, npm run test -- --run 119 passed (14 files), npm run test:server 130 passed (15 files).
  • npm run test:e2e:studio not run: the specs in apps/agent-forge/e2e do not touch the Trace tab (the ticket asks for it only if they do). pack-smoke not run: no change to exports, bin, package.json or the build.

New tests: server/__tests__/traces.test.ts (a run through RunManager writes a file under the agent folder; list; detail with kind; error status; path-like ids are 400; unknown agent/trace 404; ambiguous prefix 400), runRegistry.test.ts (span messages carry kind, and no status on a successful run), src/components/debug/__tests__/TraceHistory.test.tsx (list rendering, Live entry only while active, selecting a trace renders its spans with kind and error colour, list reloads when a run ends, error note). Note: the SDK sets a span status only on failure, so a successful run's messages have kind but no status.

Studio check (real build, offline)

npm run build:studio, then three traces produced with createAgent + mockModel + fileTraceExporter into <scratch>/.lousho/agents/demo/traces, and node bin/lousho.js studio --port 47931 started from <scratch>:

  • GET /agents/demo/traces -> 200, three summaries newest first (e.g. {"traceId":"c344fc16-...","name":"invoke_agent demo","status":"ok","modelCalls":2,"toolCalls":1,"inputTokens":82,"outputTokens":8}), no file field; ?limit=1 -> one.
  • GET /agents/demo/traces/<id> -> 200, spans with kind (client for chat, internal for the rest) and status {code:"error",...} on the failing execute_tool; a unique prefix also resolves.
  • Unknown trace -> 404 No trace 'deadbeef' for agent 'demo'; unknown agent -> 404; ..%2F..%2F..%2Fdemo.yaml, ..%5C..%5Cx, %2e%2e as trace ids -> 400 Invalid trace id; ..%2Fdemo and /agents/../traces as agent -> 400 Invalid agent id.
  • In the browser (studio, mock provider): pressed Run on untitled-agent; the Trace tab list gained a row (ok, 19ms · 1 model · 10/6 tokens) when the run stopped and the waterfall showed invoke_agent (internal) and chat (client). After a full page reload the waterfall was empty, the list still held the run, and choosing it brought the spans back. With a trace containing a failed tool call copied into the agent's folder, the execute_tool boom row read error, got the trace-row-error class and its bar was rgb(217, 45, 32) (--danger). Screenshots timed out in this environment, so this was checked through the DOM, not by eye.

Docs site follow-up

No new page and no heading changes. Edited only: docs/agent-forge.md (new "Trace history" paragraph inside step 4 of the walkthrough, an extended sentence and two table rows under ### Routes). The Arabic page needs the same paragraph and rows.

Live test spend: none (no live calls).

🤖 Generated with Claude Code

LinuxDevil and others added 4 commits October 2, 2026 19:53
Every Forge run also writes the SDK's trace files under .lousho/agents/<id>/traces;
GET /agents/:id/traces[/:traceId] reads them (only inside that folder); the Trace tab
lists past runs next to the waterfall, with span kind and error status.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…lexity threshold

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[M5b] Agent Forge: persisted trace history in the Trace tab

1 participant