Python: Fix: coalesce reasoning deltas into single block when content.id is None#6804
Open
PratikWayase wants to merge 1 commit into
Open
Python: Fix: coalesce reasoning deltas into single block when content.id is None#6804PratikWayase wants to merge 1 commit into
PratikWayase wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes AG-UI reasoning streaming so that providers which emit reasoning deltas with content.id=None (e.g., Ollama “thinking”) produce a single REASONING_START → (many) REASONING_MESSAGE_CONTENT → REASONING_END lifecycle per turn, instead of fragmenting into a new lifecycle per delta.
Changes:
- Updated
_emit_text_reasoning()to reuseflow.reasoning_message_idwhencontent.idis absent, only generating a new ID on the first delta of a reasoning block. - Added regression tests validating coalescing behavior, explicit
content.idbehavior, and “new turn/new id” behavior after_close_reasoning_block().
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| python/packages/ag-ui/agent_framework_ag_ui/_run_common.py | Reuses flow.reasoning_message_id for content.id=None reasoning deltas to prevent per-delta reasoning block fragmentation. |
| python/packages/ag-ui/tests/ag_ui/test_run_common.py | Adds regression coverage ensuring reasoning deltas coalesce into a single block/message_id per turn and reset correctly across turns. |
5 tasks
|
Fixes #6787 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation & Context
content.idper chunk, resulting incontent.id=Nonefor every delta._emit_text_reasoning) was callinggenerate_event_id()on every single delta whencontent.idwasNone. This caused the stream to emit aREASONING_START -> CONTENT -> REASONING_ENDlifecycle per token, instead of one lifecycle per turn.Description & Review Guide
Changed the
message_idassignment logic in_emit_text_reasoning()(_run_common.py). It now reuses the existingflow.reasoning_message_idwhencontent.idisNone, falling back togenerate_event_id()only on the very first delta of a turn. This brings it into parity with how_emit_text()already handles text deltas viaflow.message_id. Added 3 regression tests.Frontends will now correctly receive a single
REASONING_START -> (many) REASONING_MESSAGE_CONTENT -> REASONING_ENDblock per turn. This is a non-breaking change; providers that do supply acontent.idcontinue to use it exactly as before.Please verify the 5-line logic swap in
_emit_text_reasoningand the 3 new tests inTestReasoningCoalescingto ensure the coalescing behavior correctly mirrors_emit_text.Remaining Work (Out of Scope for this PR)
The original issue report contained a second, distinct bug regarding parallel tool calls. When Ollama issues the same tool twice in one turn,
agent-framework-ollama's_parse_tool_calls_from_ollamareuses the function name as thecall_id, causing a collision. That bug is located inagent-framework-ollamaand will be addressed in a separate PR.Related Issue
Partially addresses #6788
Contribution Checklist