Skip to content

refactor(gateway): extract GatewayPlatformMixin from run.py (slice 25 of #54962) - #77759

Open
andrexibiza wants to merge 2 commits into
NousResearch:mainfrom
andrexibiza:refactor/gateway-mixin-platform
Open

refactor(gateway): extract GatewayPlatformMixin from run.py (slice 25 of #54962)#77759
andrexibiza wants to merge 2 commits into
NousResearch:mainfrom
andrexibiza:refactor/gateway-mixin-platform

Conversation

@andrexibiza

@andrexibiza andrexibiza commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Related #54962 #55138

What

Extract the platform-adapter lifecycle cluster out of GatewayRunner in gateway/run.py (26.8k-line god file) into a new gateway/platform_mixin.py module as GatewayPlatformMixin — 34 methods / ~1,668 LOC moved byte-verbatim (zero behavior change).

This is slice 25 of the large-file decomposition campaign (Wave 3, mixin lifts), following the codebase's established mixin pattern (gateway/authz_mixin.py, gateway/kanban_watchers.py, gateway/slash_commands.py).

What moved — the adapter lifecycle cluster:

  • connect/disconnect/teardown timeouts (_await_adapter_cleanup_with_timeout, _safe_adapter_disconnect, _bounded_adapter_teardown, _adapter_disconnect_timeout_secs, _platform_connect_timeout_secs, _connect_adapter_with_timeout, _connect_initial_adapter_with_timeout)
  • fatal-error handling (_handle_adapter_fatal_error*)
  • reconnect watcher + secondary-profile (multiplex) startup (_platform_reconnect_watcher, _start_secondary_profile_adapters, _start_one_profile_adapters, _configure_profile_adapter, _run_secondary_profile_reconnect, _schedule_secondary_profile_reconnect, ...)
  • adapter credential/listener claim conflict detection (_adapter_credential_claim, _adapter_listener_claim, _adapter_credential_fingerprint)
  • handoff watcher (_handoff_watcher, _process_handoff), profile-name resolution, systemd watchdog, auth-check factory

Why

gateway/run.py is a ~26.8k-line god file. GatewayRunner is the largest class; the platform-adapter cluster is a cohesive, self-contained concern (only self.* + neutral helpers) that lifts cleanly into a mixin, exactly like the three existing ones. GatewayRunner now reads GatewayPlatformMixin first in its bases.

How

  • New module gateway/platform_mixin.py: class GatewayPlatformMixin with the 34 methods moved verbatim (docstrings, comments, and bodies byte-identical to the pre-move source).
  • gateway/run.py: methods deleted from the class body; GatewayPlatformMixin added FIRST in GatewayRunner's bases; module-attribute import added to the from gateway.* block.
  • Zero behavior change: self.* calls resolve unchanged via the MRO. Neutral dependencies import at module top. Helpers that stay in run.py (_profile_runtime_scope, _reconnect_backoff, _dispose_unused_adapter, _platform_has_bot_credential, _own_policy_open_startup_violation, MultiplexConfigError, SecondaryPortBindingConfigError, the timeout defaults, get_hermes_home, GatewayRunner itself for a staticmethod self-reference) are imported lazily inside the using method (from gateway.run import ... at call time) — the sibling-mixin pattern that avoids the import cycle. The module-level logger = logging.getLogger("gateway.run") preserves the original logger name so log records are unchanged.
  • @staticmethod decorators preserved on _adapter_credential_claim / _adapter_listener_claim / _adapter_credential_fingerprint.
  • The "Kanban board watchers" section comment (a class-body marker for the already-extracted kanban mixin) stays in run.py.

How to test

# Import smoke (mixin FIRST in MRO, methods resolve through it):
python -c "import gateway.run; assert hasattr(gateway.run.GatewayRunner, '_await_adapter_cleanup_with_timeout'); assert hasattr(gateway.run.GatewayRunner, '_create_adapter'); assert hasattr(gateway.run.GatewayRunner, '_profile_name_for_source')"

# Targeted suites (all green on this change):
python -m pytest tests/gateway/test_bounded_adapter_teardown.py tests/gateway/test_safe_adapter_disconnect.py tests/gateway/test_platform_reconnect.py tests/gateway/test_platform_reconnect_fd_leak.py tests/gateway/test_runner_fatal_adapter.py tests/gateway/test_systemd_watchdog_lifecycle.py -q --no-header -p no:cacheprovider
python -m pytest tests/gateway/test_64674_multiplex_primary_token_scope.py tests/gateway/test_multiplex_adapter_registry.py tests/gateway/test_multiplex_pairing_stores.py tests/gateway/test_multiplex_phase0.py tests/gateway/test_multiplex_profile_authz.py tests/gateway/test_handoff_watcher_async_db.py tests/gateway/test_handoff_thread_session_key.py tests/gateway/test_profile_resolution.py tests/gateway/test_platform_registry.py -q --no-header -p no:cacheprovider
python -m pytest tests/gateway/test_runner_startup_failures.py tests/gateway/test_startup_restart_race.py tests/gateway/test_telegram_network_reconnect.py tests/gateway/test_own_policy_startup_gate.py tests/gateway/test_75349_whatsapp_multiplex_secret_scope.py tests/gateway/test_api_server_multiplex_secret_scope.py tests/gateway/test_multiplex_credential_isolation.py tests/gateway/test_multiplex_lifecycle.py tests/gateway/test_multiplex_background_task_scope.py tests/gateway/test_multiplex_http_routing.py tests/gateway/test_multiplex_api_server_routing.py -q --no-header -p no:cacheprovider
python -m pytest tests/gateway/test_shutdown_cache_cleanup.py tests/gateway/test_qqbot_scope_paths.py tests/gateway/test_adapter_connect_is_reconnect_contract.py tests/gateway/test_adapter_startup_secret_scope.py tests/gateway/relay/test_handoff_relay_aliasing.py tests/gateway/test_kanban_notifier.py tests/gateway/test_telegram_topic_mode.py tests/gateway/test_loop_liveness_watchdog.py tests/gateway/test_startup_no_eager_platform_install.py tests/gateway/test_slack_socket_reconnect_heal.py -q --no-header -p no:cacheprovider

Test results (this PR): 32 + 67 + 46 + 121 + 132 passed = 398 passed, 1 xfailed, 0 failures across the moved-method suites. One unrelated pre-existing failure (test_api_server.py::TestHealthDetailedEndpoint::test_health_detailed_returns_ok) reproduces identically on pristine main (stash-proven) and is not touched by this change. git diff --check clean; check-windows-footguns.py clean on both changed files.

Shrink

  • gateway/run.py: 26,823 → 25,205 lines (−1,618)
  • New gateway/platform_mixin.py: 1,735 lines (34 methods)

Scope note

Pure mechanical move — no logic touched, no signatures changed. Byte-verbatim verified per-method against the pre-move source (the only inserted lines are the lazy from gateway.run import ... statements inside the 9 methods that reference run.py-local helpers, matching the sibling-mixin pattern). The full suite carries ~250 pre-existing environment failures unrelated to this change; only targeted suites were run here.

Part of #54962
Part of #55138

Part of #78207
Part of #78647
Part of #78791

… of NousResearch#54962)

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
@alt-glitch alt-glitch added type/refactor Code restructuring, no behavior change P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Aug 3, 2026
This was referenced Aug 4, 2026
This was referenced Aug 5, 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 P3 Low — cosmetic, nice to have sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants