Skip to navigation

pi is a minimal terminal coding agent. The @respan/instrumentation-pi package is a pi extension that traces your pi sessions to Respan: every turn, model call, tool execution, and compaction. Nothing is written to disk on your machine; spans are batched in memory and sent straight to Respan.

This page covers interactive pi sessions in the terminal. To trace the @earendil-works/pi-coding-agent SDK inside your own application, see Pi Coding Agent SDK.

Create an account at platform.respan.ai and grab an API key.

For application setup, follow Agent setup.

See pi gateway setup to route pi’s model calls through the Respan gateway. Every LLM call is then logged by the gateway with no SDK; the extension on this page adds the agent-level structure (turns, tool calls, threads) on top.

How it works

The extension traces pi by observing it, not by proxying it:

  • pi talks to its model provider directly.
  • pi’s native extension events notify the extension when sessions start, turns run, models respond, and tools execute.
  • The extension turns those events into OpenTelemetry spans and sends them to Respan from inside the pi process. There is no daemon, no local journal, and no log directory: if Respan is unreachable, the batch is retried and then dropped, and pi keeps working. For guaranteed delivery through outages, see Delivery guarantees.
  • Credentials come from RESPAN_API_KEY or from ~/.respan/credentials.json written by respan auth login; the extension never stores them in its own config.

Each prompt you send appears in Respan as one trace with turn, model call, and tool spans; all traces of a pi session share the session id as thread id. See What gets traced.

Set up tracing

The extension requires pi v0.65.0 or later.

1

Install pi

If you haven’t already, install pi.

2

Install the extension

Paste this into your coding agent:

Help me set up Respan tracing for pi: fetch and follow https://www.respan.ai/docs/documentation/agent-setup.md

For manual installation:

pi install npm:@respan/instrumentation-pi
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
3

Restart pi

Restart pi so it loads the extension. The footer shows Respan: tracing while active, and after each prompt a widget below the editor shows a link to its trace.

4

View your trace

Open the Traces page. Each pi session is one trace and every prompt adds a turn to it, even after a restart or a week-long pause; the Threads view shows the whole pi session as a conversation.

What gets traced

Each agent run (one prompt → agent_end) is one root agent span, pi.turn-<n>.agent, displayed as agent.turn-<n> — n is the prompt’s number within the pi session, so a session resumed with pi -c continues at the next turn.

pi.turn-1.agent (agent) one per prompt, shown as agent.turn-1
├── pi.chat (chat) one per assistant message
│ prompts, completion, tool_calls, usage, TTFT, cost
├── bash.tool (tool) one per tool execution
├── read.tool (tool) skill usage detected from SKILL.md
├── pi.turn-2.steer (task) a message steered into the running turn, shown as steer.turn-2
├── pi.chat (chat)
└── pi.compaction (task) when compaction happens mid-run
DataDescription
TurnsOne root agent span per prompt, with the prompt as input, the final assistant text as output, turn / tool-call counts, thinking level, pi version, session file and working directory.
Model callsOne chat span per assistant message: provider, model, the conversation sent to the model, the response, this turn’s tool calls, available tools.
UsageInput, output, total, cache-read and cache-creation tokens, reasoning tokens, estimated cost, time to first token.
Tool executionsOne tool span per execution with arguments and result; failures carry the error. When pi reads a SKILL.md or runs the skill tool, the span is tagged with the skill name.
Compaction and branch summariesTask spans with the trigger and the resulting summary.
Steered messagesA message delivered into a turn that is already working gets its own steer.turn-<n> span at the point pi injected it. See Steering.
Git metadataRepository URL (credentials stripped), branch and commit of the working directory on each turn span.
ErrorsAssistant errors and aborts, tool errors, and runs interrupted by quitting pi.

Chat and tool spans are sent the moment they complete, so a long-running turn streams into the dashboard while it is still running; the turn span arrives when the run ends.

Steering

When you send a message while pi is still working, pi does not start a new run. It queues the message and delivers it into the running turn at the next tool boundary, and the agent carries on with the new information. Respan records each delivered message as its own row under the turn, named steer.turn-<n>, at the exact point pi injected it:

agent.turn-1 steer_count: 2
├── llm.gpt-5
├── tool.read
├── steer.turn-2 input = the steered message
├── llm.gpt-5 after_steer = true
├── tool.bash
├── steer.turn-3
├── llm.gpt-5 after_steer = true
└── tool.write
agent.turn-4
WhereWhat is recorded
steer.turn-<n> spanInput is the steered message. Metadata: turn_number (the steer’s own number), steered_into_turn, steer_index, and delivered_after (tool_results, assistant_reply, or run_start).
Turn spanInput lists the original prompt followed by every steered message, so one click shows everything the run was given. Metadata: steer_count.
First LLM call after a steerMetadata after_steer = true and steer_turn_numbers. The steered message is the last item of that call’s input.

