diff --git a/packages/app/src/composer/agent-controls/index.tsx b/packages/app/src/composer/agent-controls/index.tsx index 8dadeec217..d5f09dc77f 100644 --- a/packages/app/src/composer/agent-controls/index.tsx +++ b/packages/app/src/composer/agent-controls/index.tsx @@ -394,6 +394,7 @@ type AgentControlsSlice = { runtimeModelId: string | null; model: string | null | undefined; features: AgentFeature[] | undefined; + runtimeThinkingOptionId: string | null; thinkingOptionId: string | null | undefined; lastUsage: unknown; } | null; @@ -413,6 +414,7 @@ function selectAgentControlsSlice( runtimeModelId: currentAgent.runtimeInfo?.model ?? null, model: currentAgent.model, features: currentAgent.features, + runtimeThinkingOptionId: currentAgent.runtimeInfo?.thinkingOptionId ?? null, thinkingOptionId: currentAgent.thinkingOptionId, lastUsage: currentAgent.lastUsage, }; @@ -1594,6 +1596,7 @@ export const AgentControls = memo(function AgentControls({ models, runtimeModelId: agent?.runtimeModelId, configuredModelId: agent?.model, + runtimeThinkingOptionId: agent?.runtimeThinkingOptionId, explicitThinkingOptionId: agent?.thinkingOptionId, }); diff --git a/packages/app/src/composer/agent-controls/utils.test.ts b/packages/app/src/composer/agent-controls/utils.test.ts index 993e21f0c9..1c91d8ce79 100644 --- a/packages/app/src/composer/agent-controls/utils.test.ts +++ b/packages/app/src/composer/agent-controls/utils.test.ts @@ -67,6 +67,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: null, configuredModelId: "claude-fable-5[1m]", + runtimeThinkingOptionId: null, explicitThinkingOptionId: null, }); @@ -88,6 +89,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: "a", configuredModelId: "b", + runtimeThinkingOptionId: null, explicitThinkingOptionId: null, }); @@ -112,6 +114,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: "a", configuredModelId: null, + runtimeThinkingOptionId: null, explicitThinkingOptionId: "high", }); @@ -119,6 +122,54 @@ describe("resolveAgentModelSelection", () => { expect(selection.displayThinking).toBe("High"); }); + it("shows the thinking level the agent runs on when none was chosen", () => { + const selection = resolveAgentModelSelection({ + models: [ + { + id: "openrouter/google/gemini-3.6-flash", + provider: "pi", + label: "Gemini 3.6 Flash", + thinkingOptions: [ + { id: "low", label: "Low" }, + { id: "medium", label: "Medium", isDefault: true }, + { id: "high", label: "High" }, + ], + defaultThinkingOptionId: "medium", + }, + ], + runtimeModelId: "openrouter/google/gemini-3.6-flash", + configuredModelId: null, + runtimeThinkingOptionId: "high", + explicitThinkingOptionId: null, + }); + + expect(selection.selectedThinkingId).toBe("high"); + expect(selection.displayThinking).toBe("High"); + }); + + it("falls back to the chosen thinking level when the runtime level is not a model option", () => { + 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, + runtimeThinkingOptionId: "xhigh", + explicitThinkingOptionId: "high", + }); + + expect(selection.selectedThinkingId).toBe("high"); + }); + it("formats raw thinking labels in the selected model display", () => { const selection = resolveAgentModelSelection({ models: [ @@ -134,6 +185,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: "a", configuredModelId: null, + runtimeThinkingOptionId: null, explicitThinkingOptionId: "xhigh", }); @@ -155,6 +207,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: null, configuredModelId: null, + runtimeThinkingOptionId: null, explicitThinkingOptionId: null, }); @@ -178,6 +231,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: "claude-sonnet-4-6-20260101", configuredModelId: "default", + runtimeThinkingOptionId: null, explicitThinkingOptionId: null, }); @@ -204,6 +258,7 @@ describe("resolveAgentModelSelection", () => { ], runtimeModelId: "gpt-6.1-sol", configuredModelId: "gpt-6.1-sol", + runtimeThinkingOptionId: null, explicitThinkingOptionId: "max", }); diff --git a/packages/app/src/composer/agent-controls/utils.ts b/packages/app/src/composer/agent-controls/utils.ts index 56f9bcd49f..631b55753e 100644 --- a/packages/app/src/composer/agent-controls/utils.ts +++ b/packages/app/src/composer/agent-controls/utils.ts @@ -86,9 +86,16 @@ function pickSelectedModel( } function resolveThinkingId( + runtimeThinkingOptionId: string | null | undefined, explicitThinkingOptionId: string | null | undefined, selectedModel: AgentModelDefinition | null, ): string | null { + const runtimeThinkingOption = selectedModel?.thinkingOptions?.find( + (option) => option.id === runtimeThinkingOptionId, + ); + if (runtimeThinkingOption) { + return runtimeThinkingOption.id; + } if (explicitThinkingOptionId && explicitThinkingOptionId !== "default") { return explicitThinkingOptionId; } @@ -139,9 +146,16 @@ export function resolveAgentModelSelection(input: { models: AgentModelDefinition[] | null; runtimeModelId: string | null | undefined; configuredModelId: string | null | undefined; + runtimeThinkingOptionId: string | null | undefined; explicitThinkingOptionId: string | null | undefined; }) { - const { models, runtimeModelId, configuredModelId, explicitThinkingOptionId } = input; + const { + models, + runtimeModelId, + configuredModelId, + runtimeThinkingOptionId, + explicitThinkingOptionId, + } = input; const normalizedRuntimeModelId = normalizeModelId(runtimeModelId); const normalizedConfiguredModelId = normalizeModelId(configuredModelId); @@ -162,7 +176,11 @@ export function resolveAgentModelSelection(input: { ); const thinkingOptions = selectedModel?.thinkingOptions ?? null; - const resolvedThinkingId = resolveThinkingId(explicitThinkingOptionId, selectedModel); + const resolvedThinkingId = resolveThinkingId( + runtimeThinkingOptionId, + explicitThinkingOptionId, + selectedModel, + ); const effectiveThinking = resolveEffectiveThinking(thinkingOptions, resolvedThinkingId); const selectedThinkingId = effectiveThinking?.id ?? resolvedThinkingId; const displayThinking = resolveThinkingDisplay(