Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions docs-site/src/content/docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,26 @@ Auth page can restore it: absent rows are created from the canonical preset, dis
rows are re-enabled without replacing saved mode or model settings, and noncanonical `openai`
rows are not offered that recovery path.

### Providers overview pool capacity

For Codex login in Pool mode, the Providers overview shows a configured-weight estimate of the
pool's used capacity rather than presenting one arbitrary account as the provider total. The same
row also shows the current effective account's raw quota percentage, so you can distinguish the
pool estimate from the account that a new request would use.

When reset information is available, the overview shows the next reset time and the capacity that
reset is expected to recover as `+N% pool capacity`. **Incomplete coverage** means one or more pool
accounts could not safely contribute to the estimate, for example because their plan or quota is
unknown, their reading is stale, or the account is paused or needs reauthentication.

A **partial window coverage** warning means some included accounts reported one quota window but
not another. The overview keeps those windows separate and marks each affected window incomplete
instead of treating the missing reading as usage for that window.

This estimate is display-only. It does not change account selection, session affinity, automatic
switching, cooldowns, or any other routing decision. Use the [Codex Auth account pool](/guides/web-dashboard/#codex-auth-and-account-pools)
for the individual account state and routing controls.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Shipped v1 configs migrate automatically to marker 2 and one option-aware row. The original config
is retained once at `~/.opencodex/config.json.pre-openai-tiers-v2.bak`; restore it with
`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`.
Expand Down
5 changes: 5 additions & 0 deletions docs-site/src/content/docs/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ catalog entry.

The **Codex Auth** page manages the native ChatGPT/Codex route:

The Providers overview separately summarizes Pool-mode usage as a display-only weighted capacity
estimate, alongside the effective account's raw quota and the next capacity recovery. See
[Providers overview pool capacity](/guides/providers/#providers-overview-pool-capacity) for the
visible fields, incomplete-coverage meaning, and routing boundary.

- Manually choosing an account changes the next new Codex session; an already-bound thread keeps its
current account for that manual switch.
- Thread affinity prevents per-request flapping. With quota auto-switch enabled, a long-running
Expand Down
19 changes: 19 additions & 0 deletions docs-site/src/content/docs/ja/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ max input 922,000 で `*-pro` virtual ID は公開状態を維持し、wire で

組み込み `openai` が欠落または無効な場合、ダッシュボードの Accounts ピッカーと Codex Auth から復元できます。欠落行は正規プリセットから作成され、正規の無効行は保存済みのモードやモデル設定を置き換えずに再有効化され、非正規の `openai` 行にはその復元経路は出ません。

### プロバイダー概要のプール容量

Codex login を Pool モードで使うと、Providers の概要には任意の 1 アカウントではなく、
プール全体の使用済み容量の推定値が表示されます。同じ行には現在の有効アカウントの
生のクォータ使用率も表示されるため、プールの推定値と次のリクエストで使われる
アカウントの状態を区別できます。

リセット情報がある場合は、次のリセット時刻と、その時点で回復するプール容量が表示されます。
**対象範囲が不完全**という警告は、プランやクォータが不明、読み取りが古い、アカウントが
一時停止中、または再認証が必要などの理由で、安全に推定へ含められないアカウントがあることを示します。

**期間別の対象範囲が一部不完全**という警告は、含まれるアカウントの一部が、表示中の
クォータ期間のうち一部だけを報告したことを示します。概要では各期間を分けたまま、影響を受ける
期間を個別に不完全と表示し、欠けた値をその期間の使用量として扱いません。

この推定値は表示専用です。アカウント選択、セッション affinity、自動切り替え、cooldown、
その他のルーティング判断には影響しません。個別アカウントの状態とルーティング設定は
[Codex Auth のアカウントプール](/ja/guides/web-dashboard/#codex-auth-and-account-pools)を参照してください。

出荷版 v1 config は marker 2 の単一オプション行に自動移行されます。オリジナルは
`~/.opencodex/config.json.pre-openai-tiers-v2.bak` に一度保存され、次のコマンドで復元します:
`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`。
Expand Down
18 changes: 18 additions & 0 deletions docs-site/src/content/docs/ko/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@ max input 922,000이며 `*-pro` virtual id는 공개 상태에 유지되고 wire

내장 `openai` 제공자가 없거나 비활성화된 경우 대시보드 Accounts 선택기와 Codex Auth 페이지에서 복구할 수 있습니다. 없는 항목은 정규 프리셋으로 만들고, 비활성화된 정규 항목은 저장된 모드/모델 설정을 바꾸지 않고 다시 켜며, 비정규 `openai` 항목에는 그 복구 경로를 제공하지 않습니다.

### 프로바이더 개요의 풀 용량

Codex 로그인을 Pool 모드로 사용하면 Providers 개요에는 임의의 한 계정이 아니라 풀 전체의
사용 용량 추정치가 표시됩니다. 같은 행에는 현재 유효 계정의 원본 quota 사용률도 표시되므로,
풀 추정치와 다음 요청에서 사용할 계정의 상태를 구분할 수 있습니다.

리셋 정보가 있으면 다음 리셋 시각과 그때 회복되는 풀 용량을 표시합니다. **불완전한 범위**는
요금제나 quota를 알 수 없거나, 측정값이 오래되었거나, 계정이 일시 중지되었거나 재인증이 필요한
등의 이유로 일부 계정을 안전하게 추정치에 포함하지 못했음을 뜻합니다.

**일부 기간의 범위가 불완전함**은 포함된 계정 중 일부가 표시된 quota 기간을 모두 보고하지
않았음을 뜻합니다. 개요는 각 기간을 서로 분리한 채 영향을 받은 기간을 개별적으로 불완전하다고
표시하며, 누락된 값을 해당 기간의 사용량으로 간주하지 않습니다.

이 추정치는 표시 전용입니다. 계정 선택, 세션 affinity, 자동 전환, cooldown 또는 다른 라우팅
판단을 변경하지 않습니다. 개별 계정 상태와 라우팅 제어는
[Codex Auth 계정 풀](/ko/guides/web-dashboard/#codex-auth-and-account-pools)을 참고하세요.

shipped v1 config는 marker 2의 단일 옵션 행으로 자동 이관됩니다. 원본은
`~/.opencodex/config.json.pre-openai-tiers-v2.bak`에 한 번 보존되며 다음 명령으로 복원합니다:
`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`.
Expand Down
21 changes: 21 additions & 0 deletions docs-site/src/content/docs/ru/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ description: Все способы, которыми opencodex аутентиф
канонические записи включаются без замены сохранённого режима и настроек моделей, а неканонические
записи `openai` этот путь восстановления не получают.

### Ёмкость пула в обзоре провайдеров

Для входа Codex в режиме Pool обзор Providers показывает оценку использованной ёмкости всего пула,
а не показатель произвольного аккаунта. В той же строке отображается исходный процент квоты текущего
активного аккаунта, поэтому оценку пула можно отличить от состояния аккаунта, который будет использован
для следующего запроса.

Когда доступны сведения о сбросе, обзор показывает время следующего сброса и ёмкость пула, которая
восстановится в этот момент. **Неполное покрытие** означает, что некоторые аккаунты нельзя безопасно
включить в оценку, например из-за неизвестного плана или квоты, устаревшего показания, приостановки
аккаунта либо необходимости повторной аутентификации.

Предупреждение **о частичном покрытии окон** означает, что некоторые включённые аккаунты сообщили данные
только для части показанных окон квоты. Обзор сохраняет окна раздельными, отмечает каждое затронутое
окно как неполное и не считает отсутствующее значение использованием в этом окне.

Эта оценка предназначена только для отображения. Она не меняет выбор аккаунта, привязку сессии,
автоматическое переключение, cooldown или другие решения маршрутизации. Состояние отдельных аккаунтов
и настройки маршрутизации описаны в разделе
[пула аккаунтов Codex Auth](/ru/guides/web-dashboard/#codex-auth-and-account-pools).

Поставляемые v1-конфигурации автоматически мигрируют на маркер 2 и одну строку с поддержкой опций.
Исходная конфигурация один раз сохраняется в `~/.opencodex/config.json.pre-openai-tiers-v2.bak`;
восстановить её можно командой
Expand Down
16 changes: 16 additions & 0 deletions docs-site/src/content/docs/zh-cn/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ bare `gpt-5.6-sol` 遵循 Providers 页面中的 Pool/Direct 选项,

若内置 `openai` 提供商缺失或已禁用,可在仪表盘 Accounts 选择器或 Codex Auth 页面恢复:缺失行会从规范预设创建,已禁用的规范行会在不替换已保存模式/模型设置的情况下重新启用,非规范的 `openai` 行不会提供该恢复路径。

### 提供商概览中的账户池容量

Codex 登录使用 Pool 模式时,Providers 概览显示整个账户池的已用容量估算,而不是任意一个
账户的数值。同一行还会显示当前有效账户的原始配额使用率,便于区分账户池估算与下一次请求
将使用的账户状态。

如果有重置信息,概览会显示下一次重置时间以及届时恢复的账户池容量。**覆盖不完整**表示某些
账户无法安全计入估算,例如套餐或配额未知、读数过旧、账户已暂停或需要重新认证。

**部分窗口覆盖不完整**表示某些已计入账户只报告了部分显示的配额窗口。概览会保持各窗口相互
独立,逐一标记受影响的窗口,并且不会把缺失值当作该窗口的使用量。

此估算仅用于显示,不会改变账户选择、会话关联、自动切换、cooldown 或任何其他路由决策。
各账户状态和路由控制请参阅
[Codex Auth 账户池](/zh-cn/guides/web-dashboard/#codex-auth-and-account-pools)。

shipped v1 配置自动迁移到 marker 2 的单一选项行。原配置只保留一次到
`~/.opencodex/config.json.pre-openai-tiers-v2.bak`;恢复命令:
`cp ~/.opencodex/config.json.pre-openai-tiers-v2.bak ~/.opencodex/config.json`。
Expand Down
63 changes: 57 additions & 6 deletions gui/src/components/QuotaBars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ import { type AccountQuota, normalizeQuotaForPlan } from "../codex-quota-utils";
/* Helpers are co-located with QuotaBars for overview sorting / stacked layout. */
/* eslint-disable react-refresh/only-export-components */

export type QuotaBarRow = { label: string; limitLabel: string; percent: number; resetAt?: number };
export type QuotaWindowKey = "fiveHour" | "weekly" | "monthly";
export type QuotaBarRow = {
windowKey?: QuotaWindowKey;
customLabel?: string;
label: string;
limitLabel: string;
percent: number;
resetAt?: number;
};

/**
* Window ordering is computed from RAW wire identities BEFORE localization
Expand Down Expand Up @@ -43,6 +51,7 @@ export function buildQuotaRows(quota: AccountQuota | null, plan: string | null |
ranked.push({
rank: 0,
row: {
windowKey: "fiveHour",
label: t("codexAuth.fiveHour"),
limitLabel: t("quota.fiveHourLimit"),
percent: displayQuota.fiveHourPercent,
Expand All @@ -54,6 +63,7 @@ export function buildQuotaRows(quota: AccountQuota | null, plan: string | null |
ranked.push({
rank: 1,
row: {
windowKey: "weekly",
label: t("codexAuth.weekly"),
limitLabel: t("quota.weeklyLimit"),
percent: displayQuota.weeklyPercent,
Expand All @@ -65,6 +75,7 @@ export function buildQuotaRows(quota: AccountQuota | null, plan: string | null |
ranked.push({
rank: 4,
row: {
windowKey: "monthly",
label: t("codexAuth.monthly"),
limitLabel: t("quota.monthlyLimit"),
percent: displayQuota.monthlyPercent,
Expand All @@ -76,7 +87,13 @@ export function buildQuotaRows(quota: AccountQuota | null, plan: string | null |
const localized = localizeCustomQuotaLabel(w.label, t);
ranked.push({
rank: rawCustomWindowRank(w.label),
row: { label: localized, limitLabel: localized, percent: w.percent, resetAt: w.resetAt },
row: {
customLabel: w.label,
label: localized,
limitLabel: localized,
percent: w.percent,
resetAt: w.resetAt,
},
});
}
return ranked.sort((a, b) => a.rank - b.rank).map(entry => entry.row);
Expand Down Expand Up @@ -138,7 +155,17 @@ function barFillStyle(percent: number): CSSProperties {
return { ["--bar-scale" as string]: String(barWidth(percent) / 100) };
}

export default function QuotaBars({ quota, plan, threshold, t, className, layout = "compact", pending = false }: {
export default function QuotaBars({
quota,
plan,
threshold,
t,
className,
layout = "compact",
pending = false,
incompleteWindowKeys,
incompleteCustomWindowLabels,
}: {
quota: AccountQuota | null;
plan?: string | null;
threshold: number;
Expand All @@ -151,6 +178,9 @@ export default function QuotaBars({ quota, plan, threshold, t, className, layout
* bar slot so deferred fill does not shove the page down.
*/
pending?: boolean;
/** Optional overview-only coverage status. Other quota surfaces remain unchanged when omitted. */
incompleteWindowKeys?: ReadonlySet<QuotaWindowKey>;
incompleteCustomWindowLabels?: ReadonlySet<string>;
}) {
const { locale } = useI18n();
const rows = buildQuotaRows(quota, plan, t);
Expand Down Expand Up @@ -201,7 +231,16 @@ export default function QuotaBars({ quota, plan, threshold, t, className, layout
return (
<div className={`quota-stacked${className ? ` ${className}` : ""}`}>
{rows.map(row => (
<StackedQuotaRow key={row.limitLabel} row={row} threshold={threshold} t={t} locale={locale} />
<StackedQuotaRow
key={row.limitLabel}
row={row}
threshold={threshold}
t={t}
locale={locale}
incomplete={row.windowKey
? incompleteWindowKeys?.has(row.windowKey) === true
: row.customLabel !== undefined && incompleteCustomWindowLabels?.has(row.customLabel) === true}
/>
))}
</div>
);
Expand Down Expand Up @@ -254,11 +293,12 @@ function QuotaRow({ label, percent, resetAt, threshold, t, locale }: {
);
}

function StackedQuotaRow({ row, threshold, t, locale }: {
function StackedQuotaRow({ row, threshold, t, locale, incomplete }: {
row: QuotaBarRow;
threshold: number;
t: TFn;
locale: Locale;
incomplete: boolean;
}) {
const exhausted = isQuotaExhausted(row.percent);
const warn = isQuotaWarn(row.percent, threshold);
Expand All @@ -267,7 +307,18 @@ function StackedQuotaRow({ row, threshold, t, locale }: {
return (
<div className={`quota-stacked-row${warn ? " quota-stacked-row--warn" : ""}${exhausted ? " quota-stacked-row--exhausted" : ""}`}>
<div className="quota-stacked-head">
<span className="quota-stacked-limit">{row.limitLabel}</span>
<span className="quota-stacked-limit-group">
<span className="quota-stacked-limit">{row.limitLabel}</span>
{incomplete && (
<span
className="quota-window-partial"
aria-label={t("pws.capacity.windowPartialA11y", { window: row.limitLabel })}
title={t("pws.capacity.windowPartialA11y", { window: row.limitLabel })}
>
{t("pws.capacity.windowPartial")}
</span>
)}
</span>
<span className="quota-stacked-reset muted">{resetText}</span>
</div>
<div className="quota-stacked-bar-row">
Expand Down
Loading
Loading