# pi 协作运行指南

> 只讲怎么跑。原理、架构见 [Dockerfile](./Dockerfile) 与 [supervisor.sh](./supervisor.sh)。

---

## 1. 前置检查（1 分钟）

```bash
docker --version     # 确认 Docker 可用
node --version       # 本机构建不需要，仅容器内 pi 需要 node>=22.19
```

与 pigo-coop 不同，pi-coop **不需要**预编译二进制：pi 通过 npm 全局安装在镜像内，
extension（coop.ts）由 pi 的 jiti 直接加载 .ts，无需预编译。

---

## 2. 构建

在仓库根目录执行（构建上下文为 `pi-coop/` 目录，避免把 `pi/`、`pigo/` 等大目录发给 daemon）：

```bash
docker build -f pi-coop/Dockerfile -t pi-coop pi-coop/
```

构建会：
1. 拉取 `node:24-bookworm-slim` 基础镜像；
2. `npm install -g @earendil-works/pi-coding-agent`（pi 本体）；
3. 装系统工具（git/ripgrep/python3/jq/openssl…）与 Python 常用库；
4. 拷入 coop extension、supervisor、协议与提示。

> 国内构建慢时，Dockerfile 已用清华 PyPI 镜像加速 pip。npm 若慢可配 `--build-arg` 或宿主 npm 镜像。

---

## 3. 运行

### 3.1 直接运行（不保留任何数据）

```bash
docker run --rm \
  -e MODEL=deepseek-chat \
  -e BASE_URL=https://api.deepseek.com \
  -e API_KEY=<your-key> \
  -e PROTOCOL=openai \
  -e TASK="请为 XX 编写设计文档并实现原型" \
  -e ROUND_MAX=6 \
  pi-coop
```

### 3.2 推荐运行（保留黑板产物 + 跨 run 会话）

```bash
mkdir -p blackboard

docker run --rm \
  -v "$PWD/blackboard:/blackboard" \
  -e MODEL=deepseek-chat \
  -e BASE_URL=https://api.deepseek.com \
  -e API_KEY=<your-key> \
  -e PROTOCOL=openai \
  -e TASK="请为 XX 编写设计文档并实现原型" \
  -e ROUND_MAX=6 \
  pi-coop
```

### 3.3 常用参数速查

| 参数 | 必填 | 默认 | 用途 |
| --- | --- | --- | --- |
| `MODEL` | ✅ | — | 模型名 |
| `BASE_URL` | ✅ | — | OpenAI/Anthropic 兼容 base-url |
| `API_KEY` | ✅ | — | API key |
| `PROTOCOL` | 否 | `openai` | `openai` / `anthropic` |
| `TASK` | ✅（或用 `task.md`） | — | 任务描述 |
| `ROUND_MAX` | 否 | `10` | 最大轮次 |
| `TIMEOUT` | 否 | `600` | 单轮超时秒数（`0`=不限） |

> 环境变量与 pigo-coop 完全一致，`run_coop` 工具无需改动即可注入。

---

## 4. 结果怎么看

- **完成**：stdout 打印 `[supervisor] status=solved`，退出码 `0`。
- **未完成**：达到 `ROUND_MAX`，`status=unsolved`，退出码 `1`。
- **参数错**：退出码 `2`。

保留黑板后查看：

```bash
ls blackboard/workspace/     # agent 产物
cat blackboard/DONE          # 最终交付总结
cat blackboard/result.json   # 结构化结果（status/exit_code/summary/flag/artifacts）
cat blackboard/logs/round-1.log   # 第 1 轮运行日志（pi --mode json 的 NDJSON 流）
```

`result.json` 字段固定：`status`、`exit_code`、`summary`、`flag`、`artifacts`，
与 pigo-coop 完全一致，外部调度方（如 agent-web 的 run_coop 工具）解析逻辑无需改动。

---

## 5. 与 pigo-coop 的差异

| 维度 | pigo-coop | pi-coop |
| --- | --- | --- |
| agent | Go 编译的 pigo 二进制 | npm 安装的 pi（TypeScript） |
| 模型接入 | CLI `--base-url`/`--protocol` 直传 | coop extension 读环境变量注册 provider |
| blackboard 工具 | pigo 内置（blackboard_tool.go） | coop extension 注册（coop.ts） |
| 输出格式 | `-o stream-json` | `--mode json`（NDJSON，首行 session header） |
| session 恢复 | `--resume <id>` | `--session-id <id> --session-dir <dir>` |
| cwd | `-C <dir>` | 进程 cwd（supervisor 先 `cd`） |
| 协议（task.md/DONE/result.json） | 一致 | 一致 |
| 环境变量（MODEL/BASE_URL/...） | 一致 | 一致 |

---

## 6. 常见运行问题

| 报错 / 现象 | 处理 |
| --- | --- |
| 退出 2：`必须提供 MODEL / BASE_URL / API_KEY` | 补传环境变量 |
| `DONE already exists` | 正常，上一次运行已留标记（幂等） |
| `MissingSessionCwdError` | 跨轮 resume 时 session 记录的 cwd（/blackboard/workspace）不存在；确保挂载未变 |
| extension 加载失败 | 确认镜像内 `/extensions/coop.ts` 存在；`pi -e` 用 jiti 加载 ts，无需预编译 |
| 想从头重跑 | 删除挂载目录里的 `DONE` 与 `result.json` 后重新 run |
