Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.inference.net/llms.txt

Use this file to discover all available pages before exploring further.

Catalyst instruments the OpenAI SDK in both TypeScript and Python. Initialize tracing before constructing clients so the OpenAI prototypes are patched before application calls start.

What Is Captured

  • Chat Completions request and response messages
  • Responses API input and output text
  • Tool call names, IDs, and JSON arguments
  • Tool result messages passed back into later turns
  • JSON schema response format in invocation parameters
  • Model name, finish reason, usage, and token counts
When OpenAI calls happen inside agentSpan() / agent_span(), Catalyst adds the active agent.id, agent.name, and agent.role to the OpenAI child LLM spans. This is the preferred pattern for grouping OpenAI-backed agents in the Agents dashboard.

Install

bun add @inference/tracing openai

Basic Chat

import { setup } from "@inference/tracing";
import OpenAI from "openai";

const tracing = await setup({
  serviceName: "checkout-agent",
  modules: { openai: OpenAI },
});

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const response = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [
    { role: "system", content: "You answer in one short sentence." },
    { role: "user", content: "Summarize order ABC-123." },
  ],
  max_tokens: 80,
});

console.log(response.choices[0]?.message.content);
await tracing.shutdown();

OpenAI Inside An Agent

import { agentSpan } from "@inference/tracing";

await agentSpan(
  tracing.tracer,
  {
    agentId: "checkout-agent",
    name: "CheckoutAgent",
    role: "checkout",
    system: "openai",
  },
  async (span) => {
    const input = "Summarize order ABC-123.";
    span.setInput(input);
    const response = await client.responses.create({
      model: "gpt-4o-mini",
      input,
    });
    span.setOutput(response.output_text);
  },
);

Tool Calling

The first model call records the assistant tool call. The second model call records the tool result message and the final answer.
import { setup } from "@inference/tracing";
import OpenAI from "openai";

const tracing = await setup({ modules: { openai: OpenAI } });
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const tools = [
  {
    type: "function" as const,
    function: {
      name: "get_weather",
      description: "Look up the current weather in a city.",
      parameters: {
        type: "object",
        properties: { city: { type: "string" } },
        required: ["city"],
      },
    },
  },
];

const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
  { role: "user", content: "What's the weather in San Francisco?" },
];

const first = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages,
  tools,
});

const toolCalls = first.choices[0]?.message.tool_calls ?? [];
messages.push({ role: "assistant", content: null, tool_calls: toolCalls });

for (const toolCall of toolCalls) {
  const args = JSON.parse(toolCall.function.arguments) as { city: string };
  messages.push({
    role: "tool",
    tool_call_id: toolCall.id,
    content: JSON.stringify({ city: args.city, tempF: 62 }),
  });
}

const final = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages,
  tools,
});

console.log(final.choices[0]?.message.content);
await tracing.shutdown();

Structured Outputs

response_format is included in invocation parameters, so you can inspect which schema constrained the model call.
TypeScript
const response = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [
    {
      role: "user",
      content: "Extract the city, temperature, and unit from: 72F in Berlin.",
    },
  ],
  response_format: {
    type: "json_schema",
    json_schema: {
      name: "weather_report",
      strict: true,
      schema: {
        type: "object",
        additionalProperties: false,
        properties: {
          city: { type: "string" },
          temperature: { type: "number" },
          unit: { type: "string", enum: ["F", "C"] },
        },
        required: ["city", "temperature", "unit"],
      },
    },
  },
});

console.log(response.choices[0]?.message.content);

Responses API

Responses API calls are traced with the same OpenInference attribute families as Chat Completions.
TypeScript
const response = await client.responses.create({
  model: "gpt-4o-mini",
  input: "In one sentence, what is OpenTelemetry?",
});

console.log(response.output_text);