Files
paseo/packages/app/src/composer/agent-controls/utils.test.ts
T
35f985baff Switch reasoning, mode, plan, and fast from the Command Center (#2274)
* Switch reasoning, mode, plan, and fast from the Command Center

Extend the Command Center (Cmd-K) with selectors for a focused agent's
Thinking (reasoning effort), access Mode, Plan mode, and Fast mode,
mirroring the model switcher. Typing surfaces tiered "<Setting> › <Value>"
breadcrumb rows with icons and a check on the current value, for both a
running agent and a new draft tab. Rows only appear while typing, so the
default palette is unchanged.

- Thinking and Mode are multi-option selects; Plan mode and Fast mode are
  On/Off toggles.
- Plan mode is dual-natured: a permission mode for Claude/Copilot/OpenCode
  (excluded from the Mode list, given its own toggle) and the plan_mode
  feature for Codex. Fast mode drives the fast_mode feature (model-gated).
- All logic lives in command-center/agent-setting-contributions.ts as pure,
  unit-tested builders, with a small icon helper and a hook that registers
  the running-agent selectors; the draft registers from its composer tab.
  No changes to the command palette component and no protocol changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Unify Command Center agent controls

* refactor: clarify agent control ownership

* refactor(app): tighten command center agent controls

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-07-31 17:37:04 +02:00

168 lines
4.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
getFeatureHighlightColor,
getFeatureTooltip,
getAgentControlHintKey,
normalizeModelId,
resolveAgentModelSelection,
} from "./utils";
describe("getAgentControlHintKey", () => {
it("returns translation keys for each editable agent control hint", () => {
expect(getAgentControlHintKey("thinking")).toBe("agentControls.hints.thinking");
expect(getAgentControlHintKey("model")).toBe("agentControls.hints.model");
expect(getAgentControlHintKey("mode")).toBe("agentControls.hints.mode");
});
});
describe("feature metadata helpers", () => {
it("prefers explicit feature tooltip copy", () => {
expect(
getFeatureTooltip({
label: "Plan",
tooltip: "Toggle plan mode",
}),
).toBe("Toggle plan mode");
});
it("falls back to the feature label when no tooltip is provided", () => {
expect(
getFeatureTooltip({
label: "Custom",
}),
).toBe("Custom");
});
it("maps feature highlight colors by feature id", () => {
expect(getFeatureHighlightColor("fast_mode")).toBe("yellow");
expect(getFeatureHighlightColor("plan_mode")).toBe("blue");
expect(getFeatureHighlightColor("other")).toBe("default");
});
});
describe("normalizeModelId", () => {
it("treats empty values as unset", () => {
expect(normalizeModelId("")).toBeNull();
expect(normalizeModelId(undefined)).toBeNull();
});
it("returns trimmed model ids", () => {
expect(normalizeModelId(" gpt-5.1-codex ")).toBe("gpt-5.1-codex");
expect(normalizeModelId(" default ")).toBe("default");
});
});
describe("resolveAgentModelSelection", () => {
it("prefers runtime model over configured model", () => {
const selection = resolveAgentModelSelection({
models: [
{
id: "a",
provider: "codex",
label: "Model A",
thinkingOptions: [{ id: "low", label: "Low" }],
defaultThinkingOptionId: "low",
},
],
runtimeModelId: "a",
configuredModelId: "b",
explicitThinkingOptionId: null,
});
expect(selection.activeModelId).toBe("a");
expect(selection.displayModel).toBe("Model A");
expect(selection.selectedThinkingId).toBe("low");
});
it("uses explicit thinking option when provided", () => {
const selection = resolveAgentModelSelection({
models: [
{
id: "a",
provider: "codex",
label: "Model A",
thinkingOptions: [
{ id: "low", label: "Low" },
{ id: "high", label: "High" },
],
defaultThinkingOptionId: "low",
},
],
runtimeModelId: "a",
configuredModelId: null,
explicitThinkingOptionId: "high",
});
expect(selection.selectedThinkingId).toBe("high");
expect(selection.displayThinking).toBe("High");
});
it("formats raw thinking labels in the selected model display", () => {
const selection = resolveAgentModelSelection({
models: [
{
id: "a",
provider: "claude",
label: "Model A",
thinkingOptions: [
{ id: "none", label: "none" },
{ id: "xhigh", label: "xhigh" },
],
},
],
runtimeModelId: "a",
configuredModelId: null,
explicitThinkingOptionId: "xhigh",
});
expect(selection.selectedThinkingId).toBe("xhigh");
expect(selection.displayThinking).toBe("Extra high");
});
it("falls back to the provider default model label instead of Auto", () => {
const selection = resolveAgentModelSelection({
models: [
{
id: "a",
provider: "codex",
label: "Model A",
isDefault: true,
thinkingOptions: [{ id: "low", label: "Low" }],
defaultThinkingOptionId: "low",
},
],
runtimeModelId: null,
configuredModelId: null,
explicitThinkingOptionId: null,
});
expect(selection.displayModel).toBe("Model A");
expect(selection.displayThinking).toBe("Low");
});
it("prefers the configured model when runtime model is not in the model list", () => {
const selection = resolveAgentModelSelection({
models: [
{
id: "default",
provider: "claude",
label: "Default (Sonnet 4.6)",
isDefault: true,
thinkingOptions: [
{ id: "low", label: "Low" },
{ id: "medium", label: "Medium" },
],
},
],
runtimeModelId: "claude-sonnet-4-6-20260101",
configuredModelId: "default",
explicitThinkingOptionId: null,
});
expect(selection.activeModelId).toBe("default");
expect(selection.displayModel).toBe("Default (Sonnet 4.6)");
expect(selection.selectedThinkingId).toBe("low");
expect(selection.displayThinking).toBe("Low");
});
});