Tracing

Instrument agent runs with OpenTelemetry-compatible spans for observability and debugging.

noumen includes a tracing abstraction that emits spans for provider calls, tool executions, and compaction. It integrates with OpenTelemetry when @opentelemetry/api is installed, and falls back to a no-op tracer otherwise.

Configuration

import { Agent, OTelTracer } from "noumen";
import { LocalSandbox } from "noumen/local";

const tracer = await OTelTracer.create("my-agent", "1.0.0");

const code = new Agent({
  provider,
  sandbox: LocalSandbox({ cwd: "/my/project" }),
  options: {
    tracing: { tracer },
  },
});

OTelTracer

The OTelTracer adapts noumen's Tracer interface to OpenTelemetry. It lazily loads @opentelemetry/api via dynamic import — if the package is not installed, OTelTracer.create() returns a NoopTracer.

import { OTelTracer } from "noumen";

const tracer = await OTelTracer.create("service-name", "1.0.0");
// If @opentelemetry/api is not installed, this is a no-op tracer

NoopTracer

For development or when tracing is not needed:

import { NoopTracer } from "noumen";

const tracer = new NoopTracer();

Tracer interface

Implement this interface to integrate with any tracing backend:

interface Tracer {
  startSpan(name: string, options?: SpanOptions): Span;
}

interface Span {
  readonly name: string;
  setAttribute(key: string, value: SpanAttributeValue): void;
  addEvent(name: string, attributes?: Record<string, SpanAttributeValue>): void;
  setStatus(code: SpanStatusCode, message?: string): void;
  end(): void;
}

Stream events

Tracing emits span_start and span_end stream events that you can observe:

for await (const event of thread.run("Fix the bug")) {
  if (event.type === "span_start") {
    console.log(`Span started: ${event.name}`);
  }
  if (event.type === "span_end") {
    console.log(`Span ended: ${event.name} (${event.status})`);
  }
}