diff --git a/packages/core/src/flag/flag.ts b/packages/core/src/flag/flag.ts index 88270e3c20..3ed67bb785 100644 --- a/packages/core/src/flag/flag.ts +++ b/packages/core/src/flag/flag.ts @@ -38,7 +38,6 @@ export const Flag = { ), OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT: copy === undefined ? process.platform === "win32" : truthy("OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT"), - OPENCODE_EXPERIMENTAL_MINIMAL_THINKING: truthy("OPENCODE_EXPERIMENTAL_MINIMAL_THINKING"), OPENCODE_MODELS_URL: process.env["OPENCODE_MODELS_URL"], OPENCODE_MODELS_PATH: process.env["OPENCODE_MODELS_PATH"], OPENCODE_DB: process.env["OPENCODE_DB"], diff --git a/packages/opencode/src/cli/cmd/tui/context/thinking.ts b/packages/opencode/src/cli/cmd/tui/context/thinking.ts index c5cae734b9..55e995df11 100644 --- a/packages/opencode/src/cli/cmd/tui/context/thinking.ts +++ b/packages/opencode/src/cli/cmd/tui/context/thinking.ts @@ -1,10 +1,9 @@ import { createMemo, type Setter } from "solid-js" -import { Flag } from "@opencode-ai/core/flag/flag" import { useKV } from "./kv" -export type ThinkingMode = "show" | "minimal" | "hide" +export type ThinkingMode = "show" | "hide" -const MODES: readonly ThinkingMode[] = ["show", "minimal", "hide"] as const +const MODES: readonly ThinkingMode[] = ["show", "hide"] as const // OpenAI's Responses API surfaces reasoning summaries that start with a bolded // title line: "**Inspecting PR workflow**\n\n". GitHub Copilot routes @@ -20,7 +19,7 @@ export function isThinkingMode(value: unknown): value is ThinkingMode { return typeof value === "string" && (MODES as readonly string[]).includes(value) } -// Cycle order matches the slash command: show → minimal → hide → show. +// Cycle order matches the slash command: show → hide → show. export function nextThinkingMode(current: ThinkingMode): ThinkingMode { const idx = MODES.indexOf(current) return MODES[(idx + 1) % MODES.length] ?? "show" @@ -33,7 +32,7 @@ export function useThinkingMode() { // The KVProvider only renders children once kv.ready, so reads here are safe. const hadStored = kv.get("thinking_mode") !== undefined const legacy = kv.get("thinking_visibility") - const [stored, setStored] = kv.signal("thinking_mode", "minimal") + const [stored, setStored] = kv.signal("thinking_mode", "hide") // The kv signal exposes its setter typed as `Setter` which carries Solid's // overload set; passing an updater fn through a property access loses the @@ -47,21 +46,21 @@ export function useThinkingMode() { // Preserve previous experience for users who had explicitly toggled the // legacy `thinking_visibility` boolean. First-time users (no legacy key) - // get the new "minimal" default. + // get the new "hide" default (collapsed thinking). if (!hadStored) { if (legacy === true) set("show") else if (legacy === false) set("hide") } + if ((stored() as string) === "minimal") set("hide") + const mode = createMemo(() => { - if (Flag.OPENCODE_EXPERIMENTAL_MINIMAL_THINKING) return "minimal" const value = stored() - return isThinkingMode(value) ? value : "minimal" + return isThinkingMode(value) ? value : "hide" }) return { mode, set, - locked: () => Flag.OPENCODE_EXPERIMENTAL_MINIMAL_THINKING === true, } } diff --git a/packages/opencode/src/cli/cmd/tui/feature-plugins/system/session-v2.tsx b/packages/opencode/src/cli/cmd/tui/feature-plugins/system/session-v2.tsx index dda6309d93..5017b77b00 100644 --- a/packages/opencode/src/cli/cmd/tui/feature-plugins/system/session-v2.tsx +++ b/packages/opencode/src/cli/cmd/tui/feature-plugins/system/session-v2.tsx @@ -392,7 +392,7 @@ function AssistantReasoning(props: { const thinking = useThinkingMode() const [expanded, setExpanded] = createSignal(false) const content = createMemo(() => props.part.text.replace("[REDACTED]", "").trim()) - const inMinimal = createMemo(() => thinking.mode() === "minimal") + const inMinimal = createMemo(() => thinking.mode() === "hide") // v2 reasoning parts have no per-part `time.end` (see SessionMessageAssistantReasoning // in the v2 SDK); we settle on parent-message completion instead. const isDone = createMemo(() => props.completedAt() !== undefined) @@ -404,7 +404,7 @@ function AssistantReasoning(props: { } return ( - + thinkingMode() !== "hide") + const showThinking = createMemo(() => true) const [timestamps, setTimestamps] = kv.signal<"hide" | "show">("timestamps", "hide") const [showDetails, setShowDetails] = kv.signal("tool_details_visibility", true) const [showAssistantMetadata, _setShowAssistantMetadata] = kv.signal("assistant_metadata_visibility", true) @@ -689,9 +689,8 @@ export function Session() { { title: (() => { const next = nextThinkingMode(thinkingMode()) - if (next === "minimal") return "Switch thinking to minimal" - if (next === "hide") return "Hide thinking" - return "Show thinking" + if (next === "hide") return "Collapse thinking" + return "Expand thinking" })(), value: "session.toggle.thinking", category: "Session", @@ -700,16 +699,6 @@ export function Session() { aliases: ["toggle-thinking"], }, run: () => { - // Env override forces minimal for the process. Updating KV here would - // silently diverge from what's rendered; tell the user instead. - if (thinking.locked()) { - toast.show({ - message: "Thinking mode is locked to minimal by OPENCODE_EXPERIMENTAL_MINIMAL_THINKING", - variant: "info", - }) - dialog.clear() - return - } thinking.set(nextThinkingMode(thinkingMode())) dialog.clear() }, @@ -1512,7 +1501,7 @@ const PART_MAPPING = { function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: AssistantMessage }) { const { theme, subtleSyntax } = useTheme() const ctx = use() - // Collapsed by default in minimal mode: a single line throughout, so the + // Collapsed by default in hide mode: a single line throughout, so the // layout never shifts. Click to open the full markdown block, click to close. const [expanded, setExpanded] = createSignal(false) @@ -1523,7 +1512,7 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass // Reasoning is finalized when the server sets `time.end` (see processor.ts). // Flips independently of the parent message completing. const isDone = createMemo(() => props.part.time.end !== undefined) - const inMinimal = createMemo(() => ctx.thinkingMode() === "minimal") + const inMinimal = createMemo(() => ctx.thinkingMode() === "hide") const duration = createMemo(() => { const end = props.part.time.end return end === undefined ? 0 : Math.max(0, end - props.part.time.start) @@ -1539,10 +1528,10 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass } return ( - + - {/* Full markdown block: `show` mode, or `minimal` after the user opens it. */} + {/* Full markdown block: `show` mode, or `hide` after the user opens it. */}