Skip to content

Commit 77c7589

Browse files
committed
fix(chat): restrict narration seam space to sentence boundaries
1 parent f837a5a commit 77c7589

2 files changed

Lines changed: 36 additions & 3 deletions

File tree

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,36 @@ describe('narration text seams', () => {
328328
expect(text.content).toBe('that triggered it. The failing block is X.')
329329
})
330330

331+
it('never inserts a space into a segment split mid-word or mid-URL', () => {
332+
const seam = (first: string, second: string): string => {
333+
const blocks: ContentBlock[] = [
334+
subagentStart('research', 'S1', 'main'),
335+
{ type: 'subagent_text', content: first, spanId: 'S1', subagent: 'research', timestamp: 2 },
336+
{
337+
type: 'subagent_text',
338+
content: second,
339+
spanId: 'S1',
340+
subagent: 'research',
341+
timestamp: 3,
342+
},
343+
]
344+
const segments = parseBlocks(blocks)
345+
const group = segments.find((s) => s.type === 'agent_group')
346+
if (!group || group.type !== 'agent_group') throw new Error('expected group')
347+
const text = group.items.find((i) => i.type === 'text')
348+
if (!text || text.type !== 'text') throw new Error('expected text')
349+
return text.content
350+
}
351+
352+
expect(seam('the fox jum', 'ps over')).toBe('the fox jumps over')
353+
expect(seam('see https://example', '/path for details')).toBe(
354+
'see https://example/path for details'
355+
)
356+
expect(seam('日本語のテキストが分割', 'されても壊れない')).toBe(
357+
'日本語のテキストが分割されても壊れない'
358+
)
359+
})
360+
331361
it('does not double-space when the seam already has whitespace', () => {
332362
const blocks: ContentBlock[] = [
333363
subagentStart('research', 'S1', 'main'),

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,12 @@ function createAgentGroupSegment(name: string, id: string): AgentGroupSegment {
140140
function appendTextItem(group: AgentGroupSegment, content: string): void {
141141
const lastItem = group.items[group.items.length - 1]
142142
if (lastItem?.type === 'text') {
143-
// Distinct blocks (e.g. a thinking run followed by a text run) can meet
144-
// without any whitespace at the seam — insert a space so sentences never glue.
145-
const needsSpace = !/\s$/.test(lastItem.content) && !/^\s/.test(content)
143+
// Distinct segments (e.g. a thinking run followed by a text run) can meet
144+
// without any whitespace at the seam, gluing sentences together. Repair
145+
// only unambiguous sentence boundaries — trailing punctuation meeting a
146+
// fresh alphanumeric start — so a segment split mid-word, mid-URL, or in
147+
// text that takes no spaces (CJK) is never corrupted.
148+
const needsSpace = /[.!?;:]$/.test(lastItem.content) && /^[A-Za-z0-9]/.test(content)
146149
lastItem.content += (needsSpace ? ' ' : '') + content
147150
} else {
148151
group.items.push({ type: 'text', content })

0 commit comments

Comments
 (0)