feat(other): guide standalone users to settings.json from the no-paths empty state

The standalone empty state showed the folder_paths keys but not where to
put them, and its Open Settings button led to a modal that cannot edit
primary folder paths. Now the page shows the real settings.json path and
an Open Settings Folder button backed by the existing open-location API.

Also stop open_settings_location from claiming success on headless Linux
sessions: with no DISPLAY/WAYLAND_DISPLAY, xdg-open cannot work, so the
handler now returns clipboard mode and the browser copies/shows the path
instead.
This commit is contained in:
Will Miao
2026-09-17 10:30:20 +08:00
parent 9eeebac40b
commit 369613f811
17 changed files with 231 additions and 16 deletions
+17
View File
@@ -421,6 +421,11 @@ def _wsl_to_windows_path(wsl_path: str) -> str | None:
return None
def _has_gui_display() -> bool:
"""Check whether a GUI session is reachable for xdg-open."""
return bool(os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"))
class PromptServerProtocol(Protocol):
"""Subset of PromptServer used by the handlers."""
@@ -3393,6 +3398,18 @@ class FileSystemHandler:
subprocess.Popen(["open", "-R", settings_file])
else:
folder = os.path.dirname(settings_file)
if not _has_gui_display():
# Headless/SSH session: xdg-open cannot open a file
# manager, so hand the path to the browser for copying
# instead of reporting a success that never happened.
return web.json_response(
{
"success": True,
"message": "Headless session: path available for copying",
"path": settings_file,
"mode": "clipboard",
}
)
subprocess.Popen(["xdg-open", folder])
return web.json_response(
+6 -1
View File
@@ -83,11 +83,16 @@ class OtherRoutes(BaseModelRoutes):
# resolved to no existing folder. Render an actionable empty state
# instead of an apparently broken empty grid.
standalone_mode = os.environ.get("LORA_MANAGER_STANDALONE", "0") == "1"
return {
context = {
"other_disabled": False,
"other_no_paths": not bool(config.other_roots),
"standalone_mode": standalone_mode,
}
if standalone_mode:
# The settings UI cannot edit primary folder_paths, so the empty
# state must point at the actual file the user has to edit.
context["settings_file"] = getattr(self._settings, "settings_file", "") or ""
return context
def _get_expected_model_types(self) -> str:
"""Get expected model types string for error messages"""