dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH 跨会话记忆插件:本地 markdown 落盘、自动提取+注入、零依赖 + 管理面板。Local-first cross-session memory plugin for DSH (DeepSeek Harness).
English | 中文
DSH(DeepSeek Harness)的跨会话记忆插件:对话里聊过的事自动记下来,下次对话自动带上——你不用每次重复交代背景。附带一个本地「记忆管理」面板,记了什么、删了什么、人设怎么设,全程可见可改。
package.json 为准;变更记录见 CHANGELOG.md)package.json 声明了 DSH peer 范围,安装/启动时宿主会做版本兼容检查,不匹配会让用户显式确认后才装~/.dsh/memory/,不上传任何远端;API 与面板仅本机(loopback)可访问npm install)设计参考同类 agent 的项目记忆子系统;v1 采用单次 LLM 调用简化提取。

上图为界面示意(使用示例数据渲染)。最快上手(完整步骤见快速开始):
dsh plugin --profile web add "https://github.com/axuan-1314/dsh-keepsake/archive/refs/tags/v<版本号>.tar.gz" # 版本号见 Releases
DSH 每次新会话都是从零开始:你的工作背景、这个项目的决策历史、上周聊定的口径,全都得重新说一遍。dsh-keepsake 把这件事自动化:
记忆分两层:
以下每条都有源码依据(lib/ 与 web/),按"用户看到什么 / 能得到什么"叙述。
turn/end 且 reason.kind === "completed")后自动触发一次提取判断;纯寒暄、命令式短句(不足 3 个词的用户散文)这类没内容可记的轮次自动跳过,不白花 token。cordis.patch.yml 显式指定更稳的 provider / model。complete:true 的极简预设——都生效,这是 v0.2.0 对旧版"极简模式静默失忆"的根治点;injectChannel: "section" 可回退到旧的系统提示词注入)。注入受双预算约束:字符口径 injectMaxChars(默认 30000)与 token 口径 injectMaxTokens(默认 24000,CJK 感知估算;0 = 关闭 token 预算、只用字符口径)——超限按优先级整段丢弃,两个上限同时生效。这条消息由六段组成(人设与两段运行时为锁定段,不进整段丢弃序列;只有全局索引 / 项目说明 / 项目索引可被整段丢弃),模型据此"记得"你:| 注入段 | 模型看到什么 | 预算 |
|---|---|---|
| 人设(锁定段) | 「用户叫你小助手」「希望你称呼他为朋友」+ 你编辑的补充人设正文 | 400 行 / 8k 字符(v0.6.0 起由 16k 下调) |
| 运行时用户画像(锁定段) | 开启「运行时记忆」后:由 user-profile 等条目编译的 USER.md(定长紧凑画像) | ≤ 4096 字节(编译期配额) |
| 运行时工作记忆(锁定段) | 开启「运行时记忆」后:由工作背景 / 当前关注 / 项目条目编译的 MEMORY.md | ≤ 10240 字节(编译期配额) |
| 全局记忆索引 | 四个对话分类的条目索引(长期记忆不再进注入索引,v0.6.0 起);近期动态带年龄与过期倒计时(如「3 天前 · 27 天后过期」) | 每类 22 行(超限保最新),总 120 行 / 12k 字符 |
| 项目使用说明 | 记忆目录在哪、索引怎么读、怎么按你的要求直写/删除记忆 | 固定短文 |
| 项目记忆索引 | 该项目 MEMORY.md 索引(每行指向一个记忆文件,模型按需 Read) | 200 行 / 25k 字符,超限保最新丢最旧并附 WARNING |
运行时两段在「运行时记忆」关闭时为空段(不出现在注入里),此时注入内容与旧版四段等价(唯一差异:长期记忆索引行自 v0.6.0 起不再注入)。
| 开关 | 关掉后的效果 |
|---|---|
| 对话记忆(总开关) | 六段注入全灭 + 自动提取全停;关掉期间的轮次不积累,重开后不回补 |
| 项目记忆 | 项目使用说明/项目索引不再注入,运行时两段也一并停注(保守口径);项目类记忆写入被过滤(计数可见) |
| 全局自动提取 | 不再自动写全局记忆;已有的全局条目照常注入 |
| 运行时记忆(默认关) | 不编译、不注入运行时两段;全局索引照旧全量渲染(不做去重) |
source.kind = "plugin:dsh-keepsake" 标记;提取侧按统一的机器来源判据,把任意插件(不限本插件)注入的消息、以及 instruction / summary / tool 等系统性消息,都从「用户散文」里排除(既不计入 skip 门槛、也不进提取输入),不会出现"模型把注入的记忆又记回记忆"的自食循环。真人消息(含无来源、steer / followup)永远算数;语义召回的查询文本同样只取真人消息。把条目文件编译成两份定长的紧凑记忆(USER.md 用户画像 + MEMORY.md 工作记忆),随每轮注入——不用等模型按索引主动 Read。默认关闭(runtimeEnabled),在面板「设置」页打开后下一轮生效。
runtime/<scope>/USER.md / MEMORY.md → 注入;真源永远是条目文件,产物可删可重建,手工改产物会被下次编译覆盖。USER.md ≤ 4096 字节、MEMORY.md ≤ 10240 字节(UTF-8 字节口径,含文件头声明与告警行),是编译期常量(面板与配置都不提供调高)。pinned(pinned: true)条目优先入选、永不淘汰;合计超配额时不截断、不静默——清单 status=overQuota、面板红灯、注入块内可见告警行。evictCandidates[],产物末尾留一行 [runtime evicted: N entries …] 提示;同时只要该分类还有条目没进产物,这个分类就继续留在全局索引里(去重按分类粒度,不是整类抹掉)——所以任何一条记忆至少有一个可见入口。reference 类型(不进产物)照旧留在索引。global/long-term/(归档 ≠ 删除)。backups/evict-<ts>/,保留最近 10 份),并追加持久审计 evict-audit.jsonl(时间 / 原位置 / 新位置 / 快照 / 操作者);面板「从归档移回」按条目里记录的出处(originProject / originType / originSessionId)落回原位并重编。这三个出处字段在面板编辑归档条目时原样保留——编辑一次不会让条目变成移不回去。也可手工把文件搬回原目录——路径集变化会自动触发重编。审计写入失败时本轮停止继续搬运并如实回报「已归档 N 条 / 未处理 M 条」,不会假装什么都没发生。injectMaxTokens 24000;字符口径 8000 + 4779 ≈ 12779 < injectMaxChars 30000。injectChannel: "section" 模式下同样承载这两段(插在人设与全局索引之间)。pinned 切换)。settings.json 里的 runtimeEnabled)即回到不注入 runtime 两段的旧形态,不编译、不写盘;已产生的 runtime/ 目录可整目录删除,不损失任何记忆。对话里偶尔会出现密钥、令牌、内网地址这类不该被记下来的内容。脱敏默认开启(redactionEnabled,默认 true),在两道位置拦截:
name)——密钥被写进文件名时会落盘、进索引、随每轮注入,比正文里的更持久,故一并脱敏;文件名命中后会追加源名短指纹([redacted]-<8位十六进制>)保证不同条目不会撞名。路径分隔、sha1 与操作类型不动。命中数计入提取运行日志的 redacted 字段(有命中才写),面板「最近提取记录」可查。内置 7 类固定模式(清单固定、不做用户自定义正则——防正则回溯拖垮宿主进程):
-----BEGIN ... PRIVATE KEY----- 到 -----END ... PRIVATE KEY----- 整块;sk- 前缀、GitHub PAT(ghp_ / gho_ / ghu_ / ghs_ / ghr_ / github_pat_)、AWS Access Key(AKIA)、Slack 令牌(xox)、Google API Key(AIza)、JWT(eyJ 三段式);协议://用户:密码@主机 保留协议与主机、凭据部分换占位符;password / secret / token / api_key / private_key / credentials 等键名后跟 : 或 = 的值;10.x.x.x / 172.16-31.x.x / 192.168.x.x。命中的内容替换为占位符 [redacted];对已脱敏文本重复执行不再变化(幂等)。不想用时可配 redactionEnabled: false 完全关闭,回到不脱敏的旧行为。局限见「已知限制」。
默认关闭。开启 recallEnabled 并配好嵌入端点(embeddingBaseUrl / embeddingModel)后,每轮对话会按你当前的问题语义检索最相关的记忆条目(嵌入余弦 top-k),以 <memory-recall> 块注入——不必等模型按索引主动 Read。条目向量按内容增量缓存,只有新写/改动过的条目才重新嵌入。
http://127.0.0.1:1234/v1/embeddings)则记忆文本也不出本机。cordis.patch.yml、不必重启(面板配置存于 ~/.dsh/memory/settings.json,优先于 entry config)。embeddingBaseUrl + embeddingModel 即可,本地自选模型(EmbeddingGemma、bge-m3 等)同样适用。embeddingProvider 只是显示标签,配不配都行。recallEnabled: true 但缺 embeddingBaseUrl / embeddingModel(或 injectChannel 不是 message)时,插件不再启动失败——召回被显式关闭(零嵌入调用),面板与门牌出红条按【当前生效配置】每轮现算着指路:缺哪个键、去面板「嵌入服务」卡补(要同时打开同卡的「开启语义召回」开关——开关预填为关,只填端点不打开开关的话红条会一直提示到打开为止)、通道问题只能改 cordis.patch.yml(面板救不了);配置齐了但开关没开也有一条专门的「打开开关」红条,绝不静默不召回。红条里的 settings.json 路径按 /state.storageRoot 现算(自定义了数据目录的用户看到的是真实路径)。用户补齐配置后不重启即恢复(诊断每轮现算)。其它功能(对话记忆提取与注入)完全不受影响。端点 URL 不是 http(s) 属于「配错」而非「配不全」,仍然启动即抛。/state.recall,面板与门牌同时出红条(连续失败 3 次后自动暂停召回 60 秒)。入口:DSH 设置页的记忆区块(下称门牌)→「打开记忆管理」。打开方式自动三级降级(新窗口 → 内嵌 iframe → 整页跳转),面板主题自动跟随宿主深浅色。门牌本身也是快捷操作区(速操台):总开关、「DSH 的名字」「对我的称呼」两个输入框(防抖自动保存)、状态摘要(全局 N 条 · M 个项目)、提取失败红条 + 「详情」深链。

