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
After the public release, install the package where Oh My Pi can resolve 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.