---
title: ai.util
description: Reference for async utility helpers.
type: reference
summary: Reference for ai.util.
---

# ai.util



`ai.util` contains asynchronous utility primitives used by the SDK.

## merge

`merge` consumes multiple async iterables concurrently and yields items as they
become available.

```python
async with ai.util.merge(stream, tool_runner.events()) as events:
    async for event in events:
        ...
```

## decouple

`decouple` runs an async iterable in its own task and hands its items to the
consumer through a buffer. Use it to let a producer keep going while the
consumer is slow. (`Agent.LOOP_BUFFER` exposes this for the agent loop.)

```python
async for item in ai.util.decouple(source, buffer=None):
    ...
```

`buffer` is required and sets how many items the producer may run ahead of
the consumer:

* `None`: unbounded. The producer is never held back by the consumer.
* `n`: the producer may run up to `n` items ahead.
* `0`: lockstep. The iterable is only advanced when the consumer asks for an
  item. This is how `merge` drives its sources.

Every step of the iterable runs in the same worker task.

This makes the lockstep variant useful for when an async generator needs to
be driven from multiple different tasks.

## Queues

Queue primitives:

* `AsyncIterableQueue`
* `MultiWaiter`

`AsyncIterableQueue` is an async iterable queue that can be closed. `MultiWaiter`
waits for the first completed item across multiple async sources.

## Lifecycle Helpers

Lifecycle helpers:

* `unwrap_generator_exit`
* `maybe_aclosing`

Use these helpers when implementing custom async generators or safely closing
optional async resources.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)