Usability pass: tool registry, TUI polish, saved keys and settings
Tools - Table-driven tool registry with permission classes and default/minimal profiles; new tools: edit_file, list_dir, glob, grep, delete_file, move_file, todo_write, web_fetch, ask_user (plus read_file paging). - Built-in Myers diff; write tools return unified diffs. - Persistent permission rules (.agent/permissions.json), per-turn undo snapshots (.agent/undo), AGENTS.md project notes, auto-compact at 80% of the model context, cancellable run_shell with process-group kill. TUI - Table-driven slash commands: /provider /key /effort /status /tools /permissions /yolo /undo /retry /diff /export /copy /rename /delete /init /max-steps /todo, with / and @ completion. - Permission modal with diff and prefix rules, ask_user modal, todo panel, header with model/effort/context, bracketed paste, line editing, wide-char cursor, NO_COLOR and ASCII fallback; Esc never quits. Startup and configuration - API keys are entered in the TUI (hidden) and saved per provider in <config>/credentials (0600); env variables are only a fallback. - Last provider, per-provider model and reasoning effort are remembered in <config>/settings.json; --effort/-e and /effort send reasoning_effort (low|medium|high|max) to models that accept it. - DeepSeek preset uses deepseek-flash / deepseek-v4-pro. - Session flags --new/--continue/--resume/--list-sessions, --yolo, --confirm. Compatibility and tests - ncurses detection, macOS/Homebrew support, make install, XDG config dir, POSIX cleanups; Gitea CI (gcc/clang/asan/musl/macOS). - Unit tests for diff, fs tools, registry, undo/perms and config; e2e fixtures multi_file_refactor and ask_or_todo; vendored cJSON.
This commit is contained in:
+101
-22
@@ -10,18 +10,15 @@
|
||||
| 层 | 主张 | 主变量 | 非主张 |
|
||||
|---|---|---|---|
|
||||
| 论文 CST | \(O_{\mathrm{conf}}\) 有界确认 → HTML | \(\mathcal{L}_0\) vs 引用式链接等 | — |
|
||||
| Tool-loop CST | 同构到工具帧 | **CTL vs JSON-buffer** 截断 | 网关空答率、模型智商 |
|
||||
| 工程载体 | OpenAI `tool_calls` + XML fallback | 可演示端到端 | 不算进 CST 正确性定理 |
|
||||
| Tool-loop CST | 同构到工具帧 | **CTL vs JSON-buffer** 截断;确认即执行 | 网关空答率、模型智商 |
|
||||
| 工程载体 | 五种协议同一 agent 循环 | 端到端通过率、步数、token、时延 | 不算进 CST 正确性定理 |
|
||||
|
||||
## 实验 A — 饥饿 / 截断(已自动化)
|
||||
## 实验 A — 饥饿 / 截断(合成样例,已自动化)
|
||||
|
||||
```bash
|
||||
cd agent && make check
|
||||
# 关注 ./tests/test_replay_starvation
|
||||
make check # 关注 tests/test_replay_starvation
|
||||
```
|
||||
|
||||
填写模板(跑完后更新数字):
|
||||
|
||||
| 指标 | CTL | JSON-buffer |
|
||||
|---|---|---|
|
||||
| 完整输入可执行 | yes | yes |
|
||||
@@ -29,45 +26,127 @@ cd agent && make check
|
||||
| 安全截断样本(本机 `make check`) | 3 | 3 次 trunc failure |
|
||||
|
||||
对应理论:裸 JSON ∉ \(\mathcal{L}_0^{\mathrm{tool}}\);CTL 长度前缀使参数体字节可确认,pending 有界。
|
||||
定界写法另有 `tests/test_ctl_heredoc`:对一个含 TAB、空行、`end`/`call`/围栏行和缩进 TAG 的体,
|
||||
在**每一个**字节前缀上都不产生 `CALL_READY`,完整流上体逐字节还原。
|
||||
|
||||
## 实验 B — mini_calc 端到端案例(不可逆发射)
|
||||
|
||||
协议见 [fixtures/mini_calc/](../fixtures/mini_calc/) 与 [scripts/e2e_mini_calc.sh](../scripts/e2e_mini_calc.sh)。
|
||||
协议见 [fixtures/mini_calc/](../fixtures/mini_calc/) 与 [scripts/e2e_fixture.sh](../scripts/e2e_fixture.sh)。
|
||||
|
||||
```bash
|
||||
cd agent
|
||||
./scripts/e2e_mini_calc.sh --baseline-only # 无 key:证明 fixture 初始 RED
|
||||
./scripts/e2e_mini_calc.sh # 有 key:agent 修 bug → make test
|
||||
./scripts/e2e_mini_calc.sh --baseline-only # 无 key:证明 fixture 初始 RED
|
||||
./scripts/e2e_mini_calc.sh --provider deepseek # 有 key:agent 修 bug → make test
|
||||
```
|
||||
|
||||
### 验收口径
|
||||
|
||||
每个夹具有 `TASK.md`(任务书)和 `check.sh`(判定脚本)。基线在一份临时副本上先跑 `check.sh`,必须失败。
|
||||
|
||||
| outcome | 含义 |
|
||||
|---|---|
|
||||
| `pass` | `make test` 绿 |
|
||||
| `partial` | 改了 `calc.c` 但测试仍红 |
|
||||
| `fail` | 未改文件或 agent/API 失败 |
|
||||
| `baseline_ok_agent_skipped` / `baseline_ok_no_api_key` | 仅验证夹具 |
|
||||
| `pass` | agent 结束后 `check.sh` 通过 |
|
||||
| `fail` | agent 正常结束但 `check.sh` 失败 |
|
||||
| `agent_error` | agent 非零退出(如连续契约错误、API 错误) |
|
||||
| `timeout` | 超过 `E2E_TIMEOUT`(默认 900 秒) |
|
||||
| `unexpected_green_fixture` | 夹具一开始就通过(夹具坏了) |
|
||||
|
||||
### 论文可引用的叙事
|
||||
|
||||
1. Session JSONL 中顺序:assistant `tool_calls` → `role:tool` 结果 →(可选)写文件/shell → 最终文本。
|
||||
2. 工具仅在确认/原生完整 arguments 后执行(工程桥);**CTL 饥饿实验**仍是形式主证据。
|
||||
1. Session JSONL 中顺序:assistant 调用 → 工具结果 → 最终文本;只追加。
|
||||
2. 工具仅在确认(CTL `end`、原生参数完整)后执行;**CTL 饥饿实验**仍是形式主证据。
|
||||
3. 案例展示「确认后不可撤回的磁盘副作用」与 transcript 只追加。
|
||||
|
||||
### 跑分记录(模板)
|
||||
### 稳定性(M1,DeepSeek `deepseek-chat`,ASAN + UBSan 构建)
|
||||
|
||||
| 日期 (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` |
|
||||
| 日期 (UTC) | 场景 | 结果 |
|
||||
|---|---|---|
|
||||
| 2026-09-07 | mini_calc,MiniMax-M2.7 | **pass**(旧版本,`out/result-20260907T131300Z.txt`) |
|
||||
| 2026-10-04 | mini_calc 连续 10 次,native-eos | **10/10 pass**,ASAN/LSan 无报告 |
|
||||
| 2026-10-04 | makefile_tab(写含 TAB 的 Makefile;旧版本此处 HTTP 400) | pass |
|
||||
| 2026-10-04 | big_file(写 5000 字节文件;旧版本长内容被截断) | pass |
|
||||
| 2026-10-04 | test_fix_test(先跑测试→修→再跑;旧版本第二次 `make test` 被错误去重) | pass,`make test` 实际执行 2 次 |
|
||||
| 2026-10-04 | mini_calc,`ctl` / `ctl-heredoc` / `native-inc` / `xml` 各 1 次(ASAN) | 4/4 pass |
|
||||
|
||||
## 实验 C — 真实模型流上的逐字节截断
|
||||
|
||||
```bash
|
||||
make check # 关注 tests/test_replay_real
|
||||
```
|
||||
|
||||
数据:`tests/fixtures/sse/deepseek-*/NNNN.sse`,是 `CST_RECORD_SSE` 录下的 DeepSeek 原始 SSE 流(同一任务分别用三种协议)。
|
||||
测试把每条助手消息还原成运行时看到的逻辑流,在**每一个字节**处截断:CTL 流喂给 CTL 解析器;原生流把各调用拼成
|
||||
`[{"name","arguments"},…]`,分别按 json-whole(整体可解析才执行,即 native-eos)和 json-object(每个对象可解析即执行,即 native-inc)计数。
|
||||
|
||||
全部前缀上 S1/S2/S3 成立(未完整调用不可执行;执行过的调用与完整流一致;可执行数单调)。可执行调用数随前缀比例变化:
|
||||
|
||||
| 消息 | 协议 | 字节 | 调用 | 25% | 50% | 75% | 90% | 100% | 首个调用可执行于 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| heredoc #0 | ctl-heredoc | 193 | 3 | 0 | 1 | 2 | 2 | 3 | 45% |
|
||||
| heredoc #1 | ctl-heredoc | 223 | 2 | 0 | 0 | 0 | 1 | 2 | 85% |
|
||||
| ctl #0 | ctl | 74 | 2 | 0 | 0 | 1 | 1 | 2 | 51% |
|
||||
| native #0 | json-whole | 100 | 2 | 0 | 0 | 0 | 0 | 2 | 100% |
|
||||
| native #0 | json-object | 100 | 2 | 0 | 0 | 1 | 1 | 2 | — |
|
||||
| native #1 | json-whole | 108 | 2 | 0 | 0 | 0 | 0 | 2 | 100% |
|
||||
| native #1 | json-object | 108 | 2 | 0 | 1 | 1 | 1 | 2 | — |
|
||||
|
||||
读法:json-whole 在流结束前一个调用都不能执行;CTL 与 json-object 都是前缀单调的,确认点落在每个调用结束处。
|
||||
CTL 的区别在于 pending 有界(\(\le L_{\mathrm{line}}\)),json-object 的 pending 是整个参数对象。
|
||||
另外 `ctl` 目录里 #1–#4 是四次长度前缀写错的消息(三次 patch 字节数写大、一次 content 写小,见实验 D),解析器在这些消息的任何前缀上**一次也没有执行**。
|
||||
|
||||
`tests/test_sse_decode` 还验证:录制流按 1 字节和 4096 字节分块回放,解码出的文本、调用和参数完全相同(网络分块不影响确认结果)。
|
||||
|
||||
## 实验 D — 协议对照矩阵(M3)
|
||||
|
||||
```bash
|
||||
scripts/run_matrix.sh -p "native-eos native-inc ctl ctl-heredoc xml" \
|
||||
-m "deepseek:deepseek-flash" -f "mini_calc makefile_tab big_file test_fix_test" -n 3 -r
|
||||
# → out/matrix-*/results.csv(每次运行一行)与 summary.md
|
||||
```
|
||||
|
||||
2026-10-04,DeepSeek `deepseek-chat`,5 协议 × 4 夹具 × 3 次 = 60 次(`out/matrix-m3/`):
|
||||
|
||||
| 协议 | n | 通过率 | 步数 | 墙钟 s | 模型时间 s | 工具时间 s | wait_ms | 契约错误/次 | 输入 token | 输出 token |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| native-eos | 12 | 100% | 4.2 | 5.38 | 5.11 | 0.24 | 30 | 0 | 9900 | 1058 |
|
||||
| native-inc | 12 | 100% | 4.7 | 5.90 | 5.82 | 0.26 | 0 | 0 | 10615 | 1084 |
|
||||
| ctl | 12 | 58% | 5.8 | 7.26 | 7.09 | 0.16 | 0 | 2.33 | 10574 | 1336 |
|
||||
| **ctl-heredoc** | 12 | **100%** | **3.7** | **4.48** | 4.27 | 0.24 | 0 | **0** | **5728** | **756** |
|
||||
| xml | 12 | 92% | 5.7 | 7.09 | 6.84 | 0.19 | 53 | 1.75 | 10468 | 1398 |
|
||||
|
||||
`wait_ms` = 调用确认到开始执行的平均间隔。eager 协议恒为 0;流结束后执行的协议要等到整条消息结束。
|
||||
|
||||
契约错误分解(全部 12 次运行合计):
|
||||
|
||||
| 协议 | 参数写法使用次数 | 契约错误 |
|
||||
|---|---|---|
|
||||
| ctl | 长度前缀 33、行内 73 | `unexpected_line`(数少了)20、`body_eof`(数多了)8 |
|
||||
| ctl-heredoc | 定界 30、行内 29、长度前缀 0 | 0 |
|
||||
| xml | — | 标签写坏(如 `<minimax:tool_call">`)21 |
|
||||
|
||||
结论(可写入论文):
|
||||
|
||||
1. **长度前缀对真实模型不可靠**。模型几乎从不数对多行参数的字节数(33 次长度前缀参数里 28 次契约错误),
|
||||
ctl 只有 58% 通过,失败的运行都是连续契约错误后放弃。CST 的安全性仍然成立——错误帧从未被执行——但可用性差。
|
||||
2. **定界写法消除了计数负担**,保留同样的确认前沿与有界 pending:ctl-heredoc 100% 通过、0 契约错误,
|
||||
且步数、墙钟、token 都是五种协议里最少的(输入 token 比 native-eos 少 42%:不发 `tools[]` schema,参数也不需要 JSON 转义)。
|
||||
3. **eager 执行在这些任务上的时延收益很小**:确认到执行的等待从几十毫秒降到 0;墙钟差异主要来自步数和 token,而非执行时机。
|
||||
原因是模型通常把耗时工具(make、测试)放在一条消息的最后一个调用,确认之后流几乎立即结束。
|
||||
4. **反馈让文本协议可恢复**:xml 在加入“标签写坏→契约错误→要求重发”之前为 58%(`out/matrix-m3-old-xml/`),之后为 92%(重复一组为 83%,`out/matrix-m3-xml-replicate/`)。
|
||||
|
||||
注意事项:
|
||||
|
||||
- 执行在 SSE 回调内同步进行,执行期间客户端暂停读流,所以客户端测得的“流结束”包含了工具时间。
|
||||
`summary.md` 里的 `overlap_s` 因此是上界(native-inc 下恒等于工具时间),不能当作节省的时间引用。
|
||||
- 每格只有 3 次,模型输出有随机性;引用通过率时请同时给出 n。
|
||||
|
||||
## 与主论文的衔接建议
|
||||
|
||||
- **附录 / 扩展节标题示例**:「Tool-loop CST:确认前沿到工具调用」
|
||||
- 粘贴:theory 表(theory_tool_cst.md)+ 实验 A 表 + 实验 B 一行案例。
|
||||
- 粘贴:theory 表(theory_tool_cst.md)+ 实验 A/C 表 + 实验 D 主表与结论 1–2。
|
||||
- 明确声明:主 fan-out / \(\mathcal{A}=0\) 数字仍来自 Sashidown;本笔记只提供 **同构第二实例**。
|
||||
|
||||
## 明确不写进定理的内容
|
||||
|
||||
- 商业 API 空回复、权限 UX、TUI 观感
|
||||
- 「已达生产 coding agent」类宣称
|
||||
- 实验 D 的时延数字(受网络与服务端负载影响)
|
||||
|
||||
Reference in New Issue
Block a user