fix: 修正 logo 中 N 和 G 字母造型
N 添加对角线笔画(█▄ █),G 添加内横杠(█ ▀█), 避免与 O 字母造型雷同。同步更新 ui.ts 中的硬编码 wordmark。
This commit is contained in:
137
docs/AGENTS.md
Normal file
137
docs/AGENTS.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance to the AI agent when working with code in this repository.
|
||||
|
||||
## 项目概述
|
||||
|
||||
AirCoding 是基于 OpenCode v1.17.4 fork 的多 Agent 协作 AI 编程系统,以 C++ 为首个深度支持语言。核心策略:**最小修改 OpenCode,通过 Plugin + Agent 配置植入多 Agent 调度层**。
|
||||
|
||||
- 完整架构设计:@aircoding-architecture-mvp.md
|
||||
- 实现计划:@implementation-plan.md
|
||||
- V1 痛点教训:@airplanV2-Qwen3.7-Max设计.md
|
||||
- OpenCode 参考代码:@reference/opencode/
|
||||
|
||||
## 构建与测试
|
||||
|
||||
```bash
|
||||
bun install # 安装依赖
|
||||
bun lint # oxlint 检查
|
||||
bun typecheck # turbo typecheck 全包
|
||||
bun test # ⚠️ 禁止从根目录运行,必须进入 packages/<pkg> 执行
|
||||
bun typecheck # ⚠️ 同上,从包目录执行,禁止直接运行 tsc
|
||||
```
|
||||
|
||||
## 代码风格
|
||||
|
||||
沿用 OpenCode 规范(Prettier: `semi: false`, `printWidth: 120`,oxlint):
|
||||
|
||||
- `const` 优先,禁止 `let` + 重赋值
|
||||
- 禁止 `else`,用 early return
|
||||
- 禁止不必要的解构,用 dot notation
|
||||
- 禁止 `import { x as y }` 和 `import * as Foo`
|
||||
- 禁止 `try/catch`(能用 `.catch()` 的场景)
|
||||
- 内联单次使用的值,不提前抽取 helper
|
||||
- 模块底部加 `export * as Foo from "./foo"` 自导出
|
||||
- Drizzle schema 字段用 snake_case
|
||||
- Effect v4 beta:`Effect.fork` 不存在,用 `Effect.forkIn(scope)`
|
||||
|
||||
## 分支与提交
|
||||
|
||||
- 默认分支:`dev`(不是 `main`)
|
||||
- 分支名:短名(最多三个词),短横线分隔,无前缀(如 `session-recovery`,不是 `feat/session-recovery`)
|
||||
- 提交:`type(scope): summary`,type: `feat|fix|docs|chore|refactor|test`
|
||||
|
||||
## Agent 架构约束
|
||||
|
||||
**核心原则:工具白名单是硬阻断,不是建议。**
|
||||
|
||||
| Agent | 可用工具 | 禁止工具 |
|
||||
|-------|---------|---------|
|
||||
| Architecture Designer | read, glob, grep, task | Write, Edit, Bash(代码级只读) |
|
||||
| Scheduler | read, glob, grep, task, coordinator.* | Write, Edit(不可写代码) |
|
||||
| Worker (EXECUTE) | read, write, edit, shell, glob, grep | — |
|
||||
| Worker (DEBUG) | 同上,但必须先通过 shell 取证才能修改代码 | — |
|
||||
|
||||
- Worker 是 EXECUTE + DEBUG 双模式合一,由 TaskSpec.type 切换
|
||||
- Worker 直接通过 `shell` 调用 cmake/ctest/cppcheck/ffmpeg/tcpdump,不封装 Plugin
|
||||
- EXECUTE 模式:**每次完成前必须运行 `cppcheck --enable=all`(不可跳过)**
|
||||
- DEBUG 模式:先取证(shell 调用截图/抓包/静态分析)→ 记录 → 才能改代码
|
||||
- Scheduler 通过 EventV2 事件驱动,不依赖 LLM 轮询
|
||||
- 10 分钟不活跃自动巡检 + scheduler-state.json 实时落盘
|
||||
|
||||
## 关键设计约束
|
||||
|
||||
- **单进程模型**:子代理 = OpenCode 子 session(TaskTool + BackgroundJob),不是独立进程
|
||||
- **LLM 混合策略**:正常调度走确定性代码(DAG 遍历),异常/边界才调 LLM
|
||||
- **证据门控**:按任务类型决定必需证据(GUI→截图,网络→抓包,C++→静态分析)
|
||||
- **两层审查**:Worker 自验(逐任务)+ Arc 里程碑审查 fork(全局 Code-to-Design)
|
||||
- **接口契约**:中等粒度(module + kind + spec + stability),作为概率信号而非确定性判断
|
||||
|
||||
## C++ 工具链
|
||||
|
||||
- Worker 直接通过 `shell` 调用命令行工具,不封装 Plugin
|
||||
- 构建:CMake 优先,Ninja 优先,失败回退 Make
|
||||
- 测试:CTest + GoogleTest
|
||||
- **cppcheck 强制:每次任务完成前必须运行 `cppcheck --enable=all`,无输出不允许标记完成**
|
||||
- Scheduler 校验 WorkerResult 中必须包含 cppcheck 输出
|
||||
- 编译错误解析:LLM 自行分析(不用正则)
|
||||
- compile_commands.json:按需生成,不持久化
|
||||
|
||||
## 目录约定
|
||||
|
||||
```
|
||||
.air/shared/ # 可提交 git(plan, rules, project.json)
|
||||
.air/local/ # gitignore(sessions, state, debug-records)
|
||||
.air/local/state/scheduler-state.json # 调度器实时状态
|
||||
```
|
||||
|
||||
## 测试策略
|
||||
|
||||
- 单元测试:`bun test`,无 LLM 调用,<30s
|
||||
- 集成测试:录制 LLM fixture 回放,<1min
|
||||
- E2E 测试:真实 LLM,release gate
|
||||
|
||||
## 强制规则
|
||||
- 不得以兜底方案、先这样做、以后再删、先跳过、后面再补或类似原因进行与方案不同的降级实现
|
||||
- 执行必须先读取相关需求设计与架构,先读后写,不得违背架构独自实现
|
||||
- 代码审查不能只看代码是否存在,不能只跑代码是否通过门禁,必须先读取相关设计和约束然后code to review逐条审查+功能测试用例全过才能pass
|
||||
|
||||
## 多 Agent 调度规则(Main Agent 必读)
|
||||
|
||||
你是 Main Agent(用户交互入口)。你不直接写代码或执行复杂任务,而是**派发给专门的子代理**。
|
||||
|
||||
### 何时派发 Architect(架构师)
|
||||
|
||||
- 新项目或新功能开始时 → 派发 `architect` 子代理做需求分析和架构设计
|
||||
- 用户讨论架构、需求变更时 → 派发 `architect`
|
||||
- 提示词示例:`请用 architect 子代理分析这个需求并设计架构方案:{用户需求}`
|
||||
|
||||
### 何时派发 Scheduler(调度器)
|
||||
|
||||
- 用户提出需要多步骤实现的开发任务时 → 派发 `scheduler` 子代理
|
||||
- Architect 完成架构设计后,需要执行时 → 派发 `scheduler`
|
||||
- 提示词示例:`请用 scheduler 子代理执行以下任务:{任务描述}`
|
||||
|
||||
### 派发规则
|
||||
|
||||
1. **使用 `task` 工具**,设置 `subagent_type` 为 `scheduler`、`worker` 或 `architect`
|
||||
2. **始终设置 `background: true`**,让子代理在后台运行,你保持与用户的对话
|
||||
3. 子代理完成后会自动通知你,你负责向用户汇报结果
|
||||
4. 不要同时承担多个角色——你是协调者,不是执行者
|
||||
|
||||
### 对话流程
|
||||
|
||||
```
|
||||
用户提需求
|
||||
→ 如果是新领域/复杂需求 → 派发 architect 做架构设计
|
||||
→ architect 完成后 → 派发 scheduler 执行
|
||||
→ scheduler 完成 → 向用户汇报结果
|
||||
→ 如果用户追问细节 → 派发对应子代理处理
|
||||
```
|
||||
|
||||
### 简单任务例外
|
||||
|
||||
以下情况你可以直接处理,不需要派发子代理:
|
||||
- 回答用户关于项目/代码的问题(用 read/grep/glob)
|
||||
- 单文件的小修改(直接用 edit)
|
||||
- 解释已有代码的行为
|
||||
138
docs/INTEGRATION.md
Normal file
138
docs/INTEGRATION.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# AirCoding 集成指南
|
||||
|
||||
本文档说明如何将 AirCoding 的自定义组件集成到 OpenCode v1.17.4 fork 中。
|
||||
|
||||
## 需要集成的文件
|
||||
|
||||
| 源文件 | 目标位置 | 说明 |
|
||||
|--------|---------|------|
|
||||
| `src/tool/coordinator.ts` | `packages/opencode/src/tool/coordinator.ts` | 调度工具(4 个子工具) |
|
||||
| `src/agents/prompts/scheduler.md` | `packages/opencode/src/agent/prompt/scheduler.txt` | Scheduler system prompt |
|
||||
| `src/agents/prompts/worker.md` | `packages/opencode/src/agent/prompt/worker.txt` | Worker system prompt |
|
||||
| `src/agents/prompts/architect.md` | `packages/opencode/src/agent/prompt/architect.txt` | Architect system prompt |
|
||||
| `opencode.json` | 项目根目录 `.opencode/opencode.json` 或用户配置 | Agent 定义 |
|
||||
|
||||
## 步骤 1:复制 coordinator.ts
|
||||
|
||||
```bash
|
||||
cp src/tool/coordinator.ts packages/opencode/src/tool/coordinator.ts
|
||||
```
|
||||
|
||||
## 步骤 2:修改 registry.ts
|
||||
|
||||
在 `packages/opencode/src/tool/registry.ts` 中做以下修改:
|
||||
|
||||
### 2a. 添加 import(文件顶部)
|
||||
|
||||
```typescript
|
||||
import * as coordinator from "./coordinator"
|
||||
```
|
||||
|
||||
### 2b. 注册工具(约 198 行,tool init block 中)
|
||||
|
||||
在 `const tool = yield* Effect.all({` 块中添加:
|
||||
|
||||
```typescript
|
||||
coordinator_listen: Tool.init(coordinator.listen),
|
||||
coordinator_status: Tool.init(coordinator.status),
|
||||
coordinator_save_state: Tool.init(coordinator.saveState),
|
||||
coordinator_load_state: Tool.init(coordinator.loadState),
|
||||
```
|
||||
|
||||
### 2c. 添加到 builtin 列表(约 219 行)
|
||||
|
||||
在 `builtin: [` 数组中添加:
|
||||
|
||||
```typescript
|
||||
tool.coordinator_listen,
|
||||
tool.coordinator_status,
|
||||
tool.coordinator_save_state,
|
||||
tool.coordinator_load_state,
|
||||
```
|
||||
|
||||
## 步骤 3:复制 prompt 文件
|
||||
|
||||
```bash
|
||||
cp src/agents/prompts/scheduler.md packages/opencode/src/agent/prompt/scheduler.txt
|
||||
cp src/agents/prompts/worker.md packages/opencode/src/agent/prompt/worker.txt
|
||||
cp src/agents/prompts/architect.md packages/opencode/src/agent/prompt/architect.txt
|
||||
```
|
||||
|
||||
## 步骤 4:注册 Agent(可选)
|
||||
|
||||
可以选择以下两种方式之一注册自定义 Agent:
|
||||
|
||||
### 方式 A:通过 opencode.json 配置(推荐)
|
||||
|
||||
将 `opencode.json` 放到项目的 `.opencode/` 目录或用户全局配置目录中。OpenCode 会自动加载其中的 agent 定义。
|
||||
|
||||
### 方式 B:修改 agent.ts 源码
|
||||
|
||||
在 `packages/opencode/src/agent/agent.ts` 的 `agents` 对象中添加自定义 agent 定义(约 138 行):
|
||||
|
||||
```typescript
|
||||
scheduler: {
|
||||
name: "scheduler",
|
||||
description: "任务调度引擎",
|
||||
mode: "subagent",
|
||||
native: true,
|
||||
steps: 200,
|
||||
prompt: PROMPT_SCHEDULER,
|
||||
permission: Permission.merge(defaults, Permission.fromConfig({
|
||||
edit: "deny",
|
||||
write: "deny",
|
||||
todowrite: "deny",
|
||||
}), user),
|
||||
options: {},
|
||||
},
|
||||
worker: {
|
||||
name: "worker",
|
||||
description: "执行器/调试器双模式 Worker",
|
||||
mode: "subagent",
|
||||
native: true,
|
||||
steps: 100,
|
||||
prompt: PROMPT_WORKER,
|
||||
permission: Permission.merge(defaults, user),
|
||||
options: {},
|
||||
},
|
||||
architect: {
|
||||
name: "architect",
|
||||
description: "架构规划器",
|
||||
mode: "subagent",
|
||||
native: true,
|
||||
steps: 100,
|
||||
prompt: PROMPT_ARCHITECT,
|
||||
permission: Permission.merge(defaults, Permission.fromConfig({
|
||||
"*": "deny",
|
||||
read: "allow",
|
||||
glob: "allow",
|
||||
grep: "allow",
|
||||
task: "allow",
|
||||
}), user),
|
||||
options: {},
|
||||
},
|
||||
```
|
||||
|
||||
并在文件顶部添加 prompt import:
|
||||
|
||||
```typescript
|
||||
import PROMPT_SCHEDULER from "./prompt/scheduler.txt"
|
||||
import PROMPT_WORKER from "./prompt/worker.txt"
|
||||
import PROMPT_ARCHITECT from "./prompt/architect.txt"
|
||||
```
|
||||
|
||||
## 步骤 5:启用后台子代理
|
||||
|
||||
设置环境变量以启用 OpenCode 的后台子代理功能:
|
||||
|
||||
```bash
|
||||
export OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
|
||||
```
|
||||
|
||||
## 步骤 6:验证
|
||||
|
||||
1. 构建 OpenCode:`bun run build`(或 `bun dev` 开发模式)
|
||||
2. 在项目目录中创建 `.opencode/opencode.json`(包含 agent 配置)
|
||||
3. 创建 `.air/local/state/` 目录
|
||||
4. 启动 OpenCode,尝试使用 `task` 工具派发 scheduler/worker/architect 子代理
|
||||
5. 验证 coordinator_listen / coordinator_status 工具可用
|
||||
788
docs/aircoding-architecture-mvp.md
Normal file
788
docs/aircoding-architecture-mvp.md
Normal file
@@ -0,0 +1,788 @@
|
||||
# AirCoding Agent 最小化架构设计
|
||||
|
||||
> **版本**: MVP-0.3
|
||||
> **日期**: 2026-06-12
|
||||
> **基线**: OpenCode v1.17.4 (commit abda3515)
|
||||
> **策略**: 基于 OpenCode 最小修改,复用已有架构,植入多 Agent 协作
|
||||
|
||||
---
|
||||
|
||||
## 1. 核心定位
|
||||
|
||||
AirCoding 是基于 OpenCode 改造的 AI Coding Agent,核心 runtime 语言无关,C++ 为首个深度支持的语言 profile。
|
||||
|
||||
**与 OpenCode 的关系**:Fork OpenCode 作为内核,保留其 TUI、Provider、Session、Event 系统,在其上植入多 Agent 协作层。
|
||||
|
||||
**与 AirPlan V1 的关系**:AirPlan V1 是 Claude Code 上的插件方案,已验证架构方向但暴露大量可靠性问题(详见 `airplanV2-Qwen3.7-Max设计.md`)。AirCoding 将 V1 的经验教训内化为代码级约束,不再依赖自然语言指令控制 LLM 行为。
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计原则
|
||||
|
||||
### 2.1 代码级硬阻断
|
||||
|
||||
> 永远不要用自然语言指令去约束 LLM 的行为边界。凡是"不可违反"的规则,必须在代码层面硬阻断。
|
||||
|
||||
三道防线:
|
||||
|
||||
```
|
||||
第一道:工具白名单(Agent 注册时限定 tools 列表)
|
||||
→ Architecture Designer 没有 Write/Edit → 物理上不可能写代码
|
||||
→ Scheduler 没有 Write/Edit → 物理上不可能越界编码
|
||||
|
||||
第二道:状态机(Scheduler 的流程规则是代码,不是 prompt 建议)
|
||||
→ Executor 完成 → 代码自动触发 Reviewer(Worker 无法跳过)
|
||||
→ 证据不足 → 代码阻止标记完成(Worker 无法绕过)
|
||||
|
||||
第三道:结构化契约(TaskSpec/WorkerResult 是 TypeScript 类型)
|
||||
→ 缺失必填字段 → 类型校验失败,不接受结果
|
||||
→ denied_paths 被写入 → Permission 引擎拒绝
|
||||
```
|
||||
|
||||
### 2.2 最小修改原则
|
||||
|
||||
- 直接使用 OpenCode 已有的系统,不重写
|
||||
- 新增功能通过 Plugin 和 Agent 注册实现,不改 OpenCode 核心代码
|
||||
- 仅在 OpenCode 无法满足需求时才修改核心代码
|
||||
|
||||
### 2.3 单进程模型
|
||||
|
||||
- 沿用 OpenCode 的单进程模型
|
||||
- 子代理 = 子 session(通过 TaskTool + BackgroundJob 实现)
|
||||
- 不引入独立进程 IPC,降低复杂度
|
||||
|
||||
---
|
||||
|
||||
## 3. 架构总览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ OpenCode 内核 │
|
||||
│ ┌─────────┐ ┌──────────┐ ┌────────┐ ┌───────────┐ │
|
||||
│ │ TUI │ │ Provider │ │Session │ │ EventV2 │ │
|
||||
│ │OpenTUI │ │ Anthropic│ │SQLite │ │ PubSub │ │
|
||||
│ │SolidJS │ │ OpenAI │ │Drizzle │ │ Durable │ │
|
||||
│ └────┬────┘ └────┬─────┘ └───┬────┘ └─────┬─────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌────┴───────────┴───────────┴─────────────┴────┐ │
|
||||
│ │ AirCoding 多 Agent 层 │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────┐ ┌────────────┐ ┌─────────┐ │ │
|
||||
│ │ │Main Agent│──▶│ Scheduler │──▶│ Workers │ │ │
|
||||
│ │ │(对话入口) │ │ Agent │ │ │ │ │
|
||||
│ │ │ │ │ (事件路由) │ │Executor │ │ │
|
||||
│ │ │ │ │ │ │Reviewer │ │ │
|
||||
│ │ └──────────┘ │ ┌──────┐ │ │Debugger │ │ │
|
||||
│ │ │ │Arc │ │ └─────────┘ │ │
|
||||
│ │ ┌──────────┐ │ │Design│ │ │ │
|
||||
│ │ │Experience│ │ └──────┘ │ ┌─────────┐ │ │
|
||||
│ │ │ Miner │ └────────────┘ │C++ Tool │ │ │
|
||||
│ │ └──────────┘ │ Plugin │ │ │
|
||||
│ │ └─────────┘ │ │
|
||||
│ └───────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Agent 层级与职责
|
||||
|
||||
### 4.1 Main Agent(用户唯一交互入口)
|
||||
|
||||
- **职责**:对话、意图分类、进度汇报、需求变更处理
|
||||
- **工具**:全部对话类工具 + `task`(派发子代理)
|
||||
- **核心约束**:不直接操作文件和命令,保持空闲可响应用户介入
|
||||
- **模式**:
|
||||
- 对话模式(默认):不直接执行
|
||||
- 直通模式(`/direct` 触发):前台直接执行
|
||||
|
||||
### 4.2 Architecture Designer(只读)
|
||||
|
||||
- **职责**:架构规划、需求探讨、影响评估、全周期审查
|
||||
- **工具白名单**:`read`, `glob`, `grep`(**代码级只读**,无 Write/Edit/Bash)
|
||||
- **阶段门控**:
|
||||
- `discussing` → 与用户探讨需求,禁止生成计划
|
||||
- `proposing` → 呈现架构方案,等待用户确认
|
||||
- `confirmed` → 生成 TaskGraph,允许写入 plan/ 目录
|
||||
- **V1 教训**:P0-5(被 plan mode 劫持)→ 工具白名单硬阻断
|
||||
|
||||
### 4.3 Scheduler Agent(事件路由器)
|
||||
|
||||
- **职责**:任务拆解、派发、监控、合并、流程规则执行
|
||||
- **工具白名单**:`task`, `coordinator.listen`, `coordinator.dispatch`, `coordinator.status`, `read`, `glob`, `grep`(**无 Write/Edit**)
|
||||
- **核心机制**:
|
||||
- 通过 `BackgroundJob` 非阻塞派发子代理
|
||||
- 通过 `coordinator.listen` 订阅 EventV2,被动等待子代理事件
|
||||
- 按流程规则(代码级状态机)决定下一步派发
|
||||
- **V1 教训**:
|
||||
- P0-6(停下来问)→ system prompt 强制自主决策
|
||||
- P0-7(遗忘轮询)→ 不依赖 LLM 轮询,用事件驱动
|
||||
- P0-10(偏离调度写代码)→ 工具白名单硬阻断
|
||||
|
||||
#### 防卡死机制(简化版)
|
||||
|
||||
**不活跃定时器**:Scheduler 维护 `last_activity` 时间戳。以下任一动作更新该时间戳:派发新任务、收到子代理进度/完成/失败事件、用户介入操作。如果 `now - last_activity > 10 分钟`,自动触发一轮巡检(调用 `coordinator.status` 查询所有活跃子代理状态),根据结果处理卡死/崩溃的子代理。
|
||||
|
||||
**状态实时落盘**:Scheduler 的每次状态变更写入 `.air/local/state/scheduler-state.json`。内容包括:当前图状态快照(每个 task 的 status)、活跃子代理列表 + 最后心跳时间、当前调度阶段/波次、`last_activity` 时间戳。API 挂了 / 进程崩溃 / 用户关闭后,下次启动时读取该文件重建调度上下文继续调度。
|
||||
|
||||
#### LLM 调用策略(混合模式)
|
||||
|
||||
正常流程走确定性代码,异常/边界/用户输出时才调 LLM:
|
||||
|
||||
| 决策点 | 确定性(不调 LLM) | LLM 介入 |
|
||||
|--------|-------------------|---------|
|
||||
| 下一波任务选择 | DAG 遍历,入度为 0 自动 ready | 资源不足时决定优先级 |
|
||||
| Executor 完成 → 派发 Reviewer | 自动 | — |
|
||||
| build/test 失败 → 派发 Debugger | 自动 | — |
|
||||
| Debugger 修复后重试 | retry_budget 未耗尽时自动 | 预算耗尽时评估是否继续 |
|
||||
| Reviewer 不通过 → 重新派发 | 自动(前 2 次) | 连续 2 次不通过 → LLM 分析 |
|
||||
| 任务失败(非 build 原因) | — | LLM 分析原因 |
|
||||
| 需求变更 | — | LLM 变更分类 + 影响评估 |
|
||||
| 所有任务完成 → 汇总 | — | LLM 生成汇总报告 |
|
||||
|
||||
**防卡死兜底**:确定性代码遇到未匹配的状态转换时,不阻塞,直接调 LLM 分析。LLM 也失败则进入降级模式(只做基本调度),持续失败则暂停并上报用户。
|
||||
|
||||
### 4.4 Worker Agents
|
||||
|
||||
#### Executor
|
||||
|
||||
- **职责**:写代码、编译、测试、验证
|
||||
- **工具**:`read`, `write`, `edit`, `shell`, `glob`, `grep` + C++ 工具链 Plugin 工具
|
||||
- **内部循环**:TORI(Task → Observation → Reasoning → Iteration)
|
||||
- **出口**:TaskCompleted / TaskBlocked / TaskFailed
|
||||
- **约束**:TaskSpec 中的 `acceptance_criteria` + `scope.denied_paths`
|
||||
|
||||
#### Reviewer(只读)
|
||||
|
||||
- **职责**:代码审查、需求一致性验证、高风险审计
|
||||
- **工具白名单**:`read`, `glob`, `grep`(**只读**)
|
||||
- **触发**:Scheduler 在 Executor 完成后自动派发(代码级规则,Worker 无法跳过)
|
||||
- **上下文**:ContextAssembler 按需抽取当前任务模块的 plan 段落 + 需求条目(局部视野,~4K-6K tokens)
|
||||
- **审查范围**:任务验收(acceptance_criteria)+ 模块内 Code-to-Design + 代码质量 + 高风险审计
|
||||
- **V1 教训**:P0-8(AirDo 跳过专家)→ Scheduler 强制派发,不由 Worker 决定
|
||||
|
||||
**两层审查模型**:
|
||||
|
||||
| | 逐任务审查 (Reviewer) | 里程碑审查 (Architecture Designer) |
|
||||
|---|---|---|
|
||||
| 触发时机 | 每个 Executor 完成后 | 每个阶段/波次完成后 |
|
||||
| 上下文范围 | 局部(当前任务 + 模块段落) | 全局(完整 plan + 所有审查报告) |
|
||||
| 检查重点 | 任务验收 + 模块内 Code-to-Design | 跨模块架构一致性 |
|
||||
| 上下文大小 | ~4K-6K tokens | ~8K-15K tokens |
|
||||
| 频率 | 高(每个任务一次) | 低(每个阶段一次) |
|
||||
|
||||
里程碑审查由 Scheduler 在阶段内所有任务完成后自动派发 Architecture Designer,Arc 持有完整 plan.md + 本阶段所有 Reviewer 报告,重点检查跨模块依赖方向、公共接口一致性、模块职责边界。
|
||||
|
||||
#### Debugger
|
||||
|
||||
- **职责**:证据收集、问题定位、修复、验证
|
||||
- **工具**:分两阶段
|
||||
- `GATHERING` 阶段:只读工具(`read`, `glob`, `grep`, `shell` 仅用于运行诊断命令)
|
||||
- `FIXING` 阶段:开放写工具(`write`, `edit`)
|
||||
- 阶段转换由代码检查证据列表,无证据不允许进入 FIXING
|
||||
- **V1 教训**:P1-17(未取证就改代码)→ 阶段门控硬阻断
|
||||
|
||||
#### ExperienceMiner(后台)
|
||||
|
||||
- **职责**:从会话中提取经验、生成 SKILL.md、去重归档
|
||||
- **触发**:会话结束时 / DebugRecord 产生时 / 定期触发
|
||||
- **不阻塞 Main Agent**
|
||||
|
||||
#### Compactor(后台)
|
||||
|
||||
- **职责**:上下文压缩(Copy-on-Write)
|
||||
- **触发**:Context window 占比达 70%
|
||||
- **直接复用 OpenCode 的 `compaction.ts`**
|
||||
|
||||
---
|
||||
|
||||
## 5. 子代理通信机制
|
||||
|
||||
### 5.1 通信模型
|
||||
|
||||
OpenCode 的 TaskTool 是父子树状通信。AirCoding 通过 **EventV2 + Scheduler 路由** 实现兄弟 agent 之间的松耦合通信。
|
||||
|
||||
```
|
||||
子 Agent 完成 → EventV2 广播事件 → Scheduler 收到事件 → Scheduler 按规则派发下一个子 Agent
|
||||
```
|
||||
|
||||
不是 agent 之间直接对话,而是通过事件 + Scheduler 路由。
|
||||
|
||||
### 5.2 流程规则(Scheduler 的状态机)
|
||||
|
||||
```
|
||||
Executor 完成 → 自动触发 Reviewer(逐任务审查)
|
||||
Reviewer 通过 → 标记任务完成
|
||||
build/test 失败 → 自动触发 Debugger
|
||||
Reviewer 发现问题 → 重新派发 Executor 修复
|
||||
阶段内所有任务完成 → 自动触发 Architecture Designer(里程碑审查)
|
||||
里程碑审查通过 → 进入下一阶段
|
||||
里程碑审查发现问题 → Arc 生成修复任务 → Scheduler 派发
|
||||
需求变更 → 触发动态 DAG 调度算法(§14)
|
||||
Scheduler 异常无法决策 → 派发 Architecture Designer(咨询)
|
||||
所有任务完成 → 汇总结果返回 Main Agent
|
||||
```
|
||||
|
||||
这些规则在 Scheduler 的 system prompt 中定义,但执行由 `coordinator.listen` 工具驱动——Scheduler 被动接收事件,按规则响应。
|
||||
|
||||
### 5.3 需要新增的工具
|
||||
|
||||
#### `coordinator.listen`
|
||||
|
||||
让 Scheduler 在 TORI 循环中等待子代理事件:
|
||||
|
||||
```typescript
|
||||
// .opencode/tool/coordinator.ts
|
||||
Tool.define("coordinator.listen", {
|
||||
description: "等待并返回下一个子代理事件",
|
||||
parameters: Schema.Struct({
|
||||
event_types: Schema.Array(Schema.String),
|
||||
timeout_ms: Schema.optional(Schema.Number),
|
||||
}),
|
||||
execute: async ({ event_types, timeout_ms }) => {
|
||||
// 订阅 EventV2,等待匹配的事件到达
|
||||
// 返回事件内容
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### `coordinator.dispatch`
|
||||
|
||||
让 Scheduler 批量派发子代理:
|
||||
|
||||
```typescript
|
||||
Tool.define("coordinator.dispatch", {
|
||||
description: "批量派发子代理任务",
|
||||
parameters: Schema.Struct({
|
||||
tasks: Schema.Array(Schema.Struct({
|
||||
agent_type: Schema.Literal("executor", "reviewer", "debugger"),
|
||||
task_spec: TaskSpecSchema,
|
||||
background: Schema.optional(Schema.Boolean),
|
||||
})),
|
||||
}),
|
||||
execute: async ({ tasks }) => {
|
||||
// 为每个任务创建 BackgroundJob 或前台子 session
|
||||
// 返回 job IDs
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### `coordinator.status`
|
||||
|
||||
让 Scheduler 查询当前所有子代理的状态:
|
||||
|
||||
```typescript
|
||||
Tool.define("coordinator.status", {
|
||||
description: "查询所有活跃子代理的状态",
|
||||
parameters: Schema.Struct({}),
|
||||
execute: async () => {
|
||||
// 查询所有活跃 BackgroundJob 的状态
|
||||
// 返回 [{ jobId, agentType, taskId, status, progress }]
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. TaskSpec 与 WorkerResult 结构化契约
|
||||
|
||||
### 6.1 TaskSpec
|
||||
|
||||
```typescript
|
||||
interface TaskSpec {
|
||||
id: string
|
||||
type: "execute" | "review" | "debug" | "compact" | "mine_experience"
|
||||
title: string
|
||||
description: string
|
||||
|
||||
// 验收标准(结构化,非自由文本)
|
||||
acceptance_criteria: string[]
|
||||
|
||||
// 作用域约束
|
||||
scope: {
|
||||
expected_files?: string[] // 预期修改的文件
|
||||
denied_paths?: string[] // 禁止触碰的路径
|
||||
preserved_paths?: string[] // 必须保留不动的路径
|
||||
write_area?: string // 写区域标识(用于冲突检测)
|
||||
}
|
||||
|
||||
// 接口契约(用于影响传播算法)
|
||||
contracts: {
|
||||
provides?: InterfaceContract[] // 本任务对外暴露的接口
|
||||
requires?: InterfaceContract[] // 本任务依赖的接口
|
||||
}
|
||||
|
||||
// 依赖关系
|
||||
dependencies: Array<{
|
||||
task_id: string
|
||||
type: "hard" | "soft" | "conflict" | "serialization"
|
||||
}>
|
||||
|
||||
// 验证要求
|
||||
verification: {
|
||||
commands?: string[] // 验证命令
|
||||
required: boolean // 是否必须通过验证才能标记完成
|
||||
evidence_types?: string[] // 需要的证据类型(screenshot, pcap, static_analysis 等)
|
||||
}
|
||||
|
||||
// 约束
|
||||
constraints: {
|
||||
max_turns: number
|
||||
soft_timeout_ms: number
|
||||
hard_timeout_ms: number
|
||||
retry_budget: number
|
||||
}
|
||||
}
|
||||
|
||||
interface InterfaceContract {
|
||||
module: string // "auth", "database", "ui/login"
|
||||
kind: "api" | "schema" | "file" | "config" | "protocol"
|
||||
spec: string // 人类可读的描述,不要求形式化
|
||||
stability: "stable" | "volatile" | "frozen" // stable: 大概率不变; volatile: 可能随需求调整; frozen: 已有下游依赖不应改
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 WorkerResult
|
||||
|
||||
```typescript
|
||||
interface WorkerResult {
|
||||
task_id: string
|
||||
agent_type: "executor" | "reviewer" | "debugger"
|
||||
status: "completed" | "failed" | "blocked" | "cancelled"
|
||||
|
||||
// 结构化摘要(3-6 句话)
|
||||
summary: string
|
||||
|
||||
// 变更清单
|
||||
changed_files: string[]
|
||||
diff_ref?: string
|
||||
|
||||
// 验证结果(结构化)
|
||||
verification: Array<{
|
||||
name: string
|
||||
status: "passed" | "failed" | "skipped"
|
||||
evidence_ref?: string
|
||||
notes?: string
|
||||
}>
|
||||
|
||||
// 收集的证据
|
||||
evidence: Array<{
|
||||
type: "screenshot" | "pcap" | "static_analysis" | "test_output" | "build_log" | "code_trace"
|
||||
ref: string
|
||||
summary: string
|
||||
}>
|
||||
|
||||
// 风险评估
|
||||
risks: Array<{
|
||||
severity: "low" | "medium" | "high"
|
||||
summary: string
|
||||
}>
|
||||
|
||||
// 后续建议
|
||||
follow_up_tasks?: Array<{
|
||||
title: string
|
||||
type: "execute" | "review" | "debug"
|
||||
}>
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. AirPlan V1 痛点 → AirCoding 对策清单
|
||||
|
||||
### 7.1 P0 级(已造成实际损失)
|
||||
|
||||
| ID | V1 痛点 | AirCoding 对策 | 防线 |
|
||||
|----|---------|---------------|------|
|
||||
| P0-1 | 证据门控假阳性 | Scheduler 按 TaskSpec.verification.evidence_types 决定需要什么证据 | 状态机 |
|
||||
| P0-2 | 部署验证缺口 | verification.required=true 时,Scheduler 检查 VerificationResult 才允许完成 | 状态机 |
|
||||
| P0-3 | 非原子写入 | OpenCode SQLite 事务 | 内核 |
|
||||
| P0-4 | 零并发控制 | OpenCode EventV2 + session 隔离 | 内核 |
|
||||
| P0-5 | Arc 被 plan mode 劫持 | Architecture Designer 工具白名单只含只读工具 | 工具白名单 |
|
||||
| P0-6 | Eng 停下来问不自主推进 | Scheduler system prompt 强制自主决策,仅三种情况询问用户 | prompt + 工具 |
|
||||
| P0-7 | Eng 遗忘轮询 | 不依赖 LLM 轮询,用 `coordinator.listen` 事件驱动 | 工具 |
|
||||
| P0-8 | AirDo 跳过专家插件 | Scheduler 代码级规则自动派发 Reviewer/Debugger,Worker 无权跳过 | 状态机 |
|
||||
| P0-9 | 安装器路径错误 | OpenCode Plugin SDK 标准注册 | 内核 |
|
||||
| P0-10 | Eng 偏离调度写代码 | Scheduler 工具白名单无 Write/Edit | 工具白名单 |
|
||||
|
||||
### 7.2 P1 级(限制可靠性)
|
||||
|
||||
| ID | V1 痛点 | AirCoding 对策 | 防线 |
|
||||
|----|---------|---------------|------|
|
||||
| P1-14 | 需求变更后调度恢复慢 | TaskGraph + PlanDelta 增量更新 + 影响传播算法(待设计) | 调度算法 |
|
||||
| P1-15 | 同文件无冲突被迫串行 | 区域级冲突检测 + worktree 隔离 | 调度算法 |
|
||||
| P1-16 | Arc 跳过需求探讨 | Architecture Designer 阶段门控(discussing → proposing → confirmed) | 状态机 |
|
||||
| P1-17 | AirDbg 未取证就改代码 | Debugger 分阶段工具权限(GATHERING 只读 → FIXING 写) | 工具白名单 |
|
||||
| P1-21 | ADR 变更级联失效 | Scheduler 订阅 ADR 变更事件 → 影响传播 → 选择性失效 | 调度算法 |
|
||||
| P1-22 | Dispatch→Worker 断链 | OpenCode TaskTool 代码级派发,无 JSON 中间文件 | 内核 |
|
||||
| P1-24 | 任务描述歧义导致破坏 | TaskSpec 结构化:scope.expected_files + denied_paths + acceptance_criteria | 结构化契约 |
|
||||
| P1-25 | Merge 后状态不同步 | OpenCode domain tables 事务更新 | 内核 |
|
||||
|
||||
---
|
||||
|
||||
## 8. C++ 工具链(Plugin 方式)
|
||||
|
||||
C++ 工具链作为 OpenCode Plugin 注册,放在 `.opencode/tool/` 目录或通过 Plugin SDK 注册。
|
||||
|
||||
### 8.1 工具列表
|
||||
|
||||
| 工具名 | 功能 | 对应 V1 |
|
||||
|--------|------|---------|
|
||||
| `cpp.build` | CMake/Ninja 构建 | AirSDB 扩展 |
|
||||
| `cpp.test` | CTest + GoogleTest 运行 | AirTst |
|
||||
| `cpp.analyze` | cppcheck + clang-tidy 静态分析 | AirSDB |
|
||||
| `cpp.diagnose` | 编译错误解析(LLM 驱动) | Debugger 内置 |
|
||||
| `cpp.intelligence` | clangd CLI 模式代码智能 | 新增 |
|
||||
| `cpp.screenshot` | GUI 截图采集 | AirXDB |
|
||||
| `cpp.packet_capture` | 网络抓包 | AirNDB |
|
||||
| `cpp.deploy` | SSH 远程部署 + 验证 | AirDep |
|
||||
|
||||
### 8.2 证据门控策略
|
||||
|
||||
#### 任务类型分类
|
||||
|
||||
```typescript
|
||||
enum TaskCategory {
|
||||
CPP_LOGIC = "cpp_logic", // C++ 业务逻辑、算法、状态机
|
||||
CPP_BUILD = "cpp_build", // CMake/构建配置
|
||||
CPP_GUI = "cpp_gui", // Qt/GTK UI 组件
|
||||
CPP_NETWORK = "cpp_network", // 网络协议、通信模块
|
||||
CPP_DEPLOY = "cpp_deploy", // 部署、打包、安装
|
||||
CONFIG = "config", // 配置文件修改
|
||||
DOCS = "docs", // 文档编写
|
||||
TEST = "test", // 测试用例编写/运行
|
||||
REFACTOR = "refactor", // 重构(不改功能)
|
||||
BUGFIX = "bugfix", // Bug 修复
|
||||
}
|
||||
```
|
||||
|
||||
#### 证据策略表
|
||||
|
||||
| 任务类型 | 必需证据 | 可选证据 |
|
||||
|---------|---------|---------|
|
||||
| `cpp_logic` | build_pass, test_pass | static_analysis |
|
||||
| `cpp_build` | build_pass | — |
|
||||
| `cpp_gui` | build_pass, screenshot | test_pass |
|
||||
| `cpp_network` | build_pass, pcap | test_pass |
|
||||
| `cpp_deploy` | build_pass, deploy_verify | smoke_test |
|
||||
| `config` | build_pass | — |
|
||||
| `docs` | — | — |
|
||||
| `test` | build_pass, test_output | — |
|
||||
| `refactor` | build_pass, test_pass, diff_review | static_analysis |
|
||||
| `bugfix` | build_pass, test_pass, reproduction | screenshot, pcap |
|
||||
|
||||
Architecture Designer 生成 TaskSpec 时根据任务描述和文件范围自动推断 `verification.evidence_types`。用户可在 plan 中用 `[no-screenshot]` 等标记显式跳过。
|
||||
|
||||
#### 全局强制规则
|
||||
|
||||
```typescript
|
||||
// 1. blocked/failed 状态必须附 debugger 分析
|
||||
if (result.status === "blocked" || result.status === "failed") {
|
||||
required_evidence.push("debugger_analysis")
|
||||
}
|
||||
|
||||
// 2. 无文件变更的 done 必须有解释
|
||||
if (result.status === "completed" && result.changed_files.length === 0) {
|
||||
required_evidence.push("explanation")
|
||||
}
|
||||
|
||||
// 3. C++ 文件变更强制静态分析
|
||||
if (result.changed_files.some(f => f.match(/\.(cpp|h|hpp|cc|cxx)$/))) {
|
||||
required_evidence.push("static_analysis")
|
||||
}
|
||||
```
|
||||
|
||||
Scheduler 按此策略检查 WorkerResult 中的 evidence 是否齐全,不齐全则阻止标记完成。
|
||||
|
||||
---
|
||||
|
||||
## 9. 上下文共享模型
|
||||
|
||||
### 共享数据源
|
||||
|
||||
所有 Agent 通过共享文件访问架构上下文,Scheduler 作为通信中枢派发时通过 ContextPack 传递引用:
|
||||
|
||||
```
|
||||
.air/shared/ ← 所有 Agent 可读
|
||||
├── plan/
|
||||
│ ├── plan.md ← 架构方案
|
||||
│ ├── task-graph.json ← 任务图(source of truth)
|
||||
│ ├── requirements.md ← 原始需求
|
||||
│ └── docs/
|
||||
│ └── ADR-*.md ← 架构决策记录
|
||||
└── rules/
|
||||
├── project-rules.md
|
||||
└── toolchain-rules.md
|
||||
```
|
||||
|
||||
### 三条通信路径
|
||||
|
||||
```
|
||||
路径 1: Scheduler → Architecture Designer(重规划/异常咨询)
|
||||
Scheduler 发现问题 → 派发 Arc 子 session
|
||||
→ ContextPack 携带问题描述 + 当前图引用
|
||||
→ Arc 读图 → 输出 PlanDelta 或建议
|
||||
→ 结果通过 WorkerResult 返回 Scheduler
|
||||
|
||||
路径 2: Reviewer 对照审查(Code-to-Design)
|
||||
Scheduler 派发 Reviewer 时,ContextPack 包含 plan 段落 + 需求条目
|
||||
→ Reviewer 读文件做 Code-to-Design 对照
|
||||
→ 审查报告写入 WorkerResult
|
||||
→ 里程碑审查时 Arc 持有完整 plan + 所有审查报告(全局视野)
|
||||
|
||||
路径 3: Scheduler 异常咨询 Architecture Designer
|
||||
Scheduler 确定性代码 + LLM 都无法决策
|
||||
→ 派发 Arc 子 session,task type = "consult"
|
||||
→ 传入当前困境 + 图状态
|
||||
→ Arc 返回建议 → Scheduler 按建议执行
|
||||
```
|
||||
|
||||
### ContextAssembler 按需组装
|
||||
|
||||
Agent 不直接读完整文件。ContextAssembler 根据当前任务只抽取相关片段:
|
||||
|
||||
| 完整文件 | 抽取策略 | 预估大小 |
|
||||
|---------|---------|---------|
|
||||
| plan.md (500 行) | 按 TaskSpec 涉及的 module 抽取相关段落 | ~30 行 |
|
||||
| task-graph.json (200 节点) | 仅当前任务 + 直接上下游邻居 | ~5-10 节点 |
|
||||
| requirements.md (100 行) | 按 module 过滤相关需求条目 | ~5-10 条 |
|
||||
| ADR 目录 (20 份) | 仅加载 TaskSpec.contracts 引用的 ADR | ~1-3 份 |
|
||||
| project-rules.md | 按 scope.expected_files 过滤相关规则 | ~10-20 条 |
|
||||
|
||||
各 Agent 典型上下文大小:
|
||||
|
||||
| Agent | 上下文组成 | 预估 token |
|
||||
|-------|----------|-----------|
|
||||
| Executor | TaskSpec + plan 段落 + 邻居节点 + 相关规则 + ADR | ~3K-5K |
|
||||
| Reviewer | TaskSpec + plan 段落 + 需求条目 + 相关规则 + diff | ~4K-6K |
|
||||
| Scheduler | 图状态摘要(ID + status 列表)+ 事件 | ~2K-4K |
|
||||
| Arc (里程碑审查) | 完整 plan + 本阶段所有 Reviewer 报告 | ~8K-15K |
|
||||
| Arc (重规划) | 变更描述 + 受影响任务上下文 + frozen 接口 | ~5K-8K |
|
||||
|
||||
---
|
||||
|
||||
## 10. 上下文与记忆
|
||||
|
||||
### 10.1 直接复用 OpenCode
|
||||
|
||||
- **上下文压缩**:`compaction.ts`(已有,70% 阈值触发)
|
||||
- **会话持久化**:SQLite per-session(已有)
|
||||
- **消息存储**:Anthropic 原生 content blocks(已有)
|
||||
|
||||
### 10.2 新增
|
||||
|
||||
- **Project Rules**:`.air/shared/rules/project-rules.md`(Claude Code 风格 Markdown + frontmatter)
|
||||
- **Learned Experience**:`~/.air/skills/<skill-name>/SKILL.md`(YAML frontmatter + Markdown body)
|
||||
- **Debug Knowledge**:SQLite 本地知识库,DebugRecord 结构化存储
|
||||
- **ExperienceMiner**:独立后台 Agent,会话结束时提取经验
|
||||
|
||||
---
|
||||
|
||||
## 11. 目录结构
|
||||
|
||||
### 11.1 全局
|
||||
|
||||
```
|
||||
~/.air/
|
||||
├── config.yaml # AirCoding 配置(扩展 OpenCode config)
|
||||
├── models.yaml # 模型配置
|
||||
├── permissions.yaml # 权限规则
|
||||
├── compaction-rules.md # 压缩规则
|
||||
├── skills/ # 跨项目复用技能(SKILL.md)
|
||||
└── logs/
|
||||
```
|
||||
|
||||
### 11.2 项目内
|
||||
|
||||
```
|
||||
<project>/.air/
|
||||
├── shared/ # 可提交 git
|
||||
│ ├── project.json # 项目元数据
|
||||
│ ├── rules/
|
||||
│ │ ├── project-rules.md
|
||||
│ │ └── toolchain-rules.md
|
||||
│ └── plan/
|
||||
│ ├── AGENTS.md
|
||||
│ ├── plan.md
|
||||
│ ├── task-graph.json
|
||||
│ └── docs/
|
||||
└── local/ # gitignore
|
||||
├── sessions/ # OpenCode session DB
|
||||
├── state/
|
||||
│ └── scheduler-state.json # 调度器实时状态(防卡死 + 崩溃恢复)
|
||||
├── debug-records.db
|
||||
├── learned-memory.db
|
||||
└── workspaces/ # git worktree 隔离区
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. MVP 范围
|
||||
|
||||
### 12.1 包含
|
||||
|
||||
1. **Main Agent 对话 + 意图分类**(复用 OpenCode)
|
||||
2. **Architecture Designer Agent**(只读,阶段门控)
|
||||
3. **Scheduler Agent**(事件驱动调度,coordinator 工具)
|
||||
4. **Executor Worker**(TORI 循环,C++ 工具链 Plugin)
|
||||
5. **Reviewer Worker**(只读,自动触发)
|
||||
6. **Debugger Worker**(分阶段权限,证据门控)
|
||||
7. **C++ 工具链 Plugin**(build, test, analyze, diagnose)
|
||||
8. **TaskSpec / WorkerResult 结构化契约**
|
||||
9. **Session 持久化**(复用 OpenCode)
|
||||
10. **上下文压缩**(复用 OpenCode)
|
||||
11. **Project Rules**(Markdown + frontmatter)
|
||||
|
||||
### 12.2 不包含(后续迭代)
|
||||
|
||||
- ExperienceMiner / Curator Daemon
|
||||
- Debug Knowledge Network
|
||||
- 多语言 toolchain(Python/Rust/JS)
|
||||
- HUD / Status Layer
|
||||
- 二进制分发
|
||||
- 动态 DAG 调度算法的完整实现(MVP 阶段先用简单的全量重规划,§14 的增量算法后续迭代)
|
||||
|
||||
---
|
||||
|
||||
## 13. OpenCode 改造点清单
|
||||
|
||||
### 13.1 不改(直接复用)
|
||||
|
||||
| 模块 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| TUI | `packages/tui/` | OpenTUI/Solid,直接复用 |
|
||||
| Provider | `packages/opencode/src/provider/` | Anthropic + OpenAI 抽象 |
|
||||
| Session DB | `packages/core/src/session/sql.ts` | SQLite + Drizzle |
|
||||
| Event System | `packages/core/src/event.ts` | EventV2 PubSub |
|
||||
| Context Compaction | `packages/opencode/src/session/compaction.ts` | 自动压缩 |
|
||||
| Tool Registry | `packages/opencode/src/tool/registry.ts` | 工具注册框架 |
|
||||
| Permission | OpenCode 权限系统 | 权限检查 |
|
||||
| BackgroundJob | `packages/opencode/src/background/job.ts` | 异步子代理 |
|
||||
|
||||
### 13.2 新增文件
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `.opencode/tool/coordinator.ts` | coordinator.listen / dispatch / status 工具 |
|
||||
| `.opencode/tool/cpp-*.ts` | C++ 工具链 Plugin |
|
||||
| `agents/main.ts` | Main Agent 配置(system prompt + 工具列表) |
|
||||
| `agents/architecture-designer.ts` | Arc Agent 配置(只读工具 + 阶段门控) |
|
||||
| `agents/scheduler.ts` | Scheduler Agent 配置(事件路由 + 流程规则) |
|
||||
| `agents/executor.ts` | Executor Worker 配置 |
|
||||
| `agents/reviewer.ts` | Reviewer Worker 配置(只读) |
|
||||
| `agents/debugger.ts` | Debugger Worker 配置(分阶段权限) |
|
||||
| `contracts/task-spec.ts` | TaskSpec 类型定义 |
|
||||
| `contracts/worker-result.ts` | WorkerResult 类型定义 |
|
||||
| `contracts/interface-contract.ts` | InterfaceContract 类型定义 |
|
||||
|
||||
### 13.3 需要修改的 OpenCode 代码(最小改动)
|
||||
|
||||
| 改动 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| Agent 注册扩展 | `packages/opencode/src/agent/agent.ts` | 注册自定义 Agent 类型 |
|
||||
| TaskTool 扩展 | `packages/opencode/src/tool/task.ts` | 支持 BackgroundJob 批量派发 |
|
||||
| EventV2 事件类型 | `packages/core/src/event.ts` | 新增 agent 协调事件类型 |
|
||||
|
||||
---
|
||||
|
||||
## 14. 动态 DAG 调度算法
|
||||
|
||||
核心场景:需求中途变更,任务图部分失效,部分任务还在跑,需要智能判断哪些保留、哪些重做。
|
||||
|
||||
### 算法总流程
|
||||
|
||||
```
|
||||
需求变更发生
|
||||
↓
|
||||
Phase 1: 变更分类(LLM)→ ChangeScope + 涉及模块列表
|
||||
↓
|
||||
Phase 2: 影响传播(确定性代码 + LLM 辅助)→ 每个任务标记 SAFE / BOUNDARY / IMPACTED
|
||||
↓
|
||||
Phase 3: 飞行中任务调和(确定性代码)→ cancel / wait_and_assess / let_finish
|
||||
↓
|
||||
Phase 4: 图重建(LLM)→ 仅重规划 IMPACTED 区域,SAFE 区域不动
|
||||
↓
|
||||
恢复调度
|
||||
```
|
||||
|
||||
### Phase 1: 变更分类
|
||||
|
||||
Architecture Designer (LLM) 输出结构化结果:
|
||||
|
||||
```typescript
|
||||
interface ChangeDescription {
|
||||
scope: "implementation" | "internal_interface" | "external_interface"
|
||||
| "module_replacement" | "global_constraint"
|
||||
affected_modules: string[]
|
||||
summary: string
|
||||
}
|
||||
```
|
||||
|
||||
分类规则:`implementation`(仅实现细节变,接口不变)→ `internal_interface`(模块内部接口变)→ `external_interface`(公开接口变)→ `module_replacement`(整个模块替换)→ `global_constraint`(全局约束变更)。影响范围逐级扩大。
|
||||
|
||||
### Phase 2: 影响传播
|
||||
|
||||
BFS 遍历依赖图,基于 InterfaceContract 判断影响范围:
|
||||
|
||||
```typescript
|
||||
function propagateImpact(graph, change): Map<string, ImpactZone> {
|
||||
// 1. 种子节点:直接涉及变更模块的任务 → IMPACTED
|
||||
// 2. BFS 向前传播:检查 provides/requires 契约匹配
|
||||
// - 契约 broken (volatile 接口) → IMPACTED,继续传播
|
||||
// - 契约 partial (stable 接口) → BOUNDARY,继续传播
|
||||
// - 契约 intact (frozen 接口) → SAFE,停止传播
|
||||
// 3. 未触及的节点 → SAFE
|
||||
}
|
||||
```
|
||||
|
||||
**关键**:契约匹配是概率信号,不是确定性判断。BOUNDARY 任务需要后续二次确认。
|
||||
|
||||
### Phase 3: 飞行中任务调和
|
||||
|
||||
根据任务状态 + 影响区域决定处理方式:
|
||||
|
||||
| 任务状态 | IMPACTED | BOUNDARY | SAFE |
|
||||
|---------|----------|----------|------|
|
||||
| completed | 回滚 (rollback) | 验证 (verify) | 保留 |
|
||||
| running/dispatched | 取消 (cancel) | 等完成后评估 (wait_and_assess) | 继续 |
|
||||
| pending | 冻结 (freeze) | 冻结 (freeze) | 正常调度 |
|
||||
|
||||
### Phase 4: 图重建
|
||||
|
||||
1. 移除取消和回滚的任务
|
||||
2. 冻结调度(`dispatchFrozen = true`)
|
||||
3. 提取 SAFE 已完成任务的接口作为 frozen 约束
|
||||
4. 调用 Architecture Designer 局部重规划(传入变更描述 + frozen 接口 + 受影响任务上下文)
|
||||
5. 插入新任务,重建依赖边
|
||||
6. 为 BOUNDARY 已完成任务生成验证任务
|
||||
7. 解冻调度
|
||||
|
||||
### 环检测
|
||||
|
||||
入库前和动态添加依赖边时做拓扑排序检查(Kahn 算法)。发现环时反馈给 Architecture Designer 修正,不阻塞调度。
|
||||
|
||||
### 触发方式
|
||||
|
||||
- 用户显式说"需求变了" → Main Agent 识别 → 通知 Scheduler
|
||||
- Architecture Designer 里程碑审查时发现偏离 → 主动触发
|
||||
- ADR 文件变更 → 文件监控检测
|
||||
|
||||
---
|
||||
|
||||
## 15. 已确定事项
|
||||
|
||||
| # | 议题 | 结论 |
|
||||
|---|------|------|
|
||||
| 1 | 接口契约精度 | 中等粒度:module + kind + 人类可读描述 + stability 标记。LLM 生成可靠,影响传播算法作为概率信号使用 |
|
||||
| 2 | Scheduler LLM 调用策略 | 混合模式:正常流程走确定性代码(DAG 遍历 + 状态机),异常/边界/用户输出时调 LLM。防卡死兜底:未匹配转换不阻塞,直接走 LLM |
|
||||
| 3 | 证据门控策略 | 10 种任务类型 × 必需/可选证据表 + 3 条全局强制规则。Arc 自动推断,用户可显式覆盖 |
|
||||
| 4 | 防卡死机制 | 简化方案:10 分钟不活跃定时器自动巡检 + scheduler-state.json 实时落盘(崩溃恢复) |
|
||||
| 5 | 动态 DAG 调度算法 | 四阶段算法(变更分类 → 影响传播 → 飞行调和 → 图重建)+ 环检测 + 三种触发方式 |
|
||||
| 6 | 上下文共享模型 | 共享文件 + ContextPack + WorkerResult 三通道。ContextAssembler 按需抽取,不全量加载 |
|
||||
| 7 | 审查分层 | 两层审查:Reviewer 逐任务局部审查 + Architecture Designer 阶段性里程碑审查(全局视野) |
|
||||
|
||||
---
|
||||
|
||||
## 16. 待讨论
|
||||
|
||||
(暂无)
|
||||
1985
docs/airplanV2-Qwen3.7-Max设计.md
Normal file
1985
docs/airplanV2-Qwen3.7-Max设计.md
Normal file
File diff suppressed because it is too large
Load Diff
884
docs/baselineV1.md
Normal file
884
docs/baselineV1.md
Normal file
@@ -0,0 +1,884 @@
|
||||
# AirCoding Architecture Baseline V1
|
||||
|
||||
Date: 2026-05-26
|
||||
Status: Canonical baseline for formal C4 / ADR / plan / todo work
|
||||
|
||||
This document supersedes earlier exploratory wording in `idea.md` and decision rounds where conflicts exist. Round files remain historical records; this baseline is the implementation-facing source of truth until V2.
|
||||
|
||||
## 1. Product Positioning
|
||||
|
||||
AirCoding is a self-owned AI coding agent/runtime, not a Claude Code plugin wrapper.
|
||||
|
||||
The runtime is language-agnostic. C++ is the first deep language profile, with later expansion through `toolchain-<lang>` packages.
|
||||
|
||||
Core loop:
|
||||
|
||||
```text
|
||||
Requirement understanding
|
||||
→ architecture/interface design
|
||||
→ code reading
|
||||
→ implementation planning
|
||||
→ build
|
||||
→ static analysis
|
||||
→ test
|
||||
→ run/debug
|
||||
→ crash/log/network/GUI evidence analysis
|
||||
→ fix
|
||||
→ change summary
|
||||
→ experience mining
|
||||
```
|
||||
|
||||
## 2. Reference Projects and Roles
|
||||
|
||||
### OpenCode
|
||||
|
||||
Reference for:
|
||||
|
||||
- Runtime layering
|
||||
- TUI visual style and interaction layout
|
||||
- Session/event/sync concepts
|
||||
- Provider/model abstraction
|
||||
- Plugin/SDK extension ideas
|
||||
|
||||
AirCoding reuses OpenCode-style UI primitives and OpenTUI patterns, but does **not** reuse OpenCode SDK/sync/session business state.
|
||||
|
||||
### Claude Code CLI
|
||||
|
||||
Primary reference for execution-layer quality.
|
||||
|
||||
AirCoding execution-layer primitives should align with Claude Code as much as possible to maximize code quality, correctness, safe modification behavior, and verification discipline.
|
||||
|
||||
Reference areas:
|
||||
|
||||
- File read/edit/write safety boundaries
|
||||
- Exact and conservative diff/update application behavior
|
||||
- Patch granularity and conflict handling
|
||||
- Tool lifecycle and schema style
|
||||
- Permission checks around filesystem and shell
|
||||
- Read-before-edit discipline
|
||||
- Small-step edits
|
||||
- Avoiding unrelated refactors and premature abstractions during task execution
|
||||
- Verification-before-completion discipline
|
||||
- Build/test/debug evidence collection before declaring completion
|
||||
- Project Rules / memory adherence during edits
|
||||
- Root-cause-oriented failure handling rather than random retries
|
||||
- Explicit blocker escalation when implementation discovers architecture/interface conflicts
|
||||
- TAOR / TORI execution feedback loops
|
||||
|
||||
Claude Code is the quality benchmark because it productizes coding execution discipline: conservative edits, strong tool boundaries, persistent project rules, contextual memory, and verified build/test/debug closure.
|
||||
|
||||
### Hermes Agent
|
||||
|
||||
Reference for:
|
||||
|
||||
- Experience mining
|
||||
- Nudge Engine interval-triggered learning
|
||||
- Curator daemon
|
||||
- Skill self-patching
|
||||
- SKILL.md format and FTS retrieval
|
||||
|
||||
### OpenAI Codex
|
||||
|
||||
Reference for:
|
||||
|
||||
- Shell / patch / test direct execution loop
|
||||
- Coding sandbox and tool orchestration
|
||||
- Tool/plugin/core-plugin/MCP implementation ideas
|
||||
- Wider tool surface including image generation/editing/vision capabilities
|
||||
|
||||
Local reference path: `reference/openai-codex/`.
|
||||
|
||||
### Anthropic Claude Skills
|
||||
|
||||
Reference for:
|
||||
|
||||
- `SKILL.md` structure and frontmatter conventions
|
||||
- Skill directory layout (`scripts/`, `references/`, `assets/`)
|
||||
- Reusable workflow packaging
|
||||
- Skill trigger/retrieval descriptions
|
||||
- Skill/Project Rules/MCP/Capability boundary
|
||||
|
||||
Local reference path: `reference/anthropic-skills/`.
|
||||
|
||||
### asciinema / Atuin / claude-hud
|
||||
|
||||
Reference for:
|
||||
|
||||
- PTY capture and terminal replay
|
||||
- Command metadata/history indexing
|
||||
- HUD/statusline layout and activity display
|
||||
|
||||
## 3. Technology Baseline
|
||||
|
||||
- Runtime: TypeScript on Bun
|
||||
- Monorepo: Bun workspaces + Turborepo
|
||||
- TUI: `@opentui/solid`, `@opentui/core`, `@opentui/keymap`
|
||||
- Storage: SQLite per session, project-local
|
||||
- IPC: NDJSON over stdio
|
||||
- Python: subprocess-only helper layer for existing scripts/libraries, not core runtime
|
||||
- Distribution: binary tarball before public package channels
|
||||
|
||||
## 4. Monorepo Packages
|
||||
|
||||
Canonical V1.0.0 Alpha package set:
|
||||
|
||||
```text
|
||||
packages/
|
||||
contracts/ # shared TypeScript interfaces (no implementation deps)
|
||||
cli/ # command entrypoint, resource loading, startup/doctor/init
|
||||
tui/ # OpenTUI/Solid UI, ProjectionStore consumers, HUD
|
||||
runtime/ # EventBus, Scheduler, Agent process mgmt, ToolRegistry, PermissionEngine, SessionStore, ContextAssembler
|
||||
llm/ # provider/model adapters, Anthropic canonical format, cross-provider conversion
|
||||
toolchain-cpp/ # C++ detector, build/test/static-analysis/debug tools
|
||||
```
|
||||
|
||||
Future language packages:
|
||||
|
||||
```text
|
||||
packages/toolchain-python/
|
||||
packages/toolchain-rust/
|
||||
packages/toolchain-js/
|
||||
```
|
||||
|
||||
Dependency direction:
|
||||
|
||||
```text
|
||||
contracts → (no implementation deps)
|
||||
cli → tui/runtime/llm/toolchain-cpp
|
||||
runtime → contracts, llm (interfaces/adapters), toolchain-* via registry
|
||||
tui → contracts (ProjectionClient only)
|
||||
llm → contracts
|
||||
toolchain-cpp → contracts
|
||||
runtime must not depend on tui
|
||||
tui must consume ProjectionStore, not raw DB/EventBus directly
|
||||
```
|
||||
|
||||
## 5. Project and Global Filesystem Layout
|
||||
|
||||
### Global User Directory
|
||||
|
||||
`~/.air/` stores user-global configuration, caches, global skills, logs, and project index only. It is not the source of truth for project sessions.
|
||||
|
||||
```text
|
||||
~/.air/
|
||||
├── config.yaml
|
||||
├── models.yaml
|
||||
├── permissions.yaml
|
||||
├── compaction-rules.md
|
||||
├── project-index.db
|
||||
├── cache/
|
||||
│ ├── plugins/
|
||||
│ ├── providers/
|
||||
│ ├── lsp/
|
||||
│ └── downloads/
|
||||
├── resources/versions/<version>/
|
||||
├── skills/
|
||||
└── logs/
|
||||
├── air.log
|
||||
└── air.developer.log
|
||||
```
|
||||
|
||||
### Project Directory
|
||||
|
||||
Project source of truth lives under the project.
|
||||
|
||||
```text
|
||||
<project>/.air/
|
||||
├── shared/
|
||||
│ ├── project.json
|
||||
│ ├── permissions.yaml
|
||||
│ ├── compaction-rules.md
|
||||
│ ├── rules/
|
||||
│ │ ├── project-rules.md
|
||||
│ │ └── toolchain-rules.md
|
||||
│ └── plan/
|
||||
│ ├── AGENTS.md
|
||||
│ ├── plan.md
|
||||
│ ├── todo.md
|
||||
│ └── docs/
|
||||
└── local/
|
||||
├── sessions/<session-id>/
|
||||
│ ├── session.db
|
||||
│ └── artifacts/
|
||||
├── state/
|
||||
├── backups/
|
||||
├── debug-records.db
|
||||
├── learned-memory.db
|
||||
├── workspaces/
|
||||
├── tmp/
|
||||
└── locks/
|
||||
```
|
||||
|
||||
Recommended `.gitignore`:
|
||||
|
||||
```gitignore
|
||||
.air/local/
|
||||
```
|
||||
|
||||
`.air/shared/` is git-shareable. `.air/local/` is portable with the project directory but private/local by default.
|
||||
|
||||
`project_id` is a stable UUID generated at initialization and stored in `.air/shared/project.json`. It is not derived from the absolute path.
|
||||
|
||||
## 6. Runtime Architecture
|
||||
|
||||
AirCoding is event-driven.
|
||||
|
||||
```text
|
||||
Main Agent
|
||||
→ Architecture Designer
|
||||
→ Scheduler
|
||||
→ Executor
|
||||
→ Reviewer
|
||||
→ Debugger
|
||||
→ Compactor
|
||||
→ ExperienceMiner
|
||||
```
|
||||
|
||||
### Main Agent
|
||||
|
||||
- Only user-facing agent
|
||||
- Handles conversation, decisions, progress summaries, requirement changes
|
||||
- Must remain responsive and idle-ready
|
||||
- Does not perform background work itself
|
||||
- Direct mode is a foreground execution lane, not a long-running Main Agent blockage
|
||||
|
||||
Canonical Main Agent state machine is defined in `AirPlan/docs/architecture/main-agent-state-machine.md`.
|
||||
|
||||
### Architecture Designer
|
||||
|
||||
- Architecture planning and impact assessment
|
||||
- Requirement-change assessment for design/interface/goal changes
|
||||
- C4/ADR/plan/todo alignment
|
||||
- Full-cycle architecture review
|
||||
|
||||
Canonical implementation/interface/architecture/product escalation rules are defined in `AirPlan/docs/architecture/scope-escalation-v1.md`.
|
||||
|
||||
### Scheduler
|
||||
|
||||
- Reads TaskGraph
|
||||
- Computes dependency order, write-area conflicts, waves, retries, workspaces
|
||||
- Spawns child agents as independent Bun processes
|
||||
- Monitors heartbeat and progress
|
||||
- Handles merge coordination
|
||||
|
||||
Canonical Scheduler task graph, wave, retry, heartbeat, workspace merge, and recovery state machine is defined in `AirPlan/docs/architecture/scheduler-state-machine-v1.md`.
|
||||
|
||||
### Worker Agents
|
||||
|
||||
- Executor: implementation/build/test verification
|
||||
- Reviewer: read-only code/static-analysis review
|
||||
- Debugger: evidence gathering, diagnosis, instrumentation, fix, verification
|
||||
- Compactor: copy-on-write context compaction
|
||||
- ExperienceMiner: memory/skill extraction, patching, promotion suggestions
|
||||
|
||||
Worker loops are independent implementations, not one generic shared loop.
|
||||
|
||||
## 7. RuntimeEvent and EventStore
|
||||
|
||||
Cross-cutting runtime semantics for EventIngestor, heartbeat coalescing, cross-DB/file side effects, compaction ownership, execution primitives, scanner behavior, and learning/skills lifecycle are defined in `AirPlan/docs/architecture/runtime-semantics-v1.md`.
|
||||
|
||||
Event envelope:
|
||||
|
||||
```ts
|
||||
interface RuntimeEvent<T = unknown> {
|
||||
id: string
|
||||
type: string
|
||||
version: number
|
||||
timestamp: string
|
||||
session_id: string
|
||||
project_id?: string
|
||||
source: EventSource
|
||||
route: string[]
|
||||
payload: T
|
||||
}
|
||||
```
|
||||
|
||||
`route` is an append-only structured route chain. Event durability is determined by EventStore based on event type, not by the event producer.
|
||||
|
||||
Canonical event names, payload schemas, persistence policy, and producer/consumer rules are defined in `AirPlan/docs/architecture/event-registry-v1.md`.
|
||||
|
||||
Persistence rules:
|
||||
|
||||
1. Event producers emit valid envelopes but do not decide storage ad hoc.
|
||||
2. EventStore owns persistence policy by event type.
|
||||
3. Durable event insert and matching domain table update happen in one SQLite transaction.
|
||||
4. Ephemeral stream/progress events may be throttled or coalesced by EventBus/ProjectionStore.
|
||||
5. Event payload schema changes increment that event type's `version`.
|
||||
|
||||
V1 durable event families:
|
||||
|
||||
```text
|
||||
session, message, agent, task, tool, command,
|
||||
artifact, diagnostic, evidence,
|
||||
context, summary, permission, doctor,
|
||||
requirement, architecture, workspace, memory, debug
|
||||
```
|
||||
|
||||
V1 ephemeral event families:
|
||||
|
||||
```text
|
||||
agent heartbeat, task progress, assistant message delta,
|
||||
tool progress, command stdout/stderr delta, HUD frame render
|
||||
```
|
||||
|
||||
## 8. IPC Protocol
|
||||
|
||||
Child agents are independent Bun processes.
|
||||
|
||||
IPC uses NDJSON over stdio.
|
||||
|
||||
Canonical IPC envelopes are defined in `AirPlan/docs/architecture/interface-contracts-v1.md`.
|
||||
|
||||
Required V1.0.0 Alpha IPC kinds:
|
||||
|
||||
```text
|
||||
control
|
||||
event
|
||||
log
|
||||
tool.call
|
||||
tool.result
|
||||
tool.stream
|
||||
worker.result
|
||||
worker.checkpoint
|
||||
protocol.error
|
||||
```
|
||||
|
||||
All request/response IPC messages include `id`, `direction`, `timestamp`, `session_id`, `agent_id`, and optional `correlation_id`.
|
||||
|
||||
- stdout: protocol only
|
||||
- stderr: crash fallback and fatal diagnostics
|
||||
|
||||
Exit codes:
|
||||
|
||||
```text
|
||||
0 protocol-level completion, including task failed/blocked
|
||||
1 uncaught exception
|
||||
2 startup/protocol error
|
||||
3 permission error
|
||||
4 parent cancelled
|
||||
5 hard timeout killed
|
||||
```
|
||||
|
||||
## 9. TaskSpec and WorkerResult
|
||||
|
||||
### TaskSpec
|
||||
|
||||
```ts
|
||||
interface TaskSpec {
|
||||
id: string
|
||||
type: "execute" | "review" | "debug" | "compact" | "mine_experience"
|
||||
title: string
|
||||
description: string
|
||||
acceptance_criteria: string[]
|
||||
scope: {
|
||||
write_area?: string
|
||||
expected_files?: string[]
|
||||
allowed_paths?: string[]
|
||||
denied_paths?: string[]
|
||||
}
|
||||
dependencies: Array<{
|
||||
depends_on_task_id: string
|
||||
dependency_type: "hard" | "soft" | "conflict" | "serialization"
|
||||
reason?: string
|
||||
source?: "architecture" | "scheduler" | "worker" | "user" | "system"
|
||||
}>
|
||||
verification: {
|
||||
commands?: string[]
|
||||
required: boolean
|
||||
fallback_allowed: boolean
|
||||
}
|
||||
constraints: {
|
||||
max_turns: number
|
||||
soft_timeout_ms: number
|
||||
hard_timeout_ms: number
|
||||
retry_budget: number
|
||||
model_policy: "scheduler_forced" | "agent_select"
|
||||
model_id?: string
|
||||
}
|
||||
context_refs: {
|
||||
plan_ref?: string
|
||||
arc_ref?: string
|
||||
parent_task_results?: string[]
|
||||
artifacts?: string[]
|
||||
}
|
||||
output_contract: "ExecutorResult" | "ReviewerResult" | "DebuggerResult" | "CompactorResult" | "ExperienceMinerResult"
|
||||
}
|
||||
```
|
||||
|
||||
### WorkerResult
|
||||
|
||||
```ts
|
||||
interface WorkerResult<T = unknown> {
|
||||
task_id: string
|
||||
agent_id: string
|
||||
agent_type: "executor" | "reviewer" | "debugger" | "compactor" | "experience_miner"
|
||||
status: "completed" | "failed" | "blocked" | "cancelled"
|
||||
summary: string
|
||||
changed_files: string[]
|
||||
diff_ref?: string
|
||||
artifacts: ArtifactRef[]
|
||||
verification: VerificationResult[]
|
||||
risks: Risk[]
|
||||
follow_up_tasks: FollowUpTask[]
|
||||
evidence_refs: EvidenceRef[]
|
||||
result: T
|
||||
}
|
||||
```
|
||||
|
||||
`failed` means the task goal was not achieved and Scheduler may retry/skip. `blocked` means upper-level decision is needed.
|
||||
|
||||
`summary` is a 3–6 sentence human-readable summary covering what was done, evidence, conclusion, and risk. It is not used for scheduling decisions.
|
||||
|
||||
## 10. Tool and Capability System
|
||||
|
||||
### ToolDefinition
|
||||
|
||||
```ts
|
||||
interface ToolDefinition<I = unknown, O = unknown> {
|
||||
name: string
|
||||
version: number
|
||||
description: string
|
||||
input_schema: JsonSchema<I>
|
||||
output_schema: JsonSchema<O>
|
||||
category: "filesystem" | "shell" | "build" | "test" | "debug" | "static_analysis" | "gui" | "network" | "memory" | "project" | "internal"
|
||||
permissions: {
|
||||
read_paths?: PathPolicy
|
||||
write_paths?: PathPolicy
|
||||
execute?: boolean
|
||||
network?: boolean
|
||||
system_sensitive?: boolean
|
||||
}
|
||||
streaming: boolean
|
||||
execute(input: I, context: ToolExecutionContext): AsyncIterable<ToolEvent> | Promise<ToolResult<O>>
|
||||
}
|
||||
```
|
||||
|
||||
Inputs and outputs are schema-validated. Streaming tools emit a final `tool.result`.
|
||||
|
||||
Canonical V1.0.0 Alpha built-in tool names, input/output schemas, and cut lines are defined in `AirPlan/docs/architecture/tool-registry-v1.md`.
|
||||
|
||||
Bash is implemented as `shell.run`, a normal shell tool with extra PermissionEngine risk analysis.
|
||||
|
||||
### Capability
|
||||
|
||||
Capabilities are runtime-registered tool bundles with dependencies, triggers, evidence types, and config schema.
|
||||
|
||||
Canonical capability manifest, source trust, dependency declaration, permission declaration, lifecycle, event namespace, and enable/update rules are defined in `AirPlan/docs/architecture/capability-trust-v1.md`.
|
||||
|
||||
Capability manifests declare dependencies; they do not install them directly.
|
||||
|
||||
Doctor/setup manages detection and installation.
|
||||
|
||||
## 11. Doctor and Dependency Policy
|
||||
|
||||
- First startup runs read-only doctor automatically.
|
||||
- If issues exist, user is prompted to run fix.
|
||||
- High-permission mode may `announce_then_run` dependency installation after first startup.
|
||||
- First startup always asks before `doctor --fix`, even in high-permission mode.
|
||||
- `credentials` and `system_sensitive` dependencies always require explicit confirmation.
|
||||
|
||||
## 12. Permission and Security Model
|
||||
|
||||
Canonical local security boundaries, permission profiles, path classification, command risk analysis, network policy, credential handling, logs/export rules, and refusal/block conditions are defined in `AirPlan/docs/architecture/security-model-v1.md`.
|
||||
|
||||
Core principles:
|
||||
|
||||
```text
|
||||
read → allow
|
||||
project directory → allow
|
||||
project-outside non-system → backup then allow
|
||||
system-sensitive → explicit confirmation
|
||||
credentials → explicit confirmation
|
||||
```
|
||||
|
||||
Project-outside backups are stored as a git repo at:
|
||||
|
||||
```text
|
||||
<project>/.air/local/backups/
|
||||
```
|
||||
|
||||
## 13. Session DB and Domain State
|
||||
|
||||
Session DB path:
|
||||
|
||||
```text
|
||||
<project>/.air/local/sessions/<session-id>/session.db
|
||||
```
|
||||
|
||||
Canonical schema details are defined in `AirPlan/docs/architecture/db-schema-v1.md`.
|
||||
|
||||
Canonical message storage:
|
||||
|
||||
- `messages` stores complete Anthropic canonical content JSON.
|
||||
- `message_drafts` stores streaming assistant intermediate state and is deleted after final completion.
|
||||
- `message_parts` is not a source-of-truth MVP table.
|
||||
|
||||
Domain state tables are the source of truth for scheduling/recovery/query:
|
||||
|
||||
```text
|
||||
tasks
|
||||
task_dependencies
|
||||
task_attempts
|
||||
agents
|
||||
tool_runs
|
||||
command_runs
|
||||
artifacts
|
||||
diagnostics
|
||||
evidence_refs
|
||||
workspaces
|
||||
events
|
||||
ui_state
|
||||
```
|
||||
|
||||
Query-friendly columns are preferred over parsing JSON. Examples:
|
||||
|
||||
- `tool_runs.origin_message_id`
|
||||
- `command_runs.origin_message_id`
|
||||
- common artifact foreign keys (`task_id`, `agent_id`, `tool_run_id`, `command_run_id`)
|
||||
- event source/task/agent/tool/command IDs
|
||||
- `route_json` plus `route_text`
|
||||
|
||||
`ui_state` stores only UI recovery state and is flushed periodically plus on normal exit.
|
||||
|
||||
## 14. Contract V1 Type Baseline
|
||||
|
||||
Canonical implementation-facing service/interface contracts are defined in `AirPlan/docs/architecture/interface-contracts-v1.md`.
|
||||
|
||||
Shared implementation contracts live in a dedicated package:
|
||||
|
||||
```text
|
||||
packages/contracts/
|
||||
runtime.ts
|
||||
event.ts
|
||||
ipc.ts
|
||||
task.ts
|
||||
worker-result.ts
|
||||
tool.ts
|
||||
artifact.ts
|
||||
project.ts
|
||||
provider.ts
|
||||
ui.ts
|
||||
error.ts
|
||||
```
|
||||
|
||||
Principles:
|
||||
|
||||
1. Contracts must be compileable and shared by runtime, TUI, LLM, and toolchain packages.
|
||||
2. Shape stability matters more than perfect detail in V1.
|
||||
3. Schema-heavy fields may start as `unknown` and tighten later.
|
||||
4. ContextPack stays lightweight and reference-based; large context bodies are stored as artifacts/summaries and loaded through ContextAssembler.
|
||||
5. Domain packages depend on `packages/contracts`; they must not import each other's private types.
|
||||
|
||||
Core identity aliases:
|
||||
|
||||
```ts
|
||||
type ISOTimeString = string
|
||||
type UUID = string
|
||||
type ProjectID = string
|
||||
type SessionID = string
|
||||
type TaskID = string
|
||||
type AgentID = string
|
||||
type ToolRunID = string
|
||||
type CommandRunID = string
|
||||
type ArtifactID = string
|
||||
type MessageID = string
|
||||
```
|
||||
|
||||
Core event source:
|
||||
|
||||
```ts
|
||||
interface EventSource {
|
||||
kind: "main" | "architecture_designer" | "scheduler" | "agent" | "tool" | "system"
|
||||
id?: string
|
||||
agent_type?: "executor" | "reviewer" | "debugger" | "compactor" | "experience_miner"
|
||||
}
|
||||
```
|
||||
|
||||
Control messages:
|
||||
|
||||
```ts
|
||||
type ControlMessage =
|
||||
| {
|
||||
type: "agent.start"
|
||||
version: 1
|
||||
task_spec: TaskSpec
|
||||
context_pack: ContextPack
|
||||
runtime: AgentRuntimeContext
|
||||
}
|
||||
| { type: "agent.cancel"; reason: string }
|
||||
| { type: "agent.pause"; reason: string }
|
||||
| { type: "agent.resume" }
|
||||
| { type: "agent.extend_timeout"; extra_ms: number; reason: string }
|
||||
|
||||
interface AgentRuntimeContext {
|
||||
session_id: SessionID
|
||||
project_id: ProjectID
|
||||
agent_id: AgentID
|
||||
worktree_path?: string
|
||||
permission_template: "main_direct" | "executor" | "reviewer" | "debugger" | "system"
|
||||
}
|
||||
```
|
||||
|
||||
ContextPack:
|
||||
|
||||
```ts
|
||||
interface ContextPack {
|
||||
refs: {
|
||||
plan_ref?: string
|
||||
arc_ref?: string
|
||||
task_refs?: string[]
|
||||
artifact_refs?: string[]
|
||||
rule_refs?: string[]
|
||||
}
|
||||
assembled_context_ref?: string
|
||||
notes?: string[]
|
||||
}
|
||||
```
|
||||
|
||||
Common result helpers:
|
||||
|
||||
```ts
|
||||
interface VerificationResult {
|
||||
name: string
|
||||
status: "passed" | "failed" | "skipped" | "unknown"
|
||||
evidence_refs?: string[]
|
||||
notes?: string
|
||||
}
|
||||
|
||||
interface Risk {
|
||||
severity: "low" | "medium" | "high"
|
||||
summary: string
|
||||
}
|
||||
|
||||
interface FollowUpTask {
|
||||
title: string
|
||||
description: string
|
||||
type?: "execute" | "review" | "debug" | "docs"
|
||||
}
|
||||
```
|
||||
|
||||
Provider capability matrix, model assignment, adapter conversion, fallback policy, and doctor checks are defined in `AirPlan/docs/architecture/provider-capability-matrix-v1.md`.
|
||||
|
||||
Canonical error kinds, severity, retryability, failure signatures, user-facing formatting, and Scheduler routing are defined in `AirPlan/docs/architecture/error-taxonomy-v1.md`.
|
||||
|
||||
`TaskSpec`, `WorkerResult`, `RuntimeEvent`, `ToolDefinition`, `ArtifactRef`, and `EvidenceRef` are defined by earlier sections of this baseline and must be exported from `packages/contracts`.
|
||||
|
||||
## 15. Artifact Layout
|
||||
|
||||
Artifacts live under:
|
||||
|
||||
```text
|
||||
<project>/.air/local/sessions/<session-id>/artifacts/
|
||||
```
|
||||
|
||||
Canonical URI format, artifact ID format, filename conventions, directory mapping, compression, metadata, write protocol, and evidence linking are defined in `AirPlan/docs/architecture/artifact-naming-v1.md`.
|
||||
|
||||
## 15. Context and Compaction
|
||||
|
||||
ContextAssembler outputs Anthropic canonical messages. Provider conversion happens only at the LLM adapter boundary.
|
||||
|
||||
Canonical prompt/context layer order, agent-specific context profiles, conflict handling, and prompt asset locations are defined in `AirPlan/docs/architecture/prompt-layering-v1.md`.
|
||||
|
||||
ContextAssembler records omissions and publishes `context.compaction.requested` when compaction is needed; it does not compact itself.
|
||||
|
||||
Compaction rules use Markdown + YAML frontmatter.
|
||||
|
||||
Rule locations:
|
||||
|
||||
```text
|
||||
built-in default
|
||||
~/.air/compaction-rules.md
|
||||
<project>/.air/shared/compaction-rules.md
|
||||
```
|
||||
|
||||
Compaction uses copy-on-write:
|
||||
|
||||
```text
|
||||
snapshot messages 1-N
|
||||
→ async Compactor subagent
|
||||
→ new messages keep appending
|
||||
→ compaction marker inserted when done
|
||||
→ original messages preserved for explicit backtracking
|
||||
```
|
||||
|
||||
## 16. Memory, Skills, and Debug Knowledge
|
||||
|
||||
Project Rules:
|
||||
|
||||
```text
|
||||
<project>/.air/shared/rules/project-rules.md
|
||||
```
|
||||
|
||||
Skills:
|
||||
|
||||
```text
|
||||
~/.air/skills/<skill-name>/SKILL.md
|
||||
```
|
||||
|
||||
ExperienceMiner triggers:
|
||||
|
||||
- DebugRecord produced
|
||||
- session end
|
||||
- N turns/tool calls interval
|
||||
- existing skill/rule discovered outdated during execution
|
||||
|
||||
Non-debug experiences promote after repeated occurrence and user confirmation. Debug experience confidence comes from evidence and verification, not numeric scoring.
|
||||
|
||||
Debug Knowledge is local-first. Sharing/upload is a separate explicit flow and must be redacted/previewed.
|
||||
|
||||
## 17. Provider and Model Layer
|
||||
|
||||
- Native providers: Anthropic and OpenAI
|
||||
- Compatibility: OpenRouter, ollama, custom Anthropic/OpenAI-compatible endpoints
|
||||
- Internal canonical message format: Anthropic content blocks
|
||||
- Cross-provider conversion happens at the adapter boundary
|
||||
- Same-provider model switching has no format conversion cost
|
||||
- Canonical provider/model capability contract is defined in `AirPlan/docs/architecture/provider-capability-matrix-v1.md`
|
||||
|
||||
## 18. TUI and HUD
|
||||
|
||||
TUI uses OpenTUI/Solid.
|
||||
|
||||
Reuse from OpenCode:
|
||||
|
||||
- theme system
|
||||
- dialog/modal/toast patterns
|
||||
- keymap wrapper
|
||||
- layout style
|
||||
- spinner/border/error components
|
||||
- markdown/code/diff rendering patterns
|
||||
|
||||
Do not reuse OpenCode SDK/sync/session business layer.
|
||||
|
||||
HUD/TUI consumes ProjectionStore only.
|
||||
|
||||
```text
|
||||
DB persistent state + EventBus live events
|
||||
→ ProjectionStore
|
||||
→ TUI/HUD
|
||||
```
|
||||
|
||||
HUD never directly queries SQLite.
|
||||
|
||||
## 19. UI Design Asset Capability
|
||||
|
||||
AirCoding supports optional `ui-design-assets` capability.
|
||||
|
||||
MVP supports:
|
||||
|
||||
- ASCII/wireframe mockups
|
||||
- design specs
|
||||
- SVG icons
|
||||
- screenshot design analysis
|
||||
- prompts for external image generators
|
||||
|
||||
Post-MVP supports bitmap image generation/editing via providers.
|
||||
|
||||
Generated UI/design assets are artifacts first and must be shown to the user before being written into project files.
|
||||
|
||||
## 20. C++ Toolchain V1.0.0 Alpha
|
||||
|
||||
`toolchain-cpp` provides:
|
||||
|
||||
- BuildTool: CMake built-in, Ninja first then Make fallback
|
||||
- DiagnosticParser: deterministic compiler/linker output extraction and semantic signatures (LLM-based interpretation belongs to runtime Debugger/Reviewer, not toolchain)
|
||||
- TestRunner: CTest + GoogleTest first
|
||||
- StaticAnalysis: cppcheck built-in, clang-tidy later
|
||||
- CodeIntelligence: clangd CLI mode first
|
||||
- `compile_commands.json`: generated on demand, not persisted as cache
|
||||
|
||||
Build-system conflicts are shown to the user.
|
||||
|
||||
BuildTool attempts built-in repair first; unresolved failures route to Debugger.
|
||||
|
||||
## 21. Project Initialization
|
||||
|
||||
Scanner collects filesystem metadata only:
|
||||
|
||||
- full directory tree
|
||||
- file extension statistics
|
||||
- special files
|
||||
- git summary
|
||||
|
||||
No directory exclusions and no depth limit.
|
||||
|
||||
LLM proposes ProjectProfile; user confirms/corrects.
|
||||
|
||||
Project schema lives at:
|
||||
|
||||
```text
|
||||
<project>/.air/shared/project.json
|
||||
```
|
||||
|
||||
Old schema detection triggers migration plan and user confirmation.
|
||||
|
||||
## 22. Migration
|
||||
|
||||
- Opening a project detects `.air` schema versions.
|
||||
- Old schema shows a migration plan.
|
||||
- User confirmation is always required, even in high-permission mode.
|
||||
- `.air` is backed up first.
|
||||
- Failure rolls back.
|
||||
|
||||
Migration backups should be stored under project-local backup state, e.g.:
|
||||
|
||||
```text
|
||||
<project>/.air/local/backups/migrations/<timestamp>/
|
||||
```
|
||||
|
||||
## 23. Logging and Doctor Bundles
|
||||
|
||||
`air.log` is user-readable and contains startup failures, exceptions, and environment configuration issues.
|
||||
|
||||
`air.developer.log` is full debug/performance log encrypted with the development team's public key.
|
||||
|
||||
Doctor bundles may include full diagnostics and are not automatically redacted. They are never automatically uploaded; user must explicitly export/send them.
|
||||
|
||||
Doctor bundles and Debug Knowledge sharing are separate channels:
|
||||
|
||||
- doctor bundle: development-team diagnostic channel
|
||||
- Debug Knowledge: shareable knowledge channel that requires redaction, preview, and explicit authorization
|
||||
|
||||
## 24. Testing
|
||||
|
||||
- Unit tests: `bun test`, CI, deterministic, no LLM
|
||||
- Integration tests: CI, recorded LLM fixture replay
|
||||
- E2E tests: release gate, real LLM, must pass before release
|
||||
- Platform support levels and release validation matrix are defined in `AirPlan/docs/architecture/cross-platform-matrix-v1.md`
|
||||
|
||||
## 25. Distribution
|
||||
|
||||
Canonical platform support levels, distribution targets, and release gates are defined in `AirPlan/docs/architecture/cross-platform-matrix-v1.md`.
|
||||
|
||||
Early distribution uses binary tarball:
|
||||
|
||||
```text
|
||||
bin/air
|
||||
resources/
|
||||
LICENSE
|
||||
```
|
||||
|
||||
Resources include templates, prompts, themes, HUD presets, Python scripts, and toolchain resources.
|
||||
|
||||
No public npm/brew/apt/winget channel until stable.
|
||||
|
||||
## 26. V1.0.0 Alpha Prerequisite Baselines
|
||||
|
||||
This baseline is sufficient for formal architecture design and V1.0.0 Alpha implementation planning. The following prerequisite baselines are frozen for V1:
|
||||
|
||||
1. Interface contracts: `AirPlan/docs/architecture/interface-contracts-v1.md`.
|
||||
2. SQLite schema: `AirPlan/docs/architecture/db-schema-v1.md`.
|
||||
3. Event payload registry: `AirPlan/docs/architecture/event-registry-v1.md`.
|
||||
4. Tool registry: `AirPlan/docs/architecture/tool-registry-v1.md`.
|
||||
5. Scheduler state machine: `AirPlan/docs/architecture/scheduler-state-machine-v1.md`.
|
||||
6. Prompt layering model: `AirPlan/docs/architecture/prompt-layering-v1.md`.
|
||||
7. Provider capability matrix: `AirPlan/docs/architecture/provider-capability-matrix-v1.md`.
|
||||
8. Error taxonomy: `AirPlan/docs/architecture/error-taxonomy-v1.md`.
|
||||
9. Artifact naming/layout: `AirPlan/docs/architecture/artifact-naming-v1.md`.
|
||||
10. Scope escalation model: `AirPlan/docs/architecture/scope-escalation-v1.md`.
|
||||
11. Security model: `AirPlan/docs/architecture/security-model-v1.md`.
|
||||
12. Capability trust model: `AirPlan/docs/architecture/capability-trust-v1.md`.
|
||||
13. Cross-platform matrix: `AirPlan/docs/architecture/cross-platform-matrix-v1.md`.
|
||||
14. Runtime semantics: `AirPlan/docs/architecture/runtime-semantics-v1.md`.
|
||||
|
||||
V1.0.0 Alpha scope includes a complete C++ development workflow and local/built-in plugin capability foundation.
|
||||
488
docs/idea.md
Normal file
488
docs/idea.md
Normal file
@@ -0,0 +1,488 @@
|
||||
# AirCoding Agent 设计文档
|
||||
|
||||
> 最后更新:2026-05-26
|
||||
> Canonical baseline: `AirPlan/docs/architecture/baselineV1.md`
|
||||
> 历史决策记录:`AirPlan/docs/architecture/decisions-round-1.md`、`decisions-round-2.md`、`decisions-round-3.md`
|
||||
|
||||
## 1. 背景与动机
|
||||
|
||||
当前 Air 系列插件主要运行在 Claude Code 已暴露的 agent/plugin 接口之上,能力边界受限。尤其是 AirContext 为了参与上下文管理,需要通过插件层绕行,这种方式不够优雅,也不利于长期演进。
|
||||
|
||||
新的方向是:从"Claude Code 插件外挂式扩展"转向"自有 agent/runtime 架构"。
|
||||
|
||||
目标不是做一个泛用 Claude Code clone,而是构建一个以 C++ 为首个深度支持语言、后续可扩展至 Python/Rust/JS 等多语言的长期可用 AI Coding Agent。
|
||||
|
||||
## 2. 核心定位
|
||||
|
||||
AirCoding Agent 的核心 runtime 是语言无关的。C++ 是第一个深度支持的语言 profile,后续按 `toolchain-<lang>` 包扩展。
|
||||
|
||||
开发闭环:
|
||||
|
||||
```text
|
||||
需求理解
|
||||
→ 架构/接口设计
|
||||
→ 代码阅读
|
||||
→ 修改计划
|
||||
→ 编译
|
||||
→ 静态分析
|
||||
→ 单测/集成测试
|
||||
→ 运行/调试
|
||||
→ 崩溃/日志/网络/GUI 证据分析
|
||||
→ 修复
|
||||
→ 变更总结
|
||||
→ 经验沉淀
|
||||
```
|
||||
|
||||
## 3. 参考项目分工
|
||||
|
||||
### 3.1 OpenCode
|
||||
|
||||
OpenCode 作为 runtime 骨架、TUI、provider 抽象、session/tool registry 的主要参考。
|
||||
|
||||
- TUI 交互布局以 OpenCode 为设计规范
|
||||
- runtime 分层(session/event/sync、多 agent 组织)
|
||||
- provider / model 抽象
|
||||
- plugin / SDK 扩展层
|
||||
|
||||
### 3.2 Claude Code CLI
|
||||
|
||||
Claude Code CLI 作为执行层代码质量、Executor 行为、工具调用策略、记忆系统、文件编辑安全边界的标杆。AirCoding 的执行层功能应尽可能与 Claude Code 对齐,以提升代码修改质量、安全性和验证纪律。
|
||||
|
||||
- 工具生命周期、schema 校验
|
||||
- 权限模型
|
||||
- 子代理调度
|
||||
- 文件 read/edit/write 与 diff/update 执行原语
|
||||
- 小步精确编辑、先读后改、避免无关重构、失败时定位根因而不是随机重试
|
||||
- build/test/debug 证据闭环,完成前必须验证或明确说明未验证原因
|
||||
- 实现中发现架构/接口冲突时显式上报 blocker
|
||||
- compact / resume / history / rewind 交互
|
||||
- **记忆系统**(MEMORY.md + frontmatter + 多类型分层)
|
||||
- **TAOR / TORI 设计**(Task-Agent-Observation-Result / Tool-Observation-Reasoning-Iteration 循环)
|
||||
|
||||
### 3.3 Hermes Agent
|
||||
|
||||
Hermes Agent 作为长期运行、跨会话学习、技能生成和 Curator 机制的参考。
|
||||
|
||||
- Nudge Engine 计数触发机制
|
||||
- Curator Daemon 定期去重/合并/归档
|
||||
- 使用中自我 patch
|
||||
- SKILL.md 格式(YAML frontmatter + Markdown body)
|
||||
- FTS5 语义搜索
|
||||
|
||||
### 3.4 Codex / OpenAI Coding Agent
|
||||
|
||||
Codex / OpenAI 开源 coding agent 作为通用工具调用与多模态工具面的补充参考。
|
||||
|
||||
- shell / patch / test 直接闭环
|
||||
- coding sandbox 与工具调用编排
|
||||
- tools / plugin / core-plugins / MCP 相关实现
|
||||
- 图像生成、图像编辑、视觉输入等通用工具能力的 capability 设计参考
|
||||
- 只作为工具面参考,不作为 AirCoding 核心 runtime 形态参考
|
||||
- 本地参考路径:`reference/openai-codex/`
|
||||
|
||||
### 3.5 Anthropic / Claude Skills
|
||||
|
||||
Anthropic/Claude 开源 Skills 项目作为 skill/tool 组织方式的重要参考。
|
||||
|
||||
- SKILL.md 结构、frontmatter、触发描述与资源组织
|
||||
- 技能包内 scripts / references / assets 的组织方式
|
||||
- 可复用工具步骤如何沉淀成 skill
|
||||
- skill 与 MCP / capability / Project Rules 的边界划分
|
||||
- 作为 AirCoding SkillGenerator、ExperienceMiner、Capability 文档格式的参考
|
||||
- 本地参考路径:`reference/anthropic-skills/`
|
||||
|
||||
### 3.6 asciinema / Atuin / claude-hud
|
||||
|
||||
- asciinema:PTY 接管与终端流捕获
|
||||
- Atuin:SQLite 命令历史结构化存储与搜索
|
||||
- claude-hud:实时 HUD / statusline 设计
|
||||
|
||||
## 4. 语言选型(已确定)
|
||||
|
||||
### 4.1 主语言:TypeScript + Bun
|
||||
|
||||
- **运行时**:Bun(内置 SQLite,原生 TSX 支持)
|
||||
- **TUI 框架**:`@opentui/solid`(MIT 许可独立项目,npm 依赖引入)
|
||||
- **包结构**:Bun workspaces + Turborepo monorepo
|
||||
|
||||
### 4.2 Python 角色
|
||||
|
||||
Python 退化为纯 subprocess 工具调用(`Bun.spawn` + JSON-over-stdio),仅用于封装已有 C++ 工具链脚本和 Python 特有库。经验提炼、上下文组装、记忆管理全部留在 TS runtime 内部。
|
||||
|
||||
### 4.3 多语言 toolchain 包结构
|
||||
|
||||
Runtime 核心是语言无关的。每种语言通过独立包 + LanguageDetector plugin 扩展:
|
||||
|
||||
```
|
||||
packages/
|
||||
tui/ — 语言无关 TUI
|
||||
runtime/ — 语言无关 Agent Runtime
|
||||
llm/ — 语言无关 Provider 抽象
|
||||
cli/ — 语言无关入口
|
||||
toolchain-cpp/ — C++ 工具链
|
||||
toolchain-python/ — Python 工具链(后续)
|
||||
toolchain-rust/ — Rust 工具链(后续)
|
||||
toolchain-js/ — JS/TS 工具链(后续)
|
||||
```
|
||||
|
||||
## 5. 架构设计
|
||||
|
||||
### 5.1 架构模型
|
||||
|
||||
事件驱动。Main Agent 订阅 EventBus 获取 agent/task/tool 事件并渲染 TUI/HUD。
|
||||
|
||||
Main Agent 状态机详见 `AirPlan/docs/architecture/main-agent-state-machine.md`:
|
||||
|
||||
```text
|
||||
IDLE → CLASSIFYING(LLM 判断意图)
|
||||
→ DELEGATING(需要执行时)
|
||||
→ CONFIRMING(架构级变更需确认,实现级静默通过)
|
||||
→ EXECUTING(Scheduler 派发任务,Main Agent 监控进度)
|
||||
→ INTERRUPTING(用户中途变更,LLM 判断意图)
|
||||
→ SUMMARIZING(汇总结果,触发 ExperienceMiner)
|
||||
→ IDLE
|
||||
```
|
||||
|
||||
核心约束:Main Agent 必须保持空闲可响应用户介入。后台任务派子代理做。
|
||||
|
||||
**确认门控**:实现级变更(不影响接口/架构)→ 静默进入 EXECUTING。架构级变更 → Architecture Designer 评估 → 低权限需确认,高权限自动推进但结果显示给用户。
|
||||
|
||||
### 5.2 Agent 层级
|
||||
|
||||
```
|
||||
Main Agent(用户唯一交互入口)
|
||||
├── 对话模式(默认):不直接操作文件和命令
|
||||
└── 直通模式(/direct 触发,/done 退出)
|
||||
|
||||
Architecture Designer(全周期架构规划与审查)
|
||||
|
||||
Scheduler(任务图拆解、并行/串行调度、进度监控)
|
||||
├── Executor(写代码、改文件、编译、测试验证)
|
||||
├── Reviewer(代码审查、静态分析审查,只读不改代码)
|
||||
└── Debugger(证据收集、问题定位、插桩修复,吸收 Fixer 职责)
|
||||
```
|
||||
|
||||
### 5.3 子代理进程模型
|
||||
|
||||
每个 Executor/Reviewer/Debugger 是**独立 Bun 进程**(非单进程内异步任务,也非 Worker 线程)。IPC 通过 stdio + JSON。崩溃隔离、上下文隔离、天然适配 worktree。
|
||||
|
||||
### 5.4 心跳与超时
|
||||
|
||||
- **心跳**:Push 模型。子代理每 N 秒主动推送 `AgentHeartbeat`(当前状态、turn 数、已用 token)
|
||||
- **超时**:混合硬超时(kill)+ 软超时(警告 + 允许申请延期)。Scheduler 按任务类型分情况决定
|
||||
- **死循环检测**:同一错误签名出现 N+ 次 → 上报 Main Agent
|
||||
|
||||
### 5.5 并发写入策略
|
||||
|
||||
轻量 write_area 粗分:
|
||||
|
||||
- 不同写集 → 默认可并发
|
||||
- 相同写集但大概率不写相同代码块 → git worktree 隔离并发,事后合并
|
||||
- 高概率改同一代码块或公共接口 → 串行
|
||||
|
||||
Scheduler 是合并协调者,非统一写入器。lockfile、构建配置、公共 API/schema 默认提高并发风险。
|
||||
|
||||
### 5.6 Worker Agent 类型
|
||||
|
||||
**Executor**(Claude Code 为行为标杆):
|
||||
- 内部 loop:LOADING → THINKING → ACTING → OBSERVING → (调试子循环)→ FINALIZING
|
||||
- 自治完成完整闭环,不逐步骤汇报
|
||||
- 出口:TaskCompleted / TaskBlocked / TaskFailed
|
||||
- TaskSpec 附带 max_turns / acceptance_criteria / timeout
|
||||
|
||||
**Reviewer**(只读):
|
||||
- 流程规则自动触发(Executor 完成 → Reviewer)
|
||||
- loop:LOADING → REVIEWING → DECIDING(approved / changes_requested / blocked)
|
||||
|
||||
**Debugger**(build/test 失败自动触发):
|
||||
- loop:GATHERING → ANALYZING → FIXING → RECORDING 或 ESCALATING
|
||||
- 产出 DebuggerResult + DebugRecord 候选
|
||||
|
||||
三个子代理的 Agent Loop **各自独立实现**,不共享通用 loop 引擎。
|
||||
|
||||
### 5.7 流程规则
|
||||
|
||||
```text
|
||||
Executor 完成切片 → 自动触发 Reviewer
|
||||
build/test 失败 → 自动触发 Debugger
|
||||
静态分析报警 → 自动触发 Reviewer 或 Debugger
|
||||
阶段完成 → 自动触发 Architecture Designer 架构审查
|
||||
项目完成 → Architecture Designer 最终一致性审查
|
||||
```
|
||||
|
||||
### 5.8 需求变更协议
|
||||
|
||||
用户需求变更先由 Main Agent 做 LLM 分类:
|
||||
|
||||
- execution 级 → Scheduler 直接调整
|
||||
- possible_design 级 → Architecture Designer 轻量 impact check
|
||||
- design/interface/goal 级 → Architecture Designer 完整影响评估
|
||||
|
||||
Scheduler 基于分类结果或 Arc Revision 调整 TaskGraph。
|
||||
|
||||
### 5.9 Worker Result 标准
|
||||
|
||||
所有 Worker 结果必须结构化(非自由文本摘要)。格式详见 idea.md 原始定义(ExecutorResult / ReviewerResult / DebuggerResult)。
|
||||
|
||||
## 6. C++ Toolchain 工具链
|
||||
|
||||
### 6.1 分层
|
||||
|
||||
```text
|
||||
Agent 接口: build(config) → BuildResult, test(filter) → TestResult, analyze() → Diagnostic[]
|
||||
↓
|
||||
C++ Toolchain Adapter(屏蔽 CMake/MSBuild/Bazel 差异)
|
||||
↓
|
||||
Native Tool Execution(实际调用 cmake/ninja/msbuild/...)
|
||||
```
|
||||
|
||||
### 6.2 BuildTool
|
||||
|
||||
优先级:CMake(内置)> Meson/Bazel/XMake(capability plugin)> Makefile/.sln
|
||||
|
||||
冲突处理:多种构建系统文件同时存在 → 询问用户
|
||||
Generator:Ninja 优先,失败回退 Make
|
||||
配置失败:BuildTool 内置逻辑先尝试修复 → 失败则交给 Debugger
|
||||
|
||||
### 6.3 CompilerDiagnosticParser
|
||||
|
||||
**全部走 LLM 解析**(不用正则),生成结构化 Diagnostic + 语义错误签名(归一化 GCC/Clang/MSVC 措辞差异)。链接器错误单独归类。
|
||||
|
||||
### 6.4 TestRunner / StaticAnalysis / CodeIntelligence
|
||||
|
||||
- TestRunner:CTest + GoogleTest 内置,Catch2/Boost.Test 插件
|
||||
- StaticAnalysis:cppcheck 内置,clang-tidy 插件
|
||||
- CodeIntelligence:MVP 走 clangd CLI 模式(spawn 用完即退),LSP daemon 模式后续按需加
|
||||
|
||||
### 6.5 compile_commands.json
|
||||
|
||||
按需生成(`cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON`),不做持久化缓存。
|
||||
|
||||
## 7. Project Model 项目模型
|
||||
|
||||
### 7.1 设计原则
|
||||
|
||||
- 多语言通用:语言无关层 + 语言特定层分离
|
||||
- Scanner 只收集文件系统元数据(目录树 + 文件扩展名 + 特殊文件),不读文件内容
|
||||
- LLM 驱动理解,用户确认修正
|
||||
|
||||
### 7.2 Scanner 策略
|
||||
|
||||
- **无递归深度限制、无目录排除**——完整目录树本身就是有用的结构信息
|
||||
- 15 秒硬超时兜底,超时返回部分结果 + incomplete 标记
|
||||
- 首次全量,后续增量(mtime diff)
|
||||
- 再打开时加载 project.json + 快速确认顶层无变化,有变化才增量扫描
|
||||
|
||||
### 7.3 LLM 驱动的项目初始化
|
||||
|
||||
Scanner 收集事实 → Main Agent + LLM 推理 → 提出假设 → 用户确认/修正 → 沉淀
|
||||
|
||||
- **Schema 校验**:宽松接受,缺失字段标记 unknown,不让 LLM 反复重试
|
||||
- **用户纠正**:增量更新单字段 + 提示"关联判断可能受影响",不自动重写整个 json
|
||||
- **版本迁移**:打开项目时检测旧 schema → 备份后提示用户确认迁移 → 失败回滚
|
||||
|
||||
## 8. Agent 目录结构
|
||||
|
||||
### 8.1 全局目录
|
||||
|
||||
```text
|
||||
~/.air/
|
||||
├── config.yaml
|
||||
├── models.yaml
|
||||
├── permissions.yaml
|
||||
├── compaction-rules.md # 用户模板
|
||||
├── project-index.db # 最近项目索引,不是 source of truth
|
||||
├── cache/ # plugins/providers/lsp/downloads
|
||||
├── resources/versions/<version>/
|
||||
├── skills/ # 跨项目复用技能(SKILL.md 格式)
|
||||
└── logs/
|
||||
├── air.log # 用户可读(启动失败、异常报错)
|
||||
└── air.developer.log # 开发组公钥加密全量调试日志,保留 7 天
|
||||
```
|
||||
|
||||
### 8.2 项目内 `.air/`
|
||||
|
||||
```text
|
||||
<project>/.air/
|
||||
├── shared/ # 可提交 git,共享给团队
|
||||
│ ├── project.json # 含 stable UUID project_id
|
||||
│ ├── permissions.yaml
|
||||
│ ├── compaction-rules.md
|
||||
│ ├── rules/
|
||||
│ │ ├── project-rules.md
|
||||
│ │ └── toolchain-rules.md
|
||||
│ └── plan/ # 原 AirPlan 工作流内化
|
||||
│ ├── AGENTS.md
|
||||
│ ├── plan.md
|
||||
│ ├── todo.md
|
||||
│ └── docs/
|
||||
└── local/ # 可随项目携带但默认 gitignore
|
||||
├── sessions/<session-id>/
|
||||
│ ├── session.db
|
||||
│ └── artifacts/
|
||||
├── state/
|
||||
├── backups/ # Git 仓库管理的项目外文件备份
|
||||
├── debug-records.db
|
||||
├── learned-memory.db
|
||||
├── workspaces/
|
||||
├── tmp/
|
||||
└── locks/
|
||||
```
|
||||
|
||||
推荐 `.gitignore`:
|
||||
|
||||
```gitignore
|
||||
.air/local/
|
||||
```
|
||||
|
||||
## 9. Provider / Model 抽象层
|
||||
|
||||
- 原生支持 Anthropic API + OpenAI API
|
||||
- 兼容接入:OpenRouter / ollama / 自定义 endpoint(通过 Anthropic/OpenAI 兼容模式)
|
||||
- **内部存储格式**:Anthropic 原生 content blocks(Claude Code 路线)
|
||||
- **Provider 转换**:API 边界做双向转换,存回 Anthropic 格式
|
||||
- **同 provider 切换**:零开销
|
||||
- **跨 provider 切换**:API 边界双向转换
|
||||
|
||||
## 10. Permission 权限模型
|
||||
|
||||
### 10.1 核心原则
|
||||
|
||||
```text
|
||||
只读操作 → 永远允许
|
||||
项目目录内 → 完全开放(含 build 目录,C++ 打包部署需要手动组织运行库)
|
||||
项目外非系统 → 自动备份 + Git 记录,静默执行
|
||||
高危系统操作 → 用户确认
|
||||
```
|
||||
|
||||
### 10.2 边界定义
|
||||
|
||||
- **Symlink**:按物理路径(follow realpath),防止逃逸
|
||||
- **`.git/`**:默认写保护(需确认),可在 permissions.yaml 关闭
|
||||
- **build 目录**:不加特殊规则,Agent 需要完全读写
|
||||
- **`sudo`**:不算高危(开发机日常操作)
|
||||
- **高危判断**:静态路径白名单(`/etc/fstab`、`/boot/`、`/etc/default/grub` 等),模糊情况走 LLM escape hatch
|
||||
- **`~/.air/`**:AirCoding 自身管理,不经过 PermissionEngine
|
||||
|
||||
### 10.3 备份与还原
|
||||
|
||||
- 项目外文件修改备份为 **Git 仓库**(`<project>/.air/local/backups/`)
|
||||
- 每次修改 = `cp` + `git add && git commit`(commit message: session_id、agent_type、reason)
|
||||
- `air restore` 三个粒度:单文件最近版本、指定时间点、整个 session
|
||||
- 用户手动删备份,不做自动清理
|
||||
|
||||
## 11. 会话持久化
|
||||
|
||||
### 11.1 存储策略
|
||||
|
||||
- 按 session 分库 SQLite(`<project>/.air/local/sessions/<id>/session.db`)
|
||||
- 消息存储:Anthropic 原生 content blocks(canonical source)
|
||||
- `message_drafts` 保存流式 assistant 中间态,完成后删除
|
||||
- 调度状态由 domain tables 持久化:tasks / task_dependencies / task_attempts / agents / tool_runs / command_runs / artifacts / diagnostics / evidence_refs / workspaces / events
|
||||
- `ui_state` 只保存 UI 恢复状态,定时和退出时 flush
|
||||
- ProjectionStore 从 DB + EventBus 重建 TUI/HUD view model
|
||||
- 中断恢复:Scheduler 从 domain tables 重建调度队列,running 状态按心跳时间戳判断存亡
|
||||
|
||||
### 11.2 Event Store 分层
|
||||
|
||||
- **EventBus**:高频实时事件(TokenDelta、StdoutChunk、AgentHeartbeat),不落盘
|
||||
- **PersistentEventStore**:durable events(AgentStarted、TaskCompleted、ToolRunCompleted 等),SQLite 主线程同步写入
|
||||
- **ArtifactStore**:大体积内容(build log、test log、pcap、screenshot),DB 存引用 + 摘要 + hash
|
||||
|
||||
## 12. 上下文与记忆系统
|
||||
|
||||
### 12.1 记忆分层
|
||||
|
||||
```text
|
||||
Project Rules(权威层,Claude Code 风格 Markdown + frontmatter)
|
||||
→ Project Profile(事实层)
|
||||
→ Session Memory(会话层)
|
||||
→ Learned Experience(学习层,tentative)
|
||||
→ Debug Knowledge(结构化经验库)
|
||||
→ User Preference(用户偏好)
|
||||
```
|
||||
|
||||
### 12.2 ExperienceMiner
|
||||
|
||||
- **触发**:DebugRecord 产生时 + 会话结束时 + 每 N 轮/工具调用中间触发(Hermes Nudge Engine 风格)
|
||||
- **执行者**:独立后台子代理,不阻塞 Main Agent
|
||||
- **去重**:周期性 Curator Daemon(识别重叠技能、建议合并、标记过期、归档无用)
|
||||
- **自我 patch**:Agent 执行中发现经验/规则不对,转发给 ExperienceMiner 做 patch
|
||||
- **升级**:非调试经验按出现次数(N=3)提醒升级;调试经验以验证证据为置信度,不打分
|
||||
- **格式**:SKILL.md(YAML frontmatter + Markdown body)
|
||||
|
||||
### 12.3 上下文压缩
|
||||
|
||||
- **触发**:Context window 占比达 70%
|
||||
- **策略**:Markdown + frontmatter 规则文件驱动,三层继承(系统默认 → 用户模板 `~/.air/compaction-rules.md` → 项目规则 `.air/shared/compaction-rules.md`)
|
||||
- **机制**:Copy-on-Write。快照消息 1-N → 异步压缩(独立 Compactor 子代理)→ 新消息继续追加 → 完成后插入压缩标记。LLM 看到:摘要 + 标记 + 新消息。原始消息保留,LLM 可显式回溯。
|
||||
- **系统默认模板**:确保没写规则的项目也能正常压缩
|
||||
|
||||
## 13. Debug Knowledge Network
|
||||
|
||||
- 本地优先,provider 接口预留远程共享
|
||||
- DebugRecord 结构化存储(症状、错误签名、根因、修复方案、验证步骤、证据引用)
|
||||
- 隐私:默认不上传,上传前脱敏,显式授权,可撤回
|
||||
|
||||
## 14. 分发与日志
|
||||
|
||||
### 14.1 分发
|
||||
|
||||
- **前期**:二进制 tarball(Bun compile 独立可执行文件 + Bundled Bun runtime + Python 脚本 + 默认资源文件),不发布公开渠道
|
||||
- **后续**:稳定后再考虑 npm / brew / apt / winget
|
||||
|
||||
### 14.2 日志
|
||||
|
||||
- `air.log`:用户可读(启动失败、异常报错、环境配置问题)
|
||||
- `air.developer.log`:开发组公钥加密全量调试日志 + 性能指标,7 天保留
|
||||
- `air doctor`:崩溃诊断包收集命令;诊断包不自动脱敏,但必须用户显式导出/发送
|
||||
- 下次启动自动检测异常退出并提示
|
||||
|
||||
## 15. 测试策略
|
||||
|
||||
- **单元测试**:bun test,CI 每次 push,<30s,无 LLM(覆盖所有确定性逻辑)
|
||||
- **集成测试**:CI 每次 push,<1min,录制 LLM fixture 回放(覆盖 Agent Loop、Scheduler、IPC、session 持久化、压缩、worktree)
|
||||
- **E2E 测试**:Release gate,真实 LLM(完整 C++ 项目场景),必须通过
|
||||
|
||||
## 16. HUD / Status Layer
|
||||
|
||||
- HUD 作为 runtime 内建层,通过 ProjectionStore 消费 DB + EventBus 派生状态(不依赖外部脚本解析 transcript)
|
||||
- 展示:model/project/git/session/context/tasks/agents/tools/build/test/debug
|
||||
- Preset:Full / Essential / Minimal
|
||||
- 参考 claude-hud 的 threshold 颜色、多行布局、中文 label
|
||||
|
||||
## 17. 架构决策记录(ADR)
|
||||
|
||||
原始 13 项 ADR + 三轮讨论补充的新决策,详见:
|
||||
- `AirPlan/docs/architecture/decisions-round-1.md`(D-001 ~ D-020)
|
||||
- `AirPlan/docs/architecture/decisions-round-2.md`(D-021 ~ D-037)
|
||||
- `AirPlan/docs/architecture/decisions-round-3.md`(D-038 ~ D-059)
|
||||
- `AirPlan/docs/architecture/main-agent-state-machine.md`
|
||||
|
||||
## 18. MVP 第一阶段
|
||||
|
||||
```text
|
||||
C++ local dev loop
|
||||
+ @opentui/solid TUI
|
||||
+ durable sessions(项目本地 per-session SQLite,domain tables 持续持久化)
|
||||
+ Copy-on-Write 上下文压缩(三层继承规则文件)
|
||||
+ Claude Code 风格 Project Rules + Hermes 风格 ExperienceMiner + Curator
|
||||
+ local debug knowledge base
|
||||
+ 事件驱动 EventBus + HUD
|
||||
+ 二进制分发
|
||||
```
|
||||
|
||||
具体包含:
|
||||
|
||||
1. Agent 目录与配置(`~/.air/` + `.air/shared/project.json` + `.air/local/`)
|
||||
2. LLM 驱动的项目初始化(Scanner → LLM → 用户确认 → `.air/shared/project.json`)
|
||||
3. 多语言 Project Model(语言无关层 + 语言特定 profile + LanguageDetector 接口)
|
||||
4. TUI Shell + HUD(`@opentui/solid` + ProjectionStore)
|
||||
5. SQLite Session Store(项目 `.air/local` per-session 分库,Anthropic 原生格式 + domain tables)
|
||||
6. C++ Toolchain(BuildTool / DiagnosticParser LLM / TestRunner / StaticAnalysis / clangd CLI)
|
||||
7. Provider / Model(Anthropic + OpenAI 原生,API 边界转换)
|
||||
8. Permission 引擎(信任优先 + Git 备份 + 静态白名单高危检测)
|
||||
9. Agent 分层(Main Agent 状态机 + Architecture Designer + Scheduler + Executor/Reviewer/Debugger 独立进程)
|
||||
10. Context / Memory(Project Rules + ExperienceMiner + Curator + Copy-on-Write 压缩)
|
||||
11. Local DebugRecord Store
|
||||
12. Capability Plugin Prototype(AirSDB 优先改造)
|
||||
247
docs/implementation-plan.md
Normal file
247
docs/implementation-plan.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# AirCoding 实现计划
|
||||
|
||||
> **版本**: 2.0
|
||||
> **日期**: 2026-06-12
|
||||
> **基线**: OpenCode v1.17.4 (commit abda3515)
|
||||
> **参考**: aircoding-architecture-mvp.md (完整架构设计)、reference/airplan-v2 (可复用 prompt)
|
||||
|
||||
---
|
||||
|
||||
## 1. 最终方案:4 Agent + 4 文件
|
||||
|
||||
```
|
||||
Main Agent(对话 + 意图分类 + 架构规划)
|
||||
│
|
||||
├── Scheduler Agent(任务拆解 + 派发 + 监控 + 状态落盘)
|
||||
│ └── Worker Agent(EXECUTE / DEBUG 双模式,通过 shell 调用 cmake/ctest/cppcheck 等)
|
||||
│
|
||||
└── Architecture Designer(架构规划 + 里程碑审查 fork)
|
||||
```
|
||||
|
||||
C++ 工具链不单独封装为 Plugin——Worker 直接通过 OpenCode 已有的 `shell` 工具调用命令行。
|
||||
取证工具(截图/抓包)同理,Worker 直接通过 `shell` 调用 ffmpeg/tcpdump。
|
||||
|
||||
---
|
||||
|
||||
## 2. 文件清单
|
||||
|
||||
| # | 文件 | 内容 | 类型 |
|
||||
|---|------|------|------|
|
||||
| 1 | `agents/scheduler.json` | Scheduler agent 配置 + system prompt | JSON + prompt |
|
||||
| 2 | `agents/worker.json` | Worker agent 配置 + 双模式 system prompt | JSON + prompt |
|
||||
| 3 | `agents/architect.json` | Arc agent 配置 + system prompt(含审查 fork) | JSON + prompt |
|
||||
| 4 | `.opencode/tool/coordinator.ts` | listen / dispatch / status 三个调度工具 | TypeScript |
|
||||
|
||||
运行时自动生成:`.air/local/state/scheduler-state.json`(调度器状态落盘)
|
||||
|
||||
---
|
||||
|
||||
## 3. 可复用的 AirPlan V2 资源
|
||||
|
||||
| AirCoding Agent | V2 对应 | 可复用文件 |
|
||||
|----------------|---------|-----------|
|
||||
| Scheduler | AirEng | `reference/airplan-v2/commands/eng.md` — 调度逻辑、轮询规则、自主决策指令 |
|
||||
| Worker (EXECUTE) | AirDo | `reference/airplan-v2/commands/do.md` — 执行行为、验收标准 |
|
||||
| Worker (DEBUG) | AirDbg | `reference/airplan-v2/commands/dbg.md` — 调试工作流、先取证后修复规则 |
|
||||
| Architecture Designer | AirArc | `reference/airplan-v2/commands/arc.md` — 架构规划、需求探讨、审查指令 |
|
||||
| 审查 fork | AirRvr | `reference/airplan-v2/commands/rvr.md` — Code-to-Design 审查、高风险审计 |
|
||||
|
||||
**复用方式**:将 V2 命令文件中的关键指令提取、适配后写入对应 Agent 的 system prompt。不是原封不动复制,而是提取核心约束规则,去掉 V2 特有的 Python runtime 部分。
|
||||
|
||||
---
|
||||
|
||||
## 4. 各文件实现细节
|
||||
|
||||
### 4.1 `agents/scheduler.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "scheduler",
|
||||
"name": "Scheduler",
|
||||
"description": "任务调度引擎,负责任务拆解、派发、监控和结果汇总",
|
||||
"mode": "subagent",
|
||||
"model": { "primary": "claude-sonnet-4-20250514" },
|
||||
"tools": [
|
||||
"read", "glob", "grep",
|
||||
"coordinator.listen", "coordinator.dispatch", "coordinator.status",
|
||||
"task"
|
||||
],
|
||||
"steps": 200,
|
||||
"system_prompt_file": "agents/prompts/scheduler.md"
|
||||
}
|
||||
```
|
||||
|
||||
**system prompt 核心指令**(从 `eng.md` 提取):
|
||||
- 语言锁定中文
|
||||
- 自主决策原则(不询问用户,除非修复预算耗尽/需求歧义/资源耗尽)
|
||||
- 不写代码(工具白名单已硬阻断)
|
||||
- 任务拆解策略(按模块拆分、按依赖排序)
|
||||
- 流程规则(Worker 完成 → 下一个任务 / 失败 → 重新派发调试)
|
||||
- 状态落盘要求(每次状态变更写 scheduler-state.json)
|
||||
- 10 分钟不活跃自动巡检
|
||||
|
||||
### 4.2 `agents/worker.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "worker",
|
||||
"name": "Worker",
|
||||
"description": "执行器/调试器双模式 Worker",
|
||||
"mode": "subagent",
|
||||
"model": { "primary": "claude-sonnet-4-20250514" },
|
||||
"tools": [
|
||||
"read", "write", "edit", "shell", "glob", "grep"
|
||||
],
|
||||
"steps": 100,
|
||||
"system_prompt_file": "agents/prompts/worker.md"
|
||||
}
|
||||
```
|
||||
|
||||
**system prompt 核心指令**(从 `do.md` + `dbg.md` 提取):
|
||||
|
||||
```markdown
|
||||
## EXECUTE 模式(task.type = "execute")
|
||||
- 按 acceptance_criteria 实现功能
|
||||
- 先读后改,小步编辑
|
||||
- 通过 shell 执行 cmake --build 和 ctest 验证
|
||||
- **每次任务完成前必须通过 shell 运行 cppcheck --enable=all(不可跳过)**
|
||||
- 编译通过 + 测试通过 + cppcheck 无严重问题 = 完成
|
||||
- 不修改 scope.denied_paths 中的文件
|
||||
- 完成后输出结构化结果(必须包含 cppcheck 输出)
|
||||
- **Scheduler 校验:WorkerResult 中无 cppcheck 输出则拒绝,要求补跑**
|
||||
|
||||
## DEBUG 模式(task.type = "debug")
|
||||
- 先取证后修改(不可违反)
|
||||
- 必须至少通过 shell 执行一种取证命令:
|
||||
· GUI 问题 → ffmpeg -f kmsgrab 截图
|
||||
· 网络问题 → tcpdump 抓包
|
||||
· C++ 问题 → cppcheck 静态分析
|
||||
· 通用 → 代码追踪 + 日志分析
|
||||
- 取证结果记录后才能开始修改代码
|
||||
- 修复后必须重新编译 + 测试验证
|
||||
- 修复失败不超过 retry_budget 次
|
||||
```
|
||||
|
||||
### 4.3 `agents/architect.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "architect",
|
||||
"name": "Architecture Designer",
|
||||
"description": "架构规划器,负责需求分析、架构设计和里程碑审查",
|
||||
"mode": "subagent",
|
||||
"model": { "primary": "claude-sonnet-4-20250514" },
|
||||
"tools": ["read", "glob", "grep", "task"],
|
||||
"steps": 100,
|
||||
"system_prompt_file": "agents/prompts/architect.md"
|
||||
}
|
||||
```
|
||||
|
||||
**system prompt 核心指令**(从 `arc.md` + `rvr.md` 提取):
|
||||
- 纯规划器,禁止写代码(工具白名单硬阻断)
|
||||
- 三阶段流程:探讨 → 确认 → 生成计划
|
||||
- 任务描述规范(避免歧义词、包含保留约束)
|
||||
- 里程碑审查:fork 只读子 session 做 Code-to-Design 审查
|
||||
- 审查结果精简后返回 Scheduler
|
||||
|
||||
### 4.4 `.opencode/tool/coordinator.ts`
|
||||
|
||||
三个工具的实现要点:
|
||||
|
||||
**coordinator.listen**:
|
||||
- 订阅 OpenCode EventV2 事件总线
|
||||
- 等待匹配的子代理事件(task.completed / task.failed / task.progress)
|
||||
- 超时返回 timeout 状态(触发 Scheduler 巡检)
|
||||
- 每次调用时检查 last_activity → 超过 10 分钟自动巡检
|
||||
|
||||
**coordinator.dispatch**:
|
||||
- 接收任务列表
|
||||
- 为每个任务创建 OpenCode BackgroundJob(非阻塞子 session)
|
||||
- 返回 jobId 列表
|
||||
- 更新 scheduler-state.json
|
||||
|
||||
**coordinator.status**:
|
||||
- 查询所有活跃 BackgroundJob 的状态
|
||||
- 返回 [{ jobId, taskId, agentType, status, lastHeartbeat }]
|
||||
- 检测卡死任务(心跳超时 / 硬超时)
|
||||
|
||||
**关键技术点**:需要研究 OpenCode 的以下 API:
|
||||
- `packages/opencode/src/background/job.ts` — BackgroundJob 的 start/wait/cancel
|
||||
- `packages/core/src/event.ts` — EventV2 的 subscribe/listen
|
||||
- `packages/opencode/src/tool/task.ts` — TaskTool 的子 session 创建
|
||||
|
||||
---
|
||||
|
||||
## 5. 实现顺序
|
||||
|
||||
### Step 1: 环境搭建 + 读 API(0.5 天)
|
||||
|
||||
- 确认 Bun 环境可用
|
||||
- 读懂 OpenCode Plugin 工具注册机制(`registry.ts` + `.opencode/tool/`)
|
||||
- 读懂 BackgroundJob API(`packages/opencode/src/background/job.ts`)
|
||||
- 读懂 EventV2 API(`packages/core/src/event.ts`)
|
||||
|
||||
### Step 2: 调度工具(1-2 天)
|
||||
|
||||
- 实现 `coordinator.ts`(listen + dispatch + status)
|
||||
- 这是唯一的自定义代码,需要吃透 OpenCode 内部 API
|
||||
- 验证子 session 创建和事件订阅可用
|
||||
|
||||
### Step 3: Agent 配置 + Prompt(1 天)
|
||||
|
||||
- 写 `scheduler.json` + system prompt(从 eng.md 提取)
|
||||
- 写 `worker.json` + system prompt(从 do.md + dbg.md 提取)
|
||||
- 写 `architect.json` + system prompt(从 arc.md + rvr.md 提取)
|
||||
|
||||
### Step 4: 端到端测试(0.5-1 天)
|
||||
|
||||
- 准备一个简单 C++ 项目
|
||||
- 测试完整流程:用户提需求 → Main Agent → Scheduler 拆解 → Worker 执行 → 结果汇总
|
||||
- 修复发现的问题
|
||||
|
||||
**总计:3-5 天**
|
||||
|
||||
---
|
||||
|
||||
## 6. 已知风险和对策
|
||||
|
||||
| 风险 | 对策 |
|
||||
|------|------|
|
||||
| OpenCode Plugin API 不够用 | 读源码确认,必要时做最小修改 |
|
||||
| BackgroundJob 不支持非阻塞派发 | 用 OpenCode 的 `task` 工具 + `background: true` 参数 |
|
||||
| EventV2 事件格式不符合预期 | 在 coordinator.listen 中做适配层 |
|
||||
| System prompt 不够稳定 | 从 V2 提取已验证的指令,反复测试调优 |
|
||||
| 上下文窗口不够 | 简化 prompt,Worker 只传必要上下文 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 后续迭代路线(当前不做)
|
||||
|
||||
1. C++ 工具链 Plugin(cpp.build/test/analyze/diagnose)— Worker 目前直接用 shell
|
||||
2. 取证工具 Plugin(evidence.screenshot/pcap)— Worker 目前直接用 shell
|
||||
3. 独立 Reviewer Agent
|
||||
4. 证据门控策略(10 种任务类型 × 证据表)
|
||||
5. 动态 DAG 调度算法(增量重规划)
|
||||
6. ContextAssembler(按需抽取上下文)
|
||||
7. 上下文压缩(Copy-on-Write)
|
||||
8. ExperienceMiner + Debug Knowledge
|
||||
9. HUD / Status Layer
|
||||
10. 多语言 toolchain(Python/Rust/JS)
|
||||
11. 二进制分发
|
||||
|
||||
---
|
||||
|
||||
## 8. 核心设计决策速查
|
||||
|
||||
| 决策 | 结论 |
|
||||
|------|------|
|
||||
| 基线 | OpenCode v1.17.4 |
|
||||
| 进程模型 | 单进程(子代理 = 子 session) |
|
||||
| C++ 工具链 | Worker 直接用 shell 调用(不封装 Plugin) |
|
||||
| Scheduler | 独立 Agent,事件驱动 |
|
||||
| 防卡死 | 10 分钟不活跃定时器 + 状态落盘 |
|
||||
| LLM 策略 | 混合:正常流程确定性代码,异常走 LLM |
|
||||
| 接口契约 | 中等粒度 + stability 标记 |
|
||||
| 审查 | 两层:Worker 自验 + Arc 里程碑审查 fork |
|
||||
| 上下文共享 | 共享文件 + ContextPack + WorkerResult |
|
||||
| Worker 模式 | EXECUTE + DEBUG 双模式合一 |
|
||||
268
docs/meeting-notes-20260613.md
Normal file
268
docs/meeting-notes-20260613.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# AirCoding 会议记录与当前状态
|
||||
|
||||
> 日期:2026-06-13
|
||||
> 状态:架构已确定,实现进行中,需要补全各层代码级保证和协作 prompt
|
||||
|
||||
---
|
||||
|
||||
## 一、核心架构决策(已确定)
|
||||
|
||||
### 1.1 总体架构
|
||||
|
||||
```
|
||||
用户 ↔ Main Agent(客服/乙方代表,用户唯一交互入口)
|
||||
└── Scheduler(核心枢纽,事件路由器)
|
||||
├── Architect(按需咨询/里程碑审查)
|
||||
│ └── fork → Reviewer(审查时临时创建,审查完销毁)
|
||||
├── Executor Worker(写代码、编译、测试)
|
||||
├── Debugger Worker(证据收集、问题定位、修复)
|
||||
└── 读写 .air/shared/ 共享文件
|
||||
```
|
||||
|
||||
- **Main Agent = 客服角色**:面向用户,理解意图,传达需求,汇报进度,处理变更,不做技术活
|
||||
- **Scheduler = 项目经理**:拆解任务,派发 Worker,监控进度,协调资源,不写代码
|
||||
- **Architect = 技术总监**:需求分析,架构设计,里程碑审查,常驻提供咨询
|
||||
- **Worker = 工程师**:EXECUTE + DEBUG 双模式,写代码/编译/测试/调试
|
||||
|
||||
### 1.2 通信模型
|
||||
|
||||
- **EventV2 事件总线** + **coordinator 工具**(listen/dispatch/status)
|
||||
- 子 agent 完成 → EventV2 广播 → Scheduler 收到 → 按规则派发下一个
|
||||
- **共享文件**(`.air/shared/`)+ **ContextPack**(派发时传递上下文引用)
|
||||
- **不是 agent 之间直接对话**,而是通过事件 + Scheduler 路由
|
||||
|
||||
### 1.3 三条通信路径
|
||||
|
||||
1. **Scheduler → Architect**:重规划/异常咨询,Arc 读图 → 输出 PlanDelta
|
||||
2. **Scheduler → Reviewer**:Code-to-Design 对照审查,审查报告写入 WorkerResult
|
||||
3. **Scheduler → Architect(consult)**:Scheduler 无法决策时求助
|
||||
|
||||
### 1.4 流程规则(Scheduler 状态机)
|
||||
|
||||
```
|
||||
Executor 完成 → 自动触发 Reviewer(逐任务审查)
|
||||
Reviewer 通过 → 标记任务完成
|
||||
build/test 失败 → 自动触发 Debugger
|
||||
Reviewer 发现问题 → 重新派发 Executor 修复
|
||||
阶段内所有任务完成 → 自动触发 Architect(里程碑审查)
|
||||
里程碑审查通过 → 进入下一阶段
|
||||
里程碑审查发现问题 → Architect 生成修复任务 → Scheduler 派发
|
||||
需求变更 → 触发动态 DAG 调度算法
|
||||
Scheduler 异常无法决策 → 派发 Architect(咨询)
|
||||
所有任务完成 → 汇总结果返回 Main Agent
|
||||
```
|
||||
|
||||
### 1.5 核心设计约束
|
||||
|
||||
- **单进程模型**:子代理 = OpenCode 子 session(TaskTool + BackgroundJob)
|
||||
- **代码级硬阻断**:工具白名单是硬阻断不是建议
|
||||
- **LLM 混合策略**:正常调度走确定性代码,异常/边界才调 LLM
|
||||
- **防卡死**:10 分钟不活跃定时器 + scheduler-state.json 实时落盘
|
||||
- **cppcheck 强制**:每次任务完成前必须运行,无输出不允许标记完成
|
||||
- **证据门控**:按任务类型决定必需证据
|
||||
- **两层审查**:Worker 自验 + Architect 里程碑审查 fork
|
||||
|
||||
### 1.6 基线
|
||||
|
||||
- **Fork OpenCode v1.17.4**(commit abda3515)
|
||||
- TypeScript + Bun,单进程,Effect v4 beta
|
||||
- 不封装 C++ 工具链 Plugin,Worker 直接用 shell 调用 cmake/ctest/cppcheck
|
||||
|
||||
---
|
||||
|
||||
## 二、当前实现状态
|
||||
|
||||
### 2.1 已完成的文件
|
||||
|
||||
| 文件 | 位置 | 状态 |
|
||||
|------|------|------|
|
||||
| coordinator.ts | workspace/.../src/tool/coordinator.ts | ✅ 已写入,类型检查通过 |
|
||||
| registry.ts | workspace/.../src/tool/registry.ts | ✅ 已修改(+4 工具注册) |
|
||||
| agent.ts | workspace/.../src/agent/agent.ts | ⚠️ 已回退,需要重新修改 |
|
||||
| scheduler.txt | workspace/.../src/agent/prompt/scheduler.txt | ✅ 已写入,但缺少协作指令 |
|
||||
| worker.txt | workspace/.../src/agent/prompt/worker.txt | ✅ 已写入,但缺少协作指令 |
|
||||
| architect.txt | workspace/.../src/agent/prompt/architect.txt | ✅ 已写入,但缺少协作指令 |
|
||||
| AGENTS.md | E:\WorkSpace\AirCodingCli\AGENTS.md | ✅ 已写入 |
|
||||
| opencode.json | E:\WorkSpace\AirCodingCli\opencode.json | ✅ 已创建 |
|
||||
| bun install | workspace | ✅ 成功(需要设置 WindowsSdkDir 环境变量) |
|
||||
| bun typecheck | workspace | ✅ 通过 |
|
||||
|
||||
### 2.2 启动方式
|
||||
|
||||
```bash
|
||||
cd E:\WorkSpace\AirCodingCli\workspace
|
||||
export WindowsSdkDir="D:/Dev/IDE/VS/VSIDE/Windows Kits/10/"
|
||||
export VCToolsInstallDir="D:/Dev/IDE/VS/VSIDE/VC/Tools/MSVC/14.50.35717/"
|
||||
export OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
|
||||
bun dev
|
||||
```
|
||||
|
||||
或运行 `workspace\start.bat` / `workspace\start.sh`。
|
||||
|
||||
### 2.3 测试结果
|
||||
|
||||
- TUI 正常渲染 ✅
|
||||
- 只能看到 build 和 plan 两个 agent ❌(scheduler/worker/architect 未注册)
|
||||
- Main Agent 不会自动派发 Scheduler ❌
|
||||
- 各 Agent 之间无法协作 ❌
|
||||
|
||||
---
|
||||
|
||||
## 三、待解决的问题(按优先级)
|
||||
|
||||
### 3.1 每层都需要 A(代码级保证)+ B(协作 Prompt)
|
||||
|
||||
**这是用户反复强调的核心要求。不能只靠 prompt,也不能只有代码没有 prompt。**
|
||||
|
||||
| Agent | A:代码级保证(需要改 OpenCode 源码) | B:协作 Prompt(需要补全) |
|
||||
|-------|-------------------------------------|--------------------------|
|
||||
| **Main Agent** | prompt.ts 强制转发给 Scheduler(代码路由) | 怎么汇报结果、转达变更、与用户沟通 |
|
||||
| **Scheduler** | 代码保证只能通过 task 工具派发 Worker/Architect | 怎么拆任务、怎么用 coordinator 工具、怎么读写 task-graph、怎么和 Architect 协作 |
|
||||
| **Architect** | 工具白名单已有(只读) | 怎么写 task-graph.json、怎么 fork Reviewer、审查结果发给谁 |
|
||||
| **Worker** | Scheduler 校验 WorkerResult 包含 cppcheck 输出 | 怎么汇报结果(WorkerResult 格式)、EXECUTE/DEBUG 模式切换、结果返回给谁 |
|
||||
|
||||
### 3.2 每个 Agent 需要知道的协作信息
|
||||
|
||||
```
|
||||
我是谁 → 我的角色和约束
|
||||
我的上游是谁 → 谁派发了我,结果返回给谁
|
||||
我的下游是谁 → 我能派发谁,用什么工具
|
||||
通信协议 → 共享文件在哪、结果格式是什么、事件怎么收
|
||||
```
|
||||
|
||||
### 3.3 具体改动清单
|
||||
|
||||
#### 改动 1:agent.ts — 注册 3 个自定义 Agent
|
||||
|
||||
```typescript
|
||||
// 在 agents 对象中添加:
|
||||
scheduler: {
|
||||
name: "scheduler",
|
||||
description: "AirCoding 调度引擎",
|
||||
mode: "subagent", // 不是 primary,由 Main Agent 派发
|
||||
native: true,
|
||||
steps: 200,
|
||||
prompt: PROMPT_SCHEDULER,
|
||||
permission: Permission.merge(defaults, Permission.fromConfig({
|
||||
edit: "deny", write: "deny", todowrite: "deny", task: "allow",
|
||||
}), user),
|
||||
},
|
||||
worker: { ... mode: "subagent", prompt: PROMPT_WORKER, ... },
|
||||
architect: { ... mode: "subagent", prompt: PROMPT_ARCHITECT,
|
||||
permission: { "*": "deny", read: "allow", glob: "allow", grep: "allow", task: "allow" }
|
||||
},
|
||||
```
|
||||
|
||||
#### 改动 2:build agent 加 prompt — Main Agent 编排逻辑
|
||||
|
||||
```typescript
|
||||
build: {
|
||||
name: "build",
|
||||
prompt: PROMPT_AIRCODING_MAIN, // ← 新增
|
||||
mode: "primary",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
PROMPT_AIRCODING_MAIN 内容:
|
||||
- 你是 AirCoding 主代理,面向用户的唯一交互入口
|
||||
- 你不直接执行复杂任务,通过 task 工具派发 scheduler
|
||||
- 始终设置 background: true
|
||||
- 子代理完成后自动通知你,你负责向用户汇报
|
||||
|
||||
#### 改动 3:prompt.ts — 代码级路由(可选但推荐)
|
||||
|
||||
在主循环中插入确定性路由,强制将复杂任务转发给 Scheduler:
|
||||
|
||||
```typescript
|
||||
// 在 runLoop 中,LLM 调用之前
|
||||
// 如果当前 agent 是 build,且用户消息不是简单问答
|
||||
// → 确定性派发 scheduler(不经过 LLM 判断)
|
||||
```
|
||||
|
||||
#### 改动 4:各 Agent prompt 补全协作指令
|
||||
|
||||
每个 prompt 需要补充:
|
||||
- 上游/下游是谁
|
||||
- 用什么工具通信(task, coordinator.listen, coordinator.status)
|
||||
- 共享文件路径和格式(task-graph.json, review-result.json)
|
||||
- 结果格式(WorkerResult 结构)
|
||||
|
||||
---
|
||||
|
||||
## 四、设计文档索引
|
||||
|
||||
| 文档 | 路径 | 内容 |
|
||||
|------|------|------|
|
||||
| 架构设计 | aircoding-architecture-mvp.md | 完整架构(16 章,7 项已确定决策) |
|
||||
| 实现计划 | implementation-plan.md | 实现步骤 v2.0 |
|
||||
| 集成指南 | INTEGRATION.md | 如何集成到 OpenCode fork |
|
||||
| AI 编码指南 | AGENTS.md | 代码风格 + Agent 约束 |
|
||||
| V1 痛点 | airplanV2-Qwen3.7-Max设计.md | 25 个 P0/P1 缺陷及 V2 方案 |
|
||||
| 原始愿景 | idea.md | 完整系统设计(参考用) |
|
||||
| V1 基线 | baselineV1.md | 早期基线设计(参考用) |
|
||||
|
||||
---
|
||||
|
||||
## 五、环境配置
|
||||
|
||||
```bash
|
||||
# Bun 版本
|
||||
bun 1.3.14
|
||||
|
||||
# 必需环境变量
|
||||
WindowsSdkDir=D:\Dev\IDE\VS\VSIDE\Windows Kits\10\
|
||||
VCToolsInstallDir=D:\Dev\IDE\VS\VSIDE\VC\Tools\MSVC\14.50.35717\
|
||||
OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
|
||||
|
||||
# 项目结构
|
||||
E:\WorkSpace\AirCodingCli\
|
||||
├── workspace/ # OpenCode v1.17.4 fork(工作目录)
|
||||
├── reference/opencode/ # OpenCode v1.17.4 原始参考
|
||||
├── reference/airplan-v2/ # V2 插件 prompt 参考
|
||||
├── src/ # AirCoding 自有源码(coordinator.ts, prompts)
|
||||
└── *.md # 设计文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、关键代码参考
|
||||
|
||||
### coordinator.ts 已实现的 4 个工具
|
||||
|
||||
1. `coordinator_listen` — 等待后台 Worker 完成,返回结果
|
||||
2. `coordinator_status` — 查询所有后台 Worker 状态
|
||||
3. `coordinator_save_state` — 保存调度状态到 scheduler-state.json
|
||||
4. `coordinator_load_state` — 从 scheduler-state.json 恢复状态
|
||||
|
||||
### TaskTool 关键 API(OpenCode 已有)
|
||||
|
||||
```typescript
|
||||
// 派发子代理(前台/后台)
|
||||
task({
|
||||
description: "任务描述",
|
||||
prompt: "详细任务指令",
|
||||
subagent_type: "scheduler", // 或 "worker", "architect"
|
||||
background: true, // 后台运行
|
||||
task_id: "复用已有session的ID" // 可选,复用持久 session
|
||||
})
|
||||
```
|
||||
|
||||
### 共享文件结构
|
||||
|
||||
```
|
||||
.air/shared/
|
||||
├── plan/
|
||||
│ ├── plan.md # 架构方案
|
||||
│ ├── task-graph.json # 任务图(source of truth)
|
||||
│ ├── requirements.md # 原始需求
|
||||
│ └── docs/ADR-*.md # 架构决策记录
|
||||
└── rules/
|
||||
├── project-rules.md
|
||||
└── toolchain-rules.md
|
||||
|
||||
.air/local/
|
||||
├── state/
|
||||
│ └── scheduler-state.json # 调度器实时状态
|
||||
└── sessions/
|
||||
```
|
||||
Reference in New Issue
Block a user