Skip to content

Commit 56f42e7

Browse files
committed
fix: Remove newline when combining reasoning in litellm
1 parent 0e93faf commit 56f42e7

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

src/google/adk/models/lite_llm.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,9 @@ async def _content_to_message_param(
912912
):
913913
reasoning_texts.append(_decode_inline_text_data(part.inline_data.data))
914914

915-
reasoning_content = _NEW_LINE.join(text for text in reasoning_texts if text)
915+
# Preserve reasoning deltas exactly as received. Injecting separators
916+
# between fragments can corrupt provider-streamed thinking text.
917+
reasoning_content = "".join(text for text in reasoning_texts if text)
916918
return ChatCompletionAssistantMessage(
917919
role=role,
918920
content=final_content,

tests/unittests/models/test_litellm.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,6 +2127,38 @@ async def test_content_to_message_param_assistant_thought_and_content_message():
21272127
assert message["reasoning_content"] == "internal reasoning"
21282128

21292129

2130+
@pytest.mark.asyncio
2131+
async def test_content_to_message_param_preserves_chunked_reasoning_deltas():
2132+
thought_part_1 = types.Part.from_text(text="Hel")
2133+
thought_part_1.thought = True
2134+
thought_part_2 = types.Part.from_text(text="lo")
2135+
thought_part_2.thought = True
2136+
content = types.Content(
2137+
role="assistant", parts=[thought_part_1, thought_part_2]
2138+
)
2139+
2140+
message = await _content_to_message_param(content)
2141+
2142+
assert message["role"] == "assistant"
2143+
assert message["content"] is None
2144+
assert message["reasoning_content"] == "Hello"
2145+
2146+
2147+
@pytest.mark.asyncio
2148+
async def test_content_to_message_param_preserves_reasoning_newlines():
2149+
thought_part_1 = types.Part.from_text(text="line 1\n")
2150+
thought_part_1.thought = True
2151+
thought_part_2 = types.Part.from_text(text="line 2")
2152+
thought_part_2.thought = True
2153+
content = types.Content(
2154+
role="assistant", parts=[thought_part_1, thought_part_2]
2155+
)
2156+
2157+
message = await _content_to_message_param(content)
2158+
2159+
assert message["reasoning_content"] == "line 1\nline 2"
2160+
2161+
21302162
@pytest.mark.asyncio
21312163
async def test_content_to_message_param_function_call():
21322164
content = types.Content(

0 commit comments

Comments
 (0)