From 2aa5c9eee775e151041642d573bdcb80d277416a Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:44:48 -0700 Subject: [PATCH 1/5] refactor(plugins): contextlib.suppress for try/except-pass, fold None guards --- plugins/context_engine/__init__.py | 4 +--- plugins/cron_providers/__init__.py | 9 +++------ plugins/disk-cleanup/__init__.py | 5 ++--- plugins/disk-cleanup/disk_cleanup.py | 9 +++------ plugins/google_meet/_jsonfile.py | 5 ++--- plugins/google_meet/audio_bridge.py | 5 ++--- plugins/google_meet/cli.py | 5 ++--- plugins/google_meet/process_manager.py | 9 +++------ plugins/google_meet/realtime/openai_client.py | 5 ++--- plugins/plugin_loader.py | 5 ++--- 10 files changed, 22 insertions(+), 39 deletions(-) diff --git a/plugins/context_engine/__init__.py b/plugins/context_engine/__init__.py index 56c84d5acb..57f30054ef 100644 --- a/plugins/context_engine/__init__.py +++ b/plugins/context_engine/__init__.py @@ -40,9 +40,7 @@ def _load_engine_from_dir(engine_dir: Path) -> Optional["ContextEngine"]: # noq mod = _loader.load_plugin_module( f"plugins.context_engine.{name}", engine_dir, parents=("plugins", "plugins.context_engine"), logger=logger) - if mod is None: - return None - return _loader.instance_from_module( + return mod and _loader.instance_from_module( mod, collector=_EngineCollector(engine_name=name), collected_attr="engine", base_cls=ContextEngine, name=name, logger=logger) diff --git a/plugins/cron_providers/__init__.py b/plugins/cron_providers/__init__.py index 4031c8c83b..dc40b10a97 100644 --- a/plugins/cron_providers/__init__.py +++ b/plugins/cron_providers/__init__.py @@ -53,9 +53,8 @@ def find_provider_dir(name: str) -> Optional[Path]: if bundled.is_dir() and (bundled / "__init__.py").exists(): return bundled user_dir = _loader.user_plugins_dir() - if user_dir and (user_dir / name).is_dir() and _is_cron_provider_dir(user_dir / name): - return user_dir / name - return None + user = user_dir / name if user_dir else None + return user if user and user.is_dir() and _is_cron_provider_dir(user) else None def discover_cron_schedulers() -> List[Tuple[str, str, bool]]: @@ -85,9 +84,7 @@ def _load_provider_from_dir(provider_dir: Path) -> Optional["CronScheduler"]: # mod = _loader.load_plugin_module( module_name, provider_dir, parents=("plugins", "plugins.cron_providers"), logger=logger, synthetic_namespace=None if is_bundled else _USER_NAMESPACE) - if mod is None: - return None - return _loader.instance_from_module( + return mod and _loader.instance_from_module( mod, collector=_ProviderCollector(), collected_attr="provider", base_cls=CronScheduler, name=name, logger=logger) diff --git a/plugins/disk-cleanup/__init__.py b/plugins/disk-cleanup/__init__.py index 6ab289c709..b641fab455 100644 --- a/plugins/disk-cleanup/__init__.py +++ b/plugins/disk-cleanup/__init__.py @@ -7,6 +7,7 @@ from __future__ import annotations +import contextlib import logging import re import shlex @@ -38,10 +39,8 @@ def _extract_paths_from_terminal(args: Dict[str, Any], result: str) -> Set[str]: paths: Set[str] = set() cmd = args.get("command") or "" if isinstance(cmd, str) and cmd: - try: # tokenise — catches `touch /tmp/hermes-x/test_foo.py` + with contextlib.suppress(ValueError): # tokenise — catches `touch /tmp/hermes-x/test_foo.py` paths.update(tok for tok in shlex.split(cmd, posix=True) if tok.startswith(("/", "~"))) - except ValueError: - pass # Only scan the result text if it's a reasonable size (avoid 50KB dumps). if isinstance(result, str) and len(result) < 4096: paths.update(_TERMINAL_PATH_REGEX.findall(result)) diff --git a/plugins/disk-cleanup/disk_cleanup.py b/plugins/disk-cleanup/disk_cleanup.py index 16f53509b6..15db509b49 100755 --- a/plugins/disk-cleanup/disk_cleanup.py +++ b/plugins/disk-cleanup/disk_cleanup.py @@ -8,6 +8,7 @@ Scope: strictly HERMES_HOME and /tmp/hermes-*; never ~/.hermes/logs/ or system d from __future__ import annotations +import contextlib import json import logging import shutil @@ -37,11 +38,9 @@ def _state_file(name: str) -> Path: def is_safe_path(path: Path) -> bool: """Accept only paths under HERMES_HOME or ``/tmp/hermes-*`` (rejects /mnt/c etc.).""" - try: + with contextlib.suppress(ValueError, OSError): path.resolve().relative_to(get_hermes_home()) return True - except (ValueError, OSError): - pass parts = path.parts return len(parts) >= 3 and parts[1] == "tmp" and parts[2].startswith("hermes-") @@ -284,13 +283,11 @@ def _sweep_empty_dirs(hermes_home: Path) -> int: while stack: dirpath, visited = stack.pop() if visited: - try: + with contextlib.suppress(OSError): if not any(dirpath.iterdir()): dirpath.rmdir() removed += 1 _log(f"DELETED: {dirpath} (empty dir)") - except OSError: - pass continue stack.append((dirpath, True)) stack.extend((child, False) for child in _subdirs(dirpath, _EMPTY_DIR_SWEEP_PRUNE_DIRS)) diff --git a/plugins/google_meet/_jsonfile.py b/plugins/google_meet/_jsonfile.py index 9758e57e7e..dd3a5549b3 100644 --- a/plugins/google_meet/_jsonfile.py +++ b/plugins/google_meet/_jsonfile.py @@ -2,6 +2,7 @@ from __future__ import annotations +import contextlib import json from pathlib import Path from typing import Any, Optional @@ -24,8 +25,6 @@ def write_json_atomic(path: Path, data: Any, mode: Optional[int] = None) -> None tmp = path.with_suffix(".json.tmp") tmp.write_text(json.dumps(data, indent=2), encoding="utf-8") if mode is not None: - try: + with contextlib.suppress(OSError, NotImplementedError): # best-effort on non-POSIX filesystems tmp.chmod(mode) - except (OSError, NotImplementedError): # best-effort on non-POSIX filesystems - pass tmp.replace(path) diff --git a/plugins/google_meet/audio_bridge.py b/plugins/google_meet/audio_bridge.py index 2c7d350092..c69513e94a 100644 --- a/plugins/google_meet/audio_bridge.py +++ b/plugins/google_meet/audio_bridge.py @@ -7,6 +7,7 @@ Linux: pactl creates a null-sink plus a virtual source on the sink's monitor; ca from __future__ import annotations +import contextlib import platform import subprocess from typing import Optional @@ -56,10 +57,8 @@ class AudioBridge: return if self._platform == "linux": for mod_id in reversed(self._module_ids): # virtual-source before null-sink - try: + with contextlib.suppress(Exception): _pactl("unload-module", str(mod_id), check=False) - except Exception: - pass self._module_ids = [] self._torn_down = True diff --git a/plugins/google_meet/cli.py b/plugins/google_meet/cli.py index 9ebd2a731c..912a7abfe4 100644 --- a/plugins/google_meet/cli.py +++ b/plugins/google_meet/cli.py @@ -10,6 +10,7 @@ from __future__ import annotations import argparse +import contextlib import importlib.util import json import platform @@ -220,10 +221,8 @@ def _cmd_auth() -> int: context = browser.new_context() page = context.new_page() page.goto("https://accounts.google.com/", wait_until="domcontentloaded") - try: + with contextlib.suppress(EOFError): input("press Enter after you've signed in ... ") - except EOFError: - pass context.storage_state(path=str(path)) browser.close() except Exception as e: diff --git a/plugins/google_meet/process_manager.py b/plugins/google_meet/process_manager.py index 30e9030e33..c415796254 100644 --- a/plugins/google_meet/process_manager.py +++ b/plugins/google_meet/process_manager.py @@ -8,6 +8,7 @@ across turns can find the bot. The bot is a detached subprocess reached via file from __future__ import annotations +import contextlib import json import os import signal @@ -47,10 +48,8 @@ def _active_pid() -> int: def _kill(pid: int, sig) -> None: - try: + with contextlib.suppress(ProcessLookupError): os.kill(pid, sig) - except ProcessLookupError: - pass _NO_ACTIVE = {"ok": False, "reason": "no active meeting"} @@ -72,10 +71,8 @@ def start(url: str, *, out_dir: Optional[Path] = None, headed: bool = False, out.mkdir(parents=True, exist_ok=True) # Wipe stale files from a previous run of this meeting id. for name in ("transcript.txt", "status.json"): - try: + with contextlib.suppress(OSError): (out / name).unlink() - except OSError: - pass env = {**os.environ, "HERMES_MEET_URL": url, "HERMES_MEET_OUT_DIR": str(out), "HERMES_MEET_GUEST_NAME": guest_name} for value, var in ( diff --git a/plugins/google_meet/realtime/openai_client.py b/plugins/google_meet/realtime/openai_client.py index 1f14f3933b..0eb8cc94bb 100644 --- a/plugins/google_meet/realtime/openai_client.py +++ b/plugins/google_meet/realtime/openai_client.py @@ -7,6 +7,7 @@ Chrome's fake mic. One sync WebSocket per session; ``websockets`` is imported la from __future__ import annotations import base64 +import contextlib import json import threading import time @@ -69,10 +70,8 @@ class RealtimeSession: def close(self) -> None: if self._ws is not None: - try: + with contextlib.suppress(Exception): self._ws.close() - except Exception: - pass self._ws = None def speak(self, text: str, timeout: float = 30.0) -> dict: diff --git a/plugins/plugin_loader.py b/plugins/plugin_loader.py index 49b719f75b..7f9d3594d1 100644 --- a/plugins/plugin_loader.py +++ b/plugins/plugin_loader.py @@ -5,6 +5,7 @@ or an ABC-subclass fallback.""" from __future__ import annotations +import contextlib import importlib.machinery import importlib.util import logging @@ -150,10 +151,8 @@ def instance_from_module(mod: Any, *, collector: Any, collected_attr: str, base_ for attr_name in dir(mod): attr = getattr(mod, attr_name, None) if isinstance(attr, type) and issubclass(attr, base_cls) and attr is not base_cls: - try: + with contextlib.suppress(Exception): return attr() - except Exception: - pass return None From 4de32676cecf45f8ce3adae3d98932d4241b2353 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:53:31 -0700 Subject: [PATCH 2/5] refactor(plugins/google_meet): table-drive validate_request checks (285k-case fuzz parity vs base) --- plugins/google_meet/node/protocol.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/plugins/google_meet/node/protocol.py b/plugins/google_meet/node/protocol.py index 623fe6333c..c50fdf3d09 100644 --- a/plugins/google_meet/node/protocol.py +++ b/plugins/google_meet/node/protocol.py @@ -72,18 +72,12 @@ def validate_request(msg: Dict[str, Any], expected_token: str) -> Tuple[bool, st """Return ``(True, "")`` or ``(False, )``; reasons are safe to send back to the client.""" if not isinstance(msg, dict): return False, "envelope must be a dict" - t = msg.get("type") - if not _nonempty_str(t): - return False, "missing or non-string 'type'" - if t not in VALID_REQUEST_TYPES: - return False, f"unknown request type: {t!r}" - if not _nonempty_str(msg.get("id")): - return False, "missing or non-string 'id'" - token = msg.get("token") - if not _nonempty_str(token): - return False, "missing token" - if token != expected_token: - return False, "token mismatch" - if not isinstance(msg.get("payload"), dict): - return False, "payload must be a dict" - return True, "" + t, token = msg.get("type"), msg.get("token") + checks = ( # ordered, lazily evaluated: first failing check wins + (lambda: _nonempty_str(t), "missing or non-string 'type'"), + (lambda: t in VALID_REQUEST_TYPES, f"unknown request type: {t!r}"), + (lambda: _nonempty_str(msg.get("id")), "missing or non-string 'id'"), + (lambda: _nonempty_str(token), "missing token"), + (lambda: token == expected_token, "token mismatch"), + (lambda: isinstance(msg.get("payload"), dict), "payload must be a dict")) + return next(((False, reason) for ok, reason in checks if not ok()), (True, "")) From e1f145538e18e3ad734fdb406edb42c56b25ef4c Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:56:06 -0700 Subject: [PATCH 3/5] =?UTF-8?q?refactor(plugins/google=5Fmeet):=20AudioBri?= =?UTF-8?q?dge=20=E2=80=94=20drop=20redundant=20=5Ftorn=5Fdown=20flag=20(m?= =?UTF-8?q?odule=20id=20list=20already=20encodes=20it)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/google_meet/audio_bridge.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/plugins/google_meet/audio_bridge.py b/plugins/google_meet/audio_bridge.py index c69513e94a..9ba3483fe4 100644 --- a/plugins/google_meet/audio_bridge.py +++ b/plugins/google_meet/audio_bridge.py @@ -30,7 +30,6 @@ class AudioBridge: self._device_name: Optional[str] = None self._write_target: Optional[str] = None self._module_ids: list[int] = [] - self._torn_down = False def _ready(self, value: Optional[str]) -> str: if not value: @@ -47,27 +46,20 @@ class AudioBridge: return self._setup_linux() if system == "Darwin": return self._setup_darwin() - if system == "Windows": - raise RuntimeError("windows not supported in v2") - raise RuntimeError(f"unsupported platform: {system}") + raise RuntimeError("windows not supported in v2" if system == "Windows" else f"unsupported platform: {system}") def teardown(self) -> None: """Release the virtual audio device. Idempotent; never raises.""" - if self._torn_down: - return - if self._platform == "linux": - for mod_id in reversed(self._module_ids): # virtual-source before null-sink - with contextlib.suppress(Exception): - _pactl("unload-module", str(mod_id), check=False) - self._module_ids = [] - self._torn_down = True + for mod_id in reversed(self._module_ids): # linux only; virtual-source before null-sink + with contextlib.suppress(Exception): + _pactl("unload-module", str(mod_id), check=False) + self._module_ids = [] def _finish(self, tag: str, device: str, write_target: str, module_ids: list[int]) -> dict: self._platform = tag self._device_name = device self._write_target = write_target self._module_ids = module_ids - self._torn_down = False return {"platform": tag, "device_name": device, "sample_rate": 48000, "channels": 2, "module_ids": list(module_ids), "write_target": write_target} From eb6b760981daaf674e90a49fcc4bc99f4c84fefe Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:59:19 -0700 Subject: [PATCH 4/5] =?UTF-8?q?refactor(plugins/google=5Fmeet):=20Realtime?= =?UTF-8?q?Session.speak=20=E2=80=94=20ExitStack=20for=20the=20optional=20?= =?UTF-8?q?sink=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/google_meet/realtime/openai_client.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/plugins/google_meet/realtime/openai_client.py b/plugins/google_meet/realtime/openai_client.py index 0eb8cc94bb..de0e58def4 100644 --- a/plugins/google_meet/realtime/openai_client.py +++ b/plugins/google_meet/realtime/openai_client.py @@ -86,18 +86,16 @@ class RealtimeSession: }) self._send_json({"type": "response.create", "response": {"modalities": ["audio"]}}) bytes_written = 0 - sink_fp = None - if self.audio_sink_path is not None: - self.audio_sink_path.parent.mkdir(parents=True, exist_ok=True) - sink_fp = open(self.audio_sink_path, "ab") - try: + with contextlib.ExitStack() as stack: + sink_fp = None + if self.audio_sink_path is not None: + self.audio_sink_path.parent.mkdir(parents=True, exist_ok=True) + sink_fp = stack.enter_context(open(self.audio_sink_path, "ab")) while True: frame = self._recv_frame(start + timeout, timeout) - if frame is None: # connection closed by peer + if frame is None or frame.get("type") in _TERMINAL_FRAMES: # peer closed / response done break ftype = frame.get("type") - if ftype in _TERMINAL_FRAMES: - break if ftype == "error": raise RuntimeError(f"realtime error: {frame.get('error') or frame}") if ftype == "response.audio.delta" and sink_fp is not None: @@ -108,9 +106,6 @@ class RealtimeSession: bytes_written += len(chunk) self.audio_bytes_out += len(chunk) self.last_audio_out_at = time.time() - finally: - if sink_fp is not None: - sink_fp.close() return {"ok": True, "bytes_written": bytes_written, "duration_ms": (time.monotonic() - start) * 1000.0} def cancel_response(self) -> bool: From c97257ae8e669e25e941024f4ee606c4d159c412 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 23:02:47 -0700 Subject: [PATCH 5/5] refactor(plugins/google_meet): wrap three over-long lines --- plugins/google_meet/audio_bridge.py | 3 ++- plugins/google_meet/cli.py | 3 ++- plugins/google_meet/process_manager.py | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/google_meet/audio_bridge.py b/plugins/google_meet/audio_bridge.py index 9ba3483fe4..2435622c28 100644 --- a/plugins/google_meet/audio_bridge.py +++ b/plugins/google_meet/audio_bridge.py @@ -46,7 +46,8 @@ class AudioBridge: return self._setup_linux() if system == "Darwin": return self._setup_darwin() - raise RuntimeError("windows not supported in v2" if system == "Windows" else f"unsupported platform: {system}") + raise RuntimeError("windows not supported in v2" if system == "Windows" + else f"unsupported platform: {system}") def teardown(self) -> None: """Release the virtual audio device. Idempotent; never raises.""" diff --git a/plugins/google_meet/cli.py b/plugins/google_meet/cli.py index 912a7abfe4..f251560935 100644 --- a/plugins/google_meet/cli.py +++ b/plugins/google_meet/cli.py @@ -214,7 +214,8 @@ def _cmd_auth() -> int: return 1 path = _auth_state_path() path.parent.mkdir(parents=True, exist_ok=True) - print(f"opening Chromium — sign in to Google, then return here and press Enter.\nsaving storage state to: {path}") + print("opening Chromium — sign in to Google, then return here and press Enter.\n" + f"saving storage state to: {path}") try: with sync_playwright() as pw: browser = pw.chromium.launch(headless=False) diff --git a/plugins/google_meet/process_manager.py b/plugins/google_meet/process_manager.py index c415796254..9cf6077852 100644 --- a/plugins/google_meet/process_manager.py +++ b/plugins/google_meet/process_manager.py @@ -146,7 +146,8 @@ def enqueue_say(text: str) -> Dict[str, Any]: entry = {"id": uuid.uuid4().hex[:12], "text": text} with queue_path.open("a", encoding="utf-8") as f: f.write(json.dumps(entry) + "\n") - return {"ok": True, "meetingId": active.get("meeting_id"), "enqueued_id": entry["id"], "queue_path": str(queue_path)} + return {"ok": True, "meetingId": active.get("meeting_id"), "enqueued_id": entry["id"], + "queue_path": str(queue_path)} def stop(*, reason: str = "requested") -> Dict[str, Any]: