Commit Graph
9 Commits
Author SHA1 Message Date
HuntercodeT 3438580213 fix(gateway): stop a per-model cooldown from turning 404 model_not_found into 429
classifySelectionFailureError upgrades a selection failure to 429
rate_limit_error whenever the scheduler's compact reason string matches
model_rate_limited=(\d+) with a positive count. It does so unconditionally,
including when the fallback it was handed is the authoritative 404
model_not_found classification.

Selection failure reasons are additive, so both can appear at once, e.g.
"pool=9, filtered: model_not_supported=8 model_rate_limited=1": eight accounts
cannot serve the model at all and the ninth happens to sit in a per-model
cooldown. classifyNoAccountError only produces ModelNotFound through
DiagnoseModelAvailabilityForPlatform, a dedicated database query over
persistent eligibility (active + schedulable + model_mapping), so it has
already established that no account in the group can serve the model. One
transient cooldown does not make "All available accounts are currently
rate-limited" true.

The mislabel is not cosmetic:

- Retrying can never succeed, yet 429 explicitly invites a retry.
- Clients that treat 429 as a rate limit retry hard and swallow the body;
  Codex surfaces only "exceeded retry limit, last status: 429", discarding the
  one message that names the real problem. Operators then look for capacity
  and rate limits instead of a model whitelist.
- Ops attribution becomes self-contradictory: classifyNoAccountErrorFromGin
  has already marked the request business-limited for local model
  configuration, while call sites gate markOpsRoutingCapacityLimitedIfNoAvailable
  on ModelNotFound, which the override clears, so the same request is also
  counted as routing capacity limited.

Return the fallback untouched when it is ModelNotFound. The 429 upgrade is
preserved for every other fallback, which is the case it was written for:
accounts that can serve the model exist but are all cooling down, where the
fallback is 503 and retrying is meaningful.

Claude-Session: https://claude.ai/code/session_01LwvyJVV2sdqiu41Z9JDNUq
2026-09-01 15:18:30 +08:00
IanShaw 48615d5d1f Merge remote-tracking branch 'upstream/main' into fix/openai-responses-compatibility
# Conflicts:
#	backend/internal/handler/ops_error_logger.go
2026-08-20 00:31:12 -07:00
IanShaw c374ff2951 完善 OpenAI 网关切换与运维错误语义 2026-08-19 23:13:40 -07:00
wucm667 6b0ec50f24 fix(ops): exclude model configuration errors from SLA
404 model_not_found remains unchanged while ops attribution becomes routing/business-limited.
2026-08-20 10:52:29 +08:00
Heatherm Huang ebc1028771 Add composite group routing 2026-07-23 09:19:24 +08:00
wucm667 2594950993 fix: classify transient account exhaustion as 503 instead of 404 2026-07-17 22:10:18 +08:00
Heatherm Huang 8a22dc7347 fix(grok): diagnose unavailable models by platform 2026-07-13 10:11:34 +08:00
shaw f93a6c50ce fix: repair CI build & lint regressions on main
- openai_gateway_model_availability.go: pass platform through to
  listSchedulableAccounts so OpenAI/Grok diagnosis scopes to the
  correct candidate pool (build break introduced by Grok subscription
  PR #3310).
- no_account_error.go: drop redundant context.Context type on
  ctx := context.Background() to satisfy staticcheck ST1023.
2026-06-26 16:06:01 +08:00
shaw fcd3bc1272 fix: return 404 model_not_found instead of 503 when no account supports the model 2026-06-26 15:38:06 +08:00