Skip to content
Closed
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions docs-site/src/content/docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,12 @@ full model slug sent upstream. ClinePass quota is shared by the account across r
weekly, and monthly limits. A 2026-08-13 live probe verified that every static ClinePass model
accepts `low`, `medium`, `high`, `xhigh`, and `max` at the gateway input boundary. opencodex
preserves those requested tiers; any backend-specific normalization remains ClinePass's responsibility.
Cline documents the Chat Completions route but not an OpenAI-compatible `GET /models` route, so
opencodex uses the maintained subscription catalog instead of sending an unsupported discovery probe.

**MiMo Free** also uses a maintained static catalog. Its anonymous JWT-backed chat endpoint has no
model-list contract; `mimo-auto` remains available without an API key and opencodex does not append
an invalid `/models` probe to the chat URL.

**Cline** is the same API key and endpoint on pay-as-you-go usage billing across 100+ models
(OpenRouter-style ids like `anthropic/claude-sonnet-4-6`). Cline's promotional free models are only
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ the browser or password manager's decision.
| **Add provider** | Search registry-backed presets for account login, API-key services, local servers, or a custom endpoint. |
| **Codex Auth** | Add ChatGPT/Codex pool accounts, select the next-session account, refresh 5h / weekly / 30d quotas, enable or disable quota auto-switch, set its 1–100% threshold, and configure transient-failure failover. |
| **Subagents** | Feature up to five bare native or namespaced routed models in the `spawn_agent` override list. |
| **Models** | Toggle native GPT and routed models, set provider allowlists and context caps, choose v1/base/v2, and configure the v2 thread limit. Configured providers stay visible as zero-model groups when discovery is off or returns no rows. |
| **Models** | Toggle native GPT and routed models, set provider allowlists and context caps, choose v1/base/v2, and configure the v2 thread limit. Configured providers stay visible as zero-model groups when discovery is off or returns no rows. When discovery fails, the badge hover keeps configured fallback models explicit and directs OAuth providers, such as xAI, to reauthenticate with `ocx login <provider>` or dashboard reauthentication; other providers link to endpoint and discovery settings. |
| **Logs** | Auto-refresh recent requests with tokens, requested effort and (when available) effective outbound effort, resolved model, provider, status, request id, duration, and error details. The detail view includes the exact reasoning wire field when the adapter emits one. Filter by opaque conversation/session id (when the client sends one) to total tokens and estimated list-price cost for the currently loaded Logs ring. |
| **Usage / Debug** | Inspect token-usage coverage and trends, or enable opt-in provider transport and usage-extraction diagnostics. |
| **Storage** | Read-only CODEX_HOME disk breakdown (sessions, archives, DBs, attachments). Optional archived cleanup: preview the oldest N%, then quarantine to `CODEX_HOME/.trash` (default) or permanently delete behind an explicit checkbox. **Auto-cleanup policy** is opt-in and **default OFF** (`storageCleanupPolicy.enabled`); configure threshold/target/schedule/mode on the Storage page, or trigger **Run now**. Quarantined entries can be restored from the Storage page (JSONL + threads). Active sessions stay read-only. Cleanup and restore are refused while Codex holds the newest/active `state_*.sqlite` locked. |
Expand Down
17 changes: 12 additions & 5 deletions gui/src/components/provider-workspace/ProviderSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function ProviderSettings({
onRegisterSave?: (save: (() => Promise<boolean>) | null) => void;
}) {
const t = useT();
const initialAuth = String(item.authMode ?? (item.keyOptional ? "local" : "key"));
const initialAuth = String(item.authMode ?? "key");
const [adapter, setAdapter] = useState(item.adapter);
const [baseUrl, setBaseUrl] = useState(item.baseUrl);
const [defaultModel, setDefaultModel] = useState(item.defaultModel ?? "");
Expand All @@ -59,7 +59,7 @@ export default function ProviderSettings({
setAdapter(item.adapter);
setBaseUrl(item.baseUrl);
setDefaultModel(item.defaultModel ?? "");
setAuthMode(String(item.authMode ?? (item.keyOptional ? "local" : "key")));
setAuthMode(String(item.authMode ?? "key"));
setApiKeyTransport(item.apiKeyTransport ?? "x-api-key");
setNote(item.note ?? "");
setAllowPrivateNetwork(item.allowPrivateNetwork ?? false);
Expand Down Expand Up @@ -112,7 +112,7 @@ export default function ProviderSettings({
const dirty = adapter.trim() !== item.adapter
|| baseUrl.trim() !== item.baseUrl
|| defaultModel.trim() !== (item.defaultModel ?? "")
|| authMode !== String(item.authMode ?? (item.keyOptional ? "local" : "key"))
|| authMode !== String(item.authMode ?? "key")
|| (adapter.trim() === "anthropic" && authMode === "key" && apiKeyTransport !== (item.apiKeyTransport ?? "x-api-key"))
|| note.trim() !== (item.note ?? "")
|| allowPrivateNetwork !== (item.allowPrivateNetwork ?? false)
Expand Down Expand Up @@ -335,10 +335,17 @@ export default function ProviderSettings({
<span className="pwi-settings-label">{t("pws.allowPrivateNetwork")}</span>
</label>
<label className="pwi-settings-field" style={{ flexDirection: "row", alignItems: "flex-start", gap: 8 }}>
<input type="checkbox" checked={liveModels} onChange={e => setLiveModels(e.target.checked)} />
<input
type="checkbox"
checked={liveModels}
disabled={item.liveModelDiscoverySupported === false}
onChange={e => setLiveModels(e.target.checked)}
/>
<span>
<span className="pwi-settings-label">{t("pws.liveModels")}</span>
<span className="muted text-label" style={{ display: "block", marginTop: 2 }}>{t("pws.liveModelsDesc")}</span>
<span className="muted text-label" style={{ display: "block", marginTop: 2 }}>
{t(item.liveModelDiscoverySupported === false ? "pws.liveModelsUnsupportedDesc" : "pws.liveModelsDesc")}
</span>
</span>
</label>
{dirty && (
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,9 @@ export const de: Record<TKey, string> = {
"models.discoveryFailedNetwork": "Die Modellerkennung ist an einem Netzwerkfehler gescheitert.",
"models.discoveryFailedProvider": "Der Anbieter meldete einen Fehler bei der Modellerkennung.",
"models.discoveryFailedGeneric": "Die Modellerkennung ist fehlgeschlagen.",
"models.discoveryRecoveryReauth": "Melden Sie sich erneut an, um die Live-Modellerkennung wiederherzustellen. Konfigurierte Modelle bleiben verfügbar.",
"models.discoveryRecoverySettings": "Konfigurierte Modelle bleiben verfügbar. Prüfen Sie den Endpunkt oder deaktivieren Sie die Live-Modellerkennung in den Anbietereinstellungen.",
"models.openProviderLogin": "Anbieter-Anmeldung öffnen",
"models.openProviderSettings": "Anbietereinstellungen öffnen",
"models.loading": "Lädt…",
"models.search": "Modelle suchen…",
Expand Down Expand Up @@ -1642,6 +1645,7 @@ export const de: Record<TKey, string> = {
"pws.allowPrivateNetwork": "Lokales/privates Netzwerk erlauben",
"pws.liveModels": "Modelle beim Anbieter erkennen",
"pws.liveModelsDesc": "Lädt den Live-Modellkatalog des Anbieters. Ausschalten, um nur konfigurierte statische Modelle zu verwenden.",
"pws.liveModelsUnsupportedDesc": "Dieser Anbieter hat keinen Endpunkt für die Modellliste. OpenCodex verwendet seinen gepflegten statischen Katalog.",
"pws.optionalPlaceholder": "Optional",
"pws.providerId": "Anbieter-ID",
"pws.reauth": "Erneute Anmeldung erforderlich",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,9 @@ export const en = {
"models.discoveryFailedNetwork": "Model discovery failed due to a network error.",
"models.discoveryFailedProvider": "The provider reported a model discovery error.",
"models.discoveryFailedGeneric": "Model discovery failed.",
"models.discoveryRecoveryReauth": "Re-login to restore live model discovery. Configured models remain available.",
"models.discoveryRecoverySettings": "Configured models remain available. Check the endpoint or disable live model discovery in provider settings.",
"models.openProviderLogin": "Open provider login",
"models.openProviderSettings": "Open provider settings",
"models.loading": "Loading…",
"models.search": "Search models…",
Expand Down Expand Up @@ -1153,6 +1156,7 @@ export const en = {
"pws.allowPrivateNetwork": "Allow local/private network",
"pws.liveModels": "Discover models from provider",
"pws.liveModelsDesc": "Fetch the provider's live model catalog. Turn this off to use only configured/static models.",
"pws.liveModelsUnsupportedDesc": "This provider has no model-list endpoint. OpenCodex uses its maintained static catalog.",
"pws.optionalPlaceholder": "Optional",
"pws.providerId": "Provider ID",
"pws.reauth": "Needs re-auth",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,9 @@ export const ja: Record<TKey, string> = {
"models.discoveryFailedNetwork": "ネットワークエラーによりモデル検出に失敗しました。",
"models.discoveryFailedProvider": "プロバイダーがモデル検出エラーを報告しました。",
"models.discoveryFailedGeneric": "モデル検出に失敗しました。",
"models.discoveryRecoveryReauth": "再ログインしてライブモデル検出を復元してください。設定済みのモデルは引き続き使用できます。",
"models.discoveryRecoverySettings": "設定済みのモデルは引き続き使用できます。エンドポイントを確認するか、プロバイダー設定でライブモデル検出を無効にしてください。",
"models.openProviderLogin": "プロバイダーログインを開く",
"models.openProviderSettings": "プロバイダー設定を開く",
"models.loading": "読み込み中…",
"models.search": "モデルを検索…",
Expand Down Expand Up @@ -1095,6 +1098,7 @@ export const ja: Record<TKey, string> = {
"pws.allowPrivateNetwork": "ローカル/プライベートネットワークを許可",
"pws.liveModels": "プロバイダーからモデルを検出",
"pws.liveModelsDesc": "プロバイダーのライブモデルカタログを取得します。オフにすると設定済みの静的モデルのみを使用します。",
"pws.liveModelsUnsupportedDesc": "このプロバイダーにはモデル一覧エンドポイントがありません。OpenCodex は管理された静的カタログを使用します。",
"pws.optionalPlaceholder": "任意",
"pws.providerId": "プロバイダー ID",
"pws.reauth": "再認証が必要",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,9 @@ export const ko: Record<TKey, string> = {
"models.discoveryFailedNetwork": "네트워크 오류로 모델 검색에 실패했습니다.",
"models.discoveryFailedProvider": "프로바이더가 모델 검색 오류를 보고했습니다.",
"models.discoveryFailedGeneric": "모델 검색에 실패했습니다.",
"models.discoveryRecoveryReauth": "다시 로그인하여 실시간 모델 검색을 복구하세요. 구성된 모델은 계속 사용할 수 있습니다.",
"models.discoveryRecoverySettings": "구성된 모델은 계속 사용할 수 있습니다. 엔드포인트를 확인하거나 프로바이더 설정에서 실시간 모델 검색을 끄세요.",
"models.openProviderLogin": "프로바이더 로그인 열기",
"models.openProviderSettings": "프로바이더 설정 열기",
"models.loading": "불러오는 중…",
"models.search": "모델 검색…",
Expand Down Expand Up @@ -1669,6 +1672,7 @@ export const ko: Record<TKey, string> = {
"pws.allowPrivateNetwork": "로컬/사설 네트워크 허용",
"pws.liveModels": "프로바이더에서 모델 검색",
"pws.liveModelsDesc": "프로바이더의 실시간 모델 카탈로그를 가져옵니다. 끄면 설정된 정적 모델만 사용합니다.",
"pws.liveModelsUnsupportedDesc": "이 프로바이더에는 모델 목록 엔드포인트가 없습니다. OpenCodex는 관리되는 정적 카탈로그를 사용합니다.",
"pws.optionalPlaceholder": "선택사항",
"pws.providerId": "프로바이더 ID",
"pws.reauth": "재인증 필요",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,9 @@ export const ru: Record<TKey, string> = {
"models.discoveryFailedNetwork": "Обнаружение моделей не удалось из-за сетевой ошибки.",
"models.discoveryFailedProvider": "Провайдер сообщил об ошибке обнаружения моделей.",
"models.discoveryFailedGeneric": "Не удалось обнаружить модели.",
"models.discoveryRecoveryReauth": "Войдите снова, чтобы восстановить обнаружение моделей. Настроенные модели остаются доступными.",
"models.discoveryRecoverySettings": "Настроенные модели остаются доступными. Проверьте конечную точку или отключите обнаружение моделей в настройках провайдера.",
"models.openProviderLogin": "Открыть вход провайдера",
"models.openProviderSettings": "Открыть настройки провайдера",
"models.loading": "Загрузка…",
"models.search": "Поиск моделей…",
Expand Down Expand Up @@ -1137,6 +1140,7 @@ export const ru: Record<TKey, string> = {
"pws.allowPrivateNetwork": "Разрешить локальную/частную сеть",
"pws.liveModels": "Обнаруживать модели провайдера",
"pws.liveModelsDesc": "Загружать актуальный каталог моделей провайдера. Выключите, чтобы использовать только настроенные статические модели.",
"pws.liveModelsUnsupportedDesc": "У этого провайдера нет эндпоинта списка моделей. OpenCodex использует поддерживаемый статический каталог.",
"pws.optionalPlaceholder": "Необязательно",
"pws.providerId": "ID провайдера",
"pws.reauth": "Нужна переавторизация",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,9 @@ export const tr: Record<TKey, string> = {
"models.discoveryFailedNetwork": "Model keşfi ağ hatası nedeniyle başarısız oldu.",
"models.discoveryFailedProvider": "Sağlayıcı bir model keşfi hatası bildirdi.",
"models.discoveryFailedGeneric": "Model keşfi başarısız oldu.",
"models.discoveryRecoveryReauth": "Canlı model keşfini geri yüklemek için yeniden giriş yapın. Yapılandırılmış modeller kullanılabilir durumda kalır.",
"models.discoveryRecoverySettings": "Yapılandırılmış modeller kullanılabilir durumda kalır. Uç noktayı kontrol edin veya sağlayıcı ayarlarında canlı model keşfini kapatın.",
"models.openProviderLogin": "Sağlayıcı girişini aç",
"models.openProviderSettings": "Sağlayıcı ayarlarını aç",
"models.loading": "Yükleniyor…",
"models.search": "Modellerde ara…",
Expand Down Expand Up @@ -1144,6 +1147,7 @@ export const tr: Record<TKey, string> = {
"pws.allowPrivateNetwork": "Yerel/özel ağa izin ver",
"pws.liveModels": "Sağlayıcıdan canlı model keşfet",
"pws.liveModelsDesc": "Sağlayıcının canlı model kataloğunu çekin.",
"pws.liveModelsUnsupportedDesc": "Bu sağlayıcının model listesi uç noktası yoktur. OpenCodex bakımı yapılan statik kataloğunu kullanır.",
"pws.optionalPlaceholder": "İsteğe bağlı",
"pws.providerId": "Sağlayıcı ID",
"pws.reauth": "Yeniden doğrulama gerekiyor",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ export const zhTW: Record<TKey, string> = {
"models.discoveryFailedNetwork": "由於網路錯誤,模型發現失敗。",
"models.discoveryFailedProvider": "供應商報告了模型發現錯誤。",
"models.discoveryFailedGeneric": "模型發現失敗。",
"models.discoveryRecoveryReauth": "請重新登入以恢復即時模型發現。已設定的模型仍可使用。",
"models.discoveryRecoverySettings": "已設定的模型仍可使用。請檢查端點,或在供應商設定中關閉即時模型發現。",
"models.openProviderLogin": "開啟供應商登入",
"models.openProviderSettings": "開啟供應商設定",
"models.loading": "載入中…",
"models.search": "搜尋模型…",
Expand Down Expand Up @@ -934,6 +937,7 @@ export const zhTW: Record<TKey, string> = {
"pws.allowPrivateNetwork": "允許本地/私有網路",
"pws.liveModels": "從供應商發現模型",
"pws.liveModelsDesc": "取得供應商的即時模型目錄。關閉後僅使用已配置的靜態模型。",
"pws.liveModelsUnsupportedDesc": "此供應商沒有模型清單端點。OpenCodex 將使用其維護的靜態目錄。",
"pws.optionalPlaceholder": "可選",
"pws.providerId": "供應商 ID",
"pws.reauth": "需要重新認證",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,9 @@ export const zh: Record<TKey, string> = {
"models.discoveryFailedNetwork": "由于网络错误,模型发现失败。",
"models.discoveryFailedProvider": "提供方报告了模型发现错误。",
"models.discoveryFailedGeneric": "模型发现失败。",
"models.discoveryRecoveryReauth": "请重新登录以恢复实时模型发现。已配置的模型仍可使用。",
"models.discoveryRecoverySettings": "已配置的模型仍可使用。请检查端点,或在提供方设置中关闭实时模型发现。",
"models.openProviderLogin": "打开提供方登录",
"models.openProviderSettings": "打开提供方设置",
"models.loading": "加载中…",
"models.search": "搜索模型…",
Expand Down Expand Up @@ -1662,6 +1665,7 @@ export const zh: Record<TKey, string> = {
"pws.allowPrivateNetwork": "允许本地/私有网络",
"pws.liveModels": "从提供方发现模型",
"pws.liveModelsDesc": "获取提供方的实时模型目录。关闭后仅使用已配置的静态模型。",
"pws.liveModelsUnsupportedDesc": "此提供方没有模型列表端点。OpenCodex 将使用其维护的静态目录。",
"pws.optionalPlaceholder": "可选",
"pws.providerId": "提供商 ID",
"pws.reauth": "需要重新认证",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/models-groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface ConfiguredProviderSummary {

export interface ProviderModelGroup<Row> {
provider: string;
authMode?: string;
rows: Row[];
native: boolean;
liveModels: boolean;
Expand Down Expand Up @@ -56,6 +57,7 @@ export function buildProviderModelGroups<Row extends { provider: string; native?
const configured = providerByName.get(provider);
return {
provider,
authMode: configured?.authMode,
rows: providerRows,
native: providerRows.length > 0 && providerRows.every(row => row.native === true),
liveModels: configured?.liveModels !== false,
Expand Down
Loading
Loading