From c8b1712f6c46adaab36b102b01840d562de9de6a Mon Sep 17 00:00:00 2001 From: xinyi-gong Date: Fri, 15 May 2026 10:10:03 +0800 Subject: [PATCH 1/4] merge all th thinking title to Thinking --- .../copilot/eclipse/ui/chat/Messages.java | 4 +--- .../copilot/eclipse/ui/chat/ThinkingBlock.java | 16 +++++++--------- .../eclipse/ui/chat/ThinkingTurnWidget.java | 9 ++++----- .../copilot/eclipse/ui/chat/messages.properties | 4 +--- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/Messages.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/Messages.java index 33977e8e..d24f2e3f 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/Messages.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/Messages.java @@ -40,9 +40,7 @@ public final class Messages extends NLS { public static String todoList_clearButtonDisabled; public static String todoList_expandTooltip; public static String todoList_collapseTooltip; - public static String thinking_inProgressTitle; - public static String thinking_completedTitle; - public static String thinking_cancelledTitle; + public static String thinking_title; public static String thinking_expandTooltip; public static String thinking_collapseTooltip; diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java index a3333a85..039e9e41 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java @@ -31,7 +31,7 @@ /** * Collapsible "Thinking" banner shown above an assistant turn while the model emits thinking stream. * - *

Pure view: callers drive the visual state via {@link #showCompleted(String)} and {@link #showCancelled()}. + *

Pure view: callers drive the visual state via {@link #showCompleted()} and {@link #showCancelled()}. * The owning turn widget is responsible for cancellation events and title fetching. */ public class ThinkingBlock extends Composite { @@ -86,7 +86,7 @@ public ThinkingBlock(Composite parent, int style) { addDisposeListener(e -> handleDispose()); - setTitleText(Messages.thinking_inProgressTitle); + setTitle(Messages.thinking_title); spinner = new SpinnerAnimator(iconLabel); spinner.start(); updateChevron(); @@ -102,8 +102,8 @@ public void appendText(String fragment) { requestLayout(); } - /** Update the title and finalize as completed. Block was already collapsed at seal time. */ - public void showCompleted(String title) { + /** Finalize as completed: hide spinner icon and transition to COMPLETED state. */ + public void showCompleted() { if (isFinalized()) { return; } @@ -113,7 +113,6 @@ public void showCompleted(String title) { iconLabel.setVisible(false); iconLabel.requestLayout(); } - setTitleText(title); state = State.COMPLETED; } @@ -129,7 +128,6 @@ public void showCancelled() { if (!iconLabel.isDisposed()) { iconLabel.setImage(cancelledIcon); } - setTitleText(Messages.thinking_cancelledTitle); setExpanded(false); unwrapBodyFromScroller(); state = State.CANCELLED; @@ -137,7 +135,7 @@ public void showCancelled() { /** * Mark the block as sealed: the owning widget has requested a title and any further thinking stream fragments must - * land in a new block. Stops the spinner and shows the intermediate "Thinking completed" title while the title + * land in a new block. Stops the spinner and shows the intermediate "Thinking..." title while the title * fetch is in flight. No-op once the block has been finalized or already sealed. */ public void markSealed() { @@ -146,7 +144,6 @@ public void markSealed() { } state = State.SEALED; stopSpinner(); - setTitleText(Messages.thinking_completedTitle); setExpanded(false); unwrapBodyFromScroller(); } @@ -373,7 +370,8 @@ private static String stripTrailingNewlines(String s) { return s.substring(0, end); } - private void setTitleText(String text) { + /** Update the header title text. */ + public void setTitle(String text) { if (titleLabel == null || titleLabel.isDisposed()) { return; } diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingTurnWidget.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingTurnWidget.java index 0d326f5b..1dfebda4 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingTurnWidget.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingTurnWidget.java @@ -83,7 +83,7 @@ public void sealThinking() { CopilotLanguageServerConnection ls = CopilotCore.getPlugin().getCopilotLanguageServer(); if (ls == null) { target.markSealed(); - target.showCompleted(Messages.thinking_completedTitle); + target.showCompleted(); requestLayout(); return; } @@ -99,16 +99,15 @@ public void sealThinking() { return; } if (resp != null && StringUtils.isNotBlank(resp.title())) { - target.showCompleted(resp.title()); - } else { - target.showCompleted(Messages.thinking_completedTitle); + target.setTitle(resp.title()); } + target.showCompleted(); requestLayout(); }, this)) .exceptionally(ex -> { SwtUtils.invokeOnDisplayThreadAsync(() -> { if (!isDisposed() && !target.isDisposed() && !target.isFinalized()) { - target.showCompleted(Messages.thinking_completedTitle); + target.showCompleted(); requestLayout(); } }, this); diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/messages.properties b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/messages.properties index 31ad77bb..c95feec8 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/messages.properties +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/messages.properties @@ -35,8 +35,6 @@ todoList_clearButtonDisabled=Cannot clear todos while a task is in progress todoList_expandTooltip=Click to expand the todo list todoList_collapseTooltip=Click to collapse the todo list -thinking_inProgressTitle=Thinking... -thinking_completedTitle=Thinking completed -thinking_cancelledTitle=Thinking cancelled +thinking_title=Thinking thinking_expandTooltip=Click to show the thinking details thinking_collapseTooltip=Click to hide the thinking details From 6e6a26420bd1e8a5acbd530ef444f02941f04c05 Mon Sep 17 00:00:00 2001 From: xinyi-gong Date: Fri, 15 May 2026 10:13:50 +0800 Subject: [PATCH 2/4] update comment --- .../com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java index 039e9e41..cbd0cc63 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java @@ -135,7 +135,7 @@ public void showCancelled() { /** * Mark the block as sealed: the owning widget has requested a title and any further thinking stream fragments must - * land in a new block. Stops the spinner and shows the intermediate "Thinking..." title while the title + * land in a new block. Stops the spinner and shows the intermediate "Thinking" title while the title * fetch is in flight. No-op once the block has been finalized or already sealed. */ public void markSealed() { From ff5e829da0c63c08cbce31b5c07784c08aa7b8f4 Mon Sep 17 00:00:00 2001 From: xinyi-gong Date: Fri, 15 May 2026 10:23:04 +0800 Subject: [PATCH 3/4] resolve comments --- .../com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java index cbd0cc63..938748c5 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java @@ -135,8 +135,8 @@ public void showCancelled() { /** * Mark the block as sealed: the owning widget has requested a title and any further thinking stream fragments must - * land in a new block. Stops the spinner and shows the intermediate "Thinking" title while the title - * fetch is in flight. No-op once the block has been finalized or already sealed. + * land in a new block. Stops the spinner and collapses the block while the owning widget handles any subsequent + * title updates. No-op once the block has been finalized or already sealed. */ public void markSealed() { if (state != State.STREAMING) { From 9624f4fedf3b180b9a7305f1a48121a7efb6ef56 Mon Sep 17 00:00:00 2001 From: xinyi-gong Date: Fri, 15 May 2026 10:49:42 +0800 Subject: [PATCH 4/4] change cancel timing --- .../copilot/eclipse/ui/chat/ThinkingBlock.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java index 938748c5..91ff10f5 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java @@ -116,11 +116,20 @@ public void showCompleted() { state = State.COMPLETED; } - /** Swap to the cancel icon, set the cancelled title, and collapse. No-op if already finalized. */ + /** + * Cancel the thinking block. If still streaming, shows the cancel icon and collapses. If already sealed (thinking + * content finished, title fetch in flight), simply finalizes as completed since thinking itself was not interrupted. + * No-op if already finalized. + */ public void showCancelled() { if (isFinalized()) { return; } + if (state == State.SEALED) { + // Thinking content already finished; just finalize without the cancel icon. + showCompleted(); + return; + } stopSpinner(); if (cancelledIcon == null || cancelledIcon.isDisposed()) { cancelledIcon = UiUtils.buildImageFromPngPath("/icons/cancel_status.png");