@band-ai/band-sdk-core

中文文档
6.2.0发布于 2026/11/06SEE LICENSE IN LICENSETypeScriptCommonJS零依赖近 30 天下载 2416

共享带状事件负载验证

中文使用文档
文档目录17 节
  1. 安装
  2. 快速启动
  3. 公众表面
  4. validateEventPayload(eventType, raw, traceContext?)
  5. 交付状态运行时间班
  6. SubscriptionTracker 生命周期
  7. DecisionRegistry 生命周期
  8. Session —— WebSocket 重接状态机
  9. Session 生命周期
  10. validateMemoryTypeForSystem(system, type, traceContext?)
  11. 假设内存- 分类值
  12. 一发投递生命周期
  13. 转出结果
  14. 构建/ 测试
  15. 会议室活动观察
  16. 许可证
  17. 栅栏交付结算

@ band-ai/ band-sdk- core (英语)

共享带状事件负载验证、内存分类和入境交付 运行时状态,从 Rust 编译为 Web Assembly for Node. 每个函数 是同步、纯粹的计算——没有网络、文件系统或日志.

band-sdk-core (Rust)  -->  @band-ai/band-sdk-core (this package, npm)  -->  band-sdk-typescript

如果你在用的话 band-sdk-typescript, (中文(简体) ), 它已经取决于这个软件包——你不需要安装它 你自己来 直接安装它,只有你调用它没有这个 SDK(英语:SDK). 完整图片 : 仓库架构。 。 。 .

安装

npm install @band-ai/band-sdk-core

软件包是Node CommunityJS, 装有急切的WASM载荷—— 没有 init 步骤,没有rust或 wasm-pack 需要安装工具链。 两者 require() 和无害环境管理 import() 解决它.

快速启动

const { validateEventPayload } = require("@band-ai/band-sdk-core");

try {
  const payload = validateEventPayload("room_deleted", { id: "room-1" });
} catch (err) {
  for (const { path, code, message } of err.issues) {
    console.error(`${path}: ${code} - ${message}`);
  }
}

validateEventPayload 该平台的入境WebSocket有效载荷政策: 使成型有效载荷正常化,或与所报告的每一次违反行为一起投出 有一次,从来没有只是第一次.

公众表面

validateEventPayload(eventType, raw, traceContext?)

eventType 是平台事件名称( y)"message_created", (中文(简体) ), "agent.control"(中文(简体) ). raw 是一个简单的JS价值。 成功返回 正常有效载荷event_created 返回输入后不变。 失败 丢出本地 Error 与 .issues (单位:千美元){path, code, message} 对象) 财务报告和审定财务报表 .traceContext ——不是只写消息的错误. 没有习俗 例外课.

交付状态运行时间班

ClaimRegistry, (中文(简体) ), RetryTracker, (中文(简体) ), ParticipantRoster,以及 SubscriptionTracker 这是 国家课程——生命周期和设计决定 每个类型都以生锈器的形式生活 crates/core/src/runtime/。 。 。 .

参与方是指任何普通物体; add编号 :setAll 读取 id, (中文(简体) ), name, (中文(简体) ), type, (中文(简体) ), handle, (中文(简体) ), description 从它和 list() 返回对象为 就是这五把钥匙. id 需要并且必须是字符串; 另一个 四个是每个字符串,或者 null- /缺席. setAll 选择 traceContext 和扔出——保持名册不变 .issues 财务报告和审定财务报表 .traceContext 附加类似 validateEventPayload'错误——如果是 相同的快照名称 id 两次. RetryTracker是因为 maxTracked 必须是 起码 1· ; 0 掷出. ClaimRegistry是因为 maxCompleted 必须是在 最少数 1 还有.. 0 还投出.

ClaimRegistry 每个信件保留一个终端意图,直到 rememberCompleted 或匹配 confirmSettlement数字 : rememberAckPending 记录已处理的书写和 rememberFailedAckPending 失败者携带 error。第一个 意向取胜; 投出不同的投出——使条目不变 .issues 财务报告和审定财务报表 .traceContext 重复为 没有. pendingAck 返回时 {status, error?, parked} 或者说 undefined。 。 。 . parkAck 使用一个 ParkedReason 电线名称, parkedReasons() 列出他们, 和任何其他值抛出平原 Error。 。 。 .

SubscriptionTracker 提供同步、独立的运输决定 代理主题和两个主题的房间订阅交易。 它不透明 门票为 JavaScript bigint 值,在记录时必须提供 已完成。 失败回滚和失败或未知的叶子需要明确 在允许重新提出索赔之前进行核对.

SubscriptionTracker 生命周期

import { SubscriptionTracker } from "@band-ai/band-sdk-core";

const tracker = new SubscriptionTracker();
const ticket = tracker.beginRoomSubscribe("room-1");
if (ticket === undefined) throw new Error("room is not claimable");

switch (tracker.recordRoomParticipantsJoinFailed("room-1", ticket, false)) {
  case "rollback_failed":
    if (tracker.roomStatus("room-1") !== "needs_reconciliation") {
      throw new Error("rollback state was not retained");
    }
    tracker.acknowledgeRoomReconciled("room-1");
    const retryTicket = tracker.beginRoomSubscribe("room-1");
    if (retryTicket === undefined) throw new Error("reconciled room is not claimable");
    if (tracker.recordBothRoomTopicsJoined("room-1", retryTicket) !== "subscribed") {
      throw new Error("room did not subscribe");
    }
    const leaveTicket = tracker.unsubscribeRoom("room-1");
    if (leaveTicket === undefined || !tracker.markRoomLeaveComplete("room-1", leaveTicket, "left")) {
      throw new Error("room did not leave");
    }
    break;
  case "subscribed":
  case "join_failed":
  case "rolled_back":
  case "stale":
    break;
}

DecisionRegistry 生命周期

DecisionRegistry 音轨聊天中介问:谁先声称拥有 结果。 每一份登记结果 [token, ticket],与 ticket (单位:千美元) bigint,然后叫名字 准确的注册,所以一个呆滞的持有者 获得 "stale" 而不是在新人身上行动 要求重新使用该标志. maxPending 必须是至少是一个整数 1,或省略/省略null 页:1 未受约束; seed 是可选的 bigint。 。 。 . cancelAll编号 :cancelRoom 返回 a 简单 { unclaimed, claimed } 对象. isAuthorizedSender 需要一个阵列, (单位:千美元) Set,或 null。 。 。 .

import { DecisionRegistry, isAuthorizedSender } from "@band-ai/band-sdk-core";

const registry = new DecisionRegistry(10);
const registration = registry.registerMinted("room-1");
if (registration === undefined) throw new Error("tickets exhausted");
const [token, ticket] = registration;

if (registry.tryClaim(token, ticket) !== "claimed") throw new Error("not claimed");
if (registry.tryClaim(token, ticket) !== "already_claimed") throw new Error("claimed twice");
if (registry.cancelRoom("room-1").claimed[0] !== token) throw new Error("claim not reported");
if (!isAuthorizedSender(new Set(["alice"]), "alice")) throw new Error("alice refused");

Session —— WebSocket 重接状态机

Session编号 :SessionPolicy 是 sans-io 会话状态机器 + 重新连接后退/减速政策; classifyClose编号 :classifyUpgrade 分类一个 WebSocket 关闭代码或 HTTP 升级-拒绝状态. Session 永不入睡、连接或关闭套接字本身——呼叫者 开着自己的运输车 并报告所发生的一切 onConnected编号 : onSocketClose编号 :onUpgradeRejected编号 :onSupersede它的时代票是 Java 脚本 bigint 数值,匹配 SubscriptionTracker's. 决定 像生锈地一样生活 crates/core/src/runtime/session.rs。 。 。 .

Session 生命周期

import { Session, SessionPolicy } from "@band-ai/band-sdk-core";

const session = new Session(SessionPolicy.default());
const epoch = session.beginAttempt(0.0);
if (epoch === undefined) throw new Error("fresh session must yield an epoch");

const connected = session.onConnected(epoch, 0.0);
if (connected.state !== "up") throw new Error("expected up");

const disconnected = session.onSocketClose(epoch, 5.0, 1006, 0.5);
if (disconnected.state !== "reconnecting") throw new Error("expected reconnecting");
if (disconnected.retryAfterS === undefined) throw new Error("expected a retry delay");

validateMemoryTypeForSystem(system, type, traceContext?)

验证 Cononical 内存分类学——设计决定活性 生锈道 crates/core/src/memory.rs。 。 。 . system 财务报告和审定财务报表 type 是线名字符串( r)MemorySystem编号 :MemoryType 内 index.d.ts 属于字符串升数类型,而不是类——没有运行时间 在这个边界上, 匹配方式 EventType 保留一个简单的字符串 validateEventPayload) (中文(简体) ). 回返 void 在成功方面。 失败投出 本地语言 Error 同样的 .issues编号 :.traceContext 合同为 validateEventPayload - 一个未获承认的 system 和未承认的 type 独立问题,两个字符串都报告 无效。 下方列出“ 假设内存- 分类值 ” enum的成员没有介绍.

假设内存- 分类值

memorySystems(), (中文(简体) ), memoryTypes(), (中文(简体) ), memorySegments(), (中文(简体) ), memoryStoreScopes(), (中文(简体) ), memoryListScopes(),以及 memoryStatuses() 每回那条铁丝网 名称为 string[],按照声明顺序——运行时间计数,不 引入类,匹配 MemorySegment编号 :MemoryStoreScope编号 : MemoryListScope编号 :MemoryStatus 作为字符串-升类型 index.d.ts。 。 。 .

