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..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 @@ -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,15 +113,23 @@ public void showCompleted(String title) { iconLabel.setVisible(false); iconLabel.requestLayout(); } - setTitleText(title); 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"); @@ -129,7 +137,6 @@ public void showCancelled() { if (!iconLabel.isDisposed()) { iconLabel.setImage(cancelledIcon); } - setTitleText(Messages.thinking_cancelledTitle); setExpanded(false); unwrapBodyFromScroller(); state = State.CANCELLED; @@ -137,8 +144,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 completed" 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) { @@ -146,7 +153,6 @@ public void markSealed() { } state = State.SEALED; stopSpinner(); - setTitleText(Messages.thinking_completedTitle); setExpanded(false); unwrapBodyFromScroller(); } @@ -373,7 +379,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