Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions comfy_cli/command/generate/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,21 @@ def _refresh() -> None:
with httpx.Client(timeout=30.0, follow_redirects=True) as cli:
r = cli.get(url, headers={"Comfy-Env": "comfy-cli", "User-Agent": "comfy-cli/api"})
r.raise_for_status()
except httpx.HTTPStatusError as e:
# The partner-proxy OpenAPI spec is not published at a public URL, so a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment about this URL where we list all Partner Nodes?

https://api.comfy.org/openapi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — you're right. It's published at /openapi (JSON), and /openapi.yml 404s. Fixed in a224a9c: refresh now fetches /openapi and caches it (validates it's a real spec first). Live-refresh actually works now.

# 404 here is expected, not a transient failure. Explain that the model
# catalog ships bundled with the CLI and updates via `pip install -U`,
# rather than dumping a raw HTTP error.
if e.response.status_code == 404:
rprint(
"[bold yellow]The partner model catalog is not available for live refresh.[/bold yellow]\n"
f"[dim]No public catalog is published at {url}.[/dim]\n"
f"The CLI uses its bundled catalog at [dim]{spec.active_spec_path()}[/dim].\n"
"To get newer models, update the CLI: [bold]pip install -U comfy-cli[/bold]."
)
raise typer.Exit(code=0)
rprint(f"[bold red]Failed to fetch {url}: {e}[/bold red]")
raise typer.Exit(code=1)
except httpx.HTTPError as e:
rprint(f"[bold red]Failed to fetch {url}: {e}[/bold red]")
raise typer.Exit(code=1)
Expand Down
36 changes: 26 additions & 10 deletions comfy_cli/command/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,16 +864,32 @@ def categories_cmd(

@app.command(
"refresh",
help="object_info is fetched live from the server on each command — nothing to refresh.",
help="Re-fetch node annotation data (pack/labels/cloud_disabled) from Comfy-Org/comfy-complete.",
)
@tracking.track_command("nodes")
def refresh_cmd(
where: Annotated[
str | None,
typer.Option("--where", show_default=False, help="Override the resolved routing mode."),
] = None,
):
"""Explain that object_info is fetched live and exit."""
def refresh_cmd():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropping --where makes this a breaking change for the call sites that still pass it. command/run/__init__.py:520 prints the hint run `comfy nodes refresh --where cloud` to populate the cache on cql_no_graph, and skills/comfy/SKILL.md:502 + skills/comfy-debug/SKILL.md:50 document the same command — all three now fail with No such option: --where (exit 2), right when someone's already stuck. Could we update those three references? Also worth noting: the new refresh only refreshes annotations, not the cloud object_info cache those hints are actually about.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that was broken — fixed in 4b3b3ed. Rewrote all three references (the run hint + both SKILL.md). Took your point that refresh only touches annotations now, so they point at the real fix (re-run once reachable / check comfy cloud whoami / local server) instead of re-adding --where.

"""Force-refresh the node annotation cache from the public comfy-complete repo.

``object_info`` itself is fetched live from the server on every command, so
there is nothing to refresh there. The *annotations* (which custom-node pack
a node belongs to, its behavioral labels, and whether it's disabled on
cloud) come from Comfy-Org/comfy-complete and are cached locally with a TTL;
this command pulls the latest copy immediately.
"""
renderer = get_renderer()
rprint("[dim]object_info is fetched live from the server on each command — nothing to refresh.[/dim]")
renderer.emit({"refreshed": False, "reason": "live_fetch"}, command="nodes refresh")
from comfy_cli.cql import annotations_source

results = annotations_source.refresh_annotations()
ok = all(r["source"] == "remote" for r in results)
if renderer.is_pretty():
for r in results:
if r["source"] == "remote":
rprint(f"[green]✓[/green] {r['name']} ({r['bytes']:,} bytes) → {r['path']}")
elif r["source"] == "bundled":
rprint(
f"[yellow]![/yellow] {r['name']}: remote fetch failed, using bundled snapshot "
f"([dim]{r.get('error', '')}[/dim])"
Comment on lines +889 to +891

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use neutral bundled-fallback wording.

When COMFY_CLI_NO_REMOTE_REFRESH is set, refresh_annotations() returns source: "bundled" with an error explaining remote refresh is disabled, so this pretty output reports an intentional airgapped path as a failure. Tiny wording goblin: let the reason carry the why.

Proposed wording tweak
                 rprint(
-                    f"[yellow]![/yellow] {r['name']}: remote fetch failed, using bundled snapshot "
-                    f"([dim]{r.get('error', '')}[/dim])"
+                    f"[yellow]![/yellow] {r['name']}: using bundled snapshot "
+                    f"([dim]{r.get('error') or 'remote unavailable'}[/dim])"
                 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rprint(
f"[yellow]![/yellow] {r['name']}: remote fetch failed, using bundled snapshot "
f"([dim]{r.get('error', '')}[/dim])"
rprint(
f"[yellow]![/yellow] {r['name']}: using bundled snapshot "
f"([dim]{r.get('error') or 'remote unavailable'}[/dim])"
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@comfy_cli/command/nodes.py` around lines 889 - 891, The bundled-fallback
message in refresh_annotations output is too failure-like for the intentional
COMFY_CLI_NO_REMOTE_REFRESH path. Update the rprint wording in nodes.py so the
refresh flow uses neutral “bundled” fallback language instead of “remote fetch
failed,” and let the existing error/reason field from refresh_annotations convey
why the bundled snapshot was used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 4b3b3ed — dropped the "remote fetch failed" wording, the reason field carries the why.

)
else:
rprint(f"[red]✗[/red] {r['name']}: unavailable ([dim]{r.get('error', '')}[/dim])")
renderer.emit({"refreshed": ok, "files": results}, command="nodes refresh")
21 changes: 5 additions & 16 deletions comfy_cli/command/run_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,26 +429,15 @@ def _build_steps(state: _DemoState) -> list[Step]:
],
),
Step(
title="queryCQL against the live node graph",
title="nodesintrospect the live node graph (CQL engine, flag-based)",
invocations=[
Invocation(
argv=[
*comfy,
"query",
"-q",
"from nodes where name in ('EmptyImage','ImageInvert','SaveImage') select name, category",
],
label="comfy query",
argv=[*comfy, "nodes", "search", "SaveImage"],
label="comfy nodes search SaveImage",
),
Invocation(
argv=[
*comfy,
"--json",
"query",
"-q",
"from nodes where name in ('EmptyImage','ImageInvert','SaveImage') select name, category",
],
label="comfy --json query",
argv=[*comfy, "--json", "nodes", "ls", "--produces", "IMAGE", "--limit", "5"],
label="comfy --json nodes ls --produces IMAGE --limit 5",
),
],
),
Expand Down
Loading
Loading