应用服务器控制代理 cas

CAS 技能是一个 Node 代理工具,用于控制 codex app-server,提供自动化友好的 JSONL 流 API,支持并行会话管理、自动审批处理、服务器请求转发和会话挖掘,适用于编程驱动应用服务器的自动化场景。关键词:App-Server Control, 自动化, 代理, JSONL, 并行实例, 会话挖掘, 编程驱动, 流 API。

DevOps 0 次安装 0 次浏览 更新于 3/8/2026

名称: cas 描述: 运行一个仅支持 v2 的 Node JSONL 代理,该代理会启动 codex app-server 并暴露一个自动化友好的流 API。在需要以编程方式驱动应用服务器(自动化/编排/会话挖掘)时使用,允许子代理向活跃会话发送更新或代码补丁,自动处理审批,以确定性超时转发服务器请求,通过 thread/* 挖掘会话,引导活动轮次 (turn/steer),或运行 N 个并行实例(每个实例是一个代理 + 一个 app-server 子进程)。

cas (应用服务器控制)

概述

Cas 附带一个小型 Node 代理 (scripts/cas_proxy.mjs),该代理:

  • 启动 codex app-server
  • 执行必需的交握 (initialize -> initialized),使用 experimentalApi: true 和可选的 optOutNotificationMethods
  • 通过 stdio 读写 JSONL。
  • 自动接受 v2 审批请求。
  • 将 v2 服务器请求转发给编排器。
  • 拒绝已弃用的旧版审批请求 (execCommandApproval, applyPatchApproval)。
  • 在超时时确定性地使转发请求失败(默认 30000 毫秒)。
  • 发出无损的、自动化友好的事件流(包括原始应用服务器消息加上派生的路由键)。

此技能假设 codex 在 PATH 中可用,且不需要访问任何仓库源代码树。

快速开始

CODEX_SKILLS_HOME="${CODEX_HOME:-$HOME/.codex}"
CLAUDE_SKILLS_HOME="${CLAUDE_HOME:-$HOME/.claude}"
CAS_SCRIPTS_DIR="$CODEX_SKILLS_HOME/skills/cas/scripts"
[ -d "$CAS_SCRIPTS_DIR" ] || CAS_SCRIPTS_DIR="$CLAUDE_SKILLS_HOME/skills/cas/scripts"

run_cas_tool() {
  local subcommand="${1:-}"
  if [ -z "$subcommand" ]; then
    echo "用法: run_cas_tool <smoke-check|instance-runner> [参数...]" >&2
    return 2
  fi
  shift || true

  local bin=""
  local marker=""
  local fallback=""
  case "$subcommand" in
    smoke-check)
      bin="cas_smoke_check"
      marker="cas_smoke_check.zig"
      fallback="$CAS_SCRIPTS_DIR/cas_smoke_check.mjs"
      ;;
    instance-runner)
      bin="cas_instance_runner"
      marker="cas_instance_runner.zig"
      fallback="$CAS_SCRIPTS_DIR/cas_instance_runner.mjs"
      ;;
    *)
      echo "未知的 cas 子命令: $subcommand" >&2
      return 2
      ;;
  esac

  if command -v "$bin" >/dev/null 2>&1 && "$bin" --help 2>&1 | grep -q "$marker"; then
    "$bin" "$@"
    return
  fi
  if [ "$(uname -s)" = "Darwin" ] && command -v brew >/dev/null 2>&1; then
    if ! brew install tkersey/tap/cas; then
      echo "brew install tkersey/tap/cas 失败; 拒绝静默回退。" >&2
      return 1
    fi
    if command -v "$bin" >/dev/null 2>&1 && "$bin" --help 2>&1 | grep -q "$marker"; then
      "$bin" "$@"
      return
    fi
    echo "brew install tkersey/tap/cas 未产生兼容的 $bin 二进制文件。" >&2
    return 1
  fi
  if [ -f "$fallback" ]; then
    node "$fallback" "$@"
    return
  fi
  echo "cas 二进制缺失且回退脚本未找到: $fallback" >&2
  return 1
}

run_cas_tool smoke-check --cwd /path/to/workspace --json

术语 (实例)

  • 一个“实例”是一个 cas_proxy 进程加上其启动的 app-server 子进程。
  • 每个实例有自己的 JSONL 流和自己的 sessionId
  • “N 实例”意味着 N 个并行代理+app-server 对;它不是在一个实例中的 N 个线程/轮次。
  • 隔离提示:对于多实例运行,如果不想实例共享状态,请首选每个实例的 --state-file(或运行器的 --state-file-dir)。

触发线索

  • “实例” / “多实例” / “并行会话”
  • 应用服务器控制 (JSONL 代理, JSON-RPC 方法)
  • 会话挖掘 (线程/轮次清单, 导出/索引)
  • 引导/恢复 (turn/steer, thread/resume)

工作流程

  1. 启动代理。

    • 从 cas 技能目录运行 node scripts/cas_proxy.mjs(或通过脚本路径解析:CODEX_SKILLS_HOME="${CODEX_HOME:-$HOME/.codex}"; CLAUDE_SKILLS_HOME="${CLAUDE_HOME:-$HOME/.claude}"; CAS_PROXY="$CODEX_SKILLS_HOME/skills/cas/scripts/cas_proxy.mjs"; [ -f "$CAS_PROXY" ] || CAS_PROXY="$CLAUDE_SKILLS_HOME/skills/cas/scripts/cas_proxy.mjs"; node "$CAS_PROXY")。
    • 可选:传递 --cwd /path/to/workspace 以控制 app-server 运行的位置。默认情况下,状态写入 ~/.codex/cas/state/<workspace-hash>.json
    • 可选:传递 --state-file PATH 以覆盖默认状态位置。
    • 可选:通过 --server-request-timeout-ms <N>(0 禁用超时)调整转发请求的快速失败行为。
    • 可选:控制 v2 审批自动响应(适用于安全的多实例工作器):
      • --exec-approval auto|accept|acceptForSession|decline|cancel
      • --file-approval auto|accept|acceptForSession|decline|cancel
      • --read-only(同时拒绝执行和文件审批的简写)
    • 可选:传递一个或多个 --opt-out-notification-method METHOD 标志以抑制连接中已知的嘈杂通知。
    • 等待 cas/ready 事件。

    对于并行 N 实例,首选实例运行器:

    • run_cas_tool instance-runner --cwd /path/to/workspace --instances N
  2. 通过向代理发送请求来驱动 app-server。

    • 向代理 stdin 发送 cas/request 消息(方法 + 参数)。
    • 代理分配请求 ID(除非您提供),转发给 app-server,并发出 cas/fromServer 响应。
    • 可选冒烟检查:运行 run_cas_tool smoke-check --cwd /path/to/workspace
  3. 流式和路由通知。

    • 消费 cas/fromServer 事件并通过 threadId / turnId / itemId 路由。
    • 将代理流视为真相来源;原始消息始终包含在 msg 下。
  4. 处理转发的服务器请求。

    • 仅当 cas 发出 cas/serverRequest 时回复(这些是 cas 未自动处理的服务器请求)。
    • 使用相同的 id 响应 cas/respond
    • 如果您的响应对于类型化 v2 请求格式错误,cas 会发送确定性 JSON-RPC 错误上游,而不是挂起。
    • 如果您未及时回复,cas 发出 cas/serverRequestTimeout 并使该请求上游失败。
    • 审批会自动接受(包括尽力执行策略修改)且不会阻塞您。
  5. 挖掘会话(可选)。

    • 使用 thread/list(游标分页 + 可选的 modelProviders/sourceKinds/archived/cwd 过滤器)和 thread/read(可选 includeTurns:true)构建您自己的索引。
    • 服务器不是搜索引擎;提取数据并在外部索引。

专用 API 助手

当您想要类型化意图而不是原始方法字符串时,使用 scripts/cas_client.mjs 便利包装器:

  • resumeThread(params) -> thread/resume
  • steerTurn(params) -> turn/steer
  • listExperimentalFeatures(params) -> experimentalFeature/list

动态工具 (可选)

如果您选择动态工具,请通过 dynamicToolsthread/start 上注册它们(实验性 API 表面)。 当服务器发出 cas/serverRequest 时:

  • 对于 method: "item/tool/call",在编排器中运行工具并用 cas/respond 回复。
  • 对于 method: "item/tool/requestUserInput"(实验性),收集答案并返回 { answers: ... }
  • 对于 method: "account/chatgptAuthTokens/refresh",返回刷新令牌或确定性错误。

代理 I/O 契约 (stdin/stdout)

代理本身通过 stdio 讲 JSONL。

stdin -> cas

  • cas/request 发送 JSON-RPC 请求到 codex app-server
{
  "type": "cas/request",
  "clientRequestId": "任意字符串",
  "method": "thread/start",
  "params": { "cwd": "/path", "experimentalRawEvents": false }
}
  • cas/respond 回答由 cas 转发的服务器发起的请求:
{
  "type": "cas/respond",
  "id": 123,
  "result": {
    "contentItems": [{ "type": "inputText", "text": "..." }],
    "success": true
  }
}
  • cas/send 转发原始 JSON-RPC 消息到 codex app-server(高级逃逸出口):
{
  "type": "cas/send",
  "msg": { "method": "thread/list", "id": "raw-1", "params": { "cursor": null } }
}
  • cas/state/get 发出当前代理状态。
  • cas/stats/get 发出统计快照(运行时间, 队列深度, 计数)。
  • cas/exit 关闭代理。

stdout <- cas

  • cas/ready 表示代理完成交握。
  • cas/fromServer 为每个来自 codex app-server 的 JSON 消息发出。
  • cas/toServer 为每个发送到 codex app-server 的 JSON 消息发出(包括自动审批和交握)。
  • cas/serverRequest 为需要编排器响应的服务器发起的请求(工具调用, 认证刷新等)发出。
  • cas/serverRequestTimeout 在转发的服务器请求因超时失败时发出。
  • cas/statscas/ioPaused/cas/ioResumed 帮助您监控背压。

所有事件包括:

  • seq(单调)
  • ts(自纪元以来的毫秒)
  • sessionId(每个代理实例唯一)
  • 当存在时派生键 threadId / turnId / itemId
  • msg(原始应用服务器消息; 无损)

规范模式来源

使用您安装的 codex 二进制文件生成与您的版本匹配的模式:

codex app-server generate-ts --out DIR
codex app-server generate-json-schema --out DIR

# 如果您需要实验性方法/字段(例如动态工具),包括:
codex app-server generate-ts --experimental --out DIR
codex app-server generate-json-schema --experimental --out DIR

本地参考

阅读 references/codex_app_server_contract.md 以获取控制地图和推荐的路由/响应策略。

资源

references/

实现期间的快速查找控制笔记。

scripts/

可运行的 Node 代理用于编排。

包含:

  • scripts/cas_proxy.mjs(代理)
  • scripts/cas_client.mjs(JS 包装器:启动代理 + request() + 事件流)
  • scripts/budget_governor.mjs(助手:速率限制 -> 每窗口步调 + 更严格层级钳位)
  • scripts/cas_rate_limits.mjs(CLI: 打印归一化的 account/rateLimits/read 快照)
  • scripts/cas_example_orchestrator.mjs(示例编排脚本)
  • scripts/cas_instance_runner.mjs(在许多并行 cas 会话/实例中运行一个方法)
  • scripts/cas_smoke_check.mjs(冒烟检查 experimentalFeature/list, thread/resume, turn/steer

Zig CLI 的运行时引导策略镜像 seq:首选已安装的二进制文件;在 macOS 上使用 brew 时,将 brew install tkersey/tap/cas 失败(或不兼容二进制文件)视为硬错误;否则回退到本地 Node 脚本。