Skip to content

Commit afa31f7

Browse files
committed
models - litellm - stop reasoning
1 parent eef11cc commit afa31f7

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

src/strands/models/litellm.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,22 +139,22 @@ async def stream(
139139

140140
logger.debug("got response from model")
141141
yield self.format_chunk({"chunk_type": "message_start"})
142-
yield self.format_chunk({"chunk_type": "content_start", "data_type": "text"})
143142

144143
tool_calls: dict[int, list[Any]] = {}
144+
started_reasoning = False
145+
started_text = False
145146

146147
async for event in response:
147148
# Defensive: skip events with empty or missing choices
148149
if not getattr(event, "choices", None):
149150
continue
150151
choice = event.choices[0]
151152

152-
if choice.delta.content:
153-
yield self.format_chunk(
154-
{"chunk_type": "content_delta", "data_type": "text", "data": choice.delta.content}
155-
)
156-
157153
if hasattr(choice.delta, "reasoning_content") and choice.delta.reasoning_content:
154+
if not started_reasoning:
155+
yield self.format_chunk({"chunk_type": "content_start", "data_type": "reasoning_content"})
156+
started_reasoning = True
157+
158158
yield self.format_chunk(
159159
{
160160
"chunk_type": "content_delta",
@@ -163,14 +163,27 @@ async def stream(
163163
}
164164
)
165165

166+
if choice.delta.content:
167+
if started_reasoning:
168+
yield self.format_chunk({"chunk_type": "content_stop", "data_type": "reasoning_content"})
169+
started_reasoning = False
170+
171+
if not started_text:
172+
yield self.format_chunk({"chunk_type": "content_start", "data_type": "text"})
173+
started_text = True
174+
175+
yield self.format_chunk(
176+
{"chunk_type": "content_delta", "data_type": "text", "data": choice.delta.content}
177+
)
178+
166179
for tool_call in choice.delta.tool_calls or []:
167180
tool_calls.setdefault(tool_call.index, []).append(tool_call)
168181

169182
if choice.finish_reason:
183+
if started_text:
184+
yield self.format_chunk({"chunk_type": "content_stop", "data_type": "text"})
170185
break
171186

172-
yield self.format_chunk({"chunk_type": "content_stop", "data_type": "text"})
173-
174187
for tool_deltas in tool_calls.values():
175188
yield self.format_chunk({"chunk_type": "content_start", "data_type": "tool", "data": tool_deltas[0]})
176189

tests/strands/models/test_litellm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ async def test_stream(litellm_acompletion, api_key, model_id, model, agenerator,
182182
{"messageStart": {"role": "assistant"}},
183183
{"contentBlockStart": {"start": {}}},
184184
{"contentBlockDelta": {"delta": {"reasoningContent": {"text": "\nI'm thinking"}}}},
185+
{"contentBlockStop": {}},
186+
{"contentBlockStart": {"start": {}}},
185187
{"contentBlockDelta": {"delta": {"text": "I'll calculate"}}},
186188
{"contentBlockDelta": {"delta": {"text": "that for you"}}},
187189
{"contentBlockStop": {}},
@@ -251,8 +253,6 @@ async def test_stream_empty(litellm_acompletion, api_key, model_id, model, agene
251253
tru_events = await alist(response)
252254
exp_events = [
253255
{"messageStart": {"role": "assistant"}},
254-
{"contentBlockStart": {"start": {}}},
255-
{"contentBlockStop": {}},
256256
{"messageStop": {"stopReason": "end_turn"}},
257257
]
258258

0 commit comments

Comments
 (0)