feat: AutoZero 通用 Agent 框架(从 AutoGo 五阶段拆分完成)

llm(三协议 Provider)/ session(JSONL 持久化)/ tools(Registry、围栏、
builtin、computer)/ cdp(browser)/ skills / mcp / agent(循环、两级压缩、
编排、审批门控)+ 底座 jsonl/textx/execx/diag/scratch/spill/imagecache。

产品装配代码(config 桥接、schedule 工具、memory/plan/retro/prompt)
留在 AutoGo,宿主接入方式见 MIGRATION.md。
This commit is contained in:
Sakurasan committed 2026-10-26 00:54:46 +08:00
commit d5dac5a6fc
140 files changed
+26497

No files matched your search

+143
View File
@@ -0,0 +1,143 @@
# AutoZero 搬迁清单:从 AutoGo 拆出通用 Agent 框架
> 来源仓库:`~/Code/github/AutoGo`(module `autogo`)。
> 目标:把 `llm / tools / agent` 三层通用能力拆成独立 Go module,
> AutoGo 改为依赖它的第一个宿主;channel / scheduler / webui 等产品功能留在 AutoGo。
> 原则:**不重写,纯搬家**。每搬一层 AutoGo 都能编译、测试全绿。
## 策略(2026-10-26 定)
**AutoGo 处于持续开发阶段,暂不接入 AutoZero**——不做 replace 依赖、不做 shim,
保持自包含。两侧关系是**单向同步**:
- AutoGo 仍是唯一事实源,照常开发;框架包在 AutoGo 侧的改动(bug 修复、新协议、
新工具)由人工择期同步到 AutoZero 对应包。
- AutoZero 以框架视角收口:接入门槛、API 表面、文档是它的验收标准;
产品装配代码(config 桥接、schedule 工具、memory/retro 钩子)不同步进来。
- 等 AutoGo 功能进入稳定期,再按"AutoGo 侧接线"一节做反向依赖,届时 shim 是现成方案。
已完成的阶段 1(llm)即按此模式存在:AutoZero/llm 是 AutoGo internal/llm 去产品化
的镜像(config 桥接函数不进框架)。**同步时以 AutoGo 为准,漂移靠人工对齐。**
## 模块与包布局
```
AutoZero(module git.gopher.ink/mirrors2/AutoZero)
├── llm/ 阶段1 ✅:Provider 抽象 + 三协议实现(零内部依赖)
├── jsonl/ 阶段2 ✅:JSONL 容忍读取(坏行跳过、无行长上限)
├── session/ 阶段2 ✅:JSONL 会话持久化(依赖 llm + jsonl;wsbind 留宿主)
├── textx/ 阶段2 ✅:字符截断工具(tools/agent 的公共依赖)
├── execx/ 阶段2 ✅:命令执行/截断工具
├── tools/ 阶段3 ✅:Registry、Fence、guard、builtin、computer(schedule 留宿主)
├── cdp/ 阶段3 ✅:Chrome DevTools 协议客户端 + browser 工具
├── diag/ 阶段3 ✅:诊断输出(Printf / Indirect)+ 禁直写终端静态检查
├── scratch/ 阶段3 ✅:临时文件目录(~/.autogo/scratch)
├── skills/ 阶段4 ✅:SKILL.md 扫描与解析
├── mcp/ 阶段4 ✅:MCP 客户端(stdio + HTTP)与工具适配
├── spill/ 阶段5 ✅:超长工具结果落盘(~/.autogo/results)
├── imagecache/ 阶段5 ✅:图片落盘缓存(内容 hash → 文件、TTL 清理)
└── agent/ 阶段5 ✅:循环、两级压缩、编排、子 agent、审批/提问(memory/plan/retro/prompt 留宿主)
```
阶段顺序 = 依赖自底向上;每阶段结束 AutoGo `go test ./...` 全绿才算完成。
## 各包迁移映射
### 阶段 1:`llm`(已完成 2026-10-26)
| 内容 | 去向 |
|---|---|
| types / anthropic / openai / responses / retry / image / completion / streamguard 及各自测试 | → `AutoZero/llm/` 原样搬 |
| `provider.go` 通用部分(APIFormat、NormalizeAPIFormat、ProviderSpec、NewProvider、guessFormat、DedupeModels、FilterAllowed、matchesAllowed、MissingRegisteredModels) | → `AutoZero/llm/provider.go` |
| `provider.go` config 部分(SpecFromConfig、NewConfigProvider、currentProvider、specFromProvider、AllowedForCurrent、SwitchableModels) | 留在 AutoGo(见 shim) |
| `provider_test.go` 通用测试(TestFilterAllowed / NormalizeAPIFormat / NewProviderFormats / MissingRegisteredModels / FilterAllowedWildcard) | → `AutoZero/llm/` |
| `provider_test.go` config 测试(TestSpecFromConfigCurrentProvider / SwitchableModels×2 / AllowedForCurrent) | 留在 AutoGo |
AutoGo 侧改造:`internal/llm` 变成 **shim 包**——类型别名 + 函数转发 + 保留 config 桥接函数。
全部调用方零改动;后续包迁移完成后逐包把 `autogo/internal/llm` import 换成新 module,最后删 shim。
### 阶段 2:`session` + `textx` + `execx`(已完成 2026-10-26)
- `textx` / `execx` / `jsonl`:零内部依赖,原样搬(`jsonl` 是 session 的容忍读取
底座,一并进框架)。测试全部随包通过。
- `session`:除 `wsbind.go` / `wsbind_test.go`(工作区绑定,产品功能)外全部搬入;
import 路径改为本 module。**框架侧新增 `session.SetDir`**:覆盖默认的
`~/.autogo/sessions` 布局(宿主自定义存储位置用;AutoGo 侧无此函数,属框架增量)。
- AutoGo 侧零改动。
### 阶段 3:`tools`(已完成 2026-10-26)
- 核心全量搬入:`tools.go / guard.go / builtin.go / edit_match.go / instructions.go /
bashbg.go / fetch.go / websearch.go / vision.go` + 测试;`computer*.go` 三平台
GUI(build tag)一并进框架;`cdp`(browser 工具)整体搬入。
- 随迁底座:`diag`(诊断输出,含"禁直写终端"静态检查测试)、`scratch`(临时目录,
`~/.autogo/scratch` 硬编码与 AutoGo 保持镜像,宿主自定义需求出现时再加覆盖入口)。
- **接口增量**:`snapshot.Change` 内联为 `tools.Change`,`Snapshotter` 签名改为
`Record(Change)`——留档/回退(Store/Plan/Restore)是产品功能留在 AutoGo,宿主
接入时写一个几行的适配器把 `tools.Change` 转成自己的留档记录。
- **留在 AutoGo**:`schedule.go` / `schedule_test.go`(依赖 scheduler 引擎)。
- 第三方依赖与 AutoGo 对齐:`coder/websocket v1.8.15`、`imroc/req/v3 v3.61.0`、
`golang.org/x/net v0.57.0`。
- AutoGo 侧零改动。
### 阶段 4:`skills` + `mcp`(已完成 2026-10-26)
- `skills`(SKILL.md 扫描与 frontmatter 解析)零产品依赖,仅引用 textx,原样搬。
- `mcp`(手写 JSON-RPC 2.0 客户端,stdio + HTTP 两种传输,server 工具 →
Registry 适配)依赖 diag/execx/tools,全部已迁入,原样搬。
- AutoGo 侧零改动,测试全部随包通过。
### 阶段 5:`agent`(已完成 2026-10-26,框架五阶段收敛完成)
**随迁**:循环与门控全量(agent / context / subagent / skill / ask / askuser /
dangerous / anomaly / toolfail / continue / model_routing / checkpoint / secrets
及 34 个测试文件)+ 底座 `spill`(超长结果落盘,`~/.autogo/results` 与 AutoGo
保持镜像)、`imagecache`(图片落盘缓存,零依赖)。
**留在 AutoGo 的产品文件**(宿主接入时经钩子挂回):
| 文件 | 接回方式 |
|---|---|
| `memory.go`(memory 工具 + MemorySection) | 工具进 Registry 由宿主注册;注入段经 `Agent.ExtraSections` |
| `plan.go`(plan 工具 + PlanSection,含 Agent 上的 plan 状态) | 状态挪宿主侧(工具闭包自持),注入段同走 `ExtraSections` |
| `retro.go`(复盘记录 + SelfAssess) | 经 `OnTurnEnd(TurnReport)` 取数(byTurnCap/Steps/GoalIndex 已给全) |
| `prompt.go`(SystemPrompt:品牌名/项目探测/git 快照) | 宿主组装 `Agent.System`;通用注入(AGENTS.md/子树指令/放弃分支)已在框架 |
| `checkpoint.go`(git checkpoint)/ `occupy`(工作区占用) | 经 `Options.Occupy`/`Release` 钩子(占用行为测试已随框架迁移) |
| `failfields_test.go` / `turnend_test.go` / `memory_test.go` / `plan_test.go` / `retro_test.go` / `prompt_test.go` | 随对应产品文件留宿主 |
**框架相对 AutoGo 的接口增量**(均为超集,AutoGo 接入时按此适配):
1. `OnTurnEnd` 签名 `func(err error)` → `func(TurnReport)`:复盘需要的
byTurnCap / Steps / GoalIndex / Started 一次给全。
2. `Agent.ExtraSections func() string`:DynamicSections 的宿主扩展点(原
PlanSection+MemorySection 的位置);框架自有段(放弃分支说明、子树指令)不变。
3. 回合结果常量 `Outcome*`(completed/failed/stopped/max_turns)入框架 agent 包,
**取值与 AutoGo retro 包一致**(session 文件格式跨两端兼容);Agent 结构体
移除 `Memory` / `plan` / `PlanPath` 产品字段(`ImgCache` 保留,imagecache 随迁)。
4. 测试脚手架 `stubProvider` 入框架 `helpers_test.go`(AutoGo 侧同名定义随
retro_test.go 留宿主);`turn_end_test` / `occupy_test` 按 TurnReport 适配。
5. `MaxTurns` 默认值 40 保持镜像;`~/.autogo` 系路径(spill/scratch/sessions)
与 AutoGo 保持镜像,宿主自定义入口按需再加(session.SetDir 先行)。
## AutoGo 侧接线(接入期才执行,当前暂缓)
AutoGo 进入稳定期、决定接入框架时,每阶段按相同模式操作:
1. `go.mod`:`require git.gopher.ink/mirrors2/AutoZero v0.0.0` + `replace ... => ../AutoZero`(开发期本地路径)。
2. 原 `internal/<pkg>` 改为 shim:`type X = az.X`、`func X(...) = 转发`,产品桥接代码留下。
3. 调用方零改动;稳定后再逐包替换 import 路径,shim 退役。
## 关键设计约束(随包走,写进各包 doc.go)
1. **配对不变量**:transcript 中每个 tool_use 必须有配对 tool_result(含合成 is_error),`synthMissingToolResults` 兜底不得拆。
2. **transcript 不可变**:压缩/截断/图片驱逐只在视图层(contextView),Session 是唯一事实源。
3. **fail-closed 默认**:Tool 零值 = 有副作用 + 不可并发;忘标注时行为必须保守。
4. **截断只有一个口径**:正文一律 `textx.ClipBytes`(字节预算)/ `ClipRunes`(个数),禁止裸切 `s[:n]`。
5. **零重依赖**:框架层(llm/session/skills)不新增任何第三方依赖;协议层手写。
## 决策点(已定 / 待定)
1. computer / browser 进框架(阶段 3 已落实:computer 入 tools,cdp 独立包)。
2. 框架 config → 框架只定义 `ProviderSpec` 等纯值类型,配置装载归宿主(阶段 1 已落实)。
3. 开发期用 `replace` 指向本地路径,稳定后切 git tag(随 AutoGo 接入期一起执行)。
4. 框架名 AutoZero,module 路径 `git.gopher.ink/mirrors2/AutoZero`(与 AutoGo 同源托管)。