feat: add OpenAI Responses native passthrough - #312
Open
WingI9B1 wants to merge 1 commit into
Open
Conversation
Owner
|
感谢,你说的这个功能已经做好了,正在本地测试 |
Author
|
@bestruirui 大佬辛苦😂,我自己比较需要,然后看 issue 好像没人提,就自己本地修改测试完提交 PR 了😂 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Octopus 当前使用 AxonHub
llmtransformer 处理 OpenAI Responses 请求:这套流程适合 OpenAI Responses 与 Anthropic 等协议之间的转换,但在客户端和上游都使用 OpenAI Responses/Codex 协议时,会完整解析并重新构造请求和响应。
Codex 当前使用了一些 Responses 协议扩展能力,包括:
compaction_triggercompactionencrypted_content/v1/alpha/searchRemote Compaction V2 会在普通
POST /v1/responses请求的input末尾加入:{ "type": "compaction_trigger" }上游随后通过 Responses SSE 返回包含以下内容的 item:
{ "type": "compaction", "encrypted_content": "..." }在现有 transformer 流程中,
compaction_trigger、compaction、encrypted_content或未知 SSE event 可能无法完整保留。实际表现可能是请求返回 HTTP 200,但最终得到普通 assistant 文本回复,Codex 无法获得所需的 Compaction item。Octopus 此前也没有注册:
因此 Codex 的 standalone web search 和旧版 remote compact endpoint 无法通过 Octopus 调用。
目标
当客户端使用 OpenAI Responses/Codex 协议,并且最终选中的上游 Channel 同样使用 OpenAI Responses 协议时,允许 Channel 启用原生透传。
原生透传保留 Octopus 的以下能力:
该改动不会在 Octopus 内实现远程压缩或搜索算法。Octopus 负责将客户端请求透明转发给支持这些能力的上游,并将上游响应透明返回给 Codex。
跨协议调用继续使用现有 AxonHub transformer,例如:
实现内容
1. 通用 Native Passthrough Relay
新增通用原生透传实现:
透传处理器只进行路由所需的最低限度解析:
modelmodel需要保留的内容包括:
inputitemcompaction_triggercompactionencrypted_contentmetadatatoolsreasoningprompt_cache_key2. Responses 到 Responses 自动进入透传路径
当以下条件同时满足时进入 Native Passthrough:
其他情况继续进入现有 transformer 流程。
该能力使用 Channel 级显式开关,现有 Channel 默认行为保持不变。
3. Responses SSE 透明转发
Native Passthrough 不会把 SSE 解析为
llm.Response后重新生成。上游 SSE 数据会直接转发给客户端,以保留:
response.createdresponse.in_progressresponse.output_item.addedresponse.output_item.doneresponse.completedsequence_numbercreated_atmetadatacompactionencrypted_content4. Usage 旁路观察
透明转发期间增加只读 Usage Observer。
Observer 监听:
并提取:
input_tokensoutput_tokenscached_tokensreasoning_tokensObserver 只读取 SSE frame,不修改发送给客户端的数据。
普通 JSON 响应也会在不改变响应内容的情况下旁路读取 usage。
5. Failover 边界
原生透传继续支持现有 Channel Failover,但遵循流式响应边界:
该限制用于避免将两个上游的 Responses SSE 拼接到同一个客户端响应中。
6. Codex Standalone Web Search
新增:
该 endpoint 使用相同的 Native Passthrough Relay:
model/v1/alpha/searchOctopus 不解析 standalone search 的
commands、settings、results或未来新增字段。7. 旧版 Remote Compact 兼容
新增:
该 endpoint 同样使用 Native Passthrough。
Codex 当前 Remote Compaction V2 仍通过:
完成远程压缩。
/v1/responses/compact主要用于旧 Codex 和其他兼容客户端,不会改变 Remote Compaction V2 的处理逻辑。8. Headers
原生透传尽可能保留客户端请求 headers,包括:
x-openai-*openai-*user-agent同时过滤 Hop-by-Hop headers,并重新设置上游鉴权及请求传输相关字段。
Channel 配置
Channel 设置中新增:
建议仅为确认支持 OpenAI Responses/Codex 原生能力的上游开启。
开启后,在客户端和上游均使用 OpenAI Responses 协议时,将保留原始请求字段和 SSE event,只执行鉴权、模型映射、路由、Failover、日志、用量统计和计费。
适用能力包括:
encrypted_content自动化测试
新增测试文件:
覆盖以下场景:
TestNativePassthroughOrdinaryResponsesPreservesUnknownFieldsAndMapsModelTestNativePassthroughRemoteCompactionV2AndUnknownSSEEventTestNativePassthroughAlphaSearchTestNativePassthroughLegacyResponsesCompactTestNativePassthroughFailoverBeforeStreamStartsTestNativePassthroughDoesNotFailoverAfterStreamStartsTestNativePassthroughRequiresResponsesChannelOptInTestNativePassthroughUnknownResponseItemIsPreservedTestNativePassthroughUnknownSSEEventIsByteTransparentTestNativePassthroughUsageObserverRecordsCachedAndReasoningTokens后端测试结果:
go test -modfile=.codex-test.mod -mod=mod ./...结果:
前端构建结果:
结果:
当前
pnpm lint会报告上游已有的 24 个全量 ESLint 错误,报错文件没有出现在本 PR 的修改文件中。本 PR 没有混入无关的 lint 修复。手动测试前提
测试 Channel 需要满足:
手动测试 1:Remote Compaction V2
预期结果:
200text/event-streamcompaction_triggerencrypted_content响应中应能观察到类似内容:
{ "type": "compaction", "encrypted_content": "..." }手动测试 2:Codex Standalone Web Search
该请求格式与当前 Codex
SearchRequest保持一致:预期结果:
200/v1/alpha/searchid、commands和settingsmodelresults类型和字段不会被 Octopus 删除响应格式由上游决定,当前 Codex 支持的结构包括:
{ "encrypted_output": "...", "output": "...", "results": [] }其中
encrypted_output和results可以由上游省略或返回null。手动测试 3:旧版 Remote Compact
预期结果:
404/v1/responses/compact安全与兼容性
model贡献检查
/v1/alpha/search已通过自动化测试和手动测试