Model Check offers Download (and Download all) for a missing model whose
source names one exact file: Civitai by the workflow's fingerprint, or a
Civitai version / Hugging Face / GitHub file link the workflow carries.
A dialog shows each file's size, source and full destination, with the
models folder (when there are several) and subfolder changeable; Settings
> Model downloads sets the default: where the workflow says (the node
needs no change) or a set folder, {base} sorting by base model and
matching an existing folder in any spelling.
Downloads run one at a time into <file>.part, continue after an
interruption, are checked against the SHA-256 before they get their name,
never replace a file, and send the Civitai key to Civitai only. Finished
files are put into their nodes (one Ctrl+Z step each), scanned for info
and covers, and recorded in the activity log.
A change of fingerprints alone (after any scan) no longer takes a Ctrl+Z
step that seemed to do nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.2 KiB
JavaScript
50 lines
2.2 KiB
JavaScript
/**
|
|
* ComfyUI's Ctrl+Z history. It takes a step on its own events (a mouse button or key let
|
|
* go); a canvas write made by a drop (no mouse-up follows a drag), in a click handler or
|
|
* after a request finishes would otherwise land in no step, and Ctrl+Z would skip it.
|
|
* Call after every canvas write. Takes `app` so pure modules can use it. Also keeps a change of
|
|
* fingerprints alone (absorbFingerprintChange) out of the history.
|
|
*/
|
|
|
|
export function recordCanvasStep(app) {
|
|
try {
|
|
const tracker = app?.extensionManager?.workflow?.activeWorkflow?.changeTracker;
|
|
if (typeof tracker?.captureCanvasState === 'function') tracker.captureCanvasState();
|
|
else tracker?.checkState?.(); // older ComfyUI
|
|
} catch (error) {
|
|
console.warn('[AMB] Ctrl+Z history: step not recorded.', error);
|
|
}
|
|
}
|
|
|
|
// What a saved workflow carries from the fingerprint cache (hash_resolver.js), not the canvas.
|
|
const DERIVED = ['anomalous_hashes', 'anomalous_model_sources'];
|
|
|
|
function withoutDerived(state) {
|
|
const extra = { ...(state?.extra || {}) };
|
|
for (const key of DERIVED) delete extra[key];
|
|
return { ...state, extra };
|
|
}
|
|
|
|
/**
|
|
* After the fingerprint cache changes (a scan, a download), the workflow serializes with
|
|
* other fingerprints although nothing on the canvas changed; ComfyUI would take that as a
|
|
* step, and the next Ctrl+Z would seem to do nothing. When that is the only difference, the
|
|
* history's current state takes it without a step.
|
|
*/
|
|
export function absorbFingerprintChange(app) {
|
|
try {
|
|
const tracker = app?.extensionManager?.workflow?.activeWorkflow?.changeTracker;
|
|
const graph = app?.rootGraph || app?.graph;
|
|
if (!tracker?.activeState || typeof graph?.serialize !== 'function') return;
|
|
const current = JSON.parse(JSON.stringify(graph.serialize()));
|
|
const a = withoutDerived(tracker.activeState);
|
|
const b = withoutDerived(current);
|
|
const same = typeof tracker.constructor?.graphEqual === 'function'
|
|
? tracker.constructor.graphEqual(a, b)
|
|
: JSON.stringify(a) === JSON.stringify(b);
|
|
if (same) tracker.activeState = current;
|
|
} catch (error) {
|
|
console.warn('[AMB] Ctrl+Z history: could not take the new fingerprints in.', error);
|
|
}
|
|
}
|