---
title: CAMEL-AI
description: Use @codespar/camel to give CAMEL-AI role-playing agents commerce capabilities in Latin America.
---

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

# CAMEL-AI Adapter

<VersionBadge pkg="@codespar/camel" />

The `@codespar/camel` adapter converts CodeSpar session tools into CAMEL-AI's OpenAI-compatible function format with a `callable` for execution. Each tool routes through the CodeSpar session for billing and audit. Use it to give your CAMEL role-playing agent conversations access to commerce operations in Latin America.

<Callout type="info">
**Pick this adapter when** you are running research or simulation-heavy workloads (agent-society studies, multi-role negotiations, commerce scenario testing) and want CAMEL's role-playing patterns as your orchestration layer.
</Callout>

## Framework-specific notes

- **OpenAI-compatible shape** — tools come out as OpenAI-format function declarations with a `callable`. If you know the OpenAI adapter, this will feel almost identical.
- **Two-agent role-play is the core pattern** — "customer" + "merchant" or "buyer" + "supplier" personas negotiating through `codespar_charge` / `codespar_pay`. CAMEL generates the full conversation; you review the trace.
- **Scenario testing** — run thousands of simulated commerce conversations offline against sandbox `csk_test_` keys to stress-test your agent's tool selection before shipping live.
- **Society-scale experiments** — CAMEL supports much larger agent populations than most frameworks. Fit for research into how many-agent commerce ecosystems behave, not typical production.
- **Production use is uncommon** — most CAMEL deployments stay in research / simulation. For production commerce agents, pick Claude or Vercel AI SDK.

## Installation

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

<Callout type="info">
`@codespar/camel` has a peer dependency on `@codespar/sdk@^0.10.0`. Make sure it is installed.
</Callout>
## API Reference

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

Fetches all tools and converts them to CAMEL's function format. Each tool has `type: "function"`, a `function` object with `name`, `description`, and `parameters`, plus a `callable` for execution.

```typescript
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/camel";

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(JSON.stringify(tools[0], null, 2));
```

```json title="Output: CamelFunction"
{
  "type": "function",
  "function": {
    "name": "codespar_charge",
    "description": "Create an inbound charge (buyer pays merchant) — Pix / boleto / card",
    "parameters": {
      "type": "object",
      "properties": {
        "provider": { "type": "string" },
        "amount": { "type": "number" },
        "currency": { "type": "string" }
      },
      "required": ["provider", "amount", "currency"]
    }
  }
}
```

### `toCamelTool(tool, session): CamelFunction`

Converts a single CodeSpar tool to CAMEL format with a bound `callable`.

### `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 CAMEL role-playing conversation with CodeSpar tools:

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

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 CAMEL format
  const tools = await getTools(session);

  // 3. Create a tool registry
  const toolRegistry = new Map(
    tools.map((t) => [t.function.name, t])
  );

  // 4. Define role-playing agents
  const assistantRole = {
    name: "Commerce Expert",
    description:
      "Expert in Brazilian e-commerce operations including payments, " +
      "invoicing, and shipping via Pix, boleto, and credit cards.",
  };

  const userRole = {
    name: "Store Owner",
    description: "Owner of a Brazilian online store who needs help with operations.",
  };

  // 5. Execute tool calls from the conversation
  const toolName = "codespar_charge";
  const tool = toolRegistry.get(toolName);

  if (tool) {
    const result = await tool.callable({
      provider: "stripe",
      amount: 25000,
      currency: "BRL",
      description: "Order #1234",
    });
    console.log("Tool result:", result);
  }

  // 6. Clean up
  await session.close();
}

await run("I need to process a payment of R$250 via Pix for order #1234");
```

## Handling parallel tool calls

Execute multiple tool callables in parallel:

```typescript
const toolCalls = [
  { name: "codespar_charge", args: { provider: "stripe", amount: 4990, currency: "BRL" } },
  { name: "codespar_notify", args: { channel: "email", to: "customer@example.com" } },
];

const results = await Promise.all(
  toolCalls.map(async (tc) => {
    const tool = toolRegistry.get(tc.name);
    if (!tool) throw new Error(`Unknown tool: ${tc.name}`);
    return { name: tc.name, result: await tool.callable(tc.args) };
  })
);
```

## Streaming

Use CAMEL's conversation streaming with the `callable` for tool execution:

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

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

// Register as tool executor in your CAMEL setup
async function executeToolCall(name: string, args: Record<string, unknown>) {
  const tool = tools.find((t) => t.function.name === name);
  if (!tool) return JSON.stringify({ error: `Unknown tool: ${name}` });
  return tool.callable(args);
}
```

## Error handling

Wrap `callable` invocations in try-catch:

```typescript
async function safeExecute(tool: CamelFunction, args: Record<string, unknown>) {
  try {
    return await tool.callable(args);
  } catch (error) {
    return JSON.stringify({
      error: error instanceof Error ? error.message : "Tool call failed",
      tool_name: tool.function.name,
    });
  }
}
```

<Callout type="info">
Returning errors as JSON strings lets the CAMEL agents reason about failures within the role-playing conversation.
</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 agents need.

3. **Use a tool registry.** Create a `Map` for O(1) tool lookups by name.

4. **Define clear roles.** CAMEL agents work best with specific role descriptions that explain their expertise.

5. **Return errors as strings.** Let agents reason about failures within the conversation.

6. **Share the same session.** Both agents in a role-playing pair should use the same CodeSpar session for consistent state.

## Newer SDK wrappers

`getTools(session)` is the agent-facing path. From any tool callback you can also 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: "AutoGen Adapter", description: "Similar multi-agent orchestration.", href: "/docs/providers/autogen" },
  { label: "PROVIDER", title: "OpenAI Adapter", description: "CAMEL uses OpenAI-compatible format.", href: "/docs/providers/openai" },
  { label: "QUICKSTART", title: "Quickstart", description: "End-to-end setup in under 5 minutes.", href: "/docs/quickstart" },
]} />
