From 206c3d547990588c286486a3463508ad1b732ad7 Mon Sep 17 00:00:00 2001 From: shern-point Date: Tue, 28 Apr 2026 13:27:41 +0800 Subject: [PATCH] fix: apply string protection in shared tool formatters Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- internal/toolcall/toolcall_edge_test.go | 2 +- internal/toolcall/toolcalls_format.go | 10 ++++++---- internal/toolcall/toolcalls_test.go | 2 +- internal/util/render.go | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/internal/toolcall/toolcall_edge_test.go b/internal/toolcall/toolcall_edge_test.go index 3db963a..690b756 100644 --- a/internal/toolcall/toolcall_edge_test.go +++ b/internal/toolcall/toolcall_edge_test.go @@ -9,7 +9,7 @@ import ( func TestFormatOpenAIStreamToolCalls(t *testing.T) { formatted := FormatOpenAIStreamToolCalls([]ParsedToolCall{ {Name: "search", Input: map[string]any{"q": "test"}}, - }) + }, nil) if len(formatted) != 1 { t.Fatalf("expected 1, got %d", len(formatted)) } diff --git a/internal/toolcall/toolcalls_format.go b/internal/toolcall/toolcalls_format.go index 1ef142b..9f7d001 100644 --- a/internal/toolcall/toolcalls_format.go +++ b/internal/toolcall/toolcalls_format.go @@ -7,9 +7,10 @@ import ( "github.com/google/uuid" ) -func FormatOpenAIToolCalls(calls []ParsedToolCall) []map[string]any { +func FormatOpenAIToolCalls(calls []ParsedToolCall, toolsRaw any) []map[string]any { + normalized := NormalizeParsedToolCallsForSchemas(calls, toolsRaw) out := make([]map[string]any, 0, len(calls)) - for _, c := range calls { + for _, c := range normalized { args, _ := json.Marshal(c.Input) out = append(out, map[string]any{ "id": "call_" + strings.ReplaceAll(uuid.NewString(), "-", ""), @@ -23,9 +24,10 @@ func FormatOpenAIToolCalls(calls []ParsedToolCall) []map[string]any { return out } -func FormatOpenAIStreamToolCalls(calls []ParsedToolCall) []map[string]any { +func FormatOpenAIStreamToolCalls(calls []ParsedToolCall, toolsRaw any) []map[string]any { + normalized := NormalizeParsedToolCallsForSchemas(calls, toolsRaw) out := make([]map[string]any, 0, len(calls)) - for i, c := range calls { + for i, c := range normalized { args, _ := json.Marshal(c.Input) out = append(out, map[string]any{ "index": i, diff --git a/internal/toolcall/toolcalls_test.go b/internal/toolcall/toolcalls_test.go index 62d800b..5bfe865 100644 --- a/internal/toolcall/toolcalls_test.go +++ b/internal/toolcall/toolcalls_test.go @@ -6,7 +6,7 @@ import ( ) func TestFormatOpenAIToolCalls(t *testing.T) { - formatted := FormatOpenAIToolCalls([]ParsedToolCall{{Name: "search", Input: map[string]any{"q": "x"}}}) + formatted := FormatOpenAIToolCalls([]ParsedToolCall{{Name: "search", Input: map[string]any{"q": "x"}}}, nil) if len(formatted) != 1 { t.Fatalf("expected 1, got %d", len(formatted)) } diff --git a/internal/util/render.go b/internal/util/render.go index 085ebb3..0092e4b 100644 --- a/internal/util/render.go +++ b/internal/util/render.go @@ -20,7 +20,7 @@ func BuildOpenAIChatCompletion(completionID, model, finalPrompt, finalThinking, } if len(detected) > 0 { finishReason = "tool_calls" - messageObj["tool_calls"] = toolcall.FormatOpenAIToolCalls(detected) + messageObj["tool_calls"] = toolcall.FormatOpenAIToolCalls(detected, nil) messageObj["content"] = nil } promptTokens := EstimateTokens(finalPrompt)