Skip to content

refactor(telegram): shard adapter.py wave 1 — polling, inbound, delivery, rich mixins (−6,014 lines) - #78866

Closed
andrexibiza wants to merge 6 commits into
NousResearch:mainfrom
andrexibiza:fix/tg-adapter-shard-wave1
Closed

andrexibiza wants to merge 6 commits into
NousResearch:mainfrom
andrexibiza:fix/tg-adapter-shard-wave1

Conversation

@andrexibiza

Copy link
Copy Markdown
Contributor

Summary

First slice wave of the Telegram adapter god-file decomposition
(plugins/platforms/telegram/adapter.py, 10,147 lines at base be55e99cbc).
Pure extraction — zero behavior change — of the four most entangled clusters
into focused mixin modules, following the landed TelegramAuthorizationMixin
(#75742) / SessionTelegramTopicsMixin (#75747) pattern:

Module Cluster adapter.py net delta
telegram_polling.py (1,311 ln) updates transport / polling / webhook −1,241
telegram_inbound.py (1,352 ln) inbound ingest, batching, media cache, event building −1,275
telegram_messaging.py (1,043 ln) outbound text delivery (send/edit/delete/draft) −1,000
telegram_rich.py (635 ln) rich message delivery + capability latches −572

adapter.py 10,147 → ~4,133 lines (−6,014). Each module is imported back
into adapter.py as a module attribute (existing callers/tests stay green) and
the adapter class inherits all four mixins.

Why this wave

Operator policy: all god-files are to be sharded — model first, agree on
the graph, then slice; one PR per cluster, suite green. The decomposition plan
(three-wave blind analysis, 5 domains × 2 witnesses + validation) is the agreed
graph. This wave targeted the gnarliest clusters first (largest, most
entangled, highest regression risk) so the pattern is proven where it is
hardest. Subsequent waves take the remaining clusters (formatting, reactions,
media send/ingest, drafts, controls, notifications) with the same gates.

Verification

  • Per-slice AST-fidelity (blind verifier, C:/tmp/wt-tg-verify/fidelity-report.md):
    inbound 26/26, delivery 12/12 (shim-adjusted), rich 19/19, polling verified
    in-slice with the same gates — every moved function ast.dump-identical to
    the monolith (modulo the documented function-local lazy-import shims).
  • Orphan scans: zero undefined Load names left in adapter.py per slice.
  • Monkeypatch-surface fix (one commit, 6012fd5e5d): the inbound mixin
    called cache_image_from_bytes via its own module global; the gateway suite
    monkeypatches plugins.platforms.telegram.adapter.cache_image_from_bytes
    (media-group batching), so the patch missed and photo-burst buffering broke
    (test_non_album_photo_burst_is_buffered_and_combined). Function-local lazy
    imports route resolution through the adapter namespace — the same shim
    pattern the delivery/rich slices use. Caught by the full-suite run, fixed,
    and regression-locked by that test.
  • Suite: 59 Telegram test files on the integrated branch — 601 passed,
    0 failed
    (isolated basetemp; Windows host). ruff + git diff --check clean
    per slice; DCO sign-off on every commit.
  • Net-shrink verified per slice from git diff numstat.

Scope honesty

Wave 1 of the adapter decomposition — the four hardest clusters. Remaining
adapter.py surface (formatting, reactions, media send/ingest, drafts, controls,
notifications, callback/picker machinery, gateway bindings) ships in follow-up
waves, each its own PR with the same evidence shape.

Links

…amIngestMixin (adapter god-file slice)

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
…eliveryMixin (adapter god-file slice)

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>

# Conflicts:
#	plugins/platforms/telegram/adapter.py
…xin (adapter god-file slice)

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>

# Conflicts:
#	plugins/platforms/telegram/adapter.py
…llingMixin (adapter god-file slice)

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>

# Conflicts:
#	plugins/platforms/telegram/adapter.py
… mixin

The webhook-start block (and its GHSA-3vpc-7q5r-276h secret guard) moved
from TelegramAdapter.connect() into TelegramPollingMixin._start_webhook
during the adapter god-file slice. The source-level pin now scans both
adapter.py and telegram_polling.py so the invariant survives either
layout, and the polling-branch check anchors on the new
``if not webhook_started:`` dispatch instead of the old else-branch.

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
The inbound mixin called the media cache via its own module global; the
gateway test suite monkeypatches plugins.platforms.telegram.adapter.
cache_image_from_bytes (media-group batching), so the patch missed and the
real guard rejected the fake payloads, breaking photo-burst buffering.
Function-local lazy imports route resolution through the adapter module,
matching the landed slices' shim pattern.

Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
@andrexibiza

Copy link
Copy Markdown
Contributor Author

Superseded by #79010 (adapter god-file decomposition, wave 2 consolidation). #79010's diff against main includes BOTH wave-1 (polling/inbound/delivery/rich) and wave-2 (dm-topics/lifecycle/interactive/media/config-mention/reactions) mixins — the complete 10,147 → 1,390 line decomposition in one PR. Closing this standalone to keep ONE PR per class (CCC doctrine). No work lost: every wave-1 commit is in #79010's history.

@andrexibiza

Copy link
Copy Markdown
Contributor Author

Superseded by consolidated #79010. See epic #78791.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have platform/telegram Telegram bot adapter type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants