---
title: LlamaIndex
description: Use @codespar/llama-index to give LlamaIndex.TS agents commerce capabilities in Latin America.
---

import { Callout } from "fumadocs-ui/components/callout";
import { Tab, Tabs } from "fumadocs-ui/components/tabs";

# LlamaIndex Adapter

<VersionBadge pkg="@codespar/llama-index" />

The `@codespar/llama-index` adapter converts CodeSpar session tools into LlamaIndex.TS's `FunctionTool` format. Each tool has a `call` method that routes execution through the CodeSpar session for billing and audit. Use it with LlamaIndex agents, query engines, and RAG pipelines that need commerce capabilities.

<Callout type="info">
**Pick this adapter when** your agent's primary job is retrieval over your own data (product catalogs, customer histories, fiscal archives) and the commerce actions come second. LlamaIndex gives you the indexing + query engine; CodeSpar gives the action layer.
</Callout>

## Framework-specific notes

- **Tools as `FunctionTool`** — `getTools(session)` returns `FunctionTool` instances compatible with ReAct agents, OpenAI agents, and query-engine-backed agents. Drop them into any agent constructor.
- **Query engines as retrieval sidecars** — pair the commerce tools with a LlamaIndex query engine over your order history; the agent grounds its `codespar_refund` decision against the retrieved order first.
- **ReAct is the default agent** — predictable, observable thought/action/observation loop. Good fit for commerce debugging where you need to trace why a specific tool was chosen.
- **Document-aware flows** — index your fiscal archive (NF-e XMLs, NFS-e) with LlamaIndex and let the agent query across years of documents before issuing a new one.
- **Node-first but Python available** — `@codespar/llama-index` is the TS package; Python users should use [`codespar` on PyPI](/docs/quickstart-python) with LlamaIndex.py directly.

## Installation

<Tabs items={["npm", "pnpm", "yarn"]}>
<Tab value="npm">
```bash
npm install @codespar/sdk @codespar/llama-index
```
</Tab>
<Tab value="pnpm">
```bash
pnpm add @codespar/sdk @codespar/llama-index
```
</Tab>
<Tab value="yarn">
```bash
yarn add @codespar/sdk @codespar/llama-index
```
</Tab>
</Tabs>

<Callout type="info">
`@codespar/llama-index` has a peer dependency on `@codespar/sdk@^0.10.0`. You also need `llamaindex` for the LlamaIndex runtime.
</Callout>
## API Reference

### `getTools(session): Promise<LlamaIndexTool[]>`

Fetches all tools from the session and converts them to LlamaIndex tool format. Each tool has `name`, `description`, `parameters` (JSON Schema), and a `call` method.

```typescript
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/llama-index";

const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
const session = await codespar.create("user_123", {
  servers: ["stripe", "mercadopago"],
});

const tools = await getTools(session);
console.log(tools[0].name);       // "codespar_charge"
console.log(tools[0].parameters); // { type: "object", properties: { ... } }
```

### `toLlamaIndexTool(tool, session): LlamaIndexTool`

Converts a single CodeSpar tool to LlamaIndex format with a bound `call` method.

### `handleToolCall(session, toolName, args): Promise<ToolResult>`

Convenience executor that routes a tool call through the CodeSpar session.

## Full agent loop

This is a complete example of a LlamaIndex agent with CodeSpar tools:

```typescript title="llamaindex-agent.ts"
import { OpenAIAgent } from "llamaindex";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/llama-index";

const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

async function run(userMessage: string) {
  // 1. Create a session
  const session = await codespar.create("user_123", {
    servers: ["stripe", "asaas", "correios"],
  });

  // 2. Get tools in LlamaIndex format
  const tools = await getTools(session);

  // 3. Create the agent
  const agent = new OpenAIAgent({
    tools,
    systemPrompt:
      "You are a commerce assistant for a Brazilian e-commerce store. " +
      "Handle payments, invoicing, and shipping. " +
      "Respond in the same language the user writes in.",
  });

  // 4. Chat with the agent
  const response = await agent.chat({ message: userMessage });

  // 5. Clean up
  await session.close();

  return response.message.content;
}

const reply = await run("Generate a boleto for R$250 due in 7 days");
console.log(reply);
```

