dsh-tool-vision 0.3.10 → 0.6.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/LICENSE CHANGED
@@ -1,21 +1,23 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Scorp1o117
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Scorp1o117
4
+ Bridge image preview contributed by xing666173 (dsh-bridge-preview),
5
+ Copyright (c) 2026 xing666173
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/README.md CHANGED
@@ -1,156 +1,233 @@
1
- # dsh-tool-vision
2
-
3
- [![中文文档](https://img.shields.io/badge/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3-blue)](README.zh.md)
4
-
5
- **GitHub**: [Scorp1o117/dsh-tool-vision](https://github.com/Scorp1o117/dsh-tool-vision) · **npm**: [dsh-tool-vision](https://www.npmjs.com/package/dsh-tool-vision)
6
-
7
- [![Enhancement Suite](https://img.shields.io/badge/part%20of-Enhancement%20Suite-3964fe)](https://github.com/Scorp1o117/dsh-enhancement-suite) [![npm](https://img.shields.io/npm/v/dsh-enhancement-suite)](https://www.npmjs.com/package/dsh-enhancement-suite)
8
-
9
- Part of the [DeepSeek Harness Enhancement Suite](https://github.com/Scorp1o117/dsh-enhancement-suite) — Vision · Soul/Persona · Long-term Memory · Plugin Marketplace.
10
-
11
- External vision model for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).
12
-
13
- DeepSeek's own models are text-only, and the harness derives every model
14
- request strictly from the session log (`llm/stream` requests must equal the
15
- durable derivation — the agent-loop invariant). This plugin bridges the gap
16
- in two ways:
17
-
18
- 1. **`inspect_image` tool** — sends an image (local file, or http(s) URL) to
19
- **any OpenAI-compatible** `/chat/completions` endpoint that supports
20
- `image_url` content parts, and returns the vision model's textual answer
21
- into the agent loop.
22
- 2. **Image bridge (v0.2.1)** — pasted images are turned into `inspect_image`
23
- hints *before they enter the durable log*, on the `agent/pre-step`
24
- waterfall (the one seam where the harness lets a plugin replace the
25
- messages of a proposed step). Images already logged by an older version
26
- are repaired lazily with a surface `replace` on the session's first
27
- pre-step. Only models listed in `multimodalModels` receive image blocks
28
- directly; a model's declared `inputModalities` are never consulted,
29
- because profiles routinely declare `input: [text, image]` on text-only
30
- models just to pass the harness's prompt-admission check.
31
-
32
- - Zero dependencies beyond the dsh SDK — works with any compatible endpoint:
33
- OpenAI GPT-4o, Qwen-VL (DashScope), GLM-4V (Zhipu), Moonshot, Gemini
34
- compatible endpoints, local Ollama, etc.
35
- - Registered on the **global tools layer**: every agent in the process can
36
- call `inspect_image`.
37
- - **Web UI settings section (v0.3.0)**: Settings → 视觉模型 edits the
38
- `tool-vision` namespace (API endpoint, write-only key, model, bridge
39
- options) in `settings.yaml`; changes hot-apply without a restart. The API
40
- key lives in `settings.yaml`, not the profile patch. Mount by package name
41
- (`name: 'dsh-tool-vision'`) so the web client bundle is discovered.
42
-
43
- ## Install
44
-
45
- Mount in a profile patch (`$DSH_HOME/profiles/<name>/cordis.patch.yml`):
46
-
47
- ```yaml
48
- - insert:
49
- - id: tool-vision
50
- name: 'dsh-tool-vision' # after: pnpm add dsh-tool-vision in the profile
51
- config:
52
- baseURL: 'https://api.openai.com/v1'
53
- apiKeyEnv: 'VISION_API_KEY'
54
- model: 'gpt-4o-mini'
55
- ```
56
-
57
- Or load it from a local path without npm:
58
-
59
- ```yaml
60
- - id: tool-vision
61
- name: './plugins/dsh-tool-vision/index.js'
62
- ```
63
-
64
- ## Config
65
-
66
- | Field | Default | Meaning |
67
- |---|---|---|
68
- | `baseURL` | `https://api.openai.com/v1` | OpenAI-compatible API base URL. |
69
- | `apiKey` | `''` | API key (takes precedence over env). |
70
- | `apiKeyEnv` | `VISION_API_KEY` | Env var holding the key. |
71
- | `model` | `gpt-4o-mini` | Vision model id. |
72
- | `maxTokens` | `1024` | Max output tokens. |
73
- | `timeoutMs` | `60000` | Per-request timeout. |
74
- | `maxImageBytes` | `10MB` | Largest accepted local image. |
75
- | `description` | default | Tool description shown to the model. |
76
- | `bridgeTextOnly` | `true` | Bridge pasted images to text hints on models that cannot see images. |
77
- | `bridgeExportDir` | temp | Export dir for bridged images (`os.tmpdir()/dsh-vision-bridge`). |
78
- | `multimodalModels` | `[]` | Model ids that receive image blocks directly (e.g. `mimo-v2.5`). |
79
-
80
- ## Image bridge setup
81
-
82
- 1. In your model settings, declare image input on the models you paste
83
- images onto, so the harness admits image messages (pi-ai style):
84
- ```yaml
85
- llm-pi-ai:
86
- providers:
87
- your-provider:
88
- models:
89
- - id: deepseek-v4-flash
90
- input: [text, image]
91
- ```
92
- 2. List genuinely multimodal models in the plugin config so they receive
93
- image blocks untouched:
94
- ```yaml
95
- - id: tool-vision
96
- name: 'dsh-tool-vision'
97
- config:
98
- multimodalModels: ['mimo-v2.5', 'grok-4.5']
99
- ```
100
-
101
- Then pasting an image while on a text-only model stores a hint like
102
- `[User sent an image, exported to: <path>. Inspect it with the inspect_image tool...]`
103
- in the transcript (the pasted image no longer renders as pixels in that
104
- message), and the agent inspects it through the configured vision endpoint.
105
-
106
- > Why not `llm/stream`? The harness freezes every request and the agent-loop
107
- > invariant fails any request whose messages diverge from the session-log
108
- > derivation (`log-reconstruction desync`), and this cordis waterfall's
109
- > `next()` cannot replace request arguments. The `agent/pre-step` waterfall is
110
- > the supported seam: its decision messages *become* the durable log, so the
111
- > invariant stays satisfied.
112
-
113
- Key resolution order: `config.apiKey` → `process.env[apiKeyEnv]` →
114
- `process.env.OPENAI_API_KEY`.
115
-
116
- ## Tool: `inspect_image`
117
-
118
- | Arg | Required | Meaning |
119
- |---|---|---|
120
- | `path` | ✅ | Image path (absolute, or relative to the current workspace) or http(s) URL. |
121
- | `question` | – | Optional specific question about the image. |
122
- | `detail` | – | `auto` / `low` / `high` resolution hint. |
123
-
124
- Example endpoints (`baseURL`):
125
-
126
- - **OpenAI**: `https://api.openai.com/v1` — `gpt-4o`, `gpt-4o-mini`
127
- - **Alibaba DashScope (Qwen-VL)**: `https://dashscope.aliyuncs.com/compatible-mode/v1` — `qwen-vl-plus`, `qwen-vl-max`
128
- - **Zhipu (GLM-4V)**: `https://open.bigmodel.cn/api/paas/v4` — `glm-4v-flash` (free tier), `glm-4v-plus`
129
- - **Moonshot (Kimi)**: `https://api.moonshot.cn/v1` — `moonshot-v1-8k-vision-preview`
130
- - **Ollama local**: `http://localhost:11434/v1` — `llama3.2-vision` (no key)
131
-
132
-
133
- > **Note for users**
134
- > - This plugin is a standard **profile bundle** (`dsh.bundle.patch`):
135
- > `dsh plugin --profile web add dsh-tool-vision` installs and mounts it in
136
- > one step — no manual `cordis.patch.yml` edits needed.
137
- > - The settings section needs the `dsh-host-apiproxy` namespace allowlist;
138
- > the plugin patches it automatically on first start — **restart `dsh web`
139
- > once more** and the section appears. A dsh update overwrites the patch;
140
- > the next plugin start re-applies it.
141
- > - Settings changes hot-apply (no restart needed).
142
- > - Tested against DSH `0.1.0-rc.6`.
143
-
144
-
145
- ## Limitations
146
-
147
- - A bridged image enters the conversation as a text hint (a transcript, not
148
- pixels) — pixel-precise in-context reasoning is not available to text-only
149
- models; the vision model's description comes back through `inspect_image`.
150
- - Images are base64-transferred; mind privacy and size limits.
151
- - Independent of the dsh-llm routing/retry system; failures return clear
152
- errors to the agent.
153
-
154
- ## License
155
-
156
- MIT
1
+ # dsh-tool-vision
2
+
3
+ [![中文文档](https://img.shields.io/badge/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3-blue)](README.zh.md)
4
+
5
+ **GitHub**: [Scorp1o117/dsh-tool-vision](https://github.com/Scorp1o117/dsh-tool-vision) · **npm**: [dsh-tool-vision](https://www.npmjs.com/package/dsh-tool-vision)
6
+
7
+ [![Enhancement Suite](https://img.shields.io/badge/part%20of-Enhancement%20Suite-3964fe)](https://github.com/Scorp1o117/dsh-enhancement-suite) [![npm](https://img.shields.io/npm/v/dsh-enhancement-suite)](https://www.npmjs.com/package/dsh-enhancement-suite)
8
+
9
+ Part of the [DeepSeek Harness Enhancement Suite](https://github.com/Scorp1o117/dsh-enhancement-suite) — Vision · Soul/Persona · Long-term Memory · Plugin Marketplace.
10
+
11
+ External vision model for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).
12
+
13
+ DeepSeek's own models are text-only, and the harness derives every model
14
+ request strictly from the session log (`llm/stream` requests must equal the
15
+ durable derivation — the agent-loop invariant). This plugin bridges the gap
16
+ in two ways:
17
+
18
+ 1. **`inspect_image` tool** — sends an image (local file, or http(s) URL) to
19
+ **any OpenAI-compatible** `/chat/completions` endpoint that supports
20
+ `image_url` content parts, and returns the vision model's textual answer
21
+ into the agent loop.
22
+ 2. **Image bridge (v0.2.1)** — pasted images are turned into `inspect_image`
23
+ hints *before they enter the durable log*, on the `agent/pre-step`
24
+ waterfall (the one seam where the harness lets a plugin replace the
25
+ messages of a proposed step). Images already logged by an older version
26
+ are repaired lazily with a surface `replace` on the session's first
27
+ pre-step. Only models listed in `multimodalModels` receive image blocks
28
+ directly; a model's declared `inputModalities` are never consulted,
29
+ because profiles routinely declare `input: [text, image]` on text-only
30
+ models just to pass the harness's prompt-admission check.
31
+
32
+ - Zero dependencies beyond the dsh SDK — works with any compatible endpoint:
33
+ OpenAI GPT-4o, Qwen-VL (DashScope), GLM-4V (Zhipu), Moonshot, Gemini
34
+ compatible endpoints, local Ollama, etc.
35
+ - Registered on the **global tools layer**: every agent in the process can
36
+ call `inspect_image`.
37
+ - **Web UI settings section (v0.3.0)**: Settings → 视觉模型 edits the
38
+ `tool-vision` namespace (API endpoint, write-only key, model, bridge
39
+ options) in `settings.yaml`; changes hot-apply without a restart. The API
40
+ key lives in `settings.yaml`, not the profile patch. Mount by package name
41
+ (`name: 'dsh-tool-vision'`) so the web client bundle is discovered.
42
+
43
+ ## Install
44
+
45
+ Mount in a profile patch (`$DSH_HOME/profiles/<name>/cordis.patch.yml`):
46
+
47
+ ```yaml
48
+ - insert:
49
+ - id: tool-vision
50
+ name: 'dsh-tool-vision' # after: pnpm add dsh-tool-vision in the profile
51
+ config:
52
+ baseURL: 'https://api.openai.com/v1'
53
+ apiKeyEnv: 'VISION_API_KEY'
54
+ model: 'gpt-4o-mini'
55
+ ```
56
+
57
+ Or load it from a local path without npm:
58
+
59
+ ```yaml
60
+ - id: tool-vision
61
+ name: './plugins/dsh-tool-vision/index.js'
62
+ ```
63
+
64
+ ## Config
65
+
66
+ | Field | Default | Meaning |
67
+ |---|---|---|
68
+ | `baseURL` | `https://api.openai.com/v1` | OpenAI-compatible API base URL. |
69
+ | `apiKey` | `''` | API key (takes precedence over env). |
70
+ | `apiKeyEnv` | `VISION_API_KEY` | Env var holding the key. |
71
+ | `model` | `gpt-4o-mini` | Vision model id. |
72
+ | `maxTokens` | `1024` | Max output tokens. |
73
+ | `timeoutMs` | `60000` | Per-request timeout. |
74
+ | `maxImageBytes` | `10MB` | Largest accepted local image. |
75
+ | `description` | default | Tool description shown to the model. |
76
+ | `bridgeTextOnly` | `true` | Bridge pasted images to text hints on models that cannot see images. |
77
+ | `bridgeExportDir` | temp | Export dir for bridged images (`os.tmpdir()/dsh-vision-bridge`). |
78
+ | `multimodalModels` | `[]` | Model ids that receive image blocks directly (e.g. `mimo-v2.5`). |
79
+ | `bridgePreview` | `true` | Inline preview for bridged images: thumbnail above the hint text in the user bubble (click to zoom). |
80
+ | `bridgePreviewScanIntervalMs` | `2000` | Fallback scan interval for the preview scanner (ms); `0` disables the fallback. |
81
+ | `bridgePreviewHideHint` | `true` | Hide the bridged hint text once the preview image has loaded (kept on failure — safe degradation). |
82
+ | `bridgeAutoImage` | `true` | While the bridge is on, report image input capability for **every** model to the host admission gate, so pasted images are accepted on text-only models without hand-editing provider configs. |
83
+
84
+ ## Image bridge setup
85
+
86
+ 1. (Optional, usually not needed) If `bridgeAutoImage` is disabled, declare
87
+ image input on the models you paste images onto, so the harness admits
88
+ image messages (pi-ai style):
89
+ ```yaml
90
+ llm-pi-ai:
91
+ providers:
92
+ your-provider:
93
+ models:
94
+ - id: deepseek-v4-flash
95
+ input: [text, image]
96
+ ```
97
+ 2. List genuinely multimodal models in the plugin config so they receive
98
+ image blocks untouched:
99
+ ```yaml
100
+ - id: tool-vision
101
+ name: 'dsh-tool-vision'
102
+ config:
103
+ multimodalModels: ['mimo-v2.5', 'grok-4.5']
104
+ ```
105
+
106
+ Then pasting an image while on a text-only model stores a hint like
107
+ `[User sent an image, exported to: <path>. Inspect it with the inspect_image tool...]`
108
+ in the transcript (the pasted image no longer renders as pixels in that
109
+ message), and the agent inspects it through the configured vision endpoint.
110
+
111
+ > Why not `llm/stream`? The harness freezes every request and the agent-loop
112
+ > invariant fails any request whose messages diverge from the session-log
113
+ > derivation (`log-reconstruction desync`), and this cordis waterfall's
114
+ > `next()` cannot replace request arguments. The `agent/pre-step` waterfall is
115
+ > the supported seam: its decision messages *become* the durable log, so the
116
+ > invariant stays satisfied.
117
+
118
+ Key resolution order: `config.apiKey` → `process.env[apiKeyEnv]` →
119
+ `process.env.OPENAI_API_KEY`.
120
+
121
+ ## Bridge image preview (v0.4.0)
122
+
123
+ On text-only models, pasted images become `[User sent an image...]` hint
124
+ text in the transcript. With `bridgePreview` enabled (default), the browser
125
+ half renders those hints as inline thumbnails **in the display layer only**:
126
+
127
+ - **Thumbnail + lightbox**: click to zoom full-screen; click anywhere or
128
+ press `Esc` to close;
129
+ - **Immediate + fallback**: new messages are handled by a MutationObserver;
130
+ history is back-filled by a periodic scan (interval via
131
+ `bridgePreviewScanIntervalMs`);
132
+ - **Hide the hint (P2)**: with `bridgePreviewHideHint` on, the hint text is
133
+ hidden once the image has loaded, leaving just the image; on load failure
134
+ the text stays (safe degradation — never "no image AND no text");
135
+ - **Precise identification**: bridged hints carry an invisible prefix marker
136
+ (`\u200b[bridge]`), so ordinary user text that happens to contain
137
+ "exported to:" is never misidentified;
138
+ - **Display-layer red line**: persisted messages, the transcript, the
139
+ model-facing text and the `inspect_image` chain are untouched.
140
+
141
+ Preview images are served by the same-origin loopback route
142
+ `/plugins/dsh-tool-vision/image`: read-only access to the bridge export
143
+ directory, localhost-only Host, image extensions only, ≤ 20MB per file,
144
+ path-traversal protected.
145
+
146
+ ## Tool: `inspect_image`
147
+
148
+ | Arg | Required | Meaning |
149
+ |---|---|---|
150
+ | `path` | ✅ | Image path (absolute, or relative to the current workspace) or http(s) URL. |
151
+ | `question` | – | Optional specific question about the image. |
152
+ | `detail` | – | `auto` / `low` / `high` resolution hint. |
153
+
154
+ Example endpoints (`baseURL`):
155
+
156
+ - **OpenAI**: `https://api.openai.com/v1` — `gpt-4o`, `gpt-4o-mini`
157
+ - **Alibaba DashScope (Qwen-VL)**: `https://dashscope.aliyuncs.com/compatible-mode/v1` — `qwen-vl-plus`, `qwen-vl-max`
158
+ - **Zhipu (GLM-4V)**: `https://open.bigmodel.cn/api/paas/v4` — `glm-4v-flash` (free tier), `glm-4v-plus`
159
+ - **Moonshot (Kimi)**: `https://api.moonshot.cn/v1` — `moonshot-v1-8k-vision-preview`
160
+ - **Ollama local**: `http://localhost:11434/v1` — `llama3.2-vision` (no key)
161
+
162
+
163
+ > **Note for users**
164
+ > - This plugin is a standard **profile bundle** (`dsh.bundle.patch`):
165
+ > `dsh plugin --profile web add dsh-tool-vision` installs and mounts it in
166
+ > one step — no manual `cordis.patch.yml` edits needed.
167
+ > - The settings section needs the `dsh-host-apiproxy` namespace allowlist;
168
+ > the plugin patches it automatically on first start — **restart `dsh web`
169
+ > once more** and the section appears. A dsh update overwrites the patch;
170
+ > the next plugin start re-applies it.
171
+ > - Settings changes hot-apply (no restart needed).
172
+ > - Tested against DSH `0.1.0-rc.6`.
173
+
174
+ ## Pixel-level vision tools (v0.6.0, ported from dsh-vision-router)
175
+
176
+ 14 `vision_*` tools driven by the **same** configured endpoint as
177
+ `inspect_image` (baseURL/apiKey/model) — no provider chain, no local models,
178
+ no extra settings:
179
+
180
+ | Tool | Purpose |
181
+ |---|---|
182
+ | `vision_describe` | Image Q&A / multi-image comparison (optional structured JSON) |
183
+ | `vision_ground` | Locate a target and return its ORIGINAL-pixel bounding box |
184
+ | `vision_detect` | Enumerate elements (buttons, inputs, icons…) with numbered boxes |
185
+ | `vision_crop` | Crop a pixel region to a PNG artifact |
186
+ | `vision_pixel_diff` | Per-pixel comparison: ratio, worst regions, heatmap, report |
187
+ | `vision_colors` | Dominant-color quantization for palette matching |
188
+ | `vision_ocr` | Verbatim text transcription (letters only — not scene analysis) |
189
+ | `vision_long_screenshot_ocr` | Chunked long-screenshot transcription into Markdown |
190
+ | `vision_trace` | Potrace vectorization into colored SVG (worker-thread, safe) |
191
+ | `vision_extract_foreground` | Solid-background removal → transparent PNG |
192
+ | `vision_html_screenshot` | Headless render of a local .html (network blocked) |
193
+ | `vision_screenshot` | Desktop capture (privacy-gated: enable `desktopScreenshot` in settings; Win: PowerShell / macOS: screencapture / Linux: import/scrot) |
194
+ | `vision_present` | Publish a generated image to the user via the host attachment store |
195
+ | `vision_materialize` | Copy an attachment/local image into the workspace as a real path |
196
+
197
+ Quality & safety details:
198
+
199
+ - **Content-hash cache** keyed by endpoint+model+image+question (no stale
200
+ answers across model switches, failures are never cached).
201
+ - **Uniform 4MP downscale** before every model call; oversized inputs are
202
+ rejected with a clear error (stat pre-check, 20MB cap on both file and
203
+ attachment paths).
204
+ - **Rate-limit / 5xx auto-retry** with Retry-After-aware backoff; endpoint
205
+ **content-safety rejections** are surfaced as `VISION_CONTENT_FILTERED`
206
+ instead of a generic backend error.
207
+ - **Long-OCR bounds**: 120s total budget, 40-chunk cap, cancellation checks,
208
+ stop-on-first-backend-failure.
209
+ - **Path containment** for relative inputs; artifacts land in
210
+ `<workspace>/.dsh-tool-vision/`.
211
+
212
+ Requires `sharp` / `potrace` / `puppeteer-core` (declared as optional
213
+ dependencies: a failed platform install never blocks the plugin; missing ones
214
+ degrade lazily with an install hint and never break other tools).
215
+
216
+ `vision_screenshot` is privacy-sensitive and therefore **not registered by
217
+ default** — set `desktopScreenshot: true` in the tool-vision settings to
218
+ enable desktop capture.
219
+
220
+ ## Limitations
221
+
222
+ - A bridged image enters the conversation as a text hint (a transcript, not
223
+ pixels) — pixel-precise in-context reasoning is not available to text-only
224
+ models; the vision model's description comes back through `inspect_image`.
225
+ - Images are base64-transferred; mind privacy and size limits.
226
+ - Independent of the dsh-llm routing/retry system; failures return clear
227
+ errors to the agent.
228
+
229
+ ## License
230
+
231
+ MIT — bridge preview & integration: xing666173. Pixel vision tools ported
232
+ from [dsh-vision-router](https://github.com/ysr666/dsh-vision-router)
233
+ (© ysr666, MIT) with gratitude.