@@ -241,40 +241,57 @@ export function ChatContent({
241241 const hasSpecialContent = parsed . hasPendingTag || parsed . segments . some ( ( s ) => s . type !== 'text' )
242242
243243 if ( hasSpecialContent ) {
244+ type RenderGroup =
245+ | { kind : 'inline' ; markdown : string }
246+ | { kind : 'block' ; segment : ContentSegment ; index : number }
247+
248+ const groups : RenderGroup [ ] = [ ]
249+ let pendingMarkdown = ''
250+
251+ const flushMarkdown = ( ) => {
252+ if ( pendingMarkdown . trim ( ) ) {
253+ groups . push ( { kind : 'inline' , markdown : pendingMarkdown } )
254+ }
255+ pendingMarkdown = ''
256+ }
257+
258+ for ( let i = 0 ; i < parsed . segments . length ; i ++ ) {
259+ const s = parsed . segments [ i ]
260+ if ( s . type === 'workspace_resource' ) {
261+ const label = s . data . title || s . data . id
262+ pendingMarkdown += `[${ label } ](#wsres-${ s . data . type } -${ s . data . id } )`
263+ } else if ( s . type === 'text' || s . type === 'thinking' ) {
264+ pendingMarkdown += s . content
265+ } else {
266+ flushMarkdown ( )
267+ groups . push ( { kind : 'block' , segment : s , index : i } )
268+ }
269+ }
270+ flushMarkdown ( )
271+
244272 return (
245273 < div className = 'space-y-3' >
246- { parsed . segments . map ( ( segment , i ) => {
247- if (
248- segment . type === 'text' ||
249- segment . type === 'thinking' ||
250- segment . type === 'workspace_resource'
251- ) {
252- return null
274+ { groups . map ( ( group , i ) => {
275+ if ( group . kind === 'inline' ) {
276+ return (
277+ < div
278+ key = { `inline-${ i } ` }
279+ className = { cn ( PROSE_CLASSES , '[&>:first-child]:mt-0 [&>:last-child]:mb-0' ) }
280+ >
281+ < Streamdown mode = 'static' components = { MARKDOWN_COMPONENTS } >
282+ { group . markdown }
283+ </ Streamdown >
284+ </ div >
285+ )
253286 }
254287 return (
255- < SpecialTags key = { `special-${ i } ` } segment = { segment } onOptionSelect = { onOptionSelect } />
288+ < SpecialTags
289+ key = { `special-${ group . index } ` }
290+ segment = { group . segment }
291+ onOptionSelect = { onOptionSelect }
292+ />
256293 )
257294 } ) }
258- { ( ( ) => {
259- const reassembled = parsed . segments
260- . map ( ( s ) => {
261- if ( s . type === 'workspace_resource' ) {
262- const label = s . data . title || s . data . id
263- return `[${ label } ](#wsres-${ s . data . type } -${ s . data . id } )`
264- }
265- if ( s . type === 'text' || s . type === 'thinking' ) return s . content
266- return ''
267- } )
268- . join ( '' )
269- if ( ! reassembled . trim ( ) ) return null
270- return (
271- < div className = { cn ( PROSE_CLASSES , '[&>:first-child]:mt-0 [&>:last-child]:mb-0' ) } >
272- < Streamdown mode = 'static' components = { MARKDOWN_COMPONENTS } >
273- { reassembled }
274- </ Streamdown >
275- </ div >
276- )
277- } ) ( ) }
278295 { parsed . hasPendingTag && isStreaming && < PendingTagIndicator /> }
279296 </ div >
280297 )
0 commit comments