Skip to content
dsh.fish
Bundle

@dsh-external/dsh-launcher

One-click start/restart for the DeepSeek Harness web service: /api/launcher/status and /api/launcher/restart.

Source
Nasbaye
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-launcher

DeepSeek Harness web profile 插件:一键重启服务 + 前端状态徽标 + 重启续聊 + 截断自动继续。

- `GET  /api/launcher/status` — 服务状态(JSON)
- `POST /api/launcher/restart` — 重启服务(返回 202,实际由后台 worker 完成:
  预检依赖 → 杀掉端口上的旧监听进程 → 等端口释放 → 重新拉起
  `node <dsh>/lib/bin.js web` → 健康确认)
- UI:会话头部(或新建会话模式选择器)旁的状态点,点击可确认重启;重启完成后页面自动刷新
- 重启前自动检测"正在进行"的会话,重启后向它们发送
  `因 DeepSeek Harness 重启导致对话中断,请继续`,让 agent 接着干活
- 模型输出撞到 token 上限被截断时(前端显示"已达到输出 token 上限")自动补发
  `继续`,让模型接续输出(带防循环保护)

## 目录结构

```
dsh-launcher/
├── lib/
│   ├── index.js            # 插件主体:状态/重启 API、状态点、续聊、截断自动继续
│   └── restart-worker.js   # 重启 worker:依赖预检、杀进程、拉起、健康确认
├── cordis.patch.yml        # 组合补丁(向 web profile 插入一行)
└── package.json
```

## 安装

```powershell
# 在 profile 里安装本插件(路径按实际位置调整)
pnpm --dir %USERPROFILE%\.dsh\profiles\web add file:D:/path/to/dsh-launcher
```

然后把 `@dsh-external/dsh-launcher` 加入
`%USERPROFILE%\.dsh\profiles\web\package.json` 的 `dsh.profile.bundles`:

```json
"dsh": {
  "profile": {
    "bundles": [ "...", "@dsh-external/dsh-launcher" ]
  }
}
```

完整重启 DeepSeek Harness 即生效(GUI 状态点 + API 立即可用)。

## 功能

### 1. 状态点与一键重启

- 状态点显示在会话头部的 Agent 预设标签("标准模式"等)右侧;新开会话页则显示在
  模式选择器旁。绿=在线,黄=重启中,红=离线。每 5 秒轮询。
- 点击状态点 → 确认 → `POST /api/launcher/restart`,worker 在后台完成重启。
- 重启完成后页面自动刷新一次(检测到后端离线并恢复后),确保拿到最新前端。

### 2. 重启 worker 的可靠性

`restart-worker.js` 自带三道保险:

| 保护 | 说明 |
|---|---|
| 依赖预检 | 重启前检查 `profiles/web/package.json` 的 bundles 是否都已安装(profile
  node_modules + 引擎嵌套 node_modules 两处);缺包先自动 `pnpm install`,装不上则
  **中止重启、旧服务继续跑** |
| 健康确认 | 拉起后轮询端口最多 90 秒,成功/失败写入 `dsh-web.log` |
| 无控制台弹窗 | worker 与子进程均使用 `windowsHide`,Windows 下不弹黑色窗口 |

日志以 `[launcher-worker ...]` 前缀写到 `dsh-web.log`。

### 3. 重启续聊(resume-after-restart)

重启前(调用 `restart()` 时)枚举所有 agent,按**未完成工作信号**筛选会话:

- `status === 'running'`(执行中,含等待子代理返回);
- `inbox.hasPending`(队列里还有待处理消息);
- `phase.kind === 'maintenance'`(正在压缩等维护操作)。

命中的会话 id 写入 `.dsh-launcher-resume.json`(一次性,消费即删);新进程启动后
通过引擎的 `sessions.prompt` 通道向每个会话发送一条用户消息
`因 DeepSeek Harness 重启导致对话中断,请继续` —— 与浏览器发消息完全同路径,
agent 会自动恢复并继续执行。失败自动重试(每会话最多 5 次,间隔 3 秒)。

### 4. 截断自动继续(auto-continue)

监听 `session/event`,命中 `turn/end` 且 `reason.kind === 'max-tokens'`(即前端
"已达到输出 token 上限,回答被截断"提示)时,自动向该会话发送用户消息 `继续`,
模型接着输出。防循环保护:

- 每会话连续自动"继续"最多 **3 次**;
- 同会话 5 秒冷却;
- 任何非 max-tokens 的轮次结束会重置计数;
- 只处理顶层会话(子代理暂不自动继续)。

日志:`[launcher] auto-continue #N sent to <sessionId>`。

## 日志

所有插件行为写入服务日志(默认 `D:\deepseekharness\dsh-web.log`):

- `[launcher-worker ...]` — 重启流程(预检/杀进程/拉起/健康确认)
- `[launcher ...]` — 续聊、自动继续、状态点相关

## 可选:Windows 无弹窗补丁(引擎侧)

本插件自身的子进程都带 `windowsHide`,但 DeepSeek Harness 引擎的
`dsh-subprocess-local` 默认未设置该项:当 web 服务以无控制台方式启动时,每次工具
调用(pwsh/bash 等)都会弹出可见控制台窗口。可在引擎文件中追加:

`dsh-subprocess-local/lib/index.js` 的 `spawn()` 选项里加 `windowsHide: true`
(两个 execFileSync 辅助调用同样加)。这是引擎侧补丁,随引擎更新可能丢失。

## License

MIT。

Install

dsh plugin --profile web add github:Nasbaye/dsh-launcher

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source