coding-agents
vectorize-io/hindsightHindsight:会学习的 Agent 长期记忆系统,自动召回/保存、知识页、深度反思与按仓库隔离的记忆银行。
DeepSeek Harness 本地知识库:导入 Word/PPT/Excel/PDF(文字版或扫描版)、EPUB、MOBI/AZW3,生成带页码锚点、OCR 质量/置信度与 PDF 双栏阅读顺序的 Markdown 分块;并提供 LLM 维护的编译层(schema.md 维护规范、自动 index.md 内容索引、只追加 log.md、带来源与反链的 typed 笔记),支持来源可信度标注(高/中/低)与可信度感知检索、低可信提醒,以及排序检索、跨库查询、精读修订与 md/jsonl/zip 导出。MOBI/AZW3 需 Calibre;旧版 .doc/.ppt 需 Word/PowerPoint(Windows)或 LibreOffice(Linux);扫描版 PDF 的 OCR 首次使用会下载模型。
把 Word / PPT / Excel / PDF(文字版与扫描版)等资料整理成适合大模型阅读、学习的形式, 存放在固定、可命名、可导出、可持续修订的知识库中;deepseek 通过一组 kb_* 工具 随时调用知识库内容进行问答、推理、整理、课件与文档制作等工作。
工具 · 作用 kb_import · 导入文件或目录(.docx / .doc 自动转换 / .pptx / .xlsx / .xlsm / .pdf / .md / .txt / .epub / .mobi / .azw3,扫描版 PDF 自动逐页 OCR 中文,自动识别文字层损坏页并只对问题页 OCR,文字层双栏页自动重排;Word OMML 公式转 LaTeX;Excel 按工作表转 Markdown 表格;.txt 自动识别 UTF-8/UTF-16/GBK;MOBI/AZW3 自动经 Calibre 转 EPUB)。旧版 .doc/.ppt 与 MOBI/AZW3 一律在后台任务中转换;正在导入中的同名文档自动跳过。导入前自动查重:同库重合跳过、跨库重合默认跳过并报告(见下文) kb_reparse · 从库内 sources/ 重新解析文档(无需重新上传),用于 OCR/解析器升级后刷新旧管线产物;doc 单个、all=true 批量,支持 forceOcr、forceOcrPages/skipOcrPages、后台任务 kb_list · 列出知识库 / 知识库内文档与状态(旧管线/已修订/文字层损坏/OCR 低置信会标注),每条带一行摘要与标签;省略 kb 时只列本会话范围内的库;默认最多 50 条,支持 limit/offset/query/status/kind 分页过滤(kind=note 只看笔记、kind=source 只看资料);本库有维护规范时会提示 kb_query · 全文检索(ripgrep 正则,中文短语直接搜;标准号自动兼容 GBT=GB/T=GB_T=GB∕T 与年份分隔符变体);按标题/标题行/命中密度/更新时间排序,每文档默认 5 条;kb="*" 跨库检索;限定模式下省略 kb 检索范围内全部库;命中项带 part、页码与笔记类型 kb_read · 按分块精读、读大纲、读整篇;大纲条目带页码/部分,读取时返回页码范围;支持虚拟页 doc="schema"(维护规范)、doc="index"(内容索引)、doc="log"(操作日志),按 part 分页读取 kb_view · 查看原始页面图片(PDF 按页渲染;Word/PPT/EPUB/MOBI 提取内嵌图)——公式、原理图、电路图专用 kb_edit · 精确替换修订(持续修改完善);doc="schema" 可修订该库维护规范(index/log 自动维护,不能编辑) kb_describe · 给文档写一行摘要与标签(编目):摘要会显示在 kb_list 与 index.md,重解析/重导入不会覆盖模型写的摘要;存量文档可 all=true + auto=true 批量回填缺失摘要(抽取式,不递增版本号,limit 分批) kb_retitle · 修正标题:单篇传 doc(默认按 cleanTitle 去掉站点域名、GB_T、序号、span 残留等噪声),批量传 all=true(默认 dryRun=true 只预览,确认后 dryRun=false 应用);会重建合并版首行标题、保留历史、版本+1 kb_trust · 标注来源可信度:high(已发布现行标准、正式教材)/ medium(企业文件、培训资料、报批稿)/ low(草案、征求意见稿、已废止标准)/ unknown(清除);支持单篇、docs 列表、all=true + query/stage 过滤(批量默认 dryRun)。检索会优先高可信、标注低可信并提醒用户 kb_lint · 机械体检:导入失败、旧管线、文字层损坏/OCR 低置信、内容重复、同标准号同期同阶段重复、同号多版本、未编目、笔记无来源、续/修订版提示、无入链笔记、临时/锁文件(~$*、.~lock.*、Thumbs.db/desktop.ini/.DS_Store)、缺 schema;输出分组问题与建议动作(kb_reparse/kb_describe/kb_remove/kb_edit);限定模式下省略 kb 逐库体检 kb_edit_batch · 批量精确修订(事务语义):一次提交 1–50 条 {doc, old_string, new_string, replaceAll?},先全部校验再写入;任一条失败整批不改并回滚已写分块;dryRun=true 只校验。适合“一次改 10–15 页”的跨文档维护;同一文档一批只允许一条编辑 kb_snapshot · 库级快照:把 kb.json、schema/index/log、派生 markdown/(可选 sources/)打包到知识库 snapshots/,用于批量编辑/重解析前留档;list=true 列出已有快照 kb_add_note · 写入编译页/笔记(单篇上限 2MB):kind=summary/entity/concept/topic/note、tags、sources(docId#页码 或 [[标题]]);同一标题再次调用=更新同一篇(版本+1、保留历史),不要用「续」「修订版」另起新页 kb_remove · 删除文档(默认软删除,可用 kb_restore 恢复;soft=false 永久删除)或整个知识库(删整库需显式 kb + removeKb=true 且 confirm 逐字等于知识库名称) kb_restore · 恢复软删除文档(不带 version)或恢复历史版本(version=N,来自 kb_history) kb_history · 列出文档保存过的历史版本(覆盖导入/重解析/编辑前的快照,最多 10 个) kb_export · 导出 md(单文件)/ jsonl(分块,RAG 用;chunkSize/chunkOverlap 可切 RAG 小块)/ zip(完整包,内置 JSZip 打包,不依赖系统命令)/ vault(Obsidian Vault:index.md + wiki/ 笔记与资料页 + [[双链]],includeSources=true 时带 raw/) kb_rename · 重命名知识库(kb 必填,须在本会话范围内)
大文件(如整本扫描书)导入自动转为后台任务,与内置 job_list / job_output 联动查看进度; 取消后台任务会在 job_output 中显示为 cancelled。后台任务会写逐文件统计: 只要有文件失败,任务状态就是 `failed`(详情写明“部分失败:成功 X,失败 Y”),不再把部分失败显示成完成。 长任务每 60 秒刷新一次 heartbeatAt(不改文档 updatedAt);进程崩溃后,残留的 .lock 带 owner PID,下一个操作可在 PID 消失且锁超过 60 秒时快速回收,不必等满 30 分钟。
旧版 .doc 自动转换:Windows 用本机 Microsoft Word(COM 自动化,无对话框、禁宏); macOS 用自带 textutil;Linux 可用 LibreOffice。未装任何转换工具时会给出明确提示。
~/.dsh/knowledge//)kb.json 清单:文档列表(id/标题/类型/页数/大纲/版本/状态/
sha256/解析管线版本/contentSource/OCR 元数据/
summary·tags·笔记 kind/sources/linksOut)
schema.md 维护规范(每库可定制;建库导入时写入模板)
index.md 内容索引(清单自动渲染:笔记在前、资料在后,每条一行摘要)
log.md 操作流水(只追加:ingest/edit/note/describe/remove/restore…)
sources/<docId><ext> 原始文件(逐字节保留)
markdown/<docId>/<docId>.md 合并版(整篇通读)
markdown/<docId>/parts/NNNN.md 分块版(检索、精读、RAG)
markdown/<docId>/parts/index.json 分块索引(合并版行号 → part/页码)
markdown/<docId>/pages.json 逐页质量(文字层/OCR、损坏标记、置信度)
exports/ 导出产物kb_import 的 kb 参数决定(可含中文),不存在即创建。skippedUnchanged);内容变化或 forceReparse/kb_reparse 时原位更新(版本号 +1)。kb_edit 精确替换并标记 edited=true;kb_add_note 写编译页(同标题再次调用=更新该笔记)。清单会记录每个文档的 sourcePath:同一路径重复导入是原位更新, 不同目录下的同名文件(如 A/通知.pdf 与 B/通知.pdf)会另建文档,不会互相覆盖。 旧版本清单没有 sourcePath 的条目无法追溯来源,首次重导仍按原位更新,并在导入结果的 warnings 里提示一次;担心覆盖时请先备份或导入到新库,重导一次后就会记录来源路径。
zip 是完整可迁移包(含 README、index.md/schema.md/log.md 与全部 markdown, includeSources=true 时含原始文件)。 zip 用 generateNodeStream 流式写盘,不会把整包(含原始文件)先读进内存; 导出清单剥离本机 sourcePath,失败条目整条略过。
插件在 web profile 下提供 /kb/ 工作台(可通过配置 uiEnabled: false 关闭):
.trash/);GET /kb/api/status|kbs|kbs/:name|kbs/:name/docs|...。打开方式:在浏览器访问 http://127.0.0.1:/kb/(端口见 dsh web 启动行)。
工作台支持直接在浏览器里上传资料:选文件 / 选目录 / 拖拽文件 → 逐个上传(并发 2)→ 后台导入; 目标库可在上传前切换;导入标题自动按 cleanTitle 去掉站点域名、GB_T/序号等噪声;逐文件进度与报告可见, 失败可重试。扫描件可选 OCR 精度(best 更准 / fast 更快)与「强制 OCR」(文字层损坏时)。批次临时目录在 导入成功后删除、失败保留 24 小时供排查(过期批次在新建批次时清扫)。单文件与单批次上限见配置 uiMaxUploadBytes / uiMaxBatchFiles。
~$…)、LibreOffice 锁文件(.~lock.…)与Thumbs.db / desktop.ini / .DS_Store 等系统垃圾文件,并在上传面板与导入结果里报告 「已跳过 N 个临时/锁文件」;普通 .tmp 文件不跳过。
「标准更新」面板(库详情 tab):读取 .std-check.json 的上次检查时间、缓存有效期(TTL 7 天) 与待下载数(有新版 / 草案转正 / 可补下载);支持仅检查 / 检查并下载 / 补下载 / 强制全查 / 本轮上限,运行中可取消(当前正在处理的标准完成后停止,之后不再发起新的下载); 下载前必须勾选金币确认(每个标准约 6 金币,VIP 免金币);bzCookie 只在状态里显示“已配置 / 未配置”, 不会回传给浏览器。
当前版本仍不支持合并知识库;后续版本再加入。
DELETE 只接受未开始导入的 open 批次),目录保留至清扫;重试是客户端用本地失败文件重新上传。
refreshKbIndex 仍留在 lib/import-job.js 的导入收尾里,尚未拆成独立模块。(test/ui-docs-controls.test.mjs),胶囊用 node:vm 跑 lib/client.js;样式、真实焦点顺序与 布局仍需手工验收,另有 scripts/check-ui.mjs 的语法门禁。
kb_* 工具:工作台 HTTP API 与 UI 不受范围影响(范围不是权限边界)。kb_edit_batch / kb_add_note 为单库策略:范围有多库时必须显式 kb,不做跨库事务。restoreKb / removeKbDir 未做范围同步;失效库名由读取时清理(prune)兜底。conversation.input.left;conversation.session.header.utilities 未接入。回收站的已删除资料支持跨库批量彻底删除、搜索与排序,并可按天自动过期清理;仓库新增 GitHub Actions, 跑单元/构建门禁与真实浏览器 E2E。
`彻底删除 N 篇`(N 为去重后的篇数);有重复条目时按勾选数输入也接受。服务端做同样校验,不一致回 400 CONFIRM_REQUIRED。
与跨库批量一样在清单锁内复验已删除状态(requireDeleted)。
整批拒绝(409 KB_NOT_FOUND / 409 DOC_NOT_DELETED,details 带首个问题条目),合法条目也不会被提前删掉。
「彻底删除失败:文档已不在回收站」计入 failed 并继续;不会因为并发恢复回 500。
removeDoc(..., { requireDeleted: true });单篇失败不中断其余条目,返回 {purged, failed, byKb},失败项只带库、标题与固定文案「彻底删除失败」,不跨 API 回传本机路径。每篇写所属库日志 remove(detail「彻底删除(跨库批量)」), 每个受影响库刷新一次 index.md;日志/索引是附属写入,失败不会回滚已完成的永久删除。
items 为空、缺 kb/id、超过上限都是 400 INVALID_ARGS。请求仍要求工作台写头与同源。POST /kb/api/trash/docs/purge,body {items:[{kb,id}], confirm}。Enter 立即搜索;输入法组合期间不发中间请求,compositionend 后立即应用并恢复焦点。
库名 A→Z / 库名 Z→A。切换排序立即请求并清空当前选择;未知/非法 sort 回落默认值,响应回显解析后的 sort。
total 是命中总数,列表最多 500 篇,超出时显示「仅显示前 500 篇」。deletedAt 缺失/非法的行始终排在最后。GET /kb/api/trash/docs?query=&sort=,响应额外返回归一化后的 query 与 sort。trashRetentionDays:默认 0(关闭),允许 0–3650 天。配置为 N 后,工作台启动时与访问回收站时(同一 kbRoot 每小时最多扫描一次,进程内节流)永久删除 deletedAt 超过 N 天的普通 软删除资料。
movedTo 的行):撤销移动还要依赖它,即使过期也不自动清理,只能手动处理。deletedAt 缺失或不是 ISO 日期时间(YYYY-MM-DDTHH...)的行无法判断年龄,跳过并计入 skipped;单篇删除失败(含锁内复验时已被恢复/重新导入)也计入 skipped 并继续处理其余条目。
capped=true(表示可能还有未处理条目);byKb 只统计实际删除的条目。requireDeleted: true,锁内复验已删除状态;重新导入已软删除资料时 markImporting 会清除deletedAt/deletedFromStatus,导入期间不会被回收站列表、自动清理或批量彻底删除选中。
remove(detail「自动清理(超过 N 天)」),有变动的库刷新一次 index.md;清理失败不影响工作台启动与回收站列举。目前只有配置入口,没有 UI 开关,也不是后台定时任务。
.github/workflows/ci.yml 两个 job:unit(ubuntu-latest):npm ci → npm run typecheck → npm test。e2e(macos-14):安装 @deepseek-ai/dsh@0.2.1-rc.2 → 用临时 DSH_HOME 首次启动 dsh web 生成 profile →用 install-to-machine.sh 注册本仓库 → 安装 Playwright WebKit → 跑 npm run test:e2e;失败时上传 test/e2e/.artifacts(目录以 . 开头,workflow 用 include-hidden-files: true 才会收集)。
照常执行,其余失败仍会让 job 红。
node_modules,否则使用 profiles/node_modules 共享目录;全新 CI profile 缺 pnpm-lock.yaml / pnpm-workspace.yaml 时跳过,不再启动失败。
movedTo 还要用于撤销移动),需要手动彻底删除;撤销移动后墓碑消失,才会进入普通清理范围。removeDoc,不是多库事务;单篇失败保留在 failed 里,需要人工重试。回收站分成「归档库」与「已删除资料」两个分区:整库归档仍在回收站里恢复/彻底删除,软删除的单篇资料也有了自己的跨库列表、行内操作与按库批量彻底删除;资料页还能一键清空本库回收站。
#/trash,默认):0.23.0 的整库列表,逐库 恢复 / 彻底删除,另显示文档数、笔记数与归档时间;不可恢复的库给出原因并且只能彻底删除。#/trash?tab=docs):只列 活跃库 中被软删除(status=deleted)的资料,每行带 库 徽标、类型与删除时间;归档库里的资料不单独列出——它们随库一起恢复,归档库整库恢复后回到正常状态。tab 值回落到归档库。movedTo.kb 的行不再一律只能撤销移动。GET /kb/api/trash/docs 为这类行附加 movedToState(live / deleted / missing)与 canRestoreSource,行内操作按矩阵渲染:
目标副本 B 的状态 · movedToState · 回收站行内操作 · POST .../restore 目标库可用且副本 status=ready · live · 撤销移动 · 409 DOC_MOVED(details.targetKb) 目标库可用但副本已软删除 · deleted · 恢复 · 200,恢复 A 并清除 movedTo;B 保持已删除 副本被彻底删除 / 目标库归档 / 目标库不存在 · missing · 恢复 · 200,恢复 A 并清除 movedTo;不复活 B
先彻底删除 B 会让 A 从「不可恢复」变为可恢复:B 还在时直接恢复 A 会造出两份可用副本,所以只能 409;B 被 purge(或目标库归档)后 A 的 movedToState 变为 deleted/missing,回收站改为提供 恢复,服务端清掉 A 的 movedTo 后让 A 回到删除前状态。恢复只清 movedTo,更早的 movedFrom 保留;B 不会因此复活,不存在两份可用资料。kb_restore(version=N) 的历史版本恢复默认仍拒绝移动 墓碑,只有 API 确认目标副本不可用后才显式传 clearMovedTo。撤销移动仍走 0.23.0 的 undo-move: 源文档恢复、目标副本软删除进目标库回收站。
confirm 做同样的去首尾空白比较,不一致返回 400 CONFIRM_REQUIRED(资料页「已删除」筛选里的单篇彻底删除仍是 0.23.0 的输入标题确认)。0.25.0 起跨库批量改为输入 `彻底删除 N 篇`,行内与清空本库仍是库名。markdown/ 解析内容与历史版本,不可恢复;被移动过的资料还会失去 撤销移动——确认弹窗明确提示「彻底删除会移除原件、解析内容与历史版本,且撤销移动将不再可用。」(撤销移动依赖源库清单里的 movedTo 记录,记录随永久删除一起消失)。反过来,彻底删除目标库副本 B 会让源库墓碑 A 变为可恢复(movedToState 变 missing):A 不再需要撤销移动即可恢复,服务端恢复时清除 movedTo,B 保持缺失。remove(detail「彻底删除」)并刷新 index.md;这两个附属写入是 best-effort:永久删除已完成后,日志或索引刷新失败只留在服务端,不会再让请求以 500 收场。单篇失败继续处理其余条目,最后返回 {kb, purged, failed},失败文案固定为「彻底删除失败」,不带本机路径。all=true 一次清空该库回收站。truncated=true,页面提示「仅显示前 500 篇」,total 仍是真实总数。