bug: IM/手机端未接入 Claude Opus 网关归因,仍透传误导性 "Claude Pro plan" 提示
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 401
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 问题描述 / What happened
从 IM/手机端发起 claude-code 会话并使用 Opus 模型时,出站消息直接透传了 Claude Code 的原始错误:
```
Claude Opus is not available with the Claude Pro plan. If you have updated your
subscription plan recently, run /logout and /login for the plan to take effect.
```
该提示存在两处误导:
1. **归因错误**:账号实际为支持 Opus 的计划,桌面端同账号可正常使用 Opus。真实原因是该请求走了 XD Gateway 路由而非 Claude.ai 订阅路由 —— 这正是 `apps/desktop/src/shared/claudeGatewayError.ts` 顶部注释已经说明的情况("Claude Code 会把部分上游 400 统一翻译成 Claude.ai 套餐提示")。
2. **引导有害**:用户若照提示执行 `/logout`,会登出本机 Claude.ai 订阅(桌面端随之不可用),且并不能解决问题。
桌面端在 #1607 之后已对同一错误正确归因,显示:
> 这次 Opus 请求实际走的是 XD Gateway,不是你的 Claude.ai 订阅;该网关路由拒绝了此模型。可切换到 Claude.ai 订阅后重试,或换一个模型。
IM/手机端未获得同等处理。
**期望行为**:IM/手机端出站错误复用同一归因,输出与桌面端等价的提示;至少不应透传会引导用户执行 `/logout` 的原始文案。
## 根因定位 / Root cause
归因逻辑本身已存在且正确,缺口在于它只被 renderer 消费:
- `apps/desktop/src/shared/claudeGatewayError.ts` — 已实现 gateway / subscription 两条路由的归因
- `apps/desktop/src/main/maker-host/claude-gateway-error-observer.ts:81` — 唯一调用点
- 归因结果(`CLAUDE_GATEWAY_OPUS_PLAN_MISMATCH_REASON`)的消费者仅三处,全部位于 renderer:
- `apps/desktop/src/renderer/components/chat/ErrorBanner.tsx`
- `apps/desktop/src/renderer/components/chat/errorReasonI18n.ts`
- `apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx`
- `apps/desktop/src/main/im/` 对 `claudeGatewayError` / `*_OPUS_PLAN_MISMATCH_REASON` / `errorReason` **无任何引用**,IM 出站路径直接透传原始 error 字符串
**加剧因素**:IM 默认设置中 `agents["claude-code"].providerId` 为 `null`,会按 provider 顺序回落;当 XD Gateway 排在 Claude.ai 订阅之前时必然命中该网关路由。也就是说 IM 端比桌面端更容易触发这个错误,却恰恰是缺少归因的一端。
## 环境 / Environment
- Cindy 版本 / version:v0.1.33(2026-08-06,当前最新 release)
- 平台与版本 / platform & OS:macOS(Darwin 25.5.0),Apple Silicon
- 安装方式 / install method:官方 release
## 复现步骤 / Steps to reproduce
1. 配置多个供应商,使 XD Gateway 在 provider 顺序中排在 Claude.ai 订阅之前
2. IM 默认设置保持 `agentKind: claude-code`、`providerId: null`(未显式指定供应商)、`model: claude-opus-*`
3. 从 IM/手机端发起会话
4. 观察到透传的原始 "Claude Pro plan" 文案;桌面端在同等条件下显示的是正确的归因文案
## 补充 / Notes
如果维护者认可这个方向,我可以提 PR:把 IM 出站错误路径接到现有的 `classifyClaudeGatewayError` 结果上,复用 `errorReasonI18n` 已有的文案 key,避免在 IM 侧重复实现一套判定。
Contributor guide
Research direction
Start with apps/desktop/src/shared/claudeGatewayError.ts and the observer at apps/desktop/src/main/maker-host/claude-gateway-error-observer.ts:81, then trace the IM outbound error path under apps/desktop/src/main/im/. Reuse the existing classification and renderer consumers, including errorReasonI18n; done means IM/mobile output gives the gateway attribution instead of forwarding the misleading Claude Pro plan message.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100