Сайдкары: веб-поиск и vision
Не все маршрутизируемые модели предоставляют hosted веб-поиск или нативный ввод
изображений. opencodex восполняет эти возможности двумя сайдкарами. Каждый может работать через
провайдера входа ChatGPT (forward) или через сохранённого OAuth-провайдера Anthropic. Ошибки
сайдкара превращаются в ограниченные по размеру результаты инструментов или маркеры изображений, а
не приводят к сбою всего хода.
Сайдкар веб-поиска
Заголовок раздела «Сайдкар веб-поиска»Когда 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. Потоковый ответ и цитаты становятся результатом инструмента. - Повторяет цикл, пока модель не ответит или суммарный бюджет реальных запросов не достигнет
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 своего провайдера, а запрос содержит
изображение, opencodex описывает каждое изображение до основного вызова и заменяет его текстом.
Дашборд и API управления показывают gpt-5.6-luna как текущее значение по умолчанию, а при запуске
явно сохранённое устаревшее значение gpt-5.4-mini мигрирует на Luna. Если поле
visionSidecar.model полностью отсутствует, путь выполнения vision всё же имеет зашитый в код
фолбэк gpt-5.4-mini.
- Изображения могут приходить из сообщений пользователя, разработчика и результатов инструментов,
включая
view_imageиз Codex. - Каждое изображение отправляется в настроенную нативную vision-модель с
reasoning.effort: "low"; полученное описание заменяет часть с изображением на месте. - Описания выполняются с ограниченной параллельностью (по 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:-изображений кэшируются по бэкенду, модели, детализации, байтам изображения и контексту сообщения; изменяемыеhttps:-изображения не кэшируются.
{ "visionSidecar": { "enabled": true, "backend": "anthropic", "model": "claude-sonnet-5", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 }}Модель помечается как текстовая для конкретного провайдера:
{ "providers": { "ollama-cloud": { "adapter": "openai-chat", "baseUrl": "https://ollama.com/v1", "noVisionModels": ["glm-5.2", "gpt-oss", "qwen3-coder", "deepseek-v4-pro"] } }}Управление из дашборда и отключение
Заголовок раздела «Управление из дашборда и отключение»Ключи в файле конфигурации доступны уже сейчас. Чтобы отключить любой из сайдкаров, установите ему
enabled: false в config.json. Поиск и описание изображений через Anthropic OAuth переиспользуют
существующий прецедент OAuth-отпечатка Claude Code, но их стоит обкатать с целевым аккаунтом и
нагрузкой.
Все поля описаны в справочнике по конфигурации.

