类型: OpenCode Plugin — DCP 上下文限制同步器
仓库: https://github.com/raketenkater/opencode-dcp-dynamic-limits
1. 这是什么插件?
opencode-dcp-dynamic-limits 是一个专门为 DCP (@tarquinen/opencode-dcp) 服务的 OpenCode 插件。核心概念:
DCP(Dynamic Context Pruning)是个独立的上下文裁剪插件 DCP 不知道你当前用的模型上下文窗口有多大 当你切换模型时,DCP 经常被留下陈旧的限制 —— 该剪的时候不剪,不该剪的时候乱剪,更糟的是把 dcp-system-reminder持续塞进聊天里这个插件在真实的 chat 请求上钩入 OpenCode,识别当前模型并即时更新 DCP 配置
写这个插件的人是个本地 GGUF 玩家(用 llm-server + ik_llama.cpp / llama.cpp),经常在云端模型和本地 GGUF 之间来回切,所以吃了这个亏。
与"自动配置 DCP"的区别:
dcp.jsonc | ||
/slots → /v1/models → manifest 逐级回退 | ||
2. 用来做什么?
使用它来:
✅ 本地 ↔ 云端模型 切换时自动同步上下文窗口 ✅ 修复 DCP 在错误时机裁剪 的问题 ✅ 消除 dcp-system-reminder在聊天里持续刷屏✅ 支持 llm-server/ik_llama.cpp/llama.cpp/ Ollama / LM Studio / Jan / text-generation-webui✅ 同时支持 OpenCode model manifest 里的云端模型 ✅ 写一个进程参数 → /slots→/v1/models的多层回退检测✅ 5 秒节流,不打扰正常 chat 流程
典型场景:
你:把模型从云端 Claude 切到本地 ik_llama 的 Qwen2.5-1M.gguf[dynamic-limits]- chat.params 钩子触发- 读 ps ax → 找到 ik_llama 进程的 --ctx-size 262144- 计算 dcpMin=157286, dcpMax=222822- 写入 ~/.config/opencode/dcp.jsonc- 把 pruneNotificationType 改成 toast,nudgeForce 改成 softDCP 重新加载,立即知道自己的限制 = 222822后续对话不再误剪,不再乱塞 reminder3. 如何使用?
安装
需要先装 DCP(本插件是 DCP 的"修正"层):
npm install -g @tarquinen/opencode-dcpnpm install -g opencode-dcp-dynamic-limits在 ~/.config/opencode/opencode.json 中:
{"$schema": "https://opencode.ai/config.json","plugin": ["@tarquinen/opencode-dcp@latest","opencode-dcp-dynamic-limits" ]}DCP 必须先加载。本插件只在 DCP 已存在的基础上调整它的配置。
检测逻辑
对于本地 llama.cpp 风格的服务:
优先读运行时 -ctx-size(通过ps ax)回退到 /slots的n_ctx再回退到 /v1/models的max_model_len/n_ctx_train最后用 model manifest 的 context
-parallel的 slot 大小只作为诊断信息,不会被当作完整上下文窗口。
对于云端模型:
直接用 OpenCode model manifest 里的
limit.context具体来说,OpenCode 在 chat.params 钩子里会传入 input.model 对象,其中:
model.limit.context — OpenCode 内置的该模型上下文窗口
model.limit.output — OpenCode 内置的该模型最大输出 token 对 Anthropic / OpenAI / Google 等 OpenCode 内置 provider,这些字段是 OpenCode 自己知道并自动填的。calculateOnlineLimits 直接读它们: const contextLimit = model.limit?.context ?? 128000 const outputLimit = model.limit?.output ?? 8192 如果某个云端模型 OpenCode 不认识(limit 字段缺失),就会落到硬编码的默认值 128000 / 8192 —— 这是个已知盲点,但常见云端模型都被 OpenCode 内置覆盖了。
一个边界情况需要你注意 如果你配的是自定义 cloud provider(比如自己 proxy 转发的非标准 OpenAI 兼容端),isLocalModel(index.ts:24)会通过 provider.source === "custom" 误判为本地,走 llama.cpp 检测路径,那八成会失败。 解决方法:要么把 endpoint 指向 localhost(被 url.startsWith("http://localhost") 兜底
安静模式
默认开启安静模式(避免软警告区反复触发):
{"pruneNotificationType": "toast","compress": {"nudgeForce": "soft","nudgeFrequency": 50,"iterationNudgeThreshold": 50 }}安静模式下 minContextLimit = maxContextLimit,DCP 只在硬上限处裁剪,跳过中间的软警告刷屏。
4. 何时使用?
在以下情况使用:
✅ 你的 OpenCode 在多个模型间切换(尤其本地 ↔ 云端) ✅ 用 llm-server / ik_llama.cpp/llama.cpp/ Ollama 之类的本地后端✅ DCP 在错误时机裁剪 —— 上下文远没满就开始剪 ✅ 看到 dcp-system-reminder持续出现在聊天 里✅ 不同模型的上下文窗口差异很大(例如 32K vs 262K) ✅ 想要零配置切换 —— 不用每次手动改 dcp.jsonc
不要在以下情况使用:
❌ 不使用 DCP —— 没装 DCP 这个插件就是空转 ❌ 只用单一模型且上下文窗口稳定 —— 写死配置就够 ❌ 本地后端不是 llama.cpp / Ollama 风格 API —— 检测可能失败 ❌ 不希望 DCP 配置被自动改写 —— 这个插件会直接写 dcp.jsonc
⚠️ 重要注意事项
插件加载顺序:
{"plugin": ["@tarquinen/opencode-dcp@latest","opencode-dcp-dynamic-limits" ]}DCP 不存在时这个插件不会报错,但也没意义。
限制值固定为 60% / 85%:
dcpMin= 上下文 × 0.6dcpMax= 上下文 × 0.85安静模式下 dcpMin被强制等于dcpMax
这两个百分比不在配置里暴露,需要不同比例得改源码。
输出 token 估算(仅本地):
估算为 perSlotCtx / 4限制在 [8192, 16384]区间这个值不会写进 DCP 配置,只用于日志
节流:
5 秒内不会重复同步。但模型 ID 变化或计算结果变化会强制同步。
跳过的 agent:
title agent 触发的 chat 请求不会触发同步 —— 否则每次生成标题都会把 DCP 限制改一遍。
配置文件位置:
插件会写两个常见位置:
~/.config/opencode/dcp.jsonc~/.opencode/dcp.jsonc与 oh-my-opencode 等无关:
这个插件是纯配置同步层,不引入任何 agent / 工具 / 通知。和 opencode-background-agents 这类异步委派插件完全正交。
🔗 有用链接
仓库: https://github.com/raketenkater/opencode-dcp-dynamic-limits 依赖 DCP: https://github.com/tarquinen/opencode-dcp 配套后端 llm-server: https://github.com/raketenkater/llm-server OpenCode 文档: https://opencode.ai/docs NPM 仓库: https://www.npmjs.com/package/opencode-dcp-dynamic-limits
夜雨聆风