Конфигурация провайдеров
Провайдер сообщает opencodex, где живёт модель, на каком wire-adapter’е она работает и как аутентифицируются запросы.
Выбор моделей при первой регистрации
Заголовок раздела «Выбор моделей при первой регистрации»Новое подключение без OAuth не публикует модели до получения достоверного списка. Если в Models не менее 20 уникальных строк моделей, все переключатели моделей изначально OFF, но сам провайдер остаётся ACTIVE. Подключения, фактически использующие OAuth или вход ChatGPT, сохраняют настройки по умолчанию.
Правило действует только при регистрации нового провайдера. Обновления, повторный вход и смена ключа не сбрасывают существующий выбор. После инициализации включите нужные модели в Models или командами ниже. Отдельная политика появления новых моделей не меняется. Замените <model-id> на ID из списка.
ocx models live --provider openrouterocx models enable '<model-id>'ocx models disable '<model-id>'ocx models provider openrouter onПосле регистрации или входа OAuth в интерфейсе диалог предлагает открыть Models. CLI выводит команды управления моделями; JSON содержит следующие шаги. --no-wait означает ожидание входа, а не завершение. Перед командами для актуального списка моделей запустите прокси через ocx start.
Верхнеуровневые поля, связанные с провайдерами
Заголовок раздела «Верхнеуровневые поля, связанные с провайдерами»| Поле | Тип | По умолчанию | Значение |
|---|---|---|---|
providers |
Record<string, OcxProviderConfig> |
— | Map вида provider name → provider config. |
openaiProviderTierVersion? |
2 |
set by migration | Отмечает, что единая projection OpenAI с учётом режима уже завершена. |
disabledModels? |
string[] |
— | Модели, скрытые из каталога Codex и /v1/models, но не заблокированные для прямых вызовов прокси. Routed-id удаляются из списков. Account-qualified native-id скрывает только строку этого селектора; bare native GPT-id скрывает bare-строку и строки всех селекторов аккаунтов для этой модели. Страница Models показывает только bare native- и routed-строки; чтобы скрыть одну selector-qualified строку, задайте это поле конфигурации напрямую. |
providerContextCaps? |
Record<string, number> |
{} |
Активные лимиты контекста по провайдерам. Обычные окна уменьшаются; нативные модели с поддержкой длинного контекста могут расширять окно только до собственного поддерживаемого предела. |
providerContextCapValues? |
Record<string, number> |
{} |
Последние выбранные лимиты по провайдерам, сохраняемые после отключения. Эти значения сами по себе не включают ограничение. Активное значение имеет приоритет над сохранённым. |
contextCapValue? |
number |
350000 |
Значение по умолчанию при первом включении. При повторном включении восстанавливается выбранное значение провайдера. Изменение глобального значения с setAll: true обновляет только активные лимиты; setAll: true без значения включает лимиты всех настроенных провайдеров с текущим глобальным значением. |
codexAccounts? |
CodexAccount[] |
[] |
Метаданные аккаунтов пула ChatGPT/Codex, которыми управляет Codex Auth. Секреты живут отдельно в codex-accounts.json. |
pausedCodexAccountIds? |
string[] |
[] |
Аккаунты, исключённые из выбора Pool до снятия паузы, включая основной аккаунт __main__, если он поставлен на паузу. |
codexAccountNamespaces? |
Record<string, string> |
— | Необязательное сопоставление произвольного публичного селектора модели с сохранённым аккаунтом Codex. Когда строки picker’а с указанием аккаунта включены, каждый селектор с существующей целью добавляет в model picker Codex отдельные строки <selector>/<native-openai-model>; каждая строка использует только этот аккаунт. Если активен хотя бы один селектор, bare native-строки скрываются в picker, но их id остаются маршрутизируемыми и перечисляются raw /v1/models, если они не отключены явно. |
codexAccountPickerEnabled? |
boolean |
выкл. при пустой map | Управляет созданием account-qualified строк picker’а Codex из подходящих сопоставлений codexAccountNamespaces. true разрешает показывать сопоставленные строки. Если поле не задано при непустой map, функция считается включённой для обратной совместимости; при пустой map она выключена. false скрывает созданные строки и возвращает bare native-строки в picker, не удаляя сопоставления и не отключая точную маршрутизацию <selector>/<native-openai-model>. |
activeCodexAccountId? |
string |
— | Вручную выбранный аккаунт Pool для следующего запроса. Выбор очищает thread affinity; in-flight-запросы сохраняют уже захваченные credential’ы. |
codexAccountPriorities? |
Record<string,number> |
— | Порядок выбора для каждого аккаунта пула Codex: id аккаунта → целое число от -100 до 100, больше — используется раньше, отсутствие означает 0. Это граница порядка, а не пригодности: выбор сужает уже подходящие аккаунты до самого высокого уровня, у которого ещё есть запас квоты, а внутри этого уровня аккаунт выбирает accountPoolStrategy. Уровень пропускается, только когда все его аккаунты превысили autoSwitchThreshold, находятся в cooldown, под soft-avoid, на паузе или требуют повторной аутентификации; неизвестный usage никогда не исчерпывает уровень. Порядок не делает выбираемым непригодный аккаунт и не перепривязывает поток, у которого аккаунт уже есть. Основной аккаунт __main__ участвует на равных — именно так логин Codex Desktop можно оставить на самый конец. Без записей поведение остаётся прежним. Некорректная map игнорируется с предупреждением в консоли (порядок отключается, восстановление config не запускается). Управляется через ocx account priority и страницу Codex Auth. |
autoSwitchThreshold? |
number |
80 |
Порог проактивного переключения по использованию. quota может повторно оценить следующий непривязанный запрос. Привязанная задача по умолчанию (pool.cacheAffinity) сохраняет аккаунт после порога, пока он не исчерпан и ещё может обслуживать запрос, и переносится только на аккаунт со строго меньшим usage и реальным запасом квоты. Установите pool.cacheAffinity: false, чтобы повторно оценивать привязанные задачи на этом пороге. fill-first использует его только как точку исчерпания для непривязанных назначений; обычный round-robin его не использует. Оценка берёт самое горячее из окон 5 часов, недели и 30 дней. 0 отключает только переключение по использованию, но не назначение непривязанных задач и не восстановление после сбоев. |
accountPoolStrategy? |
"quota" | "round-robin" | "fill-first" | "reset-first" |
"quota" |
Стратегия назначения для новых/непривязанных запросов Codex. Запрос непривязан, если у него нет live affinity (parent thread id, quota scope); видимая существующая задача может стать непривязанной после перезапуска прокси или сброса affinity. quota выбирает подходящий аккаунт с наименьшим известным usage, когда активного аккаунта нет, сохраняет подходящий активный аккаунт ниже autoSwitchThreshold, а после порога может перевести непривязанный запрос. Привязанные задачи следуют pool.cacheAffinity (по умолчанию включён): они остаются, пока аккаунт не исчерпан (известный usage 100%) или не может обслуживать запрос, и тогда переносятся только на аккаунт со строго меньшим usage и реальным запасом квоты. Установите флаг в false, чтобы на пороге проактивно перепривязать задачу к подходящему аккаунту с меньшим usage, всё равно только при той же проверке назначения. round-robin равномерно распределяет непривязанные запросы; fill-first назначает их активному аккаунту до cooldown, недоступности или порога исчерпания. reset-first: Среди аккаунтов ниже порога выбирается ближайший сброс 5-часовой или недельной квоты. Привязанные задачи следуют настроенной политике привязки. Независимые квоты моделей упорядочиваются по использованию. Месячный сброс не определяет этот порядок. |
pool.cacheAffinity? |
boolean |
true |
Порядок cache-affinity для привязанных потоков Codex, независимый от pool.kernel. По умолчанию включён; пропуск ключа или true сохраняет привязку, а любое значение кроме false читается как включённое. Живая привязка важнее запаса квоты: quota не переносит поток только потому, что usage пересёк autoSwitchThreshold — перенос живого разговора сбрасывает изолированный по аккаунту prompt cache. Поток всё равно уходит, если аккаунт не может обслуживать запрос — на паузе, непригоден, исключён планом, с недействительными credential’ами, со сменённой generation, с истёкшим TTL, при отказе квоты 429/402 или реально исчерпан (известный usage 100%) — и только на аккаунт со строго меньшим usage и реальным запасом квоты. Аккаунт с неизвестным usage никогда не выбирается как назначение для привязанной задачи. Если все аккаунты выше порога, привязанная задача остаётся: лучшего назначения нет. false возвращает перепривязку по порогу, всё равно только при той же проверке назначения. Affinity меняет порядок, а не закрепляет учётные данные. |
accountPoolStickyLimit? |
number |
1 |
Число назначений новых/непривязанных задач на одном выборе round-robin перед переходом дальше. Счётчик растёт при привязке задачи, а не после успеха upstream. Диапазон 1–100; только при accountPoolStrategy = round-robin. |
upstreamFailoverThreshold? |
number |
3 |
Сколько подряд transient failure допустить, прежде чем новые сессии начнут делать failover. 0 отключает эту логику. Для обычных Responses-запросов и нативных compact-отправок доказанные ошибки доступности DNS/TCP до соединения учитываются на уровне пары «провайдер, хост» и не влияют на здоровье аккаунта, кулдауны аккаунта, привязку потока/сессии, выбор активного аккаунта или маршрутизацию пула, а также не учитываются в этом пороге. |
upstreamHostCircuitThreshold? |
number |
0 |
Опциональный порог circuit breaker для доказанных DNS/TCP-сбоев до соединения в нативных OpenAI forward Responses- и compact-отправках. 0 отключает его; 1–20 открывает 30-секундный cooldown для provider-origin после такого числа завершившихся логических запросов. Пока circuit открыт, до выбора аккаунта и upstream-отправки возвращается 503 с Retry-After; после cooldown допускается один half-open запрос. Таймауты и HTTP-ответы не учитываются, а любой HTTP-ответ закрывает circuit. Применяется только к маршрутизации Codex Pool без закреплённого аккаунта; при codexAccountMode: "direct" и для селекторов с указанием аккаунта схема не активна. |
modelCacheTtlMs? |
number |
300000 |
Окно свежести для кэша /models на уровне провайдера. |
cacheRetention? |
"none" | "short" | "long" |
"short" |
Политика prompt-cache Anthropic: отключено, 5-минутный ephemeral или 1-часовой extended. |
tokenGuardian? |
OcxTokenGuardianConfig |
off | Необязательная политика proactive OAuth refresh и warmup’а аккаунтов Codex. |
Имена селекторов — выбранные пользователем публичные метки; opencodex не придаёт им семантики ролей
аккаунтов. Ключи codexAccountNamespaces имеют длину 1–64 символа. Они должны начинаться и
заканчиваться ASCII-буквой или цифрой; внутри разрешены буквы, цифры, ., _ и -. Зарезервированные
имена объектов JavaScript запрещены. Значение — допустимый id аккаунта пула (кроме внутреннего __main__)
либо "@main" для аккаунта Codex Desktop. Коллизии с provider и зарезервированными openai / combo / policy
проверяются без учёта регистра; namespace-префикс namespaced combo или routing-profile alias не может повторять селектор.
Настроенные id пула и цели других селекторов также нельзя повторно использовать как селектор. Сохраняйте
raw id аккаунтов и email приватными, а селектор используйте как публичное имя. Поведение и приоритет
явного выбора описаны в разделе Конфигурация маршрутизации.
Элемент управления на странице Codex Auth владеет map только тогда, когда в ней явно задано поле
codexAccountPickerEnabled. При включении пустой управляемой map создаются privacy-safe селекторы;
при последующем добавлении аккаунтов map расширяется даже тогда, когда строки picker’а скрыты, и
существующие селекторы не переименовываются. Написанная вручную map без этого поля остаётся ручной и
никогда не расширяется автоматически. При удалении аккаунта его сопоставление сохраняется: exact
route fail closed, пока аккаунт отсутствует, а повторное добавление того же id восстанавливает
прежний публичный селектор вместо создания нового.
Зарезервированные провайдеры OpenAI
Заголовок раздела «Зарезервированные провайдеры OpenAI»openai и openai-apikey — это фиксированные зарезервированные id. openai.codexAccountMode
по умолчанию равен "pool" и выбирает между основным и добавленными аккаунтами; "direct"
использует только текущий login вызывающей стороны / основной login. Уровень API использует только
свой настроенный API-key или key-pool. Используйте bare-model либо openai-apikey/<model>;
cross-route credential fallback не существует. Строки API GPT-5.6 несут метаданные контекста
922,000 / max input 922,000, а виртуальные Pro-id переписываются в базовую wire-модель с
reasoning.mode: "pro".
openaiProviderTierVersion: 2 отмечает текущую single-provider projection. Перед миграцией
поставляемой v1-конфигурации opencodex создаёт config.json.pre-openai-tiers-v2.bak, не
перезаписывая отличающуюся backup-копию, и переписывает известные legacy namespaced-id,
выбранные в selectedModels, в bare-id.
Псевдонимы пространств имён провайдеров
Заголовок раздела «Псевдонимы пространств имён провайдеров»У провайдеров могут быть встроенные сокращения, например agy для google-antigravity. Если имя настроенного провайдера или явный псевдоним занимает такое сокращение без учёта регистра, встроенное сокращение другого провайдера отключается и в каталоге, и при маршрутизации по псевдониму. Например, при настройке провайдера с именем agy модели Google отображаются как google-antigravity/<model>, а agy/<model> выбирает настроенного провайдера. Канонические имена провайдеров по-прежнему требуют точного совпадения регистра; для нераспознанных префиксов сохраняется существующий резервный путь маршрутизации модели.
Записи провайдеров (OcxProviderConfig)
Заголовок раздела «Записи провайдеров (OcxProviderConfig)»| Поле | Тип | Значение |
|---|---|---|
adapter |
string |
Один из openai-chat, openai-responses, anthropic, google, kiro, cursor, ollama-native, azure-openai (или alias azure). |
baseUrl |
string |
Базовый URL API upstream’а. Большинство built-in fixed-endpoint’ов игнорируют несовпадение; collision-safe key-preset’ы сохраняют старый custom destination с тем же именем. |
requestPacing? |
{ enabled, requestsPerMinute?, minIntervalMs?, models? } |
Опциональное клиентское выравнивание начала исходящих запросов, отдельное от учёта использования, биллинга и индикаторов rate limit апстрима. Лимит провайдера действует на все модели, а models сопоставляется с точными ID моделей апстрима и может только увеличить задержку. Ожидание очереди не расходует таймаут заголовков ответа. Поддерживаются HTTP, Responses WebSocket и явные вызовы адаптеров fetchResponse/runTurn. |
responsesPath? |
string |
Relative resource path для key-auth запросов openai-responses. Должен начинаться с / и не может содержать scheme, query или fragment. |
upstreamWebsocket? |
boolean |
Необязательный upstream Responses WebSocket для запросов openai-responses (по умолчанию false). Если upstream поддерживает этот протокол, потоковые POST-запросы используют настроенный путь Responses (по умолчанию /v1/responses), подключаются по WSS через HTTPS и перекодируются обратно в SSE для обычного конвейера. Провайдеры в режиме forward используют {baseUrl}/responses; провайдеры с ключом используют responsesPath или исторический fallback /v1/responses. Для HTTP остаётся SSE; пути, не относящиеся к Responses, и запросы openai-chat остаются на HTTP. |
supportsServiceTier? |
boolean |
Три состояния поддержки service_tier. true: fast mode может подставлять поле, значения вызывающего сохраняются. false: поле удаляется и никогда не подставляется (апстрим, для которого задокументировано отсутствие поддержки, не должен его получать). Не задано: провайдер не классифицирован — значения вызывающего сохраняются без изменений, fast mode не подставляет. Registry классифицирует canonical OpenAI (true), DeepSeek и Volcengine Ark (false); задавайте явно только для custom gateway’ев, реально поддерживающих tier’ы. |
preserveResponsesReasoningContent? |
boolean |
Сохранять plaintext reasoning content в replay’нутых Responses reasoning item’ах вместо очистки (очистка — правило ChatGPT backend’а). Включайте для upstream’ов, чей контракт принимает reasoning replay, например DeepSeek. Proxy-minted ocxr1 envelope’ы удаляются всегда. |
disabled? |
boolean |
Сохранить провайдера на диске, но исключить его из routing’а и из model/catalog-listing’ов. |
apiKey? |
string |
API-key либо ссылка ${ENV_VAR} / $ENV_VAR, разрешаемая при каждом запросе. |
apiKeyTransport? |
"x-api-key" | "bearer" |
Header-style для ключа Anthropic. По умолчанию нативный x-api-key; допустим только для key-auth-провайдеров anthropic. |
apiKeyPool? |
ApiKeyPoolEntry[] |
Пул из нескольких ключей. apiKey зеркалит активную запись; каждый элемент содержит id, key, необязательный label и необязательное числовое addedAt. |
defaultModel? |
string |
Модель, используемая когда этот провайдер выбран без явной модели. |
models? |
string[] |
Начальный список моделей или список для резервного режима. При liveModels: false за непустым models следует retainModels; если models пуст или отсутствует, сначала берётся настроенный defaultModel, затем retainModels. Для каждого ID сохраняется только первое вхождение. |
liveModels? |
boolean |
Получать live-каталог на start/sync (по умолчанию true). Custom-провайдеры используют ${baseUrl}/models; built-in могут использовать registry URL и дополнительно фильтровать результат. |
selectedModels? |
string[] |
Allowlist каталога после discovery. Непустой список показывает только эти id; пустой или отсутствующий показывает всё, что было обнаружено. |
modelDisplayNames? |
Record<string, string> |
Постоянные display-only имена с точным нативным id модели этого провайдера в качестве ключа. Ключи чувствительны к регистру. Имена имеют приоритет над metadata каталога провайдера и не меняют аутентификацию, adapter, routing, billing или upstream-запросы. Карта содержит не более 2 000 записей, как и discovery. |
contextWindow? |
number |
Значение контекста для всего провайдера, применяемое когда upstream не отдаёт metadata; при наличии metadata работает как cap и сохраняет более маленькое live-значение. Панель Models настраивает его отдельно от providerContextCaps. |
modelContextWindows? |
Record<string, number> |
Значения и cap’ы контекста по отдельным моделям. Перекрывают contextWindow: если окно неизвестно, берётся заданное значение, а более маленькая live-metadata остаётся авторитетной. |
modelInputModalities? |
Record<string, string[]> |
Подсказки modality по модели, например ["text"] или ["text", "image"]. |
modelMaxInputTokens? |
Record<string, number> |
Положительные лимиты max input по моделям, используемые для подсказок auto-compaction в каталоге. |
modelAutoCompactTokenLimits? |
Record<string, number> |
Мягкие бюджеты автосжатия по моделям в виде положительных безопасных целых чисел. Они могут только уменьшать эффективную границу в 90 % контекста или максимального ввода и не выдаются, если авторитетное окно контекста неизвестно. Для канонического openai ключами могут быть только точные поддерживаемые ID нативных моделей без префиксов провайдера или селектора аккаунта. PATCH провайдера объединяет записи: null для ключа удаляет его, а null для всего поля очищает карту. Такие маркеры null допустимы только в PATCH. |
defaultMaxOutputTokens? |
number |
Provider-wide fallback для openai-chat, когда клиент не передал max_output_tokens. |
modelMaxOutputTokens? |
Record<string, number> |
Положительные fallback-budget’ы openai-chat по моделям; exact/pattern-match имеет приоритет над provider-default. |
modelCosts? |
Record<string, Cost4> |
Отображаемые цены по моделям (USD за 1M токенов), ключ — точный upstream id модели этого провайдера (не идентификатор провайдера и не маршрутизируемая метка provider/model), значение — четыре поля: input, output, cacheRead, cacheWrite (пример: { "deepseek-v4-flash": { "input": 0.14, "output": 0.28, "cacheRead": 0.0028, "cacheWrite": 0 } }). Любой id допустим — кастомный провайдер может указывать на любой OpenAI-совместимый endpoint через адаптер openai-chat, а локальные и внутренние провайдеры работают даже без строки во встроенных каталогах. Пользовательские цены имеют приоритет над встроенными каталогами в оценках ~$ в Logs и Usage; исторические записи пересчитываются по текущему оверлею, поэтому изменение цены может сдвинуть прошлые суммы (порядок: пользователь → каталог jawcode → expected-price overlay → вендорская цена модели); явно заданный пользователем набор нулевых ставок означает известную нулевую оценку; удалите запись модели, чтобы восстановить автоматическую цену. Нулевые цены каталога по-прежнему переходят к следующему источнику. Каждая ставка должна быть неотрицательным конечным числом не более 1 000 000 (USD за 1M токенов); строки вне диапазона отклоняются на управляющей границе и отбрасываются при загрузке. Только оценка для отображения: оверлеи не влияют на маршрутизацию, выбор аккаунта, квоты или биллинг. |
headers? |
Record<string, string> |
Дополнительные upstream-header’ы. Заголовки авторизации, cookie, API-key-header’ы, встроенные переводы строк и невалидные имена отклоняются. |
openRouterRouting? |
OpenRouterProviderRouting |
Предпочтения по умолчанию для OpenRouter (order, only, allowFallbacks); валидно только для канонического OpenRouter с openai-chat. |
modelOpenRouterRouting? |
Record<string, OpenRouterProviderRouting> |
Exact override по model id, которые полностью заменяют provider-wide preference для OpenRouter. |
vercelGatewayRouting? |
VercelGatewayRouting |
Предпочтения по умолчанию для Vercel AI Gateway: order, only и sort ("cost" | "ttft" | "tps"); допустимо только для канонического Vercel AI Gateway с openai-chat. |
authMode? |
"key" | "forward" | "oauth" | "local" |
Режим аутентификации (по умолчанию key). OAuth/subscription credential’ы хранятся вне config.json; local разрешён только для тех провайдеров, где это допускает registry-entry. |
codexAccountMode? |
"pool" | "direct" |
Только для канонического openai; по умолчанию Pool. Direct обходит состояние пула. |
refreshPolicy? |
"proactive" | "lazy-only" | "disabled" |
Переопределение политики Token Guardian для этого OAuth-провайдера. |
reasoningEfforts? |
string[] |
Provider-wide reasoning-label’ы Codex, которые нужно рекламировать и отправлять. |
modelReasoningEfforts? |
Record<string, string[]> |
Label’ы по отдельным моделям. Пустой список скрывает управление effort. |
modelSupportsReasoningSummaries? |
Record<string, boolean> |
Установите false для модели, чтобы перестать рекламировать summary и вырезать поля доставки summary. |
modelReasoningSummaryDelivery? |
Record<string, "sequential" | "sequential_cutoff" | "concurrent" | "concurrent_cutoff"> |
Responses delivery enum по моделям; переписывает уже существующее поле delivery. |
modelAdapters? |
Record<string, string> |
Wire-override по модели для openai-chat или openai-responses в gateway с несколькими wire-форматами. Явные записи имеют приоритет над default’ами registry; preset DeepSeek может выбирать native Responses для deepseek-v4-flash, а GitHub Copilot объявляет Responses-only default’ы для моделей (gpt-5.3-codex, gpt-5.4, gpt-5.4-mini, gpt-5.5, gpt-5.6-luna, gpt-5.6-sol, gpt-5.6-terra, gpt-6-astra, grok-4.5, grok-4.6, mai-code-1.1-flash, mai-code-1-flash-picker), потому что эти модели отклоняют /chat/completions для агентного трафика. Модели без встроенного default’а (например, gpt-5.4-nano) можно включить здесь. Single-wire upstream pin’ы и canonical ChatGPT forward override не принимают. |
| Opt-in xAI Responses (панель) | переключатель | Только для xai: атомарно задаёт или удаляет записи modelAdapters для grok-4.5 и grok-4.6. Одна запись отображается как смешанное состояние до следующего переключения. Остальные override и поведение tier не меняются. |
xaiResponsesXSearch? |
boolean |
По умолчанию отключено. Для назначения xAI Responses декларация x_search, размещённая у провайдера, добавляется только тогда, когда действующий инструмент web_search сохраняется после окончательной нормализации запроса. Существующие декларации не дублируются, селекторы вызывающей стороны tool_choice/allowed_tools никогда не расширяются, и эта настройка не связана с параметрами search.xSearch сайдкара веб-поиска. |
modelPreferHostedTools? |
Record<string,string[]> |
Opt-in для точного model ID в non-forward Responses gateway, который резервирует namespace hosted tool. Сейчас допускается только ["image_generation"]; совпавшая модель должна использовать wire openai-responses и поддерживать этот hosted tool. Прокси удаляет конфликтующие клиентские объявления image_gen и переписывает их selectors, сохраняя caller tool choice. Для виртуальных моделей OpenAI API -pro сначала сопоставляется выбранный публичный ID, а затем в качестве fallback используется ID базовой wire-модели. modelAdapters сначала разрешается по публичному ID, затем по базовому ID; второй результат определяет итоговый wire. Остальные модели сохраняют обычное alias-поведение. |
annotateEmptyToolOutputs? |
boolean |
Заменяет присутствующий, но пустой результат вызова инструмента короткой меткой до его передачи модели, чтобы пустой результат не воспринимался как отсутствующий. Применяется к пустым строкам и массивам частей, содержащим только текст; части с изображениями, файлами и зашифрованными данными никогда не изменяются. Во встроенном реестре по умолчанию имеет значение true для DeepSeek, а для остальных провайдеров не задано. Укажите false, чтобы отключить эту возможность для провайдера: явное значение false сохраняется при последующих изменениях без этого поля. PATCH /api/providers?name=<provider> принимает true, false или null, чтобы удалить переопределение и вернуться к поведению по умолчанию из реестра. |
reasoningEffortMap? |
Record<string, string> |
Provider-wide wire-alias’ы для reasoning-label’ов. Отображение метки на "__omit__" полностью удаляет поле reasoning из восходящего запроса (например, для моделей Ollama, чьи шаблоны требуют пропуска reasoning_effort для глубокого режима). |
modelReasoningEffortMap? |
Record<string, Record<string, string>> |
Wire-alias’ы для reasoning-label’ов по отдельным моделям. Отображение метки на "__omit__" полностью удаляет поле reasoning из восходящего запроса. |
reasoningWireFormat? |
"gateway-object" |
Для OpenAI-совместимых шлюзов, принимающих reasoning: { enabled, effort } вместо reasoning_effort. Пресет ClinePass задаёт это автоматически. |
noReasoningModels? |
string[] |
Модели, отвергающие параметры reasoning/thinking. |
noTemperatureModels? |
string[] |
Модели, отвергающие переданный вызывающей стороной temperature. |
noTopPModels? |
string[] |
Модели, отвергающие переданный вызывающей стороной top_p. |
noPenaltyModels? |
string[] |
Модели, отвергающие penalty presence/frequency. |
noStructuredOutputModels? |
string[] |
Точные идентификаторы моделей, чей endpoint openai-chat отклоняет response_format. Поле опускается только при точном совпадении запрошенной модели; для остальных моделей openai-chat преобразование structured output остаётся включённым. |
noJsonSchemaModels? |
string[] |
Точные идентификаторы моделей, чей endpoint openai-chat отклоняет response_format типа json_schema, но принимает json_object. Такой запрос понижается до json_object, а не отбрасывается, поэтому вызывающая сторона всё равно получает JSON. Если модель есть в обоих списках, побеждает noStructuredOutputModels. Пресеты opencode go, opencode zen и opencode free включают это для своих маршрутов DeepSeek. |
parallelToolCalls? |
boolean |
Переключатель parallel tool call’ов. Для OpenAI Chat по умолчанию включено; не-chat adapter’ы рекламируют это только при явном true. |
responsesItemIdRepair? |
{ message?: string[]; reasoning?: string[]; repairMissingTerminalIds?: boolean; repairInvalidIds?: boolean } |
По умолчанию выключенная downstream SSE-repair для exact placeholder-id, отсутствующих terminal-id и (с repairInvalidIds) message/reasoning id без канонического префикса msg_/rs_. Function-call id никогда не переписываются. Встроенный DeepSeek включает последние два по умолчанию. |
responsesSnapshotRepair? |
boolean |
По умолчанию выключенная клиентская repair для неполных lifecycle snapshot’ов Responses в SSE и JSON. Добавляет отсутствующие status, output и tool metadata, не меняя raw inspection и persistence. |
retryOn429? |
{ enabled?: boolean; attempts?: number; intervalMs?: number; maxIntervalMs?: number; respectRetryAfter?: boolean } |
Только для провайдеров с API-ключом (authMode: "key"). Опциональный повтор при 429 на том же таргете: если retryOn429 отсутствует, функция выключена; наличие объекта включает её, если только enabled: false. При 429: ожидание (Retry-After апстрима или фиксированный интервал) и повтор идентичного запроса на том же ключе до любого фейловера ключей — покрывает основной цикл восстановления текстовых ходов, passthrough-канал Responses, мост изображений/видео, sidecar web-search и терминальные продолжения. Повтор допустим только для HTTP 429, полученных до начала потока; пользовательские транспорты runTurn не входят в цикл HTTP-повторов. attempts — это число повторов на том же ключе после первого 429 (всего отправок = attempts + 1) и единый бюджет на запрос, общий для основного цикла восстановления, терминального продолжения и повторов моста. Исчерпание attempts лишь останавливает дальнейшие повторы на том же ключе; далее применяется обычный фейловер ключей или финальная обработка ошибки в зависимости от доступных таргетов — на passthrough-канале с ключевой аутентификацией фейловера нет, поэтому исчерпанный 429 возвращается как есть. Codex сам никогда не повторяет 429, поэтому это единственная защита для провайдеров с одним ключом. По умолчанию: enabled: true, attempts: 3, intervalMs: 5000, maxIntervalMs: 60000 (любое ожидание ограничено maxIntervalMs, который сам ограничен 600000), respectRetryAfter: true. |
transientRetryOn5xx? |
{ enabled?: boolean; attempts?: number } |
Только для провайдеров openai-chat с аутентификацией по ключу. Провайдер, у которого adapter равен openai-responses, обрабатывается вместо этого сквозным путём Responses, который применяет собственное фиксированное число временных повторов и никогда не читает эту настройку. Опциональный повтор при временных статусах апстрима до начала потока (500, 502, 503, 504, 520, 521, 522): если параметр отсутствует, функция выключена; наличие объекта включает её, если только enabled: false. Покрывает исходный запрос Responses, продолжение терминального предохранителя, нативный /v1/chat/completions, а также повторные запросы при восстановлении после 429 или ошибки учётной записи. attempts — ОБЩЕЕ число разрешённых отправок в апстрим для одного запроса, включая первую (1..10, по умолчанию 3). Это единый бюджет на запрос, общий с восстановлением после сброса соединения, поэтому 3 означает, что до провайдера дойдут не более трёх реальных запросов. Ожидание использует экспоненциальную задержку с фиксированной начальной величиной 400 мс, ограниченную 5 с, и учитывает Retry-After. Параметр не связан с retryOn429, который обрабатывает ограничение частоты запросов; сбои после начала потока никогда не воспроизводятся. |
autoToolChoiceOnlyModels? |
string[] |
Модели, у которых tool_choice принимает только auto или none; forced choice понижается. |
preserveReasoningContentModels? |
string[] |
Модели, которым нужен предыдущий assistant reasoning_content в chat history. |
reasoningDetailsModels? |
string[] |
Модели, чей endpoint возвращает thinking как структурированный массив reasoning_details (MiniMax M-series с reasoning_split); потоковые дельты — кумулятивные снимки, сравниваемые по префиксу, а сохранённый reasoning воспроизводится массивом reasoning_details вместо строки reasoning_content. |
requiresReasoningPlaceholderModels? |
string[] |
Модели, чей upstream отклоняет tool_call-продолжение без reasoning_content (DeepSeek thinking mode); при промахе replay-кэша подставляется минимальный placeholder. По умолчанию наследует preserveReasoningContentModels; [] отключает явно. |
thinkingToggleModels? |
string[] |
Chat-модели, использующие thinking.enabled вместо effort-ladder. |
thinkingBudgetModels? |
string[] |
Chat-модели, использующие целочисленный thinking_budget; effort отображается в долю бюджета. |
noVisionModels? |
string[] |
Text-only-модели, идущие через vision sidecar; при сопоставлении tolerируется тег Ollama вида :size. |
escapeBuiltinToolNames? |
boolean |
Экранировать built-in tool name’ы для Anthropic-compatible gateway’ев и восстанавливать их в возвращаемых call’ах. |
anthropicEofTolerance? |
boolean |
Позволяет Anthropic-совместимому шлюзу завершить поток до message_stop, только если получен видимый текст или полный JSON-объект аргументов инструмента. По умолчанию выключено. |
googleMode? |
"ai-studio" | "vertex" | "cloud-code-assist" |
Режим транспорта/аутентификации Google. По умолчанию ai-studio. |
project? |
string |
Идентификатор проекта Vertex или Antigravity Cloud Code Assist. |
location? |
string |
Локация Vertex; fallback через окружение — GOOGLE_CLOUD_LOCATION. |
mcpServers? |
Record<string, CursorMcpServerConfig> |
Только Cursor: MCP-серверы в режимах stdio или Streamable HTTP. |
desktopExecutor? |
DesktopExecutorConfig |
Только Cursor: команды внешнего computer-use и record-screen. |
unsafeAllowNativeLocalExec? |
boolean |
Legacy boolean Cursor, эквивалентен nativeLocalExec: "on" только если новое поле не задано. |
nativeLocalExec? |
"off" | "codex-sandbox" | "on" |
Политика local-exec для Cursor. off — дефолт; codex-sandbox сейчас ведёт себя fail-closed как off. |
Провайдеры с API-key могут хранить literal key или environment-reference. OAuth-провайдеры
используют credential store, заполняемый через ocx login; поведение subscription-backed launcher’а
Claude Code настраивается через
claudeCode.authMode.
Безопасность исходящих диагностических запросов
Заголовок раздела «Безопасность исходящих диагностических запросов»Тест подключения из дашборда и live discovery моделей используют ограниченный transport только для GET-запросов. Если outbound-proxy не настроен, opencodex один раз разрешает hostname и затем подключается только к этому проверенному адресу. Для HTTPS сохраняются исходные Host, SNI и проверка сертификата; отключить проверку сертификата конфигурация провайдера не может.
Если активны HTTP_PROXY, HTTPS_PROXY или ALL_PROXY, эти операции оставляют встроенный fetch
Bun. Проверки URL и literal-address всё равно выполняются, но итоговый маршрут, DNS-ответ и peer
всё же выбирает прокси, поэтому opencodex не может зафиксировать или проверить этого peer’а. Это
осознанное ограничение безопасности.
Private/local destination требуют allowPrivateNetwork: true и, если активен outbound-proxy,
подходящей записи в NO_PROXY. Loopback добавляется автоматически; каждый LAN-host нужно
перечислять явно, так как CIDR-диапазоны не интерпретируются. Matcher поддерживает точные хосты,
domain suffix, необязательные порты, IPv6 в квадратных скобках и *; например, 192.168.1.50
надо перечислять явно. Metadata- и link-local-address’ы всё равно блокируются. Diagnostic-request’ы
не следуют redirect’ам и в результатах показывают только credential-stripped target. Проверка
redirect’ов для обычных provider-request’ов реализована отдельно и к этому guard не относится.
Для пользователей Clash / Surge / Mihomo предусмотрены два исключения fake-IP DNS, и оба применяются только к DNS-ответам — литеральный адрес в URL по-прежнему отклоняется. Диапазон IANA benchmark 198.18.0.0/15 (включая IPv4-mapped IPv6 записи) принимается, когда к хосту применяется исходящий прокси. Диапазон IPv6 fake-IP по умолчанию в Mihomo fdfe:dcba:9876::/48 принимается при более строгом условии: должна быть задана переменная прокси, соответствующая схеме URL (HTTPS_PROXY для https:, HTTP_PROXY для http:; ALL_PROXY не учитывается), хост не должен совпадать с NO_PROXY, и тогда запрос явно привязывается к этому прокси. Любой другой ULA, соседний префикс или fake-IP ответ вперемешку с реальным приватным ответом по-прежнему требуют allowPrivateNetwork: true. Валидация при сохранении провайдера никогда не применяет IPv6-исключение.
Пул аккаунтов Codex
Заголовок раздела «Пул аккаунтов Codex»Используйте страницу Codex Auth дашборда для добавления аккаунтов пула и обновления квот.
Конфигурация хранит только несекретные метаданные аккаунтов; access- и refresh-токены хранятся в
защищённом хранилище учётных данных аккаунтов Codex. Pool routing разделяет назначение
новых/непривязанных задач, проактивное переключение по использованию и восстановление после сбоев.
Привязанная задача обычно сохраняет affinity. По умолчанию (pool.cacheAffinity) эта перепривязка ждёт, пока
привязанный аккаунт не будет исчерпан или не сможет обслуживать запрос, и тогда только на аккаунт со строго меньшим usage и реальным запасом квоты. Установите pool.cacheAffinity: false, чтобы quota перепривязывала задачу при следующем запросе после превышения порога, всё равно только при той же проверке назначения. Отказ квоты 429/402, пауза, инвалидация credential’ов и истечение TTL по-прежнему снимают привязку сразу; серия временных сбоев (5xx и другие не-квотные ошибки) обслуживает запрос на другом аккаунте, не удаляя живую привязку. Непривязанным может стать и существующая задача
после перезапуска прокси или сброса affinity. Отказ 429/402 до вывода допускает одну попытку
на подходящем альтернативном аккаунте даже при выключенном переключении по использованию.
Контекст разговора сохраняется и воспроизводится, но prompt cache провайдера между аккаунтами
может не переиспользоваться и потребовать прогрева.
Приостановленный аккаунт и его метаданные квоты остаются видимыми, но исключаются из автоматического переключения,
повторов/failover, проб восстановления cooldown и ручной активации. Пауза также очищает карту affinity потоков
этого аккаунта: выполняющиеся запросы сохраняют захваченные учётные данные, но последующие ходы
перемаршрутизируются и не могут повторно использовать приостановленный аккаунт. Состояние сохраняется после перезапуска;
если приостановлены все аккаунты, маршрутизация Pool завершается ошибкой, а не выбирает аккаунт скрытно.
Приостановить исчерпанные сначала обновляет только подходящие аккаунты с доступными учётными данными и приостанавливает только те, для которых актуальное окно квоты в этом ответе подтверждено на уровне 100%. Аккаунты без учётных данных, с неизвестной квотой или неудачным обновлением не меняются.
При 401/403 локальная для процесса привязка к аккаунту сбрасывается и требуется повторная аутентификация.
При 429 учитывается Retry-After, для аккаунта запускается cooldown, привязка сбрасывается,
после чего запрос может перейти на другой подходящий аккаунт Pool. Эти переходы восстановления
остаются активными при autoSwitchThreshold: 0; значение 0 отключает только проактивное переключение по использованию.
Стратегии назначения и проактивного переключения: quota выбирает подходящий аккаунт с наименьшим usage, когда активного аккаунта нет, сохраняет подходящий активный аккаунт ниже autoSwitchThreshold, а после порога может перевести непривязанный запрос. Привязанные задачи по умолчанию держат cache affinity и остаются, пока аккаунт не исчерпан (известный usage 100%) или не может обслуживать запрос; перенос тогда требует реального запаса квоты и строго меньшего usage на назначении. Установите pool.cacheAffinity: false, чтобы следующий запрос привязанной задачи мог уйти на пороге, всё равно только на подходящий аккаунт с меньшим usage и реальным запасом квоты. round-robin равномерно распределяет непривязанные запросы, а порог не
меняет обычную ротацию. accountPoolStickyLimit (по умолчанию 1, 1–100) считает назначения/bind,
а не успешные ответы. fill-first назначает непривязанные запросы активному аккаунту до cooldown,
reauth или порога исчерпания; здоровые привязанные задачи сохраняют affinity. Эти стратегии не
защищают от enforcement провайдера.
anthropicAccountPool (experimental)
Заголовок раздела «anthropicAccountPool (experimental)»Этот opt-in объединяет несколько Anthropic OAuth-аккаунтов, уже сохранённых в auth.json. По
умолчанию функция выключена и не считается battle-tested. Аккаунты внутри одной организации могут
делить общую quota, а автоматическая ротация может вызвать ограничения со стороны провайдера.
| Ключ | Тип | По умолчанию | Описание |
|---|---|---|---|
anthropicAccountPool.enabled? |
boolean |
false |
Включить закрепление сессии и выбор новой сессии по использованию. Переключение при 429 здесь не управляется: оно работает, как только сохранено два и более пригодных аккаунта, как и у любого другого провайдера с несколькими учётными данными, и не отключается. |
anthropicAccountPool.autoSwitchThreshold? |
number |
80 |
Для новых сессий выбирать аккаунт с наименьшим известным cached usage в настроенном окне, если активный аккаунт достиг порога. 0 отключает выбор по quota. |
anthropicAccountPool.strategy? |
"quota" | "round-robin" | "fill-first" |
"quota" |
Стратегия для новых сессий; quota ранжирует аккаунты по окну, заданному в quotaWindow (по умолчанию это 5-hour bar’ы), а fill-first в этом же окне оценивает свой порог исчерпания. |
anthropicAccountPool.quotaWindow? |
"five-hour" | "weekly" | "max-utilization" |
"five-hour" |
Кешированная полоса использования, сообщённая провайдером и применяемая при выборе по использованию. five-hour сохраняет прежнее поведение. weekly использует недельный bar и пропускает аккаунты с исчерпанным 5-hour bar, пока остаётся другой доступный аккаунт, но возвращается к ним, если других нет. max-utilization использует наибольшее известное значение, поэтому до появления недельных данных может использовать 5-hour usage; если неизвестны оба значения, аккаунт следует порядку unknown usage. Известное использование ранжируется раньше unknown, но если у всех доступных аккаунтов оно неизвестно, выбирается аккаунт в доступном порядке. После описанного сравнения по меньшему значению 5-hour usage полное равенство также сохраняет этот порядок. Здоровая сессия с affinity не перебалансируется заранее. При назначении новой сессии и восстановлении маршрутизации после допустимой замены при 429 quota напрямую ранжирует доступных кандидатов по этому окну, fill-first идёт в стабильном порядке с учётом порога и правил исчерпания этого окна, а round-robin игнорирует настройку. Cooldown, лимиты failover и допустимость повторной аутентификации остаются отдельным локальным состоянием. Недельные bar’ы аккаунтов известны только после опроса на странице Providers в dashboard. |
anthropicAccountPool.stickyLimit? |
number |
1 |
Сколько успешных bind’ов новых сессий удерживать на одном выборе round-robin. Диапазон 1–100. |
Если функция включена, 429 записывает ограниченный cooldown из Retry-After или из default
backoff и может переключить аккаунт уже внутри текущего запроса. Affinity локальна для процесса и
ограничена по размеру. Credential 401/403 помечает аккаунт как нуждающийся в переавторизации.
Если все eligible-аккаунты в cooldown, клиент получает 429 с Retry-After, если он известен,
а не authentication error.
Формы управляемых записей
Заголовок раздела «Формы управляемых записей»В apiKeys[] записи содержат id, name, сгенерированный key и ISO-строки createdAt.
Элементы codexAccounts[] требуют id, email и isMain, а также могут нести plan,
chatgptAccountId и privacy-safe logLabel. Обычно этими записями управляет дашборд.
tokenGuardian (OcxTokenGuardianConfig)
Заголовок раздела «tokenGuardian (OcxTokenGuardianConfig)»| Поле | Тип | По умолчанию | Значение |
|---|---|---|---|
enabled? |
boolean |
false |
Глобальный переключатель proactive refresh. |
tickSeconds? |
number |
21600 |
Интервал sweep’а (6 часов, минимум 60 секунд). |
jitterSeconds? |
number |
300 |
Случайная задержка перед sweep’ом. |
concurrency? |
number |
3 |
Максимум одновременных refresh’ей. |
leadSeconds? |
number |
900 |
Дополнительное опережение refresh’а сверх одного tick’а. |
failureBackoffBaseSeconds? |
number |
300 |
Начальный backoff после transient-сбоя. |
failureBackoffMaxSeconds? |
number |
3600 |
Верхний предел backoff’а и задержки после permanent-failure. |
codexWarmupEnabled? |
boolean |
false |
Включить synthetic validation для аккаунтов пула Codex. |
codexWarmupMaxAgeSeconds? |
number |
691200 |
Повторно валидировать аккаунт через 8 дней. |
codexWarmupModel? |
string |
gpt-5.6-luna |
Нативная модель, используемая для необязательного warmup’а. |
Фиксированные endpoint’ы провайдеров
Заголовок раздела «Фиксированные endpoint’ы провайдеров»Routing сначала определяет endpoint провайдера, а уже потом adapter. Для большинства built-in
registry-endpoint имеет приоритет над настроенным baseUrl. Есть четыре типа записей, которые
сохраняют именно настроенный URL:
- провайдеры, где override разрешён:
ollama,vllm,lm-studio,litellm,qwen-cloudиalibaba-token-plan-intl; - registry template’ы, заполняемые пользователем, например
azure-openaiиcloudflare-ai-gateway; - promoted fixed API-key preset’ы, которые сохраняют старый custom destination с тем же именем; и
- провайдеры, отсутствующие в registry.
Дальше adapter может ещё раз скорректировать получившийся URL. Например, Kiro следует за
API-регионом импортированного credential’а и использует канонический runtime.{region}.kiro.dev.
См. Adapters.
Когда routing выбрасывает baseUrl, opencodex пишет в лог registry-endpoint и лишь origin из
конфига; сам настроенный путь может содержать credential. Уберите неиспользуемый URL или
выберите provider-entry, соответствующий нужному региону. alibaba-token-plan закреплён за
Beijing, а alibaba-token-plan-intl обслуживает международные endpoint’ы.
Если у вас сломан gateway openai-responses, repair нужно задавать прямо на объекте провайдера:
{ "providers": { "custom-gateway": { "adapter": "openai-responses", "baseUrl": "https://gateway.example/v1", "apiKey": "${GATEWAY_KEY}", "responsesItemIdRepair": { "reasoning": ["rs_0"], "message": ["msg_0"], "repairMissingTerminalIds": true } } }}Списки placeholder’ов сравниваются по exact-match. Для обычных/stateful Responses-провайдеров это поле оставляйте unset, чтобы passthrough оставался byte-for-byte идентичным.
Провайдер Cursor (adapter: "cursor")
Заголовок раздела «Провайдер Cursor (adapter: "cursor")»Bridge Cursor экспериментальный. После ocx login cursor добавьте или отредактируйте
providers.cursor. Optimization ladder Cursor Router раскрывается как отдельные id для Codex,
потому что picker не умеет показывать специфичные для Cursor model-parameter’ы:
| Модель Codex | Режим Cursor Router |
|---|---|
cursor/auto |
Team/account default |
cursor/auto-cost |
Cost |
cursor/auto-balance |
Balance |
cursor/auto-intelligence |
Intelligence |
Явные варианты отправляют модель Cursor default с её параметром optimization, сохраняя выбор
на каждом запросе. Они остаются доступны даже если live-discovery не вернул default.
Server-driven local tool’ы Cursor по умолчанию выключены. Codex продолжает использовать собственные
инструменты, такие как apply_patch и exec_command, со своей же approval/sandbox policy:
"off"(по умолчанию) отвергает нативное выполнениеread,write,delete,ls,grep,shellиfetchсо стороны Cursor."on"включает trusted local execution и обходит approval/sandbox semantics Codex."codex-sandbox"сохранён ради совместимости, но закрывается с ошибкой так же, как"off"; на prose запроса нельзя полагаться как на достоверную sandbox-attestation.
{ "providers": { "cursor": { "adapter": "cursor", "baseUrl": "https://api2.cursor.sh", "authMode": "oauth", "defaultModel": "auto", "nativeLocalExec": "off" } }}Задавайте это поле именно в providers.cursor, а не на верхнем уровне. В дашборде откройте
Providers → Cursor → Edit JSON, сохраните и затем перезапустите. Legacy-поле
unsafeAllowNativeLocalExec: true эквивалентно nativeLocalExec: "on" только если поле
nativeLocalExec не задано. MCP, screen recording и computer use управляются отдельно через
mcpServers и desktopExecutor.
Каждый mcpServers.<name> принимает либо command (stdio), либо url (Streamable HTTP). Для
stdio также допустимы args, env и cwd; для HTTP — headers. Оба типа поддерживают
enabled (по умолчанию true) и toolPrefix. desktopExecutor принимает
computerUseCommand, recordScreenCommand, cwd, env и timeoutMs (по умолчанию 30000).
Команды запускаются через sh -c, читают один JSON-запрос из stdin и обязаны записать один
JSON-результат в stdout.
Маршрутизация провайдера OpenRouter
Заголовок раздела «Маршрутизация провайдера OpenRouter»OpenRouter может обслуживать одну и ту же модель через нескольких inference-провайдеров.
openRouterRouting удерживает запросы на предпочитаемых провайдерах; modelOpenRouterRouting
полностью заменяет его для exact model-id. Это особенно полезно для prompt-cache affinity,
потому что support, retention, hit-rate и цена кэша зависят от inference-провайдера.
Имена провайдеров — это slug’и OpenRouter. allowFallbacks: false означает fail-closed;
true позволяет использовать другого подходящего провайдера после упорядоченного списка. Поле
only всегда трактуется как allowlist.
{ "providers": { "openrouter": { "adapter": "openai-chat", "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "${OPENROUTER_API_KEY}", "openRouterRouting": { "order": ["deepseek"], "allowFallbacks": false }, "modelOpenRouterRouting": { "anthropic/claude-sonnet-5": { "only": ["anthropic"], "allowFallbacks": false } } } }}Ключи моделей здесь должны быть exact native OpenRouter id, без внешнего префикса провайдера
opencodex. При выборе openrouter/anthropic-claude-sonnet-5 система сначала восстанавливает
native-id anthropic/claude-sonnet-5, а уже затем применяет model rule.
Маршрутизация провайдеров Vercel AI Gateway
Заголовок раздела «Маршрутизация провайдеров Vercel AI Gateway»Vercel AI Gateway может маршрутизировать одну модель между несколькими нижележащими
inference-провайдерами. vercelGatewayRouting задаёт предпочтения для всего провайдера, а
modelVercelGatewayRouting полностью заменяет их для точных идентификаторов моделей. Если обе
настройки отсутствуют, resolveVercelGatewayRouting() возвращает undefined, поэтому построители
Chat-запросов не добавляют поле provider, а Vercel AI Gateway сохраняет стандартное динамическое
поведение маршрутизации.
order: slug’и upstream-провайдеров Vercel AI Gateway в порядке приоритета.only: явный allowlist допустимых upstream-провайдеров Vercel AI Gateway.sort: автоматическая сортировка допустимых провайдеров по"cost"(минимальная стоимость),"ttft"(время до первого токена) или"tps"(токенов в секунду).
{ "providers": { "vercel-ai-gateway": { "adapter": "openai-chat", "baseUrl": "https://ai-gateway.vercel.sh/v1", "apiKey": "${VERCEL_AI_GATEWAY_KEY}", "vercelGatewayRouting": { "sort": "ttft" }, "modelVercelGatewayRouting": { "zai/glm-5.2": { "only": ["novita", "deepinfra"], "order": ["novita", "deepinfra"] } } } }}Ключи моделей — это публичные селекторы моделей Vercel без внешнего префикса провайдера OpenCodex.
При выборе vercel-ai-gateway/zai-glm-5.2 перед применением правила модели восстанавливается нативный
идентификатор zai/glm-5.2. То же преобразование применяется к нативному селектору
vercel/<model-id>: в OpenCodex используйте кодированный селектор
vercel-ai-gateway/vercel-<model-id>, а в качестве ключа модели оставьте vercel/<model-id>.
Статические allowlist’ы моделей
Заголовок раздела «Статические allowlist’ы моделей»При liveModels: false, если models пуст или отсутствует, начальный список содержит сначала
настроенный defaultModel, затем retainModels. Дубликаты удаляются с сохранением первого вхождения.
Если явно задан непустой models, за ним следует retainModels, а другой defaultModel автоматически
не добавляется. Его можно явно указать в models или retainModels. Если ни одно из этих полей
не содержит ID, начальный список пуст. Этот порядок не гарантирует итоговый порядок в селекторе.
Правила selectedModels, disabledModels и отключения провайдера продолжают действовать.
authMode: "forward" сохраняет отдельную ветвь и не использует этот статический список
маршрутизируемых моделей. Эти правила не меняют резервное поведение при сбое живого обнаружения.
Live-discovery отвергает ответы размером более 4 MiB или более 2000 сырых model-row до кэширования; built-in preset’ы могут использовать меньшие лимиты и фильтровать список до chat-совместимых строк. Oversized или malformed-результаты откатываются к stale/configured fallback. Валидный результат с нулём подходящих моделей считается авторитетным и не заменяется молча.
Используйте selectedModels, когда discovery должно продолжать работать, но в Codex и /v1/models
должны появляться только избранные id. Дашборд всё равно сохраняет полный обнаруженный список для
дальнейших изменений allowlist’а.
Используйте modelDisplayNames для отображаемых имён. Порядок приоритета: заданное оператором
modelDisplayNames, metadata каталога провайдера, затем обычная подпись provider/model. Ключом
служит точный нативный id модели внутри этого провайдера: для xai/grok-4.6 это grok-4.6.
Имя влияет только на отображение и не меняет точный routing id или upstream model id. Добавляйте
это поле в существующую запись провайдера в config.json, сохраняя все остальные поля. Отправьте
{ "modelId": "grok-4.6", "displayName": "Grok 4.6" } в
PUT /api/providers/:provider/model-display-names, чтобы сохранить имя, или displayName: null,
чтобы сбросить только это имя.
Preview fallback-записи GPT-5.6 используют тот же механизм. Preset OpenAI API-key заранее засевает
base- и Pro-id с context 922000 и max input 922000; OpenRouter заранее засевает
openai/gpt-5.6-sol, openai/gpt-5.6-terra и openai/gpt-5.6-luna с context 922000.
Pool/Direct рекламирует 922000; синхронизированный каталог показывает max, сохраняя при этом
отдельную ступень xhigh.
{ "providers": { "openrouter": { "adapter": "openai-chat", "baseUrl": "https://openrouter.ai/api/v1", "apiKey": "${OPENROUTER_API_KEY}", "liveModels": false, "models": ["deepseek/deepseek-v4-flash", "qwen/qwen3-coder-plus"] } }}Редактор отображаемых имён моделей
Заголовок раздела «Редактор отображаемых имён моделей»На странице Models в дашборде можно задать понятные имена для обнаруженных моделей и сохранить их для дальнейшего использования. Разверните провайдера,
найдите обнаруженную модель и выберите Name. При сохранении понятной подписи диалог оставляет
видимым точный селектор provider/model. Выберите Reset name, чтобы вернуться к metadata
провайдера или обычному селектору, используемому по умолчанию. Name меняет только отображение;
отдельный значок карандаша для alias меняет короткий routing alias и не является редактором
отображаемого имени. Нативные строки OpenAI и строки пользовательских моделей сохраняют
существующие элементы управления.
Если изменение сохранено, но обновление не удалось, диалог отражает сохранённое переопределение и оставляет Retry доступным. Retry повторяет приведение каталога к согласованному состоянию, если сервер сообщил о сбое этого процесса, или перезагружает список, если не удался только запрос списка. Восстановление после сброса сохраняет операцию сброса и не возвращает старое имя. Для запросов действует общий срок в 60 секунд, включающий запись и последующее обновление списка. Тайм-аут не отменяет запись: используйте Retry, чтобы проверить текущее имя перед следующим изменением.
Полный пример
Заголовок раздела «Полный пример»{ "port": 10100, "defaultProvider": "openai", "providers": { "openai": { "adapter": "openai-responses", "baseUrl": "https://chatgpt.com/backend-api/codex", "authMode": "forward" }, "anthropic": { "adapter": "anthropic", "baseUrl": "https://api.anthropic.com", "authMode": "oauth", "defaultModel": "claude-sonnet-4-6" }, "ollama-cloud": { "baseUrl": "https://ollama.com/v1", "apiKey": "${OLLAMA_API_KEY}", "defaultModel": "glm-5.2", "noVisionModels": ["glm-5.2", "gpt-oss", "qwen3-coder", "deepseek-v4-flash"] } }, "subagentModels": ["anthropic/claude-opus-5", "ollama-cloud/glm-5.2"], "disabledModels": [], "websockets": false, "webSearchSidecar": { "maxSearchesPerTurn": 3, "routedModelStallTimeoutMs": 200000, "timeoutMs": 60000 }, "visionSidecar": { "enabled": true }}
