dsh-context-window

DSH PLUGIN记忆与知识

仓库 qq-24/dsh-context-window

记忆与知识 L5 · 运行验证通过 安全审查:低风险 可信度:金 可安装插件
安装这个插件

给 DSH 每个对话一个独立的上下文窗口:不改 settings.yaml,覆盖值存在会话日志里,切换/重开都保留,并即时改变自动 compact 触发线与界面上下文环。

一句话选型结论

按资料字段整理

dsh-context-window 是记忆与知识类的 DSH 可安装插件,验证等级 L5 · 运行验证通过,安全审查为低风险,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类记忆与知识 收录类型可安装插件 验证等级L5 · 运行验证通过 安全审查低风险
验证等级 L5 L5 · 运行验证通过
GitHub 星标 1 复刻 0 · 未关闭 issue 0
最近更新 2026-10-29 创建于 2026-10-26
README 17.6 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add github:qq-24/dsh-context-window
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名未发布到 npm可用 npm view 查看包信息

能做什么

记忆与知识
字段来自项目仓库与公开索引,中文说明由本站标注

适用场景

记忆

上游标签

compactioncontext-windowdeepseek-harnessdshdsh-plugin

验证等级与安全审查

L5 · 运行验证通过
自动化流程结论,不是人工审核
验证等级L5 · 运行验证通过在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度活跃按仓库活跃度与最近更新时间给出
可信度金综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 验证等级 L5:安装和运行都在沙盒里跑通过,装完能直接用的概率高。
  • 静态安全审查为低风险,没有发现明显可疑行为。
  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在记忆与知识场景里给 DSH 补能力的人。
  • 想装完就能用、不想自己排依赖的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-context-window当前 L5 · 运行验证通过 低风险 1 未标注 有
ruflo L3 · 安装规范通过 低风险 7.4 万 未标注 无
OpenViking L3 · 安装规范通过 低风险 3.9 万 未标注 无
WeKnora L4 · 沙盒安装通过 低风险 3.3 万 未标注 有
distilly L4 · 沙盒安装通过 低风险 2.5 万 未标注 有
EverOS L4 · 沙盒安装通过 低风险 1.3 万 未标注 有

仓库档案

记忆与知识
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方qq-24仓库 dsh-context-window · 默认分支 main
分类记忆与知识memory
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言未标注仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue1 / 0 / 0收录时的数值,非实时
创建 / 更新2026-10-26 · 2026-10-29最后推送 2026-10-26
本站收录2026-10-30首次进入本站目录的时间

README 全文

17.6 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-context-window

给每个对话一个独立的上下文窗口。

不改 settings.yaml 里的模型配置,只在会话日志里存一份覆盖值:切换对话、重开 DSH、导出导入都保留,删对话即消失,并且即时改变这个对话的自动 compact 触发线,界面上的上下文环也跟着变。


它解决什么

DSH 的自动压缩触发线是一条算式:

thresholdTokens = floor(contextWindow × thresholdRatio)

(dsh-compaction-basic/lib/index.js:111 算阈值,:883 取窗口,:884 比较)

问题是两个因子都不是按对话给的:

因子 来源 粒度
contextWindow adapter 的 model catalog(dsh-llm-deepseek/lib/index.js:1566,默认 1e6) provider + model,写死在 settings.yaml
thresholdRatio compaction-basic 插件配置(默认 0.8) 全局,或 modelPolicies[] 按 provider+model

于是现实里的尴尬是:1M 窗口的模型,前 800K 都不压缩。 短对话被历史拖着走,token 白烧;想早点压缩,只能去改全局配置,把所有对话一起改掉。

本插件补的就是缺的那一层:会话级 contextWindow 覆盖。

把某个对话从 1M 调到 256K,这个对话就会在 256K × 0.8 ≈ 205K 开始压缩,而其它对话和模型配置一个字节都不动。


截图

完全跟随 DSH 自己的深浅色主题,不需要额外设置——插件只用 DSH 的语义色变量(--dsw-alias-*)取色,切主题时由浏览器自动换值,插件不判断当前是深是浅。

桌面 · 浅色

桌面 · 深色

手机(≤640px)

同一个座位,换成底部抽屉:遮罩、拖拽把手、× 关闭,避让 safe-area-inset-bottom,档位三列排布,触控目标 ≥40px:


