hermes-agent/gateway/platforms
teknium1 762eb79f1e fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451)
Two mitigations for the CLOSE_WAIT accumulation reported against QQ Bot
+ Feishu on macOS behind Cloudflare Warp.

1. Shared httpx.Limits helper (gateway/platforms/_http_client_limits.py).
   Every long-lived platform adapter now constructs httpx.AsyncClient
   with max_keepalive_connections=10 and keepalive_expiry=2.0, vs httpx's
   default of unbounded keepalive pool and 5.0s expiry. On macOS/Warp the
   default 5s window let idle keepalive sockets sit in CLOSE_WAIT long
   enough for seven persistent adapters (QQ Bot, WeCom, DingTalk, Signal,
   BlueBubbles, WeCom-callback, plus the transient Feishu helper) to
   compound to the 256-fd ulimit. Tunable via
   HERMES_GATEWAY_HTTPX_KEEPALIVE_EXPIRY and
   HERMES_GATEWAY_HTTPX_MAX_KEEPALIVE env vars.

2. whatsapp.send_typing aiohttp leak. The call was
   'await self._http_session.post(...)' with no 'async with' and no
   variable capture — the ClientResponse went out of scope unclosed,
   holding its TCP socket in CLOSE_WAIT until GC. Fixed by wrapping in
   'async with'. This was the only bare-await aiohttp leak in the
   gateway/tools/plugins tree per audit; all other aiohttp sites use
   the context-manager pattern correctly.

The underlying reporter also saw Feishu SDK (lark-oapi) connections in
CLOSE_WAIT — those are inside the SDK and out of our direct control, but
tightening httpx keepalive across adapters reduces the aggregate pool
pressure regardless of which individual adapter leaks.
2026-05-02 02:23:37 -07:00
..
qqbot fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
__init__.py yuanbao platform (#16298) 2026-04-26 18:50:49 -07:00
_http_client_limits.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
ADDING_A_PLATFORM.md feat: final platform plugin parity — webhook delivery, platform hints, docs 2026-04-29 21:56:51 -07:00
api_server.py fix(api-server): use session-scoped task IDs for tool isolation 2026-04-30 19:59:38 -07:00
base.py feat(gateway): private notice delivery and Slack format_message fixes 2026-05-01 13:33:06 -07:00
bluebubbles.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
dingtalk.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
discord.py fix(discord): close old client before reconnect to prevent zombie websockets (#18187) 2026-05-02 02:04:14 -07:00
email.py feat(gateway): native send_multiple_images for Telegram, Discord, Slack, Mattermost, Email 2026-04-30 04:28:08 -07:00
feishu.py fix(feishu): finalize remote document downloads inside httpx.AsyncClient context (#18502) 2026-05-02 02:23:37 -07:00
feishu_comment.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
feishu_comment_rules.py fix(feishu-comment): use get_hermes_home(); drop dead asyncio wrapper; AUTHOR_MAP 2026-04-17 19:04:11 -07:00
helpers.py fix(gateway): atomic writes for sibling recovery/dedup state files 2026-04-30 19:58:16 -07:00
homeassistant.py fix(gateway): add request timeouts to HA, Email, Mattermost, SMS adapters (#3258) 2026-03-26 14:36:07 -07:00
matrix.py fix(matrix): stop tagging the user on every reply (#16932) 2026-04-28 02:00:37 -07:00
mattermost.py feat(gateway): native send_multiple_images for Telegram, Discord, Slack, Mattermost, Email 2026-04-30 04:28:08 -07:00
signal.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
signal_rate_limit.py feat(gateway/signal): add support for multiple images sending 2026-04-30 04:28:08 -07:00
slack.py fix(gateway): clear slack assistant thread status 2026-05-01 14:01:26 -07:00
sms.py remove unused import and fix misleading log 2026-04-11 14:05:38 -07:00
telegram.py fix(telegram): probe polling liveness after reconnect to detect wedged Updater 2026-05-02 01:55:04 -07:00
telegram_network.py fix(telegram): honor no_proxy for explicit proxy setup 2026-04-24 14:31:04 -07:00
webhook.py feat: final platform plugin parity — webhook delivery, platform hints, docs 2026-04-29 21:56:51 -07:00
wecom.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
wecom_callback.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
wecom_crypto.py feat(gateway): add WeCom callback-mode adapter for self-built apps 2026-04-11 15:22:49 -07:00
weixin.py feat(gateway): centralize audio routing + FLAC support + Telegram doc fallback (#17833) 2026-04-30 01:32:31 -07:00
whatsapp.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
yuanbao.py fix(yuanbao): enforce owner identity check on group slash commands 2026-04-30 23:57:55 -07:00
yuanbao_media.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
yuanbao_proto.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
yuanbao_sticker.py yuanbao platform (#16298) 2026-04-26 18:50:49 -07:00