From 1f6eee54f5ceb2b8c6d642639bb8b7ac7f81e2d9 Mon Sep 17 00:00:00 2001 From: John Mull Date: Wed, 22 Jan 2025 16:21:18 +0000 Subject: [PATCH 01/62] add devcontainer and example workflows --- .devcontainer/Dockerfile | 3 + .devcontainer/Dockerfile.base | 109 +++ .devcontainer/README.md | 92 +++ .devcontainer/devcontainer.json | 41 + .devcontainer/extra_model_paths.yaml | 19 + .devcontainer/post-create.sh | 23 + workflows/ui/1 - Build ONNX.json | 94 +++ .../ui/2 - Build Static TensorRT Engine.json | 154 ++++ .../ui/3 - SD 1.5 TensorRT workflow.json | 757 ++++++++++++++++++ 9 files changed, 1292 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/Dockerfile.base create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/extra_model_paths.yaml create mode 100755 .devcontainer/post-create.sh create mode 100644 workflows/ui/1 - Build ONNX.json create mode 100644 workflows/ui/2 - Build Static TensorRT Engine.json create mode 100644 workflows/ui/3 - SD 1.5 TensorRT workflow.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..63d6001e --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,3 @@ +FROM eliteencoder/comfyui-base +ENV PATH="/miniconda3/bin:${PATH}" + diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base new file mode 100644 index 00000000..21d346c3 --- /dev/null +++ b/.devcontainer/Dockerfile.base @@ -0,0 +1,109 @@ +FROM runpod/pytorch:2.4.0-py3.11-cuda12.4.1-devel-ubuntu22.04 + +# 1. Install system dependencies +RUN apt-get update && apt-get install -y \ + git \ + wget \ + nano \ + socat \ + && rm -rf /var/lib/apt/lists/* + +# 2. Install Miniconda (optional, if you want it ready at build-time) +RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/miniconda.sh \ + && bash /tmp/miniconda.sh -b -p /miniconda3 \ + && rm /tmp/miniconda.sh + +ENV PATH="/miniconda3/bin:${PATH}" +RUN eval "$(/miniconda3/bin/conda shell.bash hook)" +RUN conda create -n comfyui python=3.11 -y +COPY . /app + +RUN source activate comfyui && git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI && \ +cd /ComfyUI && /miniconda3/envs/comfyui/bin/pip install -r requirements.txt +COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples +COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils +WORKDIR / + +# Clone ComfyUI Repo to /ComfyUI +RUN source activate comfyui && cd /ComfyUI/custom_nodes && \ + # Ryan's nodes + git clone https://github.com/pschroedl/ComfyUI_RyanOnTheInside.git && \ + cd ComfyUI_RyanOnTheInside && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + git clone https://github.com/ltdrdata/ComfyUI-Manager.git && \ + cd ComfyUI-Manager && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + git clone https://github.com/tsogzark/ComfyUI-load-image-from-url.git && \ + git clone https://github.com/ryanontheinside/ComfyUI-Misc-Effects.git && \ + git clone https://github.com/ryanontheinside/ComfyUI_RealTimeNodes.git && \ + cd ComfyUI_RealTimeNodes && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + # Utility nodes + git clone https://github.com/rgthree/rgthree-comfy.git && \ + cd rgthree-comfy && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + git clone https://github.com/kijai/ComfyUI-KJNodes.git && \ + cd ComfyUI-KJNodes && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + # Vision and AI nodes + git clone https://github.com/ad-astra-video/ComfyUI-Florence2-Vision.git && \ + cd ComfyUI-Florence2-Vision && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + git clone https://github.com/pschroedl/ComfyUI-SAM2-Realtime.git && \ + cd ComfyUI-SAM2-Realtime && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + # Core TensorRT nodes + git clone -b quantization_with_controlnet_fixes https://github.com/yondonfu/ComfyUI_TensorRT && \ + cd ComfyUI_TensorRT && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + git clone https://github.com/yondonfu/ComfyUI-Torch-Compile && \ + cd ComfyUI-Torch-Compile && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ + cd .. && \ + # Utility nodes + git clone https://github.com/yuvraj108c/ComfyUI-Depth-Anything-Tensorrt && \ + cd ComfyUI-Depth-Anything-Tensorrt && \ + /miniconda3/envs/comfyui/bin/pip install -r requirements.txt + +RUN conda create -n comfystream + +# Activate the comfystream environment and install dependencies +RUN bash -c "source activate comfystream && pip install /app && pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 && python /app/install.py --workspace /ComfyUI" +RUN rm -rf /app + +# Download models +WORKDIR /ComfyUI +RUN /miniconda3/envs/comfyui/bin/huggingface-cli download Livepeer-Studio/comfystream_checkpoints --local-dir models/checkpoints --include "*.safetensors" +RUN /miniconda3/envs/comfyui/bin/huggingface-cli download Livepeer-Studio/comfystream_loras --local-dir models/checkpoints --include "*.safetensors" + +#Download ControlNet models +RUN /miniconda3/envs/comfyui/bin/huggingface-cli download comfyanonymous/ControlNet-v1-1_fp16_safetensors --local-dir models/controlnet --include "control_v11f1p_sd15_depth_fp16.safetensors" +RUN /miniconda3/envs/comfyui/bin/huggingface-cli download comfyanonymous/ControlNet-v1-1_fp16_safetensors --local-dir models/controlnet --include "control_v11p_sd15_openpose_fp16.safetensors" + +# Download Dreamshaper 8 Model and DMD +RUN wget -O models/checkpoints/dreamshaper_8.safetensors https://civitai.com/api/download/models/128713 --content-disposition +RUN /miniconda3/envs/comfyui/bin/huggingface-cli download aaronb/dreamshaper-8-dmd-1kstep --local-dir models/unet --include "diffusion_pytorch_model.safetensors" +RUN mv /ComfyUI/models/unet/diffusion_pytorch_model.safetensors /ComfyUI/models/unet/dreamshaper_8_dmd_1kstep.safetensors + +# Download Depth-Anything model +RUN wget -O /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/depth_anything_vitl14.onnx https://huggingface.co/yuvraj108c/Depth-Anything-2-Onnx/resolve/main/depth_anything_v2_vitb.onnx?download=true --content-disposition +RUN mkdir -p /ComfyUI/models/tensorrt/depth-anything/ + +# Download TAESD +RUN wget -O models/vae_approx/taesd_decoder.pth https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_decoder.pth +RUN wget -O models/vae_approx/taesd_encoder.pth https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_encoder.pth + +# Set comfystream as the default environment +RUN conda config --set auto_activate_base false +RUN echo 'if [ -f "/miniconda3/etc/profile.d/conda.sh" ]; then' >> ~/.bashrc +RUN echo ' . "/miniconda3/etc/profile.d/conda.sh"' >> ~/.bashrc +RUN echo ' conda activate comfystream' >> ~/.bashrc +RUN echo 'fi' >> ~/.bashrc diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000..2f1b4f6a --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,92 @@ +# Dev Container Setup for ComfyStream + +This guide will help you set up and run a development container for ComfyStream using Visual Studio Code (VS Code). + +## Prerequisites + +- [Docker](https://www.docker.com/get-started) +- [Visual Studio Code](https://code.visualstudio.com/) +- [VS Code Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +## Building the Base Container + +To build the base container, run the following command in your terminal: + +```sh +docker build -f .devcontainer/Dockerfile.base -t comfyui-base . +``` + +## Using the Pre-built Base Container + +Most users will configure host paths for models in `devcontainer.json` and use the pre-built base container. Follow these steps: + +1. Pull the pre-built base container: + + ```sh + docker pull livepeer/comfyui-base + ``` + +2. Configure the host paths for models in the `devcontainer.json` file. + +3. Re-open the workspace in the dev container using VS Code: + - Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS). + - Select `Remote-Containers: Reopen in Container`. + +## Configuration + +Ensure your `devcontainer.json` is properly configured to map the necessary host paths for your models. Here is an example configuration: + +```json +{ + "name": "ComfyStream Dev Container", + "image": "livepeer/comfyui-base", + "mounts": [ + "source=/path/to/your/models,target=/workspace/models,type=bind" + ], + "workspaceFolder": "/workspace" +} +``` + +Replace `/path/to/your/models` with the actual path to your models on the host machine. + +## Additional Resources + +- [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers) +- [Docker Documentation](https://docs.docker.com/) + +By following these steps, you should be able to set up and run your development container for ComfyStream efficiently. +## Building the DepthAnything Engine + +1. Navigate to the DepthAnything directory: + + ```sh + cd /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/ + ``` + +2. Run the export script to build the engine and move the generated engine file to the appropriate directory: + + ```sh + python export_trt.py + mv depth_anything_vitl14-fp16.engine /ComfyUI/models/tensorrt/depth-anything/depth_anything_vitl14-fp16.engine + ``` + +By following these steps, you will have successfully built and copied the DepthAnything engine to the required location. + +3. Start ComfyUI + +When building engines, you should start ComfyUI normally. + +```sh +python main.py --listen +``` + +When running TensorRT engine enabled workflows, you should use the extra flag as shown below: +```sh +python main.py --listen --disable-cuda-malloc +``` + +4. Start ComfyStream + + ```sh + python server/app.py --workspace ../ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8889 + ``` \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..e77cf7e5 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,41 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "ComfyStream", + "build": { + "dockerfile": "Dockerfile" + }, + "runArgs": [ + "--gpus=all", + "--workdir", "/workspace" + ], + // Features to add to the dev container. More info: https://containers.dev/features. + // Configure tool-specific properties. + "customizations": { + "vscode": { + "settings": { + "python.defaultInterpreterPath": "/workspace/miniconda3/envs/comfystream/bin/python" + }, + "extensions": [ + "ms-python.python", + "ms-python.black-formatter", + "ms-python.vscode-pylance" + ] + } + }, + "appPort": [ + "8188:8188", // ComfyUI + "8889:8889", // ComfyStream + "3000:3000" // ComfyStream UI (optional) + ], + "forwardPorts": [8188, 8889, 3000], + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // Use 'mounts' to make a list of local folders available inside the container. + "workspaceFolder": "/workspace", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "mounts": [ + // Use 'mounts' to set models and environments for the container, the following targets are included in extra_model_paths.yaml + // "source=${localEnv:HOME}/ComfyUI-models,target=/ComfyUI/extra/models,type=bind,consistency=cached" + ], + "postCreateCommand": "bash .devcontainer/post-create.sh" +} diff --git a/.devcontainer/extra_model_paths.yaml b/.devcontainer/extra_model_paths.yaml new file mode 100644 index 00000000..a664a3d3 --- /dev/null +++ b/.devcontainer/extra_model_paths.yaml @@ -0,0 +1,19 @@ + +# Add your host mounted custom_nodes and model paths here +a111: + base_path: /workspace/ComfyUI + checkpoints: /extra/models/checkpoints + configs: /extra/models/configs + vae: /extra/models/vae + loras: | + /extra/models/loras + upscale_models: | + /extra/models/ESRGAN + /extra/models/RealESRGAN + /extra/models/SwinIR + embeddings: /extra/models/embeddings + hypernetworks: /extra/models/hypernetworks + controlnet: /extra/models/controlnet + +# Optional: Map local custom nodes (requires installation) +# custom_nodes: /extra/custom-nodes \ No newline at end of file diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100755 index 00000000..ebae87e4 --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Create a symlink to the extra_model_paths.yaml file only if /ComfyUI/extra/models exists and /ComfyUI/extra_model_paths.yaml does not exist, otherwise remove the link +if [ -d "/ComfyUI/extra/models" ] && [ ! -L "/ComfyUI/extra_model_paths.yaml" ]; then + ln -s /workspace/.devcontainer/extra_model_paths.yaml /ComfyUI/extra_model_paths.yaml +else + if [ -L "/ComfyUI/extra_model_paths.yaml" ]; then + rm /ComfyUI/extra_model_paths.yaml + fi +fi + +# Initialize conda if needed +if ! command -v conda &> /dev/null; then + /miniconda3/bin/conda init bash +fi + +# Create a symlink to the ComfyUI workspace +if [ ! -d "/workspace/ComfyUI" ]; then + ln -s /ComfyUI /workspace/ComfyUI +fi + +source ~/.bashrc +/bin/bash \ No newline at end of file diff --git a/workflows/ui/1 - Build ONNX.json b/workflows/ui/1 - Build ONNX.json new file mode 100644 index 00000000..7a903096 --- /dev/null +++ b/workflows/ui/1 - Build ONNX.json @@ -0,0 +1,94 @@ +{ + "last_node_id": 13, + "last_link_id": 2, + "nodes": [ + { + "id": 13, + "type": "ONNX_FP8_EXPORT", + "pos": [ + 1112.05517578125, + 378.7208557128906 + ], + "size": [ + 315, + 82 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 2 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "ONNX_FP8_EXPORT" + }, + "widgets_values": [ + "/workspace/ComfyUI/models/onnx", + "dreamshaper8_fp8.onnx" + ] + }, + { + "id": 12, + "type": "UNETLoader", + "pos": [ + 553.5215454101562, + 392.55853271484375 + ], + "size": [ + 315, + 82 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 2 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "UNETLoader" + }, + "widgets_values": [ + "dreamshaper_8_dmd_1kstep.safetensors", + "default" + ] + } + ], + "links": [ + [ + 2, + 12, + 0, + 13, + 0, + "MODEL" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 1.3310000000000004, + "offset": [ + -178.9215954852766, + -182.30203232582366 + ] + }, + "node_versions": { + "comfy-core": "0.3.10" + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/workflows/ui/2 - Build Static TensorRT Engine.json b/workflows/ui/2 - Build Static TensorRT Engine.json new file mode 100644 index 00000000..64780dba --- /dev/null +++ b/workflows/ui/2 - Build Static TensorRT Engine.json @@ -0,0 +1,154 @@ +{ + "last_node_id": 16, + "last_link_id": 4, + "nodes": [ + { + "id": 14, + "type": "UNETLoader", + "pos": [ + 582.37744140625, + 373.4616394042969 + ], + "size": [ + 315, + 82 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 3 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "UNETLoader" + }, + "widgets_values": [ + "dreamshaper_8_dmd_1kstep.safetensors", + "default" + ] + }, + { + "id": 16, + "type": "STATIC_TRT_MODEL_CONVERSION", + "pos": [ + 1378.02001953125, + 353.9273681640625 + ], + "size": [ + 340.20001220703125, + 202 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 3 + }, + { + "name": "onnx_model_path", + "type": "STRING", + "link": 4, + "widget": { + "name": "onnx_model_path" + }, + "shape": 7 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "STATIC_TRT_MODEL_CONVERSION" + }, + "widgets_values": [ + "tensorrt/static-dreamshaper8", + 1, + 512, + 512, + 1, + 14, + "" + ] + }, + { + "id": 15, + "type": "ONNXModelSelector", + "pos": [ + 588.3877563476562, + 534.2430419921875 + ], + "size": [ + 315, + 78 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "model_path", + "type": "STRING", + "links": [ + 4 + ], + "slot_index": 0 + }, + { + "name": "model_name", + "type": "STRING", + "links": null, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "ONNXModelSelector" + }, + "widgets_values": [ + "dreamshaper8_fp8.onnx" + ] + } + ], + "links": [ + [ + 3, + 14, + 0, + 16, + 0, + "MODEL" + ], + [ + 4, + 15, + 0, + 16, + 1, + "STRING" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 1.3310000000000004, + "offset": [ + -169.90581787445768, + -193.57175433934745 + ] + }, + "node_versions": { + "comfy-core": "0.3.10" + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json new file mode 100644 index 00000000..1d728962 --- /dev/null +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -0,0 +1,757 @@ +{ + "last_node_id": 22, + "last_link_id": 21, + "nodes": [ + { + "id": 5, + "type": "CLIPTextEncode", + "pos": [ + 1104, + 615 + ], + "size": [ + 400, + 200 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 2 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "the hulk" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 1104, + 891 + ], + "size": [ + 400, + 200 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 5 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "" + ] + }, + { + "id": 9, + "type": "ControlNetApplyAdvanced", + "pos": [ + 1602, + 664 + ], + "size": [ + 315, + 186 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "positive", + "type": "CONDITIONING", + "link": 4 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 5 + }, + { + "name": "control_net", + "type": "CONTROL_NET", + "link": 11 + }, + { + "name": "image", + "type": "IMAGE", + "link": 12 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "positive", + "type": "CONDITIONING", + "links": [ + 7 + ], + "slot_index": 0 + }, + { + "name": "negative", + "type": "CONDITIONING", + "links": [ + 8 + ], + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "ControlNetApplyAdvanced" + }, + "widgets_values": [ + 1, + 0, + 1 + ] + }, + { + "id": 10, + "type": "TorchCompileLoadControlNet", + "pos": [ + 1130, + 1226 + ], + "size": [ + 327.5999755859375, + 106 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "controlnet", + "type": "CONTROL_NET", + "link": 10 + } + ], + "outputs": [ + { + "name": "CONTROL_NET", + "type": "CONTROL_NET", + "links": [ + 11 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "TorchCompileLoadControlNet" + }, + "widgets_values": [ + "inductor", + false, + "reduce-overhead" + ] + }, + { + "id": 7, + "type": "KSampler", + "pos": [ + 2024, + 287 + ], + "size": [ + 315, + 262 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 9 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 7 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 8 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 17 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 14 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 577216550229772, + "randomize", + 1, + 1, + "lcm", + "normal", + 1 + ] + }, + { + "id": 15, + "type": "PreviewImage", + "pos": [ + 2878.828125, + 299.9607238769531 + ], + "size": [ + 210, + 246 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 15 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [] + }, + { + "id": 14, + "type": "VAEDecode", + "pos": [ + 2521.657470703125, + 307.1023254394531 + ], + "size": [ + 210, + 46 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 14 + }, + { + "name": "vae", + "type": "VAE", + "link": 16 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 15 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + }, + "widgets_values": [] + }, + { + "id": 13, + "type": "TorchCompileLoadVAE", + "pos": [ + 1138.843017578125, + 1457.9476318359375 + ], + "size": [ + 315, + 154 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "vae", + "type": "VAE", + "link": 13 + } + ], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 16 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "TorchCompileLoadVAE" + }, + "widgets_values": [ + "inductor", + true, + "reduce-overhead", + true, + true + ] + }, + { + "id": 16, + "type": "EmptyLatentImage", + "pos": [ + 1627, + -92 + ], + "size": [ + 315, + 106 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 17 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" + }, + "widgets_values": [ + 512, + 512, + 1 + ] + }, + { + "id": 1, + "type": "LoadImage", + "pos": [ + 803, + -123 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1 + ], + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "805cf30d101b7641.png", + "image" + ] + }, + { + "id": 2, + "type": "DepthAnythingTensorrt", + "pos": [ + 1238, + 77 + ], + "size": [ + 315, + 58 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 1 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 12 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "DepthAnythingTensorrt" + }, + "widgets_values": [ + "depth_anything_vitl14-fp16.engine" + ] + }, + { + "id": 3, + "type": "TensorRTLoader", + "pos": [ + 642, + 396 + ], + "size": [ + 315, + 82 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "TensorRTLoader" + }, + "widgets_values": [ + "dreamshaper_$dyn-b-1-1-1-h-512-512-512-w-512-512-512_00001_.engine", + "SD15" + ] + }, + { + "id": 8, + "type": "ControlNetLoader", + "pos": [ + 650, + 1244 + ], + "size": [ + 315, + 58 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "CONTROL_NET", + "type": "CONTROL_NET", + "links": [ + 10 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ControlNetLoader" + }, + "widgets_values": [ + "control_v11f1p_sd15_depth_fp16.safetensors" + ] + }, + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + 648, + 771 + ], + "size": [ + 315, + 98 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": null + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 2, + 3 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": null + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "dreamshaper_8.safetensors" + ] + }, + { + "id": 11, + "type": "VAELoader", + "pos": [ + 649, + 1498 + ], + "size": [ + 315, + 58 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 13 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAELoader" + }, + "widgets_values": [ + "taesd" + ] + } + ], + "links": [ + [ + 1, + 1, + 0, + 2, + 0, + "IMAGE" + ], + [ + 2, + 4, + 1, + 5, + 0, + "CLIP" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 5, + 0, + 9, + 0, + "CONDITIONING" + ], + [ + 5, + 6, + 0, + 9, + 1, + "CONDITIONING" + ], + [ + 7, + 9, + 0, + 7, + 1, + "CONDITIONING" + ], + [ + 8, + 9, + 1, + 7, + 2, + "CONDITIONING" + ], + [ + 9, + 3, + 0, + 7, + 0, + "MODEL" + ], + [ + 10, + 8, + 0, + 10, + 0, + "CONTROL_NET" + ], + [ + 11, + 10, + 0, + 9, + 2, + "CONTROL_NET" + ], + [ + 12, + 2, + 0, + 9, + 3, + "IMAGE" + ], + [ + 13, + 11, + 0, + 13, + 0, + "VAE" + ], + [ + 14, + 7, + 0, + 14, + 0, + "LATENT" + ], + [ + 15, + 14, + 0, + 15, + 0, + "IMAGE" + ], + [ + 16, + 13, + 0, + 14, + 1, + "VAE" + ], + [ + 17, + 16, + 0, + 7, + 3, + "LATENT" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 0.6830134553650707, + "offset": [ + 82.14661719380388, + 3.8953213027115225 + ] + }, + "node_versions": { + "comfy-core": "0.3.10", + "ComfyUI-Torch-Compile": "28b36d2569b39c303b2d9b0e5540ec5d628164af", + "ComfyUI-Depth-Anything-Tensorrt": "ede57bac05059731f955c1b1563af2c1947f999a" + } + }, + "version": 0.4 +} \ No newline at end of file From 499a196fff37abf5ccd784f88ca82a91758b940c Mon Sep 17 00:00:00 2001 From: John Mull Date: Wed, 22 Jan 2025 17:57:37 +0000 Subject: [PATCH 02/62] doc improvement --- .devcontainer/Dockerfile | 2 +- .devcontainer/README.md | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 63d6001e..5ec21d92 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,3 +1,3 @@ -FROM eliteencoder/comfyui-base +FROM eliteencoder/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 2f1b4f6a..58034539 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -13,7 +13,7 @@ This guide will help you set up and run a development container for ComfyStream To build the base container, run the following command in your terminal: ```sh -docker build -f .devcontainer/Dockerfile.base -t comfyui-base . +docker build -f .devcontainer/Dockerfile.base -t eliteencoder/comfyui-base:latest . ``` ## Using the Pre-built Base Container @@ -22,9 +22,9 @@ Most users will configure host paths for models in `devcontainer.json` and use t 1. Pull the pre-built base container: - ```sh - docker pull livepeer/comfyui-base - ``` +```sh +docker pull eliteencoder/comfyui-base:latest +``` 2. Configure the host paths for models in the `devcontainer.json` file. @@ -59,20 +59,20 @@ By following these steps, you should be able to set up and run your development 1. Navigate to the DepthAnything directory: - ```sh - cd /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/ - ``` +```sh +cd /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/ +``` 2. Run the export script to build the engine and move the generated engine file to the appropriate directory: - ```sh - python export_trt.py - mv depth_anything_vitl14-fp16.engine /ComfyUI/models/tensorrt/depth-anything/depth_anything_vitl14-fp16.engine - ``` +```sh +python export_trt.py +mv depth_anything_vitl14-fp16.engine /ComfyUI/models/tensorrt/depth-anything/depth_anything_vitl14-fp16.engine +``` By following these steps, you will have successfully built and copied the DepthAnything engine to the required location. -3. Start ComfyUI +### Starting ComfyUI When building engines, you should start ComfyUI normally. @@ -85,8 +85,8 @@ When running TensorRT engine enabled workflows, you should use the extra flag as python main.py --listen --disable-cuda-malloc ``` -4. Start ComfyStream +### Starting ComfyStream - ```sh - python server/app.py --workspace ../ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8889 - ``` \ No newline at end of file +```sh +python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8889 +``` \ No newline at end of file From ec1e525ef23aa782b78cd0cc944fd78eaad235de Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Wed, 22 Jan 2025 16:15:32 -0500 Subject: [PATCH 03/62] add node+model setup scripts and configs --- configs/models.yaml | 26 +++++ configs/nodes.yaml | 71 ++++++++++++++ src/comfystream/scripts/README.md | 119 +++++++++++++++++++++++ src/comfystream/scripts/__init__.py | 1 + src/comfystream/scripts/requirements.txt | 3 + src/comfystream/scripts/setup_models.py | 104 ++++++++++++++++++++ src/comfystream/scripts/setup_nodes.py | 93 ++++++++++++++++++ src/comfystream/scripts/utils.py | 22 +++++ 8 files changed, 439 insertions(+) create mode 100644 configs/models.yaml create mode 100644 configs/nodes.yaml create mode 100644 src/comfystream/scripts/README.md create mode 100644 src/comfystream/scripts/__init__.py create mode 100644 src/comfystream/scripts/requirements.txt create mode 100644 src/comfystream/scripts/setup_models.py create mode 100755 src/comfystream/scripts/setup_nodes.py create mode 100644 src/comfystream/scripts/utils.py diff --git a/configs/models.yaml b/configs/models.yaml new file mode 100644 index 00000000..c55230ee --- /dev/null +++ b/configs/models.yaml @@ -0,0 +1,26 @@ +models: + # Base models + dreamshaper-v8: + name: "Dreamshaper v8" + url: "https://civitai.com/api/download/models/128713?type=Model&format=SafeTensor&size=pruned&fp=fp16" + path: "checkpoints/SD1.5/dreamshaper-8.safetensors" + type: "checkpoint" + + # DMD models + dreamshaper-dmd: + name: "Dreamshaper DMD" + url: "https://huggingface.co/aaronb/dreamshaper-8-dmd-1kstep/resolve/main/diffusion_pytorch_model.safetensors" + path: "unet/dreamshaper-8-dmd-1kstep.safetensors" + type: "unet" + extra_files: + - url: "https://huggingface.co/aaronb/dreamshaper-8-dmd-1kstep/raw/main/config.json" + path: "unet/dreamshaper-8-dmd-1kstep.json" + + + + # ControlNet models + controlnet-depth: + name: "ControlNet Depth" + url: "https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors" + path: "controlnet/control_v11f1p_sd15_depth_fp16.safetensors" + type: "controlnet" \ No newline at end of file diff --git a/configs/nodes.yaml b/configs/nodes.yaml new file mode 100644 index 00000000..0e0237fb --- /dev/null +++ b/configs/nodes.yaml @@ -0,0 +1,71 @@ +nodes: + # Core TensorRT nodes + comfyui-tensorrt: + name: "ComfyUI TensorRT" + url: "https://github.com/yondonfu/ComfyUI_TensorRT" + branch: "quantization_with_controlnet_fixes" + type: "tensorrt" + + comfyui-depthanything-tensorrt: + name: "ComfyUI DepthAnything TensorRT" + url: "https://github.com/yuvraj108c/ComfyUI-Depth-Anything-Tensorrt" + type: "tensorrt" + + # Ryan's nodes + comfyui-ryanontheinside: + name: "ComfyUI RyanOnTheInside" + url: "https://github.com/pschroedl/ComfyUI_RyanOnTheInside.git" + type: "utility" + + comfyui-manager: + name: "ComfyUI Manager" + url: "https://github.com/ltdrdata/ComfyUI-Manager.git" + type: "utility" + + comfyui-misc-effects: + name: "ComfyUI Misc Effects" + url: "https://github.com/ryanontheinside/ComfyUI-Misc-Effects.git" + type: "effects" + + comfyui-realtimenode: + name: "ComfyUI RealTimeNodes" + url: "https://github.com/ryanontheinside/ComfyUI_RealTimeNodes.git" + type: "realtime" + dependencies: + - "opencv-python" + + comfyui-florence2-vision: + name: "ComfyUI Florence2 Vision" + url: "https://github.com/ad-astra-video/ComfyUI-Florence2-Vision.git" + type: "vision" + + comfyui-sam2-realtime: + name: "ComfyUI SAM2 Realtime" + branch: "main" + url: "https://github.com/pschroedl/ComfyUI-SAM2-Realtime.git" + type: "vision" + + comfyui-liveportraitkj: + name: "ComfyUI LivePortraitKJ" + url: "https://github.com/kijai/ComfyUI-LivePortraitKJ.git" + type: "portrait" + + comfyui-load-image-url: + name: "ComfyUI Load Image from URL" + url: "https://github.com/tsogzark/ComfyUI-load-image-from-url.git" + type: "utility" + + comfyui-torch-compile: + name: "ComfyUI Torch Compile" + url: "https://github.com/yondonfu/ComfyUI-Torch-Compile" + type: "optimization" + + rgthree-comfy: + name: "rgthree Comfy" + url: "https://github.com/rgthree/rgthree-comfy.git" + type: "utility" + + comfyui-kjnodes: + name: "ComfyUI KJNodes" + url: "https://github.com/kijai/ComfyUI-KJNodes.git" + type: "utility" \ No newline at end of file diff --git a/src/comfystream/scripts/README.md b/src/comfystream/scripts/README.md new file mode 100644 index 00000000..61d4e4ea --- /dev/null +++ b/src/comfystream/scripts/README.md @@ -0,0 +1,119 @@ +# ComfyStream Setup Scripts + +This directory contains scripts for setting up ComfyUI nodes and models. The setup is split into two main scripts: + +## Setup Scripts + +1. **setup-comfyui-nodes**: Installs custom ComfyUI nodes +2. **setup-comfyui-models**: Downloads model files and weights + +## Configuration Files + +- `configs/nodes.yaml`: Defines custom nodes to install +- `configs/models.yaml`: Defines model files to download +- `pyproject.toml`: Package dependencies and build settings + +## Basic Usage + +```bash +# Install both nodes and models (default workspace: ~/comfyui) +setup-comfyui-nodes +setup-comfyui-models + +# Use custom workspace +setup-comfyui-nodes --workspace /path/to/workspace +setup-comfyui-models --workspace /path/to/workspace + +# Using environment variable +export COMFY_UI_WORKSPACE=/path/to/workspace +setup-comfyui-nodes +setup-comfyui-models +``` + +## Configuration Examples + +### Custom Nodes (nodes.yaml) +```yaml +nodes: + comfyui-tensorrt: + name: "ComfyUI TensorRT" + url: "https://github.com/yondonfu/ComfyUI_TensorRT" + type: "tensorrt" + dependencies: + - "tensorrt" +``` + +### Models (models.yaml) +```yaml +models: + dreamshaper-v8: + name: "Dreamshaper v8" + url: "https://civitai.com/api/download/models/128713" + path: "checkpoints/SD1.5/dreamshaper-8.safetensors" + type: "checkpoint" +``` + +## Directory Structure + +``` +workspace/ +├── custom_nodes/ # Custom nodes installed by setup-comfyui-nodes +└── models/ # Models downloaded by setup-comfyui-models + ├── checkpoints/ + ├── controlnet/ + ├── unet/ + ├── vae/ + └── tensorrt/ +``` + +## Script Details + +### setup-comfyui-nodes +- Clones node repositories from GitHub +- Installs node dependencies +- Creates custom_nodes directory +- Sets up environment variables + +### setup-comfyui-models +- Downloads model weights +- Downloads additional files (configs, etc) +- Creates model directory structure +- Handles file verification + +## Environment Variables + +- `COMFY_UI_WORKSPACE`: Base directory for installation +- `PYTHONPATH`: Set to workspace directory +- `CUSTOM_NODES_PATH`: Custom nodes directory + +## Notes + +- Run both scripts to set up a complete environment +- Scripts can be run independently +- Both scripts use the same workspace configuration +- Models are only downloaded if they don't exist +- Node repositories are only cloned if not present +- Dependencies are installed automatically + +## Troubleshooting + +If you encounter issues: + +1. Check if workspace directory is writable +2. Verify config files exist in configs/ +3. Ensure Git is installed for node setup +4. Check network connection for downloads +5. Verify Python environment has required packages + +## Testing + +Run the installation tests: +```bash +python -m unittest tests/test_installation.py +``` + +This will verify: +- Directory structure +- Node installation +- Model downloads +- Environment setup \ No newline at end of file diff --git a/src/comfystream/scripts/__init__.py b/src/comfystream/scripts/__init__.py new file mode 100644 index 00000000..661b502a --- /dev/null +++ b/src/comfystream/scripts/__init__.py @@ -0,0 +1 @@ +"""Setup scripts for ComfyUI streaming server""" \ No newline at end of file diff --git a/src/comfystream/scripts/requirements.txt b/src/comfystream/scripts/requirements.txt new file mode 100644 index 00000000..ca92fc8f --- /dev/null +++ b/src/comfystream/scripts/requirements.txt @@ -0,0 +1,3 @@ +requests +tqdm +pyyaml \ No newline at end of file diff --git a/src/comfystream/scripts/setup_models.py b/src/comfystream/scripts/setup_models.py new file mode 100644 index 00000000..fcf13279 --- /dev/null +++ b/src/comfystream/scripts/setup_models.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import os +import sys +from pathlib import Path +import requests +from tqdm import tqdm +import yaml +import argparse +from utils import get_config_path, load_model_config + +def parse_args(): + parser = argparse.ArgumentParser(description='Setup ComfyUI models') + parser.add_argument('--workspace', + default=os.environ.get('COMFY_UI_WORKSPACE', os.path.expanduser('~/comfyui')), + help='ComfyUI workspace directory (default: ~/comfyui or $COMFY_UI_WORKSPACE)') + return parser.parse_args() + +def download_file(url, destination, description=None): + """Download a file with progress bar""" + response = requests.get(url, stream=True) + total_size = int(response.headers.get('content-length', 0)) + + desc = description or os.path.basename(destination) + progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True, desc=desc) + + destination = Path(destination) + destination.parent.mkdir(parents=True, exist_ok=True) + + with open(destination, 'wb') as file: + for data in response.iter_content(chunk_size=1024): + size = file.write(data) + progress_bar.update(size) + progress_bar.close() + +def setup_model_files(workspace_dir, config_path=None): + """Download and setup required model files based on configuration""" + if config_path is None: + config_path = get_config_path('models.yaml') + try: + config = load_model_config(config_path) + except FileNotFoundError: + print(f"Error: Model config file not found at {config_path}") + return + except yaml.YAMLError as e: + print(f"Error parsing model config file: {e}") + return + + models_path = workspace_dir / "models" + base_path = workspace_dir + + for model_id, model_info in config['models'].items(): + # Determine the full path based on whether it's in custom_nodes or models + if model_info['path'].startswith('custom_nodes/'): + full_path = base_path / model_info['path'] + else: + full_path = models_path / model_info['path'] + + if not full_path.exists(): + print(f"Downloading {model_info['name']}...") + download_file( + model_info['url'], + full_path, + f"Downloading {model_info['name']}" + ) + print(f"Downloaded {model_info['name']} to {full_path}") + + # Handle any extra files (like configs) + if 'extra_files' in model_info: + for extra in model_info['extra_files']: + extra_path = models_path / extra['path'] + if not extra_path.exists(): + download_file( + extra['url'], + extra_path, + f"Downloading {os.path.basename(extra['path'])}" + ) + +def setup_directories(workspace_dir): + """Create required directories in the workspace""" + # Create base directories + workspace_dir.mkdir(parents=True, exist_ok=True) + models_dir = workspace_dir / "models" + models_dir.mkdir(parents=True, exist_ok=True) + + # Create model subdirectories + model_dirs = [ + "checkpoints/SD1.5", + "controlnet", + "vae", + "tensorrt", + "unet", + ] + for dir_name in model_dirs: + (models_dir / dir_name).mkdir(parents=True, exist_ok=True) + +def main(): + args = parse_args() + workspace_dir = Path(args.workspace) + + setup_directories(workspace_dir) + setup_model_files(workspace_dir) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/comfystream/scripts/setup_nodes.py b/src/comfystream/scripts/setup_nodes.py new file mode 100755 index 00000000..603eda6c --- /dev/null +++ b/src/comfystream/scripts/setup_nodes.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +import os +import subprocess +import sys +from pathlib import Path +import shutil +import requests +from tqdm import tqdm +import yaml +import pkg_resources +import argparse + +# Change relative import to absolute import +from utils import get_config_path, load_model_config + + +def parse_args(): + parser = argparse.ArgumentParser(description='Setup ComfyUI nodes and models') + parser.add_argument('--workspace', + default=os.environ.get('COMFY_UI_WORKSPACE', os.path.expanduser('~/comfyui')), + help='ComfyUI workspace directory (default: ~/comfyui or $COMFY_UI_WORKSPACE)') + return parser.parse_args() + +def setup_environment(workspace_dir): + os.environ["COMFY_UI_WORKSPACE"] = str(workspace_dir) + os.environ["PYTHONPATH"] = str(workspace_dir) + os.environ["CUSTOM_NODES_PATH"] = str(workspace_dir / "custom_nodes") + +def setup_directories(workspace_dir): + """Create required directories in the workspace""" + # Create base directories + workspace_dir.mkdir(parents=True, exist_ok=True) + custom_nodes_dir = workspace_dir / "custom_nodes" + custom_nodes_dir.mkdir(parents=True, exist_ok=True) + +def install_custom_nodes(workspace_dir, config_path=None): + """Install custom nodes based on configuration""" + if config_path is None: + config_path = get_config_path('nodes.yaml') + try: + config = load_model_config(config_path) + except FileNotFoundError: + print(f"Error: Nodes config file not found at {config_path}") + return + except yaml.YAMLError as e: + print(f"Error parsing nodes config file: {e}") + return + + custom_nodes_path = workspace_dir / "custom_nodes" + custom_nodes_path.mkdir(parents=True, exist_ok=True) + os.chdir(custom_nodes_path) + + for node_id, node_info in config['nodes'].items(): + dir_name = node_info['url'].split("/")[-1].replace(".git", "") + node_path = custom_nodes_path / dir_name + + if not node_path.exists(): + print(f"Installing {node_info['name']}...") + + # Clone the repository + cmd = ["git", "clone", node_info['url']] + if 'branch' in node_info: + cmd.extend(["-b", node_info['branch']]) + subprocess.run(cmd, check=True) + + # Checkout specific commit if branch is a commit hash + if 'branch' in node_info and len(node_info['branch']) == 40: # SHA-1 hash length + subprocess.run(["git", "-C", dir_name, "checkout", node_info['branch']], check=True) + + # Install requirements if present + requirements_file = node_path / "requirements.txt" + if requirements_file.exists(): + subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True) + + # Install additional dependencies if specified + if 'dependencies' in node_info: + for dep in node_info['dependencies']: + subprocess.run([sys.executable, "-m", "pip", "install", dep], check=True) + + print(f"Installed {node_info['name']}") + else: + print(f"{node_info['name']} already installed") + +def main(): + args = parse_args() + workspace_dir = Path(args.workspace) + + setup_environment(workspace_dir) + setup_directories(workspace_dir) + install_custom_nodes(workspace_dir) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/comfystream/scripts/utils.py b/src/comfystream/scripts/utils.py new file mode 100644 index 00000000..9c23eea5 --- /dev/null +++ b/src/comfystream/scripts/utils.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +import yaml +from pathlib import Path + +def get_config_path(filename): + """Get the absolute path to a config file""" + config_path = Path("configs") / filename + if not config_path.exists(): + print(f"Warning: Config file {filename} not found at {config_path}") + print(f"Available files in configs/:") + try: + for f in Path("configs").glob("*"): + print(f" - {f.name}") + except FileNotFoundError: + print(" configs/ directory not found") + raise FileNotFoundError(f"Config file {filename} not found at {config_path}") + return config_path + +def load_model_config(config_path): + """Load model configuration from YAML file""" + with open(config_path, 'r') as f: + return yaml.safe_load(f) \ No newline at end of file From a8a453e070f928a9a209f18f018d28ff0b898d2c Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Wed, 22 Jan 2025 16:29:24 -0500 Subject: [PATCH 04/62] implement setup_nodes.py for custom node install --- .devcontainer/Dockerfile.base | 53 +++-------------------------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index 21d346c3..6e1d28c4 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -22,56 +22,11 @@ RUN source activate comfyui && git clone https://github.com/comfyanonymous/Comfy cd /ComfyUI && /miniconda3/envs/comfyui/bin/pip install -r requirements.txt COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils -WORKDIR / -# Clone ComfyUI Repo to /ComfyUI -RUN source activate comfyui && cd /ComfyUI/custom_nodes && \ - # Ryan's nodes - git clone https://github.com/pschroedl/ComfyUI_RyanOnTheInside.git && \ - cd ComfyUI_RyanOnTheInside && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - git clone https://github.com/ltdrdata/ComfyUI-Manager.git && \ - cd ComfyUI-Manager && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - git clone https://github.com/tsogzark/ComfyUI-load-image-from-url.git && \ - git clone https://github.com/ryanontheinside/ComfyUI-Misc-Effects.git && \ - git clone https://github.com/ryanontheinside/ComfyUI_RealTimeNodes.git && \ - cd ComfyUI_RealTimeNodes && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - # Utility nodes - git clone https://github.com/rgthree/rgthree-comfy.git && \ - cd rgthree-comfy && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - git clone https://github.com/kijai/ComfyUI-KJNodes.git && \ - cd ComfyUI-KJNodes && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - # Vision and AI nodes - git clone https://github.com/ad-astra-video/ComfyUI-Florence2-Vision.git && \ - cd ComfyUI-Florence2-Vision && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - git clone https://github.com/pschroedl/ComfyUI-SAM2-Realtime.git && \ - cd ComfyUI-SAM2-Realtime && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - # Core TensorRT nodes - git clone -b quantization_with_controlnet_fixes https://github.com/yondonfu/ComfyUI_TensorRT && \ - cd ComfyUI_TensorRT && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - git clone https://github.com/yondonfu/ComfyUI-Torch-Compile && \ - cd ComfyUI-Torch-Compile && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt && \ - cd .. && \ - # Utility nodes - git clone https://github.com/yuvraj108c/ComfyUI-Depth-Anything-Tensorrt && \ - cd ComfyUI-Depth-Anything-Tensorrt && \ - /miniconda3/envs/comfyui/bin/pip install -r requirements.txt +WORKDIR /app +# Install custom nodes +RUN source activate comfyui && /miniconda3/envs/comfyui/bin/python /app/src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI +WORKDIR / RUN conda create -n comfystream From 8124ce4acf0d5d53a007480218bd231c024104f2 Mon Sep 17 00:00:00 2001 From: Elite Date: Thu, 23 Jan 2025 23:13:20 +0000 Subject: [PATCH 05/62] implement node installation script, cleanup paths --- .devcontainer/Dockerfile.base | 45 +++++++++++++---------------------- .devcontainer/post-create.sh | 1 - configs/nodes.yaml | 2 ++ 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index 6e1d28c4..eebaeb18 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -18,41 +18,30 @@ RUN eval "$(/miniconda3/bin/conda shell.bash hook)" RUN conda create -n comfyui python=3.11 -y COPY . /app -RUN source activate comfyui && git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI && \ -cd /ComfyUI && /miniconda3/envs/comfyui/bin/pip install -r requirements.txt +# Activate the comfyui environment +SHELL ["conda", "run", "-n", "comfyui", "/bin/bash", "-c"] + +RUN git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI +RUN cd /ComfyUI && pip install -r requirements.txt COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils -WORKDIR /app # Install custom nodes -RUN source activate comfyui && /miniconda3/envs/comfyui/bin/python /app/src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI -WORKDIR / - -RUN conda create -n comfystream +WORKDIR /app +RUN python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI -# Activate the comfystream environment and install dependencies -RUN bash -c "source activate comfystream && pip install /app && pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 && python /app/install.py --workspace /ComfyUI" +# Activate the comfystream environment +RUN conda create -n comfystream python=3.11 -y +SHELL ["conda", "run", "-n", "comfystream", "/bin/bash", "-c"] +#Install ComfyStream requirements +WORKDIR /app +RUN pip install -r requirements.txt && pip install . +RUN pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 +RUN python install.py --workspace /ComfyUI RUN rm -rf /app -# Download models -WORKDIR /ComfyUI -RUN /miniconda3/envs/comfyui/bin/huggingface-cli download Livepeer-Studio/comfystream_checkpoints --local-dir models/checkpoints --include "*.safetensors" -RUN /miniconda3/envs/comfyui/bin/huggingface-cli download Livepeer-Studio/comfystream_loras --local-dir models/checkpoints --include "*.safetensors" - -#Download ControlNet models -RUN /miniconda3/envs/comfyui/bin/huggingface-cli download comfyanonymous/ControlNet-v1-1_fp16_safetensors --local-dir models/controlnet --include "control_v11f1p_sd15_depth_fp16.safetensors" -RUN /miniconda3/envs/comfyui/bin/huggingface-cli download comfyanonymous/ControlNet-v1-1_fp16_safetensors --local-dir models/controlnet --include "control_v11p_sd15_openpose_fp16.safetensors" - -# Download Dreamshaper 8 Model and DMD -RUN wget -O models/checkpoints/dreamshaper_8.safetensors https://civitai.com/api/download/models/128713 --content-disposition -RUN /miniconda3/envs/comfyui/bin/huggingface-cli download aaronb/dreamshaper-8-dmd-1kstep --local-dir models/unet --include "diffusion_pytorch_model.safetensors" -RUN mv /ComfyUI/models/unet/diffusion_pytorch_model.safetensors /ComfyUI/models/unet/dreamshaper_8_dmd_1kstep.safetensors - -# Download Depth-Anything model -RUN wget -O /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/depth_anything_vitl14.onnx https://huggingface.co/yuvraj108c/Depth-Anything-2-Onnx/resolve/main/depth_anything_v2_vitb.onnx?download=true --content-disposition -RUN mkdir -p /ComfyUI/models/tensorrt/depth-anything/ - # Download TAESD +WORKDIR /ComfyUI RUN wget -O models/vae_approx/taesd_decoder.pth https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_decoder.pth RUN wget -O models/vae_approx/taesd_encoder.pth https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_encoder.pth @@ -61,4 +50,4 @@ RUN conda config --set auto_activate_base false RUN echo 'if [ -f "/miniconda3/etc/profile.d/conda.sh" ]; then' >> ~/.bashrc RUN echo ' . "/miniconda3/etc/profile.d/conda.sh"' >> ~/.bashrc RUN echo ' conda activate comfystream' >> ~/.bashrc -RUN echo 'fi' >> ~/.bashrc +RUN echo 'fi' >> ~/.bashrc \ No newline at end of file diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index ebae87e4..50b27a30 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -19,5 +19,4 @@ if [ ! -d "/workspace/ComfyUI" ]; then ln -s /ComfyUI /workspace/ComfyUI fi -source ~/.bashrc /bin/bash \ No newline at end of file diff --git a/configs/nodes.yaml b/configs/nodes.yaml index 0e0237fb..abf8808a 100644 --- a/configs/nodes.yaml +++ b/configs/nodes.yaml @@ -16,6 +16,8 @@ nodes: name: "ComfyUI RyanOnTheInside" url: "https://github.com/pschroedl/ComfyUI_RyanOnTheInside.git" type: "utility" + dependencies: + - "scikit-image" comfyui-manager: name: "ComfyUI Manager" From 660ca311889c1436d475760cfc306cad5dce40a5 Mon Sep 17 00:00:00 2001 From: Elite Date: Thu, 23 Jan 2025 23:41:57 +0000 Subject: [PATCH 06/62] add model download and docs --- .devcontainer/README.md | 28 ++++++++++++++-------------- configs/models.yaml | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 58034539..cc2b28b8 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -49,28 +49,23 @@ Ensure your `devcontainer.json` is properly configured to map the necessary host Replace `/path/to/your/models` with the actual path to your models on the host machine. -## Additional Resources +### Download models -- [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers) -- [Docker Documentation](https://docs.docker.com/) +```sh +python src/comfystream/scripts/setup_models.py --workspace /ComfyUI +``` By following these steps, you should be able to set up and run your development container for ComfyStream efficiently. ## Building the DepthAnything Engine -1. Navigate to the DepthAnything directory: +1. Run the **export_trt.py** script from the directory of the onnx file: ```sh -cd /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/ +cd /ComfyUI/models/tensorrt/depth-anything +python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py ``` -2. Run the export script to build the engine and move the generated engine file to the appropriate directory: - -```sh -python export_trt.py -mv depth_anything_vitl14-fp16.engine /ComfyUI/models/tensorrt/depth-anything/depth_anything_vitl14-fp16.engine -``` - -By following these steps, you will have successfully built and copied the DepthAnything engine to the required location. +**Note**: You may use either conda environment for this step ### Starting ComfyUI @@ -89,4 +84,9 @@ python main.py --listen --disable-cuda-malloc ```sh python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8889 -``` \ No newline at end of file +``` + +## Additional Resources + +- [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers) +- [Docker Documentation](https://docs.docker.com/) diff --git a/configs/models.yaml b/configs/models.yaml index c55230ee..e452d3b0 100644 --- a/configs/models.yaml +++ b/configs/models.yaml @@ -16,7 +16,21 @@ models: - url: "https://huggingface.co/aaronb/dreamshaper-8-dmd-1kstep/raw/main/config.json" path: "unet/dreamshaper-8-dmd-1kstep.json" + # Depth Anything ONNX model + depthanything-onnx: + name: "DepthAnything ONNX" + url: "https://huggingface.co/yuvraj108c/Depth-Anything-2-Onnx/resolve/main/depth_anything_v2_vitb.onnx?download=true" + path: "tensorrt/depth-anything/depth_anything_vitl14.onnx" + # TAESD models + taesd: + name: "TAESD" + url: "https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_decoder.pth" + path: "vae_approx/taesd_decoder.pth" + type: "vae_approx" + extra_files: + - url: "https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_encoder.pth" + path: "vae_approx/taesd_encoder.pth" # ControlNet models controlnet-depth: From c28a131bcf3d3a804a7330d6bff09834003cb424 Mon Sep 17 00:00:00 2001 From: Elite Date: Thu, 23 Jan 2025 23:50:34 +0000 Subject: [PATCH 07/62] update model names in sample workflow for consistency with models.yaml --- workflows/ui/1 - Build ONNX.json | 2 +- workflows/ui/2 - Build Static TensorRT Engine.json | 2 +- workflows/ui/3 - SD 1.5 TensorRT workflow.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/workflows/ui/1 - Build ONNX.json b/workflows/ui/1 - Build ONNX.json index 7a903096..30074f4f 100644 --- a/workflows/ui/1 - Build ONNX.json +++ b/workflows/ui/1 - Build ONNX.json @@ -61,7 +61,7 @@ "Node name for S&R": "UNETLoader" }, "widgets_values": [ - "dreamshaper_8_dmd_1kstep.safetensors", + "dreamshaper-8-dmd-1kstep.safetensors", "default" ] } diff --git a/workflows/ui/2 - Build Static TensorRT Engine.json b/workflows/ui/2 - Build Static TensorRT Engine.json index 64780dba..346068a4 100644 --- a/workflows/ui/2 - Build Static TensorRT Engine.json +++ b/workflows/ui/2 - Build Static TensorRT Engine.json @@ -31,7 +31,7 @@ "Node name for S&R": "UNETLoader" }, "widgets_values": [ - "dreamshaper_8_dmd_1kstep.safetensors", + "dreamshaper-8-dmd-1kstep.safetensors", "default" ] }, diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index 1d728962..bdd14240 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -571,7 +571,7 @@ "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - "dreamshaper_8.safetensors" + "dreamshaper-8.safetensors" ] }, { From 7c04e67ce927665660f299f6a1bd6fc5689f0084 Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 00:12:49 +0000 Subject: [PATCH 08/62] add launch.json --- .vscode/launch.json | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100755 index 00000000..5cc262ca --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,38 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Run ComfyUI", + "type": "debugpy", + "request": "launch", + "cwd": "/ComfyUI", + "program": "main.py", + "purpose": ["debug-in-terminal"], + "env": { + "PYDEVD_DISABLE_FILE_VALIDATION": "1" + }, + "args": [ + "--listen", + ], + "python": "/miniconda3/envs/comfyui/bin/python" + }, + { + "name": "Run ComfyStream", + "type": "debugpy", + "request": "launch", + "cwd": "/workspace/server", + "program": "app.py", + "console": "integratedTerminal", + "args": [ + "--workspace=/ComfyUI", + "--media-ports=5678", + "--host=0.0.0.0", + "--port=8889" + ], + "python": "/miniconda3/envs/comfystream/bin/python" + } + ] +} \ No newline at end of file From 233e74a9f9ea95e98c0757d0196e6e9017cdfcea Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 01:41:28 +0000 Subject: [PATCH 09/62] add model download, add python extensions for managing conda shell integration --- .devcontainer/Dockerfile.base | 1 - .devcontainer/README.md | 14 ++++++++++---- .devcontainer/devcontainer.json | 8 +++++--- .devcontainer/post-create.sh | 9 --------- .gitignore | 1 + 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index eebaeb18..fd878304 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -49,5 +49,4 @@ RUN wget -O models/vae_approx/taesd_encoder.pth https://raw.githubusercontent.co RUN conda config --set auto_activate_base false RUN echo 'if [ -f "/miniconda3/etc/profile.d/conda.sh" ]; then' >> ~/.bashrc RUN echo ' . "/miniconda3/etc/profile.d/conda.sh"' >> ~/.bashrc -RUN echo ' conda activate comfystream' >> ~/.bashrc RUN echo 'fi' >> ~/.bashrc \ No newline at end of file diff --git a/.devcontainer/README.md b/.devcontainer/README.md index cc2b28b8..f2a19656 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -13,7 +13,7 @@ This guide will help you set up and run a development container for ComfyStream To build the base container, run the following command in your terminal: ```sh -docker build -f .devcontainer/Dockerfile.base -t eliteencoder/comfyui-base:latest . +docker build -f .devcontainer/Dockerfile.base -t livepeer/comfyui-base:latest . ``` ## Using the Pre-built Base Container @@ -23,7 +23,7 @@ Most users will configure host paths for models in `devcontainer.json` and use t 1. Pull the pre-built base container: ```sh -docker pull eliteencoder/comfyui-base:latest +docker pull livepeer/comfyui-base:latest ``` 2. Configure the host paths for models in the `devcontainer.json` file. @@ -34,14 +34,19 @@ docker pull eliteencoder/comfyui-base:latest ## Configuration -Ensure your `devcontainer.json` is properly configured to map the necessary host paths for your models. Here is an example configuration: +Create a directory to store the models +```sh +sudo mkdir -p /models/ComfyUI--models && sudo chown -R $USER /models/ComfyUI--models +``` + +If you have a different path for models, ensure your `devcontainer.json` is properly configured to map the correct host path to your models. Here is an example configuration: ```json { "name": "ComfyStream Dev Container", "image": "livepeer/comfyui-base", "mounts": [ - "source=/path/to/your/models,target=/workspace/models,type=bind" + "source=/path/to/your/models,target=/ComfyUI/models,type=bind" ], "workspaceFolder": "/workspace" } @@ -90,3 +95,4 @@ python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --po - [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers) - [Docker Documentation](https://docs.docker.com/) +- [Activate-Environments-in-Terminal-Using-Environment-Variables](https://github.com/microsoft/vscode-python/wiki/Activate-Environments-in-Terminal-Using-Environment-Variables) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e77cf7e5..3fd979a8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,12 +14,14 @@ "customizations": { "vscode": { "settings": { - "python.defaultInterpreterPath": "/workspace/miniconda3/envs/comfystream/bin/python" + "python.defaultInterpreterPath": "/workspace/miniconda3/envs/comfystream/bin/python", + "terminal.integrated.shellIntegration.enabled": true }, "extensions": [ "ms-python.python", "ms-python.black-formatter", - "ms-python.vscode-pylance" + "ms-python.vscode-pylance", + "ms-python.debugpy" ] } }, @@ -35,7 +37,7 @@ "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", "mounts": [ // Use 'mounts' to set models and environments for the container, the following targets are included in extra_model_paths.yaml - // "source=${localEnv:HOME}/ComfyUI-models,target=/ComfyUI/extra/models,type=bind,consistency=cached" + "source=/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached" ], "postCreateCommand": "bash .devcontainer/post-create.sh" } diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 50b27a30..d21bb443 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -1,14 +1,5 @@ #!/bin/bash -# Create a symlink to the extra_model_paths.yaml file only if /ComfyUI/extra/models exists and /ComfyUI/extra_model_paths.yaml does not exist, otherwise remove the link -if [ -d "/ComfyUI/extra/models" ] && [ ! -L "/ComfyUI/extra_model_paths.yaml" ]; then - ln -s /workspace/.devcontainer/extra_model_paths.yaml /ComfyUI/extra_model_paths.yaml -else - if [ -L "/ComfyUI/extra_model_paths.yaml" ]; then - rm /ComfyUI/extra_model_paths.yaml - fi -fi - # Initialize conda if needed if ! command -v conda &> /dev/null; then /miniconda3/bin/conda init bash diff --git a/.gitignore b/.gitignore index d63bc35d..f694eac5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ __pycache__ build .DS_STORE comfyui* +ComfyUI* # VS Code settings .vscode/ From fedae79e7f0d52d9e11735fb99549c0fd1b8358e Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 17:27:33 +0000 Subject: [PATCH 10/62] add nvm, ui launch configs improve conda --- .devcontainer/Dockerfile | 17 +++++++++++++++++ .devcontainer/Dockerfile.base | 23 ++++++++++------------- .vscode/launch.json | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5ec21d92..1a08f166 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,3 +1,20 @@ FROM eliteencoder/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" +# Install NVM +ENV NVM_DIR /root/.nvm +ENV NODE_VERSION 18.18.0 +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash + +# Install node and npm +RUN source $NVM_DIR/nvm.sh \ + && nvm install $NODE_VERSION \ + && nvm alias default $NODE_VERSION \ + && nvm use default + +# Add node and npm to path so the commands are available +ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules +ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH + + +RUN source ~/.bashrc && npm install --legacy-peer-deps diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index fd878304..a832429d 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -1,6 +1,6 @@ FROM runpod/pytorch:2.4.0-py3.11-cuda12.4.1-devel-ubuntu22.04 -# 1. Install system dependencies +# Install system dependencies RUN apt-get update && apt-get install -y \ git \ wget \ @@ -8,7 +8,7 @@ RUN apt-get update && apt-get install -y \ socat \ && rm -rf /var/lib/apt/lists/* -# 2. Install Miniconda (optional, if you want it ready at build-time) +# Install Miniconda (optional, if you want it ready at build-time) RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/miniconda.sh \ && bash /tmp/miniconda.sh -b -p /miniconda3 \ && rm /tmp/miniconda.sh @@ -16,6 +16,7 @@ RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh - ENV PATH="/miniconda3/bin:${PATH}" RUN eval "$(/miniconda3/bin/conda shell.bash hook)" RUN conda create -n comfyui python=3.11 -y +RUN conda create -n comfystream python=3.11 -y COPY . /app # Activate the comfyui environment @@ -30,23 +31,19 @@ COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils WORKDIR /app RUN python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI +# Activate the comfyui environment +SHELL ["conda", "deactivate"] + # Activate the comfystream environment -RUN conda create -n comfystream python=3.11 -y SHELL ["conda", "run", "-n", "comfystream", "/bin/bash", "-c"] + #Install ComfyStream requirements -WORKDIR /app RUN pip install -r requirements.txt && pip install . RUN pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 RUN python install.py --workspace /ComfyUI RUN rm -rf /app - -# Download TAESD -WORKDIR /ComfyUI -RUN wget -O models/vae_approx/taesd_decoder.pth https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_decoder.pth -RUN wget -O models/vae_approx/taesd_encoder.pth https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_encoder.pth +SHELL ["conda", "deactivate","/bin/bash", "-c"] # Set comfystream as the default environment -RUN conda config --set auto_activate_base false -RUN echo 'if [ -f "/miniconda3/etc/profile.d/conda.sh" ]; then' >> ~/.bashrc -RUN echo ' . "/miniconda3/etc/profile.d/conda.sh"' >> ~/.bashrc -RUN echo 'fi' >> ~/.bashrc \ No newline at end of file +# RUN conda config --set auto_activate_base false +SHELL ["conda", "config", "--set", "auto_activate_base", "false","/bin/bash", "-c"] \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 5cc262ca..809561e2 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,6 +33,24 @@ "--port=8889" ], "python": "/miniconda3/envs/comfystream/bin/python" + }, + { + "name": "Run ComfyStream UI", + "type": "chrome", + "request": "launch", + "url": "http://localhost:3000", + "webRoot": "/workspace/client" + }, + { + "name": "Run ComfyStream UI (Node.js)", + "type": "node", + "request": "launch", + "cwd": "/workspace/ui", + "runtimeExecutable": "npm", + "runtimeArgs": [ + "run", + "dev" + ] } ] } \ No newline at end of file From 9f5fd9c18526228b2e6da904cbe863a88b98a58f Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 19:15:07 +0000 Subject: [PATCH 11/62] dockerfile cleanup --- .devcontainer/Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 1a08f166..370ec8c4 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -15,6 +15,3 @@ RUN source $NVM_DIR/nvm.sh \ # Add node and npm to path so the commands are available ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH - - -RUN source ~/.bashrc && npm install --legacy-peer-deps From d89e45a14de8027a6afa6a5c3dd715b563c9f84f Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 19:16:06 +0000 Subject: [PATCH 12/62] add log to models downloader --- src/comfystream/scripts/setup_models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/comfystream/scripts/setup_models.py b/src/comfystream/scripts/setup_models.py index fcf13279..6d62c163 100644 --- a/src/comfystream/scripts/setup_models.py +++ b/src/comfystream/scripts/setup_models.py @@ -74,6 +74,7 @@ def setup_model_files(workspace_dir, config_path=None): extra_path, f"Downloading {os.path.basename(extra['path'])}" ) + print("Models download completed!") def setup_directories(workspace_dir): """Create required directories in the workspace""" From c28d4ba68300ca51512c8e796aa2b3a38f2f2b7f Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 19:16:15 +0000 Subject: [PATCH 13/62] update workflows and docs --- .devcontainer/README.md | 1 + .devcontainer/devcontainer.json | 2 +- .../ui/3 - SD 1.5 TensorRT workflow.json | 628 +++++++++--------- 3 files changed, 308 insertions(+), 323 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index f2a19656..dbf72090 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -57,6 +57,7 @@ Replace `/path/to/your/models` with the actual path to your models on the host m ### Download models ```sh +cd /workspace python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3fd979a8..4b992bb0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -36,7 +36,7 @@ "workspaceFolder": "/workspace", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", "mounts": [ - // Use 'mounts' to set models and environments for the container, the following targets are included in extra_model_paths.yaml + // Use 'mounts' to map to comfyui models on the host "source=/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached" ], "postCreateCommand": "bash .devcontainer/post-create.sh" diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index bdd14240..c14a7d7a 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -1,198 +1,156 @@ { - "last_node_id": 22, - "last_link_id": 21, + "last_node_id": 16, + "last_link_id": 32, "nodes": [ { - "id": 5, - "type": "CLIPTextEncode", + "id": 2, + "type": "DepthAnythingTensorrt", "pos": [ - 1104, - 615 + 515, + 130 ], "size": [ - 400, - 200 + 315, + 58 ], "flags": {}, - "order": 8, + "order": 10, "mode": 0, "inputs": [ { - "name": "clip", - "type": "CLIP", - "link": 2 + "name": "images", + "type": "IMAGE", + "link": 17 } ], "outputs": [ { - "name": "CONDITIONING", - "type": "CONDITIONING", + "name": "IMAGE", + "type": "IMAGE", "links": [ - 4 - ], - "slot_index": 0 + 27 + ] } ], "properties": { - "Node name for S&R": "CLIPTextEncode" + "Node name for S&R": "DepthAnythingTensorrt" }, "widgets_values": [ - "the hulk" + "depth_anything_vitl14-fp16.engine" ] }, { - "id": 6, - "type": "CLIPTextEncode", + "id": 3, + "type": "TensorRTLoader", "pos": [ - 1104, - 891 + 100, + 362 ], "size": [ - 400, - 200 + 315, + 82 ], "flags": {}, - "order": 9, + "order": 0, "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 3 - } - ], + "inputs": [], "outputs": [ { - "name": "CONDITIONING", - "type": "CONDITIONING", + "name": "MODEL", + "type": "MODEL", "links": [ - 5 - ], - "slot_index": 0 + 20 + ] } ], "properties": { - "Node name for S&R": "CLIPTextEncode" + "Node name for S&R": "TensorRTLoader" }, "widgets_values": [ - "" + "static-dreamshaper8_SD15_$stat-b-1-h-512-w-512_00001_.engine", + "SD15" ] }, { - "id": 9, - "type": "ControlNetApplyAdvanced", + "id": 5, + "type": "CLIPTextEncode", "pos": [ - 1602, - 664 + 515, + 318 ], "size": [ - 315, - 186 + 400, + 200 ], "flags": {}, - "order": 11, + "order": 8, "mode": 0, "inputs": [ { - "name": "positive", - "type": "CONDITIONING", - "link": 4 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 5 - }, - { - "name": "control_net", - "type": "CONTROL_NET", - "link": 11 - }, - { - "name": "image", - "type": "IMAGE", - "link": 12 - }, - { - "name": "vae", - "type": "VAE", - "link": null, - "shape": 7 + "name": "clip", + "type": "CLIP", + "link": 18 } ], "outputs": [ { - "name": "positive", - "type": "CONDITIONING", - "links": [ - 7 - ], - "slot_index": 0 - }, - { - "name": "negative", + "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 8 - ], - "slot_index": 1 + 24 + ] } ], "properties": { - "Node name for S&R": "ControlNetApplyAdvanced" + "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - 1, - 0, - 1 + " In a winter wonderland" ] }, { - "id": 10, - "type": "TorchCompileLoadControlNet", + "id": 6, + "type": "CLIPTextEncode", "pos": [ - 1130, - 1226 + 515, + 648 ], "size": [ - 327.5999755859375, - 106 + 400, + 200 ], "flags": {}, - "order": 7, + "order": 9, "mode": 0, "inputs": [ { - "name": "controlnet", - "type": "CONTROL_NET", - "link": 10 + "name": "clip", + "type": "CLIP", + "link": 19 } ], "outputs": [ { - "name": "CONTROL_NET", - "type": "CONTROL_NET", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 11 - ], - "slot_index": 0 + 25 + ] } ], "properties": { - "Node name for S&R": "TorchCompileLoadControlNet" + "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "inductor", - false, - "reduce-overhead" + "" ] }, { "id": 7, "type": "KSampler", "pos": [ - 2024, - 287 + 1430, + 130 ], "size": [ 315, @@ -205,22 +163,22 @@ { "name": "model", "type": "MODEL", - "link": 9 + "link": 20 }, { "name": "positive", "type": "CONDITIONING", - "link": 7 + "link": 21 }, { "name": "negative", "type": "CONDITIONING", - "link": 8 + "link": 22 }, { "name": "latent_image", "type": "LATENT", - "link": 17 + "link": 23 } ], "outputs": [ @@ -228,16 +186,15 @@ "name": "LATENT", "type": "LATENT", "links": [ - 14 - ], - "slot_index": 0 + 30 + ] } ], "properties": { "Node name for S&R": "KSampler" }, "widgets_values": [ - 577216550229772, + 431120618284339, "randomize", 1, 1, @@ -247,206 +204,238 @@ ] }, { - "id": 15, - "type": "PreviewImage", + "id": 8, + "type": "ControlNetLoader", "pos": [ - 2878.828125, - 299.9607238769531 + 100, + 802 ], "size": [ - 210, - 246 + 315, + 58 ], "flags": {}, - "order": 14, + "order": 1, "mode": 0, - "inputs": [ + "inputs": [], + "outputs": [ { - "name": "images", - "type": "IMAGE", - "link": 15 + "name": "CONTROL_NET", + "type": "CONTROL_NET", + "links": [ + 28 + ] } ], - "outputs": [], "properties": { - "Node name for S&R": "PreviewImage" + "Node name for S&R": "ControlNetLoader" }, - "widgets_values": [] + "widgets_values": [ + "control_v11f1p_sd15_depth_fp16.safetensors" + ] }, { - "id": 14, - "type": "VAEDecode", + "id": 9, + "type": "ControlNetApplyAdvanced", "pos": [ - 2521.657470703125, - 307.1023254394531 + 1015, + 130 ], "size": [ - 210, - 46 + 315, + 186 ], "flags": {}, - "order": 13, + "order": 11, "mode": 0, "inputs": [ { - "name": "samples", - "type": "LATENT", - "link": 14 + "name": "positive", + "type": "CONDITIONING", + "link": 24 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 25 + }, + { + "name": "control_net", + "type": "CONTROL_NET", + "link": 26 + }, + { + "name": "image", + "type": "IMAGE", + "link": 27 }, { "name": "vae", "type": "VAE", - "link": 16 + "link": null, + "shape": 7 } ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", + "name": "positive", + "type": "CONDITIONING", "links": [ - 15 - ], - "slot_index": 0 + 21 + ] + }, + { + "name": "negative", + "type": "CONDITIONING", + "links": [ + 22 + ] } ], "properties": { - "Node name for S&R": "VAEDecode" + "Node name for S&R": "ControlNetApplyAdvanced" }, - "widgets_values": [] + "widgets_values": [ + 1, + 0, + 1 + ] }, { - "id": 13, - "type": "TorchCompileLoadVAE", + "id": 10, + "type": "TorchCompileLoadControlNet", "pos": [ - 1138.843017578125, - 1457.9476318359375 + 515, + 978 ], "size": [ - 315, - 154 + 327.5999755859375, + 106 ], "flags": {}, - "order": 10, + "order": 6, "mode": 0, "inputs": [ { - "name": "vae", - "type": "VAE", - "link": 13 + "name": "controlnet", + "type": "CONTROL_NET", + "link": 28 } ], "outputs": [ { - "name": "VAE", - "type": "VAE", + "name": "CONTROL_NET", + "type": "CONTROL_NET", "links": [ - 16 - ], - "slot_index": 0 + 26 + ] } ], "properties": { - "Node name for S&R": "TorchCompileLoadVAE" + "Node name for S&R": "TorchCompileLoadControlNet" }, "widgets_values": [ "inductor", - true, - "reduce-overhead", - true, - true + false, + "reduce-overhead" ] }, { - "id": 16, - "type": "EmptyLatentImage", + "id": 11, + "type": "VAELoader", "pos": [ - 1627, - -92 + 100, + 990 ], "size": [ 315, - 106 + 58 ], "flags": {}, - "order": 0, + "order": 2, "mode": 0, "inputs": [], "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "VAE", + "type": "VAE", "links": [ - 17 - ], - "slot_index": 0 + 29 + ] } ], "properties": { - "Node name for S&R": "EmptyLatentImage" + "Node name for S&R": "VAELoader" }, "widgets_values": [ - 512, - 512, - 1 + "taesd" ] }, { - "id": 1, - "type": "LoadImage", + "id": 13, + "type": "TorchCompileLoadVAE", "pos": [ - 803, - -123 + 515, + 1214 ], "size": [ 315, - 314 + 154 ], "flags": {}, - "order": 1, + "order": 7, "mode": 0, - "inputs": [], + "inputs": [ + { + "name": "vae", + "type": "VAE", + "link": 29 + } + ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", + "name": "VAE", + "type": "VAE", "links": [ - 1 - ], - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null + 31 + ] } ], "properties": { - "Node name for S&R": "LoadImage" + "Node name for S&R": "TorchCompileLoadVAE" }, "widgets_values": [ - "805cf30d101b7641.png", - "image" + "inductor", + true, + "reduce-overhead", + true, + true ] }, { - "id": 2, - "type": "DepthAnythingTensorrt", + "id": 14, + "type": "VAEDecode", "pos": [ - 1238, - 77 + 1845, + 130 ], "size": [ - 315, - 58 + 210, + 46 ], "flags": {}, - "order": 6, + "order": 13, "mode": 0, "inputs": [ { - "name": "images", - "type": "IMAGE", - "link": 1 + "name": "samples", + "type": "LATENT", + "link": 30 + }, + { + "name": "vae", + "type": "VAE", + "link": 31 } ], "outputs": [ @@ -454,61 +443,50 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 12 - ], - "slot_index": 0 + 32 + ] } ], "properties": { - "Node name for S&R": "DepthAnythingTensorrt" - }, - "widgets_values": [ - "depth_anything_vitl14-fp16.engine" - ] + "Node name for S&R": "VAEDecode" + } }, { - "id": 3, - "type": "TensorRTLoader", + "id": 15, + "type": "PreviewImage", "pos": [ - 642, - 396 + 2155, + 130 ], "size": [ - 315, - 82 + 210, + 246 ], "flags": {}, - "order": 2, + "order": 14, "mode": 0, - "inputs": [], - "outputs": [ + "inputs": [ { - "name": "MODEL", - "type": "MODEL", - "links": [ - 9 - ], - "slot_index": 0 + "name": "images", + "type": "IMAGE", + "link": 32 } ], + "outputs": [], "properties": { - "Node name for S&R": "TensorRTLoader" - }, - "widgets_values": [ - "dreamshaper_$dyn-b-1-1-1-h-512-512-512-w-512-512-512_00001_.engine", - "SD15" - ] + "Node name for S&R": "PreviewImage" + } }, { - "id": 8, - "type": "ControlNetLoader", + "id": 16, + "type": "EmptyLatentImage", "pos": [ - 650, - 1244 + 100, + 1178 ], "size": [ 315, - 58 + 106 ], "flags": {}, "order": 3, @@ -516,27 +494,28 @@ "inputs": [], "outputs": [ { - "name": "CONTROL_NET", - "type": "CONTROL_NET", + "name": "LATENT", + "type": "LATENT", "links": [ - 10 - ], - "slot_index": 0 + 23 + ] } ], "properties": { - "Node name for S&R": "ControlNetLoader" + "Node name for S&R": "EmptyLatentImage" }, "widgets_values": [ - "control_v11f1p_sd15_depth_fp16.safetensors" + 512, + 512, + 1 ] }, { "id": 4, "type": "CheckpointLoaderSimple", "pos": [ - 648, - 771 + 100, + 574 ], "size": [ 315, @@ -556,10 +535,9 @@ "name": "CLIP", "type": "CLIP", "links": [ - 2, - 3 - ], - "slot_index": 1 + 18, + 19 + ] }, { "name": "VAE", @@ -571,19 +549,19 @@ "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - "dreamshaper-8.safetensors" + "SD1.5/dreamshaper-8.safetensors" ] }, { - "id": 11, - "type": "VAELoader", + "id": 1, + "type": "LoadImage", "pos": [ - 649, - 1498 + 100, + 130 ], "size": [ 315, - 58 + 314 ], "flags": {}, "order": 5, @@ -591,25 +569,30 @@ "inputs": [], "outputs": [ { - "name": "VAE", - "type": "VAE", + "name": "IMAGE", + "type": "IMAGE", "links": [ - 13 - ], - "slot_index": 0 + 17 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null } ], "properties": { - "Node name for S&R": "VAELoader" + "Node name for S&R": "LoadImage" }, "widgets_values": [ - "taesd" + "example.png", + "image" ] } ], "links": [ [ - 1, + 17, 1, 0, 2, @@ -617,7 +600,7 @@ "IMAGE" ], [ - 2, + 18, 4, 1, 5, @@ -625,7 +608,7 @@ "CLIP" ], [ - 3, + 19, 4, 1, 6, @@ -633,23 +616,15 @@ "CLIP" ], [ - 4, - 5, - 0, - 9, + 20, + 3, 0, - "CONDITIONING" - ], - [ - 5, - 6, + 7, 0, - 9, - 1, - "CONDITIONING" + "MODEL" ], [ - 7, + 21, 9, 0, 7, @@ -657,7 +632,7 @@ "CONDITIONING" ], [ - 8, + 22, 9, 1, 7, @@ -665,23 +640,31 @@ "CONDITIONING" ], [ - 9, - 3, + 23, + 16, 0, 7, - 0, - "MODEL" + 3, + "LATENT" ], [ - 10, - 8, + 24, + 5, 0, - 10, + 9, 0, - "CONTROL_NET" + "CONDITIONING" ], [ - 11, + 25, + 6, + 0, + 9, + 1, + "CONDITIONING" + ], + [ + 26, 10, 0, 9, @@ -689,7 +672,7 @@ "CONTROL_NET" ], [ - 12, + 27, 2, 0, 9, @@ -697,7 +680,15 @@ "IMAGE" ], [ - 13, + 28, + 8, + 0, + 10, + 0, + "CONTROL_NET" + ], + [ + 29, 11, 0, 13, @@ -705,7 +696,7 @@ "VAE" ], [ - 14, + 30, 7, 0, 14, @@ -713,15 +704,7 @@ "LATENT" ], [ - 15, - 14, - 0, - 15, - 0, - "IMAGE" - ], - [ - 16, + 31, 13, 0, 14, @@ -729,28 +712,29 @@ "VAE" ], [ - 17, - 16, + 32, + 14, 0, - 7, - 3, - "LATENT" + 15, + 0, + "IMAGE" ] ], "groups": [], "config": {}, "extra": { "ds": { - "scale": 0.6830134553650707, + "scale": 0.7513148009015777, "offset": [ - 82.14661719380388, - 3.8953213027115225 + 660.8600621028962, + 94.59269584816836 ] }, "node_versions": { - "comfy-core": "0.3.10", - "ComfyUI-Torch-Compile": "28b36d2569b39c303b2d9b0e5540ec5d628164af", - "ComfyUI-Depth-Anything-Tensorrt": "ede57bac05059731f955c1b1563af2c1947f999a" + "ComfyUI-Depth-Anything-Tensorrt": "ede57bac05059731f955c1b1563af2c1947f999a", + "ComfyUI_TensorRT": "657994a5481897944a62266ab9f4f9aef24f93f4", + "comfy-core": "0.3.12", + "ComfyUI-Torch-Compile": "28b36d2569b39c303b2d9b0e5540ec5d628164af" } }, "version": 0.4 From 32d66dc6302573fb679cc9808712a951deac86a7 Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 19:30:18 +0000 Subject: [PATCH 14/62] update comment --- .devcontainer/Dockerfile.base | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index a832429d..daff160a 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -44,6 +44,5 @@ RUN python install.py --workspace /ComfyUI RUN rm -rf /app SHELL ["conda", "deactivate","/bin/bash", "-c"] -# Set comfystream as the default environment -# RUN conda config --set auto_activate_base false +# Configure no environment activation by default SHELL ["conda", "config", "--set", "auto_activate_base", "false","/bin/bash", "-c"] \ No newline at end of file From bb3e0843afe04d3743dbd01641c5b3933265544a Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 22:14:17 +0000 Subject: [PATCH 15/62] fix conda env syntax --- .devcontainer/Dockerfile.base | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index daff160a..d2955bdf 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -19,30 +19,22 @@ RUN conda create -n comfyui python=3.11 -y RUN conda create -n comfystream python=3.11 -y COPY . /app -# Activate the comfyui environment -SHELL ["conda", "run", "-n", "comfyui", "/bin/bash", "-c"] - RUN git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI -RUN cd /ComfyUI && pip install -r requirements.txt COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils +WORKDIR /ComfyUI +RUN conda run -n comfyui pip install -r requirements.txt + # Install custom nodes WORKDIR /app -RUN python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI - -# Activate the comfyui environment -SHELL ["conda", "deactivate"] - -# Activate the comfystream environment -SHELL ["conda", "run", "-n", "comfystream", "/bin/bash", "-c"] +RUN conda run -n comfyui python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI #Install ComfyStream requirements -RUN pip install -r requirements.txt && pip install . -RUN pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 -RUN python install.py --workspace /ComfyUI +RUN conda run -n comfystream pip install -r requirements.txt && pip install . +RUN conda run -n comfystream pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 +RUN conda run -n comfystream python install.py --workspace /ComfyUI RUN rm -rf /app -SHELL ["conda", "deactivate","/bin/bash", "-c"] # Configure no environment activation by default -SHELL ["conda", "config", "--set", "auto_activate_base", "false","/bin/bash", "-c"] \ No newline at end of file +RUN conda config --set auto_activate_base false \ No newline at end of file From 3cbf94a4c964e94be272e23a8e96b9dd30fd2e83 Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 22:14:44 +0000 Subject: [PATCH 16/62] add livepeer welcome msg --- .devcontainer/Dockerfile | 6 ++++++ .devcontainer/welcome.txt | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 .devcontainer/welcome.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 370ec8c4..c1103da5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,12 @@ FROM eliteencoder/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" +# Remove RunPod logo, replace with Livepeer AI +RUN head -n $(($lines - 2)) ~/.bashrc > ~/.bashrc +RUN echo -e "\ncat /workspace/.devcontainer/welcome.txt\n\n" >> /root/.bashrc +RUN echo -e "echo -e '\nFor detailed documentation and guides, please visit:\n\033[1;34mhttps://pipelines.livepeer.org/docs\033[0m and \033[1;34mhttps://mirror.xyz.livepeer.eth/\033[0m\n\n'" >> /root/.bashrc + +WORKDIR / # Install NVM ENV NVM_DIR /root/.nvm ENV NODE_VERSION 18.18.0 diff --git a/.devcontainer/welcome.txt b/.devcontainer/welcome.txt new file mode 100644 index 00000000..eb1ac4f0 --- /dev/null +++ b/.devcontainer/welcome.txt @@ -0,0 +1,9 @@ + + +██╗ ██╗██╗ ██╗███████╗██████╗ ███████╗███████╗██████╗ █████╗ ██╗ +██║ ██║██║ ██║██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗ ██╔══██╗██║ +██║ ██║██║ ██║█████╗ ██████╔╝█████╗ █████╗ ██████╔╝ ███████║██║ +██║ ██║╚██╗ ██╔╝██╔══╝ ██╔═══╝ ██╔══╝ ██╔══╝ ██╔══██╗ ██╔══██║██║ +███████╗██║ ╚████╔╝ ███████╗██║ ███████╗███████╗██║ ██║██╗██║ ██║██║ +╚══════╝╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝ + From b1890c518e610eff88c9f62cdc7eeb3f59a4a930 Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 24 Jan 2025 23:01:41 +0000 Subject: [PATCH 17/62] remove unused file --- .devcontainer/extra_model_paths.yaml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .devcontainer/extra_model_paths.yaml diff --git a/.devcontainer/extra_model_paths.yaml b/.devcontainer/extra_model_paths.yaml deleted file mode 100644 index a664a3d3..00000000 --- a/.devcontainer/extra_model_paths.yaml +++ /dev/null @@ -1,19 +0,0 @@ - -# Add your host mounted custom_nodes and model paths here -a111: - base_path: /workspace/ComfyUI - checkpoints: /extra/models/checkpoints - configs: /extra/models/configs - vae: /extra/models/vae - loras: | - /extra/models/loras - upscale_models: | - /extra/models/ESRGAN - /extra/models/RealESRGAN - /extra/models/SwinIR - embeddings: /extra/models/embeddings - hypernetworks: /extra/models/hypernetworks - controlnet: /extra/models/controlnet - -# Optional: Map local custom nodes (requires installation) -# custom_nodes: /extra/custom-nodes \ No newline at end of file From 33be3b121fa4fe1b44f34c7eb1e024ad79267945 Mon Sep 17 00:00:00 2001 From: John Mull Date: Mon, 27 Jan 2025 15:14:16 -0500 Subject: [PATCH 18/62] improve devcontainer --- .devcontainer/Dockerfile | 4 +++- .devcontainer/Dockerfile.base | 3 ++- .devcontainer/README.md | 2 +- .devcontainer/devcontainer.json | 6 +++++- .devcontainer/post-create.sh | 10 +++++++--- .devcontainer/welcome.txt | 9 --------- .vscode/launch.json | 1 + 7 files changed, 19 insertions(+), 16 deletions(-) delete mode 100644 .devcontainer/welcome.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c1103da5..f411de19 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,7 +3,6 @@ ENV PATH="/miniconda3/bin:${PATH}" # Remove RunPod logo, replace with Livepeer AI RUN head -n $(($lines - 2)) ~/.bashrc > ~/.bashrc -RUN echo -e "\ncat /workspace/.devcontainer/welcome.txt\n\n" >> /root/.bashrc RUN echo -e "echo -e '\nFor detailed documentation and guides, please visit:\n\033[1;34mhttps://pipelines.livepeer.org/docs\033[0m and \033[1;34mhttps://mirror.xyz.livepeer.eth/\033[0m\n\n'" >> /root/.bashrc WORKDIR / @@ -21,3 +20,6 @@ RUN source $NVM_DIR/nvm.sh \ # Add node and npm to path so the commands are available ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH + +# Create a symlink to the ComfyUI workspace +RUN ln -s /ComfyUI /workspace/ComfyUI diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index d2955bdf..4d27a434 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -31,7 +31,8 @@ WORKDIR /app RUN conda run -n comfyui python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI #Install ComfyStream requirements -RUN conda run -n comfystream pip install -r requirements.txt && pip install . +RUN conda run -n comfystream pip install -r requirements.txt +RUN conda run -n comfystream pip install . RUN conda run -n comfystream pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 RUN conda run -n comfystream python install.py --workspace /ComfyUI RUN rm -rf /app diff --git a/.devcontainer/README.md b/.devcontainer/README.md index dbf72090..f8150295 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -36,7 +36,7 @@ docker pull livepeer/comfyui-base:latest Create a directory to store the models ```sh -sudo mkdir -p /models/ComfyUI--models && sudo chown -R $USER /models/ComfyUI--models +sudo mkdir -p /models/ComfyUI--models/output && sudo chown -R $USER /models/ComfyUI--models ``` If you have a different path for models, ensure your `devcontainer.json` is properly configured to map the correct host path to your models. Here is an example configuration: diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4b992bb0..1683c7c8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,6 +15,9 @@ "vscode": { "settings": { "python.defaultInterpreterPath": "/workspace/miniconda3/envs/comfystream/bin/python", + "python.venvPath": "/workspace/miniconda3/envs", + "python.terminal.activateEnvInCurrentTerminal": false, + "python.terminal.activateEnvironment": true, "terminal.integrated.shellIntegration.enabled": true }, "extensions": [ @@ -37,7 +40,8 @@ "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", "mounts": [ // Use 'mounts' to map to comfyui models on the host - "source=/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached" + "source=${localEnv:SystemDrive}/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached", + "source=${localEnv:SystemDrive}/models/ComfyUI--models/output,target=/ComfyUI/output,type=bind,consistency=cached" ], "postCreateCommand": "bash .devcontainer/post-create.sh" } diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index d21bb443..e582ff94 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -5,9 +5,13 @@ if ! command -v conda &> /dev/null; then /miniconda3/bin/conda init bash fi -# Create a symlink to the ComfyUI workspace -if [ ! -d "/workspace/ComfyUI" ]; then - ln -s /ComfyUI /workspace/ComfyUI +cd /workspace/ui +if [ ! -d "node_modules" ]; then + npm install --legacy-peer-deps +fi +if [ ! -d ".env" ]; then + echo "NEXT_PUBLIC_DEFAULT_STREAM_URL=http://127.0.0.1:8889" > .env fi +cd /workspace /bin/bash \ No newline at end of file diff --git a/.devcontainer/welcome.txt b/.devcontainer/welcome.txt deleted file mode 100644 index eb1ac4f0..00000000 --- a/.devcontainer/welcome.txt +++ /dev/null @@ -1,9 +0,0 @@ - - -██╗ ██╗██╗ ██╗███████╗██████╗ ███████╗███████╗██████╗ █████╗ ██╗ -██║ ██║██║ ██║██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗ ██╔══██╗██║ -██║ ██║██║ ██║█████╗ ██████╔╝█████╗ █████╗ ██████╔╝ ███████║██║ -██║ ██║╚██╗ ██╔╝██╔══╝ ██╔═══╝ ██╔══╝ ██╔══╝ ██╔══██╗ ██╔══██║██║ -███████╗██║ ╚████╔╝ ███████╗██║ ███████╗███████╗██║ ██║██╗██║ ██║██║ -╚══════╝╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝ - diff --git a/.vscode/launch.json b/.vscode/launch.json index 809561e2..8aa9048f 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,6 +16,7 @@ }, "args": [ "--listen", + // "--disable-cuda-malloc" ], "python": "/miniconda3/envs/comfyui/bin/python" }, From 7ec0eac18ca802229468efcebc4abf666c269bac Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Tue, 28 Jan 2025 09:36:54 -0500 Subject: [PATCH 19/62] Remove LivePortrait since is caused errors, update nvm install, cleanup launch config --- .devcontainer/Dockerfile | 12 +++++++----- .devcontainer/Dockerfile.base | 1 + .vscode/launch.json | 14 ++++---------- configs/nodes.yaml | 5 ----- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f411de19..9fc67467 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -7,8 +7,8 @@ RUN echo -e "echo -e '\nFor detailed documentation and guides, please visit:\n\0 WORKDIR / # Install NVM -ENV NVM_DIR /root/.nvm -ENV NODE_VERSION 18.18.0 +ENV NVM_DIR=/root/.nvm +ENV NODE_VERSION=18.18.0 RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash # Install node and npm @@ -18,8 +18,10 @@ RUN source $NVM_DIR/nvm.sh \ && nvm use default # Add node and npm to path so the commands are available -ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules -ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH +ENV NODE_PATH=$NVM_DIR/v$NODE_VERSION/lib/node_modules +ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH + +# Set the current directory as the workspace +WORKDIR /workspace -# Create a symlink to the ComfyUI workspace RUN ln -s /ComfyUI /workspace/ComfyUI diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index 4d27a434..2108dc7d 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -25,6 +25,7 @@ COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils WORKDIR /ComfyUI RUN conda run -n comfyui pip install -r requirements.txt +RUN conda run -n comfyui pip install --upgrade tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 # Install custom nodes WORKDIR /app diff --git a/.vscode/launch.json b/.vscode/launch.json index 8aa9048f..d3e630ee 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,7 @@ }, "args": [ "--listen", - // "--disable-cuda-malloc" + // "--disable-cuda-malloc", ], "python": "/miniconda3/envs/comfyui/bin/python" }, @@ -26,27 +26,21 @@ "request": "launch", "cwd": "/workspace/server", "program": "app.py", - "console": "integratedTerminal", "args": [ "--workspace=/ComfyUI", "--media-ports=5678", "--host=0.0.0.0", - "--port=8889" + "--port=8889", + "--log-level=DEBUG", ], "python": "/miniconda3/envs/comfystream/bin/python" }, - { - "name": "Run ComfyStream UI", - "type": "chrome", - "request": "launch", - "url": "http://localhost:3000", - "webRoot": "/workspace/client" - }, { "name": "Run ComfyStream UI (Node.js)", "type": "node", "request": "launch", "cwd": "/workspace/ui", + "console": "integratedTerminal", "runtimeExecutable": "npm", "runtimeArgs": [ "run", diff --git a/configs/nodes.yaml b/configs/nodes.yaml index abf8808a..514c8f53 100644 --- a/configs/nodes.yaml +++ b/configs/nodes.yaml @@ -47,11 +47,6 @@ nodes: url: "https://github.com/pschroedl/ComfyUI-SAM2-Realtime.git" type: "vision" - comfyui-liveportraitkj: - name: "ComfyUI LivePortraitKJ" - url: "https://github.com/kijai/ComfyUI-LivePortraitKJ.git" - type: "portrait" - comfyui-load-image-url: name: "ComfyUI Load Image from URL" url: "https://github.com/tsogzark/ComfyUI-load-image-from-url.git" From 959eb62b2e269cfd406055551a8863bb5d5448f8 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Tue, 28 Jan 2025 09:54:11 -0500 Subject: [PATCH 20/62] add ports for dev --- .devcontainer/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 9fc67467..ca429f8d 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,9 @@ FROM eliteencoder/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" +EXPOSE 8188 +EXPOSE 8889 +EXPOSE 3000 +EXPOSE 1024-65535/udp # Remove RunPod logo, replace with Livepeer AI RUN head -n $(($lines - 2)) ~/.bashrc > ~/.bashrc From 474b77ddecef4eb862d7bdc131f1a2d9bce2f1bd Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Tue, 28 Jan 2025 10:12:28 -0500 Subject: [PATCH 21/62] reinstall nodes even if folder already exists --- src/comfystream/scripts/setup_nodes.py | 40 +++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/comfystream/scripts/setup_nodes.py b/src/comfystream/scripts/setup_nodes.py index 603eda6c..23d5d957 100755 --- a/src/comfystream/scripts/setup_nodes.py +++ b/src/comfystream/scripts/setup_nodes.py @@ -54,32 +54,32 @@ def install_custom_nodes(workspace_dir, config_path=None): dir_name = node_info['url'].split("/")[-1].replace(".git", "") node_path = custom_nodes_path / dir_name + print(f"Installing {node_info['name']}...") + + # Clone the repository if it doesn't already exist if not node_path.exists(): - print(f"Installing {node_info['name']}...") - - # Clone the repository cmd = ["git", "clone", node_info['url']] if 'branch' in node_info: cmd.extend(["-b", node_info['branch']]) subprocess.run(cmd, check=True) - - # Checkout specific commit if branch is a commit hash - if 'branch' in node_info and len(node_info['branch']) == 40: # SHA-1 hash length - subprocess.run(["git", "-C", dir_name, "checkout", node_info['branch']], check=True) - - # Install requirements if present - requirements_file = node_path / "requirements.txt" - if requirements_file.exists(): - subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True) - - # Install additional dependencies if specified - if 'dependencies' in node_info: - for dep in node_info['dependencies']: - subprocess.run([sys.executable, "-m", "pip", "install", dep], check=True) - - print(f"Installed {node_info['name']}") else: - print(f"{node_info['name']} already installed") + print(f"{node_info['name']} already exists, skipping clone.") + + # Checkout specific commit if branch is a commit hash + if 'branch' in node_info and len(node_info['branch']) == 40: # SHA-1 hash length + subprocess.run(["git", "-C", dir_name, "checkout", node_info['branch']], check=True) + + # Install requirements if present + requirements_file = node_path / "requirements.txt" + if requirements_file.exists(): + subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True) + + # Install additional dependencies if specified + if 'dependencies' in node_info: + for dep in node_info['dependencies']: + subprocess.run([sys.executable, "-m", "pip", "install", dep], check=True) + + print(f"Installed {node_info['name']}") def main(): args = parse_args() From 50ff5dd34f5d4acc19ddccc21ad4ba28b467e364 Mon Sep 17 00:00:00 2001 From: Elite Date: Tue, 28 Jan 2025 16:12:29 +0000 Subject: [PATCH 22/62] preinstall tensorrt 10.7 in comfystream to keep env parity with comfyui and comfystream --- .devcontainer/Dockerfile.base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index 2108dc7d..74db5ab3 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -32,9 +32,9 @@ WORKDIR /app RUN conda run -n comfyui python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI #Install ComfyStream requirements +RUN conda run -n comfystream pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 RUN conda run -n comfystream pip install -r requirements.txt RUN conda run -n comfystream pip install . -RUN conda run -n comfystream pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 RUN conda run -n comfystream python install.py --workspace /ComfyUI RUN rm -rf /app From fa0fafb848316dffabe5a33b799d04dfe9c91f1f Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Tue, 28 Jan 2025 21:10:14 -0500 Subject: [PATCH 23/62] change base container, use latest tensorrt, add launch config --- .devcontainer/Dockerfile | 12 +++------ .devcontainer/Dockerfile.base | 44 ++++++++++++++++++--------------- .devcontainer/devcontainer.json | 2 +- .vscode/launch.json | 17 ++++++++++++- 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ca429f8d..233c8c30 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,25 +1,21 @@ -FROM eliteencoder/comfyui-base:latest +FROM livepeer/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" EXPOSE 8188 EXPOSE 8889 EXPOSE 3000 EXPOSE 1024-65535/udp -# Remove RunPod logo, replace with Livepeer AI -RUN head -n $(($lines - 2)) ~/.bashrc > ~/.bashrc -RUN echo -e "echo -e '\nFor detailed documentation and guides, please visit:\n\033[1;34mhttps://pipelines.livepeer.org/docs\033[0m and \033[1;34mhttps://mirror.xyz.livepeer.eth/\033[0m\n\n'" >> /root/.bashrc - WORKDIR / # Install NVM ENV NVM_DIR=/root/.nvm ENV NODE_VERSION=18.18.0 -RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash +RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash # Install node and npm -RUN source $NVM_DIR/nvm.sh \ +RUN bash -c "source $NVM_DIR/nvm.sh \ && nvm install $NODE_VERSION \ && nvm alias default $NODE_VERSION \ - && nvm use default + && nvm use default" # Add node and npm to path so the commands are available ENV NODE_PATH=$NVM_DIR/v$NODE_VERSION/lib/node_modules diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index 74db5ab3..005166d0 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -1,11 +1,12 @@ -FROM runpod/pytorch:2.4.0-py3.11-cuda12.4.1-devel-ubuntu22.04 +FROM nvidia/cuda:12.2.2-cudnn8-devel-ubuntu22.04 # Install system dependencies -RUN apt-get update && apt-get install -y \ +RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y \ git \ wget \ nano \ socat \ + build-essential llvm tk-dev \ && rm -rf /var/lib/apt/lists/* # Install Miniconda (optional, if you want it ready at build-time) @@ -16,27 +17,30 @@ RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh - ENV PATH="/miniconda3/bin:${PATH}" RUN eval "$(/miniconda3/bin/conda shell.bash hook)" RUN conda create -n comfyui python=3.11 -y -RUN conda create -n comfystream python=3.11 -y -COPY . /app +# Clone ComfyUI RUN git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI -COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples -COPY ./nodes/tensor_utils /ComfyUI/custom_nodes/tensor_utils -WORKDIR /ComfyUI -RUN conda run -n comfyui pip install -r requirements.txt -RUN conda run -n comfyui pip install --upgrade tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 +# Copy ComfyStream files into ComfyUI +COPY requirements.txt /app/requirements.txt +COPY install.py /app/install.py +COPY setup.py /app/setup.py +COPY src /app/src +COPY configs /app/configs +COPY ./nodes/ /ComfyUI/custom_nodes/ +COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples # Install custom nodes -WORKDIR /app -RUN conda run -n comfyui python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI - -#Install ComfyStream requirements -RUN conda run -n comfystream pip install tensorrt-cu12-bindings==10.7.0 tensorrt-cu12-libs==10.7.0 -RUN conda run -n comfystream pip install -r requirements.txt -RUN conda run -n comfystream pip install . -RUN conda run -n comfystream python install.py --workspace /ComfyUI -RUN rm -rf /app - -# Configure no environment activation by default +RUN conda run -n comfyui pip install aiortc aiohttp requests tqdm pyyaml +RUN conda run -n comfyui --cwd /app python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI +RUN conda create -n comfystream --clone comfyui +RUN conda run -n comfyui --cwd /ComfyUI pip install -r requirements.txt + +# Install ComfyStream requirements +RUN conda run -n comfystream --cwd /app pip install -r requirements.txt +RUN conda run -n comfystream --cwd /app pip install . +RUN conda run -n comfystream --cwd /app python install.py --workspace /ComfyUI +RUN conda run -n comfystream pip install --upgrade tensorrt-cu12-bindings tensorrt-cu12-libs + +# # Configure no environment activation by default RUN conda config --set auto_activate_base false \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1683c7c8..307f5def 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -43,5 +43,5 @@ "source=${localEnv:SystemDrive}/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached", "source=${localEnv:SystemDrive}/models/ComfyUI--models/output,target=/ComfyUI/output,type=bind,consistency=cached" ], - "postCreateCommand": "bash .devcontainer/post-create.sh" + "postCreateCommand": ".devcontainer/post-create.sh" } diff --git a/.vscode/launch.json b/.vscode/launch.json index d3e630ee..c12c3da1 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,22 @@ }, "args": [ "--listen", - // "--disable-cuda-malloc", + ], + "python": "/miniconda3/envs/comfyui/bin/python" + }, + { + "name": "Run ComfyUI (disable-cuda-malloc)", + "type": "debugpy", + "request": "launch", + "cwd": "/ComfyUI", + "program": "main.py", + "purpose": ["debug-in-terminal"], + "env": { + "PYDEVD_DISABLE_FILE_VALIDATION": "1" + }, + "args": [ + "--listen", + "--disable-cuda-malloc", ], "python": "/miniconda3/envs/comfyui/bin/python" }, From 63fb3207ae2f66c33730b545ad9e9fbfe20a510b Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Wed, 29 Jan 2025 12:09:28 -0500 Subject: [PATCH 24/62] use default port for stream url --- .devcontainer/Dockerfile | 2 +- .devcontainer/README.md | 2 +- .devcontainer/devcontainer.json | 7 ++++--- .devcontainer/post-create.sh | 3 --- .vscode/launch.json | 15 +++++++++++++++ 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 233c8c30..082df1eb 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,7 +1,7 @@ FROM livepeer/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" EXPOSE 8188 -EXPOSE 8889 +EXPOSE 8888 EXPOSE 3000 EXPOSE 1024-65535/udp diff --git a/.devcontainer/README.md b/.devcontainer/README.md index f8150295..a5e50390 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -89,7 +89,7 @@ python main.py --listen --disable-cuda-malloc ### Starting ComfyStream ```sh -python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8889 +python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8888 ``` ## Additional Resources diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 307f5def..a3c0fa3b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,8 @@ { "name": "ComfyStream", "build": { - "dockerfile": "Dockerfile" + "dockerfile": "Dockerfile", + "context": "../" }, "runArgs": [ "--gpus=all", @@ -30,10 +31,10 @@ }, "appPort": [ "8188:8188", // ComfyUI - "8889:8889", // ComfyStream + "8888:8888", // ComfyStream "3000:3000" // ComfyStream UI (optional) ], - "forwardPorts": [8188, 8889, 3000], + "forwardPorts": [8188, 8888, 3000], // Use 'forwardPorts' to make a list of ports inside the container available locally. // Use 'mounts' to make a list of local folders available inside the container. "workspaceFolder": "/workspace", diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index e582ff94..c88f2d66 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -9,9 +9,6 @@ cd /workspace/ui if [ ! -d "node_modules" ]; then npm install --legacy-peer-deps fi -if [ ! -d ".env" ]; then - echo "NEXT_PUBLIC_DEFAULT_STREAM_URL=http://127.0.0.1:8889" > .env -fi cd /workspace /bin/bash \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c12c3da1..3e9cd79a 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -60,6 +60,21 @@ "runtimeArgs": [ "run", "dev" + ], + "serverReadyAction": { + "pattern": "listening on", + "uriFormat": "http://localhost:3000", + "action": "openExternally" + } + }, + ], "compounds": [ + { + "name": "Run ComfyStream and UI", + "type": "composite", + "stopAll": true, + "configurations": [ + "Run ComfyStream", + "Run ComfyStream UI (Node.js)" ] } ] From 2662b87f83c6ef440a7396c6fb10baabd39c43ae Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Wed, 29 Jan 2025 18:47:46 +0000 Subject: [PATCH 25/62] cleanup nested volume mount, move Dockerfile.base, update readme --- .devcontainer/README.md | 7 ++++--- .devcontainer/devcontainer.json | 2 +- {.devcontainer => docker}/Dockerfile.base | 0 3 files changed, 5 insertions(+), 4 deletions(-) rename {.devcontainer => docker}/Dockerfile.base (100%) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index a5e50390..6c3025e5 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -13,7 +13,7 @@ This guide will help you set up and run a development container for ComfyStream To build the base container, run the following command in your terminal: ```sh -docker build -f .devcontainer/Dockerfile.base -t livepeer/comfyui-base:latest . +docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . ``` ## Using the Pre-built Base Container @@ -34,9 +34,10 @@ docker pull livepeer/comfyui-base:latest ## Configuration -Create a directory to store the models +Create a directory to store the models and engines ```sh -sudo mkdir -p /models/ComfyUI--models/output && sudo chown -R $USER /models/ComfyUI--models +sudo mkdir -p /models/ComfyUI--models && sudo mkdir -p /models/ComfyUI--output +sudo chown -R $USER /models/ComfyUI--output && sudo chown -R $USER /models/ComfyUI--output ``` If you have a different path for models, ensure your `devcontainer.json` is properly configured to map the correct host path to your models. Here is an example configuration: diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a3c0fa3b..a3eaf3a4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -42,7 +42,7 @@ "mounts": [ // Use 'mounts' to map to comfyui models on the host "source=${localEnv:SystemDrive}/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached", - "source=${localEnv:SystemDrive}/models/ComfyUI--models/output,target=/ComfyUI/output,type=bind,consistency=cached" + "source=${localEnv:SystemDrive}/models/ComfyUI--output,target=/ComfyUI/output,type=bind,consistency=cached" ], "postCreateCommand": ".devcontainer/post-create.sh" } diff --git a/.devcontainer/Dockerfile.base b/docker/Dockerfile.base similarity index 100% rename from .devcontainer/Dockerfile.base rename to docker/Dockerfile.base From dc0d1cf41e6ad8cae3958393298a7db919930855 Mon Sep 17 00:00:00 2001 From: Elite Date: Wed, 29 Jan 2025 19:31:52 +0000 Subject: [PATCH 26/62] Update docs --- README.md | 13 +++++- src/comfystream/scripts/README.md | 73 ++++--------------------------- 2 files changed, 21 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 33e66886..ef2d61ef 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,17 @@ This repo also includes a WebRTC server and UI that uses comfystream to support ## Quick Start -The fastest way to get started is to follow [this tutorial](https://livepeer.notion.site/ComfyStream-Dev-Environment-Setup-15d0a3485687802e9528d26050142d82) by @ryanontheinside. +### Docker DevContainer +Refer to [.devcontainer/README.md](.devcontainer/README.md) to setup ComfyStream in a devcontainer using a pre-configured ComfyUI docker environment. + +For other installation options, refer to [Install ComfyUI and ComfyStream](https://pipelines.livepeer.org/docs/technical/install/local-testing) in the Livepeer pipelines documentation. + +## Download Models + +Refer to [src/comfystream/scripts/README.md](src/comfystream/scripts/README.md) for instructions to download commonly used models. + + + For additional information, refer to the remaining sections below. @@ -189,3 +199,4 @@ This project has been tested locally successfully with the following setup: - Driver: 550.127.05 - CUDA: 12.5 - torch: 2.5.1+cu121 + diff --git a/src/comfystream/scripts/README.md b/src/comfystream/scripts/README.md index 61d4e4ea..dc9650e6 100644 --- a/src/comfystream/scripts/README.md +++ b/src/comfystream/scripts/README.md @@ -1,34 +1,25 @@ -# ComfyStream Setup Scripts - -This directory contains scripts for setting up ComfyUI nodes and models. The setup is split into two main scripts: +# ComfyStream Model and Node Install Scripts ## Setup Scripts -1. **setup-comfyui-nodes**: Installs custom ComfyUI nodes -2. **setup-comfyui-models**: Downloads model files and weights +1. **setup_nodes.py**: Installs custom ComfyUI nodes +2. **setup_models.py**: Downloads model files and weights ## Configuration Files - `configs/nodes.yaml`: Defines custom nodes to install - `configs/models.yaml`: Defines model files to download -- `pyproject.toml`: Package dependencies and build settings ## Basic Usage +From the repository root: ```bash # Install both nodes and models (default workspace: ~/comfyui) -setup-comfyui-nodes -setup-comfyui-models - -# Use custom workspace -setup-comfyui-nodes --workspace /path/to/workspace -setup-comfyui-models --workspace /path/to/workspace - -# Using environment variable -export COMFY_UI_WORKSPACE=/path/to/workspace -setup-comfyui-nodes -setup-comfyui-models +python src/comfystream/scripts/setup_nodes.py --workspace /path/to/workspace +python src/comfystream/scripts/setup_models.py --workspace /path/to/workspace ``` +> The `--workspace` flag is optional and will default to `$COMFY_UI_WORKSPACE` or `~/comfyui` + ## Configuration Examples @@ -66,54 +57,8 @@ workspace/ └── tensorrt/ ``` -## Script Details - -### setup-comfyui-nodes -- Clones node repositories from GitHub -- Installs node dependencies -- Creates custom_nodes directory -- Sets up environment variables - -### setup-comfyui-models -- Downloads model weights -- Downloads additional files (configs, etc) -- Creates model directory structure -- Handles file verification - ## Environment Variables - `COMFY_UI_WORKSPACE`: Base directory for installation -- `PYTHONPATH`: Set to workspace directory +- `PYTHONPATH`: Defaults to workspace directory - `CUSTOM_NODES_PATH`: Custom nodes directory - -## Notes - -- Run both scripts to set up a complete environment -- Scripts can be run independently -- Both scripts use the same workspace configuration -- Models are only downloaded if they don't exist -- Node repositories are only cloned if not present -- Dependencies are installed automatically - -## Troubleshooting - -If you encounter issues: - -1. Check if workspace directory is writable -2. Verify config files exist in configs/ -3. Ensure Git is installed for node setup -4. Check network connection for downloads -5. Verify Python environment has required packages - -## Testing - -Run the installation tests: -```bash -python -m unittest tests/test_installation.py -``` - -This will verify: -- Directory structure -- Node installation -- Model downloads -- Environment setup \ No newline at end of file From 52aca1746c106996fd7da7ce4feb1b5aaf7982ee Mon Sep 17 00:00:00 2001 From: Elite Date: Wed, 29 Jan 2025 19:40:03 +0000 Subject: [PATCH 27/62] udpate docs --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ef2d61ef..480c4534 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,11 @@ Refer to [.devcontainer/README.md](.devcontainer/README.md) to setup ComfyStream For other installation options, refer to [Install ComfyUI and ComfyStream](https://pipelines.livepeer.org/docs/technical/install/local-testing) in the Livepeer pipelines documentation. -## Download Models - -Refer to [src/comfystream/scripts/README.md](src/comfystream/scripts/README.md) for instructions to download commonly used models. - - +For additional information, refer to the remaining sections below. +## Download Models -For additional information, refer to the remaining sections below. +Refer to [src/comfystream/scripts/README.md](src/comfystream/scripts/README.md) for instructions to download commonly used models. ## Install package From 13805619da2ae667fb28a9525446439fec340b15 Mon Sep 17 00:00:00 2001 From: Elite Date: Wed, 29 Jan 2025 20:12:01 +0000 Subject: [PATCH 28/62] fix port in launch.json --- .vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3e9cd79a..6f8e1170 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -45,8 +45,8 @@ "--workspace=/ComfyUI", "--media-ports=5678", "--host=0.0.0.0", - "--port=8889", - "--log-level=DEBUG", + "--port=8888", + "--log-level=DEBUG", ], "python": "/miniconda3/envs/comfystream/bin/python" }, From 951d56cdf938f69e75975d1cef77685d8b6a0db9 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Wed, 29 Jan 2025 16:21:54 -0500 Subject: [PATCH 29/62] fix docs typo --- .devcontainer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 6c3025e5..e93a55c6 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -37,7 +37,7 @@ docker pull livepeer/comfyui-base:latest Create a directory to store the models and engines ```sh sudo mkdir -p /models/ComfyUI--models && sudo mkdir -p /models/ComfyUI--output -sudo chown -R $USER /models/ComfyUI--output && sudo chown -R $USER /models/ComfyUI--output +sudo chown -R $USER /models/ComfyUI--models && sudo chown -R $USER /models/ComfyUI--output ``` If you have a different path for models, ensure your `devcontainer.json` is properly configured to map the correct host path to your models. Here is an example configuration: From ac17a8ca336f79310cb7685219ffbfce1c830397 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Wed, 29 Jan 2025 16:33:52 -0500 Subject: [PATCH 30/62] move symbolic link to post-create.sh --- .devcontainer/Dockerfile | 5 ----- .devcontainer/post-create.sh | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 082df1eb..a0325cbb 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -20,8 +20,3 @@ RUN bash -c "source $NVM_DIR/nvm.sh \ # Add node and npm to path so the commands are available ENV NODE_PATH=$NVM_DIR/v$NODE_VERSION/lib/node_modules ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH - -# Set the current directory as the workspace -WORKDIR /workspace - -RUN ln -s /ComfyUI /workspace/ComfyUI diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index c88f2d66..bd0a4a22 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -5,10 +5,16 @@ if ! command -v conda &> /dev/null; then /miniconda3/bin/conda init bash fi +# Install npm packages if needed cd /workspace/ui if [ ! -d "node_modules" ]; then npm install --legacy-peer-deps fi +# Create a symlink to the ComfyUI workspace +if [ ! -d "/workspace/ComfyUI" ]; then + ln -s /ComfyUI /workspace/ComfyUI +fi + cd /workspace /bin/bash \ No newline at end of file From 91327dedf76e77a79fe30bc4ee72e9b0fb113f5b Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Thu, 30 Jan 2025 22:13:16 +0000 Subject: [PATCH 31/62] change comfystream temp folder from /app to /comfystream --- docker/Dockerfile.base | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 005166d0..8da0ce98 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -22,24 +22,24 @@ RUN conda create -n comfyui python=3.11 -y RUN git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI # Copy ComfyStream files into ComfyUI -COPY requirements.txt /app/requirements.txt -COPY install.py /app/install.py -COPY setup.py /app/setup.py -COPY src /app/src -COPY configs /app/configs +COPY requirements.txt /comfystream/requirements.txt +COPY install.py /comfystream/install.py +COPY setup.py /comfystream/setup.py +COPY src /comfystream/src +COPY configs /comfystream/configs COPY ./nodes/ /ComfyUI/custom_nodes/ COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples # Install custom nodes RUN conda run -n comfyui pip install aiortc aiohttp requests tqdm pyyaml -RUN conda run -n comfyui --cwd /app python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI +RUN conda run -n comfyui --cwd /comfystream python src/comfystream/scripts/setup_nodes.py --workspace /ComfyUI RUN conda create -n comfystream --clone comfyui RUN conda run -n comfyui --cwd /ComfyUI pip install -r requirements.txt # Install ComfyStream requirements -RUN conda run -n comfystream --cwd /app pip install -r requirements.txt -RUN conda run -n comfystream --cwd /app pip install . -RUN conda run -n comfystream --cwd /app python install.py --workspace /ComfyUI +RUN conda run -n comfystream --cwd /comfystream pip install -r requirements.txt +RUN conda run -n comfystream --cwd /comfystream pip install . +RUN conda run -n comfystream --cwd /comfystream python install.py --workspace /ComfyUI RUN conda run -n comfystream pip install --upgrade tensorrt-cu12-bindings tensorrt-cu12-libs # # Configure no environment activation by default From e25c58bd3028d7cc6af71fc20f50e824ffd34481 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 31 Jan 2025 16:51:00 +0100 Subject: [PATCH 32/62] docs: improve dev docs formatting This commit applies some improvements to the developer docs. --- .devcontainer/README.md | 31 ++++++++++++++++--------------- README.md | 3 ++- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index e93a55c6..bd43d692 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -22,19 +22,19 @@ Most users will configure host paths for models in `devcontainer.json` and use t 1. Pull the pre-built base container: -```sh -docker pull livepeer/comfyui-base:latest -``` + ```sh + docker pull livepeer/comfyui-base:latest + ``` 2. Configure the host paths for models in the `devcontainer.json` file. - 3. Re-open the workspace in the dev container using VS Code: - - Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS). - - Select `Remote-Containers: Reopen in Container`. + - Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS). + - Select `Remote-Containers: Reopen in Container`. ## Configuration -Create a directory to store the models and engines +Create a directory to store the models and engines: + ```sh sudo mkdir -p /models/ComfyUI--models && sudo mkdir -p /models/ComfyUI--output sudo chown -R $USER /models/ComfyUI--models && sudo chown -R $USER /models/ComfyUI--output @@ -44,12 +44,10 @@ If you have a different path for models, ensure your `devcontainer.json` is prop ```json { - "name": "ComfyStream Dev Container", - "image": "livepeer/comfyui-base", - "mounts": [ - "source=/path/to/your/models,target=/ComfyUI/models,type=bind" - ], - "workspaceFolder": "/workspace" + "name": "ComfyStream Dev Container", + "image": "livepeer/comfyui-base", + "mounts": ["source=/path/to/your/models,target=/ComfyUI/models,type=bind"], + "workspaceFolder": "/workspace" } ``` @@ -63,6 +61,7 @@ python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` By following these steps, you should be able to set up and run your development container for ComfyStream efficiently. + ## Building the DepthAnything Engine 1. Run the **export_trt.py** script from the directory of the onnx file: @@ -72,17 +71,19 @@ cd /ComfyUI/models/tensorrt/depth-anything python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py ``` -**Note**: You may use either conda environment for this step +> [!NOTE] +> You may use either conda environment for this step. ### Starting ComfyUI -When building engines, you should start ComfyUI normally. +When building engines, you should start ComfyUI normally. ```sh python main.py --listen ``` When running TensorRT engine enabled workflows, you should use the extra flag as shown below: + ```sh python main.py --listen --disable-cuda-malloc ``` diff --git a/README.md b/README.md index 480c4534..f461f940 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ This repo also includes a WebRTC server and UI that uses comfystream to support - [comfystream](#comfystream) - [Quick Start](#quick-start) + - [Docker DevContainer](#docker-devcontainer) + - [Download Models](#download-models) - [Install package](#install-package) - [Custom Nodes](#custom-nodes) - [Usage](#usage) @@ -196,4 +198,3 @@ This project has been tested locally successfully with the following setup: - Driver: 550.127.05 - CUDA: 12.5 - torch: 2.5.1+cu121 - From ba11da74f77b828b4051416e727f4af163369811 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 18:01:20 +0000 Subject: [PATCH 33/62] update readme, model paths --- .devcontainer/README.md | 90 +++++++++++++++++++++------------ .devcontainer/devcontainer.json | 7 ++- .vscode/launch.json | 17 +------ 3 files changed, 62 insertions(+), 52 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index bd43d692..9adb91dd 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -8,61 +8,69 @@ This guide will help you set up and run a development container for ComfyStream - [Visual Studio Code](https://code.visualstudio.com/) - [VS Code Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) -## Building the Base Container -To build the base container, run the following command in your terminal: +## Download or Build Base Docker Image +The `livepeer/comfyui-base:latest` image contains ComfyUI provides a ComfyUI workspace for comfystream development. You can either pull the base docker image from dockerhub or build it: + +- Pull from Dockerhub: +```sh +docker pull livepeer/comfyui-base:latest +``` +- Build the base image: ```sh docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . ``` -## Using the Pre-built Base Container - -Most users will configure host paths for models in `devcontainer.json` and use the pre-built base container. Follow these steps: - -1. Pull the pre-built base container: - - ```sh - docker pull livepeer/comfyui-base:latest - ``` - -2. Configure the host paths for models in the `devcontainer.json` file. -3. Re-open the workspace in the dev container using VS Code: - - Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS). - - Select `Remote-Containers: Reopen in Container`. - -## Configuration - -Create a directory to store the models and engines: +## Host Configuration +On your host system, create directories to store models and engines: ```sh -sudo mkdir -p /models/ComfyUI--models && sudo mkdir -p /models/ComfyUI--output -sudo chown -R $USER /models/ComfyUI--models && sudo chown -R $USER /models/ComfyUI--output +sudo mkdir -p ~/models/ComfyUI--models && sudo mkdir -p ~/models/ComfyUI--output ``` +> **Note:** This step should be ran on your host machine before attempting to start the container + -If you have a different path for models, ensure your `devcontainer.json` is properly configured to map the correct host path to your models. Here is an example configuration: +If you would like to use a different path to store models, open `devcontainer.json` and update the `source` to map to the correct paths to your host system. Here is an example configuration: ```json { - "name": "ComfyStream Dev Container", - "image": "livepeer/comfyui-base", - "mounts": ["source=/path/to/your/models,target=/ComfyUI/models,type=bind"], - "workspaceFolder": "/workspace" + "mounts": [ + "source=/path/to/your/model-files,target=/ComfyUI/models/ComfyUI--models,type=bind", + "source=/path/to/your/output-files,target=/ComfyUI/models/ComfyUI--output,type=bind" + ], } ``` -Replace `/path/to/your/models` with the actual path to your models on the host machine. +Replace `/path/to/your/model-files` and `path/to/your/output-files` with the path to your `models` and `output` folders on your host machine. + +## Dev Container Setup + +1. Clone the `comfystream` repository and open it in VS Code. +2. From VS Code, reload the folder as a devcontainer: + - Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS). + - Select `Remote-Containers: Reopen in Container`. + ### Download models +Download models to run the example workflows: ```sh cd /workspace python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` +For more info about configuring model downloads, see [src/comfystream/scripts/README.md](./src/comfystream/scripts/README.md) By following these steps, you should be able to set up and run your development container for ComfyStream efficiently. -## Building the DepthAnything Engine +### Building the DepthAnything Engine + +After downloading models, it is necessary to compile TensorRT engines for the example workflow. + +> [!NOTE] +> Engine files must be compiled on the same GPU hardware/architecture that are used on. This step must be ran manually after starting the devcontainer +> + 1. Run the **export_trt.py** script from the directory of the onnx file: @@ -74,23 +82,42 @@ python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py > [!NOTE] > You may use either conda environment for this step. -### Starting ComfyUI +## Debugging ComfyStream and ComfyUI + +The `launch.json` includes sample launch configurations for ComfyStream and ComfyUI. -When building engines, you should start ComfyUI normally. +## Setting the Python Environment +Conda is not initited in the bash shell to provide better interoperabiltiy with VS Code Shell Integration. + +To launch a new terminal in either `comfystream` or `comfyui` environment: +1. From VSCode, press `Ctrl-Shift-P` +2. Choose `Select Python Interpreter` +3. Select `comfystream` or `comfyui` +4. Open a new terminal, you will see the environment name to the left of the bash terminal. + +> [!NOTE] NOTE For more information, see [Python environments in VS Code](https://code.visualstudio.com/docs/python/environments) + + + +### Starting ComfyUI +Start ComfyUI from the default `/workspace`: ```sh +cd /workspace/ComfyUI python main.py --listen ``` When running TensorRT engine enabled workflows, you should use the extra flag as shown below: ```sh +cd /workspace/ComfyUI python main.py --listen --disable-cuda-malloc ``` ### Starting ComfyStream ```sh +cd /workspace python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8888 ``` @@ -98,4 +125,3 @@ python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --po - [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers) - [Docker Documentation](https://docs.docker.com/) -- [Activate-Environments-in-Terminal-Using-Environment-Variables](https://github.com/microsoft/vscode-python/wiki/Activate-Environments-in-Terminal-Using-Environment-Variables) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a3eaf3a4..dbbf00d9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,8 +7,7 @@ "context": "../" }, "runArgs": [ - "--gpus=all", - "--workdir", "/workspace" + "--gpus=all" ], // Features to add to the dev container. More info: https://containers.dev/features. // Configure tool-specific properties. @@ -41,8 +40,8 @@ "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", "mounts": [ // Use 'mounts' to map to comfyui models on the host - "source=${localEnv:SystemDrive}/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached", - "source=${localEnv:SystemDrive}/models/ComfyUI--output,target=/ComfyUI/output,type=bind,consistency=cached" + "source=${localEnv:HOME}/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached", + "source=${localEnv:HOME}/models/ComfyUI--output,target=/ComfyUI/output,type=bind,consistency=cached" ], "postCreateCommand": ".devcontainer/post-create.sh" } diff --git a/.vscode/launch.json b/.vscode/launch.json index 6f8e1170..355f767a 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,21 +14,6 @@ "env": { "PYDEVD_DISABLE_FILE_VALIDATION": "1" }, - "args": [ - "--listen", - ], - "python": "/miniconda3/envs/comfyui/bin/python" - }, - { - "name": "Run ComfyUI (disable-cuda-malloc)", - "type": "debugpy", - "request": "launch", - "cwd": "/ComfyUI", - "program": "main.py", - "purpose": ["debug-in-terminal"], - "env": { - "PYDEVD_DISABLE_FILE_VALIDATION": "1" - }, "args": [ "--listen", "--disable-cuda-malloc", @@ -46,7 +31,7 @@ "--media-ports=5678", "--host=0.0.0.0", "--port=8888", - "--log-level=DEBUG", + "--log-level=DEBUG", ], "python": "/miniconda3/envs/comfystream/bin/python" }, From 1dfa9b309232145a57303a1e6fbb117d85169845 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 18:03:14 +0000 Subject: [PATCH 34/62] fix typo in README.md --- .devcontainer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 9adb91dd..417c888c 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -11,7 +11,7 @@ This guide will help you set up and run a development container for ComfyStream ## Download or Build Base Docker Image -The `livepeer/comfyui-base:latest` image contains ComfyUI provides a ComfyUI workspace for comfystream development. You can either pull the base docker image from dockerhub or build it: +The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: - Pull from Dockerhub: ```sh From 0af70d6a5b99f2db741ec807fd4e37518c3a2b26 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 18:06:52 +0000 Subject: [PATCH 35/62] add detail to readme --- .devcontainer/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 417c888c..60fd2157 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -101,13 +101,13 @@ To launch a new terminal in either `comfystream` or `comfyui` environment: ### Starting ComfyUI -Start ComfyUI from the default `/workspace`: +Start ComfyUI: ```sh cd /workspace/ComfyUI python main.py --listen ``` -When running TensorRT engine enabled workflows, you should use the extra flag as shown below: +When using TensorRT engine enabled workflows, you should include the `---disable-cuda-malloc` flag as shown below: ```sh cd /workspace/ComfyUI From 6dd0d3525de4c05f57d4cb25d4083ecebe90c000 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 18:51:22 +0000 Subject: [PATCH 36/62] fix mkdir in readme --- .devcontainer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 60fd2157..f7757b10 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -26,7 +26,7 @@ docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . On your host system, create directories to store models and engines: ```sh -sudo mkdir -p ~/models/ComfyUI--models && sudo mkdir -p ~/models/ComfyUI--output +mkdir -p ~/models/ComfyUI--models && mkdir -p ~/models/ComfyUI--output ``` > **Note:** This step should be ran on your host machine before attempting to start the container From 737ef2b8d4a1a3ca7edcf75057908af2bd05b33b Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 14:06:08 -0500 Subject: [PATCH 37/62] move conda init bash to base container --- .devcontainer/Dockerfile | 1 + .devcontainer/post-create.sh | 5 ----- docker/Dockerfile.base | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a0325cbb..a0fda1e9 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -20,3 +20,4 @@ RUN bash -c "source $NVM_DIR/nvm.sh \ # Add node and npm to path so the commands are available ENV NODE_PATH=$NVM_DIR/v$NODE_VERSION/lib/node_modules ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH +RUN conda init bash \ No newline at end of file diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index bd0a4a22..0a69bb8a 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -1,10 +1,5 @@ #!/bin/bash -# Initialize conda if needed -if ! command -v conda &> /dev/null; then - /miniconda3/bin/conda init bash -fi - # Install npm packages if needed cd /workspace/ui if [ ! -d "node_modules" ]; then diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 8da0ce98..db1c77ee 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -43,4 +43,5 @@ RUN conda run -n comfystream --cwd /comfystream python install.py --workspace /C RUN conda run -n comfystream pip install --upgrade tensorrt-cu12-bindings tensorrt-cu12-libs # # Configure no environment activation by default -RUN conda config --set auto_activate_base false \ No newline at end of file +RUN conda config --set auto_activate_base false +RUN conda init bash \ No newline at end of file From af8804ec4cbc2f5c965251804a38be342c5faeb3 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 31 Jan 2025 20:09:34 +0100 Subject: [PATCH 38/62] docs: apply some code and doc refactoring This commit fixes some linting errors and refractors the developer docs a bit to make it more clear. --- .devcontainer/Dockerfile | 1 + .devcontainer/README.md | 78 +++++++++++-------- docker/Dockerfile.base | 2 +- src/comfystream/scripts/README.md | 25 +++--- src/comfystream/scripts/requirements.txt | 2 +- src/comfystream/scripts/setup_models.py | 17 ++-- src/comfystream/scripts/setup_nodes.py | 26 +++---- ...epth-anything-v2-trt-example-workflow.json | 2 +- workflows/depth-bg-black-gpu-workflow.json | 2 +- workflows/depth-bg-blur-gpu-workflow.json | 2 +- workflows/liveportait.json | 2 +- .../load-preview-image-example-workflow.json | 2 +- workflows/tensor-utils-example-workflow.json | 2 +- workflows/ui/1 - Build ONNX.json | 2 +- .../ui/2 - Build Static TensorRT Engine.json | 2 +- .../ui/3 - SD 1.5 TensorRT workflow.json | 2 +- 16 files changed, 90 insertions(+), 79 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a0fda1e9..43343fed 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,6 +6,7 @@ EXPOSE 3000 EXPOSE 1024-65535/udp WORKDIR / + # Install NVM ENV NVM_DIR=/root/.nvm ENV NODE_VERSION=18.18.0 diff --git a/.devcontainer/README.md b/.devcontainer/README.md index f7757b10..663741e6 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -8,37 +8,52 @@ This guide will help you set up and run a development container for ComfyStream - [Visual Studio Code](https://code.visualstudio.com/) - [VS Code Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +## Host Setup +### Clone the Repository -## Download or Build Base Docker Image -The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: +First, clone the `comfystream` repository: -- Pull from Dockerhub: ```sh -docker pull livepeer/comfyui-base:latest +clone https://github.com/yondonfu/comfystream.git +cd comfystream ``` + +### Download or Build Base Docker Image + +The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: + +- Pull from Dockerhub: + + ```sh + docker pull livepeer/comfyui-base:latest + ``` + - Build the base image: -```sh -docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . -``` -## Host Configuration -On your host system, create directories to store models and engines: + ```sh + docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . + ``` + +### Host Configuration + +On your **host** system, create directories to store models and engines: ```sh mkdir -p ~/models/ComfyUI--models && mkdir -p ~/models/ComfyUI--output ``` -> **Note:** This step should be ran on your host machine before attempting to start the container +> [!NOTE] +> This step should be ran on your host machine before attempting to start the container. -If you would like to use a different path to store models, open `devcontainer.json` and update the `source` to map to the correct paths to your host system. Here is an example configuration: +If you would like to use a different path to store models, open `.devcontainer/devcontainer.json` file and update the `source` to map to the correct paths to your host system. Here is an example configuration: ```json { "mounts": [ - "source=/path/to/your/model-files,target=/ComfyUI/models/ComfyUI--models,type=bind", - "source=/path/to/your/output-files,target=/ComfyUI/models/ComfyUI--output,type=bind" - ], + "source=/path/to/your/model-files,target=/ComfyUI/models/ComfyUI--models,type=bind", + "source=/path/to/your/output-files,target=/ComfyUI/models/ComfyUI--output,type=bind" + ] } ``` @@ -46,51 +61,48 @@ Replace `/path/to/your/model-files` and `path/to/your/output-files` with the pat ## Dev Container Setup -1. Clone the `comfystream` repository and open it in VS Code. +1. Open the `comfystream` repository in VS Code. 2. From VS Code, reload the folder as a devcontainer: - Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS). - Select `Remote-Containers: Reopen in Container`. - ### Download models -Download models to run the example workflows: + +From within the **dev container**, download models to run the example workflows: ```sh cd /workspace python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` + For more info about configuring model downloads, see [src/comfystream/scripts/README.md](./src/comfystream/scripts/README.md) By following these steps, you should be able to set up and run your development container for ComfyStream efficiently. ### Building the DepthAnything Engine -After downloading models, it is necessary to compile TensorRT engines for the example workflow. +After downloading models, it is necessary to compile TensorRT engines for the example workflow. > [!NOTE] -> Engine files must be compiled on the same GPU hardware/architecture that are used on. This step must be ran manually after starting the devcontainer -> - +> Engine files must be compiled on the same GPU hardware/architecture that they will be used on. This step must be run manually after starting the devcontainer. You may use either conda environment for this step. 1. Run the **export_trt.py** script from the directory of the onnx file: -```sh -cd /ComfyUI/models/tensorrt/depth-anything -python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py -``` - -> [!NOTE] -> You may use either conda environment for this step. + ```sh + cd /ComfyUI/models/tensorrt/depth-anything + python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py + ``` ## Debugging ComfyStream and ComfyUI -The `launch.json` includes sample launch configurations for ComfyStream and ComfyUI. +The `launch.json` includes sample launch configurations for ComfyStream and ComfyUI. ## Setting the Python Environment -Conda is not initited in the bash shell to provide better interoperabiltiy with VS Code Shell Integration. +Conda is not initiated in the bash shell to provide better interoperability with VS Code Shell Integration. + +To launch a new terminal in either `comfystream` or `comfyui` environment: -To launch a new terminal in either `comfystream` or `comfyui` environment: 1. From VSCode, press `Ctrl-Shift-P` 2. Choose `Select Python Interpreter` 3. Select `comfystream` or `comfyui` @@ -98,10 +110,10 @@ To launch a new terminal in either `comfystream` or `comfyui` environment: > [!NOTE] NOTE For more information, see [Python environments in VS Code](https://code.visualstudio.com/docs/python/environments) - - ### Starting ComfyUI + Start ComfyUI: + ```sh cd /workspace/ComfyUI python main.py --listen diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index db1c77ee..239d0640 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -44,4 +44,4 @@ RUN conda run -n comfystream pip install --upgrade tensorrt-cu12-bindings tensor # # Configure no environment activation by default RUN conda config --set auto_activate_base false -RUN conda init bash \ No newline at end of file +RUN conda init bash diff --git a/src/comfystream/scripts/README.md b/src/comfystream/scripts/README.md index dc9650e6..3b5cf92c 100644 --- a/src/comfystream/scripts/README.md +++ b/src/comfystream/scripts/README.md @@ -2,28 +2,30 @@ ## Setup Scripts -1. **setup_nodes.py**: Installs custom ComfyUI nodes -2. **setup_models.py**: Downloads model files and weights +1. **setup_nodes.py**: Installs custom ComfyUI nodes. +2. **setup_models.py**: Downloads model files and weights. ## Configuration Files -- `configs/nodes.yaml`: Defines custom nodes to install -- `configs/models.yaml`: Defines model files to download +- `configs/nodes.yaml`: Defines custom nodes to install. +- `configs/models.yaml`: Defines model files to download. ## Basic Usage From the repository root: + ```bash # Install both nodes and models (default workspace: ~/comfyui) python src/comfystream/scripts/setup_nodes.py --workspace /path/to/workspace python src/comfystream/scripts/setup_models.py --workspace /path/to/workspace ``` -> The `--workspace` flag is optional and will default to `$COMFY_UI_WORKSPACE` or `~/comfyui` +> The `--workspace` flag is optional and will default to `$COMFY_UI_WORKSPACE` or `~/comfyui`. ## Configuration Examples ### Custom Nodes (nodes.yaml) + ```yaml nodes: comfyui-tensorrt: @@ -35,6 +37,7 @@ nodes: ``` ### Models (models.yaml) + ```yaml models: dreamshaper-v8: @@ -46,15 +49,15 @@ models: ## Directory Structure -``` +```sh workspace/ ├── custom_nodes/ # Custom nodes installed by setup-comfyui-nodes └── models/ # Models downloaded by setup-comfyui-models - ├── checkpoints/ - ├── controlnet/ - ├── unet/ - ├── vae/ - └── tensorrt/ + ├── checkpoints/ + ├── controlnet/ + ├── unet/ + ├── vae/ + └── tensorrt/ ``` ## Environment Variables diff --git a/src/comfystream/scripts/requirements.txt b/src/comfystream/scripts/requirements.txt index ca92fc8f..21e11cfc 100644 --- a/src/comfystream/scripts/requirements.txt +++ b/src/comfystream/scripts/requirements.txt @@ -1,3 +1,3 @@ requests tqdm -pyyaml \ No newline at end of file +pyyaml diff --git a/src/comfystream/scripts/setup_models.py b/src/comfystream/scripts/setup_models.py index 6d62c163..01ef1e47 100644 --- a/src/comfystream/scripts/setup_models.py +++ b/src/comfystream/scripts/setup_models.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 import os -import sys from pathlib import Path import requests from tqdm import tqdm @@ -10,7 +9,7 @@ def parse_args(): parser = argparse.ArgumentParser(description='Setup ComfyUI models') - parser.add_argument('--workspace', + parser.add_argument('--workspace', default=os.environ.get('COMFY_UI_WORKSPACE', os.path.expanduser('~/comfyui')), help='ComfyUI workspace directory (default: ~/comfyui or $COMFY_UI_WORKSPACE)') return parser.parse_args() @@ -19,13 +18,13 @@ def download_file(url, destination, description=None): """Download a file with progress bar""" response = requests.get(url, stream=True) total_size = int(response.headers.get('content-length', 0)) - + desc = description or os.path.basename(destination) progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True, desc=desc) - + destination = Path(destination) destination.parent.mkdir(parents=True, exist_ok=True) - + with open(destination, 'wb') as file: for data in response.iter_content(chunk_size=1024): size = file.write(data) @@ -48,7 +47,7 @@ def setup_model_files(workspace_dir, config_path=None): models_path = workspace_dir / "models" base_path = workspace_dir - for model_id, model_info in config['models'].items(): + for _, model_info in config['models'].items(): # Determine the full path based on whether it's in custom_nodes or models if model_info['path'].startswith('custom_nodes/'): full_path = base_path / model_info['path'] @@ -82,7 +81,7 @@ def setup_directories(workspace_dir): workspace_dir.mkdir(parents=True, exist_ok=True) models_dir = workspace_dir / "models" models_dir.mkdir(parents=True, exist_ok=True) - + # Create model subdirectories model_dirs = [ "checkpoints/SD1.5", @@ -97,9 +96,9 @@ def setup_directories(workspace_dir): def main(): args = parse_args() workspace_dir = Path(args.workspace) - + setup_directories(workspace_dir) setup_model_files(workspace_dir) if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/src/comfystream/scripts/setup_nodes.py b/src/comfystream/scripts/setup_nodes.py index 23d5d957..2e4eb7ed 100755 --- a/src/comfystream/scripts/setup_nodes.py +++ b/src/comfystream/scripts/setup_nodes.py @@ -3,11 +3,7 @@ import subprocess import sys from pathlib import Path -import shutil -import requests -from tqdm import tqdm import yaml -import pkg_resources import argparse # Change relative import to absolute import @@ -16,7 +12,7 @@ def parse_args(): parser = argparse.ArgumentParser(description='Setup ComfyUI nodes and models') - parser.add_argument('--workspace', + parser.add_argument('--workspace', default=os.environ.get('COMFY_UI_WORKSPACE', os.path.expanduser('~/comfyui')), help='ComfyUI workspace directory (default: ~/comfyui or $COMFY_UI_WORKSPACE)') return parser.parse_args() @@ -49,13 +45,13 @@ def install_custom_nodes(workspace_dir, config_path=None): custom_nodes_path = workspace_dir / "custom_nodes" custom_nodes_path.mkdir(parents=True, exist_ok=True) os.chdir(custom_nodes_path) - - for node_id, node_info in config['nodes'].items(): + + for _, node_info in config['nodes'].items(): dir_name = node_info['url'].split("/")[-1].replace(".git", "") node_path = custom_nodes_path / dir_name - + print(f"Installing {node_info['name']}...") - + # Clone the repository if it doesn't already exist if not node_path.exists(): cmd = ["git", "clone", node_info['url']] @@ -64,30 +60,30 @@ def install_custom_nodes(workspace_dir, config_path=None): subprocess.run(cmd, check=True) else: print(f"{node_info['name']} already exists, skipping clone.") - + # Checkout specific commit if branch is a commit hash if 'branch' in node_info and len(node_info['branch']) == 40: # SHA-1 hash length subprocess.run(["git", "-C", dir_name, "checkout", node_info['branch']], check=True) - + # Install requirements if present requirements_file = node_path / "requirements.txt" if requirements_file.exists(): subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True) - + # Install additional dependencies if specified if 'dependencies' in node_info: for dep in node_info['dependencies']: subprocess.run([sys.executable, "-m", "pip", "install", dep], check=True) - + print(f"Installed {node_info['name']}") def main(): args = parse_args() workspace_dir = Path(args.workspace) - + setup_environment(workspace_dir) setup_directories(workspace_dir) install_custom_nodes(workspace_dir) if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/workflows/depth-anything-v2-trt-example-workflow.json b/workflows/depth-anything-v2-trt-example-workflow.json index 40d52878..73761dcb 100644 --- a/workflows/depth-anything-v2-trt-example-workflow.json +++ b/workflows/depth-anything-v2-trt-example-workflow.json @@ -34,4 +34,4 @@ "title": "Preview Image" } } -} \ No newline at end of file +} diff --git a/workflows/depth-bg-black-gpu-workflow.json b/workflows/depth-bg-black-gpu-workflow.json index 86047f2d..051530e7 100644 --- a/workflows/depth-bg-black-gpu-workflow.json +++ b/workflows/depth-bg-black-gpu-workflow.json @@ -94,4 +94,4 @@ "title": "BackgroundColor" } } -} \ No newline at end of file +} diff --git a/workflows/depth-bg-blur-gpu-workflow.json b/workflows/depth-bg-blur-gpu-workflow.json index 4bdcb77d..f232d3be 100644 --- a/workflows/depth-bg-blur-gpu-workflow.json +++ b/workflows/depth-bg-blur-gpu-workflow.json @@ -96,4 +96,4 @@ "title": "GaussianBlur" } } -} \ No newline at end of file +} diff --git a/workflows/liveportait.json b/workflows/liveportait.json index 25a402ce..f388e694 100644 --- a/workflows/liveportait.json +++ b/workflows/liveportait.json @@ -90,4 +90,4 @@ }, "class_type": "PrimaryInputLoadImage" } -} \ No newline at end of file +} diff --git a/workflows/load-preview-image-example-workflow.json b/workflows/load-preview-image-example-workflow.json index 9c4b3ae0..dc39f323 100644 --- a/workflows/load-preview-image-example-workflow.json +++ b/workflows/load-preview-image-example-workflow.json @@ -21,4 +21,4 @@ "title": "Preview Image" } } -} \ No newline at end of file +} diff --git a/workflows/tensor-utils-example-workflow.json b/workflows/tensor-utils-example-workflow.json index 395b8acd..38a788ae 100644 --- a/workflows/tensor-utils-example-workflow.json +++ b/workflows/tensor-utils-example-workflow.json @@ -18,4 +18,4 @@ "title": "LoadTensor" } } -} \ No newline at end of file +} diff --git a/workflows/ui/1 - Build ONNX.json b/workflows/ui/1 - Build ONNX.json index 30074f4f..54406e80 100644 --- a/workflows/ui/1 - Build ONNX.json +++ b/workflows/ui/1 - Build ONNX.json @@ -91,4 +91,4 @@ } }, "version": 0.4 -} \ No newline at end of file +} diff --git a/workflows/ui/2 - Build Static TensorRT Engine.json b/workflows/ui/2 - Build Static TensorRT Engine.json index 346068a4..e4155be7 100644 --- a/workflows/ui/2 - Build Static TensorRT Engine.json +++ b/workflows/ui/2 - Build Static TensorRT Engine.json @@ -151,4 +151,4 @@ } }, "version": 0.4 -} \ No newline at end of file +} diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index c14a7d7a..65cedaea 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -738,4 +738,4 @@ } }, "version": 0.4 -} \ No newline at end of file +} From 928ce027a8ad680eaa1cd5dcd6db732bddc393e5 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 31 Jan 2025 20:35:43 +0100 Subject: [PATCH 39/62] docs: small dev container docs refractor This commit adds some small changes to make the dev container docs more clear. --- .devcontainer/README.md | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 663741e6..9edcd4db 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -25,15 +25,15 @@ The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyS - Pull from Dockerhub: - ```sh - docker pull livepeer/comfyui-base:latest - ``` + ```sh + docker pull livepeer/comfyui-base:latest + ``` - Build the base image: - ```sh - docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . - ``` + ```sh + docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . + ``` ### Host Configuration @@ -72,6 +72,7 @@ From within the **dev container**, download models to run the example workflows: ```sh cd /workspace +conda activate comfystream python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` @@ -88,10 +89,10 @@ After downloading models, it is necessary to compile TensorRT engines for the ex 1. Run the **export_trt.py** script from the directory of the onnx file: - ```sh - cd /ComfyUI/models/tensorrt/depth-anything - python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py - ``` + ```sh + cd /ComfyUI/models/tensorrt/depth-anything + python /ComfyUI/custom_nodes/ComfyUI-Depth-Anything-Tensorrt/export_trt.py + ``` ## Debugging ComfyStream and ComfyUI @@ -103,9 +104,9 @@ Conda is not initiated in the bash shell to provide better interoperability with To launch a new terminal in either `comfystream` or `comfyui` environment: -1. From VSCode, press `Ctrl-Shift-P` -2. Choose `Select Python Interpreter` -3. Select `comfystream` or `comfyui` +1. From VSCode, press `Ctrl-Shift-P`. +2. Choose `Python: Select Interpreter`. +3. Select `comfystream` or `comfyui`. 4. Open a new terminal, you will see the environment name to the left of the bash terminal. > [!NOTE] NOTE For more information, see [Python environments in VS Code](https://code.visualstudio.com/docs/python/environments) @@ -116,6 +117,7 @@ Start ComfyUI: ```sh cd /workspace/ComfyUI +conda activate comfyui python main.py --listen ``` @@ -123,16 +125,28 @@ When using TensorRT engine enabled workflows, you should include the `---disable ```sh cd /workspace/ComfyUI +conda activate comfyui python main.py --listen --disable-cuda-malloc ``` ### Starting ComfyStream +Start ComfyStream: + ```sh cd /workspace +conda activate comfystream python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8888 ``` +Optionally you can also start the [ComfyStream UI](../README.md#run-ui) to view the stream: + +```sh +cd /workspace +cd ui +npm run dev +``` + ## Additional Resources - [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers) From 9ce9200e473f33d1755228af3ed70f5c36ec2934 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 31 Jan 2025 20:52:48 +0100 Subject: [PATCH 40/62] docs: ensure UI creates SSL cert This commit uses the `next dev --experimental-https` command, which is needed when running the UI in the dev container and accessing it outside of the dev container. --- .devcontainer/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 9edcd4db..9b934537 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -139,12 +139,11 @@ conda activate comfystream python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8888 ``` -Optionally you can also start the [ComfyStream UI](../README.md#run-ui) to view the stream: +Optionally, you can also start the [ComfyStream UI](../README.md#run-ui) to view the stream: ```sh -cd /workspace -cd ui -npm run dev +cd /workspace/ui +npm run dev:https ``` ## Additional Resources From f0b5b53c69b5311173f5ead8a4592c446e577233 Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Fri, 31 Jan 2025 15:01:07 -0500 Subject: [PATCH 41/62] Env docs (#4) * docs: small dev container docs refractor This commit adds some small changes to make the dev container docs more clear. * add python env info * add more python env detail --------- Co-authored-by: Rick Staa --- .devcontainer/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 9b934537..73286331 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -76,7 +76,7 @@ conda activate comfystream python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` -For more info about configuring model downloads, see [src/comfystream/scripts/README.md](./src/comfystream/scripts/README.md) +For more info about configuring model downloads, see [src/comfystream/scripts/README.md](../src/comfystream/scripts/README.md) By following these steps, you should be able to set up and run your development container for ComfyStream efficiently. @@ -100,15 +100,17 @@ The `launch.json` includes sample launch configurations for ComfyStream and Comf ## Setting the Python Environment -Conda is not initiated in the bash shell to provide better interoperability with VS Code Shell Integration. +Conda is initialized in the bash shell with no environment activated to provide better interoperability with VS Code Shell Integration. -To launch a new terminal in either `comfystream` or `comfyui` environment: +VS Code will automatically activate the `comfystream` environment, unless you change it: 1. From VSCode, press `Ctrl-Shift-P`. 2. Choose `Python: Select Interpreter`. 3. Select `comfystream` or `comfyui`. 4. Open a new terminal, you will see the environment name to the left of the bash terminal. +Alternatively, you may activate an environment manually with `conda activate comfyui` or `conda activate comfystream` + > [!NOTE] NOTE For more information, see [Python environments in VS Code](https://code.visualstudio.com/docs/python/environments) ### Starting ComfyUI From 575c35c6eb3146295c5ad544b3dd18f8b310a151 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 16:26:31 -0500 Subject: [PATCH 42/62] include all comfystream files in base container --- docker/Dockerfile.base | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 239d0640..0bfdcacb 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -21,12 +21,10 @@ RUN conda create -n comfyui python=3.11 -y # Clone ComfyUI RUN git clone https://github.com/comfyanonymous/ComfyUI.git /ComfyUI +# Copy comfystream to the container +COPY . /comfystream + # Copy ComfyStream files into ComfyUI -COPY requirements.txt /comfystream/requirements.txt -COPY install.py /comfystream/install.py -COPY setup.py /comfystream/setup.py -COPY src /comfystream/src -COPY configs /comfystream/configs COPY ./nodes/ /ComfyUI/custom_nodes/ COPY ./workflows/ui* /ComfyUI/user/default/workflows/examples @@ -45,3 +43,5 @@ RUN conda run -n comfystream pip install --upgrade tensorrt-cu12-bindings tensor # # Configure no environment activation by default RUN conda config --set auto_activate_base false RUN conda init bash + +WORKDIR /comfystream \ No newline at end of file From fce99c0d20a5f6799e4bfa3f95ead0223ea9ca79 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 16:30:20 -0500 Subject: [PATCH 43/62] mount devcontainer at `/comfystream` instead of `/workspace` --- .devcontainer/README.md | 10 +++++----- .devcontainer/devcontainer.json | 8 ++++---- .devcontainer/post-create.sh | 8 ++++---- .vscode/launch.json | 4 ++-- src/comfystream/scripts/README.md | 4 ++-- workflows/ui/1 - Build ONNX.json | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 73286331..f8119554 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -71,7 +71,7 @@ Replace `/path/to/your/model-files` and `path/to/your/output-files` with the pat From within the **dev container**, download models to run the example workflows: ```sh -cd /workspace +cd /comfystream conda activate comfystream python src/comfystream/scripts/setup_models.py --workspace /ComfyUI ``` @@ -118,7 +118,7 @@ Alternatively, you may activate an environment manually with `conda activate com Start ComfyUI: ```sh -cd /workspace/ComfyUI +cd /comfystream/ComfyUI conda activate comfyui python main.py --listen ``` @@ -126,7 +126,7 @@ python main.py --listen When using TensorRT engine enabled workflows, you should include the `---disable-cuda-malloc` flag as shown below: ```sh -cd /workspace/ComfyUI +cd /comfystream/ComfyUI conda activate comfyui python main.py --listen --disable-cuda-malloc ``` @@ -136,7 +136,7 @@ python main.py --listen --disable-cuda-malloc Start ComfyStream: ```sh -cd /workspace +cd /comfystream conda activate comfystream python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --port 8888 ``` @@ -144,7 +144,7 @@ python server/app.py --workspace /ComfyUI --media-ports=5678 --host=0.0.0.0 --po Optionally, you can also start the [ComfyStream UI](../README.md#run-ui) to view the stream: ```sh -cd /workspace/ui +cd /comfystream/ui npm run dev:https ``` diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index dbbf00d9..2fc1b41c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,8 +14,8 @@ "customizations": { "vscode": { "settings": { - "python.defaultInterpreterPath": "/workspace/miniconda3/envs/comfystream/bin/python", - "python.venvPath": "/workspace/miniconda3/envs", + "python.defaultInterpreterPath": "/comfystream/miniconda3/envs/comfystream/bin/python", + "python.venvPath": "/comfystream/miniconda3/envs", "python.terminal.activateEnvInCurrentTerminal": false, "python.terminal.activateEnvironment": true, "terminal.integrated.shellIntegration.enabled": true @@ -36,8 +36,8 @@ "forwardPorts": [8188, 8888, 3000], // Use 'forwardPorts' to make a list of ports inside the container available locally. // Use 'mounts' to make a list of local folders available inside the container. - "workspaceFolder": "/workspace", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/comfystream", + "workspaceMount": "source=${localWorkspaceFolder},target=/comfystream,type=bind", "mounts": [ // Use 'mounts' to map to comfyui models on the host "source=${localEnv:HOME}/models/ComfyUI--models,target=/ComfyUI/models,type=bind,consistency=cached", diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 0a69bb8a..915bb99c 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -1,15 +1,15 @@ #!/bin/bash # Install npm packages if needed -cd /workspace/ui +cd /comfystream/ui if [ ! -d "node_modules" ]; then npm install --legacy-peer-deps fi # Create a symlink to the ComfyUI workspace -if [ ! -d "/workspace/ComfyUI" ]; then - ln -s /ComfyUI /workspace/ComfyUI +if [ ! -d "/comfystream/ComfyUI" ]; then + ln -s /ComfyUI /comfystream/ComfyUI fi -cd /workspace +cd /comfystream /bin/bash \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 355f767a..242007b9 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -24,7 +24,7 @@ "name": "Run ComfyStream", "type": "debugpy", "request": "launch", - "cwd": "/workspace/server", + "cwd": "/comfystream/server", "program": "app.py", "args": [ "--workspace=/ComfyUI", @@ -39,7 +39,7 @@ "name": "Run ComfyStream UI (Node.js)", "type": "node", "request": "launch", - "cwd": "/workspace/ui", + "cwd": "/comfystream/ui", "console": "integratedTerminal", "runtimeExecutable": "npm", "runtimeArgs": [ diff --git a/src/comfystream/scripts/README.md b/src/comfystream/scripts/README.md index 3b5cf92c..b2661c1e 100644 --- a/src/comfystream/scripts/README.md +++ b/src/comfystream/scripts/README.md @@ -16,8 +16,8 @@ From the repository root: ```bash # Install both nodes and models (default workspace: ~/comfyui) -python src/comfystream/scripts/setup_nodes.py --workspace /path/to/workspace -python src/comfystream/scripts/setup_models.py --workspace /path/to/workspace +python src/comfystream/scripts/setup_nodes.py --workspace /path/to/comfyui +python src/comfystream/scripts/setup_models.py --workspace /path/to/comfyui ``` > The `--workspace` flag is optional and will default to `$COMFY_UI_WORKSPACE` or `~/comfyui`. diff --git a/workflows/ui/1 - Build ONNX.json b/workflows/ui/1 - Build ONNX.json index 54406e80..d8849cec 100644 --- a/workflows/ui/1 - Build ONNX.json +++ b/workflows/ui/1 - Build ONNX.json @@ -28,7 +28,7 @@ "Node name for S&R": "ONNX_FP8_EXPORT" }, "widgets_values": [ - "/workspace/ComfyUI/models/onnx", + "/comfystream/ComfyUI/models/onnx", "dreamshaper8_fp8.onnx" ] }, From d563d3874419b9bcf6e75d5c26514134b3ba7f41 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Fri, 31 Jan 2025 16:37:31 -0500 Subject: [PATCH 44/62] rename docker namespace to `/livepeerci` --- .devcontainer/Dockerfile | 2 +- .devcontainer/README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 43343fed..f02f4aae 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM livepeer/comfyui-base:latest +FROM livepeerci/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" EXPOSE 8188 EXPOSE 8888 diff --git a/.devcontainer/README.md b/.devcontainer/README.md index f8119554..0caa932f 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -21,18 +21,18 @@ cd comfystream ### Download or Build Base Docker Image -The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: +The `livepeerci/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: - Pull from Dockerhub: ```sh - docker pull livepeer/comfyui-base:latest + docker pull livepeerci/comfyui-base:latest ``` - Build the base image: ```sh - docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . + docker build -f docker/Dockerfile.base -t livepeerci/comfyui-base:latest . ``` ### Host Configuration From dafed256db391d2fee3f2e299269af7a37f014d1 Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 31 Jan 2025 21:57:29 +0000 Subject: [PATCH 45/62] Revert "rename docker namespace to `/livepeerci`" This reverts commit f6fa5b5529b472f29ec066d838aa497f5c203e48. --- .devcontainer/Dockerfile | 2 +- .devcontainer/README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f02f4aae..43343fed 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM livepeerci/comfyui-base:latest +FROM livepeer/comfyui-base:latest ENV PATH="/miniconda3/bin:${PATH}" EXPOSE 8188 EXPOSE 8888 diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 0caa932f..f8119554 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -21,18 +21,18 @@ cd comfystream ### Download or Build Base Docker Image -The `livepeerci/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: +The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyStream development. You may either pull the base docker image or build it: - Pull from Dockerhub: ```sh - docker pull livepeerci/comfyui-base:latest + docker pull livepeer/comfyui-base:latest ``` - Build the base image: ```sh - docker build -f docker/Dockerfile.base -t livepeerci/comfyui-base:latest . + docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . ``` ### Host Configuration From 84600c9fc0ee2ef533dc95574c88e7c66410aeda Mon Sep 17 00:00:00 2001 From: Elite Date: Fri, 31 Jan 2025 23:25:56 +0000 Subject: [PATCH 46/62] fix incorrect path to env --- .devcontainer/devcontainer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2fc1b41c..56a7b740 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,8 +14,8 @@ "customizations": { "vscode": { "settings": { - "python.defaultInterpreterPath": "/comfystream/miniconda3/envs/comfystream/bin/python", - "python.venvPath": "/comfystream/miniconda3/envs", + "python.defaultInterpreterPath": "/miniconda3/envs/comfystream/bin/python", + "python.venvPath": "/miniconda3/envs", "python.terminal.activateEnvInCurrentTerminal": false, "python.terminal.activateEnvironment": true, "terminal.integrated.shellIntegration.enabled": true From 57e57c2d7576035ba0a575b86d37fd1902111362 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Mon, 3 Feb 2025 11:26:56 -0500 Subject: [PATCH 47/62] add build_trt.py script --- src/comfystream/scripts/build_trt.py | 234 +++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 src/comfystream/scripts/build_trt.py diff --git a/src/comfystream/scripts/build_trt.py b/src/comfystream/scripts/build_trt.py new file mode 100644 index 00000000..3ed834aa --- /dev/null +++ b/src/comfystream/scripts/build_trt.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 + +import os +import sys +import time +import argparse + +# Reccomended running from comfystream conda environment +# in devcontainer from the workspace/ directory, or comfystream/ if you've checked out the repo +# $> conda activate comfystream +# $> python src/comfystream/scripts/build_trt.py --model /ComfyUI/models/checkpoints/SD1.5/dreamshaper-8.safetensors --out-engine /ComfyUI/output/tensorrt/static-dreamshaper8_SD15_$stat-b-1-h-512-w-512_00001_.engine + +# Paths path explicitly to use the downloaded comfyUI installation on root +ROOT_DIR="/" +COMFYUI_DIR = "/ComfyUI" +timing_cache_path = "/ComfyUI/output/tensorrt/timing_cache" + +if ROOT_DIR not in sys.path: + sys.path.insert(0, ROOT_DIR) +if COMFYUI_DIR not in sys.path: + sys.path.insert(0, COMFYUI_DIR) + +comfy_dirs = [ + "/ComfyUI/", + "/ComfyUI/comfy", + "/ComfyUI/comfy_extras" +] + +for comfy_dir in comfy_dirs: + init_file_path = os.path.join(comfy_dir, "__init__.py") + + # Check if the __init__.py file exists + if not os.path.exists(init_file_path): + try: + # Create the __init__.py file + with open(init_file_path, "w") as init_file: + init_file.write("# This file ensures comfy is treated as a package\n") + print(f"Created __init__.py at {init_file_path}") + except Exception as e: + print(f"Error creating __init__.py: {e}") + else: + print(f"__init__.py already exists at {init_file_path}") + +import comfy +import comfy.model_management + +from ComfyUI.custom_nodes.ComfyUI_TensorRT.models.supported_models import detect_version_from_model, get_helper_from_model +from ComfyUI.custom_nodes.ComfyUI_TensorRT.onnx_utils.export import export_onnx +from ComfyUI.custom_nodes.ComfyUI_TensorRT.tensorrt_diffusion_model import TRTDiffusionBackbone + +def parse_args(): + parser = argparse.ArgumentParser( + description="Build a static TensorRT engine from a ComfyUI model." + ) + parser.add_argument( + "--model", + type=str, + required=True, + help="Path to the .ckpt/.safetensors or ComfyUI model name you want to convert", + ) + parser.add_argument( + "--out-engine", + type=str, + required=True, + help="Path to the output .engine file to produce", + ) + parser.add_argument( + "--batch-size", + type=int, + default=1, + help="Batch size for the exported and built engine (default 1)", + ) + parser.add_argument( + "--width", + type=int, + default=512, + help="Width in pixels for the exported model (default 1024)", + ) + parser.add_argument( + "--height", + type=int, + default=512, + help="Height in pixels for the exported model (default 1024)", + ) + parser.add_argument( + "--context", + type=int, + default=1, + help="Context multiplier for the exported model (default 1)", + ) + parser.add_argument( + "--fp8", + action="store_true", + default=False, + help="If set, attempts to export the ONNX with FP8 transformations (Flux or standard).", + ) + parser.add_argument( + "--verbose", + action="store_true", + help="Enable more logging / debug prints." + ) + return parser.parse_args() + +def build_static_trt_engine( + model_path: str, + engine_out_path: str, + batch_size_opt: int = 1, + width_opt: int = 512, + height_opt: int = 512, + context_opt: int = 1, + num_video_frames: int = 14, + fp8: bool = False, + verbose: bool = False +): + """ + 1) Load the model from ComfyUI by path or name + 2) Export to ONNX (static shape) + 3) Build a static TensorRT .engine file + """ + + # Check if the engine file already exists + if os.path.exists(engine_out_path): + print(f"[INFO] Engine file already exists: {engine_out_path}") + return + + # Extract the directory from the file path and ensure it exists + directory = os.path.dirname(engine_out_path) + if not os.path.exists(directory): + os.makedirs(directory) + + if verbose: + print(f"[INFO] Starting build for model: {model_path}") + print(f" Output Engine Path: {engine_out_path}") + print(f" (batch={batch_size_opt}, H={height_opt}, W={width_opt}, context={context_opt}, " + f"num_video_frames={num_video_frames}, fp8={fp8})") + + # 1) Load model in GPU: + comfy.model_management.unload_all_models() + + loaded_model = comfy.sd.load_diffusion_model(model_path, model_options={}) + if loaded_model is None: + raise ValueError("Failed to load model.") + + comfy.model_management.load_models_gpu( + [loaded_model], + force_patch_weights=True, + force_full_load=True + ) + + # 2) Export to ONNX at the desired shape + # We'll place the ONNX in a temporary folder + timestamp_str = str(int(time.time())) + temp_dir = os.path.join(comfy.model_management.get_torch_device().type + "_temp", timestamp_str) + if not os.path.exists(temp_dir): + os.makedirs(temp_dir, exist_ok=True) + + onnx_filename = f"model_{timestamp_str}.onnx" + onnx_path = os.path.join(temp_dir, onnx_filename) + + if verbose: + print(f"[INFO] Exporting ONNX to: {onnx_path}") + + export_onnx( + model = loaded_model, + path = onnx_path, + batch_size = batch_size_opt, + height = height_opt, + width = width_opt, + num_video_frames = num_video_frames, + context_multiplier = context_opt, + fp8 = fp8, + ) + + # 3) Build the static TRT engine + model_version = detect_version_from_model(loaded_model) + model_helper = get_helper_from_model(loaded_model) + + trt_model = TRTDiffusionBackbone(model_helper) + + # We'll define min/opt/max config all the same (i.e. 'static') + # TODO: make this configurable + min_config = { + "batch_size": batch_size_opt, + "height": height_opt, + "width": width_opt, + "context_len": context_opt * model_helper.context_len, + } + opt_config = dict(min_config) + max_config = dict(min_config) + + if verbose: + print(f"[INFO] Building engine -> {engine_out_path}") + + success = trt_model.build( + onnx_path = onnx_path, + engine_path = engine_out_path, + timing_cache_path = timing_cache_path, + opt_config = opt_config, + min_config = min_config, + max_config = max_config, + ) + if not success: + raise RuntimeError("[ERROR] TensorRT engine build failed") + + print(f"[OK] Created TensorRT engine: {engine_out_path}") + + # Clean up + comfy.model_management.unload_all_models() + try: + os.remove(onnx_path) + except: + pass + try: + os.rmdir(temp_dir) + except: + pass + + +def main(): + args = parse_args() + build_static_trt_engine( + model_path = args.model, + engine_out_path = args.out_engine, + batch_size_opt = args.batch_size, + height_opt = args.height, + width_opt = args.width, + context_opt = args.context, + fp8 = args.fp8, + verbose = args.verbose + ) + + +if __name__ == "__main__": + main() From 084b8ad7ad8d5b43aa5cc77a2dc778bbcd053468 Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Mon, 3 Feb 2025 14:52:02 -0500 Subject: [PATCH 48/62] Update setup_node.py to give error on docker build failure, cleanup setup scripts --- src/comfystream/scripts/__init__.py | 8 ++- src/comfystream/scripts/setup_models.py | 6 +- src/comfystream/scripts/setup_nodes.py | 76 ++++++++++++------------- src/comfystream/scripts/utils.py | 1 - 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/comfystream/scripts/__init__.py b/src/comfystream/scripts/__init__.py index 661b502a..9273e242 100644 --- a/src/comfystream/scripts/__init__.py +++ b/src/comfystream/scripts/__init__.py @@ -1 +1,7 @@ -"""Setup scripts for ComfyUI streaming server""" \ No newline at end of file +from . import utils +from utils import get_config_path, load_model_config +from .setup_nodes import run_setup_nodes +from .setup_models import run_setup_models + +"""Setup scripts for ComfyUI streaming server""" + diff --git a/src/comfystream/scripts/setup_models.py b/src/comfystream/scripts/setup_models.py index 01ef1e47..2474d635 100644 --- a/src/comfystream/scripts/setup_models.py +++ b/src/comfystream/scripts/setup_models.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os from pathlib import Path import requests @@ -93,12 +92,11 @@ def setup_directories(workspace_dir): for dir_name in model_dirs: (models_dir / dir_name).mkdir(parents=True, exist_ok=True) -def main(): +def setup_models(): args = parse_args() workspace_dir = Path(args.workspace) setup_directories(workspace_dir) setup_model_files(workspace_dir) -if __name__ == "__main__": - main() +setup_models() diff --git a/src/comfystream/scripts/setup_nodes.py b/src/comfystream/scripts/setup_nodes.py index 2e4eb7ed..9818b9a3 100755 --- a/src/comfystream/scripts/setup_nodes.py +++ b/src/comfystream/scripts/setup_nodes.py @@ -1,15 +1,10 @@ -#!/usr/bin/env python3 import os import subprocess import sys from pathlib import Path import yaml import argparse - -# Change relative import to absolute import from utils import get_config_path, load_model_config - - def parse_args(): parser = argparse.ArgumentParser(description='Setup ComfyUI nodes and models') parser.add_argument('--workspace', @@ -46,38 +41,43 @@ def install_custom_nodes(workspace_dir, config_path=None): custom_nodes_path.mkdir(parents=True, exist_ok=True) os.chdir(custom_nodes_path) - for _, node_info in config['nodes'].items(): - dir_name = node_info['url'].split("/")[-1].replace(".git", "") - node_path = custom_nodes_path / dir_name - - print(f"Installing {node_info['name']}...") - - # Clone the repository if it doesn't already exist - if not node_path.exists(): - cmd = ["git", "clone", node_info['url']] - if 'branch' in node_info: - cmd.extend(["-b", node_info['branch']]) - subprocess.run(cmd, check=True) - else: - print(f"{node_info['name']} already exists, skipping clone.") - - # Checkout specific commit if branch is a commit hash - if 'branch' in node_info and len(node_info['branch']) == 40: # SHA-1 hash length - subprocess.run(["git", "-C", dir_name, "checkout", node_info['branch']], check=True) - - # Install requirements if present - requirements_file = node_path / "requirements.txt" - if requirements_file.exists(): - subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True) - - # Install additional dependencies if specified - if 'dependencies' in node_info: - for dep in node_info['dependencies']: - subprocess.run([sys.executable, "-m", "pip", "install", dep], check=True) - - print(f"Installed {node_info['name']}") + try: + for _, node_info in config['nodes'].items(): + dir_name = node_info['url'].split("/")[-1].replace(".git", "") + node_path = custom_nodes_path / dir_name + + print(f"Installing {node_info['name']}...") + + # Clone the repository if it doesn't already exist + if not node_path.exists(): + cmd = ["git", "clone", node_info['url']] + if 'branch' in node_info: + cmd.extend(["-b", node_info['branch']]) + subprocess.run(cmd, check=True) + else: + print(f"{node_info['name']} already exists, skipping clone.") + + # Checkout specific commit if branch is a commit hash + if 'branch' in node_info and len(node_info['branch']) == 40: # SHA-1 hash length + subprocess.run(["git", "-C", dir_name, "checkout", node_info['branch']], check=True) + + # Install requirements if present + requirements_file = node_path / "requirements.txt" + if requirements_file.exists(): + subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True) + + # Install additional dependencies if specified + if 'dependencies' in node_info: + for dep in node_info['dependencies']: + subprocess.run([sys.executable, "-m", "pip", "install", dep], check=True) + + print(f"Installed {node_info['name']}") + except Exception as e: + print(f"Error installing {node_info['name']} {e}") + raise e + return -def main(): +def setup_nodes(): args = parse_args() workspace_dir = Path(args.workspace) @@ -85,5 +85,5 @@ def main(): setup_directories(workspace_dir) install_custom_nodes(workspace_dir) -if __name__ == "__main__": - main() + +setup_nodes() diff --git a/src/comfystream/scripts/utils.py b/src/comfystream/scripts/utils.py index 9c23eea5..a7b37f2d 100644 --- a/src/comfystream/scripts/utils.py +++ b/src/comfystream/scripts/utils.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import yaml from pathlib import Path From ad4310c5b31c0ff501f4d3e789c7f503fb90d87e Mon Sep 17 00:00:00 2001 From: PSchroedl Date: Mon, 3 Feb 2025 15:51:42 -0800 Subject: [PATCH 49/62] python script to build dreamshaper tensorrt engine (#1) --- src/comfystream/scripts/build_trt.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/comfystream/scripts/build_trt.py b/src/comfystream/scripts/build_trt.py index 3ed834aa..41ee6c50 100644 --- a/src/comfystream/scripts/build_trt.py +++ b/src/comfystream/scripts/build_trt.py @@ -188,6 +188,11 @@ def build_static_trt_engine( opt_config = dict(min_config) max_config = dict(min_config) + # The tensorrt_diffusion_model build() signature is typically: + # build(onnx_path, engine_path, timing_cache_path, opt_config, min_config, max_config) + # If you have a separate 'timing_cache.trt', put it next to this script: + timing_cache_path = os.path.join(os.path.dirname(__file__), "timing_cache.trt") + if verbose: print(f"[INFO] Building engine -> {engine_out_path}") From 22ac410c5790dfa1f28175b270da8c07e2e4944f Mon Sep 17 00:00:00 2001 From: Elite Encoder Date: Tue, 4 Feb 2025 09:51:28 -0500 Subject: [PATCH 50/62] set log level to warning for verbose aiortc logs --- server/app.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/app.py b/server/app.py index e2a62a04..2a896e57 100644 --- a/server/app.py +++ b/server/app.py @@ -20,6 +20,8 @@ from utils import patch_loop_datagram logger = logging.getLogger(__name__) +logging.getLogger('aiortc.rtcrtpsender').setLevel(logging.WARNING) +logging.getLogger('aiortc.rtcrtpreceiver').setLevel(logging.WARNING) MAX_BITRATE = 2000000 From fd71c9c400e920dd7ca178a806e352c0529546a1 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 4 Feb 2025 20:23:04 +0100 Subject: [PATCH 51/62] refactor: make Comfy Workflow input required (#34) --- ui/src/components/settings.tsx | 1 + ui/src/components/ui/input.tsx | 50 ++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/ui/src/components/settings.tsx b/ui/src/components/settings.tsx index 76358b3c..2d784d9d 100644 --- a/ui/src/components/settings.tsx +++ b/ui/src/components/settings.tsx @@ -253,6 +253,7 @@ function ConfigForm({ config, onSubmit }: ConfigFormProps) { type="file" accept=".json" onChange={handlePromptChange} + required={true} /> diff --git a/ui/src/components/ui/input.tsx b/ui/src/components/ui/input.tsx index 919ebfb3..62018c7d 100644 --- a/ui/src/components/ui/input.tsx +++ b/ui/src/components/ui/input.tsx @@ -1,25 +1,29 @@ -import * as React from "react" +/** + * @file Contains styled input components. + */ +import * as React from "react"; +import { cn } from "@/lib/utils"; -import { cn } from "@/lib/utils" +/** + * Styled input component. + * @param props - Input props. + * @param ref - Input ref. + */ +const Input = React.forwardRef< + HTMLInputElement, + React.InputHTMLAttributes +>(({ className, ...props }, ref) => { + return ( + + ); +}); +Input.displayName = "Input"; -export interface InputProps - extends React.InputHTMLAttributes {} - -const Input = React.forwardRef( - ({ className, type, ...props }, ref) => { - return ( - - ) - } -) -Input.displayName = "Input" - -export { Input } +export { Input }; From 5ae935b7b566bde5ac2b6ee138db07bd3790e8dd Mon Sep 17 00:00:00 2001 From: Brad | ad-astra <99882368+ad-astra-video@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:08:21 -0600 Subject: [PATCH 52/62] Add ComfyUI-Backgrund-Edit tod efault nodes (#33) Updates nodes.yaml in configs to add Yondon's ComfyUI-Background-Edit nodes to support the background changing workflows. --- configs/nodes.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configs/nodes.yaml b/configs/nodes.yaml index 514c8f53..f528d55a 100644 --- a/configs/nodes.yaml +++ b/configs/nodes.yaml @@ -65,4 +65,9 @@ nodes: comfyui-kjnodes: name: "ComfyUI KJNodes" url: "https://github.com/kijai/ComfyUI-KJNodes.git" - type: "utility" \ No newline at end of file + type: "utility" + + comfyui-background-edit: + name: "ComfyUI Background Edit" + url: "https://github.com/yondonfu/ComfyUI-Background-Edit" + type: "utility" From 0a747d0785b414b3504a345e73d2c8504363bf91 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Wed, 5 Feb 2025 11:03:51 +0100 Subject: [PATCH 53/62] feat: improve camera selection behavior This commit enhances the camera selection functionality to prevent user confusion due to lack of solid error handling. It includes the following improvements: - Ensures the camera field is required, displaying a warning if no camera is selected. - Fixes the camera state setting to correctly select the first device, preventing it from being overwritten with an empty string. - Displays a descriptive label when no camera devices are available. Additionally, this commit improves the codebase structure for better maintainability and readability. --- ui/src/components/settings.tsx | 68 ++++++++++++++++++++++++--------- ui/src/components/ui/select.tsx | 66 ++++++++++++++++++++++---------- 2 files changed, 95 insertions(+), 39 deletions(-) diff --git a/ui/src/components/settings.tsx b/ui/src/components/settings.tsx index 2d784d9d..5c3377d0 100644 --- a/ui/src/components/settings.tsx +++ b/ui/src/components/settings.tsx @@ -1,3 +1,6 @@ +/** + * @file Contains a StreamSettings component for configuring stream settings. + */ import { Button } from "@/components/ui/button"; import { Dialog, @@ -38,7 +41,7 @@ export interface StreamConfig { streamUrl: string; frameRate: number; prompt?: any; - selectedDeviceId: string; + selectedDeviceId: string | undefined; } interface VideoDevice { @@ -50,7 +53,7 @@ export const DEFAULT_CONFIG: StreamConfig = { streamUrl: process.env.NEXT_PUBLIC_DEFAULT_STREAM_URL || "http://127.0.0.1:8888", frameRate: 30, - selectedDeviceId: "", + selectedDeviceId: undefined, }; interface StreamSettingsProps { @@ -77,7 +80,7 @@ export function StreamSettings({ if (isDesktop) { return ( - +
Stream Settings
@@ -133,17 +136,22 @@ function ConfigForm({ config, onSubmit }: ConfigFormProps) { const [prompt, setPrompt] = useState(null); const { setOriginalPrompt } = usePrompt(); const [videoDevices, setVideoDevices] = useState([]); - const [selectedDevice, setSelectedDevice] = useState(""); + const [selectedDevice, setSelectedDevice] = useState( + config.selectedDeviceId + ); const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: config, }); + /** + * Retrieves the list of video devices available on the user's device. + */ const getVideoDevices = useCallback(async () => { try { + // Get Available Video Devices. await navigator.mediaDevices.getUserMedia({ video: true }); - const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices .filter((device) => device.kind === "videoinput") @@ -151,16 +159,18 @@ function ConfigForm({ config, onSubmit }: ConfigFormProps) { deviceId: device.deviceId, label: device.label || `Camera ${device.deviceId.slice(0, 5)}...`, })); - setVideoDevices(videoDevices); - if (videoDevices.length > 0) { - setSelectedDevice((curr) => curr || videoDevices[0].deviceId); + + // Use first device as default and remove selected device if unavailable. + if (!videoDevices.some((device) => device.deviceId === selectedDevice)) { + setSelectedDevice(videoDevices.length > 0 ? videoDevices[0].deviceId : undefined); } - } catch (err) { - console.error("Failed to get video devices"); + } catch (err){ + console.log(`Failed to get video devices: ${err}`); } - }, []); + }, [selectedDevice]); + // Handle device change events. useEffect(() => { getVideoDevices(); navigator.mediaDevices.addEventListener("devicechange", getVideoDevices); @@ -198,6 +208,16 @@ function ConfigForm({ config, onSubmit }: ConfigFormProps) { } }; + /** + * Handles the camera selection. + * @param deviceId + */ + const handleCameraSelect = (deviceId: string) => { + if (deviceId !== selectedDevice) { + setSelectedDevice(deviceId); + } + }; + return (
@@ -231,17 +251,29 @@ function ConfigForm({ config, onSubmit }: ConfigFormProps) {
- - {videoDevices.find((d) => d.deviceId === selectedDevice)?.label || - "Select camera"} + {videoDevices.length === 0 + ? "No camera devices found" + : videoDevices.find((d) => d.deviceId === selectedDevice) + ?.label || "Select camera"} - {videoDevices.map((device) => ( - - {device.label} + {videoDevices.length === 0 ? ( + + No camera devices found - ))} + ) : ( + videoDevices.map((device) => ( + + {device.label} + + )) + )}
diff --git a/ui/src/components/ui/select.tsx b/ui/src/components/ui/select.tsx index 409f176e..82f2f72f 100644 --- a/ui/src/components/ui/select.tsx +++ b/ui/src/components/ui/select.tsx @@ -1,15 +1,29 @@ -import { cn } from "@/lib/utils" -import * as SelectPrimitive from "@radix-ui/react-select" -import { Check, ChevronDown } from "lucide-react" -import * as React from "react" +/** + * @file Contains styled Radix UI select components. + */ +import { cn } from "@/lib/utils"; +import * as SelectPrimitive from "@radix-ui/react-select"; +import { Check, ChevronDown } from "lucide-react"; +import * as React from "react"; -const Select = SelectPrimitive.Root as { - (props: SelectPrimitive.SelectProps): JSX.Element - Trigger: typeof SelectTrigger - Content: typeof SelectContent - Option: typeof SelectOption -} +/** + * Styled select component. + * @param props - Select props. + */ +const Select: React.FC & { + Trigger: typeof SelectTrigger; + Content: typeof SelectContent; + Option: typeof SelectOption; +} = (props) => { + return ; +}; +Select.displayName = SelectPrimitive.Root.displayName; +/** + * Styled select trigger element. + * @param props - Select trigger props. + * @param ref - Select trigger ref. + */ const SelectTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -17,7 +31,7 @@ const SelectTrigger = React.forwardRef< -)) -SelectTrigger.displayName = SelectPrimitive.Trigger.displayName +)); +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; +/** + * Styled select content element. + * @param props - Select content props. + * @param ref - Select content ref. + */ const SelectContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -57,9 +76,14 @@ const SelectContent = React.forwardRef< -)) -SelectContent.displayName = SelectPrimitive.Content.displayName +)); +SelectContent.displayName = SelectPrimitive.Content.displayName; +/** + * Styled select option element. + * @param props - Select option props. + * @param ref - Select option ref. + */ const SelectOption = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -79,11 +103,11 @@ const SelectOption = React.forwardRef< {children} -)) -SelectOption.displayName = SelectPrimitive.Item.displayName +)); +SelectOption.displayName = SelectPrimitive.Item.displayName; -Select.Trigger = SelectTrigger -Select.Content = SelectContent -Select.Option = SelectOption +Select.Trigger = SelectTrigger; +Select.Content = SelectContent; +Select.Option = SelectOption; -export { Select } +export { Select }; From 5b30907cd10002addd4b331c8f9bcdf7f54259cb Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Wed, 5 Feb 2025 09:12:26 -0500 Subject: [PATCH 54/62] update SD 1.5 workflow (#36) * update SD 1.5 workflow * cleanup readme --- .devcontainer/README.md | 16 +- .../ui/3 - SD 1.5 TensorRT workflow.json | 667 +++++++++--------- 2 files changed, 347 insertions(+), 336 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index f8119554..3d07a01f 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -15,7 +15,7 @@ This guide will help you set up and run a development container for ComfyStream First, clone the `comfystream` repository: ```sh -clone https://github.com/yondonfu/comfystream.git +git clone https://github.com/yondonfu/comfystream.git cd comfystream ``` @@ -25,15 +25,15 @@ The `livepeer/comfyui-base:latest` image provides a ComfyUI workspace for ComfyS - Pull from Dockerhub: - ```sh - docker pull livepeer/comfyui-base:latest - ``` +```sh +docker pull livepeer/comfyui-base:latest +``` - Build the base image: - ```sh - docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . - ``` +```sh +docker build -f docker/Dockerfile.base -t livepeer/comfyui-base:latest . +``` ### Host Configuration @@ -111,7 +111,7 @@ VS Code will automatically activate the `comfystream` environment, unless you ch Alternatively, you may activate an environment manually with `conda activate comfyui` or `conda activate comfystream` -> [!NOTE] NOTE For more information, see [Python environments in VS Code](https://code.visualstudio.com/docs/python/environments) +> [!NOTE] For more information, see [Python environments in VS Code](https://code.visualstudio.com/docs/python/environments) ### Starting ComfyUI diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index 65cedaea..24a12891 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -1,95 +1,26 @@ { - "last_node_id": 16, - "last_link_id": 32, + "last_node_id": 22, + "last_link_id": 21, "nodes": [ - { - "id": 2, - "type": "DepthAnythingTensorrt", - "pos": [ - 515, - 130 - ], - "size": [ - 315, - 58 - ], - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 17 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 27 - ] - } - ], - "properties": { - "Node name for S&R": "DepthAnythingTensorrt" - }, - "widgets_values": [ - "depth_anything_vitl14-fp16.engine" - ] - }, - { - "id": 3, - "type": "TensorRTLoader", - "pos": [ - 100, - 362 - ], - "size": [ - 315, - 82 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 20 - ] - } - ], - "properties": { - "Node name for S&R": "TensorRTLoader" - }, - "widgets_values": [ - "static-dreamshaper8_SD15_$stat-b-1-h-512-w-512_00001_.engine", - "SD15" - ] - }, { "id": 5, "type": "CLIPTextEncode", "pos": [ - 515, - 318 + 1104, + 615 ], "size": [ 400, 200 ], "flags": {}, - "order": 8, + "order": 6, "mode": 0, "inputs": [ { "name": "clip", "type": "CLIP", - "link": 18 + "link": 2 } ], "outputs": [ @@ -97,36 +28,37 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 24 - ] + 4 + ], + "slot_index": 0 } ], "properties": { "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - " In a winter wonderland" + "the hulk" ] }, { "id": 6, "type": "CLIPTextEncode", "pos": [ - 515, - 648 + 1104, + 891 ], "size": [ 400, 200 ], "flags": {}, - "order": 9, + "order": 7, "mode": 0, "inputs": [ { "name": "clip", "type": "CLIP", - "link": 19 + "link": 3 } ], "outputs": [ @@ -134,8 +66,9 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 25 - ] + 5 + ], + "slot_index": 0 } ], "properties": { @@ -146,180 +79,168 @@ ] }, { - "id": 7, - "type": "KSampler", + "id": 9, + "type": "ControlNetApplyAdvanced", "pos": [ - 1430, - 130 + 1602, + 664 ], "size": [ 315, - 262 + 186 ], "flags": {}, - "order": 12, + "order": 11, "mode": 0, "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 20 - }, { "name": "positive", "type": "CONDITIONING", - "link": 21 + "link": 4 }, { "name": "negative", "type": "CONDITIONING", - "link": 22 + "link": 5 }, { - "name": "latent_image", - "type": "LATENT", - "link": 23 + "name": "control_net", + "type": "CONTROL_NET", + "link": 11 + }, + { + "name": "image", + "type": "IMAGE", + "link": 12 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 } ], "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "positive", + "type": "CONDITIONING", "links": [ - 30 - ] + 7 + ], + "slot_index": 0 + }, + { + "name": "negative", + "type": "CONDITIONING", + "links": [ + 8 + ], + "slot_index": 1 } ], "properties": { - "Node name for S&R": "KSampler" + "Node name for S&R": "ControlNetApplyAdvanced" }, "widgets_values": [ - 431120618284339, - "randomize", - 1, 1, - "lcm", - "normal", + 0, 1 ] }, { - "id": 8, - "type": "ControlNetLoader", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 100, - 802 + 648, + 771 ], "size": [ 315, - 58 + 98 ], "flags": {}, - "order": 1, + "order": 0, "mode": 0, "inputs": [], "outputs": [ { - "name": "CONTROL_NET", - "type": "CONTROL_NET", + "name": "MODEL", + "type": "MODEL", + "links": null + }, + { + "name": "CLIP", + "type": "CLIP", "links": [ - 28 - ] + 2, + 3 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": null } ], "properties": { - "Node name for S&R": "ControlNetLoader" + "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - "control_v11f1p_sd15_depth_fp16.safetensors" + "SD1.5/dreamshaper-8.safetensors" ] }, { - "id": 9, - "type": "ControlNetApplyAdvanced", + "id": 8, + "type": "ControlNetLoader", "pos": [ - 1015, - 130 + 650, + 1244 ], "size": [ 315, - 186 + 58 ], "flags": {}, - "order": 11, + "order": 1, "mode": 0, - "inputs": [ - { - "name": "positive", - "type": "CONDITIONING", - "link": 24 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 25 - }, - { - "name": "control_net", - "type": "CONTROL_NET", - "link": 26 - }, - { - "name": "image", - "type": "IMAGE", - "link": 27 - }, - { - "name": "vae", - "type": "VAE", - "link": null, - "shape": 7 - } - ], + "inputs": [], "outputs": [ { - "name": "positive", - "type": "CONDITIONING", - "links": [ - 21 - ] - }, - { - "name": "negative", - "type": "CONDITIONING", + "name": "CONTROL_NET", + "type": "CONTROL_NET", "links": [ - 22 - ] + 10 + ], + "slot_index": 0 } ], "properties": { - "Node name for S&R": "ControlNetApplyAdvanced" + "Node name for S&R": "ControlNetLoader" }, "widgets_values": [ - 1, - 0, - 1 + "control_v11f1p_sd15_depth_fp16.safetensors" ] }, { "id": 10, "type": "TorchCompileLoadControlNet", "pos": [ - 515, - 978 + 1130, + 1226 ], "size": [ 327.5999755859375, 106 ], "flags": {}, - "order": 6, + "order": 8, "mode": 0, "inputs": [ { "name": "controlnet", "type": "CONTROL_NET", - "link": 28 + "link": 10 } ], "outputs": [ @@ -327,8 +248,9 @@ "name": "CONTROL_NET", "type": "CONTROL_NET", "links": [ - 26 - ] + 11 + ], + "slot_index": 0 } ], "properties": { @@ -340,19 +262,52 @@ "reduce-overhead" ] }, + { + "id": 3, + "type": "TensorRTLoader", + "pos": [ + 642, + 396 + ], + "size": [ + 315, + 82 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "TensorRTLoader" + }, + "widgets_values": [ + "ComfyUI_STAT_dreamshaper-8-dmd-1kstep-fp8_SD15_$stat-b-1-h-512-w-512_00001_.engine", + "SD15" + ] + }, { "id": 11, "type": "VAELoader", "pos": [ - 100, - 990 + 649, + 1498 ], "size": [ 315, 58 ], "flags": {}, - "order": 2, + "order": 3, "mode": 0, "inputs": [], "outputs": [ @@ -360,8 +315,9 @@ "name": "VAE", "type": "VAE", "links": [ - 29 - ] + 13 + ], + "slot_index": 0 } ], "properties": { @@ -372,52 +328,97 @@ ] }, { - "id": 13, - "type": "TorchCompileLoadVAE", + "id": 7, + "type": "KSampler", "pos": [ - 515, - 1214 + 2024, + 287 ], "size": [ 315, - 154 + 262 ], "flags": {}, - "order": 7, + "order": 12, "mode": 0, "inputs": [ { - "name": "vae", - "type": "VAE", - "link": 29 + "name": "model", + "type": "MODEL", + "link": 9 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 7 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 8 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 17 } ], "outputs": [ { - "name": "VAE", - "type": "VAE", + "name": "LATENT", + "type": "LATENT", "links": [ - 31 - ] + 14 + ], + "slot_index": 0 } ], "properties": { - "Node name for S&R": "TorchCompileLoadVAE" + "Node name for S&R": "KSampler" }, "widgets_values": [ - "inductor", - true, - "reduce-overhead", - true, - true + 945236422600751, + "randomize", + 1, + 1, + "lcm", + "normal", + 1 ] }, + { + "id": 15, + "type": "PreviewImage", + "pos": [ + 2878.828125, + 299.9607238769531 + ], + "size": [ + 210, + 246 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 15 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [] + }, { "id": 14, "type": "VAEDecode", "pos": [ - 1845, - 130 + 2521.657470703125, + 307.1023254394531 ], "size": [ 210, @@ -430,12 +431,12 @@ { "name": "samples", "type": "LATENT", - "link": 30 + "link": 14 }, { "name": "vae", "type": "VAE", - "link": 31 + "link": 16 } ], "outputs": [ @@ -443,125 +444,144 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 32 - ] + 15 + ], + "slot_index": 0 } ], "properties": { "Node name for S&R": "VAEDecode" - } + }, + "widgets_values": [] }, { - "id": 15, - "type": "PreviewImage", + "id": 13, + "type": "TorchCompileLoadVAE", "pos": [ - 2155, - 130 + 1138.843017578125, + 1457.9476318359375 ], "size": [ - 210, - 246 + 315, + 154 ], "flags": {}, - "order": 14, + "order": 9, "mode": 0, "inputs": [ { - "name": "images", - "type": "IMAGE", - "link": 32 + "name": "vae", + "type": "VAE", + "link": 13 + } + ], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 16 + ], + "slot_index": 0 } ], - "outputs": [], "properties": { - "Node name for S&R": "PreviewImage" - } + "Node name for S&R": "TorchCompileLoadVAE" + }, + "widgets_values": [ + "inductor", + true, + "reduce-overhead", + true, + true + ] }, { - "id": 16, - "type": "EmptyLatentImage", + "id": 1, + "type": "LoadImage", "pos": [ - 100, - 1178 + 803, + -123 ], "size": [ 315, - 106 + 314 ], "flags": {}, - "order": 3, + "order": 4, "mode": 0, "inputs": [], "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "IMAGE", + "type": "IMAGE", "links": [ - 23 - ] + 1 + ], + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null } ], "properties": { - "Node name for S&R": "EmptyLatentImage" + "Node name for S&R": "LoadImage" }, "widgets_values": [ - 512, - 512, - 1 + "DALL·E 2024-11-15 10.15.49 - An anime-style character standing in a modern office space. The character is a young professional, dressed in a stylish business outfit, with medium-l.jpg", + "image" ] }, { - "id": 4, - "type": "CheckpointLoaderSimple", + "id": 2, + "type": "DepthAnythingTensorrt", "pos": [ - 100, - 574 + 1238, + 77 ], "size": [ 315, - 98 + 58 ], "flags": {}, - "order": 4, + "order": 10, "mode": 0, - "inputs": [], - "outputs": [ + "inputs": [ { - "name": "MODEL", - "type": "MODEL", - "links": null - }, + "name": "images", + "type": "IMAGE", + "link": 1 + } + ], + "outputs": [ { - "name": "CLIP", - "type": "CLIP", + "name": "IMAGE", + "type": "IMAGE", "links": [ - 18, - 19 - ] - }, - { - "name": "VAE", - "type": "VAE", - "links": null + 12 + ], + "slot_index": 0 } ], "properties": { - "Node name for S&R": "CheckpointLoaderSimple" + "Node name for S&R": "DepthAnythingTensorrt" }, "widgets_values": [ - "SD1.5/dreamshaper-8.safetensors" + "depth_anything_v2_vits-fp16.engine" ] }, { - "id": 1, - "type": "LoadImage", + "id": 16, + "type": "EmptyLatentImage", "pos": [ - 100, - 130 + 1627, + -92 ], "size": [ 315, - 314 + 106 ], "flags": {}, "order": 5, @@ -569,30 +589,27 @@ "inputs": [], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", + "name": "LATENT", + "type": "LATENT", "links": [ 17 - ] - }, - { - "name": "MASK", - "type": "MASK", - "links": null + ], + "slot_index": 0 } ], "properties": { - "Node name for S&R": "LoadImage" + "Node name for S&R": "EmptyLatentImage" }, "widgets_values": [ - "example.png", - "image" + 512, + 512, + 1 ] } ], "links": [ [ - 17, + 1, 1, 0, 2, @@ -600,7 +617,7 @@ "IMAGE" ], [ - 18, + 2, 4, 1, 5, @@ -608,7 +625,7 @@ "CLIP" ], [ - 19, + 3, 4, 1, 6, @@ -616,15 +633,23 @@ "CLIP" ], [ - 20, - 3, + 4, + 5, 0, - 7, + 9, 0, - "MODEL" + "CONDITIONING" ], [ - 21, + 5, + 6, + 0, + 9, + 1, + "CONDITIONING" + ], + [ + 7, 9, 0, 7, @@ -632,7 +657,7 @@ "CONDITIONING" ], [ - 22, + 8, 9, 1, 7, @@ -640,31 +665,23 @@ "CONDITIONING" ], [ - 23, - 16, - 0, - 7, + 9, 3, - "LATENT" - ], - [ - 24, - 5, 0, - 9, + 7, 0, - "CONDITIONING" + "MODEL" ], [ - 25, - 6, + 10, + 8, 0, - 9, - 1, - "CONDITIONING" + 10, + 0, + "CONTROL_NET" ], [ - 26, + 11, 10, 0, 9, @@ -672,7 +689,7 @@ "CONTROL_NET" ], [ - 27, + 12, 2, 0, 9, @@ -680,15 +697,7 @@ "IMAGE" ], [ - 28, - 8, - 0, - 10, - 0, - "CONTROL_NET" - ], - [ - 29, + 13, 11, 0, 13, @@ -696,7 +705,7 @@ "VAE" ], [ - 30, + 14, 7, 0, 14, @@ -704,7 +713,15 @@ "LATENT" ], [ - 31, + 15, + 14, + 0, + 15, + 0, + "IMAGE" + ], + [ + 16, 13, 0, 14, @@ -712,30 +729,24 @@ "VAE" ], [ - 32, - 14, - 0, - 15, + 17, + 16, 0, - "IMAGE" + 7, + 3, + "LATENT" ] ], "groups": [], "config": {}, "extra": { "ds": { - "scale": 0.7513148009015777, + "scale": 0.5131581182307082, "offset": [ - 660.8600621028962, - 94.59269584816836 + -374.74081589726774, + -39.464450618247305 ] - }, - "node_versions": { - "ComfyUI-Depth-Anything-Tensorrt": "ede57bac05059731f955c1b1563af2c1947f999a", - "ComfyUI_TensorRT": "657994a5481897944a62266ab9f4f9aef24f93f4", - "comfy-core": "0.3.12", - "ComfyUI-Torch-Compile": "28b36d2569b39c303b2d9b0e5540ec5d628164af" } }, "version": 0.4 -} +} \ No newline at end of file From 89a7e218614fbbb499832b0471cac94d9d14f1c6 Mon Sep 17 00:00:00 2001 From: PSchroedl Date: Wed, 5 Feb 2025 14:34:14 -0800 Subject: [PATCH 55/62] revert tensorrt engine name change in workflow 3 (#41) --- workflows/ui/3 - SD 1.5 TensorRT workflow.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index 24a12891..241df140 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -291,7 +291,7 @@ "Node name for S&R": "TensorRTLoader" }, "widgets_values": [ - "ComfyUI_STAT_dreamshaper-8-dmd-1kstep-fp8_SD15_$stat-b-1-h-512-w-512_00001_.engine", + "static-dreamshaper8_SD15_$stat-b-1-h-512-w-512_00001_.engine", "SD15" ] }, From e4980b0ae6665581f0e107f89b2d8976215c25a5 Mon Sep 17 00:00:00 2001 From: PSchroedl Date: Thu, 6 Feb 2025 09:22:04 -0800 Subject: [PATCH 56/62] change DepthAnythingTensorrt engine to match infra (#47) --- workflows/ui/3 - SD 1.5 TensorRT workflow.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index 241df140..56818290 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -569,7 +569,7 @@ "Node name for S&R": "DepthAnythingTensorrt" }, "widgets_values": [ - "depth_anything_v2_vits-fp16.engine" + "depth_anything_v2_vitl14-fp16.engine" ] }, { From 2b37c009de0a22e6794b62d62addbfafb28ba5ab Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 6 Feb 2025 18:48:13 +0100 Subject: [PATCH 57/62] chore: Add issue templates for bug reports and feature requests (#46) This commit adds issue templates to guide users in submitting bug reports and feature requests. The templates help ensure that the submitted issues contain the necessary information, making it easier for developers to understand and address them. --- ui/.github/ISSUE_TEMPLATE/bug_report.yml | 77 +++++++++++++++++++ ui/.github/ISSUE_TEMPLATE/feature_request.yml | 46 +++++++++++ 2 files changed, 123 insertions(+) create mode 100644 ui/.github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 ui/.github/ISSUE_TEMPLATE/feature_request.yml diff --git a/ui/.github/ISSUE_TEMPLATE/bug_report.yml b/ui/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..378dc802 --- /dev/null +++ b/ui/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,77 @@ +name: Bug report +description: Create a report to help us improve +title: "[BUG] " +labels: [bug] +assignees: [] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + + - type: input + id: bug_description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + placeholder: Describe the bug here + validations: + required: true + + - type: textarea + id: bug_reproduction + attributes: + label: To Reproduce + description: | + Steps to reproduce the behavior: + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + placeholder: Steps to reproduce the behavior + validations: + required: true + + - type: input + id: expected_behavior + attributes: + label: Expected behavior + description: A clear and concise description of what you expected to happen. + placeholder: Describe the expected behavior here + validations: + required: true + + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain your problem. + placeholder: Add screenshots here + + - type: input + id: desktop_info + attributes: + label: Desktop (please complete the following information) + description: | + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + placeholder: Add desktop information here + + - type: input + id: smartphone_info + attributes: + label: Smartphone (please complete the following information) + description: | + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + placeholder: Add smartphone information here + + - type: textarea + id: additional_context + attributes: + label: Additional context + description: Add any other context about the problem here + placeholder: Add additional context here diff --git a/ui/.github/ISSUE_TEMPLATE/feature_request.yml b/ui/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..11781438 --- /dev/null +++ b/ui/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,46 @@ +name: Feature request +description: Suggest an idea for this project +title: "[FEATURE] " +labels: [enhancement] +assignees: [] +body: + - type: markdown + attributes: + value: | + Thanks for suggesting a feature! Please fill out the following details. + + - type: dropdown + id: feature_type + attributes: + label: Feature type + description: Is this feature related to the UI or the server? + options: + - UI + - Server + validations: + required: true + + - type: input + id: feature_description + attributes: + label: Describe the feature + description: A clear and concise description of what you want to happen. + placeholder: Describe the feature here + validations: + required: true + + - type: textarea + id: feature_motivation + attributes: + label: Motivation + description: Explain why this feature would be useful. + placeholder: Explain the motivation here + validations: + required: true + + - type: textarea + id: additional_context + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here + placeholder: Add additional context here From b8fc3cace436769d433ac74943bf4cc3b0e7635d Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 6 Feb 2025 20:19:34 +0100 Subject: [PATCH 58/62] fix: move issue templates to top-level folder (#49) This commit relocates the issue templates to the top-level folder of the repository. This change ensures that the issue templates are correctly recognized and utilized by GitHub for creating new issues. --- {ui/.github => .github}/ISSUE_TEMPLATE/bug_report.yml | 0 {ui/.github => .github}/ISSUE_TEMPLATE/feature_request.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {ui/.github => .github}/ISSUE_TEMPLATE/bug_report.yml (100%) rename {ui/.github => .github}/ISSUE_TEMPLATE/feature_request.yml (100%) diff --git a/ui/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml similarity index 100% rename from ui/.github/ISSUE_TEMPLATE/bug_report.yml rename to .github/ISSUE_TEMPLATE/bug_report.yml diff --git a/ui/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml similarity index 100% rename from ui/.github/ISSUE_TEMPLATE/feature_request.yml rename to .github/ISSUE_TEMPLATE/feature_request.yml From 36b31e0906b1f570543faab4ac65779491a10a12 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 6 Feb 2025 21:43:15 +0100 Subject: [PATCH 59/62] chore: update node dependencies (#43) This commit updates the node dependencies to their latest version to prevent node dependency warnings and errors from occuring. --- ui/package-lock.json | 868 ++++++++++++++----------------------------- ui/package.json | 20 +- 2 files changed, 283 insertions(+), 605 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 7038757c..0fef8b0d 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -9,20 +9,20 @@ "version": "0.1.0", "dependencies": { "@hookform/resolvers": "^3.9.1", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-select": "^2.1.2", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.6", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lucide-react": "^0.454.0", - "next": "15.0.2", - "next-themes": "^0.3.0", - "react": "19.0.0-rc-02c0e824-20241028", - "react-dom": "19.0.0-rc-02c0e824-20241028", + "next": "15.1.6", + "next-themes": "^0.4.4", + "react": "^19.0.0", + "react-dom": "^19.0.0", "react-hook-form": "^7.53.1", - "sonner": "^1.5.0", + "sonner": "^1.7.4", "tailwind-merge": "^2.5.4", "tailwindcss-animate": "^1.0.7", "vaul": "^1.1.1", @@ -43,7 +43,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "engines": { "node": ">=10" }, @@ -120,22 +119,22 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", - "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.8" + "@floating-ui/utils": "^0.2.9" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", - "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.8" + "@floating-ui/utils": "^0.2.9" } }, "node_modules/@floating-ui/react-dom": { @@ -152,9 +151,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", "license": "MIT" }, "node_modules/@hookform/resolvers": { @@ -546,7 +545,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -563,7 +561,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "engines": { "node": ">=12" }, @@ -575,7 +572,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -590,7 +586,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -604,7 +599,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -613,7 +607,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -621,23 +614,22 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@next/env": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.0.2.tgz", - "integrity": "sha512-c0Zr0ModK5OX7D4ZV8Jt/wqoXtitLNPwUfG9zElCZztdaZyNVnN40rDXVZ/+FGuR4CcNV5AEfM6N8f+Ener7Dg==" + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.6.tgz", + "integrity": "sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==", + "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { "version": "15.0.2", @@ -649,12 +641,13 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.2.tgz", - "integrity": "sha512-GK+8w88z+AFlmt+ondytZo2xpwlfAR8U6CRwXancHImh6EdGfHMIrTSCcx5sOSBei00GyLVL0ioo1JLKTfprgg==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.6.tgz", + "integrity": "sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -664,12 +657,13 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.2.tgz", - "integrity": "sha512-KUpBVxIbjzFiUZhiLIpJiBoelqzQtVZbdNNsehhUn36e2YzKHphnK8eTUW1s/4aPy5kH/UTid8IuVbaOpedhpw==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.6.tgz", + "integrity": "sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -679,12 +673,13 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.2.tgz", - "integrity": "sha512-9J7TPEcHNAZvwxXRzOtiUvwtTD+fmuY0l7RErf8Yyc7kMpE47MIQakl+3jecmkhOoIyi/Rp+ddq7j4wG6JDskQ==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.6.tgz", + "integrity": "sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -694,12 +689,13 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.2.tgz", - "integrity": "sha512-BjH4ZSzJIoTTZRh6rG+a/Ry4SW0HlizcPorqNBixBWc3wtQtj4Sn9FnRZe22QqrPnzoaW0ctvSz4FaH4eGKMww==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.6.tgz", + "integrity": "sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -709,12 +705,13 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.2.tgz", - "integrity": "sha512-i3U2TcHgo26sIhcwX/Rshz6avM6nizrZPvrDVDY1bXcLH1ndjbO8zuC7RoHp0NSK7wjJMPYzm7NYL1ksSKFreA==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.6.tgz", + "integrity": "sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -724,12 +721,13 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.2.tgz", - "integrity": "sha512-AMfZfSVOIR8fa+TXlAooByEF4OB00wqnms1sJ1v+iu8ivwvtPvnkwdzzFMpsK5jA2S9oNeeQ04egIWVb4QWmtQ==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.6.tgz", + "integrity": "sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -739,12 +737,13 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.2.tgz", - "integrity": "sha512-JkXysDT0/hEY47O+Hvs8PbZAeiCQVxKfGtr4GUpNAhlG2E0Mkjibuo8ryGD29Qb5a3IOnKYNoZlh/MyKd2Nbww==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.6.tgz", + "integrity": "sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -754,12 +753,13 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.2.tgz", - "integrity": "sha512-foaUL0NqJY/dX0Pi/UcZm5zsmSk5MtP/gxx3xOPyREkMFN+CTjctPfu3QaqrQHinaKdPnMWPJDKt4VjDfTBe/Q==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.6.tgz", + "integrity": "sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -772,7 +772,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -785,7 +784,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -794,7 +792,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -816,7 +813,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -829,17 +825,18 @@ "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", + "license": "MIT" }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.2.tgz", + "integrity": "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", @@ -857,15 +854,15 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", - "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.2.tgz", + "integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -882,25 +879,11 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -926,24 +909,25 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz", - "integrity": "sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz", + "integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -976,13 +960,14 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz", - "integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz", + "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-escape-keydown": "1.1.0" }, @@ -1016,12 +1001,13 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", - "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz", + "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==", + "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { @@ -1057,11 +1043,12 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz", - "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.2.tgz", + "integrity": "sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", @@ -1079,16 +1066,16 @@ } }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz", + "integrity": "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-arrow": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-rect": "1.1.0", @@ -1110,27 +1097,13 @@ } } }, - "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", - "integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz", + "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { @@ -1149,11 +1122,12 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", - "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { @@ -1172,11 +1146,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz", + "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==", + "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.1.0" + "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -1194,32 +1169,32 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.2.tgz", - "integrity": "sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz", + "integrity": "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==", "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.0", - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "@radix-ui/react-visually-hidden": "1.1.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -1237,11 +1212,12 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz", + "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", + "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1254,227 +1230,23 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.6.tgz", - "integrity": "sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.8.tgz", + "integrity": "sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.1", - "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-arrow": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", - "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", - "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", - "dependencies": { - "@radix-ui/primitive": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", - "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.1", - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", - "dependencies": { - "@radix-ui/react-slot": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", - "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", - "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.1" + "@radix-ui/react-visually-hidden": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -1605,12 +1377,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", - "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.2.tgz", + "integrity": "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", @@ -1651,11 +1423,12 @@ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" }, "node_modules/@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@types/json5": { @@ -1677,13 +1450,13 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "dev": true + "devOptional": true }, "node_modules/@types/react": { "version": "18.3.12", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1693,7 +1466,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -1979,7 +1752,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1988,7 +1760,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2002,14 +1773,12 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2021,8 +1790,7 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/argparse": { "version": "2.0.1", @@ -2242,14 +2010,12 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, "engines": { "node": ">=8" }, @@ -2271,7 +2037,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -2322,7 +2087,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "engines": { "node": ">= 6" } @@ -2366,7 +2130,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2390,7 +2153,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -2447,7 +2209,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2458,8 +2219,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color-string": { "version": "1.9.1", @@ -2475,7 +2235,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, "engines": { "node": ">= 6" } @@ -2490,7 +2249,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2504,7 +2262,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -2516,7 +2273,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "devOptional": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2649,14 +2406,12 @@ "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/doctrine": { "version": "3.0.0", @@ -2673,14 +2428,12 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/enhanced-resolve": { "version": "5.17.1", @@ -3328,7 +3081,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3344,7 +3096,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -3368,7 +3119,6 @@ "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -3389,7 +3139,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3446,7 +3195,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -3468,7 +3216,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -3482,7 +3229,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3595,7 +3341,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -3731,7 +3476,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -3804,14 +3548,6 @@ "node": ">= 0.4" } }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -3865,7 +3601,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -3914,7 +3649,6 @@ "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -3959,7 +3693,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3980,7 +3713,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -4004,7 +3736,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -4040,7 +3771,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -4206,8 +3936,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/iterator.prototype": { "version": "1.1.3", @@ -4229,7 +3958,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -4244,7 +3972,6 @@ "version": "1.21.6", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -4252,7 +3979,8 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", @@ -4355,7 +4083,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -4363,8 +4090,7 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/locate-path": { "version": "6.0.0", @@ -4391,6 +4117,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -4401,8 +4128,7 @@ "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, "node_modules/lucide-react": { "version": "0.454.0", @@ -4416,7 +4142,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -4425,7 +4150,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -4459,7 +4183,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -4474,7 +4197,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -4505,13 +4227,14 @@ "dev": true }, "node_modules/next": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/next/-/next-15.0.2.tgz", - "integrity": "sha512-rxIWHcAu4gGSDmwsELXacqAPUk+j8dV/A9cDF5fsiCMpkBDYkO2AEaL1dfD+nNmDiU6QMCFN8Q30VEKapT9UHQ==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.6.tgz", + "integrity": "sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==", + "license": "MIT", "dependencies": { - "@next/env": "15.0.2", + "@next/env": "15.1.6", "@swc/counter": "0.1.3", - "@swc/helpers": "0.5.13", + "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -4521,25 +4244,25 @@ "next": "dist/bin/next" }, "engines": { - "node": ">=18.18.0" + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.0.2", - "@next/swc-darwin-x64": "15.0.2", - "@next/swc-linux-arm64-gnu": "15.0.2", - "@next/swc-linux-arm64-musl": "15.0.2", - "@next/swc-linux-x64-gnu": "15.0.2", - "@next/swc-linux-x64-musl": "15.0.2", - "@next/swc-win32-arm64-msvc": "15.0.2", - "@next/swc-win32-x64-msvc": "15.0.2", + "@next/swc-darwin-arm64": "15.1.6", + "@next/swc-darwin-x64": "15.1.6", + "@next/swc-linux-arm64-gnu": "15.1.6", + "@next/swc-linux-arm64-musl": "15.1.6", + "@next/swc-linux-x64-gnu": "15.1.6", + "@next/swc-linux-x64-musl": "15.1.6", + "@next/swc-win32-arm64-msvc": "15.1.6", + "@next/swc-win32-x64-msvc": "15.1.6", "sharp": "^0.33.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-02c0e824-20241028", - "react-dom": "^18.2.0 || 19.0.0-rc-02c0e824-20241028", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "peerDependenciesMeta": { @@ -4558,12 +4281,13 @@ } }, "node_modules/next-themes": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz", - "integrity": "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.4.tgz", + "integrity": "sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==", + "license": "MIT", "peerDependencies": { - "react": "^16.8 || ^17 || ^18", - "react-dom": "^16.8 || ^17 || ^18" + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "node_modules/next/node_modules/postcss": { @@ -4597,7 +4321,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4606,7 +4329,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4615,7 +4337,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "engines": { "node": ">= 6" } @@ -4781,8 +4502,7 @@ "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -4818,7 +4538,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -4826,14 +4545,12 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -4854,7 +4571,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -4866,7 +4582,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4875,7 +4590,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, "engines": { "node": ">= 6" } @@ -4893,7 +4607,6 @@ "version": "8.4.47", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -4921,7 +4634,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -4938,7 +4650,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -4957,7 +4668,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -4992,7 +4702,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, "engines": { "node": ">=14" }, @@ -5004,7 +4713,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5029,7 +4737,6 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -5041,8 +4748,7 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -5077,7 +4783,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -5094,22 +4799,24 @@ ] }, "node_modules/react": { - "version": "19.0.0-rc-02c0e824-20241028", - "resolved": "https://registry.npmjs.org/react/-/react-19.0.0-rc-02c0e824-20241028.tgz", - "integrity": "sha512-GbZ7hpPHQMiEu53BqEaPQVM/4GG4hARo+mqEEnx4rYporDvNvUjutiAFxYFSbu6sgHwcr7LeFv8htEOwALVA2A==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.0.0-rc-02c0e824-20241028", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0-rc-02c0e824-20241028.tgz", - "integrity": "sha512-LrZf3DfHL6Fs07wwlUCHrzFTCMM19yA99MvJpfLokN4I2nBAZvREGZjZAn8VPiSfN72+i9j1eL4wB8gC695F3Q==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "license": "MIT", "dependencies": { - "scheduler": "0.25.0-rc-02c0e824-20241028" + "scheduler": "^0.25.0" }, "peerDependencies": { - "react": "19.0.0-rc-02c0e824-20241028" + "react": "^19.0.0" } }, "node_modules/react-hook-form": { @@ -5134,22 +4841,23 @@ "dev": true }, "node_modules/react-remove-scroll": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", - "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "license": "MIT", "dependencies": { - "react-remove-scroll-bar": "^2.3.6", - "react-style-singleton": "^2.2.1", + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" }, "engines": { "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -5158,19 +4866,20 @@ } }, "node_modules/react-remove-scroll-bar": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", - "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", "dependencies": { - "react-style-singleton": "^2.2.1", + "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "engines": { "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -5179,20 +4888,20 @@ } }, "node_modules/react-style-singleton": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", - "invariant": "^2.2.4", "tslib": "^2.0.0" }, "engines": { "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -5204,7 +4913,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -5213,7 +4921,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -5264,7 +4971,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5299,7 +5005,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -5325,7 +5030,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -5380,9 +5084,10 @@ } }, "node_modules/scheduler": { - "version": "0.25.0-rc-02c0e824-20241028", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0-rc-02c0e824-20241028.tgz", - "integrity": "sha512-GysnKjmMSaWcwsKTLzeJO0IhU3EyIiC0ivJKE6yDNLqt3IMxDByx8b6lSNXRNdN+ULUY0WLLjSPaZ0LuU/GnTg==" + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" }, "node_modules/semver": { "version": "7.6.3", @@ -5471,7 +5176,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5483,7 +5187,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -5510,7 +5213,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -5528,12 +5230,13 @@ } }, "node_modules/sonner": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.5.0.tgz", - "integrity": "sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz", + "integrity": "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==", + "license": "MIT", "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "node_modules/source-map-js": { @@ -5556,7 +5259,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -5574,7 +5276,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5587,14 +5288,12 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "engines": { "node": ">=12" }, @@ -5606,7 +5305,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -5720,7 +5418,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5733,7 +5430,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5788,7 +5484,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -5810,7 +5505,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -5819,7 +5513,6 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -5839,7 +5532,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5866,7 +5558,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5887,7 +5578,6 @@ "version": "3.4.14", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", - "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -5947,7 +5637,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "dependencies": { "any-promise": "^1.0.0" } @@ -5956,7 +5645,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -5968,7 +5656,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -5991,8 +5678,7 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tsconfig-paths": { "version": "3.15.0", @@ -6152,9 +5838,10 @@ } }, "node_modules/use-callback-ref": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", - "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -6162,8 +5849,8 @@ "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -6172,9 +5859,10 @@ } }, "node_modules/use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -6183,8 +5871,8 @@ "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -6195,8 +5883,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/vaul": { "version": "1.1.1", @@ -6214,7 +5901,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -6317,7 +6003,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -6335,7 +6020,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6351,14 +6035,12 @@ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6372,7 +6054,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "engines": { "node": ">=12" }, @@ -6384,7 +6065,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { "node": ">=12" }, @@ -6396,7 +6076,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -6417,7 +6096,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", - "dev": true, "bin": { "yaml": "bin.mjs" }, diff --git a/ui/package.json b/ui/package.json index 2c8abb91..26e7d1da 100644 --- a/ui/package.json +++ b/ui/package.json @@ -11,20 +11,20 @@ }, "dependencies": { "@hookform/resolvers": "^3.9.1", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-select": "^2.1.2", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.6", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lucide-react": "^0.454.0", - "next": "15.0.2", - "next-themes": "^0.3.0", - "react": "19.0.0-rc-02c0e824-20241028", - "react-dom": "19.0.0-rc-02c0e824-20241028", + "next": "15.1.6", + "next-themes": "^0.4.4", + "react": "^19.0.0", + "react-dom": "^19.0.0", "react-hook-form": "^7.53.1", - "sonner": "^1.5.0", + "sonner": "^1.7.4", "tailwind-merge": "^2.5.4", "tailwindcss-animate": "^1.0.7", "vaul": "^1.1.1", From 27781216fccfecb175c9649167845bf4f0521ec8 Mon Sep 17 00:00:00 2001 From: RyanOnTheInside Date: Thu, 6 Feb 2025 17:00:26 -0500 Subject: [PATCH 60/62] feat: persist control panel state when drawer closes (#30) - Move panel state to container component - Pass state down as props to control panels - Maintain values across drawer open/close cycles Co-authored-by: ryanontheinstide --- ui/src/components/control-panel.tsx | 113 ++++++++++-------- .../components/control-panels-container.tsx | 45 ++++++- 2 files changed, 108 insertions(+), 50 deletions(-) diff --git a/ui/src/components/control-panel.tsx b/ui/src/components/control-panel.tsx index 7788594c..2afff7da 100644 --- a/ui/src/components/control-panel.tsx +++ b/ui/src/components/control-panel.tsx @@ -17,6 +17,21 @@ interface NodeInfo { inputs: Record; } +interface ControlPanelProps { + panelState: { + nodeId: string; + fieldName: string; + value: string; + isAutoUpdateEnabled: boolean; + }; + onStateChange: (state: Partial<{ + nodeId: string; + fieldName: string; + value: string; + isAutoUpdateEnabled: boolean; + }>) => void; +} + const InputControl = ({ input, value, @@ -92,13 +107,9 @@ const InputControl = ({ } }; -export const ControlPanel = () => { +export const ControlPanel = ({ panelState, onStateChange }: ControlPanelProps) => { const { controlChannel } = usePeerContext(); const { currentPrompt, setCurrentPrompt } = usePrompt(); - const [nodeId, setNodeId] = useState(""); - const [fieldName, setFieldName] = useState(""); - const [value, setValue] = useState("0"); - const [isAutoUpdateEnabled, setIsAutoUpdateEnabled] = useState(false); const [availableNodes, setAvailableNodes] = useState>({}); // Add ref to track last sent value and timeout @@ -141,7 +152,7 @@ export const ControlPanel = () => { }, [controlChannel]); const handleValueChange = (newValue: string) => { - const currentInput = nodeId && fieldName ? availableNodes[nodeId]?.inputs[fieldName] : null; + const currentInput = panelState.nodeId && panelState.fieldName ? availableNodes[panelState.nodeId]?.inputs[panelState.fieldName] : null; if (currentInput) { // Validate against min/max if they exist for number types @@ -154,51 +165,51 @@ export const ControlPanel = () => { } } - setValue(newValue); + onStateChange({ value: newValue }); }; // Modify the effect that sends updates with debouncing useEffect(() => { - const currentInput = nodeId && fieldName ? availableNodes[nodeId]?.inputs[fieldName] : null; + const currentInput = panelState.nodeId && panelState.fieldName ? availableNodes[panelState.nodeId]?.inputs[panelState.fieldName] : null; if (!currentInput || !currentPrompt) return; let isValidValue = true; - let processedValue: any = value; + let processedValue: any = panelState.value; // Validate and process value based on type switch (currentInput.type.toLowerCase()) { case 'number': - isValidValue = /^-?\d*\.?\d*$/.test(value) && value !== ''; - processedValue = parseFloat(value); + isValidValue = /^-?\d*\.?\d*$/.test(panelState.value) && panelState.value !== ''; + processedValue = parseFloat(panelState.value); break; case 'boolean': - isValidValue = value === 'true' || value === 'false'; - processedValue = value === 'true'; + isValidValue = panelState.value === 'true' || panelState.value === 'false'; + processedValue = panelState.value === 'true'; break; case 'string': // String can be empty, so always valid - processedValue = value; + processedValue = panelState.value; break; default: if (currentInput.widget === 'combo') { - isValidValue = value !== ''; - processedValue = value; + isValidValue = panelState.value !== ''; + processedValue = panelState.value; } else { - isValidValue = value !== ''; - processedValue = value; + isValidValue = panelState.value !== ''; + processedValue = panelState.value; } } - const hasRequiredFields = nodeId.trim() !== "" && fieldName.trim() !== ""; + const hasRequiredFields = panelState.nodeId.trim() !== "" && panelState.fieldName.trim() !== ""; // Check if the value has actually changed const lastSent = lastSentValueRef.current; const hasValueChanged = !lastSent || - lastSent.nodeId !== nodeId || - lastSent.fieldName !== fieldName || + lastSent.nodeId !== panelState.nodeId || + lastSent.fieldName !== panelState.fieldName || lastSent.value !== processedValue; - if (controlChannel && isAutoUpdateEnabled && isValidValue && hasRequiredFields && hasValueChanged) { + if (controlChannel && panelState.isAutoUpdateEnabled && isValidValue && hasRequiredFields && hasValueChanged) { // Clear any existing timeout if (updateTimeoutRef.current) { clearTimeout(updateTimeoutRef.current); @@ -208,13 +219,13 @@ export const ControlPanel = () => { updateTimeoutRef.current = setTimeout(() => { // Create updated prompt while maintaining current structure const updatedPrompt = JSON.parse(JSON.stringify(currentPrompt)); // Deep clone - if (updatedPrompt[nodeId] && updatedPrompt[nodeId].inputs) { - updatedPrompt[nodeId].inputs[fieldName] = processedValue; + if (updatedPrompt[panelState.nodeId] && updatedPrompt[panelState.nodeId].inputs) { + updatedPrompt[panelState.nodeId].inputs[panelState.fieldName] = processedValue; // Update last sent value lastSentValueRef.current = { - nodeId, - fieldName, + nodeId: panelState.nodeId, + fieldName: panelState.fieldName, value: processedValue }; @@ -230,10 +241,10 @@ export const ControlPanel = () => { } }, currentInput.type.toLowerCase() === 'number' ? 100 : 300); // Shorter delay for numbers, longer for text } - }, [value, nodeId, fieldName, controlChannel, isAutoUpdateEnabled, availableNodes, currentPrompt, setCurrentPrompt]); + }, [panelState.value, panelState.nodeId, panelState.fieldName, panelState.isAutoUpdateEnabled, controlChannel, availableNodes, currentPrompt, setCurrentPrompt]); const toggleAutoUpdate = () => { - setIsAutoUpdateEnabled(!isAutoUpdateEnabled); + onStateChange({ isAutoUpdateEnabled: !panelState.isAutoUpdateEnabled }); }; // Modified to handle initial values better @@ -250,23 +261,29 @@ export const ControlPanel = () => { // Update the field selection handler const handleFieldSelect = (e: React.ChangeEvent) => { const selectedField = e.target.value; - setFieldName(selectedField); - const input = availableNodes[nodeId]?.inputs[selectedField]; + const input = availableNodes[panelState.nodeId]?.inputs[selectedField]; if (input) { const initialValue = getInitialValue(input); - setValue(initialValue); + onStateChange({ + fieldName: selectedField, + value: initialValue + }); + } else { + onStateChange({ fieldName: selectedField }); } }; return (
- {nodeId && fieldName && availableNodes[nodeId]?.inputs[fieldName] && ( + {panelState.nodeId && panelState.fieldName && availableNodes[panelState.nodeId]?.inputs[panelState.fieldName] && ( )} - {nodeId && fieldName && availableNodes[nodeId]?.inputs[fieldName]?.type === 'number' && ( + {panelState.nodeId && panelState.fieldName && availableNodes[panelState.nodeId]?.inputs[panelState.fieldName]?.type === 'number' && ( - {availableNodes[nodeId]?.inputs[fieldName]?.min !== undefined && - availableNodes[nodeId]?.inputs[fieldName]?.max !== undefined && - `(${availableNodes[nodeId]?.inputs[fieldName]?.min} - ${availableNodes[nodeId]?.inputs[fieldName]?.max})` + {availableNodes[panelState.nodeId]?.inputs[panelState.fieldName]?.min !== undefined && + availableNodes[panelState.nodeId]?.inputs[panelState.fieldName]?.max !== undefined && + `(${availableNodes[panelState.nodeId]?.inputs[panelState.fieldName]?.min} - ${availableNodes[panelState.nodeId]?.inputs[panelState.fieldName]?.max})` } )} @@ -324,13 +341,13 @@ export const ControlPanel = () => { className={`p-2 rounded ${ !controlChannel ? 'bg-gray-300 text-gray-600 cursor-not-allowed' - : isAutoUpdateEnabled + : panelState.isAutoUpdateEnabled ? 'bg-green-500 text-white' : 'bg-red-500 text-white' }`} > Auto-Update {controlChannel - ? (isAutoUpdateEnabled ? '(ON)' : '(OFF)') + ? (panelState.isAutoUpdateEnabled ? '(ON)' : '(OFF)') : '(Not Connected)'}
diff --git a/ui/src/components/control-panels-container.tsx b/ui/src/components/control-panels-container.tsx index 0bd5b0df..4aa9d569 100644 --- a/ui/src/components/control-panels-container.tsx +++ b/ui/src/components/control-panels-container.tsx @@ -15,14 +15,52 @@ export const ControlPanelsContainer = () => { const [panels, setPanels] = useState([0]); // Start with one panel const [nextPanelId, setNextPanelId] = useState(1); const [isOpen, setIsOpen] = useState(false); + const [panelStates, setPanelStates] = useState>({ + 0: { + nodeId: "", + fieldName: "", + value: "0", + isAutoUpdateEnabled: false + } + }); const addPanel = () => { - setPanels([...panels, nextPanelId]); + const newId = nextPanelId; + setPanels([...panels, newId]); + setPanelStates(prev => ({ + ...prev, + [newId]: { + nodeId: "", + fieldName: "", + value: "0", + isAutoUpdateEnabled: false + } + })); setNextPanelId(nextPanelId + 1); }; const removePanel = (id: number) => { setPanels(panels.filter(panelId => panelId !== id)); + setPanelStates(prev => { + const newState = { ...prev }; + delete newState[id]; + return newState; + }); + }; + + const updatePanelState = (id: number, state: Partial) => { + setPanelStates(prev => ({ + ...prev, + [id]: { + ...prev[id], + ...state + } + })); }; return ( @@ -108,7 +146,10 @@ export const ControlPanelsContainer = () => {
- + updatePanelState(id, state)} + />
))} From 2a6cc4653b8f6226ea5bf91d84ff7c8619290974 Mon Sep 17 00:00:00 2001 From: Peter Schroedl Date: Thu, 6 Feb 2025 23:39:17 +0000 Subject: [PATCH 61/62] reconcile depth anything naming with infra --- workflows/ui/3 - SD 1.5 TensorRT workflow.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index 24a12891..e782b858 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -569,7 +569,7 @@ "Node name for S&R": "DepthAnythingTensorrt" }, "widgets_values": [ - "depth_anything_v2_vits-fp16.engine" + "depth_anything_vits-fp16.engine" ] }, { From 88ce570e3ca5521c8fa906979f5e32293022a84e Mon Sep 17 00:00:00 2001 From: Peter Schroedl Date: Thu, 6 Feb 2025 23:44:03 +0000 Subject: [PATCH 62/62] vits -> vitl14 --- workflows/ui/3 - SD 1.5 TensorRT workflow.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/ui/3 - SD 1.5 TensorRT workflow.json b/workflows/ui/3 - SD 1.5 TensorRT workflow.json index e782b858..6611629f 100644 --- a/workflows/ui/3 - SD 1.5 TensorRT workflow.json +++ b/workflows/ui/3 - SD 1.5 TensorRT workflow.json @@ -569,7 +569,7 @@ "Node name for S&R": "DepthAnythingTensorrt" }, "widgets_values": [ - "depth_anything_vits-fp16.engine" + "depth_anything_vitl14-fp16.engine" ] }, {