From 327e6362038d21b59736532427ea5300e4f49231 Mon Sep 17 00:00:00 2001 From: SOUMITRO-SAHA Date: Wed, 8 Apr 2026 22:38:12 +0530 Subject: [PATCH 1/3] feat(app): add collapsible thinking container with `/thinking` command - Add reasoningToolDefaultOpen setting (default: true) to control thinking container state - Render reasoning parts in collapsible container with brain icon and "Thinking" label - Add /thinking slash command to toggle default open state - Remove custom thinking UI indicator in favor of tool-part pattern - Follow existing patterns from shellToolPartsExpanded and editToolPartsExpanded --- packages/app/src/context/settings.tsx | 9 ++++ .../src/pages/session/message-timeline.tsx | 1 + .../pages/session/use-session-commands.tsx | 16 ++++++ packages/ui/src/components/message-part.tsx | 52 ++++++++++++++----- packages/ui/src/components/session-turn.css | 26 ---------- packages/ui/src/components/session-turn.tsx | 25 ++------- 6 files changed, 70 insertions(+), 59 deletions(-) diff --git a/packages/app/src/context/settings.tsx b/packages/app/src/context/settings.tsx index afd03365eacc..e152abf68b43 100644 --- a/packages/app/src/context/settings.tsx +++ b/packages/app/src/context/settings.tsx @@ -24,6 +24,7 @@ export interface Settings { releaseNotes: boolean followup: "queue" | "steer" showReasoningSummaries: boolean + reasoningToolDefaultOpen: boolean shellToolPartsExpanded: boolean editToolPartsExpanded: boolean } @@ -90,6 +91,7 @@ const defaultSettings: Settings = { releaseNotes: true, followup: "steer", showReasoningSummaries: false, + reasoningToolDefaultOpen: true, shellToolPartsExpanded: false, editToolPartsExpanded: false, }, @@ -169,6 +171,13 @@ export const { use: useSettings, provider: SettingsProvider } = createSimpleCont setShowReasoningSummaries(value: boolean) { setStore("general", "showReasoningSummaries", value) }, + reasoningToolDefaultOpen: withFallback( + () => store.general?.reasoningToolDefaultOpen, + defaultSettings.general.reasoningToolDefaultOpen, + ), + setReasoningToolDefaultOpen(value: boolean) { + setStore("general", "reasoningToolDefaultOpen", value) + }, shellToolPartsExpanded: withFallback( () => store.general?.shellToolPartsExpanded, defaultSettings.general.shellToolPartsExpanded, diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index fe6447c2e8c8..f94d8af6635d 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -1097,6 +1097,7 @@ export function MessageTimeline(props: { active={active()} status={active() ? sessionStatus() : undefined} showReasoningSummaries={settings.general.showReasoningSummaries()} + reasoningToolDefaultOpen={settings.general.reasoningToolDefaultOpen()} shellToolDefaultOpen={settings.general.shellToolPartsExpanded()} editToolDefaultOpen={settings.general.editToolPartsExpanded()} classes={{ diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx index 2397953737c7..b82dea957b61 100644 --- a/packages/app/src/pages/session/use-session-commands.tsx +++ b/packages/app/src/pages/session/use-session-commands.tsx @@ -9,6 +9,7 @@ import { useLocal } from "@/context/local" import { usePermission } from "@/context/permission" import { usePrompt } from "@/context/prompt" import { useSDK } from "@/context/sdk" +import { useSettings } from "@/context/settings" import { useSync } from "@/context/sync" import { useTerminal } from "@/context/terminal" import { showToast } from "@opencode-ai/ui/toast" @@ -41,6 +42,7 @@ export const useSessionCommands = (actions: SessionCommandContext) => { const permission = usePermission() const prompt = usePrompt() const sdk = useSDK() + const settings = useSettings() const sync = useSync() const terminal = useTerminal() const layout = useLayout() @@ -118,6 +120,7 @@ export const useSessionCommands = (actions: SessionCommandContext) => { const mcpCommand = withCategory(language.t("command.category.mcp")) const agentCommand = withCategory(language.t("command.category.agent")) const permissionsCommand = withCategory(language.t("command.category.permissions")) + const settingsCommand = withCategory(language.t("command.category.settings")) const isAutoAcceptActive = () => { const sessionID = params.id @@ -559,6 +562,18 @@ export const useSessionCommands = (actions: SessionCommandContext) => { }), ] + const settingsCmds = () => [ + settingsCommand({ + id: "settings.thinking", + title: settings.general.reasoningToolDefaultOpen() + ? language.t("command.settings.thinking.disable") + : language.t("command.settings.thinking.enable"), + description: language.t("command.settings.thinking.description"), + slash: "thinking", + onSelect: () => settings.general.setReasoningToolDefaultOpen(!settings.general.reasoningToolDefaultOpen()), + }), + ] + command.register("session", () => [ ...sessionCmds(), ...shareCmds(), @@ -571,5 +586,6 @@ export const useSessionCommands = (actions: SessionCommandContext) => { ...mcpCmds(), ...agentCmds(), ...permissionsCmds(), + ...settingsCmds(), ]) } diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 3627eca409ad..af9908247731 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -570,7 +570,7 @@ function index(items: readonly T[]) { return new Map(items.map((item) => [item.id, item] as const)) } -function renderable(part: PartType, showReasoningSummaries = true) { +function renderable(part: PartType, showReasoningSummaries = false) { if (part.type === "tool") { if (HIDDEN_TOOLS.has(part.tool)) return false if (part.tool === "question") return part.state.status !== "pending" && part.state.status !== "running" @@ -581,14 +581,16 @@ function renderable(part: PartType, showReasoningSummaries = true) { return !!PART_MAPPING[part.type] } -function toolDefaultOpen(tool: string, shell = false, edit = false) { +function toolDefaultOpen(tool: string, shell = false, edit = false, reasoning = false) { if (tool === "bash") return shell if (tool === "edit" || tool === "write" || tool === "apply_patch") return edit + if (tool === "reasoning") return reasoning } -function partDefaultOpen(part: PartType, shell = false, edit = false) { +function partDefaultOpen(part: PartType, shell = false, edit = false, reasoning = false) { + if (part.type === "reasoning") return reasoning if (part.type !== "tool") return - return toolDefaultOpen(part.tool, shell, edit) + return toolDefaultOpen(part.tool, shell, edit, reasoning) } export function AssistantParts(props: { @@ -597,6 +599,7 @@ export function AssistantParts(props: { turnDurationMs?: number working?: boolean showReasoningSummaries?: boolean + reasoningToolDefaultOpen?: boolean shellToolDefaultOpen?: boolean editToolDefaultOpen?: boolean }) { @@ -616,7 +619,7 @@ export function AssistantParts(props: { groupParts( props.messages.flatMap((message) => list(data.store.part?.[message.id], emptyParts) - .filter((part) => renderable(part, props.showReasoningSummaries ?? true)) + .filter((part) => renderable(part, props.showReasoningSummaries ?? false)) .map((part) => ({ messageID: message.id, part, @@ -679,7 +682,12 @@ export function AssistantParts(props: { message={message()!} showAssistantCopyPartID={props.showAssistantCopyPartID} turnDurationMs={props.turnDurationMs} - defaultOpen={partDefaultOpen(item()!, props.shellToolDefaultOpen, props.editToolDefaultOpen)} + defaultOpen={partDefaultOpen( + item()!, + props.shellToolDefaultOpen, + props.editToolDefaultOpen, + props.reasoningToolDefaultOpen, + )} /> @@ -831,7 +839,7 @@ export function AssistantMessageDisplay(props: { () => groupParts( props.parts - .filter((part) => renderable(part, props.showReasoningSummaries ?? true)) + .filter((part) => renderable(part, props.showReasoningSummaries ?? false)) .map((part) => ({ messageID: props.message.id, part, @@ -1510,6 +1518,8 @@ PART_MAPPING["text"] = function TextPartDisplay(props) { } PART_MAPPING["reasoning"] = function ReasoningPartDisplay(props) { + const data = useData() + const i18n = useI18n() const part = () => props.part as ReasoningPart const streaming = createMemo( () => props.message.role === "assistant" && typeof (props.message as AssistantMessage).time.completed !== "number", @@ -1518,11 +1528,29 @@ PART_MAPPING["reasoning"] = function ReasoningPartDisplay(props) { return ( -
- }> - - -
+ + +
+ + + + {i18n.t("ui.messagePart.thinking")} + + + +
+
+ +
+ }> + + +
+
+
) } diff --git a/packages/ui/src/components/session-turn.css b/packages/ui/src/components/session-turn.css index b01343a01d7c..3bb9b12ad3df 100644 --- a/packages/ui/src/components/session-turn.css +++ b/packages/ui/src/components/session-turn.css @@ -43,32 +43,6 @@ align-self: stretch; } - [data-slot="session-turn-thinking"] { - display: flex; - align-items: center; - gap: 8px; - width: 100%; - min-width: 0; - color: var(--text-weak); - font-family: var(--font-family-sans); - font-size: var(--font-size-base); - font-weight: var(--font-weight-medium); - line-height: 20px; - min-height: 20px; - - [data-component="spinner"] { - width: 16px; - height: 16px; - } - } - - [data-component="text-reveal"].session-turn-thinking-heading { - flex: 1 1 auto; - min-width: 0; - color: var(--text-weaker); - font-weight: var(--font-weight-regular); - } - .error-card { color: var(--text-on-critical-base); max-height: 240px; diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index e891a6febe2f..473575601b0d 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -150,6 +150,7 @@ export function SessionTurn( messages?: MessageType[] actions?: UserActions showReasoningSummaries?: boolean + reasoningToolDefaultOpen?: boolean shellToolDefaultOpen?: boolean editToolDefaultOpen?: boolean active?: boolean @@ -322,7 +323,8 @@ export function SessionTurn( return data.store.session_status[props.sessionID] ?? idle }) const working = createMemo(() => status().type !== "idle" && active()) - const showReasoningSummaries = createMemo(() => props.showReasoningSummaries ?? true) + const showReasoningSummaries = createMemo(() => props.showReasoningSummaries ?? false) + const reasoningDefaultOpen = createMemo(() => props.reasoningToolDefaultOpen ?? true) const assistantCopyPartID = createMemo(() => { if (working()) return null @@ -361,13 +363,6 @@ export function SessionTurn( return { visible, reason } }) const assistantVisible = createMemo(() => assistantDerived().visible) - const reasoningHeading = createMemo(() => assistantDerived().reason) - const showThinking = createMemo(() => { - if (!working() || !!error()) return false - if (status().type === "retry") return false - if (showReasoningSummaries()) return assistantVisible() === 0 - return true - }) const autoScroll = createAutoScroll({ working, @@ -407,24 +402,12 @@ export function SessionTurn( turnDurationMs={turnDurationMs()} working={working()} showReasoningSummaries={showReasoningSummaries()} + reasoningToolDefaultOpen={reasoningDefaultOpen()} shellToolDefaultOpen={props.shellToolDefaultOpen} editToolDefaultOpen={props.editToolDefaultOpen} /> - -
- - - - -
-
0 && !working()}>
Date: Wed, 8 Apr 2026 22:38:34 +0530 Subject: [PATCH 2/3] feat(i18n): add thinking display translations Add translation keys for new thinking functionality across all supported languages. - Add command settings translations for thinking enable/disable toggle - command.settings.thinking.enable - command.settings.thinking.disable - command.settings.thinking.description - Add UI message part translation for thinking state - ui.messagePart.thinking Updated languages: ar, br, bs, da, de, en, es, fr, ja, ko, no, pl, ru, th, tr, zh, zht --- packages/app/src/i18n/ar.ts | 3 +++ packages/app/src/i18n/br.ts | 3 +++ packages/app/src/i18n/bs.ts | 3 +++ packages/app/src/i18n/da.ts | 3 +++ packages/app/src/i18n/de.ts | 3 +++ packages/app/src/i18n/en.ts | 3 +++ packages/app/src/i18n/es.ts | 4 ++++ packages/app/src/i18n/fr.ts | 6 ++++-- packages/app/src/i18n/ja.ts | 5 +++-- packages/app/src/i18n/ko.ts | 3 +++ packages/app/src/i18n/no.ts | 3 +++ packages/app/src/i18n/pl.ts | 5 +++-- packages/app/src/i18n/ru.ts | 3 +++ packages/app/src/i18n/th.ts | 3 +++ packages/app/src/i18n/tr.ts | 3 +++ packages/app/src/i18n/zh.ts | 4 ++++ packages/app/src/i18n/zht.ts | 3 +++ packages/ui/src/i18n/ar.ts | 1 + packages/ui/src/i18n/br.ts | 1 + packages/ui/src/i18n/bs.ts | 1 + packages/ui/src/i18n/da.ts | 1 + packages/ui/src/i18n/de.ts | 1 + packages/ui/src/i18n/en.ts | 1 + packages/ui/src/i18n/es.ts | 1 + packages/ui/src/i18n/fr.ts | 1 + packages/ui/src/i18n/ja.ts | 1 + packages/ui/src/i18n/ko.ts | 1 + packages/ui/src/i18n/no.ts | 1 + packages/ui/src/i18n/pl.ts | 1 + packages/ui/src/i18n/ru.ts | 1 + packages/ui/src/i18n/th.ts | 1 + packages/ui/src/i18n/tr.ts | 1 + packages/ui/src/i18n/zh.ts | 1 + packages/ui/src/i18n/zht.ts | 1 + 34 files changed, 71 insertions(+), 6 deletions(-) diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index 6c3f3bb55ef4..787a8e5f3ab8 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -67,6 +67,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "قبول الأذونات تلقائيًا", "command.permissions.autoaccept.disable": "إيقاف قبول الأذونات تلقائيًا", + "command.settings.thinking.enable": "إظهار التفكير", + "command.settings.thinking.disable": "إخفاء التفكير", + "command.settings.thinking.description": "تبديل عرض ملخصات تفكير النموذج في الجدول الزمني", "command.workspace.toggle": "تبديل مساحات العمل", "command.workspace.toggle.description": "تمكين أو تعطيل مساحات العمل المتعددة في الشريط الجانبي", "command.session.undo": "تراجع", diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index 63880462a467..8c07fbdbbd29 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -67,6 +67,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Aceitar permissões automaticamente", "command.permissions.autoaccept.disable": "Parar de aceitar permissões automaticamente", + "command.settings.thinking.enable": "Mostrar raciocínio", + "command.settings.thinking.disable": "Ocultar raciocínio", + "command.settings.thinking.description": "Alternar exibição de resumos de raciocínio do modelo na linha do tempo", "command.workspace.toggle": "Alternar espaços de trabalho", "command.workspace.toggle.description": "Habilitar ou desabilitar múltiplos espaços de trabalho na barra lateral", "command.session.undo": "Desfazer", diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index 2b589eb35f62..e286d8e39fd6 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -73,6 +73,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Automatski prihvati dozvole", "command.permissions.autoaccept.disable": "Zaustavi automatsko prihvatanje dozvola", + "command.settings.thinking.enable": "Prikaži razmišljanje", + "command.settings.thinking.disable": "Sakrij razmišljanje", + "command.settings.thinking.description": "Uključi/isključi prikaz sažetaka razmišljanja modela na vremenskoj traci", "command.workspace.toggle": "Prikaži/sakrij radne prostore", "command.workspace.toggle.description": "Omogući ili onemogući više radnih prostora u bočnoj traci", "command.session.undo": "Poništi", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index b096d87b4b7b..cc2002e61181 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -73,6 +73,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Accepter tilladelser automatisk", "command.permissions.autoaccept.disable": "Stop med at acceptere tilladelser automatisk", + "command.settings.thinking.enable": "Vis tænkning", + "command.settings.thinking.disable": "Skjul tænkning", + "command.settings.thinking.description": "Skift visning af model-tænkningssammendrag på tidslinjen", "command.workspace.toggle": "Skift arbejdsområder", "command.workspace.toggle.description": "Aktiver eller deaktiver flere arbejdsområder i sidebjælken", "command.session.undo": "Fortryd", diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index 6dc0b0497245..a9e306efe6ff 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -71,6 +71,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Berechtigungen automatisch akzeptieren", "command.permissions.autoaccept.disable": "Automatische Akzeptanz von Berechtigungen stoppen", + "command.settings.thinking.enable": "Denken anzeigen", + "command.settings.thinking.disable": "Denken ausblenden", + "command.settings.thinking.description": "Anzeige der Denkzusammenfassungen des Modells in der Zeitleiste umschalten", "command.workspace.toggle": "Arbeitsbereiche umschalten", "command.workspace.toggle.description": "Mehrere Arbeitsbereiche in der Seitenleiste aktivieren oder deaktivieren", "command.session.undo": "Rückgängig", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index c6bcc37b116f..0b7dff1f25af 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -75,6 +75,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Auto-accept permissions", "command.permissions.autoaccept.disable": "Stop auto-accepting permissions", + "command.settings.thinking.enable": "Show reasoning", + "command.settings.thinking.disable": "Hide reasoning", + "command.settings.thinking.description": "Toggle whether to show model reasoning summaries in the timeline", "command.workspace.toggle": "Toggle workspaces", "command.workspace.toggle.description": "Enable or disable multiple workspaces in the sidebar", "command.session.undo": "Undo", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index c600232ef613..bba9ec7c1435 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -73,6 +73,10 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Aceptar permisos automáticamente", "command.permissions.autoaccept.disable": "Dejar de aceptar permisos automáticamente", + "command.settings.thinking.enable": "Mostrar razonamiento", + "command.settings.thinking.disable": "Ocultar razonamiento", + "command.settings.thinking.description": + "Alternar la visualización de resúmenes de razonamiento del modelo en la línea de tiempo", "command.workspace.toggle": "Alternar espacios de trabajo", "command.workspace.toggle.description": "Habilitar o deshabilitar múltiples espacios de trabajo en la barra lateral", "command.session.undo": "Deshacer", diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index a140c1e3a123..7f106478a093 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -67,8 +67,10 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Accepter automatiquement les permissions", "command.permissions.autoaccept.disable": "Arrêter d'accepter automatiquement les permissions", - "command.workspace.toggle": "Basculer les espaces de travail", - "command.workspace.toggle.description": "Activer ou désactiver plusieurs espaces de travail dans la barre latérale", + "command.settings.thinking.enable": "Afficher le raisonnement", + "command.settings.thinking.disable": "Masquer le raisonnement", + "command.settings.thinking.description": + "Basculer l'affichage des résumés de raisonnement du modèle dans la chronologie", "command.session.undo": "Annuler", "command.session.undo.description": "Annuler le dernier message", "command.session.redo": "Rétablir", diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index 3da1c4b43b58..019204eb816b 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -67,8 +67,9 @@ export const dict = { "command.prompt.mode.normal": "プロンプト", "command.permissions.autoaccept.enable": "権限を自動承認する", "command.permissions.autoaccept.disable": "権限の自動承認を停止する", - "command.workspace.toggle": "ワークスペースを切り替え", - "command.workspace.toggle.description": "サイドバーでの複数のワークスペースの有効化・無効化", + "command.settings.thinking.enable": "思考を表示", + "command.settings.thinking.disable": "思考を非表示", + "command.settings.thinking.description": "タイムライン内のモデルの思考要約の表示を切り替え", "command.session.undo": "元に戻す", "command.session.undo.description": "最後のメッセージを元に戻す", "command.session.redo": "やり直す", diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 0f2f7647abf5..10b8f2f4a020 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -71,6 +71,9 @@ export const dict = { "command.prompt.mode.normal": "프롬프트", "command.permissions.autoaccept.enable": "권한 자동 수락", "command.permissions.autoaccept.disable": "권한 자동 수락 중지", + "command.settings.thinking.enable": "사고 표시", + "command.settings.thinking.disable": "사고 숨기기", + "command.settings.thinking.description": "타임라인에서 모델 사고 요약 표시 전환", "command.workspace.toggle": "작업 공간 전환", "command.workspace.toggle.description": "사이드바에서 다중 작업 공간 활성화 또는 비활성화", "command.session.undo": "실행 취소", diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index a0a968179cd0..639c4b17368b 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -76,6 +76,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Aksepter tillatelser automatisk", "command.permissions.autoaccept.disable": "Stopp automatisk akseptering av tillatelser", + "command.settings.thinking.enable": "Vis tenkning", + "command.settings.thinking.disable": "Skjul tenkning", + "command.settings.thinking.description": "Veksle visning av modellens tenkesammendrag i tidslinjen", "command.workspace.toggle": "Veksle arbeidsområder", "command.workspace.toggle.description": "Enable or disable multiple workspaces in the sidebar", "command.session.undo": "Angre", diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index 88d209f11ff2..f2e5171a8990 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -67,8 +67,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "Automatycznie akceptuj uprawnienia", "command.permissions.autoaccept.disable": "Zatrzymaj automatyczne akceptowanie uprawnień", - "command.workspace.toggle": "Przełącz przestrzenie robocze", - "command.workspace.toggle.description": "Włącz lub wyłącz wiele przestrzeni roboczych na pasku bocznym", + "command.settings.thinking.enable": "Pokaż myślenie", + "command.settings.thinking.disable": "Ukryj myślenie", + "command.settings.thinking.description": "Przełącz wyświetlanie podsumowań myślenia modelu na osi czasu", "command.session.undo": "Cofnij", "command.session.undo.description": "Cofnij ostatnią wiadomość", "command.session.redo": "Ponów", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index 688289b7e812..718b361463fc 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -73,6 +73,9 @@ export const dict = { "command.prompt.mode.normal": "Промпт", "command.permissions.autoaccept.enable": "Автоматически принимать разрешения", "command.permissions.autoaccept.disable": "Остановить автоматическое принятие разрешений", + "command.settings.thinking.enable": "Показать размышления", + "command.settings.thinking.disable": "Скрыть размышления", + "command.settings.thinking.description": "Переключить отображение сводок размышлений модели в ленте", "command.workspace.toggle": "Переключить рабочие пространства", "command.workspace.toggle.description": "Включить или отключить несколько рабочих пространств в боковой панели", "command.session.undo": "Отменить", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 5decf3adb531..8b88df3d5a2e 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -73,6 +73,9 @@ export const dict = { "command.prompt.mode.normal": "พรอมต์", "command.permissions.autoaccept.enable": "ยอมรับสิทธิ์โดยอัตโนมัติ", "command.permissions.autoaccept.disable": "หยุดยอมรับสิทธิ์โดยอัตโนมัติ", + "command.settings.thinking.enable": "แสดงการคิด", + "command.settings.thinking.disable": "ซ่อนการคิด", + "command.settings.thinking.description": "สลับการแสดงสรุปการคิดของโมเดลในไทม์ไลน์", "command.workspace.toggle": "สลับพื้นที่ทำงาน", "command.workspace.toggle.description": "เปิดหรือปิดใช้งานพื้นที่ทำงานหลายรายการในแถบด้านข้าง", "command.session.undo": "ยกเลิก", diff --git a/packages/app/src/i18n/tr.ts b/packages/app/src/i18n/tr.ts index 6a3ade0d0b07..d800ebf78b45 100644 --- a/packages/app/src/i18n/tr.ts +++ b/packages/app/src/i18n/tr.ts @@ -77,6 +77,9 @@ export const dict = { "command.prompt.mode.normal": "Komut", "command.permissions.autoaccept.enable": "Düzenlemeleri otomatik kabul et", "command.permissions.autoaccept.disable": "Otomatik kabulü durdur", + "command.settings.thinking.enable": "Düşünmeyi göster", + "command.settings.thinking.disable": "Düşünmeyi gizle", + "command.settings.thinking.description": "Zaman çizelgesinde model düşünme özetlerini göster/gizle", "command.workspace.toggle": "Çalışma alanlarını aç/kapat", "command.workspace.toggle.description": "Kenar çubuğunda birden fazla çalışma alanını göster veya gizle", "command.session.undo": "Geri al", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index 28231733eaba..60c2a1e301a1 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -99,6 +99,10 @@ export const dict = { "command.permissions.autoaccept.enable": "自动接受权限", "command.permissions.autoaccept.disable": "停止自动接受权限", + "command.settings.thinking.enable": "显示思考", + "command.settings.thinking.disable": "隐藏思考", + "command.settings.thinking.description": "在时间线中切换显示模型思考摘要", + "command.workspace.toggle": "切换工作区", "command.workspace.toggle.description": "在侧边栏启用或禁用多个工作区", diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index 4abdf5db574d..0ef2bdf4d9c3 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -77,6 +77,9 @@ export const dict = { "command.prompt.mode.normal": "Prompt", "command.permissions.autoaccept.enable": "自動接受權限", "command.permissions.autoaccept.disable": "停止自動接受權限", + "command.settings.thinking.enable": "顯示思考", + "command.settings.thinking.disable": "隱藏思考", + "command.settings.thinking.description": "在時間軸中切換顯示模型思考摘要", "command.workspace.toggle": "切換工作區", "command.workspace.toggle.description": "在側邊欄啟用或停用多個工作區", "command.session.undo": "復原", diff --git a/packages/ui/src/i18n/ar.ts b/packages/ui/src/i18n/ar.ts index ea4d03ac67ac..a7149994aafd 100644 --- a/packages/ui/src/i18n/ar.ts +++ b/packages/ui/src/i18n/ar.ts @@ -67,6 +67,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} عمليات بحث", "ui.messagePart.context.list.one": "{{count}} قائمة", "ui.messagePart.context.list.other": "{{count}} قوائم", + "ui.messagePart.thinking": "التفكير", "ui.messagePart.diagnostic.error": "خطأ", "ui.messagePart.title.edit": "تحرير", "ui.messagePart.title.write": "كتابة", diff --git a/packages/ui/src/i18n/br.ts b/packages/ui/src/i18n/br.ts index e8aefd937815..acbd585edd84 100644 --- a/packages/ui/src/i18n/br.ts +++ b/packages/ui/src/i18n/br.ts @@ -67,6 +67,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} pesquisas", "ui.messagePart.context.list.one": "{{count}} lista", "ui.messagePart.context.list.other": "{{count}} listas", + "ui.messagePart.thinking": "Pensando", "ui.messagePart.diagnostic.error": "Erro", "ui.messagePart.title.edit": "Editar", "ui.messagePart.title.write": "Escrever", diff --git a/packages/ui/src/i18n/bs.ts b/packages/ui/src/i18n/bs.ts index 4e8ce8042561..7969b042a9a3 100644 --- a/packages/ui/src/i18n/bs.ts +++ b/packages/ui/src/i18n/bs.ts @@ -71,6 +71,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} pretrage", "ui.messagePart.context.list.one": "{{count}} lista", "ui.messagePart.context.list.other": "{{count}} liste", + "ui.messagePart.thinking": "Razmišljanje", "ui.messagePart.diagnostic.error": "Greška", "ui.messagePart.title.edit": "Uredi", "ui.messagePart.title.write": "Napiši", diff --git a/packages/ui/src/i18n/da.ts b/packages/ui/src/i18n/da.ts index 846fb3ecaa27..6e59bd3c2f8c 100644 --- a/packages/ui/src/i18n/da.ts +++ b/packages/ui/src/i18n/da.ts @@ -66,6 +66,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} søgninger", "ui.messagePart.context.list.one": "{{count}} liste", "ui.messagePart.context.list.other": "{{count}} lister", + "ui.messagePart.thinking": "Tænkning", "ui.messagePart.diagnostic.error": "Fejl", "ui.messagePart.title.edit": "Rediger", "ui.messagePart.title.write": "Skriv", diff --git a/packages/ui/src/i18n/de.ts b/packages/ui/src/i18n/de.ts index c07ceade2f62..500d562627ca 100644 --- a/packages/ui/src/i18n/de.ts +++ b/packages/ui/src/i18n/de.ts @@ -72,6 +72,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} Suchen", "ui.messagePart.context.list.one": "{{count}} Liste", "ui.messagePart.context.list.other": "{{count}} Listen", + "ui.messagePart.thinking": "Denken", "ui.messagePart.diagnostic.error": "Fehler", "ui.messagePart.title.edit": "Bearbeiten", "ui.messagePart.title.write": "Schreiben", diff --git a/packages/ui/src/i18n/en.ts b/packages/ui/src/i18n/en.ts index 837fd5afcbcd..e07c1edb43e9 100644 --- a/packages/ui/src/i18n/en.ts +++ b/packages/ui/src/i18n/en.ts @@ -79,6 +79,7 @@ export const dict: Record = { "ui.messagePart.context.search.other": "{{count}} searches", "ui.messagePart.context.list.one": "{{count}} list", "ui.messagePart.context.list.other": "{{count}} lists", + "ui.messagePart.thinking": "Thinking", "ui.list.loading": "Loading", "ui.list.empty": "No results", diff --git a/packages/ui/src/i18n/es.ts b/packages/ui/src/i18n/es.ts index 3f4475a39bd2..eb3688ec377f 100644 --- a/packages/ui/src/i18n/es.ts +++ b/packages/ui/src/i18n/es.ts @@ -67,6 +67,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} búsquedas", "ui.messagePart.context.list.one": "{{count}} lista", "ui.messagePart.context.list.other": "{{count}} listas", + "ui.messagePart.thinking": "Pensando", "ui.messagePart.diagnostic.error": "Error", "ui.messagePart.title.edit": "Editar", "ui.messagePart.title.write": "Escribir", diff --git a/packages/ui/src/i18n/fr.ts b/packages/ui/src/i18n/fr.ts index 9cf17d5e336b..caac68d797f3 100644 --- a/packages/ui/src/i18n/fr.ts +++ b/packages/ui/src/i18n/fr.ts @@ -67,6 +67,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} recherches", "ui.messagePart.context.list.one": "{{count}} liste", "ui.messagePart.context.list.other": "{{count}} listes", + "ui.messagePart.thinking": "Réflexion", "ui.messagePart.diagnostic.error": "Erreur", "ui.messagePart.title.edit": "Modifier", "ui.messagePart.title.write": "Écrire", diff --git a/packages/ui/src/i18n/ja.ts b/packages/ui/src/i18n/ja.ts index 5bb7f1376bd3..ba6b62bda519 100644 --- a/packages/ui/src/i18n/ja.ts +++ b/packages/ui/src/i18n/ja.ts @@ -66,6 +66,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} 件の検索", "ui.messagePart.context.list.one": "{{count}} 件のリスト", "ui.messagePart.context.list.other": "{{count}} 件のリスト", + "ui.messagePart.thinking": "思考中", "ui.messagePart.diagnostic.error": "エラー", "ui.messagePart.title.edit": "編集", "ui.messagePart.title.write": "作成", diff --git a/packages/ui/src/i18n/ko.ts b/packages/ui/src/i18n/ko.ts index 088a2865af4a..3ddea0c8397d 100644 --- a/packages/ui/src/i18n/ko.ts +++ b/packages/ui/src/i18n/ko.ts @@ -67,6 +67,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}}개 검색", "ui.messagePart.context.list.one": "{{count}}개 목록", "ui.messagePart.context.list.other": "{{count}}개 목록", + "ui.messagePart.thinking": "생각 중", "ui.messagePart.diagnostic.error": "오류", "ui.messagePart.title.edit": "편집", "ui.messagePart.title.write": "작성", diff --git a/packages/ui/src/i18n/no.ts b/packages/ui/src/i18n/no.ts index af6e399eac5f..4c545d126a7b 100644 --- a/packages/ui/src/i18n/no.ts +++ b/packages/ui/src/i18n/no.ts @@ -70,6 +70,7 @@ export const dict: Record = { "ui.messagePart.context.search.other": "{{count}} søk", "ui.messagePart.context.list.one": "{{count}} liste", "ui.messagePart.context.list.other": "{{count}} lister", + "ui.messagePart.thinking": "Tenker", "ui.messagePart.diagnostic.error": "Feil", "ui.messagePart.title.edit": "Rediger", "ui.messagePart.title.write": "Skriv", diff --git a/packages/ui/src/i18n/pl.ts b/packages/ui/src/i18n/pl.ts index 2385edfeb751..ed70395b13be 100644 --- a/packages/ui/src/i18n/pl.ts +++ b/packages/ui/src/i18n/pl.ts @@ -66,6 +66,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} wyszukiwania", "ui.messagePart.context.list.one": "{{count}} lista", "ui.messagePart.context.list.other": "{{count}} listy", + "ui.messagePart.thinking": "Myślenie", "ui.messagePart.diagnostic.error": "Błąd", "ui.messagePart.title.edit": "Edycja", "ui.messagePart.title.write": "Pisanie", diff --git a/packages/ui/src/i18n/ru.ts b/packages/ui/src/i18n/ru.ts index f78bd5c14b60..bc75c80581bf 100644 --- a/packages/ui/src/i18n/ru.ts +++ b/packages/ui/src/i18n/ru.ts @@ -66,6 +66,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} поисков", "ui.messagePart.context.list.one": "{{count}} список", "ui.messagePart.context.list.other": "{{count}} списков", + "ui.messagePart.thinking": "Размышление", "ui.messagePart.diagnostic.error": "Ошибка", "ui.messagePart.title.edit": "Редактировать", "ui.messagePart.title.write": "Написать", diff --git a/packages/ui/src/i18n/th.ts b/packages/ui/src/i18n/th.ts index a49fc2e52e28..d94f60e24a40 100644 --- a/packages/ui/src/i18n/th.ts +++ b/packages/ui/src/i18n/th.ts @@ -68,6 +68,7 @@ export const dict = { "ui.messagePart.context.search.other": "ค้นหา {{count}} รายการ", "ui.messagePart.context.list.one": "รายการ {{count}} รายการ", "ui.messagePart.context.list.other": "รายการ {{count}} รายการ", + "ui.messagePart.thinking": "กำลังคิด", "ui.messagePart.diagnostic.error": "ข้อผิดพลาด", "ui.messagePart.title.edit": "แก้ไข", "ui.messagePart.title.write": "เขียน", diff --git a/packages/ui/src/i18n/tr.ts b/packages/ui/src/i18n/tr.ts index e6b50c1c09a3..c539d3a8727e 100644 --- a/packages/ui/src/i18n/tr.ts +++ b/packages/ui/src/i18n/tr.ts @@ -73,6 +73,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} arama", "ui.messagePart.context.list.one": "{{count}} liste", "ui.messagePart.context.list.other": "{{count}} liste", + "ui.messagePart.thinking": "Düşünüyor", "ui.messagePart.diagnostic.error": "Hata", "ui.messagePart.title.edit": "Düzenle", "ui.messagePart.title.write": "Yaz", diff --git a/packages/ui/src/i18n/zh.ts b/packages/ui/src/i18n/zh.ts index 5779754376b9..384667c3af96 100644 --- a/packages/ui/src/i18n/zh.ts +++ b/packages/ui/src/i18n/zh.ts @@ -71,6 +71,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} 次搜索", "ui.messagePart.context.list.one": "{{count}} 个列表", "ui.messagePart.context.list.other": "{{count}} 个列表", + "ui.messagePart.thinking": "思考中", "ui.messagePart.diagnostic.error": "错误", "ui.messagePart.title.edit": "编辑", "ui.messagePart.title.write": "写入", diff --git a/packages/ui/src/i18n/zht.ts b/packages/ui/src/i18n/zht.ts index 2d433b57ab41..09189a13ee85 100644 --- a/packages/ui/src/i18n/zht.ts +++ b/packages/ui/src/i18n/zht.ts @@ -71,6 +71,7 @@ export const dict = { "ui.messagePart.context.search.other": "{{count}} 次搜尋", "ui.messagePart.context.list.one": "{{count}} 個清單", "ui.messagePart.context.list.other": "{{count}} 個清單", + "ui.messagePart.thinking": "思考中", "ui.messagePart.diagnostic.error": "錯誤", "ui.messagePart.title.edit": "編輯", "ui.messagePart.title.write": "寫入", From 08e0afba93fac6bcb55405b8be24e30cb7d2aa0a Mon Sep 17 00:00:00 2001 From: SOUMITRO-SAHA Date: Thu, 9 Apr 2026 12:51:31 +0530 Subject: [PATCH 3/3] fix(ui): always render reasoning parts when text is present The reasoning part visibility was incorrectly gated by showReasoningSummaries, preventing thinking UI from displaying. Now reasoning parts render when they have text content, and the `/thinking` command controls expand/collapse state. --- packages/ui/src/components/message-part.tsx | 2 +- packages/ui/src/components/session-turn.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index af9908247731..bcd319c40e7e 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -577,7 +577,7 @@ function renderable(part: PartType, showReasoningSummaries = false) { return true } if (part.type === "text") return !!part.text?.trim() - if (part.type === "reasoning") return showReasoningSummaries && !!part.text?.trim() + if (part.type === "reasoning") return !!part.text?.trim() return !!PART_MAPPING[part.type] } diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index 473575601b0d..729cef825e2b 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -100,7 +100,7 @@ function partState(part: PartType, showReasoningSummaries: boolean) { } if (part.type === "text") return part.text?.trim() ? ("visible" as const) : undefined if (part.type === "reasoning") { - if (showReasoningSummaries && part.text?.trim()) return "visible" as const + if (part.text?.trim()) return "visible" as const return } if (PART_MAPPING[part.type]) return "visible" as const