mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-10-28 08:35:33 +08:00
fix(relaykit): preserve Gemini text alongside tool calls (#7998)
This commit is contained in:
1 parent
4d962e464d
commit
0165fef98d
2 files changed
+51
-1
No files matched your search
@@ -131,7 +131,8 @@ func GeminiGenerateContentRequestToOpenAIChat(ctx context.Context, geminiRequest
|
||||
|
||||
if len(toolCalls) > 0 {
|
||||
message.SetToolCalls(toolCalls)
|
||||
} else if len(mediaContents) == 1 && mediaContents[0].Type == "text" {
|
||||
}
|
||||
if len(mediaContents) == 1 && mediaContents[0].Type == "text" {
|
||||
message.Content = mediaContents[0].Text
|
||||
} else if len(mediaContents) > 0 {
|
||||
message.SetMediaContent(mediaContents)
|
||||
|
||||
@@ -1110,3 +1110,52 @@ func mustMarshalRequestJSON(t *testing.T, value any) []byte {
|
||||
require.NoError(t, err)
|
||||
return raw
|
||||
}
|
||||
|
||||
func TestGeminiToOpenAIChatPreservesTextAlongsideToolCalls(t *testing.T) {
|
||||
const text = "I will check the weather."
|
||||
call := dto.GeminiPart{FunctionCall: &dto.FunctionCall{
|
||||
ID: "call_weather", FunctionName: "get_weather", Arguments: map[string]any{"city": "Paris"},
|
||||
}}
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
parts []dto.GeminiPart
|
||||
wantText []string
|
||||
wantCalls int
|
||||
}{
|
||||
{name: "text and call", parts: []dto.GeminiPart{{Text: text}, call}, wantText: []string{text}, wantCalls: 1},
|
||||
{name: "text around call", parts: []dto.GeminiPart{{Text: text}, call, {Text: "Please wait."}}, wantText: []string{text, "Please wait."}, wantCalls: 1},
|
||||
{name: "call only", parts: []dto.GeminiPart{call}, wantCalls: 1},
|
||||
{name: "text only", parts: []dto.GeminiPart{{Text: text}}, wantText: []string{text}},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
request := &dto.GeminiChatRequest{Contents: []dto.GeminiChatContent{{Role: "model", Parts: tt.parts}}}
|
||||
result, err := ConvertRequest(context.Background(), &convmeta.Values{
|
||||
UpstreamModelName: "gpt-4o", ChannelMetaAttached: true,
|
||||
}, types.RelayFormatOpenAI, request)
|
||||
require.NoError(t, err)
|
||||
converted, ok := result.Value.(*dto.GeneralOpenAIRequest)
|
||||
require.True(t, ok)
|
||||
// Verify the JSON sent upstream, including custom DTO serialization.
|
||||
body, err := kitutil.Marshal(converted)
|
||||
require.NoError(t, err)
|
||||
var wire dto.GeneralOpenAIRequest
|
||||
require.NoError(t, kitutil.Unmarshal(body, &wire))
|
||||
require.Len(t, wire.Messages, 1)
|
||||
assistant := wire.Messages[0]
|
||||
assert.Equal(t, "assistant", assistant.Role)
|
||||
content := assistant.ParseContent()
|
||||
require.Len(t, content, len(tt.wantText))
|
||||
for i, want := range tt.wantText {
|
||||
assert.Equal(t, "text", content[i].Type)
|
||||
assert.Equal(t, want, content[i].Text)
|
||||
}
|
||||
calls := assistant.ParseToolCalls()
|
||||
require.Len(t, calls, tt.wantCalls)
|
||||
if tt.wantCalls > 0 {
|
||||
assert.Equal(t, "call_weather", calls[0].ID)
|
||||
assert.Equal(t, "get_weather", calls[0].Function.Name)
|
||||
assert.JSONEq(t, `{"city":"Paris"}`, calls[0].Function.Arguments)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user