Turn numbers. Turn numbers count the session’s user messages, which keeps them stable when a session is resumed in another process. A steered message takes the next number, so a turn-1 run that received three steers (steer.turn-2, steer.turn-3, steer.turn-4) is followed by agent.turn-5. Nothing was skipped: the numbers in between are the steer rows inside the turn.

Find steers across traces. On the Spans page, filter by custom property:

  • after_steer is true: exactly the model calls that reacted to a steered message.
  • steer_count is 1 (or 2, 3, …): the turn spans that received that many steers.
  • steered_into_turn is 1: the steer spans delivered into turn 1, each with its message as input.

A steer is an event inside the run, not a new run: the steps after it stay under the same turn, because the agent usually keeps working on its original task while taking the new message into account.

Steer spans require @respan/instrumentation-pi 0.1.5 or later.

Upgrade with pi update npm:@respan/instrumentation-pi.

Settings

Save non-secret configuration to ~/.pi/agent/respan.json. A project-level .pi/respan.json overrides it, and environment variables override both. The API key is never written to these files.

SettingSaved keyEnvironment variableHow to change it
Enable tracingenabledRESPAN_PI_TRACING (true/false)Ask your coding agent to update enabled, or edit the file.
API endpointbase_urlRESPAN_BASE_URLPoint it at a local collector or a self-hosted Respan.
Trace scopetrace_scopeRESPAN_PI_TRACE_SCOPE (session/run)session (default) = one trace per pi session with a root per prompt; run = one trace per prompt.
Customercustomer_idRESPAN_CUSTOMER_IDSets customer_identifier on every span.
Workflow nameworkflow_name—Set workflow_name in the configuration file; traceloop.workflow.name on turn spans (default pi).
Projectproject_idRESPAN_PROJECT_IDSet project_id in the configuration file; routes traces to a Respan project.
Extra span metadatametadata—Edit metadata (string key-value pairs) in the file.
Debug output—RESPAN_PI_DEBUG=1Prints the extension’s diagnostics to stderr.

Trace scope decides what one trace is:

  • session (default): every prompt of the session joins one trace whose id is derived from the pi session id, so a session resumed with pi -c in another process, or after a week-long pause, keeps adding turns to the same trace. Respan shows the turns as multiple roots under one synthetic root, ordered by time; the trace’s duration spans from the first to the latest turn. No span is ever held open across idle time.
  • run: every prompt is its own trace with its own cost and latency. All traces of the session still share thread_identifier = the pi session id, so the Threads view shows the whole session in order.

To switch:

Set my pi Respan tracing to one trace per prompt by setting trace_scope to run in its tracing configuration.

Common workflows

Install for one project only

pi install -l npm:@respan/instrumentation-pi

This records the extension in the project’s .pi/settings.json instead of ~/.pi/agent/settings.json.

Turn tracing off temporarily

RESPAN_PI_TRACING=false pi

For a persistent change, ask your coding agent to set enabled: false in the tracing configuration. The package remains installed.

Non-interactive runs

pi -p "..." runs are traced the same way; the extension flushes before pi exits.

Upgrade

pi update npm:@respan/instrumentation-pi

Uninstall

pi remove npm:@respan/instrumentation-pi # add -l if it was installed with --local
rm ~/.pi/agent/respan.json # optional: drop the saved settings

Delivery guarantees

Inside the pi process, spans are batched in memory and posted to Respan with retries. Nothing is written to your disk, so nothing piles up on the machine, and a session that sits idle for days costs nothing. The trade-off is that if Respan is unreachable for longer than the retry window while pi is running, that batch is lost.

If you need at-least-once delivery through outages and restarts, run the Respan Collector (see the CLI) next to pi and point the extension at it:

Set up a local Respan Collector for pi tracing and point the extension's base_url at it. Follow https://www.respan.ai/docs/documentation/cli.md for collector commands.

The collector keeps a bounded on-disk queue that drains as soon as Respan acknowledges the data; it never grows without limit.

Troubleshooting

Traces do not appear. Check the following, in order:

  1. Verify the extension is installed: pi list should show npm:@respan/instrumentation-pi.
  2. Verify the key is available: RESPAN_API_KEY is set, or respan auth status shows you are logged in. If credentials are missing, use the setup prompt above.
  3. Verify tracing is enabled: enabled is not false in ~/.pi/agent/respan.json or .pi/respan.json, and RESPAN_PI_TRACING is not set to false.
  4. Restart pi after any configuration change, then run at least one prompt; the turn span is sent when the run ends.
  5. Run RESPAN_PI_DEBUG=1 pi to print the extension’s diagnostics to stderr (initialization, export errors).

Tracing failures never interrupt pi: the session keeps working even when traces do not appear, and the footer shows Respan: tracing unavailable: <reason>.

Turn numbers skip, for example agent.turn-1 is followed by agent.turn-5. The turn in between received steered messages, and each one took a number. Expand the turn to see the steer.turn-<n> rows. See Steering.

The trace link widget does not appear. The widget is only shown in interactive mode, after the first completed prompt, and only for the Respan cloud endpoint (self-hosted or collector-routed setups show the footer status only).

Resources