Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,677 @@
|
||||
package service
|
||||
|
||||
import "strings"
|
||||
|
||||
func firstNonEmpty(values ...string) string {
|
||||
for _, value := range values {
|
||||
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
||||
return trimmed
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SystemSettings struct {
|
||||
RegistrationEnabled bool
|
||||
EmailVerifyEnabled bool
|
||||
RegistrationEmailSuffixWhitelist []string
|
||||
RegistrationEmailDomainQuotaEnabled bool // 白名单非空时放行非白名单域名限量注册(默认关闭)
|
||||
PromoCodeEnabled bool
|
||||
PasswordResetEnabled bool
|
||||
FrontendURL string
|
||||
InvitationCodeEnabled bool
|
||||
TotpEnabled bool // TOTP 双因素认证
|
||||
PasskeyEnabled bool // Passkey 登录
|
||||
SessionBindingEnabled bool // 会话 IP/UA 绑定(变更即失效)
|
||||
StepUpEnabled bool // 敏感操作 step-up 2FA 门控
|
||||
AuditLogRetentionDays int // 审计日志保留天数(<=0 永久保留)
|
||||
LoginAgreementEnabled bool
|
||||
LoginAgreementMode string
|
||||
LoginAgreementUpdatedAt string
|
||||
LoginAgreementDocuments []LoginAgreementDocument
|
||||
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
SMTPUsername string
|
||||
SMTPPassword string
|
||||
SMTPPasswordConfigured bool
|
||||
SMTPFrom string
|
||||
SMTPFromName string
|
||||
SMTPUseTLS bool
|
||||
|
||||
TurnstileEnabled bool
|
||||
TurnstileSiteKey string
|
||||
TurnstileSecretKey string
|
||||
TurnstileSecretKeyConfigured bool
|
||||
TencentCaptchaEnabled bool
|
||||
TencentCaptchaAppID string
|
||||
TencentCaptchaAppSecretKey string
|
||||
TencentCaptchaAppSecretKeyConfigured bool
|
||||
TencentCaptchaCloudSecretID string
|
||||
TencentCaptchaCloudSecretIDConfigured bool
|
||||
TencentCaptchaCloudSecretKey string
|
||||
TencentCaptchaCloudSecretKeyConfigured bool
|
||||
TencentCaptchaRegion string
|
||||
AliyunCaptchaEnabled bool
|
||||
AliyunCaptchaAccessKeyID string
|
||||
AliyunCaptchaAccessKeySecret string
|
||||
AliyunCaptchaAccessKeySecretConfigured bool
|
||||
AliyunCaptchaSceneID string
|
||||
AliyunCaptchaPrefix string
|
||||
AliyunCaptchaRegion string
|
||||
APIKeyACLTrustForwardedIP bool
|
||||
ForwardedClientIPHeaders []string
|
||||
|
||||
// LinuxDo Connect OAuth 登录
|
||||
LinuxDoConnectEnabled bool
|
||||
LinuxDoConnectClientID string
|
||||
LinuxDoConnectClientSecret string
|
||||
LinuxDoConnectClientSecretConfigured bool
|
||||
LinuxDoConnectRedirectURL string
|
||||
|
||||
// DingTalk Connect OAuth 登录
|
||||
DingTalkConnectEnabled bool
|
||||
DingTalkConnectClientID string
|
||||
DingTalkConnectClientSecret string
|
||||
DingTalkConnectClientSecretConfigured bool
|
||||
DingTalkConnectRedirectURL string
|
||||
DingTalkConnectCorpRestrictionPolicy string
|
||||
DingTalkConnectInternalCorpID string
|
||||
DingTalkConnectBypassRegistration bool
|
||||
DingTalkConnectSyncCorpEmail bool
|
||||
DingTalkConnectSyncDisplayName bool
|
||||
DingTalkConnectSyncDept bool
|
||||
DingTalkConnectSyncCorpEmailAttrKey string
|
||||
DingTalkConnectSyncDisplayNameAttrKey string
|
||||
DingTalkConnectSyncDeptAttrKey string
|
||||
DingTalkConnectSyncCorpEmailAttrName string
|
||||
DingTalkConnectSyncDisplayNameAttrName string
|
||||
DingTalkConnectSyncDeptAttrName string
|
||||
|
||||
// WeChat Connect OAuth 登录
|
||||
WeChatConnectEnabled bool
|
||||
WeChatConnectAppID string
|
||||
WeChatConnectAppSecret string
|
||||
WeChatConnectAppSecretConfigured bool
|
||||
WeChatConnectOpenAppID string
|
||||
WeChatConnectOpenAppSecret string
|
||||
WeChatConnectOpenAppSecretConfigured bool
|
||||
WeChatConnectMPAppID string
|
||||
WeChatConnectMPAppSecret string
|
||||
WeChatConnectMPAppSecretConfigured bool
|
||||
WeChatConnectMobileAppID string
|
||||
WeChatConnectMobileAppSecret string
|
||||
WeChatConnectMobileAppSecretConfigured bool
|
||||
WeChatConnectOpenEnabled bool
|
||||
WeChatConnectMPEnabled bool
|
||||
WeChatConnectMobileEnabled bool
|
||||
WeChatConnectMode string
|
||||
WeChatConnectScopes string
|
||||
WeChatConnectRedirectURL string
|
||||
WeChatConnectFrontendRedirectURL string
|
||||
|
||||
// Generic OIDC OAuth 登录
|
||||
OIDCConnectEnabled bool
|
||||
OIDCConnectProviderName string
|
||||
OIDCConnectClientID string
|
||||
OIDCConnectClientSecret string
|
||||
OIDCConnectClientSecretConfigured bool
|
||||
OIDCConnectIssuerURL string
|
||||
OIDCConnectDiscoveryURL string
|
||||
OIDCConnectAuthorizeURL string
|
||||
OIDCConnectTokenURL string
|
||||
OIDCConnectUserInfoURL string
|
||||
OIDCConnectJWKSURL string
|
||||
OIDCConnectScopes string
|
||||
OIDCConnectRedirectURL string
|
||||
OIDCConnectFrontendRedirectURL string
|
||||
OIDCConnectTokenAuthMethod string
|
||||
OIDCConnectUsePKCE bool
|
||||
OIDCConnectValidateIDToken bool
|
||||
OIDCConnectAllowedSigningAlgs string
|
||||
OIDCConnectClockSkewSeconds int
|
||||
OIDCConnectRequireEmailVerified bool
|
||||
OIDCConnectUserInfoEmailPath string
|
||||
OIDCConnectUserInfoIDPath string
|
||||
OIDCConnectUserInfoUsernamePath string
|
||||
|
||||
// GitHub / Google 邮箱快捷登录
|
||||
GitHubOAuthEnabled bool
|
||||
GitHubOAuthClientID string
|
||||
GitHubOAuthClientSecret string
|
||||
GitHubOAuthClientSecretConfigured bool
|
||||
GitHubOAuthRedirectURL string
|
||||
GitHubOAuthFrontendRedirectURL string
|
||||
GoogleOAuthEnabled bool
|
||||
GoogleOAuthClientID string
|
||||
GoogleOAuthClientSecret string
|
||||
GoogleOAuthClientSecretConfigured bool
|
||||
GoogleOAuthRedirectURL string
|
||||
GoogleOAuthFrontendRedirectURL string
|
||||
|
||||
SiteName string
|
||||
SiteLogo string
|
||||
SiteSubtitle string
|
||||
APIBaseURL string
|
||||
ContactInfo string
|
||||
DocURL string
|
||||
HomeContent string
|
||||
CompactHomeEnabled bool
|
||||
HideCcsImportButton bool
|
||||
PurchaseSubscriptionEnabled bool
|
||||
PurchaseSubscriptionURL string
|
||||
TableDefaultPageSize int
|
||||
TablePageSizeOptions []int
|
||||
CustomMenuItems string // JSON array of custom menu items
|
||||
CustomEndpoints string // JSON array of custom endpoints
|
||||
|
||||
DefaultConcurrency int
|
||||
DefaultBalance float64
|
||||
RiskControlEnabled bool
|
||||
CyberSessionBlockEnabled bool
|
||||
CyberSessionBlockTTLSeconds int
|
||||
AffiliateEnabled bool
|
||||
AffiliateRebateRate float64
|
||||
AffiliateRebateFreezeHours int
|
||||
AffiliateRebateDurationDays int
|
||||
AffiliateRebatePerInviteeCap float64
|
||||
AdminRechargeRebateEnabled bool
|
||||
DefaultUserRPMLimit int
|
||||
DefaultSubscriptions []DefaultSubscriptionSetting
|
||||
|
||||
// Model fallback configuration
|
||||
EnableModelFallback bool `json:"enable_model_fallback"`
|
||||
FallbackModelAnthropic string `json:"fallback_model_anthropic"`
|
||||
FallbackModelOpenAI string `json:"fallback_model_openai"`
|
||||
FallbackModelGemini string `json:"fallback_model_gemini"`
|
||||
FallbackModelAntigravity string `json:"fallback_model_antigravity"`
|
||||
|
||||
// Identity patch configuration (Claude -> Gemini)
|
||||
EnableIdentityPatch bool `json:"enable_identity_patch"`
|
||||
IdentityPatchPrompt string `json:"identity_patch_prompt"`
|
||||
|
||||
// Ops monitoring (vNext)
|
||||
OpsMonitoringEnabled bool
|
||||
OpsRealtimeMonitoringEnabled bool
|
||||
OpsQueryModeDefault string
|
||||
OpsMetricsIntervalSeconds int
|
||||
|
||||
// Channel Monitor feature
|
||||
ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
|
||||
ChannelMonitorMode string `json:"channel_monitor_mode"`
|
||||
ChannelMonitorDefaultIntervalSeconds int `json:"channel_monitor_default_interval_seconds"`
|
||||
ChannelMonitorHideThroughput bool `json:"channel_monitor_hide_throughput"`
|
||||
ChannelMonitorShowQuota bool `json:"channel_monitor_show_quota"`
|
||||
|
||||
// Grok model mapping policy (admin settings; empty mapping falls back to these).
|
||||
GrokDefaultTextModel string `json:"grok_default_text_model"`
|
||||
GrokCrossClientModelMapEnabled bool `json:"grok_cross_client_model_map_enabled"`
|
||||
GrokDefaultBaseURLMode string `json:"grok_default_base_url_mode"`
|
||||
|
||||
// Available Channels feature (user-facing aggregate view)
|
||||
AvailableChannelsEnabled bool `json:"available_channels_enabled"`
|
||||
|
||||
// Model Plaza feature (public group/model pricing showcase)
|
||||
ModelPlazaEnabled bool `json:"model_plaza_enabled"`
|
||||
ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
|
||||
ModelPlazaDescription string `json:"model_plaza_description"`
|
||||
|
||||
// Claude Code version check
|
||||
MinClaudeCodeVersion string
|
||||
MaxClaudeCodeVersion string
|
||||
|
||||
// 分组隔离:允许未分组 Key 调度(默认 false → 403)
|
||||
AllowUngroupedKeyScheduling bool
|
||||
|
||||
// Backend 模式:禁用用户注册和自助服务,仅管理员可登录
|
||||
BackendModeEnabled bool
|
||||
|
||||
// Gateway forwarding behavior
|
||||
EnableFingerprintUnification bool // 是否统一 OAuth 账号的指纹头(默认 true)
|
||||
EnableMetadataPassthrough bool // 是否透传客户端原始 metadata(默认 false)
|
||||
EnableCCHSigning bool // 已废弃 no-op:新版 CLI 取消 cch 签名后网关不再注入/签名 cch,开关无效果
|
||||
EnableClaudeOAuthSystemPromptInjection bool // 是否对 Claude OAuth mimic 路径注入 Claude Code system blocks(默认 true)
|
||||
ClaudeOAuthSystemPrompt string // Claude OAuth mimic 路径注入的通用扩展 system prompt;空值使用内置默认
|
||||
ClaudeOAuthSystemPromptBlocks string // Claude OAuth mimic 路径注入的 system blocks JSON 配置;空值使用内置默认
|
||||
EnableAnthropicCacheTTL1hInjection bool // 是否对 Anthropic OAuth/SetupToken 请求体注入 1h cache_control ttl(默认 false)
|
||||
EnableClientDatelineNormalization bool // 是否对 Anthropic OAuth/SetupToken 请求体做客户端 dateline 归一化(默认 true)
|
||||
RewriteMessageCacheControl bool // 是否改写 messages[*].content[*].cache_control(默认 false)
|
||||
AntigravityUserAgentVersion string // Antigravity 上游 User-Agent 版本号;空值使用配置/默认值
|
||||
OpenAICodexUserAgent string // OpenAI Codex 上游完整 User-Agent;空值由 Codex 客户端版本号拼出标准 TUI UA
|
||||
OpenAICodexClientVersion string // 出站声明的 Codex 客户端版本号(管理员覆写);空值跟随自动同步值
|
||||
OpenAICodexClientVersionSynced string // 自动同步到的官方最新稳定版版本号(只读展示)
|
||||
OpenAICodexVersionAutoSyncEnabled bool // 是否启用 Codex 客户端版本号自动同步(默认 true)
|
||||
MinCodexVersion string // codex_cli_only 最低 Codex 引擎版本;空=不检查
|
||||
MaxCodexVersion string // codex_cli_only 最高 Codex 引擎版本;空=不检查
|
||||
CodexCLIOnlyBlacklist string // codex_cli_only 全局黑名单 JSON([]AllowedClientEntry,OR deny)
|
||||
CodexCLIOnlyWhitelist string // codex_cli_only 全局白名单 JSON([]AllowedClientEntry,AND allow)
|
||||
CodexCLIOnlyAllowAppServerClients bool // codex_cli_only App Server 开关:对未列名客户端开闸(默认 false)
|
||||
CodexCLIOnlyEngineFingerprintSignals string // codex_cli_only 引擎指纹门信号列表 JSON([]EngineFingerprintSignal)
|
||||
|
||||
// Web Search Emulation
|
||||
WebSearchEmulationEnabled bool // 是否启用 web search 模拟
|
||||
|
||||
// Payment visible method routing
|
||||
PaymentVisibleMethodAlipaySource string
|
||||
PaymentVisibleMethodWxpaySource string
|
||||
PaymentVisibleMethodAlipayEnabled bool
|
||||
PaymentVisibleMethodWxpayEnabled bool
|
||||
|
||||
// OpenAI 账号调度
|
||||
OpenAILowUpstreamRatePriorityEnabled bool
|
||||
OpenAIOAuthSchedulingRateMultiplier float64
|
||||
OpenAIAdvancedSchedulerEnabled bool
|
||||
OpenAIAdvancedSchedulerStickyWeightedEnabled bool
|
||||
OpenAIAdvancedSchedulerSubscriptionPriorityEnabled bool
|
||||
OpenAIAdvancedSchedulerLBTopK string
|
||||
OpenAIAdvancedSchedulerWeightPriority string
|
||||
OpenAIAdvancedSchedulerWeightLoad string
|
||||
OpenAIAdvancedSchedulerWeightQueue string
|
||||
OpenAIAdvancedSchedulerWeightErrorRate string
|
||||
OpenAIAdvancedSchedulerWeightTTFT string
|
||||
OpenAIAdvancedSchedulerWeightReset string
|
||||
OpenAIAdvancedSchedulerWeightQuotaHeadroom string
|
||||
OpenAIAdvancedSchedulerWeightUpstreamCost string
|
||||
OpenAIAdvancedSchedulerWeightPreviousResponse string
|
||||
OpenAIAdvancedSchedulerWeightSessionSticky string
|
||||
OpenAIAdvancedSchedulerEffectiveLBTopK string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightPriority string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightLoad string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightQueue string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightErrorRate string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightTTFT string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightReset string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightQuotaHeadroom string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightUpstreamCost string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightPreviousResponse string
|
||||
OpenAIAdvancedSchedulerEffectiveWeightSessionSticky string
|
||||
|
||||
// 余额不足提醒
|
||||
BalanceLowNotifyEnabled bool
|
||||
BalanceLowNotifyThreshold float64
|
||||
BalanceLowNotifyRechargeURL string
|
||||
|
||||
// 订阅到期提醒
|
||||
SubscriptionExpiryNotifyEnabled bool
|
||||
|
||||
// 账号限额通知
|
||||
AccountQuotaNotifyEnabled bool
|
||||
AccountQuotaNotifyEmails []NotifyEmailEntry
|
||||
|
||||
// 系统全局默认平台配额(key = platform,nil/缺省 = 不限制)
|
||||
DefaultPlatformQuotas map[string]*DefaultPlatformQuotaSetting `json:"default_platform_quotas"`
|
||||
|
||||
// 系统全局账号自动停调阈值(key = platform,100 = disabled)
|
||||
AccountSchedulingThresholds map[string]int `json:"account_scheduling_thresholds"`
|
||||
|
||||
// 允许终端用户在用量页查看自己的失败请求
|
||||
AllowUserViewErrorRequests bool
|
||||
}
|
||||
|
||||
type DefaultSubscriptionSetting struct {
|
||||
GroupID int64 `json:"group_id"`
|
||||
ValidityDays int `json:"validity_days"`
|
||||
}
|
||||
|
||||
type PublicSettings struct {
|
||||
RegistrationEnabled bool
|
||||
EmailVerifyEnabled bool
|
||||
ForceEmailOnThirdPartySignup bool
|
||||
RegistrationEmailSuffixWhitelist []string
|
||||
RegistrationEmailDomainQuotaEnabled bool
|
||||
PromoCodeEnabled bool
|
||||
PasswordResetEnabled bool
|
||||
InvitationCodeEnabled bool
|
||||
TotpEnabled bool // TOTP 双因素认证
|
||||
PasskeyEnabled bool
|
||||
LoginAgreementEnabled bool
|
||||
LoginAgreementMode string
|
||||
LoginAgreementUpdatedAt string
|
||||
LoginAgreementRevision string
|
||||
LoginAgreementDocuments []LoginAgreementDocument
|
||||
TurnstileEnabled bool
|
||||
TurnstileSiteKey string
|
||||
TencentCaptchaEnabled bool
|
||||
TencentCaptchaAppID string
|
||||
TencentCaptchaRegion string
|
||||
AliyunCaptchaEnabled bool
|
||||
AliyunCaptchaSceneID string
|
||||
AliyunCaptchaPrefix string
|
||||
AliyunCaptchaRegion string
|
||||
SiteName string
|
||||
SiteLogo string
|
||||
SiteSubtitle string
|
||||
APIBaseURL string
|
||||
ContactInfo string
|
||||
DocURL string
|
||||
HomeContent string
|
||||
CompactHomeEnabled bool
|
||||
HideCcsImportButton bool
|
||||
|
||||
PurchaseSubscriptionEnabled bool
|
||||
PurchaseSubscriptionURL string
|
||||
TableDefaultPageSize int
|
||||
TablePageSizeOptions []int
|
||||
CustomMenuItems string // JSON array of custom menu items
|
||||
CustomEndpoints string // JSON array of custom endpoints
|
||||
|
||||
LinuxDoOAuthEnabled bool
|
||||
DingTalkOAuthEnabled bool
|
||||
WeChatOAuthEnabled bool
|
||||
WeChatOAuthOpenEnabled bool
|
||||
WeChatOAuthMPEnabled bool
|
||||
WeChatOAuthMobileEnabled bool
|
||||
BackendModeEnabled bool
|
||||
PaymentEnabled bool
|
||||
OIDCOAuthEnabled bool
|
||||
OIDCOAuthProviderName string
|
||||
GitHubOAuthEnabled bool
|
||||
GoogleOAuthEnabled bool
|
||||
Version string
|
||||
|
||||
BalanceLowNotifyEnabled bool
|
||||
AccountQuotaNotifyEnabled bool
|
||||
BalanceLowNotifyThreshold float64
|
||||
BalanceLowNotifyRechargeURL string
|
||||
|
||||
// Channel Monitor feature
|
||||
ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
|
||||
ChannelMonitorMode string `json:"channel_monitor_mode"`
|
||||
ChannelMonitorDefaultIntervalSeconds int `json:"channel_monitor_default_interval_seconds"`
|
||||
ChannelMonitorHideThroughput bool `json:"channel_monitor_hide_throughput"`
|
||||
ChannelMonitorShowQuota bool `json:"channel_monitor_show_quota"`
|
||||
|
||||
// Grok model mapping policy (admin settings).
|
||||
GrokDefaultTextModel string `json:"grok_default_text_model"`
|
||||
GrokCrossClientModelMapEnabled bool `json:"grok_cross_client_model_map_enabled"`
|
||||
GrokDefaultBaseURLMode string `json:"grok_default_base_url_mode"`
|
||||
|
||||
// Available Channels feature (user-facing aggregate view)
|
||||
AvailableChannelsEnabled bool `json:"available_channels_enabled"`
|
||||
|
||||
// Model Plaza feature (public group/model pricing showcase)
|
||||
ModelPlazaEnabled bool `json:"model_plaza_enabled"`
|
||||
ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
|
||||
|
||||
// Affiliate (邀请返利) feature toggle
|
||||
AffiliateEnabled bool `json:"affiliate_enabled"`
|
||||
|
||||
// 风控中心功能开关
|
||||
RiskControlEnabled bool `json:"risk_control_enabled"`
|
||||
|
||||
// 允许终端用户在用量页查看自己的失败请求
|
||||
AllowUserViewErrorRequests bool `json:"allow_user_view_error_requests"`
|
||||
}
|
||||
|
||||
type LoginAgreementDocument struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
ContentMD string `json:"content_md"`
|
||||
}
|
||||
|
||||
type WeChatConnectOAuthConfig struct {
|
||||
Enabled bool
|
||||
LegacyAppID string
|
||||
LegacyAppSecret string
|
||||
OpenAppID string
|
||||
OpenAppSecret string
|
||||
MPAppID string
|
||||
MPAppSecret string
|
||||
MobileAppID string
|
||||
MobileAppSecret string
|
||||
OpenEnabled bool
|
||||
MPEnabled bool
|
||||
MobileEnabled bool
|
||||
Mode string
|
||||
Scopes string
|
||||
RedirectURL string
|
||||
FrontendRedirectURL string
|
||||
}
|
||||
|
||||
func (cfg WeChatConnectOAuthConfig) SupportsMode(mode string) bool {
|
||||
switch normalizeWeChatConnectModeSetting(mode) {
|
||||
case "mp":
|
||||
return cfg.MPEnabled
|
||||
case "mobile":
|
||||
return cfg.MobileEnabled
|
||||
default:
|
||||
return cfg.OpenEnabled
|
||||
}
|
||||
}
|
||||
|
||||
func (cfg WeChatConnectOAuthConfig) ScopeForMode(mode string) string {
|
||||
switch normalizeWeChatConnectModeSetting(mode) {
|
||||
case "mp":
|
||||
return normalizeWeChatConnectScopeSetting(cfg.Scopes, "mp")
|
||||
case "mobile":
|
||||
return ""
|
||||
}
|
||||
return defaultWeChatConnectScopeForMode("open")
|
||||
}
|
||||
|
||||
func (cfg WeChatConnectOAuthConfig) AppIDForMode(mode string) string {
|
||||
switch normalizeWeChatConnectModeSetting(mode) {
|
||||
case "mp":
|
||||
return strings.TrimSpace(firstNonEmpty(cfg.MPAppID, cfg.LegacyAppID))
|
||||
case "mobile":
|
||||
return strings.TrimSpace(firstNonEmpty(cfg.MobileAppID, cfg.LegacyAppID))
|
||||
}
|
||||
return strings.TrimSpace(firstNonEmpty(cfg.OpenAppID, cfg.LegacyAppID))
|
||||
}
|
||||
|
||||
func (cfg WeChatConnectOAuthConfig) AppSecretForMode(mode string) string {
|
||||
switch normalizeWeChatConnectModeSetting(mode) {
|
||||
case "mp":
|
||||
return strings.TrimSpace(firstNonEmpty(cfg.MPAppSecret, cfg.LegacyAppSecret))
|
||||
case "mobile":
|
||||
return strings.TrimSpace(firstNonEmpty(cfg.MobileAppSecret, cfg.LegacyAppSecret))
|
||||
}
|
||||
return strings.TrimSpace(firstNonEmpty(cfg.OpenAppSecret, cfg.LegacyAppSecret))
|
||||
}
|
||||
|
||||
// StreamTimeoutSettings 流超时处理配置(仅控制超时后的处理方式,超时判定由网关配置控制)
|
||||
type StreamTimeoutSettings struct {
|
||||
// Enabled 是否启用流超时处理
|
||||
Enabled bool `json:"enabled"`
|
||||
// Action 超时后的处理方式: "temp_unsched" | "error" | "none"
|
||||
Action string `json:"action"`
|
||||
// TempUnschedMinutes 临时不可调度持续时间(分钟)
|
||||
TempUnschedMinutes int `json:"temp_unsched_minutes"`
|
||||
// ThresholdCount 触发阈值次数(累计多少次超时才触发)
|
||||
ThresholdCount int `json:"threshold_count"`
|
||||
// ThresholdWindowMinutes 阈值窗口时间(分钟)
|
||||
ThresholdWindowMinutes int `json:"threshold_window_minutes"`
|
||||
}
|
||||
|
||||
// StreamTimeoutAction 流超时处理方式常量
|
||||
const (
|
||||
StreamTimeoutActionTempUnsched = "temp_unsched" // 临时不可调度
|
||||
StreamTimeoutActionError = "error" // 标记为错误状态
|
||||
StreamTimeoutActionNone = "none" // 不处理
|
||||
)
|
||||
|
||||
// DefaultStreamTimeoutSettings 返回默认的流超时配置
|
||||
func DefaultStreamTimeoutSettings() *StreamTimeoutSettings {
|
||||
return &StreamTimeoutSettings{
|
||||
Enabled: false,
|
||||
Action: StreamTimeoutActionTempUnsched,
|
||||
TempUnschedMinutes: 5,
|
||||
ThresholdCount: 3,
|
||||
ThresholdWindowMinutes: 10,
|
||||
}
|
||||
}
|
||||
|
||||
// RectifierSettings 请求整流器配置
|
||||
type RectifierSettings struct {
|
||||
Enabled bool `json:"enabled"` // 总开关
|
||||
ThinkingSignatureEnabled bool `json:"thinking_signature_enabled"` // Thinking 签名整流
|
||||
ThinkingBudgetEnabled bool `json:"thinking_budget_enabled"` // Thinking Budget 整流
|
||||
APIKeySignatureEnabled bool `json:"apikey_signature_enabled"` // API Key 签名整流开关
|
||||
APIKeySignaturePatterns []string `json:"apikey_signature_patterns"` // API Key 自定义匹配关键词
|
||||
}
|
||||
|
||||
// DefaultRectifierSettings 返回默认的整流器配置(全部启用)
|
||||
func DefaultRectifierSettings() *RectifierSettings {
|
||||
return &RectifierSettings{
|
||||
Enabled: true,
|
||||
ThinkingSignatureEnabled: true,
|
||||
ThinkingBudgetEnabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Beta Policy 策略常量
|
||||
const (
|
||||
BetaPolicyActionPass = "pass" // 透传,不做任何处理
|
||||
BetaPolicyActionFilter = "filter" // 过滤,从 beta header 中移除该 token
|
||||
BetaPolicyActionBlock = "block" // 拦截,直接返回错误
|
||||
|
||||
BetaPolicyScopeAll = "all" // 所有账号类型
|
||||
BetaPolicyScopeOAuth = "oauth" // 仅 OAuth 账号
|
||||
BetaPolicyScopeAPIKey = "apikey" // 仅 API Key 账号
|
||||
BetaPolicyScopeBedrock = "bedrock" // 仅 AWS Bedrock 账号
|
||||
)
|
||||
|
||||
// BetaPolicyRule 单条 Beta 策略规则
|
||||
type BetaPolicyRule struct {
|
||||
BetaToken string `json:"beta_token"` // beta token 值
|
||||
Action string `json:"action"` // "pass" | "filter" | "block"
|
||||
Scope string `json:"scope"` // "all" | "oauth" | "apikey" | "bedrock"
|
||||
ErrorMessage string `json:"error_message,omitempty"` // 自定义错误消息 (action=block 时生效)
|
||||
ModelWhitelist []string `json:"model_whitelist,omitempty"` // 模型匹配模式列表(为空=对所有模型生效)
|
||||
FallbackAction string `json:"fallback_action,omitempty"` // 未匹配白名单的模型的处理方式
|
||||
FallbackErrorMessage string `json:"fallback_error_message,omitempty"` // 未匹配白名单时的自定义错误消息 (fallback_action=block 时生效)
|
||||
}
|
||||
|
||||
// BetaPolicySettings Beta 策略配置
|
||||
type BetaPolicySettings struct {
|
||||
Rules []BetaPolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// OverloadCooldownSettings 529过载冷却配置
|
||||
type OverloadCooldownSettings struct {
|
||||
// Enabled 是否在收到529时暂停账号调度
|
||||
Enabled bool `json:"enabled"`
|
||||
// CooldownMinutes 冷却时长(分钟)
|
||||
CooldownMinutes int `json:"cooldown_minutes"`
|
||||
}
|
||||
|
||||
// RateLimit429CooldownSettings 429默认回避配置
|
||||
type RateLimit429CooldownSettings struct {
|
||||
// Enabled 是否在无法解析上游重置时间时应用默认429回避
|
||||
Enabled bool `json:"enabled"`
|
||||
// CooldownSeconds 默认回避时长(秒)
|
||||
CooldownSeconds int `json:"cooldown_seconds"`
|
||||
}
|
||||
|
||||
// DefaultOverloadCooldownSettings 返回默认的过载冷却配置(启用,10分钟)
|
||||
func DefaultOverloadCooldownSettings() *OverloadCooldownSettings {
|
||||
return &OverloadCooldownSettings{
|
||||
Enabled: true,
|
||||
CooldownMinutes: 10,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultRateLimit429CooldownSettings 返回默认的429回避配置(启用,5秒)
|
||||
func DefaultRateLimit429CooldownSettings() *RateLimit429CooldownSettings {
|
||||
return &RateLimit429CooldownSettings{
|
||||
Enabled: true,
|
||||
CooldownSeconds: 5,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultBetaPolicySettings 返回默认的 Beta 策略配置
|
||||
//
|
||||
// context-1m-2025-08-07 的默认策略:
|
||||
// - 仅 claude-sonnet-5 及后续版本(如 claude-sonnet-5-*)在上游默认支持 1M 上下文。
|
||||
// - Sonnet 4.x 及以下、Opus、Haiku 上游都不支持该 beta,透传上去会被上游 400 或降级。
|
||||
// - 因此默认对 sonnet-5* 放行、其余全部过滤,与上游能力保持一致。
|
||||
//
|
||||
// 白名单需要覆盖每个上游路径的模型 ID 变形:
|
||||
// - 直连 Anthropic API(OAuth mimic / API Key / SetupToken):模型保持客户端原样
|
||||
// (如 "claude-sonnet-5"、"claude-sonnet-5-YYYYMMDD"、"claude-sonnet-5-thinking")。
|
||||
// - Vertex AI:normalizeVertexAnthropicModelID 会把 "-YYYYMMDD" 后缀转成 "@YYYYMMDD"
|
||||
// (如 "claude-sonnet-5@YYYYMMDD")。
|
||||
// - AWS Bedrock:ResolveBedrockModelID 会输出带跨区域前缀的模型 ID
|
||||
// (us./eu./apac./jp./au./us-gov./global. 或无前缀的 "anthropic." 形式)。
|
||||
//
|
||||
// 白名单只用后缀通配符(matchModelPattern 语义),因此每个路径都需要显式列出前缀。
|
||||
// 精确匹配 "claude-sonnet-5" + 后缀 "-*" 与 "@*",可覆盖直连/Vertex 场景,同时避免误伤
|
||||
// 未来可能出现的 "claude-sonnet-50" 或 "claude-sonnet-5.x" 之类的意外命名。
|
||||
func DefaultBetaPolicySettings() *BetaPolicySettings {
|
||||
return &BetaPolicySettings{
|
||||
Rules: []BetaPolicyRule{
|
||||
{
|
||||
BetaToken: "fast-mode-2026-02-01",
|
||||
Action: BetaPolicyActionFilter,
|
||||
Scope: BetaPolicyScopeAll,
|
||||
},
|
||||
{
|
||||
BetaToken: "context-1m-2025-08-07",
|
||||
Action: BetaPolicyActionPass,
|
||||
Scope: BetaPolicyScopeAll,
|
||||
ModelWhitelist: []string{
|
||||
// 直连 Anthropic API(客户端请求 model 原样)
|
||||
"claude-sonnet-5",
|
||||
"claude-sonnet-5-*",
|
||||
// Vertex AI 走 normalizeVertexAnthropicModelID 后 "@YYYYMMDD" 格式
|
||||
"claude-sonnet-5@*",
|
||||
// AWS Bedrock cross-region inference profile
|
||||
"us.anthropic.claude-sonnet-5*",
|
||||
"eu.anthropic.claude-sonnet-5*",
|
||||
"apac.anthropic.claude-sonnet-5*",
|
||||
"jp.anthropic.claude-sonnet-5*",
|
||||
"au.anthropic.claude-sonnet-5*",
|
||||
"us-gov.anthropic.claude-sonnet-5*",
|
||||
"global.anthropic.claude-sonnet-5*",
|
||||
// AWS Bedrock 无 cross-region 前缀
|
||||
"anthropic.claude-sonnet-5*",
|
||||
},
|
||||
FallbackAction: BetaPolicyActionFilter,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAI Fast Policy 策略常量
|
||||
// OpenAI 的 "fast 模式" 通过请求体中的 service_tier 字段识别:
|
||||
// - "priority"(客户端可传 "fast",归一化为 "priority"):fast 模式
|
||||
// - "flex":低优先级模式
|
||||
// - 省略:normal 默认
|
||||
//
|
||||
// 本策略复用 BetaPolicyAction*/BetaPolicyScope* 常量语义,只是匹配键从
|
||||
// anthropic-beta header 换成 body 的 service_tier 字段。
|
||||
const (
|
||||
OpenAIFastTierAny = "all" // 匹配任意已识别的 service_tier
|
||||
OpenAIFastTierPriority = "priority" // 仅匹配 fast(priority)
|
||||
OpenAIFastTierFlex = "flex" // 仅匹配 flex
|
||||
|
||||
// OpenAIFastPolicyActionForcePriority 会保留 service_tier 字段并强制写成
|
||||
// priority,用于把 flex/auto/default/scale 等已识别 tier 收敛为 fast。
|
||||
OpenAIFastPolicyActionForcePriority = "force_priority"
|
||||
)
|
||||
|
||||
// OpenAIFastPolicyRule 单条 OpenAI fast/flex 策略规则
|
||||
type OpenAIFastPolicyRule struct {
|
||||
ServiceTier string `json:"service_tier"` // "priority" | "flex" | "auto" | "default" | "scale" | "all"
|
||||
Action string `json:"action"` // "pass" | "filter" | "block" | "force_priority"
|
||||
Scope string `json:"scope"` // "all" | "oauth" | "apikey" | "bedrock"
|
||||
UserIDs []int64 `json:"user_ids,omitempty"` // 空=所有 Sub2API 用户;非空=仅指定 API Key 所属用户
|
||||
ErrorMessage string `json:"error_message,omitempty"` // 自定义错误消息 (action=block 时生效)
|
||||
ModelWhitelist []string `json:"model_whitelist,omitempty"` // 模型匹配模式列表(为空=对所有模型生效)
|
||||
FallbackAction string `json:"fallback_action,omitempty"` // 未匹配白名单的模型的处理方式
|
||||
FallbackErrorMessage string `json:"fallback_error_message,omitempty"` // 未匹配白名单时的自定义错误消息 (fallback_action=block 时生效)
|
||||
}
|
||||
|
||||
// OpenAIFastPolicySettings OpenAI fast 策略配置
|
||||
type OpenAIFastPolicySettings struct {
|
||||
Rules []OpenAIFastPolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// DefaultOpenAIFastPolicySettings 返回默认的 OpenAI fast 策略配置。
|
||||
// 默认不配置任何规则,保留 OpenAI 上游 service_tier 语义;管理员如需
|
||||
// 限制 priority/flex,可以在 admin UI 中显式配置 filter 或 block 规则。
|
||||
func DefaultOpenAIFastPolicySettings() *OpenAIFastPolicySettings {
|
||||
return &OpenAIFastPolicySettings{
|
||||
Rules: []OpenAIFastPolicyRule{},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user