Training: the preset you pick stays picked when you change a setting after it

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpnF7GwNGMbngU11wjym7P
This commit is contained in:
Claude
2026-10-17 22:16:13 +00:00
parent 1b6935af8a
commit c485c4f5df
3 changed files with 27 additions and 2 deletions
+1
View File
@@ -113,6 +113,7 @@ export default {
if (!doc) return;
await session.flush();
const settings = settingsOf(doc);
delete settings.preset; // a starting point the person picked, not a setting of the trainer
settings.trigger = doc.trigger || "";
settings.postfix = doc.postfix || "";
if (resumeId) settings.resume = resumeId;
+2 -2
View File
@@ -38,9 +38,9 @@ export function trainStep({ app, session, go, ui }) {
const caption = used.filter((i) => i.caption.trim()).length;
const name = c.field.default({ label: "Name of the LoRA", hint: "Saved in your loras folder. An earlier file is never overwritten.", control: c.input.md({ label: "Name", value: v.name, onCommit: set("name") }) });
const preset = c.segmented.sm({ label: "Preset", options: PRESETS, value: (PRESETS.find((p) => p.steps === v.steps && p.rank === v.rank) || {}).value, onChange: (key) => {
const preset = c.segmented.sm({ label: "Preset", options: PRESETS, value: v.preset || (PRESETS.find((p) => p.steps === v.steps && p.rank === v.rank) || {}).value, onChange: (key) => {
const p = PRESETS.find((x) => x.value === key);
session.edit((d) => { d.settings = { ...(d.settings || {}), steps: p.steps, rank: p.rank }; });
session.edit((d) => { d.settings = { ...(d.settings || {}), preset: key, steps: p.steps, rank: p.rank }; });
ui.redraw();
} });
+24
View File
@@ -386,3 +386,27 @@ test("Restore and continue is offered for a failed run, goes away while it carri
assert.ok(click("Restore and continue") && !click("Restore and continue").hidden, "offered again after the next failure");
off();
});
test("Train step: the preset picked stays picked when a setting is changed after it, and is not sent to the trainer", async () => {
const f = fake();
const { button, off } = await open(f);
button.click();
await wait(60);
click("Skip to training").click();
await wait(20);
click("Thorough").click();
await wait(20);
const rank = [...document.querySelectorAll(".cx-field")].find((x) => x.textContent.startsWith("Rank")).querySelector("input");
rank.value = "8";
rank.dispatchEvent(new window.Event("change", { bubbles: true }));
await wait(700);
const picked = [...document.querySelectorAll("[aria-pressed=true], [aria-checked=true], .is-active, .on")].map((e) => e.textContent.trim());
assert.ok(picked.includes("Thorough") && !picked.includes("Quick check"), `picked: ${picked}`);
click("Start training").click();
await wait(60);
const plan = f.calls.find((c) => c[0] === "plan");
assert.equal(plan[2].rank, 8);
assert.equal(plan[2].steps, 2000);
assert.ok(!("preset" in plan[2]));
off();
});