fix(ui): resolve session thinking defaults

This commit is contained in:
Val Alexander 2026-05-05 22:11:20 -05:00
parent f292cc67dc
commit a906cb75ce
No known key found for this signature in database
2 changed files with 70 additions and 8 deletions

View file

@ -5,12 +5,15 @@ import { describe, expect, it, vi } from "vitest";
import type { SessionsListResult } from "../types.ts";
import { renderSessions, type SessionsProps } from "./sessions.ts";
function buildResult(session: SessionsListResult["sessions"][number]): SessionsListResult {
function buildResult(
session: SessionsListResult["sessions"][number],
defaults?: Partial<SessionsListResult["defaults"]>,
): SessionsListResult {
return {
ts: Date.now(),
path: "(multiple)",
count: 1,
defaults: { modelProvider: null, model: null, contextTokens: null },
defaults: { modelProvider: null, model: null, contextTokens: null, ...defaults },
sessions: [session],
};
}
@ -268,6 +271,41 @@ describe("sessions view", () => {
).toBe("Override: adaptive");
});
it("labels inherited thinking from list defaults when lightweight rows omit row defaults", async () => {
const container = document.createElement("div");
render(
renderSessions(
buildProps(
buildResult(
{
key: "agent:main:main",
kind: "direct",
updatedAt: Date.now(),
},
{
modelProvider: "openai-codex",
model: "gpt-5.5",
thinkingDefault: "high",
thinkingLevels: [
{ id: "off", label: "off" },
{ id: "high", label: "high" },
],
},
),
),
),
container,
);
await Promise.resolve();
const thinking = container.querySelector("tbody select") as HTMLSelectElement | null;
expect(thinking?.value).toBe("");
expect(thinking?.options[0]?.textContent?.trim()).toBe("Inherited: high");
expect(Array.from(thinking?.options ?? []).map((option) => option.textContent?.trim())).toEqual(
["Inherited: high", "Off", "Override: high"],
);
});
it("keeps legacy binary thinking labels patching canonical ids", async () => {
const container = document.createElement("div");
const onPatch = vi.fn();

View file

@ -92,16 +92,37 @@ function getAgentIdentity(
: null;
}
function rowMatchesSessionDefaults(
row: GatewaySessionRow,
defaults: SessionsListResult["defaults"] | undefined,
): boolean {
return (
(!row.modelProvider || row.modelProvider === defaults?.modelProvider) &&
(!row.model || row.model === defaults?.model)
);
}
function resolveThinkLevelOptions(
row: GatewaySessionRow,
defaults?: SessionsListResult["defaults"],
): readonly { value: string; label: string }[] {
const defaultLabel = formatInheritedThinkingLabel(row.thinkingDefault);
const sessionModelMatchesDefaults = rowMatchesSessionDefaults(row, defaults);
const defaultLabel = formatInheritedThinkingLabel(
row.thinkingDefault ?? (sessionModelMatchesDefaults ? defaults?.thinkingDefault : undefined),
);
const options: readonly GatewayThinkingLevelOption[] = row.thinkingLevels?.length
? row.thinkingLevels
: (row.thinkingOptions?.length ? row.thinkingOptions : DEFAULT_THINK_LEVELS).map((label) => ({
id: normalizeThinkingOptionValue(label),
label,
}));
: sessionModelMatchesDefaults && defaults?.thinkingLevels?.length
? defaults.thinkingLevels
: (row.thinkingOptions?.length
? row.thinkingOptions
: sessionModelMatchesDefaults && defaults?.thinkingOptions?.length
? defaults.thinkingOptions
: DEFAULT_THINK_LEVELS
).map((label) => ({
id: normalizeThinkingOptionValue(label),
label,
}));
return [
{ value: "", label: defaultLabel },
...options.map((option) => ({
@ -684,7 +705,10 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {
const updated = row.updatedAt ? formatRelativeTimestamp(row.updatedAt) : t("common.na");
const rawThinking = row.thinkingLevel ?? "";
const thinking = rawThinking ? normalizeThinkingOptionValue(rawThinking) : "";
const thinkLevels = withCurrentLabeledOption(resolveThinkLevelOptions(row), thinking);
const thinkLevels = withCurrentLabeledOption(
resolveThinkLevelOptions(row, props.result?.defaults),
thinking,
);
const fastMode = row.fastMode === true ? "on" : row.fastMode === false ? "off" : "";
const fastLevels = withCurrentLabeledOption(buildFastLevelOptions(), fastMode);
const verbose = row.verboseLevel ?? "";