Skip to main content

Local stack

Start the local stack:
Or use the all-in-one reset:
Expected endpoints:
  • Grafana: http://localhost:3001
  • Prometheus: http://localhost:9090
  • Tempo: http://localhost:3200
  • Loki: http://localhost:3100
  • OTEL collector HTTP: http://localhost:4318
Validate the stack:

Enable OTEL export

Demo workflow

Use the built-in reproducible workflow at workflows/agent-trace-otel-demo.tsx. It emits:
  • one Pi-like high-fidelity attempt with canonical trace events plus persisted session transcript rows
  • one Claude-like structured attempt with canonical trace events plus provider session transcript rows
  • one Codex-like structured attempt with canonical trace events plus provider session transcript rows
  • one Gemini-like structured attempt
  • one SDK-style final-only attempt
  • stable run annotations for Loki queries
Run the success case:
Run the malformed JSON failure case:
Optional durable-local verification:

End-to-end verification script

scripts/verify-observability.sh runs the full reset → start → demo workflow (success + failure) → Loki/Tempo query verification flow and writes a timestamped evidence bundle under tmp/verification/<timestamp>. Use this as the canonical reproduction path for reviewers:
The bundle contains every Loki query result, the Tempo trace export, Grafana datasource health, and the success/failure CLI run logs as JSON.

Loki queries

Smithers OTEL attributes are exposed to Loki as sanitized structured metadata fields such as:
  • smithers_event_category
  • run_id
  • workflow_path
  • node_id
  • node_attempt
  • agent_family
  • agent_capture_mode
  • trace_completeness
  • event_kind
  • session_row_type
Smithers exports two related Loki log families:
  • agent-trace: normalized canonical execution events such as deltas, tool lifecycle, usage, and capture warnings/errors
  • agent-session: provider transcript/session rows observed live or backfilled from persisted session logs
Both families share the same run/workflow/node/attempt/agent correlation fields and the same redaction rules. artifact.created remains local-only and is not exported to Loki. Use {service_name="smithers-dev"} as the stream selector, then filter on structured metadata in the LogQL pipeline. Use | json to inspect the structured log body. All events for one run:
One node attempt:
Thinking deltas only:
Tool execution only:
Capture errors only:
Inspect the structured JSON body for one run:
Canonical trace rows only:
Provider session rows only:
Pi persisted session metadata:
Claude persisted session queue events:
Codex persisted session reasoning rows:
Redaction proof query:

API query examples

Equivalent direct Loki API checks:

Tempo trace checks

Tempo search should show Smithers spans once a workflow has run:
Inspect one trace directly:
Expected trace attributes include at least:
  • service.name = smithers-dev
  • runId = <RUN_ID>
  • workflowPath = <workflow path>

Verification checklist

  • stack starts successfully in Docker
  • Loki is present and queryable
  • collector logs pipeline is active
  • Pi traces show text deltas, thinking deltas, tool execution lifecycle, final message, usage, and run/node/attempt correlation
  • Pi session transcript rows are queryable in Loki
  • Claude session transcript rows are queryable in Loki
  • Codex session transcript rows are queryable in Loki
  • second agent family is exported with truthful final-only completeness classification
  • Gemini stream-json attempts preserve structured deltas truthfully
  • malformed or truncated structured streams emit capture.error and classify as capture-failed
  • artifact write failures emit capture.warning and degrade to partial-observed without losing durable DB truth
  • Tempo search shows Smithers spans and trace attributes including runId
  • Prometheus is still scraping the collector successfully
  • secrets are redacted from canonical events, OTEL log bodies, and persisted trace artifacts

Automated coverage

apps/observability/tests/agentTrace.test.js covers the canonical contract:
  • capability profiles for every agent family
  • family + capture-mode detection
  • Pi / Claude / Codex / Gemini structured event normalization
  • redaction rules for API keys, bearer tokens, and secret-ish key=value pairs
  • canonical OTEL log record shaping with stable Loki query attributes
  • session-event OTEL log record shaping
The full provider-specific test matrix from PR #119 (truncated streams, artifact write failures, multi-family final-only classification) is partially covered and will be extended in a follow-up.