Merge pull request #4469 from seefs001/fix/tool-arguments-object

fix: support raw JSON response tool arguments
This commit is contained in:
Calcium-Ion
2026-04-26 20:20:03 +08:00
committed by GitHub
5 changed files with 76 additions and 3 deletions
+16
View File
@@ -43,3 +43,19 @@ func GetJsonType(data json.RawMessage) string {
return "number"
}
}
// JsonRawMessageToString returns JSON strings as their decoded value and other JSON values as raw text.
func JsonRawMessageToString(data json.RawMessage) string {
trimmed := bytes.TrimSpace(data)
if len(trimmed) == 0 || bytes.Equal(trimmed, []byte("null")) {
return ""
}
if trimmed[0] != '"' {
return string(trimmed)
}
var value string
if err := Unmarshal(trimmed, &value); err != nil {
return string(trimmed)
}
return value
}
+43
View File
@@ -0,0 +1,43 @@
package common
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
func TestJsonRawMessageToString(t *testing.T) {
tests := []struct {
name string
data json.RawMessage
want string
}{
{
name: "object",
data: json.RawMessage(`{"city":"Paris","days":0,"strict":false}`),
want: `{"city":"Paris","days":0,"strict":false}`,
},
{
name: "string",
data: json.RawMessage(`"{\"city\":\"Paris\",\"days\":0,\"strict\":false}"`),
want: `{"city":"Paris","days":0,"strict":false}`,
},
{
name: "null",
data: json.RawMessage(`null`),
want: "",
},
{
name: "empty",
data: nil,
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, JsonRawMessageToString(tt.data))
})
}
}
+15 -1
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/types"
)
@@ -346,7 +347,20 @@ type ResponsesOutput struct {
Size string `json:"size"`
CallId string `json:"call_id,omitempty"`
Name string `json:"name,omitempty"`
Arguments string `json:"arguments,omitempty"`
Arguments json.RawMessage `json:"arguments,omitempty"`
}
// ArgumentsString returns function call arguments in the string form expected by Chat Completions.
func (r *ResponsesOutput) ArgumentsString() string {
if r == nil {
return ""
}
return ResponsesArgumentsString(r.Arguments)
}
// ResponsesArgumentsString returns function call arguments in the string form expected by Chat Completions.
func ResponsesArgumentsString(arguments json.RawMessage) string {
return common.JsonRawMessageToString(arguments)
}
type ResponsesOutputContent struct {
+1 -1
View File
@@ -408,7 +408,7 @@ func OaiResponsesToChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo
toolCallNameByID[callID] = name
}
newArgs := streamResp.Item.Arguments
newArgs := streamResp.Item.ArgumentsString()
prevArgs := toolCallArgsByID[callID]
argsDelta := ""
if newArgs != "" {
+1 -1
View File
@@ -60,7 +60,7 @@ func ResponsesResponseToChatCompletionsResponse(resp *dto.OpenAIResponsesRespons
Type: "function",
Function: dto.FunctionResponse{
Name: name,
Arguments: out.Arguments,
Arguments: out.ArgumentsString(),
},
})
}