OpenAI
Конвертация OpenAI API в Meridian — что важно знать при работе с OpenAI через единый интерфейс.
Обзор
OpenAI — это базовая схема для Meridian. При работе с OpenAI напрямую параметры пробрасываются с минимальной конверсией: преимущественно валидация и фильтрация специфичных для OpenAI полей.
Поддерживаемые операции
| Операция | Без стриминга | Стриминг | Эндпоинт |
|---|---|---|---|
| Chat Completions | ✅ | ✅ | /v1/chat/completions |
| Responses API | ✅ | ✅ | /v1/responses |
| Text Completions | ✅ | ✅ | /v1/completions |
| Embeddings | ✅ | — | /v1/embeddings |
| Speech (TTS) | ✅ | ✅ | /v1/audio/speech |
| Transcriptions (STT) | ✅ | ✅ | /v1/audio/transcriptions |
| Image Generation | ✅ | ✅ | /v1/images/generations |
| Image Edit | ✅ | ✅ | /v1/images/edits |
| Image Variation | ✅ | — | /v1/images/variations |
| Files | ✅ | — | /v1/files |
| Batch | ✅ | — | /v1/batches |
| Video Generation | ✅ | — | /v1/videos |
| List Models | ✅ | — | /v1/models |
1. Chat Completions
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели |
messages | array | ✅ | Массив ChatMessage (docs) |
temperature | float | ❌ | Sampling temperature (0–2) |
top_p | float | ❌ | Nucleus sampling |
stop | string/array | ❌ | Стоп-последовательности |
max_completion_tokens | int | ❌ | Минимум 16, максимум — output tokens |
frequency_penalty | float | ❌ | Frequency penalty (−2…2) |
presence_penalty | float | ❌ | Presence penalty (−2…2) |
logit_bias | object | ❌ | Корректировки logit'ов токенов |
logprobs | bool | ❌ | Включить log-вероятности |
top_logprobs | int | ❌ | Количество log-вероятностей на токен |
seed | int | ❌ | Seed для воспроизводимости |
response_format | object | ❌ | Формат вывода (docs) |
tools | array | ❌ | Объекты Tool (docs) |
tool_choice | string/object | ❌ | "auto", "none", "required" или конкретный инструмент |
parallel_tool_calls | bool | ❌ | Разрешить несколько одновременных tool-вызовов |
stream_options | object | ❌ | Параметры стриминга (docs) |
reasoning | object | ❌ | Reasoning-параметры (docs) |
user | string | ❌ | Усечён до 64 символов |
metadata | object | ❌ | Произвольные метаданные |
store | bool | ❌ | Фильтруется при роутинге не в OpenAI |
service_tier | string | ❌ | Фильтруется при роутинге не в OpenAI |
prompt_cache_key | string | ❌ | Фильтруется при роутинге не в OpenAI |
prediction | object | ❌ | Predicted output для ускорения |
audio | object | ❌ | Конфигурация аудио-вывода |
modalities | array | ❌ | Модальности ответа (text, audio) |
- Reasoning. OpenAI поддерживает
reasoning.effort(minimal,low,medium,high) иreasoning.max_tokens— оба пробрасываются напрямую. При роутинге в других провайдеров значение"minimal"приводится к"low"для совместимости. - Сообщения. Поддерживаются все роли:
system,user,assistant,tool,developer(трактуется какsystem). Типы контента: текст, изображения по URL (image_url), аудио-вход (input_audio). Tool-сообщения содержатtool_call_id. - Инструменты. Стандартный формат OpenAI с поддержкой strict-режима. Tool choice:
"auto","none","required"или конкретный инструмент по имени. - Ответы. Пробрасываются в стандартном формате OpenAI. Finish reasons:
stop,length,tool_calls,content_filter. В usage содержатся счётчики токенов, при необходимости — детализация cached/reasoning токенов. - Стриминг. Server-Sent Events с
delta.content,delta.tool_calls,finish_reasonиusage(только в финальном чанке; Meridian подставляет автоматически). По умолчанию для всех стриминговых вызовов выставляетсяstream_options: { include_usage: true }. - Cache control. Поля
cache_controlудаляются из сообщений, content-блоков и определений инструментов перед отправкой. - Token enforcement. Для
max_completion_tokensдействует минимум 16: меньшие значения автоматически приводятся к 16. - Специальная обработка. Поле
userусекается до 64 символов;prompt_cache_key,store,service_tierфильтруются при роутинге к не-OpenAI-провайдерам.
2. Responses API
Responses API — это API структурированного вывода от OpenAI.
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели |
input | string/array | ✅ | Текст или массив ContentBlock (docs) |
max_output_tokens | int | ✅ | Максимальная длина вывода |
background | bool | ❌ | Запуск запроса в фоновом режиме |
conversation | string | ❌ | ID conversation для продолжения диалога |
include | array | ❌ | Поля для включения в ответ (например, "web_search_call.action.sources") |
instructions | string | ❌ | System-инструкции |
max_tool_calls | int | ❌ | Максимальное число tool-вызовов |
metadata | object | ❌ | Произвольные метаданные |
parallel_tool_calls | bool | ❌ | Разрешить параллельные tool-вызовы |
previous_response_id | string | ❌ | ID предыдущего ответа для продолжения |
prompt_cache_key | string | ❌ | Ключ для prompt caching |
reasoning | object | ❌ | Конфигурация ResponsesParametersReasoning |
safety_identifier | string | ❌ | Идентификатор для content filtering |
service_tier | string | ❌ | Service tier для запроса |
stream_options | object | ❌ | Конфигурация ResponsesStreamOptions |
store | bool | ❌ | Сохранить ответ для последующего получения |
temperature | float | ❌ | Sampling temperature |
text | object | ❌ | ResponsesTextConfig для форматирования вывода |
top_logprobs | int | ❌ | Число log-вероятностей на токен |
top_p | float | ❌ | Nucleus sampling |
tool_choice | string/object | ❌ | Стратегия ResponsesToolChoice |
tools | array | ❌ | Объекты ResponsesTool (docs) |
truncation | string | ❌ | Стратегия усечения (auto или off) |
user | string | ❌ | Усечён до 64 символов |
Особая обработка сообщений (gpt-oss vs другие модели). OpenAI обрабатывает reasoning по-разному в зависимости от семейства моделей:
- Не-gpt-oss модели (GPT-4o, o1 и т. п.): reasoning отправляется как summary. Reasoning-only сообщения (без summary, только с content-блоками) фильтруются — эти модели не принимают reasoning-блоки в запросе.
- gpt-oss модели: reasoning отправляется как content blocks. Reasoning-summary в запросе конвертируются в content-блоки, потому что gpt-oss ожидает structured-блоки, а не summary.
Эта конверсия обеспечивает совместимость между разными архитектурами моделей в structured Responses API.
Token & parameter enforcement:
- Для
max_output_tokensдействует минимум 16: меньшие значения автоматически приводятся к 16. - Поле
reasoning.max_tokensавтоматически удаляется из JSON-вывода (OpenAI Responses API его не принимает).
Прочие конверсии:
- Action types
zoomиregionприводятся кscreenshot. - Поля
cache_controlудаляются из сообщений и определений инструментов. - Неподдерживаемые типы инструментов тихо фильтруются (поддерживаются только:
function,file_search,computer_use_preview,web_search,mcp,code_interpreter,image_generation,local_shell,custom,web_search_preview).
Ответ: содержит id, status (completed, incomplete, pending, error), массив output с контентом и usage.
Стриминг: Server-Sent Events с типами событий response.created, response.in_progress, response.output_item.added, response.content_part.added, response.output_text.delta, response.function_call_arguments.delta, response.completed, response.incomplete. По умолчанию для всех стриминговых вызовов выставляется stream_options: { include_usage: true }.
3. Text Completions (legacy)
Text Completions — legacy-API. Для новых интеграций используйте Chat Completions.
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели |
prompt | string/array | ✅ | Промпт(ы) для completion |
max_tokens | int | ❌ | Максимум output-токенов |
temperature | float | ❌ | Sampling temperature |
top_p | float | ❌ | Nucleus sampling |
stop | string/array | ❌ | Стоп-последовательности |
user | string | ❌ | Усечён до 64 символов |
- Массив prompts генерирует несколько completion'ов. Finish reasons:
stopилиlength. Стриминг — SSE-формат, по умолчаниюstream_options: { include_usage: true }. - Поле
userусекается до 64 символов или сбрасывается вnil, если превышает лимит.
4. Embeddings
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели |
input | string/array | ✅ | Текст(ы) для embedding (docs) |
encoding_format | string | ❌ | float или base64 |
dimensions | int | ❌ | Размерность выходного embedding |
user | string | ❌ | НЕ усекается (в отличие от chat/text) |
- Стриминг не поддерживается. Возвращает массив
embeddingсо счётчиками usage.
5. Speech (Text-to-Speech)
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | tts-1 или tts-1-hd |
input | string | ✅ | Текст для синтеза |
voice | string | ✅ | alloy, echo, fable, onyx, nova, shimmer |
response_format | string | ❌ | mp3, opus, aac, flac, wav, pcm |
speed | float | ❌ | 0.25–4.0 (по умолчанию 1.0) |
- Возвращает сырые бинарные аудио-данные. Стриминг поддерживается через SSE (base64-чанки), но не для всех моделей. По умолчанию
stream_options: { include_usage: true }.
6. Transcriptions (Speech-to-Text)
Запросы используют multipart/form-data, а не JSON.
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
file | binary | ✅ | Аудио-файл (multipart form-data) |
model | string | ✅ | whisper-1 |
language | string | ❌ | ISO-639-1 код языка |
prompt | string | ❌ | Подсказывающий контекст |
temperature | float | ❌ | Sampling temperature |
response_format | string | ❌ | json, text, srt, vtt, verbose_json |
- Поддерживаемые форматы аудио: mp3, mp4, mpeg, mpga, m4a, wav, webm.
- Ответ содержит
text,task,language,durationи опционально word-level timing. Стриминг — SSE, по умолчаниюstream_options: { include_usage: true }.
7. Image Generation
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели (например, dall-e-3) |
prompt | string | ✅ | Текстовое описание изображения |
n | int | ❌ | Число изображений (1–10) |
size | string | ❌ | "256x256", "512x512", "1024x1024", "1792x1024", "1024x1792", "1536x1024", "1024x1536", "auto" |
quality | string | ❌ | "auto", "high", "medium", "low", "hd", "standard" |
style | string | ❌ | "natural", "vivid" |
response_format | string | ❌ | "url" или "b64_json" |
background | string | ❌ | "transparent", "opaque", "auto" |
output_format | string | ❌ | "png", "webp", "jpeg" |
output_compression | int | ❌ | Уровень компрессии (0–100%) |
partial_images | int | ❌ | Число партий частичных изображений (0–3) |
moderation | string | ❌ | "low", "auto" |
user | string | ❌ | Идентификатор пользователя |
Конверсия запроса. OpenAI — базовая схема для image generation. Параметры пробрасываются с минимальной конверсией:
- Model и Prompt:
bifrostReq.Model→req.Model,bifrostReq.Prompt→req.Prompt. - Параметры: все поля из
bifrostReq(ImageGenerationParameters) встраиваются непосредственно в OpenAI-структуру через struct embedding. Маппинг полей и трансформация не выполняются. - Стриминг: при включённом стриминге в тело запроса добавляется
stream: true.
Конверсия ответа:
-
Без стриминга. OpenAI-ответы анмаршалятся напрямую в
BifrostImageGenerationResponse, поскольку схема ответа Meridian — надмножество формата OpenAI. Все поля пробрасываются как есть. -
Стриминг. OpenAI-ответы — Server-Sent Events с типами событий:
image_generation.partial_image— промежуточные чанки изображения сb64_json.image_generation.completed— финальный чанк для каждого изображения с usage.error— события ошибок.
Каждый чанк содержит:
type— тип события;sequence_number— порядковый номер чанка;partial_image_index— индекс изображения (0…N) для partial-чанков;b64_json— base64-кодированные данные изображения (указатель, может бытьnil);usage— счётчики токенов (только вcompleted-событиях);created_at,size,quality,background,output_format— дополнительные метаданные.
Meridian преобразует их в чанки
BifrostImageGenerationStreamResponseс per-imagechunkIndexдля упорядочивания внутри каждого изображения;Indexуказывает, к какому изображению (0…N) относится чанк;PartialImageIndexустанавливается только для partial-чанков; usage прикрепляется к completed-чанкам; на каждый чанк фиксируется latency.
Эндпоинт: /v1/images/generations.
8. Image Edit
Запросы используют multipart/form-data, а не JSON.
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели |
prompt | string | ✅ | Текстовое описание правки |
image[] | binary | ✅ | Файл(ы) изображения (multipart, поддерживается несколько) |
mask | binary | ❌ | Файл маски (multipart) |
n | int | ❌ | Число изображений (1–10) |
size | string | ❌ | "256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "auto" |
quality | string | ❌ | "auto", "high", "medium", "low", "standard" |
response_format | string | ❌ | "url" или "b64_json" |
background | string | ❌ | "transparent", "opaque", "auto" |
input_fidelity | string | ❌ | "low", "high" |
partial_images | int | ❌ | Число партий частичных изображений (0–3) |
output_format | string | ❌ | "png", "webp", "jpeg" |
output_compression | int | ❌ | Уровень компрессии (0–100%) |
user | string | ❌ | Идентификатор пользователя |
stream | bool | ❌ | Включить стриминг |
Конверсия запроса:
- Model и Input:
bifrostReq.Model→req.Model,bifrostReq.Input.Images→req.Input.Images,bifrostReq.Input.Prompt→req.Input.Prompt. - Параметры: все поля из
bifrostReq.Params(ImageEditParameters) встраиваются в OpenAI-структуру через struct embedding. Маппинг и трансформация не выполняются. - Multipart form data: запрос сериализуется как
multipart/form-data:- Model и Prompt — отдельные form-поля (
model,prompt). - Images — каждое изображение из
Input.Imagesпишется отдельным полемimage[]с автоопределением MIME-типа (image/jpeg,image/webp,image/png) и заголовком Content-Type. - Mask — если присутствует, пишется полем
maskс MIME-типом и подходящим именем файла (mask.png,mask.jpg,mask.webp). - Опциональные параметры (
n,size,quality,response_format,background,input_fidelity,partial_images,output_format,output_compression,user) — отдельные form-поля. - Числовые поля (
n,partial_images,output_compression) конвертируются в строки черезstrconv.Itoa. - Стриминг:
stream: "true"пишется как form-поле.
- Model и Prompt — отдельные form-поля (
Конверсия ответа:
- Без стриминга. OpenAI-ответы анмаршалятся напрямую в
BifrostImageGenerationResponse. Все поля пробрасываются как есть. - Стриминг. SSE-события:
image_edit.partial_image,image_edit.completed,error. Поля чанков и логика преобразования аналогичны image generation; добавляется устойчивая обработка interleaved-чанков через incomplete-image-tracking.
Эндпоинт: /v1/images/edits.
9. Image Variation
Запросы используют multipart/form-data, а не JSON.
Параметры запроса
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Идентификатор модели |
image | binary | ✅ | Исходное изображение (multipart) |
n | int | ❌ | Число изображений (1–10) |
size | string | ❌ | "256x256", "512x512", "1024x1024", "1792x1024", "1024x1792", "1536x1024", "1024x1536", "auto" |
response_format | string | ❌ | "url" или "b64_json" |
user | string | ❌ | Идентификатор пользователя |
Конверсия запроса:
- Model и Input:
bifrostReq.Model→req.Model,bifrostReq.Input.Image.Image→req.Input.Image.Image. - Параметры: все поля из
bifrostReq.Params(ImageVariationParameters) встраиваются через struct embedding. - Multipart form data:
model— form-поле;image— поле с MIME-типом (image/jpeg,image/webp,image/png); если MIME не определяется, по умолчаниюimage/png;- опциональные
n,size,response_format,user— form-поля;nконвертируется в строку.
- Несколько изображений: дополнительные изображения сверх первого (через
ExtraParams["images"]) сохраняются вExtraParams, но в OpenAI уходит только первое — апстрим поддерживает один входной image.
Конверсия ответа:
- Без стриминга. OpenAI-ответы анмаршалятся в
BifrostImageVariationResponse(тип-алиас дляBifrostImageGenerationResponse). - Стриминг для image variation не поддерживается.
Эндпоинт: /v1/images/variations.
10. Files API
Загрузка
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
file | binary | ✅ | Загружаемый файл (multipart) |
purpose | string | ✅ | batch, fine-tune или assistants |
filename | string | ❌ | Произвольное имя файла (по умолчанию file.jsonl) |
Ответ — FileObject с id, bytes, created_at, filename, purpose, status (docs).
Листинг
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
purpose | string | ❌ | Фильтр по purpose |
limit | int | ❌ | Размер страницы |
after | string | ❌ | Курсор пагинации |
order | string | ❌ | asc или desc |
Курсорная пагинация с флагом has_more.
Получение / удаление / содержимое
GET /v1/files/{file_id}— метаданные файла;DELETE /v1/files/{file_id}— удаление;GET /v1/files/{file_id}/content— скачивание содержимого.
11. Batch API
Создание batch'а
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
input_file_id | string | условно | ID файла ИЛИ массив requests (взаимоисключающие) |
requests | array | условно | Объекты BatchRequestItem (конвертируются в JSONL) |
endpoint | string | ✅ | Целевой эндпоинт (например, /v1/chat/completions) |
completion_window | string | ❌ | 24h (по умолчанию) |
metadata | object | ❌ | Произвольные метаданные |
Ответ: BifrostBatchCreateResponse с id, endpoint, input_file_id, status, created_at, request_counts (docs). Статусы (BatchStatus): validating, failed, in_progress, finalizing, completed, expired, cancelling, cancelled.
Листинг batch'ей
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
limit | int | ❌ | Размер страницы |
after | string | ❌ | Курсор пагинации |
Получение / отмена
GET /v1/batches/{batch_id}—BifrostBatchRetrieveResponse(docs);POST /v1/batches/{batch_id}/cancel— отмена (docs).
Получение результатов
- Batch должен быть в статусе
completed(естьoutput_file_id). - Скачайте output-файл через Files API.
- Распарсите JSONL — каждая запись
BatchResultItem:{id, custom_id, response: {status_code, body}}.
12. List Models
GET /v1/models — листинг доступных моделей с метаданными. Идентификаторы моделей в ответах Meridian имеют префикс openai/ (например, openai/gpt-4o). Результаты агрегируются по всем настроенным API-ключам. Тело и параметры запроса не нужны.
13. Video Generation
Создание (POST /v1/videos)
| Параметр | Тип | Обязательный | Замечания |
|---|---|---|---|
model | string | ✅ | Например, sora-2 |
prompt | string | ✅ | Текстовое описание видео |
input_reference | string | ❌ | Входное изображение для image-to-video. Только base64 data URL (например, data:image/png;base64,...); обычные URL не принимаются. |
seconds | string | ❌ | Длительность в секундах |
size | string | ❌ | Разрешение: 720x1280 (по умолчанию), 1280x720, 1024x1792, 1792x1024 |
Ответ: BifrostVideoGenerationResponse — id, status, model, prompt, created_at.
Статусы задачи: queued → in_progress → completed / failed.
Получение / скачивание / удаление / листинг / remix
| Операция | Эндпоинт | Замечания |
|---|---|---|
| Статус | GET /v1/videos/{id} | Поллинг до status: completed |
| Скачивание | GET /v1/videos/{id}/content | Возвращает сырые байты видео |
| Удаление | DELETE /v1/videos/{id} | Удаляет задачу |
| Листинг | GET /v1/videos | Query-параметры: after, limit, order |
| Remix | POST /v1/videos/{id}/remix | Тело: {"prompt": "..."} |
Типичные коды ошибок
Маппинг HTTP-статусов → тип ошибки:
400—invalid_request_error;401—authentication_error;403—permission_error;404—not_found_error;429—rate_limit_error;500—api_error.