Framework Integrations

OpenAI Agents SDK

Instrument @openai/agents runs to capture the final agent output as a Buzo generation trace. Combine with retrieval traces emitted from inside your agent tools to unlock CITED_FLAGGED attribution.

Install

npm
npm install buzo-sdk @openai/agents

Basic usage

Wrap run(agent, input) with runWithBuzo. The wrapper reads finalOutput and token usage from the run result and records the generation trace after the run resolves.

OpenAI Agents
import { Agent, run } from '@openai/agents'
import { Buzo } from 'buzo-sdk'
import { runWithBuzo } from 'buzo-sdk/openai-agents'
import { randomUUID } from 'node:crypto'

export const buzo = new Buzo({
  apiKey: process.env.BUZO_API_KEY!,
  outputCapture: 'redacted',
})

const agent = new Agent({
  name: 'support',
  instructions: 'You are a support agent for Acme. Be concise.',
  tools: [searchKbTool(buzo)],  // instrument retrievals inside tools (see below)
})

export async function handleQuestion(question: string) {
  const runId = randomUUID()
  const result = await runWithBuzo(
    buzo,
    {
      runId,
      collectionId: 'prod-support-kb',
      agentId: 'support-v3',
      model: 'gpt-4o',
    },
    () => run(agent, question),
  )
  return result.finalOutput
}

Retrievals inside tools

Agents typically call vector stores from inside tool handlers. Call recordRetrieval from the handler — pass the same runId you used for the outer runWithBuzo call so the server can correlate retrieval and generation for CITED_FLAGGED.

Tool handler
import { tool } from '@openai/agents'
import { z } from 'zod'

function searchKbTool(buzo: Buzo) {
  return tool({
    name: 'search_kb',
    description: 'Search the support knowledge base',
    parameters: z.object({ query: z.string() }),
    async execute({ query }, { runContext }) {
      const started = Date.now()
      const hits = await vectorStore.query({ topK: 5, vector: await embed(query) })

      buzo.recordRetrieval({
        collectionId: 'prod-support-kb',
        // Correlation — must equal the runId passed to runWithBuzo outside.
        parentQueryId: runContext?.runId,
        query: { text: query },
        results: hits.matches.map((m) => ({ id: m.id, score: m.score })),
        latencyMs: Date.now() - started,
      })

      return hits.matches.map((m) => m.metadata.text).join('\n\n')
    },
  })
}

What gets captured

FieldSource
output.textresult.finalOutput (post-redaction if enabled)
promptTokens / completionTokensresult.usage — falls back to inputTokens/outputTokens on older SDK versions.
runIdYour correlation id. Stamp the same value as parentQueryId on the tool's recordRetrieval.
modelWhatever you pass in the context (the Agents SDK doesn't always return it on the result).
Handoffs and sub-agents. If your agent hands off to another agent mid-run, runWithBuzo still captures a single generation trace per top-level run() call. Per-handoff visibility is on the roadmap — for now, the final finalOutput is what reaches the user and what Buzo matches against.