Port from earendil-works/pi#7493: advertise AI_AGENT env var for child-process attribution
CLI and gateway entry points now set AI_AGENT=hermes (the emerging cross-agent standard read by e.g. huggingface_hub agent detection) and HERMES_AGENT=true, via setdefault so an outer harness is never clobbered.
This commit is contained in:
parent
0957277f2f
commit
fde6a843e5
|
|
@ -27020,6 +27020,14 @@ async def start_gateway(config: Optional[GatewayConfig] = None, replace: bool =
|
|||
|
||||
def main():
|
||||
"""CLI entry point for the gateway."""
|
||||
# Advertise the agent harness to child processes (AI_AGENT is the
|
||||
# cross-agent standard; HERMES_AGENT the Hermes-specific marker — see
|
||||
# _advertise_agent_env in hermes_cli/main.py, kept inline here to avoid
|
||||
# importing that module's startup side effects). setdefault so an outer
|
||||
# harness is never clobbered.
|
||||
os.environ.setdefault("AI_AGENT", "hermes")
|
||||
os.environ.setdefault("HERMES_AGENT", "true")
|
||||
|
||||
# Force UTF-8 stdio on Windows — gateway logs and startup banner would
|
||||
# otherwise UnicodeEncodeError on cp1252 consoles. No-op on POSIX.
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -11180,12 +11180,30 @@ def cmd_claw(args):
|
|||
claw_command(args)
|
||||
|
||||
|
||||
def _advertise_agent_env() -> None:
|
||||
"""Advertise the agent harness to child processes.
|
||||
|
||||
``AI_AGENT`` is the emerging cross-agent standard (huggingface_hub's agent
|
||||
detection reads it; pi and other agents set it — earendil-works/pi#7493)
|
||||
so generic tooling can attribute subprocesses to the harness that spawned
|
||||
them. ``HERMES_AGENT`` is the Hermes-specific marker. setdefault: never
|
||||
clobber an outer harness (e.g. Hermes running inside another agent's
|
||||
terminal).
|
||||
"""
|
||||
os.environ.setdefault("AI_AGENT", "hermes")
|
||||
os.environ.setdefault("HERMES_AGENT", "true")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point for hermes CLI."""
|
||||
# Cosmetic: make the process show up as 'hermes' instead of 'python3.11'
|
||||
# in ps/top/htop. Non-fatal — just a nicer UX.
|
||||
_set_process_title()
|
||||
|
||||
# Let child processes (and tools like huggingface_hub) detect they run
|
||||
# under an AI agent harness.
|
||||
_advertise_agent_env()
|
||||
|
||||
# Force UTF-8 stdio on Windows before anything prints. No-op elsewhere.
|
||||
try:
|
||||
from hermes_cli.stdio import configure_windows_stdio
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
"""Tests for the AI_AGENT / HERMES_AGENT harness-attribution env vars.
|
||||
|
||||
Port of earendil-works/pi#7493: entry points advertise the agent harness to
|
||||
child processes via the cross-agent ``AI_AGENT`` standard plus a
|
||||
Hermes-specific marker, without clobbering an outer harness.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from hermes_cli.main import _advertise_agent_env
|
||||
|
||||
|
||||
class TestAdvertiseAgentEnv:
|
||||
def test_sets_both_vars_when_unset(self, monkeypatch):
|
||||
monkeypatch.delenv("AI_AGENT", raising=False)
|
||||
monkeypatch.delenv("HERMES_AGENT", raising=False)
|
||||
_advertise_agent_env()
|
||||
assert os.environ["AI_AGENT"] == "hermes"
|
||||
assert os.environ["HERMES_AGENT"] == "true"
|
||||
|
||||
def test_does_not_clobber_outer_harness(self, monkeypatch):
|
||||
monkeypatch.setenv("AI_AGENT", "pi")
|
||||
monkeypatch.delenv("HERMES_AGENT", raising=False)
|
||||
_advertise_agent_env()
|
||||
assert os.environ["AI_AGENT"] == "pi"
|
||||
assert os.environ["HERMES_AGENT"] == "true"
|
||||
|
||||
def test_idempotent(self, monkeypatch):
|
||||
monkeypatch.delenv("AI_AGENT", raising=False)
|
||||
monkeypatch.delenv("HERMES_AGENT", raising=False)
|
||||
_advertise_agent_env()
|
||||
_advertise_agent_env()
|
||||
assert os.environ["AI_AGENT"] == "hermes"
|
||||
assert os.environ["HERMES_AGENT"] == "true"
|
||||
|
|
@ -864,6 +864,8 @@ Unset the variable or remove it from `.env` to restore normal writes (still subj
|
|||
| `SESSION_IDLE_MINUTES` | Reset sessions after N minutes of inactivity (default: 1440) |
|
||||
| `SESSION_RESET_HOUR` | Daily reset hour in 24h format (default: 4 = 4am) |
|
||||
| `HERMES_SESSION_ID` | **Exported automatically into every tool subprocess** Hermes spawns (`terminal`, `execute_code`, persistent shell, Docker/Singularity backends, delegated subagent runs). Set by the agent to the current session ID; user scripts called from tools can read it to correlate their output, telemetry, or side effects with the originating Hermes session. **You should not set this manually** — overriding it from a parent shell only takes effect outside an agent run, and is overwritten the moment the agent starts a session. |
|
||||
| `AI_AGENT` | **Set to `hermes` by the CLI and gateway entry points** (only when not already set by an outer harness). The emerging cross-agent standard for child-process attribution — generic tooling (e.g. huggingface_hub's agent detection) reads it to know it runs under an AI agent. Don't set manually. |
|
||||
| `HERMES_AGENT` | **Set to `true` by the CLI and gateway entry points** so child processes can detect they run inside Hermes specifically. Don't set manually. |
|
||||
|
||||
## Context Compression (config.yaml only)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue