A custom node's own range decides the packages it names
TripoSR's checkpoint loads with transformers 4, and ComfyUI runs 5: of a package a node names, its range decides, and of everything else what ComfyUI runs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4b68328e3e
commit
dfc2f0bf15
6 files changed
+51
-11
No files matched your search
@@ -8626,7 +8626,7 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Requirements are the PyPI packages the node needs that ComfyUI does not have, by name and version range only. They are installed beside the replica, never into ComfyUI's environment, at the versions that environment already has of anything it shares."
|
||||
"description": "Requirements are the PyPI packages the node needs, by name and version range only. They are installed beside the replica, never into ComfyUI's environment: a package named here at the range named, and every other one at the version ComfyUI already runs. One named here is first on ComfyUI's path, so its range must suit ComfyUI too."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+5
-4
@@ -912,10 +912,11 @@ node that changed under a model is a model that changed unasked.
|
||||
|
||||
`[]string`
|
||||
|
||||
Requirements are the PyPI packages the node needs that ComfyUI does
|
||||
not have, by name and version range only. They are installed beside
|
||||
the replica, never into ComfyUI's environment, at the versions that
|
||||
environment already has of anything it shares.
|
||||
Requirements are the PyPI packages the node needs, by name and version
|
||||
range only. They are installed beside the replica, never into
|
||||
ComfyUI's environment: a package named here at the range named, and
|
||||
every other one at the version ComfyUI already runs. One named here
|
||||
is first on ComfyUI's path, so its range must suit ComfyUI too.
|
||||
|
||||
## Endpoint
|
||||
|
||||
|
||||
+30
-1
@@ -83,7 +83,7 @@ func installNodes(ctx context.Context, state, python string, nodes []Node, uv st
|
||||
return "", fmt.Errorf("reading ComfyUI's packages: %w", err)
|
||||
}
|
||||
constraints := filepath.Join(state, "constraints.txt")
|
||||
if err := os.WriteFile(constraints, freeze, 0o644); err != nil { //nolint:gosec // not secret
|
||||
if err := os.WriteFile(constraints, withoutNamed(freeze, reqs), 0o644); err != nil { //nolint:gosec // not secret
|
||||
return "", err
|
||||
}
|
||||
_ = os.RemoveAll(site)
|
||||
@@ -136,3 +136,32 @@ func lastLines(b []byte) string {
|
||||
}
|
||||
return strings.Join(lines, " | ")
|
||||
}
|
||||
|
||||
// withoutNamed is ComfyUI's packages less those a node names itself: of a
|
||||
// package a node asks for by name, the node's range decides — TripoSR's
|
||||
// checkpoint loads with transformers 4 and not 5 — and of everything else,
|
||||
// what ComfyUI runs. A node that names a package must name a range ComfyUI
|
||||
// can run with too: the copy it gets is first on ComfyUI's path.
|
||||
func withoutNamed(freeze []byte, reqs []string) []byte {
|
||||
named := map[string]bool{}
|
||||
for _, r := range reqs {
|
||||
named[packageName(r)] = true
|
||||
}
|
||||
var out []string
|
||||
for _, line := range strings.Split(string(freeze), "\n") {
|
||||
if strings.TrimSpace(line) == "" || named[packageName(line)] {
|
||||
continue
|
||||
}
|
||||
out = append(out, line)
|
||||
}
|
||||
return []byte(strings.Join(out, "\n") + "\n")
|
||||
}
|
||||
|
||||
// packageName is a requirement's package, as PyPI compares them.
|
||||
func packageName(spec string) string {
|
||||
s := strings.TrimSpace(spec)
|
||||
if i := strings.IndexAny(s, "<>=!~;[ @"); i >= 0 {
|
||||
s = s[:i]
|
||||
}
|
||||
return strings.NewReplacer("_", "-", ".", "-").Replace(strings.ToLower(s))
|
||||
}
|
||||
@@ -181,3 +181,12 @@ func TestANodeIsPutAtItsCommit(t *testing.T) {
|
||||
t.Errorf("packages without a uv: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestANodesOwnRangeDecidesThePackagesItNames(t *testing.T) {
|
||||
freeze := []byte("numpy==2.3.1\ntransformers==5.19.0\nhuggingface-hub==1.33.0\nPillow==12.3.0\n")
|
||||
got := string(withoutNamed(freeze, []string{"transformers>=4.50.3,<5", "Huggingface_Hub<1", "trimesh"}))
|
||||
if strings.Contains(got, "transformers") || strings.Contains(got, "huggingface") ||
|
||||
!strings.Contains(got, "numpy==2.3.1") || !strings.Contains(got, "Pillow==12.3.0") {
|
||||
t.Errorf("constraints %q", got)
|
||||
}
|
||||
}
|
||||
@@ -564,10 +564,11 @@ type CustomNode struct {
|
||||
// Commit is the full commit the node is used at: a branch moves, and a
|
||||
// node that changed under a model is a model that changed unasked.
|
||||
Commit string `json:"commit" koanf:"commit"`
|
||||
// Requirements are the PyPI packages the node needs that ComfyUI does
|
||||
// not have, by name and version range only. They are installed beside
|
||||
// the replica, never into ComfyUI's environment, at the versions that
|
||||
// environment already has of anything it shares.
|
||||
// Requirements are the PyPI packages the node needs, by name and version
|
||||
// range only. They are installed beside the replica, never into
|
||||
// ComfyUI's environment: a package named here at the range named, and
|
||||
// every other one at the version ComfyUI already runs. One named here
|
||||
// is first on ComfyUI's path, so its range must suit ComfyUI too.
|
||||
Requirements []string `json:"requirements,omitempty" koanf:"requirements"`
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ var Reference = []Block{
|
||||
{Package: "catalog", Name: "CustomNode", Title: "CustomNode", Doc: "", Fields: []Field{
|
||||
{Key: "repo", Type: "string", Doc: "Repo is the repository, https only.", Nested: ""},
|
||||
{Key: "commit", Type: "string", Doc: "Commit is the full commit the node is used at: a branch moves, and a\nnode that changed under a model is a model that changed unasked.", Nested: ""},
|
||||
{Key: "requirements", Type: "[]string", Doc: "Requirements are the PyPI packages the node needs that ComfyUI does\nnot have, by name and version range only. They are installed beside\nthe replica, never into ComfyUI's environment, at the versions that\nenvironment already has of anything it shares.", Nested: ""},
|
||||
{Key: "requirements", Type: "[]string", Doc: "Requirements are the PyPI packages the node needs, by name and version\nrange only. They are installed beside the replica, never into\nComfyUI's environment: a package named here at the range named, and\nevery other one at the version ComfyUI already runs. One named here\nis first on ComfyUI's path, so its range must suit ComfyUI too.", Nested: ""},
|
||||
}},
|
||||
{Package: "config", Name: "Endpoint", Title: "Endpoint", Doc: "", Fields: []Field{
|
||||
{Key: "id", Type: "string", Doc: "", Nested: ""},
|
||||
|
||||
Reference in new issue
Block a user