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/agentsBasic 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
| Field | Source |
|---|---|
output.text | result.finalOutput (post-redaction if enabled) |
promptTokens / completionTokens | result.usage — falls back to inputTokens/outputTokens on older SDK versions. |
runId | Your correlation id. Stamp the same value as parentQueryId on the tool's recordRetrieval. |
model | Whatever 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.
Buzo