mirror of
https://github.com/hanzoai/Hanzo-EasyUse.git
synced 2026-10-30 18:51:27 +00:00
114 lines
3.8 KiB
JavaScript
114 lines
3.8 KiB
JavaScript
import { app } from "../../../../scripts/app.js";
|
|
|
|
function links_with(p, node_id, down, up) {
|
|
const links_with = [];
|
|
p.workflow.links.forEach((l) => {
|
|
if (down && l[1]===node_id && !links_with.includes(l[3])) links_with.push(l[3])
|
|
if (up && l[3]===node_id && !links_with.includes(l[1])) links_with.push(l[1])
|
|
});
|
|
return links_with;
|
|
}
|
|
|
|
function _all_v_nodes(p, here_id) {
|
|
/*
|
|
Make a list of all downstream nodes.
|
|
*/
|
|
const downstream = [];
|
|
const to_process = [here_id]
|
|
while(to_process.length>0) {
|
|
const id = to_process.pop();
|
|
downstream.push(id);
|
|
to_process.push(
|
|
...links_with(p,id,true,false).filter((nid)=>{
|
|
return !(downstream.includes(nid) || to_process.includes(nid))
|
|
})
|
|
)
|
|
}
|
|
|
|
/*
|
|
Now all upstream nodes from any of the downstream nodes (except us).
|
|
Put us on the result list so we don't flow up through us
|
|
*/
|
|
to_process.push(...downstream.filter((n)=>{ return n!=here_id}));
|
|
const back_upstream = [here_id];
|
|
while(to_process.length>0) {
|
|
const id = to_process.pop();
|
|
back_upstream.push(id);
|
|
to_process.push(
|
|
...links_with(p,id,false,true).filter((nid)=>{
|
|
return !(back_upstream.includes(nid) || to_process.includes(nid))
|
|
})
|
|
)
|
|
}
|
|
|
|
const keep = [];
|
|
keep.push(...downstream);
|
|
keep.push(...back_upstream.filter((n)=>{return !keep.includes(n)}));
|
|
|
|
console.log(`Nodes to keep: ${keep}`);
|
|
return keep;
|
|
}
|
|
|
|
async function all_v_nodes(here_id) {
|
|
const p = structuredClone(await app.graphToPrompt());
|
|
const all_nodes = [];
|
|
p.workflow.nodes.forEach((node)=>{all_nodes.push(node.id)})
|
|
p.workflow.links = p.workflow.links.filter((l)=>{ return (all_nodes.includes(l[1]) && all_nodes.includes(l[3]))} )
|
|
return _all_v_nodes(p,here_id);
|
|
}
|
|
|
|
async function restart_from_here(here_id, go_down_to_chooser=false) {
|
|
const p = structuredClone(await app.graphToPrompt());
|
|
/*
|
|
Make a list of all nodes, and filter out links that are no longer valid
|
|
*/
|
|
const all_nodes = [];
|
|
p.workflow.nodes.forEach((node)=>{all_nodes.push(node.id)})
|
|
p.workflow.links = p.workflow.links.filter((l)=>{ return (all_nodes.includes(l[1]) && all_nodes.includes(l[3]))} )
|
|
|
|
/* Move downstream to a chooser */
|
|
if (go_down_to_chooser) {
|
|
while (!app.graph._nodes_by_id[here_id].isChooser) {
|
|
here_id = links_with(p, here_id, true, false)[0];
|
|
}
|
|
}
|
|
|
|
const keep = _all_v_nodes(p, here_id);
|
|
|
|
/*
|
|
Filter p.workflow.nodes and p.workflow.links
|
|
*/
|
|
p.workflow.nodes = p.workflow.nodes.filter((node) => {
|
|
if (node.id===here_id) node.inputs.forEach((i)=>{i.link=null}) // remove our upstream links
|
|
return (keep.includes(node.id)) // only keep keepers
|
|
})
|
|
p.workflow.links = p.workflow.links.filter((l) => {return (keep.includes(l[1]) && keep.includes(l[3]))})
|
|
|
|
/*
|
|
Filter the p.output object to only include nodes we're keeping
|
|
*/
|
|
const new_output = {}
|
|
for (const [key, value] of Object.entries(p.output)) {
|
|
if (keep.includes(parseInt(key))) new_output[key] = value;
|
|
}
|
|
/*
|
|
Filter the p.output entry for the start node to remove any list (ie link) inputs
|
|
*/
|
|
const new_inputs = {};
|
|
for (const [key, value] of Object.entries(new_output[here_id.toString()].inputs)) {
|
|
if (!Array.isArray(value)) new_inputs[key] = value;
|
|
}
|
|
new_output[here_id.toString()].inputs = new_inputs;
|
|
|
|
p.output = new_output;
|
|
|
|
// temporarily hijack graph_to_prompt with a version that restores the old one but returns this prompt
|
|
const gtp_was = app.graphToPrompt;
|
|
app.graphToPrompt = () => {
|
|
app.graphToPrompt = gtp_was;
|
|
return p;
|
|
}
|
|
app.queuePrompt(0);
|
|
}
|
|
|
|
export { restart_from_here, all_v_nodes } |