feat(settings): OpenAI 403 临时冷却参数改为后台可配置 - #6347
Open
ryanchou1994 wants to merge 1 commit into
Open
Conversation
OpenAI 账号收到 403 后的处置策略此前完全硬编码在 ratelimit_service.go: 单次临时冷却 10 分钟、计数窗口 180 分钟、窗口内累计 3 次转永久错误。 403 在很多部署里是 IP / 代理出口被拒而非账号问题,管理员却只能改代码 重新构建才能调整,issue Wei-Shaw#5280 及其下多位用户对此反馈强烈。 本次把这三个参数(外加一个总开关)做成系统设置,接线完全照既有的 529 过载冷却 / 429 默认回避两条范本: - 后端:新增 OpenAI403CooldownSettings(enabled / cooldown_minutes / disable_threshold / window_minutes),设置键 openai_403_cooldown_settings, 读端 clamp、写端启用时校验范围(1-1440 分钟 / 1-100 次)、停用时归一化; handleOpenAI403 在 HTML 403 守卫之后读取设置,三个数值全部改走配置; 新增 GET/PUT /api/v1/admin/settings/openai-403-cooldown。 - 前端:设置页「网关」分组内新增「OpenAI 403 临时冷却」卡片,中英文案。 默认值锁定为原常量(启用 / 10 / 3 / 180),未改设置的部署升级后行为 逐字不变;原三个常量保留作为唯一默认值来源,Kimi 并发限制路径借用 openAI403CooldownMinutesDefault 的逻辑不受影响。 enabled=false 的语义是「403 只换号、不罚号」:不递增计数、不临时停调、 不写永久错误,与既有 HTML 403(端点级错误)分支的处置一致。 附 10 个单元测试:设置读写默认 / clamp / 校验 / 归一化各一,处理链上 冷却时长 / 阈值 / 窗口三项分别断言走配置值,停用跳过处罚、无设置服务 时回落默认、HTML 守卫仍先于设置分支各一。撤掉读取点或删掉停用分支时 对应测试实测失败。 Fixes Wei-Shaw#5280
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
#5280:OpenAI 账号只要收到 403 就被临时冷却 10 分钟,窗口内累计 3 次直接转永久错误。这三个数字全部硬编码在
backend/internal/service/ratelimit_service.go:不少部署里 403 是 IP / 代理出口被上游拒绝,和账号本身无关;管理员想把冷却调短、把阈值调高,或干脆只换号不罚号,目前都只能改代码重新构建。
修复
把这三个参数(外加一个总开关)做成系统设置,接线完全照仓库里已有的 529 过载冷却(
OverloadCooldownSettings)和 429 默认回避(RateLimit429CooldownSettings)两条范本复制,没有引入新的模式:后端
settings_view.go:新增OpenAI403CooldownSettings { enabled, cooldown_minutes, disable_threshold, window_minutes }与DefaultOpenAI403CooldownSettings()domain_constants.go:设置键openai_403_cooldown_settingssetting_features.go:Get缺值 / 空值 / 坏 JSON 回默认,读到的数值 clamp 到范围;Set启用状态下越界直接报错(错误信息带字段名),停用状态下越界归一化为默认值——与 529 的处理一致ratelimit_service.go:handleOpenAI403在既有 HTML 403 守卫之后读取设置;enabled=false时只换号不罚号(不递增计数、不临时停调、不写永久错误,和 HTML 403 分支同一口径);冷却时长 / 阈值 / 计数窗口三处全部改走配置。读取失败或未注入SettingService时回落默认值setting_handler_runtime.go+routes/admin.go:GET/PUT /api/v1/admin/settings/openai-403-cooldown前端
范围与默认值
ratelimit_cn_providers.go里 Kimi 并发限制借用openAI403CooldownMinutesDefault的路径不在本 PR 范围内,行为不变。测试
新增
backend/internal/service/openai_403_cooldown_test.go(-tags=unit),10 个用例:TestGetOpenAI403CooldownSettings_DefaultsWhenNotSetTestGetOpenAI403CooldownSettings_ClampsOutOfRangeTestSetOpenAI403CooldownSettings_RejectsOutOfRangeWhenEnabledTestSetOpenAI403CooldownSettings_NormalizesWhenDisabledTestHandleOpenAI403_UsesConfiguredCooldownMinutesSetTempUnschedulable的until落在 now+2min,不是 +10minTestHandleOpenAI403_UsesConfiguredThresholdTestHandleOpenAI403_PassesConfiguredWindowToCounterIncrementOpenAI403Count收到 30TestHandleOpenAI403_DisabledSkipsAccountPenaltyTestHandleOpenAI403_FallsBackToDefaultsWithoutSettingServiceTestHandleOpenAI403_HTMLBodyStillSkipsPenaltyWhenEnabled红 → 绿验证(golang:1.27 容器):
handleOpenAI403的三处读取改回常量 ⇒ 冷却时长 / 阈值 / 窗口三个用例失败,其余通过enabled=false分支 ⇒DisabledSkipsAccountPenalty失败HTMLBodyStillSkipsPenaltyWhenEnabled等失败go test -tags=unit ./...全绿;gofmt -l空;go vet通过pnpm typecheck/pnpm lint:check通过既有引用这三个常量的测试(
openai_gateway_cn_fixes_test.go、ratelimit_service_403_html_test.go等)未改动,默认值不变所以原样通过。查重与已知限制
enabled=false意味着账号级 403(比如真的被封)也不会再自动进错误状态,只靠换号——这是把选择权交给管理员,默认仍是启用;文案里已写明。