Skip to content

fix: cross-channel send_message failures (Telegram proxy + WeChat event loop)#12370

Closed
calonye wants to merge 2 commits into
NousResearch:mainfrom
calonye:fix/cross-channel-send-event-loop
Closed

fix: cross-channel send_message failures (Telegram proxy + WeChat event loop)#12370
calonye wants to merge 2 commits into
NousResearch:mainfrom
calonye:fix/cross-channel-send-event-loop

Conversation

@calonye

@calonye calonye commented Apr 19, 2026

Copy link
Copy Markdown

Problem

This PR addresses four issues:

  1. Cross-channel WeChat → Telegram: Telegram send failed: Timed out
  2. Cross-channel Telegram → WeChat: Timeout context manager should be used inside a task
  3. Session continuity on restart: Every gateway restart loses the active conversation
  4. Proxy auto-detection: macOS system proxy doesn't detect SOCKS proxies

Root Causes & Fixes

1. _send_telegram() missing proxy support (send_message_tool.py)

The send_message tool's _send_telegram() created Bot(token=token) without proxy configuration, bypassing TELEGRAM_PROXY. The gateway adapter correctly uses the proxy, but the tool's direct send path didn't.

Fix: Added resolve_proxy_url("TELEGRAM_PROXY") + HTTPXRequest(proxy=...), matching the gateway adapter's pattern.

2. send_weixin_direct() event loop mismatch (weixin.py)

When send_weixin_direct() is called via _run_async() from a different async context (e.g. cross-channel Telegram→WeChat), _run_async spawns a new thread with asyncio.run() creating a fresh event loop. The code tries to reuse a live_adapter from _LIVE_ADAPTERS, but that adapter's aiohttp session is bound to the gateway's main event loop. Using it from the new loop causes aiohttp's timeout context manager to fail.

Fix: Added event loop compatibility check. If the live adapter's aiohttp session connector loop doesn't match the current running loop, skip adapter reuse and fall through to the existing fresh-session fallback path.

3. edit_message() missing finalize kwarg (telegram.py)

The gateway calls TelegramAdapter.edit_message(..., finalize=...) but the method signature didn't accept this keyword argument, causing TypeError.

Fix: Added finalize: bool = False parameter.

4. Session continuity on restart (gateway/run.py)

When gateway restart is called, _drain_active_agents() waits up to 60s for running agents to finish. The current agent can't self-terminate mid-response, so drain times out. The code then skips writing the .clean_shutdown marker, causing the next startup to call suspend_recently_active() — suspending all sessions and losing the conversation.

Fix: Always write the .clean_shutdown marker, even on drain timeout. The interrupt signal has been sent and agents handle it cleanly on their next iteration. The existing 3-restart stuck-loop detection (#7536) already suspends truly stuck sessions as a safety net. Losing every conversation on restart is far worse than resuming an interrupted one.

5. SOCKS proxy auto-detection (gateway/platforms/base.py)

_detect_macos_system_proxy() only checked HTTP/HTTPS proxy settings from scutil --proxy, ignoring SOCKS proxies. Many users (especially behind GFW) use SOCKS5 proxies (V2rayU, Clash, Shadowrocket).

Fix: Added SOCKS proxy detection (SOCKSEnable/SOCKSProxy/SOCKSPort) returning socks5:// URLs. Added explanatory comment for why http:// scheme is used for HTTPS proxies (HTTP CONNECT tunnelling). Env vars (ALL_PROXY, TELEGRAM_PROXY etc.) remain the recommended way to configure any proxy scheme.

Testing

  • ✅ WeChat → Telegram: message delivered
  • ✅ Telegram → WeChat: message delivered
  • ✅ Gateway restart + message continues same session
  • ✅ No new errors in gateway logs

calonye added 2 commits April 19, 2026 10:27
…nt loop)

Two fixes for cross-channel messaging via the send_message tool:

1. fix(send_message): add proxy support for _send_telegram()
   - send_message tool's _send_telegram() created Bot(token=token) without
     proxy config, causing timeouts when TELEGRAM_PROXY is configured.
   - Now uses resolve_proxy_url() + HTTPXRequest(proxy=...) matching
     the gateway adapter's pattern.

2. fix(weixin): prevent event-loop mismatch in send_weixin_direct()
   - When called via _run_async from a different async context (e.g.
     cross-channel Telegram→WeChat), the live adapter's aiohttp session
     is bound to the gateway's main event loop.
   - Using it from _run_async's new thread's loop causes
     "Timeout context manager should be used inside a task".
   - Added event loop compatibility check: if the session's connector
     loop doesn't match the current running loop, skip adapter reuse
     and fall through to the fresh-session fallback path.

3. fix(telegram): add missing finalize kwarg to edit_message()
   - edit_message() was called with finalize=... by the gateway but the
     method signature didn't accept it, causing TypeError.
1. fix(gateway): always write .clean_shutdown marker on stop
   Previously, when drain timed out (e.g. agent mid-API-call during
   restart), the marker was skipped, causing all recently-active
   sessions to be suspended on next startup. This meant EVERY restart
   lost the active conversation.

   Now we always write the marker because:
   - The interrupt signal has been sent; agents handle it cleanly
   - 3-restart stuck-loop detection (#7536) already suspends truly
     stuck sessions as a safety net
   - Losing every conversation on restart is far worse than resuming
     an interrupted one

2. fix(proxy): detect SOCKS proxy in macOS system proxy fallback
   _detect_macos_system_proxy() now checks SOCKSEnable/SOCKSProxy/
   SOCKSPort from scutil --proxy, returning socks5:// URLs.
   Added comment explaining why HTTP scheme is used for HTTPS proxies
   (HTTP CONNECT tunnelling). Env vars (ALL_PROXY, TELEGRAM_PROXY
   etc.) remain the recommended way to configure any proxy scheme.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter platform/wecom WeCom / WeChat Work adapter labels Apr 23, 2026
@calonye calonye closed this by deleting the head repository Jun 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 P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter platform/wecom WeCom / WeChat Work adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants