Initial CST-Agent: portable Linux/Termux/Windows coding agent.

Vendored sashidown, OpenAI-compatible env (OPENAI_*), and bootstrap scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-09-07 22:42:32 +08:00
co-authored by Cursor
commit 1f1fcba7ad
75 changed files with 14940 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
# CST-Agent on Windows
## Release layout
```
cst-agent.exe
busybox.exe # built from busybox-w32
libwinpthread-1.dll # MinGW runtime (required)
LICENSE.busybox
README-windows.md
```
Prebuilt tree from Linux cross-compile: `agent/dist/windows-x86_64/`.
## Build (MinGW-w64 cross from Linux)
```bash
cd agent
# 1) third-party: curl (Schannel) + PDCurses + busybox-w32
./scripts/build_third_party_mingw.sh all
# sources:
# https://github.com/rmyorston/busybox-w32.git
# https://github.com/curl/curl.git
# https://github.com/wmcbrine/PDCurses.git
# Unix busybox (optional, Linux/Termux bundle):
# ./scripts/build_third_party_mingw.sh busybox-unix
# https://github.com/mirror/busybox.git
# 2) headless
cmake -B build-win -DCMAKE_TOOLCHAIN_FILE=cmake/mingw-w64-x86_64.cmake \
-DCST_BUILD_TUI=OFF -DCMAKE_PREFIX_PATH=$PWD/third_party/prefix-mingw
cmake --build build-win
# 3) TUI (PDCurses)
cmake -B build-win-tui -DCMAKE_TOOLCHAIN_FILE=cmake/mingw-w64-x86_64.cmake \
-DCST_BUILD_TUI=ON -DCMAKE_PREFIX_PATH=$PWD/third_party/prefix-mingw \
-DPDCurses_ROOT=$PWD/third_party/prefix-mingw
cmake --build build-win-tui
```
Copy `build-win-tui/cst-agent.exe`, `third_party/busybox/busybox.exe`, and
`libwinpthread-1.dll` into one folder.
## Run
```bat
set CST_API_KEY=...
cst-agent.exe --headless --workspace . --prompt "echo hi"
cst-agent.exe --workspace .
```
Shell: bundled `busybox.exe sh -c ...` unless `CST_SHELL` is set.
Credentials: `%APPDATA%\cst-agent\credentials` (or console prompt).
+73
View File
@@ -0,0 +1,73 @@
# OpenAI 兼容 API 环境变量
CST-Agent 使用 **OpenAI Chat Completions** 协议(`POST {base}/chat/completions`),
可对接官方 OpenAI、MiniMax、以及其它兼容网关。
## 必填 / 常用
| 变量 | 别名 | 说明 | 示例 |
|---|---|---|---|
| `CST_API_KEY` | `OPENAI_API_KEY`、`MINIMAX_API_KEY` | API Key(按此优先级读取) | `sk-...` |
| `CST_API_BASE` | `OPENAI_BASE_URL`、`OPENAI_API_BASE` | API 根路径,须含 `/v1`(不要带 `/chat/completions`) | `https://api.openai.com/v1` |
| `CST_MODEL` | `OPENAI_MODEL` | 模型名 | `gpt-4.1-mini` / `MiniMax-M2.7` |
未设置 key 时:读配置文件 →(Linux)zenity / 控制台输入。
配置文件:
- Linux/Termux:`~/.config/cst-agent/credentials`
- Windows:`%APPDATA%\cst-agent\credentials`
## 示例
### OpenAI 官方
```bash
export OPENAI_API_KEY='sk-...'
export OPENAI_BASE_URL='https://api.openai.com/v1'
export OPENAI_MODEL='gpt-4.1-mini'
./cst-agent --workspace .
```
等价 CST 前缀:
```bash
export CST_API_KEY='sk-...'
export CST_API_BASE='https://api.openai.com/v1'
export CST_MODEL='gpt-4.1-mini'
```
### MiniMax(默认)
```bash
export CST_API_KEY='...' # 或 MINIMAX_API_KEY
# 默认 base=https://api.minimax.cn/v1 model=MiniMax-M2.7
./cst-agent --workspace .
```
### 任意兼容网关
```bash
export OPENAI_API_KEY='...'
export OPENAI_BASE_URL='https://your-gateway.example/v1'
export OPENAI_MODEL='your-model'
./cst-agent --headless --prompt 'ping' --workspace .
```
命令行也可覆盖:`--api-base` / `--api-key` / `--model`。
## 其它环境变量
| 变量 | 说明 |
|---|---|
| `CST_MODELS` | `/model` 可选列表,`:` 或 `,` 分隔 |
| `CST_AUTO_APPROVE=1` | 自动允许 shell/写文件(headless 常用) |
| `CST_SHELL` | shell 解释器路径(覆盖 busybox/`sh`) |
| `CST_EXE_DIR` | 可执行文件目录(Termux 旁路 busybox 时有用) |
## CLI 对照
```text
--api-base URL ← CST_API_BASE / OPENAI_BASE_URL
--api-key KEY ← CST_API_KEY / OPENAI_API_KEY
--model NAME ← CST_MODEL / OPENAI_MODEL
```
+73
View File
@@ -0,0 +1,73 @@
# Tool-loop CST 评测笔记(反哺论文素材)
> 本文是 **CST-Agent** 侧的评测/案例记录,供写入 SD 主论文附录或独立 TR 时粘贴。
> **不**替代 [`SD/paper/sections/eval_zh.tex`](../../SD/paper/sections/eval_zh.tex) 中 Markdown→HTML 主实验。
理论锚点见 [theory_tool_cst.md](theory_tool_cst.md)。
## 命题分工
| 层 | 主张 | 主变量 | 非主张 |
|---|---|---|---|
| 论文 CST | \(O_{\mathrm{conf}}\) 有界确认 → HTML | \(\mathcal{L}_0\) vs 引用式链接等 | — |
| Tool-loop CST | 同构到工具帧 | **CTL vs JSON-buffer** 截断 | 网关空答率、模型智商 |
| 工程载体 | OpenAI `tool_calls` + XML fallback | 可演示端到端 | 不算进 CST 正确性定理 |
## 实验 A — 饥饿 / 截断(已自动化)
```bash
cd agent && make check
# 关注 ./tests/test_replay_starvation
```
填写模板(跑完后更新数字):
| 指标 | CTL | JSON-buffer |
|---|---|---|
| 完整输入可执行 | yes | yes |
| 截断点上过早执行次数 | **0** | n/a(截断即失败) |
| 安全截断样本(本机 `make check`) | 3 | 3 次 trunc failure |
对应理论:裸 JSON ∉ \(\mathcal{L}_0^{\mathrm{tool}}\);CTL 长度前缀使参数体字节可确认,pending 有界。
## 实验 B — mini_calc 端到端案例(不可逆发射)
协议见 [fixtures/mini_calc/](../fixtures/mini_calc/) 与 [scripts/e2e_mini_calc.sh](../scripts/e2e_mini_calc.sh)。
```bash
cd agent
./scripts/e2e_mini_calc.sh --baseline-only # 无 key:证明 fixture 初始 RED
./scripts/e2e_mini_calc.sh # 有 key:agent 修 bug → make test
```
### 验收口径
| outcome | 含义 |
|---|---|
| `pass` | `make test` 绿 |
| `partial` | 改了 `calc.c` 但测试仍红 |
| `fail` | 未改文件或 agent/API 失败 |
| `baseline_ok_agent_skipped` / `baseline_ok_no_api_key` | 仅验证夹具 |
### 论文可引用的叙事
1. Session JSONL 中顺序:assistant `tool_calls` → `role:tool` 结果 →(可选)写文件/shell → 最终文本。
2. 工具仅在确认/原生完整 arguments 后执行(工程桥);**CTL 饥饿实验**仍是形式主证据。
3. 案例展示「确认后不可撤回的磁盘副作用」与 transcript 只追加。
### 跑分记录(模板)
| 日期 (UTC) | model | outcome | notes |
|---|---|---|---|
| 2026-09-07 | MiniMax-M2.7 | **pass** | `e2e_mini_calc.sh`;baseline RED → agent 修 `add`/`div_ints` → `make test` 绿;见 `out/result-20260907T131300Z.txt` |
## 与主论文的衔接建议
- **附录 / 扩展节标题示例**:「Tool-loop CST:确认前沿到工具调用」
- 粘贴:theory 表(theory_tool_cst.md)+ 实验 A 表 + 实验 B 一行案例。
- 明确声明:主 fan-out / \(\mathcal{A}=0\) 数字仍来自 Sashidown;本笔记只提供 **同构第二实例**。
## 明确不写进定理的内容
- 商业 API 空回复、权限 UX、TUI 观感
- 「已达生产 coding agent」类宣称
+60
View File
@@ -0,0 +1,60 @@
# Tool-loop CST:确认前沿推广到工具调用
## 命题
在 agent 工具环中,对模型输出做**确认流式转导**:只在 \(O_{\mathrm{conf}}\) 内不可逆地发射「可执行工具调用 / 可应用补丁 / 可提交会话状态」。相对「拼到合法 JSON 再执行」的缓冲基线,这能降低注意力饥渴导致的残缺工具帧(未闭合括号、半截 arguments)被过早执行或整轮失败的问题。
## 与论文 CST 的对应
| 论文(Markdown→HTML) | 工具环推广 |
|---|---|
| 输入字母表 \(\Sigma\) | 模型文本 / CTL 字节流 |
| 指称 \(f,g\) → HTML | \(f_{\mathrm{tool}}\) → 已确认 `ToolCall` / `PatchHunk` |
| \(O_{\mathrm{conf}}\) 不可撤回 HTML | 不可撤回:开始执行工具、应用 hunk、写入 transcript |
| \(\mathcal{L}_0\) 排除引用式链接 | \(\mathcal{L}_0^{\mathrm{tool}}\) **排除裸 JSON 对象** |
| \(K=2L_{\mathrm{line}}\) | 工具帧同样要求有界 pending |
## 为何排除裸 JSON
JSON 对象依赖括号匹配与字符串转义。在未闭合 `"` / `{` 时,任意后缀都可能改变已见结构的指称,故 \(O_{\mathrm{conf}}\) 往往停在空前缀,pending 随流长增长——这与论文中引用式链接的**无界后向绑定**同构。「等整个 JSON `Parse` 成功」只是 EOF 缓冲,不是有界 CST。
## \(\mathcal{L}_0^{\mathrm{tool}}\):CTL(CST Tool Language)
行界 \(L_{\mathrm{line}}\);参数体用长度前缀,避免转义歧义。
```text
call <id> <name>\n
arg <key> <nbytes>\n
<raw bytes exactly nbytes>
end\n
```
### 确认规则
1. **`call` 行以 `\n` 结束**:确认 `(id, name)`(此后不可撤回工具身份)。
2. **`arg` 头以 `\n` 结束**:确认 `(key, nbytes)`;随后精确消费 `nbytes` 字节,每字节到达即可确认(无 JSON 转义)。
3. **`end\n`**:确认整次调用可执行;转导器发射一个 `ToolCall` 事件。
4. 行长 \(> L_{\mathrm{line}}\)、非法 token、`nbytes` 超上限、非 CTL 噪声 → 离开契约,标记 `tool_parse_error`。
### 有界 pending \(K\)
- 解析行头时 pending \(\le L_{\mathrm{line}}\)。
- 读参数体时 pending \(\le\) 剩余未读字节数,但**已读体字节已确认**,工作区只需当前行缓冲 + 当前 arg 剩余计数(\(O(L_{\mathrm{line}})\) 寄存器),不随会话总长增长。
取 \(K = L_{\mathrm{line}}\)(行头)与实现常量 `CTL_MAX_ARG`(单参上限,契约拒绝更大值)。
## 不可逆发射
实现是确认忠实的,当且仅当:
- 拼接发射的工具事件序列是 \(O_{\mathrm{conf}}(u)\) 的前缀;
- 一旦 `ToolCall` 被发射,runtime **必须**执行(或显式记录拒绝),不得因后续字节撤回;
- session transcript 只追加:用户消息、已确认助手文本、工具调用与结果。
## 对照基线
**JSON-buffer**:将模型输出拼接到可 `cJSON_Parse` 的 `{"name","arguments"}`(或 OpenAI `tool_calls` 形)才执行;流中途截断则失败。与 CTL 使用同一截断点集合,只换帧语法。
## 补丁确认
`apply_patch` 的 patch 文本作为 CTL 的一个 `arg`;应用侧再要求 unified diff 的每个 hunk 完整(`@@` 到下一块或 EOF)才写盘——整 hunk 确认,禁止半截应用。
+11
View File
@@ -0,0 +1,11 @@
# Windows self-test checklist
Run on a Windows machine (or wine) after MinGW build + busybox.exe beside the binary.
1. `cst-agent.exe --help` exits 0
2. `set CST_API_KEY=...` then `--headless --workspace . --prompt "run echo hello"` — tool output contains hello
3. `write_file` under workspace succeeds; path outside workspace rejected
4. Credentials saved under `%APPDATA%\cst-agent\credentials`
5. With PDCurses build: launch without `--headless`, confirm TUI draws, `/help` works, Esc cancels
Shell must resolve to bundled busybox unless `CST_SHELL` is set.