fix(gateway): multiplex primary bot tokens without empty reconnect loops (#64674) - #64986
fix(gateway): multiplex primary bot tokens without empty reconnect loops (#64674)#64986SAMBAS123 wants to merge 1 commit into
Conversation
…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.
tonydwb
left a comment
There was a problem hiding this comment.
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
|
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
left a comment
There was a problem hiding this comment.
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:7222treats Matrix as token/api-key-only. Matrix supports password login atplugins/platforms/matrix/adapter.py:1255-1269; a valid multiplexed Matrix password configuration would now be skipped. - The reconnect deletion at
gateway/run.py:8069is not gated onmultiplex_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.
| # 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 " |
There was a problem hiding this comment.
_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.
| # 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): |
There was a problem hiding this comment.
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.
…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.
|
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 ( |
…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.
…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.
Summary
Fixes #64674.
When
gateway.multiplex_profiles: trueand a bot token (e.g.TELEGRAM_BOT_TOKEN) lives only under a profile.env, the default-profile gateway used to:load_gateway_config()unscoped atGatewayRunner.__init__os.environ(often empty once secrets moved out of the default.env)No bot token configuredSecondary profiles already load under
_profile_runtime_scopeand 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.tests/gateway/test_64674_multiplex_primary_token_scope.py(8 passed).Why this is backward-compatible
multiplex_profiles→ no behavior change.GatewayRunner(config=...)injection (tests) is untouched.os.environ(preserves multiplex credential isolation / Workstream A).Tests
pytest tests/gateway/test_64674_multiplex_primary_token_scope.py -q # 8 passedRelated