diff --git a/dto/gemini.go b/dto/gemini.go index fdeb2793d..feee333cb 100644 --- a/dto/gemini.go +++ b/dto/gemini.go @@ -293,12 +293,13 @@ type GeminiChatSafetyRating struct { type GeminiChatPromptFeedback struct { SafetyRatings []GeminiChatSafetyRating `json:"safetyRatings"` + BlockReason *string `json:"blockReason,omitempty"` } type GeminiChatResponse struct { - Candidates []GeminiChatCandidate `json:"candidates"` - PromptFeedback GeminiChatPromptFeedback `json:"promptFeedback"` - UsageMetadata GeminiUsageMetadata `json:"usageMetadata"` + Candidates []GeminiChatCandidate `json:"candidates"` + PromptFeedback *GeminiChatPromptFeedback `json:"promptFeedback,omitempty"` + UsageMetadata GeminiUsageMetadata `json:"usageMetadata"` } type GeminiUsageMetadata struct { diff --git a/relay/channel/gemini/relay-gemini.go b/relay/channel/gemini/relay-gemini.go index fa932e51e..a8247217b 100644 --- a/relay/channel/gemini/relay-gemini.go +++ b/relay/channel/gemini/relay-gemini.go @@ -1050,7 +1050,12 @@ func GeminiChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError) } if len(geminiResponse.Candidates) == 0 { - return nil, types.NewOpenAIError(errors.New("no candidates returned"), types.ErrorCodeBadResponseBody, http.StatusInternalServerError) + //return nil, types.NewOpenAIError(errors.New("no candidates returned"), types.ErrorCodeBadResponseBody, http.StatusInternalServerError) + if geminiResponse.PromptFeedback != nil && geminiResponse.PromptFeedback.BlockReason != nil { + return nil, types.NewOpenAIError(errors.New("request blocked by Gemini API: "+*geminiResponse.PromptFeedback.BlockReason), types.ErrorCodePromptBlocked, http.StatusBadRequest) + } else { + return nil, types.NewOpenAIError(errors.New("empty response from Gemini API"), types.ErrorCodeEmptyResponse, http.StatusInternalServerError) + } } fullTextResponse := responseGeminiChat2OpenAI(c, &geminiResponse) fullTextResponse.Model = info.UpstreamModelName diff --git a/service/convert.go b/service/convert.go index b232ca396..1a39e537a 100644 --- a/service/convert.go +++ b/service/convert.go @@ -636,9 +636,6 @@ func extractTextFromGeminiParts(parts []dto.GeminiPart) string { func ResponseOpenAI2Gemini(openAIResponse *dto.OpenAITextResponse, info *relaycommon.RelayInfo) *dto.GeminiChatResponse { geminiResponse := &dto.GeminiChatResponse{ Candidates: make([]dto.GeminiChatCandidate, 0, len(openAIResponse.Choices)), - PromptFeedback: dto.GeminiChatPromptFeedback{ - SafetyRatings: []dto.GeminiChatSafetyRating{}, - }, UsageMetadata: dto.GeminiUsageMetadata{ PromptTokenCount: openAIResponse.PromptTokens, CandidatesTokenCount: openAIResponse.CompletionTokens, @@ -735,9 +732,6 @@ func StreamResponseOpenAI2Gemini(openAIResponse *dto.ChatCompletionsStreamRespon geminiResponse := &dto.GeminiChatResponse{ Candidates: make([]dto.GeminiChatCandidate, 0, len(openAIResponse.Choices)), - PromptFeedback: dto.GeminiChatPromptFeedback{ - SafetyRatings: []dto.GeminiChatSafetyRating{}, - }, UsageMetadata: dto.GeminiUsageMetadata{ PromptTokenCount: info.PromptTokens, CandidatesTokenCount: 0, // 流式响应中可能没有完整的 usage 信息 diff --git a/types/error.go b/types/error.go index a42e84385..72f26ff30 100644 --- a/types/error.go +++ b/types/error.go @@ -69,6 +69,7 @@ const ( ErrorCodeEmptyResponse ErrorCode = "empty_response" ErrorCodeAwsInvokeError ErrorCode = "aws_invoke_error" ErrorCodeModelNotFound ErrorCode = "model_not_found" + ErrorCodePromptBlocked ErrorCode = "prompt_blocked" // sql error ErrorCodeQueryDataError ErrorCode = "query_data_error"