mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-23 06:02:11 -03:00
Adds custom words autocomplete functionality similar to comfyui-custom-scripts, with the following features: Backend (Python): - Create CustomWordsService for CSV parsing and priority-based search - Add API endpoints: GET/POST /api/lm/custom-words and GET /api/lm/custom-words/search - Share storage with pysssss plugin (checks for their user/autocomplete.txt first) - Fallback to Lora Manager's user directory for storage Frontend (JavaScript/Vue): - Add 'custom_words' and 'prompt' model types to autocomplete system - Prompt node now supports dual-mode autocomplete: * Type 'emb:' prefix → search embeddings * Type normally → search custom words (no prefix required) - Add AUTOCOMPLETE_TEXT_PROMPT widget type - Update Vue component and composable types Key Features: - CSV format: word[,priority] compatible with danbooru-tags.txt - Priority-based sorting: 20% top priority + prefix + include matches - Preview tooltip for embeddings (not for custom words) - Dynamic endpoint switching based on prefix detection Breaking Changes: - Prompt (LoraManager) node widget type changed from AUTOCOMPLETE_TEXT_EMBEDDINGS to AUTOCOMPLETE_TEXT_PROMPT - Removed standalone web/comfyui/prompt.js (integrated into main widgets) Fixes comfy_dir path calculation by prioritizing folder_paths.base_path from ComfyUI when available, with fallback to computed path.
57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
from typing import Any, Optional
|
|
|
|
class PromptLM:
|
|
"""Encodes text (and optional trigger words) into CLIP conditioning."""
|
|
|
|
NAME = "Prompt (LoraManager)"
|
|
CATEGORY = "Lora Manager/conditioning"
|
|
DESCRIPTION = (
|
|
"Encodes a text prompt using a CLIP model into an embedding that can be used "
|
|
"to guide the diffusion model towards generating specific images."
|
|
)
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"text": (
|
|
"AUTOCOMPLETE_TEXT_PROMPT",
|
|
{
|
|
"placeholder": "Enter prompt...",
|
|
"tooltip": "The text to be encoded.",
|
|
},
|
|
),
|
|
"clip": (
|
|
'CLIP',
|
|
{"tooltip": "The CLIP model used for encoding the text."},
|
|
),
|
|
},
|
|
"optional": {
|
|
"trigger_words": (
|
|
'STRING',
|
|
{
|
|
"forceInput": True,
|
|
"tooltip": (
|
|
"Optional trigger words to prepend to the text before "
|
|
"encoding."
|
|
)
|
|
},
|
|
)
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ('CONDITIONING', 'STRING',)
|
|
RETURN_NAMES = ('CONDITIONING', 'PROMPT',)
|
|
OUTPUT_TOOLTIPS = (
|
|
"A conditioning containing the embedded text used to guide the diffusion model.",
|
|
)
|
|
FUNCTION = "encode"
|
|
|
|
def encode(self, text: str, clip: Any, trigger_words: Optional[str] = None):
|
|
prompt = text
|
|
if trigger_words:
|
|
prompt = ", ".join([trigger_words, text])
|
|
|
|
from nodes import CLIPTextEncode # type: ignore
|
|
conditioning = CLIPTextEncode().encode(clip, prompt)[0]
|
|
return (conditioning, prompt,) |