Skip to content

Conversation

@extremk
Copy link

@extremk extremk commented Jan 5, 2026

这次修改方案修改力度远低于以前方案,侵入性更低,原先逻辑保持得更好,且完全修正了多个渠道Gemini 不支持多候选功能,实测 Antigravity与Gemini CLI都得到修正

多候选功能 在某些场合非常有用,可以大幅度减少请求次数,节约Token与请求次数,提醒,此功能主要针对Gemini 2.5模型,Gemini 2.5系列支持到8,Qwen CLI渠道 支持到4,iFlow 渠道 Kimi支持5,其他模型大多数支持到1
所有的Gemini生图模型1,Gemini 3 预览版仅允许1,超过报错,但是 正式版可能会提高上限

Claude和百度不支持,会被忽略,视为1

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @extremk, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在全面增强对Gemini多候选功能的兼容性。通过在请求转换时正确处理OpenAI的n参数,并在流式和非流式响应转换时准确解析和呈现Gemini返回的多个候选,确保了Gemini的多候选功能在Antigravity和Gemini CLI等多个渠道中得到完整支持,且对现有逻辑的侵入性较低。

Highlights

  • 多候选请求参数支持: 在Antigravity、Gemini CLI和Gemini的OpenAI请求转换器中,新增了对OpenAI n 参数(即generationConfig.candidateCount)的映射支持,确保请求能正确指定生成多个候选回复。
  • 流式响应多候选处理: 重构了Gemini到OpenAI流式响应的转换逻辑,现在能够正确处理并返回Gemini响应中的所有候选(candidates),为每个候选生成独立的choices块,并使用map来追踪每个候选的函数调用索引,以支持多候选的函数调用。
  • 非流式响应多候选处理: 更新了Gemini到OpenAI非流式响应的转换逻辑,使其能够遍历Gemini响应中的所有候选,并为每个候选构建一个完整的choice对象,包含其内容、推理、工具调用和图片信息,最终在OpenAI响应中返回一个包含所有候选的choices数组。
  • OpenAI到Gemini请求参数回译: 在OpenAI到Gemini的请求转换中,增加了将Gemini的generationConfig.candidateCount参数正确映射回OpenAI的n参数的逻辑。

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

本次 PR 旨在为 Gemini 添加多候选(multi-candidate)功能,通过支持 OpenAI 的 n 参数来实现。您对请求和响应转换逻辑进行了相应的修改,以正确处理多个候选结果。

整体来看,代码修改是有效的,成功地实现了多候选功能。主要修改集中在 gemini_openai_response.go 文件中,通过循环处理 candidates 数组,为流式和非流式响应都生成了正确的 OpenAI 格式。请求转换部分也正确地将 n 参数映射到了 Gemini 的 candidateCount

我提出了一些关于代码格式和参数初始化逻辑的建议,旨在提高代码的可读性和一致性。请查看具体的评论。

