| name | vibe-async |
| description | Async and concurrency patterns for Mistral Vibe. Use when working with asyncio, the agent loop, Textual TUI threading, HTTP clients, streaming surfaces, or core-to-TUI communication. |
| metadata | {"display-name":"Vibe Async","short-description":"Async and concurrency patterns for Vibe","default-prompt":"Use $vibe-async to follow Vibe async conventions when working with concurrent or event-loop code."} |
Vibe Async Patterns
Conventions for async and concurrent code in Vibe. Apply when touching the agent loop, Textual event loop, HTTP clients, streaming, or any async code.
Runtime
asyncio is the orchestration runtime in the agent loop and tool execution. Use asyncio.create_task + queues for concurrent work, not blanket gather.
Blocking work
- Never run CPU-heavy or I/O-bound code on the UI thread. The Textual TUI and the agent loop share one event loop, so anything blocking (large JSON/Pydantic serialization,
os.fsync, subprocess calls, recursive globs) freezes the UI — offload it with asyncio.to_thread.
- Async file wrappers don't make blocking syscalls non-blocking.
- Use
anyio.Path for file I/O on async paths.
Streaming
- Streaming surfaces return
AsyncGenerator[Event, None], not coroutines.
Core-to-TUI communication
- Route core-to-TUI communication through
vibe.app_server. Server requests such as approvals and user input become canonical Vibe events; neither the TUI nor app server may register callbacks, listeners, or message observers directly on the agent loop.
HTTP clients
- When Vibe owns an HTTP client, use
VibeAsyncHTTPClient from vibe.utils.http instead of httpx.AsyncClient so proxy env vars are handled consistently.
- Its CIDR
NO_PROXY matching applies only to IP-literal request hosts; do not resolve DNS before proxy selection.
- Mock outbound HTTP with
respx in tests.