1515 OpenAIToolStreamState ,
1616)
1717from fast_agent .llm .stream_types import StreamChunk
18+ from fast_agent .utils .reasoning_chunk_join import normalize_reasoning_delta
1819
1920if TYPE_CHECKING :
2021 from openai .types .responses import (
@@ -200,11 +201,19 @@ def tool_use_id_for_event(*, event: Any, item: Any, index: int | None) -> str:
200201 part_type = getattr (part , "type" , None )
201202 part_text = getattr (part , "text" , None )
202203 if part_type in {"reasoning" , "reasoning_text" } and part_text :
203- reasoning_segments .append (part_text )
204+ last_char = (
205+ reasoning_segments [- 1 ][- 1 ]
206+ if reasoning_segments and reasoning_segments [- 1 ]
207+ else None
208+ )
209+ normalized_delta = normalize_reasoning_delta (last_char , part_text )
210+ if not normalized_delta :
211+ continue
212+ reasoning_segments .append (normalized_delta )
204213 self ._notify_stream_listeners (
205- StreamChunk (text = part_text , is_reasoning = True )
214+ StreamChunk (text = normalized_delta , is_reasoning = True )
206215 )
207- reasoning_chars += len (part_text )
216+ reasoning_chars += len (normalized_delta )
208217 await self ._emit_streaming_progress (
209218 model = f"{ model } (reasoning)" ,
210219 new_total = reasoning_chars ,
@@ -217,11 +226,19 @@ def tool_use_id_for_event(*, event: Any, item: Any, index: int | None) -> str:
217226 "response.reasoning_summary.delta" ,
218227 }:
219228 if delta :
220- reasoning_segments .append (delta )
229+ last_char = (
230+ reasoning_segments [- 1 ][- 1 ]
231+ if reasoning_segments and reasoning_segments [- 1 ]
232+ else None
233+ )
234+ normalized_delta = normalize_reasoning_delta (last_char , delta )
235+ if not normalized_delta :
236+ continue
237+ reasoning_segments .append (normalized_delta )
221238 self ._notify_stream_listeners (
222- StreamChunk (text = delta , is_reasoning = True )
239+ StreamChunk (text = normalized_delta , is_reasoning = True )
223240 )
224- reasoning_chars += len (delta )
241+ reasoning_chars += len (normalized_delta )
225242 await self ._emit_streaming_progress (
226243 model = f"{ model } (summary)" ,
227244 new_total = reasoning_chars ,
@@ -234,11 +251,19 @@ def tool_use_id_for_event(*, event: Any, item: Any, index: int | None) -> str:
234251 "response.reasoning_text.delta" ,
235252 }:
236253 if delta :
237- reasoning_segments .append (delta )
254+ last_char = (
255+ reasoning_segments [- 1 ][- 1 ]
256+ if reasoning_segments and reasoning_segments [- 1 ]
257+ else None
258+ )
259+ normalized_delta = normalize_reasoning_delta (last_char , delta )
260+ if not normalized_delta :
261+ continue
262+ reasoning_segments .append (normalized_delta )
238263 self ._notify_stream_listeners (
239- StreamChunk (text = delta , is_reasoning = True )
264+ StreamChunk (text = normalized_delta , is_reasoning = True )
240265 )
241- reasoning_chars += len (delta )
266+ reasoning_chars += len (normalized_delta )
242267 await self ._emit_streaming_progress (
243268 model = f"{ model } (reasoning)" ,
244269 new_total = reasoning_chars ,
0 commit comments