npm.io
0.5.0 • Published yesterday

@qmilab/lodestar-otel-exporter

Licence
Apache-2.0
Version
0.5.0
Deps
3
Size
105 kB
Vulns
0
Weekly
0
Stars
3

@qmilab/lodestar-otel-exporter

The OpenTelemetry bridge for Lodestar. It projects a session's event log into OTel spans that follow the GenAI semantic conventions and exports them over OTLP/HTTP (JSON) — so the epistemic chain shows up in any OTLP-compatible trace tool: Langfuse, Phoenix, Jaeger, Tempo, Datadog.

Lodestar is not an observability platform. It records what an agent observed, claimed, believed, decided, and what policy allowed; this package hands that record to the tool you already use to look at traces.

It is a read-side, batch exporter: it reads a finished NDJSON event log, projects it, and emits a trace. No SDK, no live in-process instrumentation, no new runtime dependencies — the OTLP/HTTP trace wire format is a small, stable JSON shape we build directly.

Span model

Action-centric — the shape Langfuse and Phoenix render natively:

trace = session
└─ span: invoke_agent (the session)
   ├─ event: observation.recorded
   ├─ event: belief.adopted        (truth_status, sensitivity, confidence …)
   ├─ span:  execute_tool fs.read  [ok]
   ├─ span:  execute_tool git.push [error: policy denied]
   └─ event: firewall.belief.transitioned

Each governed Action becomes an execute_tool span (gen_ai.operation.name, gen_ai.tool.name, gen_ai.tool.call.id) carrying Lodestar's policy verdict, trust level, blast radius, and outcome as lodestar.* attributes. Observations, beliefs, decisions, and firewall transitions ride as span events on the session root. Span and trace ids are derived deterministically from the project, session, and action ids, so re-exporting the same log produces the same trace (and two projects that reuse a session id stay distinct).

The sensitivity gate

Content above a configured sensitivity ceiling (default internal) is never exported: the span or event is still emitted with its structural metadata (ids, timing, type, status) and the payload is dropped, leaving the envelope's payload_hash in its place. A secret-sensitivity belief shows up in your trace tool as "a secret belief existed and backed this decision" — never as its content. This honours the locked v0.2 invariant (docs/architecture/v02-delta.md §3).

Usage

# Print the OTLP JSON for a session (no collector needed)
lodestar otel export <session-id> --stdout

# Push to a collector / Langfuse / Phoenix OTLP endpoint
lodestar otel export <session-id> --endpoint http://localhost:4318

# Raise the ceiling, add auth headers, write to a file
lodestar otel export <session-id> \
  --sensitivity-ceiling confidential \
  --header "authorization=Bearer $TOKEN" \
  --out trace.json

Programmatically:

import { exportSession } from "@qmilab/lodestar-otel-exporter"

const summary = await exportSession({
  sessionId: "my-session",
  endpoint: "http://localhost:4318",
  sensitivityCeiling: "internal",
})
// → { trace_id, span_count, event_count, redacted_count }

License

Apache-2.0