From 8b8221c31915b5760060f2a33eae264c7c604463 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Mon, 10 Aug 2026 16:12:41 -0700 Subject: [PATCH 1/2] Update chat_session.dart --- examples/simple_chat/lib/chat_session.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple_chat/lib/chat_session.dart b/examples/simple_chat/lib/chat_session.dart index ff69f7a05..9e00153d8 100644 --- a/examples/simple_chat/lib/chat_session.dart +++ b/examples/simple_chat/lib/chat_session.dart @@ -121,7 +121,7 @@ sealed class ChatSession extends ChangeNotifier { _currentAiMessage = Message(isUser: false, text: ''); _messages.add(_currentAiMessage!); } - _currentAiMessage!.text = (_currentAiMessage!.text ?? '') + chunk; + _currentAiMessage!.text = '${_currentAiMessage!.text ?? ''}\n$chunk'; notifyListeners(); } From ed661389ef7f0f473874aa03494e5d3d8e0f1a71 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Tue, 11 Aug 2026 12:33:41 -0700 Subject: [PATCH 2/2] - --- examples/simple_chat/lib/chat_session.dart | 2 +- packages/genui/CHANGELOG.md | 5 +++++ .../lib/src/transport/a2ui_transport_adapter.dart | 5 ++++- packages/genui/pubspec.yaml | 2 +- .../test/transport/a2ui_transport_adapter_test.dart | 10 ++++++++++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/examples/simple_chat/lib/chat_session.dart b/examples/simple_chat/lib/chat_session.dart index 9e00153d8..ff69f7a05 100644 --- a/examples/simple_chat/lib/chat_session.dart +++ b/examples/simple_chat/lib/chat_session.dart @@ -121,7 +121,7 @@ sealed class ChatSession extends ChangeNotifier { _currentAiMessage = Message(isUser: false, text: ''); _messages.add(_currentAiMessage!); } - _currentAiMessage!.text = '${_currentAiMessage!.text ?? ''}\n$chunk'; + _currentAiMessage!.text = (_currentAiMessage!.text ?? '') + chunk; notifyListeners(); } diff --git a/packages/genui/CHANGELOG.md b/packages/genui/CHANGELOG.md index 591849fe0..c45e8e9f3 100644 --- a/packages/genui/CHANGELOG.md +++ b/packages/genui/CHANGELOG.md @@ -1,5 +1,10 @@ # `genui` Changelog +## 0.10.2 + +- Fixed `A2uiTransportAdapter.incomingText` trimming every streamed chunk, which + made words run together when chunks were concatenated. + ## 0.10.1 - Depend on `a2ui_core` 0.1.0, its first non-pre-release version. diff --git a/packages/genui/lib/src/transport/a2ui_transport_adapter.dart b/packages/genui/lib/src/transport/a2ui_transport_adapter.dart index 7eacaa883..ddc0f8bef 100644 --- a/packages/genui/lib/src/transport/a2ui_transport_adapter.dart +++ b/packages/genui/lib/src/transport/a2ui_transport_adapter.dart @@ -61,11 +61,14 @@ class A2uiTransportAdapter implements Transport { } /// A stream of sanitizer text for the chat UI. + /// + /// Chunk whitespace is preserved as emitted, so consumers can concatenate + /// chunks without words smashing together across chunk boundaries. @override Stream get incomingText => _pipeline .where((e) => e is TextEvent) .cast() - .map((e) => e.text.trim()) + .map((e) => e.text) .where((text) => text.isNotEmpty); /// A stream of A2UI messages parsed from the input. diff --git a/packages/genui/pubspec.yaml b/packages/genui/pubspec.yaml index 0cc248f82..60aa77285 100644 --- a/packages/genui/pubspec.yaml +++ b/packages/genui/pubspec.yaml @@ -4,7 +4,7 @@ name: genui description: Generates and displays generative user interfaces (GenUI) in Flutter using AI. -version: 0.10.1 +version: 0.10.2 homepage: https://github.com/flutter/genui/tree/main/packages/genui license: BSD-3-Clause issue_tracker: https://github.com/flutter/genui/issues diff --git a/packages/genui/test/transport/a2ui_transport_adapter_test.dart b/packages/genui/test/transport/a2ui_transport_adapter_test.dart index 3c6b92f08..012a60060 100644 --- a/packages/genui/test/transport/a2ui_transport_adapter_test.dart +++ b/packages/genui/test/transport/a2ui_transport_adapter_test.dart @@ -29,6 +29,16 @@ void main() { await textFuture; }); + test('incomingText preserves chunk whitespace', () async { + final Future textFuture = expectLater( + transportAdapter.incomingText, + emitsInOrder(['a variety of friendly ', 'spots']), + ); + transportAdapter.addChunk('a variety of friendly '); + transportAdapter.addChunk('spots'); + await textFuture; + }); + test('addChunk with message updates state', () async { // Using JSON block final json = '''```json