Эксперименты
План внедрения OpenResponses Gateway
Контекст
OpenClaw Gateway в настоящее время предоставляет минимально совместимую с OpenAI конечную точку Chat Completions по адресу /v1/chat/completions (см. OpenAI Chat Completions). Open Responses — это открытый стандарт инференса, основанный на OpenAI Responses API. Он разработан для агентных рабочих процессов и использует ввод на основе элементов (item-based inputs) и семантические стриминговые события. Спецификация OpenResponses определяет /v1/responses, а не /v1/chat/completions.
Цели
- Добавить конечную точку
/v1/responses, соответствующую семантике OpenResponses. - Сохранить Chat Completions в качестве слоя совместимости, который легко отключить и в конечном итоге удалить.
- Стандартизировать валидацию и парсинг с помощью изолированных, переиспользуемых схем.
Нецели
- Полная функциональная эквивалентность OpenResponses в первой реализации (изображения, файлы, размещённые инструменты).
- Замена внутренней логики выполнения агентов или оркестрации инструментов.
- Изменение поведения существующей конечной точки
/v1/chat/completionsна первом этапе.
Краткое описание исследования
Источники: OpenResponses OpenAPI, сайт спецификации OpenResponses и публикация в блоге Hugging Face. Ключевые моменты:
POST /v1/responsesпринимает поляCreateResponseBody, такие какmodel,input(строка илиItemParam[]),instructions,tools,tool_choice,stream,max_output_tokensиmax_tool_calls.ItemParam— это дискриминированное объединение (discriminated union):- элементы
messageс ролямиsystem,developer,user,assistant function_callиfunction_call_outputreasoningitem_reference
- элементы
- Успешные ответы возвращают
ResponseResourceс полямиobject: "response",statusи элементамиoutput. - Стриминг использует семантические события, такие как:
response.created,response.in_progress,response.completed,response.failedresponse.output_item.added,response.output_item.doneresponse.content_part.added,response.content_part.doneresponse.output_text.delta,response.output_text.done
- Спецификация требует:
Content-Type: text/event-streamevent:должен соответствовать полю JSONtype- терминальным событием должна быть строка
[DONE]
- Элементы reasoning (рассуждения) могут содержать
content,encrypted_contentиsummary. - Примеры от HF включают
OpenResponses-Version: latestв запросах (необязательный заголовок).
Предлагаемая архитектура
- Добавить
src/gateway/open-responses.schema.ts, содержащий только схемы Zod (без импортов из gateway). - Добавить
src/gateway/openresponses-http.ts(илиopen-responses-http.ts) для/v1/responses. - Оставить
src/gateway/openai-http.tsбез изменений в качестве адаптера для обратной совместимости. - Добавить конфигурацию
gateway.http.endpoints.responses.enabled(по умолчаниюfalse). - Оставить
gateway.http.endpoints.chatCompletions.enabledнезависимой; разрешить включать/выключать обе конечные точки отдельно. - Выдавать предупреждение при запуске, когда Chat Completions включён, чтобы обозначить его устаревший статус.
Путь к устареванию Chat Completions
- Сохранять строгие границы модулей: никаких общих типов схем между responses и chat completions.
- Сделать Chat Completions опциональным через конфигурацию, чтобы его можно было отключить без изменений кода.
- Обновить документацию, пометив Chat Completions как устаревший, когда
/v1/responsesстанет стабильным. - Опциональный будущий шаг: преобразовывать запросы Chat Completions в обработчик Responses для упрощения пути к удалению.
Поддерживаемое подмножество в Фазе 1
- Принимать
inputкак строку илиItemParam[]с ролями сообщений иfunction_call_output. - Извлекать системные и developer-сообщения в
extraSystemPrompt. - Использовать последнее сообщение
userилиfunction_call_outputв качестве текущего сообщения для запуска агента. - Отклонять неподдерживаемые части контента (изображение/файл) с ошибкой
invalid_request_error. - Возвращать одно сообщение assistant с контентом
output_text. - Возвращать
usageс нулевыми значениями, пока не будет подключён учёт токенов.
Стратегия валидации (без SDK)
- Реализовать схемы Zod для поддерживаемого подмножества:
CreateResponseBodyItemParam+ объединения частей контента сообщенийResponseResource- Формы стриминговых событий, используемые шлюзом
- Хранить схемы в одном изолированном модуле, чтобы избежать расхождения и позволить будущую генерацию кода.
Реализация стриминга (Фаза 1)
- Строки SSE с
event:иdata:. - Обязательная последовательность (минимально жизнеспособная):
response.createdresponse.output_item.addedresponse.content_part.addedresponse.output_text.delta(повторять по необходимости)response.output_text.doneresponse.content_part.doneresponse.completed[DONE]
План тестирования и проверки
- Добавить сквозное (e2e) тестирование для
/v1/responses:- Требуется аутентификация
- Форма нестримингового ответа
- Порядок событий стриминга и
[DONE] - Маршрутизация сессий с заголовками и
user
- Оставить
src/gateway/openai-http.test.tsбез изменений. - Ручная проверка: curl к
/v1/responsesсstream: trueи проверка порядка событий и терминального[DONE].
Обновления документации (в последующем)
- Добавить новую страницу документации по использованию
/v1/responsesс примерами. - Обновить
/gateway/openai-http-apiс пометкой об устаревании и ссылкой на/v1/responses.
Рефакторинг Browser Evaluate CDPПлан PTY и Process Supervision