- 目标仓库:
CLIProxyAPI-main.__latest_20260304000229 - 修复范围:
OpenAI <-> Claude/Gemini/Gemini-CLI的请求与响应转换 - 重点:参数兼容、字段类型一致性、流式/非流式行为一致性、工具调用字段保真
- 文件:
internal/translator/openai/openai/responses/openai_openai-responses_request.go - 修复:对象/数组使用
SetRaw,基础类型使用Set - 结果:保留
tool_choice原始 JSON 结构
- 文件:
internal/translator/gemini/openai/responses/gemini_openai-responses_request.go - 修复:读取
output的.Raw/.Value(),对象走SetRaw - 结果:工具输出对象不再丢字段
- 文件:
internal/translator/gemini/openai/responses/gemini_openai-responses_request.go - 修复:同时支持
stop与stop_sequences - 结果:统一映射到
generationConfig.stopSequences
- 文件:
internal/translator/gemini/openai/chat-completions/gemini_openai_request.go - 修复:
max_tokens|max_completion_tokens -> generationConfig.maxOutputTokensstop|stop_sequences -> generationConfig.stopSequences
- 文件:
internal/translator/gemini/openai/chat-completions/gemini_openai_request.go - 修复:
- 新增
parseDataURI,拆分mime与纯 base64 数据 - 远程图片 URL 映射到
fileData.fileUri - 新增
guessMimeTypeFromURL补fileData.mimeType
- 新增
- 文件:
internal/translator/gemini/openai/chat-completions/gemini_openai_request.gointernal/translator/gemini/openai/responses/gemini_openai-responses_request.go
- 修复:
auto -> AUTOnone -> NONErequired -> ANY- 指定函数名映射到
allowedFunctionNames
- 文件:
internal/translator/gemini/openai/chat-completions/gemini_openai_response.go - 修复:
- 新增
mapGeminiFinishReason MAX_TOKENS -> length,并保留native_finish_reason=max_tokens- 流式场景按当前 candidate 读取
finishReason,不再固定读取candidates.0
- 新增
- 文件:
internal/translator/claude/openai/responses/claude_openai-responses_request.go - 修复:
- 增加
input字符串到用户消息映射 - 增加
temperature/top_p/stop映射
- 增加
- 文件:
internal/translator/claude/openai/chat-completions/claude_openai_request.go - 修复:非 data URL 的
image_url映射为 Claudesource.type=url
- 文件:
sdk/translator/registry.go - 修复:
from->to与to->from双向判定 - 结果:避免“可翻译却被判定不存在”问题
- 文件:
internal/translator/gemini/openai/chat-completions/gemini_openai_request.gointernal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_request.go
- 修复:
functionResponse.response.result对象走SetRaw,基础类型走Set - 结果:工具结果对象不再退化成 JSON 字符串
- 文件:
internal/translator/openai/openai/responses/openai_openai-responses_request.go - 修复:保留
web_search/file_search等内建工具定义,不再静默忽略 - 结果:跨端点转换时工具能力信息保真
- 文件:
internal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_request.go - 修复:
max_completion_tokens|max_tokens -> request.generationConfig.maxOutputTokensstop|stop_sequences -> request.generationConfig.stopSequencestool_choice -> request.toolConfig.functionCallingConfigimage_url同时支持data:与远程 URL(远程映射到fileData.fileUri)- 工具结果为 JSON 字符串时尝试反序列化后保留对象结构
- 文件:
internal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_response.go - 修复:
- 不再固定读取
candidates.0,按response.candidates遍历输出 chunk MAX_TOKENS -> finish_reason=length,并保留native_finish_reason=max_tokens- 对
stop/safety等原因进行 OpenAI 语义映射
- 不再固定读取
- 文件:
internal/translator/openai/gemini/openai_gemini_response.go - 修复:
- 流式与非流式均按 choice index 写入
candidates.{index} - 消除
n>1场景下“后写覆盖前写”的问题
- 流式与非流式均按 choice index 写入
- 文件:
internal/translator/openai/gemini/openai_gemini_request.go - 修复:
generationConfig.stop字符串输入兼容functionCallingConfig.mode=ANY + allowedFunctionNames=[name]映射为 OpenAI 指定函数tool_choice对象functionResponse的tool_call_id优先按name精确匹配,减少错绑
- 文件:
internal/translator/openai/claude/openai_claude_request.go - 修复:
stop_sequences之外,新增stop字段兼容(字符串/数组)
- 文件:
internal/translator/gemini/openai/responses/gemini_openai-responses_response.go - 修复:
- 非流式聚合不再固定
candidates.0 - 按所有
candidates[*].content.parts生成output项,避免多候选文本被静默丢弃 - 保持候选内
function_call/reasoning/message的输出语义
- 非流式聚合不再固定
- 文件:
internal/translator/gemini/openai/responses/gemini_openai-responses_response.go - 修复:
- 流式路径按
candidates[*]逐个处理,不再固定candidates.0 - 新增按 candidate 维度的 message/reasoning 状态,避免
n>1时互相覆盖 response.completed聚合阶段按output_index汇总所有 candidate 的 message/reasoning/function_call- 补充流式多候选回归测试,覆盖
response.output双候选文本输出
- 流式路径按
internal/translator/openai/openai/responses/openai_openai-responses_request_test.gointernal/translator/gemini/openai/responses/gemini_openai-responses_request_test.gointernal/translator/gemini/openai/chat-completions/gemini_openai_request_test.gointernal/translator/gemini/openai/chat-completions/gemini_openai_response_test.gointernal/translator/gemini/openai/responses/gemini_openai-responses_response_test.gointernal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_request_test.gointernal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_response_test.gointernal/translator/claude/openai/responses/claude_openai-responses_request_test.gointernal/translator/claude/openai/chat-completions/claude_openai_request_test.gointernal/translator/openai/gemini/openai_gemini_request_test.gointernal/translator/openai/gemini/openai_gemini_response_test.go
go test ./internal/translator/...:通过go test ./sdk/api/handlers/openai/...:通过go test ./internal/runtime/executor/... -run "OpenAI|compat|Translator":通过