fix(deps): pin brotlicffi so aiohttp can decode Discord's Brotli attachments

Discord's CDN serves attachments with Content-Encoding: br. aiohttp's
compression_utils tries 'import brotlicffi as brotli' first and falls back
to google's Brotli, but Brotli<1.2.0's Decompressor.process() is 1-arg
while aiohttp calls it with 2 args (data, max_length). Result: every
.txt/.md/.doc uploaded to a Discord-gateway session fails to decode at
att.read() with 'Can not decode content-encoding: br' / 'TypeError:
process() takes exactly 1 argument (2 given)', the agent never sees the
bytes, and falls back to filesystem guessing.

Pin brotlicffi==1.2.0.1 in both surfaces:

  - tools/lazy_deps.py 'platform.discord' tuple: Discord users on the
    lazy-install path get it on first discord.py import.
  - pyproject.toml [messaging] extra: users who explicitly install
    hermes-agent[messaging] (skipping the lazy path) get it eagerly.

brotlicffi wins aiohttp's import race regardless of what else is
installed (try brotlicffi / except: import brotli), so existing setups
that already pulled google's Brotli transitively don't change behavior
beyond the bug fix. ~1.5 MB wheel, manylinux/macOS/Windows coverage.

E2E verified: round-trip decode of Brotli-compressed payload via
aiohttp.compression_utils.brotli succeeds with brotlicffi pinned; same
test against Brotli==1.1.0 alone reproduces the reported TypeError.

Credit to @Korkyzer for the original diagnosis and fix shape in #15744;
the lazy-deps gating layer was added on top to keep brotlicffi out of
the install path for users who don't run a Discord gateway.

Fixes #12511.
Closes #15744.

Co-authored-by: Korky <korkyzer@gmail.com>
This commit is contained in:
teknium1 2026-05-14 22:30:12 -07:00 committed by Teknium
parent c8c6ce1731
commit bcca5ed34d
4 changed files with 35 additions and 2 deletions

View file

@ -116,7 +116,12 @@ LAZY_DEPS: dict[str, tuple[str, ...]] = {
# ─── Messaging platforms (lazy-installable on demand) ──────────────────
"platform.telegram": ("python-telegram-bot[webhooks]==22.6",),
"platform.discord": ("discord.py[voice]==2.7.1",),
# brotlicffi gives aiohttp a working 2-arg Decompressor.process() for
# Discord CDN's Brotli-encoded attachments. Without it, aiohttp falls
# back to google's `Brotli` package (1-arg API), and any .txt/.md/.doc
# uploaded to the Discord gateway fails to decode at att.read() with
# "Can not decode content-encoding: br" — see #12511 / #15744.
"platform.discord": ("discord.py[voice]==2.7.1", "brotlicffi==1.2.0.1"),
"platform.slack": (
"slack-bolt==1.27.0",
"slack-sdk==3.40.1",