Commit Graph
895 Commits
Author SHA1 Message Date
ZheFox f822df6cce Merge remote-tracking branch 'origin/main' into codex/fix-antigravity-quota 2026-09-03 10:46:49 +08:00
ZheFox 45c840b8d3 fix(providers): refresh Antigravity grouped quotas 2026-09-03 10:46:44 +08:00
elky 7323d41fbe feat(routing): move sticky-key retries into routing policy with lazy attempts
Replace the provider/endpoint max_retries fields as the source of same-key
retries with a routing policy setting, sticky_key_attempts (default 2). Only
the first-ranked candidate is retried on the same key; every failover
candidate gets a single attempt so failover keeps advancing instead of
retrying each fallback key.

Materialize exactly one attempt per candidate and derive same-key retries in
the attempt loop after a candidate-scoped failure, so the retry budget no
longer inflates up-front materialization and needs no upper bound. The budget
travels in the report context; retries reuse the plan with a fresh candidate
id and incremented retry index. Pool groups only retry their first key within
the retry-index stride.

Expose the setting in the routing profile editor and the set_scheduling rule
action, and drop the max_retries input from the provider form.
2026-09-02 20:48:40 +08:00
elky 415b2da81b feat(routing): make routing profiles the sole scheduler policy source
Bootstrap an enabled system-default routing group from the legacy
scheduler config keys on startup, resolve the default ordering config
from that group before falling back to the legacy keys, and stop merging
keep_priority_on_conversion with the legacy flag when a policy is
resolved. Thread the policy-derived ordering config into candidate
preselection so it no longer reads system config independently.

Add per-API-format key priority overrides so a key serving several
formats keeps independent ordering, matching the legacy
global_priority_by_format semantics. Expose keep_priority_on_conversion
in the routing profile editor and read the effective policy in the
model routing preview, monitoring metrics and provider page badge.
2026-09-02 17:04:04 +08:00
zhefox 2ed2cc66ef fix(formats): retain response field normalization import 2026-09-02 15:44:15 +08:00
zhefox b1bf7837cf style: format quota and response changes 2026-09-02 15:40:40 +08:00
zhefox 77229943d1 fix(pool): preserve generic quota windows for model scheduling 2026-09-02 15:29:56 +08:00
zhefox a0369cf49a Merge remote-tracking branch 'zhefox/main' into zhefox-main
# Conflicts:
#	crates/aether-admin/src/provider/quota.rs
#	crates/aether-ai/formats/src/formats/openai/chat/stream.rs
#	crates/aether-ai/formats/src/formats/openai/responses/mod.rs
#	crates/aether-provider/pool/src/provider.rs
#	crates/aether-provider/pool/src/quota.rs
2026-09-02 15:25:27 +08:00
zhefox dbbe7b22ab fix(pool): isolate dynamic model quota buckets and 429 scheduling 2026-09-02 15:23:23 +08:00
ZheFox 144a28f544 feat(admin-users): add plan entitlement revocation flow 2026-09-02 11:23:24 +08:00
Kayphoon 88d2b002be fix(formats): ignore Responses ping stream events 2026-09-01 12:58:21 +00:00
ZheFox 5a69cfe40d Merge pull request #772 from zhefox/main
fix(gateway): handle pool saturation and malformed Gemini calls
2026-09-01 19:31:44 +08:00
ZheFox 3d87bbf230 style(rust): apply workspace formatting 2026-09-01 19:31:13 +08:00
ZheFox 633363e190 fix(gateway): handle pool saturation and malformed Gemini calls 2026-09-01 19:25:00 +08:00
elky d07dc86376 refactor(codex): generalize fingerprint convergence 2026-09-01 17:05:54 +08:00
elky a39048ecce feat(codex): stabilize identity across retries 2026-09-01 15:33:40 +08:00
ZheFox 57abb20778 fix(pool): show Antigravity quota reset times 2026-09-01 11:29:48 +08:00
ZheFox 2fe2600021 fix(pool): isolate model quotas and compact account display 2026-09-01 10:15:57 +08:00
ZheFox 9b819169d5 Merge pull request #767 from zhefox/fix/provider-key-concurrency-cache-affinity
fix(gateway): improve provider pool concurrency, quotas, and affinity
2026-09-01 08:11:46 +08:00
ZheFox 9631b229b3 fix(gateway): add provider key concurrency and cache affinity modes 2026-09-01 08:06:58 +08:00
Brisbanehuang 4dbf98163e feat(provider-ops): add generic usage API template 2026-08-29 09:04:05 -04:00
zhefox 56395945c0 fix(gateway): route Responses compaction only to Responses providers 2026-08-29 12:28:55 +08:00
zhefox b35364d7fd fix(antigravity): normalize private search tool name 2026-08-29 11:09:15 +08:00
ZheFox 36daba7a34 fix(antigravity): align tool schema wire fields 2026-08-29 08:45:19 +08:00
ZheFox 9837ce1197 fix(antigravity): use Gemini schema field for tools 2026-08-29 02:50:07 +08:00
ZheFox 1bc2287baa fix(gemini): normalize mixed tools for same-format providers 2026-08-29 01:08:01 +08:00
ZheFox 5bcdcca784 fix(formats): normalize Responses additional tools for Chat 2026-08-28 23:03:56 +08:00
ZheFox 83098f98b6 fix(formats): gate mixed Gemini tools by model 2026-08-28 20:42:49 +08:00
ZheFox f0b0064f3d fix(formats): enable mixed Gemini tool calls 2026-08-28 16:55:38 +08:00
ZheFox 64e5725331 fix(formats): sanitize Gemini tool schemas 2026-08-28 16:11:16 +08:00
ZheFox 5b6fce1a77 fix(formats): degrade Responses reasoning summaries for Chat 2026-08-28 14:05:48 +08:00
ZheFox 5687dad177 fix(formats): scope signature helper to tests 2026-08-28 13:21:35 +08:00
ZheFox dd2958a458 fix(admin): persist provider settings and enforce quotas 2026-08-28 12:47:54 +08:00
ZheFox c4b4dfa996 fix(formats): preserve Gemini tool thought signatures 2026-08-28 12:47:34 +08:00
ZheFox 8cdfa338e5 fix(gemini): pair idless tool history 2026-08-28 02:15:00 +08:00
ZheFox 4da8c57fe3 fix(ai): align Gemini and Responses compatibility 2026-08-27 22:13:20 +08:00
ZheFox e2b003af24 fix(formats): preserve Responses namespace tools through Chat 2026-08-26 00:43:50 +08:00
ZheFox ec6ddb43a7 fix(data): retain applied legacy backfill for upgrades 2026-08-25 21:22:57 +08:00
ZheFox 2f2d444f97 fix(codex): self-heal Spark-contaminated account quotas
Keep model-scoped Spark windows out of account state, preserve authoritative WHAM exhaustion flags, and repair historical cross-family quota generations without weakening stale-response guards.
2026-08-25 19:13:41 +08:00
stabeyandClaude Opus 5 42deab67b3 fix(admin): keep a model-scoped 429 reset out of the account quota slot
`parse_codex_websocket_usage_limit_error` backfills `primary_reset_at` and
`primary_reset_after_seconds` from the error body whenever the embedded headers
did not supply them. Now that a named per-model limit no longer claims the
unprefixed window headers, that absence is exactly what a Spark 429 produces —
and `resets_at` on such an error is the Spark window's reset, so the backfill
put model-scoped timing back on the account's own quota.

