fix(gateway): slash config writes, executor hops, personality and status follow the routed profile (#87939 #75684 #89161, salvage #87976 #78440 #69118) - #101246
Merged
Conversation
૮ >ﻌ< ა ci reviewran on 9011fe3 — chore: retrigger CI (zero-job dispatch failure, auto-heal)
|
teknium1
force-pushed
the
salvage/mux-slash-scope
branch
4 times, most recently
from
September 2, 2026 13:09
07460ad to
1e8d2fb
Compare
… profile
The multiplexed inbound handler wraps every message in _profile_runtime_scope,
which installs the routed profile's HERMES_HOME override and its secret scope
as contextvars. A bare loop.run_in_executor(None, fn) starts the worker with an
EMPTY context, so neither reaches the blocking work.
GatewaySlashCommandsMixin already knows this -- /compress goes through
_run_in_executor_with_context and the call site says why. Three siblings in the
same file still used the bare hop:
/insights SessionDB() with no explicit path resolves get_hermes_home() at
call time (_default_db_path), so the worker opened the DEFAULT
profile's state.db. Under multiplexing the command reported
another profile's conversations, session counts and sources to
this profile's user.
/debug collects that home's logs/config and uploads them to a public
paste, so it published the default profile's diagnostics from
another profile's chat.
/goal draft calls the auxiliary LLM, whose provider/credential resolution
reads the profile secret scope -- unscoped it falls back to
process-global os.environ, which under multiplexing may hold a
different profile's keys.
Route all three through _run_in_executor_with_context.
/reload-skills is deliberately left alone: tools.skills_tool binds SKILLS_DIR
at import time, so it does not follow the contextvar either way. Fixing that
needs the module-global retarget web_server._profile_scope performs under a
lock, which is a different change from context propagation.
Single-profile gateways never enter the scope, so their behaviour is unchanged.
…the scoped helper Sibling sites of the bare loop.run_in_executor(None, …) class fixed for /insights, /debug and /goal draft: the worker started with an empty context, so get_hermes_home()-relative reads (skills.external_dirs, disabled skills, the reviewer subagent's home and secret scope) resolved the launch home instead of the routed profile under multiplex.
…file Slash dispatch already runs inside _profile_runtime_scope under multiplex, but _save_gateway_config_key (/reasoning --global, /fast, show/hide), /memory approval, /skills approval, /verbose and /footer built their write path from the module constant gateway.run._hermes_home — the launch home — so a routed profile's toggles landed in the default profile's config.yaml while the reads (via _gateway_config_home()) saw the routed one. Resolve the write path through _gateway_config_home() at all five sites so reads and writes agree. Single-profile gateways never install the override and keep resolving the launch home. Fixes #87939 Fixes #75684 Co-authored-by: Bao <nnqbao@gmail.com>
…the scoped profile GatewayRunner.__init__ snapshotted _ephemeral_system_prompt once from the launch profile's config and _get_system_prompt_for_channel returned that string for every source, so under multiplex a routed profile's display.personality / agent.system_prompt never injected (#89161), and /personality from any chat rewrote the one process-global attribute for everyone. Drop the snapshot: _get_system_prompt_for_channel now calls _load_ephemeral_system_prompt() (env var, then resolve_ephemeral_system_prompt_from_config(_load_gateway_runtime_config())) on each call. Its caller run_sync already runs inside _profile_runtime_scope, so the routed profile's config.yaml is what gets read; single-profile hot-edits of the personality also take effect on the next turn instead of requiring a restart. /personality only persists via persist_personality() (get_hermes_home()/config.yaml = the routed profile) and no longer touches in-memory state. Fixes #89161 Co-authored-by: worlldz <101180447+worlldz@users.noreply.github.com>
…xer serves it `hermes gateway status`, `hermes gateway list`, `hermes profile list/show` and the dashboard profiles payload keyed liveness off the profile's own gateway.pid / gateway_state.json, so a satellite profile served by the default multiplexer (gateway.multiplex_profiles) showed "not running" even though the multiplexer is its live inbound process. Reuse the single lookup the start guard and cron liveness already share — named_profile_served_by_running_multiplexer() — with an optional profile_name so list surfaces can ask about any profile, and OR it into gateway_running for named profiles. Default profile and unserved named profiles are unchanged. Salvage of #69118 rebased onto the shared helper (which post-dates it). Co-authored-by: Isaac Dobson <isaac@dobsonheadlights.com> Co-authored-by: Mushisushi28 <133449918+Mushisushi28@users.noreply.github.com>
teknium1
force-pushed
the
salvage/mux-slash-scope
branch
from
September 2, 2026 13:19
1e8d2fb to
39d5492
Compare
This was referenced Sep 2, 2026
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
Under
gateway.multiplex_profiles, slash dispatch already runs inside_profile_runtime_scope(9ab748a), but four residual paths still resolved the launch profile: handlers building write paths from the module constant_hermes_home, bareloop.run_in_executor(None, …)hops that drop the contextvar, a boot-time_ephemeral_system_promptsnapshot handed to every routed turn, and PID-only liveness that reported served named profiles as stopped.Changes
_save_gateway_config_key(/reasoning, /fast, show/hide), /memory, /skills, /verbose, /footer write via_gateway_config_home()(reads already did)._run_in_executor_with_context._get_system_prompt_for_channelresolvesdisplay.personality/agent.system_promptper turn from the scoped profile's config;/personalityonly persists (routed profile), no process-global state.named_profile_served_by_running_multiplexer(profile_name=None)reused bygateway status/list,profile list/show, dashboard profiles payload.Validation
_save_gateway_config_key//memory approval onin routed scope/insights,/reload-skillsworkerget_hermes_home()DEFAULT-PERSONA;/personalityfrom routed chat changed default's turn tooBETA-PERSONA; after/personality pirate: routedARR, defaultDEFAULT-PERSONAgateway list/gateway status/list_profilesfor served profileCredits
@StanleyStetson (#87976, commit author) · @kingrubic (#75729) · @Drexuxux (#78440, cherry-picked) · @worlldz (#89177) · @Mushisushi28 (#69118) · reporters @kh-mitya #87939, @jimzord12 #75684, @pipidaxian #89161
Fixes #87939
Fixes #75684
Fixes #89161
Infographic