Repository navigation
Description
Цель
Сделать переключение между OpenAI-совместимыми LLM-провайдерами предсказуемым и удобным для сравнительного тестирования, не привязывая приложение к Yandex AI и не добавляя SDK конкретных поставщиков.
Контекст
Issue #1 и PR #3 добавляют базовый OpenAiCompatibleGateway, работающий с общим подмножеством Chat Completions API. После стабилизации коннектора нужно явно зафиксировать границы совместимости, улучшить диагностику конфигурации и подготовить воспроизводимый способ сравнения нескольких провайдеров.
Входит в задачу
- Описать поддерживаемый контракт провайдера:
POSTна Chat Completions endpoint, поляmodel,messages,temperatureи ответ вchoices[0].message.content - Зафиксировать, что Yandex AI является одной из конфигураций универсального коннектора, а не архитектурным дефолтом самого gateway
- Добавить примеры конфигурации минимум для Yandex AI и одного стандартного Bearer-провайдера с собственными URL и моделью
- Добавить контрактные тесты минимум для двух конфигураций: Yandex-style
Api-Keyс полным URI модели и стандартныйBearerс произвольными URL и именем модели - Проверить, что переключение провайдера выполняется только изменением переменных окружения и перезапуском приложения без пересборки кода
- Явно различать полностью отсутствующую LLM-конфигурацию и частично заполненную некорректную конфигурацию
- Для частично заполненной конфигурации возвращать понятную техническую ошибку при запуске, не выводя ключи и другие секреты
- Использовать нейтральное пользовательское сообщение для временной недоступности настроенного провайдера вместо формулировки «генерация не подключена»
- Определить безопасный способ передавать дополнительные обязательные заголовки для провайдеров, которым недостаточно стандартного
Authorization - Добавить локальный smoke-check или короткий сценарий ручного сравнения моделей, который не запускается в CI и не требует хранения секретов в репозитории
- Не добавлять SDK конкретных провайдеров, streaming, Responses API и автоматический выбор модели в рамках этой задачи
- Перед завершением выполнить
pnpm check
Критерии готовности
- В документации однозначно описано поддерживаемое подмножество OpenAI-compatible API
- Yandex AI и стандартный Bearer-провайдер проходят одинаковый транспортный контракт
- Для переключения модели или провайдера достаточно изменить
.envи перезапустить приложение - Неполная конфигурация диагностируется отдельно от полностью отключённой генерации
- Пользовательское сообщение не утверждает, что генерация не подключена, если настроенный провайдер временно недоступен
- Дополнительные заголовки можно настроить без изменения исходного кода и без утечки секретов
- Smoke-check не зависит от CI и не публикует ключи или пользовательские тексты
Зависимости и параллельность
Задачу выполнять после merge issue #1 и стабилизации PR #3. Она не блокирует текущий MVP и может выполняться параллельно с подготовкой обезличенных сценариев из issue #6.
Остаточный срез — 04.11.2026
На актуальном main транспорт, диагностика, Yandex/Bearer примеры и ручной benchmark уже реализованы. Завершить настройку дополнительных обязательных заголовков через LLM_EXTRA_HEADERS — JSON-объект строковых значений. JSON здесь отражает map HTTP-заголовков внутри env, отдельный файл конфигурации не вводится.
Неизвестные, неполные или некорректные значения конфигурации отклоняются при запуске до provider request с безопасной ошибкой без имён и значений секретных заголовков. Имена/значения проверяются через стандартные HTTP primitives. Дубликаты без учёта регистра запрещены. Нельзя переопределять Authorization, Content-Type, служебные transport headers, x-folder-id или x-data-logging-enabled. Последние два остаются под управлением существующего контракта конфигурации и privacy.
При отсутствии новой переменной поведение сохраняется. Дополнительные заголовки передаются только настроенному endpoint существующим gateway, не попадают в diagnostics, logs и публичные ответы. Production env и модель не изменяются. Приёмка: разрешённый синтетический заголовок доходит до mocked transport, недопустимые значения fail closed, existing config/privacy tests проходят, документация содержит безопасный пример без реальных credentials. TDD, независимое review, make lint-md, pnpm check и git diff --check обязательны. Платные вызовы не нужны.
Отказ от перенаправлений
Независимое review воспроизвело передачу секретного дополнительного заголовка на другой origin через HTTP 307. Provider endpoint должен быть конечным: gateway отклоняет redirect до запроса получателю, без повторной попытки. Это явное уточнение транспортного контракта, сохраняющее действующие HTTP-коды приложения и безопасную диагностику. Приёмка — реальный локальный HTTP regression с синтетическим заголовком: первый сервер получает запрос, второй не получает ничего, генерация завершается контролируемой ошибкой без секрета. Production endpoint не меняется.
Завершено
Реализовано и доставлено в main через PR #327. Diff, тесты и CI PR проверены. Issue закрыта как completed после независимой сверки интеграции.
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Activity
ashikov commentedon Nov 4, 2026
Оставшийся срез реализован в PR #327 (
4fd1359bf271d0a3da1cf9a95ad1ff9899a43147) от актуального main. Дополнительные заголовки задаются через env, валидируются до provider request и не могут заменить служебные/privacy headers. HTTP redirects отклоняются, чтобы секретные заголовки не отправлялись другому получателю. Production-конфигурация не менялась.TDD и regression: конфигурация, повторные JSON-ключи, реальный HTTP redirect между двумя синтетическими серверами.
make lint-md,pnpm check(1079 тестов, lint/typecheck/build),git diff --check— PASS. Независимое review обнаружило Medium по redirect, исправление проверено повторно, открытых findings нет.Платные attempts этой итерации: 0, расходы: 0 ₽. Общий расход марафона остаётся 7 attempts / 6,7688 ₽ по usage из 500 ₽. PR не слит, Task остаётся открытой до merge.