Skip to content

feat(gemini): map OpenAI stop to Gemini stopSequences - #2779

Merged
Calcium-Ion merged 1 commit into
QuantumNous:mainfrom
RedwindA:feat/gemini2oaiSTOP
Jan 29, 2026
Merged

feat(gemini): map OpenAI stop to Gemini stopSequences#2779
Calcium-Ion merged 1 commit into
QuantumNous:mainfrom
RedwindA:feat/gemini2oaiSTOP

Conversation

@RedwindA

@RedwindA RedwindA commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

PR 类型

  • Bug 修复
  • 新功能
  • 文档更新
  • 其他

PR 是否包含破坏性更新?

PR 描述

close #2777
image

将 OpenAI 的 stop 参数转换为 Gemini 的 stopSequences,确保停止序列在 Gemini 渠道生效。

实现细节:

  • 在 OpenAI → Gemini 转换中解析 stop(支持 string/array)。
  • 按 Gemini 规范最多保留 5 个 stopSequences。
  • 新增通用解析函数以复用逻辑。

Summary by CodeRabbit

  • New Features
    • Added stop sequence support for Gemini API requests with flexible input handling
    • Stop sequences are automatically capped at 5 to comply with Gemini API specifications

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds support for parsing and applying stop sequences when converting OpenAI-format requests to Gemini requests. Introduces a new parseStopSequences function to extract valid stop sequences from various input types, caps them at Gemini's five-sequence limit, and assigns them to the generation configuration during the conversion process.

Changes

Cohort / File(s) Summary
Stop Sequence Support for Gemini Relay
relay/channel/gemini/relay-gemini.go
Introduces parseStopSequences function to handle stop sequences from OpenAI-compatible requests and integrates it into CovertOpenAI2Gemini to assign parsed sequences (max 5) to GenerationConfig.StopSequences.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • PR #2536: Modifies the same CovertOpenAI2Gemini conversion path to handle "developer" message merging into Gemini system instructions, sharing the same code-level modification point.

Suggested reviewers

  • seefs001

Poem

🐰 A stop sequence lands, graceful and neat,
Five whispers at most, the Gemini heartbeat,
OpenAI's format now speaks with one tongue,
Through relay and channels, the harmony's sung! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing mapping of OpenAI stop parameters to Gemini stopSequences.
Linked Issues check ✅ Passed The PR implements the required functionality from issue #2777: parsing OpenAI stop parameters and converting them to Gemini stopSequences with proper constraints (max 5 sequences).
Out of Scope Changes check ✅ Passed All changes are scoped to parsing and integrating OpenAI stop parameters into Gemini requests, which directly addresses the linked issue objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@relay/channel/gemini/relay-gemini.go`:
- Around line 641-664: The parseStopSequences function currently returns
[]string unchanged for the []string case while filtering out empty strings for
[]interface{}; update the []string branch in parseStopSequences to iterate over
the input slice and append only non-empty strings (like the []interface{}
branch) so empty entries are consistently removed before returning; keep the
existing nil handling and preserve the function signature and behavior for
string and other cases.

Comment on lines +641 to +664
// parseStopSequences 解析停止序列,支持字符串或字符串数组
func parseStopSequences(stop any) []string {
if stop == nil {
return nil
}

switch v := stop.(type) {
case string:
if v != "" {
return []string{v}
}
case []string:
return v
case []interface{}:
sequences := make([]string, 0, len(v))
for _, item := range v {
if str, ok := item.(string); ok && str != "" {
sequences = append(sequences, str)
}
}
return sequences
}
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent empty-string filtering between []string and []interface{} cases.

The []interface{} case (lines 654-661) filters out empty strings, but the []string case (lines 652-653) returns the slice directly without any filtering. This inconsistency could allow empty stop sequences to reach the Gemini API when the input is []string.

🔧 Proposed fix to add filtering for []string
 	case []string:
-		return v
+		sequences := make([]string, 0, len(v))
+		for _, s := range v {
+			if s != "" {
+				sequences = append(sequences, s)
+			}
+		}
+		return sequences
 	case []interface{}:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// parseStopSequences 解析停止序列,支持字符串或字符串数组
func parseStopSequences(stop any) []string {
if stop == nil {
return nil
}
switch v := stop.(type) {
case string:
if v != "" {
return []string{v}
}
case []string:
return v
case []interface{}:
sequences := make([]string, 0, len(v))
for _, item := range v {
if str, ok := item.(string); ok && str != "" {
sequences = append(sequences, str)
}
}
return sequences
}
return nil
}
// parseStopSequences 解析停止序列,支持字符串或字符串数组
func parseStopSequences(stop any) []string {
if stop == nil {
return nil
}
switch v := stop.(type) {
case string:
if v != "" {
return []string{v}
}
case []string:
sequences := make([]string, 0, len(v))
for _, s := range v {
if s != "" {
sequences = append(sequences, s)
}
}
return sequences
case []interface{}:
sequences := make([]string, 0, len(v))
for _, item := range v {
if str, ok := item.(string); ok && str != "" {
sequences = append(sequences, str)
}
}
return sequences
}
return nil
}
🤖 Prompt for AI Agents
In `@relay/channel/gemini/relay-gemini.go` around lines 641 - 664, The
parseStopSequences function currently returns []string unchanged for the
[]string case while filtering out empty strings for []interface{}; update the
[]string branch in parseStopSequences to iterate over the input slice and append
only non-empty strings (like the []interface{} branch) so empty entries are
consistently removed before returning; keep the existing nil handling and
preserve the function signature and behavior for string and other cases.

@Calcium-Ion
Calcium-Ion merged commit 9d0fde9 into QuantumNous:main Jan 29, 2026
1 check passed
ennnnny pushed a commit to ennnnny/new-api that referenced this pull request Mar 17, 2026
feat(gemini): map OpenAI stop to Gemini stopSequences
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.

【功能】OpenAI 兼容格式调用 Gemini 模型兼容 stop 字段

2 participants