mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-03 04:50:52 +08:00
Enhance response and request handling in translators
- Refactored response handling to process multiple content parts effectively. - Improved `tool_calls` structure with unique ID generation and enhanced mapping logic. - Simplified `SystemInstruction` and tool message parsing in requests for better accuracy. - Enhanced handling of function calls and tool responses with improved data integration.
This commit is contained in:
@@ -24,6 +24,39 @@ func PrepareRequest(rawJson []byte) (string, *client.Content, []client.Content,
|
|||||||
contents := make([]client.Content, 0)
|
contents := make([]client.Content, 0)
|
||||||
var systemInstruction *client.Content
|
var systemInstruction *client.Content
|
||||||
messagesResult := gjson.GetBytes(rawJson, "messages")
|
messagesResult := gjson.GetBytes(rawJson, "messages")
|
||||||
|
|
||||||
|
toolItems := make(map[string]*client.FunctionResponse)
|
||||||
|
if messagesResult.IsArray() {
|
||||||
|
messagesResults := messagesResult.Array()
|
||||||
|
for i := 0; i < len(messagesResults); i++ {
|
||||||
|
messageResult := messagesResults[i]
|
||||||
|
roleResult := messageResult.Get("role")
|
||||||
|
if roleResult.Type != gjson.String {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
contentResult := messageResult.Get("content")
|
||||||
|
if roleResult.String() == "tool" {
|
||||||
|
toolCallID := messageResult.Get("tool_call_id").String()
|
||||||
|
if toolCallID != "" {
|
||||||
|
var responseData string
|
||||||
|
if contentResult.Type == gjson.String {
|
||||||
|
responseData = contentResult.String()
|
||||||
|
} else if contentResult.IsObject() && contentResult.Get("type").String() == "text" {
|
||||||
|
responseData = contentResult.Get("text").String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// drop the timestamp from the tool call ID
|
||||||
|
toolCallIDs := strings.Split(toolCallID, "-")
|
||||||
|
strings.Join(toolCallIDs, "-")
|
||||||
|
newToolCallID := strings.Join(toolCallIDs[:len(toolCallIDs)-1], "-")
|
||||||
|
|
||||||
|
functionResponse := client.FunctionResponse{Name: newToolCallID, Response: map[string]interface{}{"result": responseData}}
|
||||||
|
toolItems[toolCallID] = &functionResponse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if messagesResult.IsArray() {
|
if messagesResult.IsArray() {
|
||||||
messagesResults := messagesResult.Array()
|
messagesResults := messagesResult.Array()
|
||||||
for i := 0; i < len(messagesResults); i++ {
|
for i := 0; i < len(messagesResults); i++ {
|
||||||
@@ -97,39 +130,43 @@ func PrepareRequest(rawJson []byte) (string, *client.Content, []client.Content,
|
|||||||
contents = append(contents, client.Content{Role: "model", Parts: []client.Part{{Text: contentResult.String()}}})
|
contents = append(contents, client.Content{Role: "model", Parts: []client.Part{{Text: contentResult.String()}}})
|
||||||
} else if !contentResult.Exists() || contentResult.Type == gjson.Null {
|
} else if !contentResult.Exists() || contentResult.Type == gjson.Null {
|
||||||
// Handle tool calls made by the assistant.
|
// Handle tool calls made by the assistant.
|
||||||
|
functionIDs := make([]string, 0)
|
||||||
toolCallsResult := messageResult.Get("tool_calls")
|
toolCallsResult := messageResult.Get("tool_calls")
|
||||||
if toolCallsResult.IsArray() {
|
if toolCallsResult.IsArray() {
|
||||||
|
parts := make([]client.Part, 0)
|
||||||
tcsResult := toolCallsResult.Array()
|
tcsResult := toolCallsResult.Array()
|
||||||
for j := 0; j < len(tcsResult); j++ {
|
for j := 0; j < len(tcsResult); j++ {
|
||||||
tcResult := tcsResult[j]
|
tcResult := tcsResult[j]
|
||||||
|
|
||||||
|
functionID := tcResult.Get("id").String()
|
||||||
|
functionIDs = append(functionIDs, functionID)
|
||||||
|
|
||||||
functionName := tcResult.Get("function.name").String()
|
functionName := tcResult.Get("function.name").String()
|
||||||
functionArgs := tcResult.Get("function.arguments").String()
|
functionArgs := tcResult.Get("function.arguments").String()
|
||||||
var args map[string]any
|
var args map[string]any
|
||||||
if err := json.Unmarshal([]byte(functionArgs), &args); err == nil {
|
if err := json.Unmarshal([]byte(functionArgs), &args); err == nil {
|
||||||
contents = append(contents, client.Content{
|
parts = append(parts, client.Part{
|
||||||
Role: "model", Parts: []client.Part{{
|
|
||||||
FunctionCall: &client.FunctionCall{
|
FunctionCall: &client.FunctionCall{
|
||||||
Name: functionName,
|
Name: functionName,
|
||||||
Args: args,
|
Args: args,
|
||||||
},
|
},
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(parts) > 0 {
|
||||||
|
contents = append(contents, client.Content{
|
||||||
|
Role: "model", Parts: parts,
|
||||||
|
})
|
||||||
|
|
||||||
|
toolParts := make([]client.Part, 0)
|
||||||
|
for _, functionID := range functionIDs {
|
||||||
|
if functionResponse, ok := toolItems[functionID]; ok {
|
||||||
|
toolParts = append(toolParts, client.Part{FunctionResponse: functionResponse})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Tool messages contain the output of a tool call.
|
contents = append(contents, client.Content{Role: "tool", Parts: toolParts})
|
||||||
case "tool":
|
}
|
||||||
toolCallID := messageResult.Get("tool_call_id").String()
|
|
||||||
if toolCallID != "" {
|
|
||||||
var responseData string
|
|
||||||
if contentResult.Type == gjson.String {
|
|
||||||
responseData = contentResult.String()
|
|
||||||
} else if contentResult.IsObject() && contentResult.Get("type").String() == "text" {
|
|
||||||
responseData = contentResult.Get("text").String()
|
|
||||||
}
|
}
|
||||||
functionResponse := client.FunctionResponse{Name: toolCallID, Response: map[string]interface{}{"result": responseData}}
|
|
||||||
contents = append(contents, client.Content{Role: "tool", Parts: []client.Part{{FunctionResponse: &functionResponse}}})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package translator
|
package translator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
@@ -62,7 +63,11 @@ func ConvertCliToOpenAI(rawJson []byte, unixTimestamp int64, isGlAPIKey bool) st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process the main content part of the response.
|
// Process the main content part of the response.
|
||||||
partResult := gjson.GetBytes(rawJson, "response.candidates.0.content.parts.0")
|
partsResult := gjson.GetBytes(rawJson, "response.candidates.0.content.parts")
|
||||||
|
if partsResult.IsArray() {
|
||||||
|
partResults := partsResult.Array()
|
||||||
|
for i := 0; i < len(partResults); i++ {
|
||||||
|
partResult := partResults[i]
|
||||||
partTextResult := partResult.Get("text")
|
partTextResult := partResult.Get("text")
|
||||||
functionCallResult := partResult.Get("functionCall")
|
functionCallResult := partResult.Get("functionCall")
|
||||||
|
|
||||||
@@ -76,18 +81,22 @@ func ConvertCliToOpenAI(rawJson []byte, unixTimestamp int64, isGlAPIKey bool) st
|
|||||||
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
|
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
|
||||||
} else if functionCallResult.Exists() {
|
} else if functionCallResult.Exists() {
|
||||||
// Handle function call content.
|
// Handle function call content.
|
||||||
functionCallTemplate := `[{"id": "","type": "function","function": {"name": "","arguments": ""}}]`
|
toolCallsResult := gjson.Get(template, "choices.0.delta.tool_calls")
|
||||||
|
if !toolCallsResult.Exists() || !toolCallsResult.IsArray() {
|
||||||
|
template, _ = sjson.SetRaw(template, "choices.0.delta.tool_calls", `[]`)
|
||||||
|
}
|
||||||
|
|
||||||
|
functionCallTemplate := `{"id": "","type": "function","function": {"name": "","arguments": ""}}`
|
||||||
fcName := functionCallResult.Get("name").String()
|
fcName := functionCallResult.Get("name").String()
|
||||||
functionCallTemplate, _ = sjson.Set(functionCallTemplate, "0.id", fcName)
|
functionCallTemplate, _ = sjson.Set(functionCallTemplate, "id", fmt.Sprintf("%s-%d", fcName, time.Now().UnixNano()))
|
||||||
functionCallTemplate, _ = sjson.Set(functionCallTemplate, "0.function.name", fcName)
|
functionCallTemplate, _ = sjson.Set(functionCallTemplate, "function.name", fcName)
|
||||||
if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {
|
if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {
|
||||||
functionCallTemplate, _ = sjson.Set(functionCallTemplate, "0.function.arguments", fcArgsResult.Raw)
|
functionCallTemplate, _ = sjson.Set(functionCallTemplate, "function.arguments", fcArgsResult.Raw)
|
||||||
}
|
}
|
||||||
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
|
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
|
||||||
template, _ = sjson.SetRaw(template, "choices.0.delta.tool_calls", functionCallTemplate)
|
template, _ = sjson.SetRaw(template, "choices.0.message.tool_calls.-1", functionCallTemplate)
|
||||||
} else {
|
}
|
||||||
// If no usable content is found, return an empty string.
|
}
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return template
|
return template
|
||||||
@@ -163,7 +172,7 @@ func ConvertCliToOpenAINonStream(rawJson []byte, unixTimestamp int64, isGlAPIKey
|
|||||||
}
|
}
|
||||||
functionCallItemTemplate := `{"id": "","type": "function","function": {"name": "","arguments": ""}}`
|
functionCallItemTemplate := `{"id": "","type": "function","function": {"name": "","arguments": ""}}`
|
||||||
fcName := functionCallResult.Get("name").String()
|
fcName := functionCallResult.Get("name").String()
|
||||||
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "id", fcName)
|
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "id", fmt.Sprintf("%s-%d", fcName, time.Now().UnixNano()))
|
||||||
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.name", fcName)
|
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.name", fcName)
|
||||||
if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {
|
if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {
|
||||||
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.arguments", fcArgsResult.Raw)
|
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.arguments", fcArgsResult.Raw)
|
||||||
|
|||||||
Reference in New Issue
Block a user