From 83e0ee92290adbaae49279303e67fa56518311c1 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:05:12 -0700 Subject: [PATCH 1/5] refactor(hermes_cli/web_routers): shared device-code /start response + custom-endpoint row builder --- hermes_cli/web_routers/config_env.py | 41 ++++++++++++++------------ hermes_cli/web_routers/oauth.py | 44 +++++++++++++++------------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/hermes_cli/web_routers/config_env.py b/hermes_cli/web_routers/config_env.py index 4b7aa3fc47..c836730034 100644 --- a/hermes_cli/web_routers/config_env.py +++ b/hermes_cli/web_routers/config_env.py @@ -352,6 +352,19 @@ def _config_api_key_is_env_ref(endpoint_id: str) -> bool: return bool(isinstance(raw_key, str) and re.search(r"\$\{[^}]+\}", raw_key)) +def _endpoint_row( + endpoint_id: str, name: str, base_url: str, model: str, models: List[str], context_length, + discover_models: bool, key_entry: Dict[str, Any], is_current: bool, source: str, +) -> Dict[str, Any]: + has_api_key, api_key_preview = _api_key_display(key_entry) + return { + "id": endpoint_id, "name": name, "base_url": base_url, "model": model, "models": models, + "context_length": context_length, "discover_models": discover_models, + "has_api_key": has_api_key, "api_key_preview": api_key_preview, + "is_current": is_current, "source": source, + } + + def _custom_endpoint_response(cfg: Dict[str, Any]) -> Dict[str, Any]: model_cfg = cfg.get("model", {}) if isinstance(cfg.get("model"), dict) else {} current_provider = str(model_cfg.get("provider", "") or "") @@ -369,26 +382,18 @@ def _custom_endpoint_response(cfg: Dict[str, Any]) -> Dict[str, Any]: continue endpoint_id = str(provider_id) models = _models_from_custom_endpoint_entry(raw_entry) - endpoint_model = str(raw_entry.get("model") or raw_entry.get("default_model") or (models[0] if models else "")) - has_api_key, api_key_preview = _api_key_display(raw_entry) - endpoints.append({ - "id": endpoint_id, "name": str(raw_entry.get("name") or endpoint_id), - "base_url": base_url, "model": endpoint_model, "models": models, - "context_length": raw_entry.get("context_length"), - "discover_models": bool(raw_entry.get("discover_models", True)), - "has_api_key": has_api_key, "api_key_preview": api_key_preview, - "is_current": endpoint_id == current_provider, "source": "providers", - }) + endpoints.append(_endpoint_row( + endpoint_id, str(raw_entry.get("name") or endpoint_id), base_url, + str(raw_entry.get("model") or raw_entry.get("default_model") or (models[0] if models else "")), + models, raw_entry.get("context_length"), bool(raw_entry.get("discover_models", True)), + raw_entry, endpoint_id == current_provider, "providers", + )) if current_provider.lower() == "custom" and current_base_url and not any(e["id"] == "custom" for e in endpoints): - has_api_key, api_key_preview = _api_key_display(model_cfg) - endpoints.insert(0, { - "id": "custom", "name": "Custom", "base_url": current_base_url, "model": current_model, - "models": [current_model] if current_model else [], - "context_length": model_cfg.get("context_length"), "discover_models": True, - "has_api_key": has_api_key, "api_key_preview": api_key_preview, "is_current": True, - "source": "direct-config", - }) + endpoints.insert(0, _endpoint_row( + "custom", "Custom", current_base_url, current_model, [current_model] if current_model else [], + model_cfg.get("context_length"), True, model_cfg, True, "direct-config", + )) return { "endpoints": endpoints, diff --git a/hermes_cli/web_routers/oauth.py b/hermes_cli/web_routers/oauth.py index 221e343b11..6e33afc809 100644 --- a/hermes_cli/web_routers/oauth.py +++ b/hermes_cli/web_routers/oauth.py @@ -107,6 +107,14 @@ def _start_poller(target, sid: str) -> None: threading.Thread(target=target, args=(sid,), daemon=True, name=f"oauth-poll-{sid[:6]}").start() +def _device_code_started(sid: str, user_code, verification_url, expires_in: int, poll_interval: int) -> Dict[str, Any]: + """The /start response shape shared by every device-code flow.""" + return { + "session_id": sid, "flow": "device_code", "user_code": user_code, + "verification_url": verification_url, "expires_in": expires_in, "poll_interval": poll_interval, + } + + def _codex_full_login_worker(session_id: str) -> None: """Run the complete OpenAI Codex device-code flow. @@ -359,11 +367,10 @@ async def _start_nous_device_code(profile: Optional[str]) -> Dict[str, Any]: client_id=client_id, scope=effective_scope, ) _start_poller(_nous_poller, sid) - return { - "session_id": sid, "flow": "device_code", "user_code": str(device_data["user_code"]), - "verification_url": str(device_data["verification_uri_complete"]), - "expires_in": int(device_data["expires_in"]), "poll_interval": int(device_data["interval"]), - } + return _device_code_started( + sid, str(device_data["user_code"]), str(device_data["verification_uri_complete"]), + int(device_data["expires_in"]), int(device_data["interval"]), + ) async def _start_codex_device_code(profile: Optional[str]) -> Dict[str, Any]: @@ -385,11 +392,9 @@ async def _start_codex_device_code(profile: Optional[str]) -> Dict[str, Any]: raise HTTPException(status_code=500, detail=s.get("error_message") or "device-auth failed") if not s.get("user_code"): raise HTTPException(status_code=504, detail="device-auth timed out before returning a user code") - return { - "session_id": sid, "flow": "device_code", "user_code": s["user_code"], - "verification_url": s["verification_url"], "expires_in": int(s.get("expires_in") or 900), - "poll_interval": int(s.get("interval") or 5), - } + return _device_code_started( + sid, s["user_code"], s["verification_url"], int(s.get("expires_in") or 900), int(s.get("interval") or 5) + ) async def _start_minimax_device_code(profile: Optional[str]) -> Dict[str, Any]: @@ -433,11 +438,10 @@ async def _start_minimax_device_code(profile: Optional[str]) -> Dict[str, Any]: expires_in_seconds = expired_in_raw sess["expires_at"] = expires_at_ts _start_poller(_minimax_poller, sid) - return { - "session_id": sid, "flow": "device_code", "user_code": str(device_data["user_code"]), - "verification_url": str(device_data["verification_uri"]), "expires_in": expires_in_seconds, - "poll_interval": max(2, (sess["interval_ms"] or 2000) // 1000), - } + return _device_code_started( + sid, str(device_data["user_code"]), str(device_data["verification_uri"]), expires_in_seconds, + max(2, (sess["interval_ms"] or 2000) // 1000), + ) async def _start_xai_device_code(profile: Optional[str]) -> Dict[str, Any]: @@ -455,11 +459,11 @@ async def _start_xai_device_code(profile: Optional[str]) -> Dict[str, Any]: expires_at=time.time() + int(device_data["expires_in"]), ) _start_poller(_xai_device_poller, sid) - return { - "session_id": sid, "flow": "device_code", "user_code": str(device_data["user_code"]), - "verification_url": str(device_data.get("verification_uri_complete") or device_data["verification_uri"]), - "expires_in": int(device_data["expires_in"]), "poll_interval": int(device_data["interval"]), - } + return _device_code_started( + sid, str(device_data["user_code"]), + str(device_data.get("verification_uri_complete") or device_data["verification_uri"]), + int(device_data["expires_in"]), int(device_data["interval"]), + ) _DEVICE_CODE_STARTERS = { From 7d60d28f410cab56972d5033f621a592986d2a6e Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:20:21 -0700 Subject: [PATCH 2/5] refactor(hermes_cli/web_routers): drop post-docstring blank lines --- hermes_cli/web_routers/actions.py | 2 -- hermes_cli/web_routers/audio.py | 3 --- hermes_cli/web_routers/config_env.py | 1 - hermes_cli/web_routers/memory_providers.py | 1 - 4 files changed, 7 deletions(-) diff --git a/hermes_cli/web_routers/actions.py b/hermes_cli/web_routers/actions.py index dca8bbd7b3..39e35f05f2 100644 --- a/hermes_cli/web_routers/actions.py +++ b/hermes_cli/web_routers/actions.py @@ -39,13 +39,11 @@ _ACTION_RESULTS = LateState("_ACTION_RESULTS") def _action_log_dir() -> Path: """Live ``web_server._ACTION_LOG_DIR`` (a Path value, so not proxied by LateState).""" from hermes_cli.web_server import _ACTION_LOG_DIR - return _ACTION_LOG_DIR def _project_root() -> Path: from hermes_cli.web_server import PROJECT_ROOT - return PROJECT_ROOT diff --git a/hermes_cli/web_routers/audio.py b/hermes_cli/web_routers/audio.py index db0337c4eb..81ea6120e0 100644 --- a/hermes_cli/web_routers/audio.py +++ b/hermes_cli/web_routers/audio.py @@ -155,7 +155,6 @@ async def get_client_voice_config(profile: Optional[str] = None): Gate: ``voice.client_direct`` in config.yaml (default true). """ from tools.voice_client_config import resolve_client_voice_config - try: result = await _run_config_scoped(profile, resolve_client_voice_config) except Exception: @@ -323,7 +322,6 @@ async def tts_lease(payload: TTSLeaseRequest, profile: Optional[str] = None): def _apply(): from tools.tts_tool import acquire_tts_lease, release_tts_lease - if payload.active: with _config_profile_scope(profile): return acquire_tts_lease(lease) @@ -376,7 +374,6 @@ async def speak_stream_ws(ws: "WebSocket") -> None: def _resolve(): from tools.tts_streaming import resolve_streaming_provider from tools.tts_tool import _get_provider, _load_tts_config, _resolve_max_text_length - with _config_profile_scope(profile): cfg = _load_tts_config() streamer = resolve_streaming_provider(cfg) diff --git a/hermes_cli/web_routers/config_env.py b/hermes_cli/web_routers/config_env.py index c836730034..5868018895 100644 --- a/hermes_cli/web_routers/config_env.py +++ b/hermes_cli/web_routers/config_env.py @@ -105,7 +105,6 @@ async def get_schema(profile: Optional[str] = None): async def get_egress_status(): """Dashboard/Desktop-readable egress proxy status and remediation text.""" from hermes_cli.proxy_cli import format_status_text - return {"text": format_status_text()} diff --git a/hermes_cli/web_routers/memory_providers.py b/hermes_cli/web_routers/memory_providers.py index a3e2568251..ea327e748b 100644 --- a/hermes_cli/web_routers/memory_providers.py +++ b/hermes_cli/web_routers/memory_providers.py @@ -124,7 +124,6 @@ def _read_flat_json(provider: ProviderConfigSchema) -> Dict[str, Any]: def _honcho_resolvers(): """Lazily import the Honcho plugin's resolvers (optional plugin).""" from plugins.memory.honcho.client import _host_block, resolve_active_host, resolve_config_path - return resolve_active_host, resolve_config_path, _host_block From e2ba8a4e5334bbb7438554e8acf174de4a83b01c Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:21:56 -0700 Subject: [PATCH 3/5] refactor(hermes_cli/web_routers): oauth status cards via one _status_card builder + table (json-parity verified) --- hermes_cli/web_routers/oauth.py | 117 +++++++++++++------------------- 1 file changed, 47 insertions(+), 70 deletions(-) diff --git a/hermes_cli/web_routers/oauth.py b/hermes_cli/web_routers/oauth.py index 6e33afc809..ac8905ca3c 100644 --- a/hermes_cli/web_routers/oauth.py +++ b/hermes_cli/web_routers/oauth.py @@ -240,63 +240,46 @@ def _codex_full_login_worker(session_id: str) -> None: s["error_message"] = str(e) -# Hand-written status card shapes per provider id: (hauth getter name, shaper). +_OMIT: Any = object() + + +def _status_card( + raw: dict, source, source_label, token_preview, expires_at, has_refresh_token, last_refresh=_OMIT +) -> Dict[str, Any]: + card = { + "logged_in": bool(raw.get("logged_in")), "source": source, "source_label": source_label, + "token_preview": token_preview, "expires_at": expires_at, "has_refresh_token": has_refresh_token, + } + if last_refresh is not _OMIT: + card["last_refresh"] = last_refresh + return card + + +# Hand-written status cards per provider id: (hauth getter name, raw -> card). # Providers absent here fall through to the slug-driven ``get_auth_status``. -def _nous_status(raw): - # Refresh-free snapshot so listing providers never performs an OAuth refresh. - return { - "logged_in": bool(raw.get("logged_in")), "source": "nous_portal", - "source_label": raw.get("portal_base_url") or "Nous Portal", - "token_preview": _truncate_token(raw.get("access_token")), - "expires_at": raw.get("access_expires_at"), - "has_refresh_token": bool(raw.get("has_refresh_token")), - } - - -def _codex_status(raw): - return { - "logged_in": bool(raw.get("logged_in")), "source": raw.get("source") or "openai_codex", - "source_label": raw.get("auth_mode") or "OpenAI Codex", - "token_preview": _truncate_token(raw.get("api_key")), "expires_at": None, - "has_refresh_token": False, "last_refresh": raw.get("last_refresh"), - } - - -def _qwen_status(raw): - return { - "logged_in": bool(raw.get("logged_in")), "source": "qwen_cli", - "source_label": raw.get("auth_store_path") or "Qwen CLI", - "token_preview": _truncate_token(raw.get("access_token")), - "expires_at": raw.get("expires_at"), - "has_refresh_token": bool(raw.get("has_refresh_token")), - } - - -def _minimax_status(raw): - return { - "logged_in": bool(raw.get("logged_in")), "source": "minimax_oauth", - "source_label": f"MiniMax ({raw.get('region', 'global')})", "token_preview": None, - "expires_at": raw.get("expires_at"), "has_refresh_token": True, - } - - -def _xai_status(raw): - # source_label is a human-readable origin (auth-store path / credential - # source), not the internal auth_mode string ("oauth_pkce"). - return { - "logged_in": bool(raw.get("logged_in")), "source": raw.get("source") or "xai_oauth", - "source_label": raw.get("auth_store") or raw.get("source") or "xAI Grok OAuth", - "token_preview": _truncate_token(raw.get("api_key")), "expires_at": None, - "has_refresh_token": True, "last_refresh": raw.get("last_refresh"), - } - - +# nous: refresh-free local snapshot so listing providers never performs an OAuth +# refresh. xai: source_label is a human-readable origin (auth-store path / +# credential source), not the internal auth_mode string ("oauth_pkce"). _PROVIDER_STATUS: Dict[str, tuple[str, Callable[[dict], dict]]] = { - "nous": ("get_nous_auth_status_local", _nous_status), - "openai-codex": ("get_codex_auth_status", _codex_status), - "qwen-oauth": ("get_qwen_auth_status", _qwen_status), - "minimax-oauth": ("get_minimax_oauth_auth_status", _minimax_status), - "xai-oauth": ("get_xai_oauth_auth_status", _xai_status), + "nous": ("get_nous_auth_status_local", lambda r: _status_card( + r, "nous_portal", r.get("portal_base_url") or "Nous Portal", + _truncate_token(r.get("access_token")), r.get("access_expires_at"), bool(r.get("has_refresh_token")), + )), + "openai-codex": ("get_codex_auth_status", lambda r: _status_card( + r, r.get("source") or "openai_codex", r.get("auth_mode") or "OpenAI Codex", + _truncate_token(r.get("api_key")), None, False, r.get("last_refresh"), + )), + "qwen-oauth": ("get_qwen_auth_status", lambda r: _status_card( + r, "qwen_cli", r.get("auth_store_path") or "Qwen CLI", + _truncate_token(r.get("access_token")), r.get("expires_at"), bool(r.get("has_refresh_token")), + )), + "minimax-oauth": ("get_minimax_oauth_auth_status", lambda r: _status_card( + r, "minimax_oauth", f"MiniMax ({r.get('region', 'global')})", None, r.get("expires_at"), True, + )), + "xai-oauth": ("get_xai_oauth_auth_status", lambda r: _status_card( + r, r.get("source") or "xai_oauth", r.get("auth_store") or r.get("source") or "xAI Grok OAuth", + _truncate_token(r.get("api_key")), None, True, r.get("last_refresh"), + )), } @@ -318,21 +301,15 @@ def _resolve_provider_status(provider_id: str, status_fn) -> Dict[str, Any]: # a new OAuth/account provider plugin never renders permanently logged-out. raw = hauth.get_auth_status(provider_id) if isinstance(raw, dict) and "logged_in" in raw: - return { - "logged_in": bool(raw.get("logged_in")), - "source": raw.get("source") or raw.get("provider") or provider_id, - "source_label": ( - raw.get("source_label") - or raw.get("auth_store") - or raw.get("auth_store_path") - or raw.get("base_url") - or raw.get("name") - or "" - ), - "token_preview": _truncate_token(raw.get("access_token") or raw.get("api_key")), - "expires_at": raw.get("expires_at") or raw.get("access_expires_at"), - "has_refresh_token": bool(raw.get("has_refresh_token")), - } + return _status_card( + raw, + raw.get("source") or raw.get("provider") or provider_id, + raw.get("source_label") or raw.get("auth_store") or raw.get("auth_store_path") + or raw.get("base_url") or raw.get("name") or "", + _truncate_token(raw.get("access_token") or raw.get("api_key")), + raw.get("expires_at") or raw.get("access_expires_at"), + bool(raw.get("has_refresh_token")), + ) except Exception as e: return {"logged_in": False, "error": str(e)} return {"logged_in": False} From a8be68f98547ad342956846d65618a99f4bf86a1 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:26:11 -0700 Subject: [PATCH 4/5] =?UTF-8?q?refactor(hermes=5Fcli/web=5Frouters):=20mem?= =?UTF-8?q?ory=5Fproviders=20external-dependency=20runner=20=E2=80=94=20on?= =?UTF-8?q?e=20=5Frun=20helper=20(405-case=20fuzz=20parity)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hermes_cli/web_routers/memory_providers.py | 50 ++++++++-------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/hermes_cli/web_routers/memory_providers.py b/hermes_cli/web_routers/memory_providers.py index ea327e748b..d0730abdef 100644 --- a/hermes_cli/web_routers/memory_providers.py +++ b/hermes_cli/web_routers/memory_providers.py @@ -433,40 +433,28 @@ def _install_memory_provider_external_dependencies( check_cmd = dep.get("check") or "" install_cmd = dep.get("install") or "" - def _check(status_of) -> bool: - """Run the check command; append its result; True when it passed.""" + def _run(kind: str, command: str, status_of, **kwargs) -> Optional[int]: + """Run a setup command, append its result row; returncode or None on spawn failure.""" try: - check = _run_setup_command(shlex.split(check_cmd), display=check_cmd, timeout=20) + completed = _run_setup_command(command if kwargs.get("shell") else shlex.split(command), display=command, **kwargs) except Exception as exc: - results.append(_command_result(kind="external_check", name=name, status=status_of(None), command=check_cmd, error=str(exc))) - return False - ok = check.returncode == 0 - results.append(_command_result(kind="external_check", name=name, status=status_of(ok), command=check_cmd, completed=check)) - return ok + results.append(_command_result(kind=kind, name=name, status=status_of(None), command=command, error=str(exc))) + return None + results.append(_command_result(kind=kind, name=name, status=status_of(completed.returncode == 0), command=command, completed=completed)) + return completed.returncode - if check_cmd: - if _check(lambda ok: "already_installed" if ok else ("missing" if install_cmd else "failed")): - continue - if not install_cmd: - continue - - if install_cmd: - try: - install = _run_setup_command(install_cmd, display=install_cmd, shell=True, timeout=300) - except Exception as exc: - results.append(_command_result(kind="external_install", name=name, status="failed", command=install_cmd, error=str(exc))) - continue - - results.append( - _command_result( - kind="external_install", name=name, - status="installed" if install.returncode == 0 else "failed", - command=install_cmd, completed=install, - ) - ) - - if check_cmd and install.returncode == 0: - _check(lambda ok: "verified" if ok else "failed") + # Check first: "already_installed" short-circuits; a failed check is + # "missing" when an install step can fix it, "failed" otherwise. + if check_cmd and _run( + "external_check", check_cmd, + lambda ok: "already_installed" if ok else ("missing" if install_cmd else "failed"), timeout=20, + ) == 0: + continue + if not install_cmd: + continue + rc = _run("external_install", install_cmd, lambda ok: "installed" if ok else "failed", shell=True, timeout=300) + if check_cmd and rc == 0: + _run("external_check", check_cmd, lambda ok: "verified" if ok else "failed", timeout=20) return results From 7d41871beb3211474293ae54ded63eddedb95bcf Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:39:20 -0700 Subject: [PATCH 5/5] refactor(hermes_cli/web_routers): config_env auth-type env-var table replaces aws/vertex branches (json-parity verified) --- hermes_cli/web_routers/config_env.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/hermes_cli/web_routers/config_env.py b/hermes_cli/web_routers/config_env.py index 5868018895..3f37548c6a 100644 --- a/hermes_cli/web_routers/config_env.py +++ b/hermes_cli/web_routers/config_env.py @@ -148,6 +148,15 @@ def _provider_card(d, description: str, url, *, is_password: bool, advanced: boo } +_AUTH_TYPE_ENV_VARS = { + "aws_sdk": ( + ("AWS_REGION", lambda d, var: f"{d.label} ({var})"), + ("AWS_PROFILE", lambda d, var: f"{d.label} ({var})"), + ), + "vertex": (("VERTEX_CREDENTIALS_PATH", lambda d, var: f"{d.label} — service account JSON path (or use ADC)"),), +} + + def _catalog_provider_env_metadata() -> dict: """Map provider env vars -> desktop card metadata, derived from the catalog. @@ -195,19 +204,11 @@ def _catalog_provider_env_metadata() -> dict: # the Keys tab: AWS-SDK providers (Bedrock) authenticate via the AWS # credential chain, Vertex via OAuth2 (service-account JSON path or # ADC — a path, not a secret). Tag their env vars to the card. - if d.auth_type == "aws_sdk": - for aws_var in ("AWS_REGION", "AWS_PROFILE"): - existing = meta.get(aws_var, {}) - meta[aws_var] = _provider_card( - d, existing.get("description") or f"{d.label} ({aws_var})", existing.get("url"), - is_password=False, advanced=existing.get("advanced", True), - ) - if d.auth_type == "vertex": - existing = meta.get("VERTEX_CREDENTIALS_PATH", {}) - meta["VERTEX_CREDENTIALS_PATH"] = _provider_card( - d, - existing.get("description") or f"{d.label} — service account JSON path (or use ADC)", - existing.get("url"), is_password=False, advanced=existing.get("advanced", True), + for var, describe in _AUTH_TYPE_ENV_VARS.get(d.auth_type, ()): + existing = meta.get(var, {}) + meta[var] = _provider_card( + d, existing.get("description") or describe(d, var), existing.get("url"), + is_password=False, advanced=existing.get("advanced", True), ) return meta