Перейти к содержимому

Как это работает

Codex общается по протоколу OpenAI Responses API. opencodex принимает POST /v1/responses по HTTP с Server-Sent Events, а также опционально поддерживает WebSocket upgrade на том же пути. Он переводит запрос в сетевой формат вашего провайдера, а ответ — обратно в события Responses, поэтому Codex даже не догадывается, что общается не с OpenAI.

┌──────────────────────────── opencodex ────────────────────────────┐
│ │
Codex ──▶ │ parser ──▶ router ──▶ [vision] ──▶ adapter ──▶ provider │ ──▶ Codex
(/v1/ │ │ │ │ │ │ │ (SSE / WS)
responses)│ OcxParsed provider describe buildRequest parseStream │
│ Request +adapter images + fetch AdapterEvent[] │
│ │ │ │
│ [web-search loop] bridge ─▶ SSE │
└─────────────────────────────────────────────────────────────────────┘

Маршрутизация Codex по нескольким аккаунтам: существующие треды сохраняют тот же аккаунт ChatGPT, а новые сессии могут обновить квоту и выбрать исправный аккаунт с меньшим использованием.

Если выбранный провайдер — это passthrough ChatGPT/Codex, opencodex может выбрать аккаунт из сохранённого пула перед тем, как переслать запрос вышестоящему провайдеру. Правило намеренно разделено на части:

  • Существующие id тредов сохраняют привязку. Тред привязывается к поколению аккаунта (account generation), с которого он начался, поэтому долгая сессия Codex по SSH, в tmux или с подключённого мобильного устройства продолжает использовать один аккаунт и не перераспределяется посреди разговора.
  • Новые сессии могут перераспределяться. Для нового треда opencodex сравнивает известное использование квоты в окнах 5 часов, недели и 30 дней, пропускает аккаунты, требующие повторной аутентификации или находящиеся в кулдауне, и может переключиться на подходящий аккаунт с меньшим использованием, когда активный аккаунт превышает настроенный порог.
  • Квоты и сигналы об ошибках влияют на маршрутизацию. Панель управления может принудительно обновить квоту запросом GET /api/codex-auth/accounts?refresh=1; успешные ответы вышестоящего провайдера сохраняют заголовки квоты, 429 отправляет аккаунт в кулдаун, а 401/403 помечает его как требующий повторной аутентификации.

После чистой установки subagentModels включает gpt-5.5, тройку GPT-5.6 Sol/Terra/Luna и gpt-5.4-mini в селекторе подагентов Codex. Через панель управления можно переупорядочить или заменить до пяти записей нативными или маршрутизируемыми моделями. Для v1-запросов совместной работы необязательные настройки injectionModel и injectionEffort добавляют developer-инструкцию, которая сообщает spawn_agent, какую модель и какой уровень рассуждений использовать; v2-запросы используют нативные мультиагентные инструкции Codex.

  1. Parseresponses/parser.ts проверяет запрос по Zod-схеме (responses/schema.ts) и преобразует его во внутренний OcxParsedRequest: системный промпт, нормализованный список сообщений (текст, изображения, вызовы инструментов, результаты инструментов), определения инструментов, параметры генерации и флаги возможностей, такие как _webSearch (запрошен hosted web_search) и _structuredOutput (задан text.format с JSON-схемой или JSON-объектом). Изображения сохраняются как настоящие части контента — они никогда не встраиваются в текст в виде base64.

  2. Routerouter.ts сопоставляет запрошенный id модели с настроенным провайдером по фиксированному приоритету: явный provider/modeldefaultModel провайдера → встроенные префиксные шаблоны (claude-, gpt-, o1-/o3-/o4-, llama-/mixtral-/gemma-) → models[] провайдера → запасной вариант defaultProvider. См. Маршрутизация моделей.

  3. Authenticate — для провайдера типа oauth opencodex подставляет свежий, автоматически обновляемый access-токен в качестве bearer-ключа, поэтому существующие адаптеры аутентифицируются без изменений. Для аккаунтов пула ChatGPT/Codex codex/auth-context.ts сначала определяет аккаунт, и passthrough-адаптер отказывается продолжать, если нужные учётные данные пула недоступны.

  4. Vision-сайдкар (опционально) — если маршрутизируемая модель указана в provider.noVisionModels, а запрос содержит изображение, opencodex описывает каждое изображение с помощью настроенного vision-сайдкара ChatGPT и заменяет его текстом, чтобы модель без поддержки изображений всё равно могла о нём рассуждать. См. Сайдкары.

  5. Быстрый путь passthrough — если адаптер является passthrough для Responses (openai-responses или azure-openai), opencodex сохраняет тело Responses, применяет точечные правки для маршрутизации и совместимости, а затем ретранслирует ответ провайдера без преобразования через AdapterEvent.

  6. Веб-поисковый сайдкар (опционально) — если Codex включил hosted web_search, но маршрутизируемая модель не от OpenAI, opencodex предоставляет синтетический function-инструмент web_search и запускает модель в небольшом агентном цикле: реальные поиски по умолчанию выполняются через gpt-5.6-luna с использованием вашего входа в ChatGPT, а результаты внедряются обратно как результаты инструментов.

  7. Compact (по запросу) — Codex v1 вызывает POST /v1/responses/compact; v2 добавляет compaction_trigger в ход (turn) Responses. Нативный passthrough передаёт сжатие вышестоящему провайдеру, а маршрутизируемая модель выполняет роль суммаризатора без инструментов и возвращает заменяющую историю в формате, который ожидает Codex.

  8. Adapt — в остальных случаях buildRequest() выбранного адаптера формирует HTTP-запрос к вышестоящему провайдеру (URL, заголовки, тело) в нативном формате провайдера, и opencodex выполняет его через fetch.

  9. BridgeparseStream() адаптера (или parseResponse()) порождает внутренние события AdapterEvent (текст, рассуждения, tool-call start/delta/end, done, error). bridge.ts преобразует этот поток обратно в SSE-события Responses — response.output_text.delta, response.reasoning_summary_text.delta, response.function_call_arguments.delta, response.completed и так далее. Опциональный транспорт WebSocket отправляет те же полезные нагрузки событий текстовыми фреймами.

В Codex протокол Responses API жёстко зашит. Выполняя преобразование на границе протокола, opencodex работает с CLI, App и SDK Codex без изменений, переживает обновления Codex и позволяет переключать провайдеров для каждого запроса, не трогая сам Codex. Преобразование двунаправленное и точно сохраняет стриминг: сводки рассуждений, пространства имён MCP-инструментов, freeform-инструменты (apply_patch) и обнаружение через tool_search — всё корректно проходит в обе стороны. Соответствие событий описано в справочнике по архитектуре.