Skip to content

fix(gateway): respect profile-scoped adapters in multiplex response delivery - #52225

Closed
franklinbravos wants to merge 1 commit into
NousResearch:mainfrom
franklinbravos:fix/multiplex-adapter-routing
Closed

fix(gateway): respect profile-scoped adapters in multiplex response delivery#52225
franklinbravos wants to merge 1 commit into
NousResearch:mainfrom
franklinbravos:fix/multiplex-adapter-routing

Conversation

@franklinbravos

Copy link
Copy Markdown

Summary

In multiplex mode (gateway.multiplex_profiles: true), each profile has its own platform adapters stored in _profile_adapters[profile_name][platform]. However, ~12 call sites in the response delivery path only consulted self.adapters (the default profile's adapters), causing responses to always be sent through the default profile's bot regardless of which profile's adapter received the original message.

Changes

gateway/config.py

  • Updated _get_env() to use per-profile secret scope instead of process-global os.environ in multiplex mode, preventing cross-profile token leaks.
  • Propagated multiplex_profiles when set under the gateway: key in config.yaml.
  • Replaced bare os.getenv() calls with _e() for profile-scoped resolution.

gateway/run.py

Patched all self.adapters.get(source.platform) call sites in the response delivery path to first check self._profile_adapters[source.profile] when a profile is set. This covers proxy mode (stream consumer, typing indicator, goal status notice) and local agent (stream consumer, status adapter, progress callback, cleanup, typing stop, stale result, pairing responses).

The fallback to self.adapters preserves existing single-profile behavior with zero overhead.

Testing

Tested with 5 profiles (default, elias, iago, matias, sofia) each with distinct Telegram bot tokens. Verified that messages to a secondary profile's bot are now correctly delivered through that profile's bot instead of the default.

…elivery

In multiplex mode (gateway.multiplex_profiles: true), each profile has its
own platform adapters stored in `_profile_adapters[profile_name][platform]`.
However, ~20 call sites in the response delivery path only consulted
`self.adapters` (the default profile's adapters), causing responses to
always be sent through the default profile's bot/credentials regardless of
which profile's adapter received the original message.

Fixes include:

gateway/config.py:
- Ensure `_get_env()` uses the per-profile secret scope instead of
  process-global `os.environ` in multiplex mode, preventing token leaks
  across profiles that caused exclusive_bot_mentions to break.
- Also propagate `multiplex_profiles` when set under the `gateway:` key
  in config.yaml (not just top-level).
- Replace bare `os.getenv()` calls with `_e()` so they pick up profile
  secrets during secondary profile startup.

gateway/run.py — stream/delivery path (12 sites):
- `_run_agent_via_proxy` (proxy mode): stream consumer adapter, typing
  indicator, and goal status notice.
- `_run_agent_inner` (local agent): stream consumer adapter, status
  adapter, progress callback adapter, cleanup adapter, typing stop,
  stale result cleanup, and pairing response adapters.
- `_handle_message`: pairng code and rate-limit response adapters.

The fix pattern at each site is the same:

    # Before — always uses default profile's adapter:
    adapter = self.adapters.get(source.platform)

    # After — uses the source's profile adapter when available:
    _profile_name = getattr(source, "profile", None)
    _profile_adapter = (
        self._profile_adapters.get(_profile_name, {}).get(source.platform) if _profile_name else None
    )
    adapter = _profile_adapter or self.adapters.get(source.platform)

When multiplex is off, `_profile_adapters` is empty and `source.profile`
is unset, so the fallback to `self.adapters` preserves existing
single-profile behavior with zero overhead.
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists 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 labels Jun 25, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for identifying the multiplex response-routing issue. This is an automated hermes-sweeper review; the requested behavior is already on current main through a broader merged salvage.

@teknium1 teknium1 closed this Jul 15, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 15, 2026
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 sweeper:implemented-on-main Sweeper: behavior already present on current main 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.

3 participants