fix: preserve explicit zero values in native relay requests
This commit is contained in:
@@ -11,15 +11,25 @@ import (
|
||||
"github.com/QuantumNous/new-api/relay/channel/openrouter"
|
||||
relaycommon "github.com/QuantumNous/new-api/relay/common"
|
||||
"github.com/QuantumNous/new-api/relay/reasonmap"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func ClaudeToOpenAIRequest(claudeRequest dto.ClaudeRequest, info *relaycommon.RelayInfo) (*dto.GeneralOpenAIRequest, error) {
|
||||
openAIRequest := dto.GeneralOpenAIRequest{
|
||||
Model: claudeRequest.Model,
|
||||
MaxTokens: claudeRequest.MaxTokens,
|
||||
Temperature: claudeRequest.Temperature,
|
||||
TopP: claudeRequest.TopP,
|
||||
Stream: claudeRequest.Stream,
|
||||
}
|
||||
if claudeRequest.MaxTokens != nil {
|
||||
openAIRequest.MaxTokens = lo.ToPtr(lo.FromPtr(claudeRequest.MaxTokens))
|
||||
}
|
||||
if claudeRequest.TopP != nil {
|
||||
openAIRequest.TopP = lo.ToPtr(lo.FromPtr(claudeRequest.TopP))
|
||||
}
|
||||
if claudeRequest.TopK != nil {
|
||||
openAIRequest.TopK = lo.ToPtr(lo.FromPtr(claudeRequest.TopK))
|
||||
}
|
||||
if claudeRequest.Stream != nil {
|
||||
openAIRequest.Stream = lo.ToPtr(lo.FromPtr(claudeRequest.Stream))
|
||||
}
|
||||
|
||||
isOpenRouter := info.ChannelType == constant.ChannelTypeOpenRouter
|
||||
@@ -613,7 +623,7 @@ func toJSONString(v interface{}) string {
|
||||
func GeminiToOpenAIRequest(geminiRequest *dto.GeminiChatRequest, info *relaycommon.RelayInfo) (*dto.GeneralOpenAIRequest, error) {
|
||||
openaiRequest := &dto.GeneralOpenAIRequest{
|
||||
Model: info.UpstreamModelName,
|
||||
Stream: info.IsStream,
|
||||
Stream: lo.ToPtr(info.IsStream),
|
||||
}
|
||||
|
||||
// 转换 messages
|
||||
@@ -698,21 +708,21 @@ func GeminiToOpenAIRequest(geminiRequest *dto.GeminiChatRequest, info *relaycomm
|
||||
if geminiRequest.GenerationConfig.Temperature != nil {
|
||||
openaiRequest.Temperature = geminiRequest.GenerationConfig.Temperature
|
||||
}
|
||||
if geminiRequest.GenerationConfig.TopP > 0 {
|
||||
openaiRequest.TopP = geminiRequest.GenerationConfig.TopP
|
||||
if geminiRequest.GenerationConfig.TopP != nil && *geminiRequest.GenerationConfig.TopP > 0 {
|
||||
openaiRequest.TopP = lo.ToPtr(*geminiRequest.GenerationConfig.TopP)
|
||||
}
|
||||
if geminiRequest.GenerationConfig.TopK > 0 {
|
||||
openaiRequest.TopK = int(geminiRequest.GenerationConfig.TopK)
|
||||
if geminiRequest.GenerationConfig.TopK != nil && *geminiRequest.GenerationConfig.TopK > 0 {
|
||||
openaiRequest.TopK = lo.ToPtr(int(*geminiRequest.GenerationConfig.TopK))
|
||||
}
|
||||
if geminiRequest.GenerationConfig.MaxOutputTokens > 0 {
|
||||
openaiRequest.MaxTokens = geminiRequest.GenerationConfig.MaxOutputTokens
|
||||
if geminiRequest.GenerationConfig.MaxOutputTokens != nil && *geminiRequest.GenerationConfig.MaxOutputTokens > 0 {
|
||||
openaiRequest.MaxTokens = lo.ToPtr(*geminiRequest.GenerationConfig.MaxOutputTokens)
|
||||
}
|
||||
// gemini stop sequences 最多 5 个,openai stop 最多 4 个
|
||||
if len(geminiRequest.GenerationConfig.StopSequences) > 0 {
|
||||
openaiRequest.Stop = geminiRequest.GenerationConfig.StopSequences[:4]
|
||||
}
|
||||
if geminiRequest.GenerationConfig.CandidateCount > 0 {
|
||||
openaiRequest.N = geminiRequest.GenerationConfig.CandidateCount
|
||||
if geminiRequest.GenerationConfig.CandidateCount != nil && *geminiRequest.GenerationConfig.CandidateCount > 0 {
|
||||
openaiRequest.N = lo.ToPtr(*geminiRequest.GenerationConfig.CandidateCount)
|
||||
}
|
||||
|
||||
// 转换工具调用
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
"github.com/QuantumNous/new-api/dto"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func normalizeChatImageURLToString(v any) any {
|
||||
@@ -79,7 +80,7 @@ func ChatCompletionsRequestToResponsesRequest(req *dto.GeneralOpenAIRequest) (*d
|
||||
if req.Model == "" {
|
||||
return nil, errors.New("model is required")
|
||||
}
|
||||
if req.N > 1 {
|
||||
if lo.FromPtrOr(req.N, 1) > 1 {
|
||||
return nil, fmt.Errorf("n>1 is not supported in responses compatibility mode")
|
||||
}
|
||||
|
||||
@@ -356,9 +357,10 @@ func ChatCompletionsRequestToResponsesRequest(req *dto.GeneralOpenAIRequest) (*d
|
||||
|
||||
textRaw := convertChatResponseFormatToResponsesText(req.ResponseFormat)
|
||||
|
||||
maxOutputTokens := req.MaxTokens
|
||||
if req.MaxCompletionTokens > maxOutputTokens {
|
||||
maxOutputTokens = req.MaxCompletionTokens
|
||||
maxOutputTokens := lo.FromPtrOr(req.MaxTokens, uint(0))
|
||||
maxCompletionTokens := lo.FromPtrOr(req.MaxCompletionTokens, uint(0))
|
||||
if maxCompletionTokens > maxOutputTokens {
|
||||
maxOutputTokens = maxCompletionTokens
|
||||
}
|
||||
// OpenAI Responses API rejects max_output_tokens < 16 when explicitly provided.
|
||||
//if maxOutputTokens > 0 && maxOutputTokens < 16 {
|
||||
@@ -366,15 +368,14 @@ func ChatCompletionsRequestToResponsesRequest(req *dto.GeneralOpenAIRequest) (*d
|
||||
//}
|
||||
|
||||
var topP *float64
|
||||
if req.TopP != 0 {
|
||||
topP = common.GetPointer(req.TopP)
|
||||
if req.TopP != nil {
|
||||
topP = common.GetPointer(lo.FromPtr(req.TopP))
|
||||
}
|
||||
|
||||
out := &dto.OpenAIResponsesRequest{
|
||||
Model: req.Model,
|
||||
Input: inputRaw,
|
||||
Instructions: instructionsRaw,
|
||||
MaxOutputTokens: maxOutputTokens,
|
||||
Stream: req.Stream,
|
||||
Temperature: req.Temperature,
|
||||
Text: textRaw,
|
||||
@@ -386,6 +387,9 @@ func ChatCompletionsRequestToResponsesRequest(req *dto.GeneralOpenAIRequest) (*d
|
||||
Store: req.Store,
|
||||
Metadata: req.Metadata,
|
||||
}
|
||||
if req.MaxTokens != nil || req.MaxCompletionTokens != nil {
|
||||
out.MaxOutputTokens = lo.ToPtr(maxOutputTokens)
|
||||
}
|
||||
|
||||
if req.ReasoningEffort != "" {
|
||||
out.Reasoning = &dto.Reasoning{
|
||||
|
||||
Reference in New Issue
Block a user