diff --git a/README.md b/README.md index 6962d553..28a3f9c8 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Codex Panel supports Codex App Server workflows that fit a persistent panel in O - Manage thread history from the panel or slash commands: clear (`/clear`), resume (`/resume`), rename, auto-name, fork (`/fork`), roll back (`/rollback`), compact (`/compact`), and archive (`/archive`) Codex threads. - Compose with Codex-aware completions for slash commands, enabled skills (`$skill-name`), recent threads, models, and supported reasoning efforts; use `/help` to show available slash commands. - Reference another non-archived thread without switching away from the current one (`/refer`). -- Control subsequent turns from the toolbar or slash commands: Plan mode (`/plan`), fast mode (`/fast`), approval auto-review (`/auto-review`), model (`/model`), and reasoning effort (`/effort`). +- Control subsequent turns from the toolbar or slash commands: Plan mode (`/plan`), fast mode (`/fast`), approval auto-review (`/auto-review`), model (`/model`), and reasoning effort (`/reasoning`). - Follow a running turn as Codex streams assistant messages, reasoning, commands, tool calls, hooks, file changes, plan updates, and agent activity. - Respond to Codex questions, command approvals, file approvals, MCP requests, and permission requests; send steering messages; or interrupt when the composer is empty. - Inspect context usage, usage limits, connection diagnostics, MCP servers, enabled skills, effective Codex config, and discovered hooks from the toolbar, settings, or `/status`, `/doctor`, and `/mcp`. diff --git a/src/features/chat/composer/slash-commands.ts b/src/features/chat/composer/slash-commands.ts index 862f0534..8ac218e1 100644 --- a/src/features/chat/composer/slash-commands.ts +++ b/src/features/chat/composer/slash-commands.ts @@ -97,11 +97,11 @@ export const SLASH_COMMANDS = [ detail: "Show or set the model for subsequent turns.", }, { - command: "/effort", - usage: "/effort [effort|default]", + command: "/reasoning", + usage: "/reasoning [level|default]", argsKind: "showOrSet", surface: "threadSetting", - detail: "Show or set reasoning effort for subsequent turns.", + detail: "Show or set reasoning level for subsequent turns.", }, { command: "/help", diff --git a/src/features/chat/composer/suggestions.ts b/src/features/chat/composer/suggestions.ts index 2029f2fb..a47aae93 100644 --- a/src/features/chat/composer/suggestions.ts +++ b/src/features/chat/composer/suggestions.ts @@ -318,7 +318,7 @@ export function activeReasoningEffortSuggestions( models: readonly Model[], currentModel: string | null, ): ComposerSuggestion[] | null { - const completion = activeCommandArgumentCompletionQuery(beforeCursor, /^\/effort\s+([^\n]{0,120})$/); + const completion = activeCommandArgumentCompletionQuery(beforeCursor, /^\/reasoning\s+([^\n]{0,120})$/); if (!completion) return null; const { query, start } = completion; diff --git a/src/features/chat/slash-commands.ts b/src/features/chat/slash-commands.ts index d7f99610..5117d98e 100644 --- a/src/features/chat/slash-commands.ts +++ b/src/features/chat/slash-commands.ts @@ -190,7 +190,7 @@ export async function executeSlashCommand( return; } - if (command === "effort") { + if (command === "reasoning") { const requested = parseReasoningEffortOverride(args); if (requested !== undefined) { const applied = await context.setRequestedReasoningEffort(requested); @@ -199,7 +199,7 @@ export async function executeSlashCommand( return; } if (args) { - context.addSystemMessage(`Unsupported effort: ${args}. Usage: ${slashCommandDefinition(command).usage}`); + context.addSystemMessage(`Unsupported reasoning level: ${args}. Usage: ${slashCommandDefinition(command).usage}`); return; } context.addStructuredSystemMessage("Reasoning effort", detailsFromLines(context.effortStatusLines())); diff --git a/src/runtime/settings.ts b/src/runtime/settings.ts index c703f01d..d92c322f 100644 --- a/src/runtime/settings.ts +++ b/src/runtime/settings.ts @@ -22,7 +22,9 @@ export function modelOverrideMessage(model: string | null): string { } export function reasoningEffortOverrideMessage(effort: ReasoningEffort | null): string { - return effort === null ? "Effort reset to default for subsequent turns." : `Effort set to ${effort} for subsequent turns.`; + return effort === null + ? "Reasoning effort reset to default for subsequent turns." + : `Reasoning effort set to ${effort} for subsequent turns.`; } export function compactModelLabel(model: string | null): string { diff --git a/tests/features/chat/composer/composer-suggestions.test.ts b/tests/features/chat/composer/composer-suggestions.test.ts index b145c135..242a2c5d 100644 --- a/tests/features/chat/composer/composer-suggestions.test.ts +++ b/tests/features/chat/composer/composer-suggestions.test.ts @@ -140,7 +140,7 @@ describe("composer suggestions", () => { expect(parseSlashCommand("/plan")).toEqual({ command: "plan", args: "" }); expect(parseSlashCommand("/plan OK、実装してください")).toEqual({ command: "plan", args: "OK、実装してください" }); expect(parseSlashCommand("/model gpt-5.5")).toEqual({ command: "model", args: "gpt-5.5" }); - expect(parseSlashCommand("/effort high")).toEqual({ command: "effort", args: "high" }); + expect(parseSlashCommand("/reasoning high")).toEqual({ command: "reasoning", args: "high" }); expect(parseSlashCommand("/new")).toBeNull(); expect(parseSlashCommand("/unknown")).toBeNull(); }); @@ -223,7 +223,7 @@ describe("composer suggestions", () => { it("uses one active suggestion family at a time", () => { expect(activeComposerSuggestions("[[bet", notes, [])[0]?.replacement).toBe("[[Beta Note]]"); expect(activeComposerSuggestions("/pla", notes, [])[0]?.replacement).toBe("/plan"); - expect(activeComposerSuggestions("/eff", notes, [])[0]?.replacement).toBe("/effort"); + expect(activeComposerSuggestions("/rea", notes, [])[0]?.replacement).toBe("/reasoning"); expect(activeComposerSuggestions("/sta", notes, [])[0]?.replacement).toBe("/status"); expect(activeComposerSuggestions("/doc", notes, [])[0]?.replacement).toBe("/doctor"); expect(activeComposerSuggestions("/status", notes, [])).toEqual([]); @@ -237,7 +237,7 @@ describe("composer suggestions", () => { expect(activeComposerSuggestions("please\n/sta", notes, [])).toEqual([]); expect(activeComposerSuggestions("please\n/resume codex", notes, [], threads)).toEqual([]); expect(activeComposerSuggestions("please\n/model gpt", notes, [], [], models)).toEqual([]); - expect(activeComposerSuggestions("please\n/effort h", notes, [], [], models, "gpt-5.5")).toEqual([]); + expect(activeComposerSuggestions("please\n/reasoning h", notes, [], [], models, "gpt-5.5")).toEqual([]); }); it("suggests recent threads for /resume, /refer, and /archive arguments", () => { @@ -314,21 +314,21 @@ describe("composer suggestions", () => { expect(activeComposerSuggestions("/model gpt-5.5 ", notes, [], [], models)).toEqual([]); }); - it("suggests reasoning effort arguments for /effort", () => { + it("suggests reasoning effort arguments for /reasoning", () => { const models = [model("gpt-5.5", ["low", "medium", "high"]), model("gpt-5.4-mini", ["minimal", "low", "medium"])]; - expect(activeComposerSuggestions("/effort h", notes, [], [], models, "gpt-5.5")[0]).toMatchObject({ + expect(activeComposerSuggestions("/reasoning h", notes, [], [], models, "gpt-5.5")[0]).toMatchObject({ display: "high", detail: "Supported by gpt-5.5", replacement: "high", appendSpaceOnInsert: true, }); expect( - activeComposerSuggestions("/effort ", notes, [], [], models, "gpt-5.4-mini").map((suggestion) => suggestion.replacement), + activeComposerSuggestions("/reasoning ", notes, [], [], models, "gpt-5.4-mini").map((suggestion) => suggestion.replacement), ).toEqual(["default", "minimal", "low", "medium"]); - expect(activeComposerSuggestions("/effort x", notes, [], [], models, "gpt-5.4-mini")).toEqual([]); - expect(activeComposerSuggestions("/effort high", notes, [], [], models, "gpt-5.5")).toEqual([]); - expect(activeComposerSuggestions("/effort high ", notes, [], [], models, "gpt-5.5")).toEqual([]); + expect(activeComposerSuggestions("/reasoning x", notes, [], [], models, "gpt-5.4-mini")).toEqual([]); + expect(activeComposerSuggestions("/reasoning high", notes, [], [], models, "gpt-5.5")).toEqual([]); + expect(activeComposerSuggestions("/reasoning high ", notes, [], [], models, "gpt-5.5")).toEqual([]); }); it("adds a trailing space for slash command and skill insertions only", () => { diff --git a/tests/features/chat/composer/slash-commands.test.ts b/tests/features/chat/composer/slash-commands.test.ts index ee7f39d5..73fd8bad 100644 --- a/tests/features/chat/composer/slash-commands.test.ts +++ b/tests/features/chat/composer/slash-commands.test.ts @@ -426,10 +426,10 @@ describe("slash commands", () => { it("rejects unsupported reasoning effort with usage", async () => { const ctx = context(); - await executeSlashCommand("effort", "extreme", ctx); + await executeSlashCommand("reasoning", "extreme", ctx); expect(ctx.setRequestedReasoningEffort).not.toHaveBeenCalled(); - expect(ctx.addSystemMessage).toHaveBeenCalledWith("Unsupported effort: extreme. Usage: /effort [effort|default]"); + expect(ctx.addSystemMessage).toHaveBeenCalledWith("Unsupported reasoning level: extreme. Usage: /reasoning [level|default]"); }); it("does not announce model or effort changes when applying them fails", async () => { @@ -439,7 +439,7 @@ describe("slash commands", () => { }); await executeSlashCommand("model", "gpt-5.5", ctx); - await executeSlashCommand("effort", "high", ctx); + await executeSlashCommand("reasoning", "high", ctx); expect(ctx.setRequestedModel).toHaveBeenCalledWith("gpt-5.5"); expect(ctx.setRequestedReasoningEffort).toHaveBeenCalledWith("high"); diff --git a/tests/runtime/runtime-settings.test.ts b/tests/runtime/runtime-settings.test.ts index bd03b8a9..7f249f41 100644 --- a/tests/runtime/runtime-settings.test.ts +++ b/tests/runtime/runtime-settings.test.ts @@ -88,8 +88,8 @@ describe("runtime settings", () => { it("formats runtime override messages", () => { expect(modelOverrideMessage("gpt-5.5")).toBe("Model set to gpt-5.5 for subsequent turns."); expect(modelOverrideMessage(null)).toBe("Model reset to default for subsequent turns."); - expect(reasoningEffortOverrideMessage("low")).toBe("Effort set to low for subsequent turns."); - expect(reasoningEffortOverrideMessage(null)).toBe("Effort reset to default for subsequent turns."); + expect(reasoningEffortOverrideMessage("low")).toBe("Reasoning effort set to low for subsequent turns."); + expect(reasoningEffortOverrideMessage(null)).toBe("Reasoning effort reset to default for subsequent turns."); }); it("formats compact runtime labels", () => {