@local/context-guard · 上下文管家
已合并进
dsh-wide-focus(v0.12.0 起)。 本仓库不再单独安装; 请改用 https://github.com/quanwenbo/dsh-wide-focus,上下文管家的芯片、 决策卡片与/context-guard/*路由都已包含在里面。
一个独立的 DSH 插件(host + client 两半),在任务面板里显示当前会话的上下文占用,并在水位越过时提醒你压缩或换会话。点击指示器可展开决策卡片:已用占比、token 占用、缓存命中、轮次、任务连贯性,以及「继续本会话 / 新开会话」的利弊与推荐;卡片底部是唯一的动作按钮「生成交接文档并新开会话」。
0.9.x 把卡片扩回决策视图(指标 + 连贯性 + 继续/新开建议),保留 0.7.0 的锚定与磨砂蒙版;所有百分比统一按已用占用显示,不再显示剩余量。
它做什么
- 在任务面板右上角显示占用指示:彩色圆点 + 百分比(按 prompt tokens / 模型窗口计算)。
若同时装了
@local/wide-focus(任务面板插件),指示器通过window.__dshWideFocus.registerTool挂到面板工具位; 没有任务面板时回退到会话标题栏。点击指示器展开/收起决策卡片。 - 占用分级决定颜色:<60% 绿 → 60% 琥珀 → 70% 橙 → 80% 红 → 85% 红色脉冲闪烁
(
prefers-reduced-motion下自动关闭动画)。 - 越过 70% / 80% / 85% 时各弹一次浮层 toast 提醒(每个会话每级只提醒一次): 70%「可再次压缩或继续」、80%「建议开新会话并迁移摘要」、85%「立刻生成交接并开新会话」。
决策卡片
- 以任务面板为锚居中弹出,面板同时变暗模糊;
Esc或点击卡片外关闭。 - 抬头:健康度
NN%(= 100% − 占用)、状态词(宽裕 / 偏紧 / 偏高 / 临界)、Token 占用 xK / yK · NN%、单条进度条、一句建议。 - 指标四行:Token 占用(百分比 + prompt/窗口)、缓存命中(有缓存 token 时显示)、轮次(turns · 工具调用次数)、任务连贯性(高 / 中 / 低;按轮次、工具调用与改动文件数判定)。
- 决策区只讲方向、不描述本会话状态:「这些情况下不切换」(同一目标/代码还在改、下一步依赖刚讨论的细节、验证未收尾)与「这些情况下建议换」(任务已收口要换主题、前面主要是探索且结论已写下、同一问题反复返工),下面一行推荐结论:
- 占用 ≥ 85% → 建议新开;
- 最近压缩过(占用比上次明显下降)→ 建议继续;
- 占用 ≥ 80% 且像讨论 → 建议新开,否则「两边都行」;
- 其余 → 建议继续。
- 底部唯一动作按钮「生成交接文档并新开会话」:调用 host 写
docs/handoff/*.md,复制路径与摘要,再打开新会话;推荐「新开」时按钮为白底高亮。
阈值
| 占用 | 颜色 | 行为 |
|---|---|---|
| < 60% | 绿 | 无 |
| ≥ 60% | 琥珀 | 变黄,状态词「偏紧」,不打扰 |
| ≥ 70% | 橙 | toast 一次 |
| ≥ 80% | 红 | toast 一次,自动打开卡片 |
| ≥ 85% | 红色脉冲 | toast 一次,最高优先级 |
数据来源(全部本机,只读)
宿主侧 ctx.get('sessions') 拿到活会话对象,按下面的优先级取「当前提示词有多大」:
sessionProjections.stateOf(session, 'contextPressure')的pressureTokens(提供方最近一次报告的 prompt 规模;同一次读取里的contextWindow也优先用它)——这是 DSH 界面里显示占用时用的同一份数据;缺pressureTokens时用projectedTokens。- 最近一条
assistant/message的usage:inputTokens + cacheReadTokens + cacheWriteTokens(缓存命中的部分同样占上下文,不能只取 uncached)。 tokenMeter.measure(session, requestHeader).totalTokens—— 仅在它是复用提供方记账(baseline.kind === 'usage')或不超过模型窗口时采用。tokenMeter 在请求信封与最近一次成功调用不一致时会对整个 envelope 重新定价,那个值可能远超窗口(曾出现2.17M / 1.05M),不能当作实时占用显示。- 都没有时才退回
字符数 / 3.2的粗估(指示器加≈,卡片脚注说明)。
ratio = promptTokens / contextWindow;超过 100% 时ratio夹到 1、并置overflow: true,界面显示>100%而不是假装成 100%。cacheHitRate = cacheReadTokens / promptTokens(夹到 0–1)。- 轮次、工具调用、文件路径来自
session.snapshotEvents()的只读统计。
路由
GET /context-guard/state?sessionId=<id>→ 占用与元数据。POST /context-guard/handoffbody{ sessionId }→ 在会话 cwd 的docs/handoff/下写一份交接 markdown,返回{ path, markdown }。
路由
GET /context-guard/state?sessionId=<id>→ 占用与元数据。POST /context-guard/handoffbody{ sessionId }→ 在会话 cwd 的docs/handoff/下写一份交接 markdown,返回{ path, markdown }。 交接内容:一、我们在做什么;二、最近改了什么;三、当前状态;四、关键决策/约束;五、下一步(自动生成,可修改,含任务面板里未完成的第一条待办)。
安装
# 1) 从 AtomGit(公开仓库,固定 commit)
dsh plugin --profile desktop add git+https://github.com/quanwenbo/dsh-context-guard.git#<commit-sha>
# 2) 从本地目录(开发时)
dsh plugin --profile desktop add C:\Users\BOB\dsh-plugins\context-guard
安装后刷新页面即加载客户端;宿主路由(含 handoff)要重启一次桌面客户端才注册(重启前指示器显示 —)。
与任务面板插件的桥接:dsh-wide-focus 通过 window.__dshWideFocus.registerTool 暴露工具位;本插件每秒检查一次桥是否可用,可用则把指示器挂到面板工具行,否则回退到会话标题栏(conversation.session.header.utilities)。
License
MIT © 2026 BOB
自动打开规则:占用 ≥80% 时卡片会自动展开,但每个会话最多自动打开一次(标记写在 dsh.context-guard.autoOpened:<session>);之后可以随手关掉(✕ / Esc / 点卡片外),再涨到 85% 只弹提醒、不再自动弹卡。手动打开不受限制。
模拟测试(不消耗真实上下文)
在 DSH 的开发者控制台里(F12 → Console)可以直接伪造占用水位,卡片与提醒会立刻按该档位渲染:
__contextGuard.simulate(0.82) // 模拟 82% 占用
__contextGuard.simulate(null) // 退出模拟,回到真实数据(刷新页面也会清除)
模拟值只在当前页面内存里生效,不写 profile、不会影响真实会话;render-check.mjs 与 simulate.mjs 是自动化断言脚本(node simulate.mjs 会跑 30%–96% 十个档位)。
已知边界
- 压缩动作本身由对话里的 AI 执行(
compress工具),插件只负责提醒。 - 用量取自上一轮 prompt 大小,与真实 prompt 可能有小幅偏差(工具结果/图片等)。
- 「换会话」通过
uiWorkspace.startSession()打开,但无法把摘要自动写进新会话的输入框;路径已复制,需要你贴一句「读这个文件继续」。
No comments yet. Be the first to write one.