@ codespar/ sdk 代码
AI代理商的SDK——会议、管理认证、拉丁美洲商业API的完整循环管弦乐.
0.9中运出的东西
目前放行为0.10;下注为0.9换行,保存以供参考.
八种新打入的方法 Session按能力分类:
元工具包装符 ——中性输入外形,打出的有效载荷回放,同同线 session.execute(...)数字 :
session.charge(args)- INBOUND费用codespar_charge) (中文(简体) ). 买家付商人. Pix BRL通过Asaas / MP / iugu / Stone;卡片美元通过Frede. 与codespar_pay(境外转让).session.ship(args)——航运codespar_ship) (中文(简体) ). 1个打入了Melhor Envio的3个铁路(action: "label" | "quote" | "track") (中文(简体) ).session.shop(args)- 购买方购物(codespar_shop) (中文(简体) ). 目录搜索 → 同步检出 → Pix 薄荷 (action: "search" | "checkout" | "checkout_status") (中文(简体) ). 歧视ShopArgs编号 :ShopResult给出动作正确结果类型。 退票是Async:开始,然后是民意调查checkout_status直至ready_for_payment(卡车)pix_copia_e_cola)或(或)canceled. 通过单独的支付工具解决返回的Pix——结算和治理不在本合同中。 全谱:docs/codespar-shop-contract.md。 。 。 .
Async 结算 —— 说 codespar_charge 编号 : codespar_pay 同步返回,但真实的定居土地通过webhook:
session.paymentStatus(toolCallId)调查最新已知状况(待定) 成功/失败/退款。 通过响应等效性 key \\ 提供者外部 引用 .session.paymentStatusStream(toolCallId, { onUpdate?, signal? })——SSE变种. 打开快照,每个状态变化一个信封,每15秒心跳,在终端状态后自动关闭5秒.signal从呼叫方中止 .
同步验证 —— 说 codespar_kyc 返回查询 id; 买方完成主机平台外流量:
session.verificationStatus(toolCallId)调查处置情况(待批准/驳回/审查/已过期).session.verificationStatusStream(toolCallId, { onUpdate?, signal? })——SSE变种. 与paymentStatusStream。 。 。 .
工具发现 + 连接向导 (已在0.4.0中重报完整):
session.discover(query, options?)——语义+词典工具搜索横跨目录(codespar_discover, pgvector + pg trgm)). 维基百科中的相关条目: 维基语录链接,存档副本.session.connectionWizard(options)——连接深链接后端(codespar_manage_connections) (中文(简体) ). 证书从不通过这种方法.
所有包装器调用相同的运行时间 session.execute(...); 获得打入的有效载荷, 而不是手滚动元工具信封.
已输入的元工具外观( T)
shop(), (中文(简体) ),charge(), (中文(简体) ),ship(),.)是客户,而不是执行. 每个都是薄薄的包裹execute("codespar_<tool>", args)并且需要运行时间 执行 工具(合同背后的注册执行)。 与没有注册的运行时间相对应,呼叫返回Tool not registered。合同 + 这里的打字外观船 MIT; 执行在您指定的运行时间注册baseUrl临τ.
加密 + KYC 元工具
codespar_crypto_pay (Coinbase Commerce + Bitso + UnblockPay + Foxbit) 和 (中文(简体) ) codespar_kyc (Persona, Sift, Konduto, Truora) 今天的路由。 核查部分现在有一个打字包(session.verificationStatus 编号 : verificationStatusStream页:1 session.cryptoPay(...) 已打入的包装器不是0.9.0——通过原始调用 session.execute("codespar_crypto_pay", {...}) 现在.
// Crypto: receive a USDC payment via Coinbase Commerce hosted checkout
const charge = await session.execute("codespar_crypto_pay", {
amount: 29.9,
currency: "USDC",
direction: "receive",
description: "Order #42",
});
// charge.output.hosted_url → redirect buyer here
// Crypto: send a USDC payout to an external wallet (UnblockPay stablecoin-payout)
const payout = await session.execute("codespar_crypto_pay", {
rail: "stablecoin-payout",
amount: 100,
currency: "USDC",
direction: "send",
counterparty: {
address: "0xRecipientWalletAddress...",
country: "MX", // ISO 3166-1 alpha-2 — required when direction is "send"
},
});
// payout.output.id / .status → poll via session.paymentStatus(payout.tool_call_id)
// KYC: kick off a Persona identity verification, then poll typed
const inquiry = await session.execute("codespar_kyc", {
buyer: { email: "[email protected]", first_name: "Alice", last_name: "Smith" },
check_type: "identity",
});
const v = await session.verificationStatus(inquiry.tool_call_id);
// ^^ approved | rejected | review | expired | pending
安装
npm install @codespar/sdk
使用量
import { CodeSpar } from "@codespar/sdk";
const cs = new CodeSpar({ apiKey: "ak_..." });
const session = await cs.create("user_123", {
preset: "brazilian",
manageConnections: { waitForConnections: true },
// projectId: "prj_a1b2c3d4e5f6g7h8", // optional — overrides client default, falls back to org's default project
});
// Natural language
const result = await session.send("Charge R$150 via Pix and issue the NF-e");
// Direct tool execution
const charge = await session.execute("asaas/create_payment", {
customer: "cus_xxx",
billingType: "PIX",
value: 150,
});
// Complete Loop — tools, findTools, and loop are free functions
import { tools, findTools, loop } from "@codespar/sdk";
const available = await tools(session);
const payments = await findTools(session, "payment");
const result = await loop(session, {
steps: [
{ tool: "codespar_charge", params: { amount: 150, currency: "BRL", method: "pix", buyer: { name, document: cpf } } },
{ tool: "codespar_invoice", params: (prev) => ({ rail: "nfe", company_id, payment_id: prev[0].data.id }) },
{ tool: "codespar_ship", params: { action: "label", origin, destination, items } },
{ tool: "codespar_notify", params: { recipient: phone, message: "Your order is on the way!" } },
],
onStepComplete: (step, r) => console.log(`✓ ${step.tool}`),
retryPolicy: { maxRetries: 3, backoff: "exponential" },
});
API 密码
new CodeSpar(config)
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
apiKey | string | CODESPAR_API_KEY 环境 | 您的 API 键 |
baseUrl | string | CODESPAR_BASE_URL 否则 https://api.codespar.dev | API 基础 URL. 设定 CODESPAR_BASE_URL=http://localhost:8000 将SDK指向一个 当地开放源码软件运行时间; 管理后端为默认. |
managed | boolean | true | 启用管理下的计费/ 日志 |
projectId | string | —— 说 | 可选 prj_<16alphanum>。全客户端默认项目;作为 x-codespar-project。省略时会回到 Org 的默认项目. |
cs.create(userId, config)
| 选项 | 类型 | 说明 |
|---|---|---|
servers | string[] | 要连接的 MCP 服务器 |
preset | string | "brazilian", (中文(简体) ), "mexican", (中文(简体) ), "argentinian", (中文(简体) ), "colombian", (中文(简体) ), "all" |
manageConnections.waitForConnections | boolean | 屏蔽直到所有服务器连接 |
projectId | string | 可选 prj_<16alphanum>。覆盖客户端 projectId; 当两者均未被设置时, 倒回到 org 的默认项目 . |
mocks | Record<string, MockValue> | 可选测试模式取笑. 见 测试模式模拟。 。 。 . |
会议方法
| 方法 | 说明 |
|---|---|
session.execute(tool, params) | 执行特定工具 |
session.send(message) | 发送自然语言信息 |
session.sendStream(message) | 从自然语言信息流出的事件 |
session.authorize(serverId) | 为服务器启动 OAuth 流量 |
session.proxyExecute(request) | 通过会话代理原始 HTTP 呼叫 |
session.connections() | 列出已连接的服务器 |
session.discover(query, options?) | 通过工具搜索 codespar_discover (类型) |
session.connectionWizard(options) | 通过连接深链接 codespar_manage_connections (类型) |
session.charge(args) | 通过入境收费 codespar_charge (类型)——买方向商人付款 |
session.ship(args) | 通过 codespar_ship (类型) - action: "label" | "quote" | "track" |
session.paymentStatus(toolCallId) | 自动结算状态 codespar_charge 编号 : codespar_pay 调用 |
session.paymentStatusStream(toolCallId, opts) | SSE 变种 paymentStatus; 终端解析 |
session.verificationStatus(toolCallId) | Async KYC 处理 codespar_kyc 调用 |
session.verificationStatusStream(toolCallId, opts) | SSE 变种 verificationStatus; 终端解析 |
session.mcp | MCP 传输 URL 和信头( 当使用管理的运行时间时) |
session.close() | 闭会 |
API在会话表层外的 REST 上暴露的一切 从 OpenAPI 文档生成的 REST 客户端。 。 。 .
免费函数
tools, (中文(简体) ), findTools,以及 loop 是接受任何 SessionBase 他们与管理下的运行时间、管理下的代理会议和定制的运行时间合作.
| 函数 | 说明 |
|---|---|
tools(session) | 从会话中获取所有可用的工具 |
findTools(session, query) | 按名称或描述分列的搜索工具 |
loop(session, config) | 运行完整循环工作流程 |
付款文件和批次
cs.payables 上传 boleto PDF、 Pix QR 图像和 CSV/XLSX 列表,构建一个
并支付你审查过的确切名单。 目的地是那个
已解析( 受益名称、 被遮盖的文档) , 且空白的 Pix 键永远不会
设定金额.
import { readFile } from "node:fs/promises";
import { CodeSpar, payableBatchFromError } from "@codespar/sdk";
const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
const file = await cs.payables.files.upload(await readFile("conta.pdf"), { filename: "conta.pdf" });
let batch = await cs.payables.batches.create(
{ fileIds: [file.file_id], items: [{ pixKey: "[email protected]", amountMinor: 5000 }] },
{ idempotencyKey: "batch-2026-10-24-001" },
);
// Complement what the files did not say, then pay the list you reviewed.
const missing = batch.items.find((i) => i.missing.includes("amount"));
if (missing) {
batch = await cs.payables.batches.updateItem(batch.batch_id, missing.item_id, {
expectedVersion: batch.version,
amountMinor: 1990,
});
}
try {
batch = await cs.payables.batches.pay(batch.batch_id, {
version: batch.version,
listHash: batch.list_hash,
mandateId: "mdt_example",
});
} catch (err) {
const current = payableBatchFromError(err); // 409: the list changed, confirm again
if (!current) throw err;
}
for (const item of batch.items) console.log(item.item_id, item.payment?.state);
从 OpenAPI 文档生成的 REST 客户端
cs.api 到达 API 出版的每个操作
https://api.codespar.dev/openapi.json数字 :
215次行动横跨175道 在快照本版本的舰只。 没有
方法用手书写。 该文件承诺
openapi-snapshot.json,下划为类型 src/generated/ 生产
从它中取出openapi-typescrip,客户端按路径和
方法: 不声明方法不编译的路径, a
缺少所需的路径参数或正文字段不编译
结果是文件 2xx 形状.
import { CodeSpar } from "@codespar/sdk";
const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
// 1. List wallets in the project the key is bound to.
const wallets = await cs.api.get("/v1/wallets");
// 2. Create a payment from a wallet. The gateway answers 200 (completed),
// 402 (requires approval), 403 (denied) or 422 (failed) with the same
// body shape, so read it with response() and branch on status.
const payment = await cs.api.response("post", "/v1/wallets/{id}/execute", {
path: { id: "wal_example" },
body: {
amount: 1,
currency: "BRL",
recipient: "[email protected]",
description: "Example payment",
mandate_id: "mnd_example",
},
});
if (payment.status === 402) {
console.log("approval needed", payment.data);
}
// 3. Read one agentic receipt by id.
const receipt = await cs.api.get("/v1/consumers/receipts/{id}", {
path: { id: "rcpt_example" },
});
console.log(receipt.state); // "paid" | "delivered" | "exception" | "voided"
get编号 :post编号 :put编号 :patch编号 :delete 财务报告和审定财务报表 request(method, path, options)
返回所记录的 2xx 数据并丢弃 CodesparApiError 关于任何其他
状态( 已解析 e.body,与会话方法相同).
response(method, path, options) 返回时 { status, ok, data, response }
所列出的每一种状况 status选项
携带 path, (中文(简体) ), query, (中文(简体) ), header 财务报告和审定财务报表 body 与文档完全相同
宣布,加上SDK全程呼叫 timeout 财务报告和审定财务报表 signal。 。 。 .
业务记录 text/event-stream 决 定
Response 一旦信头到达.
客户只知道文件上写了什么 参数一个路径
接受但不声明不在此键入; 固定在
文档,不在此软件包中. createApiClient(config) 构造相同
无客户端 CodeSpar 实例,以及 ApiClient.operations() 列表
所达到的.
保持当前状态 : npm run sdk:spec:refresh (repo root) 重排
文件和再生; npm run sdk:spec:check 失败当
当生成的文件不匹配时, 快照被手工编辑
快照,或者服务文档不再匹配快照时.
测试套间把前两套钉上 并发送所有215个操作
通过客户端.
从0.2.x移走
tools, (中文(简体) ), findTools,以及 loop 0.3.0中从会话实例方法移到释放函数.
// 0.2.x
const tools = await session.tools();
const found = await session.findTools("payment");
const result = await session.loop({ steps: [...] });
// 0.3.0
import { tools, findTools, loop } from "@codespar/sdk";
const available = await tools(session);
const found = await findTools(session, "payment");
const result = await loop(session, { steps: [...] });
多种环境(项目)
代码Spar orgs有第二层租赁层—— 项目 ——所以 dev / controduction / prod 每一个都得到孤立的 API 密钥,连接的账户,触发器,和会话,同时计费时会停留在 org 级别. 每个请求都接受一个选项 x-codespar-project: prj_<16 hex> 头;省去后端解决了org的默认项目(先读后自愈).
将整个客户端绑入一个环境 :
const cs = new CodeSpar({
apiKey: process.env.CODESPAR_API_KEY!,
projectId: "prj_staging0123abcd", // every session this client spawns scopes here
});
或取消每个会话 :
const session = await cs.create("user_123", {
preset: "brazilian",
projectId: "prj_prod0123abcd", // overrides the client default
});
优先发言: sessionConfig.projectId > 翻译: clientConfig.projectId >后端的org默认值. 格式通过 Zod 验证(/^prj_[A-Za-z0-9]{16}$/)所以打字失败快. 见 项目概念文件 完全租赁模式.
测试模式模拟
在测试中跳过直播提供者通过 a mocks 地图到 cs.create键是划线形式的犬形工具名称(asaas/create_payment, (中文(简体) ), melhor-envio/calculate_shipping(中文(简体) ). 值要么是单个对象——作为每个匹配呼叫的响应——要么是按顺序消耗的一系列对象,返回 mocks_exhausted 一旦名单排出.
import { CodeSpar } from "@codespar/sdk";
const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
const session = await cs.create("user_test", {
servers: ["asaas"],
mocks: {
"asaas/create_payment": { id: "pay_test", status: "PENDING" },
},
});
const result = await session.execute("asaas/create_payment", { value: 100 });
// result.data === { id: "pay_test", status: "PENDING" }
通过数组进行状态模拟 :
mocks: {
"asaas/create_payment": [
{ id: "pay_1", status: "PENDING" },
{ id: "pay_1", status: "RECEIVED" },
],
}
模具住在管理后端的测试模式门后——a csk_test_* API 密钥对齐 a test- 环境项目。 对同一地图返回的活键 mocks_not_permitted。SDK将密钥逐字转发;如果发送OSS双下分数格式(asaas__create_payment后端拒绝使用 mocks_invalid 而不是SDK悄悄地改写.
OSS运行时间接受相同的 mocks 形状 API(参见 代码/代码# 113),所以同样的测试固定装置不管你指向 api.codespar.dev 或自主办实例 CODESPAR_BASE_URL自办运行时间必须另作安排 CODESPAR_TEST_MODE_ENABLED=true ; 没有它, SDK 接收 mocks_not_permitted / HTTP 501 而不是固定响应.
存储形状因运行时间而异——电线合同没有. 管理后端持续使用模拟和每个工具消耗计数器;会话及其固定装置在重启和多平台部署后幸存. OSS运行时间既持有进程内存;它们被范围化为HTTP会话进程,并在重启时丢失;通道-桥会话(WhatsApp, Slack, Telegram, Discord)不能在OSS外形下携带模拟. 反应信封,状态代码,兄弟字段,和出道门订购,无论运行时间如何,都是同字节. 见 测试模式概念文件 每跑一次的全票.
测试模式是运行时间的属性,而不是会话. 在管理后端是 project.environment === 'test'在自办的OSS运行时间 CODESPAR_TEST_MODE_ENABLED=true 在服务器进程上。 当运行时间处于测试模式时,每个外部工具调用您的代码或 LLM 调度必须匹配一个已声明的模拟器—— 无匹配的调用返回 tool_not_mocked (HTTP 422在目录上) /execute 路径; a tool_result 块在聊天-浏览器上),没有上游提供者运行。 该信封涵盖三种失败模式: mocks 映射没有关于 cononic 名称的条目, 会话创建时没有 mocks 字段,或词条名称有一个未知的服务器前缀。 一个不宣布的会话 mocks 无法在测试模式下发送任何工具; 声明模拟测试会锻炼, 或运行相同的代码, 对应一个实时模式运行时间, 由真正的提供者处理发送 。 内建元数据工具 - codespar_list_tools 在开放源码软件上, codespar_discover 财务报告和审定财务报表 codespar_manage_connections 在管理的后端上——绕过此门.
类型别名
MockObject (单位:千美元)Record<string, unknown>和 MockValue (单位:千美元)MockObject | MockObject[](从 @codespar/types 并通过 @codespar/sdk。当您想要定义模拟定着和模拟定着时使用它们 create 呼叫现场.
import type { MockValue } from "@codespar/sdk";
const fixtures: Record<string, MockValue> = {
"asaas/create_payment": { id: "pay_test", status: "PENDING" },
};
输入错误
每一次运输故障 createSession, (中文(简体) ), proxyExecute, (中文(简体) ), send, (中文(简体) ), sendStream, (中文(简体) ), paymentStatus(Stream), (中文(简体) ), verificationStatus(Stream),以及 authorize 丢出一个 CodesparApiError 结构化 code 字段。 旧的 e.message.includes("foo") 模式已消失 e.code 换句话说.
import { CodesparApiError } from "@codespar/sdk";
try {
await cs.create("user_test", { mocks: { "asaas/create_payment": {} } });
} catch (err) {
if (err instanceof CodesparApiError) {
if (err.code === "mocks_not_permitted") {
// Live key against a mocks map. Swap to csk_test_*.
} else if (err.code === "mocks_invalid") {
// Backend rejected a tool-name key. Check the slash form.
} else if (err.status === 0) {
// Network never reached the backend; err.cause has the fetch rejection.
}
throw err;
}
}
session.execute 保持返回- vs- 扔出不对称: 工具失败返回为 ToolResult.success === false 尸体打开 error。只有运输级别的故障.
工具结果警卫
五个保留的工具-结果代码(policy_denied, (中文(简体) ), approval_required, (中文(简体) ), mocks_exhausted, (中文(简体) ), mocks_engine_error, (中文(简体) ), tool_not_mocked(b) 船型警卫加上一个详尽无遗的辅助人员。 卫兵对阵任何 unknown 有效载荷——两者 ToolResult.data 从 session.execute 财务报告和审定财务报表 ToolCallRecord.output 从 send 编号 : sendStream每个警卫检查 code 歧义和变体需要的双胞胎球场,所以一个畸形的有效载荷返回虚假,而不是仅仅缩小代码上的正数.
import {
isApprovalRequired,
isMocksEngineError,
isMocksExhausted,
isPolicyDenied,
isToolNotMocked,
assertExhaustiveToolResult,
ToolResultCode,
} from "@codespar/sdk";
const result = await session.execute("asaas/create_payment", { value: 100 });
if (isPolicyDenied(result.data)) {
console.warn(`blocked by ${result.data.rule_id}: ${result.data.message}`);
} else if (isApprovalRequired(result.data)) {
console.log(`needs approval ${result.data.approval_id} by ${result.data.expires_at}`);
} else if (isMocksExhausted(result.data)) {
// Stateful mock array drained — pad it or extend the test.
} else if (isMocksEngineError(result.data)) {
// Backend-side mocks engine failure; usually a malformed fixture.
} else if (isToolNotMocked(result.data)) {
console.warn(`no mock for ${result.data.tool_name}`);
}
同一警卫适用a sendStream 循环对齐 event.toolCall.output。 。 。 .
当a switch 结束 ToolResultCode 覆盖每个变体,呼叫 assertExhaustiveToolResult 在默认分支中。 TypeScript 如果第六个代码没有匹配的手臂而降落,则无法编译 .
function handle(outcome: ToolResultOutcome): string {
switch (outcome.code) {
case ToolResultCode.PolicyDenied: return outcome.rule_id;
case ToolResultCode.ApprovalRequired: return outcome.approval_id;
case ToolResultCode.MocksExhausted: return "exhausted";
case ToolResultCode.MocksEngineError: return "engine";
case ToolResultCode.ToolNotMocked: return outcome.tool_name;
default: return assertExhaustiveToolResult(outcome);
}
}
还需要吗?
需要治理、预算限制和代理付款的审计线索? 代码Spar 企业 在这些MCP服务器上添加了政策引擎,支付路由,以及合规模板.
许可证
麻省理工学院 - 代码.dev