mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-02-15 23:52:32 +08:00
set version info on node
This commit is contained in:
parent
0cb34f3a9f
commit
0fae537e48
@ -3,12 +3,21 @@
|
|||||||
* - custom node pack version to all custom nodes used in the workflow
|
* - custom node pack version to all custom nodes used in the workflow
|
||||||
*
|
*
|
||||||
* Example metadata:
|
* Example metadata:
|
||||||
"extra": {
|
* "nodes": {
|
||||||
"node_versions": {
|
* "1": {
|
||||||
"comfy-core": "v0.3.8-4-g0b2eb7f",
|
* type: "CheckpointLoaderSimple",
|
||||||
"comfyui-easy-use": "1.2.5"
|
* ...
|
||||||
}
|
* properties: {
|
||||||
},
|
* cnr_id: "comfy-core",
|
||||||
|
* version: "0.3.8",
|
||||||
|
* },
|
||||||
|
* },
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @typedef {Object} NodeInfo
|
||||||
|
* @property {string} ver - Version (git hash or semantic version)
|
||||||
|
* @property {string} cnr_id - ComfyRegistry node ID
|
||||||
|
* @property {boolean} enabled - Whether the node is enabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app } from "../../scripts/app.js";
|
import { app } from "../../scripts/app.js";
|
||||||
@ -23,7 +32,7 @@ class WorkflowMetadataExtension {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the installed nodes info
|
* Get the installed nodes info
|
||||||
* @returns {Promise<Record<string, {ver: string, cnr_id: string, enabled: boolean}>>} The mapping from node name to its info.
|
* @returns {Promise<Record<string, NodeInfo>>} The mapping from node name to its info.
|
||||||
* ver can either be a git commit hash or a semantic version such as "1.0.0"
|
* ver can either be a git commit hash or a semantic version such as "1.0.0"
|
||||||
* cnr_id is the id of the node in the ComfyRegistry
|
* cnr_id is the id of the node in the ComfyRegistry
|
||||||
* enabled is true if the node is enabled, false if it is disabled
|
* enabled is true if the node is enabled, false if it is disabled
|
||||||
@ -34,44 +43,80 @@ class WorkflowMetadataExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the node versions for the given graph
|
* Set node versions for the given graph
|
||||||
* @param {LGraph} graph The graph to get the node versions for
|
* @param {LGraph} graph The graph to process
|
||||||
* @returns {Promise<Record<string, string>>} The mapping from node name to version
|
* @param {Object} workflow The serialized workflow object
|
||||||
*/
|
*/
|
||||||
getGraphNodeVersions(graph) {
|
setGraphNodeVersions(graph, workflow) {
|
||||||
const nodeVersions = {};
|
if (!graph?.nodes || !workflow?.nodes) return;
|
||||||
for (const node of graph.nodes) {
|
|
||||||
const nodeData = node.constructor.nodeData;
|
|
||||||
// Frontend only nodes don't have nodeData
|
|
||||||
if (!nodeData) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const modules = nodeData.python_module.split(".");
|
|
||||||
|
|
||||||
if (modules[0] === "custom_nodes") {
|
// Create a map of workflow nodes by ID
|
||||||
const nodePackageName = modules[1];
|
const workflowNodesById = {};
|
||||||
const nodeInfo =
|
for (const node of workflow.nodes) {
|
||||||
this.installedNodes[nodePackageName] ??
|
if (node.id != null) {
|
||||||
this.installedNodes[nodePackageName.toLowerCase()];
|
workflowNodesById[node.id] = node;
|
||||||
if (nodeInfo) {
|
|
||||||
nodeVersions[nodePackageName] = nodeInfo.ver;
|
|
||||||
}
|
|
||||||
} else if (["nodes", "comfy_extras"].includes(modules[0])) {
|
|
||||||
nodeVersions["comfy-core"] = this.comfyCoreVersion;
|
|
||||||
} else {
|
|
||||||
console.warn(`Unknown node source: ${nodeData.python_module}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nodeVersions;
|
|
||||||
|
// Process each graph node and find its corresponding workflow node by ID
|
||||||
|
for (const graphNode of graph.nodes) {
|
||||||
|
const workflowNode = workflowNodesById[graphNode.id];
|
||||||
|
if (!workflowNode) continue;
|
||||||
|
this.setNodeVersion(graphNode, workflowNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The node versions embedded in the workflow json's initial state.
|
* Set version information for a single node
|
||||||
* @returns {Record<string, string> | undefined} The mapping from node name to version
|
* @param {Object} graphNode The graph node
|
||||||
|
* @param {Object} workflowNode The workflow node
|
||||||
*/
|
*/
|
||||||
get workflowNodeVersions() {
|
setNodeVersion(graphNode, workflowNode) {
|
||||||
return app.extensionManager?.workflow?.activeWorkflow?.initialState?.extra
|
const nodeProperties = (workflowNode.properties ??= {});
|
||||||
?.node_versions;
|
const nodeData = graphNode.constructor?.nodeData;
|
||||||
|
|
||||||
|
// The node is missing or is a frontend only node
|
||||||
|
// (node was not constructed in registerNodes closure where nodeData is set)
|
||||||
|
if (!nodeData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const modules = nodeData.python_module.split(".");
|
||||||
|
const moduleType = modules[0];
|
||||||
|
|
||||||
|
if (moduleType === "custom_nodes") {
|
||||||
|
this.setCustomNodeVersion(modules[1], nodeProperties);
|
||||||
|
} else if (["nodes", "comfy_extras"].includes(moduleType)) {
|
||||||
|
this.setCoreNodeVersion(nodeProperties);
|
||||||
|
} else {
|
||||||
|
console.warn(`Unknown node source: ${nodeData.python_module}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set version for custom nodes
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
setCustomNodeVersion(nodePackageName, nodeProperties) {
|
||||||
|
const nodeInfo =
|
||||||
|
this.installedNodes[nodePackageName] ??
|
||||||
|
this.installedNodes[nodePackageName.toLowerCase()];
|
||||||
|
|
||||||
|
if (nodeInfo) {
|
||||||
|
if (nodeInfo.cnr_id === "comfy-core") return; // reserved package name
|
||||||
|
// Preserve workflow cnr_id and version if they exist
|
||||||
|
nodeProperties.cnr_id ??= nodeInfo.cnr_id;
|
||||||
|
nodeProperties.version ??= nodeInfo.ver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set version for core nodes
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
setCoreNodeVersion(nodeProperties) {
|
||||||
|
nodeProperties.cnr_id ??= "comfy-core";
|
||||||
|
nodeProperties.version ??= this.comfyCoreVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
@ -84,20 +129,13 @@ class WorkflowMetadataExtension {
|
|||||||
LGraph.prototype.serialize = function () {
|
LGraph.prototype.serialize = function () {
|
||||||
const workflow = originalSerialize.apply(this, arguments);
|
const workflow = originalSerialize.apply(this, arguments);
|
||||||
|
|
||||||
// Add metadata to the workflow
|
// Add metadata to the nodes
|
||||||
if (!workflow.extra) {
|
|
||||||
workflow.extra = {};
|
|
||||||
}
|
|
||||||
const graph = this;
|
const graph = this;
|
||||||
try {
|
try {
|
||||||
workflow.extra["node_versions"] = {
|
extension.setGraphNodeVersions(graph, workflow);
|
||||||
...extension.getGraphNodeVersions(graph),
|
|
||||||
...extension.workflowNodeVersions, // give precedence to the workflow node versions
|
|
||||||
};
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return workflow;
|
return workflow;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user