refactor(gateway): extract GatewayMediaMixin from run.py (slice 22 of #54962) - #77751
Open
andrexibiza wants to merge 2 commits into
Open
refactor(gateway): extract GatewayMediaMixin from run.py (slice 22 of #54962)#77751andrexibiza wants to merge 2 commits into
andrexibiza wants to merge 2 commits into
Conversation
…ousResearch#54962) Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
andrexibiza
force-pushed
the
refactor/gateway-mixin-media
branch
from
August 3, 2026 14:30
88683e3 to
cde3c94
Compare
This was referenced Aug 4, 2026
Open
Open
Open
Open
Open
This was referenced Aug 5, 2026
Open
Open
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.
Related #54962 #55138
What
Extract the media-processing cluster out of
GatewayRunneringateway/run.py(26,823 → 25,798 lines) into a newgateway/media_mixin.pymodule —class GatewayMediaMixin— following the codebase's existing mixin pattern (gateway/authz_mixin.py,gateway/kanban_watchers.py,gateway/slash_commands.py).The 14 methods moved verbatim (zero behavior change):
_warn_if_docker_media_delivery_is_risky_prepare_inbound_message_text_prepare_profile_scoped_inbound_message_text_prepare_clarify_reply_text_consume_pending_native_image_paths_enrich_message_with_vision_enrich_message_with_transcription_pending_event_audio_paths_transcribe_pending_audio_event_once_echo_pending_stt_transcripts_once_transcribe_and_echo_pending_voice_should_echo_stt_transcripts_deliver_media_from_response_decide_image_input_modeGatewayRunnernow inheritsGatewayMediaMixinfirst:class GatewayRunner(GatewayMediaMixin, GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, GatewaySlashCommandsMixin). Allself.*call sites resolve unchanged via the MRO.Why
Phase 3 of the large-file decomposition campaign for #54962: mechanically lift cohesive method clusters out of the 26.8k-line
gateway/run.pyinto focused mixins, shrinking the god file without changing behavior.GatewayMediaMixinis the media cluster (gate 4 / tree 17 of the mixin wave).How the move stays behavior-neutral
from gateway.run import ...at call time — the exact patterngateway/slash_commands.pyalready uses for_load_gateway_config,_profile_runtime_scope, etc.):_event_media_is_*,_build_document_context_note,_load_gateway_config,_probe_audio_duration,_profile_runtime_scope,_DOCKER_VOLUME_SPEC_RE,_DOCKER_MEDIA_OUTPUT_CONTAINER_PATHS. This keeps the module free of any import-timegateway.runback-reference (no import cycle)._UNSETmoves with the cluster and is re-exported: it is used as a default argument (metadata=_UNSET) in_transcribe_and_echo_pending_voice, so it must resolve at class-definition time in the new module.gateway/run.pyre-exports it (from gateway.media_mixin import GatewayMediaMixin, _UNSET # noqa: F401), sogateway.run._UNSETstays the same object (verified: r._UNSET is mm._UNSET).logger = logging.getLogger("gateway.run")keeps log records' provenance identical.vision_analyze_tool,transcribe_audio,to_agent_visible_cache_path,decide_image_input_mode,BasePlatformAdapter, etc.) moved with them untouched.How to test
python -c "import gateway.run; assert hasattr(gateway.run.GatewayRunner, '_prepare_inbound_message_text')" python -m pytest tests/agent/test_image_routing.py tests/gateway/test_73771_media_resend_dedup.py \ tests/gateway/test_busy_session_ack.py tests/gateway/test_context_ref_expansion_runtime.py \ tests/gateway/test_discord_channel_prompts.py tests/gateway/test_fast_command.py \ tests/gateway/test_image_input_routing_runtime.py tests/gateway/test_native_image_buffer_isolation.py \ tests/gateway/test_post_stream_media_delivery.py tests/gateway/test_queued_native_image_session_key.py \ tests/gateway/test_reply_to_injection.py tests/gateway/test_session.py \ tests/gateway/test_shared_group_sender_prefix.py tests/gateway/test_streaming_tts_gateway_regression.py \ tests/gateway/test_stt_config.py tests/gateway/test_telegram_audio_vs_voice.py \ tests/gateway/test_telegram_voice_v0_regressions.py tests/gateway/test_tts_media_routing.py \ tests/gateway/test_video_context_note.py tests/gateway/test_vision_memory_leak.py \ tests/gateway/test_weixin.py tests/gateway/test_media_extraction.py tests/gateway/test_audio_cache.py \ tests/gateway/test_media_cache.py tests/gateway/test_media_download_retry.py \ tests/gateway/test_media_spaced_paths_and_history_dedupe.py tests/gateway/test_media_tag_cleanup.py \ tests/gateway/test_media_tag_formatting_variants.py tests/gateway/test_media_tag_separator.py \ tests/gateway/test_media_metadata_contract.py tests/gateway/test_history_media_current_turn.py -qPlatforms tested
test_image_routing.py::TestExtractImageRefs::test_finds_absolute_path,...test_finds_home_relative_path,test_73771_media_resend_dedup.py::test_streamed_explicit_media_resend_is_delivered,test_post_stream_media_delivery.py::test_explicit_media_tag_still_delivers_post_stream,test_media_spaced_paths_and_history_dedupe.py::TestHistoryMediaDedupe::test_quoted_spaced_home_path_is_collected_in_delivery_form) are pre-existing on pristinemain— stash-proven identical without this change (Windows path-vs-file://URL-encoding env issue, unrelated to the move).git diff --checkclean;scripts/check-windows-footguns.pyclean on both files.Shrink
gateway/run.py: 26,823 → 25,798 lines (net −1,025: 1,027 deleted − 2 added import/bases lines)gateway/media_mixin.py: new, 1,077 lines (14 methods, ~1,007 body lines + header/imports/logger/_UNSET)Scope note
This is a pure mechanical lift — no logic changes, no signature changes, no reordering of behavior. The moved methods are verified byte-identical to their originals modulo the documented lazy imports. Follow-up slices (voice, threads, platform, etc.) continue the campaign from the remaining
GatewayRunnerclusters.Part of #54962
Part of #55138
Part of #78207
Part of #78647
Part of #78791