Commit Graph
3 Commits
Author SHA1 Message Date
alfadb ca08825935 feat(claude): 自动同步 Claude Code 客户端版本号
出站伪装用的 Claude Code 版本号此前硬编码在 claude.CLICurrentVersion,
只能靠环境变量 SUB2API_CLAUDE_CLI_VERSION 覆盖且需重启;Anthropic 抬高
版本下限时(如 Opus 5.5 要求 >= 2.1.280)必须改代码发版才能跟上。

改为每小时从官方 GitHub Releases 同步最新稳定版,无需重启也无需发版。

- 新增 ClaudeCodeVersionSyncService:1 小时间隔,数据源 anthropics/claude-code
  的 releases/latest,失败回退最近 30 条列表;过滤 draft/prerelease;
  只向前推进,拉取失败保留上次值不降级;面板可关闭
- 新增三个设置项:claude_code_client_version(管理员手动固定)、
  claude_code_client_version_synced(同步服务独占写)、
  claude_code_version_auto_sync_enabled(开关,默认开)
- 取值优先级:面板手动值 -> 同步值 -> SUB2API_CLAUDE_CLI_VERSION -> 内置基线,
  每层经 IsSupportedCLIVersion 校验,含 60s 缓存与 singleflight
- 版本号运行期化:claude.DefaultHeaders 由包级 var 改为函数,新增
  EffectiveCLIVersion/DefaultUserAgent 与 SetCLIVersionResolver(未注入时
  与 CLIVersion() 等价);identity 的 defaultFingerprint 不再在包 init 固化,
  指纹下限与主版本超前校验改用运行期值
- 守住一致性铁律:buildUpstreamRequest 与 count_tokens 各取一次 UA 字符串,
  同时喂给出站 User-Agent 头与请求体 billing 的 cc_version,避免缓存翻转
  瞬间头体版本不一致被判非正版客户端
- 管理后台设置页新增配置区块,含中英文案与「当前同步到」只读展示
2026-09-23 13:35:44 +08:00
alfadb 3efeba33a4 test(claude): 版本覆盖用例字面量随内置基线升至 2.1.259
这三个用例的字面量 2.1.251 写于内置基线为 2.1.220 的时期,本意是取一个
高于基线的补丁位验证"覆盖不得低于 pin"规则。基线升至 2.1.258 后,2.1.251
落在 pin 之下:IsSupportedCLIVersion 应判 false、resolveCLIVersion 应回落
基线,与用例原意相悖,CI 随之失败。

改为真正高于当前 pin 的最小补丁位 2.1.259,用例语义不变;实现未放宽,
constants_cli_version_test.go 中独立的 Fable 5.1 闸门下限 2.1.251 保持不变。
2026-09-07 16:34:35 +08:00
LuckyandClaude Opus 5 e9bad40b10 feat(claude): allow operators to override the advertised CLI version
Anthropic gates newer models on a minimum Claude Code client version. With
CLICurrentVersion pinned at 2.1.220, claude-fable-5-1 fails every request with
"Claude Code 2.1.220 does not support this model; version 2.1.251 or newer is
required", and the only fix is a release that bumps one constant.

Add SUB2API_CLAUDE_CLI_VERSION, mirroring what internal/pkg/xai already does
with XAI_GROK_CLI_VERSION. CLICurrentVersion remains the built-in pin; the new
CLIVersion() is what every consumer reads. With no env var set the resolved
value equals the pin, so existing deployments are unaffected.

The value is resolved once at package init rather than per call: the User-Agent
header and the request body's cc_version are written by different code paths for
the same request, and reading different values would make that request
contradict itself.

Validation is strict (three numeric segments, not below the pin) because
identity_service.go documents what a malformed version does once it reaches an
account's persistent fingerprint: sustained 429s without reset headers, 5s
fallback cooldown, pool collapse into a 503 storm, and no reset entry point.
Invalid values warn and fall back rather than being silently dropped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168uDMAj9anaJrnH8CeFze6
2026-09-04 18:01:34 +00:00