fix: Prevent accidental loss of output text by refining tool call parsing for standalone payloads.

This commit is contained in:
CJACK
2026-02-20 03:18:28 +08:00
parent db49a3ec02
commit 1d2a6bf281
2 changed files with 29 additions and 1 deletions

View File

@@ -43,7 +43,10 @@ func BuildChatCompletion(completionID, model, finalPrompt, finalThinking, finalT
}
func BuildResponseObject(responseID, model, finalPrompt, finalThinking, finalText string, toolNames []string) map[string]any {
detected := util.ParseToolCalls(finalText, toolNames)
// Responses output should only be treated as tool calls when the model
// produced a standalone structured payload. This prevents accidental
// empty output_text on normal prose that merely contains tool_call-like text.
detected := util.ParseStandaloneToolCalls(finalText, toolNames)
exposedOutputText := finalText
output := make([]any, 0, 2)
if len(detected) > 0 {

View File

@@ -62,3 +62,28 @@ func TestBuildResponseObjectToolCallsFollowChatShape(t *testing.T) {
t.Fatalf("unexpected arguments: %#v", args)
}
}
func TestBuildResponseObjectKeepsOutputTextForMixedProse(t *testing.T) {
obj := BuildResponseObject(
"resp_test",
"gpt-4o",
"prompt",
"",
`示例格式:{"tool_calls":[{"name":"search","input":{"q":"golang"}}]},但这条是普通回答。`,
[]string{"search"},
)
outputText, _ := obj["output_text"].(string)
if outputText == "" {
t.Fatalf("expected output_text to be preserved for mixed prose")
}
output, _ := obj["output"].([]any)
if len(output) != 1 {
t.Fatalf("expected one output item, got %#v", obj["output"])
}
first, _ := output[0].(map[string]any)
if first["type"] != "message" {
t.Fatalf("expected output type message, got %#v", first["type"])
}
}