# API Reference (Русский) 🌐 **Languages:** 🇺🇸 [English](../../../../reference/API_REFERENCE.md) · 🇪🇹 [am](../../../am/docs/reference/API_REFERENCE.md) · 🇸🇦 [ar](../../../ar/docs/reference/API_REFERENCE.md) · 🇦🇿 [az](../../../az/docs/reference/API_REFERENCE.md) · 🇧🇬 [bg](../../../bg/docs/reference/API_REFERENCE.md) · 🇧🇩 [bn](../../../bn/docs/reference/API_REFERENCE.md) · 🇧🇦 [bs](../../../bs/docs/reference/API_REFERENCE.md) · 🇨🇿 [cs](../../../cs/docs/reference/API_REFERENCE.md) · 🇩🇰 [da](../../../da/docs/reference/API_REFERENCE.md) · 🇩🇪 [de](../../../de/docs/reference/API_REFERENCE.md) · 🇬🇷 [el](../../../el/docs/reference/API_REFERENCE.md) · 🇪🇸 [es](../../../es/docs/reference/API_REFERENCE.md) · 🇪🇪 [et](../../../et/docs/reference/API_REFERENCE.md) · 🇮🇷 [fa](../../../fa/docs/reference/API_REFERENCE.md) · 🇫🇮 [fi](../../../fi/docs/reference/API_REFERENCE.md) · 🇫🇷 [fr](../../../fr/docs/reference/API_REFERENCE.md) · 🇮🇪 [ga](../../../ga/docs/reference/API_REFERENCE.md) · 🇮🇳 [gu](../../../gu/docs/reference/API_REFERENCE.md) · 🇳🇬 [ha](../../../ha/docs/reference/API_REFERENCE.md) · 🇮🇱 [he](../../../he/docs/reference/API_REFERENCE.md) · 🇮🇳 [hi](../../../hi/docs/reference/API_REFERENCE.md) · 🇭🇷 [hr](../../../hr/docs/reference/API_REFERENCE.md) · 🇭🇺 [hu](../../../hu/docs/reference/API_REFERENCE.md) · 🇦🇲 [hy](../../../hy/docs/reference/API_REFERENCE.md) · 🇮🇩 [id](../../../id/docs/reference/API_REFERENCE.md) · 🇳🇬 [ig](../../../ig/docs/reference/API_REFERENCE.md) · 🇮🇹 [it](../../../it/docs/reference/API_REFERENCE.md) · 🇯🇵 [ja](../../../ja/docs/reference/API_REFERENCE.md) · 🇬🇪 [ka](../../../ka/docs/reference/API_REFERENCE.md) · 🇰🇭 [km](../../../km/docs/reference/API_REFERENCE.md) · 🇮🇳 [kn](../../../kn/docs/reference/API_REFERENCE.md) · 🇰🇷 [ko](../../../ko/docs/reference/API_REFERENCE.md) · 🇱🇹 [lt](../../../lt/docs/reference/API_REFERENCE.md) · 🇱🇻 [lv](../../../lv/docs/reference/API_REFERENCE.md) · 🇮🇳 [ml](../../../ml/docs/reference/API_REFERENCE.md) · 🇮🇳 [mr](../../../mr/docs/reference/API_REFERENCE.md) · 🇲🇾 [ms](../../../ms/docs/reference/API_REFERENCE.md) · 🇲🇹 [mt](../../../mt/docs/reference/API_REFERENCE.md) · 🇲🇲 [my](../../../my/docs/reference/API_REFERENCE.md) · 🇳🇵 [ne](../../../ne/docs/reference/API_REFERENCE.md) · 🇳🇱 [nl](../../../nl/docs/reference/API_REFERENCE.md) · 🇳🇴 [no](../../../no/docs/reference/API_REFERENCE.md) · 🇮🇳 [or](../../../or/docs/reference/API_REFERENCE.md) · 🇮🇳 [pa](../../../pa/docs/reference/API_REFERENCE.md) · 🇵🇭 [phi](../../../phi/docs/reference/API_REFERENCE.md) · 🇵🇱 [pl](../../../pl/docs/reference/API_REFERENCE.md) · 🇵🇹 [pt](../../../pt/docs/reference/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/reference/API_REFERENCE.md) · 🇷🇴 [ro](../../../ro/docs/reference/API_REFERENCE.md) · 🇱🇰 [si](../../../si/docs/reference/API_REFERENCE.md) · 🇸🇰 [sk](../../../sk/docs/reference/API_REFERENCE.md) · 🇸🇮 [sl](../../../sl/docs/reference/API_REFERENCE.md) · 🇷🇸 [sr](../../../sr/docs/reference/API_REFERENCE.md) · 🇸🇪 [sv](../../../sv/docs/reference/API_REFERENCE.md) · 🇰🇪 [sw](../../../sw/docs/reference/API_REFERENCE.md) · 🇮🇳 [ta](../../../ta/docs/reference/API_REFERENCE.md) · 🇮🇳 [te](../../../te/docs/reference/API_REFERENCE.md) · 🇹🇭 [th](../../../th/docs/reference/API_REFERENCE.md) · 🇹🇷 [tr](../../../tr/docs/reference/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/reference/API_REFERENCE.md) · 🇵🇰 [ur](../../../ur/docs/reference/API_REFERENCE.md) · 🇺🇿 [uz](../../../uz/docs/reference/API_REFERENCE.md) · 🇻🇳 [vi](../../../vi/docs/reference/API_REFERENCE.md) · 🇳🇬 [yo](../../../yo/docs/reference/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/reference/API_REFERENCE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/reference/API_REFERENCE.md) --- 🌐 **Языки:** 🇺🇸 [English](./API_REFERENCE.md) | 🇪🇹 [አማርኛ](../i18n/am/docs/reference/API_REFERENCE.md) | 🇸🇦 [العربية](../i18n/ar/docs/reference/API_REFERENCE.md) | 🇦🇿 [Azərbaycan dili](../i18n/az/docs/reference/API_REFERENCE.md) | 🇧🇬 [Български](../i18n/bg/docs/reference/API_REFERENCE.md) | 🇧🇩 [বাংলা](../i18n/bn/docs/reference/API_REFERENCE.md) | 🇧🇦 [Bosanski](../i18n/bs/docs/reference/API_REFERENCE.md) | 🇨🇿 [Čeština](../i18n/cs/docs/reference/API_REFERENCE.md) | 🇩🇰 [Dansk](../i18n/da/docs/reference/API_REFERENCE.md) | 🇩🇪 [Deutsch](../i18n/de/docs/reference/API_REFERENCE.md) | 🇬🇷 [Ελληνικά](../i18n/el/docs/reference/API_REFERENCE.md) | 🇪🇸 [Español](../i18n/es/docs/reference/API_REFERENCE.md) | 🇪🇪 [Eesti](../i18n/et/docs/reference/API_REFERENCE.md) | 🇮🇷 [فارسی](../i18n/fa/docs/reference/API_REFERENCE.md) | 🇫🇮 [Suomi](../i18n/fi/docs/reference/API_REFERENCE.md) | 🇫🇷 [Français](../i18n/fr/docs/reference/API_REFERENCE.md) | 🇮🇪 [Gaeilge](../i18n/ga/docs/reference/API_REFERENCE.md) | 🇮🇳 [ગુજરાતી](../i18n/gu/docs/reference/API_REFERENCE.md) | 🇳🇬 [Hausa](../i18n/ha/docs/reference/API_REFERENCE.md) | 🇮🇱 [עברית](../i18n/he/docs/reference/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../i18n/hi/docs/reference/API_REFERENCE.md) | 🇭🇷 [Hrvatski](../i18n/hr/docs/reference/API_REFERENCE.md) | 🇭🇺 [Magyar](../i18n/hu/docs/reference/API_REFERENCE.md) | 🇦🇲 [Հայերեն](../i18n/hy/docs/reference/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../i18n/id/docs/reference/API_REFERENCE.md) | 🇳🇬 [Igbo](../i18n/ig/docs/reference/API_REFERENCE.md) | 🇮🇹 [Italiano](../i18n/it/docs/reference/API_REFERENCE.md) | 🇯🇵 [日本語](../i18n/ja/docs/reference/API_REFERENCE.md) | 🇬🇪 [ქართული](../i18n/ka/docs/reference/API_REFERENCE.md) | 🇰🇭 [ខ្មែរ](../i18n/km/docs/reference/API_REFERENCE.md) | 🇮🇳 [ಕನ್ನಡ](../i18n/kn/docs/reference/API_REFERENCE.md) | 🇰🇷 [한국어](../i18n/ko/docs/reference/API_REFERENCE.md) | 🇱🇹 [Lietuvių](../i18n/lt/docs/reference/API_REFERENCE.md) | 🇱🇻 [Latviešu](../i18n/lv/docs/reference/API_REFERENCE.md) | 🇮🇳 [മലയാളം](../i18n/ml/docs/reference/API_REFERENCE.md) | 🇮🇳 [मराठी](../i18n/mr/docs/reference/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../i18n/ms/docs/reference/API_REFERENCE.md) | 🇲🇹 [Malti](../i18n/mt/docs/reference/API_REFERENCE.md) | 🇲🇲 [မြန်မာ](../i18n/my/docs/reference/API_REFERENCE.md) | 🇳🇵 [नेपाली](../i18n/ne/docs/reference/API_REFERENCE.md) | 🇳🇱 [Nederlands](../i18n/nl/docs/reference/API_REFERENCE.md) | 🇳🇴 [Norsk](../i18n/no/docs/reference/API_REFERENCE.md) | 🇮🇳 [ଓଡ଼ିଆ](../i18n/or/docs/reference/API_REFERENCE.md) | 🇮🇳 [ਪੰਜਾਬੀ](../i18n/pa/docs/reference/API_REFERENCE.md) | 🇵🇭 [Filipino](../i18n/phi/docs/reference/API_REFERENCE.md) | 🇵🇱 [Polski](../i18n/pl/docs/reference/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../i18n/pt/docs/reference/API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../i18n/pt-BR/docs/reference/API_REFERENCE.md) | 🇷🇴 [Română](../i18n/ro/docs/reference/API_REFERENCE.md) | 🇷🇺 [Русский](../i18n/ru/docs/reference/API_REFERENCE.md) | 🇱🇰 [සිංහල](../i18n/si/docs/reference/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../i18n/sk/docs/reference/API_REFERENCE.md) | 🇸🇮 [Slovenščina](../i18n/sl/docs/reference/API_REFERENCE.md) | 🇷🇸 [Српски](../i18n/sr/docs/reference/API_REFERENCE.md) | 🇸🇪 [Svenska](../i18n/sv/docs/reference/API_REFERENCE.md) | 🇰🇪 [Kiswahili](../i18n/sw/docs/reference/API_REFERENCE.md) | 🇮🇳 [தமிழ்](../i18n/ta/docs/reference/API_REFERENCE.md) | 🇮🇳 [తెలుగు](../i18n/te/docs/reference/API_REFERENCE.md) | 🇹🇭 [ไทย](../i18n/th/docs/reference/API_REFERENCE.md) | 🇹🇷 [Türkçe](../i18n/tr/docs/reference/API_REFERENCE.md) | 🇺🇦 [Українська](../i18n/uk-UA/docs/reference/API_REFERENCE.md) | 🇵🇰 [اردو](../i18n/ur/docs/reference/API_REFERENCE.md) | 🇺🇿 [Oʻzbekcha](../i18n/uz/docs/reference/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../i18n/vi/docs/reference/API_REFERENCE.md) | 🇳🇬 [Yorùbá](../i18n/yo/docs/reference/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../i18n/zh-CN/docs/reference/API_REFERENCE.md) | 🇹🇼 [中文 (繁體)](../i18n/zh-TW/docs/reference/API_REFERENCE.md) Основная справочная документация по API OmniRoute. Она охватывает общедоступную поверхность `/v1` и наиболее часто используемые конечные точки управления; исчерпывающими источниками являются машиночитаемый файл [`docs/openapi.yaml`](../openapi.yaml) и дерево маршрутов в `src/app/api/`. Подробное описание протокола, совместимого с OpenAI, и матрицы возможностей провайдеров см. в [`OPENAI_COMPATIBILITY.md`](./OPENAI_COMPATIBILITY.md). --- ## Содержание - [Завершения чата](#chat-completions) - [Эксклюзивные аренды управляемых сеансов](#exclusive-managed-session-leases) - [Векторные представления](#embeddings) - [Генерация изображений](#image-generation) - [OCR документов](#document-ocr) - [Список моделей](#list-models) - [Манифест плагина провайдера](#provider-plugin-manifest) - [Эндпоинты совместимости](#compatibility-endpoints) - [API файлов](#files-api) - [API пакетной обработки](#batches-api) - [API поиска](#search-api) - [Потоковая передача через WebSocket](#websocket-streaming) - [Квоты и сообщения о проблемах](#quotas--issues-reporting) - [Семантический кэш](#semantic-cache) - [Панель управления и администрирование](#dashboard--management) - [Управление комбинациями](#combo-management) - [Вебхуки](#webhooks) - [Зарегистрированные ключи (автоматическое управление)](#registered-keys-auto-management) - [Протокол агентов](#agents-protocol) - [Прокси-серверы управления](#management-proxies) - [Отказоустойчивость (расширенная)](#resilience-extended) - [Навыки](#skills) - [Память](#memory) - [Сервер MCP](#mcp-server) - [Сервер A2A](#a2a-server) - [Облако, оценки и анализ](#cloud-evals--assess) - [Обработка запросов](#request-processing) - [Аутентификация](#authentication) --- ## Завершения чата ```bash POST /v1/chat/completions Authorization: Bearer your-api-key Content-Type: application/json { "model": "cc/claude-opus-4-6", "messages": [ {"role": "user", "content": "Write a function to..."} ], "stream": true } ``` ### Пользовательские заголовки | Заголовок | Направление | Описание | | ------------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-OmniRoute-No-Cache` | Запрос | Установите значение `true`, чтобы обойти кэш | | `x-omniroute-no-memory` | Запрос | Установите значение `true`, чтобы пропустить внедрение памяти и навыков для этого запроса (аналогично отключению кэша; позволяет избежать дополнительных затрат токенов и средств для каждого вызова) | | `X-OmniRoute-Progress` | Запрос | Установите значение `true`, чтобы получать события о ходе выполнения | | `X-Session-Id` | Запрос | Ключ закреплённого сеанса для внешней привязки сеанса | | `x_session_id` | Запрос | Также принимается вариант с символами подчёркивания (прямой HTTP-запрос) | | `X-OmniRoute-Session-Id` | Запрос | Предоставленный вызывающей стороной тег сеанса/диалога (также передаётся в память). Если указан, сохраняется без изменений в `call_logs.session_tag` для учёта затрат по сеансам (#8249) — не создаётся при отсутствии | | `Idempotency-Key` | Запрос | Ключ дедупликации (окно 5 с) | | `X-Request-Id` | Запрос | Альтернативный ключ дедупликации | | `X-OmniRoute-Cache` | Ответ | `HIT` или `MISS` (без потоковой передачи) | | `X-OmniRoute-Idempotent` | Ответ | `true`, если была выполнена дедупликация | | `X-OmniRoute-Progress` | Ответ | `enabled`, если включено отслеживание хода выполнения | | `X-OmniRoute-Session-Id` | Ответ | Фактический идентификатор сеанса, используемый OmniRoute | | `X-OmniRoute-Request-Id` | Ответ | Идентификатор корреляции запроса (если известен) | | `X-OmniRoute-Version` | Ответ | Версия сборки OmniRoute (присутствует всегда) | | `X-OmniRoute-Cost-Saved` | Ответ | Сумма в USD, сэкономленная благодаря кэшу при `HIT` (только для попаданий в кэш) | | `X-OmniRoute-Decision` | Ответ | Трассировка маршрутизации: `strategy=; provider=; latency_ms=` (`` — стратегия комбинации или `single` для запроса без комбинации) — всегда присутствует в завершающих ответах | > Примечание по Nginx: если вы используете заголовки с символами подчёркивания (например, `x_session_id`), включите `underscores_in_headers on;`. > **Заголовки телеметрии стоимости:** успешные ответы без потоковой передачи также содержат набор заголовков телеметрии стоимости `X-OmniRoute-*` — `X-OmniRoute-Response-Cost` (USD, фиксированные 10 знаков после десятичной точки; `0.0000000000` для бесплатных запросов или запросов без заданной цены), `X-OmniRoute-Tokens-In` / `X-OmniRoute-Tokens-Out`, `X-OmniRoute-Model`, `X-OmniRoute-Provider`, `X-OmniRoute-Latency-Ms`, `X-OmniRoute-Cache-Hit` и `X-OmniRoute-Fallback-Attempts` (только если > 0), а также `X-OmniRoute-Request-Id` и `X-OmniRoute-Version`. Эти заголовки возвращаются для завершений чата, `/v1/responses`, `/v1/messages`, **а также для конечных точек мультимедиа** — `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations` и `/v1/moderations` (стоимость всегда равна `0`). Стоимость мультимедиа рассчитывается для каждой модальности отдельно (за изображение, за секунду, за символ или за единицу поиска), если информация о ценах доступна; в противном случае она равна `0` (fail-open). > **Семантика стоимости при попадании в кеш:** при ПОПАДАНИИ в семантический кеш (`X-OmniRoute-Cache-Hit: true`) обращение к вышестоящему сервису не выполняется, поэтому значение `X-OmniRoute-Response-Cost` равно `0.0000000000` (**инкрементальная** стоимость обслуживания попадания). Исходная или предполагаемая стоимость указывается отдельно в `X-OmniRoute-Cost-Saved`. Потребителям данных для биллинга следует суммировать `X-OmniRoute-Response-Cost` (попадания ничего не стоят); для аналитики кеша можно агрегировать `X-OmniRoute-Cost-Saved`. ## Эксклюзивные управляемые аренды сессий Эксклюзивная управляемая аренда сессий — это опциональный, клиент-нейтральный контракт маршрутизации: один активный владелец удерживает одно подходящее соединение OmniRoute. Она не арендует модель, не требует OAuth, не идентифицирует конкретного клиента и не требует конкретного провайдера. Ключ API для аутентификации должен иметь область действия `lease:exclusive` и явный непустой список `allowedConnections`. Граница мутации базы данных обеспечивает совместное применение обоих полей при создании ключа и частичных обновлениях. ```http POST /api/v1/session-leases Authorization: Bearer Content-Type: application/json X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> {"action":"acquire","model":"glm/glm-4.6"} ``` Успешные ответы на запросы acquire (получение), renew (продление) и release (освобождение) содержат временные метки, `state` и точное положительное `generation`, но никогда не содержат выбранное соединение или учетные данные. Запросы renew и release передают generation в теле JSON: ```json { "action": "renew", "generation": 1 } ``` ```json { "action": "release", "generation": 1, "reason": "OWNER_EXIT" } ``` Активный владелец аренды может явно запросить метаданные для отображения, безопасные для конфиденциальности, для своего текущего привязки: ```json { "action": "status", "generation": 1 } ``` ```json { "state": "ACTIVE", "generation": 1, "acquiredAt": "2026-08-28T12:00:00.000Z", "renewedAt": "2026-08-28T12:00:30.000Z", "expiresAt": "2026-08-28T12:02:30.000Z", "connection": { "displayName": "Primary Codex", "provider": "codex" } } ``` Это опциональное действие статуса ограничено непрозрачным владельцем, аутентифицированным управляемым ключом API и точной активной генерацией в одной транзакции базы данных. `displayName` — это только усеченное настроенное имя соединения; оно `null`, если безопасное настроенное имя не существует. OmniRoute никогда не подставляет адрес электронной почты или сгенерированный идентификатор учетной записи. Значение `provider` является нечувствительной меткой для отображения и никогда не является сгенерированным идентификатором совместимого провайдера. Учетные данные, токены, куки, необработанные идентификаторы соединения или ключа API, хеши владельцев, секреты ограждения и внутренние данные маршрутизации исключены. Поиски с неверным ключом, неверным владельцем, устаревшей генерацией, отсутствующие, истекшие, освобожденные и недействительные запросы возвращают одну и ту же ошибку `409 LEASE_FENCE_STALE` без метаданных соединения. Клиент, получивший ответ об ожидании доступности, не имеет активной привязки для проверки. Когда маршрутизация переводит активную аренду, та же генерация остается действительной, и статус атомарно возвращает новую привязку, а не старую. Существующие клиенты остаются без изменений, потому что ответы acquire, renew, release и waiting сохраняют свои предыдущие формы. Этот серверный контракт не изменяет стандартный `/status` OpenAI Codex. Стандартный Codex в настоящее время сообщает своего поставщика модели и встроенное состояние аутентификации/учетной записи, но не отображает произвольные пользовательские метаданные учетной записи поставщика; более поздняя клиентская интеграция должна вызвать это действие и решить, как отображать `connection.displayName`. Каждый управляемый запрос вывода затем предоставляет оба управляющих заголовка: ```http X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> X-OmniRoute-Lease-Generation: 1 ``` Точный владелец, генерация, активное соединение и аутентифицированный ключ API ограждаются непосредственно перед каждой поддерживаемой попыткой восходящего потока. Повторное использование владельца и генерации с другим ключом завершится неудачей, даже если этот ключ разрешает то же соединение. Необработанные владельцы не сохраняются, не логируются, не хранятся в снимке запроса и не пересылаются вверх по потоку. Временная конкуренция возвращает HTTP `429` с `Retry-After` и: ```json { "state": "WAITING_FOR_CAPACITY", "error": { "type": "lease_error", "code": "LEASE_CAPACITY_UNAVAILABLE" }, "reason": "NO_FREE_ELIGIBLE_CONNECTION", "retryAfter": 30 } ``` Этот ответ означает лишь, что обычный набор подходящих кандидатов был непустым, и каждый свободный кандидат был занят чужой активной арендой. Неподдерживаемые модели/провайдеры, несоответствие политик, период охлаждения, квоты, состояние работоспособности и другие обычные сбои соответствия сохраняют свои существующие ответы OmniRoute. ### `x-omniroute-compression` Переопределение плана сжатия для каждого запроса. Наивысший приоритет — превосходит переопределение комбинации маршрутизации, активный профиль, автозапуск и панель Default. Значения: | Значение | Эффект | | ------------- | ------------------------------------------------------------------------------------------------------------- | | `off` | Без сжатия для этого запроса. | | `default` | Профиль Default, полученный из панели (игнорирует активный профиль). Движки с потерями остаются выключенными. | | `safe` | Только дедупликация и свертывание пробелов. | | `allow-lossy` | Сохранить план оператора для этого запроса, включая сводки и переписывания стилей. | | `engine:` | Один движок, если включен, например `engine:rtk`. Опциональное включение этого движка для каждого запроса. | | `` | Именованная комбинация, сопоставляется сначала по имени (без учета регистра), затем по id. | Примечания: - Неизвестные значения игнорируются (запрос никогда не отклоняется); разрешение переходит к обычному приоритету оператора. - Если несколько комбинаций имеют одно и то же имя, передайте **id** комбинации для детерминированного сопоставления. - Комбинация, имя которой `off` или `default`, не может быть выбрана по имени (эти ключевые слова интерпретируются первыми); ссылайтесь на такую комбинацию по ее id. - Главный переключатель сжатия является жестким ограничением: если сжатие отключено глобально, этот заголовок не может его включить. Примененный план возвращается в заголовке ответа: ``` X-OmniRoute-Compression: ; source= ``` где `` — это одно из значений: `request-header`, `routing-override`, `active-profile`, `auto-trigger`, `default` или `off`. --- ## Эмбеддинги ```bash POST /v1/embeddings Authorization: Bearer your-api-key Content-Type: application/json { "model": "nebius/Qwen/Qwen3-Embedding-8B", "input": "The food was delicious" } ``` Доступные провайдеры: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, Jina AI. Идентификаторы в каталоге имеют формат `provider/model` (пример: `jina-ai/jina-embeddings-v5-omni-small`). Также распознаются идентификаторы моделей Jina без имени провайдера, присутствующие в реестре (например, `jina-embeddings-v5-text-small`, `jina-reranker-v3.5`). Для операций Jina embed/rerank/classify/segment в первую очередь используются учётные данные `jina-ai` из панели управления; `JINA_AI_API_KEY` используется в качестве резервного варианта, только если ключ в панели управления отсутствует. Карточка `jina-reader` предназначена только для Reader / `r.jina.ai` (`POST /v1/web/fetch`) и никогда не обслуживает эмбеддинги или переранжирование. Модели в реестре, для которых заявлена поддержка мультимодальности, также принимают до 32 структурированных элементов в нейтральном для провайдеров формате. Типы медиаэлементов: `text`, `image`, `audio`, `video` и `document`. Их поле `source` может иметь вид `{"type":"url","url":"https://..."}` или `{"type":"base64","data":"...","media_type":"..."}`. Jina v5 Omni (`jina-ai/jina-embeddings-v5-omni-small`, `jina-ai/jina-embeddings-v5-omni-nano` и псевдоним семейства `jina-ai/jina-embeddings-v5-omni` → omni-small) также принимает нативные документы EmbeddingsV5Request от Jina и **перенаправляет их без изменений** в `https://api.jina.ai/v1/embeddings`: ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "task": "retrieval.query", "normalized": true, "input": [ { "text": "a red bicycle" }, { "image": "https://example.com/bike.png" }, { "content": [{ "text": "caption" }, { "image": "data:image/png;base64,..." }] } ] } ``` Нативные значения `{ image | audio | video | pdf }` могут представлять собой общедоступный HTTPS URL, URI `data:` или необработанные данные base64. OmniRoute не сериализует эти объекты в строки и не загружает нативные URL изображений — Jina самостоятельно получает общедоступные медиафайлы. Дополнительные поля Jina (`task`, `normalized`, `truncate`, `embedding_type`) перенаправляются. SKU Jina, поддерживающие только текст, по-прежнему отклоняют нетекстовые документы. Ограничения безопасности и передачи данных: - Удалённые URL медиафайлов должны быть общедоступными и использовать HTTPS. Канонические элементы `{type,source:url}` загружаются на стороне сервера (с повторной проверкой перенаправлений, ограничениями по времени и размеру, проверкой общедоступности DNS и фиксацией соединения) и встраиваются до вызова провайдера. Нативные элементы Jina `{image:"https://..."}` перенаправляются без изменений после такой же проверки общедоступности HTTPS; URL загружает Jina. - Размер встроенных медиафайлов в формате base64 ограничен 8 МиБ декодированных данных на элемент и 16 МиБ декодированных данных на весь запрос. Преобразование для провайдеров (канонические элементы никогда не перенаправляются без изменений): - Мультимодальные модели Jina: каждый элемент верхнего уровня преобразуется в один объект с ключом модальности (`text` / `image` / `audio` / `video` / `pdf`), использующий URI данных для встроенных медиафайлов; один вектор на элемент верхнего уровня. - Семейство Gemini Embedding 2: один массив верхнего уровня преобразуется в один нативный запрос `models/{model}:embedContent` с `content.parts` (`text` или `inline_data`). - llama.cpp (`llama-cpp/`, любая модель, загруженная локальным сервером): канонические элементы `text` преобразуются в обычные строки, а `image` / `audio` / `video` — каждый в один объект `{"content": [part]}` с использованием частей содержимого чата llama-server (`image_url`, `input_audio` с форматом `wav` / `mp3` / `flac`, `input_video`) и встроенными данными; один вектор на элемент верхнего уровня. Сервер должен быть запущен с `--embedding --mmproj …`; без проектора он самостоятельно отклоняет медиафайлы. `document` не поддерживается. - Неизвестные/динамические модели без явных метаданных о модальностях отклоняют структурированный ввод с кодом HTTP 400. ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "input": [ { "type": "text", "text": "A red bicycle" }, { "type": "image", "source": { "type": "url", "url": "https://example.com/bicycle.png" } } ], "dimensions": 512, "encoding_format": "float" } ``` Неподдерживаемые сочетания модели и модальности возвращают HTTP 400 вместо принудительного преобразования элемента. Поля расширений, не относящиеся к вводу, в устаревших запросах со строками/токенами по-прежнему передаются без изменений. ```bash # Вывести список всех моделей эмбеддингов GET /v1/embeddings ``` --- ## Генерация изображений ```bash POST /v1/images/generations Authorization: Bearer your-api-key Content-Type: application/json { "model": "openai/gpt-image-2", "prompt": "Красивый закат над горами", "size": "1024x1024" } ``` Среди доступных провайдеров — OpenAI (GPT Image 2), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, **ZenMux**, SD WebUI (локально), ComfyUI (локально). `n` возвращает `n` изображений в `data[]`. Для провайдеров, чей вышестоящий API возвращает одно изображение за вызов (Black Forest Labs, Stability AI, Leonardo, Ideogram, Haiper, Hyperbolic, Magnific/Freepik, NVIDIA NIM, Cloudflare Workers AI), выполняется `n` отдельных вышестоящих вызовов, не более 4 одновременно. При фиксированном `seed` к нему добавляется индекс вызова (`seed`, `seed + 1`, …), поэтому изображения различаются, но остаются воспроизводимыми. Максимальное значение `n` — 10. Если какой-либо вызов завершается ошибкой, весь запрос считается неуспешным. Список форматов с разветвлением вызовов задаётся в `SINGLE_IMAGE_FANOUT_FORMATS` в `open-sse/handlers/imageGeneration/fanOut.ts`. ZenMux повторно использует существующее подключение с API-ключом и принимает префиксы `zenmux/` или `zm/`: - `zenmux/openai/gpt-image-2` использует OpenAI Images API от ZenMux. Доступные параметры включают `size`, `quality`, `n`, `output_format`, `output_compression`, `background` и `response_format`. - Другие издатели, например `zm/meta/muse-image-1.0`, используют конечную точку Vertex AI `:predict` от ZenMux. `n` сопоставляется с `sampleCount`, `aspect_ratio` — с `aspectRatio`, а `image_size` (`1K`, `2K`, `4K`) — с `sampleImageSize`. Значение `size` в пикселях задаёт только соотношение сторон, а не гарантированные размеры в пикселях. Поддерживаемые соотношения сторон, разрешения и количества зависят от модели. - `zm/inclusionai/ming-image-0.1-design` самостоятельно выбирает размеры. Не указывайте `size`, `aspect_ratio` и `image_size`; явное задание этих значений приводит к ответу HTTP 400. Форматы PNG, JPEG и WebP можно запросить с помощью `output_format`. Эта интеграция поддерживает генерацию изображений по тексту, но не редактирование по референсному изображению. Выходные данные Vertex нормализуются в `data[].b64_json`; `response_format: "url"` возвращает вышестоящий HTTPS URL или URL с данными в формате base64, если доступны только байты изображения. Пустой или отфильтрованный результат приводит к ошибке, а не к пустому успешному ответу. Доступ к моделям зависит от учётной записи ZenMux. См. [Vertex API от ZenMux](https://docs.zenmux.ai/api/vertexai/generate-images) и [OpenAI Images API](https://docs.zenmux.ai/api/openai/generate-an-image). ```bash # Вывести список всех моделей изображений GET /v1/images/generations ``` --- ## OCR документов ```bash POST /v1/ocr Authorization: Bearer your-api-key Content-Type: application/json { "model": "mistral/mistral-ocr-latest", "document": { "type": "document_url", "document_url": "https://example.com/invoice.pdf" } } ``` `model` выбирает провайдера OCR с помощью префикса `provider/model`; идентификатор модели без префикса (например, `mistral-ocr-latest`) сопоставляется с зарегистрированным провайдером, а если `model` не указан, по умолчанию используется Mistral (`mistral-ocr-latest`). Зарегистрированные провайдеры (`open-sse/config/ocrRegistry.ts`): | Идентификатор провайдера | Идентификатор модели | Значение `model` | Примечания | | ----------------------------- | -------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `mistral` | `mistral-ocr-latest` | `mistral/mistral-ocr-latest` (или `mistral-ocr-latest` без префикса) | Синхронный — ответ возвращается непосредственно из единственного восходящего запроса. | | `azure-document-intelligence` | `prebuilt-read` | `azure-document-intelligence/prebuilt-read` | Асинхронный восходящий запрос (`analyze` + опрос) — см. ниже. | | `vertex-deepseek-ocr` | `deepseek-ocr-maas` | `vertex-deepseek-ocr/deepseek-ocr-maas` | Синхронный, через партнёрскую конечную точку Vertex AI `openapi/chat/completions` — сведения об аутентификации и URL см. ниже. | Все три провайдера возвращают тело ответа в одинаковом формате Mistral: ```json { "pages": [{ "index": 0, "markdown": "# Извлечённый текст..." }], "model": "mistral-ocr-latest", "usage_info": { "pages_processed": 1 } } ``` ### Процесс опроса Azure Document Intelligence API `analyze` сервиса Azure Document Intelligence работает асинхронно: первоначальный запрос вместо тела ответа возвращает заголовок `Operation-Location`, после чего результат необходимо получать путём опроса. Обработчик (`open-sse/handlers/ocr.ts`) опрашивает этот URL каждую секунду, выполняя до 30 попыток, немедленно завершается с ошибкой (не продолжая опрос) при ответе опроса без статуса `ok` или при статусе `"failed"` и возвращает `504`, если операция всё ещё выполняется после исчерпания лимита попыток. Перед возвратом вызывающей стороне итоговый ответ Azure нормализуется в тот же формат `pages`/`markdown`, который используется Mistral, поэтому клиентскому коду не требуется отдельно обрабатывать этого провайдера. ### Аутентификация и разрешение конечной точки Vertex AI DeepSeek OCR `vertex-deepseek-ocr` повторно использует тот же механизм аутентификации Vertex AI, который OmniRoute уже поддерживает для трафика чатов и изображений (`open-sse/executors/vertex.ts`): API-ключ подключения представляет собой либо учётные данные Service Account в формате JSON (обмениваемые на краткосрочный токен доступа OAuth посредством потока JWT-bearer), либо уже выпущенный токен доступа OAuth, используемый без изменений. В качестве восходящего URL конечной точки используется универсальная партнёрская конечная точка Vertex `openapi/chat/completions`, сформированная на основе проекта и региона подключения: явно заданные `providerSpecificData.project`/`providerSpecificData.region` всегда имеют приоритет; в противном случае проект определяется из `project_id` в JSON Service Account, а регионом по умолчанию является `us-central1`. Оба значения разрешаются в `open-sse/handlers/ocr.ts` (`resolveVertexOcrAccessToken`, `resolveVertexOcrBaseUrl`) и используются в `src/app/api/v1/ocr/route.ts` перед передачей управления в `handleOcr`. --- ## Список моделей ```bash GET /v1/models Authorization: Bearer your-api-key → Возвращает все модели чата, эмбеддингов и изображений, а также комбинации в формате OpenAI ``` ### Префиксы идентификаторов моделей (`?prefix=`) Большинство моделей публикуются с **префиксом провайдера**. Используемый префикс определяется флагом функции `MODELS_CATALOG_PREFIX_MODE` и может быть переопределён **для каждого запроса** с помощью параметра запроса — это удобно для клиента, которому нужен чистый список без изменения общесерверной настройки для всех остальных: ```bash GET /v1/models?prefix=alias # один идентификатор на модель — короткий префикс-псевдоним GET /v1/models?prefix=dual # обе формы (настройка сервера по умолчанию) GET /v1/models?prefix=canonical # только полный префикс идентификатора провайдера ``` | Режим | Возвращает | Примечания | | ----------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `dual` | `cc/claude-sonnet-4-6` **и** `claude/claude-sonnet-4-6` | **По умолчанию.** Оба идентификатора направляют запросы к одной модели; это сохранено, чтобы клиентские конфигурации, в которых жёстко задана любая из форм, продолжали работать. Примерно удваивает размер каталога. | | `alias` | `cc/claude-sonnet-4-6` | Одна запись на модель. Провайдеры без отдельного псевдонима всё равно возвращают свою запись, поэтому ничего не теряется. | | `canonical` | `claude/claude-sonnet-4-6` | Одна запись на модель с полным префиксом идентификатора провайдера. Провайдеры без отдельного псевдонима (например, `antigravity/…`, `agy/…`) также возвращают здесь свой единственный идентификатор, поэтому ничего не теряется. | Зеркальную запись в режиме `dual` также можно распознать без параметра запроса: она содержит поле `parent`, указывающее на основной идентификатор. Клиентам, отображающим средство выбора модели, следует запрашивать `?prefix=alias` — именно так поступает [расширение OmniCopilot для VS Code](../guides/VSCODE-COPILOT.md). ### Отдельно скрытые модели чата Модель, помеченная как **Hidden** на странице своего провайдера, исключается из каталога, а при явном запросе отклоняется с HTTP `404` / `model_not_found`. Проверка использует разрешённые провайдера и модель, включая псевдонимы провайдеров, префиксы узлов совместимых провайдеров и настройки соединения по умолчанию. Комбинация пропускает скрытые целевые модели и может использовать видимую родственную модель; если не остаётся ни одной доступной для выполнения целевой модели, возвращается тот же код ошибки. Снятие скрытия вступает в силу при следующем запросе. Переопределения видимости только для изображений не скрывают модель чата с тем же идентификатором. Эта индивидуальная настройка модели не связана со [списками разрешения/запрета публикации моделей](../routing/MODEL_EXPOSURE_LIST.md), которые фильтруют публикацию в каталоге и кандидатов для автоматической маршрутизации, сохраняя при этом явную диспетчеризацию. Разрешения моделей для API-ключей продолжают применяться независимо. Режим префиксов каталога по умолчанию остаётся `dual`. ### Варианты моделей без размышления Для моделей Claude с поддержкой размышления `/v1/models` также публикует вариант **без размышления**, идентификатор которого начинается с `claude-3-omniroute-no-thinking/`: ``` claude-3-omniroute-no-thinking// ``` При выборе этого идентификатора (например, в конфигурации Claude Code, которая всегда добавляет блок `thinking`) он разрешается обратно в реальный `/` с отключённым рассуждением — `thinking:{type:"disabled"}` для пути `/v1/messages` либо с удалёнными полями `reasoning`/`reasoning_effort` для пути `/v1/chat/completions`. Вариант отображается только для моделей семейства Claude, которые поддерживают размышление **и** учитывают значение `disabled` (поэтому, например, модели только с адаптивным режимом, отклоняющие `disabled`, исключаются). Операторы могут принудительно включить или отключить этот вариант для каждой модели с помощью `ModelSpec.noThinkingAlias`. --- ## Манифест плагинов провайдеров ```bash GET /api/v1/provider-plugin-manifest ``` Возвращает JSON-совместимый манифест плагинов провайдеров, используемый Bifrost, CLIProxyAPI и будущими маршрутизаторами-сайдкарами. Ответ формируется на основе реестра провайдеров TypeScript и намеренно не включает секреты OAuth-клиентов, разрешение переменных среды во время выполнения, функции-исполнители, заголовки запросов и данные учётных записей. Используйте эту конечную точку, когда сайдкар выполняется вне процесса и не может напрямую импортировать `open-sse/config/providerPluginManifestRegistry.ts`. --- ## Эндпоинты совместимости | Метод | Путь | Формат | | ----- | ----------------------------------------- | ------------------------------------------- | | POST | `/v1/chat/completions` | OpenAI | | POST | `/v1/messages` | Anthropic | | POST | `/v1/responses` | OpenAI Responses | | POST | `/v1/embeddings` | OpenAI | | POST | `/v1/images/generations` | OpenAI Images | | POST | `/v1/images/edits` | OpenAI Images (редактирование/дорисовка) | | POST | `/v1/videos/generations` | Генерация видео в стиле OpenAI | | POST | `/v1/music/generations` | Генерация музыки в стиле OpenAI | | POST | `/v1/audio/transcriptions` | OpenAI Audio (STT) | | POST | `/v1/audio/speech` | OpenAI TTS (возвращает тело с аудио) | | POST | `/v1/rerank` | Реранжирование в стиле Cohere/Voyage | | POST | `/v1/classify` | Классификация Jina (`api.jina.ai`) | | POST | `/v1/segment` | Сегментатор Jina (`segment.jina.ai`) | | POST | `/v1/moderations` | OpenAI Moderations | | GET | `/v1/models` | OpenAI | | POST | `/v1/messages/count_tokens` | Anthropic | | GET | `/v1beta/models` | Gemini | | POST | `/v1beta/models/{...path}` | Gemini generateContent | | POST | `/v1/api/chat` | Ollama | | GET | `/api/v1/vscode/{token}/` | Псевдоним каталога OpenAI | | GET | `/api/v1/vscode/{token}/models` | Псевдоним моделей OpenAI | | POST | `/api/v1/vscode/{token}/chat/completions` | Токенизированный псевдоним OpenAI | | POST | `/api/v1/vscode/{token}/responses` | Токенизированный псевдоним OpenAI Responses | | POST | `/api/v1/vscode/{token}/api/chat` | Токенизированный псевдоним Ollama | | GET | `/api/v1/vscode/{token}/api/tags` | Токенизированный псевдоним тегов Ollama | Все маршруты POST имеют одинаковую структуру: `Bearer your-api-key` + проверяемое Zod тело JSON (`v1RerankSchema`, `v1ModerationSchema`, `v1AudioSpeechSchema` и т. д.; см. `src/shared/validation/schemas.ts`). При ошибке проверки схемы возвращается 4xx. Для клиентов, которые не могут добавить `Authorization: Bearer ...`, OmniRoute также принимает ключи API в URL: либо через совместимые параметры строки запроса (`?token=...`, `?apiKey=...`, `?api_key=...`, `?key=...`), либо через специальные эндпоинты `/api/v1/vscode/{token}/...`, описанные ниже. ```bash # Реранжирование (провайдер из облачного реестра или узел OpenAI-совместимого провайдера в виде "/") POST /v1/rerank { "model": "jina-ai/jina-reranker-v3.5", "query": "...", "documents": ["..."] } # Классификация Jina (учётные данные Foundation API) POST /v1/classify { "model": "jina-embeddings-v5-text-small", "input": ["..."], "labels": ["a", "b"] } # Сегментатор Jina POST /v1/segment { "content": "...", "return_chunks": true } # Поиск Jina (s.jina.ai; псевдонимы провайдера: jina-search, jina-ai, jina) POST /v1/search { "query": "...", "provider": "jina-search" } # Модерация POST /v1/moderations { "model": "omni-moderation-latest", "input": "..." } # TTS — возвращает тело audio/mpeg (или в запрошенном формате) POST /v1/audio/speech { "model": "openai/tts-1", "input": "Hello", "voice": "alloy" } # Для Soniox TTS требуются язык и голос: значение `language` по умолчанию — "en"; отсутствующий # голос или стандартное имя голоса OpenAI (alloy, nova, …) заменяется на "Adrian" POST /v1/audio/speech { "model": "soniox/tts-rt-v1", "input": "Xin chào", "voice": "Adrian", "language": "vi" } # Редактирование изображения (multipart) POST /v1/images/edits -F image=@input.png -F prompt="..." -F mask=@mask.png # Генерация видео/музыки (идентификатор модели с префиксом провайдера) POST /v1/videos/generations { "model": "runway/gen-3", "prompt": "..." } POST /v1/music/generations { "model": "kie/suno-v4.0", "prompt": "..." } ``` > **Узлы провайдеров реранжирования:** `POST /v1/rerank` также направляет запросы к узлам > OpenAI-совместимых провайдеров (oMLX, vLLM, Infinity, TEI за шлюзом и т. д.), адресуемым > как `/`. Узлы loopback (`localhost`, `127.0.0.1`, `172.16.0.0/12`) > доступны всегда, как и имена хостов, перечисленные оператором в > `OMNIROUTE_LOCAL_PROVIDER_NODE_HOSTS` (например, имя сервиса Docker/Compose, такое как > `http://reranker:8080/v1`; обращения к ним выполняются напрямую, без использования > `HTTP(S)_PROXY` или закреплённого за подключением прокси). Узлы на любом другом > хосте — компьютере в локальной сети или пире Tailscale — доступны, только если оператор > включил флаг функции `RERANK_REMOTE_PROVIDER_NODES` **и** базовый URL узла соответствует > политике исходящих URL провайдера (`OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` / > `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS`). Этап реранжирования движка памяти вызывает > этот маршрут через loopback, поэтому то же правило применяется к `rerankProviderModel` > в настройках памяти. > > **Форматы локальных серверов:** узел вызывается по адресу `/v1/rerank`, а при ответе > 404 — по адресу `/rerank` (Infinity, TEI). Тело вышестоящего запроса содержит как > варианты написания Cohere/OpenAI (`documents`, `return_documents`), так и варианты TEI > (`texts`, `return_text`), а ответ вышестоящего сервера нормализуется до оболочки Cohere: > чистый массив TEI `[{index, score, text}]`, `{results: [{index, score}]}` от тонких шлюзов > и `{data: [...]}` в стиле Voyage возвращаются клиенту в виде > `{results: [{index, relevance_score, document?}]}`, отсортированного по оценке и ограниченного > значением `top_n`. > **Обнаружение моделей узла провайдера:** модели на узле OpenAI-совместимого провайдера отображаются в `GET /v1/models` > с префиксом узла. Строки без метаданных конечной точки (что типично для локальных списков `/v1/models`) > наследуют `apiType` узла, поэтому модели узла `embeddings` имеют `type: "embedding"`, а модели узла > `rerank` — `type: "rerank"` вместо типа чата по умолчанию; явно заданное значение > `supportedEndpoints` в синхронизированной или добавленной вручную строке по-прежнему имеет приоритет. ### Выделенные маршруты провайдера ```bash POST /v1/providers/{provider}/chat/completions POST /v1/providers/{provider}/embeddings POST /v1/providers/{provider}/images/generations ``` Префикс провайдера добавляется автоматически, если он отсутствует. При несовпадении моделей возвращается `400`. --- ## Files API Совместимый с OpenAI эндпоинт для пакетного ввода/вывода файлов и загрузки файлов с указанием назначения. | Метод | Путь | Описание | | ------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------- | | POST | `/v1/files` | Загрузить файл (multipart: `file`, `purpose`, `expires_after[anchor]`, `expires_after[seconds]`) — не более 512 МиБ | | GET | `/v1/files` | Получить список файлов для аутентифицированного API-ключа | | GET | `/v1/files/[id]` | Получить метаданные файла | | DELETE | `/v1/files/[id]` | Удалить файл | | GET | `/v1/files/[id]/content` | Получить необработанное содержимое файла в потоковом режиме | **Аутентификация:** API-ключ Bearer — область видимости файлов ограничивается каждым API-ключом с помощью `getApiKeyRequestScope`. Ключ может просматривать, скачивать и удалять только собственные файлы; сеанс панели управления без ключа имеет доступ ко всему экземпляру; доступ к файлу без владельца (загруженному анонимно или через сеанс панели управления) запрещён для любого вызывающего клиента без сеанса. `GET /v1/files` отклоняет запрос анонимного клиента — а также запрос с предоставленным ключом, который не удаётся разрешить, — с кодом `401`, даже если `REQUIRE_API_KEY=false`, вместо предоставления списка файлов всех арендаторов (GHSA-m3hp-hq9g-fpmv, GHSA-2jm2-mpx8-6523). --- ## Batches API Совместимая с OpenAI пакетная обработка. | Метод | Путь | Описание | | ------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------- | | POST | `/v1/batches` | Создать пакет — тело проверяется с помощью `v1BatchCreateSchema` (`input_file_id`, `endpoint`, `completion_window`) | | GET | `/v1/batches` | Получить список пакетов | | GET | `/v1/batches/[id]` | Получить состояние пакета и `request_counts` | | DELETE | `/v1/batches/[id]` | Удалить завершённый пакет или пакет с ошибкой | | POST | `/v1/batches/[id]/cancel` | Отменить выполняющийся пакет | **Аутентификация:** API-ключ Bearer. Область видимости пакетов ограничивается каждым API-ключом по тому же трёхвариантному правилу, что и для файлов: доступ только по собственному ключу, доступ ко всему экземпляру через сеанс панели управления, запрет доступа к записям с владельцем null для любого вызывающего клиента без сеанса (при получении, удалении, отмене и проверке `input_file_id` во время создания). `GET /v1/batches` отклоняет запрос анонимного клиента с кодом `401`, даже если `REQUIRE_API_KEY=false`. --- ## Search API Абстракция провайдеров веб-поиска (Tavily, Brave, Exa, Serper и т. д.). | Метод | Путь | Описание | | ----- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | | GET | `/v1/search` | Список настроенных поисковых провайдеров и их возможностей | | POST | `/v1/search` | Выполнение поискового запроса — тело проверяется с помощью `v1SearchSchema`, поддерживает кеширование/объединение запросов | | GET | `/v1/search/analytics` | Статистика попаданий, задержек и кеша по каждому провайдеру | **Аутентификация:** API-ключ Bearer (`extractApiKey` + `isValidApiKey`). Политика поиска применяется через `enforceApiKeyPolicy`. --- ## Web Fetch API Извлечение содержимого из URL через настроенного провайдера веб-загрузки (Firecrawl, Jina Reader, Tavily Extract, TinyFish Fetch, Nimble Extract). | Метод | Путь | Описание | | ----- | --------------- | ---------------------------------------------------------------------- | | POST | `/v1/web/fetch` | Загрузка/скрейпинг URL — тело проверяется с помощью `v1WebFetchSchema` | **Аутентификация:** API-ключ Bearer (`extractApiKey` + `isValidApiKey`). Политика применяется через `enforceApiKeyPolicy`. **Резервное переключение с учётом квот (#8297):** если явный `provider` не указан, пул (`firecrawl` → `jina-reader` → `tavily-search` → `tinyfish` → `nimble-search`) перебирается в фиксированном порядке приоритета (сначала заполняется первый) — настроенный провайдер, достигший ограничения частоты запросов, пропускается вместо немедленного завершения запроса, а повторяемая ошибка вышестоящего сервиса или ошибка квоты (HTTP 429 всегда; 402/403 для бесплатных тарифов Firecrawl/Tavily/TinyFish с ограничениями квоты — не для Jina Reader и никогда для обычного некорректного запроса 400) приводит к переходу к следующему ещё не опробованному провайдеру с настроенными учётными данными во время выполнения запроса. Когда все провайдеры в пуле исчерпаны, конечная точка возвращает единый `429` (с заголовком `Retry-After`) вместо прежнего общего `400`. Когда явно запрошен `provider`, **скрытого резервного переключения нет** — для явно указанного провайдера, достигшего ограничения частоты запросов или завершившегося ошибкой, возвращается его собственная ошибка (`429` при ограничении частоты запросов, в остальных случаях — статус вышестоящего сервиса). --- ## Потоковая передача через WebSocket ```bash GET /v1/ws?handshake=1 ``` Проверяет рукопожатие обновления соединения до WebSocket и возвращает примеры сообщений протокола передачи (`request`, `cancel`). Фактические кадры WS обрабатываются встроенным сервером WS вне таблицы маршрутов Next.js. **Аутентификация:** API-ключ Bearer во время рукопожатия. ### Responses API через WebSocket (только codex) ```bash # Тот же host:port, что и у HTTP API (по умолчанию 20128); обновите соединение: wscat -c "ws://localhost:20128/v1/responses?api_key=" # (или: -H "Authorization: Bearer ") # Первым кадром ОБЯЗАТЕЛЬНО должен быть response.create: { "type": "response.create", "model": "gpt-5.5", "input": [ { "role": "user", "content": "hi" } ] } ``` Прокси Responses API через WebSocket подключён **исключительно к `codex`** (бэкенд ChatGPT). Он прослушивает тот же порт, что и API/панель управления, по путям `/v1/responses`, `/responses` и `/api/v1/responses`. При получении первого кадра `response.create` он выполняет аутентификацию и подготовку через внутренний мост `codex-responses-ws`, выбирает OAuth-подключение codex и создаёт туннель к `wss://chatgpt.com/backend-api/codex/responses` через транспорт `wreq-js`. **Модели, не относящиеся к codex, отклоняются** (`codex_ws_provider_required`). Для маршрутизации с распределением квоты используйте `model: "qtSd//codex/"`. Реализовано в `app/server-ws.mjs` + `scripts/dev/responses-ws-proxy.mjs` + `src/app/api/internal/codex-responses-ws/route.ts`. **Аутентификация:** API-ключ Bearer во время рукопожатия. Встроенный HTTP-сервер (`server-ws.mjs`) должен быть активной точкой входа (по умолчанию это так, если существует `app/server-ws.mjs`). #### Идентификатор модели: используйте простой идентификатор ChatGPT (без префикса `codex/`) OpenAI **Codex CLI** проверяет имя модели на стороне клиента, когда `supports_websockets = true`, и **отклоняет идентификаторы с префиксом провайдера**, например `codex/gpt-5.5` (`The 'codex/gpt-5.5' model is not supported when using Codex with a ChatGPT account`). Передавайте **простой** идентификатор (например, `gpt-5.5`). Мост OmniRoute работает только с codex, поэтому перед созданием туннеля к вышестоящему сервису он повторно определяет простой идентификатор как модель codex (`resolveCodexWsModelInfo`) — даже несмотря на то, что простой `gpt-5.5` при использовании HTTP в ином случае был бы направлен к другому провайдеру. #### Настройка OpenAI Codex CLI Настройте Codex CLI для работы с OmniRoute, добавив пользовательского провайдера с поддержкой WebSocket в `~/.codex/config.toml` (используйте отдельный `CODEX_HOME`, чтобы не изменять существующую конфигурацию): ```toml model = "gpt-5.5" # простой идентификатор — НЕ "codex/gpt-5.5" model_provider = "omniroute" [model_providers.omniroute] name = "OmniRoute (WS)" base_url = "http://localhost:20128/v1" # без завершающей косой черты; URL-адрес WS формируется автоматически (в рабочей среде используйте https/wss) wire_api = "responses" # единственное поддерживаемое значение с февраля 2026 года supports_websockets = true # включает транспорт Responses через WS env_key = "OMNIROUTE_API_KEY" # содержит API-ключ OmniRoute (Bearer) ``` ```bash export OMNIROUTE_API_KEY=sk-... # API-ключ OmniRoute (любой ключ, если REQUIRE_API_KEY=false) codex exec "Responda apenas: PONG" ``` CLI обновляет соединение по адресу `base_url + /responses` до WebSocket, а OmniRoute создаёт туннель к выбранному OAuth-подключению codex. Работа полностью проверена на локальном сервере: ChatGPT возвращает `codex.rate_limits` + `response.created` и передаёт завершение в потоковом режиме. --- ## Квоты и сообщения о проблемах | Метод | Путь | Описание | | ----- | ------------------- | --------------------------------------------------------------------------------------------------- | | GET | `/v1/quotas/check` | Предварительная проверка квоты для `provider` + `accountId` перед выдачей зарегистрированного ключа | | POST | `/v1/issues/report` | Отправка сообщения о сбое квоты/выдачи ключа в GitHub (требуются `GITHUB_ISSUES_REPO` и токен) | **Аутентификация:** API-ключ Bearer (`isAuthenticated`). --- ## Самостоятельный просмотр использования (`/api/usage/om-usage`) Любой API-ключ может просматривать **собственные** данные об использовании и квотах — управленческая авторизация не требуется. Это конечная точка, которую клиент (CLI, панель OmniCopilot) использует, чтобы показать владельцу ключа его расходы. ```bash # Текстовый формат (исторический контракт — обычный текст для терминала) curl -H "Authorization: Bearer " \ http://localhost:20128/api/usage/om-usage # Структурированный формат — используется пользовательским интерфейсом curl -H "Authorization: Bearer " \ "http://localhost:20128/api/usage/om-usage?format=json" ``` Для ключа необходимо включить **`allowUsageCommand`** (по умолчанию отключено — диспетчер API-ключей на панели управления переключает этот параметр отдельно для каждого ключа). Если параметр не включён, конечная точка возвращает `403`. `?format=json` возвращает дискриминированную структуру, благодаря чему вызывающая сторона никогда не считывает поле данных из ответа с отказом. При успешном выполнении: ```jsonc { "allowed": true, // присутствует, только если для ключа включены индивидуальные лимиты использования (дневные/недельные, в USD): "personal": { "dailySpentUsd": 1.25, "dailyLimitUsd": 5, "dailyResetAtIso": "…", "weeklySpentUsd": 8, "weeklyLimitUsd": 20, "weeklyResetAtIso": "…" /* … */, }, // снимок квот выбранного провайдера или null, если в кэше пока ничего нет: "provider": { "connectionId": "…", "provider": "claude", "plan": "…", "quotas": {/* … */}, }, // снимок для каждого подключения, чтобы пользовательский интерфейс мог отображать несколько провайдеров рядом: "providers": [ { "connectionId": "…", "provider": "claude" /* … */ }, { "provider": "codex" /* … */ }, ], } ``` При отказе (`401` — неверный ключ / `403` — доступ запрещён) тот же маршрут возвращает `{ "allowed": false, "error": { "message": "…" } }` — присутствующие, но пустые `personal`/`provider` (ключу разрешён доступ, но данные ещё не получены) представляют собой состояние, отличное от отказа, и различить их позволяет только формат JSON. **Аутентификация:** собственный Bearer API-ключ вызывающей стороны, проверяемый с помощью `isValidApiKey` — это _не_ интерфейс управления (`/api/keys/…`), который остаётся защищённым посредством `requireManagementAuth`. ### Необработанные и скорректированные с учётом порога проценты квоты При использовании `/api/usage/om-usage` вызывающим сторонам следует учитывать различие между процентными значениями, представленными в **текстовом выводе**, и структурированным **выводом JSON**: | Аспект | Текстовый формат (`/api/usage/om-usage` / `@@om-usage`) | Формат JSON (`?format=json`) | | :------------------------- | :---------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- | | **Поле вывода** | `NN% left` (например, `20% left`) | `provider.quotas` / `providers[].quotas` | | **Измеряемая величина** | **Доступный объём с поправкой на порог**: оставшийся ресурс сверх порогового значения | **Необработанная вышестоящая квота**: нескорректированное значение провайдера | | **Масштабирование порога** | Масштабируется через `effectiveRemainingPercent()`, чтобы защищённый резерв отображался как `0% left` | Отсутствует (необработанные значения снимка, сообщённые провайдером) | | **Данные о пороге** | Учтены в отображаемом процентном значении | Хранятся в `quotaWindowThresholds` для каждого подключения (или используются значения сервера по умолчанию) | | **Основной потребитель** | Интерактивные CLI, терминальные подсказки, операторы | Программные интеграции, панели мониторинга, аналитика, средства учёта расходов | #### Формула корректировки с учётом порога OmniRoute поддерживает упреждающие пороги отключения квот, предотвращающие исчерпание вышестоящих ресурсов (настраиваются через параметры подключения `quotaWindowThresholds`, значения провайдера по умолчанию или глобальные настройки отказоустойчивости). Когда для окна квоты действует порог отключения (например, `cutoff = 25%`), средство текстового отображения рассчитывает оставшийся доступный объём следующим образом: - Если `remaining <= cutoff`: возвращается `0%`. - Если `remaining > cutoff`: возвращается `((remaining - cutoff) / (100 - cutoff)) * 100`. В форматированном текстовом выводе результат округляется до ближайшего целого числа (`Math.round(...)`). #### Наглядный пример Рассмотрим окно провайдера с **60% необработанного использования** (следовательно, остаётся **40% необработанной квоты**) и настроенным порогом отключения при **25% оставшейся квоты**: | Представление | Расчёт | Осталось | Подразумеваемое использование | | :--------------------------------------- | :------------------------------------------------- | :------: | :--------------------------------------------: | | **Необработанный JSON (`?format=json`)** | Снимок вышестоящей системы (`quotas[window]`) | **40%** | **60%** | | **Текстовый формат (`NN% left`)** | `((40 - 25) / (100 - 25)) * 100 = (15 / 75) * 100` | **20%** | **80%** (если вычислять как `100 - remaining`) | - **Почему в тексте отображается 20% оставшегося объёма:** из 40% физической квоты, оставшейся в учётной записи, 25% зарезервировано политикой порогового отключения. Вызывающей стороне доступно только 15% из 75% используемого резерва до того, как маршрутизатор перестанет направлять запросы через это подключение. Масштабирование гарантирует, что подключение сообщит об исчерпании (`0% left`) именно в тот момент, когда маршрутизация будет прекращена. - **Почему JSON сохраняет необработанные значения:** полезная нагрузка JSON возвращает точный снимок провайдера (`UsageSnapshot`), чтобы внешние инструменты имели доступ к достоверным данным об использовании вышестоящих ресурсов и к параметрам `quotaWindowThresholds` на уровне подключения без масштабирования с потерей данных на стороне сервера. #### Рекомендации по миграции для потребителей Если внешняя интеграция (например, плагин редактора или расширение агента) ранее извлекала данные из текстовой конечной точки (`NN% left`) и вычисляла процент использования как `100 - NN`, то при переходе на `?format=json` следует учитывать следующее: - Необработанные значения JSON будут отражать **фактическое потребление вышестоящего ресурса** (в приведённом выше примере использовано 60%). - Если интеграции требуется сохранить семантику доступного объёма из текстовой конечной точки, она может вычислять формулу эффективного оставшегося объёма на стороне клиента, используя `quotaWindowThresholds` для переопределений на уровне подключения. --- ## Семантический кеш ```bash # Получить статистику кеша GET /api/cache/stats # Очистить все кеши DELETE /api/cache/stats ``` Пример ответа: ```json { "semanticCache": { "memorySize": 42, "memoryMaxSize": 500, "dbSize": 128, "hitRate": 0.65 }, "idempotency": { "activeKeys": 3, "windowMs": 5000 } } ``` ### Влияние на задержку При попадании в семантический кеш ответ предоставляется из кеша **без запроса к вышестоящему сервису**, поэтому значение `X-OmniRoute-Response-Latency` будет близко к нулю (независимо от исходной задержки вышестоящего сервиса). Клиентам, чувствительным к задержкам (тестирование производительности, мониторинг p50/p99), следует проверять заголовок ответа `X-OmniRoute-Cache-Latency`: | Значение | Значение | | --------------- | ---------------------------------------------------------------------------------------------- | | `synthetic` | Ответ предоставлен из кеша; задержка не отражает реальное время запроса к вышестоящему сервису | | _(отсутствует)_ | Ответ получен в результате реального запроса к вышестоящему сервису | ### Обход кеша для отдельных ключей API-ключи могут отключать чтение из семантического кеша с помощью `cacheDefaultMode`: | Значение | Поведение | | -------- | --------------------------------------------------------------------------- | | `legacy` | Обычное поведение кеша (по умолчанию) | | `bypass` | Полностью пропускать поиск в кеше; всегда обращаться к вышестоящему сервису | Задаётся при создании ключа (`POST /api/keys`) или обновлении (`PATCH /api/keys/[id]`): ```json { "cacheDefaultMode": "bypass" } ``` ### Обход кеша для отдельного запроса Любой запрос может обойти кеш независимо от настроек ключа: ``` X-OmniRoute-No-Cache: true ``` --- ## Панель управления и администрирование Маршруты управления (`/api/*`, кроме общедоступных маршрутов аутентификации/входа) **не** авторизуются с помощью обычных API-ключей для инференса. Семейства учетных данных, области действия и примеры curl: [Аутентификация управления](../guides/MANAGEMENT-AUTH.md). ### Аутентификация | Конечная точка | Метод | Описание | | ----------------------------- | ------- | -------------------------- | | `/api/auth/login` | POST | Вход | | `/api/auth/logout` | POST | Выход | | `/api/settings/require-login` | GET/PUT | Включение требования входа | ### Управление провайдерами | Конечная точка | Метод | Описание | | --------------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/providers` | GET/POST | Получение списка / создание провайдеров | | `/api/providers/[id]` | GET/PUT/DELETE | Управление провайдером | | `/api/providers/[id]/test` | POST | Проверка подключения к провайдеру | | `/api/providers/[id]/models` | GET | Получение списка моделей провайдера | | `/api/providers/validate` | POST | Проверка конфигурации провайдера | | `/api/providers/bulk` | POST | Массовое добавление API-ключей для ОДНОГО провайдера | | `/api/providers/import` | POST | Импорт разнородного СПИСКА провайдеров из разобранного файла CSV/JSON (#6836); результаты с частичными ошибками для каждой строки | | `/api/provider-nodes*` | Различные | Управление узлами провайдера | | `/api/provider-models` | GET/POST/PUT/PATCH/DELETE | Пользовательские модели и переопределения для отдельных моделей (добавление, обновление, скрытие/отображение, удаление) | | `/api/provider-models/validate-and-add` | POST | Аутентифицированная для управления, явно включаемая строгая проверка подключения и атомарная регистрация пользовательской модели; см. [Проверка модели](../guides/MODEL-VALIDATION.md) | Для синхронизированных/импортированных моделей `PUT /api/provider-models` принимает `provider`, `modelId` и `maxOutputTokenOverride`: положительное целое число задает установленное вручную ограничение выходных токенов, а `null` сбрасывает его, восстанавливая значение по умолчанию. `GET /api/provider-models?provider=` возвращает эти значения в `modelOutputOverrides`, включая модели без строки пользовательской модели. Переопределение использует возможность среды выполнения `max_output_tokens` и сохраняется после повторной синхронизации модели. Страница OpenAI-совместимого провайдера предлагает те же элементы управления для изменения/сброса и отмечает модели с явно заявленной поддержкой компьютерного зрения. Пользовательские узлы Chat Completions адаптируют явный отказ от рассуждений для вышестоящего бэкенда. Успешная проверка подключения автоматически выбирает элементы управления шаблоном чата для каждого точного идентификатора модели, чья запись `/models` подтверждает распознанное значение `owned_by`: `vllm`, `sglang` или `llamacpp`. Прозрачные OpenAI-совместимые обертки могут сохранять исходную запись модели во вложенном объекте `openai`; обнаружение проходит не более чем через три такие обертки. Модели с отсутствующей, неизвестной или противоречивой принадлежностью сохраняют обычное поведение OpenAI. Обнаружение повторно использует существующий запрос каталога, не генерирует токены завершения и становится недействительным при изменении конечной точки подключения. Чтобы закрепить это поведение для бэкенда, который не предоставляет такие метаданные, используйте существующий API частичного обновления провайдера: ```json { "providerSpecificData": { "reasoningControl": "chat-template" } } ``` Отправьте это тело с помощью `PUT /api/providers/`. Для этого подключения явно заданное усилие рассуждения `none` передается как `chat_template_kwargs.thinking=false` и `chat_template_kwargs.enable_thinking=false`. Явно заданные нативные значения шаблона сохраняют приоритет, если только серверное правило рассуждений не задает усилие принудительно. Эта настройка применяется только тогда, когда пользовательское OpenAI-совместимое подключение отправляет тело Chat Completions; запросы Responses и обычные провайдеры сохраняют нативную структуру запросов. Установите для `reasoningControl` значение `openai`, чтобы принудительно использовать обычную сквозную передачу OpenAI-параметра `reasoning_effort`, либо опустите его/задайте `null`, чтобы использовать автоматическое обнаружение. Запросы классификатора автоматического режима Claude Code по умолчанию отключают нативное мышление, если они не содержат явных настроек рассуждения. Для обнаружения используется системный маркер классификатора в запросах формата Claude, а не имена моделей или ограничения генерации. Явные настройки в теле запроса, поддерживаемые заголовки усилия/мышления, правила маршрутизации и определённый уровень усилия модели сохраняют свой текущий приоритет. Оба этапа классификатора сохраняют свои промпты, ограничения генерации, стоп-последовательности и реальные вердикты вышестоящего сервиса о разрешениях; второй этап по-прежнему может выдавать запрошенные видимые рассуждения как обычный текст. ### Потоки OAuth | Эндпоинт | Метод | Описание | | -------------------------------- | ------ | -------------------------------- | | `/api/oauth/[provider]/[action]` | Разные | OAuth для конкретного провайдера | ### Маршрутизация и конфигурация | Эндпоинт | Метод | Описание | | --------------------- | -------- | ------------------------------- | | `/api/models/alias` | GET/POST | Псевдонимы моделей | | `/api/models/catalog` | GET | Все модели по провайдеру и типу | | `/api/combos*` | Разные | Управление комбинациями | | `/api/keys*` | Разные | Управление API-ключами | | `/api/pricing` | GET | Цены на модели | ### Использование и аналитика | Эндпоинт | Метод | Описание | | -------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/usage/history` | GET | История использования | | `/api/usage/logs` | GET | Журналы использования | | `/api/usage/request-logs` | GET | Журналы на уровне запросов | | `/api/usage/[connectionId]` | GET | Использование для каждого подключения | | `/api/usage/token-limits` | GET/POST/DELETE | Бюджеты лимитов токенов для каждого API-ключа | | `/api/usage/model-latency-stats` | GET | Скользящие агрегированные показатели задержки по провайдеру/модели (avg/p50/p95/p99, доля успешных запросов); фильтры: `windowHours`/`minSamples`/`maxRows`/`provider`/`model` (#6873) | | `/api/usage/cache-health` | GET | Сводка состояния кеша промптов по `call_logs` — соотношение записей и чтений, распределение размера записи p50/p90/p99, концентрация интенсивных записей, разбивка по моделям и вердикт `healthy`/`degraded`/`thrash`/`no-data`; параметры запроса `range` (`1h`\|`24h`\|`7d`\|`30d`, по умолчанию `24h`) и необязательный параметр `model` (#8827) | ### Разрешения API-ключей `PATCH /api/keys/{id}` обновляет разрешения существующего ключа. Как и для каждого маршрута `/api/keys*`, для него требуется авторизация управления (см. [Аутентификация управления](../guides/MANAGEMENT-AUTH.md)), а не ключ инференса. Отправляйте только те поля, которые хотите изменить; запрос без таких полей отклоняется с сообщением `No valid fields to update`. Допустимые поля определены схемой `updateKeyPermissionsSchema` в `src/shared/validation/schemas/keys.ts`. | Поле | Тип | Примечания | | ------------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | строка, 1–200 символов | | | `isActive` | логическое значение | | | `isBanned` | логическое значение | | | `expiresAt` | дата и время в формате ISO 8601 или `null` | `null` сбрасывает срок действия | | `modelAccessMode` | `all` \| `restricted` | `allowedModels` должен быть пустым, когда установлен режим `all` | | `allowedModels`, `blockedModels` | массив строк, до 1000 элементов | | | `allowedCombos` | массив строк, до 500 элементов | Ограничивает комбинации, которые может вызывать ключ; доступ к моделям напрямую регулируется параметрами `modelAccessMode` / `allowedModels` | | `connectionAccessMode` | `all` \| `restricted` | `allowedConnections` должен быть непустым при `restricted` и пустым при `all` | | `allowedConnections` | массив UUID, до 100 элементов | | | `allowAutoCombos` | логическое значение | `false` отклоняет запросы к моделям `auto/*` с этим ключом; ключам, для которых значение не задано, доступ разрешён | | `catalogScope` | `all` \| `combos` \| `models` | Определяет, что возвращает `GET /v1/models` для этого ключа (только комбинации, только модели или и то и другое); не изменяет доступные для вызова ресурсы | | `noLog`, `autoResolve` | логическое значение | | | `throttleDelayMs` | целое число, 0–300000 | | | `maxSessions` | целое число, 0–10000 | | | `rateLimits` | массив объектов `{ limit, window }` (положительные целые числа, до 50 элементов) или `null` | `null` сбрасывает ограничения | | `accessSchedule` | объект расписания или `null` | `null` сбрасывает расписание | | `scopes` | массив строк, до 32 элементов | | | `allowedEndpoints` | массив строк, до 20 элементов | | | `streamDefaultMode` | `legacy` \| `json` | | | `cacheDefaultMode` | `legacy` \| `bypass` | См. [Обход кеша для отдельного ключа](#per-key-cache-bypass) | | `compressionEnabled` | логическое значение | | | `codexServiceMode` | один из режимов службы Codex | | | `disableNonPublicModels` | логическое значение | | | `allowUsageCommand` | boolean | | | `usageLimitEnabled` | boolean | | | `dailyUsageLimitUsd`, `weeklyUsageLimitUsd` | number >= 0 или `null` | | | `chaosModeEnabled` | boolean | | ```bash curl -X PATCH "$OMNIROUTE_URL/api/keys/$KEY_ID" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "allowAutoCombos": false, "catalogScope": "combos" }' ``` ### Настройки | Конечная точка | Метод | Описание | | ------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/settings` | GET/PUT/PATCH | Общие настройки | | `/api/settings/proxy` | GET/PUT | Конфигурация сетевого прокси | | `/api/settings/proxy/test` | POST | Проверка подключения через прокси | | `/api/settings/ip-filter` | GET/PUT | Список разрешённых/заблокированных IP-адресов | | `/api/settings/thinking-budget` | GET/PUT | Режим перезаписи **запроса** на обдумывание/рассуждение (без изменений / автоудаление / пользовательский / адаптивный). Не зависит от сжатия. См. [THINKING_BUDGET.md](../guides/THINKING_BUDGET.md). | | `/api/settings/system-prompt` | GET/PUT | Глобальный системный промпт | | `/api/settings/compression` | GET/PUT | Глобальная конфигурация сжатия | | `/api/settings/purge-request-history` | POST | Очистка строк журнала запросов и локальных артефактов журнала вызовов | ### Контекст и сжатие | Конечная точка | Метод | Описание | | -------------------------------------- | -------------- | ----------------------------------------------------------------------------------------- | | `/api/compression/preview` | POST | Предварительный просмотр сжатия off/lite/standard/aggressive/ultra/RTK/stacked | | `/api/compression/language-packs` | GET | Список доступных языковых пакетов Caveman | | `/api/compression/rules` | GET | Список метаданных правил Caveman | | `/api/context/caveman/config` | GET/PUT | Псевдоним настроек Caveman | | `/api/context/rtk/config` | GET/PUT | Настройки RTK, включая пользовательские фильтры и хранение необработанного вывода | | `/api/context/rtk/filters` | GET | Каталог фильтров RTK и диагностика пользовательских фильтров | | `/api/context/rtk/test` | POST | Запуск предварительного просмотра/теста RTK для текстовой полезной нагрузки | | `/api/context/rtk/raw-output/[id]` | GET | Чтение сохранённого отредактированного необработанного вывода по идентификатору указателя | | `/api/context/combos` | GET/POST | Получение списка/создание комбинаций сжатия | | `/api/context/combos/[id]` | GET/PUT/DELETE | Получение сведений/обновление/удаление комбинации сжатия | | `/api/context/combos/[id]/assignments` | GET/PUT | Назначение комбинаций сжатия комбинациям маршрутизации | | `/api/context/analytics` | GET | Псевдоним аналитики сжатия | ### Мониторинг | Эндпоинт | Метод | Описание | | ------------------------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/sessions` | GET | Отслеживание активных сессий | | `/api/rate-limits` | GET | Ограничения частоты запросов для каждой учётной записи | | `/api/monitoring/health` | GET | Проверка работоспособности и сводка по провайдерам (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`). Представление управления включает `credentialHealth`: скалярные значения кеша проверок, `failedConnections`, когда `failed>0`, и `staleDbNonOkCount` (закреплённый `test_status` SQLite, а не измеряемый показатель). См. [MONITORING_GUIDE.md](../ops/MONITORING_GUIDE.md#credentialhealth-probe-cache-vs-sqlite-test_status). | | `/api/cache/stats` | GET/DELETE | Статистика кеша / очистка | | `/api/modality-bridge/stats` | GET | Хранящиеся в памяти `attempts`, успешные попытки/`bridged`, сбои, попадания в кеш, `totalLatencyMs`, `latencySamples`, рассчитанное по выборкам `averageLatencyMs` и время последнего использования (сбрасываются при перезапуске; требуется аутентификация управления) | | `/api/modality-bridge/video/runtime` | GET | Строгая проверка доверенного loopback-интерфейса перед аутентификацией управления/проверкой; санитизированные сведения о доступности и версиях FFmpeg/ffprobe (без сохранения в кеше) | | `/api/modality-bridge/video/extract` | POST | Внутренний аутентифицированный брокер байтов через доверенный loopback-интерфейс; входные данные до 50 МиБ, ограниченная очередь/выходные данные до 32 МиБ, `503` при исчерпании ресурсов, `499` при отключении, `504` при превышении крайнего срока; не является публичным API загрузки файлов | ### Резервное копирование и экспорт/импорт | Эндпоинт | Метод | Описание | | --------------------------- | ----- | -------------------------------------------------------------------------------- | | `/api/db-backups` | GET | Вывод списка доступных резервных копий | | `/api/db-backups` | PUT | Создание резервной копии вручную | | `/api/db-backups` | POST | Восстановление из указанной резервной копии | | `/api/db-backups/export` | GET | Скачивание базы данных в виде файла .sqlite | | `/api/db-backups/import` | POST | Загрузка файла .sqlite для замены базы данных (`?dryRun=true` — только проверка) | | `/api/db-backups/exportAll` | GET | Скачивание полной резервной копии в виде архива .tar.gz | `/api/db-backups/export`, `/api/db-backups/exportAll` и `/api/settings/export-json` предоставляют все сохранённые учётные данные, поэтому требуют сессию панели управления или локальный CLI (либо отключённый вход). API-ключи с любой областью действия и токены доступа `oma_` получают `403`. `/api/db-backups/export`, `/api/db-backups/exportAll` and `/api/settings/export-json` hand out every stored credential, so they require the dashboard session or the local CLI (or login disabled). API keys of any scope and `oma_` access tokens get `403`. The restores hold the same boundary: `POST /api/db-backups/import` (`dryRun=true` included), `POST /api/db-backups` (restore by id) and `POST /api/settings/import-json` replace the live database or settings, so a machine credential gets `403` there too; `omniroute sync import` sends the local CLI credential. ### Облачная синхронизация | Эндпоинт | Метод | Описание | | ---------------------- | --------- | ------------------------------- | | `/api/sync/cloud` | Различные | Операции облачной синхронизации | | `/api/sync/initialize` | POST | Инициализация синхронизации | | `/api/cloud/*` | Различные | Управление облачными ресурсами | ### Туннели | Эндпоинт | Метод | Описание | | -------------------------- | ----- | ------------------------------------------------------------------------- | | `/api/tunnels/cloudflared` | GET | Получить статус установки и выполнения Cloudflare Quick Tunnel для панели | | `/api/tunnels/cloudflared` | POST | Включить или отключить Cloudflare Quick Tunnel (`action=enable/disable`) | | `/api/tunnels/ngrok` | GET | Получить статус выполнения ngrok Tunnel для панели | | `/api/tunnels/ngrok` | POST | Включить или отключить ngrok Tunnel (`action=enable/disable`) | ### Инструменты CLI | Эндпоинт | Метод | Описание | | ---------------------------------- | ----- | --------------------------------------- | | `/api/cli-tools/claude-settings` | GET | Статус Claude CLI | | `/api/cli-tools/codex-settings` | GET | Статус Codex CLI | | `/api/cli-tools/droid-settings` | GET | Статус Droid CLI | | `/api/cli-tools/openclaw-settings` | GET | Статус OpenClaw CLI | | `/api/cli-tools/runtime/[toolId]` | GET | Среда выполнения общего CLI-инструмента | Ответы CLI включают: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. ### Агенты ACP | Эндпоинт | Метод | Описание | | ----------------- | ------ | ------------------------------------------------------------------------------------- | | `/api/acp/agents` | GET | Получить список всех обнаруженных агентов (встроенных и пользовательских) со статусом | | `/api/acp/agents` | POST | Добавить пользовательского агента или обновить кеш обнаружения | | `/api/acp/agents` | DELETE | Удалить пользовательского агента по параметру запроса `id` | Ответ GET включает `agents[]` (id, name, binary, version, installed, protocol, isCustom) и `summary` (total, installed, notFound, builtIn, custom). ### Отказоустойчивость и ограничения частоты запросов | Эндпоинт | Метод | Описание | | --------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------- | | `/api/resilience` | GET/PATCH | Получить или обновить очередь запросов, период ожидания подключения, прерыватель провайдера и настройки ожидания | | `/api/resilience/reset` | POST | Сбросить прерыватели цепи провайдеров | | `/api/resilience/model-cooldowns` | GET | Получить список активных блокировок для сочетаний (провайдер, подключение, модель), отсортированный по оставшемуся времени | | `/api/resilience/model-cooldowns` | DELETE | Снять блокировку модели — тело `{provider, model}` или `{all: true}` для полной очистки | | `/api/rate-limits` | GET | Статус ограничения частоты запросов для каждой учётной записи | | `/api/rate-limit` | GET | Глобальная конфигурация ограничения частоты запросов | > Все четыре маршрута `/api/resilience/*` требуют **управленческой аутентификации** (`requireManagementAuth`). Полное описание различий между прерывателем провайдера, периодом ожидания подключения и блокировкой модели см. в разделе [Отказоустойчивость (расширенное описание)](#resilience-extended). ### Оценивания | Эндпоинт | Метод | Описание | | ------------ | -------- | ----------------------------------------------------- | | `/api/evals` | GET/POST | Получить список наборов тестов / запустить оценивание | ### Политики | Эндпоинт | Метод | Описание | | --------------- | --------------- | ----------------------------------- | | `/api/policies` | GET/POST/DELETE | Управление политиками маршрутизации | ### Соответствие требованиям | Эндпоинт | Метод | Описание | | --------------------------- | ----- | ------------------------------------------------------------ | | `/api/compliance/audit-log` | GET | Журнал аудита соответствия требованиям (последние N записей) | ### v1beta (совместимость с Gemini) | Эндпоинт | Метод | Описание | | -------------------------- | ----- | ---------------------------------------- | | `/v1beta/models` | GET | Получить список моделей в формате Gemini | | `/v1beta/models/{...path}` | POST | Эндпоинт Gemini `generateContent` | Эти эндпоинты воспроизводят формат API Gemini для клиентов, которым требуется совместимость с нативным SDK Gemini. ### Внутренние / системные API | Эндпоинт | Метод | Описание | | ------------------------ | ----- | --------------------------------------------------------------------- | | `/api/init` | GET | Проверка инициализации приложения (используется при первом запуске) | | `/api/tags` | GET | Совместимые с Ollama теги моделей (для клиентов Ollama) | | `/api/restart` | POST | Инициировать корректный перезапуск сервера | | `/api/shutdown` | POST | Инициировать корректное завершение работы сервера | | `/api/system/env/repair` | POST | Восстановить переменные окружения OAuth-провайдера | | `/api/system/version` | GET | Текущая/последняя версия, статус обновления и канал выпуска | | `/api/system/version` | POST | Запустить обновление до последней версии с учётом среды развёртывания | > **Примечание:** Эти эндпоинты используются системой для внутренних нужд или для обеспечения совместимости с клиентами Ollama. Обычно конечные пользователи не обращаются к ним напрямую. ### Восстановление окружения OAuth _(v3.6.1+)_ ```bash POST /api/system/env/repair Content-Type: application/json { "provider": "claude-code" } ``` Восстанавливает отсутствующие или повреждённые переменные окружения OAuth для указанного провайдера. Возвращает: ```json { "success": true, "repaired": ["CLAUDE_CODE_OAUTH_CLIENT_ID", "CLAUDE_CODE_OAUTH_CLIENT_SECRET"], "backupPath": "/home/user/.omniroute/backups/env-repair-2026-04-11.bak" } ``` ### Версия и канал выпуска ```bash GET /api/system/version ``` Маршрут управления, доступный только через loopback-интерфейс (аутентификация администратора). Возвращает запущенную версию, последнюю опубликованную версию и состояние автоматического обновления. `releaseChannel` и `channels` — дополнительные поля (ветка 3.8.54); `channel` сохраняет своё значение — режим развёртывания, который использует средство обновления панели управления (`npm`, `source` или `docker-compose`). ```json { "current": "3.8.52", "latest": "3.8.52", "updateAvailable": false, "channel": "npm", "autoUpdateSupported": true, "autoUpdateError": null, "news": null, "releaseChannel": "latest", "channels": { "latest": "3.8.52", "next": "3.8.53-rc.1" } } ``` - `releaseChannel` — npm-канал запущенной сборки: `nightly` для версий `-nightly.*`, `next` для других предварительных выпусков (`-rc.*`, `-beta.*`, `-alpha.*`), `lts` для стабильной версии более старшей основной ветки, чем `channels.latest`, в остальных случаях — `latest`. Используются те же правила, что и в `scripts/release/dist-tag.mjs`, который выбирает npm dist-tag во время публикации. - `channels` — последняя опубликованная версия каждого dist-tag, полученная через `npm view omniroute dist-tags` (с резервным запросом к реестру по HTTP), кэшируемая с тем же TTL в 10 минут, что и `latest`. `latest` присутствует всегда (при недоступности используется поле `latest`, а затем `"unavailable"`); `next`, `nightly` и `lts` отображаются только при наличии соответствующего dist-tag. Запрос с `Cache-Control: no-cache` обновляет результаты обоих запросов. Модель каналов (`latest` = v3 до общедоступного выпуска 4.0, `next` = rc, `nightly` = сборки `develop`, `lts` = исправления v3 после общедоступного выпуска 4.0) описана в `docs/ops/RELEASE_STRATEGY.md`. --- ## Транскрипция аудио ```bash POST /v1/audio/transcriptions Authorization: Bearer your-api-key Content-Type: multipart/form-data ``` Транскрибируйте аудиофайлы с помощью любого настроенного провайдера STT. Первый сегмент пути выбирает нативного провайдера (`openai/…`, `deepgram/…`). Для шлюзов, которые повторно экспортируют модель другого поставщика, используется квалифицированный идентификатор (`openrouter/deepgram/nova-3`). **Запрос:** ```bash curl -X POST http://localhost:20128/v1/audio/transcriptions \ -H "Authorization: Bearer your-api-key" \ -F "file=@recording.mp3" \ -F "model=openai/whisper-1" ``` **Ответ:** ```json { "text": "Здравствуйте, это транскрибированное содержимое аудиозаписи.", "task": "transcribe", "language": "en", "duration": 12.5 } ``` **Примеры идентификаторов моделей:** `openai/whisper-1` (требуется ключ OpenAI), `openrouter/deepgram/nova-3` (требуется ключ OpenRouter), `deepgram/nova-3` (требуется нативный ключ Deepgram). Запрос только с `deepgram/nova-3` **не** использует OpenRouter. **Поддерживаемые форматы:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. --- ## Совместимость с Ollama Для клиентов, использующих формат API Ollama: ```bash # Эндпоинт чата (формат Ollama) POST /v1/api/chat # Получение списка моделей (формат Ollama) GET /api/tags ``` Запросы автоматически преобразуются между форматами Ollama и внутренними форматами. ## Токенизированные псевдонимы VS Code без заголовков Используйте эти псевдонимы, если интеграция не может добавить заголовок `Authorization` и требуется встроить ключ API в базовый URL. ```bash # Псевдоним каталога в стиле OpenAI GET /api/v1/vscode/{token}/ GET /api/v1/vscode/{token}/models # Псевдонимы чата в стиле OpenAI POST /api/v1/vscode/{token}/chat/completions POST /api/v1/vscode/{token}/responses # Псевдонимы в стиле Ollama POST /api/v1/vscode/{token}/api/chat GET /api/v1/vscode/{token}/api/tags ``` Пример: ```bash curl https://your-host.example/api/v1/vscode/YOUR_API_KEY/models curl -X POST https://your-host.example/api/v1/vscode/YOUR_API_KEY/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"auto","messages":[{"role":"user","content":"hello"}]}' ``` Примечания: - Токенизированные псевдонимы используют те же обработчики, что и `/v1/*` и `/api/tags`; структуры ответов остаются идентичными. - По возможности используйте `Authorization: Bearer ...`, если клиент поддерживает пользовательские заголовки. - Токены в URL могут появляться в журналах обратного прокси, истории браузера и телеметрии за пределами OmniRoute. Рассматривайте их как вариант для обеспечения совместимости, а не как режим аутентификации по умолчанию. --- ## Телеметрия ```bash # Получение сводки телеметрии задержек (p50/p95/p99 для каждого провайдера) GET /api/telemetry/summary ``` **Ответ:** ```json { "providers": { "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } } } ``` --- ## Бюджет ```bash # Получение состояния бюджета для всех ключей API GET /api/usage/budget # Установка или обновление бюджета POST /api/usage/budget Content-Type: application/json { "apiKeyId": "key-123", "dailyLimitUsd": 5.00, "weeklyLimitUsd": 30.00, "monthlyLimitUsd": 100.00, "warningThreshold": 0.8, "resetInterval": "monthly" } ``` > **Примечания к схеме** (`setBudgetSchema`): поле `apiKeyId` является обязательным; хотя бы одно из полей `dailyLimitUsd`, `weeklyLimitUsd` или `monthlyLimitUsd` должно иметь значение больше нуля. Необязательные поля: `warningThreshold` (0–1), `resetInterval` (`daily` | `weekly` | `monthly`), `resetTime` (`HH:MM`). Устаревшая структура `{keyId, limit, period}` возвращает `400 Bad Request`. ## Лимиты токенов Бюджеты **токенов** для каждого API-ключа (отличаются от указанного выше бюджета в USD). Применяются непосредственно при обработке запроса: когда использование ключа в текущем временном окне достигает установленного лимита, запросы отклоняются с ошибкой `429 Too Many Requests`. Лимиты могут быть привязаны к конкретной `model`, `provider` или применяться `global` ко всему ключу; если запрос соответствует нескольким лимитам, применяется самый строгий из них. ```bash # Получить список лимитов токенов ключа (включая текущее использование окна) GET /api/usage/token-limits?apiKeyId=key-123 # Создать или обновить лимит токенов POST /api/usage/token-limits Content-Type: application/json { "apiKeyId": "key-123", "scopeType": "model", "scopeValue": "openai/gpt-4o", "tokenLimit": 1000000, "resetInterval": "monthly", "enabled": true } # Удалить лимит токенов по идентификатору DELETE /api/usage/token-limits?id=tl-abc ``` > **Примечания к схеме** (`setTokenLimitSchema`): `apiKeyId` и `scopeType` (`model` | `provider` | `global`) обязательны. `scopeValue` обязателен, кроме случаев, когда `scopeType` имеет значение `global` (например, идентификатор модели для области действия `model` или идентификатор провайдера для области действия `provider`). `tokenLimit` должен быть положительным целым числом (строка автоматически преобразуется в число). Необязательные поля: `id` (не указывайте для создания, укажите для обновления), `resetInterval` (`daily` | `weekly` | `monthly`, по умолчанию `monthly`), `resetTime` (`HH:MM`), `enabled` (по умолчанию `true`). Ответы `GET` дополняют каждый лимит полями `tokensUsed`, `remaining`, `windowStart`, `periodStartAt` и `nextResetAt`. Это конечная точка класса управления (аутентификация централизованно обеспечивается конвейером авторизации). ## Обработка запросов 1. Клиент отправляет запрос в `/v1/*` 2. Обработчик маршрута вызывает `handleChat`, `handleEmbedding`, `handleAudioTranscription` или `handleImageGeneration` 3. Определяется модель (непосредственно через провайдера/модель либо через псевдоним/комбинацию) 4. Учётные данные выбираются из локальной базы данных с фильтрацией по доступности учётной записи 5. Для чата: `handleChatCore` проверяет семантический кэш/кэш сигнатур и определяет настройки сжатия комбинации 6. Если включено упреждающее сжатие, оно выполняется до преобразования запроса для провайдера (`lite`, Caveman, RTK или их сочетание) 7. Исполнитель провайдера отправляет восходящий запрос 8. Ответ преобразуется обратно в клиентский формат (для чата) или возвращается без изменений (для векторных представлений, изображений и аудио) 9. Регистрируются использование, аналитика сжатия и журналы запросов 10. При ошибках применяется резервный вариант в соответствии с правилами комбинации Полное описание архитектуры: [`ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) --- ## Управление комбинациями Комбинации маршрутизации более высокого уровня (уже описанные в разделе `/api/combos*`) также можно сопоставлять с шаблоном идентификатора модели в отношении 1:1, обеспечивая прозрачное перенаправление идентификатора модели в стиле OpenAI на комбинацию. | Метод | Путь | Описание | | ------ | -------------------------------- | ------------------------------------------------------------------------------------- | | GET | `/api/model-combo-mappings` | Получить список всех сопоставлений модель→комбинация | | POST | `/api/model-combo-mappings` | Создать сопоставление — тело: `{pattern, comboId, priority?, enabled?, description?}` | | GET | `/api/model-combo-mappings/[id]` | Получить отдельное сопоставление | | PUT | `/api/model-combo-mappings/[id]` | Обновить поля существующего сопоставления | | DELETE | `/api/model-combo-mappings/[id]` | Удалить сопоставление | **Аутентификация:** сессия управления/API-ключ (`requireManagementAuth`). --- ## Вебхуки Подписки на исходящие вебхуки для событий OmniRoute (завершение запроса, исчерпание квоты, ротация ключей и т. д.). | Метод | Путь | Описание | | ------ | ------------------------- | ----------------------------------------------------------------------------- | | GET | `/api/webhooks` | Список вебхуков (секреты маскируются в формате `...`) | | POST | `/api/webhooks` | Создание вебхука — тело: `{url, events?: ["*"], secret?, description?}` | | GET | `/api/webhooks/[id]` | Получение вебхука | | PUT | `/api/webhooks/[id]` | Обновление url/events/secret/description | | DELETE | `/api/webhooks/[id]` | Удаление вебхука | | POST | `/api/webhooks/[id]/test` | Отправка тестовой полезной нагрузки на URL вебхука и возврат статуса доставки | **Аутентификация:** сеанс управления/API-ключ (`requireManagementAuth`). --- ## Зарегистрированные ключи (автоматическое управление) Используется подсистемой автоматического управления ключами для выпуска и ротации API-ключей у базового провайдера/учётной записи с учётом дневных и почасовых квот. | Метод | Путь | Описание | | ------ | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/registered-keys` | Получить список зарегистрированных ключей (только замаскированный префикс) | | POST | `/api/v1/registered-keys` | Выпустить новый зарегистрированный ключ — тело: `{name, provider?, accountId?, idempotencyKey?, expiresAt?, dailyBudget?, hourlyBudget?}`. Возвращает исходный ключ **один раз**. При отказе из-за квоты возвращает `429`. | | GET | `/api/v1/registered-keys/[id]` | Получить метаданные зарегистрированного ключа (без исходного ключевого материала) | | DELETE | `/api/v1/registered-keys/[id]` | Отозвать зарегистрированный ключ | | POST | `/api/v1/registered-keys/[id]/revoke` | Явная конечная точка для отзыва (действует так же, как DELETE) | **Аутентификация:** сессия управления/API-ключ (`requireManagementAuth`) — та же проверка доступа, что и для `/api/keys`: сессия панели управления, локальный токен CLI или API-ключ с областью доступа `manage`/`admin`; API-ключи, предназначенные только для инференса, получают `403`. См. также `/v1/quotas/check` и `/v1/issues/report`. --- ## Протокол агентов Задачи облачных агентов (Claude Code, Codex Cloud, OpenHands и т. д.), удалённо выполняемые от имени пользователей OmniRoute. | Метод | Путь | Описание | | ------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/agents/tasks` | Список задач — необязательные параметры `?provider=`, `?status=`, `?limit=` (1–500, по умолчанию 50) | | POST | `/api/v1/agents/tasks` | Создание задачи — тело проверяется с помощью `CreateCloudAgentTaskSchema` (`providerId`, `prompt`, `source`, `options?`). Возвращает `201` с оболочкой задачи | | DELETE | `/api/v1/agents/tasks?id=...` | Удаление задачи | | GET | `/api/v1/agents/tasks/[id]` | Получение задачи — синхронно обновляет статус через вышестоящий облачный агент, если задан `external_id` | | POST | `/api/v1/agents/tasks/[id]` | Дискриминированное действие: `{action: "approve"}`, `{action: "message", message}` или `{action: "cancel"}` | | DELETE | `/api/v1/agents/tasks/[id]` | Удаление конкретной задачи по id | > **Аутентификация:** для каждого метода требуется управленческая аутентификация (`requireCloudAgentManagementAuth`). До v3.8.0 эти методы не требовали аутентификации — критическое изменение описано в коммите `588a0333`. ```bash # Создание облачной задачи Claude Code curl -X POST http://localhost:20128/api/v1/agents/tasks \ -H "Authorization: Bearer your-management-key" \ -H "Content-Type: application/json" \ -d '{"providerId":"claude-code-cloud","prompt":"Fix the failing test","source":{"repo":"...","branch":"..."}}' ``` --- ## Управление прокси Исходящие прокси HTTP(S)/SOCKS, которые можно назначать провайдерам, учётным записям или глобально. | Метод | Путь | Описание | | ------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/v1/management/proxies` | Список прокси (с `?id=` возвращает один прокси; с `?id=&where_used=1` возвращает граф назначений) | | POST | `/api/v1/management/proxies` | Создание прокси — тело проверяется с помощью `createProxyRegistrySchema` | | PATCH | `/api/v1/management/proxies` | Обновление прокси — тело проверяется с помощью `updateProxyRegistrySchema` (требуется `id`) | | DELETE | `/api/v1/management/proxies?id=...&force=1` | Удаление прокси (используйте `force=1`, чтобы отменить назначения) | | GET | `/api/v1/management/proxies/assignments` | Список назначений — поддерживает фильтрацию по `proxy_id`, `scope`, `scope_id`; передайте `resolve_connection_id=`, чтобы определить активный прокси для подключения | | PUT | `/api/v1/management/proxies/assignments` | Назначение — тело проверяется с помощью `proxyAssignmentSchema` (`{scope, scopeId?, proxyId?}`). Очищает кеш диспетчера | | PUT | `/api/v1/management/proxies/bulk-assign` | Массовое назначение — тело проверяется с помощью `bulkProxyAssignmentSchema` (`{scope, scopeIds[], proxyId?}`) | | GET | `/api/v1/management/proxies/health?hours=24` | Агрегированное состояние прокси за заданный период (число успешных и неудачных запросов, задержка) | **Аутентификация:** для каждого маршрута требуется управленческая сессия/API-ключ (`requireManagementAuth`). > Указанные в описании задачи маршруты `POST /api/v1/management/proxies/[id]/assignments` и `POST /api/v1/management/proxies/[id]/health` обслуживаются показанными выше плоскими маршрутами `/assignments` и `/health` — в кодовой базе нет отдельных подмаршрутов для каждого id. --- ## Отказоустойчивость (расширенная) OmniRoute предоставляет три независимых механизма обработки временных сбоев; приведённые ниже конечные точки управления позволяют операторам просматривать и переопределять их: | Область | Хранилище состояния | Просмотр | Сброс / очистка | | ------------------------- | ----------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------- | | Предохранитель провайдера | `domain_circuit_breakers` + оперативная память | `/api/monitoring/health` | `POST /api/resilience/reset` | | Задержка подключения | `rateLimitedUntil` в подключениях провайдера | `/api/rate-limits`, `/api/providers/[id]` | (повторно включается отложенно; очистка через PUT провайдера) | | Блокировка модели | Реестр доступности моделей в оперативной памяти | `GET /api/resilience/model-cooldowns` | `DELETE /api/resilience/model-cooldowns` | `PATCH /api/resilience` принимает переопределения предохранителей провайдеров в `providerBreaker.oauth` и `providerBreaker.apikey`. Каждый профиль поддерживает `degradationThreshold`, `failureThreshold` и `resetTimeoutMs`; эти же поля доступны в Панель управления → Настройки → Отказоустойчивость. ```bash # Очистить блокировку одной модели curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -H "Content-Type: application/json" \ -d '{"provider":"openai","model":"gpt-4o-mini"}' # Очистить все блокировки curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -d '{"all":true}' ``` Полное концептуальное описание и значения предохранителей по умолчанию: см. [`CLAUDE.md`](../../CLAUDE.md) → «Состояние среды выполнения отказоустойчивости». --- ## Навыки Платформа навыков для расширения OmniRoute с помощью пользовательских исполняемых обработчиков, а также интеграций с маркетплейсами. | Метод | Путь | Описание | | ------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/skills` | Список установленных навыков — фильтрация по `?q=`, `?mode=on\|off\|auto`, `?source=skillsmp\|skillssh\|local`, с пагинацией | | GET | `/api/skills/[id]` | Получить один навык | | PUT | `/api/skills/[id]` | Обновить навык (имя, описание, режим, схема, обработчик, теги) | | DELETE | `/api/skills/[id]` | Удалить навык | | POST | `/api/skills/install` | Установить навык из исходного манифеста — тело: `{name, version, description, schema:{input, output}, handlerCode, apiKeyId?}` | | GET | `/api/skills/executions` | Список последних выполнений навыков (журнал аудита с входными/выходными данными и длительностью) | | GET | `/api/skills/marketplace?q=...` | Поиск/список популярных навыков из маркетплейса SkillsMP (требуется настройка `skillsmpApiKey`) | | POST | `/api/skills/marketplace/install` | Установить навык по идентификатору из SkillsMP | | GET | `/api/skills/skillssh?q=&limit=` | Поиск в реестре skills.sh | | POST | `/api/skills/skillssh/install` | Установить навык по идентификатору из skills.sh | **Аутентификация:** сеанс управления/API-ключ. Маршруты поиска в маркетплейсах принимают либо аутентификацию управления, либо Bearer API-ключ (`isAuthenticated`). --- ## Память Постоянное хранилище контекстной и фактической памяти, изолированное на уровне API-ключа / сессии. | Метод | Путь | Описание | | ------ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/memory` | Список воспоминаний — `?apiKeyId=`, `?type=`, `?sessionId=`, `?q=`, с пагинацией через `offset/limit` или `page/limit` | | POST | `/api/memory` | Создание воспоминания — тело проверяется с помощью Zod: `{content, key, type?, sessionId?, apiKeyId?, metadata?, expiresAt?}` | | GET | `/api/memory/[id]` | Получение одного воспоминания | | DELETE | `/api/memory/[id]` | Удаление воспоминания | | GET | `/api/memory/health` | Состояние подсистемы памяти (подключение к БД, серверная часть эмбеддингов, состояние векторного индекса) | **Аутентификация:** сессия управления/API-ключ (`requireManagementAuth`). Перечисление `type`: `FACTUAL`, `EPISODIC`, `SEMANTIC`, `PROCEDURAL` (см. `MemoryType` в `src/lib/memory/types.ts`). --- ## Сервер MCP OmniRoute поставляется со встроенным сервером Model Context Protocol с 3 транспортами (stdio, SSE, streamable-http) и инструментами с разграниченными областями доступа. Приведённые ниже конечные точки панели управления считывают данные о состоянии/аудите и проксируют HTTP-транспорты. | Метод | Путь | Описание | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------- | | GET | `/api/mcp/status` | Сигнал активности, транспорт, состояние подключения, последний вызов, наиболее используемые инструменты, доля успешных запросов за 24 ч | | GET | `/api/mcp/tools` | Список инструментов MCP с полями `name`, `description`, `scopes`, `phase`, `auditLevel`, `sourceEndpoints` | | GET | `/api/mcp/sse` | Открытие потока SSE для транспорта SSE (возвращает `503`, если MCP отключён или транспорт не соответствует настройкам) | | POST | `/api/mcp/sse` | Отправка кадра JSON-RPC через транспорт SSE | | GET | `/api/mcp/stream` | Открытие SSE-стороны транспорта Streamable HTTP (сообщения, инициируемые сервером) | | POST | `/api/mcp/stream` | Отправка кадра JSON-RPC через транспорт Streamable HTTP | | DELETE | `/api/mcp/stream` | Завершение сеанса Streamable HTTP | | GET | `/api/mcp/audit` | Запрос журнала аудита — `?limit=`, `?offset=`, `?tool=`, `?success=true | false`, `?apiKeyId=` | | GET | `/api/mcp/audit/stats` | Агрегированная статистика аудита (итоговые значения, доля успешных запросов, средняя длительность, наиболее используемые инструменты) | **Аутентификация:** транспорты `sse`/`stream` используют специализированный механизм аутентификации MCP (Bearer API-ключ с областью доступа `mcp`); маршруты `status`/`tools`/`audit*` доступны для чтения из панели управления (дополнительная аутентификация помимо доступа к хосту панели управления не требуется). > Оба HTTP-транспорта управляются настройками `settings.mcpEnabled` и `settings.mcpTransport` — несоответствие транспорта возвращает `400`, а отключённое состояние MCP возвращает `503`. --- ## Сервер A2A OmniRoute предоставляет конечную точку A2A (Agent-to-Agent) на основе JSON-RPC 2.0, а также REST-обёртку для инспектирования и использования в панели управления. ### JSON-RPC ```bash POST /a2a Authorization: Bearer your-api-key # необязательно, если не задан OMNIROUTE_API_KEY Content-Type: application/json { "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "skill": "smart-routing", "messages": [{"role": "user", "content": "Маршрутизируй эту задачу по программированию"}] } } ``` Поддерживаемые методы (все зависят от `settings.a2aEnabled`): | Метод | Описание | | ---------------- | ---------------------------------------------------------------------- | | `message/send` | Синхронное выполнение навыка; возвращает `{task, artifacts, metadata}` | | `message/stream` | Потоковое выполнение того же набора навыков через SSE | | `tasks/get` | Получение задачи по `taskId` | | `tasks/cancel` | Отмена задачи по `taskId` | Встроенные навыки: `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`. ### Карточка агента ```bash GET /.well-known/agent.json ``` Возвращает публичную карточку агента A2A (имя, описание, возможности, каталог навыков, схема аутентификации), которая публично кэшируется на 1 час. Аутентификация не требуется. ### Вспомогательные REST-маршруты | Метод | Путь | Описание | | ----- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------- | | GET | `/api/a2a/status` | Состояние A2A + статистика задач + сводка кэшированной карточки агента | | GET | `/api/a2a/tasks` | Список задач — `?state=submitted\|working\|completed\|failed\|cancelled`, `?skill=`, `?limit=` (≤200), `?offset=` | | POST | `/api/a2a/tasks` | (Не реализовано как вспомогательный REST-маршрут — создавайте через JSON-RPC `message/send`) | | GET | `/api/a2a/tasks/[id]` | Получение одной задачи | | POST | `/api/a2a/tasks/[id]/cancel` | Отмена задачи | **Аутентификация:** вспомогательные REST-маршруты работают без аутентификации управления (доступны для чтения из панели управления); маршрут JSON-RPC `/a2a` использует Bearer `OMNIROUTE_API_KEY`, если он настроен. --- ## Облако, тесты и оценка | Метод | Путь | Описание | | ------ | ------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------- | ----------------------------------- | | POST | `/api/cloud/auth` | Проверить ключ Bearer и вернуть замаскированные подключения к провайдерам и псевдонимы моделей для клиентов облачной синхронизации | | POST | `/api/cloud/credentials/update` | Обновить зашифрованные учетные данные для провайдера, синхронизированного с облаком | | POST | `/api/cloud/model/resolve` | Сопоставить логический идентификатор модели с конкретным провайдером и моделью, используя локальную таблицу маршрутизации | | GET | `/api/cloud/models/alias` | Получить список псевдонимов моделей, доступных для облачной синхронизации | | GET | `/api/assess` | Получить последние результаты категоризации оценки (для каждой пары провайдер/модель) | | POST | `/api/assess` | Выполнить оценку — тело: `{scope: {type:"all"} | {type:"provider", providerId} | {type:"model", modelId}, trigger?}` | | GET | `/api/evals` | Получить список встроенных наборов тестов и последних запусков | | POST | `/api/evals` | Запустить выполнение тестов | | POST | `/api/evals/suites` | Создать пользовательский набор тестов — тело проверяется с помощью `evalSuiteSaveSchema` | | GET | `/api/evals/suites/[id]` | Получить пользовательский набор тестов | **Аутентификация:** `/api/cloud/auth` напрямую проверяет ключ Bearer и возвращает замаскированный ключ и `projectId` каждого подключения только для ключа с областью доступа `manage` / `admin`; остальные маршруты `/api/cloud/*`, `/api/evals/*` и `/api/assess` требуют сессию управления/API-ключ. POST-запрос `/api/assess` использует `validateBody` со схемой области действия на основе размеченного объединения. --- ## Управление ACP (Agent Client Protocol) как дочерними процессами. Эти конечные точки управляют обнаружением ACP-агентов и регистрацией пользовательских агентов. | Метод | Путь | Описание | | ------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/acp/agents` | Получение списка всех известных CLI-агентов (встроенных и пользовательских) со статусом установки, версией и исполняемым файлом | | POST | `/api/acp/agents` | Регистрация пользовательского ACP-агента или обновление кеша — тело: `{id, name, binary, versionCommand, providerAlias, spawnArgs, protocol}` или `{action: "refresh"}` | | DELETE | `/api/acp/agents` | Удаление пользовательского ACP-агента — параметр запроса: `?id=` | **Пример ответа** (`GET /api/acp/agents`): ```json { "agents": [ { "id": "claude", "name": "Claude Code CLI", "binary": "claude", "version": "1.0.45", "installed": true, "protocol": "stdio", "providerAlias": "claude", "isCustom": false }, { "id": "my-custom-cli", "name": "My Custom CLI", "installed": false, "protocol": "stdio", "providerAlias": "my-provider", "isCustom": true } ], "cacheTtlMs": 60000, "cacheAge": 1234 } ``` **Аутентификация:** Требуется сеанс управления (файл cookie `auth_token` панели управления) или API-ключ с областью действия управления. Полную информацию см. в разделе [Фреймворк ACP](../frameworks/ACP.md). --- ## Аналитика и наблюдаемость Конечные точки аналитики в реальном времени для мониторинга маршрутизации, сжатия и разнообразия провайдеров. Они обеспечивают работу страниц `/dashboard/analytics/*`. ### Аналитика автоматической маршрутизации | Метод | Путь | Описание | | ----- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/auto-routing` | Агрегированная статистика автоматической маршрутизации: общее число вызовов, распределение по стратегиям и уровням, ведущие провайдеры | | GET | `/api/analytics/auto-routing?days=7` | Статистика за временной интервал (по умолчанию 24 ч) | **Пример ответа**: ```json { "window": "24h", "totalCalls": 1234, "strategyBreakdown": { "rules": 800, "cost": 200, "latency": 150, "sla-aware": 50, "lkgp": 34 }, "tierBreakdown": { "ultra": 100, "pro": 500, "standard": 400, "free": 234 }, "topProviders": [ { "provider": "openai", "calls": 500, "avgLatencyMs": 850 }, { "provider": "anthropic", "calls": 300, "avgLatencyMs": 1200 } ] } ``` ### Аналитика сжатия | Метод | Путь | Описание | | ----- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/compression` | Агрегированная статистика сжатия: сэкономленные токены, процент экономии, распределение по режимам, использование движков | **Пример ответа**: ```json { "window": "24h", "totalOriginalTokens": 5000000, "totalCompressedTokens": 3500000, "totalSavings": 1500000, "savingsPct": 30.0, "modeBreakdown": { "lite": 400, "standard": 600, "aggressive": 100, "ultra": 50, "rtk": 84 }, "engineBreakdown": { "caveman": 800, "rtk": 434 } } ``` ### Отслеживание разнообразия провайдеров | Метод | Путь | Описание | | ----- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/diversity` | Отслеживание разнообразия на основе энтропии Шеннона: предотвращает единые точки отказа путём измерения распределения нагрузки между провайдерами | **Пример ответа**: ```json { "window": "24h", "shannonEntropy": 2.45, "maxEntropy": 3.17, "diversityRatio": 0.77, "providerUsage": { "openai": 0.4, "anthropic": 0.25, "google": 0.2, "kiro": 0.15 }, "warnings": ["OpenAI accounts for 40% of traffic — consider diversifying"] } ``` **Аутентификация:** Требуется сеанс управления или API-ключ с областью действия управления. --- ## Административные операции Доступные только администраторам конечные точки для операционного управления. | Метод | Путь | Описание | | ----- | ------------------------ | --------------------------------------------------------------------------------------------------- | | GET | `/api/admin/concurrency` | Получить текущие ограничения параллелизма (глобальные и для каждого провайдера) | | POST | `/api/admin/concurrency` | Обновить ограничения параллелизма — тело: `{global?: number, perProvider?: Record}` | **Аутентификация:** Требуется сеанс управления с областью доступа администратора. --- ## Управление инструментами CLI Управление инструментами CLI, интегрированными с OmniRoute (antigravity, commandCode, devin-cli и т. д.). Полный список см. в [справочнике по провайдерам](./PROVIDER_REFERENCE.md). | Метод | Путь | Описание | | ----- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/cli-tools/all-statuses` | Состояние всех инструментов CLI (установлен, версия, время последнего обнаружения) | | GET | `/api/cli-tools/status` | Подробное состояние одного инструмента CLI (параметр запроса `?tool=`) | | POST | `/api/cli-tools/apply` | Записывает сгенерированную конфигурацию инструмента (`dryRun` — предварительный просмотр; `422` + `containerEphemeralTarget` при запуске в контейнере; `migration` содержит примечание об устаревшем YAML-файле Codex) | | GET | `/api/cli-tools/backups` | Выводит список резервных копий конфигураций инструментов CLI | | POST | `/api/cli-tools/backups` | Создаёт резервную копию конфигураций всех инструментов CLI | | POST | `/api/cli-tools/backups` | Восстановление: тот же эндпоинт с `{tool, backupId}` в теле запроса восстанавливает указанную резервную копию | | GET | `/api/cli-tools/antigravity-mitm` | Состояние MITM-прокси Antigravity (инструмент CLI «antigravity-mitm») | | POST | `/api/cli-tools/antigravity-mitm/alias` | Настраивает псевдонимы antigravity-mitm | **Аутентификация:** требуется сеанс управления. --- ## Навыки агентов Управление навыками агентов ИИ (аналогично пользовательским GPT OpenAI, но для агентов). | Метод | Путь | Описание | | ------ | ---------------------------- | ------------------------------------------------------------------------------------------------- | | GET | `/api/agent-skills` | Получить список всех навыков агентов (встроенных и пользовательских) | | GET | `/api/agent-skills/[id]` | Получить определённый навык агента | | POST | `/api/agent-skills` | Создать пользовательский навык агента — тело: `{name, description, prompt, model?, temperature?}` | | PUT | `/api/agent-skills/[id]` | Обновить пользовательский навык агента | | DELETE | `/api/agent-skills/[id]` | Удалить пользовательский навык агента | | GET | `/api/agent-skills/[id]/raw` | Получить исходный промпт и метаданные (без выполнения) | | POST | `/api/agent-skills/generate` | Сгенерировать новый навык с помощью ИИ на основе описания на естественном языке | **Аутентификация:** Требуется сеанс управления или API-ключ с областью доступа для управления. --- ## Управление кешем Управление семантическим кешем и кешем рассуждений. | Метод | Путь | Описание | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/cache` | Обзор кеша: общее количество записей, частота попаданий, размер на диске | | GET | `/api/cache/entries` | Список кешированных записей (с пагинацией) | | DELETE | `/api/cache/entries` | Удаление записей кеша (фильтрация по параметрам запроса) | | GET | `/api/cache/stats` | Подробная статистика кеша (по поставщикам и моделям) | | GET | `/api/cache/reasoning` | Состояние кеша рассуждений (для воспроизведения рассуждений) | | DELETE | `/api/cache/reasoning` | Очистка кеша рассуждений — параметры запроса: `?toolCallId=` (одна запись), `?provider=

