> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipecat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding the Bus Bridge

> How BusBridgeProcessor routes frames between the transport pipeline and the agent bus.

## What is the bus bridge?

The `BusBridgeProcessor` is a pipeline processor that connects a transport pipeline to the agent bus. It sits in the main agent's pipeline where an LLM would normally go, routing frames to whichever agent is currently active.

Without the bridge, your main agent's pipeline would look like:

```
transport.input → STT → context_agg → LLM → TTS → transport.output
```

With the bridge, the LLM is replaced:

```
transport.input → STT → context_agg → BusBridge → TTS → transport.output
```

The bridge sends outgoing frames (like transcribed text) to the bus, and receives incoming frames (like LLM-generated text) from the active agent.

<Info>
  The examples above show a voice pipeline, but `BusBridgeProcessor` can be used
  in any type of pipeline. It works with any frames, not just audio.
</Info>

## How it works

The bridge operates in two directions:

**Outgoing** (pipeline to bus): Frames flowing downstream through the pipeline are captured by the bridge and published as `BusFrameMessage` on the bus. The active agent receives these frames.

**Incoming** (bus to pipeline): When an active agent sends frames back through the bus, the bridge pushes them into the pipeline. These frames continue downstream to TTS and the transport output.

Certain frames are never sent across the bus:

* Lifecycle frames (`StartFrame`, `EndFrame`, `CancelFrame`, `StopFrame`)
* Transport-urgent frames (these pass through the bridge locally)

## Basic usage

The main agent is a `PipelineWorker` wrapping a pipeline that contains a `BusBridgeProcessor`. The bridge gets its bus from `runner.bus`:

```python theme={null}
from pipecat.bus import BusBridgeProcessor
from pipecat.pipeline.pipeline import Pipeline
from pipecat.workers.runner import WorkerRunner
from pipecat.pipeline.worker import PipelineParams, PipelineWorker

MAIN_NAME = "acme"

runner = WorkerRunner()

bridge = BusBridgeProcessor(
    bus=runner.bus,
    worker_name=MAIN_NAME,
    name=f"{MAIN_NAME}::BusBridge",
)

pipeline = Pipeline([
    transport.input(),
    stt,
    context_aggregator.user(),
    bridge,
    tts,
    transport.output(),
    context_aggregator.assistant(),
])

main = PipelineWorker(pipeline, name=MAIN_NAME, params=PipelineParams())

await runner.add_workers(main)
```

The worker gets its bus from the runner when added with `runner.add_workers()`. You build the `BusBridgeProcessor` ahead of time with `runner.bus` and place it in the pipeline where an LLM would normally go.

## Named bridges

When you have multiple bridges in a system, you can name them to control which agents receive frames from which bridge. This is useful with [parallel pipelines](/server/pipeline/parallel-pipeline) where each branch has its own bridge (for example, separate audio and video branches):

```python theme={null}
voice_bridge = BusBridgeProcessor(
    bus=runner.bus,
    worker_name=MAIN_NAME,
    name=f"{MAIN_NAME}::VoiceBridge",
    bridge="voice",
)
```

Agents control which bridges they listen to through the `bridged` argument when they are created:

```python theme={null}
# Receives frames from all bridges
all_bridges_agent = MyLLMWorker("all", llm=llm, bridged=())

# Receives frames only from the "voice" bridge
voice_only_agent = MyLLMWorker("voice-only", llm=llm, bridged=("voice",))
```

## The bridged agent side

When an agent sets `bridged=()` (or a tuple of bridge names), the framework automatically wraps its pipeline with edge processors that handle bus frame conversion. An LLM agent subclasses `LLMWorker` and passes its own LLM service:

```python theme={null}
from pipecat.services.openai.llm import OpenAILLMService
from pipecat.workers.llm import LLMWorker, tool

class MyLLMWorker(LLMWorker):
    @tool
    async def my_function(self, params, arg: str):
        ...

llm = OpenAILLMService(api_key="...")
agent = MyLLMWorker("greeter", llm=llm, bridged=())
```

A worker never takes a `bus=` argument. It receives its bus from the runner when you register it with `runner.add_workers()`.

The resulting pipeline looks like:

```
BusEdgeProcessor (upstream) → [your pipeline] → BusEdgeProcessor (downstream)
```

The upstream edge processor receives `BusFrameMessage` from the bus and converts them back to regular Pipecat frames. The downstream edge processor captures output frames and sends them back through the bus. You don't need to manage this -- it happens automatically when `bridged` is set.
