Skip to content

fix: carry Spark quota scope onto dev2-go (#599) - #662

Merged
Wibias merged 1 commit into
lidge-jun:dev2-gofrom
Wibias:sync/599-to-dev2-go
Jul 29, 2026
Merged

fix: carry Spark quota scope onto dev2-go (#599)#662
Wibias merged 1 commit into
lidge-jun:dev2-gofrom
Wibias:sync/599-to-dev2-go

Conversation

@Wibias

@Wibias Wibias commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Go port

Go has Codex routing/cooldown (go/internal/codex/routing*.go, auth_context.go) but not the new CodexQuotaScope / Spark-independent quota mapping from #599.

Tracking issue will follow after this lands. This PR does not claim the Go side is done.

* Merge remote-tracking branch 'origin/dev' into fix/codex-spark-quota-scope-dev

* fix: retain affinity per Codex quota scope

* fix: address scoped affinity review feedback

* fix: restore dev version and harden compact test

(cherry picked from commit 20cdc0d)
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • ^dev$
  • ^preview$

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c69f1fc0-8620-4cf8-bb79-84125edf5d74

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@Wibias
Wibias merged commit f148ea9 into lidge-jun:dev2-go Jul 29, 2026
7 of 10 checks passed
@github-actions github-actions Bot added the bug Something isn't working label Jul 29, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75be2831c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +21 to +24
An explicit `Retry-After` or an unclassified quota 429 is account-wide. A reset-derived native-model
429 is advisory and remains within its confirmed quota group: `gpt-5.3-codex-spark` is separate from
the shared native group (including GPT-5.6 Terra/Luna). This allows a same-account combo to test an
independent quota without allowing fallbacks that share the exhausted quota.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Retarget this TypeScript-only change to dev

The commit explicitly targets dev2-go, but the diff only changes the TypeScript runtime, tests, structure notes, and documentation; it does not touch go/, the native runtime entrypoint, or Go release-asset tooling. Repository policy requires such changes to target dev, so retarget this change rather than carrying an incomplete TS-only implementation onto the Go integration line.

AGENTS.md reference: AGENTS.md:L84-L89

Useful? React with 👍 / 👎.

Comment on lines +1567 to +1569
modelId: route.modelId,
probeLeaseId: codexProbeLeaseId(authCtx),
probeQuotaScope: codexProbeQuotaScope(authCtx),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record deferred scoped cooldowns before combo fallback

When a failover combo has another eligible target on the same provider, deferCodexResetDerivedCooldown prevents this newly model-scoped outcome from being recorded, and the combo loop never records it later. For a Spark reset-derived 429 followed by a successful Terra fallback, only the combo target's default 60-second cooldown remains, so subsequent requests retry the known-exhausted Spark quota every minute instead of respecting its reset-derived cooldown and probe schedule. Record the scoped Spark outcome before advancing the combo; doing so no longer blocks the shared Terra/Luna target.

Useful? React with 👍 / 👎.

Comment thread src/codex/routing.ts
Comment on lines +1278 to +1279
if (quotaScope === "shared") {
clearThreadAccountMapForAccount(accountId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve Spark affinities when shared quota cools down

If a thread already has a healthy Spark affinity to account A and a shared Terra/Luna request on A receives a reset-derived 429, this call removes every affinity for A, including the independent Spark binding. Because the same branch can then promote the shared active account to B, the thread's next Spark request may incorrectly move to B even though A's Spark quota remains healthy. Clear only the failed shared affinity here rather than all scoped affinities for the account.

Useful? React with 👍 / 👎.

Comment on lines 439 to +443
recordCodexUpstreamOutcome(config, authCtx.accountId, outcome, {
threadId,
modelId,
probeLeaseId: codexProbeLeaseId(authCtx),
probeQuotaScope: codexProbeQuotaScope(authCtx),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Forward reset headers to the terminal outcome recorder

When an HTTP-successful streaming response ends with an SSE response.failed carrying a 429/402 status, this recorder receives the semantic status and model but not the response's Retry-After or x-codex-*-reset-at metadata captured earlier in quotaMeta. Consequently computeQuotaCooldown selects the default source, making a Spark terminal quota failure account-wide and blocking Terra/Luna instead of creating the intended scoped reset-derived cooldown. Pass the captured quota metadata into the terminal recorder.

Useful? React with 👍 / 👎.

let authCtx: CodexAuthContext;
if (route.codexAccountMode) {
authCtx = await resolveCodexAuthContext(req.headers, config, route.codexAccountMode);
authCtx = await resolveCodexAuthContext(req.headers, config, route.codexAccountMode, { modelId: route.modelId });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preview subagent accounts with the primary model's quota scope

Final authentication is now model-scope-aware, but the earlier subagent account preview still calls previewCodexAccountForRequest without a quota scope. If account A has a Spark-scoped cooldown and account B can serve Spark, fallback selection is evaluated against A's account-specific model health even though this call will authenticate against B; that can unnecessarily rewrite Spark to a fallback model or consult the wrong failure state. Pass the primary routed model's quota scope into the preview so fallback selection and final authentication predict the same account.

Useful? React with 👍 / 👎.

Comment thread src/codex/routing.ts
Comment on lines +500 to +503
const account = getCodexAccountHealthSnapshot(accountId, now);
if (account) return account;
if (!quotaScope) return null;
const scoped = scopedHealthFor(accountId, quotaScope);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route OpenAI sidecars with their actual quota scope

Model-less callers return here without consulting scoped health, but resolveFirstUsableOpenAiSidecar still resolves pool authentication without a model ID even though the web-search and vision sidecars use shared native models such as gpt-5.6-luna and gpt-5.4-mini. After account A receives a shared reset-derived cooldown, a routed request needing one of these sidecars can therefore select A and hit the exhausted shared quota instead of selecting an eligible account B. Thread the configured sidecar model through auth resolution and outcome recording so sidecars participate in the shared scope.

Useful? React with 👍 / 👎.

@Wibias
Wibias deleted the sync/599-to-dev2-go branch July 30, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants