Skip to main content

CAMEL-AI

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

1 min read · updated

CAMEL-AI Adapter

@codespar/camelv0.4.0

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.

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.

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

npm install @codespar/sdk @codespar/camel
pnpm add @codespar/sdk @codespar/camel
yarn add @codespar/sdk @codespar/camel

@codespar/camel has a peer dependency on @codespar/sdk@^0.9.0. Make sure it is installed.

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.

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));
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:

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:

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:

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:

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,
    });
  }
}

Returning errors as JSON strings lets the CAMEL agents reason about failures within the role-playing conversation.

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.

Next steps

Edit on GitHub

Last updated on