dsh-vision-router 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -22
- package/README.zh.md +38 -22
- package/docs/doctor.md +19 -1
- package/docs/update-check.md +8 -6
- package/docs/update-check.zh-CN.md +8 -6
- package/entry.js +6 -4
- package/index.js +875 -128
- package/lib/client.js +939 -142
- package/lib/doctor-cli.js +35 -6
- package/lib/doctor.js +106 -2
- package/lib/file-logger.js +81 -2
- package/lib/replay-delegation.js +90 -0
- package/lib/self-update.js +135 -12
- package/lib/vision-resilience.js +395 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
18
|
-
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v1.
|
|
18
|
+
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v1.4.1"><img src="https://img.shields.io/badge/release-v1.4.1-5B4CF0?style=flat-square" alt="Release v1.4.1" /></a>
|
|
19
19
|
<a href="tests"><img src="https://img.shields.io/badge/verified-149%20tests-2EA44F?style=flat-square" alt="Verified: 149 tests" /></a>
|
|
20
20
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat-square" alt="License: MIT" /></a>
|
|
21
21
|
<a href="package.json"><img src="https://img.shields.io/badge/Node.js-%3E%3D22-339933?style=flat-square&logo=nodedotjs&logoColor=white" alt="Node.js >=22" /></a>
|
|
@@ -28,20 +28,26 @@
|
|
|
28
28
|
<p align="center">💬 <strong>QQ community group: 1105463028</strong></p>
|
|
29
29
|
|
|
30
30
|
> [!WARNING]
|
|
31
|
-
> 📌 **Announcement (v1.
|
|
31
|
+
> 📌 **Announcement (v1.4.1)**
|
|
32
32
|
>
|
|
33
|
-
> **v1.
|
|
34
|
-
>
|
|
35
|
-
> v1.2.3 fixes DSH Desktop's re-appearing first-run dialog: the onboarding "seen" flag and the model-guide step now persist in the profile settings file instead of origin-scoped `localStorage`, which a random per-launch port (`--port 0`) wiped on every boot (issue #78).
|
|
36
|
-
>
|
|
37
|
-
> v1.2.2 closed the last attachment-id gap — ids announced for images the host persisted itself (e.g. `read_image` re-uploads, `sha256:…`) now resolve in `vision_describe` and every pixel tool (issue #72) — stopped `vision_present` and other tool-result image blocks from ever locking a text-model session with `UNSUPPORTED_CONTENT` (issue #74; already-locked sessions heal after upgrading), and warned loudly when a stale sharp left over from a pre-v1.2 upgrade would break the pixel tools with `colourspace: parameter space not set` (issue #75).
|
|
38
|
-
>
|
|
39
|
-
> v1.2.1 hardened the pixel loop: all eleven pixel tools now accept uploaded-image attachment ids directly (no more `cannot read …/sha256:…` round trips), artifact filenames carry collision-free fingerprints, `vision_ground` retries degenerate boxes, the model guide replays fully from step 1 (leaving the settings first), and the settings card scrolls smoothly even with hundreds of models per provider.
|
|
33
|
+
> **v1.4.1 now supports** hardened vision failure handling — a single broken vision backend (401 / 429 / outage) can no longer stall a text turn: circuit breaking, shared task budgets and structured failure results keep DeepSeek conversations moving.
|
|
40
34
|
|
|
41
35
|
<p align="center">
|
|
42
36
|
<img src="assets/vision-demo.gif" width="640" alt="Demo: paste an image, the agent locates the send button with vision_ground / vision_crop / vision_pixel_diff and answers with coordinates" />
|
|
43
37
|
</p>
|
|
44
38
|
|
|
39
|
+
## Contents
|
|
40
|
+
|
|
41
|
+
- [Why this exists](#why-this-exists)
|
|
42
|
+
- [How it compares](#how-it-compares)
|
|
43
|
+
- [Quick start](#quick-start)
|
|
44
|
+
- [Highlights](#highlights)
|
|
45
|
+
- [How it works](#how-it-works)
|
|
46
|
+
- [Tools](#tools)
|
|
47
|
+
- [Configuration](#configuration)
|
|
48
|
+
- [Install and lifecycle](#install-and-lifecycle)
|
|
49
|
+
- [Troubleshooting](#troubleshooting)
|
|
50
|
+
|
|
45
51
|
## Why this exists
|
|
46
52
|
|
|
47
53
|
Most DSH vision plugins bridge images to DeepSeek as *text descriptions* — lossy, one-shot, and blind to pixels. This plugin keeps the **original pixels on the vision model's side** and DeepSeek on the reasoning side, and makes looking at an image an **ordinary tool call**:
|
|
@@ -72,24 +78,25 @@ Both are MIT-licensed and one command away. Pick this plugin when you want image
|
|
|
72
78
|
|
|
73
79
|
## Quick start
|
|
74
80
|
|
|
75
|
-
### 1. Install
|
|
81
|
+
### 1. Install the plugin
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
For normal npm/npx installs, installation is a single command:
|
|
78
84
|
|
|
79
85
|
```sh
|
|
80
86
|
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router
|
|
81
|
-
npx @deepseek-ai/dsh web
|
|
82
87
|
```
|
|
83
88
|
|
|
89
|
+
> [!NOTE]
|
|
90
|
+
> Third-party `dsh-web-plugin-manager` / `dshpm` **v0.4.2+** is also compatible: its quality gate now correctly allows `@deepseek-ai/schemastery` as a runtime dependency. The official DSH CLI above remains the recommended install path.
|
|
91
|
+
|
|
84
92
|
If you run DeepSeek Harness from a source checkout with pnpm, use the workspace script instead — `dsh` is not necessarily on your shell `PATH`:
|
|
85
93
|
|
|
86
94
|
```sh
|
|
87
95
|
cd deepseek-harness
|
|
88
96
|
pnpm dsh plugin --profile web add dsh-vision-router
|
|
89
|
-
pnpm dsh web
|
|
90
97
|
```
|
|
91
98
|
|
|
92
|
-
If you already installed the DSH CLI globally and `dsh` is on `PATH`, the shorter `dsh ...` form works too.
|
|
99
|
+
If you already installed the DSH CLI globally and `dsh` is on `PATH`, the shorter `dsh ...` form works too. After installation, start or reload DSH Web as you normally do.
|
|
93
100
|
|
|
94
101
|
> [!NOTE]
|
|
95
102
|
> If you install the plugin **into a Web process that was already running long-term**, let that DSH Web process reload once so the plugin bundle itself is discovered. After the plugin is loaded, adding/removing models or changing wrapper scope **hot-updates without further DSH restarts**.
|
|
@@ -169,7 +176,7 @@ Default `progressiveTools: false`: all eleven deep tools stay registered from pl
|
|
|
169
176
|
| `vision_ocr` | Text transcription: local tesseract (chi_sim+eng) first, vision model fallback | — |
|
|
170
177
|
| `vision_trace` | SVG vectorization (potrace posterization; icons/logos) | SVG |
|
|
171
178
|
| `vision_extract_foreground` | Cutout via border flood fill (uniform backgrounds) | transparent PNG |
|
|
172
|
-
| `vision_html_screenshot` | Screenshot a local HTML file (headless system Chrome) | PNG |
|
|
179
|
+
| `vision_html_screenshot` | Screenshot a local HTML file (headless system Chrome); `fullPage: true` captures the whole page and reports `pageHeight` | PNG |
|
|
173
180
|
| `vision_long_screenshot_ocr` | Long-screenshot transcription: overlapping chunks, tesseract first / vision model fallback, stitched Markdown | chunk PNGs + Markdown + manifest |
|
|
174
181
|
|
|
175
182
|
Formats are sniffed from magic bytes, so extensionless content-addressed attachment files work everywhere (no `.png` renaming needed).
|
|
@@ -187,6 +194,7 @@ vision_colors image="ref.png" top=8
|
|
|
187
194
|
vision_trace image="icon.png" steps=4
|
|
188
195
|
vision_extract_foreground image="logo.png"
|
|
189
196
|
vision_html_screenshot source="page.html" width=1200 height=720
|
|
197
|
+
vision_html_screenshot source="page.html" width=1200 height=720 fullPage=true
|
|
190
198
|
vision_long_screenshot_ocr image="chat-log.png" chunkHeight=1200 overlap=120
|
|
191
199
|
```
|
|
192
200
|
|
|
@@ -288,18 +296,23 @@ Everything is optional; defaults work out of the box. Edit via the Web card or a
|
|
|
288
296
|
|
|
289
297
|
### Install
|
|
290
298
|
|
|
291
|
-
Normal npm/npx install:
|
|
299
|
+
Normal npm/npx install — one command:
|
|
292
300
|
|
|
293
301
|
```sh
|
|
294
302
|
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router
|
|
295
|
-
npx @deepseek-ai/dsh --profile web --dump-config | grep vision-router
|
|
296
303
|
```
|
|
297
304
|
|
|
298
305
|
From a DeepSeek Harness source checkout:
|
|
299
306
|
|
|
300
307
|
```sh
|
|
301
308
|
pnpm dsh plugin --profile web add dsh-vision-router
|
|
302
|
-
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Optional verification:
|
|
312
|
+
|
|
313
|
+
```sh
|
|
314
|
+
npx @deepseek-ai/dsh --profile web --dump-config | grep vision-router
|
|
315
|
+
# source checkout: pnpm dsh --profile web --dump-config | grep vision-router
|
|
303
316
|
```
|
|
304
317
|
|
|
305
318
|
When first adding the plugin to an already long-lived Web profile, let that Web process reload the plugin bundle; the host discovers the browser bundle through `dsh.client` at startup. **After the plugin is loaded, model-catalog and wrapper-scope changes hot-update and do not require a restart.**
|
|
@@ -316,14 +329,17 @@ Set it back to `false` to re-enable. Unloading removes the wrapper routes, tools
|
|
|
316
329
|
### Upgrade
|
|
317
330
|
|
|
318
331
|
```sh
|
|
319
|
-
# normal npm/npx install
|
|
320
|
-
|
|
332
|
+
# normal npm/npx install — install the version you want explicitly; a bare
|
|
333
|
+
# `update` is silently held back for releases younger than 24h (pnpm v11)
|
|
334
|
+
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router@<version>
|
|
321
335
|
|
|
322
336
|
# DeepSeek Harness source checkout
|
|
323
|
-
pnpm dsh plugin --profile web
|
|
337
|
+
pnpm dsh plugin --profile web add dsh-vision-router@<version>
|
|
324
338
|
```
|
|
325
339
|
|
|
326
|
-
Settings live in the profile's settings provider and survive upgrades.
|
|
340
|
+
Settings live in the profile's settings provider and survive upgrades. The settings card's one-click update installs the registry-confirmed version explicitly and verifies the installed manifest afterwards — it never reports success on a package-manager exit code alone.
|
|
341
|
+
|
|
342
|
+
> **A fresh release does not take effect (`downloaded 0` / `added 0`):** pnpm v11 holds versions younger than 24h back; install the target version explicitly as above (pnpm auto-exempts it), or `npx dsh-vision-router repair` fixes the stale version-pinned profile exemption so updates take effect immediately.
|
|
327
343
|
|
|
328
344
|
> **Upgrading from a pre-bundle-patch install (v0.x):** the package now mounts
|
|
329
345
|
> itself through its own bundle patch, so a leftover manual row in
|
package/README.zh.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
18
|
-
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v1.
|
|
18
|
+
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v1.4.1"><img src="https://img.shields.io/badge/release-v1.4.1-5B4CF0?style=flat-square" alt="Release v1.4.1" /></a>
|
|
19
19
|
<a href="tests"><img src="https://img.shields.io/badge/verified-149%20tests-2EA44F?style=flat-square" alt="Verified: 149 tests" /></a>
|
|
20
20
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat-square" alt="License: MIT" /></a>
|
|
21
21
|
<a href="package.json"><img src="https://img.shields.io/badge/Node.js-%3E%3D22-339933?style=flat-square&logo=nodedotjs&logoColor=white" alt="Node.js >=22" /></a>
|
|
@@ -28,20 +28,26 @@
|
|
|
28
28
|
<p align="center">💬 <strong>QQ 用户交流群:1105463028</strong></p>
|
|
29
29
|
|
|
30
30
|
> [!WARNING]
|
|
31
|
-
> 📌 **公告(v1.
|
|
31
|
+
> 📌 **公告(v1.4.1)**
|
|
32
32
|
>
|
|
33
|
-
> **v1.
|
|
34
|
-
>
|
|
35
|
-
> v1.2.3 现已支持:修复 DSH Desktop 每次启动都重复弹出首次引导的问题——引导「已读」标记与模型引导步骤改存 profile 设置文件(不再依赖按 origin 隔离、每次随机端口重启即清零的 `localStorage`)(issue #78)。
|
|
36
|
-
>
|
|
37
|
-
> v1.2.2 现已支持:补上最后一处附件 ID 缺口——宿主 `read_image` 回挂图片公布的 `sha256:…` ID 现在可被 `vision_describe` 与全部像素工具解析(issue #72);`vision_present` 等工具结果里的图像块不再把文本模型会话锁死在 `UNSUPPORTED_CONTENT`(issue #74,已锁死的历史会话升级后自动修复);检测到 v1.1.x 升级残留的旧版 sharp 时明确告警,把玄学的 `colourspace` 报错变成一眼可见的修复指引(issue #75)。
|
|
38
|
-
>
|
|
39
|
-
> v1.2.1 加固像素闭环:十一个像素工具可直接接受上传图片的附件 ID(告别 `cannot read …/sha256:…` 的绕路),产物文件名带指纹不再互相覆盖,`vision_ground` 对退化框自动重试,模型引导支持从第 1 步完整重放(先退出设置页),设置卡片在数百模型目录下滚动依然流畅。
|
|
33
|
+
> **v1.4.1 现已支持**:视觉失败链加固——单个视觉后端(401 / 429 / 故障)不再拖垮文本对话;熔断、共享任务预算与结构化失败结果让对话始终顺畅继续。
|
|
40
34
|
|
|
41
35
|
<p align="center">
|
|
42
36
|
<img src="assets/vision-demo.gif" width="640" alt="演示:粘贴图片,Agent 用 vision_ground / vision_crop / vision_pixel_diff 定位发送按钮并给出坐标" />
|
|
43
37
|
</p>
|
|
44
38
|
|
|
39
|
+
## 目录
|
|
40
|
+
|
|
41
|
+
- [为什么做这个](#为什么做这个)
|
|
42
|
+
- [对比同类插件](#对比同类插件)
|
|
43
|
+
- [快速开始](#快速开始)
|
|
44
|
+
- [亮点](#亮点)
|
|
45
|
+
- [工作原理](#工作原理)
|
|
46
|
+
- [工具](#工具)
|
|
47
|
+
- [配置项](#配置项)
|
|
48
|
+
- [安装与生命周期](#安装与生命周期)
|
|
49
|
+
- [故障排查](#故障排查)
|
|
50
|
+
|
|
45
51
|
## 为什么做这个
|
|
46
52
|
|
|
47
53
|
大多数 DSH 视觉插件把图片“翻译”成一段文字描述再喂给 DeepSeek——有损、一次性、看不见像素。本插件把**原图像素留在视觉模型侧**、把推理留在 DeepSeek 侧,并把“看图”变成一次**普通的工具调用**:
|
|
@@ -72,24 +78,25 @@
|
|
|
72
78
|
|
|
73
79
|
## 快速开始
|
|
74
80
|
|
|
75
|
-
### 1.
|
|
81
|
+
### 1. 安装插件
|
|
76
82
|
|
|
77
|
-
普通 npm / npx
|
|
83
|
+
普通 npm / npx 安装只需要一条命令:
|
|
78
84
|
|
|
79
85
|
```sh
|
|
80
86
|
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router
|
|
81
|
-
npx @deepseek-ai/dsh web
|
|
82
87
|
```
|
|
83
88
|
|
|
89
|
+
> [!NOTE]
|
|
90
|
+
> 第三方 `dsh-web-plugin-manager` / `dshpm` **v0.4.2+** 现已兼容:其质量门已正确放行作为运行时依赖的 `@deepseek-ai/schemastery`。上面的官方 DSH CLI 仍是推荐安装方式。
|
|
91
|
+
|
|
84
92
|
如果你是从 DeepSeek Harness 源码仓库通过 pnpm 运行,`dsh` 不一定在系统 `PATH` 里,请改用工作区脚本:
|
|
85
93
|
|
|
86
94
|
```sh
|
|
87
95
|
cd deepseek-harness
|
|
88
96
|
pnpm dsh plugin --profile web add dsh-vision-router
|
|
89
|
-
pnpm dsh web
|
|
90
97
|
```
|
|
91
98
|
|
|
92
|
-
如果你已经全局安装 DSH CLI,并且终端里能直接执行 `dsh`,也可以继续使用较短的 `dsh ...`
|
|
99
|
+
如果你已经全局安装 DSH CLI,并且终端里能直接执行 `dsh`,也可以继续使用较短的 `dsh ...` 写法。安装完成后,按你平时的方式启动或重新加载 DSH Web 即可。
|
|
93
100
|
|
|
94
101
|
> [!NOTE]
|
|
95
102
|
> 如果你是把插件**首次安装进一个已经长期运行的 Web 进程**,需要让 DSH Web 进程重新加载一次插件本体。插件加载完成后,新增/删除模型、修改自动识图包装范围都会**热更新,无需再重启 DSH**。
|
|
@@ -169,7 +176,7 @@ Agent 仅根据参考图复刻 UI,再用 `vision_pixel_diff` 验证最终结
|
|
|
169
176
|
| `vision_ocr` | 文字转写:本地 tesseract(中英)优先,视觉模型兜底 | — |
|
|
170
177
|
| `vision_trace` | SVG 矢量化(potrace 分色;图标/logo) | SVG |
|
|
171
178
|
| `vision_extract_foreground` | 边界洪泛抠图(纯色背景) | 透明 PNG |
|
|
172
|
-
| `vision_html_screenshot` | 给本地 HTML 文件截图(无头系统 Chrome
|
|
179
|
+
| `vision_html_screenshot` | 给本地 HTML 文件截图(无头系统 Chrome);`fullPage: true` 截整页并返回 `pageHeight` | PNG |
|
|
173
180
|
| `vision_long_screenshot_ocr` | 长截图转写:重叠分片,tesseract 优先 / 视觉模型回退,按序拼接 Markdown | 分片 PNG + Markdown + manifest |
|
|
174
181
|
|
|
175
182
|
图片格式按**魔数识别**,无扩展名的内容寻址附件文件也能直接用(不用再复制成 `.png`)。
|
|
@@ -187,6 +194,7 @@ vision_colors image="ref.png" top=8
|
|
|
187
194
|
vision_trace image="icon.png" steps=4
|
|
188
195
|
vision_extract_foreground image="logo.png"
|
|
189
196
|
vision_html_screenshot source="page.html" width=1200 height=720
|
|
197
|
+
vision_html_screenshot source="page.html" width=1200 height=720 fullPage=true
|
|
190
198
|
vision_long_screenshot_ocr image="chat-log.png" chunkHeight=1200 overlap=120
|
|
191
199
|
```
|
|
192
200
|
|
|
@@ -288,18 +296,23 @@ Web 配置页在 **设置 → 插件 → 插件配置** 下注册「视觉路由
|
|
|
288
296
|
|
|
289
297
|
### 安装
|
|
290
298
|
|
|
291
|
-
普通 npm / npx
|
|
299
|
+
普通 npm / npx 安装——一条命令:
|
|
292
300
|
|
|
293
301
|
```sh
|
|
294
302
|
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router
|
|
295
|
-
npx @deepseek-ai/dsh --profile web --dump-config | grep vision-router
|
|
296
303
|
```
|
|
297
304
|
|
|
298
305
|
从 DeepSeek Harness 源码仓库运行:
|
|
299
306
|
|
|
300
307
|
```sh
|
|
301
308
|
pnpm dsh plugin --profile web add dsh-vision-router
|
|
302
|
-
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
可选验证:
|
|
312
|
+
|
|
313
|
+
```sh
|
|
314
|
+
npx @deepseek-ai/dsh --profile web --dump-config | grep vision-router
|
|
315
|
+
# 源码仓库:pnpm dsh --profile web --dump-config | grep vision-router
|
|
303
316
|
```
|
|
304
317
|
|
|
305
318
|
首次把插件装进已经长期运行的 Web profile 时,需要让 Web 进程重新加载插件本体;宿主在启动时通过 `dsh.client` 声明发现浏览器端包。**插件加载完成后,模型目录与包装范围的变化会热更新,不需要为这些变化重启。**
|
|
@@ -316,14 +329,17 @@ pnpm dsh --profile web --dump-config | grep vision-router
|
|
|
316
329
|
### 升级
|
|
317
330
|
|
|
318
331
|
```sh
|
|
319
|
-
# 普通 npm / npx 安装
|
|
320
|
-
|
|
332
|
+
# 普通 npm / npx 安装 —— 显式安装目标版本;裸 `update` 会被 pnpm v11
|
|
333
|
+
# 静默拦下发布不足 24 小时的新版本
|
|
334
|
+
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router@<版本号>
|
|
321
335
|
|
|
322
336
|
# DeepSeek Harness 源码仓库
|
|
323
|
-
pnpm dsh plugin --profile web
|
|
337
|
+
pnpm dsh plugin --profile web add dsh-vision-router@<版本号>
|
|
324
338
|
```
|
|
325
339
|
|
|
326
|
-
设置存放在 profile
|
|
340
|
+
设置存放在 profile 的设置提供方里,升级不丢失。设置卡里的一键更新会自动显式安装 registry 已确认的版本,并在命令结束后核对实际安装版本——绝不只凭包管理器退出码就报成功。
|
|
341
|
+
|
|
342
|
+
> **新版本一直不生效(`downloaded 0` / `added 0`):** pnpm v11 会拦下发布不足 24 小时的版本;按上面方式显式安装目标版本(pnpm 会自动写入豁免),或运行 `npx dsh-vision-router repair` 修复过期的带版本号豁免条目后,更新立即生效。
|
|
327
343
|
|
|
328
344
|
> **从 bundle 补丁之前(v0.x)升级:** 现在插件由自带的 bundle 补丁自动挂载,
|
|
329
345
|
> 若 `~/.dsh/profiles/<profile>/cordis.patch.yml` 里还残留旧版手动行,会与之
|
package/docs/doctor.md
CHANGED
|
@@ -32,7 +32,7 @@ To inspect only the Web profile:
|
|
|
32
32
|
npx dsh-vision-router doctor --profile web
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
The command locates the DSH home (`$DSH_HOME` when set, otherwise `~/.dsh`), scans profile `package.json` files, reports UTF-8 BOM bytes, validates the JSON after ignoring a leading BOM for diagnosis,
|
|
35
|
+
The command locates the DSH home (`$DSH_HOME` when set, otherwise `~/.dsh`), scans profile `package.json` files, reports UTF-8 BOM bytes, validates the JSON after ignoring a leading BOM for diagnosis, reports whether `dsh-vision-router` is present as a profile dependency and bundle layer, and flags version-pinned `minimumReleaseAgeExclude` entries in the profile's `pnpm-workspace.yaml` that would hold back the next release.
|
|
36
36
|
|
|
37
37
|
## Repair the UTF-8 BOM startup failure
|
|
38
38
|
|
|
@@ -50,3 +50,21 @@ npx dsh-vision-router repair --profile web
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
`repair` removes only the three-byte UTF-8 BOM prefix (`EF BB BF`) when it is present, then validates the remaining JSON. It does not reformat, regenerate, or otherwise rewrite the profile contents. If JSON is still invalid for another reason, the command reports that and stops rather than guessing a repair.
|
|
53
|
+
|
|
54
|
+
## Repair a stale release-age exemption (the "update does nothing" gate)
|
|
55
|
+
|
|
56
|
+
pnpm v11 defaults `minimumReleaseAge` to 1440 minutes: a version published less than 24 hours ago is not resolved, so `dsh plugin update` silently keeps the previous version and prints `downloaded 0 / added 0`. An exemption entry that pins a version — `dsh-vision-router@1.2.0` — only exempts that one version and goes stale on the next release, which is why "a new release is out but the update does nothing" keeps recurring.
|
|
57
|
+
|
|
58
|
+
The doctor flags version-pinned entries for `dsh-vision-router` and the `@deepseek-ai/*` host packages:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
✗ web — … — release-age exemption version-pinned (dsh-vision-router@1.2.0) — releases younger than 24h will not be picked up
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Run:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
npx dsh-vision-router repair --profile web
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
to rewrite them to bare names (`dsh-vision-router`, `@deepseek-ai/*`), which exempt every future version, so upgrades take effect immediately again. Unrelated entries and the rest of the file are left untouched.
|
package/docs/update-check.md
CHANGED
|
@@ -18,25 +18,27 @@ DSH and the plugin may have been launched through different paths, including `np
|
|
|
18
18
|
When an update is available, the plugin inspects the CLI entry of the current process. One-click update is enabled only when that entry can be traced to a real `@deepseek-ai/dsh` package and can be executed safely by the current Node runtime. In that case Vision Router runs the documented DSH updater through the **same DSH CLI that is already hosting the plugin**:
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
|
-
dsh plugin --profile <current-profile>
|
|
21
|
+
dsh plugin --profile <current-profile> add dsh-vision-router@<latest>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
The
|
|
24
|
+
The registry-confirmed target version is installed explicitly rather than through a bare `update`. This matters because pnpm 11 applies `minimumReleaseAge` (default 1440 minutes): a plain `pnpm update` silently keeps the current version while every candidate release is younger than 24h and still exits 0 ("Already up to date") — a false-success update that leaves the old version running after restart. `add <name>@<version>` installs the confirmed release (pnpm auto-exempts the requested version from the policy when needed). For non-registry installs (git/file/link/workspace specs) the updater keeps `update` semantics and only verifies the result.
|
|
25
|
+
|
|
26
|
+
The subprocess uses `execFile` with `shell: false`; no shell command is constructed from browser input. The update endpoint also requires a process-local token returned by the same-origin update-check endpoint. After the updater exits, the plugin reads the `dsh-vision-router` manifest under the profile's `node_modules` and verifies that the installed version actually reached the target — **a zero exit code alone is never reported as success**. Only a verified update asks the user to restart DSH so the new plugin bundle is loaded.
|
|
25
27
|
|
|
26
28
|
If the CLI cannot be verified — for example a raw TypeScript source entry that needs a workspace-specific loader — the one-click button is not offered. This commonly applies to a DSH source checkout launched with `pnpm dsh`: version checking still works, but updating remains under the source workspace's own pnpm workflow. The card keeps the version information and release-notes link and tells the user to update through their original DSH installation path instead.
|
|
27
29
|
|
|
28
30
|
## Manual recovery
|
|
29
31
|
|
|
30
|
-
If automatic update is unavailable, the version check fails, or a one-click update fails, the settings card still shows direct Project/Releases links and a manual command. For a DeepSeek Harness source checkout run:
|
|
32
|
+
If automatic update is unavailable, the version check fails, or a one-click update fails, the settings card still shows direct Project/Releases links and a manual command. When a newer version is known, the shown commands install that version explicitly, which bypasses the release-age withholding described above. For a DeepSeek Harness source checkout run:
|
|
31
33
|
|
|
32
34
|
```sh
|
|
33
|
-
pnpm dsh plugin --profile web
|
|
35
|
+
pnpm dsh plugin --profile web add dsh-vision-router@<latest>
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
For normal npm/npx DSH usage run:
|
|
37
39
|
|
|
38
40
|
```sh
|
|
39
|
-
npx @deepseek-ai/dsh plugin --profile web
|
|
41
|
+
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router@<latest>
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
The settings card substitutes the active profile when it can determine one.
|
|
44
|
+
The settings card substitutes the active profile when it can determine one. If the version still does not change after an update command, check the profile's `pnpm-workspace.yaml` for a version-pinned `minimumReleaseAgeExclude` entry — `npx dsh-vision-router repair` rewrites stale pins to bare names so future releases resolve again (see `docs/doctor.md`).
|
|
@@ -18,25 +18,27 @@ Vision Router 会检查是否有新的已发布版本;当当前运行中的 DS
|
|
|
18
18
|
发现新版本后,插件会检查当前进程真正使用的 DSH CLI 入口。只有该入口能够向上验证到真实的 `@deepseek-ai/dsh` 包,并且可以由当前 Node 运行时安全执行时,设置卡才显示“一键更新”。此时调用的不是某个猜出来的包管理器,而是**当前正在托管插件的同一套 DSH CLI**:
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
|
-
dsh plugin --profile <当前 profile>
|
|
21
|
+
dsh plugin --profile <当前 profile> add dsh-vision-router@<最新版>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
这里会**显式安装 registry 已确认的目标版本**,而不是裸 `update`。原因是 pnpm 11 默认启用 `minimumReleaseAge`(1440 分钟):当候选新版本发布不足 24 小时时,裸 `pnpm update` 会静默保留当前版本并仍然以退出码 0 结束(输出 “Already up to date”)——这就是“点了更新、提示成功、重启后版本没变”的假成功。`add <包名>@<版本>` 会安装确认过的发布版(pnpm 需要时会自动为新版本写入策略豁免)。对于非 registry 安装(git / file / link / workspace 规格),更新器保持 `update` 语义、只校验结果。
|
|
25
|
+
|
|
26
|
+
子进程通过 `execFile` 且 `shell: false` 启动,不会把浏览器输入拼成 shell 命令。更新接口还要求由同源更新检查接口返回的本进程临时 token,避免网页跨站请求直接触发更新。更新命令退出后,插件会读取 profile `node_modules` 下 `dsh-vision-router` 的清单并核对安装版本确实达到目标——**仅凭退出码 0 永远不会被当作成功**。只有校验通过的更新才会提示用户重启 DSH,让新插件 bundle 真正加载。
|
|
25
27
|
|
|
26
28
|
若无法可靠验证当前 CLI——例如直接运行需要 workspace 专用 loader 的 TypeScript 源码入口——就不会显示一键更新按钮。**源码仓库里通过 `pnpm dsh` 启动通常属于这种情况:版本检查仍然可以正常工作,只是一键更新继续交给源码工作区自己的 pnpm 流程。** 此时仍会显示当前/最新版本和 Release Notes,并提示用户沿用原来的 DSH 安装方式手动更新。
|
|
27
29
|
|
|
28
30
|
## 手动兜底
|
|
29
31
|
|
|
30
|
-
如果自动更新不可用、版本检查失败,或一键更新失败,设置卡仍会直接显示项目主页 / Releases
|
|
32
|
+
如果自动更新不可用、版本检查失败,或一键更新失败,设置卡仍会直接显示项目主页 / Releases 入口和可执行的手动命令。发现新版本时,显示的命令会带版本号显式安装,从而绕过上面描述的发布龄拦截。DeepSeek Harness 源码仓库通过 pnpm 启动时使用:
|
|
31
33
|
|
|
32
34
|
```sh
|
|
33
|
-
pnpm dsh plugin --profile web
|
|
35
|
+
pnpm dsh plugin --profile web add dsh-vision-router@<最新版>
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
普通 npm / npx DSH 使用:
|
|
37
39
|
|
|
38
40
|
```sh
|
|
39
|
-
npx @deepseek-ai/dsh plugin --profile web
|
|
41
|
+
npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router@<最新版>
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
如果插件能识别当前 profile,设置页会把命令里的 `web` 自动替换成实际 profile
|
|
44
|
+
如果插件能识别当前 profile,设置页会把命令里的 `web` 自动替换成实际 profile。若执行后版本仍未变化,请检查 profile 的 `pnpm-workspace.yaml` 里是否有版本钉住的 `minimumReleaseAgeExclude` 条目——`npx dsh-vision-router repair` 会把过期的钉住条目改写为裸名,让后续新版本恢复正常解析(见 `docs/doctor.md`)。
|
package/entry.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import z from '@deepseek-ai/schemastery'
|
|
10
10
|
import * as core from './index.js'
|
|
11
11
|
import { installVisionRouterFileLogging } from './lib/file-logger.js'
|
|
12
|
+
import { contextWithDelegatedReplay } from './lib/replay-delegation.js'
|
|
12
13
|
|
|
13
14
|
// Schemastery object schemas expose set() as the supported way to replace a
|
|
14
15
|
// field schema. This mutates the Config object that index.js itself later uses
|
|
@@ -21,13 +22,14 @@ export const Config = core.Config
|
|
|
21
22
|
|
|
22
23
|
// Defense in depth for direct/programmatic callers that invoke apply() without
|
|
23
24
|
// first running the Cordis Config resolver: only an explicit true enables the
|
|
24
|
-
// schema-changing progressive mode. The wrapped context changes
|
|
25
|
-
//
|
|
26
|
-
//
|
|
25
|
+
// schema-changing progressive mode. The wrapped context changes logger plus a
|
|
26
|
+
// private llm view used only by Vision Router: wrapper -> delegate calls can
|
|
27
|
+
// restore adapter-owned replay identity without mutating the host LLM service.
|
|
27
28
|
export function apply(ctx, config = {}) {
|
|
28
29
|
const logging = installVisionRouterFileLogging(ctx)
|
|
30
|
+
const runtimeCtx = contextWithDelegatedReplay(logging.ctx)
|
|
29
31
|
try {
|
|
30
|
-
const result = core.apply(
|
|
32
|
+
const result = core.apply(runtimeCtx, {
|
|
31
33
|
...config,
|
|
32
34
|
progressiveTools: config.progressiveTools === true,
|
|
33
35
|
})
|