## Handling parallel tool calls

Execute multiple tool calls in parallel:

```typescript
const results = await Promise.all(
  toolCalls.map(async (tc) => {
    const tool = tools.find((t) => t.name === tc.name);
    if (!tool) throw new Error(`Unknown tool: ${tc.name}`);
    return tool.call(tc.args);
  })
);
```

## Streaming

LlamaIndex supports streaming via the agent's `chat` method with streaming enabled:

```typescript title="llamaindex-streaming.ts"
import { OpenAIAgent } from "llamaindex";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/llama-index";

const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

async function runStreaming(userMessage: string) {
  const session = await codespar.create("user_123", {
    servers: ["stripe", "mercadopago"],
  });

  const tools = await getTools(session);
  const agent = new OpenAIAgent({
    tools,
    systemPrompt: "You are a commerce assistant for a Brazilian store.",
  });

  const stream = await agent.chat({
    message: userMessage,
    stream: true,
  });

  for await (const chunk of stream) {
    process.stdout.write(chunk.message.content);
  }

  await session.close();
}

await runStreaming("Create a Pix payment for R$150");
```

## Error handling

Wrap `tool.call()` in try-catch:

```typescript
for (const tool of tools) {
  try {
    const result = await tool.call(args);
    console.log(`${tool.name}:`, result);
  } catch (error) {
    console.error(`${tool.name} failed:`, error instanceof Error ? error.message : error);
  }
}
```

<Callout type="info">
LlamaIndex agents handle tool errors internally and feed them back to the LLM for reasoning.
</Callout>
## Best practices

1. **Always close sessions.** Use `try/finally` to ensure `session.close()` runs.

2. **Scope servers narrowly.** Only connect the MCP servers your agent needs.

3. **Combine with RAG.** Use LlamaIndex's retrieval capabilities alongside CodeSpar tools for context-aware commerce operations.

4. **Use OpenAIAgent for tool calling.** It has the best tool-calling support in LlamaIndex.TS.

5. **Return errors as strings.** Let the agent reason about failures.

6. **Filter tools when possible.** Use `session.findTools()` to get only relevant tools.

## Newer SDK wrappers

`getTools(session)` covers the LLM-driven path. For deterministic post-retrieval steps you can call typed wrappers on the session — same routing, no LLM hop:

- `session.discover(query)` / `session.charge(args)` / `session.pay(args)` / `session.ship(args)` — typed shortcuts for the meta-tools.
- `session.connectionWizard(serverId)` — open a hosted auth flow for a missing connection.
- `session.paymentStatus(toolCallId)` and `session.paymentStatusStream(toolCallId)` — async settlement correlation (poll or SSE).
- `session.verificationStatus(toolCallId)` and `session.verificationStatusStream(toolCallId)` — KYC outcome polling / SSE.

Full reference at [/docs/api/sdk](/docs/api/sdk).

## Next steps

<NextStepsGrid items={[
  { label: "CONCEPT", title: "Sessions", description: "Session lifecycle and configuration.", href: "/docs/concepts/sessions" },
  { label: "CONCEPT", title: "Tools & Meta-Tools", description: "Meta-tools and how routing works.", href: "/docs/concepts/tools" },
  { label: "PROVIDER", title: "LangChain Adapter", description: "Alternative agent framework with LangChain.js.", href: "/docs/providers/langchain" },
  { label: "PROVIDER", title: "OpenAI Adapter", description: "Direct OpenAI SDK integration.", href: "/docs/providers/openai" },
  { label: "QUICKSTART", title: "Quickstart", description: "End-to-end setup in under 5 minutes.", href: "/docs/quickstart" },
]} />
