dsh-acp-window-guard: Adding guardrails for windows and channels in billion-context (ACP)

前言

在 DSH 里跑大上下文对话时,如果宿主进程挂着 billion-context(ACP) 做代理与压缩,按理说不该再出现「一百多万 token 直接打上游」或「消息卡十五秒无首字后失败」。实际环境里常见两类现象:上游返回 prompt is too long(code 11115),或本地没有把超长请求拦住却最终 400。

根因往往不在模型本身,而在于 ACP 对「可用窗口」的估算路径不一致:有的请求带齐插件上下文头,有的走匿名链 pfa-* 或旁路 fetch,默认配置只有 20 万级窗口,再叠加升级后补丁被覆盖,超窗保险会整段失效。下面介绍社区插件 dsh-acp-window-guard(维护者 Lumid0uce,分类 admin-security),在启动时用幂等步骤抬高配置下限、重打 dsh-native.js 补丁,并在 fetch 层把模型请求钉回 ACP /bili/ 通道。

这是什么

dsh-acp-window-guard 是 DeepSeek Harness 的 Cordis patch 型插件(当前资料中版本 0.3.0,MIT 许可证)。它面向已使用 billion-context(ACP) 的 DSH 配置,解决三件事:

  1. 避免匿名或未归因请求按 ACP 默认 modelContextLimit(200000)推算窗口,导致压缩目标偏小、上游仲裁失败。
  2. 在 declaredWindow 缺失时,让本地「可证超窗」逻辑仍有 1M token 量级兜底,超长请求在本地 422 拒掉,而不是裸发。
  3. 从 0.2.0 起在 globalThis.fetch 上安装桥接,防止部分轮次(资料中提及手机 App 消息等场景)模型请求绕过 ACP。

插件全程 try/catch,任一步失败只记日志,不阻塞宿主启动。上游 issue #5907 与 PR #5910 修合后,作者说明可卸载本插件;届时 bundle 补丁可能与上游重叠并出现 pattern not found(不抛错)。

问题背景:窗口从哪里来

ACP 的「可用窗口」为 contextWindow − maxTokens。contextWindow 常见两种来源(资料中的表格归纳):

来源 数值 结果
宿主透传 x-bili-plugin-context-window 1,000,000 − 128,000 约 872,000,压缩后行为正常
拿不到头(匿名链、部分子代理调用等) 配置默认 200000 − 预留 32768 167,232,仍可能判超窗并触发 forwarding once for the upstream to arbitrate

此外,bodyProvablyOverWindow 在 declaredWindow === undefined 时直接返回 undefined,本地超窗保险不生效,百万级 prompt 会原样外出。插件针对的就是「窗口算小 + 保险哑火 + 请求旁路」这一组合。

核心功能

启动时执行两类幂等操作(可通过 cordis.patch.yml 的 config 调整或关闭部分能力):

1. 抬高 ACP 配置里的 context 下限

把 ~/.config/billion-context/billion-context.json 的 modelContextLimit 抬到 minContextLimit(默认 1000000),修改前备份为 .bak-window-guard-<ts>。

2. 维护 dsh-native.js 超窗补丁

在 profile 内 billion-context 包的 dist/agent/dsh-native.js 中,将两处
bodyProvablyOverWindow2(body,init,effectiveContextWindow(ctx))
改为带 ??MIN_ASSUMED_WINDOW_TOKENS 的形式(兼容 bodyOverWindowDetail2 的 0.1.213 命名);上游覆盖文件后会自动重打。patchAcpCode: false 可只改配置、不动代码。

3. fetch 桥接(0.2.0+)与身份头(0.3.0)

  • fetch bridge:对模型端点(/chat/completions、/completions、/responses、/messages)且目标不在 ACP 的请求,改写为 {ACP代理}/bili/{原始URL}。启动日志可见 bridge: installed:<origin> 或 fetch bridge installed;fetchBridge: false 可关闭。
  • 0.3.0:改写时补上 x-bili-plugin、x-bili-plugin-conversation 等头,减轻漏网请求被当成匿名链;日志中期望 hook: on,bili.log 不再频繁出现 new anonymous session pfa-…。

可选的环境变量 ACP_GUARD_BASEURL=1 会改动 ~/.dsh/settings.yaml 里 provider 的 loopback baseURL,但桌面端退出时会写回配置,默认关闭;日常一般只需运行时 bridge。

