feat: a warning beside Generate when SLA and ComfyUI's Model Sparse Attention node are both in the pipeline

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-10-10 15:58:31 +03:00
co-authored by Claude Haiku 5.5
parent 4869c85ff2
commit dcb6d5cd49
2 changed files with 27 additions and 2 deletions
+13 -2
View File
@@ -15,8 +15,18 @@ export default {
const keyless = c.button.sm({ label: "⚠ No Taste key", tone: "ghost", title: "A feature that learns from ratings is on, but no Taste key is set: ratings teach nothing. Name one in Settings ▸ Engine ▸ System.",
onClick: () => app.openSettings?.("engine") }).node;
keyless.hidden = true;
host.append(chip, plain, keyless);
// Two sparse attentions at once: the pipeline's own SLA and a native Model Sparse Attention node. Both run on
// every block; the native one's dense fall-throughs print their own log lines, and nothing else says it is there.
const twice = c.button.sm({ label: "⚠ Two sparse attentions", tone: "ghost", disabled: true,
title: "SLA and ComfyUI's Model Sparse Attention node are both in this pipeline. Both sparsify attention; remove one." }).node;
twice.hidden = true;
host.append(chip, plain, keyless, twice);
const draw = (slots) => { chip.hidden = !(slots && !slots.some((s) => (s.roles || []).some((r) => r.at === "generation.prompt"))); };
const drawTwice = (slots) => {
const native = (slots || []).some((s) => /SparseAttention/.test(String(s.node || "")));
const sla = (slots || []).some((s) => (s.inputs || {}).sla === true);
twice.hidden = !(native && sla);
};
const drawPlain = () => {
const ps = app.pipeline, taste = ps.modulesById?.().taste;
plain.hidden = !ps.allOff?.();
@@ -24,6 +34,7 @@ export default {
};
drawPlain();
draw(app.pipeline.slots());
return app.pipeline.subscribe ? app.pipeline.subscribe(() => { draw(app.pipeline.slots()); drawPlain(); }) : undefined;
drawTwice(app.pipeline.slots());
return app.pipeline.subscribe ? app.pipeline.subscribe(() => { draw(app.pipeline.slots()); drawTwice(app.pipeline.slots()); drawPlain(); }) : undefined;
},
};
+14
View File
@@ -21,3 +21,17 @@ test("the No Taste key chip shows only while a learning feature is on and the ke
values = { taste: { key: "" } }; learning = false; listener();
assert.equal(chip(host).hidden, true, "nothing learns, so a missing key changes nothing");
});
test("the two-sparse-attentions chip shows only when SLA and a native sparse node are both in the pipeline", () => {
let slots = [{ id: "loader", node: "FunPackLoader", inputs: { sla: true } }, { id: "sa", node: "BlockSparseAttention", inputs: {} }];
let listener;
const pipeline = { slots: () => slots, allOff: () => false, modulesById: () => ({}), activeModules: () => [], useful: () => false,
currentValues: () => ({}), subscribe: (fn) => { listener = fn; return () => {}; } };
const host = document.createElement("div");
warn.setup({ host, app: { pipeline } });
const twice = () => [...host.querySelectorAll("button")].find((b) => /Two sparse attentions/.test(b.textContent));
assert.equal(twice().hidden, false, "both present: said");
slots = [{ id: "loader", node: "FunPackLoader", inputs: { sla: false } }, { id: "sa", node: "BlockSparseAttention", inputs: {} }];
listener();
assert.equal(twice().hidden, true, "SLA off: the native node alone is not a clash");
});