From 2cb0a580f34377c8b014ce20d8fdb370cfc2a12e Mon Sep 17 00:00:00 2001 From: Devon Rifkin Date: Thu, 21 Aug 2025 21:03:12 -0700 Subject: [PATCH] thinking: fix double emit when no opening tag The thinking parser will automatically transition to being a pass-through if non-whitespace is seen before an opening tag. However, we weren't clearing the buffer after the first non-whitespace input, so in practice the first token would be emitted twice. Added a test that demonstrated this, and then fixed the bug. --- thinking/parser.go | 4 +++- thinking/parser_test.go | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/thinking/parser.go b/thinking/parser.go index a4d05e35a3..bec0fb0e62 100644 --- a/thinking/parser.go +++ b/thinking/parser.go @@ -103,7 +103,9 @@ func eat(s *Parser) (string, string, bool) { // note that we use the original content, not the trimmed one because we // don't want to eat any whitespace in the real content if there were no // thinking tags - return "", s.acc.String(), false + untrimmed := s.acc.String() + s.acc.Reset() + return "", untrimmed, false } case thinkingState_ThinkingStartedEatingWhitespace: trimmed := strings.TrimLeftFunc(s.acc.String(), unicode.IsSpace) diff --git a/thinking/parser_test.go b/thinking/parser_test.go index 78c297cd95..460cf39248 100644 --- a/thinking/parser_test.go +++ b/thinking/parser_test.go @@ -58,6 +58,15 @@ func TestThinkingStreaming(t *testing.T) { wantContent: " abc", wantStateAfter: thinkingState_ThinkingDone, }, + // regression test for a bug where we were transitioning directly to + // ThinkingDone without clearing the buffer. This would cuase the first + // step to be outputted twice + { + input: "def", + wantThinking: "", + wantContent: "def", + wantStateAfter: thinkingState_ThinkingDone, + }, }, }, {