FabricFabricHarness
Reference

Telemetry

Events, metrics, and OpenTelemetry hooks.

Fabric Harness emits structured events for every meaningful step in an agent run. The full notes live at docs/telemetry.md.

Event types

agent_start
text_delta
prompt_start       prompt_end
tool_start         tool_end
command_start      command_end
task_start         task_end
approval_requested approval_granted approval_denied approval_expired
checkpoint_created checkpoint_restored
compaction
mount
metric
result_retry      result
error

Transports

  • SSEGET /agents/:name/:id/stream emits typed AgentEvent values for any consumer (curl, fetch, downstream worker).
  • OpenTelemetryopenTelemetryExporter adapts Fabric's TelemetrySpan shape to any @opentelemetry/api Tracer (App Insights, Jaeger, Honeycomb, generic OTLP). Pass conventions: 'foundry' to emit gen_ai.* span names matching Azure AI Foundry / OpenTelemetry Generative AI semantic conventions.
  • LangfuselangfuseExporter for direct trace export (peer-deps langfuse).
  • Azure Monitor / App InsightsapplicationInsightsExporter from @fabric-harness/azure/app-insights (peer-deps applicationinsights).
  • ConsoleconsoleTelemetryExporter for local debugging.
import { openTelemetryExporter, langfuseExporter, eventToTelemetrySpan } from '@fabric-harness/sdk';
import { Langfuse } from 'langfuse';

const langfuse = new Langfuse({ publicKey, secretKey, baseUrl });
const exporter = langfuseExporter({ client: langfuse, attributes: { service: 'support-agent' } });

const session = await fabric.session(undefined, {
  onEvent: async (event) => {
    const span = eventToTelemetrySpan(event);
    if (span) await exporter.export(span);
  },
});

Metrics from the CLI

fh metrics <session-id> [--json]

Aggregates:

  • token usage (input + output + total) and costUsd if the provider reports it,
  • tool calls (with per-tool breakdown for the top 5),
  • shell commands and durations,
  • artifacts,
  • mounts (count, total bytes, total files, top sources by bytes),
  • model attempts.

Per-event hooks

Subscribe to events at agent or session scope via the onEvent callback. Wire any of the exporters above (or a custom one implementing TelemetryExporter) into the callback to forward spans.

Hierarchical OpenTelemetry observer

openTelemetryExporter emits one flat span per duration-bearing event. For a nested trace — a single parent span per operation, with turn, tool, and shell spans inside — use the observer instead:

import { trace } from '@opentelemetry/api';
import { createOpenTelemetryObserver } from '@fabric-harness/sdk/otel-observer';

const observe = createOpenTelemetryObserver({
  tracer: trace.getTracer('fabric-harness'),
  conventions: 'fabric', // or 'foundry' for gen_ai.* span names + attributes
});

const agent = await init({ onEvent: observe });

It lives on the @fabric-harness/sdk/otel-observer subpath (not the main entry) because building parent spans needs @opentelemetry/api at runtime, while the main SDK keeps it an optional peer dependency. The tree is inferred from event start/end ordering; a task() sub-session traces separately with a wrapping task span, and an error event closes open spans with ERROR status.