Skip to main content
Prerequisites: Quick Start complete, pip install mellea, Ollama running locally.

Async methods

Every sync method on MelleaSession has an a-prefixed async counterpart with the same signature and return type:

Parallel generation

ainstruct() returns a ModelOutputThunk immediately — generation starts in the background but the value is not resolved until you call avalue(). This lets you fire multiple generations and resolve them all at once:
For a list of thunks, wait_for_all_mots is a convenience wrapper:
Note: All thunks passed to wait_for_all_mots must belong to the same event loop, which is always the case when using MelleaSession.

Streaming

Enable streaming by passing ModelOption.STREAM: True in model_options. Consume incremental output chunks with mot.astream():
How astream() behaves:
  • Each call returns only the new content since the previous call.
  • When the thunk is fully computed (is_computed() returns True), the final astream() call returns the complete value.
  • If the thunk is already computed, astream() returns the full value immediately.
Warning: Do not call astream() from multiple coroutines simultaneously on the same thunk. Each thunk should have a single reader.

Async and context

Use SimpleContext (the default) with concurrent async requests. Using ChatContext with concurrent requests can cause stale context issues — Mellea logs a warning when this is detected:
If you need ChatContext with async, await each call before starting the next:
For parallel generation, use SimpleContext.

Streaming with per-chunk validation

stream_with_chunking() adds per-chunk validation to a streaming generation. It splits the accumulated text into semantic units (sentences, words, or paragraphs), calls stream_validate() on each chunk in parallel, and can exit early if any requirement returns "fail" — preventing the consumer from seeing invalid content mid-stream. The primary way to observe a stream_with_chunking() run is via typed StreamEvent objects from result.events():
If you only need the raw validated text without event metadata, use result.astream() instead:
Both astream() (raw chunks) and events() are available on the same result object. They use independent queues, so you can run them concurrently with asyncio.gather. Both are single-consumer — a second iteration on either will block indefinitely.

The stream_validate tri-state

Each call to stream_validate returns a PartialValidationResult with one of three values: After a natural stream end, validate() is called on every non-"fail" requirement (both "pass" and "unknown"). This means "pass" from stream_validate does not replace the final validate() call.
See also: The Requirements System — Streaming validation

See also: Tutorial 02: Streaming and Async | act() and aact()