安装

dsh plugin --profile web add github:qq-24/dsh-context-window

然后重启 dsh web(宿主侧代码不热载)。重启完刷新页面即可。

要求:DSH ≥ 0.1.2-rc.1,Node ≥ 22。

用法

输入框右侧的胶囊就是入口:

形态 用模型默认 有会话覆盖
桌面(>640px) 上下文 默认 1.0M 上下文 256K
手机(≤640px) ctx 1.0M ctx 256K

> 手机上刻意保留 ctx 前缀:纯数字会和 DSH 自带的上下文用量计(4/6 那种)混在一起,认不出是哪个控件。

面板里能做什么

  • 滑块:16K ~ 2M,对数刻度——线性刻度下 16K~64K 会挤在最左边一丁点,对数刻度让整个行程手感均匀
  • 数字输入:任意精确值,回车或点「应用」生效
  • 预设档位:64K / 128K / 256K / 512K / 1M / 2M
  • 用模型默认:清除覆盖,回到 adapter 那份值
  • 对比行:模型默认 X · 模型名 · 当前 Y,超过模型默认时会标黄

交互约定

拖动滑块只是预览——把手位置和数字实时跟随,但不会写入;只有点「应用」或数字框回车才真正生效。这样做的原因是每帧提交一次 RPC 会把宿主刷爆,而且误触一下滑块就改掉压缩时机也太容易出事。


设计边界

这几条是产品决策,不是技术限制:

  • 不限制、仅提示:允许把窗口设得比模型真实容量大。插件不做钳制,只在 UI 上标黄警告。理由:调大调小都应该由用户决定,插件替用户猜容量反而添乱。
  • 不改 settings:模型默认值永远是 adapter 那份,覆盖只是会话级叠加,随时可清除。
  • 可增可减:改的是 compact 判定用的窗口,不是模型真实容量,所以两个方向都生效。
  • 即时生效:不需要重启,下一条消息就走新阈值。
  • 随会话走:值存在会话日志里,重开、fork、导出导入都带着;删对话就跟着删,不留孤儿文件。

> ⚠️ 调高超过真实窗口会撞墙。 contextWindow 不只是压缩线参数,它还是 request/context 事件的记录值和 pi-ai 溢出检测的基准。设成比真实容量大,压缩永远不触发,直到 provider 返回上下文超限的 400。这是唯一会咬人的地方,所以 UI 里给了显式警告。


怎么做到的(不改 DSH 核心)

核心难点:压缩判定和界面上下文环读的是两个不同的窗口来源。

读者 读哪里 影响
compaction-basic llm.resolveModelInfo(...).context.contextWindow(:879) 自动压缩在什么水位触发
token-meter(界面上下文环) request/context 事件的 data.contextWindow(:373) 环的分母显示多少

只改其中一个,症状就是「压缩线动了但环不动」——用户会以为持久化坏了。所以有两条独立的接入路径。

路径一:压缩判定(AsyncLocalStorage)

agent/pre-step 是 waterfall 事件(dsh-agent/lib/types/runtime-types.d.ts:237),cordis 的 waterfall 是"每个 listener 包住链条的剩余部分"(cordis/lib/index.js:317-325):

1. 用 prepend:true 把本插件挂到 pre-step 链最前面
2. 在 listener 里 AsyncLocalStorage.run(session, () => next())
→ 后续所有 listener(含 compaction-basic)都跑在这个 async 上下文里
3. 包一层 llm.resolveModelInfo,在 ALS 上下文内把 context.contextWindow 换成会话覆盖值

compaction-basic 完全不知道自己被改了。

路径二:界面上下文环(改会话读写两端)

环的分母来自 request/context 事件,它由 agent-loop 在 step 主体里写:

const contextWindow = preparedCall?.context?.contextWindow;            // :757
const previousContext = session.requestContext();                      // :763
if (previousContext?.contextWindow !== requestContext.contextWindow)   // :764
session.append('request/context', requestContext);

preparedCall 由 llm.prepareCall() 在 :726 造,在 step 主体里。而 DSH 没有任何能包住整个 step 的钩子——agent/pre-step 的 next() 返回 PreStepDecision(进不进这一步),agent/request 的 next() 返回 config,都在 step 主体之前返回。所以 ALS 够不到 prepareCall,LlmCallConfig 里也没有 sessionId 字段可以反查会话。

