makecindy / makecindy/cindy

[Bug] 自定义 50K 上下文已生效,右下角用量仍显示官方 372K

Open
#3,871 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
2.7k
Forks
401
Avg merge
21h 48m
Merged PRs (30d)
776

Description

### 问题描述 / What happened

自定义 Provider 把 Claude Code 模型上下文设为 50K 后,自动压缩和会话库已经按 50K 工作,但聊天右下角 Context 圆环仍显示官方更大窗口(本次为 `/372K`)。用量占比被明显低估,用户无法用界面判断真实压缩临界点。

实际行为:

- 模型选择器显示当前来源上下文为 50K。
- 自动压缩日志为 `contextWindow: 50000`、`threshold: 50`。
- 会话库记录 `context_window = 50000`。
- 右下角仍显示 `Context 51.3K / 372K`。
- 压缩确认框与圆环共用同一套显示窗口。

期望行为:

- 右下角 Context 的分母与当前会话路由的核实窗口一致。
- 本次场景应显示约 `51.3K / 50K`,而不是官方 Terra 的 `372K`。
- 自定义窗口已经传给运行时后,界面不得再改用扁平目录里同 id 的另一条路由。

### 环境 / Environment

- Cindy 版本或 commit / version or commit: `origin/main` `b43ee771`(2026-09-03 源码复核仍存在)
- 平台与版本 / platform & OS version: macOS;CindyGlobal
- 安装方式 / install method: 本机 CindyGlobal
- Agent: Claude Code
- 来源: 自定义 Provider(LiteLLM)
- 模型: Codex GPT-5.6 Terra
- 自定义上下文窗口: 50K
- Claude Code 自动压缩阈值: 50%

Codex / Pi 与 Claude Code 共用同一套圆环显示逻辑。若用同一个自定义 50K 模型且 model id 与官方条目碰撞,预期也会画错;本次实机证据来自 Claude Code。

### 复现步骤 / Steps to reproduce

1. 在自定义 Provider 中配置一个与官方同 id 的模型,上下文窗口设为 `50000`。
2. 将 Claude Code 自动压缩阈值设为 `50%`。
3. 新建 Claude Code 会话,明确选中该来源和该模型。确认模型选择器显示 `50K`。
4. 发送前段标记:

```text
请记住唯一标记:BH021-AUTO-COMPACT-20260903。
只回复“标记已记录”。
```

5. 持续发送较长内容,直到接近 `25K`,观察是否自动压缩。不要点手动压缩。

```text
请详细扩展“会话上下文压缩的失败恢复策略”,至少包含背景、触发条件、快照保存、回滚、重试、数据一致性和验收测试,每个部分都尽量展开。
```

6. 对比三处数字:
- 模型选择器窗口
- 右下角 `Context used / total`
- 会话日志或会话库中的 `contextWindow` / `context_window`

### 日志与截图 / Logs & screenshots

脱敏后的运行时证据:

```text
auto-compact triggered
threshold : 50
contextWindow : 50000
```

会话库:

```text
context_tokens = 51327
context_window = 50000
```

界面:

```text
Context 51.3K / 372K
```

提交时请附脱敏截图:模型选择器 50K,以及右下角 `/372K`。

### 源码定位

当前 `origin/main`(`b43ee771`):

- 运行时已按当前路由取核实窗口:Claude Code / Codex 走 `resolveVerifiedContextWindow(providerId, model)`,Pi 走 `resolvePiRuntimeModelDescriptor(providerId, modelId)`。host 明确写了不能按 id 回查扁平 `availableModels`。
- 右下角圆环走另一条链路:`ContextCapacityRing` → `getModelContextWindow(model, vendorKey)` → `getModelsForVendor(...).find(m => m.id === model)`。这里不带 `providerId`,命中跨 provider 首见去重后的官方窗口(Terra 为 `372000`)。
- `resolveDisplayContextWindow()` 在 `sdk <= 200_000 && catalog > sdk` 时改用目录值。该启发式本意是覆盖 Claude Code 未知模型默认 `200K`,也会把已经核实的 `50K` 抬成 `372K`。
- 现有单测只锁了「`200K` 默认值让位给更大目录」,没有覆盖「运行时 50K、目录 372K」。按当前函数,后者会返回 `372000`。

因此:压缩行为是对的,显示口径是错的。不要把它写成 Claude Code 窗口传递失败。

### 建议方向

圆环和压缩确认框的分母应与当前会话路由的核实窗口一致。运行时已经给出该路由窗口时,不要再用扁平目录按模型 id 首见值覆盖,也不要把 `<=200K` 一律当成 Claude 未知模型默认值去抬高显示。

相关但不重复:

- #3621:Claude Code CLI 不读自定义窗,运行时问题,已关闭。
- #1439:同一圆环函数,方向相反,SDK `>200K` 兜底窗盖住更大真实窗。
- #3470:Codex 自定义窗传入 `model_context_window`,不是本单的显示分母问题。

Contributor guide

Open the contributing guide

Research direction

Start at ContextCapacityRing and trace getModelContextWindow(model, vendorKey) through resolveDisplayContextWindow(), then inspect the existing unit test for the 200K default versus catalog behavior. Verify the display and compression-confirmation denominator uses the current routed 50K window rather than the deduplicated catalog entry, and add coverage for the 50K runtime versus 372K catalog case.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.