From 58b4f35dfae35cac0ff685de0d0adeb669bbc4b2 Mon Sep 17 00:00:00 2001 From: Yufeng He <40085740+he-yufeng@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:43:46 +0800 Subject: [PATCH] fix(cli): skip thought parts in copy output (#4738) --- .../cli/src/ui/commands/copyCommand.test.ts | 26 +++++++++++++++++++ packages/cli/src/ui/commands/copyCommand.ts | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/ui/commands/copyCommand.test.ts b/packages/cli/src/ui/commands/copyCommand.test.ts index d199c702a9..aee08e8537 100644 --- a/packages/cli/src/ui/commands/copyCommand.test.ts +++ b/packages/cli/src/ui/commands/copyCommand.test.ts @@ -160,6 +160,32 @@ describe('copyCommand', () => { }); }); + it('should not copy thought parts from the last AI message', async () => { + if (!copyCommand.action) throw new Error('Command has no action'); + + const historyWithThoughtPart = [ + { + role: 'model', + parts: [ + { text: 'internal reasoning', thought: true }, + { text: 'Visible report' }, + ], + }, + ]; + + mockGetHistoryShallow.mockReturnValue(historyWithThoughtPart); + mockCopyToClipboard.mockResolvedValue(undefined); + + const result = await copyCommand.action(mockContext, ''); + + expect(mockCopyToClipboard).toHaveBeenCalledWith('Visible report'); + expect(result).toEqual({ + type: 'message', + messageType: 'info', + content: 'Last output copied to the clipboard', + }); + }); + it('should filter out non-text parts', async () => { if (!copyCommand.action) throw new Error('Command has no action'); diff --git a/packages/cli/src/ui/commands/copyCommand.ts b/packages/cli/src/ui/commands/copyCommand.ts index 789376f1e0..cbf214ae69 100644 --- a/packages/cli/src/ui/commands/copyCommand.ts +++ b/packages/cli/src/ui/commands/copyCommand.ts @@ -362,7 +362,7 @@ export const copyCommand: SlashCommand = { } // Extract text from the parts const lastAiOutput = lastAiMessage.parts - ?.filter((part) => part.text) + ?.filter((part) => part.text && !part.thought) .map((part) => part.text) .join('');