refactor(hermes_cli): drop intra-function paragraph blanks in g5 files (whitespace-only)

This commit is contained in:
Teknium
2026-09-02 21:00:55 -07:00
parent 9395796fac
commit 7d4207ed1b
9 changed files with 0 additions and 78 deletions

View File

@@ -70,7 +70,6 @@ class NousPortalAdapter(UpstreamAdapter):
state = self._read_state()
if state is None:
raise RuntimeError("Not logged into Nous Portal. Run `hermes auth add nous` first.")
try:
refreshed = resolve_nous_runtime_credentials(force_refresh=force_refresh)
except Exception as exc:
@@ -78,14 +77,12 @@ class NousPortalAdapter(UpstreamAdapter):
_quarantine_nous_oauth_state(state, exc, reason="proxy_refresh_failure")
self._save_state(state, quarantine_error=exc, quarantine_reason="proxy_refresh_failure")
raise RuntimeError(f"Failed to refresh Nous Portal credentials: {exc}") from exc
runtime_key = refreshed.get("api_key")
if not runtime_key:
raise RuntimeError(
"Nous Portal refresh did not return a usable inference JWT. "
"Try `hermes auth add nous` to re-authenticate."
)
# The returned base_url already honors the NOUS_INFERENCE_BASE_URL override (documented
# dev/staging hatch); validating it against the prod allowlist would reject a legit
# staging URL. So: env override wins, else network-validate the returned URL, else the
@@ -95,7 +92,6 @@ class NousPortalAdapter(UpstreamAdapter):
or _validate_nous_inference_url_from_network(refreshed.get("base_url"))
or DEFAULT_NOUS_INFERENCE_URL
).rstrip("/")
return UpstreamCredential(bearer=runtime_key, base_url=base_url, expires_at=refreshed.get("expires_at"))
# auth.json access — kept local so hermes_cli.auth's public surface does not grow.

View File

@@ -52,14 +52,12 @@ class XAIGrokAdapter(UpstreamAdapter):
raise RuntimeError(
"No xAI OAuth credentials found. Run `hermes auth add xai-oauth --type oauth` first."
)
entry = pool.select()
if entry is None:
raise RuntimeError(
"No available xAI OAuth credentials found. Run "
"`hermes auth reset xai-oauth` or re-authenticate with `hermes auth add xai-oauth --type oauth`."
)
self._pool = pool
return self._credential_from_entry(entry)
@@ -68,12 +66,10 @@ class XAIGrokAdapter(UpstreamAdapter):
) -> Optional[UpstreamCredential]:
if status_code not in {401, 429}:
return None
with self._lock:
pool = self._pool or self._load_pool()
if pool is None:
return None
# 401: refresh the current key first. 429: never refresh — cooldown the rate-limited
# key and rotate. None when the pool has nothing else → the status flows to the client.
refreshed = pool.try_refresh_current() if status_code == 401 else None
@@ -81,7 +77,6 @@ class XAIGrokAdapter(UpstreamAdapter):
refreshed = pool.mark_exhausted_and_rotate(status_code=status_code)
if refreshed is None:
return None
retry_cred = self._credential_from_entry(refreshed)
if retry_cred.bearer == failed_credential.bearer:
return None
@@ -102,11 +97,9 @@ class XAIGrokAdapter(UpstreamAdapter):
"xAI OAuth credential pool entry did not contain an access token. "
"Re-authenticate with `hermes auth add xai-oauth --type oauth`."
)
base_url = str(
getattr(entry, "runtime_base_url", None) or entry.base_url or DEFAULT_XAI_OAUTH_BASE_URL
).strip().rstrip("/")
return UpstreamCredential(
bearer=bearer, base_url=base_url or DEFAULT_XAI_OAUTH_BASE_URL, expires_at=entry.expires_at
)

View File

