This page documents the GatewayRunner class and its role in orchestrating message routing between messaging platforms and the AIAgent. The gateway runs as a persistent daemon that connects to multiple platforms (Telegram, Discord, WhatsApp, Slack, Signal, etc.) and manages AIAgent instances per session.
Key architectural difference from CLI: While the CLI maintains a single persistent AIAgent instance for a local terminal session, the gateway orchestrates multiple concurrent sessions across different platforms. It instantiates or reuses agents based on incoming MessageEvent data gateway/run.py61-66 Session state is preserved by loading conversation history from a SQLite database (state.db) via SessionDB hermes_state.py7-15
The gateway consists of three main layers: platform adapters, the orchestration runner, and the core agent logic.
The following diagram bridges the conceptual messaging flow to the specific Python classes and files responsible for execution.
Sources: gateway/run.py5-14 gateway/run.py158-936 hermes_state.py17-30 gateway/platforms/base.py1-21
| Component | Purpose | Location |
|---|---|---|
GatewayRunner | Main orchestration class, manages platform adapters and message routing | gateway/run.py158-936 |
SessionDB | SQLite-backed session storage with FTS5 full-text search | hermes_state.py17-30 |
SessionSource | Describes origin metadata (platform, chat_id, user_id, chat_type) | gateway/session.py148-180 |
AIAgent | The core agent class that executes the conversation loop | run_agent.py17-21 |
GatewayStreamConsumer | Bridges sync agent callbacks to async platform delivery for progressive edits | gateway/stream_consumer.py83-140 |
DeliveryRouter | Routes messages to platform adapters for delivery | gateway/run.py98-100 |
BasePlatformAdapter | Abstract base class for all platform-specific message handling | gateway/platforms/base.py21-25 |
The GatewayRunner manages a pool of AIAgent instances using an LRU cache to prevent memory exhaustion in long-lived daemons.
_AGENT_CACHE_MAX_SIZE) gateway/run.py78_AGENT_CACHE_IDLE_TTL_SECS; agents inactive for this duration are evicted gateway/run.py79_session_expiry_watcher) periodically scans and prunes stale agents from memory gateway/run.py76-77Sources: gateway/run.py73-80
The gateway startup sequence involves PID management and platform initialization.
Sources: gateway/run.py27-42 hermes_cli/gateway.py84-161 gateway/status.py66-70
Notable startup behaviors:
{HERMES_HOME}/gateway.pid gateway/status.py66-70_ensure_windows_gateway_venv_imports() ensures the Hermes venv packages are visible even if launched via pythonw.exe to avoid missing dependencies gateway/run.py160-191acquire_gateway_runtime_lock() to prevent multiple gateway instances from running in the same profile simultaneously gateway/status.py150-160Incoming messages are mapped to sessions using a deterministic session_key.
build_session_key(source), typically formatted as agent:main:<platform>:<chat_id> gateway/session.py105-107..) or unsafe characters to prevent filesystem escape gateway/session.py108-120auto_continue_freshness_window(). If a session is older than this window, the gateway may force a fresh start depending on the SessionResetPolicy gateway/session.py31-57is_source_allowed() before processing messages gateway/run.py105-110Sources: gateway/session.py31-120 gateway/run.py105-110
The GatewayStreamConsumer handles real-time delivery of tokens.
on_delta() callbacks from the agent worker thread and queues them for an asyncio task gateway/stream_consumer.py4-9edit_interval (e.g., 1.0s) to avoid platform rate limits (flood control) gateway/stream_consumer.py55-60<think> or <thought> to handle internal model deliberation separately from user-facing content gateway/stream_consumer.py102-112Sources: gateway/stream_consumer.py4-112
The gateway serves as the primary delivery vehicle for scheduled tasks.
DeliveryRouter to send results back to the original SessionSource gateway/session.py148-156hermes_cli/main.py cron subcommands hermes_cli/main.py17-20Sources: gateway/session.py148-156 hermes_cli/main.py17-20
GATEWAY_SERVICE_RESTART_EXIT_CODE (75) triggers a service restart by systemd or launchd hermes_cli/gateway.py33-37DEFAULT_GATEWAY_RESTART_DRAIN_TIMEOUT hermes_cli/gateway.py33-40hermes-gateway.service) and handles daemon-reload automatically when units are updated hermes_cli/gateway.py107-127gateway.systemd_watchdog_seconds gateway/config.py153-160Sources: hermes_cli/gateway.py33-127 gateway/config.py153-160
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.