fix(gateway): honor nested gateway.multiplex_profiles in load_gateway_config (#51372 salvage) - #59320
Merged
Merged
Conversation
This was referenced Jul 6, 2026
load_gateway_config() only surfaced the top-level `multiplex_profiles` key into gw_data before calling GatewayConfig.from_dict(). A config.yaml that pinned the flag under the nested `gateway:` section -- the form written by `hermes config set gateway.multiplex_profiles true` -- was silently ignored, so the gateway loaded with multiplex_profiles=False. from_dict() already honors the nested fallback, but load_gateway_config() builds gw_data from top-level keys first, so the nested value never reached it. Read gateway.multiplex_profiles into gw_data when the top-level key is absent, mirroring the existing nested fallback for max_concurrent_sessions. Adds a load_gateway_config() regression test that writes a config.yaml with `gateway.multiplex_profiles: true` and asserts the loaded config has multiplex_profiles=True (fails without the fix). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
teknium1
force-pushed
the
salvage/51372-nested-multiplex-key
branch
from
July 6, 2026 05:02
12fcc8f to
56d1385
Compare
4 tasks
5 tasks
teknium1
pushed a commit
that referenced
this pull request
Jul 20, 2026
load_gateway_config() already accepted both the top-level key and the nested gateway.<key> form (written by `hermes config set gateway.<key> ...`) for multiplex_profiles, max_concurrent_sessions, streaming, and write_sessions_json — each fixed one at a time as users hit it (most recently #59320 for multiplex_profiles). Nine sibling top-level keys never got the same nested fallback: session_reset, quick_commands, stt, stt_echo_transcripts, group_sessions_per_user, thread_sessions_per_user, reset_triggers, always_log_local, and unauthorized_dm_behavior. `hermes config set gateway.<any-of-these> ...` builds exactly this nested shape (hermes_cli/config.py's _set_nested has no schema, so it accepts any dotted path), so a user following the same pattern that legitimately works for gateway.multiplex_profiles/gateway.streaming gets a silent no-op for these nine keys instead. Fix: read `gateway: {...}` into a single `gateway_section` variable once (consolidating three separate `yaml_cfg.get("gateway")` calls already in the function) and add the same top-level-wins/nested-fallback check for each of the nine keys, mirroring the existing write_sessions_json precedent exactly. Note: because every fallback here is guarded by `isinstance(gateway_section, dict)`, this also makes the streaming fallback tolerate a scalar `gateway:` block (e.g. `gateway: disabled`) without crashing — the same crash #40837 (open) targets specifically for streaming. This change doesn't set out to fix that PR's issue, but the consolidated guard covers it as a side effect; flagging it for the reviewer rather than leaving it to be found in review.
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
load_gateway_config() already accepted both the top-level key and the nested gateway.<key> form (written by `hermes config set gateway.<key> ...`) for multiplex_profiles, max_concurrent_sessions, streaming, and write_sessions_json — each fixed one at a time as users hit it (most recently NousResearch#59320 for multiplex_profiles). Nine sibling top-level keys never got the same nested fallback: session_reset, quick_commands, stt, stt_echo_transcripts, group_sessions_per_user, thread_sessions_per_user, reset_triggers, always_log_local, and unauthorized_dm_behavior. `hermes config set gateway.<any-of-these> ...` builds exactly this nested shape (hermes_cli/config.py's _set_nested has no schema, so it accepts any dotted path), so a user following the same pattern that legitimately works for gateway.multiplex_profiles/gateway.streaming gets a silent no-op for these nine keys instead. Fix: read `gateway: {...}` into a single `gateway_section` variable once (consolidating three separate `yaml_cfg.get("gateway")` calls already in the function) and add the same top-level-wins/nested-fallback check for each of the nine keys, mirroring the existing write_sessions_json precedent exactly. Note: because every fallback here is guarded by `isinstance(gateway_section, dict)`, this also makes the streaming fallback tolerate a scalar `gateway:` block (e.g. `gateway: disabled`) without crashing — the same crash NousResearch#40837 (open) targets specifically for streaming. This change doesn't set out to fix that PR's issue, but the consolidated guard covers it as a side effect; flagging it for the reviewer rather than leaving it to be found in review.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
gateway.multiplex_profiles: truein config.yaml — the exact form written byhermes config set gateway.multiplex_profiles true— now actually enables multiplexing; previouslyload_gateway_config()only surfaced the top-level key, so the documented path silently loadedmultiplex_profiles=False.Salvages #51372 by @davidgut1982 (clean cherry-pick, authorship preserved).
Root cause:
from_dict()honors the nested fallback, butload_gateway_config()buildsgw_dataas a synthesized dict from top-level keys, so the nestedgateway:section never reached it. Mirrors the existing nested handling formax_concurrent_sessions/streaming.Changes
gateway/config.py: readgateway.multiplex_profilesintogw_datawhen the top-level key is absenttests/gateway/test_config.py: regression test (fails without the fix)Validation
gateway:\n multiplex_profiles: trueThird PR in the multiplex isolation cluster (#59310, #59315). The empirical premise check was re-verified today:
from_dictresolves the nested form, the loader does not.Infographic