From 976b00861136855759a650cea038df0f0d3415a1 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 21:14:17 -0700 Subject: [PATCH] refactor(web-profiles/status): AST-neutral bracket hugging --- hermes_cli/web_routers/profiles.py | 48 +++++++----------- hermes_cli/web_routers/status.py | 78 ++++++++++-------------------- hermes_cli/web_server_profiles.py | 13 ++--- 3 files changed, 47 insertions(+), 92 deletions(-) diff --git a/hermes_cli/web_routers/profiles.py b/hermes_cli/web_routers/profiles.py index 402666c7d8..d123daf639 100644 --- a/hermes_cli/web_routers/profiles.py +++ b/hermes_cli/web_routers/profiles.py @@ -90,8 +90,7 @@ def _profile_to_dict(info) -> Dict[str, Any]: "distribution_name": attr("distribution_name", None), "distribution_version": attr("distribution_version", None), "distribution_source": attr("distribution_source", None), - "has_alias": attr("alias_path", None) is not None, - } + "has_alias": attr("alias_path", None) is not None} def _profile_setup_command(name: str) -> str: @@ -128,7 +127,8 @@ def _disable_unselected_skills(profile_dir: Path, keep: List[str]) -> int: keep_set = {s.strip() for s in keep if s and s.strip()} with _hermes_home_scope(profile_dir): skills_root = profile_dir / "skills" - installed = [md.parent.name for md in skills_root.rglob("SKILL.md")] if skills_root.is_dir() else [] + installed = ([md.parent.name for md in skills_root.rglob("SKILL.md")] + if skills_root.is_dir() else []) cfg = load_config() disabled = get_disabled_skills(cfg) newly = 0 @@ -202,8 +202,7 @@ def _tag_rows(rows: List[Dict[str, Any]], name: str, now: float) -> List[Dict[st s["profile"] = name s["is_default_profile"] = name == "default" s["is_active"] = ( - s.get("ended_at") is None - and (now - s.get("last_active", s.get("started_at", 0))) < 300 + s.get("ended_at") is None and (now - s.get("last_active", s.get("started_at", 0))) < 300 ) s["archived"] = bool(s.get("archived")) s["pinned"] = bool(s.get("pinned")) @@ -413,8 +412,7 @@ def get_profiles_sessions( source: str = None, sources: str = None, exclude_sources: str = None, - full: bool = False, -): + full: bool = False): """Unified, read-only session list aggregated across ALL profiles. Process-light: opens each profile's ``state.db`` directly from disk — it does NOT spawn @@ -441,8 +439,7 @@ def get_profiles_sessions( exclude_sources=_csv_list(exclude_sources) or None, min_message_count=max(0, min_messages), include_archived=archived == "include", - archived_only=archived == "only", - ) + archived_only=archived == "only") # Over-fetch per profile so the merged+sorted window is correct for the requested page. # Capped so a huge profile can't blow up the response. per_profile = min(max(limit + offset, limit), 500) @@ -456,8 +453,7 @@ def get_profiles_sessions( rows = db.list_sessions_rich( limit=per_profile, offset=0, order_by_last_active=order == "recent", # Same SQL-level blob skip as /api/sessions. - compact_rows=not full, include_pinned=True, **filters, - ) + compact_rows=not full, include_pinned=True, **filters) totals[name] = db.session_count(exclude_children=True, **filters) merged.extend(_tag_rows(rows, name, now)) _read_profile_db(name, home, errors, _read) @@ -479,8 +475,7 @@ def get_profiles_sessions_sidebar( recents_exclude: str = None, cron_limit: int = 50, messaging_limit: int = 100, - messaging_exclude: str = None, -): + messaging_exclude: str = None): """Batched sidebar session slices — one profile-DB open per refresh. The desktop sidebar needs three source-scoped windows per refresh: recents (local @@ -518,8 +513,7 @@ def get_profiles_sessions_sidebar( return db.list_sessions_rich( source=source, exclude_sources=exclude or None, limit=cap, offset=0, min_message_count=1, include_archived=False, archived_only=False, - order_by_last_active=True, compact_rows=True, include_pinned=True, - ) + order_by_last_active=True, compact_rows=True, include_pinned=True) def _build_slices(db, cache_key): slices = { @@ -528,8 +522,7 @@ def get_profiles_sessions_sidebar( # and a total that shrank when you scrolled would be worse than no total at all. "usage": db.usage_totals(), "cron": _slice(db, source="cron", cap=cron_cap), - "messaging": _slice(db, exclude=messaging_exclude_list, cap=messaging_cap), - } + "messaging": _slice(db, exclude=messaging_exclude_list, cap=messaging_cap)} _sidebar_profile_cache_put(cache_key, slices) return slices @@ -571,8 +564,7 @@ def get_profiles_sessions_sidebar( "profiles_truncated": recents_truncated, "profiles_usage": profile_totals}, "cron": {"sessions": _window(cron_rows, cron_cap)}, "messaging": {"sessions": _window(messaging_rows, messaging_cap), "total": len(messaging_rows)}, - "errors": errors, - } + "errors": errors} def _merge_by_id(into: Dict[str, Dict[str, Any]], entries: List[Dict[str, Any]], child_key: str) -> None: @@ -601,8 +593,7 @@ def _merge_profile_tree( merged: Dict[str, Dict[str, Any]], projects: List[Dict[str, Any]], profile: str, - preview_limit: int, -) -> None: + preview_limit: int) -> None: """Fold one profile's projects into the shared tree, keyed by folder. The same checkout in two profiles is one group, as is ``__no_project__`` (every profile @@ -677,8 +668,7 @@ def get_profiles_projects_tree(preview_limit: int = 3, session_limit: int = 2000 "projects": sorted(merged.values(), key=lambda p: p.get("lastActive") or 0, reverse=True), # Ownership is per profile, so no project is "the active one" here; the desktop only # reads active_id to bias its overview sort. - "active_id": None, "scoped_session_ids": scoped_session_ids, "errors": errors, - } + "active_id": None, "scoped_session_ids": scoped_session_ids, "errors": errors} # `gh pr create` prints the PR url and nothing else, so a tool result whose whole output IS @@ -803,8 +793,7 @@ async def create_profile_endpoint(body: ProfileCreate): {"identifier": ident, "pid": _best_effort( "Spawning hub-skill install %s for new profile %s failed", ident, body.name, fn=lambda: _spawn_install(ident))} - for ident in ((i or "").strip() for i in body.hub_skills) if ident - ] + for ident in ((i or "").strip() for i in body.hub_skills) if ident] return {"ok": True, "name": body.name, "path": str(path), "model_set": model_set, "mcp_written": mcp_written, "skills_disabled": skills_disabled, @@ -855,8 +844,7 @@ async def get_profile_setup_command(name: str): _LINUX_TERMINALS = ( ("x-terminal-emulator", "-e"), ("gnome-terminal", "--"), ("konsole", "-e"), ("xfce4-terminal", None), ("mate-terminal", None), ("lxterminal", None), - ("tilix", "-e"), ("alacritty", "-e"), ("kitty", ""), ("xterm", "-e"), -) + ("tilix", "-e"), ("alacritty", "-e"), ("kitty", ""), ("xterm", "-e")) def _linux_terminal_commands(command: str) -> list: @@ -864,8 +852,7 @@ def _linux_terminal_commands(command: str) -> list: quoted = f"sh -lc '{command}'" return [ (exe, [exe, "-e", quoted] if flag is None else [exe, *([flag] if flag else []), *sh]) - for exe, flag in _LINUX_TERMINALS - ] + for exe, flag in _LINUX_TERMINALS] @router.post("/api/profiles/{name}/open-terminal") @@ -1028,8 +1015,7 @@ async def describe_profile_auto_endpoint(name: str, body: ProfileDescribeAuto): "description": outcome.description, # Only a successful generation is an auto-authored description. A failed sweep # leaves any existing description untouched, so don't claim it's auto-generated. - "description_auto": bool(outcome.ok), - } + "description_auto": bool(outcome.ok)} # ── Export / Import ────────────────────────────────────────────────────────── diff --git a/hermes_cli/web_routers/status.py b/hermes_cli/web_routers/status.py index 5e7feddeca..f38b535894 100644 --- a/hermes_cli/web_routers/status.py +++ b/hermes_cli/web_routers/status.py @@ -75,8 +75,7 @@ def _count_status_active_sessions() -> int: return sum( 1 for s in sessions if s.get("ended_at") is None - and (now - s.get("last_active", s.get("started_at", 0))) < 300 - ) + and (now - s.get("last_active", s.get("started_at", 0))) < 300) finally: db.close() @@ -85,13 +84,11 @@ async def _status_active_sessions() -> int: try: return await asyncio.wait_for( run_in_threadpool(_count_status_active_sessions), - timeout=_STATUS_ACTIVE_SESSIONS_TIMEOUT, - ) + timeout=_STATUS_ACTIVE_SESSIONS_TIMEOUT) except asyncio.TimeoutError: _log.debug( "/api/status active session count exceeded %.2fs; returning 0", - _STATUS_ACTIVE_SESSIONS_TIMEOUT, - ) + _STATUS_ACTIVE_SESSIONS_TIMEOUT) except Exception as exc: _log.debug("/api/status active session count unavailable: %s", exc) return 0 @@ -107,8 +104,7 @@ async def get_ssh_ownership(request: Request): "ok": True, "sshOwnerNonce": _SSH_OWNER_NONCE, "protocolVersion": 1, - "runtimeIntact": _ssh_runtime_intact(), - } + "runtimeIntact": _ssh_runtime_intact()} @router.get("/api/health") @@ -117,8 +113,7 @@ async def get_health(): return { "ok": True, "version": __version__, - "auth_required": bool(getattr(app.state, "auth_required", False)), - } + "auth_required": bool(getattr(app.state, "auth_required", False))} # Profile segment mirrors hermes_cli.profiles._PROFILE_ID_RE. Platform segment mirrors the @@ -202,8 +197,7 @@ def _bounded_health_probe(): _log.warning( "/api/status gateway health probe exceeded %.2fs; " "using local status", - _GATEWAY_HEALTH_ROUTE_TIMEOUT, - ) + _GATEWAY_HEALTH_ROUTE_TIMEOUT) return False, None except Exception: return False, None @@ -226,8 +220,7 @@ def _project_gateway_platforms(gateway_platforms: dict, configured: "set[str] | platforms = { key: _public_platform_entry(value) for key, value in gateway_platforms.items() - if _status_platform_key_allowed(key, configured) - } + if _status_platform_key_allowed(key, configured)} if gateway_running: return platforms if gateway_state == "startup_failed": @@ -297,8 +290,7 @@ async def _resolve_gateway_status(profile_dir: Optional[Path], health_url) -> Di return { "runtime": runtime, "gateway_running": gateway_running, "gateway_pid": liveness.pid, "gateway_state": gateway_state, "gateway_platforms": gateway_platforms, - "gateway_exit_reason": gateway_exit_reason, "gateway_updated_at": gateway_updated_at, - } + "gateway_exit_reason": gateway_exit_reason, "gateway_updated_at": gateway_updated_at} def _auth_gate_status() -> Dict[str, Any]: @@ -318,9 +310,7 @@ def _auth_gate_status() -> Dict[str, Any]: auth_flows: list[str] = [] try: from hermes_cli.dashboard_auth import ( - list_providers as _list_providers, - list_session_providers as _list_session_providers, - ) + list_providers as _list_providers, list_session_providers as _list_session_providers) auth_providers = [p.name for p in _list_providers()] if auth_required: auth_flows.append("cookie") @@ -357,10 +347,8 @@ async def _component_health(gateway: Dict[str, Any]) -> Dict[str, Any]: components: Dict[str, Any] = { "gateway": { "status": "ok" if gateway_running and gateway_state in {"running", "draining"} else "degraded", - "state": gateway_state or ("running" if gateway_running else "stopped"), - }, - "dashboard": DASHBOARD_HEALTH.snapshot(), - } + "state": gateway_state or ("running" if gateway_running else "stopped")}, + "dashboard": DASHBOARD_HEALTH.snapshot()} try: from gateway.readiness import _probe_state_db @@ -371,14 +359,12 @@ async def _component_health(gateway: Dict[str, Any]) -> Dict[str, Any]: platform_states = [ str(value.get("state") or value.get("status") or "").lower() for value in gateway_platforms.values() - if isinstance(value, dict) - ] + if isinstance(value, dict)] connected = sum(1 for state in platform_states if state in _HEALTHY_PLATFORM_STATES) components["platforms"] = { "status": "ok" if connected == len(platform_states) else "degraded", "configured": len(gateway_platforms), - "connected": connected, - } + "connected": connected} return components @@ -485,8 +471,7 @@ async def get_status(profile: Optional[str] = None): "restart_drain_timeout": restart_drain_timeout, "active_sessions": active_sessions, **auth, - "nous_session_valid": _nous_session_validity(), - } + "nous_session_valid": _nous_session_validity()} # Stable per-install identity. First call may touch disk, so keep it off the loop; # afterwards it is a process-global cache hit. Omitted (not null) when unpersistable @@ -519,8 +504,7 @@ async def get_status(profile: Optional[str] = None): "env_path": str(get_env_path()), "gateway_pid": gateway["gateway_pid"], "gateway_health_url": _GATEWAY_HEALTH_URL, - "gateways": topology["gateways"], - }) + "gateways": topology["gateways"]}) return status finally: @@ -540,15 +524,13 @@ async def get_system_stats(): system=_platform.system(), release=_platform.release(), version=_platform.version(), - platform_label=_platform.platform(), - ), + platform_label=_platform.platform()), "arch": _platform.machine(), "hostname": _platform.node(), "python_version": _platform.python_version(), "python_impl": _platform.python_implementation(), "hermes_version": __version__, - "cpu_count": os.cpu_count(), - } + "cpu_count": os.cpu_count()} def _optional(fill): try: @@ -579,7 +561,8 @@ async def get_system_stats(): import psutil # type: ignore vm = psutil.virtual_memory() - info["memory"] = {"total": vm.total, "available": vm.available, "used": vm.used, "percent": vm.percent} + info["memory"] = {"total": vm.total, "available": vm.available, "used": vm.used, + "percent": vm.percent} for fill in (_disk, _cpu, _uptime, _process): _optional(fill) info["psutil"] = True @@ -617,8 +600,7 @@ async def get_curator_status(): "last_run_at": state.get("last_run_at"), "min_idle_hours": _safe_call(curator, "get_min_idle_hours", None), "stale_after_days": _safe_call(curator, "get_stale_after_days", None), - "archive_after_days": _safe_call(curator, "get_archive_after_days", None), - } + "archive_after_days": _safe_call(curator, "get_archive_after_days", None)} @router.put("/api/curator/paused") @@ -751,8 +733,7 @@ def _get_portal_status_sync(): "inference_url": auth.get("inference_base_url"), "provider": str((model_cfg or {}).get("provider") or ""), "subscription_url": "https://portal.nousresearch.com/manage-subscription", - "features": features, - } + "features": features} # --------------------------------------------------------------------------- @@ -790,10 +771,7 @@ async def run_debug_share_endpoint(body: DebugShareRequest | None = None): req = body or DebugShareRequest() try: result = await asyncio.to_thread( - build_debug_share, - log_lines=max(1, min(int(req.lines), 5000)), - redact=bool(req.redact), - ) + build_debug_share, log_lines=max(1, min(int(req.lines), 5000)), redact=bool(req.redact)) except RuntimeError as exc: # Required summary-report upload failed (offline / paste service down). raise HTTPException(status_code=502, detail=f"Upload failed: {exc}") @@ -806,8 +784,7 @@ async def run_debug_share_endpoint(body: DebugShareRequest | None = None): "urls": result.urls, "failures": result.failures, "redacted": result.redacted, - "auto_delete_seconds": result.auto_delete_seconds, - } + "auto_delete_seconds": result.auto_delete_seconds} # --------------------------------------------------------------------------- @@ -821,8 +798,7 @@ async def get_logs( lines: int = 100, level: Optional[str] = None, component: Optional[str] = None, - search: Optional[str] = None, -): + search: Optional[str] = None): from hermes_cli.logs import _read_tail, LOG_FILES log_name = LOG_FILES.get(file) @@ -847,8 +823,7 @@ async def get_logs( raise HTTPException( status_code=400, detail=f"Unknown component: {component}. " - f"Available: {', '.join(sorted(COMPONENT_PREFIXES))}", - ) + f"Available: {', '.join(sorted(COMPONENT_PREFIXES))}") else: comp_prefixes = None @@ -857,8 +832,7 @@ async def get_logs( log_path, min(lines, 500) if not search else 2000, has_filters=has_filters, min_level=min_level, - component_prefixes=comp_prefixes, - ) + component_prefixes=comp_prefixes) # _read_tail doesn't support free-text search, so post-filter (case-insensitive # substring) here and trim to the requested line count afterward. if search: diff --git a/hermes_cli/web_server_profiles.py b/hermes_cli/web_server_profiles.py index 39a0d8ce85..dfd3c82204 100644 --- a/hermes_cli/web_server_profiles.py +++ b/hermes_cli/web_server_profiles.py @@ -122,8 +122,7 @@ def _fallback_profile_entry(profiles_mod, name: str, home: Path, *, is_default: "gateway_running": _safe(gateway_running, False), "description": meta("description", ""), "description_auto": meta("description_auto", False), "distribution_name": None, "distribution_version": None, "distribution_source": None, - "has_alias": False, - } + "has_alias": False} def _fallback_profile_dicts(profiles_mod) -> List[Dict[str, Any]]: @@ -281,9 +280,7 @@ _TERMINAL_BACKENDS: List[Dict[str, str]] = [ "Run commands in a Singularity/Apptainer container (HPC-friendly, rootless)."), ("modal", "Modal", "Run commands in a Modal cloud sandbox."), ("daytona", "Daytona", "Run commands in a Daytona cloud sandbox."), - ("ssh", "SSH", "Run commands on a remote host over SSH."), - ) -] + ("ssh", "SSH", "Run commands on a remote host over SSH."))] def _plugin_terminal_backend_rows() -> List[Dict[str, str]]: @@ -349,8 +346,7 @@ def _aux_usage_rows(db, cutoff: float) -> List[Dict[str, Any]]: def _merge_aux_into_by_model( - by_model: List[Dict[str, Any]], aux_rows: List[Dict[str, Any]] -) -> List[Dict[str, Any]]: + by_model: List[Dict[str, Any]], aux_rows: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Fold aux usage rows into the sessions-derived per-model list. Aux usage lives only in session_model_usage (never in the sessions counters), so @@ -430,7 +426,6 @@ def _installed_hub_identifiers(profile: Optional[str] = None) -> dict: return { entry["identifier"]: {"name": entry.get("name"), "trust_level": entry.get("trust_level"), "scan_verdict": entry.get("scan_verdict")} - for entry in lock.list_installed() if entry.get("identifier") - } + for entry in lock.list_installed() if entry.get("identifier")} except Exception: return {}