Connect accumulator preview by store key

This commit is contained in:
2026-06-25 05:56:53 +02:00
parent e65b67fe85
commit de4ac97665
3 changed files with 20 additions and 6 deletions
+1
View File
@@ -110,6 +110,7 @@ COMMON_INPUT_TOOLTIPS = {
"collection": "Existing accumulated value or batch.", "collection": "Existing accumulated value or batch.",
"value": "Value to append, store, or pass through.", "value": "Value to append, store, or pass through.",
"store_key": "Accumulator memory key. Same key shares stored entries across executions.", "store_key": "Accumulator memory key. Same key shares stored entries across executions.",
"store_key_input": "Connect SxCP Accumulator store_key here so preview/delete/save uses the same accumulator and graph dependency.",
"action": "Accumulator operation: append, replace, clear, read, or append a variant.", "action": "Accumulator operation: append, replace, clear, read, or append a variant.",
"max_items": "Maximum stored entries kept in this accumulator.", "max_items": "Maximum stored entries kept in this accumulator.",
"image_batch_mode": "How image entries are batched when dimensions differ.", "image_batch_mode": "How image entries are batched when dimensions differ.",
+11 -5
View File
@@ -646,13 +646,13 @@ class SxCPAccumulator:
}, },
} }
RETURN_TYPES = tuple([ANY_TYPE, "IMAGE", "IMAGE"] + ["IMAGE"] * ACCUMULATOR_IMAGE_GROUPS + ["INT", "STRING"]) RETURN_TYPES = tuple([ANY_TYPE, "IMAGE", "IMAGE"] + ["IMAGE"] * ACCUMULATOR_IMAGE_GROUPS + ["INT", "STRING", "STRING"])
RETURN_NAMES = tuple( RETURN_NAMES = tuple(
["collection", "image_batch", "image_list"] ["collection", "image_batch", "image_list"]
+ [f"image_batch_{index}" for index in range(1, ACCUMULATOR_IMAGE_GROUPS + 1)] + [f"image_batch_{index}" for index in range(1, ACCUMULATOR_IMAGE_GROUPS + 1)]
+ ["count", "status"] + ["count", "status", "store_key"]
) )
OUTPUT_IS_LIST = tuple([False, False, True] + [False] * ACCUMULATOR_IMAGE_GROUPS + [False, False]) OUTPUT_IS_LIST = tuple([False, False, True] + [False] * ACCUMULATOR_IMAGE_GROUPS + [False, False, False])
FUNCTION = "accumulate" FUNCTION = "accumulate"
CATEGORY = "prompt_builder/loop" CATEGORY = "prompt_builder/loop"
@@ -771,7 +771,7 @@ class SxCPAccumulator:
grouped_outputs = image_batches[:ACCUMULATOR_IMAGE_GROUPS] grouped_outputs = image_batches[:ACCUMULATOR_IMAGE_GROUPS]
grouped_outputs += [None] * (ACCUMULATOR_IMAGE_GROUPS - len(grouped_outputs)) grouped_outputs += [None] * (ACCUMULATOR_IMAGE_GROUPS - len(grouped_outputs))
status = self._status(key, store, image_batch, image_batches) status = self._status(key, store, image_batch, image_batches)
return tuple([self._collection(store), image_batch, images] + grouped_outputs + [len(store), status]) return tuple([self._collection(store), image_batch, images] + grouped_outputs + [len(store), status, key])
class SxCPAccumulatorPreview: class SxCPAccumulatorPreview:
@@ -792,6 +792,9 @@ class SxCPAccumulatorPreview:
"filename_prefix": ("STRING", {"default": "sxcp_accum", "multiline": False}), "filename_prefix": ("STRING", {"default": "sxcp_accum", "multiline": False}),
"clear_after_save": ("BOOLEAN", {"default": False}), "clear_after_save": ("BOOLEAN", {"default": False}),
}, },
"optional": {
"store_key_input": ("STRING", {"forceInput": True}),
},
"hidden": { "hidden": {
"prompt": "PROMPT", "prompt": "PROMPT",
"extra_pnginfo": "EXTRA_PNGINFO", "extra_pnginfo": "EXTRA_PNGINFO",
@@ -838,11 +841,13 @@ class SxCPAccumulatorPreview:
save_path, save_path,
filename_prefix, filename_prefix,
clear_after_save, clear_after_save,
store_key_input=None,
prompt=None, prompt=None,
extra_pnginfo=None, extra_pnginfo=None,
unique_id=None, unique_id=None,
): ):
key = _accumulator_store_key(store_key, unique_id) key_source = str(store_key_input or "").strip() or store_key
key = _accumulator_store_key(key_source, unique_id)
store = _ACCUMULATOR_STORES.setdefault(key, []) store = _ACCUMULATOR_STORES.setdefault(key, [])
removed = self._delete_from_inputs(key, delete_action, delete_entry_id, delete_index) removed = self._delete_from_inputs(key, delete_action, delete_entry_id, delete_index)
images = [entry["image"] for entry in store if entry.get("image") is not None] images = [entry["image"] for entry in store if entry.get("image") is not None]
@@ -870,6 +875,7 @@ class SxCPAccumulatorPreview:
"entries": entries, "entries": entries,
"status": [status], "status": [status],
"saved_paths": saved_paths, "saved_paths": saved_paths,
"store_key": [key],
}, },
"result": (len(store), status, saved_json), "result": (len(store), status, saved_json),
} }
+8 -1
View File
@@ -46,6 +46,12 @@ function outputStatus(output) {
return status || ""; return status || "";
} }
function outputStoreKey(output) {
const key = output?.store_key;
if (Array.isArray(key)) return key[0] || "";
return key || "";
}
function outputEntries(output) { function outputEntries(output) {
const entries = output?.entries; const entries = output?.entries;
if (!entries) return []; if (!entries) return [];
@@ -91,7 +97,7 @@ function selectedEntry(node) {
} }
function storeKey(node) { function storeKey(node) {
return String(widget(node, "store_key")?.value || "").trim(); return String(widget(node, "store_key")?.value || node._sxcpResolvedStoreKey || "").trim();
} }
async function postJson(path, payload) { async function postJson(path, payload) {
@@ -196,6 +202,7 @@ app.registerExtension({
const node = getNodeById(detail?.node); const node = getNodeById(detail?.node);
if (!isAccumulatorPreviewNode(node)) return; if (!isAccumulatorPreviewNode(node)) return;
const output = detail?.output || {}; const output = detail?.output || {};
node._sxcpResolvedStoreKey = outputStoreKey(output);
setEntries(node, outputEntries(output), outputStatus(output)); setEntries(node, outputEntries(output), outputStatus(output));
}); });
}, },