Gate the backfill on the same ownership rule the window parsing uses.

Reported by Cursor Bugbot on the fork PR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 15:22:29 +08:00
stabeyandClaude Opus 5 1b1be918a9 fix(admin): keep Codex model-scoped rate-limit headers out of the account quota
`parse_codex_usage_headers` reads the unprefixed `x-codex-primary/secondary-*`
headers as the account's own quota. They are not: they carry whichever limit
governed the request, and `x-codex-active-limit` names it — `premium` for the
plan's own limit, or a metered feature such as `codex_bengalfox` for a named
per-model limit. On a request billed against a named limit the unprefixed
headers repeat that limit's windows verbatim.

So a single request to a model with its own limit writes that model's windows
into the account slots. The paid-window swap then makes it worse: a named
limit's secondary window is active, unlike the plan's disabled one, so the swap
promotes the model's weekly window into the account's weekly slot — the slot
the UI labels and the scheduler reads through `quota_usage_ratio`.

It also sticks. Both weekly windows share `window_minutes`, so
`codex_quota_same_window_identity` treats them as one window, and
`codex_quota_merge_same_window` drops an observation whose deadline is earlier
than the stored one. The two weeks start at different instants, so every later
account observation looks like a stale sample of a window that already rolled
over and is discarded until the model window's own deadline passes.

Observed on a `pro` key running both model families: one `gpt-5.3-codex-spark`
request replaced the account weekly window with the Spark weekly one, and the
~3000 plan-limit responses over the next 100 minutes were all discarded. The
account's real weekly usage never landed, and its reset time was reported nine
hours late.

The header set describes itself — every named limit announces
`x-codex-<feature>-limit-name` and carries its windows under the same prefix —
so parse the named families directly and only claim the unprefixed windows for
the account when no announced limit owns them. Responses without
`x-codex-active-limit` keep the previous behaviour.

This also stops the Spark windows from going stale: they were only ever written
by the `wham/usage` admin probe even though every response carries them.

Refs #746

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 15:22:29 +08:00
ZheFox 2cd20da1ec fix(gateway): support current Codex Realtime live routes 2026-08-23 02:51:49 +08:00
ZheFox acde38b8e7 fix(usage): unify OpenAI Live and WebSocket records 2026-08-21 11:53:53 +08:00
ZheFox 9996e75a34 fix(ci): align database snapshot migration cutoff 2026-08-21 11:11:45 +08:00
ZheFox 2c89202001 feat(gateway): add Codex Live and OpenAI Realtime
Implement preflighted Live/Realtime WebSocket transports, protocol-aware authentication, usage auditing, UI filtering, and legacy Codex permission migration.
2026-08-21 04:27:34 +08:00
ZheFox 4185ad1b1e feat(gateway): add Codex Live transport 2026-08-20 21:59:05 +08:00
ZheFox 654f798d25 fix(ws): harden Responses continuation state 2026-08-20 08:51:16 +08:00
ZheFox bef282cfee fix(responses): replay DeepSeek opaque reasoning state 2026-08-20 00:40:48 +08:00
ZheFox d21d8ce9f5 fix(codex): avoid replaying static config on websocket continuations 2026-08-20 00:40:40 +08:00
ZheFox c8118edf36 fix(ws): harden Responses connection lifecycle
Revalidate control policy per turn, isolate downstream credentials, and make planner/turn ownership cancellation-safe.

Preserve opaque protocol events, align configurable timeout semantics, and extend end-to-end security and settlement coverage.
2026-08-17 18:50:29 +08:00