CrewAI
Use @codespar/crewai to give CrewAI agent crews commerce capabilities in Latin America.
CrewAI Adapter
@codespar/crewaiv0.4.0The @codespar/crewai adapter converts CodeSpar session tools into CrewAI's tool format. Each tool has a run method that routes execution through the CodeSpar session for billing and audit. Use it to give your CrewAI crews access to payments, invoicing, shipping, and other commerce operations in Latin America.
Pick this adapter when your commerce flow decomposes naturally into specialist roles (a "payments agent", a "fiscal agent", a "logistics agent" collaborating on one order) and you want CrewAI's role-based orchestration to coordinate them.
Framework-specific notes
- Tools attached per-agent, not per-crew — scope payments tools to the payments agent, fiscal tools to the fiscal agent. CrewAI's role-based design pairs well with the meta-tool layer: one role per domain.
.run()is sync by default — CrewAI tools expose arun(input)method; the adapter wires it tosession.executeunder the hood. For async-heavy commerce flows, prefer the async agent constructor.- Delegation between agents — a Crew with a "research" agent (calls
codespar_discover) delegating to an "execution" agent (callscodespar_pay) models real human-team workflows; the adapter does not need special wiring for this. - Memory is CrewAI-native — CodeSpar sessions expire after 30 min of inactivity, but CrewAI's agent memory (short-term + long-term) persists across runs. Combine for returning-customer scenarios.
Installation
npm install @codespar/sdk @codespar/crewaipnpm add @codespar/sdk @codespar/crewaiyarn add @codespar/sdk @codespar/crewai@codespar/crewai has a peer dependency on @codespar/sdk@^0.9.0. Make sure it is installed.
API Reference
getTools(session): Promise<CrewAITool[]>
Fetches all tools from the session and converts them to CrewAI tool format. Each tool has name, description, schema (JSON Schema), and a run method.
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/crewai";
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].schema); // { type: "object", properties: { ... } }toCrewAITool(tool, session): CrewAITool
Converts a single CodeSpar tool to CrewAI format. The run method is bound to the session for execution.
import { toCrewAITool } from "@codespar/crewai";
const allTools = await session.tools();
const paymentTools = allTools
.filter((t) => t.name.includes("pay"))
.map((t) => toCrewAITool(t, session));handleToolCall(session, toolName, args): Promise<ToolResult>
Convenience executor that routes a tool call through the CodeSpar session.
import { handleToolCall } from "@codespar/crewai";
const result = await handleToolCall(session, "codespar_charge", {
provider: "stripe",
amount: 4990,
currency: "BRL",
});Full agent loop
This is a complete example of a CrewAI crew using CodeSpar tools for commerce operations:
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/crewai";
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
async function run(userMessage: string) {
// 1. Create a session with the servers you need
const session = await codespar.create("user_123", {
servers: ["stripe", "asaas", "correios"],
});
// 2. Get tools in CrewAI format
const tools = await getTools(session);
// 3. Define your agents
const paymentAgent = {
role: "Payment Specialist",
goal: "Handle all payment operations for Brazilian e-commerce",
backstory: "Expert in Brazilian payment methods including Pix, boleto, and credit cards.",
tools,
};
const shippingAgent = {
role: "Shipping Coordinator",
goal: "Manage shipping and logistics across Brazil",
backstory: "Expert in Brazilian shipping via Correios and private carriers.",
tools,
};
// 4. Define tasks and create crew
const task = {
description: userMessage,
agent: paymentAgent,
expectedOutput: "A confirmation of the completed operation with details.",
};
// 5. Execute (using your CrewAI runtime)
// const crew = new Crew({ agents: [paymentAgent, shippingAgent], tasks: [task] });
// const result = await crew.kickoff();
// For manual execution:
for (const tool of tools) {
if (tool.name === "codespar_charge") {
const result = await tool.run({
provider: "stripe",
amount: 25000,
currency: "BRL",
description: "Order #1234",
});
console.log("Charge result:", result);
}
}
// 6. Clean up
await session.close();
}
await run("Process payment of R$250 via Pix for order #1234");Handling parallel tool calls
When multiple tools need to run concurrently, use Promise.all with the run method:
const results = await Promise.all([
tools.find((t) => t.name === "codespar_charge")!.run({
provider: "stripe",
amount: 4990,
currency: "BRL",
}),
tools.find((t) => t.name === "codespar_notify")!.run({
channel: "email",
to: "customer@example.com",
subject: "Payment received",
}),
]);Streaming
CrewAI supports step-by-step callbacks. Use handleToolCall in your callbacks to stream tool results:
import { CodeSpar } from "@codespar/sdk";
import { handleToolCall } from "@codespar/crewai";
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
const session = await codespar.create("user_123", {
servers: ["stripe"],
});
// In your crew step callback:
async function onToolCall(toolName: string, args: Record<string, unknown>) {
console.log(`Executing: ${toolName}`);
const result = await handleToolCall(session, toolName, args);
console.log(`Result:`, result.data);
return result;
}Error handling
Wrap tool.run() calls in try-catch and return errors as structured data:
for (const tool of tools) {
try {
const result = await tool.run(input);
console.log("Success:", result);
} catch (error) {
console.error(`Tool ${tool.name} failed:`, error instanceof Error ? error.message : error);
// Return error to the agent for reasoning
}
}Returning errors as tool results (instead of throwing) lets the agent reason about the failure and decide whether to retry with different parameters.
Best practices
-
Always close sessions. Use
try/finallyto ensuresession.close()runs even if the crew throws. -
Scope servers narrowly. Only connect the MCP servers your crew needs. Fewer tools improves agent accuracy.
-
Assign tools per agent. Give each agent only the tools relevant to its role instead of sharing all tools across agents.
-
Set clear goals. CrewAI agents work best with specific, measurable goals and clear backstories.
-
Return errors as results. Let agents reason about failures instead of crashing the crew.
-
Limit task delegation. Use
allow_delegation: falsefor simple tasks to prevent unnecessary back-and-forth between agents.
Newer SDK wrappers
getTools(session) is the agent-facing path. From any agent task or 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)andsession.paymentStatusStream(toolCallId)— async settlement correlation (poll or SSE).session.verificationStatus(toolCallId)andsession.verificationStatusStream(toolCallId)— KYC outcome polling / SSE.
Full reference at /docs/api/sdk.
Next steps
Last updated on