pi-otel, patched: TRACEPARENT at start, tool span context for other extensions (carvers/gestell#46)
  • TypeScript 75.8%
  • JavaScript 24.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Andreas Brenner 5df6d721ea feat: hand the tool span's context to other extensions over pi.events
An extension whose tool calls another process, such as an MCP client,
emits a carrier with its toolCallId on pi-otel:tool-context. pi-otel fills
in traceparent and tracestate of the open tool span before emit returns,
so the callee's spans nest under the tool span.

Assumed pi opens the tool span (tool_execution_start) before it calls the
tool's execute; pi 0.85.1 awaits the extension handlers first. Flag if wrong.

Refs carvers/gestell#46.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 21:34:29 +03:00
.github/workflows ✨ feat: add docs site, biome tooling, license, and otel improvements 2026-05-16 12:02:52 +03:00
.husky 📝 docs(readme): split intro into separate paragraphs 2026-05-16 12:39:30 +03:00
assets ✨ docs: add demo video to package.json and include video asset 2026-05-16 12:26:46 +03:00
docs feat: hand the tool span's context to other extensions over pi.events 2026-09-26 21:34:29 +03:00
samples ✨ feat: add docs site, biome tooling, license, and otel improvements 2026-05-16 12:02:52 +03:00
src feat: hand the tool span's context to other extensions over pi.events 2026-09-26 21:34:29 +03:00
test feat: hand the tool span's context to other extensions over pi.events 2026-09-26 21:34:29 +03:00
.gitignore ✨ feat: add docs site, biome tooling, license, and otel improvements 2026-05-16 12:02:52 +03:00
AGENTS.md feat(shell): opt-in TRACEPARENT propagation into bash/powershell children 2026-09-13 13:43:20 +03:00
biome.json 🎨 style: apply biome formatting to remaining files 2026-05-16 12:04:42 +03:00
CLAUDE.md ✨ feat(spans): add pi.turn span + AGENTS.md 2026-05-15 21:28:58 +03:00
LICENSE ✨ feat: add docs site, biome tooling, license, and otel improvements 2026-05-16 12:02:52 +03:00
package-lock.json chore: release 0.3.0 2026-09-13 13:50:01 +03:00
package.json chore: release 0.3.0 2026-09-13 13:50:01 +03:00
README.md feat: hand the tool span's context to other extensions over pi.events 2026-09-26 21:34:29 +03:00
tsconfig.json chore: initial commit 2026-05-15 21:08:27 +03:00

pi-otel

npm version npm downloads Docs

OpenTelemetry tracing for pi agent.

Full OTel GenAI semantic-convention coverage (gen_ai.*) for token usage, cost, model, finish reasons, and tool calls.

Aspire dashboard
Grafana LGTM

Install

pi install npm:pi-otel

Quickstart

/otel start         # spawn local Aspire dashboard

Backend auto-detect: Aspire CLI first, then Docker / Podman. Install one:

  • Aspire CLI
  • Docker or Podman

Configuration

.pi/settings.json (project) or ~/.pi/agent/settings.json (global):

{
  "otel": {
    "enabled": true,
    "endpoint": "http://localhost:4317",
    "protocol": "grpc",
    "headers": {},
    "serviceName": "pi",
    "captureContent": "metadata_only",
    "spanNaming": "legacy",
    "sampleRatio": 1.0,
    "signals": { "traces": true, "metrics": false, "logs": false }
  }
}

For the http/protobuf and http/json protocols, endpoint is the base URL — each signal appends its own resource path (/v1/traces, /v1/metrics, /v1/logs). For grpc the endpoint is used as-is.

spanNaming: "genai" (default "legacy") renames spans to the OTel GenAI agent conventions — invoke_agent pi / chat {model} / execute_tool {tool} — and adds gen_ai.operation.name plus the spec SpanKind, so backends recognise pi as an agent. It also adds gen_ai.agent.name on the interaction span and, on chat spans only, gen_ai.provider.name (the request's inference provider, e.g. openai, aws.bedrock). No existing attribute is ever removed in either mode; legacy keeps the pi.* names existing dashboards query.

Key env var overrides: OTEL_EXPORTER_OTLP_ENDPOINT, PI_OTEL_SPAN_NAMING=genai, PI_OTEL_METRICS=1, PI_OTEL_LOGS=1, PI_OTEL_DISABLED=1.

Custom providers that skip pi's onPayload hook (pi-vertex and others) still get a pi.llm_request span with tokens and cost, opened from the assistant message_start and tagged pi.llm_request.synthesized=true. See custom providers.

propagateToShell: true (default false) passes TRACEPARENT to processes started by the bash and powershell tools, so instrumented children nest under the tool span. It overrides the built-in tool, which pi reports with a one-time warning. See shell propagation.

A TRACEPARENT in pi's environment becomes the parent of every interaction span, so pi nests under the trace of the process that started it. See parent trace.

Another extension can ask for the W3C context of its running tool call on the pi-otel:tool-context channel, for example to pass it on in an MCP request. See tool span context.

Only one OpenTelemetry SDK can own a process. If another extension registers its providers first, pi-otel warns once and stays disabled instead of silently routing spans into the other SDK. See running alongside other OTel extensions.

Full reference — settings, env vars, content capture modes, sampling, logs signal, and extensibility: nikiforovall.blog/pi-otel/configuration