Oh My Pi
Trace Oh My Pi turns, model calls, tools, usage, timing, retries, and compaction.
@telemetry-dev/omp adds telemetry.dev to Oh My Pi through its extension API. It accepts @oh-my-pi/pi-coding-agent 17 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_agentrecords one complete prompt turn, including continuations, retries, and compaction.chat {model}records provider, model, response ID, finish reason, token usage, duration, TTFT, and errors.execute_tool {toolName}records the tool-call ID, arguments, result, and error state.- Session, branch, compaction, retry, and shutdown events become logs.
Oh My Pi does not report client-side cost for these messages. The integration exports token usage, but it does not add a cost value.
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 Oh My Pi:
export TELEMETRY_DEV_API_KEY=td_live_...
export TELEMETRY_DEV_ENVIRONMENT=development
export OTEL_SERVICE_NAME=omp
The package includes an omp.extensions manifest. The manifest points to ./dist/register.mjs, which exports an environment-configured extension.
The package also exposes this entry as @telemetry-dev/omp/register. Oh My Pi loads the manifest entry when it finds the installed package.
Extension file
Install the package where Oh My Pi can find it. Then add one of these files:
~/.omp/agent/extensions/telemetry-dev.tsfor all projects.omp/extensions/telemetry-dev.tsfor one project
import { telemetryDevExtension } from "@telemetry-dev/omp";
export default telemetryDevExtension();
Use the factory form when you must set options in code:
import { telemetryDevExtension } from "@telemetry-dev/omp";
export default telemetryDevExtension({
agentName: "omp",
captureInput: false,
captureOutput: true,
});
Span lifecycle
agent_start opens the invoke_agent span. A terminal agent_end closes the span and unfinished tool spans.
An agent_end event with willContinue: true keeps the same span open. Retries, compaction, and queued continuations remain in one prompt trace.
The integration also compares the terminal assistant message with the latest completed message. A stale agent_end event does not close the trace.
If a new prompt starts before the prior loop closes, the integration closes the prior span as incomplete. session_shutdown also closes an unfinished span and waits for a flush.
Oh My Pi supplies the message timestamp, duration, and TTFT. The integration uses those host values for each chat span.
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 | omp |
OpenTelemetry service name. |
Options
telemetryDevExtension() accepts TelemetryDevExtensionOptions. The type contains SDK options except registerGlobal, plus agentName.
| Option | Type | Default | Description |
|---|---|---|---|
agentName |
string |
omp |
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 omp |
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 Oh My Pi. |
The integration forces registerGlobal to false. The first initialization in a process supplies the SDK options.
Open the trace explorer after a prompt completes. For API key setup, refer to the quickstart.