Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b96aa7d
fix(codex): defer validation for quota-exhausted account registration
Sep 7, 2026
be3b780
fix(codex): fence deferred validation against stale guardian results
Sep 7, 2026
32e3b31
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
ec9cc94
fix(codex): publish readiness changes and recheck pending selection
Sep 7, 2026
1639ce4
fix(codex): enforce pending readiness at request auth boundaries
Sep 7, 2026
2636e63
fix(codex): fence failed warmup metadata by credential generation
Sep 7, 2026
d2d6626
fix(codex): distinguish manual validation from background quota refresh
Sep 7, 2026
ebf4728
fix(codex): report pending validation in local health diagnostics
Sep 7, 2026
3dd3cfd
test(codex): distinguish passive quota observation from validation
Sep 7, 2026
94c175e
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
77ac748
test: remove host timing dependencies from readiness checks
Sep 7, 2026
ceca43d
docs(pr): replace component preview with dashboard registration evidence
Sep 7, 2026
acfdf51
fix(codex): require a CSRF-protected POST for deferred validation
Sep 7, 2026
094d253
fix(codex): support explicit CLI recovery and await validation in the…
Sep 7, 2026
a1ec6b3
docs(codex): publish CLI recovery reference and final dashboard evidence
Sep 7, 2026
3d901b5
fix(cli): retain pending Codex readiness in account output
Sep 7, 2026
25798a5
fix(codex): report deferred readiness when login completes
Sep 7, 2026
f4ae062
fix(codex): retain actionable validation failures without changing pa…
Sep 7, 2026
55de3ee
fix(codex): clear matching reauth state after deferred validation
Sep 7, 2026
f1d7683
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
8f94fd1
fix(codex): require dashboard consent for deferred validation
Sep 7, 2026
4136572
fix(codex): preserve validation intent at quota flight settlement
Sep 7, 2026
a1b5d23
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
255fa82
test: keep quota registration PR scoped to account readiness
Sep 7, 2026
57b59a0
Merge dev quota activation while preserving pending validation guards
Sep 7, 2026
cb28a09
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
aeb86cb
Merge the terminal-validation fix (#4120) into quota-deferred registr…
lidge-jun Sep 9, 2026
703f002
Merge origin/dev into quota-deferred registration
lidge-jun Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/pr-assets/codex-quota-registration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 5 additions & 7 deletions docs-site/src/content/docs/fr/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,11 @@ délégation v1/base/v2 et de ses mécanismes de repli.

## Préchauffage des comptes Codex

Lorsqu'un compte ChatGPT est ajouté au groupe de comptes Codex, opencodex le vérifie avant de l'enregistrer
avec une petite requête en streaming vers le service Codex Responses. La requête utilise un véritable tableau
d'éléments Responses (`input: [{ type: "message", ... }]`), attend `response.completed` et utilise par défaut
`gpt-5.4-mini`. Si ce modèle renvoie HTTP 400, opencodex réessaie avec `gpt-5.5` ; les détails structurés de
l'erreur en amont sont affichés sans exposer le corps brut de la réponse. La revalidation en arrière-plan est
distincte et désactivée par défaut. Elle ne s'exécute que si Token Guardian est actif, si la stratégie
d'actualisation `chatgpt` vaut `proactive` et si `tokenGuardian.codexWarmupEnabled` vaut true.
L’ajout ou la réauthentification vérifie normalement le compte avant son enregistrement par une petite requête attendant `response.completed`. Le modèle par défaut est `gpt-5.4-mini`, avec un essai sur `gpt-5.5` en cas de HTTP 400. Les erreurs publiques contiennent des catégories fixes, sans corps de réponse brut.

Si la lecture authentifiée des quotas avec le nouveau jeton OAuth confirme un quota de 5 heures, hebdomadaire ou mensuel épuisé, le compte est enregistré sans appel au modèle et affiche **Validation en attente**. Il reste exclu du routage après un redémarrage ou un renouvellement du jeton. Après récupération du quota, actualisez les quotas : une lecture récente et complète avec de la capacité disponible permet une petite requête de validation. Seule sa réussite active le compte. Tout échec conserve la restriction. Les lectures passives ne déclenchent pas cette requête. Un quota inconnu à l’inscription conserve la vérification habituelle.

La revalidation en arrière-plan est distincte et désactivée par défaut. Elle nécessite Token Guardian, la politique `proactive` du fournisseur `openai` et `tokenGuardian.codexWarmupEnabled`, et ignore les comptes dont la validation d’inscription est en attente.

## Restauration de Codex natif

Expand Down
12 changes: 5 additions & 7 deletions docs-site/src/content/docs/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -547,13 +547,11 @@ Catalog sync makes the selected sub-agent models available to Codex; see [Codex

## Codex account warmup

When a ChatGPT account is added to the Codex account pool, opencodex verifies it before persistence
with a small streaming request to the Codex Responses backend. The request uses a real Responses
item array (`input: [{ type: "message", ... }]`), waits for `response.completed`, and defaults to
`gpt-5.4-mini`. If that model returns HTTP 400, it retries with `gpt-5.5`; structured upstream error
details are surfaced without exposing raw response bodies. Background revalidation is separate and
off by default; it runs only when Token Guardian is enabled, the `chatgpt` refresh policy is
`proactive`, and `tokenGuardian.codexWarmupEnabled` is true.
When a ChatGPT account is added or reauthenticated, OpenCodex normally verifies it before saving with a small streaming request to the Codex Responses backend. It waits for `response.completed`, defaults to `gpt-5.4-mini`, and retries with `gpt-5.5` on HTTP 400. Public errors contain fixed failure categories rather than raw upstream response bodies.

If the new OAuth credential's authenticated usage lookup confirms an exhausted 5-hour, weekly, or monthly quota, the account is saved without this model request and shows **Validation pending**. It cannot serve pool requests, even after a restart or token refresh. Once quota recovers, **Refresh quotas** finishes validation: a fresh, complete usage reading with headroom permits one small model request, and only a completed response enables the account. Failed or incomplete readings and failed validation preserve the restriction. Passive account polling does not trigger deferred validation. Unknown usage during initial registration retains the normal warmup gate.

Background revalidation is separate and off by default. It requires Token Guardian, the `openai` provider's `proactive` refresh policy, and `tokenGuardian.codexWarmupEnabled`. It skips accounts awaiting deferred registration validation.

## Restoring native Codex

Expand Down
3 changes: 3 additions & 0 deletions docs-site/src/content/docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ Desktop mode and current credential-bound upstream permission; a catalog entry a
authorize a request. See [Luna Reserve alongside routed models](/reference/cli/providers-accounts/#luna-reserve-alongside-routed-models)
for setup, restart order, authorization requirements, and unsupported helpers.

For adding an account with exhausted quota and finishing its deferred validation, see
[Codex account warmup](/guides/codex-integration/#codex-account-warmup).

### Providers overview pool capacity

For Codex login in Pool mode, the Providers overview shows a configured-weight estimate of the
Expand Down
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/ja/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,11 @@ ocx service install # persistent: auto-starts on login and respawns on crash

## Codex アカウントのウォームアップ

ChatGPT アカウントが Codex アカウント プールに追加されると、opencodex は、Codex Response バックエンドへの小さなストリーミング リクエストで永続化する前にそれを検証します。リクエストは実際の応答項目配列 (`input: [{ type: "message", ... }]`) を使用し、`response.completed` を待機し、デフォルトは `gpt-5.4-mini` になります。そのモデルが HTTP 400 を返した場合、`gpt-5.5` で再試行します。構造化されたアップストリーム エラーの詳細は、生の応答本体を公開することなく表示されます。バックグラウンドの再検証は個別に行われ、デフォルトではオフになっています。これは、トークン ガーディアンが有効で、`chatgpt` 更新ポリシーが `proactive` で、`tokenGuardian.codexWarmupEnabled` が true の場合にのみ実行されます。
アカウントの追加・再認証では通常、保存前に小さなモデルリクエストで `response.completed` を確認します。既定モデルは `gpt-5.4-mini` で、HTTP 400 の場合は `gpt-5.5` で再試行します。公開エラーには固定の分類のみを表示し、生の応答本文は公開しません。

新しい OAuth トークンによる使用量取得で5時間・週次・月次の上限到達が確認された場合、モデルを呼ばずに保存し、**検証待ち**と表示します。再起動やトークン更新後も使用できません。上限回復後に使用量を更新すると、十分な空き容量を示す完全な最新情報を確認してから小さなモデルリクエストを送り、完了した場合のみ使用可能になります。取得や検証の失敗では待機状態を維持します。通常の状態ポーリングは検証リクエストを送りません。初回登録時の使用量が不明な場合は通常の検証が必要です。

バックグラウンド再検証は別機能で既定では無効です。Token Guardian、`openai` の `proactive` 更新ポリシー、`tokenGuardian.codexWarmupEnabled` が必要で、登録検証待ちのアカウントは除外します。

## ネイティブ Codexの復元

Expand Down
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/ko/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ catalog sync는 선택된 서브에이전트 모델을 Codex가 쓸 수 있게

## Codex 계정 워밍업

ChatGPT 계정을 Codex account pool에 추가하면, opencodex는 이를 저장하기 전에 Codex Responses backend로 작은 streaming request를 보내 확인합니다. 요청은 실제 Responses item array(`input: [{ type: "message", ... }]`)를 사용하고, `response.completed`를 기다리며, 기본값은 `gpt-5.4-mini`입니다. 그 모델이 HTTP 400을 반환하면 `gpt-5.5`로 다시 시도합니다. 구조화된 upstream error detail은 보여 주되 raw response body는 노출하지 않습니다. background revalidation은 별도 기능이며 기본값은 꺼져 있습니다. Token Guardian이 활성화되고, `chatgpt` refresh policy가 `proactive`이며, `tokenGuardian.codexWarmupEnabled`가 true일 때만 실행됩니다.
ChatGPT 계정을 추가하거나 재인증할 때 OpenCodex는 일반적으로 저장 전에 작은 모델 요청으로 확인합니다. `gpt-5.4-mini`의 `response.completed`를 기다리며 HTTP 400이면 `gpt-5.5`로 재시도합니다. 오류에는 고정된 실패 분류만 표시하고 원본 응답 본문은 노출하지 않습니다.

새 OAuth 토큰으로 인증된 사용량 조회에서 5시간·주간·월간 한도 소진이 확인되면 모델 요청 없이 계정을 저장하고 **검증 대기**로 표시합니다. 재시작이나 토큰 갱신 후에도 요청에 사용되지 않습니다. 한도 회복 후 **사용량 새로고침**을 실행하면, 여유가 있는 완전한 최신 사용량을 확인한 뒤 작은 모델 요청을 보내고 완료 응답을 받아야 계정을 사용할 수 있습니다. 조회나 검증 실패 시 대기 상태를 유지합니다. 일반적인 화면 상태 조회는 이 모델 요청을 보내지 않습니다. 최초 등록 때 사용량이 불명확하면 기존 워밍업 검증이 필요합니다.

별도의 백그라운드 재검증은 기본적으로 꺼져 있습니다. Token Guardian, `openai`의 `proactive` 갱신 정책, `tokenGuardian.codexWarmupEnabled`가 필요하며 등록 검증 대기 계정은 제외합니다.

## 네이티브 Codex 복원

Expand Down
13 changes: 5 additions & 8 deletions docs-site/src/content/docs/ru/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,11 @@ v1/base/v2 при делегировании и fallback — в

## Прогрев аккаунтов Codex

Когда аккаунт ChatGPT добавляется в пул аккаунтов Codex, opencodex проверяет его до сохранения
небольшим streaming-запросом в backend Codex Responses. Запрос использует настоящий массив
Responses item'ов (`input: [{ type: "message", ... }]`), ждёт `response.completed` и по умолчанию
использует `gpt-5.4-mini`. Если эта модель отвечает HTTP 400, выполняется повтор с `gpt-5.5`;
структурированные детали upstream-ошибки показываются без раскрытия сырых тел ответа. Фоновая
перепроверка отделена от этого процесса и по умолчанию выключена; она запускается только когда
включён Token Guardian, у `chatgpt` выставлена политика refresh `proactive`, а
`tokenGuardian.codexWarmupEnabled` равен true.
При добавлении или повторной аутентификации аккаунт обычно проверяется до сохранения небольшим запросом, ожидающим `response.completed`. По умолчанию используется `gpt-5.4-mini`, при HTTP 400 — повтор с `gpt-5.5`. Публичные ошибки содержат фиксированные категории без исходного тела ответа.

Если запрос квоты с новым OAuth-токеном подтверждает исчерпание пятичасовой, недельной или месячной квоты, аккаунт сохраняется без вызова модели со статусом **Ожидает проверки**. Перезапуск и обновление токена не включают маршрутизацию. После восстановления квоты обновите её: полные свежие данные с доступной ёмкостью разрешают небольшой проверочный запрос. Только успешное завершение включает аккаунт. Ошибки сохраняют ограничение. Пассивный опрос не отправляет такой запрос. Неизвестная квота при регистрации требует обычной проверки.

Фоновая проверка — отдельная функция, выключенная по умолчанию. Она требует Token Guardian, политики `proactive` провайдера `openai` и `tokenGuardian.codexWarmupEnabled` и пропускает аккаунты, ожидающие проверки регистрации.

## Восстановление нативного Codex

Expand Down
14 changes: 5 additions & 9 deletions docs-site/src/content/docs/tr/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,15 +417,11 @@ Arayüzü](/tr/guides/sub-agent-surface/) sayfasına bakın.

## Codex hesap ısınması

Codex hesap havuzuna bir ChatGPT hesabı eklendiğinde opencodex, Codex Responses
arka ucuna küçük bir akış isteği ile kalıcılıktan önce hesabı doğrular. İstek
gerçek bir Responses öğe dizisi kullanır (`input: [{ type: "message", ... }]`),
`response.completed` bekler ve varsayılan olarak `gpt-5.4-mini` kullanır. Bu
model HTTP 400 döndürürse `gpt-5.5` ile yeniden dener; ham yanıt gövdelerini
açığa çıkarmadan yapılandırılmış yukarı akış hata ayrıntıları ortaya çıkarılır.
Arka plan yeniden doğrulaması ayrıdır ve varsayılan olarak kapalıdır; yalnızca
Token Guardian etkinleştirildiğinde, `chatgpt` yenileme politikası `proactive`
olduğunda ve `tokenGuardian.codexWarmupEnabled` true olduğunda çalışır.
Hesap ekleme veya yeniden kimlik doğrulama, normalde kaydetmeden önce `response.completed` bekleyen küçük bir model isteğiyle doğrulanır. Varsayılan model `gpt-5.4-mini` olup HTTP 400 durumunda `gpt-5.5` denenir. Genel hatalar ham yanıt gövdesi yerine sabit hata kategorilerini içerir.

Yeni OAuth belirteciyle yapılan kota sorgusu 5 saatlik, haftalık veya aylık kotanın tükendiğini doğrularsa hesap model çağrısı olmadan kaydedilir ve **Doğrulama bekleniyor** gösterilir. Yeniden başlatma veya belirteç yenileme yönlendirmeyi açmaz. Kota geri geldiğinde kotaları yenileyin: kullanılabilir kapasite gösteren eksiksiz güncel veri küçük bir doğrulama isteğine izin verir. Yalnızca tamamlanan yanıt hesabı etkinleştirir. Hatalarda kısıtlama korunur. Pasif sorgulama bu isteği göndermez. İlk kayıtta bilinmeyen kota normal doğrulamayı gerektirir.

Arka plan doğrulaması ayrı ve varsayılan olarak kapalıdır. Token Guardian, `openai` için `proactive` yenileme ilkesi ve `tokenGuardian.codexWarmupEnabled` gerektirir; kayıt doğrulaması bekleyen hesapları atlar.

## Yerel Codex'i geri yükleme

Expand Down
11 changes: 5 additions & 6 deletions docs-site/src/content/docs/zh-cn/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,11 @@ fallback 行为,参见 [Sub-agent Surface](/guides/sub-agent-surface/)。

## Codex 账号预热

当把一个 ChatGPT 账号加入 Codex 账号池时,opencodex 会在持久化前向 Codex Responses backend
发送一个小型 streaming 请求来验证它。该请求使用真正的 Responses item 数组
(`input: [{ type: "message", ... }]`),等待 `response.completed`,并默认使用 `gpt-5.4-mini`。
如果该模型返回 HTTP 400,则会改用 `gpt-5.5` 重试;结构化的上游错误详情会被展示给用户,但不会暴露
原始响应正文。后台重新验证是独立功能,默认关闭;只有在启用 Token Guardian、将 `chatgpt` 刷新策略设为
`proactive`,并且 `tokenGuardian.codexWarmupEnabled` 为 true 时才会运行。
添加或重新认证账号时,通常会在保存前发送一个小型模型请求并等待 `response.completed`。默认使用 `gpt-5.4-mini`,HTTP 400 时改用 `gpt-5.5` 重试。公开错误仅包含固定分类,不包含原始响应正文。

如果新 OAuth 凭据的已认证用量查询确认5小时、每周或每月额度耗尽,则不调用模型而直接保存账号,显示**等待验证**。重启或刷新令牌也不会使其可用。额度恢复后刷新额度:只有完整的最新用量显示有余额,才会发送一个小型验证请求;请求完成后账号才可用于路由。查询或验证失败将保留等待状态。普通状态轮询不会发送该请求。初次注册时用量未知仍需常规预热验证。

后台重新验证是独立功能,默认关闭。它要求 Token Guardian、`openai` 的 `proactive` 刷新策略及 `tokenGuardian.codexWarmupEnabled`,并跳过等待注册验证的账号。

## 恢复原生 Codex

Expand Down
11 changes: 5 additions & 6 deletions docs-site/src/content/docs/zh-tw/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,11 @@ ocx service install # 常駐:登入時自動啟動,崩潰後自動重新

## Codex 帳號預熱

向 Codex 帳號池新增 ChatGPT 帳號時,opencodex 會先用一個小型 streaming 請求向 Codex Responses
backend 驗證,成功後才持久化。請求使用真正的 Responses item 陣列
(`input: [{ type: "message", ... }]`),等待 `response.completed`,預設模型為 `gpt-5.4-mini`。若該
模型回傳 HTTP 400,則改用 `gpt-5.5` 重試;結構化上游錯誤細節會呈現給使用者,但不暴露原始 response
body。背景重新驗證是獨立功能,預設關閉;只有啟用 Token Guardian、將 `chatgpt` refresh policy 設為
`proactive`,並把 `tokenGuardian.codexWarmupEnabled` 設為 true 時才會執行。
新增或重新驗證帳號時,通常會在儲存前傳送小型模型請求並等待 `response.completed`。預設使用 `gpt-5.4-mini`,HTTP 400 時改用 `gpt-5.5` 重試。公開錯誤僅包含固定分類,不包含原始回應本文。

若新 OAuth 憑證的已驗證用量查詢確認5小時、每週或每月額度耗盡,則不呼叫模型而直接儲存帳號,顯示**等待驗證**。重新啟動或更新權杖也不會使其可用。額度恢復後重新整理額度:只有完整的最新用量顯示有餘額,才會傳送小型驗證請求;請求完成後帳號才可用於路由。查詢或驗證失敗將保留等待狀態。一般狀態輪詢不會傳送該請求。首次註冊時用量未知仍需一般預熱驗證。

背景重新驗證是獨立功能,預設關閉。它需要 Token Guardian、`openai` 的 `proactive` 更新政策及 `tokenGuardian.codexWarmupEnabled`,並略過等待註冊驗證的帳號。

## 恢復原生 Codex

Expand Down
5 changes: 3 additions & 2 deletions gui/src/components/codex-account-pool-cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function CodexAccountPoolCards({
const healthStatus = a.health?.status;
const showReauth = Boolean(a.needsReauth) || oauthHealthShowsReauth(healthStatus);
const inCooldown = oauthHealthIsCooldown(healthStatus);
const validationPending = a.health?.reason === "validation_pending";
const healthLabel = formatOAuthHealthLabel(t, a.health);
const healthSummary = formatOAuthHealthSummary(t, "codex", a.id, a.health);
return (
Expand All @@ -101,13 +102,13 @@ export function CodexAccountPoolCards({
<span className={oauthHealthBadgeClass(healthStatus)}>{healthLabel}</span>
)}
{showReauth && !healthLabel && <span className="badge badge-amber">{t("codexAuth.needsReauth")}</span>}
{isNext(a) && !showReauth && !inCooldown && (
{isNext(a) && !showReauth && !inCooldown && !validationPending && (
<span className="badge badge-primary">
{t(accountModeState === "direct" ? "codexAuth.poolPrepared" : "codexAuth.nextSession")}
</span>
)}
</span>
{!a.paused && (!isNext(a) || pinnedId !== a.id) && !showReauth && !inCooldown && (
{!a.paused && (!isNext(a) || pinnedId !== a.id) && !showReauth && !inCooldown && !validationPending && (
<button type="button" className="btn btn-ghost btn-sm codex-account-switch" onClick={() => onSwitch(a)}>
{switchActionLabel}
</button>
Expand Down
Loading
Loading