Merge branch 'main' into bb/gui

This commit is contained in:
emozilla
2026-05-09 00:27:42 -04:00
319 changed files with 10598 additions and 2078 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ def discover_context_engines() -> List[Tuple[str, str, bool]]:
if yaml_file.exists():
try:
import yaml
with open(yaml_file) as f:
with open(yaml_file, encoding="utf-8-sig") as f:
meta = yaml.safe_load(f) or {}
desc = meta.get("description", "")
except Exception:
+1 -1
View File
@@ -90,7 +90,7 @@ def _log(message: str) -> None:
log_file = get_log_file()
log_file.parent.mkdir(parents=True, exist_ok=True)
ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
with open(log_file, "a") as f:
with open(log_file, "a", encoding="utf-8") as f:
f.write(f"[{ts}] {message}\n")
except OSError:
# Never let the audit log break the agent loop.
+6 -9
View File
@@ -70,14 +70,11 @@ def _clear_active() -> None:
def _pid_alive(pid: int) -> bool:
try:
os.kill(pid, 0)
except ProcessLookupError:
return False
except PermissionError:
# Process exists but we can't signal it — treat as alive.
return True
return True
# ``os.kill(pid, 0)`` is NOT a no-op on Windows (bpo-14484) — it
# routes through GenerateConsoleCtrlEvent and can kill the target.
# Use the cross-platform existence check.
from gateway.status import _pid_exists
return _pid_exists(pid)
# ---------------------------------------------------------------------------
@@ -313,7 +310,7 @@ def stop(*, reason: str = "requested") -> Dict[str, Any]:
time.sleep(0.5)
if _pid_alive(pid):
try:
os.kill(pid, signal.SIGKILL)
os.kill(pid, signal.SIGKILL) # windows-footgun: ok — POSIX-only plugin (google_meet registers no-op on Windows; see __init__.py)
except ProcessLookupError:
pass
@@ -292,7 +292,7 @@ class RealtimeSpeaker:
return
self.processed_path.parent.mkdir(parents=True, exist_ok=True)
record = {"id": entry.get("id"), "text": entry.get("text", ""), "result": result}
with open(self.processed_path, "a") as fp:
with open(self.processed_path, "a", encoding="utf-8") as fp:
fp.write(json.dumps(record) + "\n")
# ── main loop ────────────────────────────────────────────────────────
+2 -2
View File
@@ -135,7 +135,7 @@ def discover_memory_providers() -> List[Tuple[str, str, bool]]:
if yaml_file.exists():
try:
import yaml
with open(yaml_file) as f:
with open(yaml_file, encoding="utf-8-sig") as f:
meta = yaml.safe_load(f) or {}
desc = meta.get("description", "")
except Exception:
@@ -381,7 +381,7 @@ def discover_plugin_cli_commands() -> List[dict]:
if yaml_file.exists():
try:
import yaml
with open(yaml_file) as f:
with open(yaml_file, encoding="utf-8-sig") as f:
meta = yaml.safe_load(f) or {}
desc = meta.get("description", "")
if desc:
+4 -4
View File
@@ -1215,7 +1215,7 @@ class HindsightMemoryProvider(MemoryProvider):
# would capture output from other threads.
import hindsight_embed.daemon_embed_manager as dem
from rich.console import Console
dem.console = Console(file=open(log_path, "a"), force_terminal=False)
dem.console = Console(file=open(log_path, "a", encoding="utf-8"), force_terminal=False)
client = self._get_client()
profile = self._config.get("profile", "hermes")
@@ -1231,15 +1231,15 @@ class HindsightMemoryProvider(MemoryProvider):
if config_changed:
profile_env = _materialize_embedded_profile_env(self._config)
if client._manager.is_running(profile):
with open(log_path, "a") as f:
with open(log_path, "a", encoding="utf-8") as f:
f.write("\n=== Config changed, restarting daemon ===\n")
client._manager.stop(profile)
client._ensure_started()
with open(log_path, "a") as f:
with open(log_path, "a", encoding="utf-8") as f:
f.write("\n=== Daemon started successfully ===\n")
except Exception as e:
with open(log_path, "a") as f:
with open(log_path, "a", encoding="utf-8") as f:
f.write(f"\n=== Daemon startup failed: {e} ===\n")
traceback.print_exc(file=f)
+3 -3
View File
@@ -101,7 +101,7 @@ def _load_plugin_config() -> dict:
return {}
try:
import yaml
with open(config_path) as f:
with open(config_path, encoding="utf-8-sig") as f:
all_config = yaml.safe_load(f) or {}
return cfg_get(all_config, "plugins", "hermes-memory-store", default={}) or {}
except Exception:
@@ -136,11 +136,11 @@ class HolographicMemoryProvider(MemoryProvider):
import yaml
existing = {}
if config_path.exists():
with open(config_path) as f:
with open(config_path, encoding="utf-8-sig") as f:
existing = yaml.safe_load(f) or {}
existing.setdefault("plugins", {})
existing["plugins"]["hermes-memory-store"] = values
with open(config_path, "w") as f:
with open(config_path, "w", encoding="utf-8") as f:
yaml.dump(existing, f, default_flow_style=False)
except Exception:
pass
+4 -5
View File
@@ -2936,15 +2936,14 @@ def interactive_setup() -> None:
prompt for env vars, persist them to ``~/.hermes/.env`` so the next
gateway restart picks them up.
"""
from hermes_cli.config import (
get_env_value,
save_env_value,
prompt,
prompt_yes_no,
from hermes_cli.cli_output import (
print_info,
print_success,
print_warning,
prompt,
prompt_yes_no,
)
from hermes_cli.config import get_env_value, save_env_value
existing_sub = get_env_value("GOOGLE_CHAT_SUBSCRIPTION_NAME")
if existing_sub: