Skip to content

Commit 27b43ed

Browse files
authored
Merge pull request #658 from moxi000/fix-responses-convert
Fix responses-format handling for chat completions(Support Cursor)
2 parents a86d501 + f6a3a1d commit 27b43ed

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

sdk/api/handlers/openai/openai_handlers.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
. "github.com/router-for-me/CLIProxyAPI/v6/internal/constant"
1818
"github.com/router-for-me/CLIProxyAPI/v6/internal/interfaces"
1919
"github.com/router-for-me/CLIProxyAPI/v6/internal/registry"
20+
responsesconverter "github.com/router-for-me/CLIProxyAPI/v6/internal/translator/openai/openai/responses"
2021
"github.com/router-for-me/CLIProxyAPI/v6/sdk/api/handlers"
2122
"github.com/tidwall/gjson"
2223
"github.com/tidwall/sjson"
@@ -109,14 +110,39 @@ func (h *OpenAIAPIHandler) ChatCompletions(c *gin.Context) {
109110

110111
// Check if the client requested a streaming response.
111112
streamResult := gjson.GetBytes(rawJSON, "stream")
112-
if streamResult.Type == gjson.True {
113+
stream := streamResult.Type == gjson.True
114+
115+
// Some clients send OpenAI Responses-format payloads to /v1/chat/completions.
116+
// Convert them to Chat Completions so downstream translators preserve tool metadata.
117+
if shouldTreatAsResponsesFormat(rawJSON) {
118+
modelName := gjson.GetBytes(rawJSON, "model").String()
119+
rawJSON = responsesconverter.ConvertOpenAIResponsesRequestToOpenAIChatCompletions(modelName, rawJSON, stream)
120+
stream = gjson.GetBytes(rawJSON, "stream").Bool()
121+
}
122+
123+
if stream {
113124
h.handleStreamingResponse(c, rawJSON)
114125
} else {
115126
h.handleNonStreamingResponse(c, rawJSON)
116127
}
117128

118129
}
119130

131+
// shouldTreatAsResponsesFormat detects OpenAI Responses-style payloads that are
132+
// accidentally sent to the Chat Completions endpoint.
133+
func shouldTreatAsResponsesFormat(rawJSON []byte) bool {
134+
if gjson.GetBytes(rawJSON, "messages").Exists() {
135+
return false
136+
}
137+
if gjson.GetBytes(rawJSON, "input").Exists() {
138+
return true
139+
}
140+
if gjson.GetBytes(rawJSON, "instructions").Exists() {
141+
return true
142+
}
143+
return false
144+
}
145+
120146
// Completions handles the /v1/completions endpoint.
121147
// It determines whether the request is for a streaming or non-streaming response
122148
// and calls the appropriate handler based on the model provider.

0 commit comments

Comments
 (0)