feat: publish sanitized custom.97 source

This commit is contained in:
cneicy committed 2026-10-27 20:43:39 +08:00
1 parent 8e6ed0317b
commit 86c0276156
1022 files changed
+69903 -19207

No files matched your search

@@ -8,6 +8,7 @@ import (
"time"
"github.com/QuantumNous/new-api/relaykit/dto"
"github.com/QuantumNous/new-api/relaykit/relayconvert/convmeta"
kitutil "github.com/QuantumNous/new-api/relaykit/relayconvert/kitutil"
)
@@ -24,9 +25,14 @@ const (
responsesEventOutputItemDone = "response.output_item.done"
responsesEventFunctionArgsDelta = "response.function_call_arguments.delta"
responsesEventFunctionArgsDone = "response.function_call_arguments.done"
responsesEventCustomToolInputDelta = "response.custom_tool_call_input.delta"
responsesEventCustomToolInputDone = "response.custom_tool_call_input.done"
responsesEventReasoningSummaryPartAdded = "response.reasoning_summary_part.added"
responsesEventReasoningSummaryDelta = "response.reasoning_summary_text.delta"
responsesEventReasoningSummaryDone = "response.reasoning_summary_text.done"
responsesEventReasoningSummaryPartDone = "response.reasoning_summary_part.done"
responsesOutputTypeFunctionCall = "function_call"
responsesOutputTypeCustomToolCall = "custom_tool_call"
responsesOutputTypeMessage = "message"
responsesOutputTypeReasoning = "reasoning"
responsesIncompleteReasonContentFilter = "content_filter"
@@ -34,6 +40,12 @@ const (
)
func ChatCompletionsResponseToResponsesResponse(resp *dto.OpenAITextResponse, id string) (*dto.OpenAIResponsesResponse, *dto.Usage, error) {
return ChatCompletionsResponseToResponsesResponseWithTools(resp, id, nil)
}
// ChatCompletionsResponseToResponsesResponseWithTools also restores function
// calls that tools marks as Responses custom tools into custom_tool_call items.
func ChatCompletionsResponseToResponsesResponseWithTools(resp *dto.OpenAITextResponse, id string, tools *convmeta.ResponsesToolState) (*dto.OpenAIResponsesResponse, *dto.Usage, error) {
if resp == nil {
return nil, nil, errors.New("response is nil")
}
@@ -93,7 +105,10 @@ func ChatCompletionsResponseToResponsesResponse(resp *dto.OpenAITextResponse, id
}
for i, toolCall := range choice.Message.ParseToolCalls() {
toolOutput, err := chatToolCallToResponsesOutput(toolCall, id, i, responseOutputStatus(out))
if (toolCall.Type == "" || toolCall.Type == "function") && strings.TrimSpace(toolCall.Function.Name) == "" {
continue
}
toolOutput, err := chatToolCallToResponsesOutput(toolCall, id, i, responseOutputStatus(out), tools)
if err != nil {
return nil, nil, err
}
@@ -202,18 +217,31 @@ func responseStatusString(resp *dto.OpenAIResponsesResponse) string {
return strings.TrimSpace(status)
}
func chatToolCallToResponsesOutput(toolCall dto.ToolCallRequest, responseID string, index int, status string) (dto.ResponsesOutput, error) {
func chatToolCallToResponsesOutput(toolCall dto.ToolCallRequest, responseID string, index int, status string, tools *convmeta.ResponsesToolState) (dto.ResponsesOutput, error) {
callID := strings.TrimSpace(toolCall.ID)
if callID == "" {
callID = fmt.Sprintf("%s_call_%d", responseID, index)
}
if toolCall.Type == "" || toolCall.Type == "function" {
namespace, name := tools.ResponsesToolName(toolCall.Function.Name)
if tools.IsCustomTool(toolCall.Function.Name) {
return dto.ResponsesOutput{
Type: responsesOutputTypeCustomToolCall,
ID: callID,
Status: status,
CallId: callID,
Name: name,
Namespace: namespace,
Input: chatArgumentsRawMessage(customToolInputFromArguments(toolCall.Function.Arguments)),
}, nil
}
return dto.ResponsesOutput{
Type: responsesOutputTypeFunctionCall,
ID: callID,
Status: status,
CallId: callID,
Name: toolCall.Function.Name,
Name: name,
Namespace: namespace,
Arguments: chatArgumentsRawMessage(toolCall.Function.Arguments),
}, nil
}
@@ -226,6 +254,28 @@ func chatToolCallToResponsesOutput(toolCall dto.ToolCallRequest, responseID stri
}, nil
}
// customToolInputFromArguments unwraps the raw custom tool input from the
// {"input": ...} arguments a Chat function call carries. Arguments of any other
// shape are returned unchanged so the model's output is never dropped.
func customToolInputFromArguments(arguments string) string {
var value map[string]any
if err := kitutil.UnmarshalJsonStr(arguments, &value); err != nil {
return arguments
}
input, ok := value[convmeta.CustomToolInputArgument]
if !ok {
return arguments
}
if text, ok := input.(string); ok {
return text
}
raw, err := kitutil.Marshal(input)
if err != nil {
return arguments
}
return string(raw)
}
func chatArgumentsRawMessage(arguments string) []byte {
raw, err := kitutil.Marshal(arguments)
if err != nil {