Skip to main content
Catalyst instruments @mariozechner/pi-ai in TypeScript. PI AI is a unified LLM API and provider registry. Catalyst patches the registered PI AI providers so each model turn through stream, streamSimple, complete, or completeSimple emits an OpenInference LLM span. Use this guide for Node applications that use PI AI for model calls, tool calling, cross-provider handoffs, or agent workflows. PI AI is a TypeScript package, so there is no Python equivalent for this integration.

What Is Captured

  • One LLM span per PI AI model turn, named like pi-ai.<provider>.turn
  • stream and streamSimple calls, plus complete and completeSimple calls because PI AI completes by resolving the underlying stream
  • System prompts, input messages, assistant output, model name, provider, and invocation parameters
  • Tool call IDs, names, and JSON arguments from assistant messages
  • Token usage, prompt cache read/write counts, and total cost when PI AI returns them
  • Finish reason, errors, aborts, and exception details
  • Active agentSpan() identity, including agent.id, agent.name, agent.role, and session.id

Install

TypeScript

Configure Export

Set the Catalyst endpoint and token before your app starts. Generate a token at API Keys.

Initialize Tracing

Initialize Catalyst before making PI AI calls. Import the PI AI namespace and pass it to setup() so Catalyst patches the same provider registry your app uses.
TypeScript
For explicit manual initialization, disable auto-instrumentation and use the PI AI subpath helper.
TypeScript

Complete Call

completeSimple() is the smallest path. PI AI resolves it through a provider stream, so Catalyst emits the LLM span when the call finishes. The examples below assume you initialized tracing with the setup block above.
TypeScript
Expected span:
  • pi-ai.openai.turn
Expected promoted fields include llm.model_name, input.value, output.value, llm.token_count.prompt, llm.token_count.completion, llm.token_count.total, and llm.invocation_parameters when PI AI returns the corresponding data.

Streaming

For streaming calls, consume the stream and call await stream.result() before process shutdown. Catalyst finishes the span when PI AI emits a done/error event or when .result() resolves.
TypeScript
For short-lived scripts, call await tracing.shutdown() after the stream is fully consumed.

Tool Loop

PI AI returns tool calls in assistant message content. Catalyst records the tool call name, ID, and arguments on the PI AI LLM span. Your local tool execution is application code, so wrap it with manualSpan() if you also want a TOOL child span for the work your app performs.
TypeScript
Expected spans:
  • pi-ai.openai.turn for the first model turn with the tool call
  • lookup_order TOOL span when you wrap local execution with manualSpan()
  • another pi-ai.openai.turn for the continuation after the tool result

Stable Agent Identity

Wrap the full PI AI run in agentSpan() when one user request can produce multiple model turns or tool executions. PI AI LLM spans inherit the active agent identity and nest under the AGENT span.
TypeScript

Verify In Catalyst

Filter traces by your service.name, for example pi-ai-agent. A successful run should show PI AI LLM spans named by provider, such as pi-ai.openai.turn, with captured input/output, model metadata, usage, finish reason, and tool call attributes. If you wrap the run in agentSpan(), the same LLM spans should show the inherited agent.id, agent.name, and agent.role. If no PI AI spans appear:
  • Initialize Catalyst before making PI AI calls.
  • Pass the PI AI namespace directly with modules: { piAi } or instrumentPiAi(piAi, tracing).
  • Consume streaming results or call .result() so PI AI can finish the turn.
  • Call await tracing.shutdown() before process exit in short-lived scripts.