Comment on lines +84 to +90
// Candidate count (OpenAI 'n' parameter)
if n := gjson.GetBytes(rawJSON, "n"); n.Exists() && n.Type == gjson.Number {
if val := n.Int(); val > 1 {
out, _ = sjson.SetBytes(out, "request.generationConfig.candidateCount", val)
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

代码格式存在一些小问题:

  • 第84行的注释 // Candidate count... 有多余的缩进,应与下方的 if 语句对齐。
  • 第90行是一个空行,但包含了多余的制表符(tab)。

建议修正这些格式问题以保持代码风格统一。

Suggested change
// Candidate count (OpenAI 'n' parameter)
if n := gjson.GetBytes(rawJSON, "n"); n.Exists() && n.Type == gjson.Number {
if val := n.Int(); val > 1 {
out, _ = sjson.SetBytes(out, "request.generationConfig.candidateCount", val)
}
}
// Candidate count (OpenAI 'n' parameter)
if n := gjson.GetBytes(rawJSON, "n"); n.Exists() && n.Type == gjson.Number {
if val := n.Int(); val > 1 {
out, _ = sjson.SetBytes(out, "request.generationConfig.candidateCount", val)
}
}

Comment on lines +102 to +108
// Candidate count (OpenAI 'n' parameter)
if n := gjson.GetBytes(rawJSON, "n"); n.Exists() && n.Type == gjson.Number {
if val := n.Int(); val > 1 {
out, _ = sjson.SetBytes(out, "generationConfig.candidateCount", val)
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

代码格式存在一些小问题:

  • 第102行的注释 // Candidate count... 有多余的缩进,应与下方的 if 语句对齐。
  • 第108行是一个空行,但包含了多余的制表符(tab)。

建议修正这些格式问题以保持代码风格统一。

Suggested change
// Candidate count (OpenAI 'n' parameter)
if n := gjson.GetBytes(rawJSON, "n"); n.Exists() && n.Type == gjson.Number {
if val := n.Int(); val > 1 {
out, _ = sjson.SetBytes(out, "generationConfig.candidateCount", val)
}
}
// Candidate count (OpenAI 'n' parameter)
if n := gjson.GetBytes(rawJSON, "n"); n.Exists() && n.Type == gjson.Number {
if val := n.Int(); val > 1 {
out, _ = sjson.SetBytes(out, "generationConfig.candidateCount", val)
}
}

Comment on lines 30 to +40
if *param == nil {
*param = &convertGeminiResponseToOpenAIChatParams{
UnixTimestamp: 0,
FunctionIndex: 0,
FunctionIndex: make(map[int]int),
}
}
// 确保 Map 已初始化 (针对旧的 param 可能的情况)
p := (*param).(*convertGeminiResponseToOpenAIChatParams)
if p.FunctionIndex == nil {
p.FunctionIndex = make(map[int]int)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这部分参数初始化的逻辑可以写得更简洁和符合 Go 的习惯用法。当前的实现中,对 p.FunctionIndex 的 nil 检查在 *param 初始化之后,显得有些分散。

建议将类型断言和初始化逻辑合并,这样代码更易读,也能一次性处理 *paramnil、类型不匹配或 FunctionIndex 未初始化的情况。

Suggested change
if *param == nil {
*param = &convertGeminiResponseToOpenAIChatParams{
UnixTimestamp: 0,
FunctionIndex: 0,
FunctionIndex: make(map[int]int),
}
}
// 确保 Map 已初始化 (针对旧的 param 可能的情况)
p := (*param).(*convertGeminiResponseToOpenAIChatParams)
if p.FunctionIndex == nil {
p.FunctionIndex = make(map[int]int)
}
p, ok := (*param).(*convertGeminiResponseToOpenAIChatParams)
if !ok || p == nil {
p = &convertGeminiResponseToOpenAIChatParams{
// UnixTimestamp 默认为 0
FunctionIndex: make(map[int]int),
}
*param = p
} else if p.FunctionIndex == nil {
// 处理 param 已存在但 map 未初始化的情况(为了兼容性)
p.FunctionIndex = make(map[int]int)
}

@extremk extremk changed the title 做了较小的修正,以便使得Gemini完全的修正多候选功能 做了较小的修正,使得Gemini完全支持修正多候选功能 Jan 5, 2026
@extremk extremk changed the title 做了较小的修正,使得Gemini完全支持修正多候选功能 做了较小的修正,使得Gemini完全支持多候选功能 Jan 5, 2026
HsnSaboor added a commit to HsnSaboor/CLIProxyAPI that referenced this pull request Jan 6, 2026
…auto-update, request timeout, multi-candidate, auth persistence

Applied features from upstream PRs:
- PR router-for-me#878: Usage statistics persistence (SetPersistPath, LoadStatistics, SaveStatistics)
- PR router-for-me#877: Codex plan type credential filename handling
- PR router-for-me#868: Claude request cloaking utilities (obfuscation, fake user IDs)
- PR router-for-me#715: Auto-update command for self-updating binary
- PR router-for-me#860: Configurable request timeout with RequestTimeout config
- PR router-for-me#879: Gemini multi-candidate support (n param -> candidateCount)
- PR router-for-me#869: Auth token persistence for non-Google OAuth providers

Fixed build issues:
- Added applyPayloadConfig wrapper function
- Added originalTranslated computation in claude/antigravity/codex executors
- Fixed model registry hook methods
- Removed duplicate SanitizeFunctionName
- Fixed gemini_schema placeholder logic for nested object properties

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Ptah-CT pushed a commit to Ptah-CT/CLIProxyAPIPlusPlus that referenced this pull request Jan 8, 2026
Cherry-picked from upstream PR router-for-me#879
- Maps OpenAI 'n' parameter to generationConfig.candidateCount
- Handles multiple candidates in streaming and non-streaming responses
@luispater luispater changed the base branch from main to dev January 9, 2026 21:27
@luispater
Copy link
Collaborator

请把代码中的所有中文注释修改成英文以后我再进行审核。

@extremk extremk closed this Jan 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants