Сайдкары: веб-поиск и vision
Не все маршрутизируемые модели предоставляют hosted веб-поиск или нативный ввод
изображений. opencodex восполняет эти возможности двумя сайдкарами. Каждый может работать через
провайдера входа ChatGPT (forward) или через сохранённого OAuth-провайдера Anthropic; веб-поиск
также может использовать сохранённый Grok OAuth через явно выбранный бэкенд xai. Ошибки
сайдкара превращаются в ограниченные по размеру результаты инструментов или маркеры изображений, а
не приводят к сбою всего хода.
Сайдкар веб-поиска
Заголовок раздела «Сайдкар веб-поиска»Когда Codex запрашивает hosted web_search для маршрутизируемой модели вне сквозного режима,
opencodex:
- Убирает hosted-инструмент
web_searchи вместо него предоставляет маршрутизируемой модели синтетический функциональный инструментweb_search(query). Исходные опции hosted-инструмента сохраняются для вызова сайдкара. - Запускает маршрутизируемую модель в небольшом агентном цикле. Когда она вызывает
web_search, opencodex использует выбранный бэкенд сайдкара: OpenAI выполняет hostedweb_searchпо умолчанию сgpt-5.6-luna; Anthropic выполняетweb_search_20250305по умолчанию сclaude-sonnet-5. xAI выполняет hostedweb_searchпо умолчанию сgrok-4.6и добавляетx_searchв тот же запрос, когдаxSearch.enabledравно true. Потоковый ответ и цитаты становятся результатом инструмента. - Повторяет цикл, пока модель не ответит или суммарный бюджет реальных запросов не достигнет
maxSearchesPerTurn(по умолчанию 3), после чего убирает инструмент поиска и принуждает к финальному ответу. Настоящие клиентские инструменты вродеapply_patchили shell завершают ход, чтобы эти вызовы дошли до Codex.
Каждая итерация маршрутизируемой модели запрашивает у вышестоящего провайдера stream: true, но
opencodex полностью буферизует семантические события внутри, прежде чем решить, искать дальше или
вернуть финальный ответ. Заранее получаются только финальные заголовки/статус первой итерации и
ротации ключей по 429. Поэтому синтетические поисковые вызовы и промежуточный вывод никогда не
попадают к клиенту как видимый вывод модели.
Внедряемый результат оборачивается в границу недоверенных данных, ограничивается по длине и
дедуплицируется по URL источника. В ходах со структурированным выводом (json_schema /
json_object) он передаётся компактным JSON, а не прозой. Для текстовых маршрутизируемых моделей
поисковой модели дополнительно поручается описывать релевантные изображения словами и указывать их
исходные URL.
{ "webSearchSidecar": { "enabled": true, "backend": "anthropic", "model": "claude-sonnet-5", "reasoning": "low", "maxSearchesPerTurn": 3, "routedModelStallTimeoutMs": 200000, "timeoutMs": 200000 }}Уровень рассуждений minimal не используется, потому что hosted-бэкенд отклоняет инструменты на
этом уровне. Неудачный поиск возвращается маршрутизируемой модели как ограниченный по размеру
результат с ошибкой, позволяя ей ответить на основе уже имеющегося контекста.
Действуют четыре отдельных таймера. stallTimeoutSec — базовый бюджет простоя событий моста.
connectTimeoutMs (по умолчанию 200000) покрывает только DNS/TCP/TLS и финальные заголовки
ответа. Задаваемый только в файле конфигурации webSearchSidecar.routedModelStallTimeoutMs (по
умолчанию 200000, целое 1..2147483647) ограничивает непрерывное отсутствие сырых байтов ответа
для каждой итерации маршрутизируемой модели и сбрасывается при каждом непустом байте.
webSearchSidecar.timeoutMs отдельно ограничивает один hosted-запрос поиска. Итоговый сторожевой
таймер моста —
max(base stall, connect timeout, routed-model stall, sidecar timeout) + 30 seconds. Простой
маршрутизируемой модели не является общим таймаутом генерации. Сбои до начала SSE возвращают JSON
с кодом, отличным от 2xx; сбои генерации после отправки заголовков ответа доставляются как
SSE-событие response.failed.
Vision-сайдкар
Заголовок раздела «Vision-сайдкар»Когда маршрутизируемая модель указана в noVisionModels своего провайдера — либо для неё в
modelInputModalities явно указана только текстовая модальность — и запрос содержит изображение,
opencodex описывает каждое изображение до основного вызова и заменяет его текстом, если доступен
план vision-сайдкара. Без доступного плана исходное изображение удаляется, а не передаётся текстовому
бэкенду. Каталог моделей объявляет вход изображений для каждой модели, покрытой сайдкаром. Комбо
объявляют вход изображений только если каждый участник принимает изображения нативно или через
сайдкар и параметр комбо imageInput не отключён; поэтому такие клиенты, как приложение Codex,
разрешают вложения вместо их блокировки до запуска сайдкара. Если visionSidecar.model отсутствует или пуст, путь выполнения OpenAI, дашборд и API управления
используют фолбэк gpt-5.4-mini. При запуске явно сохранённое устаревшее значение
gpt-5.4-mini по-прежнему мигрирует на gpt-5.6-luna; миграция применяется только к сохранённому
значению, а не к отсутствующему полю модели.
- Изображения могут приходить из сообщений пользователя, разработчика и результатов инструментов,
включая
view_imageиз Codex. - На пути OpenAI (passthrough с логином ChatGPT) каждое изображение отправляется в настроенную
vision-модель через endpoint Responses с выбранным
reasoning.effort(по умолчаниюlow), и полученное описание заменяет часть с изображением на месте. Путь Anthropic использует endpoint Messages со своим mapping’ом thinking-бюджета и игнорирует эту специфичную для OpenAI настройку. - Для нативных моделей с надёжными метаданными возможностей неподдерживаемый уровень нормализуется к самому высокому поддерживаемому уровню, не превышающему запрошенный; если такого нет, используется самый низкий поддерживаемый уровень. Неизвестные и пользовательские модели без надёжных метаданных остаются без ограничений.
- Описания выполняются с ограниченной параллельностью (по 3 одновременно, порядок входа
сохраняется). Пользовательский контекст, передаваемый описывающей модели, ограничен 800
символами, а каждое внедряемое описание — 2 000 символами. Запрос не отправляет
max_output_tokens, который бэкенд ChatGPT отклоняет. - URL изображений проверяются перед пересылкой: data-URL должны использовать
png/jpeg/jpg/webp/gif, а объём base64-данных ограничен примерно 20 МБ. Принимаются только схемыdata:иhttps:; удалённыеhttps-изображения загружает бэкенд OpenAI, а не прокси. - Сопоставление
noVisionModelsигнорирует суффикс:sizeв стиле Ollama, поэтому записьgpt-ossпокрывает иgpt-oss:120b. - Если описание не удалось, модель получает короткий маркер ошибки обработки. (Если доступного плана сайдкара нет, описание не запускается, а исходное изображение удаляется, как описано выше.)
maxDescriptionsPerTurn(по умолчанию 8) ограничивает число новых описаний за один ход основной модели. Попадания в кэш и дубликаты в рамках того же хода лимит не расходуют. Успешные описанияdata:-изображений кэшируются по бэкенду, модели, детализации, байтам изображения и контексту сообщения; в ключи OpenAI дополнительно входит уровень рассуждений (в ключи Anthropic — нет, поскольку там это поле игнорируется). Изменяемыеhttps:-изображения не кэшируются.
{ "visionSidecar": { "enabled": true, "backend": "openai", "model": "gpt-5.6-luna", "reasoning": "medium", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 }}Модель помечается как текстовая для конкретного провайдера:
{ "providers": { "ollama-cloud": { "baseUrl": "https://ollama.com/v1", "noVisionModels": ["glm-5.2", "gpt-oss", "qwen3-coder", "deepseek-v4-pro"] } }}Управление из дашборда и отключение
Заголовок раздела «Управление из дашборда и отключение»Карточка Vision sidecar на дашборде позволяет включать и выключать сайдкар, задавать
maxDescriptionsPerTurn и timeoutMs, не убирая уже существующие элементы модели, бэкенда и
рассуждения. Выключение не удаляет эти настройки; повторное включение сохраняет прежние
значения модели, бэкенда, reasoning, таймаута и лимита.
PUT /api/sidecar-settings принимает те же поля. Частичное обновление оставляет непереданные ключи
без изменений. timeoutMs использует целочисленные границы рантайма (1–2147483647 мс).
Если удобнее править файл, по-прежнему можно поставить enabled: false в config.json. Поиск и описание изображений через Anthropic OAuth переиспользуют
существующий прецедент OAuth-отпечатка Claude Code, но их стоит обкатать с целевым аккаунтом и
нагрузкой.
Все поля описаны в справочнике по конфигурации.