安装与启用

资料中的安装方式是将插件目录挂进当前 DSH profile 的 node_modules,并在 package.json 里声明 link 依赖与 bundle(Windows 示例 profile 名为 desktop,macOS/Linux 换成本机 profile 目录名)。修改 package.json 前请先备份。

Windows(junction + package.json)示例:

$src = "C:\path\to\dsh-acp-window-guard"
$dst = "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-acp-window-guard"
New-Item -ItemType Junction -Path $dst -Target $src

在 ~/.dsh/profiles/desktop/package.json 中:

  • dependencies 增加:"dsh-acp-window-guard": "link:<$src 的绝对路径>"
  • dsh.profile.bundles 数组追加:"dsh-acp-window-guard"

Unix 环境将 junction 换为 ln -s 即可,路径按本机 profile 调整。

生效顺序(仅在下一次 ACP 代理启动时应用插件逻辑):

  1. 退出 DSH 桌面端(以便 bundle 写回 profile)。
  2. 结束旧 billion-context 节点进程并重新启动代理,例如 Windows:
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
  Where-Object { $_.CommandLine -match 'billion-context' } |
  ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
Start-Sleep -Seconds 2
node "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\billion-context\dist\index.js" start --host 127.0.0.1 --port 18790
  1. 重新打开 DSH。

运行环境要求(package.json):Node ^22.19.0 || >=24.0.0。

验证方式

查看 ACP 日志 ~/.local/state/billion-context/bili.log:

  • 匿名链窗口应从约 167232 变为约 967232(1,000,000 − 32,768);有归因会话仍约 872000。
  • 被本地拦下的裸发请求:HTTP 422,响应头 x-bili-gate: oversize-refusal-unattributed。

资料还给出了直连代理与 /bili/ 重写通道的 curl 对照(非 /bili/ POST 得 403,/bili/http://… 形式得 200),用于确认代理只接受改写通道。

不想装插件时,仓库内脚本可手工等价执行(幂等):

  • Windows:pwsh scripts/reapply-acp-window-patch.ps1(-CheckOnly 只查不改)
  • macOS / Linux:bash scripts/reapply-acp-window-patch.sh(--check 只查不改)

配置项

cordis.patch.yml 内 config 常用字段:

键 默认 说明
minContextLimit 1000000 期望的最小 modelContextLimit
patchAcpCode true 是否维护 dsh-native.js 补丁
dryRun false 只报告,不写盘
configFile 自动 覆盖 ACP 配置路径(亦认 BILI_CONFIG_FILE / XDG_CONFIG_HOME)
acpBundlePath 自动 覆盖 dsh-native.js 路径
fetchBridge 默认开启 设为 false 关闭 fetch 兜底

回滚

从 .bak-window-guard-* 恢复 billion-context.json 与 dsh-native.js 即可;或设置 patchAcpCode: false 停止改代码。资料中含 PowerShell 的 Copy-Item 回滚示例,路径需按本机 profile 下的 billion-context 包位置替换。

适用场景与注意

适合谁: 已在 DSH profile 中启用 billion-context,并出现超长 prompt 报错、匿名会话窗口异常偏小,或日志显示部分轮次完全未经 ACP 的开发者。

权限与安全: 插件以当前 DSH 进程权限运行,会修改用户目录下的 ACP 配置与(可选)node_modules 内 JS 文件。安装前应阅读 GitHub 仓库 源码与 MIT 许可证,确认可接受对 ACP 的二进制邻近补丁策略。社区插件目录 SkillHub 条目 与 GitHub 无 DeepSeek / 幻方官方从属关系,属社区「一切皆插件」生态。

版本提示: 0.2.1 起兼容 billion-context 0.1.213 的 bodyOverWindowDetail2 命名;命令输出中的 shape 字段可确认命中哪一版补丁逻辑。

结尾

经过上面的步骤,dsh-acp-window-guard 把 ACP 的窗口下限、本地超窗拒发和 fetch 通道路由收成启动期可重复的护栏,专门针对匿名窗口与旁路请求两类长期痛点。上游 billion-context 合入正式修复并升级后,可按 README 建议卸掉插件,仅保留无害的配置抬高亦可。

  • 社区目录:https://www.skillhub.cn/plugins/Lumid0uce/dsh-acp-window-guard
  • 源码与说明:https://github.com/Lumid0uce/dsh-acp-window-guard
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye