Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion py/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
def get_workflow_data(workflow_file):
nodes = {"WorkflowInput": {}, "WorkflowOutput": {}}
# Extraire les nœuds WorkflowInput et WorkflowOutput
# print(workflow_file["nodes"]);
for node in workflow_file["nodes"]:

node_type = node.get("type")
Expand Down
35 changes: 33 additions & 2 deletions web/js/inputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,14 @@ export function addInputs(node, inputs, widgets_values) {
(input) => input.value !== undefined && input.value !== null
);
// replace value in widget_inputs with the value in widgets_values
if (widgets_values) {
if (widgets_values && widgets_values.length > 2) {
// widgets_values[0] = workflow name, widgets_values[1] = workflow JSON
// Input values start from index 2
for (let i = 0; i < widget_inputs.length; i++) {
const widget_input = widget_inputs[i];
const widget_value = widgets_values[2 + i];
//find name in mapped_input and replace value
if (widget_value)
if (widget_value !== undefined && widget_value !== null)
for (let j = 0; j < mapped_input.length; j++)
if (mapped_input[j].name == widget_input.name) {
mapped_input[j].value = widget_value;
Expand Down Expand Up @@ -421,6 +423,35 @@ export function addInputs(node, inputs, widgets_values) {
}*/
}

// Update widgets_values array to reflect current widget values
if (node.widgets && node.widgets.length > 0) {
// Ensure widgets_values array exists and has correct length
if (!node.widgets_values) {
node.widgets_values = [];
}

// Update widgets_values with current widget values
// widgets_values[0] = workflow name, widgets_values[1] = workflow JSON
// Input values start from index 2
for (let i = 0; i < node.widgets.length; i++) {
const widget = node.widgets[i];
const valueIndex = 2 + i;

// Ensure the array is long enough
while (node.widgets_values.length <= valueIndex) {
node.widgets_values.push(undefined);
}

// Update the value, but don't overwrite workflow JSON if it's "false"
if (valueIndex === 1 && widget.value === "false") {
// Don't update the workflow JSON if it's "false"
continue;
}

node.widgets_values[valueIndex] = widget.value;
}
}

// Rafraîchir le canvas si nécessaire
if (node.graph) {
node.graph.setDirtyCanvas(false, true);
Expand Down
82 changes: 45 additions & 37 deletions web/js/nodetype_workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,37 +101,24 @@ function initialisation_preGraph(node) {
} else if (app && app.lipsync_studio && app.lipsync_studio[value]) {
try {
let workflowJSON = await importWorkflow(node, value, app); // importWorkflow updates node.title

// Check if importWorkflow returned false (error case)
if (workflowJSON === false) {
console.error(`Failed to import workflow: ${value}`);
node.title = "Workflow (FlowChain ⛓️)"; // Reset title on error
return;
}

workflowJSON = JSON.parse(workflowJSON);
// Ensure app.lipsync_studio[value] (and its .inputs) is still valid after await
if (app.lipsync_studio[value] && app.lipsync_studio[value].inputs) {
const inputs = app.lipsync_studio[value].inputs;
const outputs = app.lipsync_studio[value].outputs;
for (let [key, value] of Object.entries(inputs)) {
if (
value["inputs"][2]?.values &&
value["inputs"][2].values.length > 0
) {
workflowJSON[key]["inputs"]["type"] = "COMBO";
} else {
workflowJSON[key]["inputs"]["type"] = value["inputs"][1];
}
}
for (let [key, value] of Object.entries(outputs)) {
if (value["inputs"].length === undefined) {
workflowJSON[key]["inputs"]["type"] =
value["inputs"].type.value;
} else {
workflowJSON[key]["inputs"]["type"] = value["inputs"][1];
}
}
workflowJSON = JSON.stringify(workflowJSON);

// We no longer mutate workflowJSON by numeric keys; IDs may differ after conversion
if (node.widgets && node.widgets[1]) {
node.widgets[1].value = workflowJSON;
node.widgets[1].value = ""; // keep hidden field empty to avoid bloat
}

addInputs(node, inputs, []); // Requires node.graph
addOutputs(node, value); // Requires node.graph
addInputs(node, inputs, node.widgets_values || []);
addOutputs(node, value);
fitHeight(node);
} else {
console.error(
Expand Down Expand Up @@ -184,6 +171,7 @@ function initialisation_onAdded(node) {
if (
node.widgets[1] &&
(node.widgets[1].value === "" ||
node.widgets[1].value === "false" ||
typeof node.widgets[1].value !== "string" ||
!node.widgets[1].value.startsWith("{"))
) {
Expand Down Expand Up @@ -245,9 +233,13 @@ function configure(info) {
this.widgets &&
this.widgets[1] &&
info.widgets_values &&
info.widgets_values[1]
info.widgets_values[1] &&
info.widgets_values[1] !== "false"
) {
this.widgets[1].value = info.widgets_values[1]; // Set the hidden workflow JSON
} else if (info.widgets_values && info.widgets_values[1] === "false") {
// If the stored value is "false", clear it and trigger re-import
this.widgets[1].value = "";
}

if (selectedWorkflowName === "None") {
Expand Down Expand Up @@ -296,20 +288,30 @@ function configure(info) {
const outputs = app.lipsync_studio[selectedWorkflowName].outputs;

for (let [key, value] of Object.entries(inputs)) {
data_json[key]["inputs"]["type"] = value["inputs"][1];
// Check if the key exists in data_json before accessing it
if (data_json[key] && data_json[key]["inputs"]) {
data_json[key]["inputs"]["type"] = value["inputs"][1];
} else {
console.warn(`Key '${key}' not found in data_json for inputs processing`);
}
}
for (let [key, value] of Object.entries(outputs)) {
if (value["inputs"].length === undefined) {
data_json[key]["inputs"]["type"] = value["inputs"].type.value;
} else {
if (
value["inputs"][2]?.values &&
value["inputs"][2].values.length > 0
) {
data_json[key]["inputs"]["type"] = "COMBO";
// Check if the key exists in data_json before accessing it
if (data_json[key] && data_json[key]["inputs"]) {
if (value["inputs"].length === undefined) {
data_json[key]["inputs"]["type"] = value["inputs"].type.value;
} else {
data_json[key]["inputs"]["type"] = value["inputs"][1];
if (
value["inputs"][2]?.values &&
value["inputs"][2].values.length > 0
) {
data_json[key]["inputs"]["type"] = "COMBO";
} else {
data_json[key]["inputs"]["type"] = value["inputs"][1];
}
}
} else {
console.warn(`Key '${key}' not found in data_json for outputs processing`);
}
}
this.widgets[1].value = JSON.stringify(data_json);
Expand Down Expand Up @@ -395,6 +397,12 @@ export function setupWorkflowNode(nodeType) {
initialisation_preGraph(this); // Our graph-independent setup

chainCallback(this, "onConfigure", configure);
chainCallback(this, "onSerialize", serialize);
chainCallback(this, "onSerialize", function(info){
// Ensure workflow_json is not persisted to avoid runaway nested JSON
if (info.widgets_values && info.widgets_values.length > 1) {
info.widgets_values[1] = "";
}
serialize.call(this, info);
});
};
}
6 changes: 2 additions & 4 deletions web/js/workflows.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ async function convertWorkflowToApiFormat(standardWorkflow) {
const originalGraph = app.graph;

// Utiliser graphToPrompt en mode isolé
app.graph = tempGraph;
// Instead of setting app.graph directly, we'll pass the tempGraph to graphToPrompt
// Configurer sans déclencher de callbacks
tempGraph.configure(standardWorkflow);

app.graphToPrompt(tempGraph)
.then(apiData => {
// Restaurer le graphe original
app.graph = originalGraph;
// No need to restore app.graph since we didn't change it

// Résoudre avec le format API
resolve(apiData.output);
Expand Down Expand Up @@ -89,7 +88,6 @@ export async function importWorkflow(root_obj, workflow_path, app){
const filename = workflow_path.replace(/\\/g, '/').split("/");
root_obj.title = "Workflow: "+filename[filename.length-1].replace(".json", "").replace(/_/g, " ");


return api.fetchApi("/flowchain/workflow?workflow_path="+workflow_path)
.then(response => response.json())
.then(async data => {
Expand Down
Loading