dsh-vision-router 2.0.0 → 2.1.0
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 +33 -16
- package/README.zh.md +34 -17
- package/cordis.patch.yml +19 -9
- package/docs/architecture/2x-contract-ledger.md +165 -0
- package/docs/architecture/compat-inventory.md +121 -0
- package/docs/architecture/dsh-compatibility-matrix.md +57 -0
- package/docs/architecture/dsh-support-window.md +50 -0
- package/docs/architecture/final-closure-audit.md +148 -0
- package/docs/architecture/p2-jobs-feasibility.md +94 -0
- package/docs/architecture/p3-compat-retirement.md +46 -0
- package/docs/architecture/p3-host-native-seams.md +43 -0
- package/docs/architecture/p3-native-recovery-evaluation.md +65 -0
- package/docs/architecture/runtime-boundaries.md +124 -0
- package/docs/releases/v2.0.1.md +17 -0
- package/docs/releases/v2.1.0-support-window.md +29 -0
- package/docs/releases/v2.1.0.md +83 -0
- package/entry.js +13 -307
- package/index.js +85 -352
- package/lib/abort-signal-compat.js +191 -0
- package/lib/adapter-update-coalescer.js +113 -29
- package/lib/adversarial-hardening.js +24 -9
- package/lib/artifact-boundary.js +16 -175
- package/lib/artifact-io.js +220 -0
- package/lib/artifact-retention.js +305 -53
- package/lib/catalog-corrections.js +6 -1
- package/lib/client-host-compat-prelude.js +249 -0
- package/lib/client-presentation-boundary.js +61 -3
- package/lib/client.js +71 -72
- package/lib/core-vision-surface.js +124 -0
- package/lib/depth-guidance.js +114 -90
- package/lib/doctor-cli-p0.js +168 -0
- package/lib/doctor-cli.js +7 -0
- package/lib/doctor-vision-limits.js +72 -0
- package/lib/dsh-contract-compat.js +207 -39
- package/lib/dsh-host-capabilities.js +107 -0
- package/lib/dsh-support-window.js +48 -0
- package/lib/http-compat.js +22 -6
- package/lib/image-resource-governor.js +35 -10
- package/lib/legacy-core-vision-policy-bridge.js +25 -226
- package/lib/legacy-global-proxy-boundary.js +127 -0
- package/lib/live-model-client-prelude.js +0 -12
- package/lib/mixed-router.js +81 -81
- package/lib/public-entry.js +42 -4
- package/lib/runtime-composition.js +348 -0
- package/lib/runtime-i18n-boundary.js +683 -0
- package/lib/runtime-i18n-core-scope.js +56 -0
- package/lib/runtime-i18n-core.js +34 -0
- package/lib/runtime-i18n.js +121 -0
- package/lib/session-surface-policy.js +97 -0
- package/lib/session-vision-index.js +282 -0
- package/lib/session-vision-runtime.js +48 -0
- package/lib/settings-factory-lifecycle.js +144 -0
- package/lib/settings-ia-client-prelude.js +74 -2
- package/lib/settings-limit-client-prelude.js +110 -0
- package/lib/settings-native-card-layout.js +297 -0
- package/lib/settings-number-contract.js +29 -0
- package/lib/structured-flow-hardening.js +207 -76
- package/lib/tesseract-exec-compat.js +58 -32
- package/lib/update-check.js +17 -5
- package/lib/v2-settings-ia-integration.js +9 -4
- package/lib/vision-artifact-store.js +77 -0
- package/lib/vision-backend-runtime-policy.js +6 -2
- package/lib/vision-background-benchmark.js +130 -41
- package/lib/vision-background-failure-policy.js +70 -0
- package/lib/vision-background-stop-store.js +54 -9
- package/lib/vision-capability-benchmark-client.js +57 -66
- package/lib/vision-capability-benchmark-presentation.js +97 -0
- package/lib/vision-capability-benchmark-service.js +3 -3
- package/lib/vision-execution-order-apply.js +61 -0
- package/lib/vision-execution-order-plan.js +64 -0
- package/lib/vision-execution-order.js +38 -0
- package/lib/vision-limit-diagnostics.js +202 -0
- package/lib/vision-product-presentation.js +284 -0
- package/lib/vision-provider-transport.js +197 -0
- package/lib/vision-resilience.js +87 -45
- package/lib/vision-routing-evidence.js +366 -0
- package/lib/vision-routing-runtime.js +278 -0
- package/lib/vision-tool-runtime-boundary.js +27 -21
- package/lib/vision-turn-budget-client-prelude.js +9 -9
- package/lib/web/benchmark-panel.js +6 -0
- package/lib/web/diagnostics-panel.js +44 -0
- package/lib/web/index.js +60 -0
- package/lib/web/model-picker.js +22 -0
- package/lib/web/onboarding.js +6 -0
- package/lib/web/product-state.js +59 -0
- package/lib/web/remote-settings-client.js +8 -0
- package/lib/web/routing-section.js +6 -0
- package/lib/web/settings-controller.js +6 -0
- package/lib/web-capability-boundary.js +65 -9
- package/lib/windows-screenshot-dpi-compat.js +148 -0
- package/package.json +14 -6
- package/lib/vision-capability-shadow.js +0 -576
package/README.md
CHANGED
|
@@ -10,18 +10,28 @@
|
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://awesome-dsh-plugin.com"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="awesome · DSH plugin" /></a>
|
|
13
|
-
<a href="https://github.com/zp-home/dsh-recommend"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fzp-home%2Fdsh-recommend%2Fmain%2Fdata%2Fbadges%2Fysr666__dsh-vision-router.certified.json&style=flat-square" alt="dsh-recommend 🏅
|
|
14
|
-
<a href="https://
|
|
15
|
-
<a href="https://
|
|
13
|
+
<a href="https://github.com/zp-home/dsh-recommend"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fzp-home%2Fdsh-recommend%2Fmain%2Fdata%2Fbadges%2Fysr666__dsh-vision-router.certified.json&style=flat-square" alt="dsh-recommend 🏅 certified" /></a>
|
|
14
|
+
<a href="https://www.dshbase.com/plugins/dsh-vision-router/"><img src="https://img.shields.io/badge/dshbase-install--tested-2EA44F?style=flat-square" alt="dshbase install-tested" /></a>
|
|
15
|
+
<a href="https://github.com/SoberReport-AI/DeepGuard/blob/main/reports/dsh-vision-router/2.0.1/39c8f2b2d69aa398418fd6c8ab40b691a92a1a3d.json"><img src="https://img.shields.io/badge/DeepGuard-audit%20clean-2EA44F?style=flat-square" alt="DeepGuard audit clean" /></a>
|
|
16
|
+
<a href="https://whyihaveyou.github.io/dsh-suite/"><img src="https://img.shields.io/badge/featured%20on-dsh--suite-4d6bfe?style=flat-square" alt="featured on dsh-suite" /></a>
|
|
16
17
|
</p>
|
|
17
18
|
|
|
18
19
|
<p align="center">
|
|
19
|
-
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v2.
|
|
20
|
+
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v2.1.0"><img src="https://img.shields.io/badge/release-v2.1.0-5B4CF0?style=flat-square" alt="Release v2.1.0" /></a>
|
|
20
21
|
<a href="tests"><img src="https://img.shields.io/badge/verified-Node%2022%20%2B%2024-2EA44F?style=flat-square" alt="Verified: Node 22 + 24" /></a>
|
|
21
22
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat-square" alt="License: MIT" /></a>
|
|
22
23
|
<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>
|
|
23
24
|
<img src="https://img.shields.io/badge/runtime-no%20Python-8A2BE2?style=flat-square" alt="No Python" />
|
|
24
|
-
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<sub>Ecosystem:</sub>
|
|
29
|
+
<a href="https://dshplugin.app/plugins/dsh-vision-router">DSHPlugin.app</a> ·
|
|
30
|
+
<a href="https://github.com/diegosouzapw/awesome-omni-dsh-plugins">Awesome Omni DSH Plugins</a> ·
|
|
31
|
+
<a href="https://dshpluginhub.ai/plugins/dsh-vision-router">dshpluginhub.ai</a> ·
|
|
32
|
+
<a href="https://www.dsh.plus/en/plugins/dsh-vision-router/">dsh.plus</a> ·
|
|
33
|
+
<a href="https://dshplugins.ai/">dshplugins.ai</a> ·
|
|
34
|
+
<a href="https://dshmarket.com/p/ysr666/dsh-vision-router/">dsh-market</a>
|
|
25
35
|
</p>
|
|
26
36
|
|
|
27
37
|
<p align="center">English · <a href="README.zh.md">中文</a></p>
|
|
@@ -29,9 +39,9 @@
|
|
|
29
39
|
<p align="center">💬 <strong>QQ community group: 1105463028</strong></p>
|
|
30
40
|
|
|
31
41
|
> [!WARNING]
|
|
32
|
-
> 📌 **Announcement (v2.
|
|
42
|
+
> 📌 **Announcement (v2.1.0)**
|
|
33
43
|
>
|
|
34
|
-
> **v2.
|
|
44
|
+
> **v2.1.0:** Native five-card Settings, explicit Vision mode, runtime i18n, hardened capability routing/benchmarks, and the DSH rc.8 support floor. [What’s new →](docs/releases/v2.1.0.md)
|
|
35
45
|
|
|
36
46
|
<p align="center">
|
|
37
47
|
<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" />
|
|
@@ -54,7 +64,7 @@
|
|
|
54
64
|
|
|
55
65
|
## Why this exists
|
|
56
66
|
|
|
57
|
-
Most DSH vision plugins bridge images to DeepSeek as *text descriptions* — lossy, one-shot, and blind to pixels. This plugin keeps the **
|
|
67
|
+
Most DSH vision plugins bridge images to DeepSeek as *text descriptions* — lossy, one-shot, and blind to pixels. This plugin keeps the **Host-canonical image pixels on the vision model's side** and DeepSeek on the reasoning side, and makes looking at an image an **ordinary tool call**:
|
|
58
68
|
|
|
59
69
|
- **One command install.** The package ships its own composition patch (`dsh.bundle.patch`): `dsh plugin add` wires the row, the admission wrapper and the attachment limits automatically — zero manual file edits. Taking over the official DeepSeek route is an optional setting (stealth mode, off by default).
|
|
60
70
|
- **Free by default.** Vision tools end with a five-model OVHcloud anonymous fallback: no account, no key, 2 requests/minute per IP per model, roughly 10 RPM in theory across independent buckets. User-provided vision models run first.
|
|
@@ -67,11 +77,14 @@ Most DSH vision plugins bridge images to DeepSeek as *text descriptions* — los
|
|
|
67
77
|
|
|
68
78
|
**One-line take**: most dsh vision plugins turn images into *text descriptions* for DeepSeek
|
|
69
79
|
(description bridge — lossy); this plugin hands the image turn *straight to a vision model*
|
|
70
|
-
(routing bridge — pixel-
|
|
80
|
+
(routing bridge — pixel-level), with a built-in keyless free fallback.
|
|
81
|
+
|
|
82
|
+
> [!NOTE]
|
|
83
|
+
> On DSH 0.1.2-alpha.1+, attachments remain Host-owned. Vision Router consumes the Host-persisted canonical image: clean single-frame 8-bit sRGB/sRGBA images inside the configured normalization limits can pass through byte-identically, while images that need orientation, color-space, metadata, animation, or size normalization may be re-encoded. Pixel tools therefore promise the Host-canonical raster, not preservation of the uploader's original encoded bytes.
|
|
71
84
|
|
|
72
85
|
| | Manual model switching | MCP vision bridge | dsh-vision-router |
|
|
73
86
|
|---|---|---|---|
|
|
74
|
-
|
|
|
87
|
+
| Image pixels | ✅ available (when switched) | ❌ text description only | ✅ Host-canonical raster, on the image turn |
|
|
75
88
|
| Automatic | ❌ | ✅ | ✅ |
|
|
76
89
|
| Daily model untouched | ❌ (whole session swapped) | ✅ | ✅ |
|
|
77
90
|
| Provider failure recovery | ❌ | ❌ | ✅ fallback chains |
|
|
@@ -83,7 +96,7 @@ Most DSH vision plugins bridge images to DeepSeek as *text descriptions* — los
|
|
|
83
96
|
|
|
84
97
|
| Project | Approach | What this plugin adds |
|
|
85
98
|
|---|---|---|
|
|
86
|
-
| [dsh-vision-sidecar](https://github.com/121103qwq/dsh-vision-sidecar) | Pre-describes images with an external VLM; the description joins the session as a message to DeepSeek; LLM7.io anonymous endpoint by default (OVHcloud listed as a no-key alternative) | Description bridge; this plugin adds
|
|
99
|
+
| [dsh-vision-sidecar](https://github.com/121103qwq/dsh-vision-sidecar) | Pre-describes images with an external VLM; the description joins the session as a message to DeepSeek; LLM7.io anonymous endpoint by default (OVHcloud listed as a no-key alternative) | Description bridge; this plugin adds image routing, with `vision_describe` covering descriptions on demand |
|
|
87
100
|
| [dsh-vision-proxy](https://github.com/Flyvhidbwo/dsh-vision-proxy) | Wraps a provider route and transcribes images into text in the request stream | Transcription bridge; this plugin wraps no provider — it rewrites routing through `agent/request` waterfalls |
|
|
88
101
|
| [dsh-vision-provider](https://github.com/libinyam/dsh-vision-provider) | Registers `DeepSeek + Vision` combined routes: images are described by the chosen vision model before reaching DeepSeek | Two-model bridge idea; this plugin adds automatic routing, fallback chains and tools on top |
|
|
89
102
|
| [modlens](https://github.com/liustack/modlens) | The first dsh vision plugin; reuses local Claude Code/Codex/OpenCode/Pi logins as vision engines | Engine-reuse idea; this plugin ships its own provider chain and depends on no other local CLI |
|
|
@@ -199,7 +212,7 @@ Any of these channels can join the vision chain as an `httpProviders` entry (key
|
|
|
199
212
|
- **Original pixels, real answers.** The vision chain reads the image at original resolution (auto-downscaled only to protect latency/quota); the agent's question travels with the image, so answers are about *your* question, not a generic description.
|
|
200
213
|
- **Automatic failover with classified errors.** Region blocks, ToS filtering, 402 quota, 429 rate limits, context overflow, network failures — the chain walks providers one by one and only reports after all of them failed, with actionable advice. A 429 immediately advances to the next backend and opens a Retry-After-aware cooldown instead of sleeping inside the request.
|
|
201
214
|
- **Image memory.** Vision answers are cached by attachment content hash; later text turns substitute the recorded description (marked as untrusted evidence), so DeepSeek genuinely remembers earlier images without re-spending vision calls.
|
|
202
|
-
- **A verifiable pixel loop.** Reference → `vision_html_screenshot` → `vision_pixel_diff` (ratio +
|
|
215
|
+
- **A verifiable pixel loop.** Reference → `vision_html_screenshot` → `vision_pixel_diff` (ratio + worst 8×8-grid regions) → fix → repeat until the mismatch converges. UI restoration becomes measurable instead of eyeballed.
|
|
203
216
|
- **Stable tool schema.** All fourteen deep tools are registered from session start by default, avoiding a mid-conversation tool-list expansion that can invalidate long-context KV/prefix caches. `progressiveTools: true` remains an advanced boot-time opt-in; only then does `vision_activate` mount the tools on demand. See [`docs/progressive-tools-cache.md`](docs/progressive-tools-cache.md).
|
|
204
217
|
- **Selective proxy.** Only the configured vision provider hosts go through your local proxy; DeepSeek stays direct.
|
|
205
218
|
|
|
@@ -400,6 +413,7 @@ ollama pull qwen2.5vl
|
|
|
400
413
|
## Requirements
|
|
401
414
|
|
|
402
415
|
- DeepSeek Harness Web profile. Normal installs can use `npx @deepseek-ai/dsh ...`; source checkouts use `pnpm dsh ...`. A bare `dsh ...` command only works when the CLI is already on your shell `PATH`.
|
|
416
|
+
- **DSH Host support window:** DVR 2.1.x supports DSH `0.1.0-rc.8` (minimum), `0.1.1-rc.1` (previous released train), and current `0.1.1-rc.2`; DSH `0.1.2-alpha.4` is canary-only evidence. DVR 2.0.x was the final train with public support for rc.6/rc.7. See [DSH Host support window](docs/architecture/dsh-support-window.md).
|
|
403
417
|
- Node ≥ 22 (host side).
|
|
404
418
|
- No API key for the default free chain; a credential reference (`apiKeyEnv`) only for paid `httpProviders`.
|
|
405
419
|
- Chrome / Chromium / Edge is needed only for `vision_html_screenshot`; every other tool works without a browser.
|
|
@@ -573,8 +587,11 @@ Manual fallback: in VS Code, use “Save with Encoding” → `UTF-8` (without B
|
|
|
573
587
|
## Star History
|
|
574
588
|
|
|
575
589
|
<p align="center">
|
|
576
|
-
<
|
|
577
|
-
<
|
|
578
|
-
|
|
579
|
-
|
|
590
|
+
<a href="https://www.star-history.com/?repos=ysr666%2Fdsh-vision-router&type=date&legend=top-left">
|
|
591
|
+
<picture>
|
|
592
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=ysr666/dsh-vision-router&type=date&theme=dark&legend=top-left&sealed_token=bl3whaniTB54-d4wMda4a454thk48mT71wkNh8VrSD8OhCKWdBOOQpVKGUXzoEq4kx0_0jhQzEimHIqKAaGftFVV48sqgJ1niBfGy51AX5k_soGw_e7-5Nea6ZY5To0iz7jY9ORc5a_P5N6Qlfm32G2pdHf8_5dZeuHMn5NOZCyTgFcmq2eK1Jwg8ILe" />
|
|
593
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=ysr666/dsh-vision-router&type=date&legend=top-left&sealed_token=bl3whaniTB54-d4wMda4a454thk48mT71wkNh8VrSD8OhCKWdBOOQpVKGUXzoEq4kx0_0jhQzEimHIqKAaGftFVV48sqgJ1niBfGy51AX5k_soGw_e7-5Nea6ZY5To0iz7jY9ORc5a_P5N6Qlfm32G2pdHf8_5dZeuHMn5NOZCyTgFcmq2eK1Jwg8ILe" />
|
|
594
|
+
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=ysr666/dsh-vision-router&type=date&legend=top-left&sealed_token=bl3whaniTB54-d4wMda4a454thk48mT71wkNh8VrSD8OhCKWdBOOQpVKGUXzoEq4kx0_0jhQzEimHIqKAaGftFVV48sqgJ1niBfGy51AX5k_soGw_e7-5Nea6ZY5To0iz7jY9ORc5a_P5N6Qlfm32G2pdHf8_5dZeuHMn5NOZCyTgFcmq2eK1Jwg8ILe" width="100%" />
|
|
595
|
+
</picture>
|
|
596
|
+
</a>
|
|
580
597
|
</p>
|
package/README.zh.md
CHANGED
|
@@ -11,17 +11,27 @@
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://awesome-dsh-plugin.com"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="awesome · DSH plugin" /></a>
|
|
13
13
|
<a href="https://github.com/zp-home/dsh-recommend"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fzp-home%2Fdsh-recommend%2Fmain%2Fdata%2Fbadges%2Fysr666__dsh-vision-router.certified.json&style=flat-square" alt="dsh-recommend 🏅 精选认证" /></a>
|
|
14
|
-
<a href="https://
|
|
15
|
-
<a href="https://
|
|
14
|
+
<a href="https://www.dshbase.com/plugins/dsh-vision-router/"><img src="https://img.shields.io/badge/dshbase-install--tested-2EA44F?style=flat-square" alt="dshbase 实机安装验证" /></a>
|
|
15
|
+
<a href="https://github.com/SoberReport-AI/DeepGuard/blob/main/reports/dsh-vision-router/2.0.1/39c8f2b2d69aa398418fd6c8ab40b691a92a1a3d.json"><img src="https://img.shields.io/badge/DeepGuard-audit%20clean-2EA44F?style=flat-square" alt="DeepGuard 审计 clean" /></a>
|
|
16
|
+
<a href="https://whyihaveyou.github.io/dsh-suite/"><img src="https://img.shields.io/badge/featured%20on-dsh--suite-4d6bfe?style=flat-square" alt="dsh-suite 精选收录" /></a>
|
|
16
17
|
</p>
|
|
17
18
|
|
|
18
19
|
<p align="center">
|
|
19
|
-
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v2.
|
|
20
|
-
<a href="tests"><img src="https://img.shields.io/badge/verified-Node%2022%20%2B%2024-2EA44F?style=flat-square" alt="
|
|
21
|
-
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat-square" alt="
|
|
20
|
+
<a href="https://github.com/ysr666/dsh-vision-router/releases/tag/v2.1.0"><img src="https://img.shields.io/badge/release-v2.1.0-5B4CF0?style=flat-square" alt="Release v2.1.0" /></a>
|
|
21
|
+
<a href="tests"><img src="https://img.shields.io/badge/verified-Node%2022%20%2B%2024-2EA44F?style=flat-square" alt="已验证 Node 22 + 24" /></a>
|
|
22
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat-square" alt="MIT 许可证" /></a>
|
|
22
23
|
<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>
|
|
23
|
-
<img src="https://img.shields.io/badge/runtime-no%20Python-8A2BE2?style=flat-square" alt="
|
|
24
|
-
|
|
24
|
+
<img src="https://img.shields.io/badge/runtime-no%20Python-8A2BE2?style=flat-square" alt="无需 Python" />
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<sub>生态收录:</sub>
|
|
29
|
+
<a href="https://dshplugin.app/plugins/dsh-vision-router">DSHPlugin.app</a> ·
|
|
30
|
+
<a href="https://github.com/diegosouzapw/awesome-omni-dsh-plugins">Awesome Omni DSH Plugins</a> ·
|
|
31
|
+
<a href="https://dshpluginhub.ai/plugins/dsh-vision-router">dshpluginhub.ai</a> ·
|
|
32
|
+
<a href="https://www.dsh.plus/zh/plugins/dsh-vision-router/">dsh.plus</a> ·
|
|
33
|
+
<a href="https://dshplugins.ai/">dshplugins.ai</a> ·
|
|
34
|
+
<a href="https://dshmarket.com/p/ysr666/dsh-vision-router/">dsh-market</a>
|
|
25
35
|
</p>
|
|
26
36
|
|
|
27
37
|
<p align="center"><a href="README.md">English</a> · 中文</p>
|
|
@@ -29,9 +39,9 @@
|
|
|
29
39
|
<p align="center">💬 <strong>QQ 用户交流群:1105463028</strong></p>
|
|
30
40
|
|
|
31
41
|
> [!WARNING]
|
|
32
|
-
> 📌 **公告(v2.
|
|
42
|
+
> 📌 **公告(v2.1.0)**
|
|
33
43
|
>
|
|
34
|
-
> **v2.
|
|
44
|
+
> **v2.1.0:原生五卡设置、输入框识图、运行时双语、能力路由/测评加固,并正式启用 DSH rc.8 最低支持线。** [查看完整更新 →](docs/releases/v2.1.0.md)
|
|
35
45
|
|
|
36
46
|
<p align="center">
|
|
37
47
|
<img src="assets/vision-demo.gif" width="640" alt="演示:粘贴图片,Agent 用 vision_ground / vision_crop / vision_pixel_diff 定位发送按钮并给出坐标" />
|
|
@@ -54,7 +64,7 @@
|
|
|
54
64
|
|
|
55
65
|
## 为什么做这个
|
|
56
66
|
|
|
57
|
-
大多数 DSH 视觉插件把图片“翻译”成一段文字描述再喂给 DeepSeek
|
|
67
|
+
大多数 DSH 视觉插件把图片“翻译”成一段文字描述再喂给 DeepSeek——有损、一次性、看不见像素。本插件把**Host 规范化后的图像像素留在视觉模型侧**、把推理留在 DeepSeek 侧,并把“看图”变成一次**普通的工具调用**:
|
|
58
68
|
|
|
59
69
|
- **一条命令安装。** 包自带组合补丁(`dsh.bundle.patch`):`dsh plugin add` 自动完成插件行挂载、准入包装与附件限制放宽——不用手改任何文件。是否接管官方 DeepSeek 路由由「隐身模式」开关决定(默认关)。
|
|
60
70
|
- **默认免费。** 视觉工具最终兜底为 5 个 OVHcloud 匿名视觉模型:免注册、免 Key,每 IP、每模型 2 次/分钟,独立限额理论合计约 10 次/分钟;用户自备视觉模型会优先调用。
|
|
@@ -66,11 +76,14 @@
|
|
|
66
76
|
## 对比同类插件
|
|
67
77
|
|
|
68
78
|
**一句话讲清区别**:其他 dsh 视觉插件大多"把图片转成文字描述再喂给 DeepSeek"(描述桥,有信息损耗);
|
|
69
|
-
本插件主打"
|
|
79
|
+
本插件主打"**图片轮直接交给视觉模型看图像像素**"(路由桥,像素级),同时内置免 Key 免费模型兜底。
|
|
80
|
+
|
|
81
|
+
> [!NOTE]
|
|
82
|
+
> 在 DSH 0.1.2-alpha.1+ 上,附件仍由 Host 单一持有。Vision Router 消费的是 Host 持久化后的 canonical image:落在规范化限制内的单帧 8-bit sRGB/sRGBA 图片可以逐字节直通;需要旋转、色彩空间、元数据、动画或尺寸规范化的图片可能会被重新编码。因此像素工具承诺的是 Host canonical raster,而不是上传源文件编码字节逐字节不变。
|
|
70
83
|
|
|
71
84
|
| | 手动切换模型 | MCP 视觉桥 | 本插件 |
|
|
72
85
|
|---|---|---|---|
|
|
73
|
-
|
|
|
86
|
+
| 图像像素 | ✅ 可用(切换后) | ❌ 只有文字描述 | ✅ Host 规范化栅格,图片轮内 |
|
|
74
87
|
| 自动化 | ❌ | ✅ | ✅ |
|
|
75
88
|
| 日常模型不受影响 | ❌(整会话被换) | ✅ | ✅ |
|
|
76
89
|
| 供应商失败恢复 | ❌ | ❌ | ✅ 降级链 |
|
|
@@ -82,7 +95,7 @@
|
|
|
82
95
|
|
|
83
96
|
| 项目 | 思路 | 本插件的差异 |
|
|
84
97
|
|---|---|---|
|
|
85
|
-
| [dsh-vision-sidecar](https://github.com/121103qwq/dsh-vision-sidecar) | 图片先经外部 VLM 做 OCR/描述,描述作为会话消息交给 DeepSeek;默认 LLM7.io 匿名端点(OVHcloud 为无 Key 备选) | 描述桥方案;本插件提供"
|
|
98
|
+
| [dsh-vision-sidecar](https://github.com/121103qwq/dsh-vision-sidecar) | 图片先经外部 VLM 做 OCR/描述,描述作为会话消息交给 DeepSeek;默认 LLM7.io 匿名端点(OVHcloud 为无 Key 备选) | 描述桥方案;本插件提供"图像直看"路由,描述能力由 `vision_describe` 按需替代 |
|
|
86
99
|
| [dsh-vision-proxy](https://github.com/Flyvhidbwo/dsh-vision-proxy) | 包装 provider 路由,请求流里把图片转译成文本再交给 DeepSeek | 转译桥方案;本插件不包装 provider,通过 `agent/request` 瀑布改写路由 |
|
|
87
100
|
| [dsh-vision-provider](https://github.com/libinyam/dsh-vision-provider) | 注册 `DeepSeek + Vision` 组合路由:图片先经所选视觉模型转成描述,再交给 DeepSeek | 双模型桥思路;本插件在此基础上增加自动路由、降级链与工具 |
|
|
88
101
|
| [modlens](https://github.com/liustack/modlens) | 最早的 dsh 视觉插件;复用本机 Claude Code/Codex/OpenCode/Pi 等登录态作为视觉引擎 | 引擎复用思路;本插件自带供应商链,不依赖本机其他 CLI |
|
|
@@ -398,6 +411,7 @@ ollama pull qwen2.5vl
|
|
|
398
411
|
## 环境要求
|
|
399
412
|
|
|
400
413
|
- DeepSeek Harness 的 Web profile。普通安装可用 `npx @deepseek-ai/dsh ...`;从源码仓库运行时用 `pnpm dsh ...`。只有 CLI 已经进入系统 `PATH` 时才能直接写 `dsh ...`。
|
|
414
|
+
- **DSH Host 支持窗口:** DVR 2.1.x 支持 DSH `0.1.0-rc.8`(最低)、`0.1.1-rc.1`(上一正式支持线)以及当前 `0.1.1-rc.2`;DSH `0.1.2-alpha.4` 仅作为 canary 兼容证据。DVR 2.0.x 是最后公开支持 rc.6/rc.7 的版本线。详见 [DSH Host 支持窗口](docs/architecture/dsh-support-window.md)。
|
|
401
415
|
- Node ≥ 22(宿主侧)。
|
|
402
416
|
- 默认免费链路无需 API Key;付费 `httpProviders` 只需一个凭据引用(`apiKeyEnv`)。
|
|
403
417
|
- 只有 `vision_html_screenshot` 需要 Chrome / Chromium / Edge;其余工具无浏览器也能用。
|
|
@@ -569,8 +583,11 @@ npx dsh-vision-router doctor --profile web
|
|
|
569
583
|
## Star 趋势
|
|
570
584
|
|
|
571
585
|
<p align="center">
|
|
572
|
-
<
|
|
573
|
-
<
|
|
574
|
-
|
|
575
|
-
|
|
586
|
+
<a href="https://www.star-history.com/?repos=ysr666%2Fdsh-vision-router&type=date&legend=top-left">
|
|
587
|
+
<picture>
|
|
588
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=ysr666/dsh-vision-router&type=date&theme=dark&legend=top-left&sealed_token=bl3whaniTB54-d4wMda4a454thk48mT71wkNh8VrSD8OhCKWdBOOQpVKGUXzoEq4kx0_0jhQzEimHIqKAaGftFVV48sqgJ1niBfGy51AX5k_soGw_e7-5Nea6ZY5To0iz7jY9ORc5a_P5N6Qlfm32G2pdHf8_5dZeuHMn5NOZCyTgFcmq2eK1Jwg8ILe" />
|
|
589
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=ysr666/dsh-vision-router&type=date&legend=top-left&sealed_token=bl3whaniTB54-d4wMda4a454thk48mT71wkNh8VrSD8OhCKWdBOOQpVKGUXzoEq4kx0_0jhQzEimHIqKAaGftFVV48sqgJ1niBfGy51AX5k_soGw_e7-5Nea6ZY5To0iz7jY9ORc5a_P5N6Qlfm32G2pdHf8_5dZeuHMn5NOZCyTgFcmq2eK1Jwg8ILe" />
|
|
590
|
+
<img alt="Star 历史趋势图" src="https://api.star-history.com/chart?repos=ysr666/dsh-vision-router&type=date&legend=top-left&sealed_token=bl3whaniTB54-d4wMda4a454thk48mT71wkNh8VrSD8OhCKWdBOOQpVKGUXzoEq4kx0_0jhQzEimHIqKAaGftFVV48sqgJ1niBfGy51AX5k_soGw_e7-5Nea6ZY5To0iz7jY9ORc5a_P5N6Qlfm32G2pdHf8_5dZeuHMn5NOZCyTgFcmq2eK1Jwg8ILe" width="100%" />
|
|
591
|
+
</picture>
|
|
592
|
+
</a>
|
|
576
593
|
</p>
|
package/cordis.patch.yml
CHANGED
|
@@ -18,13 +18,20 @@
|
|
|
18
18
|
config:
|
|
19
19
|
progressiveTools: false
|
|
20
20
|
|
|
21
|
-
# Vision Router 的附件产品契约:Host attachment store
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
21
|
+
# Vision Router 的附件产品契约:Host attachment store 是 durable 图片的唯一
|
|
22
|
+
# owner,视觉工具只读取 Host 已持久化、校验后的 canonical pixels。DSH rc.8
|
|
23
|
+
# 以前 Host 会把已准入的源编码直接持久化;0.1.2-alpha.1 开始又增加独立的
|
|
24
|
+
# provider-independent normalization stage。若沿用 alpha.1 的 4.2MP / 4MiB
|
|
25
|
+
# 默认值,DVR 的 crop / grounding / OCR / pixel-diff 会在用户毫不知情时换到
|
|
26
|
+
# 一个更小的像素坐标系。因此这里把 normalization policy 同步到 DVR 既有的
|
|
27
|
+
# 20MiB / 1 亿像素 / 10000px 准入边界:普通 8-bit sRGB 图片继续 pass-through,
|
|
28
|
+
# 不扩大 DVR 在 rc.8 时已经允许的 durable 存储上限,同时仍让 Host 独占
|
|
29
|
+
# normalization、完整性校验和对象身份。
|
|
30
|
+
#
|
|
31
|
+
# 注意:alpha.1 对 EXIF/色彩空间/GIF/超限编码等输入仍可能规范化或重编码。
|
|
32
|
+
# DVR 不另存第二份 raw attachment,也不声称能从 canonical object 恢复源字节;
|
|
33
|
+
# 像素工具的合同因此以 Host canonical pixels 为准。ImageAttachmentRef 的
|
|
34
|
+
# originalDimensions 仅用于说明 Host 曾缩放,不能被当作可读取的原图。
|
|
28
35
|
#
|
|
29
36
|
# DSH 的 patch 是“整段 config 替换”而非深度合并。旧版 Vision Router 曾在
|
|
30
37
|
# profile 自己的 cordis.patch.yml 写入同一行的 20MiB/100MP 两个字段;这层
|
|
@@ -34,11 +41,14 @@
|
|
|
34
41
|
# 这样升级旧 profile 不要求用户手工清理配置,同时后续 profile/--patch 的
|
|
35
42
|
# 明确部署策略仍保持最终所有权。
|
|
36
43
|
#
|
|
37
|
-
# rc.6/rc.7 没有
|
|
38
|
-
#
|
|
44
|
+
# rc.6/rc.7/rc.8 没有 normalizedImage*;发布合同 CI 会用真实旧包验证额外
|
|
45
|
+
# 配置键仍被安全忽略。若旧 Host 开始严格拒绝未知键,此处必须改为按能力
|
|
39
46
|
# 生成配置,而不是靠版本字符串分支。
|
|
40
47
|
- id: attachment-local
|
|
41
48
|
config:
|
|
42
49
|
maxImageBytes: 20971520
|
|
43
50
|
maxImagePixels: 100000000
|
|
44
51
|
maxImageDimension: 10000
|
|
52
|
+
normalizedImageMaxBytes: 20971520
|
|
53
|
+
normalizedImageMaxPixels: 100000000
|
|
54
|
+
normalizedImageMaxDimension: 10000
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# 2.x Architecture Closure Contract Ledger
|
|
2
|
+
|
|
3
|
+
Status: **normative for Post-P3 closure**
|
|
4
|
+
|
|
5
|
+
Baseline main: `1f78443a75e76a8fbba5d90a305e8c53db93bb7f`
|
|
6
|
+
|
|
7
|
+
This ledger freezes the externally observable and cross-boundary contracts that the 2.x Architecture Closure is not allowed to change while ownership is being simplified.
|
|
8
|
+
|
|
9
|
+
The closure is a structural migration, not a product feature release. A cleaner dependency graph is not a valid reason to change user-visible behavior, Host persistence, routing semantics, authority, provider order, failure policy, or compatibility support.
|
|
10
|
+
|
|
11
|
+
## Closure method
|
|
12
|
+
|
|
13
|
+
Every semantic-owner migration follows the same order:
|
|
14
|
+
|
|
15
|
+
1. **Characterize** the existing behavior and public/Host contract.
|
|
16
|
+
2. **Add** the new internal path without deleting the old path.
|
|
17
|
+
3. **Compare** old and new decisions in tests; the old path remains the parity oracle.
|
|
18
|
+
4. **Switch** production ownership only after parity is complete.
|
|
19
|
+
5. **Delete** the old implementation and rerun the same gates after deletion.
|
|
20
|
+
6. **Merge**, then rerun the relevant gates on `main`.
|
|
21
|
+
|
|
22
|
+
A green test run while the old path can still silently rescue the new path is not deletion proof.
|
|
23
|
+
|
|
24
|
+
## External contract — frozen during Closure
|
|
25
|
+
|
|
26
|
+
| Surface | Frozen contract |
|
|
27
|
+
|---|---|
|
|
28
|
+
| package entry | package root continues to resolve through `lib/public-entry.js` |
|
|
29
|
+
| plugin identity | `vision-router` remains the plugin name |
|
|
30
|
+
| settings namespace | `vision-router` remains the Host settings namespace |
|
|
31
|
+
| settings contract revision | existing 2.0.x field meanings/defaults remain unchanged unless a separate product change is approved |
|
|
32
|
+
| routing mode | `ordered` remains the safe default; `auto` requires live authority |
|
|
33
|
+
| routing preference | `balanced`, `quality`, `speed`, `local` retain their existing meaning |
|
|
34
|
+
| background measurement | `off`, `local-free`, `all` remain separate authority states; absence does not grant work |
|
|
35
|
+
| route identity | existing wrapper/chain/provider route names and aliases remain compatible |
|
|
36
|
+
| tools | existing tool names, argument schemas, result shapes and error classes remain compatible |
|
|
37
|
+
| native multimodal | native image ownership remains non-intervention for automatic Router orchestration; explicit Router tools are not disabled merely because a model is native multimodal |
|
|
38
|
+
| fallback | execution may reorder only already-eligible candidates; it may not invent a provider or delete a configured/local/discovered fallback |
|
|
39
|
+
| session persistence | no new Host Session event type or durable index format is introduced by Closure |
|
|
40
|
+
| session surface repair | existing `surfaceOp: { op: 'replace' }` and `sourceEventSeqs` semantics remain compatible |
|
|
41
|
+
| attachment identity | durable attachment ids remain Host/session identities; no cross-session lookup is introduced |
|
|
42
|
+
| artifact publication | existing public derived-artifact paths/return values remain compatible; managed run cleanup remains confined to Router-owned provenance/namespaces |
|
|
43
|
+
| proxy setting | existing proxy/proxyHosts behavior remains compatible; Router-owned HTTP stays independent of process-global fetch mutation |
|
|
44
|
+
| Doctor | Closure does not turn advisory architecture/support diagnostics into new failure exit codes |
|
|
45
|
+
| support window | DVR 2.0.x continues to support the published minimum/previous/current DSH window; rc.6 support is not removed by a patch-level closure |
|
|
46
|
+
| runtime platforms | Node 22/24 and the existing Ubuntu/macOS/Windows host-sharp contract remain supported |
|
|
47
|
+
|
|
48
|
+
## Internal ownership target
|
|
49
|
+
|
|
50
|
+
Closure may change implementation only toward this dependency direction:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
Authority -> Evidence -> Planner -> Execution
|
|
54
|
+
\-> Host product projection -> Presentation
|
|
55
|
+
|
|
56
|
+
SessionVisionRuntime
|
|
57
|
+
|- SessionVisionStateStore (bounded process-local state)
|
|
58
|
+
`- SessionVisionIndex (durable-log indexing/recovery/surface repair)
|
|
59
|
+
|
|
60
|
+
VisionArtifactStore (derived artifact ownership)
|
|
61
|
+
VisionProviderTransport (Router-owned provider HTTP)
|
|
62
|
+
Compat (only supported Host/provider gaps with exit criteria)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Single-owner rules
|
|
66
|
+
|
|
67
|
+
The final closure must make these statements true:
|
|
68
|
+
|
|
69
|
+
- routing authority has one production owner;
|
|
70
|
+
- planner output is data, never a disguised Settings object;
|
|
71
|
+
- session durable-log indexing/targeted recovery/surface repair has one production implementation;
|
|
72
|
+
- a Session store is not discovered through an implicit process-global "current" owner;
|
|
73
|
+
- browser code renders Host product decisions instead of re-deriving routing/background authority or eligibility;
|
|
74
|
+
- Router-owned provider HTTP has one transport boundary;
|
|
75
|
+
- compatibility shims translate supported gaps but do not own product policy.
|
|
76
|
+
|
|
77
|
+
## C1 — Session/Core policy convergence contract
|
|
78
|
+
|
|
79
|
+
Allowed changes:
|
|
80
|
+
|
|
81
|
+
- add one narrow internal SessionVisionRuntime dependency to core composition;
|
|
82
|
+
- make SessionVisionIndex the sole owner of event-log scan, targeted attachment recovery and surface repair;
|
|
83
|
+
- replace SessionSurfacePolicy -> fake Settings projection with explicit derived runtime flags;
|
|
84
|
+
- remove obsolete current-store/service-locator and store monkey-patching after parity proof.
|
|
85
|
+
|
|
86
|
+
Forbidden changes:
|
|
87
|
+
|
|
88
|
+
- cache size/TTL changes;
|
|
89
|
+
- attachment-id semantics;
|
|
90
|
+
- Session event format changes;
|
|
91
|
+
- new persistence files;
|
|
92
|
+
- route/provider/tool policy changes;
|
|
93
|
+
- native-image ownership changes;
|
|
94
|
+
- timeout/retry/budget changes.
|
|
95
|
+
|
|
96
|
+
**Stop condition:** if the migration starts requiring provider/routing/artifact redesign or broad public/core API churn beyond one narrow optional runtime dependency, stop and redesign rather than pursuing DI purity.
|
|
97
|
+
|
|
98
|
+
## C2 — Presentation convergence contract
|
|
99
|
+
|
|
100
|
+
Host owns decisions; browser owns presentation and user interaction.
|
|
101
|
+
|
|
102
|
+
The stable presentation DTO should be additive and versioned. It may expose decisions such as:
|
|
103
|
+
|
|
104
|
+
- `canBenchmark` / `benchmarkReason`;
|
|
105
|
+
- `capabilityState`;
|
|
106
|
+
- `healthClass`;
|
|
107
|
+
- `backgroundEligible` / `backgroundReason`;
|
|
108
|
+
- routing/authority summaries safe for presentation.
|
|
109
|
+
|
|
110
|
+
The DTO must not expose credentials, credential references, raw endpoints/fingerprints solely for internal execution, mutable breaker internals, or evidence objects that require the browser to reinterpret validity.
|
|
111
|
+
|
|
112
|
+
Prefer extending an existing benchmark/runtime snapshot over creating another long-lived polling surface. Existing 2.0.x routes are removed only under the normal compatibility/version policy.
|
|
113
|
+
|
|
114
|
+
## C3 — Bounded cleanup contract
|
|
115
|
+
|
|
116
|
+
Mandatory low-risk cleanup:
|
|
117
|
+
|
|
118
|
+
- retire obsolete capability-shadow naming/shim once no production consumer remains;
|
|
119
|
+
- remove stale migration comments whose stated deletion phase has passed;
|
|
120
|
+
- ensure every retained compatibility seam has Reason, Host gap, Feature detection, Removal condition and Tests.
|
|
121
|
+
|
|
122
|
+
Conditional cleanup:
|
|
123
|
+
|
|
124
|
+
- remove the VisionProviderTransport module registry only if explicit injection has a small, local change radius and does not broaden public/core signatures materially;
|
|
125
|
+
- otherwise document a concrete later removal trigger and retain the working boundary.
|
|
126
|
+
|
|
127
|
+
Not a closure target:
|
|
128
|
+
|
|
129
|
+
- deleting legitimate rc.6/rc.8 compatibility merely to reduce file count;
|
|
130
|
+
- deleting `vision-chain`;
|
|
131
|
+
- rewriting the mature core for LOC reduction;
|
|
132
|
+
- migrating the scheduler to `ctx.jobs` without the already-defined GO criteria;
|
|
133
|
+
- changing artifact layout again.
|
|
134
|
+
|
|
135
|
+
## Mandatory validation after each semantic switch
|
|
136
|
+
|
|
137
|
+
At minimum, the affected slice must retain coverage for:
|
|
138
|
+
|
|
139
|
+
- Ordered exact behavior;
|
|
140
|
+
- Auto exact behavior and live authority revoke/recheck;
|
|
141
|
+
- fallback preservation and stale-plan filtering;
|
|
142
|
+
- native multimodal non-intervention;
|
|
143
|
+
- text-only/plugin-owned/unknown image ownership;
|
|
144
|
+
- Session restart/cold resume;
|
|
145
|
+
- bounded-cache target recovery;
|
|
146
|
+
- same-session and cross-session concurrency;
|
|
147
|
+
- cancellation/no ALS leak;
|
|
148
|
+
- artifact retention and unknown-entry preservation;
|
|
149
|
+
- Router-owned HTTP independence from the global fetch patch;
|
|
150
|
+
- remote/local settings behavior;
|
|
151
|
+
- Node 22 and Node 24;
|
|
152
|
+
- minimum/previous/current DSH contract;
|
|
153
|
+
- platform/resource gates relevant to the changed boundary.
|
|
154
|
+
|
|
155
|
+
## Closure completion rule
|
|
156
|
+
|
|
157
|
+
The architecture is not declared CLOSED merely because C1/C2/C3 PRs merge. After deletion of the old paths, run one final adversarial audit on the resulting `main` and prove:
|
|
158
|
+
|
|
159
|
+
1. one semantic owner per boundary;
|
|
160
|
+
2. no duplicate production algorithm can still rescue the replacement;
|
|
161
|
+
3. every remaining compatibility seam has a currently reachable supported case or an explicit removal trigger;
|
|
162
|
+
4. adding a new modality (PDF/video/1+x) does not require a new Settings impersonation layer, process-global runtime locator, duplicate Session cache/index, or browser-owned authority algorithm;
|
|
163
|
+
5. the full regression/contract/stress/security matrix is green on merged `main`.
|
|
164
|
+
|
|
165
|
+
Only then mark **2.x architecture convergence: CLOSED**.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Compatibility seam inventory
|
|
2
|
+
|
|
3
|
+
P0 records why each major compatibility seam exists and the condition that permits its removal. This inventory is normative for 2.x convergence: a shim without an exit criterion is architectural debt that cannot silently become permanent.
|
|
4
|
+
|
|
5
|
+
## `lib/dsh-contract-compat.js`
|
|
6
|
+
|
|
7
|
+
- **Reason:** preserve released attachment/settings/provider-ownership behavior across the supported DSH window.
|
|
8
|
+
- **Host gap:** rc.6 has the single-attachment contract; later Hosts add batch save, max-dimension policy and newer settings/provider lifecycle behavior.
|
|
9
|
+
- **First needed for:** minimum rc.6 support and the subsequent rc.7/rc.8 attachment migration.
|
|
10
|
+
- **Feature detection:** `attachments.saveImages`, attachment `imageLimits`, settings registration/scope functions, and LLM registration methods. No version-string branch.
|
|
11
|
+
- **Removal condition:** minimum supported DSH natively exposes the required attachment/settings/provider seams and legacy profile overlays are outside support.
|
|
12
|
+
- **Tests:** `rc6-rc7-compat`, `rc6-real-settings-persistence`, `attachment-admission-policy`, `dsh-host-capabilities`, minimum/legacy/current contract CI.
|
|
13
|
+
|
|
14
|
+
## `lib/adapter-update-coalescer.js`
|
|
15
|
+
|
|
16
|
+
- **Reason:** keep Vision Router-owned duck-typed adapters compatible with Host `prepareCall` dispatch and prevent synchronous adapter-topology events from recursively reconciling forever.
|
|
17
|
+
- **Host gap:** older plugin adapters do not inherit the Host adapter base class; supported Host generations can emit adapter updates synchronously during registration.
|
|
18
|
+
- **First needed for:** DSH 0.1.1 `prepareCall` and atomic registration behavior.
|
|
19
|
+
- **Feature detection:** adapter-local `prepareCall` presence; actual `llm/adapters-updated` event path. No version inference.
|
|
20
|
+
- **Removal condition:** every supported Vision Router adapter directly satisfies the Host adapter contract and supported Host event semantics no longer require the bounded coalescer.
|
|
21
|
+
- **Tests:** `adapter-prepare-call-compat`, `runtime-boundary-fixes`, current-contract Host smoke.
|
|
22
|
+
|
|
23
|
+
## `lib/android-attachment-compat.js`
|
|
24
|
+
|
|
25
|
+
- **Reason:** allow the minimum Host path to survive Termux/Android attachment persistence permission boundaries without taking ownership on batch-capable Hosts.
|
|
26
|
+
- **Host gap:** file-backed attachment storage can fail with `EACCES`/`EPERM` in Android/Termux environments on the legacy path.
|
|
27
|
+
- **First needed for:** Android/Termux support while rc.6 remains minimum.
|
|
28
|
+
- **Feature detection:** Android/Termux environment, permission-boundary error and absence of the batch attachment contract.
|
|
29
|
+
- **Removal condition:** minimum supported DSH owns a working Android attachment implementation for the same path and the fallback is no longer reachable.
|
|
30
|
+
- **Tests:** `android-attachment-compat`, image-resource/resource-retention tests.
|
|
31
|
+
|
|
32
|
+
## `lib/replay-envelope-v2-compat.js`
|
|
33
|
+
|
|
34
|
+
- **Reason:** preserve delegated replay identity when producer provider/model moved into durable pi-ai replay envelope v2.
|
|
35
|
+
- **Host gap:** older Vision Router replay code expected producer identity at the top level.
|
|
36
|
+
- **First needed for:** rc.7 replay-envelope v2 histories.
|
|
37
|
+
- **Feature detection:** exact durable producer proof: `response.kind === 'pi-ai'`, `response.version === 2`, provider and model match.
|
|
38
|
+
- **Removal condition:** the supported runtime/history window no longer includes envelopes requiring source rebinding, or the Host exposes an equivalent native replay identity seam consumed directly by Vision Router.
|
|
39
|
+
- **Tests:** `replay-delegation`, session/cold-resume regression coverage.
|
|
40
|
+
|
|
41
|
+
## `lib/pi-ai-bridge-wire-compat.js`
|
|
42
|
+
|
|
43
|
+
- **Reason:** make the legacy direct image bridge transport-equivalent to pi-ai declared wire compatibility without reading credentials or changing provider priority.
|
|
44
|
+
- **Host gap:** the direct bridge predates route/model wire metadata such as max-token fields and route-owned headers.
|
|
45
|
+
- **First needed for:** DSH 0.1.1 pi-ai declared provider/wire compatibility.
|
|
46
|
+
- **Feature detection:** exact non-streaming OpenAI-compatible image bridge fingerprint plus resolved route/model facts; normal streaming Host traffic does not match.
|
|
47
|
+
- **Removal condition:** the direct bridge is removed or every supported Host executes this image path through the native pi-ai wire seam.
|
|
48
|
+
- **Tests:** `pi-ai-bridge-wire-compat`, native process-restart/cold-resume contract.
|
|
49
|
+
|
|
50
|
+
## `lib/settings-client-rc8-lifecycle.js`
|
|
51
|
+
|
|
52
|
+
- **Reason:** keep browser settings lifecycle coherent across legacy and current Host client generations.
|
|
53
|
+
- **Host gap:** settings client attachment/replacement lifecycle is not identical across the support window.
|
|
54
|
+
- **First needed for:** rc.8-era settings UI coexistence.
|
|
55
|
+
- **Feature detection:** actual client/runtime lifecycle surfaces; never the Host version label.
|
|
56
|
+
- **Removal condition:** supported Hosts expose one stable settings client lifecycle and the compatibility branch is proven unreachable by contract tests.
|
|
57
|
+
- **Tests:** settings IA, client lifecycle, remote-settings and Web acceptance regressions.
|
|
58
|
+
|
|
59
|
+
## `lib/http-compat.js`
|
|
60
|
+
|
|
61
|
+
- **Reason:** isolate evidenced provider/model wire quirks from generic visual HTTP execution.
|
|
62
|
+
- **Host gap:** this is provider compatibility rather than a DSH Host gap; some OpenAI-compatible endpoints reject otherwise valid generic payload shapes.
|
|
63
|
+
- **First needed for:** model-family quirks such as GLM-4V-Flash output limits and image-only message handling.
|
|
64
|
+
- **Feature detection:** provider/model/url rule predicates backed by known wire behavior.
|
|
65
|
+
- **Removal condition:** upstream endpoint behavior becomes generic-compatible for a rule and regression evidence confirms the preset is no longer needed.
|
|
66
|
+
- **Tests:** `http-compat`, provider HTTP regression tests.
|
|
67
|
+
|
|
68
|
+
## `lib/vision-provider-transport.js` process/profile registry
|
|
69
|
+
|
|
70
|
+
- **Reason:** carry the Router-owned provider transport into compatibility callers whose mature function signatures still accept only a raw `fetch` or use an internal direct HTTP call, while keeping Router traffic off the process-global fetch patch.
|
|
71
|
+
- **Host gap:** this is an internal composition gap rather than a DSH version persona: `fetchWithOpenAICompatibility(...)` and the Anthropic catalog-correction path do not yet receive a `VisionProviderTransport` parameter explicitly.
|
|
72
|
+
- **First needed for:** provider-scoped transport ownership and proxy narrowing without rewriting the mature compatibility call signatures in the same migration.
|
|
73
|
+
- **Feature detection:** explicit transport-aware callers bypass the registry; only compatibility paths that call `currentVisionProviderTransport()` consume the currently installed process/profile transport. The registry never patches `globalThis.fetch`.
|
|
74
|
+
- **Removal condition:** every Router-owned compatibility caller receives `VisionProviderTransport` explicitly, production has zero reads of `currentVisionProviderTransport()`, and the install/release registry can be removed without changing proxy, credential, bounded-body or cancellation behavior.
|
|
75
|
+
- **Tests:** `vision-provider-transport`, `http-compat`, `catalog-corrections`, P2 Data Boundary provider-transport Node 22/24, Host pack/install smoke.
|
|
76
|
+
|
|
77
|
+
## `lib/legacy-global-proxy-boundary.js`
|
|
78
|
+
|
|
79
|
+
- **Reason:** retain the process-global proxy patch only for Host-owned/raw-fetch visual providers that still lack a provider-scoped proxy seam. Router-owned `vision-http` and direct protocol-correction traffic already uses `VisionProviderTransport` with an explicit dispatcher.
|
|
80
|
+
- **Host gap:** the supported Host window does not yet guarantee one provider-scoped/shared HTTP proxy seam that third-party Host-owned adapters can consume without a process-global fetch wrapper.
|
|
81
|
+
- **First needed for:** legacy/custom Host-owned visual provider compatibility when users configure Vision Router proxy routing.
|
|
82
|
+
- **Feature detection:** live visual-chain ownership. Router-owned routes bypass the legacy patch; any unknown/Host-owned provider conservatively keeps it available. This is capability/ownership detection, not a Host-version persona.
|
|
83
|
+
- **Removal condition:** **the minimum supported DSH provides a provider-scoped/shared HTTP proxy seam** that covers the remaining Host-owned/raw-fetch provider compatibility requirement.
|
|
84
|
+
- **Tests:** `legacy-global-proxy-boundary`, `vision-provider-transport`, `adversarial-hardening`, P2 Data Boundary Node 22/24.
|
|
85
|
+
|
|
86
|
+
## `lib/legacy-core-vision-policy-bridge.js`
|
|
87
|
+
|
|
88
|
+
- **Reason:** preserve the two remaining pre-step compatibility behaviors after Core policy ownership moved to explicit session/Core surfaces: reuse the exact `SessionMemoryView` for text-only image-history rewrite, and expose exact current-turn durable attachment IDs as read-only model context for Vision Router-owned wrappers.
|
|
89
|
+
- **Host gap:** the supported Host pre-step path does not natively provide both an exact session-scoped visual-memory rewrite seam for text-only fallback and a model-readable durable attachment-reference seam for Router-owned image turns.
|
|
90
|
+
- **First needed for:** the Core/session ownership migration that removed Settings/config impersonation while retaining these two real pre-step behaviors.
|
|
91
|
+
- **Feature detection:** live `SessionSurfacePolicy` (`rewriteCurrentImages` and ownership), exact known session visual memory, and actual current-turn image attachment IDs. No Host version-string branch and no Settings/config projection.
|
|
92
|
+
- **Removal condition:** the minimum supported Host exposes native pre-step/session-memory and durable attachment-reference capabilities that make both behaviors redundant, and contract/parity tests prove the bridge can be removed without reintroducing Settings impersonation or degrading text-only/native image turns.
|
|
93
|
+
- **Tests:** `settings-impersonation-closure`, `session-surface-policy`, session/runtime parity and native cold-resume coverage.
|
|
94
|
+
|
|
95
|
+
## `lib/tesseract-exec-compat.js`
|
|
96
|
+
|
|
97
|
+
- **Reason:** own the single process-wide `promisify(execFile)` compatibility boundary for the two narrow child-process cases Vision Router still needs: materializing Tesseract stdin image bytes, and replacing only Core's exact legacy Windows `VirtualScreen`/`CopyFromScreen` desktop-capture command with a per-monitor-DPI-safe equivalent. One owner prevents cleanup-order bugs from independently stacked `execFile` wrappers.
|
|
98
|
+
- **Host gap:** these are runtime/platform gaps rather than DSH semantic ownership: Node's async `execFile` path does not consume the historical OCR `options.input`, while non-DPI-aware Windows PowerShell virtualizes desktop metrics and can disagree with physical screen-copy coordinates on scaled/mixed-DPI displays.
|
|
99
|
+
- **First needed for:** Node 24/local Tesseract process execution reliability; Windows scaled/mixed-DPI `vision_screenshot` correctness (#340).
|
|
100
|
+
- **Feature detection:** exact executable/call fingerprints only. Tesseract handling requires `tesseract[.exe]` + stdin input; Windows screenshot handling requires `win32`, `powershell[.exe]`, `-Command`, and the exact legacy `SystemInformation.VirtualScreen` + `Graphics.CopyFromScreen` script shape. No Host/Node version persona and unrelated child processes delegate unchanged.
|
|
101
|
+
- **Removal condition:** local OCR no longer needs an `execFile` stdin shim **and** Core/Host exposes a native DPI-correct desktop-capture seam (or the legacy PowerShell command is removed), with Node 22/24 and Windows platform matrices proving the shared wrapper is unreachable before deletion.
|
|
102
|
+
- **Tests:** `tesseract-node24-boot`, `qa-screenshot-runtime` (PMv2/PMv1 ordering, context restoration, exact-match passthrough, Windows PowerShell compile smoke), cross-platform Host tests.
|
|
103
|
+
|
|
104
|
+
## `lib/abort-signal-compat.js`
|
|
105
|
+
|
|
106
|
+
- **Reason:** keep Vision Router cancellation/deadline composition working when a supported DSH Host or bridge exposes `AbortSignal`/`AbortController` but omits the standard static `AbortSignal.any()` or `AbortSignal.timeout()` helpers used by the Router's runtime boundaries.
|
|
107
|
+
- **Host gap:** some real Host/bridge environments can surface a partial AbortSignal runtime even though the declared Node support window normally provides both helpers, producing `AbortSignal.any is not a function` inside visual work.
|
|
108
|
+
- **First needed for:** partial Host/bridge AbortSignal runtimes observed during Vision Router image execution and exact capability checks.
|
|
109
|
+
- **Feature detection:** only the actual static helper presence is inspected. Existing native `AbortSignal.any` and `AbortSignal.timeout` functions are never replaced; only a missing helper is installed. No Node or DSH version persona is inferred.
|
|
110
|
+
- **Removal condition:** every supported Host/runtime contract guarantees both static helpers in the actual realm used by plugin execution, and a cross-Host regression proves no supported bridge can present the partial runtime anymore.
|
|
111
|
+
- **Tests:** `qa-turn-budget-cancellation` legacy-realm fallback/validation/non-intervention coverage plus Node 22/24 and DSH contract CI.
|
|
112
|
+
|
|
113
|
+
## Removal protocol
|
|
114
|
+
|
|
115
|
+
A compatibility seam may be deleted only when all of the following are true:
|
|
116
|
+
|
|
117
|
+
1. its **Removal condition** is satisfied by the declared support window;
|
|
118
|
+
2. the relevant capability is proved by a gating Host contract fixture or direct feature test;
|
|
119
|
+
3. deleting the seam leaves Node 22/24, minimum/legacy/current Host contracts and relevant platform tests green;
|
|
120
|
+
4. no Authority, Session, Storage or native-multimodal invariant changes as a side effect;
|
|
121
|
+
5. the deletion is a focused change, not bundled into an unrelated routing/data-boundary refactor.
|