Vanilla retrievers
For codebases that don't use a framework — or when a specific integration doesn't fit — the SDK provides two drop-in helpers: wrap() for any invoke()-shaped retriever, and wrapPineconeIndex() for the official Pinecone client.
wrap()
wrap() accepts any object exposing invoke(query): Promise<Document[]> and returns a drop-in replacement that also emits a Buzo trace per call. It's the generic escape hatch when your retriever already matches the LangChain document shape but you don't want to pull in the full LangChain callback handler.
import { Buzo, wrap } from 'buzo-sdk'
export const buzo = new Buzo({ apiKey: process.env.BUZO_API_KEY! })
const tracedRetriever = wrap(buzo, vectorStore.asRetriever({ k: 5 }), {
collectionId: 'prod-support-kb',
agentId: 'support-v3',
})
const docs = await tracedRetriever.invoke('how do I reset my password?')wrapPineconeIndex()
Dedicated helper for @pinecone-database/pinecone. Wraps index.query() and preserves namespace chaining — calls like index.namespace('tenant-a').query(...) keep tracing automatically without any per-namespace setup.
import { Pinecone } from '@pinecone-database/pinecone'
import { Buzo, wrapPineconeIndex } from 'buzo-sdk'
export const buzo = new Buzo({ apiKey: process.env.BUZO_API_KEY! })
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! })
const index = wrapPineconeIndex(buzo, pc.index('support-kb'), {
collectionId: 'prod-support-kb',
})
const result = await index.query({ vector, topK: 5, includeMetadata: true })recordRetrieval (direct)
If no helper fits — e.g. a custom retrieval path with pre-filters, reranking, or a vector store whose client shape doesn't match either helper — call recordRetrieval directly from your retrieval code.
import { ChromaClient } from 'chromadb'
const client = new ChromaClient({ path: process.env.CHROMA_URL })
const collection = await client.getCollection({ name: 'support-kb' })
const started = Date.now()
const result = await collection.query({
queryTexts: [question],
nResults: 5,
})
buzo.recordRetrieval({
collectionId: 'prod-support-kb',
query: { text: question },
results: result.ids[0].map((id, i) => ({
id,
score: 1 - (result.distances?.[0]?.[i] ?? 0), // Chroma returns distance, not score
})),
latencyMs: Date.now() - started,
})recordGeneration. Mint one correlation id per request and stamp it as parentQueryId on the retrieval and as runId (or parentRunId) on the generation so Buzo can attribute citations back.
Buzo