Skip to main content
atlanai SDK traces pi agents for you. With ATLAN_INSTRUMENT=pi set, init() wraps pi’s public Agent.prompt() and Agent.continue(), so every run, model call, tool call, and skill appears in Agent Registry with its token usage. You don’t change any agent code beyond one init() call. Use this guide when your TypeScript agent embeds @mariozechner/pi-agent-core (pi 0.67) or @earendil-works/pi-agent-core (pi 1.x).

Before you begin

Before you start, make sure you have:
  • Project: a Node.js app that embeds pi-agent-core 0.67 or 1.x. pi 1.x needs Node.js 22.19 or later. The pi command-line agent itself never calls init(), so this setup doesn’t trace it.
  • Tracing: atlanai SDK (@atlanai/sdk) installed, as in Install atlanai SDK, with ATLAN_API_KEY, ATLAN_WORKSPACE_ID, and ATLAN_BASE_URL set.
  • Credential: the agent’s own API key from its Identity tab. Runs sent with a personal key are filed under that person and do not appear on the agent’s Usage tab.

Trace runs

1

Turn on pi instrumentation

Set ATLAN_INSTRUMENT in the agent’s environment. The value is a comma-separated list of frameworks, so pi is enough here.
To keep prompts and responses out of the trace and send only structure and token usage, also set ATLAN_TRACE_CONTENT=false. See Control trace privacy.
2

Call init before the first prompt

Keep your existing init() call, or add one at startup before the agent sends its first prompt.
Instead of the environment variable, you can pass instrument: ["pi"] to init(). On startup the SDK logs pi instrumentation on for <package>@<version> at <path> (content capture on) to stderr. Agents created before or after init() are traced from their next prompt.
3

Name skills, if you use your own skill tool

By default, a call to a tool named skill with a string args.name is recorded as that skill, in atlan.skill.name. If your agent uses skills under a different tool, pass your own rule. It replaces the default, so return args.name for a skill tool too if you still use one.
4

Verify trace

Run one prompt with synthetic input, then await client.flush() before the process exits. Open the agent in Agent Registry, select Usage, then the run in Recent runs, and select Full trace. Confirm the run step, one model call per turn with token usage, and tool calls with their arguments and results.If the startup line is missing, see Troubleshooting. If no traces arrive at all, see init() disables tracing and no traces are exported.

What a run looks like

Each prompt() or continue() call is one run. Span names and attributes follow the OpenTelemetry GenAI conventions. Input tokens are sent with the cached part included, as the GenAI conventions define them, and cache reads and writes are sent separately, so Agent Registry prices cached tokens once. A run that pi ends with an error or an abort, or whose call throws, is marked as failed. A continue() with no active span is recorded as a child of the same agent’s last prompt() run. When that agent’s previous run failed, it also carries atlan.run.retry set to true.

Join runs across processes

A run joins the trace that is active when it starts. To continue a trace in a worker process, pass the parent’s W3C trace context in the TRACEPARENT environment variable. Without either, each prompt() starts its own trace, and a continue() joins the agent’s last prompt(). Runs of agents created with the same sessionId are grouped by gen_ai.conversation.id.

Limitations

  • Zero-code tracing needs pi to load synchronously during init(). That means compiled JavaScript on Node.js 20.19 or later in the 20 line, or 22.12 or later, with no loader hooks such as tsx. Under a loader, pi is wrapped once it loads, and prompts that start before then are not traced. The SDK logs a warning that names the reason.
  • pi instrumentation runs on Node.js only. On other runtimes the SDK logs a warning and traces nothing.
  • prompt() and continue() return a new promise that settles with the same value or error as pi’s own, so code that compares the returned promise object to pi’s sees a different one. A rejection you don’t handle still raises unhandledRejection.
  • Only prompt() and continue() are traced. For work outside them, create your own spans, as in Create spans for agent run.
  • In short-lived processes, flush before exit, as in Export traces from serverless.

Troubleshooting

For other setup problems, see Install and setup errors.

Next steps

See also