From 4fcf23936038d9718a065a1092e96eac5fc6e2cc Mon Sep 17 00:00:00 2001 From: ajianaz Date: Wed, 15 Jul 2026 19:31:20 +0700 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20fix=20Mode=20C=20handler=20?= =?UTF-8?q?=E2=80=94=20replace=20/proc=20with=20cwd-based=20agent=20resolu?= =?UTF-8?q?tion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /proc/self/cmdline approach is unreliable because shell hooks run as child subprocesses whose cmdline is the handler script, not the gateway process. This caused agent name resolution to fail when hooks were invoked from asyncio contexts (e.g., session expiry watcher). Changes: - Replace /proc/self/cmdline with cwd-based resolution from payload - Dynamically resolve agent per invocation (not at module load time) - Remove hardcoded UTEKE_BIN path check (assume uteke on PATH) - Remove cron session skip (handler-level concern, not docs example) - Pass agent name to recall function explicitly --- docs/integrations/hermes.md | 42 +++++++++++++++---------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/docs/integrations/hermes.md b/docs/integrations/hermes.md index c10d66b5..8c038344 100644 --- a/docs/integrations/hermes.md +++ b/docs/integrations/hermes.md @@ -398,29 +398,25 @@ import pathlib import subprocess import sys -def _resolve_agent_name() -> str: - """Extract agent name from Hermes CLI invocation.""" - try: - with open("/proc/self/cmdline", "rb") as f: - parts = f.read().split(b"\x00") - for i, part in enumerate(parts): - if part == b"-p" and i + 1 < len(parts): - name = parts[i + 1].decode("utf-8", errors="ignore").strip() - if name: - return name - except Exception: - pass +def _resolve_agent_name(cwd: str = "") -> str: + """Extract agent name from Hermes hook payload cwd. + + Priority: cwd from payload > HERMES_PROFILE env > fallback. + The /proc/self/cmdline approach is unreliable — shell hooks run as + child subprocesses whose cmdline is the handler script, not the + gateway. Use the cwd payload field (always set by Hermes) instead. + """ + if cwd: + p = pathlib.Path(cwd) + for parent in [p, *p.parents]: + if parent.name and parent.name != "profiles": + return parent.name return "default" -AGENT = _resolve_agent_name() -UTEKE_BIN = pathlib.Path(shutil.which("uteke") or "/opt/data/.cargo/bin/uteke") # adjust to your path - -def _recall_uteke(query: str, limit: int = 5) -> list: - if not UTEKE_BIN.exists(): - return [] +def _recall_uteke(query: str, agent: str, limit: int = 5) -> list: try: proc = subprocess.run( - [str(UTEKE_BIN), "recall", "--namespace", AGENT, + ["uteke", "recall", "--namespace", agent, "--limit", str(limit), "--json", query], capture_output=True, text=True, timeout=15, ) @@ -446,12 +442,8 @@ def main(): if not isinstance(message, str) or not message.strip() or len(message) < 5: sys.exit(0) - # Skip cron sessions - session_id = raw.get("session_id", "") - if isinstance(session_id, str) and session_id.startswith("cron_"): - sys.exit(0) - - memories = _recall_uteke(message.strip()[:500], limit=5) + agent = _resolve_agent_name(raw.get("cwd", "")) + memories = _recall_uteke(message.strip()[:500], agent, limit=5) if not memories: sys.exit(0) From de8799fbd6715b018b2648baa9a845160e04d5b0 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Wed, 15 Jul 2026 19:42:26 +0700 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20fix=20docstring=20=E2=80=94=20remov?= =?UTF-8?q?e=20false=20HERMES=5FPROFILE=20fallback=20claim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cora review: docstring claimed 'Priority: cwd > HERMES_PROFILE env > fallback' but code only checks cwd then returns 'default'. Fix docstring to match actual behavior. --- docs/integrations/hermes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/integrations/hermes.md b/docs/integrations/hermes.md index 8c038344..450fa8e9 100644 --- a/docs/integrations/hermes.md +++ b/docs/integrations/hermes.md @@ -401,10 +401,11 @@ import sys def _resolve_agent_name(cwd: str = "") -> str: """Extract agent name from Hermes hook payload cwd. - Priority: cwd from payload > HERMES_PROFILE env > fallback. The /proc/self/cmdline approach is unreliable — shell hooks run as child subprocesses whose cmdline is the handler script, not the gateway. Use the cwd payload field (always set by Hermes) instead. + + Falls back to "default" if cwd is empty or resolution fails. """ if cwd: p = pathlib.Path(cwd)