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
87692e60
authored
Dec 23, 2024
by
Calcium-Ion
Committed by
GitHub
Dec 23, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #652 from Yan-Zero/main
fix: mutil func call in gemini
parents
6288b26f
dbd412f8
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
80 additions
and
41 deletions
+80
-41
.gitignore
+2
-0
common/str.go
+3
-1
relay/channel/gemini/relay-gemini.go
+75
-40
No files found.
.gitignore
View file @
87692e60
...
@@ -8,3 +8,4 @@ build
...
@@ -8,3 +8,4 @@ build
logs
logs
web/dist
web/dist
.env
.env
one-api
\ No newline at end of file
common/str.go
View file @
87692e60
...
@@ -35,7 +35,9 @@ func StrToMap(str string) map[string]interface{} {
...
@@ -35,7 +35,9 @@ func StrToMap(str string) map[string]interface{} {
m
:=
make
(
map
[
string
]
interface
{})
m
:=
make
(
map
[
string
]
interface
{})
err
:=
json
.
Unmarshal
([]
byte
(
str
),
&
m
)
err
:=
json
.
Unmarshal
([]
byte
(
str
),
&
m
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
return
map
[
string
]
interface
{}{
"result"
:
str
,
}
}
}
return
m
return
m
}
}
...
...
relay/channel/gemini/relay-gemini.go
View file @
87692e60
...
@@ -95,7 +95,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -95,7 +95,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
geminiRequest
.
GenerationConfig
.
ResponseSchema
=
cleanedSchema
geminiRequest
.
GenerationConfig
.
ResponseSchema
=
cleanedSchema
}
}
}
}
tool_call_ids
:=
make
(
map
[
string
]
string
)
//shouldAddDummyModelMessage := false
//shouldAddDummyModelMessage := false
for
_
,
message
:=
range
textRequest
.
Messages
{
for
_
,
message
:=
range
textRequest
.
Messages
{
...
@@ -108,6 +108,27 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -108,6 +108,27 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
},
},
}
}
continue
continue
}
else
if
message
.
Role
==
"tool"
{
if
len
(
geminiRequest
.
Contents
)
==
0
||
geminiRequest
.
Contents
[
len
(
geminiRequest
.
Contents
)
-
1
]
.
Role
!=
"user"
{
geminiRequest
.
Contents
=
append
(
geminiRequest
.
Contents
,
GeminiChatContent
{
Role
:
"user"
,
})
}
var
parts
=
&
geminiRequest
.
Contents
[
len
(
geminiRequest
.
Contents
)
-
1
]
.
Parts
name
:=
""
if
message
.
Name
!=
nil
{
name
=
*
message
.
Name
}
else
if
val
,
exists
:=
tool_call_ids
[
message
.
ToolCallId
];
exists
{
name
=
val
}
functionResp
:=
&
FunctionResponse
{
Name
:
name
,
Response
:
common
.
StrToMap
(
message
.
StringContent
()),
}
*
parts
=
append
(
*
parts
,
GeminiPart
{
FunctionResponse
:
functionResp
,
})
continue
}
}
var
parts
[]
GeminiPart
var
parts
[]
GeminiPart
content
:=
GeminiChatContent
{
content
:=
GeminiChatContent
{
...
@@ -125,23 +146,10 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -125,23 +146,10 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
},
},
}
}
parts
=
append
(
parts
,
toolCall
)
parts
=
append
(
parts
,
toolCall
)
tool_call_ids
[
call
.
ID
]
=
call
.
Function
.
Name
}
}
}
}
if
!
isToolCall
{
if
!
isToolCall
{
if
message
.
Role
==
"tool"
{
content
.
Role
=
"user"
name
:=
""
if
message
.
Name
!=
nil
{
name
=
*
message
.
Name
}
functionResp
:=
&
FunctionResponse
{
Name
:
name
,
Response
:
common
.
StrToMap
(
message
.
StringContent
()),
}
parts
=
append
(
parts
,
GeminiPart
{
FunctionResponse
:
functionResp
,
})
}
else
{
openaiContent
:=
message
.
ParseContent
()
openaiContent
:=
message
.
ParseContent
()
imageNum
:=
0
imageNum
:=
0
for
_
,
part
:=
range
openaiContent
{
for
_
,
part
:=
range
openaiContent
{
...
@@ -180,7 +188,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
...
@@ -180,7 +188,7 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest) (*GeminiChatReque
}
}
}
}
}
}
}
content
.
Parts
=
parts
content
.
Parts
=
parts
// there's no assistant role in gemini and API shall vomit if Role is not user or model
// there's no assistant role in gemini and API shall vomit if Role is not user or model
...
@@ -242,19 +250,13 @@ func (g *GeminiChatResponse) GetResponseText() string {
...
@@ -242,19 +250,13 @@ func (g *GeminiChatResponse) GetResponseText() string {
return
""
return
""
}
}
func
getToolCalls
(
candidate
*
GeminiChatCandidate
)
[]
dto
.
ToolCall
{
func
getToolCall
(
item
*
GeminiPart
)
*
dto
.
ToolCall
{
var
toolCalls
[]
dto
.
ToolCall
item
:=
candidate
.
Content
.
Parts
[
0
]
if
item
.
FunctionCall
==
nil
{
return
toolCalls
}
argsBytes
,
err
:=
json
.
Marshal
(
item
.
FunctionCall
.
Arguments
)
argsBytes
,
err
:=
json
.
Marshal
(
item
.
FunctionCall
.
Arguments
)
if
err
!=
nil
{
if
err
!=
nil
{
//common.SysError("getToolCall
s
failed: " + err.Error())
//common.SysError("getToolCall failed: " + err.Error())
return
toolCalls
return
nil
}
}
toolCall
:=
dto
.
ToolCall
{
return
&
dto
.
ToolCall
{
ID
:
fmt
.
Sprintf
(
"call_%s"
,
common
.
GetUUID
()),
ID
:
fmt
.
Sprintf
(
"call_%s"
,
common
.
GetUUID
()),
Type
:
"function"
,
Type
:
"function"
,
Function
:
dto
.
FunctionCall
{
Function
:
dto
.
FunctionCall
{
...
@@ -262,10 +264,32 @@ func getToolCalls(candidate *GeminiChatCandidate) []dto.ToolCall {
...
@@ -262,10 +264,32 @@ func getToolCalls(candidate *GeminiChatCandidate) []dto.ToolCall {
Name
:
item
.
FunctionCall
.
FunctionName
,
Name
:
item
.
FunctionCall
.
FunctionName
,
},
},
}
}
toolCalls
=
append
(
toolCalls
,
toolCall
)
return
toolCalls
}
}
// func getToolCalls(candidate *GeminiChatCandidate, index int) []dto.ToolCall {
// var toolCalls []dto.ToolCall
// item := candidate.Content.Parts[index]
// if item.FunctionCall == nil {
// return toolCalls
// }
// argsBytes, err := json.Marshal(item.FunctionCall.Arguments)
// if err != nil {
// //common.SysError("getToolCalls failed: " + err.Error())
// return toolCalls
// }
// toolCall := dto.ToolCall{
// ID: fmt.Sprintf("call_%s", common.GetUUID()),
// Type: "function",
// Function: dto.FunctionCall{
// Arguments: string(argsBytes),
// Name: item.FunctionCall.FunctionName,
// },
// }
// toolCalls = append(toolCalls, toolCall)
// return toolCalls
// }
func
responseGeminiChat2OpenAI
(
response
*
GeminiChatResponse
)
*
dto
.
OpenAITextResponse
{
func
responseGeminiChat2OpenAI
(
response
*
GeminiChatResponse
)
*
dto
.
OpenAITextResponse
{
fullTextResponse
:=
dto
.
OpenAITextResponse
{
fullTextResponse
:=
dto
.
OpenAITextResponse
{
Id
:
fmt
.
Sprintf
(
"chatcmpl-%s"
,
common
.
GetUUID
()),
Id
:
fmt
.
Sprintf
(
"chatcmpl-%s"
,
common
.
GetUUID
()),
...
@@ -275,6 +299,8 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
...
@@ -275,6 +299,8 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
}
}
content
,
_
:=
json
.
Marshal
(
""
)
content
,
_
:=
json
.
Marshal
(
""
)
for
i
,
candidate
:=
range
response
.
Candidates
{
for
i
,
candidate
:=
range
response
.
Candidates
{
// jsonData, _ := json.MarshalIndent(candidate, "", " ")
// common.SysLog(fmt.Sprintf("candidate: %v", string(jsonData)))
choice
:=
dto
.
OpenAITextResponseChoice
{
choice
:=
dto
.
OpenAITextResponseChoice
{
Index
:
i
,
Index
:
i
,
Message
:
dto
.
Message
{
Message
:
dto
.
Message
{
...
@@ -284,16 +310,20 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
...
@@ -284,16 +310,20 @@ func responseGeminiChat2OpenAI(response *GeminiChatResponse) *dto.OpenAITextResp
FinishReason
:
constant
.
FinishReasonStop
,
FinishReason
:
constant
.
FinishReasonStop
,
}
}
if
len
(
candidate
.
Content
.
Parts
)
>
0
{
if
len
(
candidate
.
Content
.
Parts
)
>
0
{
if
candidate
.
Content
.
Parts
[
0
]
.
FunctionCall
!=
nil
{
choice
.
FinishReason
=
constant
.
FinishReasonToolCalls
choice
.
Message
.
SetToolCalls
(
getToolCalls
(
&
candidate
))
}
else
{
var
texts
[]
string
var
texts
[]
string
var
tool_calls
[]
dto
.
ToolCall
for
_
,
part
:=
range
candidate
.
Content
.
Parts
{
for
_
,
part
:=
range
candidate
.
Content
.
Parts
{
if
part
.
FunctionCall
!=
nil
{
choice
.
FinishReason
=
constant
.
FinishReasonToolCalls
if
call
:=
getToolCall
(
&
part
);
call
!=
nil
{
tool_calls
=
append
(
tool_calls
,
*
call
)
}
}
else
{
texts
=
append
(
texts
,
part
.
Text
)
texts
=
append
(
texts
,
part
.
Text
)
}
}
choice
.
Message
.
SetStringContent
(
strings
.
Join
(
texts
,
"
\n
"
))
}
}
choice
.
Message
.
SetStringContent
(
strings
.
Join
(
texts
,
"
\n
"
))
choice
.
Message
.
SetToolCalls
(
tool_calls
)
}
}
fullTextResponse
.
Choices
=
append
(
fullTextResponse
.
Choices
,
choice
)
fullTextResponse
.
Choices
=
append
(
fullTextResponse
.
Choices
,
choice
)
}
}
...
@@ -304,18 +334,23 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) *dto.Ch
...
@@ -304,18 +334,23 @@ func streamResponseGeminiChat2OpenAI(geminiResponse *GeminiChatResponse) *dto.Ch
var
choice
dto
.
ChatCompletionsStreamResponseChoice
var
choice
dto
.
ChatCompletionsStreamResponseChoice
//choice.Delta.SetContentString(geminiResponse.GetResponseText())
//choice.Delta.SetContentString(geminiResponse.GetResponseText())
if
len
(
geminiResponse
.
Candidates
)
>
0
&&
len
(
geminiResponse
.
Candidates
[
0
]
.
Content
.
Parts
)
>
0
{
if
len
(
geminiResponse
.
Candidates
)
>
0
&&
len
(
geminiResponse
.
Candidates
[
0
]
.
Content
.
Parts
)
>
0
{
respFirstParts
:=
geminiResponse
.
Candidates
[
0
]
.
Content
.
Parts
if
respFirstParts
[
0
]
.
FunctionCall
!=
nil
{
// function response
choice
.
Delta
.
ToolCalls
=
getToolCalls
(
&
geminiResponse
.
Candidates
[
0
])
}
else
{
// text response
var
texts
[]
string
var
texts
[]
string
for
_
,
part
:=
range
respFirstParts
{
var
tool_calls
[]
dto
.
ToolCall
for
_
,
part
:=
range
geminiResponse
.
Candidates
[
0
]
.
Content
.
Parts
{
if
part
.
FunctionCall
!=
nil
{
if
call
:=
getToolCall
(
&
part
);
call
!=
nil
{
tool_calls
=
append
(
tool_calls
,
*
call
)
}
}
else
{
texts
=
append
(
texts
,
part
.
Text
)
texts
=
append
(
texts
,
part
.
Text
)
}
}
}
if
len
(
texts
)
>
0
{
choice
.
Delta
.
SetContentString
(
strings
.
Join
(
texts
,
"
\n
"
))
choice
.
Delta
.
SetContentString
(
strings
.
Join
(
texts
,
"
\n
"
))
}
}
if
len
(
tool_calls
)
>
0
{
choice
.
Delta
.
ToolCalls
=
tool_calls
}
}
}
var
response
dto
.
ChatCompletionsStreamResponse
var
response
dto
.
ChatCompletionsStreamResponse
response
.
Object
=
"chat.completion.chunk"
response
.
Object
=
"chat.completion.chunk"
...
...
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