From fe0f3d2c17a3ffdf6ce8845f142730e749b3b3ea Mon Sep 17 00:00:00 2001 From: "CJACK." Date: Sun, 22 Mar 2026 09:29:21 +0800 Subject: [PATCH] fix: strip empty json fences from sanitized stream text --- internal/adapter/openai/tool_history_sanitize.go | 5 ++++- internal/adapter/openai/tool_history_sanitize_test.go | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/internal/adapter/openai/tool_history_sanitize.go b/internal/adapter/openai/tool_history_sanitize.go index 6a2e80a..126414a 100644 --- a/internal/adapter/openai/tool_history_sanitize.go +++ b/internal/adapter/openai/tool_history_sanitize.go @@ -5,10 +5,13 @@ import ( ) var leakedToolHistoryPattern = regexp.MustCompile(`(?is)\[TOOL_CALL_HISTORY\][\s\S]*?\[/TOOL_CALL_HISTORY\]|\[TOOL_RESULT_HISTORY\][\s\S]*?\[/TOOL_RESULT_HISTORY\]`) +var emptyJSONFencePattern = regexp.MustCompile("(?is)```json\\s*```") func sanitizeLeakedToolHistory(text string) string { if text == "" { return text } - return leakedToolHistoryPattern.ReplaceAllString(text, "") + out := leakedToolHistoryPattern.ReplaceAllString(text, "") + out = emptyJSONFencePattern.ReplaceAllString(out, "") + return out } diff --git a/internal/adapter/openai/tool_history_sanitize_test.go b/internal/adapter/openai/tool_history_sanitize_test.go index 02128c9..7c10ad2 100644 --- a/internal/adapter/openai/tool_history_sanitize_test.go +++ b/internal/adapter/openai/tool_history_sanitize_test.go @@ -43,6 +43,14 @@ func TestSanitizeLeakedToolHistoryPreservesChunkWhitespace(t *testing.T) { } } +func TestSanitizeLeakedToolHistoryRemovesEmptyJSONFence(t *testing.T) { + raw := "before\n```json\n```\nafter" + got := sanitizeLeakedToolHistory(raw) + if got != "before\n\nafter" { + t.Fatalf("unexpected sanitized empty json fence: %q", got) + } +} + func TestFlushToolSieveDropsToolHistoryLeak(t *testing.T) { var state toolStreamSieveState chunk := "[TOOL_CALL_HISTORY]\nstatus: already_called\nfunction.name: exec\nfunction.arguments: {}\n[/TOOL_CALL_HISTORY]"