@@ -164,39 +164,52 @@ const FloatingAssistant: React.FC<FloatingAssistantProps> = () => {
164164 }
165165
166166 let accumulated = '' ;
167+ let aborted = false ;
167168
168- for await ( const event of parseSseStream ( response ) ) {
169- if ( event . type === 'text' ) {
170- accumulated += event . content ;
171- setStreamingText ( accumulated ) ;
172- } else if ( event . type === 'tool-start' ) {
173- setToolStatus ( `Using ${ event . toolName } …` ) ;
174- } else if ( event . type === 'tool-result' ) {
175- setToolStatus ( '' ) ;
176- } else if ( event . type === 'done' ) {
177- break ;
178- } else if ( event . type === 'error' ) {
179- throw new Error ( event . content ) ;
169+ try {
170+ for await ( const event of parseSseStream ( response ) ) {
171+ if ( event . type === 'text' ) {
172+ accumulated += event . content ;
173+ setStreamingText ( accumulated ) ;
174+ } else if ( event . type === 'tool-start' ) {
175+ setToolStatus ( `Using ${ event . toolName } …` ) ;
176+ } else if ( event . type === 'tool-result' ) {
177+ setToolStatus ( '' ) ;
178+ } else if ( event . type === 'done' ) {
179+ break ;
180+ } else if ( event . type === 'error' ) {
181+ throw new Error ( event . content ) ;
182+ }
183+ }
184+ } catch ( err : unknown ) {
185+ if ( err instanceof Error && err . name === 'AbortError' ) {
186+ aborted = true ;
187+ } else {
188+ accumulated = '' ;
180189 }
181190 }
182191
183- // Commit the full response to messages only once, when complete
184- setMessages ( [ ...updatedMessages , { role : 'assistant' , content : accumulated || 'No response received.' } ] ) ;
192+ // Batch all final state updates together in one synchronous block
193+ // so React never renders a frame with both messages + isLoading true
194+ if ( ! aborted ) {
195+ setMessages ( [
196+ ...updatedMessages ,
197+ {
198+ role : 'assistant' ,
199+ content : accumulated || 'Sorry, something went wrong. Please try again.' ,
200+ } ,
201+ ] ) ;
202+ }
203+ setStreamingText ( '' ) ;
204+ setToolStatus ( '' ) ;
205+ setIsLoading ( false ) ;
206+ abortRef . current = null ;
185207 } catch ( err : unknown ) {
186- if ( err instanceof Error && err . name === 'AbortError' ) return ;
187- setMessages ( [
188- ...updatedMessages ,
189- {
190- role : 'assistant' ,
191- content : 'Sorry, something went wrong. Please try again.' ,
192- } ,
193- ] ) ;
194- } finally {
195208 setStreamingText ( '' ) ;
196209 setToolStatus ( '' ) ;
197210 setIsLoading ( false ) ;
198211 abortRef . current = null ;
199- }
212+ } finally {
200213 } ;
201214
202215 const handleKeyDown = ( e : React . KeyboardEvent < HTMLTextAreaElement > ) => {
0 commit comments