[Feature Request]: hide the ".safetensors" file extension from nodes
Opened this issue · 9 comments
Is there an existing issue for this?
- I have searched the existing issues and checked the recent builds/commits
What would your feature do ?
Since the file extension ".safetensors" is so long, is it possible to hide the file extensions in all the nodes like Windows Explorer does? This would increase the general overview on smaller monitors as you can make the nodes smaller without loosing the model name. For reference I use a 27" screen and don't have the sharpest vision which means I need to crank up the zoom a bit in order to be able to read text properly and I'm probably not the only one.
This is how my the checkpoint loader looks with the nodes nicely aligned:
And this is what I need to do to read the whole name:
Proposed workflow
- Load any model (checkpoint, lora, upscaler etc.).
- Only display the name of the file without the ".safetensors" extension or any other file extension for that matter (though others are not as long and don't foul up the display so much).
Additional information
No response
I do support this idea myself, I did this same thing in Swarm a couple months ago for the same reason (only for .safetensors
specifically, everything else renders as normal)
Nice suggestion, perhaps hide extension for all and have a hoover with the full name to keep consistent
Nice suggestion, perhaps hide extension for all and have a hoover with the full name to keep consistent
Thanks but I can't take all the credit. There was an "idea" which someone popped in back in October last year but nobody looked at it until I replied yesterday. Then it was closed and we were asked to put in a request - which I did now lol
all the enum-like or list nodes need to be gracefully "upgraded to work like
old behavior:
["checkpoint1.safetensors", "checkpoint2.safetensors"]
additionally supported behavior:
[{value: "checkpoint1.safetensors", text: "checkpoint1", {value: "checkpoint2.safetensors", text: "checkpoint2"}]
additionally supported behavior:
[{value: "checkpoint1.safetensors", html: "<span>checkpoint1</span>", {value: "checkpoint2.safetensors", html: "<span>checkpoint2</span>"}]
where text is sanitized and put directly into the label, whereas html is dangerously setting inner html for the dropdown element.
imo it is painful that python doesn't have a built-in JSON serialization for enums and similar.
I wasn't aware that the frontend was outsourced to a separate project. The question is how to achieve the desired behavior as quickly as possible. Without having looked at it in more detail, I suspect that the frontend queries the backend (ComfyUI) via API for a list of models, which are then displayed as a selection in the node. So I can well imagine that you can get to the goal more quickly in the code from the backend.
I looked at the protocol between the frontend and the backend using Firefox. It works like this: when the frontend is loaded, a query is made:
http://127.0.0.1:8188/object_info
If you search in the response, you will find a list of model names in many places, specifically in all nodes that have a model to choose from.
These exact names are then sent as a request (post) in a "queue prompt".
In my opinion, you just have to find the corresponding place in the server code (server.py) and build a mapping there. It will probably be a lot of work to find the right place, but the change should then be manageable.
I dug a little further. My hack looks like this. It depends on two API queries.
-
"/object_info" provides information about the server and it contains the file names for the models. Here I replace the string ".safetensors" with ".sft" in the server response
-
"/prompt" is used by the frontend to send a request. Here I replace every string ".sft" with ".safetensors"
That's the idea. There could of course be side effects because ".safetensors" or ".sft" are used for other purposes. I have to take that risk.
Both adjustments can be made in server.py:
...
import comfy.utils
import comfy.model_management
from app.user_manager import UserManager
# SFT-HACK-BEGIN
def sft_hack(data, s1, s2):
if isinstance(data, dict):
for key, value in data.items():
data[key] = sft_hack(value,s1,s2)
elif isinstance(data, list):
data = [sft_hack(item,s1,s2) for item in data]
elif isinstance(data, tuple):
data = tuple([sft_hack(item,s1,s2) for item in data])
elif isinstance(data, str):
return data.replace(s1,s2)
return data
# SFT-HACK-END
class BinaryEventTypes:
PREVIEW_IMAGE = 1
UNENCODED_PREVIEW_IMAGE = 2
...
@routes.get("/object_info")
async def get_object_info(request):
out = {}
for x in nodes.NODE_CLASS_MAPPINGS:
try:
out[x] = node_info(x)
except Exception as e:
logging.error(f"[ERROR] An error occurred while retrieving information for the '{x}' node.")
logging.error(traceback.format_exc())
# SFT-HACK-BEGIN
out = sft_hack(out, '.safetensors', '.sft')
# SFT-HACK-END
return web.json_response(out)
@routes.get("/object_info/{node_class}")
async def get_object_info_node(request):
```...
3) 4 times
...
json_data = await request.json()
# SFT-HACK-BEGIN
json_data = sft_hack(json_data, '.sft', '.safetensors')
# SFT-HACK-BEGIN
Works in the first view. ".safetensors" is replaced by ".sft" in the GUI.
![sft_hack](https://github.com/user-attachments/assets/e86bc473-0c7c-4f95-8385-0fe4dceac974)
When you save an image, the embedded workflow contains all the labels as the server sees them, i.e. the original names. If you save a workflow directly via the frontend, the labels are included as they are in the frontend.
The new model library sidebar view hides the .safetensors
extension