import { memorySystems, memoryStatuses } from "@band-ai/band-sdk-core";

if (!memorySystems().includes("sensory")) {
  throw new Error("memorySystems() missing sensory");
}
if (!memoryStatuses().includes("active")) {
  throw new Error("memoryStatuses() missing active");
}

一发投递生命周期

evaluateDeliveryEvent, (中文(简体) ), evaluateNextMessage, (中文(简体) ), evaluateDrainCandidate,以及 evaluateAdapterResult 是无国籍的一发子弹 交付生命周期 ——设计决定作为生动的 crates/core/src/runtime/delivery.rs。每个返回一个普通标记对象; 这里没有交叉召集国 所以这里没有可以建造的阶级. 决策字段保留了蛇 case(消息线词汇: room_id, (中文(简体) ), sender_id, (中文(简体) ), sender_type,...),不同于这个模块自己的骆驼Case 函数/参数名称,所以相同的形状从两个函数返回到相同的 装订.

evaluateDeliveryEvent(eventType, roomId, payload, agentId, traceContext?) 路径 : "ignored" 未确认或范围外的 eventType· ; "cleanup" 页:1 room_removed编号 :room_deleted· ; "skip_self" 或者说 "invocation" 页:1 message_created,取决于发送者是否 此代理( r)sender_type === "Agent" 财务报告和审定财务报表 sender_id === agentId) (中文(简体) ). message_created 代表团 validateEventPayload 有效载荷形状 验证,所以不正确 payload 抛出相同的 Error,以及 附加拒绝空的 payload.id - 一个没有身份的信息 不能要求或承认. room_removed编号 :room_deleted 需要没有 有效载荷形状并读取 id 直接卸下原始载荷.

roomId 由呼叫者提供的解析 roomId 首先,否则有效载荷的 拥有 chat_room_id (信息事件)或 id (房间活动). 空字符串 这两步都缺席。 无法解答 Error 只有一个问题 路径 room_id代码 missing 当后退场缺位或空出时, wrong_type 当它存在但不是一个字符串.

evaluateNextMessage(triggeringMessageId, nextMessageId) 比较 触发针对平台权威的"下一个打开消息"的信息 一个房间 "no_pending", (中文(简体) ), "already_processed",或 "ready_to_claim"。 。 。 .

evaluateDrainCandidate(candidate, seenIds, agentId) 分类一个 已经很困难的排水候选人—— candidate 实值 {id, sender_id, sender_type},或 null编号 :undefined 当采集到没有返回时: "no_candidate", (中文(简体) ), "self_echo" (快照前检查过,所以回声) 永不停息地排水, "out_of_snapshot" (停车),或 "drain" (续). 呼叫者自有限制或无限制的循环拥有上限; 此功能 每通电话将一名候选人分类.

evaluateAdapterResult(roomId, messageId, succeeded) 映射适配器 成果 "processed" 或者说 "failed"。 。 。 .

isSelfEcho(senderId, senderType, agentId) 是一个定义: "自我回声"(英语:senderType === "Agent" && senderId === agentId这 evaluateDeliveryEvent 财务报告和审定财务报表 evaluateDrainCandidate 内部使用, 曝光给主机本身的呼叫站点, 将发送者分类而不进行 通过任一函数.

转出结果

TurnLedger - 设计决定以铁道为主 crates/core/src/turn.rs。每转一转, record 页:1 TurnEffect 联 合 国 每个成功的工具呼叫(一个失败的呼叫记录无),并要求 verdict() 当模型停止时: "complete" 一旦转弯, 拒绝,或做真正的工作, 否则 "missing_reply" (转弯时) missingReplyMessage()) (中文(简体) ). settle() sDK自己回答说 noteReported() 一个已经报告失败的人,两人都完成. replySettled() 实值 true 曾经有录音的电话贴入房间或 拒绝,所以没有退后文本到期. record 抛出平原 Error 页:1 除了一个 TurnEffect 线名.

bandToolEffects() 将每个条形带工具名称映射到它的 TurnEffect· ; 正常化化的化名 与它的犬名 在检查前. noReplyTool() 返回时 band_no_reply定义为 ToolSpec (单位:千美元)name, (中文(简体) ), description, (中文(简体) ), parameters) (中文(简体) ). turnEffects() 财务报告和审定财务报表 turnVerdicts() 列出电线名称.

import { TurnLedger, bandToolEffects } from "@band-ai/band-sdk-core";

const ledger = new TurnLedger();
ledger.record(bandToolEffects().band_send_event);
if (ledger.verdict() !== "missing_reply") {
  throw new Error("an observe-only turn is a missing reply");
}

