@@ -1,548 +1,195 @@
# CST-Agent
C11 OpenCode-like carrier that extends paper **CST ** (confirmation frontier / irreversible emission) from Markdown→HTML to the **agent tool loop ** .
本地 coding agent:终端 TUI、可选 WebUI / 桌面 GUI,在工作区里读改文件、跑命令、管会话。
C11 实现,OpenAI 兼容网关(DeepSeek / Kimi / MiniMax / OpenAI 等)。
See [docs/theory_tool_cst.md ](docs/theory_tool_cst.md ).
评测/反哺论文素材:[ docs/eval_tool_cst.md ]( docs/eval_tool_cst.md ) 。
**适合 ** :有监督的本地改动与仓库探索(权限确认、diff、`/undo` 、沙箱)。
**慎用 ** :完全无人值守的长任务;headless 默认自动批准 。
## 能不能用来工作?
文档索引:[docs/README.md ](docs/README.md )。
**可以 ** :有监督的本地改动 / 探索仓库(TUI + 13 个内置工具 + 带 diff 的权限确认 + `/undo` )。
**不宜 ** :无人值守长任务或当 CI 主力(网关偶发空答;headless 模式默认自动批准)。
---
### 5 分钟试用
## 安装
### Linux / WSL / macOS(推荐)
``` bash
# Linux / WSL / macOS 一键:克隆到 ~/CST-agent、编译、装到 ~/.local/bin
# 预编译包(快;失败则自动回退源码编译)
curl -fsSL https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/bootstrap_linux.sh | bash -s -- --release
# 或始终从源码增量编译安装到 ~/.local/bin
curl -fsSL https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/bootstrap_linux.sh | bash
# 已有仓库目录内(装到别处:CST_AGENT_PREFIX=/usr/local)
./scripts/bootstrap_linux.sh .
# 以后升级:拉取最新代码、重新编译并安装(本地有未提交改动时跳过 pull)
cst-agent-update
cst-agent --version
# 在项目目录里直接启动:首次会让你选 provider 并输入 API key(遮罩输入,按 provider 保存)
cd ~/my-project && cst-agent
```
不想编译:[Release ](https://git.whcself.xyz/WHC/CST-agent/releases ) 里有静态链接的 Linux 单文件
( `cst-agent-VERSION-linux-{x86_64,x86,aarch64}.tar.gz` ,musl,任何发行版都能直接跑),解压后把 `cst-agent`
放进 `PATH` 即可;每个文件旁边有 `.sha256` 。
已有仓库目录:
Windows 10 1903+( PowerShell,不需要管理员):
``` bash
./scripts/bootstrap_linux.sh . # 源码
./scripts/bootstrap_linux.sh . --release # 只装 Release 二进制
cst-agent-update # 之后升级
cst-agent --version
```
[Release ](https://git.whcself.xyz/WHC/CST-agent/releases ) 也提供静态 musl 包
`cst-agent-VERSION-linux-{x86_64,x86,aarch64}.tar.gz` (旁有 `.sha256` ),解压后把 `cst-agent` 放进 `PATH` 即可。
### Windows 10 1903+
``` powershell
irm https : / / git . whcself . xyz / WHC / CST-agent / raw / branch / main / scripts / install_windows . ps1 | iex
# 新开终端后:cd 到项目目录运行 cst-agent;升级用 cst-agent-update
```
也可以下载 Release 里的安装包 `cst-agent-VERSION-windows-x86_64-setup.exe` (按用户安装、自动加 PATH、
开始菜单有 WebUI 入口),或便携版 zip。详见 [docs/README-windows.md ](docs/README-windows.md )。
一键脚本可以重复运行:已有仓库会 `git pull --ff-only` , **增量编译**后重新安装(`CST_AGENT_CLEAN=1` 才强制 clean);
同时装 `cst-agent-update` 与 `cst-agent-service` (议会席位服务辅助)。NixOS 上会自动进 `nix-shell` 编译。
之后再启动会沿用上次的 provider、模型和推理强度(low / medium / high / max),不需要任何参数或环境变量。
界面里用 `/provider` 切换(没保存过 key 的会当场询问),`/model` 、`/effort` 切换模型和推理强度,`/key` 更换 key。
完整环境变量说明:[docs/env_openai.md ](docs/env_openai.md )。
多设备议会(密码 Realm / 主席 / 常驻同步):[docs/parliament.md ](docs/parliament.md )。
| 平台 | 一键脚本 |
|---|---|
| Linux | [`scripts/bootstrap_linux.sh` ](scripts/bootstrap_linux.sh ) |
| Termux | [`scripts/bootstrap_termux.sh` ](scripts/bootstrap_termux.sh ) |
| Windows 安装 / 升级 | [`scripts/install_windows.ps1` ](scripts/install_windows.ps1 )(从 Release 安装),之后 `cst-agent-update` |
| Linux 静态发行包(musl 交叉) | [`scripts/package_linux.sh` ](scripts/package_linux.sh ) `x86_64\|x86\|aarch64` → `dist/*.tar.gz` |
| Windows 交叉构建(在 Linux 上) | [`scripts/bootstrap_windows.sh` ](scripts/bootstrap_windows.sh ) → `dist/windows-x86_64/` 、zip 和安装包 |
| Windows 原生构建(MSYS2 UCRT64) | [`scripts/bootstrap_msys2.sh` ](scripts/bootstrap_msys2.sh ) → `dist/windows-x86_64/` |
### 迷你验收工程(论文案例)
故意带 bug 的小计算器:[`fixtures/mini_calc/` ](fixtures/mini_calc/ )(任务书 `TASK.md` )。
``` bash
./scripts/e2e_mini_calc.sh --baseline-only # 无 API:证明初始测试 RED
./scripts/e2e_mini_calc.sh --provider deepseek --protocol ctl # 有 key
```
更多夹具(每个都有 `TASK.md` + `check.sh` ):`makefile_tab` (写含 TAB 的 Makefile)、
`big_file` (写 5000 字节文件)、`test_fix_test` (先跑测试→修→再跑测试)、
`multi_file_refactor` (跨文件改名 + 修 bug,适合 `edit_file` / `grep` )、
`ask_or_todo` (必须用 `todo_write` 规划并全部完成;无人回答 `ask_user` )。
后两个需要 `--tools default` (脚本默认 `minimal` ,即论文用的 4 个工具)。
``` bash
scripts/e2e_fixture.sh makefile_tab --provider deepseek --protocol native-inc
scripts/e2e_fixture.sh multi_file_refactor --provider deepseek --tools default
# 批量实验:协议 x 模型 x 夹具 x N 次 → results.csv + summary.md
scripts/run_matrix.sh -p "native-eos native-inc ctl ctl-heredoc xml" \
-m "deepseek:deepseek-flash deepseek:deepseek-v4-pro" -n 3 -r
```
口径:`pass` / `fail` / `agent_error` / `timeout` — 见 [docs/eval_tool_cst.md ](docs/eval_tool_cst.md )。
## Build
### Make( Linux 默认)
``` bash
cd CST-agent
make -j$( nproc) # 增量编译;头文件依赖走 -MMD,测试复用 libcstcore.a
make -j$( nproc) check # 并行编测试二进制,再串行跑
make asan # AddressSanitizer + UBSan 构建并跑全部测试
make CC = tcc AR = ar check # TinyCC:整套构建 + 测试十几秒(CI 的校验就是这条)
make install PREFIX = $HOME /.local # 或 sudo make install(默认 /usr/local)
make install-service PREFIX = $HOME /.local # 可选:systemd --user 议会服务单元
```
NixOS: `nix-shell --run 'make -j$(nproc) && make install PREFIX=$HOME/.local'` ( CLI);Qt 桌面用 `nix-build` / `cst-agent-app` 。
macOS: `brew install curl ncurses pkg-config` 后直接 `make` ( Makefile 会找 Homebrew 的 keg-only 库)。
各平台细节与验收清单见 [docs/compat.md ](docs/compat.md )。
### CMake(推荐跨编译器 / 交叉)
``` bash
# GCC
cmake -B build-gcc -DCMAKE_C_COMPILER= gcc -DCST_BUILD_TUI= ON
cmake --build build-gcc && ctest --test-dir build-gcc
# Clang
cmake -B build-clang -DCMAKE_C_COMPILER= clang -DCST_BUILD_TUI= ON
cmake --build build-clang
# Headless only(无 ncurses)
cmake -B build-hd -DCST_BUILD_TUI= OFF && cmake --build build-hd
# Windows:用一键脚本(见下方“Windows 发行包”),会先编译静态依赖
./scripts/bootstrap_windows.sh
```
依赖:`gcc` 、`clang` 或 `tcc` ( 0.9.27 mob 以上)、`libcurl` 、TUI 需 `ncursesw` ( Windows 版用打过补丁的 ncurses 6.6,脚本自动编译)。
### 桌面 GUI( Qt/QML,可选)
把引擎放进同一个进程的窗口前端(无端口、无第二个进程):`app/` ,细节见 [app/README.md ](app/README.md )。
``` bash
# NixOS / nix:装进用户 profile( PATH + 菜单项 + 图标),卸载 nix profile remove cst-agent
nix profile add --file .
# 其他发行版(需要 Qt 6 的 Quick/Qml/QuickControls2 与 libcurl)
cmake -B build-app -DCST_BUILD_APP= ON -DCMAKE_BUILD_TYPE= Release
cmake --build build-app -j && cmake --install build-app --component app --prefix ~/.local
```
菜单里启动时工作区=启动目录(即 `$HOME` );在项目目录里 `cst-agent-app` 启动则工作区就是那个目录。
Sashidown( `vendor/sashidown` )与 cJSON( `vendor/cjson` , MIT)已随仓库提供。
API Key: TUI 里输入并按 provider 保存到配置目录的 `credentials` (权限 0600);`/key` 更换,`--ask-key` 在命令行输入。
`--api-key` 只用于本次进程、不落盘;`DEEPSEEK_API_KEY` 等环境变量和 `CST_API_KEY` 仅作为没有保存 key 时的兜底(方便 CI)。
## 平台支持矩阵
| OS | Arch | 编译器 | Headless | TUI | Shell |
|---|---|---|---|---|---|
| Linux( glibc / musl) | x86_64 / x86 / aarch64 | GCC, Clang, TinyCC | yes | ncursesw | `/bin/sh` 或旁路 `busybox` |
| WSL2 | x86_64 | 同 Linux | yes | ncursesw | `/bin/sh` (工作区建议放在 Linux 文件系统内) |
| macOS | arm64 / x86_64 | Apple Clang | yes | ncurses( Homebrew) | `/bin/sh` |
| Android Termux | aarch64 / … | Clang (Termux) | yes | ncurses( Termux 包) | `$PREFIX/bin/sh` ;可旁路 busybox |
| Windows 10 1903+ | x86_64 | MinGW-w64 GCC( UCRT) | yes | ncurses 6.6( Windows 控制台) | **捆绑 busybox-w32 ** |
### WebUI( `--web`)
同一个二进制内置一个 HTTP + SSE 前端:`cst-agent --web` (默认 `http://127.0.0.1:8787/` )。
它和 TUI 是同一引擎的两个前端,浏览器里能流式看回答、点审批、切会话、贴图。
协议是一份稳定的 JSON + SSE 接口,供以后的专用客户端复用。详见 [docs/webui.md ](docs/webui.md )。
``` bash
cst-agent --web # 本机浏览器打开 http://127.0.0.1:8787/
cst-agent --web --web-port 0 # 端口交给系统,启动日志里给 URL
cst-agent --web --web-dev ./web # 开发前端:直接读目录,改完刷新
cst-agent --web --web-host 0.0.0.0 --web-token 口令 # 手机/局域网访问
sh scripts/e2e_webui.sh # 用录制流跑完整轮次,不需要 API key
```
不带 TUI 的构建也可以开 WebUI(`cmake -DCST_BUILD_WEBUI=ON -DCST_BUILD_TUI=OFF` );
`-DCST_BUILD_WEBUI=OFF` 时 `--web` 只打印一条提示。
或下载 `cst-agent-VERSION-windows-x86_64-setup.exe` / 便携 zip。详见 [ docs/README-windows.md ]( docs/README-windows.md )。
### Termux
``` bash
# 一键:装依赖、克隆到 ~/CST-agent、编译、安装到 $PREFIX/bin
curl -fsSL https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/bootstrap_termux.sh | bash
# 以后升级(重跑上面那条也一样)
cst-agent-update
# 或手动
pkg install git clang make pkg-config binutils libcurl ncurses
git clone https://git.whcself.xyz/WHC/CST-agent.git && cd CST-agent
make && make install # 装到 Termux 的 $PREFIX/bin,之后任意目录运行 cst-agent
# 可选:旁路 Unix busybox
# ./scripts/build_third_party_mingw.sh busybox-unix
```
环境:`PREFIX` 自动用于找 `sh` ; `CST_EXE_DIR` / `argv[0]` 用于定位旁路 busybox( `/proc/self/exe` 受限时)。
临时目录:依次试 `$TMPDIR` 、`$PREFIX/tmp` 、`/tmp` 、`/var/tmp` 、`~/.cache/cst-agent/tmp` ,用第一个真能建文件的,
并写回 `TMPDIR` 给 shell 子进程和沙箱用(Termux 的 `/tmp` 常常不存在或被 SELinux 拒绝)。
### Linux 静态发行包
### 第一次用
``` bash
scripts/package_linux.sh x86_64 # 或 x86 / aarch64; CST_LINUX_CHECK=1 顺便跑 make check
cd ~/my-project && cst-agent
```
用 Bootlin 的 musl 交叉 gcc(固定版本、校验 sha256)静态编译 mbedTLS、curl 8.22(只开 HTTP/HTTPS)和宽字符 ncurses,
再以 `STATIC=1` 和 `-Werr or` 编出 `cst-agent` ,产物是 `dist/cst-agent-VERSION-linux-ARCH.tar.gz` ( + `.sha256 `) 。
宿主需要 `cmake ninja make perl` 以及 `tic` /`infocmp` 和终端条目(Debian: `ncurses-bin ncurses-term` )。
ncurses 会去常见目录找 terminfo,找不到时用编进去的 `xterm-256color` 、`xterm` 、`screen-256color` 、`tmux-256color` 、`linux` 、`vt100` 。
CA 证书:`CST_CA_BUNDLE` → `SSL_CERT_FILE` → 各发行版的常见位置(Debian/Ubuntu、Fedora/RHEL、openSUSE、Alpine)。
首次选择 provider 并输入 API key(遮罩输入,按 provider 存到配置目录 `credentials` ,权限 0600)。
之后用 `/provider` 、 `/model` 、 `/eff ort `、 `/key` 切换;选择会记在 `settings.json ` 。
### Windows 发行包
完整环境变量:[docs/env_openai.md ](docs/env_openai.md )。
多设备议会:[docs/parliament.md ](docs/parliament.md )。
见 [docs/README-windows.md ](docs/README-windows.md )(安装、编码、沙箱、构建、已知限制)。
``` bash
./scripts/bootstrap_windows.sh # Linux 交叉编译;Windows 上在 MSYS2 UCRT64 里用 scripts/bootstrap_msys2.sh
```
产物:`dist/windows-x86_64/` (静态链接的 `cst-agent.exe` + `busybox.exe` ,无其他 DLL)、
`dist/cst-agent-VERSION-windows-x86_64.zip` ,以及装了 `makensis` 时的安装包 `dist/cst-agent-VERSION-windows-x86_64-setup.exe` 。
### CI 与 Release
`.gitea/workflows/ci.yml` : TinyCC 校验(构建、`make check` 、WebUI 端到端)通过后,用 gcc(`-Werror` )打发行包——
Linux x86_64 / x86 / aarch64 静态包(前两者跑 `make check` , aarch64 用 qemu 冒烟),
Windows x86_64 的 zip 和安装包(Debian mingw-w64 UCRT + NSIS)。
推送到 `main` 或 `v*` tag 时各任务经 `scripts/ci_publish.sh` 上传到 Gitea Release `vVERSION` (同名资源会被替换);
仓库可设 `RELEASE_TOKEN` ( `write:repository` ),否则用任务自带 token。
共用逻辑在 `scripts/lib_release.sh` (版本号、sha256、打包、下载镜像)。
本地:`GITEA_TOKEN=... scripts/release.sh dist/cst-agent-*.tar.gz dist/cst-agent-*.zip dist/cst-agent-*-setup.exe` 。
快速安装预编译包:`scripts/bootstrap_linux.sh --release` (失败则回退源码编译)。
环境变量:`CST_SHELL` 、`CST_EXE_DIR` 、`CST_AUTO_APPROVE` 等。
## Defaults (API)
`--provider` (或 `CST_PROVIDER` )选择预设;显式的 `--api-base` / `--model` / 环境变量优先。
| provider | API Base | 默认模型 | Key 变量 |
|---|---|---|---|
| `minimax` (默认) | `https://api.minimax.cn/v1` | `MiniMax-M2.7` | `MINIMAX_API_KEY` |
| `deepseek` | `https://api.deepseek.com/v1` | `deepseek-flash` (另有 `deepseek-v4-pro` ) | `DEEPSEEK_API_KEY` |
| `kimi` | `https://api.moonshot.ai/v1` | `kimi-k3` (另有 `kimi-k2.6` 、`kimi-k2.7-code` ) | `MOONSHOT_API_KEY` |
| `kimi-code` | `https://api.kimi.ai/coding/v1` | `k3` (另有 `k3-256k` 、`kimi-for-coding` 、`kimi-for-coding-highspeed` ) | `KIMI_API_KEY` |
| `openai` | `https://api.openai.com/v1` | `gpt-4.1-mini` | `OPENAI_API_KEY` |
| `teamorouter` | `https://api.teamorouter.com/v1` | 登录后自动取 `/models` 第一个(`/model` 可换) | `TEAMOROUTER_API_KEY` |
| 用途 | 来源(优先级从高到低) |
| 平台 | 脚本 |
|---|---|
| Provider | `--provider` → `CST_PROVIDER` → 上次使用 → `minimax` |
| Key | `--api-key` → 已保存的 key( `credentials` )→ provider 的 Key 变量 → `CST_API_KEY` → TUI 询问 |
| Base(含 `/v1` ) | `--api-base` → `CST_API_BASE` → `OPENAI_BASE_URL` → `OPENAI_API_BASE` → 预设 |
| Model | `--model` → `CST_MODEL` → `OPENAI_MODEL` → 该 provider 上次使用的模型 → 预设 |
| 推理强度 | `--effort` → `CST_EFFORT` → 上次使用 → `medium` |
| Linux / macOS | [ `scripts/bootstrap_linux.sh` ]( scripts/bootstrap_linux.sh ) |
| Termux | [ `scripts/bootstrap_termux.sh` ]( scripts/bootstrap_termux.sh ) |
| Windows 安装 | [ `scripts/install_windows.ps1` ]( scripts/install_windows.ps1 ) |
| Linux 静态包 | [ `scripts/package_linux.sh` ]( scripts/package_linux.sh ) `x86_64\|x86\|aarch64` |
| Windows 交叉构建 | [ `scripts/bootstrap_windows.sh` ]( scripts/bootstrap_windows.sh ) |
| Windows 原生(MSYS2) | [`scripts/bootstrap_msys2.sh` ](scripts/bootstrap_msys2.sh ) |
“上次使用”记在配置目录的 `settings.json` ( TUI 里切换时更新;headless 运行不改它)。
推理强度会按 provider 适配:DeepSeek/OpenAI 使用 `reasoning_effort` , Kimi K3 使用同名字段,Kimi K2 使用 `thinking` 并保留 `reasoning_content` 。Kimi 默认开启 1 小时隐式 prompt cache,可用 `CST_KIMI_CACHE_TTL=5m|1h` 调整,或用 `CST_NO_CACHE_HINTS=1` 关闭提示。
---
Kimi 与 DeepSeek 还提供官方联网工具:`web_search` 调用 provider 的 Search API, `web_fetch` 调用 provider 的 Fetch API;其它 provider 继续使用通用 HTTP 抓取。
`kimi` 是按量计费的 Kimi 开放平台,`kimi-code` 是会员订阅的 Kimi Code API;两者的 Base URL 和 API Key 不通用。
详见 [docs/env_openai.md ](docs/env_openai.md )。
| 变量 | 作用(默认) |
|---|---|
| `CST_PROTOCOL` / `--protocol` | 工具调用协议(`native-eos` ) |
| `CST_TOOLS` / `--tools` | 工具集:`default` (全部)/ `minimal` (论文 4 件套) |
| `CST_MODE` / `--mode` | 工作模式:`coding` (默认,代码口径)/ `general` (通用助手口径) |
| `CST_EFFORT` / `--effort` | 推理强度 `low` / `medium` / `high` / `max` |
| `CST_CONFIRM` / `--confirm` | 哪些类别要确认:`shell,write,net` (默认)或 `none` |
| `CST_MAX_STEPS` / `--max-steps` | 每个用户回合最多调用模型几次(30) |
| `CST_TOOL_OUT_CAP` | 单个工具输出发给模型的字节上限(16384,保留头 60% + 尾 40%) |
| `CST_CTX_WINDOW` | 发给模型的最近非 system 消息条数(80) |
| `CST_CTX_TOKENS` / `CST_AUTO_COMPACT=0` | 覆盖模型上下文窗口大小 / 关闭自动压缩(用到 75% 时自动 `/compact` ) |
| `CST_NO_PROJECT_NOTES=1` | 不把工作区的 `AGENTS.md` 注入 system prompt |
| `NO_COLOR` / `CST_ASCII=1` | 关闭颜色 / 强制 ASCII 图形(非 UTF-8 终端自动退化) |
| `CST_SHELL_TIMEOUT` | `run_shell` 超时秒数(默认不限),设了才在超时后整组杀进程,exit=124 |
| `CST_METRICS=0` / `CST_METRICS_PATH` | 关闭 / 指定计时埋点 JSONL(默认 `.agent/metrics/<session>.jsonl` ) |
| `CST_RECORD_SSE=DIR` / `CST_REPLAY_SSE=DIR` | 录制 / 回放原始 SSE 流(`NNNN.sse` + `NNNN.req.json` ) |
| `CST_APPROVAL=ask\|auto\|yolo` / `CST_SANDBOX=off\|landlock\|seccomp` | 审批模式 / 关闭沙箱(回落到只读白名单规则)或只用指定沙箱 |
| `CST_CA_BUNDLE` | HTTPS 用的 CA 证书文件(默认:`SSL_CERT_FILE` 、libcurl 自带路径、常见发行版位置;Windows 用系统证书库) |
| `CST_MODELS` 、`CST_AUTO_APPROVE=1` 、`CST_SHELL` 、`CST_EXE_DIR` | 模型列表、自动批准(= yolo)、shell、旁路 busybox |
## Run
## 构建
``` bash
# TUI(工作目录 = 当前目录;Assistant Markdown 经 Sashidown CST 渲染)
cst-agent
make -j$( nproc) # 增量;有 ccache 会自动用;make help 看目标
make -j$( nproc) check # 单元测试
make asan # ASan + UBSan
make CC = tcc AR = ar check # TinyCC 快校验(CI 同款)
make install PREFIX = $HOME /.local
make install-service PREFIX = $HOME /.local # 可选:systemd --user 议会单元
```
# Local CTL demo (no API)
cst-agent --demo-ctl
NixOS: `nix-shell --run 'make -j$(nproc)'` 。macOS: `brew install curl ncurses pkg-config` 后直接 `make` 。
平台细节:[docs/compat.md ](docs/compat.md )。
# 在命令行输入并保存当前 provider 的 key(不回显)
``` bash
# CMake(多编译器 / 无 TUI)
cmake -B build -DCMAKE_C_COMPILER= gcc -DCST_BUILD_TUI= ON
cmake --build build -j && ctest --test-dir build --output-on-failure
```
可选 Qt 桌面前端:[app/README.md ](app/README.md )。
Android APK: [docs/android.md ](docs/android.md )。
### CI 与发布
推送 `main` / `v*` 时 [`.gitea/workflows/ci.yml` ](.gitea/workflows/ci.yml ) 会:TinyCC `check` → 打 Linux/Windows 发行包 → `scripts/ci_publish.sh` 上传 Gitea Release。
共用逻辑:[`scripts/lib_release.sh` ](scripts/lib_release.sh )。本地上传:`GITEA_TOKEN=... scripts/release.sh dist/cst-agent-*` 。
---
## 用法速览
``` bash
cst-agent # TUI,工作区=当前目录
cst-agent --web # 浏览器 http://127.0.0.1:8787/
cst-agent --headless --prompt '…' # 无人值守(默认自动批准)
cst-agent --ask-key --provider deepseek
# Headless(默认 auto-approve shell/写文件)
cst-agent --headless --prompt 'List files'
```
会话相关命令行参数:
| 参数 | 作用 |
|---|---|
| `-c` / `--continue` | 打开上次的会话(默认行为) |
| `-N ` / `--new ` | 开新会话 |
| `-R ID` / `--resume ID` | 打开指定会话(完整 id 或唯一前缀 ) |
| `-L` / `--list-sessions` | 列出会话(时间、条数、标题)后退出 |
| `--migrate-store` | 把旧版本的会话(扁平 `<id>.jsonl` )搬进新布局后退出 |
| `-A MODE` / `--approval MODE` | 审批模式 `ask` / `auto` (默认)/ `yolo` ,见下文 |
| `-y` / `--yolo` | 等同 `--approval yolo` ,只对本次运行有效 |
| `-C LIST` / `--confirm LIST` | 需要确认的类别:`shell,write,net` 的任意组合或 `none` |
| `-T PROFILE` / `--tools PROFILE` | `default` 或 `minimal` |
| `-M MODE` / `--mode MODE` | 工作模式 `coding` (默认)/ `general` ,也读 `CST_MODE` ,并记进 `settings.json` |
| `-P NAME` / `-m NAME` / `-e LEVEL` | 本次使用的 provider / 模型 / 推理强度(不传则用上次的) |
| `-a` / `--ask-key` | 在命令行输入并保存当前 provider 的 key |
| `-c` / `-N` / `-R ID` / `-L` | 继续上次 / 新会话 / 恢复 / 列表 |
| `-A ask\|auto\|yolo ` / `-y ` | 审批模式 |
| `-T default\|minimal` | 工具集( `minimal` = 读写 shell 四件套 ) |
| `-M coding\|general` | 工作模式 |
| `-P` / `-m` / `-e` | provider / 模型 / 推理强度 |
| `-w DIR` | 工作区 |
工作目录默认就是当前 目录( `-w DIR` 可指定别的目录) 。
会话 目录: `<workspace>/.agent/sessions/<uuid>/` (自带 `.gitignore` )。WebUI 协议:[ docs/webui.md ]( docs/webui.md ) 。
会话落盘:一个会话一个目录 `<workspace>/.agent/sessions/<id>/` ( `session.jsonl` 转录、`title` 、`attachments/` 、子 agent 的 `sub-N.jsonl` ) + `CURRENT` 指向下次打开的会话;id 是 uuid,两台机器共用一份工作目录也不会撞。旧版本写的扁平会话仍然可读,`--migrate-store` 一次搬进新布局(幂等)。`.agent/` 自带 `.gitignore` ,不会被误提交。
### Provider 默认
### 内置工具
| 工具 | 类别 | 说明 |
|---|---|---|
| `read_file` | 读 | 支持 `offset` / `limit` 分段读和行号 |
| `list_dir` | 读 | 目录树(`depth` ),遵守 `.gitignore` ,跳过 `.git` / `node_modules` 等 |
| `glob` | 读 | 按通配符找文件(支持 `**` ) |
| `grep` | 读 | 正则搜索内容,可限定路径 / glob、忽略大小写、带上下文 |
| `write_file` | 写 | 整文件写入(自动建父目录) |
| `edit_file` | 写 | 精确片段替换(必须唯一,或 `replace_all` ) |
| `apply_patch` | 写 | 应用 unified diff,多文件原子生效 |
| `delete_file` / `move_file` | 写 | 删除 / 移动(重命名)文件 |
| `run_shell` | shell | 非交互命令,超时整组进程被杀,Esc 可中断 |
| `web_fetch` | 网络 | 抓取 URL, HTML 转纯文本 |
| `web_search` | 网络 | 使用 Kimi 或 DeepSeek 的官方 Search API 搜索实时网页 |
| `download` | 网络 | 把 URL 抓成工作区里的文件(≤128 MB,超限删掉残file);字节落在磁盘上,不进模型上下文 |
| `read_pdf` | 读 | 读 PDF 的文本层(`read_file` 因二进制拒收的缺口),带页数,文本默认截到 256 KiB |
| `clipboard_read` | 读 | 读系统剪贴板里的文本(`max_bytes` 默认 64 KiB,超出截断并说明) |
| `clipboard_write` | 写 | 把文本放进系统剪贴板(按写类权限确认;本机走 pbcopy / wl-copy / xclip / Win32 API) |
| `todo_write` | 元 | 维护任务清单(TUI 右侧面板,Ctrl+T 开关) |
| `ask_user` | 询问 | 向用户提问(可给选项);headless 下返回错误让模型自行决定 |
| `skill` | 元 | 加载一个 skill 的说明(`SKILL.md` )或其中的文件;有 skill 时才出现 |
| `task` | 子 agent | 把独立任务交给子 agent(`general` / `explore` / `plan` / 自定义角色),只返回最终报告 |
| `deliver_file` | 交付 | 把工作区里的成品文件复制进会话库并交给用户(任意字节,≤64 MB):前端画成文件卡,可打开 / 分享;带 `for_user` 标记,永不进模型上下文 |
| `md_to_html` | 文档 | 把 markdown(文本或工作区 `.md` )渲染成一份自包含 HTML 文档写进工作区并交付成文件卡:utf-8、标题、内联样式,无脚本无外链 |
| `md_to_pdf` | 文档 | 图形前端(桌面 / APK)自带:把 markdown 或工作区 `.md` / `.html` 排成 A4 PDF(15 mm 边距,自动分页)写进工作区并交付成文件卡;不需要 Qt PrintSupport,手机上也能出 |
| `session_search` | 读 | 在过去和当前的所有会话转录里搜子串,给会话 id、条数、标题和匹配行(行号 + 角色 + 上下文);有预算:`max_bytes` (默认 32 MB)、`max_seconds` (默认 5 s),超 64 KiB 的单行跳过,被预算截断时结果里写清楚 |
| `device_info` | 读 | 报告运行环境:系统 / 架构 / CPU 数、工作区、沙箱、模型与审批模式、config / temp / 程序目录、pid(审批策略名 `device` ) |
插件工具和 MCP 工具(`mcp__<server>__<tool>` )在运行时注册,和内置工具走同一套审批与 `/tools` 开关。
同一步里的多个只读调用(读文件、搜索、只读子 agent)会并行执行(最多 4 个)。
`--tools minimal` 只保留 `read_file` / `run_shell` / `write_file` / `apply_patch` (论文实验口径)。
TUI 中 `/tools off NAME` 、`/tools on NAME` 可临时开关单个工具。
### 工作模式(coding / general)
`--mode general` (或 TUI 里 `/mode general` 、WebUI 运行设置里的「工作模式」、`CST_MODE=general` )把默认口径
从"代码助手"换成"通用助手":工作流从改代码/跑测试换成"先弄清要什么、再动手、给出处和不确定的地方",
工具说明从"仓库"改成"文件与数据",并说明 `web_fetch` 可以拿外部资料;`/status` 第一行显示当前模式,
切换后 history 里会留一条系统提示。默认仍是 `coding` ,选择记在 `settings.json` ;
`--tools minimal` (论文口径)的提示词按字节冻结,不受模式影响。
### 剪贴板与文档附件
- **剪贴板**: `clipboard_read` / `clipboard_write` 两个工具(写剪贴板是不可逆发射,要确认);
TUI 里 `/attach paste` 在剪贴板里没有图片时,把剪贴板的**文本**放进输入框(丢掉 CR 与控制字节,尊重输入长度上限)。
- **附件**( `/attach <path>` 、拖入终端、剪贴板图片都算):图片按原样存进会话目录,发给模型时是 image part;
**PDF 在摄取时就抽出文本层 ** (零依赖解析器:Flate / ASCIIHex / ASCII85、对象流、CID 字体 ToUnicode、
内联图像跳过),存的是文本、`mime` 仍是 `application/pdf` ;其余文件必须是 UTF-8 文本。
文档以 **text part 内联**发出,所以不受 `CST_NO_IMAGES` 或非视觉模型影响;图片照旧会被换成一行"未发送"说明。
上限:单个附件 ≤16 MB(文档文本 ≤4 MiB),每条消息最多 8 个。
加密 PDF、扫描件(无文本层)会被明确拒绝并说明原因;
`view_image` 仍只收图片,文本/PDF 走 `/attach` 。
### 权限、撤销与项目说明
- **审批模式**( Shift+Tab 循环切换,`/approval` , `--approval` , `CST_APPROVAL` ):
| 模式 | 写文件 | run_shell | web_fetch |
| provider | API Base | 默认模型 | Key |
|---|---|---|---|
| `ask` | 询问 | 询问 | 询问 |
| `auto` (默认) | 直接执行 | 有沙箱 → 在沙箱里直接执行;没有沙箱 → 只读白名单命令直接执行,其余询问 | 询问 |
| `yolo` | 直接执行 | 直接执行(不进沙箱) | 直接执行 |
| `minimax` (默认) | `https://api.minimax.cn/v1` | `MiniMax-M2.7` | `MINIMAX_API_KEY` |
| `deepseek` | `https://api.deepseek.com/v1` | `deepseek-flash` | `DEEPSEEK_API_KEY` |
| `kimi` | `https://api.moonshot.ai/v1` | `kimi-k3` | `MOONSHOT_API_KEY` |
| `kimi-code` | `https://api.kimi.ai/coding/v1` | `k3` | `KIMI_API_KEY` |
| `openai` | `https://api.openai.com/v1` | `gpt-4.1-mini` | `OPENAI_API_KEY` |
| `teamorouter` | `https://api.teamorouter.com/v1` | `/models` 首个 | `TEAMOROUTER_API_KEY` |
已保存的规则( `a` / `p` )优先:匹配的命令不进沙箱直接运行 。
`ask` / `auto` 的选择会记在 `settings.json` ; `yolo` 只在本次运行有效。headless 行为不变(全部自动)。
- **沙箱**( C 实现,`src/sandbox_exec.c` ):
- Linux: Landlock(内核 5.13+,直接 syscall,无需 libseccomp)。子进程只能写工作区、临时目录、`/dev/null` 、`/dev/tty` ;
读、执行和联网不受限。
- Linux 没有 Landlock 时(Android / Termux、WSL、老发行版;内核 5.5+, x86_64 / aarch64):seccomp user-notify
(界面显示 `auto · seccomp` )。子进程的写类系统调用(带写标志的 open、创建 / 删除 / 改名 / 链接 / chmod 等)先交给
agent 里的监督线程,按真实路径判断是否在工作区、临时目录或 `/dev/null` 等之内,不在就返回 `EACCES` 。联网不受限。
读、执行和已打开文件的写入不检查。它防的是误操作而不是恶意程序:检查之后内核会再读一次路径,多线程程序可以趁机换掉。
探测还会确认能读直接子进程的内存;`ptrace_scope=2` 且无 `CAP_SYS_PTRACE` 时 seccomp 不会启用。
比 shell 活得久的后台进程:桌面发行版开着 Yama(`ptrace_scope` ≥ 1)时它们的受检写入会被拒;命令结束后一律失败。
- macOS: `sandbox_init` profile,同样只放行工作区和临时目录写入,不限制联网。
- Windows 10 1903+: Low 完整性级别的受限令牌 + Job Object(界面显示 `auto · lowil` )。第一次在工作区运行时
给它打上 Low 标签,之后子进程只能写工作区和沙箱临时目录,读不到凭据文件;不限制联网。
`/sandbox` 查看、`/sandbox reset-labels` 撤销标签,详见 [docs/README-windows.md ](docs/README-windows.md )。
- 更老的内核:没有沙箱,自动回落到规则判断(界面显示 `auto · rules` )。
- `CST_SANDBOX=off` 强制关闭沙箱;`CST_SANDBOX=landlock` / `seccomp` / `lowil` 只用指定的那种。
- 沙箱里的命令如果像是被拦了(`Permission denied` / `权限不够` / `Read-only file system` 等),会弹窗问
“Rerun outside the sandbox?”:`y` 在沙箱外重跑一次 · `p` 保存命令前缀规则并重跑 · `n` 保留沙箱结果(模型会收到说明)。
- **只读白名单**(无沙箱时 `auto` 用):`ls cat head tail wc grep rg find pwd echo which file stat du tree`
和 `git status/diff/log/show/branch` ;可以用 `|` `&&` `||` `;` 串联,但每段都必须在白名单里。
`find -exec/-delete` 、`rg --pre` 、`git branch NAME` 、`>` 重定向(`2>&1` 、`>/dev/null` 除外)、`$(…)` 、反引号、
`<(…)` 、`sudo` 、`rm` 一律不算安全。
- **确认弹窗**会显示命令或写入的 diff:
`y` 允许一次 · `a` 本工具总是允许 · `p` 总是允许这个命令前缀(如 `make` 、`git status` )· `n` / Esc 拒绝。
`a` / `p` 写入 `<workspace>/.agent/permissions.json` , `/permissions` 查看,`/permissions reset` 清空。
`sudo` 、`rm` 、解释器(`python3 -c …` )等危险前缀不会被建议成规则。
- **撤销**:每轮写文件前自动快照到 `.agent/undo/` , `/undo` 恢复上一轮改动的全部文件(新建的文件会被删除)。
- **AGENTS.md**:工作区根目录的 `AGENTS.md` 会注入 system prompt; `/init` 让 agent 自己生成一份。
- **自动压缩**:上一轮 prompt 用到模型上下文 75% 时,下一轮开始前自动总结历史(`CST_AUTO_COMPACT=0` 关闭)。
优先级:CLI → 已保存 credentials → 环境变量 → TUI 询问。详见 [ docs/env_openai.md ]( docs/env_openai.md ) 。
### 扩展:Skills、插件、MCP、子 agent
### 内置能力(摘要)
多模型角色绑定、可续接 worker、共享执行预算与编排模式见 [worker 配置指南 ](docs/workers.md )。
- **文件**: `read_file` / `list_dir` / `glob` / `grep` / `edit_file` / `apply_patch` / `write_file` / `delete_file` / `move_file`
- **命令**: `run_shell` (沙箱 + 可中断;超时 `CST_SHELL_TIMEOUT` )
- **网络**: `web_fetch` ; Kimi/DeepSeek 另有官方 `web_search`
- **任务**: `todo_write` 、`ask_user` 、`task` 子 agent、后台 `job_*` (完成会推 TUI / 下一回合笔记)
- **扩展**: Skills、插件、MCP( [docs/plugins.md ](docs/plugins.md ));worker 编排([docs/workers.md ](docs/workers.md ))
`--tools minimal` 下这些都不加载(论文口径保持不变)。配置写法与示例见 [ docs/plugins.md ]( docs/plugins.md ) 。
同一步里连续只读调用会自动并行(默认最多 8, `CST_PAR_MAX` 可调)。截断结果带 `[truncated … evidence=ID]` ,用 `evidence_read` 续读 。
- **Skills**: `<dir>/SKILL.md` ( frontmatter `name` + `description` ),放在工作区 `.agent/skills/` 、`.claude/skills/`
或配置目录 `skills/` 。system prompt 只放名字和一句描述,模型需要时调用 `skill(name)` 读全文;
`/skills` 浏览,`/skill NAME 任务` 直接带着某个 skill 开始一轮。
- **插件**: `plugins/<name>/plugin.json` 声明外部命令工具(参数以 JSON 写到 stdin, stdout 即结果,`perm` 决定审批,
默认 60 s 超时),也可以附带 skills 目录和 MCP 服务器。
- **MCP**: `mcp.json` ( `{"mcpServers": {...}}` ,与 Claude/Cursor 格式相同)里的 stdio 服务器在后台启动,
工具注册为 `mcp__<server>__<tool>` ,默认按网络工具审批(`autoApprove` 可放行)。`/mcp` 看状态,侧栏显示连接数。
- **工作区信任**:工作区里的 `.agent/plugins/` 和 `.agent/mcp.json` 会执行命令,默认不加载;
`/plugins trust` 后才生效(记在 `settings.json` )。配置目录(`~/.config/cst-agent/` )下的始终加载。
- **子 agent**: `task(description, prompt, agent?)` 新开一个独立上下文跑完一轮,把最终报告交回主 agent。
内置 `general` (除 task 外全部工具)、`explore` (只读,可并行)、`plan` (只读,输出计划);
`.agent/agents/*.md` 或配置目录 `agents/*.md` 可自定义角色(frontmatter `name / description / model / tools /
max_steps / readonly` ,正文是角色说明)。子 agent 不能再开子 agent;Esc 会一并取消;它的审批弹窗标 `[角色名]` ;
文件改动并入当前轮,`/undo` 一起撤销。转录在 `.agent/sessions/<会话>/sub-N.jsonl` , `/agents` 查看。
### 审批与沙箱
### TUI 快捷键
Shift+Tab / `/approval` 在 `ask` → `auto` → `yolo` 间切换。`auto` 下 Linux 优先 Landlock(否则 seccomp),macOS `sandbox_init` , Windows Low IL;详见源码与 [docs/compat.md ](docs/compat.md )。
写文件前自动快照,`/undo` 可回滚;工作区 `AGENTS.md` 会注入系统提示。
默认 leader 是 **Ctrl+X ** :先按 Ctrl+X,再按后面的字母。`/keys` (或 F1、Ctrl+X h)列出当前全部绑定。
### TUI 常用
| 按键 | 说明 |
| 按键 / 命令 | 说明 |
|---|---|
| Enter | 发送; busy 时入队 |
| Ctrl+N / Alt+Enter | 换行(粘贴的多行文本保持原样,不会被当成发送) |
| Shift+Enter / Ctrl+Enter | 换行;需要支持 kitty 键盘协议的终端(kitty、WezTerm、foot、Ghostty、WHC Shell 等),启动时自动探测 |
| ← → Home End Ctrl+A/E Ctrl+B/F Alt+B/F Ctrl/Alt+← → | 移动光标(按字 / 按词,支持中文宽字符 ) |
| Ctrl+W / Alt+Backspace / Ctrl+Backspace / Ctrl+Delete | 向前删词 / 向后删词(Ctrl+Backspace 需要 kitty 键盘协议) |
| Ctrl+U / Ctrl+K / Delete | 删到行首 / 删到行尾 / 删后一个字符 |
| ↑ / ↓ | 提示历史(多行输入时先在行间移动) |
| Tab | 补全 `/命令` 和 `@文件` ;没有可补全时切换 Build / Plan(Plan 只开放只读工具) |
| Shift+Tab | 循环切换审批模式 ask → auto → yolo |
| Ctrl+P | 命令面板(输入过滤,↑↓ / 鼠标选择) |
| Ctrl+O / Ctrl+R | 展开/折叠最近的 tool 输出 / 最近的 Thought |
| Ctrl+T / Ctrl+L | 开关任务面板 / 重绘 |
| PgUp / PgDn、Alt+↑ / Alt+↓、Ctrl+Home / Ctrl+End | 半页滚动、单行滚动、跳到开头 / 最新 |
| Ctrl+X n / l | 新会话 / 会话列表 |
| Ctrl+X m / p / e | 模型 / provider / 推理强度 |
| Ctrl+X u / r / c | 撤销上一轮改动 / 重问 / 压缩上下文 |
| Ctrl+X y / x | 复制上一条回复 / 导出记录 |
| Ctrl+X t / d / s | 全部 Thought 默认展开或折叠 / 全部 tool 输出 / 侧栏 |
| Ctrl+X a / k / g | 子 agent 面板 / skills / 插件 |
| Ctrl+X h、F1 / Ctrl+X q | 快捷键列表 / 退出 |
| 鼠标点击 | 展开/折叠 tool 卡片和 Thought、在输入框里定位光标、点模式行切换 Build/Plan、在选择框里选中 |
| 鼠标拖动 / 双击 / 三击 | 在对话区选中文字(按字符 / 词 / 行),松开即通过 OSC 52 复制到剪贴板;拖到上下边缘会自动滚动。Shift+拖动或 `/mouse` 关闭后用终端原生选择 |
| Esc | 取消当前 turn(不会退出) |
| Ctrl+C 两次 / 空输入 Ctrl+D | 退出 |
| Enter / Esc | 发送( busy 时入队) / 取消当前回合 |
| Tab / Shift+Tab | 补全或 Build↔Plan / 审批模式 |
| Ctrl+P / Ctrl+T | 命令面板 / 任务面板 |
| Ctrl+X 再按字母 | Leader 快捷键( `/keys` 或 F1 查看 ) |
| `/provider` `/model` `/effort` `/key` | 切换后端 |
| `/realm` `/motion` | 议会登录提示、Seat Deck 动效 |
| `/web` `/quit` | 起 WebUI / 退出 |
Thought(推理过程)默认折叠成一行“Thought · 3.2s”,生成中显示实时计时; `/thinking on` 改为默认展开 。
完整快捷键与斜杠命令仍以 TUI 内 `/help` 、 `/keys` 为准 。
**自定义按键 ** : `~/.config/cst-agent/keybinds.json` ,键是动作名(`/keys` 里能看到),值是一个或多个按键,
`"none"` 解除绑定:
### 工具协议(可选)
``` json
{
"leader" : "ctrl+x" ,
"new_session" : [ "<leader> n" , "f2" ] ,
"toggle_thought" : "ctrl+g" ,
"todo" : "none"
}
```
默认 `native-eos` ( OpenAI `tools[]` ,流结束后执行)。也可 `native-inc` 、文本帧 `ctl` / `ctl-heredoc` 、`xml` ( `CST_PROTOCOL` / `/protocol` )。日常使用保持默认即可。
按键写法:`ctrl+x` 、`alt+b` 、`shift+tab` 、`f1` …`f12` 、`pgup` 、`home` 、`<leader> n` 。
写错的条目会被跳过并在 `/keys` 里提示,其余照常生效。
---
### 斜杠命令
## 平台
输入 `/` 弹出补全;唯一前缀即可(如 `/st` → `/status` )。标 * 的命令在模型运行中也能用。
| OS | Arch | TUI | 备注 |
|---|---|---|---|
| Linux glibc/musl | x86_64 / x86 / aarch64 | ncursesw | 静态 Release 为 musl |
| WSL2 | x86_64 | ncursesw | 工作区放在 Linux 文件系统 |
| macOS | arm64 / x86_64 | Homebrew ncurses | |
| Termux | aarch64 等 | Termux ncurses | |
| Windows 10 1903+ | x86_64 | 捆绑 ncurses | shell 为 busybox-w32 |
| 命令 | 说明 |
|---|---|
| `/help` * | 命令与按键 |
| `/new` 、`/session [id]` 、`/rename <标题>` *、`/delete [id]` | 新建 / 选择切换 / 命名 / 删除会话 |
| `/provider [name]` 、`/model [name]` 、`/effort [level]` | 切换 provider(缺 key 时当场输入并用 `/models` 校验)、模型(列表优先显示 API 实际返回的模型,标 `(api)` )、推理强度;都会记住 |
| `/key` | 输入或更换当前 provider 的 API key(遮罩输入并保存) |
| `/protocol [name]` | 切换工具调用协议 |
| `/mode [coding\|general]` | 工作模式(通用助手 / 代码助手口径) |
| `/tools [on\|off NAME\|minimal\|default]` | 查看或开关工具 |
| `/approval [ask\|auto\|yolo]` * 、`/yolo` * | 审批模式;本次开关 yolo |
| `/permissions [reset]` * 、`/max-steps [N]` * | 权限规则、每轮步数 |
| `/sidebar` * 、`/mouse` * | 开关右侧边栏(≥120 列时显示)、开关鼠标 |
| `/status` * 、`/todo` * | 会话 / 模型 / 上下文占比 / 设置;任务清单 |
| `/undo` 、`/retry` | 撤销上一轮文件改动;丢弃上一条回复重问 |
| `/diff [path]` * | `git status` + `git diff` |
| `/compact` | 手动压缩上下文 |
| `/export [file]` * 、`/copy` * | 导出 Markdown 记录;复制上一条回复(OSC 52,需终端支持) |
| `/attach [path\|paste\|list\|clear]` | 给下一条消息带附件:图片、PDF(自动取文本层)、文本文件;`paste` 优先取剪贴板图片,没有就把剪贴板文本放进输入框 |
| `/web` * | 后台起一个 WebUI 进程(同 workspace、新会话,日志写到 `.agent/webui.log` ) |
| `/init` | 让 agent 写 `AGENTS.md` |
| `/details` * 、`/thinking [on\|off]`、`/keys` * | 展开全部 tool 输出;Thought 默认展开/折叠;快捷键列表 |
| `/skills [reload\|list]` 、`/skill <name> [任务]` | 浏览 skills;带着某个 skill 开始一轮 |
| `/plugins [trust\|untrust\|reload]` 、`/mcp [reload]` | 插件与工作区信任;MCP 服务器状态 |
| `/agents` | 子 agent 角色与本会话的子 agent 记录(可查看转录) |
| `/quit` * | 退出 |
---
### 协议
请求统一走 OpenAI 兼容 `POST …/chat/completions` ( SSE)。工具调用的承载方式由 `--protocol` 决定:
| 协议 | 承载 | 何时执行 |
|---|---|---|
| `native-eos` (默认) | 原生 `tools[]` / SSE `tool_calls` | 整个流结束后(基线) |
| `native-inc` | 同上 | 某个 index 的参数完整(下一个 index 开始或 finish)即执行 |
| `ctl` | 正文中的 CTL 帧,长度前缀参数 | `end` 行一被确认即执行,流仍在继续 |
| `ctl-heredoc` | 正文中的 CTL 帧,`<<TAG` 定界参数 | 同上 |
| `xml` | MiniMax `<minimax:tool_call>` 文本 | 流结束后 |
文本协议(ctl / ctl-heredoc / xml)不发送 `tools[]` ,工具结果以
`result <id> exit=<n> <nbytes>` … `end` 帧放在下一条 user 消息里。
同一会话可以随时切换协议:历史中的调用会按当前协议重新渲染。
## CTL tool language
``` text
call <id> <name>
arg <key> <nbytes>
<raw bytes exactly nbytes>
arg <key> <<TAG
<lines, verbatim>
TAG
arg <key> short inline value
end
```
Execution happens only on confirmed `end` (`CTL_EV_CALL_READY` ); no prefix of
a call is ever executable. See [docs/theory_tool_cst.md ](docs/theory_tool_cst.md ).
## Starvation experiment
## 开发者备忘
``` bash
make check
./ scripts/replay_starvation.sh
./tests/test_replay_real # 真实 DeepSeek 录制流上的逐字节截断(实验 C )
scripts/prompt_smoke.sh # 系统提示契约(无 API)
scripts/e2e_webui.sh # WebUI 录制流(无 API )
scripts/e2e_fixture.sh mini_calc --provider deepseek # 可选:带 key 的夹具
```
CTL vs JSON-buffer 截断数字写入 [ docs/eval_tool_cst.md ]( docs/eval_tool_cst.md ) 实验 A / C;与 mini_calc e2e 一起作为 Tool-loop CST 附录素材(**不**替代 SD 主论文 Markdown→HTML 实验) 。
`fixtures/` 下是可重复的本地任务夹具( `TASK.md` + `check.sh` ),用于手工或脚本验收,不是产品依赖 。
许可证与第三方:`vendor/sashidown` 、`vendor/cjson` ( MIT)、`vendor/monocypher` 随仓库提供。