@@ -24,22 +24,18 @@ def cmd_proxy_start(args: Any) -> int:
if not AIOHTTP_AVAILABLE:
_err("hermes proxy requires aiohttp. Run `hermes setup` to install it.")
return 1
provider = getattr(args, "provider", None) or "nous"
try:
adapter = get_adapter(provider)
except ValueError as exc:
_err(f"Error: {exc}")
return 2
if not adapter.is_authenticated():
auth_hint = getattr(adapter, "auth_hint", f"hermes auth add {adapter.name}")
_err(f"Not logged into {adapter.display_name}. Run `{auth_hint}` first.")
return 2
host = getattr(args, "host", None) or DEFAULT_HOST
port = getattr(args, "port", None) or DEFAULT_PORT
_err(
f"Starting Hermes proxy for {adapter.display_name}\n"
f" Listening on: http://{host}:{port}/v1\n"
@@ -48,7 +44,6 @@ def cmd_proxy_start(args: Any) -> int:
f"\n"
f"Press Ctrl+C to stop."
)
try:
asyncio.run(run_server(adapter, host=host, port=port))
except KeyboardInterrupt:

View File

@@ -132,7 +132,6 @@ def create_app(adapter: UpstreamAdapter) -> "web.Application":
the single loop and every other in-flight streaming completion.
"""
_require_aiohttp()
app = web.Application(client_max_size=MAX_REQUEST_BYTES)
# AppKey: forward-compat with aiohttp versions that strip bare-string keys.
app[web.AppKey("adapter", UpstreamAdapter)] = adapter
@@ -153,14 +152,12 @@ def create_app(adapter: UpstreamAdapter) -> "web.Application":
except Exception as exc:
logger.warning("proxy: credential resolution failed: %s", exc)
return _json_error(401, str(exc), code="upstream_auth_failed")
# Body read into memory once (chat/embeddings payloads are small); switch to streaming
# if large multipart uploads ever need forwarding.
body = await request.read()
session, upstream_resp = await _open_upstream(request, rel_path, body, cred)
if upstream_resp is None:
return session
if upstream_resp.status in {401, 429}:
# One-shot retry with a refreshed/rotated credential (Nous: unconditional refresh
# POST under the auth lock; xAI: pool rotation).
@@ -177,7 +174,6 @@ def create_app(adapter: UpstreamAdapter) -> "web.Application":
session, upstream_resp = await _open_upstream(request, rel_path, body, retry_cred)
if upstream_resp is None:
return session
return await _stream_back(request, session, upstream_resp)
app.router.add_get("/health", handle_health) # never goes upstream
@@ -193,15 +189,12 @@ async def run_server(
) -> None:
"""Run the proxy in the current event loop until shutdown_event is set."""
_require_aiohttp()
app = create_app(adapter)
runner = web.AppRunner(app, access_log=None)
await runner.setup()
site = web.TCPSite(runner, host=host, port=port)
await site.start()
logger.info("proxy: listening on http://%s:%d/v1 -> %s", host, port, adapter.display_name)
stop_event = shutdown_event or asyncio.Event()
if shutdown_event is None: # we own the loop's lifetime → wire signal handlers
loop = asyncio.get_running_loop()
@@ -210,7 +203,6 @@ async def run_server(
loop.add_signal_handler(sig, stop_event.set) # windows-footgun: ok
except NotImplementedError:
pass # Windows / restricted envs — Ctrl+C still raises KeyboardInterrupt
try:
await stop_event.wait()
finally:

View File

@@ -147,7 +147,6 @@ def _setup_ca_cert(console: Console):
def _setup_mint_tokens(console: Console, args: argparse.Namespace):
"""Discover providers, merge with existing tokens (rotating on request), print the table."""
_step(console, 3, "Mint proxy tokens for known providers")
available_env_names: List[str] = []
if args.from_bitwarden:
available_env_names = _bitwarden_env_names(console)
@@ -159,9 +158,7 @@ def _setup_mint_tokens(console: Console, args: argparse.Namespace):
loaded = _load_env_file_into_environ()
if loaded:
console.print(f" [dim]Loaded {loaded} provider key name(s) from ~/.hermes/.env for discovery.[/dim]")
discovered = ip.discover_provider_mappings(available_env_names=available_env_names or None)
# Preserve existing tokens unless rotation was requested — re-running setup must not
# invalidate tokens baked into already-running sandboxes.
existing = ip.load_mappings()
@@ -192,7 +189,6 @@ def _setup_mint_tokens(console: Console, args: argparse.Namespace):
console.print(
"[dim]Note: --rotate-tokens is a no-op on first-time setup (no existing tokens to rotate).[/dim]"
)
mappings = ip.merge_mappings(existing=existing, discovered=discovered, rotate=rotate)
if not mappings:
console.print(" [yellow]No known provider API keys found in env/Bitwarden.[/yellow]")
@@ -200,7 +196,6 @@ def _setup_mint_tokens(console: Console, args: argparse.Namespace):
for env_name in sorted(ip._BEARER_PROVIDERS):
console.print(f" - {env_name}")
return None
# Providers we recognise but can't proxy (SigV4, service-account OAuth) still work — they
# just bypass the egress isolation, so say so.
uncovered = ip.discover_uncovered_providers(available_env_names=available_env_names or None)
@@ -214,7 +209,6 @@ def _setup_mint_tokens(console: Console, args: argparse.Namespace):
"OAuth (SigV4, service-account files) and will hold real "
"credentials inside the sandbox. Egress isolation is INCOMPLETE for these.[/dim]"
)
console.print(_mappings_table(mappings, "Provider env", "Upstream hosts", show_tokens=False))
return mappings
@@ -222,7 +216,6 @@ def _setup_mint_tokens(console: Console, args: argparse.Namespace):
def _setup_write_config(console: Console, args: argparse.Namespace, mappings, ca_crt, ca_key):
"""Write proxy.yaml + mappings, then enable the integration in config; returns ``proxy_cfg``."""
_step(console, 4, "Write config and persist mappings")
cfg = load_config()
proxy_cfg = cfg.setdefault("proxy", {})
# None = flag not given. ``0`` is not a valid TCP listener, so it is a hard error rather
@@ -237,10 +230,8 @@ def _setup_write_config(console: Console, args: argparse.Namespace, mappings, ca
else:
tunnel_port = int(proxy_cfg.get("tunnel_port", ip._DEFAULT_TUNNEL_PORT))
proxy_cfg["tunnel_port"] = tunnel_port
extra_hosts = list(proxy_cfg.get("extra_allowed_hosts") or [])
allowed = list(ip._DEFAULT_ALLOWED_HOSTS) + [h for h in extra_hosts if h not in ip._DEFAULT_ALLOWED_HOSTS]
# Pre-create the audit log 0o600. The pinned v0.39 daemon never writes it (reserved for
# v0.40+ per-request records), so a pre-create failure is a WARNING, not a setup abort.
audit_log_path = ip._proxy_state_dir() / "audit.log"
@@ -250,7 +241,6 @@ def _setup_write_config(console: Console, args: argparse.Namespace, mappings, ca
except RuntimeError as exc:
audit_log_ok = False
console.print(f" [yellow]⚠ {exc}[/yellow]")
# ``proxy.upstream_deny_cidrs`` overrides the deny list; None yields the documented safe
# default-deny set (loopback, IMDS, RFC1918).
iron_cfg = ip.build_proxy_config(
@@ -275,7 +265,6 @@ def _setup_write_config(console: Console, args: argparse.Namespace, mappings, ca
f"[dim](reserved — not written by iron-proxy v0.39; "
f"per-request records land in iron-proxy.log)[/dim]"
)
proxy_cfg["enabled"] = True
proxy_cfg.setdefault("auto_install", True)
proxy_cfg.setdefault("enforce_on_docker", True)
@@ -310,7 +299,6 @@ def _setup_restart_daemon(console: Console, args: argparse.Namespace, proxy_cfg:
was_running = ip.get_status().pid is not None
if was_running:
ip.stop_proxy()
restart_pref = getattr(args, "restart", None)
if restart_pref is True or restart_pref is False:
do_restart = restart_pref
@@ -323,7 +311,6 @@ def _setup_restart_daemon(console: Console, args: argparse.Namespace, proxy_cfg:
)
else:
do_restart = False
if do_restart:
try:
new_status = ip.start_proxy(install_if_missing=bool(proxy_cfg.get("auto_install", True)))
@@ -352,7 +339,6 @@ def cmd_start(args: argparse.Namespace) -> int:
if not proxy_cfg.get("enabled"):
console.print("[yellow]proxy.enabled is false — run `hermes egress setup` first.[/yellow]")
return 1
# ``credential_source: bitwarden`` refreshes upstream secrets from BSM at startup — that is
# the rotation guarantee distinguishing it from ``env``.
credential_source = proxy_cfg.get("credential_source", "env")
@@ -380,7 +366,6 @@ def cmd_start(args: argparse.Namespace) -> int:
if refresh_bw and bw_cfg is not None:
bw_cfg = dict(bw_cfg)
bw_cfg["allow_env_fallback"] = bool(proxy_cfg.get("allow_env_fallback", False))
# (fail_on_uncovered_providers was removed: the fail-closed provider tier is now empty.)
# Pre-check the BWS token + project here so bitwarden mode fails loud with actionable
# messages BEFORE start_proxy could silently degrade to a stale/mismatched host env.
@@ -400,7 +385,6 @@ def cmd_start(args: argparse.Namespace) -> int:
"Run `hermes secrets bitwarden setup` to configure the "
"project, or switch back via `hermes egress setup --no-bitwarden`.",
)
try:
status = ip.start_proxy(
install_if_missing=bool(proxy_cfg.get("auto_install", True)),
@@ -463,32 +447,27 @@ def format_status_text(*, show_tokens: bool = False) -> str:
cfg = load_config()
proxy_cfg = cfg.get("proxy") or {}
status = ip.get_status()
lines = ["Egress proxy status", ""]
lines.extend(
f"{label}: {value}"
for label, value in _status_rows(proxy_cfg, status, yn=lambda v: "yes" if v else "no", dim=lambda t: t)
)
lines.append("Scope: Docker backend only in this release")
mappings = ip.load_mappings()
if mappings:
lines.extend(["", "Token mappings:"])
for m in mappings:
tok = m.proxy_token if show_tokens else _redact_token(m.proxy_token)
lines.append(f" - {m.real_env_name}: {tok} ({', '.join(m.upstream_hosts)})")
uncovered = ip.discover_uncovered_providers()
if uncovered:
lines.extend(["", "Uncovered providers (real credentials still visible inside the sandbox):"])
for name in uncovered:
lines.append(f" - {name}")
if bool(proxy_cfg.get("enabled")) and not status.configured:
lines.extend(["", "Next: run `hermes egress setup` to mint tokens and write proxy.yaml."])
elif bool(proxy_cfg.get("enabled")) and not (status.pid and status.listening):
lines.extend(["", "Next: run `hermes egress start` before launching Docker sandboxes."])
return "\n".join(lines)
@@ -497,14 +476,12 @@ def cmd_status(args: argparse.Namespace) -> int:
cfg = load_config()
proxy_cfg = cfg.get("proxy") or {}
status = ip.get_status()
table = Table(show_header=False, box=None, padding=(0, 2))
table.add_column("", style="bold")
table.add_column("")
for label, value in _status_rows(proxy_cfg, status, yn=_yn, dim=lambda t: f"[dim]{t}[/dim]"):
table.add_row(label, value)
console.print(table)
mappings = ip.load_mappings()
if mappings:
console.print()
@@ -515,7 +492,6 @@ def cmd_status(args: argparse.Namespace) -> int:
"[yellow]⚠[/yellow] proxy tokens just printed in full — "
"they may persist in your shell history. Consider clearing it after this command."
)
# Uncovered providers = the isolation boundary is incomplete for those upstreams.
uncovered = ip.discover_uncovered_providers()
if uncovered:
@@ -523,7 +499,6 @@ def cmd_status(args: argparse.Namespace) -> int:
console.print("[yellow]Uncovered providers[/yellow] (real credentials still visible inside the sandbox):")
for name in uncovered:
console.print(f" - {name}")
return 0

View File

@@ -34,22 +34,17 @@ def _safe_extract_tar_gz(archive: Path, destination: Path) -> None:
for member in tf.getmembers():
parts = _normalize_member_parts(member.name)
target = destination.joinpath(*parts)
if member.isdir():
target.mkdir(parents=True, exist_ok=True)
continue
if not member.isfile():
raise PsutilAndroidInstallError(f"Unsupported archive member type: {member.name}")
target.parent.mkdir(parents=True, exist_ok=True)
extracted = tf.extractfile(member)
if extracted is None:
raise PsutilAndroidInstallError(f"Cannot read archive member: {member.name}")
with extracted, open(target, "wb") as dst:
shutil.copyfileobj(extracted, dst)
try:
target.chmod(member.mode & 0o777)
except OSError:
@@ -59,11 +54,9 @@ def _safe_extract_tar_gz(archive: Path, destination: Path) -> None:
def prepare_patched_psutil_sdist(archive: Path, destination: Path) -> Path:
"""Safely extract the pinned psutil sdist and patch it for Android."""
_safe_extract_tar_gz(archive, destination)
src_roots = [path for path in destination.iterdir() if path.is_dir() and path.name.startswith("psutil-")]
if not src_roots:
raise PsutilAndroidInstallError("psutil sdist did not contain a psutil-* directory")
src_root = min(src_roots, key=lambda path: path.name)
common_py = src_root / "psutil" / "_common.py"
rel = common_py.relative_to(src_root)

View File

@@ -15,7 +15,6 @@ def _build_inherited_flag_table() -> list[tuple[str, bool]]:
"""``(option_string, takes_value)`` for every parser Action carrying ``inherit_on_relaunch``
(set by ``_parser._inherited_flag``), plus the pre-argparse flags."""
parser, _subparsers, chat_parser = build_top_level_parser()
table: list[tuple[str, bool]] = []
seen: set[tuple[str, bool]] = set()
for p in (parser, chat_parser):
@@ -30,7 +29,6 @@ def _build_inherited_flag_table() -> list[tuple[str, bool]]:
if key not in seen:
seen.add(key)
table.append(key)
table.extend(PRE_ARGPARSE_INHERITED_FLAGS)
return table
@@ -49,7 +47,6 @@ def _extract_inherited_flags(argv: Sequence[str]) -> list[str]:
flags.append(arg)
i += 1
continue
for flag, takes_value in _INHERITED_FLAGS_TABLE:
if arg == flag:
flags.append(arg)
@@ -90,10 +87,8 @@ def build_relaunch_argv(
bin_path = resolve_hermes_bin()
argv = [bin_path] if bin_path else [sys.executable, "-m", "hermes_cli.main"]
src = list(original_argv) if original_argv is not None else list(sys.argv[1:])
if preserve_inherited:
argv.extend(_extract_inherited_flags(src))
argv.extend(extra_args)
return argv

View File

@@ -30,21 +30,17 @@ def configured_nofile_soft_limit(config: Mapping[str, Any] | None = None) -> int
try:
# Profile-aware loader (applies managed-scope overlays and defaults).
from hermes_cli.config import load_config_readonly
config = load_config_readonly()
except Exception:
logger.debug("Could not load config for RLIMIT_NOFILE", exc_info=True)
return None
if not isinstance(config, Mapping):
return None
runtime = config.get("runtime", _MISSING)
if runtime is _MISSING:
return DEFAULT_NOFILE_SOFT_LIMIT
if not isinstance(runtime, Mapping):
return None
raw_value = runtime.get("nofile_soft_limit", _MISSING)
if raw_value is _MISSING:
return DEFAULT_NOFILE_SOFT_LIMIT
@@ -62,11 +58,9 @@ def apply_nofile_soft_limit(config: Mapping[str, Any] | None = None) -> bool:
"""
if _resource is None:
return False
target = configured_nofile_soft_limit(config)
if target is None:
return False
try:
nofile = _resource.RLIMIT_NOFILE
current_soft, current_hard = _resource.getrlimit(nofile)
@@ -78,7 +72,6 @@ def apply_nofile_soft_limit(config: Mapping[str, Any] | None = None) -> bool:
new_soft = target if current_hard == infinity else min(target, current_hard)
if new_soft <= current_soft:
return False
_resource.setrlimit(nofile, (new_soft, current_hard))
return True
except Exception:

