快速了解
它能做什么
为 DeepSeek Harness 网页编辑器扩展 PDF、Office、文本和更多图像格式的附件处理能力。
本站提供的是中文说明,不代表该项目或 Plugin 自身提供中文界面;语言支持请以上游文档为准。
Web Profile
Not declared in supplied evidence
证据已验证
核对日期 2026/9/16 UTC 14:09
有代码证据的贡献
它为 DSH 增加什么
为编辑器增加附件按钮,以及全页拖放和粘贴处理,用于文档转换和附件卡片。
机制证据 ↗选择前先看
该插件为 DeepSeek Harness 网页编辑器添加附件按钮,并支持拖放和粘贴。它会将 PDF 和 Office 文档提取为可移除的文档卡片,将图像继续交给原生图片草稿栏;超长文档会保存到工作区并以索引卡形式提供,避免静默截断。
适合谁
需要让 DeepSeek Harness 网页端模型阅读 PDF、扫描件、Office 文档、电子书或非常见图像格式的用户。
常见任务
- 附加带文本层的 PDF,并在发送时附带带文件来源标记的提取文本。
- 将 DOCX、XLSX 或 PPTX 转换为发送前可查看和移除的文档卡片。
- 在配置支持时,对扫描版 PDF 使用 OCR 或将页面转为图片。
- 将大型文档保留在会话工作区中,让模型根据索引指针读取。
权限与数据
会在浏览器和宿主转换链路中处理所选附件;可选集成可能向外部服务传输内容。
权限- 向网页编辑器添加 UI,并拦截文件选择、拖放和粘贴事件。
- 注册附件转换路由,并将超长附件内容写入会话工作区。
- 提取出的文本和转换元数据可能保存在会话工作区的附件缓存中。
- 工作区零拷贝检查会向宿主发送文件名、大小和完整 SHA-256;命中时可引用文件而不上传文件内容。
- 启用后,可选的百度 OCR 会接收扫描页 JPEG。
- 配置后,可选的 OpenAI 兼容视觉 OCR 和外部文档解析服务会接收文档内容。
- 启用百度 OCR 需要 API Key 和 Secret。
- 远程视觉 OCR 可能需要端点、模型和可选 API Key。
局限
- 提供的证据未声明 DeepSeek Harness 的版本范围。
- 旧版 DOC、XLS、PPT 转换需要 LibreOffice;RTF 需要 Pandoc。
- OCR 可能失败并回退为页面图片;低置信度 OCR 文本不会被注入。
- 暂不转换 iWork、压缩包和音视频文件。
- 文档卡片的发送合并依赖未公开的 Harness API,核心升级后可能失效。
DSHub 已核对
- 已验证固定源提交、包结构和 Bundle patch。
- 清单声明了 web 客户端 Bundle 以及 Node.js >=20。
- 该包声明 Apache-2.0 许可证。
DSHub 未核对
- 未执行或验证安装、运行时行为、转换质量以及对特定 Harness 版本的兼容性。
- 提供的记录中未找到对应 npm 包版本。
固定版本安装
安装 Attachment Format Expansion for DeepSeek Harness
这个Plugin Bundle没有 DSH Plugin 安装操作,请根据源码文档使用真实交付方式。
维护者原文
项目 README
dsh-attachment-formats — Attachment Format Expansion (Codex-style)
English | 中文
A DeepSeek Harness web plugin that makes the composer accept many more attachment formats, Codex-style. Zero core-package changes: a pure plugin that reuses the harness-native image draft rail, upload limits, history rendering and model request pipeline.
Supported formats
| File | Handling | Destination |
|---|---|---|
| PNG / JPEG / WebP / GIF | native pipeline (plugin not involved) | image draft rail (native) |
| PDF (with text layer) | text-layer extraction (≤40 pages via the pymupdf4llm high-fidelity engine; larger/unavailable falls back to pdfjs) | full text on a document card (merged on send); over-limit → workspace spill + index card |
| PDF (scanned / no text layer) | tesseract.js OCR (accepted only at confidence ≥45), falls back to page images | OCR success → text channel; failure → image draft rail (vision models only) |
| Word (.docx) / Excel (.xlsx) / PPT (.pptx) | text extraction — docx via mammoth HTML → turndown, tables kept as Markdown pipe tables | document card (merged on send); over-limit → spill + index card |
| Legacy .doc / .xls / .ppt | LibreOffice headless → docx/xlsx/pptx → standard Office pipeline (needs soffice; clear error when absent) |
document card (merged on send) |
| epub / odt / rtf | pandoc → Markdown (probe on PATH); epub/odt fall back to jszip+turndown without pandoc; rtf requires pandoc | document card (merged on send) |
| TIFF (.tiff/.tif) | sharp (libvips) → PNG pages (multi-page, ≤20) | native image draft rail |
| txt / md / json / code | read in the browser (UTF-8, GB18030 fallback) | document card (merged on send); over-limit → spill + index card |
| BMP / ICO / AVIF / SVG etc. | browser decode → canvas → PNG | native image draft rail |
| iWork / audio-video / archives | — (not yet supported; explicit notice, skipped) | — |
Document cards (Codex-style mounting, composer stays clean)
Text-like attachments that are dragged in or picked are not stuffed into the input
box: their content mounts as a document card above the composer (file name +
character count + full-text/index label, individually removable), while images keep
flowing into the native image draft rail. You type normally, and at the moment of
sending the plugin merges the card content into the message (with
[attachment: <file name>] provenance markers) before the native submit — your prompt
always stays on top and no content is lost:
- each card has a send button: send documents even without typing anything;
- pressing Enter / the native send button merges the cards first, then submits;
- cards are not merged while the model is mid-reply (they stay put for later).
Long documents (index-card mode, never silently truncated)
Text beyond 80k characters and long multi-page PDFs are not stuffed into the message. Instead:
- the host spills them into the session workspace
.dsh-attachments/<sha-16>/(content-addressed, reused on re-drop, auto-cleaned after ~7 days of no access):doc.md— PDF text layer assembled per page (leading<!-- pN -->markers), Office-extracted text, long text as-is (long JSON is prettified todoc.json);pages/pNN.png— rendered page images (≤100 pages, for vision models viaread_image; rendered lazily, only when the index-card path needs them);manifest.json— source, page/line/char counts, engine, full source SHA-256 and the converter-policy fingerprint (engine/OCR/doc-server switches invalidate the cache automatically);INDEX.md(cache root) — the aggregated list of every spilled document in this workspace.
- the message carries only a few-hundred-token index card: page/line/char counts, an outline (PDF heading heuristics, md headings, JSON first-level key tree) and reading pointers.
- the model reads page-by-page with the stock
readtool (offset/limit, line numbers as coordinates) — full summaries read through (no dropped tails), targeted lookups jump by outline; missing content is an explicit tool failure, never silent loss.
Design rationale and evidence: docs/design-longdoc.md; comparison with similar work:
docs/alternatives.md. Upgrades for current limitations (researched GitHub solutions
and v0.6 roadmap): docs/upgrade-v6.md.
Engines & OCR (v3)
- PDF text engine:
auto(default) → the venv's pymupdf4llm for ≤40 pages (high-fidelity tables/headings); pdfjs (seconds) for larger documents or when the venv is missing. Env:DSH_ATTACH_ENGINE=auto|python|builtin. - Scanned-PDF OCR: python (PyMuPDF, needs system tesseract) → tesseract.js (pure JS;
first use downloads the ~24MB eng/chi_sim language data into
vendor/tessdata/). Confidence below 45 falls back to page images with a clear reason. Env:DSH_ATTACH_OCR=auto|baidu|tesseract-js|off(see below).
Fidelity & format coverage
- DOCX tables: mammoth HTML → turndown + GFM plugin — tables survive as Markdown pipe tables (replaces the old cell-by-cell reading order).
- TIFF: decoded by sharp (libvips prebuilt binary) into PNG pages, multi-page supported (≤20 pages per file).
- epub / odt / rtf: pandoc (probed on PATH) converts to Markdown; without pandoc, epub/odt fall back to in-process jszip + turndown, rtf reports a clear install hint.
- Legacy .doc / .xls / .ppt: LibreOffice headless (
soffice, probed on PATH plus the usual Windows install locations) converts to the modern OOXML format first, then the standard Office pipeline runs. Each run uses an isolatedUserInstallationprofile to avoid lock conflicts. - PDF outlines: bookmark TOCs (
get_toc/ pdfjsgetOutline) now feed the index card's outline first; the font-size heuristic is only the fallback. Empty-bookmark PDFs are unaffected.
Cloud OCR & content-adaptive engine (zero new heavyweight deps)
- Baidu OCR API (preferred scanned-PDF OCR, free tier: 1,000 calls/month for
personal accounts / 2,000 for enterprise on both 标准版 and 高精度版, per the
official free-quota page): pages are sent as JPEG via plain HTTPS — no new
dependencies. Configure via env:
BAIDU_OCR_API_KEY/BAIDU_OCR_SECRET(console → 文字识别 → create app);DSH_ATTACH_OCR=auto|baidu|tesseract-js|off(auto = Baidu when credentials exist, else local tesseract.js);DSH_ATTACH_OCR_ACCURATE=1for the high-accuracy endpoint (separate free quota). Quota exhausted / API failure → automatic fallback to local tesseract.js with a note; forcedbaidumode reports the reason instead.
- Remote VLM OCR (optional, token-billed):
DSH_ATTACH_VLM_BASE/DSH_ATTACH_VLM_MODEL(+ optionalDSH_ATTACH_VLM_KEY) point at any OpenAI-compatible vision endpoint (olmOCR-2, GLM-4V, Qwen-VL…). Pages are transcribed one by one via chat/completions. OCR chain: Baidu → VLM → tesseract.js (or force withDSH_ATTACH_OCR=vlm). - Content-adaptive PDF engine: documents of 41–160 pages now let the Python
engine decide by vector density (sampled
get_drawings) — text-heavy manuals skip the slow high-fidelity pass and go straight to the fast pdfjs engine, while table/graphic-heavy documents still get pymupdf4llm. ≤40 pages are unchanged.
External doc server, cache page & workspace zero-copy
- External document parser (optional):
DSH_ATTACH_DOC_SERVER=<base URL>points at a parser service (PP-StructureV3paddleocr serve, MinerU, or any shim). Contract:POST {base}/convertwith multipart fieldfile→{ "ok": true, "markdown": "..." }. When configured, PDFs go to the server first; any failure falls through to the local engine chain. - Attachment cache settings page: Settings → 附件缓存 lists every spilled
document (size/engine/time) with per-item delete and clear-all, backed by
GET /api/attach-formats/cache+POST .../cache/delete+POST .../cache/clear. - Workspace zero-copy: text files between 512KB and 16MB are first resolved
against the session workspace: the browser reads the file locally to compute its
full SHA-256, then
GET /api/attach-formats/resolveasks the host to confirm a same-source file by name + size + full SHA-256 (bounded ~2.5s walk skipping dependency dirs). A hit mounts a 📎 reference card — the content is not uploaded (only the name, size and hash are sent); the model reads the path with itsreadtool. A miss falls back to the normal upload pipeline. Files over 16MB are rejected outright (no zero-copy attempt).
Context adaptation & full-text command (v2b)
- Adaptive merge limit: the client reads the token-meter
contextPressureprojection (model context window × current usage); the full-text merge limit becomes min(80k chars, headroom × 1.5) — when headroom is short, the card automatically turns into an index card with a status-bar note, so merged content can never blow up the context and get silently truncated by the API. A missing projection falls back to the fixed 80k threshold. /attachcommand (composer slash menu, host-registered):/attach list— list the spilled documents in this workspace (id/name/size/engine);/attach full <id|name>— merge the full text into model context as a next-step message (takes effect on the next message, current turn untouched); 300k-char cap with an explicit truncation notice — never silent loss.readstill works afterwards for line-precise lookup.
Interactions
- Paperclip button: composer tool row (
conversation.input.left), opens a multi-select file picker whoseacceptlist covers every format in the table above. - Drag & drop: drop a PDF / Office / text file anywhere on the page.
- Paste: copy a file and Ctrl+V into the composer (or the whole page).
Native image drag/paste stays on the harness built-in pipeline; when a single drop mixes other formats in, the plugin takes over the whole batch (converts first, then hands the produced images back to the built-in draft rail as a "synthetic drop").
Architecture
dsh-attachment-formats/
├── lib/
│ ├── index.js # host half: POST /api/attach-formats/convert + engine routing
│ ├── client.js # browser half: button/drop interception/synthetic drop/text injection/status bar
│ ├── cache.js # workspace .dsh-attachments spill/manifest/INDEX.md/cleanup
│ ├── py/pymupdf4llm_convert.py # venv high-fidelity engine (subprocess call)
│ └── convert/
│ ├── util.js # magic-byte sniffing (pdf/tiff/OLE/rtf/zip), base64, truncation
│ ├── provider.js # engine/binary detection (venv python, pandoc, LibreOffice) + subprocess bridges
│ ├── pdftext.js # pdfjs text-layer extraction: line assembly/header-footer dedup/bookmark TOC
│ ├── outline.js # md heading outline, JSON first-level key tree
│ ├── ocr.js # tesseract.js OCR (traineddata download cache/confidence)
│ ├── pdf.js # pdfjs-dist + @napi-rs/canvas → PNG/JPEG pages
│ ├── docx.js # mammoth HTML → turndown+GFM → Markdown (tables preserved)
│ ├── xlsx.js # exceljs → tab-separated text
│ ├── pptx.js # jszip + a:t text runs → per-slide text
│ ├── tiff.js # sharp (libvips) → PNG pages
│ ├── pandoc.js # pandoc → Markdown + epub/odt zip fallback
│ └── libreoffice.js # legacy .doc/.xls/.ppt → modern OOXML
├── .venv/ # (optional) pymupdf4llm engine (generated by setup, not committed)
├── vendor/tessdata/ # OCR language-data cache (downloaded on first use, not committed)
├── docs/ # design-longdoc.md / alternatives.md / upgrade-v6.md
├── scripts/smoke-*.mjs # five offline smoke suites (converters/router/client/OCR/P0)
└── cordis.patch.yml
- The host route re-sniffs magic bytes and never trusts the client-declared kind; 160MB
request cap and 64MB per-file cap;
cwdis read by the client from session state and sent with the request (it decides where the spill lands). - Tiered thresholds: full-text merge cap 80k chars (v2b lowers it adaptively by context headroom); spill page images ≤100 pages (1100px wide; PNG over the per-image byte budget falls back to JPEG); scanned-page image cap follows the deployment limit; OCR ≤20 pages per run (2000px wide), confidence <45 falls back to page images.
- Document-card content is merged into the React controlled input through a DOM event bridge at send time (same path as the native submit); the image path is fully independent and untouched.
- Conversion progress/errors show in a temporary status bar above the composer
(
conversation.input.dock); success auto-hides after 6s, errors can be dismissed.
Installation
From GitHub (recommended):
dsh plugin --profile web add github:linkingoscar/dsh-attachment-formats
Local development:
cd path\to\dsh-attachment-formats
npm install # host dependencies (first time)
# optional: high-fidelity PDF engine (pymupdf4llm, self-contained venv)
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install pymupdf4llm
npm run smoke # offline smoke tests (optional)
dsh plugin --profile web add link:path\to\dsh-attachment-formats
Restart dsh web (close the page → the desktop shortcut auto-restarts, or re-run
dsh web) and refresh the browser. OCR language data downloads automatically on the
first scanned-PDF recognition (≈24MB, cached in vendor/tessdata/, offline-ready
afterwards).
Known limitations
- OCR (tesseract.js) quality is limited on low-resolution scans and complex tables;
insufficient confidence falls back to page images with an explicit note — garbled text
is never injected. Higher-quality OCR (RapidOCR/MinerU/PaddleOCR) can be added as
pluggable backends later (see
docs/upgrade-v6.md). - The pymupdf4llm high-fidelity engine handles ≤40-page PDFs only (larger documents use the fast pdfjs engine); table/formula reconstruction is good but not typesetting-grade — layout details can be cross-checked against page images.
- Scanned PDFs without a text layer can only go the page-image route when OCR is unavailable or fails (vision models can read them).
- Legacy
.doc/.xls/.pptrequire LibreOffice (soffice);rtfrequires pandoc;epub/odtwork out of the box but pandoc (if installed) gives better fidelity. Missing binaries produce clear, actionable errors — nothing is silently dropped. - DOCX formulas and embedded images are not extracted (tables, headings and text are).
- XLSX outputs displayed text/results only; charts and comments are not extracted.
- Outlines prefer bookmark TOCs; PDFs without bookmarks fall back to font-size heuristics (weak on documents without strong heading styling) — the index card still carries line/page counts and reading pointers.
- iWork and archives are not converted yet.
- Attachments are attributed to the shell's current conversation (the one being viewed). Text/document cards therefore land in the dialog you are looking at. Converted page images go through the harness's native drop pipeline: if the current conversation is mid-reply it temporarily refuses drops, so the plugin waits for it to become idle before feeding the images. With several conversations open at once, other idle conversations may also accept that same synthetic drop — a harness-level behavior the plugin cannot scope; prefer attaching images with a single conversation open (text/code files are unaffected: they always stay in the current dialog).
- The "merge on send" for document cards bridges into the React controlled input over DOM events — an adaptation to an unpublished harness API; if a core upgrade breaks it, the symptom is "card content didn't enter the message", and the card's send button is the fallback (synthetic Enter path). The image path is never affected.
Releases
- v0.6.4
(latest) — session-correct attachments & verified zero-copy: attachments now
attribute to the shell's current conversation (no more cards/images landing in
another dialog); converted images wait for the current conversation to become
idle before the synthetic drop; workspace zero-copy is confirmed by name + size +
full SHA-256 (no silent substitution), >16MB is rejected outright; INDEX.md cells
are escaped, INDEX rebuilds are serialized per workspace, cache hits keep the
source-count fields, legacy-Office manifests carry the
libreoffice+builtinengine label. - v0.6.3
— cache lifecycle hardening: v0.6.1 8-hex cache dirs are now swept by
cleanup/clear (no invisible orphans), JSON spill keeps source vs artifact sizes
separate (tiering uses the spilled
doc.*size), page images materialize lazily when a cache hit downgrades to index mode, INDEX.md is fully rebuilt from live manifests (no ghost rows, populated timestamps), legacy.doc/.xls/.pptcache keys use the original OLE bytes so hits skip LibreOffice, atomic manifest/INDEX writes. - v0.6.2
— cache correctness & fast path: 16-hex cache ids with full SHA-256 in the
manifest, converter-policy fingerprint (engine/OCR/doc-server switches invalidate
the cache), index cards rebuilt from structured metadata on every hit (no filename
bleed-through), TTL counts model
readaccess via file atime, page images rendered lazily (clean small PDFs skip rasterization), 2–16 MB text files reach the host spill instead of being rejected, React key warnings eliminated, Node >=20, CI actions upgraded to v7. - v0.6.1
— correctness & engineering fixes: attachment-dock crash fix (
useCallbackreference), converters no longer pre-truncate (never-silent-truncation restored end-to-end), session-derived workspace authority for all routes, XLSX empty-column coordinate fix, true conversion cache keyed by source hash, cache TTL based on last access, verified merge into the composer draft; added ESLint, CI (Node 20/22) and component-level smoke tests. - v0.6.0 — fidelity & format coverage (DOCX tables, TIFF, epub/odt/rtf, legacy Office, PDF bookmark outlines), Baidu OCR API + remote VLM OCR + external doc server, content-adaptive engine, attachment cache settings page, workspace zero-copy references.
- v0.5.0
— document cards, index-card spill,
/attach list|full, adaptive merge limit, pymupdf4llm/pdfjs engines, tesseract.js OCR.
License
Apache-2.0 © 2026 linkingoscar
有意识地管理
安装与管理
前置条件与目标 Profile
目标: Web Profile
交付方式: Git Bundle — genusamblyrhynchusbrunooftoul602/dsh-attachment-formats#9982caf6512e8ea173dc9fa69eb4b014f2bf18dc。
验证、更新与移除
显示生命周期命令
dsh plugin --profile web list兼容性与访问范围
DeepSeek Harness web bundle; Node.js >=20 declared: Not declared in supplied evidence。
风险事实
证据与编辑审查Manifest、Bundle patch、分发与新鲜度
不可变证据
审查状态与源码活动
请通过固定的 Git Bundle 安装,不要依赖 npm 可用性。处理敏感附件前,请审查可选 OCR 和文档解析服务的配置。
AI 审查于 2026/9/16 UTC 14:10。GitHub 事实核对日期: 2026/9/16 UTC 14:10。
自当前证据基线以来,没有记录到重要源码变化。