Skip to content

Gateway Profiles — Slack Multiplex & Telegram Bots

This page documents how the Hermes messaging gateway on the Agent Host serves the default, bourgon, and djuly profiles, and how each profile is reached from Slack and Telegram. It supersedes the earlier per-profile gateway services.

A single hermes-gateway.service serves all three profiles (gateway multiplexing). The profile is selected differently depending on the platform:

  • Slack — one shared bot; the inbound channel selects the profile via profile_routes.
  • Telegram — one bot per profile; the bot itself selects the profile.

Slack uses a single Socket Mode App (@hermes) owned by the default gateway. The inbound channel determines which profile handles the message:

Slack channel Profile
#djuly-diet (C0B786XP4FQ) djuly
#chateaudebourgon-website (C0BCNA7V2TC) bourgon
any other channel / DM default

That routing is declared in the default profile’s config.yaml:

gateway:
multiplex_profiles: true
profile_routes:
- name: bourgon-website
platform: slack
chat_id: C0BCNA7V2TC
profile: bourgon
- name: djuly-diet
platform: slack
chat_id: C0B786XP4FQ
profile: djuly

Why not a per-profile Slack gateway? Slack Socket Mode forbids two concurrent connections using the same App Token. Running default and bourgon as separate gateways sharing the same token caused Slack app token already in use failures. Channel allowlists would not help because the collision happens at connect time, before any message filtering. A single gateway owning the ingress and routing channels is the clean solution.

The named profiles must not start their own Slack adapters when the default gateway owns the shared ingress; their Slack adapters remain disabled.

Each profile owns its own Telegram bot token (in its own .env). The multiplexed gateway connects all three bots simultaneously:

Telegram bot Profile Token fingerprint
hermes_fducat_bot default bccbb31deaea
bourgon bourgon 4ab831bb220c
nutry_djuly_bot djuly 4a83bf72fcd5

A message to nutry_djuly_bot is handled by the djuly profile; a message to hermes_fducat_bot by the default profile. No profile_routes work is needed — the bot identity is the selector. There is no token collision because the bots are distinct.

Regardless of how a message was routed (channel or bot), the turn executes inside the target profile’s isolated runtime: its own configuration, model, reasoning settings, SOUL.md, skills, memory, credentials (.env), cron store, and HERMES_HOME.

The former dedicated units still exist on disk but are legacy and disabled:

hermes-gateway-bourgon.service
hermes-gateway-djuly.service

Do not start them while the multiplexed gateway is authoritative; that would create duplicate profile runtimes or duplicate platform adapters. Their definitive removal is pending the dashboard profile status fix (the view still expects a process per profile and can incorrectly report a multiplexed profile as “not started”).