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
12335d92
authored
Dec 21, 2024
by
Calcium-Ion
Committed by
GitHub
Dec 21, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #645 from MartialBE/gemini_res_format
支持gemini结构化输出
parents
1888a103
a8fa11f9
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
1 deletions
+61
-1
dto/openai_request.go
+9
-1
relay/channel/gemini/dto.go
+2
-0
relay/channel/gemini/relay-gemini.go
+50
-0
No files found.
dto/openai_request.go
View file @
12335d92
...
@@ -4,6 +4,14 @@ import "encoding/json"
...
@@ -4,6 +4,14 @@ import "encoding/json"
type
ResponseFormat
struct
{
type
ResponseFormat
struct
{
Type
string
`json:"type,omitempty"`
Type
string
`json:"type,omitempty"`
JsonSchema
*
FormatJsonSchema
`json:"json_schema,omitempty"`
}
type
FormatJsonSchema
struct
{
Description
string
`json:"description,omitempty"`
Name
string
`json:"name"`
Schema
any
`json:"schema,omitempty"`
Strict
any
`json:"strict,omitempty"`
}
}
type
GeneralOpenAIRequest
struct
{
type
GeneralOpenAIRequest
struct
{
...
@@ -25,7 +33,7 @@ type GeneralOpenAIRequest struct {
...
@@ -25,7 +33,7 @@ type GeneralOpenAIRequest struct {
Functions
any
`json:"functions,omitempty"`
Functions
any
`json:"functions,omitempty"`
FrequencyPenalty
float64
`json:"frequency_penalty,omitempty"`
FrequencyPenalty
float64
`json:"frequency_penalty,omitempty"`
PresencePenalty
float64
`json:"presence_penalty,omitempty"`
PresencePenalty
float64
`json:"presence_penalty,omitempty"`
ResponseFormat
any
`json:"response_format,omitempty"`
ResponseFormat
*
ResponseFormat
`json:"response_format,omitempty"`
EncodingFormat
any
`json:"encoding_format,omitempty"`
EncodingFormat
any
`json:"encoding_format,omitempty"`
Seed
float64
`json:"seed,omitempty"`
Seed
float64
`json:"seed,omitempty"`
Tools
[]
ToolCall
`json:"tools,omitempty"`
Tools
[]
ToolCall
`json:"tools,omitempty"`
...
...
relay/channel/gemini/dto.go
View file @
12335d92
...
@@ -46,6 +46,8 @@ type GeminiChatGenerationConfig struct {
...
@@ -46,6 +46,8 @@ type GeminiChatGenerationConfig struct {
MaxOutputTokens
uint
`json:"maxOutputTokens,omitempty"`
MaxOutputTokens
uint
`json:"maxOutputTokens,omitempty"`
CandidateCount
int
`json:"candidateCount,omitempty"`
CandidateCount
int
`json:"candidateCount,omitempty"`
StopSequences
[]
string
`json:"stopSequences,omitempty"`
StopSequences
[]
string
`json:"stopSequences,omitempty"`
ResponseMimeType
string
`json:"responseMimeType,omitempty"`
ResponseSchema
any
`json:"responseSchema,omitempty"`
}
}
type
GeminiChatCandidate
struct
{
type
GeminiChatCandidate
struct
{
...
...
relay/channel/gemini/relay-gemini.go
View file @
12335d92
...
@@ -77,6 +77,16 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -77,6 +77,16 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
},
},
}
}
}
}
if
textRequest
.
ResponseFormat
!=
nil
&&
(
textRequest
.
ResponseFormat
.
Type
==
"json_schema"
||
textRequest
.
ResponseFormat
.
Type
==
"json_object"
)
{
geminiRequest
.
GenerationConfig
.
ResponseMimeType
=
"application/json"
if
textRequest
.
ResponseFormat
.
JsonSchema
!=
nil
&&
textRequest
.
ResponseFormat
.
JsonSchema
.
Schema
!=
nil
{
cleanedSchema
:=
removeAdditionalPropertiesWithDepth
(
textRequest
.
ResponseFormat
.
JsonSchema
.
Schema
,
0
)
geminiRequest
.
GenerationConfig
.
ResponseSchema
=
cleanedSchema
}
}
//shouldAddDummyModelMessage := false
//shouldAddDummyModelMessage := false
for
_
,
message
:=
range
textRequest
.
Messages
{
for
_
,
message
:=
range
textRequest
.
Messages
{
...
@@ -165,6 +175,46 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -165,6 +175,46 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
return
&
geminiRequest
,
nil
return
&
geminiRequest
,
nil
}
}
func
removeAdditionalPropertiesWithDepth
(
schema
interface
{},
depth
int
)
interface
{}
{
if
depth
>=
5
{
return
schema
}
v
,
ok
:=
schema
.
(
map
[
string
]
interface
{})
if
!
ok
||
len
(
v
)
==
0
{
return
schema
}
// 如果type不为object和array,则直接返回
if
typeVal
,
exists
:=
v
[
"type"
];
!
exists
||
(
typeVal
!=
"object"
&&
typeVal
!=
"array"
)
{
return
schema
}
switch
v
[
"type"
]
{
case
"object"
:
delete
(
v
,
"additionalProperties"
)
// 处理 properties
if
properties
,
ok
:=
v
[
"properties"
]
.
(
map
[
string
]
interface
{});
ok
{
for
key
,
value
:=
range
properties
{
properties
[
key
]
=
removeAdditionalPropertiesWithDepth
(
value
,
depth
+
1
)
}
}
for
_
,
field
:=
range
[]
string
{
"allOf"
,
"anyOf"
,
"oneOf"
}
{
if
nested
,
ok
:=
v
[
field
]
.
([]
interface
{});
ok
{
for
i
,
item
:=
range
nested
{
nested
[
i
]
=
removeAdditionalPropertiesWithDepth
(
item
,
depth
+
1
)
}
}
}
case
"array"
:
if
items
,
ok
:=
v
[
"items"
]
.
(
map
[
string
]
interface
{});
ok
{
v
[
"items"
]
=
removeAdditionalPropertiesWithDepth
(
items
,
depth
+
1
)
}
}
return
v
}
func
(
g
*
GeminiChatResponse
)
GetResponseText
()
string
{
func
(
g
*
GeminiChatResponse
)
GetResponseText
()
string
{
if
g
==
nil
{
if
g
==
nil
{
return
""
return
""
...
...
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