只能改会话对象本身,而且必须读写两端一起改:

  • session.requestContext() 读 → 返回覆盖值,让 :764 判断"变了"
  • session.append 写 → 落盘前把 contextWindow 换成覆盖值

> 为什么不能只拦 append:preparedCall 给的值恒等于原始值,:764 判断恒为"没变化",agent-loop 压根不调 append,拦不到任何东西。实测证据:一个 9246 事件的会话里 request/context 只有 1 条(停在会话开头)。

代价:每次请求都会多写一条 request/context(比较恒不等)。事件很小,可接受。

持久化

写进会话日志,不碰 settings.yaml:

事件 负载 含义
context-window/set { window: number } 该会话的自定义窗口
context-window/clear {} 清除覆盖,回到模型默认

DSH 核心明确接受插件自定义事件类型(dsh-session/lib/types/index.js:106-108:"SessionEventMap is merge-extensible; plugin-owned events carry no core message"),envelope 校验只要求 type 是 string(:159-165)。写入时带 ignorable: true,避免被 DSH 的未知事件处理误伤。

并发安全:ALS 按 async 链隔离,主对话、子代理、goal 轮次同时 pre-step 不会串值(离线测试专门验证)。路径二的读写 patch 挂在各自的 session 实例上,天然按会话隔离。

刻意不替换官方 compaction-basic:它是 45KB 实现,含 assertNoActiveCompaction、toolPairingBalancedBefore/After、surface replaceGeneration、checkpoint 约束等不变量,且 selectCompactableRange 未从 dsh-compaction 导出。抄错的失败形态不是报错,而是"会话看起来正常、恢复时校验失败"。压缩动作始终由官方插件执行,本插件只提供窗口值。

主题适配

插件不自己存任何颜色,全部从 DSH 的语义色变量取:

text:    'var(--dsw-alias-label-primary, #1f2328)',
dim:     'var(--dsw-alias-label-secondary, var(--dsw-alias-label-dimmed, #6b7280))',
border:  'var(--dsw-alias-border-l2, var(--dsw-alias-border-l1, rgba(127,127,127,0.28)))',
surface: 'var(--dsw-alias-bg-layer-1, var(--dsw-alias-bg-base, #ffffff))',
accent:  'var(--dsw-alias-state-business-primary, #4d6bfe)',
warn:    'var(--dsw-alias-state-warn-label, ...)',
danger:  'var(--dsw-alias-state-error-primary, #dc2626)',

DSH 的深浅色是这样实现的——两套 CSS 规则,切主题只是给 body 加/去掉 data-ds-dark-theme 属性:

body                     { --dsw-alias-bg-base: var(--dsw-static-neutral-bluish-00); }
body[data-ds-dark-theme] { --dsw-alias-bg-base: var(--dsw-static-neutral-bluish-950); }

所以插件不需要监听 theme/change、也不需要判断当前是深是浅——var() 在计算时自动取当前生效的那套值。

