DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Context Pilot — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
C

dsh-context-pilot

Context Pilot

DSH context-aware compression + adaptive reasoning: injects usage each round, lets the model decide when to compress and automatically resume; optionally lets the model adjust its reasoning intensity based on task difficulty

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Shuffle-1992/dsh-context-pilot#844104eedcc1250735d91af4f6189db5e7833c9a
READMECompatibilityVersions

Compatibility and provenance

Context Pilot is published as dsh-context-pilot and currently resolves to version 0.1.35. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
10/16/2026

Versions

0.1.35stable
10/16/2026
0.1.29stable
10/16/2026
0.1.23stable
10/16/2026
Show 8 more versionsCollapse versions
0.1.22stable
10/15/2026
0.1.13stable
10/15/2026
0.1.12stable
10/15/2026
0.1.8stable
10/15/2026
0.1.7stable
10/15/2026
0.1.5stable
10/13/2026
0.1.2stable
10/12/2026
0.1.1stable
10/10/2026

Related plugins

Loading related plugins…

Latest
0.1.35
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 2
Weekly downloads
0
Last push
10/16/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in memory-context.

Hindsight Coding Agents@vectorize-io/hindsight-coding-agentsReflect-only Hindsight long-term memory for coding agents (harness-pluggable: opencode, …), with automatic background ingestion (no setup CLI).Memsearch Dsh@zilliz/memsearch-dshMemSearch plugin for DeepSeek Harness: shared markdown memory across agents, with capture, pre-step context injection, memory-recall skill, and a skill-candidate review panel.Memory@furongjun1999/dsh-memoryLingshu (Lingshu·líng shū) DeepSeek Harness plugin: a complete brain—long-term memory/knowledge flywheel/self-awareness/recursive reflection integrated with DSH, with conversations automatically distilled into the md_cg cognitive graph (md documents)Archive Manager@michengai/dsh-archive-manager归档、恢复、收藏和永久删除会话,并诊断损坏的会话日志。 · Archive, restore, favorite, and permanently delete sessions, and diagnose damaged session logs.

README

dsh-context-pilot — DSH 上下文智能压缩 + 智能思考插件

DSH(DeepSeek Harness)宿主侧插件 dsh-context-pilot(面板名「上下文智能压缩」,曾用名「上下文领航」): 让长会话的上下文压力可见、可控,并把「何时压缩」的决策权交给模型——用工具调用触发压缩, 压缩在你的下一个步骤开始前落地,本轮不中断、不注入任何消息、不伪造任何用户发言。 另含可选的智能思考:把当前模型的思考强度档位告知 Agent,由它按任务难度自主换档(同样是工具)。

安装

# 从 GitHub 仓库安装(本项目**不分发 npm 包**,这是推荐路径;pnpm 规格)
dsh plugin --profile web add github:Shuffle-1992/dsh-context-pilot

分发方式(2026-10-10 决定):不发布 npm。安装一律走上面的 GitHub 仓库规格; dsh plugin --profile web add dsh-context-pilot 这条 npm 形式在本项目不可用(无 npm 包)。

安装后重启 DSH 生效(bundle 资格由本包 package.json 的 dsh.bundle.patch 声明, patch 文件:plugin/cordis.patch.yml)。

本地开发挂载(本机已实测的路径)

profile package.json 两处要改(以本机 desktop profile 为例):

{
  "dependencies": { "dsh-context-pilot": "link:F:/My Code/dsh-context-pilot/plugin" },
  "dsh": { "profile": { "bundles": [ /* … 其它 bundle …, */ "dsh-context-pilot" ] } }
}

再手工 Junction(可免 pnpm install):node_modules/dsh-context-pilot → <仓库>/plugin。

⚠️ 插件 package.json 必须有 dsh.bundle 段,否则 plugin-manager 报 not-bundle 并静默跳过 (重启几次都不生效、host 无日志)——详见 docs/setup.md §2 坑 P1。 包名统一为 dsh-context-pilot(2026-10-10 起去掉 @local/ 前缀);旧挂载名 @local/dsh-context-pilot 仍可用 plugin/cordis.patch.local.yml 兼容,但新装请用正式名。

仓库结构

路径作用
package.json(根)可分发包清单(name/version/license/repository/dsh.bundle.patch/meta)——市场按仓库根识别
plugin/插件本体(entry.mjs / client.js / 域模块 / icon.svg / 两个 patch 文件)——也是本机 link: 挂载目标
test/四套断言(contract / static / report / boot)
docs/设计与交接文档(含 docs/setup.md 部署矩阵、docs/hub-publishing.md 上架清单)

交接说明:本文是入口,读完 §1–§3 即可上手;深入内容在 docs/。最后更新 2026-10-15。

当前版本 v0.1.8 · 逐版本历史与实证记录见 docs/milestones.md。

最近更新(v0.1.6 → v0.1.35)

