环境
- 插件:
@mars-sea/dsh-commandcode-provider@0.12.0(npm 最新版)
- DSH:桌面端 win-x64(nightly 通道),Windows 11
- 模型:
commandcode/claude-sonnet-5-5,reasoningEffort: xhigh
- 会话记录的
contextWindow 为 1000000
现象
会话第一步即失败,界面上依次出现两条提示:
Command Code stream error: max_tokens: 131072 > 128000, which is the maximum allowed number of output tokens for claude-sonnet-5-5
Command Code API 拒绝了这次请求:内容超出模型上下文窗口。正在压缩上下文后重试;如仍失败,请新建会话或减少上下文
第二条提示具有误导性:这不是上下文超限。压缩上下文后重试时 max_tokens 并没有下调,仍会以 131072 被同一个 400 拒绝,因此"新建会话 / 减少上下文"永远不会解决问题。
原因
1. 目录只有 context_length,插件用窗口推算输出上限,得到 131072
/provider/v1/models 只发布 context_length,parseCatalogResponse() 便以 Math.min(contextLength, DEFAULT_MAX_OUTPUT_TOKENS) 代替输出上限(DEFAULT_MAX_OUTPUT_TOKENS = 131072)。claude-sonnet-5-5 的窗口是 1,000,000,于是推导出的 maxTokens 就是 131072。
2. 请求侧同样落到 131072
stream() 中:
const modelMax = modelEntry?.maxTokens ?? 131072;
const requestedMaxTokens = Math.min(options.maxTokens ?? modelMax, modelMax, DEFAULT_GENERATE_MAX_TOKENS);
宿主不传 options.maxTokens 时,max_tokens = 131072。
3. 该模型的真实输出上限是 128000
131072 = 128 × 1024,比十进制的 128K 多 1072,上游按模型自己的上限直接 400 拒绝。
4. 这个 400 被误判为上下文超限,触发了无效的压缩重试
isContextOverflowDetail() 用 CLI_CONTEXT_OVERFLOW_PATTERN 判定:
/prompt is too long|context.*(length|window)|max_tokens|maximum.*tokens/i
错误正文里含 max_tokens,因此命中该正则,被当成上下文超限,进入"压缩后重试"分支;而重试并没有降低 max_tokens,必然再次失败,最终把错误暴露给用户。
建议修复
- 为有真实输出上限的模型维护上限表(至少 Claude 家族 ≤ 128000);或直接把
DEFAULT_MAX_OUTPUT_TOKENS / DEFAULT_GENERATE_MAX_TOKENS 从 131072 降到 128000——插件 CHANGELOG 自己也说明这些模型的真实输出上限是 64K / 128K,131072 并不比 128000 多出任何可用空间。
- 解析 400 里的上限并降额重试一次:
max_tokens: X > Y, which is the maximum allowed... 这类错误可以直接取出 Y,用 Y 重发,而不是压缩上下文。
- 不要把含
max_tokens 字样的错误一律当作上下文超限:它同时掩盖了这类输出上限错误,用户看到的是"上下文超限"的误导提示。
复现
任选 claude-* 模型(claude-sonnet-5-5 必现),宿主不传 options.maxTokens,插件即发送 max_tokens: 131072。
临时规避(供其他用户参考)
- 该会话改用非 Claude 模型(如
z-ai/glm-5.3-flash、deepseek/deepseek-v4.1-flash);
- 或在本地把请求上限对
claude-* 收窄到 128000(lib/index.js 的 stream() 内):
const modelMax = Math.min(modelEntry?.maxTokens ?? 131072, options.model.startsWith("claude-") ? 128000 : Infinity);
已验证改后请求为 max_tokens: 128000,语法校验通过。
环境
@mars-sea/dsh-commandcode-provider@0.12.0(npm 最新版)commandcode/claude-sonnet-5-5,reasoningEffort: xhighcontextWindow为1000000现象
会话第一步即失败,界面上依次出现两条提示:
第二条提示具有误导性:这不是上下文超限。压缩上下文后重试时
max_tokens并没有下调,仍会以 131072 被同一个 400 拒绝,因此"新建会话 / 减少上下文"永远不会解决问题。原因
1. 目录只有
context_length,插件用窗口推算输出上限,得到 131072/provider/v1/models只发布context_length,parseCatalogResponse()便以Math.min(contextLength, DEFAULT_MAX_OUTPUT_TOKENS)代替输出上限(DEFAULT_MAX_OUTPUT_TOKENS = 131072)。claude-sonnet-5-5 的窗口是 1,000,000,于是推导出的maxTokens就是 131072。2. 请求侧同样落到 131072
stream()中:宿主不传
options.maxTokens时,max_tokens = 131072。3. 该模型的真实输出上限是 128000
131072 = 128 × 1024,比十进制的 128K 多 1072,上游按模型自己的上限直接 400 拒绝。
4. 这个 400 被误判为上下文超限,触发了无效的压缩重试
isContextOverflowDetail()用CLI_CONTEXT_OVERFLOW_PATTERN判定:/prompt is too long|context.*(length|window)|max_tokens|maximum.*tokens/i错误正文里含
max_tokens,因此命中该正则,被当成上下文超限,进入"压缩后重试"分支;而重试并没有降低max_tokens,必然再次失败,最终把错误暴露给用户。建议修复
DEFAULT_MAX_OUTPUT_TOKENS/DEFAULT_GENERATE_MAX_TOKENS从 131072 降到 128000——插件 CHANGELOG 自己也说明这些模型的真实输出上限是 64K / 128K,131072 并不比 128000 多出任何可用空间。max_tokens: X > Y, which is the maximum allowed...这类错误可以直接取出 Y,用 Y 重发,而不是压缩上下文。max_tokens字样的错误一律当作上下文超限:它同时掩盖了这类输出上限错误,用户看到的是"上下文超限"的误导提示。复现
任选
claude-*模型(claude-sonnet-5-5 必现),宿主不传options.maxTokens,插件即发送max_tokens: 131072。临时规避(供其他用户参考)
z-ai/glm-5.3-flash、deepseek/deepseek-v4.1-flash);claude-*收窄到 128000(lib/index.js的stream()内):已验证改后请求为
max_tokens: 128000,语法校验通过。