Merge branch 'main' into bb/gui
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 ────────────────────────────────────────────────────────
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user