Transport

The transport layer connects each participant to the session and translates between your AI framework's events and Ably's messages.

Open in

The transport layer handles communication between participants and the session. There are two transports: the client transport for client applications, and the agent transport for agent processes. A pluggable codec bridges your AI framework's event types to Ably messages, so the transport works with any framework without modification.

Understand the client transport

The client transport is how a client application connects to a session. It is a long-lived object that subscribes to the channel, materialises the session into a tree, and provides one or more views for the application to work with.

The client transport owns the read path: decoding incoming channel messages, applying them to the tree, and emitting scoped events through views so the application knows when visible state has changed. It also owns the client's side of the write path. When the application sends a message, the transport publishes turn-start and the user's input messages to the channel, then sends a poke to the agent endpoint to trigger an execution. The channel publish and the poke are decoupled: the turn is established on the session before the agent is triggered, and the poke is deferred or retried independently. Cancellation is a channel publish: the transport sends a cancel signal targeting a turn, and the agent receives it through its own channel subscription.

The client transport is also responsible for connection resilience. It monitors channel continuity, detects if messages were lost during a disconnection, and keeps the session state consistent after reconnection.

A client transport is not the session. It is one participant's connection to the session. Multiple clients connect to the same session simultaneously, each with their own views and branch selections, all sharing the same underlying conversation state on the channel.

Understand the agent transport

The agent transport is how an agent connects to a session for a single execution attempt within a turn. It is typically short-lived: created when the agent receives a poke, used for the duration of that execution, then disposed.

The agent transport handles the write path for the agent's contribution: piping model output through the codec encoder to the channel, publishing turn-end when the task completes, and listening for cancel signals that target the active turn. When the agent receives a poke, it uses the transport to hydrate the session from the channel (or from an external store), locate the message the poke references, and begin its work.

The agent is stateless between execution attempts. The agent transport does not maintain long-lived subscriptions or accumulated state. Each execution hydrates what it needs, does its work, publishes its output, and tears down. If the turn spans multiple executions (a human-in-the-loop step, a retry after failure), each execution creates its own agent transport against the same session. The session on the channel provides continuity, not the transport.

Understand the codec

The codec is the translation layer between domain-specific message models and Ably's native message primitives. It defines how events in the application's domain (text deltas, tool calls, finish signals, or whatever the domain model requires) are encoded into Ably messages for transmission over the channel, and how incoming Ably messages are decoded back into domain events and accumulated into domain messages.

The codec is an interface, not an implementation. The generic layer of the SDK knows nothing about what the events or messages look like. It operates entirely through the codec contract. A Vercel AI SDK codec translates UIMessageChunk events into Ably messages and assembles them into UIMessage objects. A different codec does the same for a different framework, or for a custom domain model.

The codec has three responsibilities:

ComponentWhat it does
EncoderTake domain events and produce Ably message operations: publishes for discrete messages, append sequences for streamed content.
DecoderTake incoming Ably messages and produce domain events. Handle the reconstruction of streaming state from Ably's message lifecycle (create, append, update).
AccumulatorTake a sequence of decoded events and assemble them into complete domain messages. Track which messages are still streaming and which are complete.

The codec also determines what constitutes a terminal event: the event that signals a stream is finished. This is domain-specific knowledge (a finish chunk in the Vercel model, for example) that the generic transport layer needs in order to close streams at the right time.

The codec is the boundary between transport concerns and application domain concerns. Everything below the codec (headers, serials, channel operations, tree structure) is generic. Everything above (the shape of events, the structure of messages, what a tool call or text delta means) is domain-specific.

Connect a client transport

A client transport is created with an Ably channel, a codec, and the HTTP endpoint that triggers the agent:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

import * as Ably from 'ably';
import { createClientTransport } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';

const ably = new Ably.Realtime({ authUrl: '/auth' });
const channel = ably.channels.get('conversation-42');

const transport = createClientTransport({
  channel,
  codec: UIMessageCodec,
  api: '/api/chat',
});

The codec is what makes the same transport carry a Vercel UIMessage, an OpenAI completion, or a custom domain event. UIMessageCodec is provided for the Vercel AI SDK; the Vercel entry point also re-exports createClientTransport with the codec pre-bound and api defaulted to /api/chat. See the codec API reference for the full interface.