- local_rig/ 完整包(7 源文件 + ui.html + CHANGELOG) - tests/test_local_rig.py + test_rig_real_agent.py(纯 local_rig 测试) - scripts/15-criterion4-live.sh(判据④活环境门) - README.md(定位/快速开始/与 tutti-selfhost 的关系) - requirements.txt(唯一外部依赖 pyyaml) - .gitignore 来源: figmar/tutti-selfhost @ 3b23853 (2026-10-06) 原 PR #43 已合入 tutti-selfhost main
160 lines
6.2 KiB
Markdown
160 lines
6.2 KiB
Markdown
# local_rig 变更记录
|
||
|
||
> 分支:`feat/local-rig` → main
|
||
> PR:#43
|
||
> 基线:main `992ad7c`(rebase 后,2026-10-05)
|
||
> 最后更新:2026-10-05
|
||
|
||
## 与多智能体协作工作台的关系
|
||
|
||
local_rig 是工作台的**单机执行层**:
|
||
|
||
| 层 | 组件 | 职责 |
|
||
|---|---|---|
|
||
| **协作层**(Matrix 房间) | `22-agent-bus.sh` + bridge + tuttid | 人 + 多 Agent 在 #agent-hub-test 里 @ 派任务、收回执、翻历史 |
|
||
| **执行层**(本 PR) | `local_rig` daemon | 单台机器上跑多个 agent 实例(hermes CLI / terminal),任务入队 → on-demand spawn → 结果回报 |
|
||
|
||
对接点:
|
||
- 协作层里 @ 一个 agent 后,bridge 把任务经 tuttid 派到 `local_rig` daemon(`:27900`)
|
||
- `local_rig` 执行完把结果写回 tuttid → bridge → Matrix 房间(`com.apescale.tutti.result.v1`)
|
||
- 没有 local_rig 时,bridge 只能回执"accepted → running → succeeded"但没有真实产出(TY02 当前状态)
|
||
- local_rig 是**让 @ 之后有真 agent 执行并回报**的那一环(dsh 在 issue#2 里指出的断链)
|
||
|
||
## 回滚锚点
|
||
|
||
| 锚点 | 含义 |
|
||
|---|---|
|
||
| `main @ 8f547cc` | 合并前 main 的 HEAD(完全回滚 = `git reset --hard 8f547cc`) |
|
||
| `feat/local-rig @ 3f688bb` | 第一版(rig_schema/queue/daemon/cli/runtime + 测试) |
|
||
| `feat/local-rig @ f0ff9fe` | 第二版(on-demand dispatch + profile + dsh/workbuddy) |
|
||
| 下一个 commit(待提交) | 第三版(UI dashboard) |
|
||
|
||
**回滚操作**:
|
||
```bash
|
||
# 完全回滚(丢弃 local_rig)
|
||
git checkout main && git reset --hard 8f547cc
|
||
|
||
# 回到第一版(去掉 on-demand/profile 改动)
|
||
git checkout feat/local-rig && git reset --hard 3f688bb
|
||
|
||
# 回到第二版(去掉 UI)
|
||
git checkout feat/local-rig && git reset --hard f0ff9fe
|
||
```
|
||
|
||
## 文件清单
|
||
|
||
| 文件 | 行数 | 职责 | 新增/修改 |
|
||
|---|---|---|---|
|
||
| `local_rig/__init__.py` | 7 | 版本号 | 新增 |
|
||
| `local_rig/rig_schema.py` | 195 | YAML 解析 + 校验(pods/members/edges) | 新增 |
|
||
| `local_rig/queue.py` | 219 | SQLite WAL 持久化队列,状态机 | 新增 |
|
||
| `local_rig/daemon.py` | 326 | HTTP daemon + on-demand dispatch + `/ui` | 新增 |
|
||
| `local_rig/runtime_terminal.py` | 90 | tmux 裸终端运行时 | 新增 |
|
||
| `local_rig/runtime_hermes.py` | 157 | hermes CLI 运行时(profile + 自动检测 bin) | 新增 |
|
||
| `local_rig/cli.py` | 136 | `rig start/status/assign/tasks/stop` | 新增 |
|
||
| `local_rig/ui.html` | 183 | 单文件 HTML dashboard(vanilla JS) | 新增 |
|
||
| `demo/rig.yaml` | 50 | 示例团队(5 Agent 含 dsh/workbuddy) | 新增 |
|
||
| `tests/test_local_rig.py` | 401 | 29 个测试(schema/queue/daemon) | 新增 |
|
||
| `README.md` | +81 | 新增「单机轻量版」章节 | 修改 |
|
||
|
||
**总计**:11 个新文件 + 1 个修改,~1,830 行
|
||
|
||
## 变更时间线
|
||
|
||
### Commit 1: `3f688bb` — 单机轻量 Agent 团队
|
||
- `rig_schema.py`:YAML → `Rig` 对象(pods/members/edges,runtime 枚举校验)
|
||
- `queue.py`:SQLite WAL,`pending→running→done|failed|timeout`,`BEGIN IMMEDIATE` 原子领取
|
||
- `daemon.py`:`ThreadingHTTPServer`,API 见下
|
||
- `runtime_terminal.py`:tmux session 管理(start/stop/status)
|
||
- `runtime_hermes.py`:spawn `hermes chat`(预起常驻)
|
||
- `cli.py`:`rig start/status/assign/tasks/stop`
|
||
- `tests/test_local_rig.py`:29 例
|
||
- `demo/rig.yaml`:2 pod(dev + ops),3 member
|
||
|
||
### Commit 2: `f0ff9fe` — on-demand dispatch + profile
|
||
- **daemon.py**:
|
||
- `start_member()` hermes-cli 改 on-demand(不预起,任务到达时 spawn)
|
||
- `enqueue()` 触发 `_dispatch_hermes()` → 独立线程跑 `hermes -z "prompt"`
|
||
- `terminal` 失败不阻塞(tmux 未装 graceful degrade)
|
||
- `stop()` 加 `server_close()`(修端口释放)
|
||
- **runtime_hermes.py**:
|
||
- 自动检测 hermes bin(PATH → `~/Library/Application Support/.../desktop-bin/hermes`)
|
||
- `--profile` 支持(`HermesProcess.profile` 字段)
|
||
- `available()` 绝对路径走 `Path.exists()` 不走 `which`
|
||
- **demo/rig.yaml**:加 `dev.impl`(profile=dsh)+ `dev.qa`(profile=workbuddy)
|
||
|
||
### Commit 3(待提交):UI dashboard
|
||
- **ui.html**:单文件 HTML(暗色主题,vanilla JS,3s 轮询)
|
||
- Members 面板:状态灯 + runtime + profile
|
||
- Tasks 面板:状态 badge + result/error
|
||
- Assign 表单:选 member + 输入 prompt + 派发
|
||
- **daemon.py**:`GET /ui` 返回 `ui.html`
|
||
|
||
## API 一览
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|---|---|---|
|
||
| GET | `/health` | `{"status":"ok","rig":"name"}` |
|
||
| GET | `/rig` | rig 定义(pods/members/edges) |
|
||
| GET | `/status` | 所有 member 状态 |
|
||
| GET | `/tasks` | 任务列表(`?status=&assignee=&limit=`) |
|
||
| GET | `/tasks/{id}` | 单个任务 |
|
||
| GET | `/ui` | HTML dashboard |
|
||
| POST | `/tasks` | 入队 `{"assignee","prompt","deadline_s"}` |
|
||
| POST | `/tasks/{id}/claim` | 领取 |
|
||
| POST | `/tasks/{id}/done` | 完成 `{"result"}` |
|
||
| POST | `/tasks/{id}/fail` | 失败 `{"error"}` |
|
||
| POST | `/start` | 启动所有 member |
|
||
| POST | `/start/{member}` | 启动单个 |
|
||
| POST | `/stop` | 停止所有 |
|
||
| POST | `/stop/{member}` | 停止单个 |
|
||
|
||
## CLI 用法
|
||
|
||
```bash
|
||
# 启动(前台,Ctrl+C 停)
|
||
python3 -m local_rig.cli -f demo/rig.yaml start --port 27900
|
||
|
||
# 状态
|
||
python3 -m local_rig.cli -f demo/rig.yaml status --port 27900
|
||
|
||
# 派任务
|
||
python3 -m local_rig.cli -f demo/rig.yaml assign --to dev.lead "修复登录 bug"
|
||
|
||
# 查任务
|
||
python3 -m local_rig.cli -f demo/rig.yaml tasks --status done
|
||
|
||
# 停止
|
||
python3 -m local_rig.cli -f demo/rig.yaml stop --port 27900
|
||
```
|
||
|
||
## 本机部署
|
||
|
||
```bash
|
||
# 1. 启动 daemon(后台)
|
||
cd <repo>
|
||
python3 -c "
|
||
import sys; sys.path.insert(0,'.')
|
||
from local_rig.daemon import serve
|
||
d = serve('demo/rig.yaml', port=27900)
|
||
import time
|
||
while True: time.sleep(60)
|
||
" &
|
||
|
||
# 2. 打开 UI
|
||
open http://127.0.0.1:27900/ui
|
||
|
||
# 3. CLI
|
||
python3 -m local_rig.cli -f demo/rig.yaml status
|
||
python3 -m local_rig.cli -f demo/rig.yaml assign --to dev.lead "reply OK"
|
||
```
|
||
|
||
## 已知限制
|
||
|
||
| 限制 | 影响 | 后续 |
|
||
|---|---|---|
|
||
| tmux 未装 | `terminal` 运行时不可用(graceful degrade) | `brew install tmux` |
|
||
| dsh/workbuddy 无独立 CLI | 通过 `hermes --profile` 代理 | 等 DSH CLI / WorkBuddy API |
|
||
| hermes-acp 未实现 | 需 tuttid 运行时 | 第二版接入 `:27800` WS |
|
||
| 单 daemon 单进程 | 不支持多 rig 并发 | 多端口多实例 |
|