Bundle
unipet-dsh
DSH -> UniPet 桌面宠物状态联动:监听 agent/session 生命周期事件,把思考/工具/等待/失败状态推给本地 UniPet 宠物
- Source
- ztyhehe
- License
- MIT
- Updated
- Updated 8 days ago
Readme
# unipet-dsh
[DSH(DeepSeek Harness)](https://github.com/deepseek-ai)→ [UniPet](https://github.com/ydyangdan/UniPet) 桌面宠物联动插件:监听 DSH 的 agent / session 生命周期事件,把状态实时推送给本地 UniPet 宠物(HTTP API,默认 `127.0.0.1:8768`),让桌宠反映 AI 的干活状态。
## ✨ 状态映射
| DSH 事件 | UniPet 状态 | 气泡文案 |
|---|---|---|
| `turn/start`(新轮次开始) | running | Thinking… |
| `tool/call`(工具调用前) | running | Editing code / Running command / Searching / Delegating |
| `approval/asked`(权限询问) | waiting | Waiting for your approval |
| 提问类工具(ask/question) | waiting | Waiting for your answer |
| `tool/result` 失败 / `agent/error` | failed | Task failed |
| `agent/status` idle(轮次结束) | review | Done - ready for review(8s 后自动复位) |
## 📦 安装(标准 bundle 通道)
```bash
cd ~/.dsh && dsh plugin --profile web add git+https://github.com/ztyhehe/unipet-dsh.git
```
安装后重启 `dsh web` 即生效。
> 若 profile 的 `cordis.patch.yml` 里还留着旧的手工挂载行(`name: './plugins/unipet-dsh/index.js'`),请删除该条 insert,避免双实例重复推送。
### 卸载
```bash
cd ~/.dsh && dsh plugin --profile web remove unipet-dsh
```
## ⚙️ 配置(可选)
默认值即可使用;需要时在 profile 的 `cordis.patch.yml` 里覆盖插件 insert 的 `config`:
| 键 | 默认 | 说明 |
|---|---|---|
| `host` | `127.0.0.1` | UniPet HTTP 地址 |
| `port` | `8768` | UniPet HTTP 端口 |
| `source` | `dsh` | 事件来源标识(宠物侧区分多来源) |
| `autoStart` | `true` | 宠物不在线时尝试 `unipet start` 拉起 |
| `debounceMs` | `400` | 同类状态最小发送间隔(去抖窗口);高频事件在窗口内合并。设为 `0` 恢复逐事件直推 |
| `healthIntervalMs` | `30000` | 宠物健康探测周期;断线期间停止推送,恢复后自动回 `idle`。设为 `0` 关闭周期探测 |
| `aggregate` | `true` | 多 agent 聚合:失败最高优先,其余以根(主)agent 状态为准,子 agent 不再互相覆盖 |
| `softFail` | `true` | 扩展语义失败识别:工具结果文本命中关键词白名单时映射到 `failed` |
| `softFailKeywords` | 见源码 | 语义失败关键词白名单(字符串数组,大小写不敏感);覆盖默认列表 |
| `startRetry` | `false` | 拉起失败有限重试:`true` = 最多 3 次、间隔 5s;也可传正整数(次数)或 `{ maxAttempts, intervalMs }` |
| `ttl.{idle,running,waiting,failed,review}` | 见源码 | 各状态气泡存活毫秒数 |
> 新增的 `debounceMs` / `healthIntervalMs` / `aggregate` / `softFail` 默认开启;
> 逐一设为关闭值(`0` / `false` / `false` / `false`)即可回归(近似)v0.1.0 行为。
### 拉起失败与降级提示
- 未安装(找不到 `unipet` 命令):日志明确提示「宠物未安装,请先安装 UniPet」,不无限重试。
- 已安装但拉起失败(权限 / 崩溃 / 超时):输出可读日志;可按需开启 `startRetry` 有限重试。
- headless 降级:Linux 无 `DISPLAY` / `WAYLAND_DISPLAY` 时判定为无桌面会话,本次运行不推送、不拉起并记录一条说明;macOS / Windows 默认视为桌面环境。
## 📡 状态集与 UniPet 协议
状态枚举与 UniPet overlay 的 `PET_STATES` 一一对应:
| 枚举 | 含义 | 默认 TTL |
|---|---|---|
| `idle` | 就绪 / 空闲,收到即切换 | 无 |
| `running` | 思考 / 工具执行中 | 5 分钟 |
| `waiting` | 等待用户审批 / 回答 | 1 小时 |
| `failed` | 任务失败 | 30 秒 |
| `review` | 轮次结束等待复查 | 8 秒(随后自动复位) |
每个状态对应一次 HTTP `POST /api/pet/events`。`action: "update"` 的消息载荷字段:
```json
{
"source": "dsh",
"state": "running",
"message": "Editing code",
"action": "update",
"ttl": 300000
}
```
| 字段 | 说明 |
|---|---|
| `source` | 事件来源标识(默认 `dsh`,宠物侧用于区分多来源) |
| `state` | `PET_STATES` 之一 |
| `message` | 气泡文案(最长 180 字符) |
| `action` | `update`(更新状态)/ `clear`(复位气泡;`ttl` 到期或 idle 后使用) |
| `ttl` | 可选,气泡存活毫秒数;`idle` 不携带 TTL |
## 🔒 说明
- 纯 host 侧插件(无 client 半),仅访问本机回环地址,不外发任何数据
- 与 UniPet 自身交互的工具不会回推状态,避免自激
- 卸载时清理全部定时器与未发出的去抖状态
- 协议兼容:`source/state/message/action/ttl` 字段与 v0.1.0 完全一致,仅新增状态合并、健康探测与失败判定,不要求 UniPet 升级
## 🩺 排障
- **日志出现 `push failed: request timeout`,但 UniPet 明明在运行、curl 手测也通**
v0.2.0 已修复的已知误报:插件此前不消费 HTTP 响应,Node 19+ 默认 keep-alive 下 socket 在推送**成功**后保持空闲,`timeout`(socket 空闲超时)在约 2s 后触发,被误报为超时。修复后(`lib/push.js` 补 `res.resume()`)成功推送不会再出这条日志。若仍出现,说明跑的还是旧 bundle —— 完全重启 `dsh web` 再观察。
- 手工验证推送链路(与插件真实 payload 一致):
```bash
curl -sS -m 5 -w "\nHTTP=%{http_code} total=%{time_total}s\n" \
-X POST http://127.0.0.1:8768/api/pet/events \
-H 'Content-Type: application/json' \
--data '{"source":"dsh","state":"idle","message":"DSH ready","action":"update"}'
```
正常应返回 200(注意 `action` 固定为 `update`/`clear`,`idle` 等是 `state` 的值,写错会得到 400)。
## 🧪 开发
```bash
npm run check # 语法检查
npm test # Node 内置 test runner 跑单测
```
版本发布使用 `npm version minor`(preversion 会自动跑 check + test),版本号、CHANGELOG 与 git tag 在 `postversion` 自动推送保持一致。
## 📄 许可
MIT
Install
dsh plugin --profile web add github:ztyhehe/unipet-dsh
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install unipet-dsh from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.