Show the thinking level an agent runs on in its composer (#5804)

The composer picked the thinking level from what was chosen at launch and
fell back to the model's catalog default when nothing was chosen. A Pi agent
started without a thinking level runs on Pi's own configured default, so the
composer showed Medium while the agent ran on High. The composer now prefers
the level the running agent reports when it is one of the model's options,
the same way it already prefers the running model.

Fixes #5800

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
paseo-bot[bot]
2026-10-01 02:55:22 +02:00
committed by GitHub
parent e0a0cf990d
commit 4893629ff5
3 changed files with 78 additions and 2 deletions
@@ -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,
});
@@ -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",
});
@@ -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(