🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话压缩助手 133563825as-ai/oha-whale-compress

DeepSeek 客户端
133563825as-ai37 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

按 token 阈值自动压缩会话,一键手动触发

31.5/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/28 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/133563825as-ai/oha-whale-compress.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
生态插件
可安装,未声明 dsh 能力
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 37 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-oha-whale-compress(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 15:37:34

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 8 处,展示前 8 条)
  • 发起网络请求
    client/client.js:103
    const res = await fetch(path, {
  • 读取本地文件
    src/config-store.js:51
    const raw = await readFile(file, 'utf8')
  • 写入本地文件
    src/config-store.js:66
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/config-store.js:67
    await writeFile(file, JSON.stringify(next, null, 2) + '\n', 'utf8')
  • 读取本地文件
    src/http.js:175
    const buf = await readFile(ICON_PATH)
  • 读取本地文件
    src/injector.js:190
    const text = await readFile(file, 'utf8')
  • 写入本地文件
    src/injector.js:213
    await copyFile(file, backup)
  • 写入本地文件
    src/injector.js:214
    await writeFile(file, result.text, 'utf8')
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 自定义token阈值
  • 自动压缩会话
  • 一键压缩当前会话

DeepSeek Harness「压缩会话」插件:自定义 token 阈值自动压缩、一键压缩当前会话、输入框常驻按钮可开关。哦鲸鲸出品。

README

由 DeepSeek 最新模型翻译生成
dsh-oha-whale-compress DeepSeek Harness 专用「压缩会话」插件(哦鲸鲸 family,与 dsh-session-manager 同品牌设计)。 功能 - 侧边栏底部入口(挨着「会话管理」):点开完整面板。 - 完整面板:自动压缩开关与阈值 · 输入框下方按钮开关 · 压缩用 provider / model · 一键「压缩当前会话」。 - 自动压缩:上下文估算超过阈值时自动压一次。阈值是绝对 token 数,可开关、可改(默认 409600,即 400K)。 - 输入框下方常驻「压缩」按钮:可一键显示 / 隐藏,关掉后输入框下方恢复干净;点它开的是减半面板。 - 减半面板:只留两个开关 + 压缩按钮 + 结果,去掉选 API、保留条数与提示词。 - 查看结果:展示当前会话大小(节点数 / token 数)与本次压缩的状态 / checkpoint 文本。 两个开关在完整面板与减半面板里都显示 —— 减半面板正是从输入框下方的按钮点进来的,开关得在它自己面前可调。两个开关都是拨动即存;阈值输入在失焦或回车时落盘(边打字边存会把中间态写进配置)。 自动压缩怎么工作 框架自带的自动压缩按窗口比例判定(contextWindow * thresholdRatio),表达不了「到 400K 就压」这种绝对值。
展开完整文档(README 剩余 1 节)
dsh-oha-whale-compress

DeepSeek Harness 专用「压缩会话」插件(哦鲸鲸 family,与 dsh-session-manager 同品牌设计)。

功能

- 侧边栏底部入口(挨着「会话管理」):点开完整面板。
- 完整面板:自动压缩开关与阈值 · 输入框下方按钮开关 · 压缩用 provider / model · 一键「压缩当前会话」。
- 自动压缩:上下文估算超过阈值时自动压一次。阈值是绝对 token 数,可开关、可改(默认 409600,即 400K)。
- 输入框下方常驻「压缩」按钮:可一键显示 / 隐藏,关掉后输入框下方恢复干净;点它开的是减半面板。
- 减半面板:只留两个开关 + 压缩按钮 + 结果,去掉选 API、保留条数与提示词。
- 查看结果:展示当前会话大小(节点数 / token 数)与本次压缩的状态 / checkpoint 文本。

两个开关在完整面板与减半面板里都显示 —— 减半面板正是从输入框下方的按钮点进来的,开关得在它自己面前可调。两个开关都是拨动即存;阈值输入在失焦或回车时落盘(边打字边存会把中间态写进配置)。

自动压缩怎么工作

框架自带的自动压缩按窗口比例判定(contextWindow * thresholdRatio),表达不了「到 400K 就压」这种绝对值。本插件的做法是把判定权拆开:

1. 注入 preset 时把父类的 thresholdRatio 让到一个哑值(0.02),父类从此不再实际把关 —— 但仍保留 2% 窗口的兜底,万一插件那条路径失效也不至于彻底失控;
2. 子类 WhaleCompactionEngine.compactIfNeeded 接管「步进压力」这一路:
- 未到 autoThresholdTokens → 直接返回 null,父类根本不会跑;
- 到了阈值 → 交给父类,此时它的哑阈值必然已被越过,压缩照常发生;
3. context-overflow(模型已经报窗口溢出)是兜底路径,不受阈值与开关管辖,一律放行。

配置落在 ~/.dsh/storages/dsh-oha-whale-compress/config.json:

| 字段 | 默认 | 含义 |
| autoCompress | true | 自动压缩总开关 |
| autoThresholdTokens | 409600 | 触发线(绝对 token 数) |
| dockButton | true | 输入框下方按钮是否显示 |

为什么 preset 里会多出一段托管块

自动压缩保留多少由框架的 selectCompactableRange 决定 —— 那是 dsh-compaction-basic 的内部函数,既不在 @deepseek-ai/dsh-compaction 的导出里,插件也触及不到。所以面板没有、也不该有「保留多少条」这类选项(早期版本有过一个 keepN,从头到尾没接上,已删除)。实际保留量写在这段托管块里:retainTokens: 40000,即压缩后保留尾部约 40K tokens。

retainTokens 用绝对值而不是 retainRatio,一是语义直接,二是可以绕开上游「retainRatio 必须小于 thresholdRatio」的加载期校验(那条校验只在比例存在时触发)。托管块由注入器写入、由还原精确删除,不会碰你自己写的 config。

触发链路

侧边栏 / 常驻按钮 → POST /oha-whale-compress/compress {sessionId} → host 取 agent = ctx.get('agents').get(sessionId) → ctx.get('commands').execute(agent, '/compact', [], signal)
→ (command-compact 在压缩 group 里执行 compactNow,真正压缩)
→ 返回 { ok, message }

手动压缩必须走框架 ctx.get('commands').execute(agent, '/compact', ...),绝不直写会话日志。

自动压缩走的是另一条路:agent/pre-step → compactIfNeeded('pressure') → 本插件先判阈值 → 再交父类。

HTTP 路由

| 路由 | 方法 | 作用 |
| /oha-whale-compress/configure | GET / POST | 读 / 写面板配置(provider / model / keepN / promptTemplate / prompt / autoCompress / autoThresholdTokens / dockButton) |
| /oha-whale-compress/status | GET | 当前会话大小(?sessionId=,nodes/totalTokens),非破坏性 |
| /oha-whale-compress/compress | POST | {sessionId} → 触发 /compact |
| /oha-whale-compress/icon | GET | 返回 assets/icon.png(image/png,max-age=3600) |

把引擎挂到 preset 上

自动压缩要真的按本插件的阈值走,preset 里那行引擎名必须换成 dsh-oha-whale-compress/engine。

运行时的权威源是 profile 的 cordis.patch.yml:每个 preset 在 config.plugins 里内联一份完整 composition,而 @deepseek-ai/dsh-agent-preset 的 schema 里 plugins 是必填字段 —— 所以 ~/.dsh/.agent-presets//agent.cordis.yml 那套目录不是加载源,改它没有任何效果(踩过)。

一个文件里内联着四个 preset,因此要批量替换:

cd /root/dsha-oha-whale-compress && node --input-type=module -e "
const { injectPreset } = await import('file:///root/dsha-oha-whale-compress/src/injector.js')js
const r = await injectPreset({
presetPath: '/root/.dsh/profiles/web/cordis.patch.yml',
userRoot: '/root/.dsh/profiles',
mode: 'inject',
expectedCount: 4
})
console.log(r)"

还原把 mode 换成 'restore' 即可。整个注入器守五条规矩:只写 user 根之内、绝不重新序列化 YAML(注释与 !!js 表达式原样保留)、唯一性或期望数量硬校验、先备份、幂等。

expectedCount 不是装饰:数量对不上就报 count-mismatch 并拒绝写入 —— 宁可不动,也不猜着改。

dsh-purge 的「应用补丁」也会写 cordis.patch.yml。如果哪天应用完补丁发现阈值不生效了,重跑一遍上面的注入即可。

安装 sh
dsh plugin --profile web add dsh-oha-whale-compress

或源码方式:dsh plugin --profile web add file:/root/dsha-oha-whale-compress。

生效条件

| 改了什么 | 怎么生效 |
| src/*(host 半) | 重启 dsh |
| client/client.js | 刷新页面 |
| preset 的引擎行(注入 / 还原) | 重启 dsh(loader 不监听 preset 文件) |

血泪教训(勿踩)

- 插件只硬 inject webServer,其余服务一律 ctx.get() 运行时懒取,取不到优雅返回(如 503),绝不阻塞激活 —— 否则整棵插件树崩,Web 打不开。
- compaction 服务是隔离的(压缩 group isolate),profile 插件取不到,只能走 /compact 命令触发;要改压缩策略,只能像本插件这样顶替 preset 里的引擎行。
- package.json 的 exports 必须声明 ./engine:preset 行写的是 dsh-oha-whale-compress/engine,缺了它加载直接 ERR_PACKAGE_PATH_NOT_EXPORTED。宿主只换解析基点,不会绕过 ESM 的 exports 白名单。
- 测试夹具要跟着宿主的会话 API 走:0.1.7 起 dsh-compaction-basic 的摘要调用会读 agent.session.toolHistory(),假的 session 漏了这个方法,所有走原生支路的用例会一起红。
- 反转布尔写错了不报错,只会让一整块 UI 静默不渲染。 Overlay 里把完整面板的判定写成 full: mode.mode !== 'full',方向一反,if (full) 包住的字段(开关、阈值、API、提示词、保存按钮)一次都没出现过,面板却"看着正常"。改完模式判定,务必把每个字段挨个点一遍。
- shell.overlay 和 conversation.composer.dock 的 slot props 是空对象。 宿主渲染它们时写的是 renderSlot(name, {}),所以 props.useSessions / props.sessionId / props.modelDirectories 全是 undefined。这些数据得自己从 client 侧服务取:ctx.get('uiSession').current(当前会话绑定)、ctx.get('modelDirectories')(模型目录)。
- sessions store 里没有 current 字段。 它只有 byId / list;useSessions((s) => s.current) 恒为 undefined —— 这就是面板永远显示「未打开会话」的根因。当前会话要靠 uiSession.current 的绑定值,或从 byId 里找 retainedBy.mainView > 0 的那一个(本插件两条路都走,前者优先)。
- 异步加载的值不要直接喂给开关。 面板 state 若用默认值起跳、等 fetch 回来再改成真实值,开关就会当着用户的面重播一次切换动画 —— 每次打开面板都重播一次。初值应当取模块级 config store 里已经加载好的那份。注意那份必须在所有 useState 之前取,否则撞 const 的 TDZ。

License

MIT
预览分享卡片长什么样 ↓133563825as-ai/oha-whale-compress
分享 · DeepSeek Harness Hub
133563825as-ai/oha-whale-compress

按 token 阈值自动压缩会话,一键手动触发

这是你的仓库?认领条目

回到顶部