Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
35105b3d
authored
Oct 05, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: update Gemini API response handling to include block reason and improve error reporting
parent
d76ee92f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
11 additions
and
10 deletions
+11
-10
dto/gemini.go
+4
-3
relay/channel/gemini/relay-gemini.go
+6
-1
service/convert.go
+0
-6
types/error.go
+1
-0
No files found.
dto/gemini.go
View file @
35105b3d
...
@@ -293,12 +293,13 @@ type GeminiChatSafetyRating struct {
...
@@ -293,12 +293,13 @@ type GeminiChatSafetyRating struct {
type
GeminiChatPromptFeedback
struct
{
type
GeminiChatPromptFeedback
struct
{
SafetyRatings
[]
GeminiChatSafetyRating
`json:"safetyRatings"`
SafetyRatings
[]
GeminiChatSafetyRating
`json:"safetyRatings"`
BlockReason
*
string
`json:"blockReason,omitempty"`
}
}
type
GeminiChatResponse
struct
{
type
GeminiChatResponse
struct
{
Candidates
[]
GeminiChatCandidate
`json:"candidates"`
Candidates
[]
GeminiChatCandidate
`json:"candidates"`
PromptFeedback
GeminiChatPromptFeedback
`json:"promptFeedback
"`
PromptFeedback
*
GeminiChatPromptFeedback
`json:"promptFeedback,omitempty
"`
UsageMetadata
GeminiUsageMetadata
`json:"usageMetadata"`
UsageMetadata
GeminiUsageMetadata
`json:"usageMetadata"`
}
}
type
GeminiUsageMetadata
struct
{
type
GeminiUsageMetadata
struct
{
...
...
relay/channel/gemini/relay-gemini.go
View file @
35105b3d
...
@@ -1050,7 +1050,12 @@ func GeminiChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
...
@@ -1050,7 +1050,12 @@ func GeminiChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
return
nil
,
types
.
NewOpenAIError
(
err
,
types
.
ErrorCodeBadResponseBody
,
http
.
StatusInternalServerError
)
return
nil
,
types
.
NewOpenAIError
(
err
,
types
.
ErrorCodeBadResponseBody
,
http
.
StatusInternalServerError
)
}
}
if
len
(
geminiResponse
.
Candidates
)
==
0
{
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
:=
responseGeminiChat2OpenAI
(
c
,
&
geminiResponse
)
fullTextResponse
.
Model
=
info
.
UpstreamModelName
fullTextResponse
.
Model
=
info
.
UpstreamModelName
...
...
service/convert.go
View file @
35105b3d
...
@@ -636,9 +636,6 @@ func extractTextFromGeminiParts(parts []dto.GeminiPart) string {
...
@@ -636,9 +636,6 @@ func extractTextFromGeminiParts(parts []dto.GeminiPart) string {
func
ResponseOpenAI2Gemini
(
openAIResponse
*
dto
.
OpenAITextResponse
,
info
*
relaycommon
.
RelayInfo
)
*
dto
.
GeminiChatResponse
{
func
ResponseOpenAI2Gemini
(
openAIResponse
*
dto
.
OpenAITextResponse
,
info
*
relaycommon
.
RelayInfo
)
*
dto
.
GeminiChatResponse
{
geminiResponse
:=
&
dto
.
GeminiChatResponse
{
geminiResponse
:=
&
dto
.
GeminiChatResponse
{
Candidates
:
make
([]
dto
.
GeminiChatCandidate
,
0
,
len
(
openAIResponse
.
Choices
)),
Candidates
:
make
([]
dto
.
GeminiChatCandidate
,
0
,
len
(
openAIResponse
.
Choices
)),
PromptFeedback
:
dto
.
GeminiChatPromptFeedback
{
SafetyRatings
:
[]
dto
.
GeminiChatSafetyRating
{},
},
UsageMetadata
:
dto
.
GeminiUsageMetadata
{
UsageMetadata
:
dto
.
GeminiUsageMetadata
{
PromptTokenCount
:
openAIResponse
.
PromptTokens
,
PromptTokenCount
:
openAIResponse
.
PromptTokens
,
CandidatesTokenCount
:
openAIResponse
.
CompletionTokens
,
CandidatesTokenCount
:
openAIResponse
.
CompletionTokens
,
...
@@ -735,9 +732,6 @@ func StreamResponseOpenAI2Gemini(openAIResponse *dto.ChatCompletionsStreamRespon
...
@@ -735,9 +732,6 @@ func StreamResponseOpenAI2Gemini(openAIResponse *dto.ChatCompletionsStreamRespon
geminiResponse
:=
&
dto
.
GeminiChatResponse
{
geminiResponse
:=
&
dto
.
GeminiChatResponse
{
Candidates
:
make
([]
dto
.
GeminiChatCandidate
,
0
,
len
(
openAIResponse
.
Choices
)),
Candidates
:
make
([]
dto
.
GeminiChatCandidate
,
0
,
len
(
openAIResponse
.
Choices
)),
PromptFeedback
:
dto
.
GeminiChatPromptFeedback
{
SafetyRatings
:
[]
dto
.
GeminiChatSafetyRating
{},
},
UsageMetadata
:
dto
.
GeminiUsageMetadata
{
UsageMetadata
:
dto
.
GeminiUsageMetadata
{
PromptTokenCount
:
info
.
PromptTokens
,
PromptTokenCount
:
info
.
PromptTokens
,
CandidatesTokenCount
:
0
,
// 流式响应中可能没有完整的 usage 信息
CandidatesTokenCount
:
0
,
// 流式响应中可能没有完整的 usage 信息
...
...
types/error.go
View file @
35105b3d
...
@@ -69,6 +69,7 @@ const (
...
@@ -69,6 +69,7 @@ const (
ErrorCodeEmptyResponse
ErrorCode
=
"empty_response"
ErrorCodeEmptyResponse
ErrorCode
=
"empty_response"
ErrorCodeAwsInvokeError
ErrorCode
=
"aws_invoke_error"
ErrorCodeAwsInvokeError
ErrorCode
=
"aws_invoke_error"
ErrorCodeModelNotFound
ErrorCode
=
"model_not_found"
ErrorCodeModelNotFound
ErrorCode
=
"model_not_found"
ErrorCodePromptBlocked
ErrorCode
=
"prompt_blocked"
// sql error
// sql error
ErrorCodeQueryDataError
ErrorCode
=
"query_data_error"
ErrorCodeQueryDataError
ErrorCode
=
"query_data_error"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment