| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- // Package claude provides constants and helpers for Claude API integration.
- package claude
- // Claude Code 客户端相关常量
- // Beta header 常量
- //
- // 这里的常量对齐真实 Claude Code CLI 的最新流量(截至 2026-04)。
- // 选型参考:与 Parrot (src/transform/cc_mimicry.py) 的 BETAS 保持一致,
- // 原因:Anthropic 上游会基于 anthropic-beta 的完整集合判定请求来源;
- // 缺少任何"官方 Claude Code 请求才会带"的 beta,都会被降级到第三方额度,
- // 对应报错:`Third-party apps now draw from your extra usage, not your plan limits.`
- const (
- BetaOAuth = "oauth-2025-04-20"
- BetaClaudeCode = "claude-code-20250219"
- BetaInterleavedThinking = "interleaved-thinking-2025-05-14"
- BetaFineGrainedToolStreaming = "fine-grained-tool-streaming-2025-05-14"
- BetaTokenCounting = "token-counting-2024-11-01"
- BetaContext1M = "context-1m-2025-08-07"
- BetaFastMode = "fast-mode-2026-02-01"
- // 新增(对齐官方 CLI 2.1.9x 以来的流量)
- BetaPromptCachingScope = "prompt-caching-scope-2026-01-05"
- BetaEffort = "effort-2025-11-24"
- BetaRedactThinking = "redact-thinking-2026-02-12"
- BetaContextManagement = "context-management-2025-06-27"
- BetaThinkingBindingControls = "thinking-binding-controls-2026-08-01"
- BetaExtendedCacheTTL = "extended-cache-ttl-2025-04-11"
- // server-side refusal fallback beta 字段族(beta Messages API 专有)。
- // 客户端(Claude Code / SDK / OpenCode 等)会默认透传 body.fallbacks /
- // body.fallback_credit_token,上游仅在 anthropic-beta 携带对应 token 时接受;
- // 缺 token 时 Pydantic 拒收:"fallbacks: Extra inputs are not permitted"。
- // 仅用于 sanitize 的条件判断(strip-or-keep),禁止加入
- // FullClaudeCodeMimicryBetas / DefaultBetaHeader / APIKeyBetaHeader /
- // Bedrock 白名单:server-side fallback 会换模型、改计费,不能默认打开。
- BetaServerSideFallback = "server-side-fallback-2026-07-01"
- BetaFallbackCredit = "fallback-credit-2026-07-01"
- BetaFallbackCreditLegacy = "fallback-credit-2026-06-01"
- )
- // DroppedBetas 是转发时需要从 anthropic-beta header 中移除的 beta token 列表。
- // 这些 token 是客户端特有的,不应透传给上游 API。
- var DroppedBetas = []string{}
- // DefaultBetaHeader Claude Code 客户端默认的 anthropic-beta header
- const DefaultBetaHeader = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleavedThinking + "," + BetaFineGrainedToolStreaming
- // MessageBetaHeaderNoTools /v1/messages 在无工具时的 beta header
- //
- // NOTE: Claude Code OAuth credentials are scoped to Claude Code. When we "mimic"
- // Claude Code for non-Claude-Code clients, we must include the claude-code beta
- // even if the request doesn't use tools, otherwise upstream may reject the
- // request as a non-Claude-Code API request.
- const MessageBetaHeaderNoTools = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleavedThinking
- // MessageBetaHeaderWithTools /v1/messages 在有工具时的 beta header
- const MessageBetaHeaderWithTools = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleavedThinking
- // CountTokensBetaHeader count_tokens 请求使用的 anthropic-beta header
- const CountTokensBetaHeader = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleavedThinking + "," + BetaTokenCounting
- // HaikuBetaHeader Haiku 模型在 OAuth 真实客户端透传路径上的默认 anthropic-beta header。
- // OAuth mimic 路径统一使用 FullClaudeCodeMimicryBetas。
- const HaikuBetaHeader = BetaOAuth + "," + BetaInterleavedThinking
- // APIKeyBetaHeader API-key 账号建议使用的 anthropic-beta header(不包含 oauth)
- const APIKeyBetaHeader = BetaClaudeCode + "," + BetaInterleavedThinking + "," + BetaFineGrainedToolStreaming
- // APIKeyHaikuBetaHeader Haiku 模型在 API-key 账号下使用的 anthropic-beta header(不包含 oauth / claude-code)
- const APIKeyHaikuBetaHeader = BetaInterleavedThinking
- // DefaultCacheControlTTL 是网关代理为自己生成的 cache_control 块默认使用的 ttl。
- // 真实 Claude Code CLI 当前使用 "1h",但本仓策略是"客户端透传 ttl 优先;
- // 客户端缺省时统一使用 5m",这样既不浪费 1h 缓存额度,也保留客户端自定义能力。
- const DefaultCacheControlTTL = "5m"
- // CLICurrentVersion 是内置的 Claude Code CLI 伪装版本号基线(三段 semver)。
- // 用于 billing attribution block 中的 cc_version=X.Y.Z.{fp} 前缀以及 fingerprint 计算。
- // 必须与 DefaultHeaders["User-Agent"] 中的版本号严格一致;不一致会被 Anthropic 判第三方。
- //
- // ⚠️ 读取实际生效的版本号请用 CLIVersion(),它会叠加 SUB2API_CLAUDE_CLI_VERSION 覆盖。
- // 直接引用本常量只在"表达内置基线"时才正确(例如覆盖值的下限校验)。
- const CLICurrentVersion = "2.1.258"
- // FullClaudeCodeMimicryBetas 返回最"像"真实 Claude Code CLI 的完整 beta 列表,
- // 用于 OAuth 账号伪装成 Claude Code 时使用。
- // 顺序与真实 CLI 抓包一致。
- //
- // 使用建议:
- // - OAuth mimic:所有模型(包括 Haiku)都使用这整份列表。
- // - OAuth 真实客户端透传:保留客户端 beta;未提供时使用模型对应默认值。
- // - API-key 账号:不要使用本函数,参见 APIKeyBetaHeader。
- // - 不默认加入 redact-thinking,避免上游抹除 thinking 内容;客户端显式传入时由合并逻辑保留。
- func FullClaudeCodeMimicryBetas() []string {
- return []string{
- BetaClaudeCode,
- BetaOAuth,
- BetaInterleavedThinking,
- BetaPromptCachingScope,
- BetaEffort,
- BetaContextManagement,
- BetaThinkingBindingControls,
- BetaExtendedCacheTTL,
- }
- }
- // DefaultHeaders 是 Claude Code 客户端默认请求头。
- var DefaultHeaders = map[string]string{
- // Keep these in sync with recent Claude CLI traffic to reduce the chance
- // that Claude Code-scoped OAuth credentials are rejected as "non-CLI" usage.
- // 版本参考:对齐 Parrot (src/transform/cc_mimicry.py:49) 的 CLI_USER_AGENT。
- "User-Agent": "claude-cli/" + CLIVersion() + " (external, cli)",
- "X-Stainless-Lang": "js",
- "X-Stainless-Package-Version": "0.94.0",
- "X-Stainless-OS": "Linux",
- "X-Stainless-Arch": "arm64",
- "X-Stainless-Runtime": "node",
- "X-Stainless-Runtime-Version": "v24.3.0",
- "X-Stainless-Retry-Count": "0",
- "X-Stainless-Timeout": "600",
- "X-App": "cli",
- "Anthropic-Dangerous-Direct-Browser-Access": "true",
- }
- // Model 表示一个 Claude 模型
- type Model struct {
- ID string `json:"id"`
- Type string `json:"type"`
- DisplayName string `json:"display_name"`
- CreatedAt string `json:"created_at"`
- }
- // DefaultModels Claude Code 客户端支持的默认模型列表
- var DefaultModels = []Model{
- {
- ID: "claude-fable-5-1",
- Type: "model",
- DisplayName: "Claude Fable 5.1",
- CreatedAt: "2026-09-01T00:00:00Z",
- },
- {
- ID: "claude-fable-5",
- Type: "model",
- DisplayName: "Claude Fable 5",
- CreatedAt: "2026-06-09T00:00:00Z",
- },
- {
- ID: "claude-opus-4-5-20251101",
- Type: "model",
- DisplayName: "Claude Opus 4.5",
- CreatedAt: "2025-11-01T00:00:00Z",
- },
- {
- ID: "claude-opus-4-6",
- Type: "model",
- DisplayName: "Claude Opus 4.6",
- CreatedAt: "2026-02-06T00:00:00Z",
- },
- {
- ID: "claude-opus-4-7",
- Type: "model",
- DisplayName: "Claude Opus 4.7",
- CreatedAt: "2026-04-17T00:00:00Z",
- },
- {
- ID: "claude-opus-4-8",
- Type: "model",
- DisplayName: "Claude Opus 4.8",
- CreatedAt: "2026-05-29T00:00:00Z",
- },
- {
- ID: "claude-opus-5",
- Type: "model",
- DisplayName: "Claude Opus 5",
- CreatedAt: "2026-07-25T00:00:00Z",
- },
- {
- ID: "claude-sonnet-5",
- Type: "model",
- DisplayName: "Claude Sonnet 5",
- CreatedAt: "2026-07-01T00:00:00Z",
- },
- {
- ID: "claude-sonnet-4-6",
- Type: "model",
- DisplayName: "Claude Sonnet 4.6",
- CreatedAt: "2026-02-18T00:00:00Z",
- },
- {
- ID: "claude-sonnet-4-5-20250929",
- Type: "model",
- DisplayName: "Claude Sonnet 4.5",
- CreatedAt: "2025-09-29T00:00:00Z",
- },
- {
- ID: "claude-haiku-4-5-20251001",
- Type: "model",
- DisplayName: "Claude Haiku 4.5",
- CreatedAt: "2025-10-01T00:00:00Z",
- },
- }
- // DefaultModelIDs 返回默认模型的 ID 列表
- func DefaultModelIDs() []string {
- ids := make([]string, len(DefaultModels))
- for i, m := range DefaultModels {
- ids[i] = m.ID
- }
- return ids
- }
- // DefaultTestModel 测试时使用的默认模型
- const DefaultTestModel = "claude-sonnet-4-5-20250929"
- // ModelIDOverrides Claude OAuth 请求需要的模型 ID 映射
- var ModelIDOverrides = map[string]string{
- "claude-sonnet-4-5": "claude-sonnet-4-5-20250929",
- "claude-opus-4-5": "claude-opus-4-5-20251101",
- "claude-haiku-4-5": "claude-haiku-4-5-20251001",
- }
- // ModelIDReverseOverrides 用于将上游模型 ID 还原为短名
- var ModelIDReverseOverrides = map[string]string{
- "claude-sonnet-4-5-20250929": "claude-sonnet-4-5",
- "claude-opus-4-5-20251101": "claude-opus-4-5",
- "claude-haiku-4-5-20251001": "claude-haiku-4-5",
- }
- // NormalizeModelID 根据 Claude OAuth 规则映射模型
- func NormalizeModelID(id string) string {
- if id == "" {
- return id
- }
- if mapped, ok := ModelIDOverrides[id]; ok {
- return mapped
- }
- return id
- }
- // DenormalizeModelID 将上游模型 ID 转换为短名
- func DenormalizeModelID(id string) string {
- if id == "" {
- return id
- }
- if mapped, ok := ModelIDReverseOverrides[id]; ok {
- return mapped
- }
- return id
- }
|