fix: run async setup() on the same event loop as predict() (#2927)
Async predictors that create event-loop-bound resources in setup()
(httpx.AsyncClient, aiohttp.ClientSession, etc.) crash because setup()
ran via asyncio.run() on an ephemeral loop that's destroyed, while
predict() runs on a separate persistent shared loop.
Submit async setup coroutines to the shared event loop via
run_coroutine_threadsafe instead, so both phases share the same loop.
The non-worker path (cog predict CLI) keeps using asyncio.run().
Fixes #2926