[codex] Fix widget diff traversal for single-child nodes#113
Closed
weedon-openai wants to merge 1 commit intomainfrom
Closed
[codex] Fix widget diff traversal for single-child nodes#113weedon-openai wants to merge 1 commit intomainfrom
weedon-openai wants to merge 1 commit intomainfrom
Conversation
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.
Summary
This PR fixes widget diff traversal when a component's
childrenfield is represented as a single object instead of a list.User-visible effect
In streaming updates, some valid widget shapes could silently skip text-delta emission. The UI would then miss incremental updates and treat the widget as unchanged (or defer to later full updates), even when streaming text content changed.
Root cause
diff_widgetrecursively discovers streamingText/Markdownnodes by walkingchildren. The previous implementation assumedchildrenwas iterable as a list and iterated directly over it. Whenchildrenwas a singleWidgetComponentBaseobject, recursion did not traverse that child, so no streaming node was discovered and no delta was produced.Fix
Update traversal in
chatkit/server.pyso recursion handles both valid shapes:childrenas a singleWidgetComponentBasechildrenas a list of componentsTests
Added a regression case in
tests/test_widgets.pyundertest_diffthat usesDynamicWidgetRootwith a single-child object and asserts awidget.streaming_text.value_deltaevent is emitted when text grows.Validation run:
PYTHONPATH=. uv run pytest tests/test_widgets.py(passes)