Fix chunk newline. - #1017
Conversation
There was a problem hiding this comment.
Code Review
This pull request modifies how AI message chunks are appended in chat_session.dart by inserting a newline before each chunk. The reviewer correctly pointed out that this will break streaming message rendering by splitting the text across multiple lines, and suggested reverting to direct concatenation.
| _messages.add(_currentAiMessage!); | ||
| } | ||
| _currentAiMessage!.text = (_currentAiMessage!.text ?? '') + chunk; | ||
| _currentAiMessage!.text = '${_currentAiMessage!.text ?? ''}\n$chunk'; |
There was a problem hiding this comment.
Are you sure this works as expected?
My understanding is that the LLM emits a sequence of chunks structured however it wants, and there are no guarantees that the chunk boundary coincides with a newline, so therefore we should not inject additional newlines automatically, because they might be in the wrong place.
I don't fully understand the problem you're fixing, but if it's a lack of whitespace in the layout, perhaps this could be accomplished by post-processing the messages at render time to non-destructively add a newline at the end, rather than destructively adding it here in the chunk processing logic.
There was a problem hiding this comment.
Check screensots and comments on the issue to better understand both issue and fix: a2ui-project/a2ui#1891
There was a problem hiding this comment.
new line in most cases is noop for markdown, that makes me think the fix is right
There was a problem hiding this comment.
Hey Polina! Sorry I should have looked at the linked issue first to get more context - I'll do that next time.
I do think that it could cause problems to add a newline here because it's not always a no-op in markdown and could accidentally break words.
Analysis from Gemini
It turns out the issue isn't that the LLM is omitting spaces between chunks, but rather that A2uiTransportAdapter.incomingText is explicitly stripping them.
Specifically, in packages/genui/lib/src/transport/a2ui_transport_adapter.dart#L68:
@override
Stream<String> get incomingText => _pipeline
.where((e) => e is TextEvent)
.cast<TextEvent>()
.map((e) => e.text.trim()) // <-- Strips leading/trailing whitespace from every chunk!
.where((text) => text.isNotEmpty);Because .trim() is called on every TextEvent chunk before it reaches _updateAiMessage, any trailing or leading whitespace in streamed chunks (e.g. "ty of friendly ") gets stripped. When _updateAiMessage concatenates these trimmed chunks, words smash together across boundaries (e.g. "friendlyspots").Adding \n before every chunk in chat_session.dart forces literal line breaks inside sentences when chunks split mid-sentence or mid-word, leading to broken streaming rendering and unexpected formatting in Markdown (such as inside code blocks, tables, or lists).
Suggested Fix
Instead of appending in chat_session.dart, we should remove .trim() from A2uiTransportAdapter.incomingText so that original chunk whitespace is preserved as emitted.
There was a problem hiding this comment.
that's cool! I am impressed.
which model did you use?
applied the fix
There was a problem hiding this comment.
I think that was just flash actually! I'll send you a screenshot of my workflow :-D
Fixes a2ui-project/a2ui#1891 by removing
.trim()in transport layer.