Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions relay/channel/openai/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayIn
if request == nil {
return nil, errors.New("request is nil")
}
// 归一化 stop 字段:某些严格的 OpenAI 兼容上游(基于 Java/Jackson,将 stop 声明为
// ArrayList 且未启用 ACCEPT_SINGLE_VALUE_AS_ARRAY)收到单字符串会返回 400。
// 转成数组形式,OpenAI 官方/Azure 等主流上游同样接受。
if s, ok := request.Stop.(string); ok && s != "" {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
request.Stop = []string{s}
}
Comment on lines +234 to +242
Comment on lines +237 to +242
Comment on lines +237 to +242

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Empty-string stop is not normalized.

The guard s != "" skips normalization when request.Stop is an empty string. Strict Jackson-based upstreams that reject a bare string stop (the exact issue this PR fixes) would still receive a string type in that case and could return the same 400 error.

🐛 Proposed fix
-	if s, ok := request.Stop.(string); ok && s != "" {
+	if s, ok := request.Stop.(string); ok {
 		logger.LogWarn(c.Request.Context(), fmt.Sprintf(
 			"stop field normalized from string to array for channel %d (model: %s)",
 			info.ChannelId, info.UpstreamModelName))
-		request.Stop = []string{s}
+		if s == "" {
+			request.Stop = nil
+		} else {
+			request.Stop = []string{s}
+		}
 	}
📝 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
if s, ok := request.Stop.(string); ok && s != "" {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
request.Stop = []string{s}
}
if s, ok := request.Stop.(string); ok {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
if s == "" {
request.Stop = nil
} else {
request.Stop = []string{s}
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/openai/adaptor.go` around lines 237 - 242, The stop
normalization in adaptor.go skips empty strings because of the s != "" guard, so
a bare string stop can still be sent upstream and trigger the same Jackson 400.
Update the request.Stop handling in the adaptor’s normalization block to convert
any string value, including empty string, into a []string, and keep the existing
warning/logging around the normalization path.

if info.ChannelType != constant.ChannelTypeOpenAI && info.ChannelType != constant.ChannelTypeAzure {
request.StreamOptions = nil
}
Expand Down