dsh-deepseek-web-image
带图片输入支持的 DeepSeek Web 插件(非官方)
这是一个针对 y-wi/dsh-deepseek-web 的二次修改版本。
上游 v1.1.1 已经写好图片上传的底层基础设施,但适配层从未接线,
入口反而硬性拒绝图片。本仓库补齐了最后一环,让 DeepSeek Web 真正能看图。
与上游的差异
不只是"能发图",而是对齐 Harness 的多模态一等公民契约。
| 上游 v1.1.1 | 本仓库 | |
|---|---|---|
inputModalities |
['text'] |
['text', 'image'] |
| 粘贴图片 | 直接抛 UNSUPPORTED_IMAGE |
上传后随请求发送 |
ref_file_ids |
定义了但从不传 | 已贯通到 client.complete |
| 提示词附件说明 | 有模板但从不赋值 | 如实反映本轮附件数 |
| 上传失败 | — | 降级为文字占位,不中断对话 |
imageRequestPricing |
未实现(中性估算) | DeepSeek 视觉 token 精确计价 |
imageRequestTarget |
未实现(基类恒等) | 与实际上传尺寸严格一致 |
| 模型上下文元数据 | 无 | contextWindow + defaultMaxTokens |
| 工具结果中的图片 | 丢弃 | 递归收集并上传 |
| 多轮 / 重建会话 | 历史图片丢失 | 按计划增量取图,不重传 |
| 单消息图片上限 | — | 16 张,超出保留最新 |
安装
方式一:插件界面
打开 插件 → 添加插件,粘贴下面这个地址,安装后启用:
https://github.com/dz3197578117-lab/dsh-deepseek-web-image/releases/download/v1.1.1-image.2/dsh-deepseek-web-image-1.1.1-image.2.tgz
方式二:本地 tarball
cd "$env:USERPROFILE\.dsh\profiles\desktop"
pnpm add "file:C:/path/to/dsh-deepseek-web-image-1.1.1-image.2.tgz"
启用后进入 插件 → DeepSeek Web → 使用 DeepSeek 登录,在浏览器窗口完成登录。
需要 DeepSeek Harness
0.2.1-rc.2(>=0.2.1-rc.2 <0.3.0)。旧版 0.1 宿主请用上游 1.0.x。
⚠️ 安装后需重启 DeepSeek Harness,插件在宿主启动时加载。
v1.1.1-image.1的 tarball 缺少package/前缀、无法安装,请勿使用。
实现要点
改动集中在 lib/index.js 适配层(124409 → 130108 字节):
第一层:让图片真的发得出去
- 声明图片能力 — 两个模型
inputModalities: ['text', 'image'] - 删除入口拦截 — 移除
UNSUPPORTED_IMAGE的throw - 新增
uploadTurnImages()— 上传图片,按model:attachmentId缓存 - 贯通
refFileIds—executeConversation→completeWithRepair→completeChecked→client.complete(首次发送与 rebuild 重试都带) - 注入依赖 — adapter 增加
resolveAttachments: () => ctx.get('attachments')
第二层:对齐多模态一等公民契约
imageRequestPricing()— 移植 DeepSeek 官方视觉 token 算法 (14px patch 网格、3:1 降采样、544×544 放大下限、1024 token 上限), 277 种几何尺寸与 Harness 官方实现逐值比对,零偏差imageRequestTarget()— 暴露与实际上传严格一致的尺寸与字节目标, 让 Harness 的 token 计量、截图消费方看到真实值- 模型上下文元数据 —
contextWindow: 131072+defaultMaxTokens: 8192 - 工具结果图片 — 通用递归收集(带环路与深度保护),不再丢弃
- 增量取图 — 按
planConversation结果决定收集范围:续聊只取增量, 重建才取全量,避免重复上传 - 上限与保留策略 — 单消息 16 张,超出时保留最新(丢最旧)
设计取舍
- 缓存:同一张图(同
attachmentId+ model)不重复上传 - 失败降级:单张上传失败只会让 prompt 少一句 "Treat them as visual input", 并明确告知模型「N 张不可见」——绝不因为图片问题让整轮对话失败
- 中止透传:
signal.aborted时错误正常上抛,不吞掉 - 不计费幻觉:未上传成功的图片
visualTokens记为 0,不虚报
验证
| 层级 | 项目 | 结果 |
|---|---|---|
| 语法 | node --check |
✅ |
| 单元(基础) | 19 项(notice / collect / target / media) | ✅ 19/19 |
| 单元(新增) | 15 项(递归收集 / 环路 / token 边界) | ✅ 15/15 |
| 集成 | 16 项(缓存 / 降级 / 上限 / 中止 / 保留策略) | ✅ 16/16 |
| token 一致性 | 277 种几何 vs 官方实现 | ✅ 零偏差 |
| 端到端(单图) | 上传 PNG → ref_file_ids → 描述 |
✅ |
| 端到端(多图) | 两张图分别上传 → 分别描述 | ✅ |
单图端到端实际输出:
A red circle, a blue square, and a green triangle are arranged on a white background.
多图端到端实际输出(两张独立图片):
Image 1: A red circle, a blue square, and a green triangle are arranged on a white background.
Image 2: A yellow circle is centered inside a black rectangular frame on a white background.
两张图内容完全不同,模型分别准确描述,证明多附件链路正确。
已知边界
- 改的是构建产物
lib/index.js,不是 TypeScript 源码。上游源码修复后本仓库即无必要 contextWindow/defaultMaxTokens是保守取值,非上游权威声明- 只支持
image/png、image/jpeg、image/webp、image/gif - 未实现
image/offload事件协议(超限走本地保留策略而非 Harness 的 compaction 流程)
许可证与声明
MIT,见 LICENSE。原始代码版权归上游贡献者所有。
本插件通过兼容层访问 DeepSeek Web,不是官方 Open Platform 适配器, 不绕过 CAPTCHA / WAF 或账号访问控制。请遵守 DeepSeek 的使用条款, 仅供个人学习使用。
No comments yet. Be the first to write one.