fix: resolve 'Timeout context manager should be used inside a task' in Weixin send#14530
Open
yyufoyy02 wants to merge 1 commit into
Open
fix: resolve 'Timeout context manager should be used inside a task' in Weixin send#14530yyufoyy02 wants to merge 1 commit into
yyufoyy02 wants to merge 1 commit into
Conversation
…n Weixin send When send_weixin_direct() reuses the live adapter's aiohttp session (from the gateway's event loop) but runs via _run_async on a worker thread, asyncio.current_task() returns None because run_until_complete() does not create a task. This causes aiohttp's ClientTimeout.__enter__ to raise RuntimeError. Two changes: 1. gateway/platforms/weixin.py — send_weixin_direct() always creates its own aiohttp.ClientSession instead of reusing the live adapter's session bound to the gateway's event loop. 2. model_tools.py — _run_async() uses asyncio.run() instead of run_until_complete() for both worker-thread and main-thread paths. asyncio.run() creates a proper task context, which aiohttp >= 3.9 requires for ClientTimeout. Fixes: send_message tool and cron delivery failing for Weixin platform with 'Timeout context manager should be used inside a task' error.
This was referenced Apr 26, 2026
This was referenced Apr 30, 2026
Open
2 tasks
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.
Problem
When the gateway is running and a Weixin user sends a message, the agent responds via
send_weixin_direct()which tries to reuse the live adapter'saiohttp.ClientSession(bound to the gateway's event loop). However,send_messagetool calls are dispatched via_run_async()which may run on a worker thread usingloop.run_until_complete().run_until_complete()does not create a task, soasyncio.current_task()returnsNone. This causesaiohttp.ClientTimeout.__enter__to raise:This breaks all Weixin send operations (text + media) from the
send_messagetool and cron delivery when the gateway is running.Introduced by commit
5ca52bae(split poll/send sessions, reuse live adapter).Fix
gateway/platforms/weixin.py—send_weixin_direct()always creates its ownaiohttp.ClientSessioninstead of reusing the live adapter's session (which is bound to the gateway's event loop and may be on a different thread).model_tools.py—_run_async()usesasyncio.run()instead ofrun_until_complete()for both worker-thread and main-thread fallback paths.asyncio.run()creates a proper task context, whichaiohttp >= 3.9requires forClientTimeout.Trade-off
Using
asyncio.run()instead of a persistent loop means each call creates/destroys an event loop. The original persistent loop was introduced to prevent "Event loop is closed" errors with cachedhttpx/AsyncOpenAIclients (commit7a427d7b). If this becomes an issue again, an alternative fix would be to wrap the coroutine inloop.create_task()beforerun_until_complete(), e.g.:This preserves the persistent loop while still providing a task context.
Verification
send_messagecalls to Weixin fail with timeout error when gateway is runningsend_weixin_direct()creates its own session,asyncio.run()provides task context