diff --git a/ui-tui/src/__tests__/createGatewayEventHandler.test.ts b/ui-tui/src/__tests__/createGatewayEventHandler.test.ts index 071f8141a0..517b2be0c2 100644 --- a/ui-tui/src/__tests__/createGatewayEventHandler.test.ts +++ b/ui-tui/src/__tests__/createGatewayEventHandler.test.ts @@ -175,6 +175,26 @@ describe('createGatewayEventHandler', () => { expect(appended[0]?.text).toContain(cleaned) }) + it('does not append inline_diff twice when assistant text already contains it', () => { + const appended: Msg[] = [] + const onEvent = createGatewayEventHandler(buildCtx(appended)) + const cleaned = '--- a/foo.ts\n+++ b/foo.ts\n@@\n-old\n+new' + const assistantText = `Done. Here's the inline diff:\n\n\`\`\`diff\n${cleaned}\n\`\`\`` + + onEvent({ + payload: { inline_diff: cleaned, summary: 'patched', tool_id: 'tool-1' }, + type: 'tool.complete' + } as any) + onEvent({ + payload: { text: assistantText }, + type: 'message.complete' + } as any) + + expect(appended).toHaveLength(1) + expect(appended[0]?.text).toBe(assistantText) + expect((appended[0]?.text.match(/```diff/g) ?? []).length).toBe(1) + }) + it('shows setup panel for missing provider startup error', () => { const appended: Msg[] = [] const onEvent = createGatewayEventHandler(buildCtx(appended)) diff --git a/ui-tui/src/app/turnController.ts b/ui-tui/src/app/turnController.ts index db312d20e2..005eed4bcb 100644 --- a/ui-tui/src/app/turnController.ts +++ b/ui-tui/src/app/turnController.ts @@ -187,7 +187,7 @@ class TurnController { queueInlineDiff(diffText: string) { const text = diffText.trim() - if (!text) { + if (!text || this.pendingInlineDiffs.includes(text)) { return } @@ -239,8 +239,9 @@ class TurnController { const rawText = (payload.rendered ?? payload.text ?? this.bufRef).trimStart() const split = splitReasoning(rawText) const finalText = split.text - const inlineDiffBlock = this.pendingInlineDiffs.length - ? `\`\`\`diff\n${this.pendingInlineDiffs.join('\n\n')}\n\`\`\`` + const remainingInlineDiffs = this.pendingInlineDiffs.filter(diff => !finalText.includes(diff)) + const inlineDiffBlock = remainingInlineDiffs.length + ? `\`\`\`diff\n${remainingInlineDiffs.join('\n\n')}\n\`\`\`` : '' const mergedText = [finalText, inlineDiffBlock].filter(Boolean).join('\n\n') const existingReasoning = this.reasoningText.trim() || String(payload.reasoning ?? '').trim()