Framework Integrations

LlamaIndex

First-class wrapper for LlamaIndex.TS retrievers. LlamaIndex uses retrieve(query) and returns NodeWithScore[] — a shape Buzo's generic wrap() helper doesn't cover, sobuzo-sdk/llamaindex ships a dedicated adapter.

Install

npm
npm install buzo-sdk llamaindex

Basic usage

Wrap any retriever returned by VectorStoreIndex.asRetriever() (or any object implementing retrieve()). The original behavior is unchanged — nodes flow through exactly as LlamaIndex returned them.

LlamaIndex.TS
import { Buzo } from 'buzo-sdk'
import { wrapLlamaRetriever } from 'buzo-sdk/llamaindex'
import { VectorStoreIndex, Document } from 'llamaindex'

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

const index = await VectorStoreIndex.fromDocuments([
  new Document({ text: '...', metadata: { id: 'doc-1' } }),
])

const retriever = wrapLlamaRetriever(
  buzo,
  index.asRetriever({ similarityTopK: 5 }),
  {
    collectionId: 'prod-support-kb',
    agentId: 'support-v3',
  },
)

const nodes = await retriever.retrieve('how do I reset my password?')

What gets captured

One retrieval trace per call to retrieve(). Each node's vector id is derived from node.id_, falling back to node.metadata.id or node.metadata.vector_id when id_ isn't populated. Score is copied from NodeWithScore.score as-is.

Capturing LLM outputs

LlamaIndex QueryEngine / ChatEngine methods return a Response with a .response string. Because LlamaIndex does not stamp retriever and query-engine calls with a shared run id the way LangChain does, you mint a correlation id per request and pass it on both sides — as parentQueryId on recordRetrieval and as runId on recordGeneration. For this flow, call recordRetrieval directly instead of the wrapper so you can stamp the correlation id yourself.

ts
import { randomUUID } from 'node:crypto'

const correlationId = randomUUID()

// 1. Retrieval — call recordRetrieval directly so you can stamp parentQueryId.
const retStart = Date.now()
const nodes = await retriever.retrieve(question)
buzo.recordRetrieval({
  collectionId: 'prod-support-kb',
  parentQueryId: correlationId,
  query: { text: question },
  results: nodes.map((n, i) => ({
    id: n.node.id_ ?? `idx:${i}`,
    score: n.score ?? 0,
  })),
  latencyMs: Date.now() - retStart,
})

// 2. Generation.
const queryEngine = index.asQueryEngine()
const genStart = Date.now()
const response = await queryEngine.query({ query: question })
buzo.recordGeneration({
  runId: correlationId,
  collectionId: 'prod-support-kb',
  output: { text: response.response },
  latencyMs: Date.now() - genStart,
})
Why not the wrapper here? wrapLlamaRetriever doesn't currently accept a parentQueryId through its trace context, so it can't stamp the correlation id for you. It remains the right helper when you only need retrieval observability without CITED_FLAGGED attribution.

Compatibility

  • llamaindex is declared as an optional peer dependency — the SDK imports no LlamaIndex symbols at runtime, so installing buzo-sdk in a non-LlamaIndex project has zero cost.
  • Works with any retriever shape that matches retrieve(query) => Promise<NodeWithScore[]>, including custom retrievers you built on top of the SDK.