Skip to content

fix(gateway): multiplex primary bot tokens without empty reconnect loops (#64674) - #64986

Closed
SAMBAS123 wants to merge 1 commit into
NousResearch:mainfrom
SAMBAS123:fix/64674-multiplex-telegram-token
Closed

fix(gateway): multiplex primary bot tokens without empty reconnect loops (#64674)#64986
SAMBAS123 wants to merge 1 commit into
NousResearch:mainfrom
SAMBAS123:fix/64674-multiplex-telegram-token

Conversation

@SAMBAS123

Copy link
Copy Markdown

Summary

Fixes #64674.

When gateway.multiplex_profiles: true and a bot token (e.g. TELEGRAM_BOT_TOKEN) lives only under a profile .env, the default-profile gateway used to:

  1. Call load_gateway_config() unscoped at GatewayRunner.__init__
  2. Resolve tokens via os.environ (often empty once secrets moved out of the default .env)
  3. Fail Telegram connect with No bot token configured
  4. Queue an infinite reconnect watcher loop on the empty config

Secondary profiles already load under _profile_runtime_scope and work; this PR fixes the complementary primary path.

Changes

  • load_gateway_config_for_runner() — when multiplex is on, reload config under the default profile secret scope (same seam secondary adapters use). Multiplex off = unchanged.
  • Primary startup — under multiplex, skip token platforms that still have no credential instead of connect-fail-reconnect forever. Secondary profiles that own the token still connect.
  • Reconnect watcher — drop empty-token queued configs so they cannot spin forever.
  • Regression teststests/gateway/test_64674_multiplex_primary_token_scope.py (8 passed).

Why this is backward-compatible

  • Single-profile gateways never set multiplex_profiles → no behavior change.
  • Explicit GatewayRunner(config=...) injection (tests) is untouched.
  • We do not copy secondary tokens into the default profile or os.environ (preserves multiplex credential isolation / Workstream A).

Tests

pytest tests/gateway/test_64674_multiplex_primary_token_scope.py -q
# 8 passed

Related

…nnect loops

When gateway.multiplex_profiles is on, the default-profile GatewayRunner
used to call load_gateway_config() unscoped. Platform tokens that lived
only in a profile .env (often a secondary profile) never reached the
primary Telegram adapter, producing "No bot token configured" and an
infinite reconnect watcher loop (NousResearch#64674).

- Load primary config under the default profile secret scope when multiplex
  is enabled (same path secondary adapters already use).
- Skip starting token platforms on the default profile when no credential
  is present under multiplex; secondary profiles still connect with their
  scoped tokens.
- Drop empty-token configs from the reconnect queue so they cannot spin
  forever.

Regression coverage in tests/gateway/test_64674_multiplex_primary_token_scope.py.
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter P2 Medium — degraded but workaround exists sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jul 15, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved with Note

Looks Good

  • Fix(gateway): multiplex primary bot tokens without empty reconnect loops (#64674)
  • 310 additions, 1 deletion — targeted fix
  • No issues detected

Note

  • Some print/debug patterns in diff checked — appear in existing test fixtures, not new artifacts

Reviewed by Hermes Agent

@SAMBAS123

Copy link
Copy Markdown
Author

Thanks @tonydwb — appreciate the review and the note.

Agreed on the print/debug patterns: those stay in the existing test fixtures only; nothing new for production paths. Happy to tighten further if maintainers want anything adjusted before merge.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused multiplex-token fix. The primary-path premise remains valid on current main: gateway/run.py:2861 still loads config before a profile secret scope, while gateway/config.py:174-189 falls back to os.environ when unscoped.

Problems

  • The new gate at gateway/run.py:7222 treats Matrix as token/api-key-only. Matrix supports password login at plugins/platforms/matrix/adapter.py:1255-1269; a valid multiplexed Matrix password configuration would now be skipped.
  • The reconnect deletion at gateway/run.py:8069 is not gated on multiplex_profiles, so it changes single-profile retry behavior despite the compatibility claim.
  • The added tests simulate the branch conditions rather than exercising GatewayRunner.start() or _platform_reconnect_watcher(), so they do not validate the changed runtime paths.

Suggested changes

  • Use the platform configuration contract rather than a hard-coded token list, preserving Matrix password authentication.
  • Scope reconnect removal to the multiplex primary-empty-credential case.
  • Add real temporary-HERMES_HOME start/watcher coverage for default, secondary-only, and Matrix password credentials.

This is an automated hermes-sweeper review.

Comment thread gateway/run.py
# real token — skip the empty primary instead of failing loudly.
if _multiplex_on and not _platform_has_bot_credential(platform, platform_config):
logger.info(
"Skipping %s on default profile: no bot credential in this "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_platform_has_bot_credential() treats Matrix as token/api-key-only, but plugins/platforms/matrix/adapter.py:1255-1269 supports MATRIX_USER_ID + MATRIX_PASSWORD login. This guard skips a valid enabled Matrix adapter under multiplexing; use the platform's actual configured-credential contract instead.

Comment thread gateway/run.py
# Empty-token primary configs can never reconnect; drop them so
# multiplex setups where a secondary profile owns the bot do
# not spin forever (#64674).
if not _platform_has_bot_credential(platform, platform_config):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This queue removal is unconditional, so it changes reconnect behavior when multiplexing is off as well. Gate it to the multiplex primary-empty-credential case; otherwise the stated single-profile compatibility guarantee is not true.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 16, 2026
teknium1 added a commit that referenced this pull request Jul 16, 2026
…m map + unserved-platform warning

Follow-ups to @SAMBAS123's #64986 salvage:

- Replace the hardcoded token-platform set in _platform_has_bot_credential
  with PLATFORM_TOKEN_ENV_NAMES, a shared canonical map in gateway/config.py
  also used by the empty-token validation warning — one source of truth, so
  future token platforms can't silently bypass the gate or drift between
  the two sites.
- After secondary-profile startup, warn loudly for any platform skipped on
  the primary that no secondary profile ended up serving: an enabled
  platform with no credential anywhere is a config error, not a silent
  no-op.
- AUTHOR_MAP entry for the salvaged commit's author email.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #65525 — your commit was cherry-picked onto current main with your authorship preserved in git log (rebase merge). On top of it we replaced the hardcoded token-platform set with a canonical shared map (PLATFORM_TOKEN_ENV_NAMES in gateway/config.py) and added a loud warning when a skipped platform ends up served by no profile. Nice root-cause work on the scoped-load seam — thanks!

@teknium1 teknium1 closed this Jul 16, 2026
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…m map + unserved-platform warning

Follow-ups to @SAMBAS123's NousResearch#64986 salvage:

- Replace the hardcoded token-platform set in _platform_has_bot_credential
  with PLATFORM_TOKEN_ENV_NAMES, a shared canonical map in gateway/config.py
  also used by the empty-token validation warning — one source of truth, so
  future token platforms can't silently bypass the gate or drift between
  the two sites.
- After secondary-profile startup, warn loudly for any platform skipped on
  the primary that no secondary profile ended up serving: an enabled
  platform with no credential anywhere is a config error, not a silent
  no-op.
- AUTHOR_MAP entry for the salvaged commit's author email.
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…m map + unserved-platform warning

Follow-ups to @SAMBAS123's NousResearch#64986 salvage:

- Replace the hardcoded token-platform set in _platform_has_bot_credential
  with PLATFORM_TOKEN_ENV_NAMES, a shared canonical map in gateway/config.py
  also used by the empty-token validation warning — one source of truth, so
  future token platforms can't silently bypass the gate or drift between
  the two sites.
- After secondary-profile startup, warn loudly for any platform skipped on
  the primary that no secondary profile ended up serving: an enabled
  platform with no credential anywhere is a config error, not a silent
  no-op.
- AUTHOR_MAP entry for the salvaged commit's author email.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Telegram adapter fails to start on default-profile gateway when multiplex_profiles: true and bot token lives in a secondary profile .env

4 participants