Skip to content

Commit e7d9e0a

Browse files
committed
fix: close <think> block only when reasoning_content is None
Signed-off-by: Yuichiro Utsumi <utsumi.yuichiro@fujitsu.com>
1 parent 194bb77 commit e7d9e0a

2 files changed

Lines changed: 12 additions & 14 deletions

File tree

python/dify_plugin/interfaces/model/large_language_model.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ def _wrap_thinking_by_reasoning_content(self, delta: dict, is_reasoning: bool) -
537537
content = delta.get("content") or ""
538538
reasoning_content = delta.get("reasoning_content")
539539
output = content
540-
if reasoning_content:
540+
if reasoning_content is not None:
541541
if not is_reasoning:
542542
output = "<think>\n" + reasoning_content
543543
is_reasoning = True
@@ -546,8 +546,7 @@ def _wrap_thinking_by_reasoning_content(self, delta: dict, is_reasoning: bool) -
546546
else:
547547
if is_reasoning:
548548
is_reasoning = False
549-
if not reasoning_content:
550-
output = "\n</think>"
549+
output = "\n</think>"
551550
if content:
552551
output += content
553552

python/tests/interfaces/model/test_wrap_think.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,16 @@ def test_wrap_thinking_logic_closure(self):
6262
chunks = [
6363
# Chunk 1: Thinking started
6464
{"reasoning_content": "Thinking started.", "content": ""},
65-
# Chunk 2: Still thinking
66-
{"reasoning_content": " Still thinking.", "content": ""},
67-
# Chunk 3: Thinking ended, transitioned to Tool Call (reasoning_content=None, content=None/Empty)
65+
# Chunk 2: Still thinking #1
66+
{"reasoning_content": " Still thinking #1.", "content": ""},
67+
# Chunk 3: Still thinking (reasoning_content=Empty)
68+
{"reasoning_content": "", "content": ""},
69+
# Chunk 4: Still thinking #2
70+
{"reasoning_content": " Still thinking #2.", "content": ""},
71+
# Chunk 5: Thinking ended, transitioned to Tool Call (reasoning_content=None, content=None/Empty)
6872
# This is a critical point, old logic would fail here because content is empty
6973
{"reasoning_content": None, "content": "", "tool_calls": [{"id": "call_1", "function": {}}]},
70-
# Chunk 4: Subsequent tool parameter stream
74+
# Chunk 6: Subsequent tool parameter stream
7175
{"reasoning_content": None, "content": "", "tool_calls": [{"function": {"arguments": "{"}}]},
7276
]
7377

@@ -86,13 +90,8 @@ def test_wrap_thinking_logic_closure(self):
8690
# Verify results
8791
print(f"DEBUG Output: {full_output!r}")
8892

89-
assert "<think>" in full_output
90-
assert "Thinking started. Still thinking." in full_output
91-
assert "</think>" in full_output, "Should verify <think> tag is closed properly"
92-
93-
# Verify the position of the closing tag: should be after the thinking content
94-
expected_part = "Thinking started. Still thinking.\n</think>"
95-
assert expected_part in full_output
93+
expected_output = "<think>\nThinking started. Still thinking #1. Still thinking #2.\n</think>"
94+
self.assertEqual(full_output, expected_output)
9695

9796
def test_standard_reasoning_flow(self):
9897
"""Test standard reasoning -> text flow"""

0 commit comments

Comments
 (0)