阴影和遮罩同样走主题 token:

  • box-shadow 直接用 var(--dsw-elevation-panel) / var(--dsw-elevation-prominent)。它们本身就是"描边 + 多层投影"的完整值(形如 0 0 0 .5px #fff3, 0 3px 8px 0 #00000008, ...),不要在自己写的偏移后面拼它们——拼出来是畸形 shadow,整条声明会被 CSS 丢弃(实测 computed boxShadow 变成 none)。
  • 手机抽屉的遮罩用 var(--dsw-alias-bg-mask-1, ...),不写死 rgba(0,0,0,.38)——那在深色下脏得发灰。

验证状态

项 状态
语法检查(index / client / typert) ✅ node --check
readWindow 日志解析(set/clear/穿插/非法值) ✅ 8/8
ALS + resolveModelInfo 包装(上下文内/外) ✅ 4/4
并发隔离(两会话交错 pre-step) ✅ 2/2
waterfall prepend 语义(compaction 看到覆盖值) ✅ 3/3
apply() 冒烟(注册/patch/服务/卸载还原) ✅ 23/23
client 契约(codec / inject / call 信封) ✅ 19/19
配置树包含本插件 ✅ dsh web --dump-config 可见
桌面 UI 渲染 + 打开面板 + 点档位生效 ✅ 无头 CDP 实测
手机 UI(390×844 DPR2) ✅ 胶囊 ctx 256K、抽屉、6 档位、× 关闭
跨刷新持久化 ✅ 二次探测直接读到上次设的值
界面上下文环跟随 ✅ 日志实证:request/context 的 contextWindow 为设定值
滑块交互契约(拖动不提交 / 把手跟手 / 应用才生效) ✅ 6 项断言全过
深浅色主题适配(桌面 + 手机) ✅ 强制切两种主题,面板 bg/border/shadow/文字全部随之变化
zod 解析失败的兜底(不炸启动) ✅ 无 node_modules 目录实测
compact 真实提前触发 ✅ 真实 Web 会话写入 16K,后续 request/context 为 16K,官方 compaction/start → summary → end(success) 已观察到;触发边界受可压缩区间与固定提示开销影响

亲眼确认 compact 线动了

触发线的计算是 floor(contextWindow × thresholdRatio);默认 ratio 为 0.8,因此 16K 的名义阈值是 12,800 tokens。达到阈值是必要条件,但不是充分条件:官方 compaction-basic 还必须找到可压缩的历史前缀,并保留 retainTokens;system prompt、工具定义等固定开销不能靠摘要消掉。

本机真实 Web 验收结果:

  • 测试会话的 context-window/set 持久化 16000(ignorable: true);压力回合及后续短回合的 request/context(seq62/79/107/133)contextWindow 均为 16000。
  • 官方自动压缩真实记录了 compaction/start → compaction/summary → compaction/end 成功,证明会话覆盖已进入官方 compact 路径。
  • 用当前版本生产 dsh-token-meter 对日志重放:在只有约 2,574 surface tokens、保留预算 2,560 时,虽总压力已超过名义阈值,仍没有可切掉的前缀;增加一条长消息后 surface 扩大,才选中约 2,574 tokens 的历史并完成 compact。因此首次 compact 事件可以晚于 12,800,不能只凭 UI 环的整数或用户输入字符数判断阈值是否生效。
  • compact 后以生产 TokenMeter.measure 重放,在这个测试会话的当前 anchor 下,保守的非-surface 压力下界约 21,624 tokens;下一 turn 的下界约 24,517,都高于 12,800。官方引擎因此又对极小 span 做了一次有界无收益尝试(summary 未变短);下一条短 turn 又观察到“成功 summary + 一次小 span 拒绝”,但原生日志有 turn/end,没有阻塞后续 prompt。此结果只证明该 session 的连续两轮行为,不代表无限重试,也不是所有会话共用的固定常数。这个 16K 测试点低于该 session 测得的当前上下文底座;真实使用应按自己的 preset、工具和注入提示调到高于该 session 的不可压缩部分。

800K × 0.8 = 640K 是模型默认窗口下的名义阈值;本次没有另做灌到 640K 的默认窗口对照,因此这里只报告公式,不把它说成已实测的对照结果。


排障

按这个顺序查,每一条都对应一个真实踩过的坑。

1. 插件装了我看不到控件

先分清是"没装上"还是"渲染成空":

# ① client bundle 有没有被交付:抓首页 HTML,搜 /plugins/?? 组合列表里有没有 <包名>/client.js
# ② typert 端点有没有被认领(应该返回 200 且 body 是 gateway/bad-request,404 说明清单没注册)
curl -s -X POST http://127.0.0.1:3080/api/contextWindow/getState -H 'content-type: application/json' -d '{}'

2. 整个 DSH 起不来,报 ERR_MODULE_NOT_FOUND: Cannot find package 'zod'

zod 是 dsh-typert-loader 校验 codec 的硬要求(它检查 "_zod" in schema,手写 {parse} 会被拒)。Node 的模块解析是从插件文件位置往上找,插件源码不在 profile 的 node_modules 树里时就找不到。

本插件已内置多层兜底:先试常规解析,再试 $DSH_HOME 与 ~/.dsh/profiles/*/node_modules,全失败就退到结构等价的直通 codec(功能不受影响,只往 stderr 写一句告警)。正常情况下你应该看不到任何告警。

3. 改了窗口但界面上下文环没变

确认三件事:

  1. 发消息了吗?request/context 只在窗口发生变化时才写,设完窗口得发一条消息。
  2. 日志里写的是什么?解压会话日志看最后几条 request/context:
node tools/read-request-context.mjs ~/.dsh/sessions///session.jsonl.zstd
  1. 补丁挂上了吗?看 ~/.dsh/diagnostics/dsh-context-window.log:
patch session: ok (append+requestContext), frozen=false

如果出现 PARTIAL appendOk=... readOk=... frozen=...,说明 Session 被冻结改不动,那是另一种修法。

4. 改 client.js 不生效 / 改 index.js 不生效

  • client.js:刷新页面即可,bundle URL 带内容哈希 rev,不用重启
  • index.js(宿主侧):必须重启,宿主代码不热载

重启前先看监听端口的进程真实命令行,别用裸 node bin.js web 覆盖它——本机的真实启动链是 dsh-memory-v3-runtime\dsh-web-entry.mjs web,会额外注入 --patch startup-overlay.yml。


卸载

dsh plugin --profile web remove dsh-context-window

或者手动从 ~/.dsh/profiles/web/package.json 删掉 dependencies["dsh-context-window"] 与 dsh.profile.bundles 里的对应项,再 pnpm install。

完全无残留:卸载后所有会话回到模型默认窗口,日志里的 context-window/* 事件被忽略(DSH 对未知事件类型是宽容的)。


已知限制

  1. 模型切换没有事件可监听。DSH 没给插件暴露 model-selection 变更事件,所以面板打开时每 2.5 秒轻量重拉一次来刷新"模型默认"对比值;面板关着时不轮询。
  2. 每次请求多写一条 request/context。这是双端 patch 的代价(见上文),事件很小,但日志体积会略微增长。
  3. 子代理会话:agent/pre-step 对所有 agent 生效,所以子代理也会读到自己会话的覆盖值(通常子代理没有覆盖,走模型默认,行为不变)。
  4. /compact 手动命令不受影响:手动压缩不看阈值,直接压。
  5. 窗口不要低于当前会话的不可压缩底座:system prompt、工具 schema、request envelope 与 retain budget 的组成依会话而异。若 floor(contextWindow × thresholdRatio) 低于该会话能达到的底座,官方 compact 仍会尝试可压缩前缀;压完若仍超线,可能再对很小的尾段尝试一次,并以“summary not smaller”结束。自动压缩不会因此拦住后续 prompt,但会增加无收益压缩尝试;应按该会话实际 prompt/tool 开销设置窗口。本机16K实测只是一个具体 session 的结果,不是全 profile 固定常数。

目录结构

dsh-context-window/
├── index.js          # 宿主侧:ALS patch + 会话读写 patch + RPC 服务
├── client.js         # 浏览器侧:胶囊 + 双形态面板(桌面气泡 / 手机抽屉)
├── typert.js         # Typert 清单:让 /api/contextWindow/* 被宿主认领
├── cordis.patch.yml  # bundle patch:一行挂进 web profile
├── docs/             # README 用的实机截图
└── package.json      # dsh.bundle.patch 自挂载 + dsh.client.platform: web

License

MIT

常见问题

6 问
答案由本站依据条目字段整理,不引用上游原文
dsh-context-window 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add github:qq-24/dsh-context-window` 即可。

dsh-context-window 的验证等级是什么意思?

L5 · 运行验证通过。在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来

dsh-context-window 安全吗?

低风险。

dsh-context-window 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-context-window 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

同名或近似条目

2 条
不同作者的仓库分开列,请确认你要装的是哪一个
记忆与知识
按星标排序,可作替代方案

ruflo

ruflo

L3 · 安装规范通过 7.4 万 星

OpenViking

OpenViking

面向 DeepSeek Harness 的 OpenViking 记忆与上下文插件:pre-step 自动召回与画像注入、会话捕获、`vik

L3 · 安装规范通过 3.9 万 星

WeKnora

WeKnora

把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己

L4 · 沙盒安装通过 3.3 万 星

distilly

distilly

Distilly — Distill how they think into reusable Skills for any Agent o

L4 · 沙盒安装通过 2.5 万 星

EverOS

EverOS

L4 · 沙盒安装通过 1.3 万 星

MemOS

MemOS

L4 · 沙盒安装通过 1.2 万 星

qq-24 的其它插件

1 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。