|
|
@@ -157,13 +157,36 @@ function findPlaceholders(text) {
|
|
|
return found;
|
|
|
}
|
|
|
|
|
|
+// Inside a loop the engine hands a node the loop item rather than the upstream
|
|
|
+// node's output, and the upstream result is nested somewhere under it. Resolve a
|
|
|
+// path against the obvious roots first, then search the tree for it.
|
|
|
+function deepResolve(root, path, depth) {
|
|
|
+ if (!root || typeof root !== 'object' || depth > 6) {
|
|
|
+ return undefined;
|
|
|
+ }
|
|
|
+
|
|
|
+ const direct = getPath(root, path);
|
|
|
+ if (direct !== undefined) {
|
|
|
+ return direct;
|
|
|
+ }
|
|
|
+
|
|
|
+ const keys = Object.keys(root);
|
|
|
+ for (let i = 0; i < keys.length; i++) {
|
|
|
+ const found = deepResolve(root[keys[i]], path, depth + 1);
|
|
|
+ if (found !== undefined) {
|
|
|
+ return found;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined;
|
|
|
+}
|
|
|
+
|
|
|
function substitute(template, data) {
|
|
|
let out = String(template);
|
|
|
const keys = findPlaceholders(out);
|
|
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
|
|
const key = keys[i];
|
|
|
- let value = getPath(data, key);
|
|
|
+ let value = deepResolve(data, key, 0);
|
|
|
|
|
|
if (value === undefined && key === 'seed') {
|
|
|
value = Math.floor(Math.random() * 1000000000000000);
|
|
|
@@ -311,7 +334,9 @@ module.exports = {
|
|
|
throw new Error('A ComfyUI workflow graph is required');
|
|
|
}
|
|
|
|
|
|
- const data = input && input.data !== undefined ? input.data : input;
|
|
|
+ // Resolve against the whole input: the upstream result may be nested under
|
|
|
+ // the loop item rather than sitting at input.data.
|
|
|
+ const data = input;
|
|
|
const base = String(config.baseUrl).replace(/\/+$/, '');
|
|
|
const attempts = 1 + (Number(config.retryCount) > 0 ? Number(config.retryCount) : 0);
|
|
|
|