feat: a chip beside Generate says shot camera aims with rougher word rules while spaCy is off

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-10-14 23:13:46 +03:00
co-authored by Claude Sonnet 5.5
parent 1fe48d868b
commit fc1158f66f
2 changed files with 38 additions and 2 deletions
+15 -2
View File
@@ -25,7 +25,11 @@ export default {
const slow = c.button.sm({ label: "⚠ Slow torch for int8", tone: "ghost", title: "",
onClick: () => app.maintenance?.cuda13(slow.title) }).node;
slow.hidden = true;
host.append(chip, plain, keyless, twice, slow);
// Shot camera runs without spaCy, but aims its moves with plain word rules.
const rough = c.button.sm({ label: "Camera targets rougher", tone: "ghost", title: "Shot camera is on, but spaCy is not: camera moves aim with simple word rules and pick worse targets. Switch on Automatic camera and focus in Settings ▸ Modules.",
onClick: () => app.openSettings?.("modules") }).node;
rough.hidden = true;
host.append(chip, plain, keyless, twice, slow, rough);
Promise.resolve().then(() => app.api?.torchBuild?.()).then((r) => {
if (r && r.slow_int8) { slow.title = r.slow_int8; slow.hidden = false; }
}).catch(() => {}); // unknown build: the loader still says it in the log when an int8 model loads
@@ -40,9 +44,18 @@ export default {
plain.hidden = !ps.allOff?.();
keyless.hidden = !(taste && ps.activeModules().includes(taste) && ps.useful(taste) && !String((ps.currentValues().taste || {}).key || "").trim());
};
let asking = 0;
const drawRough = () => {
const ps = app.pipeline, cam = ps.modulesById?.().conditioning_shot_camera, ask = ++asking;
if (!cam || !ps.activeModules().includes(cam) || ps.allOff?.()) { rough.hidden = true; return; }
Promise.resolve().then(() => app.api?.addons?.()).then((all) => {
if (ask === asking) rough.hidden = !all || all.some((a) => a.id === "camera" && a.state === "installed");
}).catch(() => {}); // no add-on list: say nothing
};
drawPlain();
drawRough();
draw(app.pipeline.slots());
drawTwice(app.pipeline.slots());
return app.pipeline.subscribe ? app.pipeline.subscribe(() => { draw(app.pipeline.slots()); drawTwice(app.pipeline.slots()); drawPlain(); }) : undefined;
return app.pipeline.subscribe ? app.pipeline.subscribe(() => { draw(app.pipeline.slots()); drawTwice(app.pipeline.slots()); drawPlain(); drawRough(); }) : undefined;
},
};
+23
View File
@@ -61,3 +61,26 @@ test("the slow-torch chip shows the server's sentence when this build runs int8
await tick();
assert.equal(slowChip(host).hidden, true, "an unreadable build is not a claim");
});
test("the rougher-camera chip shows only while shot camera is active and the camera add-on is not installed", async () => {
const cam = { id: "conditioning_shot_camera" };
let active = [cam], listener;
const pipeline = { slots: () => [], allOff: () => false, modulesById: () => ({ conditioning_shot_camera: cam }), activeModules: () => active,
useful: () => false, currentValues: () => ({}), subscribe: (fn) => { listener = fn; return () => {}; } };
const rough = (host) => [...host.querySelectorAll("button")].find((b) => /Camera targets rougher/.test(b.textContent));
const tick = () => new Promise((r) => setTimeout(r, 0));
let state = "available";
const host = document.createElement("div");
let opened = null;
warn.setup({ host, app: { pipeline, openSettings: (id) => { opened = id; }, api: { addons: async () => [{ id: "camera", state }] } } });
await tick();
assert.equal(rough(host).hidden, false, "camera on, spaCy absent: said");
rough(host).click();
assert.equal(opened, "modules");
state = "installed"; listener(); await tick();
assert.equal(rough(host).hidden, true, "spaCy installed and on");
state = "disabled"; listener(); await tick();
assert.equal(rough(host).hidden, false, "spaCy installed but switched off");
active = []; listener(); await tick();
assert.equal(rough(host).hidden, true, "shot camera not in use: nothing to say");
});