` или без параметров (все) | **Аутентификация:** Требуется сеанс управления. --- ## Система памяти Управление постоянной памятью (FTS5 + векторные эмбеддинги). | Метод | Путь | Описание | | ------ | ------------------ | --------------------------------------------------------------------------------- | | GET | `/api/memory` | Список записей памяти (фильтрация по области действия, типу и поисковому запросу) | | POST | `/api/memory` | Создание новой записи памяти — тело: `{scope, type, content, metadata?}` | | GET | `/api/memory/[id]` | Получение определённой записи памяти | | PUT | `/api/memory/[id]` | Обновление записи памяти | | DELETE | `/api/memory/[id]` | Удаление записи памяти | | GET | `/api/memory?q=` | Поиск в памяти (FTS5 + векторный поиск) — статистика включена в тот же ответ | **Аутентификация:** Требуется сеанс управления или API-ключ с областью управления. --- ## Вебхуки Управление подписками вебхуков на события. | Метод | Путь | Описание | | ------ | ------------------------------- | -------------------------------------------------------------------------- | | GET | `/api/webhooks` | Список всех подписок вебхуков | | POST | `/api/webhooks` | Создание подписки вебхука — тело: `{url, events[], secret?, active?}` | | GET | `/api/webhooks/[id]` | Получение определённой подписки вебхука | | PUT | `/api/webhooks/[id]` | Обновление подписки вебхука | | DELETE | `/api/webhooks/[id]` | Удаление подписки вебхука | | GET | `/api/webhooks/[id]/deliveries` | Список истории доставок для вебхука (журнал успешных и неудачных доставок) | | POST | `/api/webhooks/[id]/test` | Отправка тестового события вебхуку | **Аутентификация:** Требуется сеанс управления. Полный список типов событий см. в разделе [Фреймворк вебхуков](../frameworks/WEBHOOKS.md). --- ## Фреймворк Skills Управление Skills (фреймворком агентных расширений). | Метод | Путь | Описание | | ------ | ------------------------ | ------------------------------------------------------------------------------------------ | | GET | `/api/skills` | Получить список всех установленных skills (встроенных и пользовательских) | | POST | `/api/skills/install` | Установить skill из локального пути или URL | | DELETE | `/api/skills/[id]` | Удалить skill | | PUT | `/api/skills/[id]` | Включить или отключить skill — тело: `{enabled?: boolean, mode?: "on" \| "off" \| "auto"}` | | POST | `/api/skills/executions` | Выполнить skill — тело: `{skillName, apiKeyId, input?, sessionId?}` | | GET | `/api/skills/executions` | Получить историю выполнения всех skills (фильтр по `?apiKeyId=`) | **Аутентификация:** Требуется управляющая сессия или API-ключ с областью управления. Полную информацию см. в разделе [Фреймворк Skills](../frameworks/SKILLS.md). --- ## Плагины Управление плагинами OmniRoute (сторонними расширениями). | Метод | Путь | Описание | | ------ | ---------------------------------- | -------------------------------------- | | GET | `/api/plugins` | Получить список установленных плагинов | | POST | `/api/plugins/marketplace/install` | Установить плагин из маркетплейса | | DELETE | `/api/plugins/[name]` | Удалить плагин | | POST | `/api/plugins/[name]/activate` | Активировать плагин | | POST | `/api/plugins/[name]/deactivate` | Деактивировать плагин | | GET | `/api/plugins/[name]/config` | Получить конфигурацию плагина | | PUT | `/api/plugins/[name]/config` | Обновить конфигурацию плагина | **Аутентификация:** Требуется управляющая сессия. Полную информацию см. в разделе [Фреймворк плагинов](../frameworks/PLUGIN_SDK.md). --- ## Теневое маршрутизирование Теневое сравнение провайдеров / A/B-сравнение **не является отдельным REST-интерфейсом** — оно настраивается через комбинированную маршрутизацию (см. [Автоматические комбинации](../routing/AUTO-COMBO.md)). Метрики сравнения для каждой комбинации предоставляются через `GET /api/combos/metrics`. --- ## Защитные механизмы Просмотр защитных механизмов среды выполнения (обнаружение персональных данных, обнаружение инъекций в промпты, промежуточная обработка изображений). Защитные механизмы выполняются при каждом запросе; отказаться от их использования для отдельного вызова можно с помощью заголовка запроса `x-omniroute-disabled-guardrails` — сохраняемого интерфейса включения/отключения не предусмотрено. | Метод | Путь | Описание | | ----- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/guardrails` | Получить список зарегистрированных защитных механизмов и их состояний (имя / включён / приоритет) | | POST | `/api/guardrails/test` | Выполнить пробный прогон конвейера предварительной обработки для примера входных данных — тело: `{input, disabledGuardrails?}` | **Аутентификация:** Требуется управляющая сессия. Полную информацию см. в разделе [Безопасность > Защитные механизмы](../security/GUARDRAILS.md). --- --- ## Аутентификация Описание четырёх типов учётных данных (сессия панели управления, локальный токен CLI, токен доступа `oma_live_…`, API-ключ с областью управления) и их отличий от ключей для инференса см. в разделе [Аутентификация управления](../guides/MANAGEMENT-AUTH.md). - Маршруты панели управления (`/dashboard/*`) используют cookie `auth_token` - Для входа используется сохранённый хеш пароля; резервный вариант — `INITIAL_PASSWORD` - Параметр `requireLogin` можно переключать через `/api/settings/require-login` - Маршруты `/v1/*` могут требовать Bearer API-ключ, если `REQUIRE_API_KEY=true` - Термины «токен управления» / «API-ключ с областью управления» в этом справочнике означают один из типов, описанных в указанном руководстве, а не какой-либо дополнительный неопределённый тип секрета > **Критическое изменение (v3.8.0)** — `/api/v1/agents/tasks/*` и эндпоинты управления периодом ожидания теперь требуют **аутентификацию управления** (cookie `auth_token` панели управления или API-ключ с областью управления). Клиенты, которые ранее обращались к этим маршрутам без аутентификации, теперь получат ответ `401 Unauthorized`. См. коммит `588a0333` (`fix(auth): require management auth for agent and cooldown APIs`).