diff --git a/README.md b/README.md index 7a5132f3..73967425 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ Insomnia Art Designs, megakirbs, Brennok, 2018cfh, W+K+White, wackop, Takkan, Ca ### v0.9.14 * **LoRA Cycler Node** - Introduced a new LoRA Cycler node that enables iteration through specified LoRAs with support for repeat count and pause iteration functionality. Refer to the new "Lora Cycler" template workflow for concrete example. -* **Enhanced Prompt Node with Tag Autocomplete** - Enhanced the Prompt node with comprehensive tag autocomplete based on merged Danbooru + e621 tags. Supports tag search and autocomplete functionality. Implemented a command system with shortcuts like `/char` or `/artist` for category-specific tag searching. Added `/ac` or `/noac` commands to quickly enable or disable autocomplete. Refer to the "Lora Manager Basic" template workflow in ComfyUI -> Templates -> ComfyUI-Lora-Manager for detailed tips. +* **Enhanced Prompt Node with Tag Autocomplete** - Enhanced the Prompt node with comprehensive tag autocomplete based on merged Danbooru + e621 tags. Supports tag search and autocomplete functionality. Implemented a command system with shortcuts like `/character` or `/artist` for category-specific tag searching. Added `/ac` or `/noac` commands to quickly enable or disable autocomplete. Refer to the "Lora Manager Basic" template workflow in ComfyUI -> Templates -> ComfyUI-Lora-Manager for detailed tips. * **Bug Fixes & Stability** - Addressed multiple bugs and improved overall stability. ### v0.9.12 diff --git a/example_workflows/Lora_Manager_Basic.json b/example_workflows/Lora_Manager_Basic.json index 3924c943..a6848f2b 100644 --- a/example_workflows/Lora_Manager_Basic.json +++ b/example_workflows/Lora_Manager_Basic.json @@ -1 +1 @@ -{"id":"151410b3-7845-4561-aac4-8968574e9ba2","revision":0,"last_node_id":79,"last_link_id":153,"nodes":[{"id":68,"type":"Reroute","pos":[998.4027324863023,692.2310592692698],"size":[75,26],"flags":{},"order":14,"mode":0,"inputs":[{"name":"","type":"*","link":142}],"outputs":[{"name":"","type":"VAE","links":[143]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":67,"type":"Reroute","pos":[-86.5906935091898,690.9580502534923],"size":[75,26],"flags":{},"order":10,"mode":0,"inputs":[{"name":"","type":"*","link":148}],"outputs":[{"name":"","type":"VAE","links":[142]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":69,"type":"Reroute","pos":[978.2273004802915,-259.1147333678449],"size":[75,26],"flags":{},"order":11,"mode":0,"inputs":[{"name":"","type":"*","link":144}],"outputs":[{"name":"","type":"MODEL","links":[145]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":14,"type":"PreviewImage","pos":[1713.5381320312501,-264.6858476562499],"size":[537.9034423828125,705.2806396484375],"flags":{},"order":19,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":140}],"outputs":[],"properties":{"Node name for S&R":"PreviewImage","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[]},{"id":71,"type":"MarkdownNote","pos":[1279.261094792334,651.6318783062643],"size":[427.3741705387979,420.4396672979459],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["## Save image with metadata\n\nAvailable filename_prefix Pattern Codes\n\n- %seed% - Inserts the generation seed number\n- %width% - Inserts the image width\n- %height% - Inserts the image height\n- %pprompt:N% - Inserts the positive prompt (limited to N characters)\n- %nprompt:N% - Inserts the negative prompt (limited to N characters)\n- %model:N% - Inserts the model/checkpoint name (limited to N characters)\n- %date% - Inserts current date/time as \"yyyyMMddhhmmss\"\n- %date:FORMAT% - Inserts date using custom format with:\n - yyyy - 4-digit year\n - yy - 2-digit year\n - MM - 2-digit month\n - dd - 2-digit day\n - hh - 2-digit hour\n - mm - 2-digit minute\n - ss - 2-digit second\n\nExamples\n\n- image_%seed% → image_1234567890\n- gen_%width%x%height% → gen_512x768\n- %model:10%_%seed% → dreamshape_1234567890\n- %date:yyyy-MM-dd% → 2025-04-28\n- %pprompt:20%_%seed% → beautiful landscape_1234567890\n- %model%_%date:yyMMdd%_%seed% → dreamshaper_v8_250428_1234567890\n\nYou can combine multiple patterns to create detailed, organized filenames for your generated images."],"color":"#432","bgcolor":"#653"},{"id":60,"type":"Save Image (LoraManager)","pos":[1275.2038808593754,416.62814648437484],"size":[380.4000244140625,202],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":128},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"file_format","name":"file_format","type":"COMBO","widget":{"name":"file_format"},"link":null},{"localized_name":"lossless_webp","name":"lossless_webp","shape":7,"type":"BOOLEAN","widget":{"name":"lossless_webp"},"link":null},{"localized_name":"quality","name":"quality","shape":7,"type":"INT","widget":{"name":"quality"},"link":null},{"localized_name":"embed_workflow","name":"embed_workflow","shape":7,"type":"BOOLEAN","widget":{"name":"embed_workflow"},"link":null},{"localized_name":"save_with_metadata","name":"save_with_metadata","shape":7,"type":"BOOLEAN","widget":{"name":"save_with_metadata"},"link":null},{"localized_name":"add_counter_to_filename","name":"add_counter_to_filename","shape":7,"type":"BOOLEAN","widget":{"name":"add_counter_to_filename"},"link":null}],"outputs":[{"localized_name":"images","name":"images","type":"IMAGE","links":[]}],"properties":{"Node name for S&R":"Save Image (LoraManager)","cnr_id":"comfyui-lora-manager","ver":"f51f49eb60e1c7e524fa71c07bdea138824164e1"},"widgets_values":["ComfyUI","jpeg",false,100,false,true,true],"color":"#323","bgcolor":"#535"},{"id":74,"type":"Prompt (LoraManager)","pos":[403.28939580427357,-589.3789158346285],"size":[398.9062311540674,208.65451316663655],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":null},{"localized_name":"trigger_words1","name":"trigger_words1","shape":7,"type":"STRING","link":null},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_PROMPT,STRING","widget":{"name":"text"},"link":null},{"localized_name":"trigger_words","name":"trigger_words","shape":7,"type":"STRING","link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":null},{"localized_name":"PROMPT","name":"PROMPT","type":"STRING","links":null}],"properties":{"Node name for S&R":"Prompt (LoraManager)","__lm_widget_ids":["__lm_autocomplete_meta_text","text"]},"widgets_values":[{"version":1,"textWidgetName":"text"},""]},{"id":70,"type":"MarkdownNote","pos":[-609.5947235373926,-334.9082558764654],"size":[505.3054777679118,514.1363636363633],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[],"title":"LoRA Manager – LoRA Loader Node Usage Guide","properties":{},"widgets_values":["## Sending from LM UI to Workflow\n- **Click**: Append the selected LoRA(s) to the current LoRA Loader node. \n- **Shift + Click**: Replace the current node content with the selected LoRA(s). \n- **Color-code your target nodes**: \n If multiple valid target nodes exist, you can assign colors to them. \n LM will display these colors in the *Send to workflow* picker, making target selection easier.\n\n---\n\n## Text Input Autocomplete\n- Supports **multi-token search**, **case-insensitive**, and **token exclusion**.\n- Examples:\n - `enhance low` → matches LoRAs containing **both** “enhance” and “low”.\n - `detail -sdxl` → matches LoRAs containing “detail” but **not** “sdxl”.\n\n---\n\n## LoRA Widget Shortcuts\n### Navigation\n- **Arrow Up / Arrow Down** — Select previous / next LoRA.\n- **Ctrl/Cmd + Arrow Up** — Move selected LoRA upward.\n- **Ctrl/Cmd + Arrow Down** — Move selected LoRA downward.\n- **Ctrl/Cmd + Home** — Move selected LoRA to top.\n- **Ctrl/Cmd + End** — Move selected LoRA to bottom.\n\n### Editing & Deleting\n- **Delete / Backspace** — Remove current LoRA.\n- **Tab / Shift + Tab** — After confirming strength input, jump to next / previous editable field.\n\n---\n\nThese same features also apply to **LoRA Stacker**, **WanVideo LoRA Select**, and other LoRA Manager lora nodes. \n"],"color":"#432","bgcolor":"#653"},{"id":8,"type":"VAEDecode","pos":[1462.004865809667,9.84471397317456],"size":[210,46],"flags":{"collapsed":false},"order":17,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":7},{"localized_name":"vae","name":"vae","type":"VAE","link":143}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","slot_index":0,"links":[128,140]}],"properties":{"Node name for S&R":"VAEDecode","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[]},{"id":5,"type":"EmptyLatentImage","pos":[904.6207446270088,323.25821148560544],"size":[210,106],"flags":{"collapsed":true},"order":3,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"batch_size","name":"batch_size","type":"INT","widget":{"name":"batch_size"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","slot_index":0,"links":[2]}],"properties":{"Node name for S&R":"EmptyLatentImage","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[1024,1024,1]},{"id":73,"type":"MarkdownNote","pos":[466.1270343136322,315.36865571116505],"size":[419.2747375949979,368.826133884363],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[],"title":"Prompt Node Usage","properties":{},"widgets_values":["## Tag Autocomplete\n- **Type directly** to trigger tag autocomplete suggestions. \n Suggestions are based on **merged Danbooru + e621 tags**.\n- Use **category shortcuts** for faster searches, such as:\n - `/char` — character tags \n - `/artist` — artist tags \n - Type `/` alone to see **more categories and available commands**.\n- Use `/ac` and `/noac` to **enable or disable autocomplete**:\n - When autocomplete is **disabled**, `/` commands are still available for **category-specific tag search**.\n- Check **ComfyUI Settings** for additional autocomplete-related options.\n\n---\n\n## Embedding Search\n- Use the `/emb` command or the `emb:` prefix to search embeddings.\n- Supports **multi-token search** with **inclusion and exclusion**.\n- Examples:\n - `/emb lazy pos` → matches embeddings containing **both** `lazy` **and** `pos`.\n - `emb: lazy -neg` → matches embeddings containing `lazy` but **excluding** `neg`.\n"],"color":"#432","bgcolor":"#653"},{"id":75,"type":"Checkpoint Loader (LoraManager)","pos":[-631.0284354158929,447.72116940437536],"size":[327.960546875,98],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"ckpt_name","name":"ckpt_name","type":"COMBO","widget":{"name":"ckpt_name"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[146]},{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[147]},{"localized_name":"VAE","name":"VAE","type":"VAE","links":[148]}],"properties":{"Node name for S&R":"Checkpoint Loader (LoraManager)"},"widgets_values":["Illustrious/anime/waiIllustriousSDXL_v140.safetensors"],"color":"#233","bgcolor":"#355"},{"id":77,"type":"Unet Loader (LoraManager)","pos":[-629.521013073885,614.6529081448173],"size":[321.3446154127322,89.6620986362143],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"unet_name","name":"unet_name","type":"COMBO","widget":{"name":"unet_name"},"link":null},{"localized_name":"weight_dtype","name":"weight_dtype","type":"COMBO","widget":{"name":"weight_dtype"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":null}],"properties":{"Node name for S&R":"Unet Loader (LoraManager)"},"widgets_values":["Qwen/qwenImageEdit_qwenImgEditFp8E4m3fn.safetensors","default"],"color":"#233","bgcolor":"#355"},{"id":72,"type":"MarkdownNote","pos":[-76.81724129033134,560.7435438197762],"size":[412.2107438016527,119.40082644628092],"flags":{},"order":7,"mode":0,"inputs":[],"outputs":[],"title":"TriggerWord Toggle Node Usage","properties":{},"widgets_values":["## TriggerWord Toggle Node Usage\n\n- When a LoRA is selected in a connected LoRA Loader/Stacker node, \n the **corresponding trigger words** in the TriggerWord Toggle node will be **highlighted automatically**, \n making it easy to see which trigger words belong to the selected LoRA.\n"],"color":"#432","bgcolor":"#653"},{"id":76,"type":"MarkdownNote","pos":[-630.0201675769378,775.9108880568566],"size":[412.2107438016527,119.40082644628092],"flags":{},"order":8,"mode":0,"inputs":[],"outputs":[],"title":"Checkpoint / Unet Loader Node Usage","properties":{},"widgets_values":["## Checkpoint / Unet Loader Node Usage\n- Works exactly like the built in **Load Checkpoint** and **Load Diffusion Model** nodes, but can load from LoRA Manager exclusive extra folder paths.\n- The **UNet Loader** node from LoRA Manager can also load GGUF models. The **ComfyUI-GGUF** custom node must be installed to enable this.\n"],"color":"#432","bgcolor":"#653"},{"id":55,"type":"TriggerWord Toggle (LoraManager)","pos":[-80.30650479770253,252.03850016031464],"size":[415.05371900826435,284],"flags":{"collapsed":false},"order":13,"mode":0,"inputs":[{"localized_name":"group_mode","name":"group_mode","type":"BOOLEAN","widget":{"name":"group_mode"},"link":null},{"localized_name":"default_active","name":"default_active","type":"BOOLEAN","widget":{"name":"default_active"},"link":null},{"localized_name":"allow_strength_adjustment","name":"allow_strength_adjustment","type":"BOOLEAN","widget":{"name":"allow_strength_adjustment"},"link":null},{"name":"trigger_words","shape":7,"type":"string","link":123}],"outputs":[{"localized_name":"filtered_trigger_words","name":"filtered_trigger_words","type":"STRING","links":[149]}],"properties":{"Node name for S&R":"TriggerWord Toggle (LoraManager)","cnr_id":"comfyui-lora-manager","ver":"ad56cafd62e42e67f282a967627f26b8fa6ce00a"},"widgets_values":[true,[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],false,[{"text":"masterpiece, best quality, very aesthetic, absurdres","active":[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],"strength":null,"highlighted":false},{"text":"69yottea_style_illu","active":[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],"strength":null,"highlighted":false},{"text":"7481llu","active":[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],"strength":null,"highlighted":false}],"masterpiece, best quality, very aesthetic, absurdres,, 69yottea_style_illu,, 7481llu"],"color":"#323","bgcolor":"#535"},{"id":78,"type":"Prompt (LoraManager)","pos":[458.47823804087926,-172.43375605957237],"size":[428.81081321022725,195.58589311079544],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":150},{"localized_name":"trigger_words1","name":"trigger_words1","shape":7,"type":"STRING","link":149},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_PROMPT,STRING","widget":{"name":"text"},"link":null},{"name":"trigger_words2","type":"STRING","link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[151]},{"localized_name":"PROMPT","name":"PROMPT","type":"STRING","links":null}],"properties":{"Node name for S&R":"Prompt (LoraManager)","__lm_widget_ids":["__lm_autocomplete_meta_text","text"]},"widgets_values":[{"version":1,"textWidgetName":"text"},"adult,\n1woman, volumetric lighting, ambient occlusion, luminescent background, masterpiece, best quality, absurdres,masterpiece, best quality, very awa, absurdres,,mage,dynamic pose,dynamic angle,upper body focus, floating hair,impressionism, excellent depth of field, partly realistic texture, dramatic lighting, sharp focus, newest, absurdres, highres, very aesthetic, masterpiece, eye-catching, beautiful body, detailed skin features, beautiful eye details, bright colors, vivid colors, extreme contrast, foreshortening, high resolution, best quality, ultra high definition, extremely high detail, wide angle, cinematic field of view, perfect composition,\nBREAK\nelf,blonde hair,long hair,braid,pointy ears, green eyes, choker,capelet, dress,belt,pouch,staff,holding staff,\nmasterpiece, best quality, very aesthetic, absurdres..."],"color":"#232","bgcolor":"#353"},{"id":56,"type":"Lora Loader (LoraManager)","pos":[-80.30650479770253,-261.59171061870467],"size":[423.7818298339844,432],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":146},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_LORAS","widget":{"name":"text"},"link":null},{"name":"clip","shape":7,"type":"CLIP","link":147},{"name":"lora_stack","shape":7,"type":"LORA_STACK","link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[144]},{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[150,152]},{"localized_name":"trigger_words","name":"trigger_words","type":"STRING","links":[123]},{"localized_name":"loaded_loras","name":"loaded_loras","type":"STRING","links":null}],"properties":{"Node name for S&R":"Lora Loader (LoraManager)","cnr_id":"comfyui-lora-manager","ver":"ad56cafd62e42e67f282a967627f26b8fa6ce00a","__lm_widget_ids":["__lm_autocomplete_meta_text","text","loras"]},"widgets_values":[{"version":1,"textWidgetName":"text"}," ",[{"name":"illustrious_all_rated_v1","strength":0.6,"active":true,"expanded":false,"clipStrength":0.6,"locked":false},{"name":"69yottea_illu_v2","strength":0.4,"active":true,"expanded":false,"clipStrength":0.4,"locked":false},{"name":"748cm_illu","strength":0.6,"active":true,"expanded":false,"clipStrength":0.6,"locked":false},{"name":"ppw_v7_Animv4","strength":0.6,"active":true,"expanded":false,"clipStrength":0.6,"locked":false}]],"color":"#323","bgcolor":"#535"},{"id":3,"type":"KSampler","pos":[1116.852600902062,-4.25493111593072],"size":[315,262],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":145},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":151},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":153},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":2},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"cfg","name":"cfg","type":"FLOAT","widget":{"name":"cfg"},"link":null},{"localized_name":"sampler_name","name":"sampler_name","type":"COMBO","widget":{"name":"sampler_name"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"denoise","name":"denoise","type":"FLOAT","widget":{"name":"denoise"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","slot_index":0,"links":[7]}],"properties":{"Node name for S&R":"KSampler","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[42,"fixed",30,7,"euler_ancestral","karras",1]},{"id":79,"type":"Prompt (LoraManager)","pos":[461.615667018153,74.56083123179819],"size":[423.9230069247159,198.89166814630676],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":152},{"localized_name":"trigger_words1","name":"trigger_words1","shape":7,"type":"STRING","link":null},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_PROMPT,STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[153]},{"localized_name":"PROMPT","name":"PROMPT","type":"STRING","links":null}],"properties":{"Node name for S&R":"Prompt (LoraManager)","__lm_widget_ids":["__lm_autocomplete_meta_text","text"]},"widgets_values":[{"version":1,"textWidgetName":"text"},"embedding:lazyneg, lowres,bad anatomy,blurry,(worst quality:1.8),low quality,hands bad,(normal quality:1.3),bad hands,mutated hands and fingers,extra legs,extra arms,duplicate,cropped,jpeg,artifacts,long body,multiple breasts,mutated,disfigured,bad proportions,bad feet,ugly,text font ui,missing limb,monochrome,face bad, crown, tiara, jewelry, earring,pubes,pubic hair, censored,black bars, four legs,ugly hands,big earring,hoop earring,sleeves,collar,glasses, extra fingers,sunglasses, (hat:1.3),multiple hands..."],"color":"#322","bgcolor":"#533"}],"links":[[2,5,0,3,3,"LATENT"],[7,3,0,8,0,"LATENT"],[123,56,2,55,3,"string"],[128,8,0,60,0,"IMAGE"],[140,8,0,14,0,"IMAGE"],[142,67,0,68,0,"*"],[143,68,0,8,1,"VAE"],[144,56,0,69,0,"*"],[145,69,0,3,0,"MODEL"],[146,75,0,56,0,"MODEL"],[147,75,1,56,2,"CLIP"],[148,75,2,67,0,"VAE"],[149,55,0,78,1,"STRING"],[150,56,1,78,0,"CLIP"],[151,78,0,3,1,"CONDITIONING"],[152,56,1,79,0,"CLIP"],[153,79,0,3,2,"CONDITIONING"]],"groups":[],"config":{},"extra":{"ds":{"scale":1.1000000000000003,"offset":[142.00898896551203,398.3750291419585]},"frontendVersion":"1.16.8","VHS_latentpreview":false,"VHS_latentpreviewrate":0,"VHS_MetadataImage":true,"VHS_KeepIntermediate":true},"version":0.4} \ No newline at end of file +{"id":"151410b3-7845-4561-aac4-8968574e9ba2","revision":0,"last_node_id":79,"last_link_id":153,"nodes":[{"id":68,"type":"Reroute","pos":[998.4027324863023,692.2310592692698],"size":[75,26],"flags":{},"order":14,"mode":0,"inputs":[{"name":"","type":"*","link":142}],"outputs":[{"name":"","type":"VAE","links":[143]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":67,"type":"Reroute","pos":[-86.5906935091898,690.9580502534923],"size":[75,26],"flags":{},"order":10,"mode":0,"inputs":[{"name":"","type":"*","link":148}],"outputs":[{"name":"","type":"VAE","links":[142]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":69,"type":"Reroute","pos":[978.2273004802915,-259.1147333678449],"size":[75,26],"flags":{},"order":11,"mode":0,"inputs":[{"name":"","type":"*","link":144}],"outputs":[{"name":"","type":"MODEL","links":[145]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":14,"type":"PreviewImage","pos":[1713.5381320312501,-264.6858476562499],"size":[537.9034423828125,705.2806396484375],"flags":{},"order":19,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":140}],"outputs":[],"properties":{"Node name for S&R":"PreviewImage","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[]},{"id":71,"type":"MarkdownNote","pos":[1279.261094792334,651.6318783062643],"size":[427.3741705387979,420.4396672979459],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"properties":{},"widgets_values":["## Save image with metadata\n\nAvailable filename_prefix Pattern Codes\n\n- %seed% - Inserts the generation seed number\n- %width% - Inserts the image width\n- %height% - Inserts the image height\n- %pprompt:N% - Inserts the positive prompt (limited to N characters)\n- %nprompt:N% - Inserts the negative prompt (limited to N characters)\n- %model:N% - Inserts the model/checkpoint name (limited to N characters)\n- %date% - Inserts current date/time as \"yyyyMMddhhmmss\"\n- %date:FORMAT% - Inserts date using custom format with:\n - yyyy - 4-digit year\n - yy - 2-digit year\n - MM - 2-digit month\n - dd - 2-digit day\n - hh - 2-digit hour\n - mm - 2-digit minute\n - ss - 2-digit second\n\nExamples\n\n- image_%seed% → image_1234567890\n- gen_%width%x%height% → gen_512x768\n- %model:10%_%seed% → dreamshape_1234567890\n- %date:yyyy-MM-dd% → 2025-04-28\n- %pprompt:20%_%seed% → beautiful landscape_1234567890\n- %model%_%date:yyMMdd%_%seed% → dreamshaper_v8_250428_1234567890\n\nYou can combine multiple patterns to create detailed, organized filenames for your generated images."],"color":"#432","bgcolor":"#653"},{"id":60,"type":"Save Image (LoraManager)","pos":[1275.2038808593754,416.62814648437484],"size":[380.4000244140625,202],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":128},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"file_format","name":"file_format","type":"COMBO","widget":{"name":"file_format"},"link":null},{"localized_name":"lossless_webp","name":"lossless_webp","shape":7,"type":"BOOLEAN","widget":{"name":"lossless_webp"},"link":null},{"localized_name":"quality","name":"quality","shape":7,"type":"INT","widget":{"name":"quality"},"link":null},{"localized_name":"embed_workflow","name":"embed_workflow","shape":7,"type":"BOOLEAN","widget":{"name":"embed_workflow"},"link":null},{"localized_name":"save_with_metadata","name":"save_with_metadata","shape":7,"type":"BOOLEAN","widget":{"name":"save_with_metadata"},"link":null},{"localized_name":"add_counter_to_filename","name":"add_counter_to_filename","shape":7,"type":"BOOLEAN","widget":{"name":"add_counter_to_filename"},"link":null}],"outputs":[{"localized_name":"images","name":"images","type":"IMAGE","links":[]}],"properties":{"Node name for S&R":"Save Image (LoraManager)","cnr_id":"comfyui-lora-manager","ver":"f51f49eb60e1c7e524fa71c07bdea138824164e1"},"widgets_values":["ComfyUI","jpeg",false,100,false,true,true],"color":"#323","bgcolor":"#535"},{"id":74,"type":"Prompt (LoraManager)","pos":[403.28939580427357,-589.3789158346285],"size":[398.9062311540674,208.65451316663655],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":null},{"localized_name":"trigger_words1","name":"trigger_words1","shape":7,"type":"STRING","link":null},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_PROMPT,STRING","widget":{"name":"text"},"link":null},{"localized_name":"trigger_words","name":"trigger_words","shape":7,"type":"STRING","link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":null},{"localized_name":"PROMPT","name":"PROMPT","type":"STRING","links":null}],"properties":{"Node name for S&R":"Prompt (LoraManager)","__lm_widget_ids":["__lm_autocomplete_meta_text","text"]},"widgets_values":[{"version":1,"textWidgetName":"text"},""]},{"id":70,"type":"MarkdownNote","pos":[-609.5947235373926,-334.9082558764654],"size":[505.3054777679118,514.1363636363633],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[],"title":"LoRA Manager – LoRA Loader Node Usage Guide","properties":{},"widgets_values":["## Sending from LM UI to Workflow\n- **Click**: Append the selected LoRA(s) to the current LoRA Loader node. \n- **Shift + Click**: Replace the current node content with the selected LoRA(s). \n- **Color-code your target nodes**: \n If multiple valid target nodes exist, you can assign colors to them. \n LM will display these colors in the *Send to workflow* picker, making target selection easier.\n\n---\n\n## Text Input Autocomplete\n- Supports **multi-token search**, **case-insensitive**, and **token exclusion**.\n- Examples:\n - `enhance low` → matches LoRAs containing **both** “enhance” and “low”.\n - `detail -sdxl` → matches LoRAs containing “detail” but **not** “sdxl”.\n\n---\n\n## LoRA Widget Shortcuts\n### Navigation\n- **Arrow Up / Arrow Down** — Select previous / next LoRA.\n- **Ctrl/Cmd + Arrow Up** — Move selected LoRA upward.\n- **Ctrl/Cmd + Arrow Down** — Move selected LoRA downward.\n- **Ctrl/Cmd + Home** — Move selected LoRA to top.\n- **Ctrl/Cmd + End** — Move selected LoRA to bottom.\n\n### Editing & Deleting\n- **Delete / Backspace** — Remove current LoRA.\n- **Tab / Shift + Tab** — After confirming strength input, jump to next / previous editable field.\n\n---\n\nThese same features also apply to **LoRA Stacker**, **WanVideo LoRA Select**, and other LoRA Manager lora nodes. \n"],"color":"#432","bgcolor":"#653"},{"id":8,"type":"VAEDecode","pos":[1462.004865809667,9.84471397317456],"size":[210,46],"flags":{"collapsed":false},"order":17,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":7},{"localized_name":"vae","name":"vae","type":"VAE","link":143}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","slot_index":0,"links":[128,140]}],"properties":{"Node name for S&R":"VAEDecode","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[]},{"id":5,"type":"EmptyLatentImage","pos":[904.6207446270088,323.25821148560544],"size":[210,106],"flags":{"collapsed":true},"order":3,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"batch_size","name":"batch_size","type":"INT","widget":{"name":"batch_size"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","slot_index":0,"links":[2]}],"properties":{"Node name for S&R":"EmptyLatentImage","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[1024,1024,1]},{"id":73,"type":"MarkdownNote","pos":[466.1270343136322,315.36865571116505],"size":[419.2747375949979,368.826133884363],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[],"title":"Prompt Node Usage","properties":{},"widgets_values":["## Tag Autocomplete\n- **Type directly** to trigger tag autocomplete suggestions. \n Suggestions are based on **merged Danbooru + e621 tags**.\n- Use **category shortcuts** for faster searches, such as:\n - `/character` — character tags \n - `/artist` — artist tags \n - Type `/` alone to see **more categories and available commands**.\n- Use `/ac` and `/noac` to **enable or disable autocomplete**:\n - When autocomplete is **disabled**, `/` commands are still available for **category-specific tag search**.\n- Check **ComfyUI Settings** for additional autocomplete-related options.\n\n---\n\n## Embedding Search\n- Use the `/emb` command or the `emb:` prefix to search embeddings.\n- Supports **multi-token search** with **inclusion and exclusion**.\n- Examples:\n - `/emb lazy pos` → matches embeddings containing **both** `lazy` **and** `pos`.\n - `emb: lazy -neg` → matches embeddings containing `lazy` but **excluding** `neg`.\n"],"color":"#432","bgcolor":"#653"},{"id":75,"type":"Checkpoint Loader (LoraManager)","pos":[-631.0284354158929,447.72116940437536],"size":[327.960546875,98],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"ckpt_name","name":"ckpt_name","type":"COMBO","widget":{"name":"ckpt_name"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[146]},{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[147]},{"localized_name":"VAE","name":"VAE","type":"VAE","links":[148]}],"properties":{"Node name for S&R":"Checkpoint Loader (LoraManager)"},"widgets_values":["Illustrious/anime/waiIllustriousSDXL_v140.safetensors"],"color":"#233","bgcolor":"#355"},{"id":77,"type":"Unet Loader (LoraManager)","pos":[-629.521013073885,614.6529081448173],"size":[321.3446154127322,89.6620986362143],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"unet_name","name":"unet_name","type":"COMBO","widget":{"name":"unet_name"},"link":null},{"localized_name":"weight_dtype","name":"weight_dtype","type":"COMBO","widget":{"name":"weight_dtype"},"link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":null}],"properties":{"Node name for S&R":"Unet Loader (LoraManager)"},"widgets_values":["Qwen/qwenImageEdit_qwenImgEditFp8E4m3fn.safetensors","default"],"color":"#233","bgcolor":"#355"},{"id":72,"type":"MarkdownNote","pos":[-76.81724129033134,560.7435438197762],"size":[412.2107438016527,119.40082644628092],"flags":{},"order":7,"mode":0,"inputs":[],"outputs":[],"title":"TriggerWord Toggle Node Usage","properties":{},"widgets_values":["## TriggerWord Toggle Node Usage\n\n- When a LoRA is selected in a connected LoRA Loader/Stacker node, \n the **corresponding trigger words** in the TriggerWord Toggle node will be **highlighted automatically**, \n making it easy to see which trigger words belong to the selected LoRA.\n"],"color":"#432","bgcolor":"#653"},{"id":76,"type":"MarkdownNote","pos":[-630.0201675769378,775.9108880568566],"size":[412.2107438016527,119.40082644628092],"flags":{},"order":8,"mode":0,"inputs":[],"outputs":[],"title":"Checkpoint / Unet Loader Node Usage","properties":{},"widgets_values":["## Checkpoint / Unet Loader Node Usage\n- Works exactly like the built in **Load Checkpoint** and **Load Diffusion Model** nodes, but can load from LoRA Manager exclusive extra folder paths.\n- The **UNet Loader** node from LoRA Manager can also load GGUF models. The **ComfyUI-GGUF** custom node must be installed to enable this.\n"],"color":"#432","bgcolor":"#653"},{"id":55,"type":"TriggerWord Toggle (LoraManager)","pos":[-80.30650479770253,252.03850016031464],"size":[415.05371900826435,284],"flags":{"collapsed":false},"order":13,"mode":0,"inputs":[{"localized_name":"group_mode","name":"group_mode","type":"BOOLEAN","widget":{"name":"group_mode"},"link":null},{"localized_name":"default_active","name":"default_active","type":"BOOLEAN","widget":{"name":"default_active"},"link":null},{"localized_name":"allow_strength_adjustment","name":"allow_strength_adjustment","type":"BOOLEAN","widget":{"name":"allow_strength_adjustment"},"link":null},{"name":"trigger_words","shape":7,"type":"string","link":123}],"outputs":[{"localized_name":"filtered_trigger_words","name":"filtered_trigger_words","type":"STRING","links":[149]}],"properties":{"Node name for S&R":"TriggerWord Toggle (LoraManager)","cnr_id":"comfyui-lora-manager","ver":"ad56cafd62e42e67f282a967627f26b8fa6ce00a"},"widgets_values":[true,[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],false,[{"text":"masterpiece, best quality, very aesthetic, absurdres","active":[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],"strength":null,"highlighted":false},{"text":"69yottea_style_illu","active":[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],"strength":null,"highlighted":false},{"text":"7481llu","active":[{"text":"createconcept","active":true},{"text":"DS-Illu","active":true}],"strength":null,"highlighted":false}],"masterpiece, best quality, very aesthetic, absurdres,, 69yottea_style_illu,, 7481llu"],"color":"#323","bgcolor":"#535"},{"id":78,"type":"Prompt (LoraManager)","pos":[458.47823804087926,-172.43375605957237],"size":[428.81081321022725,195.58589311079544],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":150},{"localized_name":"trigger_words1","name":"trigger_words1","shape":7,"type":"STRING","link":149},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_PROMPT,STRING","widget":{"name":"text"},"link":null},{"name":"trigger_words2","type":"STRING","link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[151]},{"localized_name":"PROMPT","name":"PROMPT","type":"STRING","links":null}],"properties":{"Node name for S&R":"Prompt (LoraManager)","__lm_widget_ids":["__lm_autocomplete_meta_text","text"]},"widgets_values":[{"version":1,"textWidgetName":"text"},"adult,\n1woman, volumetric lighting, ambient occlusion, luminescent background, masterpiece, best quality, absurdres,masterpiece, best quality, very awa, absurdres,,mage,dynamic pose,dynamic angle,upper body focus, floating hair,impressionism, excellent depth of field, partly realistic texture, dramatic lighting, sharp focus, newest, absurdres, highres, very aesthetic, masterpiece, eye-catching, beautiful body, detailed skin features, beautiful eye details, bright colors, vivid colors, extreme contrast, foreshortening, high resolution, best quality, ultra high definition, extremely high detail, wide angle, cinematic field of view, perfect composition,\nBREAK\nelf,blonde hair,long hair,braid,pointy ears, green eyes, choker,capelet, dress,belt,pouch,staff,holding staff,\nmasterpiece, best quality, very aesthetic, absurdres..."],"color":"#232","bgcolor":"#353"},{"id":56,"type":"Lora Loader (LoraManager)","pos":[-80.30650479770253,-261.59171061870467],"size":[423.7818298339844,432],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":146},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_LORAS","widget":{"name":"text"},"link":null},{"name":"clip","shape":7,"type":"CLIP","link":147},{"name":"lora_stack","shape":7,"type":"LORA_STACK","link":null}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[144]},{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[150,152]},{"localized_name":"trigger_words","name":"trigger_words","type":"STRING","links":[123]},{"localized_name":"loaded_loras","name":"loaded_loras","type":"STRING","links":null}],"properties":{"Node name for S&R":"Lora Loader (LoraManager)","cnr_id":"comfyui-lora-manager","ver":"ad56cafd62e42e67f282a967627f26b8fa6ce00a","__lm_widget_ids":["__lm_autocomplete_meta_text","text","loras"]},"widgets_values":[{"version":1,"textWidgetName":"text"}," ",[{"name":"illustrious_all_rated_v1","strength":0.6,"active":true,"expanded":false,"clipStrength":0.6,"locked":false},{"name":"69yottea_illu_v2","strength":0.4,"active":true,"expanded":false,"clipStrength":0.4,"locked":false},{"name":"748cm_illu","strength":0.6,"active":true,"expanded":false,"clipStrength":0.6,"locked":false},{"name":"ppw_v7_Animv4","strength":0.6,"active":true,"expanded":false,"clipStrength":0.6,"locked":false}]],"color":"#323","bgcolor":"#535"},{"id":3,"type":"KSampler","pos":[1116.852600902062,-4.25493111593072],"size":[315,262],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":145},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":151},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":153},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":2},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"cfg","name":"cfg","type":"FLOAT","widget":{"name":"cfg"},"link":null},{"localized_name":"sampler_name","name":"sampler_name","type":"COMBO","widget":{"name":"sampler_name"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"denoise","name":"denoise","type":"FLOAT","widget":{"name":"denoise"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","slot_index":0,"links":[7]}],"properties":{"Node name for S&R":"KSampler","cnr_id":"comfy-core","ver":"0.3.18"},"widgets_values":[42,"fixed",30,7,"euler_ancestral","karras",1]},{"id":79,"type":"Prompt (LoraManager)","pos":[461.615667018153,74.56083123179819],"size":[423.9230069247159,198.89166814630676],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":152},{"localized_name":"trigger_words1","name":"trigger_words1","shape":7,"type":"STRING","link":null},{"localized_name":"text","name":"text","type":"AUTOCOMPLETE_TEXT_PROMPT,STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[153]},{"localized_name":"PROMPT","name":"PROMPT","type":"STRING","links":null}],"properties":{"Node name for S&R":"Prompt (LoraManager)","__lm_widget_ids":["__lm_autocomplete_meta_text","text"]},"widgets_values":[{"version":1,"textWidgetName":"text"},"embedding:lazyneg, lowres,bad anatomy,blurry,(worst quality:1.8),low quality,hands bad,(normal quality:1.3),bad hands,mutated hands and fingers,extra legs,extra arms,duplicate,cropped,jpeg,artifacts,long body,multiple breasts,mutated,disfigured,bad proportions,bad feet,ugly,text font ui,missing limb,monochrome,face bad, crown, tiara, jewelry, earring,pubes,pubic hair, censored,black bars, four legs,ugly hands,big earring,hoop earring,sleeves,collar,glasses, extra fingers,sunglasses, (hat:1.3),multiple hands..."],"color":"#322","bgcolor":"#533"}],"links":[[2,5,0,3,3,"LATENT"],[7,3,0,8,0,"LATENT"],[123,56,2,55,3,"string"],[128,8,0,60,0,"IMAGE"],[140,8,0,14,0,"IMAGE"],[142,67,0,68,0,"*"],[143,68,0,8,1,"VAE"],[144,56,0,69,0,"*"],[145,69,0,3,0,"MODEL"],[146,75,0,56,0,"MODEL"],[147,75,1,56,2,"CLIP"],[148,75,2,67,0,"VAE"],[149,55,0,78,1,"STRING"],[150,56,1,78,0,"CLIP"],[151,78,0,3,1,"CONDITIONING"],[152,56,1,79,0,"CLIP"],[153,79,0,3,2,"CONDITIONING"]],"groups":[],"config":{},"extra":{"ds":{"scale":1.1000000000000003,"offset":[142.00898896551203,398.3750291419585]},"frontendVersion":"1.16.8","VHS_latentpreview":false,"VHS_latentpreviewrate":0,"VHS_MetadataImage":true,"VHS_KeepIntermediate":true},"version":0.4} diff --git a/py/nodes/prompt.py b/py/nodes/prompt.py index f6154637..1d2ae8c4 100644 --- a/py/nodes/prompt.py +++ b/py/nodes/prompt.py @@ -71,8 +71,8 @@ class PromptLM: "AUTOCOMPLETE_TEXT_PROMPT,STRING", { "widgetType": "AUTOCOMPLETE_TEXT_PROMPT", - "placeholder": "Enter prompt... /char, /artist, /wild for quick search", - "tooltip": "The text to be encoded. Wildcard references inserted with /wild are expanded at runtime.", + "placeholder": "Enter prompt... /character, /artist, /wildcard for quick search", + "tooltip": "The text to be encoded. Wildcard references inserted with /wildcard are expanded at runtime.", }, ), "clip": ( diff --git a/py/nodes/text.py b/py/nodes/text.py index 2a2fa87e..6b044bdd 100644 --- a/py/nodes/text.py +++ b/py/nodes/text.py @@ -20,8 +20,8 @@ class TextLM: "AUTOCOMPLETE_TEXT_PROMPT,STRING", { "widgetType": "AUTOCOMPLETE_TEXT_PROMPT", - "placeholder": "Enter text... /char, /artist, /wild for quick search", - "tooltip": "The text output. Wildcard references inserted with /wild are expanded at runtime.", + "placeholder": "Enter text... /character, /artist, /wildcard for quick search", + "tooltip": "The text output. Wildcard references inserted with /wildcard are expanded at runtime.", }, ), }, diff --git a/tests/frontend/components/autocomplete.behavior.test.js b/tests/frontend/components/autocomplete.behavior.test.js index e4a2a1eb..0d0ebf94 100644 --- a/tests/frontend/components/autocomplete.behavior.test.js +++ b/tests/frontend/components/autocomplete.behavior.test.js @@ -286,7 +286,6 @@ describe('AutoComplete widget interactions', () => { const commandNames = autoComplete.items.map((item) => item.command); expect(commandNames).toContain('/character'); - expect(commandNames).toContain('/char'); expect(commandNames).toContain('/artist'); expect(commandNames).toContain('/general'); expect(commandNames).toContain('/copyright'); @@ -295,7 +294,6 @@ describe('AutoComplete widget interactions', () => { expect(commandNames).toContain('/lore'); expect(commandNames).toContain('/emb'); expect(commandNames).toContain('/embedding'); - expect(commandNames).toContain('/wild'); expect(commandNames).toContain('/wildcard'); }); @@ -817,12 +815,12 @@ describe('AutoComplete widget interactions', () => { json: () => Promise.resolve({ success: true, words: mockTags }), }); - // Simulate "/char looking to the side" input - caretHelperInstance.getBeforeCursor.mockReturnValue('/char looking to the side'); + // Simulate "/character looking to the side" input + caretHelperInstance.getBeforeCursor.mockReturnValue('/character looking to the side'); caretHelperInstance.getCursorOffset.mockReturnValue({ left: 15, top: 25 }); const input = document.createElement('textarea'); - input.value = '/char looking to the side'; + input.value = '/character looking to the side'; input.selectionStart = input.value.length; input.focus = vi.fn(); input.setSelectionRange = vi.fn(); @@ -840,7 +838,7 @@ describe('AutoComplete widget interactions', () => { autoComplete.activeCommand = { categories: [4, 11], label: 'Character' }; autoComplete.items = mockTags; autoComplete.selectedIndex = 0; - autoComplete.currentSearchTerm = '/char looking to the side'; + autoComplete.currentSearchTerm = '/character looking to the side'; await autoComplete.insertSelection('looking_to_the_side'); @@ -1147,18 +1145,18 @@ describe('AutoComplete widget interactions', () => { expect(fetchApiMock).toHaveBeenCalledWith('/lm/custom-words/search?enriched=true&search=cat&limit=100'); }); - it('searches wildcard keys when using the /wild command', async () => { + it('searches wildcard keys when using the /wildcard command', async () => { vi.useFakeTimers(); fetchApiMock.mockResolvedValue({ json: () => Promise.resolve({ success: true, words: ['animals/cat'] }), }); - caretHelperInstance.getBeforeCursor.mockReturnValue('/wild cat'); + caretHelperInstance.getBeforeCursor.mockReturnValue('/wildcard cat'); caretHelperInstance.getCursorOffset.mockReturnValue({ left: 15, top: 25 }); const input = document.createElement('textarea'); - input.value = '/wild cat'; + input.value = '/wildcard cat'; input.selectionStart = input.value.length; document.body.append(input); @@ -1179,11 +1177,11 @@ describe('AutoComplete widget interactions', () => { expect(autoComplete.items).toEqual(['animals/cat']); }); - it('inserts wildcard references when accepting a /wild result', async () => { - caretHelperInstance.getBeforeCursor.mockReturnValue('/wild animals/cat'); + it('inserts wildcard references when accepting a /wildcard result', async () => { + caretHelperInstance.getBeforeCursor.mockReturnValue('/wildcard animals/cat'); const input = document.createElement('textarea'); - input.value = '/wild animals/cat'; + input.value = '/wildcard animals/cat'; input.selectionStart = input.value.length; input.focus = vi.fn(); input.setSelectionRange = vi.fn(); diff --git a/web/comfyui/autocomplete.js b/web/comfyui/autocomplete.js index b66074ec..ff49573d 100644 --- a/web/comfyui/autocomplete.js +++ b/web/comfyui/autocomplete.js @@ -19,7 +19,6 @@ import { showToast } from "./utils.js"; // Command definitions for category filtering const TAG_COMMANDS = { '/character': { categories: [4, 11], label: 'Character' }, - '/char': { categories: [4, 11], label: 'Character' }, '/artist': { categories: [1, 8], label: 'Artist' }, '/general': { categories: [0, 7], label: 'General' }, '/copyright': { categories: [3, 10], label: 'Copyright' }, @@ -1270,7 +1269,7 @@ class AutoComplete { }; } - // Command with search term (e.g., "/char miku") + // Command with search term (e.g., "/character miku") const commandPart = trimmed.slice(0, spaceIndex).toLowerCase(); const searchPart = trimmed.slice(spaceIndex + 1).trim(); @@ -1417,7 +1416,7 @@ class AutoComplete { /** * Insert a command into the input - * @param {string} command - The command to insert (e.g., "/char") + * @param {string} command - The command to insert (e.g., "/character") */ _insertCommand(command) { const currentValue = this.inputElement.value; @@ -2310,7 +2309,7 @@ class AutoComplete { // This allows "hello 1gi" + selecting "1girl" to become "hello 1girl, " // However, if the user typed a multi-word phrase that matches a tag (e.g., "looking to the side" // matching "looking_to_the_side"), replace the entire phrase instead of just the last word. - // Command mode (e.g., "/char miku") should replace the entire command+search + // Command mode (e.g., "/character miku") should replace the entire command+search let searchTerm = fullSearchTerm; if (this.modelType === 'prompt' && this.searchType === 'custom_words' && !this.activeCommand) { // Check if the selectedItem exists and its tag_name matches the full search term diff --git a/web/comfyui/autocomplete_wildcards.js b/web/comfyui/autocomplete_wildcards.js index 3e32a9ec..78b796e0 100644 --- a/web/comfyui/autocomplete_wildcards.js +++ b/web/comfyui/autocomplete_wildcards.js @@ -1,5 +1,4 @@ export const WILDCARD_COMMANDS = { - '/wild': { type: 'wildcard', label: 'Wildcards' }, '/wildcard': { type: 'wildcard', label: 'Wildcards' }, };