Comfy-Org / ComfyUI_frontend

Official front-end implementation of ComfyUI
https://www.comfy.org/
GNU General Public License v3.0
449 stars 54 forks source link

[Feature Request]: hide the ".safetensors" file extension from nodes #527

Open ardri1166 opened 1 month ago

ardri1166 commented 1 month ago

Is there an existing issue for this?

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: image

And this is what I need to do to read the whole name: image

Proposed workflow

  1. Load any model (checkpoint, lora, upscaler etc.).
  2. 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

mcmonkey4eva commented 1 month ago

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)

hartmark commented 1 month ago

Nice suggestion, perhaps hide extension for all and have a hoover with the full name to keep consistent

ardri1166 commented 1 month ago

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

doctorpangloss commented 3 weeks ago

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.

pluberd commented 2 weeks ago

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.

pluberd commented 2 weeks ago

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.

pluberd commented 2 weeks ago

I dug a little further. My hack looks like this. It depends on two API queries.

1) "/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

2) "/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:

1)

...
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

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)
pluberd commented 2 weeks ago

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.