版本更新为什么值得知道
v0.1.35面板行后缀也带「预计稳定后」(与回执同源同数)R45 只改了回执;用户同意后,三条面板路径共用的 occupancyActSuffix 也带上预计值:「压后占用 19.0%(provider 待刷新,预计稳定后 ≈10%)」。第三实参就是回执用的那个 settledRatio(pre-step 用同一局部量 ⇒ 两处永远一致);无样本保持原话「下次请求后会回落」(不编数字);非 stale 不加后缀。顺手修掉 R38 单源守卫的脆弱判据(原用 200 字符窗口,函数体一变长就误报)
v0.1.34回执给「稳定后预计」——不再把 provider 未刷新的中间值当结果用户实测:压缩后回执显示 19%,稳定后回落到 10%(行为没问题,只是回执报的是中间值)。修法:压缩完成时挂「稳定观察」⇒ 下一次非 stale 实测里量出真实回落量(tokens,中位数,≤8 样本)⇒ 回执改写成「压缩后占用 ≈19%(192k)(provider 未刷新)⇒ 稳定后预计 ≈10%(100k)」;无样本时如实说「本会话暂无实测回落值」(不编数字);stale 实测不得记回落(否则量的是假回落)
v0.1.33真机走查锚点压缩 + 回执补「下限保护」按用户要求实跑 keepFrom:{recentUser:1}:回执「锚点之后原样保留 ~40k(启发式;表盘 ≈ 62k(×1.56))…压缩后占用 ≈19%(192k)」,账本 anchorProbe = {via:'recent-user', seq:7783, tokens:1431, margin:8000, budget:40000, clamped:true}。四条硬证据:①锚点命中;②retainBudgetHeur = retainBudget = 40000 ⇒ 锚点确实没被折算(因子 1.56 只用于落点预估);③两个数分别=「该段 62k」与「压后总占用 192k」;④新发现:锚点段只有 1.4k,被 MIN 下限抬到 40k(clamped)⇒ 回执原先会被读成"那段有 40k"⇒ 现补「下限保护:锚点段实际只有 ~1.4k,为防丢新需求抬到 ~40k」
v0.1.32决策卡写清「两种模式」与优先级(全中文)用户要求「卡里要说清优先用 keepFrom 还是档位」。新增独立一条:「两种模式(二选一,锚点优先):①按比例(默认)tier 浅压24% ⇒ 表盘 ≈ 档位名 + 约 3%;②按位置 keepFrom:{recentUser:1}(或 {text:'开头十来字'})⇒ 该处起原样保留、不折算(表盘由位置定,回执给落点)。锚点未命中自动退回档位。」 并删掉原句尾重复的锚点提示、压缩冗词 ⇒ 教学预算 2998/3000。新增全中文守卫(剥掉代码标识符后不得残留拉丁字母;真机抓出过漏网的英文「3pp」)
v0.1.31锚点语义定案:绝不折算(保持 R21 位置语义)用户明确「keepFrom 不用强制符合这个计算逻辑,应准确保留之前的逻辑」⇒ 确认现有实现即如此:scaleRetainBudget 只作用于档位预算,锚点预算原样进入范围选择;锚点侧(resolveAnchorBudget + R21「范围绝不越过锚点」护栏)未改动,唯一变的是回执文案(只读)。新增契约守卫:源码里不得出现 scaleRetainBudget(anchorBudget;变异 2/2 CAUGHT(把折算套到锚点上 ⇒ 各红 2 条)
v0.1.30锚点回执给出「真实口径落点」——可按表盘挑锚点

更早的更新(R18 单档模型零注入、R17 改档轮首知情、R16 档位与教学去重、R5 保留范围自选…)见 docs/milestones.md。


1. 它做什么

插件只做三件事:把读数讲清(窗口 / 已用 / 占比 + 达标时的决策卡)、把选项给足(三档 + 语义锚点)、 把执行做对(按选定预算自选保留范围,边界交引擎校验)。"何时压、留多少"由模型决定——它才看得到任务形态。

每轮任务前 → 读上下文用量(tokenMeter.measure)→ 注入「窗口 / 已用 / 占比」到 prompt
           | 档位(R16):深压8% / 标准16%(默认)/ 浅压24%;锚点(R21):keepFrom(更精确的"指位置")
           → 占用达「智能压缩线」时附决策卡(当前档位 + 两个方向的数字 + 趋势)
           → 模型【先在正文说一句理由,再】调用 compact_context(可选 tier / keepFrom)
           → 下一步的 pre-step 执行压缩:按锚点或档位算预算 → 自选范围 → compactRegion
           → 之后所有步骤跑在压缩后的上下文上(本轮不中断、不注入消息、不伪造发言)
           → 占用达「强制压缩线」时插件在 pre-step 无条件发起压缩(同一条预算/范围路径)

可选(智能思考开关):读当前模型档位 → 注入给模型 → 模型【先说理由,再】调 set_reasoning_effort

1.1 兜底链:当前实现的全部降级路径

总原则——失败极性统一:凡「信息不足 / 能力不可用」一律保守:宁可多留、多花 token、少做动作; 且绝不静默——每一跳都写进报告字段与「压缩自检」回执(anchorProbe / rangeProbe / rangeSource / effortGate…)。

环节主路径一级兜底二级兜底最后兜底
保留预算(R21+R16)keepFrom:{text:'…'}(前缀→包含定位)keepFrom:{recentUser:N}(最近第 N 条你的消息)tier(本次传入 / 会话已登记)标准16%(从未登记);每跳记 tried/reason
保留范围(R5)selectRange 按预算从尾部回退(+keepFromSeq 护栏:绝不越过锚点)末端边界不合法 ⇒ prevEnd 逐节点回退(≤64 次)仍不合法 ⇒ 官方 compactIfNeeded('context-overflow')判定「没什么可压」且未越线 ⇒ 什么都不压(source:none)
压完仍越线(R16)自算压完即收工仍 ≥ 强制线 ⇒ 追加官方 overflow 收口(rangeSource=own+official)—记录 officialWhy(如实标注是官方手段)
档位/路由读数(R1/R17)投影 pending(用户刚改的模型/档位)requestHeader(上次请求的已生效值)两者都没有 ⇒ 取模型默认档并标 adapterDefault读不到 ⇒ 不注入(不编造档位),记 effortDiag.error
换档请求(R1/R3)合法 ⇒ 写期望档,下一步生效不在可选集 ⇒ 工具拒绝并回可选集他人已显式指定 ⇒ 让位(不覆盖别人的选择)内部异常 ⇒ 吞成结构化结果(绝不抛错、不中断本轮)
工具存在性(R18)全局注册 + 按 agent 可见单档模型 ⇒ restrict 对该会话隐藏restrict 不可用 / 拿不到回滚句柄 ⇒ 不隐藏(宁可多花 ~417 字符/请求)开关关闭 ⇒ 撤回注册(模型清单里没有它)
可切性判据/收敛(R18)每步算 canSwitch,按路由变化收敛读不到路由/可选集 ⇒ 不抑制(保守:继续注入 + 保留工具)路由键未变 ⇒ 走快路径跳过重算(零异步开销)异常 ⇒ 保持现状 + 留痕(effortReconcileError)
模块加载(R10/M3)域模块懒加载 + 空值降级范围模块未就绪 ⇒ 退官方路径M3 未就绪 ⇒ 本轮跳过(m3-module-missing 留痕)defineTool 未就绪 ⇒ 工具不注册,下一步重试

1.2 关键机制:各自解决什么问题

改进内容为什么重要
压缩改「工具触发」(R4)模型调用 compact_context ⇒ 登记意图 ⇒ 下一步 pre-step 执行 ⇒ 本轮无缝继续彻底删掉「伪造用户消息拉起会话」那套(maybeResumeAfterMarker / sessionController.prompt / agent.followup 在代码里零出现)。压缩与「叫醒」解耦:工具调用本身就保证有下一步,不需要叫醒
保留范围「自己算」(R5+R16)保留预算由会话档位决定(R16 三档,见下一行)⇒ 调公开方法 compactRegion;边界不合法则逐节点回退;失败或压完仍越线才沿用官方 overflow 兜底引擎 context-overflow 写死 retainTokens = 0:真机实测在只有 53% 占用时把 surface 从 1117 节点 / 367,794 token 砍到 4 节点 / 8,603 token(影子化 97.7%)。现在近端细节留得住,且整段没超预算时什么都不会压
语义锚点保留(R21)keepFrom:{recentUser:1|2|3}(从最近第 N 条你的消息起)或 {text:'开头十来字'}(按文本定位)。模型指位置、插件算预算;预算 = 锚点→末尾 token + 余量,且 keepFromSeq 护栏保证范围绝不越过锚点三档只能按比例留,而常见形态是「旧需求占地方、新需求只在最后几个百分点」⇒ 白留旧内容(浪费 + 降智源)。降级链 text → recentUser → 三档 → 标准16%,每跳都留痕
压缩档位(R16)compact_context 可选参数 tier:深压8% / 标准16%(默认)/ 浅压24%;会话级持续生效(含强制线,未选 = 标准16% 兜底);范围计算/边界保护三档完全一致,夹取 [40k, 窗口×50%]把「不可靠的自由度」换成「有界的选择」:模型只在语义档位里挑,不接触会「切坏 tool 对」的底层参数;选档理由照旧写在正文(先说再调用);回执带档位与保留预算,Agent 能确认选档真的生效
换档改「工具」(R2/R3)模型调用 set_reasoning_effort ⇒ 下一步请求即用新档位替代「写文本标记、等用户再发一条消息才生效」——旧方案要求用户参与才能生效
「先说,再调用」(R6)两个工具的 description + 一次性说明 + 决策卡都要求:先在回复正文里用一句话说明理由,再调用工具工具调用对用户是静默的(只显示「调用了某工具」)。理由写进正文,用户才看得出为什么压、为什么换档
强制线恒低于引擎 5pp生效值 = min(配置, 引擎阈值 − 5pp)(内置 80% ⇒ 75%)两线相等时谁先命中取决于各自测量时机,插件可能「什么都没做、占用却降了」⇒ HUD 记录失真
全程留痕报告记录 rangeProbe(保留预算/起止/影子 token)/ rangeSource / compactTool / / …

| 退役零残留(R7) | marker 触发通道 + M5.5「挂起-自动恢复」通道整体清零(host/client/schema/wire/tests 五层成对删除);6 个「静默降级」真缺陷修复;无界状态有界化;CardBoundary 改为真正的 React 错误边界 | 那条通道在 R6 之后已永远不会命中(三处教学都改工具版),却仍在四层之间成对存在;而四个真缺陷的共同形态是「看起来成功了,其实什么都没发生」(工具回成功但意图丢了 / 冷却扣了但没压 / 字段算了但没人读 / 教学 catch 了但没日志)。审查报告:docs/r7-review-and-hardening.md |

要解决的问题:长会话上下文压力不可见;原生自动压缩(80%)只看占用、不看任务—— 重任务需要全上下文,轻任务其实可以先压缩腾空间。这个判断只有模型能做,插件的职责是 把读数、选项、执行三件事做好。

智能思考解决的问题:同一个模型的不同思考档位(off/low/high/max…)成本与质量差异显著, 但用户很难预判每个任务该用哪档;而模型自己看得到任务复杂度。插件把「当前档位 + 可选档」 告知模型,由它自己决定升档/降档——简单任务省钱、难题给足推理预算。

产出:弹窗 HUD(最近压缩记录 + 阈值速览 + 两个开关)、输入框档位 chip、 配置面板(两线阈值 + 成本计算器)、报告的完整取证字段。


2. 关键概念(读这一节就够)

2.1 两条压缩线

面板名配置键含义
智能压缩线markerMinRatio占用达此值时注入决策卡,模型可自行决定压缩(含选档,见 R16)并自动续跑
强制压缩线criticalRatio占用达此值无条件发起压缩(pre-step / idle 兜底;执行路径同上——先按会话档位自算保留范围,官方 overflow 只作兜底/收口;档位由 Agent 事先选定,未选 = 标准16%)。生效值 = min(配置, DSH 引擎阈值 − 5pp),即内置 80% ⇒ 上限 75%

推荐值(按计费口径,计算器可按实价实时推导):

DeepSeek API(命中:未命中 = 1:50)高缓存价档(1:4 ~ 1:8)
智能压缩线0.300.15–0.20
强制压缩线0.850.80

核心原则:不要把阈值调得过低去追命中率——过度压缩导致模型重读文件/重跑命令的返工成本, 远超省下的 token。高缓存价档(命中仍计费)压早更划算;DeepSeek 命中近免费,压晚保信息更好。

2.2 自动压缩:工具触发(零输入、零消息、本轮不中断)

  1. 模型判断该压缩时,先在回复正文里用一句话说明理由(R6 教学要求),再调用工具 compact_context(可选 reason)
  2. 插件登记「下一步压缩」意图并立即返回 → 工具调用让本轮继续到下一步
  3. 下一步的 agent/pre-step 先执行轮内压缩(R5 起:自选保留范围,失败才沿用官方),再组装本步请求
  4. 之后的步骤都在压缩后的上下文上继续 —— 本轮不中断、不注入任何消息

用户全程零操作,且不存在任何伪造用户发言(旧「标记 + 自动拉起」机制已于 R4 整体删除)。

为什么工具能做到:工具调用 ⇒ 必须回灌 tool result ⇒ 下一步必然存在, 而 pre-step 天然在下一步请求之前。压缩与「叫醒」因此解耦——不需要叫醒。 详见 docs/r4-compaction-tool-design.md。

占用达强制压缩线(生效值 = min(配置, DSH 引擎阈值 − 5pp);内置 80% ⇒ 75%)时, 仍由既有 pre-step / idle 安全网自动发起压缩——执行路径与工具触发完全相同 (不是切到 DSH 自带压缩);保留档位同样由 Agent 事先选定的 tier 决定 (R16:会话级持续生效,未选 = 标准16% 兜底);详见下一条。

保留多少近端内容(R5+R16):无论哪条触发,都先按会话档位自算范围 → 只压这一段。 三档:深压8% = 窗口 × 8%(1M ⇒ ~80k)/ 标准16% = 16%(~160k,默认)/ 浅压24% = 24%(~240k);预算被夹取在 [40k, 窗口 × 50%]。 边界不合法则逐节点回退;仍不行或压完还在强制线之上,才沿用官方 overflow 兜底; 整段对话未超预算时什么都不会压。这条规则已教给 Agent(R6/R16), 所以它知道压缩后还剩什么,不必靠猜。 详见 docs/r5-retention-range-design.md 与 docs/milestones.md 的 R16 节。

「先说,再调用」(R6,用户要求):工具调用对用户静默(只显示「调用了某工具」), 所以两个工具——compact_context 与 set_reasoning_effort——的描述、一次性说明、决策卡 都要求先在回复正文里说一句理由,再调用。工具 description 每轮随请求下发 ⇒ 这条提醒是零额外 token 的每轮提醒。

2.2b 智能思考(可选,默认关闭)

开关语义(一个开关管两件事):开 = 注入思考强度信息 + 允许 Agent 换档;关 = 两者都不做。

项内容
注入一次性教学(教工具用法)+ 每轮用量行后缀「| 思考强度 high」;用户手动改档时后缀直接点明「用户刚把档位从 high 调到 max,本步骤即生效」(R17,见下)
触发工具 set_reasoning_effort(参数 effort=<档位>)—— 见下「为什么是工具不是标记」
执行 seamagent/request waterfall + prepend: true(见下「为什么必须 prepend」)
不中断只改请求头一个字段:会话历史不动、不插消息、工具链不断
显示输入框模型选择器左侧 chip「智能思考档位 high · 冷却 23s」——响应式投影,零轮询
冷却30s(防频繁换档反复打断前缀缓存);chip 上显示剩余秒数

为什么是工具而不是文本标记(2026-10-08 用户指出后重构): 原方案是模型在回复末尾写 [cp:effort high] 文本标记,但有两个致命问题:

  1. 需要用户再发消息——标记写在回复末尾时本轮已结束,档位只在下一轮(用户下次说话)生效
  2. 若仿压缩"自动拉起"则是伪造用户输入——那是往 inbox.next-turn 塞一条假用户消息

工具为什么能解决(dsh-agent-loop L1152-1155 源码实证):

const toolCalls = message.content.filter((b) => b.type === "tool-call");
if (toolCalls.length === 0) return { kind: "completed" };   // 无工具 ⇒ 本轮结束
return concluded ? { kind: "completed" } : null;            // 有工具 ⇒ null = 继续下一步

⇒ 工具调用让本轮继续到下一步,而每步都重走 agent/request ⇒ 下一步的请求即带新档位。 全程零用户输入、零伪造消息、同轮内生效。 顺带消除了文本标记的「散文提及误触发」风险 (工具参数结构化,无正则误判面)。

为什么必须 prepend: true(2026-10-08 实测踩坑): 官方 installModelSelection 挂在同一个 agent/request 上且在外层, 它 await next() 后会 delete reasoningEffort 再套回持久化 header 的值 ⇒ 内层写入必被剥掉。症状极隐蔽:applied: true 却完全没生效。 故本插件必须 prepend 成为最外层,且 pending 需持久(每轮覆盖回去,不能一次用完就删)。

为什么用 agent/request 而不是 sessionController.selectModel: 后者内部还会 agentDefaultModel.saveSelection()——写全局默认模型(实测会重写 profile)。 Agent 自改档不应改掉新会话的默认档。

档位必须动态取:同一个 model id 在不同 provider 档位不同 (实测 trae/deepseek-v4.1-flash = low/high/xhigh,workbuddy 同名模型 = off/low/high/max), 绝不硬编码档位表。应用前必须校验合法性,否则 dsh-llm 会抛 UNSUPPORTED_REASONING_EFFORT 中断该次请求。 工具侧不抛错——非法档/冷却中返回结构化错误让模型自行纠正(抛错会中断本轮); agent/request 侧则必须校验并静默忽略(那是请求能否发出的最后一道闸)。

让位他人选择:若当前请求的档位既不是本插件上次写的、也不是本次想写的 (用户手动选档 / subagent 自带 reasoning_effort)⇒ 不覆盖。

用户手动改档,模型怎么知道(R17,2026-10-12 用户实测反馈): 用户改档(UI 选择器 / /model 命令)在 DSH 里只落成 model/selection 事件 ⇒ modelSelection 投影的 pending;官方要到本步骤的 system-prompt/assemble → agent/request 才把它落到请求上,而插件的注入在 agent/pre-step(更早)⇒ 那一刻 requestHeader() 还是上一次请求的档位。 故 read() 改为 pending 优先(与 client chip 的 sel.pending || sel.lastUsed 同源), 后缀随之变成: 思考强度 max(**用户刚把档位从 high 调到 max**,本步骤的请求即用它;可选 …)—— 模型不用等下一轮就知道用户调了档、调到了哪一档。无 pending 时文案与旧版逐字一致(零额外 token)。

单档模型下完全静默(R18,2026-10-13 用户要求):当本模型排除 Default 后只剩一档(例如只有 high), 或模型明确不支持思考档时,插件不注入任何换档文本(后缀 / 一次性教学 / 换档提醒 / 压缩自检回执里的换档提示 四处全静默),并把换档工具从该会话的模型工具清单里收起(agent 作用域 tools.restrict({deny})) ⇒ 省约 417 字符/请求(工具 schema,最大那笔)+ 60 字符/轮(后缀)。

  • 判据是单一真相(canSwitch):工具可见性与四处文本永远同源,绝不出现「工具已隐藏、文本却还在教你调用它」。
  • 未知 ≠ 没有(R7 结论):可选项取不到 / 空数组 / 读取异常时一律不抑制——最坏多花 token,绝不锁死能力。
  • 切到多档模型当轮恢复:判据读投影 pending(与 R17 同源),工具可见性在 pre-step 收敛(早于 system-prompt/assemble);一次性教学因「只有真注入才标记已讲」而自动重讲一次。
  • 稳定性:限制的 disposer 存进进程级注册表(跨插件热换存活)+ 激活/开关翻转时清扫残留; 失败极性铁律——拿不到可回滚句柄就不隐藏(宁可多花 token,绝不把能力锁死)。
  • 开关联动(R18 修掉的真实缺口):关闭「智能思考」⇒ 换档工具立刻从模型清单撤回(连 schema 都不再下发); 重新打开 ⇒ 自动重新注册;「智能压缩」同理(关 ⇒ compact_context 退出清单)。 此前只停了行为(不注入、执行被拒),工具却仍每请求下发、白付 schema。

真机 E2E(2026-10-13 实测,带数值):

场景实测
单档 workbuddy/hy4-preview-f可见工具 73、清单里无 set_reasoning_effort;用量行后缀与一次性教学均不注入
切回多档 deepseek-account/deepseek-flash可见工具 74;后缀 + 教学当轮恢复
单档下 toggle 插件激活期清扫 released=1 ⇒ 跨热换不留残(杜绝「切多档后工具永远不见」)
关闭「智能思考」Inspect 清单里该工具 0 命中(compact_context 仍在 ⇒ 精确收敛,非一刀切)

成本:一次性教学 ≈120 token + 每轮后缀 ≈7 token。 ⚠️ 换档可能使前缀缓存失效(call-config.js 注明 effort 属 cache-affecting 状态)—— 这是换档的真实代价,故设 30s 冷却并建议一次任务 1–2 次(已写进注入的教学文本)。

已实测(2026-10-08):工具注册成功(effortTool.ok=true, via=tools.register)+ 注入改写为工具版本。

调查与设计全文:docs/r1-reasoning-effort-investigation.md | docs/r1-effort-design.md

恢复投递走三通道,当前实际生效顺序(2026-10-07 实证):

通道方式状态
AsessionController.prompt(request, AbortSignal.timeout(30s))✅ 当前首选({"accepted":true},一次命中)
Bctx.remote.session.prompt 代理❌ 不可用(插件 ctx 无 remote inject 权限)
CcreateUserMessage + agent.followup(官方同原语)✅ 兜底(早期历史走此路)

通道 A 早期因缺 AbortSignal 第二参被拒(官方 prompt() 首行 throwIfAborted)—— 补参后即通。这印证了「官方契约的参数一个都不能少」。

2.3 三个可改动点

改什么生效方式
面板配置(两条线、有效期、换档冷却等)即时生效(host 活读 config,无需重启)
host.impl.mjs / effort.mjs / compact-tool.mjs / compact-range.mjs / threshold.mjs / m3.compact.mjs / m5.hud.mjs / m2.inject.mjs / m1.snapshot.mjsplugin toggle 热换(?ts= 动态 import)
client.js刷新页面
plugin-config.schema.mjs / wire.host.mjs / entry.mjs需要重启 DSH(entry 由 cordis loader 经 ESM 缓存加载)
core.mjs需要重启 DSH:它必须由 entry.mjs 用同一个 ?ts= 预加载后传给 apply(state/log/svc/schedule 在 apply 期同步使用,而动态 import 是异步的)。未重启时旧 entry 不传 core ⇒ 宿主降级但不崩(打一条 warn、不接线),见 core.mjs 文件头与 boot 冒烟的同名断言

R3(2026-10-08)起智能思考功能域独立为 plugin/effort.mjs:host 用 import(\./effort.mjs?ts=${implTs}`)加载(ts 取自 impl 自身),**与 impl 同批热换**;static.mjs§4/§5 的依赖方向与「动态 import 必须带?ts=」护栏自动覆盖它。 R5(2026-10-08)同款加载 plugin/compact-range.mjs(保留范围自选,纯函数叶子)。 ⚠️ **压缩档位是模块常量表 TIERS**(R16:深压8% = 0.08 / 标准16% = 0.16(引擎默认)/ 浅压24% = 0.24), 由 **Agent 经 compact_context(tier=…)选择**(会话级持续生效,含强制线;未选 = 标准16%), 不在面板配置。要改成面板可调,需给plugin-config.schema.mjs` 加字段 + 重启 DSH——未做,等用户确认。

详见 docs/setup.md。


3. 当前状态

已完成:M1–M5(用量读取 / 每轮注入 / 会话自说明 / HUD 弹窗 / 历史持久化)、R1–R21 (智能思考 + 换档工具、压缩改工具触发、保留范围自算、全面审查加固、压缩档位三选一、 工具后自检回执、回执按会话隔离、用户手动改档的轮首知情、单档模型零注入 + 工具静默)。9 个域模块 + core,host.impl.mjs 1836 → 518 行。 测试:contract 597 + static 72 + report 54 + boot 21 = 744 断言全绿;关键回归均有变异验证。 逐里程碑台账(含踩坑与实测数值):docs/milestones.md; 早期进度历史存档:docs/status-archive.md。

4. 测试与取证

4.1 测试(npm test,<1 秒)

npm test              # 跑全部四个套件
npm run test:contract # 只跑契约对账
npm run test:static   # 只跑静态约束
npm run test:report   # 只跑报告形状
套件断言数查什么能抓到什么
contract.mjs597face 方法表 ↔ client 描述符 ↔ TYPERT 三端对账;Config 字段在 FIELDS/schema/M3_DEFAULTS 三处齐全且默认值值级一致;退役字段未复活;mergeConfig 读取集 ↔ schema;getHud 作用域契约(防 ReferenceError 回归);弹窗/阈值行排版契约(状态提示独立成行,防窄弹窗逐字断开);智能思考 UI 契约(开关尺寸/右对齐/字段三端/chip 两态色 token);压缩工具化契约(工具注册/意图 TTL/消费顺序/伪造恢复零残留);阈值余量契约(引擎阈值 −5pp 三处同源 / 阈值核心已抽为叶子模块且 host 不再重复定义 / 未就绪时空值降级 / 面板自取上限 / 输入即时钳制 / 已存超限自动钳回保存 / 教学传生效值);组件作用域对账(防跨组件引用面板 state ⇒ 整卡崩掉,node --check 的盲区);R5 保留范围契约(RETAIN_RATIO 与引擎 DEFAULT_RETAIN_RATIO 同源 / 起点跳过 system/message / 走 session.eventAt 而非猜 / 真跑纯函数验证预算-范围-影子量-一致性拒绝-回退上限 / 引擎错误文案逐字对账 + 边界错误分类 / 官方兜底与强制线收口接线 / 留痕);R6 教学契约(实例化两个模块真跑 renderBrief/renderCard:先说再调用的「显著标注」与「具体做法」分两半钉死 / 两个工具 description 也要求 / 参数说明也要求 / 「自己算范围」按活值渲染 / 拿不到活值时不编数字 / host 活值接线);R7 加固契约(退役零残留 4 类 × 4 文件剥注释判定 / 保留项 markerMinRatio 未被误删 / 随会话增长的 Set 已有界化 / 意图表真跑 runTool:登记→pending()→跨 sid 隔离→消费 / 全表 TTL 清扫 / 空可选集不否决档位 / 顺序契约(F1 冷却在成功分支 / F5 消费在服务确认之后 / F2 可抛语句前移)/ 真错误边界 / occupancy 搬运 / alive 守卫计数);R8/R9/R10 解耦契约(阈值核心与 M3 压缩域(执行核心 + 编排层)已抽为叶子模块 / 宿主不得把 api.RETAIN_RATIO、api.selectRange(、state.m3.lastPreStep、sweepInFlight 抄回来(查独有产物而非函数名,防改名躲过)/ 跨域回调(publishHud/recordHudAct/formatAct/clearBriefed/schedule)必须显式注入 / 未就绪时空值降级并留痕 / 模块对宿主内部件零 import);智能思考 8 条实证结论(prepend 最外层 / pending 持久 / 冷却基准 / 计数语义 / 两侧校验 / agent.ctx / sid 现读 / 删 maxTokens);R17 用户手动改档的「轮首知情」(读 modelSelection 投影的 pending,而非上一次请求的 header;行为级覆盖改档/降级/兜底五条路径)调用静默失败(P29:三端漂移不报错、只是拿不到数据);已实测抓过 7 个真 bug
static.mjs72真实 node --check(含 );client 自足(无外部 import,require 仅 react);entry 薄壳(<40 行、有静态 Config、动态 import 带 );模块依赖方向无环;热换纪律;(effort / compact-tool / compact-range / threshold / m3.compact / m5.hud / m2.inject);调试残留扫描(tools 下的 属 CLI 正常输出,豁免);(根清单可被市场识别 / Bundle patch 指向存在的公开 patch / 包名↔patch name 一致 / 版本一致 / README 有安装命令 / LICENSE 与 license 字段一致)

合计 744 条断言(四套:contract / static / report / boot)。

已验证有效:注入 3 个人为 bug(m3-act 误入精简档 / client face 改名 / host 引用 client.js), 三套件全部抓到且定位精准。新增断言均实测验证过「对回归确实失败」(两边都通过的测试等于没测):

  • R5 换了 9 个针对性变异(保留比例 / 起点跳系统头 / 一致性校验 / 回退上限 / 错误分类 / 兜底分支 / 预算守卫 / measure 传递 / 强制线收口)逐个注入,9/9 被捕获——其中「去掉回退上限」第一次逃逸, 说明原断言只匹配了 return official('boundary-exhausted') 而没钉住 MAX_WALK_BACK,已加固。
  • R6 换了 11 个(教学标注 / 教学做法 / 卡片做法 / 两个工具 description / 参数说明 / 写死比例 / 卡片保留行 / host 活值接线)——11/11 被捕获。两次逃逸都极有教育意义: ① 「先说再调用」最初用**「或」关系的单个正则**,去掉显著标注后同段的具体做法仍能匹配 ⇒ 漏网, 现改为**「显著标注」与「具体做法」分两半钉死**; ② 变异脚本把锚点打在了同文件的注释上(注释里也写了那个词)⇒ 代码没被改,看起来"逃逸"。

4.2 取证工具

npm run dump -- --tail 20          # 报告概览 + 尾部条目
npm run dump -- --kind m3-act      # 按 reason 过滤
npm run dump -- --field m3.eff     # 取最近一条的某字段
npm run dump -- --history-acts     # 压缩历史(含 hud-acts.json)

npm run asar -- list --filter dsh-token-meter
npm run asar -- grep --pattern compactIfNeeded --ext js --ctx 3

# 会话存储逐帧取证(压缩是否真发生 / 阴影了哪些 seq / 系统头是否被保留)
node docs/reference/tools/session-records.cjs --find <会话 id 片段> --compaction
node docs/reference/tools/session-records.cjs --find <会话 id 片段> --shadowed 15513
node docs/reference/tools/session-records.cjs --find <会话 id 片段> --from 18300 --type 'compaction/*'

⚠️ 路径约定:报告的 m3/m5/m55 块在每个 history 条目上,不在顶层(report.mjs 已断言此约定)。 ⚠️ session-records.cjs 读的是 DSH 的私有存储格式(多帧 zstd + JSONL):直接扫魔数有假阳性, 必须 try/catch 跳过;官方改格式时该工具需同步。它是本项目「不靠插件自证」的关键手段—— R5 就是靠它统计 12 次压缩的 shadowedSeqs,才证明 system/message 15513 从未被阴影化。



5. 成本模型与推荐配置

结论(推导与官方单价取证见 docs/cost-model.md):缓存命中率会下降 (每轮注入约 300–500 token 未命中;压缩重置前缀),但绝对费用两种计费口径都降—— 按量付费约 10–30%(收益来自避免超大上下文的天价 miss)、订阅套餐约 40–70%(命中仍计费, 压小直接换额度)。「压得勤更贵」是错的:摊销成本 ≈ 新增内容 × 未命中价,与阈值几乎无关。 同一组阈值在高缓存价档(1:4)的钱效约为 DeepSeek(1:50)的 3.8 倍。

6. 配置面速查

面板字段配置键默认说明
总开关enabledtrue关闭后完全恢复原生 DSH(面板为开关滑块)
智能思考effortEnabledfalse开=暴露思考档位 + 注册 set_reasoning_effort 工具;关=提示词不注入、工具也不注册
换档冷却(秒)effortCooldownMs30两次换档的最小间隔(存储为 ms)。换档会使前缀缓存失效 ⇒ 计费敏感,故可配(R3-S7)
智能压缩线markerMinRatio0.2占用达此值时注入决策卡,模型可自行决定压缩(决策卡门槛,与已退役的文本标记无关)
强制压缩线criticalRatio0.85占用达此值无条件发起压缩(先按会话档位自算保留范围,官方 overflow 兜底/收口);生效值 = min(配置, 引擎阈值 − 5pp)(内置 80% ⇒ 75%)
强制压缩冷却(秒)sweepMinIntervalMs600两次强制压缩的最小间隔(存储为 ms)
(无面板字段)——压缩档位(R16):tier = 深压8% / 标准16% / 浅压24%(会话级、含强制线,夹 [40k, 窗口×50%]);语义锚点(R21):keepFrom 指位置、锚点之后原样保留。两者都取代引擎的 retainTokens = 0(R5)。详见 R5 / R21 设计文档

R7 删除的两个字段:marker(压缩标记)与 armedTtlMs(标记有效期)——随 marker 通道整体退役。 压缩改由工具 compact_context 在轮内触发,回复尾行文本标记既无教学也无执行路径。 旧配置里的残留键会被静默忽略(不报错、不迁移)。

智能思考换档工具:set_reasoning_effort(参数 effort=<档位>)——工具名固定, 档位取值由当前模型动态决定(插件注入时会告知可选档)。不设独立配置键(无需用户填)。

R1 曾用文本标记 [cp:effort <档>],因「需用户再发消息才生效」于 R2 改为工具(用户决定,不保留标记)。

历史版本曾有的 policyCardMinRatio(决策卡门槛)、highRatio(审计参考线)、 lightTaskChars(轻任务阈值)已删除——前者并入 markerMinRatio,后两者在决策主体 移交模型后已无触发作用。旧配置残留键会被静默忽略(不报错、不迁移)。


7. 已知设计风险(开发前必读)

  1. 激活安全:插件 apply() 内任何异常只记录不抛(DSH 纪律:抛 = 条目装载失败)。
  2. CJK 计数低估:占用比是估计值(无 provider usage 时按 4 字符/token 启发式), 决策阈值要留余量。
  3. compactNow 约束:必须传 Agent 本体 + 必须 idle + signal 必传 (官方实现首行 signal.throwIfAborted())。
  4. 弹窗 DOM 注入的脆弱性:弹窗是宿主内部组件、无官方插槽,靠 aria 属性定位, DSH 升级可能失效——失效只是开关/HUD 行不见了,注入与压缩功能不受影响。
  5. 热换语义:ctx.effect(execute) 的 execute 立即执行=setup,返回值才是卸载器 (曾因此误用导致心跳从未运行 + 卸载零清理,见 docs/milestones.md)。
  6. client 协议变更需重启:wire.host.mjs 的 face 声明与 TYPERT 走包 exports, 改协议(增删参数)必须重启 DSH 一次。

8. 文档索引

文档内容
docs/setup.md环境事实、composition 真相(not-bundle 坑)、部署与热换矩阵
docs/milestones.md逐里程碑台账(M1 → 现在,含踩坑与实测数值)
docs/status-archive.md早期进度历史存档(原 README §3)
docs/cost-model.md成本模型全文(官方单价 / 缓存命中率 / 阈值弹性 / 计算器)
docs/api-notes.md已验证的官方 API + 修正记录
docs/cross-repo-sync.md与 dsh-browser-kit 的同步清单
docs/r1*–r7*.md各里程碑的设计/审查文档(R1 智能思考调查与设计、R2 换档改工具、R3 解耦、R4 压缩工具化、R5 保留范围、R7 审查加固)
docs/r18-single-tier-suppression-design.md · docs/r21-semantic-anchor-design.mdR18 单档模型「零注入 + 工具静默」、R21 语义锚点(keepFrom:模型指位置、插件算预算)的设计文档

运行期取证:plugin/.data/m1-report.json(全字段报告)、plugin/.data/hud-acts.json(压缩历史)。

node docs/reference/tools/dump-report.cjs                # 报告概览 / --tail N / --kind m3-act / --field m3.eff
node docs/reference/tools/asar-query.cjs grep --pattern compactIfNeeded --ext js --ctx 3

9. 验收标准

  1. 每轮 prompt 含实时用量三元组(上限/已用/占比),模型可正确复述;
  2. 占用达智能压缩线时,模型可调用 compact_context 触发压缩(可选 tier 选档),插件在下一步自动执行(用户零重发);
  3. 占用达强制压缩线时,插件在 pre-step / idle 无条件发起压缩——保留范围按会话档位自算 (未选 = 标准16% 兜底;官方 overflow 只作兜底/收口),压缩事件出现在会话日志;
  4. 两条线可经 Config 配置(面板按秒/比率显示),改后即时生效(活读,无需重启);
  5. 插件任何异常不影响 DSH 主流程(激活安全零抛)。
  6. 智能思考(开启时):注入当前档位 + 可选档;Agent 调用工具 set_reasoning_effort 可自主换档,本次任务内立即生效、任务不中断、无需用户操作;关闭时提示词不注入、工具不注册。
用户追问「锚点能否也像档位那样折算成 26%?」⇒ 不能也不该:档位是预算承诺(能折算),锚点是位置承诺("之后一律原样保留",折算就是把锚点之后的内容丢掉)。但用户要的"可预期"能做到:锚点回执现在直接算给你看——「锚点之后原样保留 ~95k(启发式口径;表盘 ≈ 143k(×1.5))」。等价规则:想让表盘 ≈24%,锚点要选在启发式 ≈16% 的位置(即比过去更靠后一点)
v0.1.29锚点(keepFrom)与真实口径的关系 + 修一处回归锚点路径有意不折算:它是"位置承诺"(「从这条消息起之后一律原样保留」),按真实口径缩它就会越过锚点 ⇒ 违背 R21 护栏。所以档位=真实口径(降到 X%)、锚点=位置口径(这段不能丢),表盘落点分别 ≈ 档位名+固定开销 / ≈1.5×该段启发式量。同时修回归:R39 曾无条件报 tierBudget ⇒ 锚点生效时误报「保留预算 ~240k」;现按来源切换,回执也按来源标口径(锚点写「锚点之后原样保留 ~95k(启发式口径;表盘 ≈ ×1.5)」)
v0.1.28修 R39:折算没生效(读错了"三行组成"的来源)首次实测:回执没带 ×因子、只省 51.7K、压后 42% ⇒ 折算失效。账本证据 retainBudgetHeur: 240000 / retainFactor: 1(新代码在跑,因子恒 1)。根因:R39 把整个 measure 传给 summarizeBreakdown,而按契约它要的是 svc('sessionProjections').stateOf(session,'contextBreakdown') 的结果 ⇒ 拿不到组成。现改用正确来源 + 三行齐全守卫(不齐就不折算,否则"只有 system 行"会把 factor 顶到上限 2 ⇒ 压过头)。测试教训:原测试把 summarizeBreakdown 整体桩成"返回三行"⇒ 太配合、放过了这个 bug;现改为只在服务边界打桩 + 用真函数,该 bug 已有变异覆盖
v0.1.27保留预算改「真实口径」——让档位名副其实用户实测:DSH 原生 /compact 能压到 5%(messages 只剩 3.9K),我们的浅压24% 压完仍 40%。量化 6 个会话:表盘真实 / 三行启发式 ≈ 1.31–1.51(典型 1.4) ⇒ 我们按启发式保留 240K,实际保留 ≈340K ⇒ 档位名与表盘对不上。现按实测因子折算:预算 / factor(夹在 [1,2],只减不增;因子只用非 stale 实测、pre-step 每轮刷新)⇒ 浅压24% 压完应落在 24–28%。回执会写「保留预算 ~240k(真实口径 ×1.4)」
v0.1.26面板「压后占用」后缀单源 + 自选范围那条也报占用;实测确认「缺口是黏的」现场压缩实测(60%→40.1%):回执 455k ⇔ 账本 455,337 逐位吻合,面板 40% ⇔ 插件 40.1% 完全一致 ✅。⚠️ 我预测"会落到 26%"错了——压后真值 ≈ 保留 240k + 系统/工具 18k + 黏性缺口 ~136K ≈ 40%(那份"provider 计入而三行不计"的开销不随压缩消失,本会话有大量截图)。现把「压后占用」后缀抽成单源 occupancyActSuffix,三条面板路径(引擎/手动、自选范围、idle)共用,自选范围那条也从"只报省 XK"升级为"报占用 + provider 待刷新提示"
v0.1.25压缩后「压后占用」带「provider 待刷新」提示(13%→5% 之谜)真机:手动 /compact 后面板写「压后占用 12.6%」,13 分钟后表盘变成 5%。原因:表盘锚在 provider 实报上、滞后一次请求——刚压完是「旧实报 387,168 + 新 surface 8,194 − 上报时 surface 269,183 = 126,179」的过渡值;下一次请求完成后 provider 实报真实值(~53.6K)⇒ 落到 5%。现面板行在 stale(surface 缩水 >50%)时追加「(provider 待刷新,下次请求后会回落)」,正常轮次不附
v0.1.24手动切档后不再写「保持 X」(措辞失真修正)真机:用户 06:25:57 手动把档位从 max 切到 high,插件 06:26:01 已注入「用户刚把档位从 最高(max) 调到 高(high)」(检测正常 ✓),但模型 06:26:20 写成「档位决策:保持 高(high)」——照抄了卡片模板里的"保持" ⇒ 用户以为它没感知到切换。现切档那一轮后缀显式补「这是用户改的,不是"保持":请写「用户刚调到 X」」,教学同步加一句。另:手动纠正的效果已复测确认(t108–t112 连续 5 轮都只有 1 条决策行)
v0.1.23持续重复 ⇒ 上报面板(含可复制纠正文案);备注上限 4→1备注 4 条/轮已被证明压不住模型(实测照写 18–22 条/轮),压缩清先例也无效 ⇒ 不再跟模型较劲,改为把异常上报给用户:同轮决策行 ≥6 条时,面板 acts 行出现「20:xx · 决策行重复 12 次/轮 · 建议手动纠正;可直接复制:请停止在每个步骤重复写决策行…」——后半段可直接粘贴给 Agent(无需改客户端/刷新页面);同轮只上报一次。备注上限降到 1(留提示位、省 token)
v0.1.22「动作背书」的决策行不算重复(修 R31 的误报)用户追问「被纠正后就不会注入了吧」时复查判据,发现:R27 允许「中途真的改了决定再补一行」,而 R31 按"同轮 ≥2 条 = 重复"⇒ 合法补行被误判。现统计前先看该条消息里有没有指向压缩/换档工具的 tool-call(工具名从 api 取,不硬编码);有 ⇒ 不计入。其它 tool-call(如 pwsh)不豁免。完整语义:守规矩 ⇒ 永不注入;停手 ⇒ 同轮也不再注入;下轮重置;复发才再注入
v0.1.21反重复备注改为「检测驱动」:监测到重复才注入用户要求「只有当这种被强化后反复写决策的时候,监测到才注入」。R30 的固定节拍会打扰守规矩的会话。现改为读会话事件检测:assistant/message 自带 data.turn/step,只数正文 text 块(reasoning 里提到"压缩决策:"不算);同轮 ≥2 条才认定重复并投一条,只写 1 条完全不打扰;投后再写满 3 条才再提醒,每轮上限 4 条,新轮重置。state.m2.decisionRepeat / repeatNudges 进报告可核对
v0.1.20反重复备注:决策行每步重复是"模型模式",用结构性信号压会话日志取证(97 轮/3032 步):插件注入 108 次(≈1.1 次/轮 ⇒ 卡只在轮首一次,不是每步),而模型写的决策行 t86 2 条 → t92 25 条 → t95 27 条 ⇒ 自我强化,纯文案压不住。现于重复发生处投极短备注:本轮发过卡 + step≥2 + 每 3 步一次(回执优先),文本为「本轮决策行只需写一次,后续步骤不必重复」。⚠️ plugin/*.mjs 只需 toggle(无需重启 DSH);重启也解决不了这个问题
v0.1.19手动压缩不误报「引擎抢先」+ 压缩后投影偏高会标注真机手动 /compact 成功后:① 记录被写成「手动压缩(/compact) · 引擎抢先…」——用户主动压的,没有"抢先"(preempted 没判 kind,已修);② 表盘 13.1% 而当前 surface 只剩 6,185(真实约 2.4%)——投影公式里旧 provider 报的"非 surface 开销"(125K)压缩后没同步缩小,要等 provider 实报才回落。方向偏高=保守,故只标注:surface 缩水 >50% 时用量行附「provider 待刷新」。另附真机四口径前后对比(消息 221,980 → 4,062)
v0.1.18非插件压缩的失败原因可见(/compact 失败不再只说"失败")真机:同一会话连试 3 次 /compact 全失败(DSH 码 summary),我们记到了 3 条但只有「失败」两个字——原因只存内存、且这条路径不触发报告快照。现把 DSH 失败码翻成中文短语写进面板行(失败(摘要无法生成))与记录(error + reason),并在记录后立刻落一次报告快照;认不出码则截断原文照抄(不编造)。⚠️ 我们自己的压缩用同一个官方摘要后端 ⇒ summary 失败也可能打到我们,但会明确回报「未执行 + 原因」
v0.1.17决策行节奏:每轮开头一次 + 中途变更再一次长任务里同一轮的每个步骤都出现 档位决策:… + 压缩决策:不压|占用 ~57%|理由…(模型把每步都当成"阶段变化")。现两处文案写明一轮只写一次,中途真的改了决定(决定压缩 / 升或降档)再补一行,其余步骤不要重复。⚠️ 我第一版把卡改成稀疏(首次/涨5pp/隔20轮),与用户口径不符已撤销——卡照旧每轮一张(它是每轮决策的提醒位),改的只是决策行作用域
v0.1.16压缩回执显式消歧:档位名里的百分比 ≠ 占用回执原先虽已报「压缩后占用 ≈51%(510k)」,但同句仍有「浅压24% 档」「保留 ~240k」两个含 24 的数字 ⇒ 模型仍可能挑错那个数(真机先例:写出「回到 ~24%」)。现明写「档位名里的百分比是保留预算比例、不是占用」,「保留 ~240k」改为「保留预算 ~240k」,并预告「provider 下次实报后可能略降」(该数是压缩那一刻的 provider 锚定投影,真机 51% → 实报后 40%);每轮用量行的 used 始终与表盘同口径
v0.1.15报告新增「占用账本」+ 口径公式单源每个会话记 contextLedger:表盘口径(provider 实报 / 采样 surface / 计算投影 / 来源标注)+ 启发式口径(日志总量 / surface / 三行分项 system·tools·messages)+ 两口径之差 ⇒ 「表盘 408K 而三行 272K,差的 136K 是什么」直接从 m1-report.json 读(真机样例:748806+247859−487049=509616,三行 2161+200000+58256=260417,差 249,199)。公式实现唯一一份在 core.mjs(命名导出给测试 + 注入 M1/M3),m3 里出现第二份即被守卫断言抓红
v0.1.14R24.1:自算 DSH 投影公式(修我上一版的真缺陷)v0.1.13 直接读 projectedTokens,但它只存在于 DSH 发给客户端的 view,插件读投影 state 拿到 undefined ⇒ 退回过期的 provider 实报值(真机压缩后仍是 748,806/74.9%,而表盘已是 51%→40%,比改之前更糟)。现照抄 DSH 源码自算:projected = max(0, pressureTokens + surfaceTokens − sampledSurfaceTokens),真机配对验证 509,616(51%) ✓
v0.1.13占用口径对齐 DSH 表盘真机反馈「压缩时 DSH 显示 75%、压完 40%,插件却说 ~24%」——查下来 DSH 有三套口径(表盘 = provider 锚定的投影;弹窗三行 = 启发式组成,含被取代的提示且不含图片/文件路由定价;measure().totalTokens = 又一码事)。现将 used 对齐表盘并从 v0.1.14 起自算投影、标明来源,回执直接念「压缩后占用 ≈41%(408k)」
v0.1.12锚点来源中文描述 + 思考强度「低(low)」修两处显示:① 压缩回执把内部 token recent-user/text 直接给模型 ⇒ 改为「语义锚点(从最近第 1 条你的消息起)」/「(按文本「…」定位)」;② 思考强度的用量行后缀、一次性教学、错误文案、HUD tooltip 全是裸英文 id ⇒ 统一为 低(low) / 高(high) / 最高(max),且入参兼容回填(照抄显示名也能生效)。⚠️ 本次含 client.js 变更 ⇒ 除 toggle 外需刷新页面
v0.1.11档位说法全中文(英文 id 清零)审计出 3 条运行期泄漏:工具返回值 {"tier":"heavy"}、回执与 HUD 行的异常兜底会退回英文 id;另有 1 个隐患——canonicalTier 不认卡片上的「浅压24%」⇒ 模型照卡片回填会静默退回标准16%。现对外一律中文标签、内部与持久化仍用 id(兼容不变),并新增「模型可见文本扫描」断言(含"范围域未加载"的兜底路径)
v0.1.10R21.2 真机测试发现并修掉的两处① 不传 tier 会重置档位(卡片/文档都写"沿用",代码却写回 标准16% 并落盘)⇒ 改成真沿用;② 锚点未命中时回执不再丢降级痕迹("无需压缩"与"官方兜底"两条 return 路径补齐 retainSource/anchorFailReason)。两处都是真机跑出来的,各带行为级回归断言与变异验证
v0.1.9R21.1 紧急修复:工具静默不注册v0.1.8 的 keepFrom 是 type:'object' 却没写 additionalProperties ⇒ defineTool 拒收 ⇒ 整个 compact_context 不注册(模型调不了,教学还在喊它;强制线自动压缩不受影响)。已修 + 新增「工具 spec 结构化自检」断言(桩绕不过校验层)
v0.1.8语义锚点保留 keepFrom压缩不再只能"按比例留":可以让模型指位置——keepFrom:{recentUser:1}(从最近第 1 条你的消息起)或 {text:'开头十来字'},插件据此算预算,并保证锚点之后一律原样保留。典型收益:600k 里新需求只占 6% 时,从"留 240k(白留旧内容)"变成"留 ~44k"
v0.1.7决策卡「对称化」+ 越线反向建议卡片原先只给"多留的好处" ⇒ 等于在劝模型选浅压24%。现两个方向都给数字(丢多少 / 压后占用 / 距线轮数),越线时明确建议选深压8% 或 标准16%(越线选浅压会"压了等于没压")
v0.1.6档位说法改中文三档统一为 深压8% / 标准16% / 浅压24%(百分比由常量推导,不写死);英文 id 退为内部/兼容值,tier 中英都能传,老会话与落盘档位零迁移
档位/锚点持久化(R16.16/R21)
与档位一起落盘 compact-tier.json
写失败 ⇒ 内存仍生效 + 日志
热换/重启 ⇒ 落盘恢复(tierState=restored)
文件损坏 ⇒ 按未登记处理(标准16%)
开关关闭(R18.2)「智能思考」关 ⇒ 不注入、不注册已注册过 ⇒ 撤回(成功支)撤回不可用(无 disposer)⇒ 留痕 + per-agent 限制兜底「智能压缩」关 ⇒ 回到原生 DSH(不注入、不压缩、不注册)
跨热换残留(R18)限制的 disposer 存进程级注册表激活时清扫(released≥1)开关翻转时再清扫拿不到回滚句柄 ⇒ 当初就不隐藏(失败极性)
preStepErrors
lastPreStepError
链路任一环静默失败都能定位——已靠它当场抓出「工具从未注册成功」「面板整卡崩掉」等真 bug
docs/reference/tools/*.cjs
?ts=
功能域叶子模块清单
console.log
上架基础项
语法错误、破坏热换、client 引入依赖、循环依赖、TODO/XXX/console.log 残留、上架基础项漂移(改了清单名/schema 而 patch 或 README 没跟上)
report.mjs54产出侧字段契约;republishFromReport(原 bfOnce)回填链依赖;C3② 关键事件必须走 full 档(含满环优先淘汰 slim,防 FULL 取证被高频事件挤出);getHud 作用域与 criticalCap 实参契约;调查结论留档(探针退役后结论不得丢);真实报告结构自洽(无嵌套条件断言 ⇒ 断言数不得随数据漂移);hud-acts.json 去重;dump 工具可跑报告形状无声破坏(踩过 2 次:顶层读 m3/m5、脚本读已删字段);证据静默丢失(120 条全 slim、FULL 被挤光而断言全绿)
boot.mjs21宿主启动冒烟:真跑 apply(ctx, {}, {pluginDir, reportPath})(桩 ctx)→ HUD 面注册 → 真调 getHud(null) 必须 ok:true → criticalCap/occupancy/effortEnabled 三线 → 四个监听器 → 真调 pre-step handler(abort 与 step=1 两次)→ M2 注入路径留下记账(m2.skips 有键或 injections>0)→ 有历史时 m5.lastPublish==='ok' → 报告落盘。副作用边界:报告写临时目录、hud-acts.json 只读不写接线不可达(R11 真事故:接线块被嵌进 schedule() 函数体、语法合法、423 条源断言全绿,压缩与弹窗全链路静默失效)——node --check 与源断言都看不见「代码在不在正确的函数里」
docs/compaction-failure-diagnosis.md
压缩全线失效定位(provider×model 锐化)
docs/d1-module-split-brief.mdD1 模块切分任务书
docs/reference/README.md第三方(DSH 官方)抽取材料来源与许可 + 统一取证工具
review-brief.md / review-findings.md只读审查任务书与报告