上图为设置页示意(使用示例数据渲染)。记忆管理面板的条目管理见文首截图。
面板(/dsh-keepsake/panel/,仅本机可访问)包含:
.json / .md 文件(≤2MB)或直接粘贴,三种格式(JSON 结构化逐条 / Markdown 按 ## 拆条 / Markdown 整段);先预览将要写入的条目(与现有内容冲突或批内改名的标红),确认后才落盘(落盘前自动备份);批内同名自动 -2 / -3 避让。USER.md / MEMORY.md 只读预览、用量进度条(越界红显)、淘汰候选勾选 +「执行归档」、「重新编译」、「从归档移回」。默认关;未开启时页面给一句引导。settings.json / addressing.json / persona.md 解析失败时,门牌与面板显示红条「解析失败(已按缺省运行)」,点任意开关 / 重新保存对应内容即可重写修复;损坏档在覆盖写前自动备份 *.corrupt-<ts>,原数据不失访。settings.json 损坏时除了保留原档(改名 settings.json.corrupt-<ts>),还会从影子档 settings.last-good.json(每次成功写入同步刷新)恢复用户的开关,恢复不了才落默认——不是简单丢弃重写。设置值不合法被纠正落默认时,设置页会出黄条「N 项设置值不合法已回默认」并列出字段名(/state.settingsDiagnostics.coercedFields),重存设置可修正。设置页的「自动提取管道」健康卡让你一眼看出记忆提取是否健康:
UNSUPPORTED_REASONING_EFFORT 拒绝),插件按模型默认档重发一次并在健康卡与门牌各显示一行「思考档降级 N 次」——这趟额外往返此前只进日志,用户既不知道发生了、也无从判断要不要换档位。written 行若带 truncatedParse(输出被 max-tokens 腰斩但仍解析成功),标签附「(输出被截断,可能少存)」——这是"看起来正常的成功",不标出来永远不知道那次可能少存了几条。/state.extractionLog.coverage 给出 distinct 区间数(distinctFailedRanges / distinctWrittenRanges / distinctAbandonedRanges)与区间级成功率 writtenRangeRate。区间口径,不是轮次口径(宿主不提供总轮次数,故不编造);failed 计数下降 ≠ 记忆变多,只有 distinct 区间数说得清。<storageRoot>/extraction-errors.log)排障。injectMaxTokens 为 0 时不显 token 段、退回字符展示);数据源是 /state.injection 的 lastTokens / totalTokens。provider/model,或「未指定(跟随会话路由)」)、fallback 换道配置、最近一次提取用车(路由 + 相对时间)、嵌入模型(语义召回所用;未配置时显示为未启用)。此前"聊了几轮、记忆里看不出任何反馈"的根因是:成功 / 零产出 / 跳过都不留痕,失败详情只活在进程内存(DSH 一重启归零),失败区间跨重启就永久丢失。本版补上持久观测面:
<storageRoot>/extraction-journal.jsonl 追加一行——written(写 / 删了几条)/ zero-ops(模型无可记、或有 op 无可落盘)/ skipped(直写记忆、无有效用户发言、总开关关、格式只读)/ failed(与失败分桶同名的病因)/ abandoned(同一结构性病因连续失败过多,显式放弃该区间、游标已推进不再重试)。追加串行化防并发写坏,行数超 2000 自动轮转留尾 1000;写日志失败只告警、不阻断提取。它不是记忆真源,删除不损失任何记忆(代价是丢掉观测历史与续提边界),见 FORMAT.md 第七节。提取要消耗 token,触发侧有三道成本闸门(全部默认开启,各有独立回滚开关):
extractGateEnabled,默认开;阈值 extractGateMinScore,默认 6):提取前对这批轮次打分——分数 = 用户词数 + 2×工具种类数 + 2×真人轮次数,分数低于阈值就不调模型、直接记 skipped/thin-evidence(运行日志留痕、进度照常推进)。用户词数沿用既有散文口径(空格词数 + 中文按每 2 字折 1 词);带工具调用或多轮真人发言的会话轻松过门,纯寒暄薄轮不再白花一次 LLM 调用。extractIdleDelayMs,默认 3000 毫秒;0 = 立即提取):一轮结束后不立刻起跑,等 3 秒空闲再跑——期间新完成的轮次合并进同一批,突发连续对话只触发一次提取。定时是固定时刻而非滑动窗口,持续对话中也会到期;会话关闭/插件退出时挂起中的提取立即收口执行(进既有有界 drain),不丢最后一轮。extractMaxRunsPerSession,默认 50;0 = 不限):单个会话的自动提取次数到顶后,后续触发记 skipped/session-cap 并推进进度,不再调模型——病态循环轮(模型反复空转)不会无限烧钱。只约束自动链路,面板手动补提不受限。v0.4.1 让失败区间跨重启看得见(运行日志持久留痕),v0.4.2 把它推进到补得上:
autoRecoverEnabled,默认开):除手动按钮外,插件还会在三个时机自动补提失败区间——① 会话关闭时(session/disposed,只补该会话);② 每轮对话完成后(turn/end,全局清扫);③ 插件装载后数秒(启动清扫,跨重启续提闭环)。规则:
autoRecoverCooldownMs,默认 300000 毫秒 = 5 分钟),防止宿主读不回的区间被每个触发面反复白读;E_HOST_UNSUPPORTED)——不假装补过。POST /api/sessions/recover 即回 202、后台执行(同一时刻只有一次补提,在途再点返回 409),结果经 /state.recover(inFlight / lastAt / lastOutcome / lastSessionId / autoEnabled / autoAttempts / lastAutoAt / lastAutoTrigger)观测;清单数据面是 GET /api/sessions/pending。设置页新增「记忆整理」卡,只出建议、不自动改动你的记忆:
MEMORY.md 索引与磁盘对账(悬挂行 = 索引指向已不存在的文件、漏登记 = 磁盘有条目但索引没这行、空分类),一键修复只增删索引行、绝不删条目文件;改动前先把索引原文存进快照(可在「快照」页找回),留档失败即拒绝本次修复。GET /api/maintenance/suggestions(建议清单)、POST /api/maintenance/repair-index(响应 fixed 为已应用动作明细数组、fixedCount、unchanged)。提取是后台静默发生的,所以失败处理必须显式可见:
Retry-After 时优先采用(钳制防恶意长等)。插件卸载/进程退出时退避立即中断,不白等。failure.code 判可重试(EMPTY_RESPONSE / RATE_LIMIT / SERVER / TIMEOUT / TRANSPORT);AUTH / INVALID_REQUEST / QUOTA 这类确定性失败立即摊牌,不浪费 attempt。fallback 配置逐条换道(换道同样走完整 attempt 链);换道成功计入 /state 的 fallbackUsed 并把最近用车指向该道。未配置 fallback 时行为与纯重试完全一致。<storageRoot>/extraction-errors.log——常开,不依赖任何环境变量;只记摘要(时间 / pid / 原因 / 路由 / 错误摘要),不含会话内容;超过 512KB 轮转两档。所有批量破坏性操作都有后悔药:
global/,含人设与称呼)+ settings.json + 项目记忆(projects/)全量备份到 <storageRoot>/backups/<时间戳>/;complete: false,拷完改 true),中断的半备份在面板标「不完整」且拒绝恢复;pre-restore),恢复中途失败时响应会带上这份备份 id 指路自救。自动提取的写入不是一锤子买卖——项目侧与全局侧各自留了后路,面板里可查可回滚:
backups/surgical/<batchId>/(按 surgicalKeep 保留最新 30 份)。面板「快照」页可整份恢复或只恢复某个文件,恢复后自动对账 MEMORY.md 索引。trash/<entryId>/ 落副本、确认副本落稳后再删原件,按 trashKeepDays 默认保留 30 天。面板「回收站」页可单条恢复、单文件恢复,也可清除单条 / 按保留天数清理 / 全清(清空=真正删除)。此路同时覆盖自动提取产生的删除与面板手动「删除条目」(DELETE /entry);而分类重置(clearCategory) 与 近期动态滚动清理(pruneRecentActivity) 仍是直接删除、不进回收站(分类重置前另有整类自动备份)。failed/。全局侧写路径同样回读校验。hardfactDrops;hardfactPolicy 设为 block 则回滚该 op 并计 hardfactBlocks(与写后校验失败 verifyFailed 分列,不混计;默认 warn:只告警不阻断)。判据局限如实说明:检出口径是「同类型硬事实在新文里一个都不剩」或「被极近的值顶掉(疑似誊写错误,如 269 记成 267)」——frontmatter、索引行与日期 / 倒计时等动态注记不参与比对,而正文里同类数字很多时,整行删除也可能检不出;warn / block 的策略语义不变。sha1 字段与当前文件不符即拒绝该 op(并计计数器 expectedSha1Mismatches),防基于过期内容误覆写;不带 sha1 的「盲写」不会覆盖旧正文,而是降级为追加(保留旧正文,新内容接在分隔线后)而不是整段覆盖;提取落盘抢批锁(<storageRoot>/extract.lock),锁冲突时阻断破坏性操作。backups/surgical/;快照失败则跳过这次覆盖、原文保持不动(宁可漏一次更新,不可丢旧文)。面板手动保存(改条目)同样先留档:留档失败直接拒绝保存(503,旧文一字未动),成功响应带 preSaveSnapshotId,可在「快照」页找回被顶掉的旧文。restoreBackup)走「旧档改名 retired-* → 换入」流程,换入失败会把旧档改名回原位(自动回滚;回滚也失败则保留 retired-* 目录供手工恢复)。而快照 / 回收站恢复(restoreSurgicalSnapshot / restoreTrash)不自动回滚——它们按条循环写文件,中途失败就地停下、不改回原状;但恢复前的留底快照仍在盘上,API 的失败响应会带上 preRestoreSnapshotId 与提示,指向它供你手工找回被覆盖的旧版。恢复端点与提取落盘共用同一把批锁,不会边恢复边写入。/state.safety 共十个字段:盘上三项(surgicalBackups / lastSnapshotAt / trashPending)每次请求实时现算,进程内七项计数(verifyFailed / hardfactDrops / hardfactBlocks / expectedSha1Mismatches / blindWriteDowngrades / lockConflicts / snapshotFailures)重启清零。真源只有
*.md与MEMORY.md:backups/与trash/是可安全删除的副本目录(删掉不损失当前记忆,只失去回滚能力)。见 FORMAT.md 第七节。
三项安全面设置写在 ~/.dsh/memory/settings.json(与三层开关同一份文件,不是 entry config——写进 cordis.patch.yml 会被拒)。其中 surgicalKeep / trashKeepDays 与近期动态保留天数 recentKeepDays 可在设置页「保留策略」卡直接改(下一轮对话生效);hardfactPolicy 有意不给输入控件(拨到 block 会把合法更新一起回滚,用户会看到「我改的记忆自己变回去了」),面板保留策略卡有一段指路文案说清现值、两值语义与改法(路径按 /state.storageRoot 现算),改文件仍是手工、下一轮生效:
| 设置 | 默认 | 说明 |
|---|---|---|
surgicalKeep | 30 | 批前快照保留份数;超过的最旧快照由写入路径自动清理 |
trashKeepDays | 30 | 回收站条目保留天数;过期的由写入路径与面板「清理过期」清掉 |
hardfactPolicy | warn | 硬事实丢失策略:warn=只告警落日志;block=回滚并计 hardfactBlocks |
手改取值规则(面板走 PUT /settings 同语义):未提及的键保留现值;surgicalKeep / trashKeepDays 显式给了非法值(非正整数 / 负数 / 非数值)时按默认值生效;hardfactPolicy 给白名单外的值时保留现值(手工写坏文件被读到时回 warn)。
两种渠道任选(零运行时依赖,全程无需 npm install):
① GitHub tag tarball(推荐) —— 从仓库 tag 直接安装,钉死版本:
dsh plugin --profile web add "https://github.com/axuan-1314/dsh-keepsake/archive/refs/tags/v<版本号>.tar.gz" # 版本号见 Releases
# profile 可选 web / headless / desktop
② 本地克隆(开发 / 自用) —— 源码改动即时生效,适合改代码:
dsh plugin --profile web add "<克隆到本地的仓库路径>" # 或 git URL
装完验证 entry 入树:dsh --profile web --dump-config。
安装即启用:cordis.patch.yml 显式 enabled: true(代码缺省关,fail-closed),开关状态在 YAML 里可见。
改代码 / 换版本后要跑新代码:web profile 由 HMR 自动重载;desktop / headless 需重启对应实例(桌面端重启应用;headless 每次启动天然取最新)。本地克隆渠道是
link:软链,源码改动无需重新安装。
DSH 的插件管理器不支持自动更新(官方文案:升级 = 先卸载再装新版)。所以升级 = 用新版本重跑一次安装命令:
# tag tarball 渠道:升级 = 用目标版本号重跑一次(版本号见 Releases 或 CHANGELOG.md)
dsh plugin --profile web add "https://github.com/axuan-1314/dsh-keepsake/archive/refs/tags/v<新版本号>.tar.gz"
# 本地克隆渠道:git pull 后无需重装(软链生效)
~/.dsh/memory/——在插件包目录之外,卸载 / 重装都不碰它(除非你手动删除该目录)。数据与代码分离是刻意设计。long-term)不再进注入索引(归档条目对所有会话不可见,提取 prompt 仍可见);② 人设段上限 16000 → 8000 字符;③ injectMaxTokens 默认 16000 → 24000;④ 新增「运行时记忆」开关,默认关(不开则注入内容与旧版等价,只是少了 long-term 索引行);⑤ 存储格式版本 1 → 2,退回旧版会自动只读。细节见 CHANGELOG.md 的 0.6.0 条目。keepsake-format.json 记录存储格式版本(见 FORMAT.md)。v0.6.0 起 FORMAT_VERSION=2(v0.3.0 → v0.5.0 期间一直为 1):新增可选 pinned 与 long-term 的 origin 三字段,属可选增量、无数据迁移。由此——从 v0.6.0 退回 v0.5.0 或更旧版本时,旧版读到 v2 标记会自动转只读(写端点 503 + 门牌/健康卡报警,读取仍放行),这是防「旧版覆写剥掉 pin」的兜底;而 v0.4.0/v0.5.0 退回 v0.2.x 时格式闸不会触发,旧版可以正常读写同一份数据,但它没有 v0.4.0 的写入安全面(批前快照 / 回收站 / sha1 覆盖闸 / 写后读校验),其自动提取的覆写是直接替换。降级前建议先做一次全量备份(设置页数据卡「导出全部」,或直接拷走 ~/.dsh/memory/)。extractReasoningEffort(本版本新增的键)与 maxOutputTokens: 0(v0.6.4 的校验要求正整数,0 会被拒)在旧版 resolveConfig 里分别是「未知键」与「非法值」,而 apply() 第一步就调 resolveConfig 且无 try/catch——旧版会装载即失败,不是降级运行。cordis.patch.yml 出厂配置里这两个键默认就是注释状态(代码缺省已等价于「0 + 不下发」),只有你自己显式取消注释时才需要手动删掉。~/.dsh/memory/projects/<slug>-<hash16>/memory/ 是否出现 MEMORY.md 与记忆文件,或全局分类目录(如 ~/.dsh/memory/global/work-profile/)是否出现条目;GET /dsh-keepsake/api/state(本机 loopback)看 counts(全局条目数 / 项目数)与 extractionFailures(应为全零);注意:desktop / headless profile 改 cordis.patch.yml 等 entry config 后需重启对应实例才生效(web profile 由 HMR 自动生效);而面板里的三层开关、称呼、人设走 ~/.dsh/memory/settings.json,宿主每轮读取,下一轮对话即生效,无需重启。
cordis entry config(见 cordis.patch.yml):
| 字段 | 默认 | 说明 |
|---|---|---|
enabled | false(代码缺省关,fail-closed) | 总开关;cordis.patch.yml 显式 enabled: true,安装即启用且开关可见于 YAML |
injectChannel | "message" | 注入通道:"message"=durable 用户消息通道(默认,全预设生效);"section"=旧 systemPrompt 注入通道(一键回滚;v0.6.0 起同样承载六段,含 runtime 两段) |
injectMaxChars | 30000 | 消息通道注入总预算(字符口径):召回块与主块共享此预算,主块为召回块让位;超限按优先级整段丢弃并附可见 WARNING。v0.4.2 起默认由 60000 下调(块首取代声明 / 免责两行固定开销 + 节流收敛,见「工作原理」);需要更大预算时显式配置即可覆盖 |
injectMaxTokens | 24000 | 消息通道注入总预算的 token 口径(CJK 感知估算;含召回块,主块让位;与 injectMaxChars 双上限同时生效,取更严者)。0 = 关闭 token 预算,退回纯字符口径。v0.6.0 起默认由 16000 上调:为运行时记忆层留预算(persona 8000 字符 ≈12000 tokens + runtime 两段常驻 ≈7170 tokens ≈ 19170)。token 估算是近似值(CJK 字 ≈1.5 token/字、其余 ≈0.25 token/字),非精确分词 |
redactionEnabled | true | 内容脱敏总开关(见「内容脱敏」):提取提示词与落盘写入两道位置的密钥类内容替换为 [redacted];false = 完全不脱敏,回旧行为 |
storageRoot | ~/.dsh/memory | 记忆总根(测试/迁移用,一般不动) |
provider / model | 空(跟随会话路由) | 提取调用的模型路由;成对出现,否则报错。缺省时自动捕获本会话路由(request/header 优先,assistant/message 的 source 兜底,同 session-title 策略) |
minUserWords | 3 | skip 条件的散文词数下限 |
extractGateEnabled | true | 提取触发打分门开关(见「提取触发门槛」);false = 关门,过薄轮次也会照旧调模型提取(旧行为) |
extractGateMinScore | 6 | 打分门阈值:分数 = 用户词数 + 2×工具种类数 + 2×真人轮次数,低于该值记 skipped/thin-evidence 跳过提取(不调模型、进度照常推进) |
extractIdleDelayMs | 3000 | 提取空闲延迟(毫秒):轮次结束后延迟等待、合并突发轮次为一次提取;0 = 立即提取(旧行为)。上限受定时器最大延迟约束,超限启动即抛 |
extractMaxRunsPerSession | 50 | 每会话自动提取次数上限:到顶后后续触发记 skipped/session-cap 并推进进度(不调模型);0 = 不限。只约束自动链路,手动补提不受限 |
autoRecoverEnabled | true | 自动补提开关(见「会话补提」的「自动收口」):会话关闭 / 轮次完成 / 启动清扫三个时机自动补提未恢复的失败区间;false = 关闭自动补提,只保留面板手动按钮。宿主无会话持久化时自动链路静默不跑 |
autoRecoverCooldownMs | 300000 | 同一失败区间两次自动补提尝试的最小间隔(毫秒),防宿主读不回的区间被反复白读;上限受定时器最大延迟约束 |
timeoutMs | 120000 | 单次提取调用超时 |
maxOutputTokens | 0 | 提取输出上限。0 = 跟随模型(不发 maxTokens,由宿主套模型默认值;推荐);>0 时照旧作为硬上限。显式 4096 会让带思考的模型把预算全花在思考上(实测 88 条 llm-error 里 81 条是 kind=max-tokens) |
extractReasoningEffort | 不下发(缺省) | 提取调用的思考档:"minimal" / "low" / "medium" / "high"(非法值启动即抛,带允许值提示)。缺省不下发(options 里不出现该键,跟随模型默认档):宿主按模型能力声明校验档位,不被支持的档位会在 provider I/O 前被拒(UNSUPPORTED_REASONING_EFFORT), |