fix(models): preserve preset rename compatibility

This commit is contained in:
Xubin Ren
2026-08-16 11:50:56 +08:00
parent a956fe1d60
commit 0a6ee1c539
20 changed files with 307 additions and 46 deletions
@@ -225,7 +225,8 @@ export function useModelSettingsActions({
);
if (!selectedPreset) return;
const nextName = form.modelPreset.trim();
if (presetNameConflict(nextName, selectedPreset.name)) {
const nameChanged = form.modelPreset !== selectedPreset.name;
if (nameChanged && presetNameConflict(nextName, selectedPreset.name)) {
showPresetNameConflict();
return;
}
@@ -235,7 +236,7 @@ export function useModelSettingsActions({
try {
const payload = await updateModelConfiguration(client, {
name: selectedPreset.name,
newName: nextName !== selectedPreset.name ? nextName : undefined,
newName: nameChanged ? nextName : undefined,
model: form.model !== selectedPreset.model ? form.model : undefined,
provider: form.provider !== selectedPreset.provider ? form.provider : undefined,
maxTokens:
@@ -260,7 +260,7 @@ export function useSettingsController({
);
if (!selectedPreset) return false;
return (
form.modelPreset.trim() !== selectedPreset.name ||
form.modelPreset !== selectedPreset.name ||
form.model !== selectedPreset.model ||
form.provider !== selectedPreset.provider ||
form.maxTokens !== selectedPreset.max_tokens ||
+41
View File
@@ -112,6 +112,47 @@ describe("Settings models", () => {
expect(within(editor).queryByText("minimax")).not.toBeInTheDocument();
});
it("edits a legacy case-conflicting preset without treating its own name as a rename", async () => {
const payload = settingsPayload();
const primary = {
...payload.model_presets[0],
name: "Fast",
label: "Fast",
active: true,
};
const legacyConflict = {
...primary,
name: "fast",
label: "fast",
active: false,
};
const legacyPayload: SettingsPayload = {
...payload,
agent: { ...payload.agent, model_preset: "Fast" },
model_presets: [primary, legacyConflict],
model_call_order: ["Fast", "fast"],
};
vi.stubGlobal("fetch", vi.fn(() => new Promise<Response>(() => {})));
requestMutationMock.mockResolvedValueOnce(legacyPayload);
renderSettingsView({ initialSection: "models", initialSettings: legacyPayload });
await togglePresetEditor("Fast");
fireEvent.click(screen.getByRole("button", { name: /Advanced options/ }));
fireEvent.change(screen.getByLabelText("Temperature"), {
target: { value: "0.4" },
});
fireEvent.click(screen.getByRole("button", { name: "Save preset" }));
await waitFor(() => {
expect(requestMutationMock).toHaveBeenCalledWith(
"settings.model_configuration.update",
{ name: "Fast", temperature: 0.4 },
20_000,
);
});
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
});
it("renames an existing preset without losing the editor selection", async () => {
const payload = settingsPayload();
const renamedPayload: SettingsPayload = {