fix(FN-2662): clarify project default model setting

This commit is contained in:
gsxdsm
2026-04-28 18:29:39 -07:00
parent 5cc7597b5f
commit f3d7eef2fe
2 changed files with 15 additions and 6 deletions

View File

@@ -1882,6 +1882,11 @@ export function SettingsModal({
const resolvedPlanningModel = resolvePlanningSettingsModel(form); const resolvedPlanningModel = resolvePlanningSettingsModel(form);
const resolvedDefaultModel = resolveProjectDefaultModel(form); const resolvedDefaultModel = resolveProjectDefaultModel(form);
const resolvedTitleSummarizerModel = resolveTitleSummarizerSettingsModel(form); const resolvedTitleSummarizerModel = resolveTitleSummarizerSettingsModel(form);
const getProjectLaneLabel = (lane: ModelLane) => lane.laneId === "default" ? "Project Default Model" : lane.label;
const getProjectLaneHelperText = (lane: ModelLane) =>
lane.laneId === "default"
? "Project-wide default AI model used when no more specific task or project lane override is set."
: lane.helperText;
return ( return (
<> <>
@@ -1922,6 +1927,7 @@ export function SettingsModal({
<p className="settings-description"> <p className="settings-description">
Override global model settings at the project level. Each lane controls a specific AI usage context. Override global model settings at the project level. Each lane controls a specific AI usage context.
Unset lanes inherit from the corresponding global lane. Unset lanes inherit from the corresponding global lane.
The Project Default Model is the fallback for this project when a more specific lane is unset.
</p> </p>
{modelsLoading ? ( {modelsLoading ? (
<div className="settings-empty-state">Loading available models</div> <div className="settings-empty-state">Loading available models</div>
@@ -1935,11 +1941,12 @@ export function SettingsModal({
const status = getLaneStatus(lane); const status = getLaneStatus(lane);
const value = getLaneValue(lane); const value = getLaneValue(lane);
const isOverridden = status === "overridden"; const isOverridden = status === "overridden";
const laneLabel = getProjectLaneLabel(lane);
return ( return (
<div className="form-group" key={lane.laneId}> <div className="form-group" key={lane.laneId}>
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem", marginBottom: "0.25rem" }}> <div style={{ display: "flex", alignItems: "center", gap: "0.5rem", marginBottom: "0.25rem" }}>
<label htmlFor={`${lane.laneId}Model`}>{lane.label}</label> <label htmlFor={`${lane.laneId}Model`}>{laneLabel}</label>
<span <span
className={`settings-lane-badge ${isOverridden ? "settings-lane-badge--override" : "settings-lane-badge--inherited"}`} className={`settings-lane-badge ${isOverridden ? "settings-lane-badge--override" : "settings-lane-badge--inherited"}`}
title={isOverridden ? "Explicitly set for this project" : "Inherited from global settings"} title={isOverridden ? "Explicitly set for this project" : "Inherited from global settings"}
@@ -1951,11 +1958,11 @@ export function SettingsModal({
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
<CustomModelDropdown <CustomModelDropdown
id={`${lane.laneId}Model`} id={`${lane.laneId}Model`}
label={lane.label} label={laneLabel}
models={availableModels} models={availableModels}
value={value} value={value}
onChange={(val) => updateLaneValue(lane, val)} onChange={(val) => updateLaneValue(lane, val)}
placeholder="Use global" placeholder={lane.laneId === "default" ? "Use global default" : "Use global"}
favoriteProviders={favoriteProviders} favoriteProviders={favoriteProviders}
onToggleFavorite={handleToggleFavorite} onToggleFavorite={handleToggleFavorite}
favoriteModels={favoriteModels} favoriteModels={favoriteModels}
@@ -1975,7 +1982,7 @@ export function SettingsModal({
)} )}
</div> </div>
<small> <small>
{lane.helperText} Falls back to: {lane.fallbackOrder}. {getProjectLaneHelperText(lane)} Falls back to: {lane.fallbackOrder}.
</small> </small>
</div> </div>
); );

View File

@@ -415,7 +415,9 @@ describe("SettingsModal", () => {
await userEvent.click(screen.getByRole("button", { name: "Project Models" })); await userEvent.click(screen.getByRole("button", { name: "Project Models" }));
const defaultSection = screen.getByLabelText("Default Model").closest(".form-group"); expect(screen.getByText(/The Project Default Model is the fallback for this project/i)).toBeInTheDocument();
const defaultSection = screen.getByLabelText("Project Default Model").closest(".form-group");
expect(defaultSection).toBeTruthy(); expect(defaultSection).toBeTruthy();
expect(within(defaultSection as HTMLElement).getByText("Inherited (Global)")).toBeInTheDocument(); expect(within(defaultSection as HTMLElement).getByText("Inherited (Global)")).toBeInTheDocument();
}); });
@@ -444,7 +446,7 @@ describe("SettingsModal", () => {
await waitForSettingsModalReady(); await waitForSettingsModalReady();
await userEvent.click(screen.getByRole("button", { name: "Project Models" })); await userEvent.click(screen.getByRole("button", { name: "Project Models" }));
await userEvent.click(screen.getByLabelText("Default Model")); await userEvent.click(screen.getByLabelText("Project Default Model"));
await userEvent.click(screen.getByText("GPT-4o")); await userEvent.click(screen.getByText("GPT-4o"));
await userEvent.click(screen.getByText("Save")); await userEvent.click(screen.getByText("Save"));