Skip to content

Commit c423779

Browse files
committed
fix(copilot): render unclosed special tags as text on completed messages
The special-tag parser suppressed everything after an opening tag with no close, even after streaming ended — so an assistant message that merely MENTIONED `<workspace_resource>` in prose lost its entire remainder in the UI. The stream itself completed fine; only the render truncated. Suppression now applies only while streaming. A completed message can never finish an unclosed tag, so the marker was literal text and the remainder is rendered as-is. Originally written alongside the docs/ VFS work and reverted at review time to keep that PR to one concern; this restores it on its own.
1 parent f43b52c commit c423779

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,21 @@ describe('parseSpecialTags with <question>', () => {
149149
expect(segments).toEqual([{ type: 'text', content: 'Thinking about it. ' }])
150150
})
151151

152+
it('renders an unclosed tag as text once the message is complete', () => {
153+
const content =
154+
'The `<workspace_resource>` file chip only renders when its path points to a real file.'
155+
const { segments, hasPendingTag } = parseSpecialTags(content, false)
156+
expect(hasPendingTag).toBe(false)
157+
expect(segments).toEqual([
158+
{ type: 'text', content: 'The `' },
159+
{
160+
type: 'text',
161+
content:
162+
'<workspace_resource>` file chip only renders when its path points to a real file.',
163+
},
164+
])
165+
})
166+
152167
it('strips a trailing partial opening tag while streaming', () => {
153168
const { segments, hasPendingTag } = parseSpecialTags('Let me ask. <ques', true)
154169
expect(hasPendingTag).toBe(true)

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,18 @@ export function parseSpecialTags(content: string, isStreaming: boolean): ParsedS
526526
const closeIdx = content.indexOf(closeTag, bodyStart)
527527

528528
if (closeIdx === -1) {
529-
hasPendingTag = true
530-
cursor = content.length
529+
if (isStreaming) {
530+
hasPendingTag = true
531+
cursor = content.length
532+
break
533+
}
534+
// A completed message can never finish an unclosed tag — the marker was
535+
// literal text mentioning the tag (e.g. "the `<workspace_resource>`
536+
// chip"), not a real tag. Render the remainder instead of swallowing it.
537+
const remaining = content.slice(nearestStart)
538+
if (remaining.trim()) {
539+
segments.push({ type: 'text', content: remaining })
540+
}
531541
break
532542
}
533543

0 commit comments

Comments
 (0)