Skip to content
telemetry.dev
Esc
navigateopen⌘Jpreview
On this page

Pi coding agent

Trace pi agent loops, model calls, tool executions, usage, cost, and lifecycle events.

@telemetry-dev/pi adds telemetry.dev to @earendil-works/pi-coding-agent. It targets pi 0.82.1 and accepts pi 0.80.4 or later.

What it captures

Each prompt produces one trace with this shape:

invoke_agent
├── chat {model}
│   ├── execute_tool {toolName}
│   └── execute_tool {toolName}
└── chat {model}
  • invoke_agent records the prompt, final assistant text, result, and session ID.
  • chat {model} records provider, models, response ID, finish reason, token usage, and pi’s estimated USD cost.
  • execute_tool {toolName} records the tool-call ID, arguments, result, and error state.
  • Session, turn, compaction, model-change, and shutdown events become logs.

Tool spans nest under the chat span that issued the tool call. A tool without a matching chat span nests under invoke_agent.

Only text blocks become assistant output. Thinking and tool-call blocks do not become output, but usage can include reasoning tokens.

Set up the integration

Make a project at telemetry.dev. Then copy an API key from the project’s setup page.

Set these variables in the environment that starts pi:

export TELEMETRY_DEV_API_KEY=td_live_...
export TELEMETRY_DEV_ENVIRONMENT=development
export OTEL_SERVICE_NAME=pi

The integration reads all setup values from the environment when pi loads the package entry.

Pi package

After the public release, add the package to ~/.pi/agent/settings.json:

{
  "packages": ["npm:@telemetry-dev/pi"]
}

The package manifest points to ./dist/register.mjs. The public @telemetry-dev/pi/register entry exports telemetryDevExtension() with environment setup.

Extension file

If pi can resolve the package, add ~/.pi/agent/extensions/telemetry-dev.ts:

import { telemetryDevExtension } from "@telemetry-dev/pi";

export default telemetryDevExtension();

Use the factory form when you must set options in code:

import { telemetryDevExtension } from "@telemetry-dev/pi";

export default telemetryDevExtension({
  agentName: "pair-programmer",
  captureInput: false,
  captureOutput: true,
});

Span lifecycle

agent_start opens the invoke_agent span. Retries and compaction can start the agent loop again, but they keep the same span.

This behavior lets a later retry replace a retryable result before the prompt settles. session_shutdown closes an unfinished loop and waits for the final flush.

Pi does not supply TTFT or request-duration values. The integration measures chat duration from message_start to message_end with the local clock.

Environment variables

Variable Required Default Description
TELEMETRY_DEV_API_KEY Yes None Ingest API key. Without a key, the integration is a no-op.
TELEMETRY_DEV_BASE_URL No https://ingest.telemetry.dev OTLP ingest base URL.
TELEMETRY_DEV_ENVIRONMENT No production Environment on exported telemetry.
OTEL_SERVICE_NAME No pi OpenTelemetry service name.

Options

telemetryDevExtension() accepts TelemetryDevExtensionOptions. The type contains SDK options except registerGlobal, plus agentName.

Option Type Default Description
agentName string pi Value for gen_ai.agent.name.
apiKey string TELEMETRY_DEV_API_KEY Ingest API key.
baseUrl string TELEMETRY_DEV_BASE_URL or production ingest Ingest base URL.
environment string TELEMETRY_DEV_ENVIRONMENT or production Deployment environment.
serviceName string OTEL_SERVICE_NAME or pi Service name on each trace.
enabled boolean true Set to false for a complete no-op.
exportMode "batched" | "immediate" batched Span export mode.
captureInput boolean true Capture prompts and tool arguments.
captureOutput boolean true Capture assistant text and tool results.
mask (value, context) => unknown None Change captured values before serialization.
maxAttributeLength number 65536 Maximum content attribute length.
batch BatchOptions SDK defaults Batch size, delay, queue, and timeout settings.
spanFilter (span) => boolean None Select spans for export.
resourceAttributes Record<string, AttributeValue> None Add OpenTelemetry resource attributes.
logLevel "debug" | "info" | "warn" | "error" | "silent" warn SDK diagnostic level.
fetch typeof fetch globalThis.fetch Custom fetch implementation.
waitUntil (promise) => void None Extend serverless work for export.
onError (error) => void None Receive integration errors. The extension does not throw them into pi.

The integration forces registerGlobal to false. The first initialization in a process supplies the SDK options.

Open the trace explorer after a prompt settles. For API key setup, refer to the quickstart.

Last updated on August 3, 2026

Was this page helpful?