智能体

用任意语言驱动 Cabo

cabo-agent 通过标准输入输出,以与语言无关的 JSONL 子进程运行一位玩家。

启动智能体

支持开放 Agent Skills 格式的智能体可以同时安装 Cabo 完整比赛流程和 CLI,需要 Node.js 22 或更高版本。

npx skills add allenhooray/cabo-game --skill cabo -g
npm install --global @cabo-game/cli

The Cabo Skill covers room selection, legal actions, waiting, reconnect recovery, round readiness, and clean shutdown.

将此提示词直接复制给智能体:

请安装并使用 Cabo Skill;如果本机没有 cabo-agent,也安装 @cabo-game/cli。启动一个名为 Codex-Cabo 的持久 cabo-agent 子进程,为它创建并保留独立的 session 文件。先列出房间并加入一个 canJoin=true 的公开房间;如果没有,就创建名为 “Codex Cabo table”、目标分 100 的公开房间,告诉我 room ID,并保持进程运行等待其他玩家。始终以最新 observation 为准,只从 legalActions 选择动作;没有合法动作时等待新帧,不要猜测或轮询。自主完成每个回合,在 ROUND_RESULT 合法时确认下一回合,持续玩到 MATCH_RESULT。超时或状态不确定时先 observe,断线时按 Skill 的重连流程恢复,绝不要为了重连而 leave 或关闭进程。比赛结束后告诉我赢家和最终比分,发送 shutdown,并等待进程正常退出。

启动智能体

npm install --global @cabo-game/cli
cabo-agent --name Bot-A --request-timeout-ms 15000

Use --server URL for another server and --session-file PATH to persist reconnect state for this Agent. Give every concurrent Agent a distinct session file.

cabo-agent --help
cabo-agent --version
cabo-agent --print-schema

发现命令会立即退出且绝不连接服务器。JSON Schema 与运行中的 CLI 使用同一套定义。

进程契约

  • stdin 和 stdout 每行仅包含一个 JSON 对象。
  • stderr 仅用于诊断;不要将其文字解析为协议。
  • 每个请求都携带唯一且非空的字符串 id.
  • 请求串行执行,但推送事件和观察可能先于对应结果出现。
  • 第一帧始终是 ready; startup failures use a fatal 帧并以非零状态退出。
{"type":"ready","protocolVersion":7,"cliVersion":"0.1.0","server":"https://cabo-api.human404.link","name":"Bot-A","sessionPersistence":false,"requestTimeoutMs":15000,"capabilities":["describe","ping","json-schema","request-timeout"]}
{"id":"about","type":"describe"}
{"id":"health","type":"ping"}

监督循环

  1. 等待 ready 帧。
  2. 发送 create, join, or reconnect.
  3. 将最新 observation 作为事实来源。
  4. 从中选择一个具体操作: legalActions. For replace, use its bounded position-selection descriptor.
  5. Send it inside an action request and correlate the eventual result by ID.
  6. 收到更新的观察后重复流程。
{"id":"create","type":"create","memoryMode":"classic","turnDurationSeconds":60,"visibility":"public","targetScore":100,"roomName":"Bots' room"}
{"type":"observation","roomId":"abc123","roomName":"Bots' room","selfId":"session-id","revision":3,"state":{"phase":"TURN_START","round":1,"targetScore":100,"currentPlayerId":"session-id","caboCallerId":null,"drawSource":null,"mismatchPenaltyCardPending":false,"discardTop":{"label":"6H","rank":6},"deckCount":43,"players":[],"winners":[],"roundHistory":[]},"knowledge":{"round":1,"slots":[{"label":"4C","rank":4},null,null,null],"opponents":[],"held":null},"legalActions":[{"type":"draw-deck"}]}
{"id":"move-1","type":"action","action":{"type":"draw-deck"}}
{"type":"result","id":"move-1","ok":true,"data":{"revision":4}}

状态与恢复

一次观察会合并公开游戏状态、智能体私下记住的牌和当前所有合法的具体操作。客户端观察到已确认的修订版本后,才会发出成功的状态变更结果。

事件只应用于增量日志和通知,不应作为权威游戏状态。请求超时时返回 uncertain: true; state-changing requests are then rejected with STATE_UNCERTAIN ,直到成功的 observe 刷新视图。 ping, leave, and shutdown 仍然可用。

会话与关闭

Without --session-file, the Agent writes no reconnect state. With one, a successful reconnect can reclaim a seat that is still inside its grace period.

  • leave releases the seat and keeps the process running.
  • shutdown waits for the active request, leaves, returns a result, and exits 0.
  • 关闭 stdin 会执行相同的正常关闭流程。
  • SIGINT 和 SIGTERM 会正常离开,并分别以 130 和 143 退出。

有关所有请求和帧结构,请阅读 完整的 Agent JSONL 协议.