ledger.record("reply");
if (ledger.verdict() !== "complete" || !ledger.replySettled()) {
  throw new Error("a reply must complete the turn");
}

公开声明是: index.d.ts。 。 。 .

构建/ 测试

just check 为主机编译并涂上这个箱子 .

just test-wasm   # suite in Node
just pack-npm    # Node tarball + require/import consumers
just build-wasm  # Node package output

会议室活动观察

normalizeRoomActivitySnapshot(raw, selfAgentId, traceContext?) 接受 包含 working_agents 返回已输入本地 RoomActivityPeer 对象。 它会验证所有行, 保存最后的复制 代理/执行密钥,按代理/执行方式排除自我和类型 先说 输出省略了执行ID. 缺少细节和未知字符串类型 成为推理; 错误的字段抛出 Error 与 issues 财务报告和审定财务报表 traceContext峡谷野规则在Rust上直播 normalize_room_activity_snapshot。 。 。 .

import { normalizeRoomActivitySnapshot } from "@band-ai/band-sdk-core";

const peers = normalizeRoomActivitySnapshot({working_agents: [
  {agent_id: "peer", working: true, activity: {kind: "tool_call", name: "search"}},
]}, "self");
if (peers[0].activity.kind !== "tool_call" || peers[0].activity.name !== "search") {
  throw new Error("expected peer tool declaration");
}

输入必须是 JSON 内置: 来自任意域的平面对象(包括无原型) 对象)具有数据属性,密集数组,有限度的JavaScript Number 数值 和 Unicode scalar 字符串。 未定义的值, 稀有的数组, 连接器、符号、非无限数字和孤独的UTF-16代用符 Error 在损失转换之前。 最大深度为64 (root 0), 有 65 536 值和 UTF-8 字符串内容的 1 MiB ,包括密钥和字符串参数. 额外的字段也会被检查 。 循环和过度输入安全拒绝. 每通电话都是独立的;SDK拥有I/O并可用. 本意见 没有提供锁或证明对等方没有工作.

许可证

专有、二进制的乐队SDK许可证协议——见捆绑 自由主义。 Rust 执行来源是私人的.

栅栏交付结算

guardedClaim 共享跨发现路径的资格。 其任择事实 对象接受布尔 self_echo, (中文(简体) ), durably_processed, (中文(简体) ), durably_failed,以及 allow_failed_retry 字段。 仅 allow_failed_retry 默认为真实。 未知 字段和非布尔值在所有权改变前抛出.

在停放时,待发原件仍被排除在外。 记录终端处置 在运输前,并在接受和当前执行检查后确认. (一) 重试确认恢复带有更严格重试上限的企图; 它不会错误地完成原件。 托肯斯是不透明的本地字符串.

import { ClaimRegistry, RetryTracker } from "@band-ai/band-sdk-core";

const claims = new ClaimRegistry();
const previous = new RetryTracker(3);
if (claims.guardedClaim("room", "message", previous) !== "runnable") throw new Error("not admitted");
previous.recordAttempt("message");
const pending = claims.recordFailedSettlement("room", "message", "failure", previous, true);
claims.release("room", "message");
const current = new RetryTracker(3);
if (!claims.confirmSettlement("room", "message", pending.token, current)) throw new Error("not confirmed");
if (claims.isCompleted("room", "message")) throw new Error("retry falsely completed");
if (current.recordAttempt("message")[0] !== 2) throw new Error("charge lost");

版本与发布记录

@band-ai/band-sdk-core 共发布 38 个版本,首次发布于 2026/08/21;过去 12 个月发布了 38 个版本。

版本发布日期距今
6.2.0latest2026/11/062 天前
6.1.22026/11/025 天前
6.1.12026/10/2612 天前
6.1.02026/10/2613 天前
6.0.02026/10/2513 天前
5.0.02026/10/1919 天前

其他发布通道:dev → 0.4.0-dev.2。

关于 @band-ai/band-sdk-core 的常见问题

@band-ai/band-sdk-core 是什么?

共享带状事件负载验证

如何安装 @band-ai/band-sdk-core?

在项目目录运行 npm install @band-ai/band-sdk-core,或使用 pnpm add / yarn add / bun add。

@band-ai/band-sdk-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@band-ai/band-sdk-core 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@band-ai/band-sdk-core 可以商用吗?

@band-ai/band-sdk-core 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@band-ai/band-sdk-core 的下载量有多少?

根据 npm 官方下载统计,@band-ai/band-sdk-core 在 2026/10/08 – 2026/11/06 这 30 天内被下载 2,416 次,日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@band-ai/band-sdk-core 还在维护吗?

最新版本 6.2.0 发布于 2026/11/06(2 天前);至今共发布 38 个版本,其中过去 12 个月发布了 38 个;首次发布于 2026/08/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。