# deepseek-harness-desktop

> Adds image understanding to text-only models: sends images to OpenAI-compatible vision endpoints for parsing, with only text results returned to the conversation and image bytes excluded from logs.

## Metadata

- Author: [@ningbainb](https://github.com/ningbainb)
- Repo: <https://github.com/ningbainb/deepseek-harness-desktop.git>
- GitHub: [ningbainb/deepseek-harness-desktop](https://github.com/ningbainb/deepseek-harness-desktop)
- Stars: 156
- Language: TypeScript
- License: [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)
- Homepage: <https://ningbainb.github.io/deepseek-harness-desktop/>
- Topics: `ai-agent`, `ai-coding-assistant`, `codex`, `deepseek`, `deepseek-harness`, `desktop-app`, `dsh`, `dsh-plugin`, `electron`, `electron-app`, `gui`, `open-source`, `plugin-system`, `plugins`, `remote-access`, `skills`, `ssh-client`, `windows`, `windows-desktop`
- Forks: 5
- Open Issues: 6
- Last push: 2026-08-20T05:29:52.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:ningbainb/deepseek-harness-desktop/packages/dsh-tool-describe-image
```

## Wiki

## 一句话定位
为 DSH 中的纯文本模型补齐"看图"能力：在工具调用时把图片交给 OpenAI 兼容的视觉端点解析，仅把模型返回的文字结果送回会话，图片字节本身不进对话日志。

## 核心能力
- 给纯文本模型补齐图像理解：模型可主动调用 `describe_image` 工具，分析一张图片并拿到文字描述
- 接受三种图片来源：本地绝对路径、`http(s)` 链接（拒绝重定向）、会话附件引用（拖拽/粘贴产生的 markdown 引用）
- 直接在纯文本会话里发图：拖拽或粘贴图片会被自动改写为引用，图片正常渲染，模型通过工具分析
- 支持自定义指令：调用时可传 `prompt`（OCR、图表解读、UI 诊断、翻译等），未传则用 `defaultPrompt` 兜底
- 双协议适配：`chat-completions` 走 `/chat/completions`，`responses` 走 `/responses`，覆盖 Qwen-VL、GLM-4V、GPT-4o、Ollama 等
- 实时配置卡：设置 → 插件配置 → Web UI 插件组 → 图像理解，修改端点、模型、密钥、上限后即时生效，无需重启

## 技术实现
- **语言**: TypeScript
- **关键依赖**: `@deepseek-ai/cordis`（cordis 插件运行时）、`@deepseek-ai/dsh-tools`（模型工具注册）、`@deepseek-ai/dsh-credentials`（密钥解析服务）、`schemastery`（设置卡 schema）
- **架构模式**: host + client 双半区 cordis bundle；host 半区在 DSH 进程注册 `describe_image` 工具与 `/describe-image/attach` / `/describe-image/raw` 路由，client 半区在浏览器侧改写图片发送并渲染设置卡；通过 `cordis.patch.yml` 注入，零修改 DSH 源码
- **入口文件**: `src/index.ts`（host 半区）、`src/client/index.ts`（浏览器半区）

## 适用场景
当你在 DSH 中使用 DeepSeek V4 这类不支持原生图像输入的文本模型，又希望它能"看图"：上传截图让模型描述界面、把表格图转 CSV、做 OCR 识别、对 UI 截图做问题诊断等。插件把"图"翻译成"描述文字"喂给文本模型，整个过程图片字节不写入会话历史，规避敏感截图泄入日志的风险。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.7+ | devDependencies 中各 `@deepseek-ai/dsh-*` 包均声明 `^0.1.0-rc.7` |
| Node | ^22.19.0 或 >=24.0.0 | `engines.node` 字段声明 |
| 平台 | 跨平台 | host 半区跑在 Node，client 半区跑在浏览器，无需操作系统特定依赖 |
| 原生模块 | 无 | 仅依赖官方 SDK 与 schemastery，无需编译原生扩展 |

## 安装方式
```bash
dsh plugin --profile web add github:ningbainb/deepseek-harness-desktop/packages/dsh-tool-describe-image
```

## 配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| `baseURL` | 字符串 | OpenAI 兼容视觉端点的根地址（如 `https://dashscope.aliyuncs.com/compatible-mode/v1`），末尾斜杠会被自动去掉 | 必填，无默认 |
| `model` | 字符串 | 要调用的视觉模型 id | 必填，无默认 |
| `apiKey` | 字符串 | 内联 API 密钥，本地调试用，建议用环境变量注入而非明文 | 无（未设置时按 `apiKeyEnv` 解析） |
| `apiKeyEnv` | 字符串 | 凭证引用对应的环境变量名；插件按"内联 key → 凭证服务 → 启动环境"逐级回退 | `VISION_API_KEY` |
| `defaultPrompt` | 字符串 | 模型未传 `prompt` 时的兜底指令（让模型"按事实描述、转录可读文字、提示异常"） | 见源码中 `DEFAULT_PROMPT` |
| `apiStyle` | 枚举 | 端点协议形态：`chat-completions` 走 `/chat/completions`，`responses` 走 `/responses` | `chat-completions` |
| `maxBytes` | 整数 | 图片字节上限（本地文件与下载链接共用），超出则拒绝 | `10485760`（10 MiB） |
| `maxOutputTokens` | 整数 | 单次请求输出 token 上限，分别映射为 `max_tokens` 或 `max_output_tokens` | `1024` |
| `timeoutMs` | 整数 | 单次视觉请求超时（毫秒） | `60000` |

## 常见问题
**Q: 第一次调用就报错说 baseURL 不对，怎么修？**

A: 打开"设置 → 插件配置 → Web UI 插件组 → 图像理解"卡片，把端点根地址（如 https://dashscope.aliyuncs.com/compatible-mode/v1）和模型 id 填进去，保存后立即生效，不用重启。

**Q: API key 应该写在哪里比较安全？**

A: 不建议把 key 直接写进配置文件。默认会从环境变量 VISION_API_KEY 读取（可通过 apiKeyEnv 改成别的名字），也可以在设置卡里粘贴内联 apiKey 用于本地调试；密钥不会写入日志。

**Q: 在纯文本会话里拖图片，模型能"看到"吗？**

A: 不能直接看到。插件在发送时会自动把图片块改写为引用（形如 ![图片](/describe-image/raw/sha256:…)），图片字节经 attach 路由上传到附件存储、只把引用文本带进会话，模型再通过 describe_image 工具间接"看到"并分析。

**Q: 协议选 chat-completions 还是 responses？**

A: 默认 chat-completions，访问 baseURL/chat/completions；如果端点只提供 OpenAI Responses API，把 apiStyle 设为 responses，会改用 baseURL/responses 和 input/max_output_tokens/output_text 形态。

**Q: 一张图片不够用，能不能一次给多张？**

A: 目前一次只能处理一张图片，不支持多图输入，也不支持追问上一张图或输出坐标框等结构化结果，这是已声明的功能边界。

**Q: 把插件卸载干净要怎么操作？**

A: 在 dsh profile 中移除 describe-image 这个组合条目（cordis.patch.yml 对应的行），并按需清理本地 .npmrc 与符号链接；插件本身不向宿主持久化任何状态。

## 上手难度
入门 — 配置项集中在设置卡的一张表单里，填好端点、模型、API key 就能用；无需编写代码或修改 DSH 源码。

## 已知问题与限制
- 仅做 magic-byte 头校验、不解码图片内容：扩展名正确但文件实际损坏的情况下，要等到请求打到视觉端点才会报错
- 单图单答：每次 `describe_image` 调用只能处理一张图片，不支持多图输入、不支持追问上一张图、不输出坐标/框等结构化结果
- OCR 也算一次 VLM 调用：纯文字提取场景下仍消耗视觉模型额度，可将 `baseURL` 指向更便宜的 OCR 专用端点来降本
- 仅 OpenAI 兼容协议：只支持 Chat Completions 与 Responses 两种请求/响应形态，使用其他私有协议的厂商需要单独适配
- 响应体按 `maxOutputTokens * 8 + 64 KiB` 截断后解析，模型回答极长时被截断的风险由 `maxOutputTokens` 控制

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [deepseek-harness-desktop](https://deepseek-plugin.org/plugins/ningbainb/deepseek-harness-desktop/packages/dsh-tool-describe-image)
Wiki generated by AI (model: `MiniMax-M3`)
