comfy-env 0.1.9__py3-none-any.whl → 0.1.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- comfy_env/isolation/wrap.py +29 -3
- comfy_env/pixi/core.py +32 -1
- comfy_env/prestartup.py +13 -2
- comfy_env/workers/mp.py +58 -0
- comfy_env/workers/subprocess.py +16 -4
- {comfy_env-0.1.9.dist-info → comfy_env-0.1.10.dist-info}/METADATA +1 -1
- {comfy_env-0.1.9.dist-info → comfy_env-0.1.10.dist-info}/RECORD +10 -10
- {comfy_env-0.1.9.dist-info → comfy_env-0.1.10.dist-info}/WHEEL +0 -0
- {comfy_env-0.1.9.dist-info → comfy_env-0.1.10.dist-info}/entry_points.txt +0 -0
- {comfy_env-0.1.9.dist-info → comfy_env-0.1.10.dist-info}/licenses/LICENSE +0 -0
comfy_env/isolation/wrap.py
CHANGED
|
@@ -34,6 +34,12 @@ from typing import Any, Dict, Optional
|
|
|
34
34
|
# Debug logging (set COMFY_ENV_DEBUG=1 to enable)
|
|
35
35
|
_DEBUG = os.environ.get("COMFY_ENV_DEBUG", "").lower() in ("1", "true", "yes")
|
|
36
36
|
|
|
37
|
+
|
|
38
|
+
def get_env_name(dir_name: str) -> str:
|
|
39
|
+
"""Convert directory name to env name: ComfyUI-UniRig → _env_unirig"""
|
|
40
|
+
name = dir_name.lower().replace("-", "_").lstrip("comfyui_")
|
|
41
|
+
return f"_env_{name}"
|
|
42
|
+
|
|
37
43
|
# Global worker cache (one per isolated environment)
|
|
38
44
|
_workers: Dict[str, Any] = {}
|
|
39
45
|
_workers_lock = threading.Lock()
|
|
@@ -144,13 +150,27 @@ def _find_env_paths(node_dir: Path) -> tuple[Optional[Path], Optional[Path]]:
|
|
|
144
150
|
"""
|
|
145
151
|
import glob
|
|
146
152
|
|
|
147
|
-
# Check
|
|
153
|
+
# Check _env_<name> directory first (new pattern)
|
|
154
|
+
env_name = get_env_name(node_dir.name)
|
|
155
|
+
env_dir = node_dir / env_name
|
|
156
|
+
if env_dir.exists():
|
|
157
|
+
if sys.platform == "win32":
|
|
158
|
+
site_packages = env_dir / "Lib" / "site-packages"
|
|
159
|
+
lib_dir = env_dir / "Library" / "bin"
|
|
160
|
+
else:
|
|
161
|
+
pattern = str(env_dir / "lib" / "python*" / "site-packages")
|
|
162
|
+
matches = glob.glob(pattern)
|
|
163
|
+
site_packages = Path(matches[0]) if matches else None
|
|
164
|
+
lib_dir = env_dir / "lib"
|
|
165
|
+
if site_packages and site_packages.exists():
|
|
166
|
+
return site_packages, lib_dir if lib_dir.exists() else None
|
|
167
|
+
|
|
168
|
+
# Fallback: Check old .pixi/envs/default (for backward compat)
|
|
148
169
|
pixi_env = node_dir / ".pixi" / "envs" / "default"
|
|
149
170
|
if pixi_env.exists():
|
|
150
|
-
# Find site-packages (pythonX.Y varies)
|
|
151
171
|
if sys.platform == "win32":
|
|
152
172
|
site_packages = pixi_env / "Lib" / "site-packages"
|
|
153
|
-
lib_dir = pixi_env / "Library" / "bin"
|
|
173
|
+
lib_dir = pixi_env / "Library" / "bin"
|
|
154
174
|
else:
|
|
155
175
|
pattern = str(pixi_env / "lib" / "python*" / "site-packages")
|
|
156
176
|
matches = glob.glob(pattern)
|
|
@@ -176,6 +196,12 @@ def _find_env_paths(node_dir: Path) -> tuple[Optional[Path], Optional[Path]]:
|
|
|
176
196
|
|
|
177
197
|
def _find_env_dir(node_dir: Path) -> Optional[Path]:
|
|
178
198
|
"""Find the environment directory (for cache key)."""
|
|
199
|
+
# Check _env_<name> first
|
|
200
|
+
env_name = get_env_name(node_dir.name)
|
|
201
|
+
env_dir = node_dir / env_name
|
|
202
|
+
if env_dir.exists():
|
|
203
|
+
return env_dir
|
|
204
|
+
# Fallback to old paths
|
|
179
205
|
pixi_env = node_dir / ".pixi" / "envs" / "default"
|
|
180
206
|
if pixi_env.exists():
|
|
181
207
|
return pixi_env
|
comfy_env/pixi/core.py
CHANGED
|
@@ -281,6 +281,12 @@ def ensure_pixi(
|
|
|
281
281
|
return pixi_path
|
|
282
282
|
|
|
283
283
|
|
|
284
|
+
def get_env_name(dir_name: str) -> str:
|
|
285
|
+
"""Convert directory name to env name: ComfyUI-UniRig → _env_unirig"""
|
|
286
|
+
name = dir_name.lower().replace("-", "_").lstrip("comfyui_")
|
|
287
|
+
return f"_env_{name}"
|
|
288
|
+
|
|
289
|
+
|
|
284
290
|
def clean_pixi_artifacts(node_dir: Path, log: Callable[[str], None] = print) -> None:
|
|
285
291
|
"""Remove previous pixi installation artifacts."""
|
|
286
292
|
for path in [node_dir / "pixi.toml", node_dir / "pixi.lock"]:
|
|
@@ -289,11 +295,21 @@ def clean_pixi_artifacts(node_dir: Path, log: Callable[[str], None] = print) ->
|
|
|
289
295
|
pixi_dir = node_dir / ".pixi"
|
|
290
296
|
if pixi_dir.exists():
|
|
291
297
|
shutil.rmtree(pixi_dir)
|
|
298
|
+
# Also clean old _env_* directories
|
|
299
|
+
env_name = get_env_name(node_dir.name)
|
|
300
|
+
env_dir = node_dir / env_name
|
|
301
|
+
if env_dir.exists():
|
|
302
|
+
shutil.rmtree(env_dir)
|
|
292
303
|
|
|
293
304
|
|
|
294
305
|
def get_pixi_python(node_dir: Path) -> Optional[Path]:
|
|
295
306
|
"""Get path to Python in the pixi environment."""
|
|
296
|
-
|
|
307
|
+
# Check new _env_<name> location first
|
|
308
|
+
env_name = get_env_name(node_dir.name)
|
|
309
|
+
env_dir = node_dir / env_name
|
|
310
|
+
if not env_dir.exists():
|
|
311
|
+
# Fallback to old .pixi path
|
|
312
|
+
env_dir = node_dir / ".pixi" / "envs" / "default"
|
|
297
313
|
if sys.platform == "win32":
|
|
298
314
|
python_path = env_dir / "python.exe"
|
|
299
315
|
else:
|
|
@@ -507,5 +523,20 @@ def pixi_install(
|
|
|
507
523
|
|
|
508
524
|
log("CUDA packages installed")
|
|
509
525
|
|
|
526
|
+
# Move environment from .pixi/envs/default to _env_<name>
|
|
527
|
+
old_env = node_dir / ".pixi" / "envs" / "default"
|
|
528
|
+
env_name = get_env_name(node_dir.name)
|
|
529
|
+
new_env = node_dir / env_name
|
|
530
|
+
|
|
531
|
+
if old_env.exists():
|
|
532
|
+
if new_env.exists():
|
|
533
|
+
shutil.rmtree(new_env) # Clean old env
|
|
534
|
+
shutil.move(str(old_env), str(new_env))
|
|
535
|
+
# Clean up .pixi directory (keep pixi.toml and pixi.lock)
|
|
536
|
+
pixi_dir = node_dir / ".pixi"
|
|
537
|
+
if pixi_dir.exists():
|
|
538
|
+
shutil.rmtree(pixi_dir)
|
|
539
|
+
log(f"Moved environment to {new_env}")
|
|
540
|
+
|
|
510
541
|
log("Installation complete!")
|
|
511
542
|
return True
|
comfy_env/prestartup.py
CHANGED
|
@@ -11,6 +11,12 @@ from pathlib import Path
|
|
|
11
11
|
from typing import Optional, Dict
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
def get_env_name(dir_name: str) -> str:
|
|
15
|
+
"""Convert directory name to env name: ComfyUI-UniRig → _env_unirig"""
|
|
16
|
+
name = dir_name.lower().replace("-", "_").lstrip("comfyui_")
|
|
17
|
+
return f"_env_{name}"
|
|
18
|
+
|
|
19
|
+
|
|
14
20
|
def _load_env_vars(config_path: str) -> Dict[str, str]:
|
|
15
21
|
"""
|
|
16
22
|
Load [env_vars] section from comfy-env.toml.
|
|
@@ -121,10 +127,15 @@ def setup_env(node_dir: Optional[str] = None) -> None:
|
|
|
121
127
|
for key, value in env_vars.items():
|
|
122
128
|
os.environ[key] = value
|
|
123
129
|
|
|
124
|
-
|
|
130
|
+
# Check _env_<name> first, then fallback to old .pixi path
|
|
131
|
+
env_name = get_env_name(os.path.basename(node_dir))
|
|
132
|
+
pixi_env = os.path.join(node_dir, env_name)
|
|
125
133
|
|
|
126
134
|
if not os.path.exists(pixi_env):
|
|
127
|
-
|
|
135
|
+
# Fallback to old .pixi path
|
|
136
|
+
pixi_env = os.path.join(node_dir, ".pixi", "envs", "default")
|
|
137
|
+
if not os.path.exists(pixi_env):
|
|
138
|
+
return # No environment found
|
|
128
139
|
|
|
129
140
|
if sys.platform == "win32":
|
|
130
141
|
# Windows: add to PATH for DLL loading
|
comfy_env/workers/mp.py
CHANGED
|
@@ -40,6 +40,53 @@ _SHUTDOWN = object()
|
|
|
40
40
|
_CALL_METHOD = "call_method"
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
# Tensor file transfer - avoids CUDA IPC issues with cudaMallocAsync
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
def _save_tensors_to_files(obj, file_registry=None):
|
|
48
|
+
"""Recursively save torch tensors to temp files for IPC."""
|
|
49
|
+
if file_registry is None:
|
|
50
|
+
file_registry = []
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
import torch
|
|
54
|
+
if isinstance(obj, torch.Tensor):
|
|
55
|
+
import tempfile
|
|
56
|
+
f = tempfile.NamedTemporaryFile(suffix='.pt', delete=False)
|
|
57
|
+
torch.save(obj.cpu(), f.name) # Always save as CPU tensor
|
|
58
|
+
f.close()
|
|
59
|
+
file_registry.append(f.name)
|
|
60
|
+
return {"__tensor_file__": f.name, "dtype": str(obj.dtype), "device": str(obj.device)}
|
|
61
|
+
except ImportError:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
if isinstance(obj, dict):
|
|
65
|
+
return {k: _save_tensors_to_files(v, file_registry) for k, v in obj.items()}
|
|
66
|
+
elif isinstance(obj, list):
|
|
67
|
+
return [_save_tensors_to_files(v, file_registry) for v in obj]
|
|
68
|
+
elif isinstance(obj, tuple):
|
|
69
|
+
return tuple(_save_tensors_to_files(v, file_registry) for v in obj)
|
|
70
|
+
return obj
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _load_tensors_from_files(obj):
|
|
74
|
+
"""Recursively load torch tensors from temp files."""
|
|
75
|
+
if isinstance(obj, dict):
|
|
76
|
+
if "__tensor_file__" in obj:
|
|
77
|
+
import os
|
|
78
|
+
import torch
|
|
79
|
+
tensor = torch.load(obj["__tensor_file__"], weights_only=True)
|
|
80
|
+
os.unlink(obj["__tensor_file__"]) # Cleanup temp file
|
|
81
|
+
return tensor
|
|
82
|
+
return {k: _load_tensors_from_files(v) for k, v in obj.items()}
|
|
83
|
+
elif isinstance(obj, list):
|
|
84
|
+
return [_load_tensors_from_files(v) for v in obj]
|
|
85
|
+
elif isinstance(obj, tuple):
|
|
86
|
+
return tuple(_load_tensors_from_files(v) for v in obj)
|
|
87
|
+
return obj
|
|
88
|
+
|
|
89
|
+
|
|
43
90
|
def _dump_worker_env(worker_name: str = "unknown", print_to_terminal: bool = False):
|
|
44
91
|
"""Dump worker environment to .comfy-env/logs/ (always) and optionally print."""
|
|
45
92
|
import json
|
|
@@ -205,14 +252,20 @@ def _worker_loop(queue_in, queue_out, sys_path_additions=None, lib_path=None, en
|
|
|
205
252
|
# Handle method call protocol
|
|
206
253
|
if isinstance(item, tuple) and len(item) == 6 and item[0] == _CALL_METHOD:
|
|
207
254
|
_, module_name, class_name, method_name, self_state, kwargs = item
|
|
255
|
+
# Load tensors from files (saved by host to avoid cudaMallocAsync IPC issues)
|
|
256
|
+
kwargs = _load_tensors_from_files(kwargs)
|
|
208
257
|
result = _execute_method_call(
|
|
209
258
|
module_name, class_name, method_name, self_state, kwargs
|
|
210
259
|
)
|
|
260
|
+
# Save tensors to files to avoid CUDA IPC issues with cudaMallocAsync
|
|
261
|
+
result = _save_tensors_to_files(result)
|
|
211
262
|
queue_out.put(("ok", result))
|
|
212
263
|
else:
|
|
213
264
|
# Direct function call (legacy)
|
|
214
265
|
func, args, kwargs = item
|
|
215
266
|
result = func(*args, **kwargs)
|
|
267
|
+
# Save tensors to files to avoid CUDA IPC issues with cudaMallocAsync
|
|
268
|
+
result = _save_tensors_to_files(result)
|
|
216
269
|
queue_out.put(("ok", result))
|
|
217
270
|
|
|
218
271
|
except Exception as e:
|
|
@@ -646,6 +699,9 @@ class MPWorker(Worker):
|
|
|
646
699
|
"""
|
|
647
700
|
self._ensure_started()
|
|
648
701
|
|
|
702
|
+
# Save tensors to files to avoid CUDA IPC issues with cudaMallocAsync
|
|
703
|
+
kwargs = _save_tensors_to_files(kwargs)
|
|
704
|
+
|
|
649
705
|
# Send method call request using protocol
|
|
650
706
|
self._queue_in.put((
|
|
651
707
|
_CALL_METHOD,
|
|
@@ -672,6 +728,8 @@ class MPWorker(Worker):
|
|
|
672
728
|
|
|
673
729
|
# Handle response
|
|
674
730
|
if status == "ok":
|
|
731
|
+
# Load tensors from temp files
|
|
732
|
+
result = _load_tensors_from_files(result)
|
|
675
733
|
return result
|
|
676
734
|
elif status == "error":
|
|
677
735
|
msg, tb = result
|
comfy_env/workers/subprocess.py
CHANGED
|
@@ -221,10 +221,12 @@ def _to_shm(obj, registry, visited=None):
|
|
|
221
221
|
visited[obj_id] = result
|
|
222
222
|
return result
|
|
223
223
|
|
|
224
|
-
# torch.Tensor → convert to numpy → shared memory
|
|
224
|
+
# torch.Tensor → convert to numpy → shared memory (with marker to restore type)
|
|
225
225
|
if t == 'Tensor':
|
|
226
226
|
arr = obj.detach().cpu().numpy()
|
|
227
|
-
|
|
227
|
+
result = _to_shm(arr, registry, visited)
|
|
228
|
+
result["__was_tensor__"] = True
|
|
229
|
+
return result
|
|
228
230
|
|
|
229
231
|
# trimesh.Trimesh → vertices + faces arrays → shared memory
|
|
230
232
|
if t == 'Trimesh':
|
|
@@ -279,13 +281,17 @@ def _from_shm(obj, unlink=True):
|
|
|
279
281
|
return [_from_shm(v, unlink) for v in obj]
|
|
280
282
|
return obj
|
|
281
283
|
|
|
282
|
-
# numpy array
|
|
284
|
+
# numpy array (or tensor that was converted to numpy)
|
|
283
285
|
if "__shm_np__" in obj:
|
|
284
286
|
block = shm.SharedMemory(name=obj["__shm_np__"])
|
|
285
287
|
arr = np.ndarray(tuple(obj["shape"]), dtype=np.dtype(obj["dtype"]), buffer=block.buf).copy()
|
|
286
288
|
block.close()
|
|
287
289
|
if unlink:
|
|
288
290
|
block.unlink()
|
|
291
|
+
# Convert back to tensor if it was originally a tensor
|
|
292
|
+
if obj.get("__was_tensor__"):
|
|
293
|
+
import torch
|
|
294
|
+
return torch.from_numpy(arr)
|
|
289
295
|
return arr
|
|
290
296
|
|
|
291
297
|
# trimesh
|
|
@@ -544,7 +550,9 @@ def _to_shm(obj, registry, visited=None):
|
|
|
544
550
|
|
|
545
551
|
if t == 'Tensor':
|
|
546
552
|
arr = obj.detach().cpu().numpy()
|
|
547
|
-
|
|
553
|
+
result = _to_shm(arr, registry, visited)
|
|
554
|
+
result["__was_tensor__"] = True
|
|
555
|
+
return result
|
|
548
556
|
|
|
549
557
|
if t == 'Trimesh':
|
|
550
558
|
verts = np.ascontiguousarray(obj.vertices, dtype=np.float64)
|
|
@@ -587,6 +595,10 @@ def _from_shm(obj):
|
|
|
587
595
|
block = shm.SharedMemory(name=obj["__shm_np__"])
|
|
588
596
|
arr = np.ndarray(tuple(obj["shape"]), dtype=np.dtype(obj["dtype"]), buffer=block.buf).copy()
|
|
589
597
|
block.close()
|
|
598
|
+
# Convert back to tensor if it was originally a tensor
|
|
599
|
+
if obj.get("__was_tensor__"):
|
|
600
|
+
import torch
|
|
601
|
+
return torch.from_numpy(arr)
|
|
590
602
|
return arr
|
|
591
603
|
if "__shm_trimesh__" in obj:
|
|
592
604
|
import trimesh
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: comfy-env
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: Environment management for ComfyUI custom nodes - CUDA wheel resolution and process isolation
|
|
5
5
|
Project-URL: Homepage, https://github.com/PozzettiAndrea/comfy-env
|
|
6
6
|
Project-URL: Repository, https://github.com/PozzettiAndrea/comfy-env
|
|
@@ -3,14 +3,14 @@ comfy_env/cli.py,sha256=ty4HYlzollCUCS0o6Sha6eczPAsW_gHRVgvck3IfA2w,12723
|
|
|
3
3
|
comfy_env/errors.py,sha256=q-C3vyrPa_kk_Ao8l17mIGfJiG2IR0hCFV0GFcNLmcI,9924
|
|
4
4
|
comfy_env/install.py,sha256=N7eBj8wB2DrGepVYk-Hks2mSf6UuGzj34pfVLNYJgQ4,10357
|
|
5
5
|
comfy_env/nodes.py,sha256=nR-LctovXYTqk-seHovq9W_Ll0hlLeGMw-SQsa6IkBM,5235
|
|
6
|
-
comfy_env/prestartup.py,sha256=
|
|
6
|
+
comfy_env/prestartup.py,sha256=aKuW07R0CmoeIXukENJZnGMPzCv7kU7azvHgIOt2usk,5813
|
|
7
7
|
comfy_env/config/__init__.py,sha256=4Guylkb-FV8QxhFwschzpzbr2eu8y-KNgNT3_JOm9jc,403
|
|
8
8
|
comfy_env/config/parser.py,sha256=dA1lX5ExBEfCqUJwe4V5i_jn2NJ69bMq3c3ji3lMSV8,4295
|
|
9
9
|
comfy_env/config/types.py,sha256=Sb8HO34xsSZu5YAc2K4M7Gb3QNevJlngf12hHiwuU0w,2140
|
|
10
10
|
comfy_env/isolation/__init__.py,sha256=vw9a4mpJ2CFjy-PLe_A3zQ6umBQklgqWNxwn9beNw3g,175
|
|
11
|
-
comfy_env/isolation/wrap.py,sha256=
|
|
11
|
+
comfy_env/isolation/wrap.py,sha256=9pxlrO2qUP-4Aov9LUXhgqkDw8V4FT-M-YPeDRXUjuE,13664
|
|
12
12
|
comfy_env/pixi/__init__.py,sha256=BUrq7AQf3WDm0cHWh72B2xZbURNnDu2dCuELWiQCUiM,997
|
|
13
|
-
comfy_env/pixi/core.py,sha256=
|
|
13
|
+
comfy_env/pixi/core.py,sha256=jy1CAaryPlldCm9bGq6i2UnPckYqyqzQELSDhQsB8ho,19958
|
|
14
14
|
comfy_env/pixi/cuda_detection.py,sha256=sqB3LjvGNdV4eFqiARQGfyecBM3ZiUmeh6nG0YCRYQw,9751
|
|
15
15
|
comfy_env/pixi/resolver.py,sha256=U_A8rBDxCj4gUlJt2YJQniP4cCKqxJEiVFgXOoH7vM8,6339
|
|
16
16
|
comfy_env/pixi/platform/__init__.py,sha256=Nb5MPZIEeanSMEWwqU4p4bnEKTJn1tWcwobnhq9x9IY,614
|
|
@@ -22,11 +22,11 @@ comfy_env/templates/comfy-env-instructions.txt,sha256=ve1RAthW7ouumU9h6DM7mIRX1M
|
|
|
22
22
|
comfy_env/templates/comfy-env.toml,sha256=ROIqi4BlPL1MEdL1VgebfTHpdwPNYGHwWeigI9Kw-1I,4831
|
|
23
23
|
comfy_env/workers/__init__.py,sha256=TMVG55d2XLP1mJ3x1d16H0SBDJZtk2kMC5P4HLk9TrA,1073
|
|
24
24
|
comfy_env/workers/base.py,sha256=4ZYTaQ4J0kBHCoO_OfZnsowm4rJCoqinZUaOtgkOPbw,2307
|
|
25
|
-
comfy_env/workers/mp.py,sha256=
|
|
26
|
-
comfy_env/workers/subprocess.py,sha256=
|
|
25
|
+
comfy_env/workers/mp.py,sha256=vsxDGWepmSNgfqBhZPW7h8yOiKEyQcDFYP09masLTV4,32337
|
|
26
|
+
comfy_env/workers/subprocess.py,sha256=neggSmCqJxfiIOCUQwn_TrDONFJoT5veBZuMjDYf_LA,58537
|
|
27
27
|
comfy_env/workers/tensor_utils.py,sha256=TCuOAjJymrSbkgfyvcKtQ_KbVWTqSwP9VH_bCaFLLq8,6409
|
|
28
|
-
comfy_env-0.1.
|
|
29
|
-
comfy_env-0.1.
|
|
30
|
-
comfy_env-0.1.
|
|
31
|
-
comfy_env-0.1.
|
|
32
|
-
comfy_env-0.1.
|
|
28
|
+
comfy_env-0.1.10.dist-info/METADATA,sha256=tfO_Jhe-jz6XY_AHhfnHroJAVuAzDAe4evf9FYY3nw0,6971
|
|
29
|
+
comfy_env-0.1.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
30
|
+
comfy_env-0.1.10.dist-info/entry_points.txt,sha256=J4fXeqgxU_YenuW_Zxn_pEL7J-3R0--b6MS5t0QmAr0,49
|
|
31
|
+
comfy_env-0.1.10.dist-info/licenses/LICENSE,sha256=E68QZMMpW4P2YKstTZ3QU54HRQO8ecew09XZ4_Vn870,1093
|
|
32
|
+
comfy_env-0.1.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|