View File

@@ -61,7 +61,6 @@ def detect_service_manager() -> ServiceManagerKind:
# Deferred so importing this module (Protocol type, validate_profile_name) doesn't drag in
# the whole gateway dependency graph.
from hermes_cli.gateway import is_macos, is_windows, supports_systemd_services
# Gate on _s6_running() alone, NOT is_container(): the latter only detects Docker/Podman/lxc
# and is False on Fly's Firecracker microVMs even though s6-overlay is PID 1 there — that
# made the s6 dispatch inert on Fly, so `hermes gateway start` spawned a foreground gateway
@@ -112,9 +111,7 @@ class _HostServiceManager:
def _backend_module(self):
import importlib
import hermes_cli
importlib.import_module(f"hermes_cli.{self._backend}")
return getattr(hermes_cli, self._backend)
@@ -437,7 +434,6 @@ class S6ServiceManager:
restarting would turn every normal exit into a reconnect storm) both map to 125 so s6 stops
restarting; only other non-zero exits let s6 restart normally."""
from gateway.restart import GATEWAY_FATAL_CONFIG_EXIT_CODE
code = GATEWAY_FATAL_CONFIG_EXIT_CODE
return (
"#!/command/with-contenv sh\n"
@@ -489,7 +485,6 @@ class S6ServiceManager:
service_dir = self.scandir / name
if not service_dir.is_dir():
raise GatewayNotRegisteredError(_profile_from_service(name))
try:
_s6_run("s6-svc", action_flag, str(service_dir), check=True)
except subprocess.CalledProcessError as exc:
@@ -520,7 +515,6 @@ class S6ServiceManager:
if pid is not None:
try:
from gateway.status import write_planned_stop_marker
write_planned_stop_marker(pid)
except Exception:
pass
@@ -553,7 +547,6 @@ class S6ServiceManager:
svc_dir = self._service_dir(profile)
if svc_dir.exists():
raise ValueError(f"profile gateway {profile!r} already registered at {svc_dir}")
# Build atomically in a DOT-PREFIXED sibling (``.gateway-<profile>.tmp``) then rename:
# s6-svscan skips dot entries, so a concurrent rescan (cont-init reconciler, sibling
# register) cannot supervise the half-built slot. Otherwise s6-supervise would spawn AS
@@ -581,12 +574,10 @@ class S6ServiceManager:
# Mirrors container_boot._register_gateway_slot when start=False.
if not start_now:
(tmp_dir / "down").touch()
tmp_dir.rename(svc_dir)
except Exception:
shutil.rmtree(tmp_dir, ignore_errors=True)
raise
result = _s6_run("s6-svscanctl", "-a", str(self.scandir))
if result.returncode != 0:
# No supervisor is watching it — leaving the directory would be confusing.
@@ -605,7 +596,6 @@ class S6ServiceManager:
svc_dir = self._service_dir(profile)
if not svc_dir.exists():
return
_s6_run("s6-svc", "-d", str(svc_dir))
_s6_run("s6-svwait", "-D", "-t", "10000", str(svc_dir), timeout=15)
_s6_run("s6-svscanctl", "-an", str(self.scandir))