Fixing async REPL for Python 3.14 | Generated by AI
22 pass, 1 pre-existing failure (unrelated — your config has search_provider: "bing" but the test hardcodes "duckduckgo").
Here’s what I changed:
iclaw/main.py — 3 edits:
- Added
import asyncio - Split
main()into a sync wrapper (main()callsasyncio.run(_main())) and an async_main()function - Changed
session.prompt("> ")toawait session.prompt_async("> ")
tests/test_main.py — 2 edits:
- Updated
_mock_session()to mockprompt_async(async function) instead of justprompt - Fixed
test_main_token_refresh— replaced finiteside_effect=[0, 99999, 99999, 99999]list with a callable, sinceasyncio.run()now also callstime.monotonic()internally (becausepatch("iclaw.main.time.monotonic")patches the realtime.monotonicglobally)
Root cause: Python 3.14 made asyncio.run() stricter — it raises RuntimeError when called from within a running event loop. prompt_toolkit 3.0.52’s Application.run() calls asyncio.run(), but the browser tool’s Playwright sync API (or the previous prompt_toolkit iteration itself) left an event loop running. By making the REPL async with prompt_async(), there’s a single event loop for the entire session.