mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat: add dynamic trigger_words inputs to PromptLM node
- Backend: Add _AllContainer for dynamic input validation bypass - Backend: Modify INPUT_TYPES to support trigger_words1, trigger_words2, etc. - Backend: Update encode() to collect all trigger_words* from kwargs - Frontend: Create prompt_dynamic_inputs.js extension - Frontend: Implement onConnectionsChange to auto-add/remove input slots - Frontend: Renumber inputs sequentially on connect/disconnect Based on Impact Pack's Switch (Any) node dynamic input pattern.
This commit is contained in:
112
web/comfyui/prompt_dynamic_inputs.js
Normal file
112
web/comfyui/prompt_dynamic_inputs.js
Normal file
@@ -0,0 +1,112 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
|
||||
/**
|
||||
* Extension for PromptLM node to support dynamic trigger_words inputs.
|
||||
* Based on the dynamic input pattern from Impact Pack's Switch (Any) node.
|
||||
*/
|
||||
app.registerExtension({
|
||||
name: "Comfy.LoraManager.PromptLM",
|
||||
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name !== "Prompt (LoraManager)") {
|
||||
return;
|
||||
}
|
||||
|
||||
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
|
||||
|
||||
nodeType.prototype.onConnectionsChange = function(type, index, connected, link_info) {
|
||||
const stackTrace = new Error().stack;
|
||||
|
||||
// Skip during graph loading/pasting to avoid interference
|
||||
if (stackTrace.includes('loadGraphData') || stackTrace.includes('pasteFromClipboard')) {
|
||||
return onConnectionsChange?.apply?.(this, arguments);
|
||||
}
|
||||
|
||||
// Skip subgraph operations
|
||||
if (stackTrace.includes('convertToSubgraph') || stackTrace.includes('Subgraph.configure')) {
|
||||
return onConnectionsChange?.apply?.(this, arguments);
|
||||
}
|
||||
|
||||
if (!link_info) {
|
||||
return onConnectionsChange?.apply?.(this, arguments);
|
||||
}
|
||||
|
||||
// Handle input connections (type === 1)
|
||||
if (type === 1) {
|
||||
const input = this.inputs[index];
|
||||
|
||||
// Only process trigger_words inputs
|
||||
if (!input || !input.name.startsWith('trigger_words')) {
|
||||
return onConnectionsChange?.apply?.(this, arguments);
|
||||
}
|
||||
|
||||
// Count existing trigger_words inputs
|
||||
let triggerWordCount = 0;
|
||||
for (const inp of this.inputs) {
|
||||
if (inp.name.startsWith('trigger_words')) {
|
||||
triggerWordCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Renumber all trigger_words inputs sequentially
|
||||
let slotIndex = 1;
|
||||
for (const inp of this.inputs) {
|
||||
if (inp.name.startsWith('trigger_words')) {
|
||||
inp.name = `trigger_words${slotIndex}`;
|
||||
slotIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new input slot if connected and this was the last one
|
||||
if (connected) {
|
||||
const lastTriggerIndex = triggerWordCount;
|
||||
if (index === lastTriggerIndex || index === this.inputs.findIndex(i => i.name === `trigger_words${lastTriggerIndex}`)) {
|
||||
this.addInput(`trigger_words${slotIndex}`, "STRING", {
|
||||
forceInput: true,
|
||||
tooltip: "Trigger words to prepend. Connect to add more inputs."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove disconnected empty input slots (but keep at least one)
|
||||
if (!connected && triggerWordCount > 1) {
|
||||
// Check if this input is now empty and can be removed
|
||||
const disconnectedInput = this.inputs[index];
|
||||
if (disconnectedInput && disconnectedInput.name.startsWith('trigger_words')) {
|
||||
// Only remove if it has no link and is not the last trigger_words input
|
||||
const isLastTriggerSlot = index === this.inputs.findLastIndex(i => i.name.startsWith('trigger_words'));
|
||||
if (!isLastTriggerSlot && !disconnectedInput.link) {
|
||||
this.removeInput(index);
|
||||
|
||||
// Renumber again after removal
|
||||
let newSlotIndex = 1;
|
||||
for (const inp of this.inputs) {
|
||||
if (inp.name.startsWith('trigger_words')) {
|
||||
inp.name = `trigger_words${newSlotIndex}`;
|
||||
newSlotIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return onConnectionsChange?.apply?.(this, arguments);
|
||||
};
|
||||
},
|
||||
|
||||
nodeCreated(node, app) {
|
||||
if (node.comfyClass !== "Prompt (LoraManager)") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure at least one trigger_words input exists on creation
|
||||
const hasTriggerWords = node.inputs.some(inp => inp.name.startsWith('trigger_words'));
|
||||
if (!hasTriggerWords) {
|
||||
node.addInput("trigger_words1", "STRING", {
|
||||
forceInput: true,
|
||||
tooltip: "Trigger words to prepend. Connect to add more inputs."
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user