ChatTransport

The Vercel entry point pre-binds the Vercel codec and exposes a ChatTransport adapter that satisfies the contract Vercel AI SDK's useChat hook expects. Use createClientSession, createAgentSession and createChatTransport whenever you build a chat UI on top of useChat, and each one supplies the codec for you.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

import * as Ably from 'ably';
import { createClientSession, createChatTransport } from '@ably/ai-transport/vercel';

const ably = new Ably.Realtime({ authUrl: '/api/auth/token' });

const session = createClientSession({
  client: ably,
  channelName: 'conversation-42',
});

await session.connect();

const chatTransport = createChatTransport(session);

The React provider and hooks (ChatTransportProvider, useChatTransport, useMessageSync) are in @ably/ai-transport/vercel/react.

Create a Vercel client session

function createClientSession(options: VercelClientSessionOptions): ClientSession<VercelSessionInput, VercelOutput, VercelProjection, UIMessage>

A pre-bound version of the core createClientSession with the Vercel codec already supplied. The api default is set on createChatTransport rather than here.

JavaScript

1

2

3

4

5

6

7

8

9

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

const ably = new Ably.Realtime({ authUrl: '/api/auth/token' });

const session = createClientSession({
  client: ably,
  channelName: 'conversation-42',
});

Parameters

clientrequiredAbly.Realtime
The Ably Realtime client. The caller owns its lifecycle. The session's identity is read from this client's auth.clientId at publish time and carried on every message the session publishes.
channelNamerequiredString
The channel to subscribe to and publish cancel signals on.
channelModesoptionalAbly.ChannelMode[]
Extra channel modes to request on top of the modes AI Transport always needs. Pass OBJECT_MODES to use Ably LiveObjects.
historyPageSizeoptionalNumber
Wire-message limit fetched per channel-history round trip when paging older history. Defaults to 100.
reorderWindowMsoptionalNumber
Advanced. How long, in milliseconds on the Ably message-timestamp timeline, a structurally complete run's event log is kept after its last activity before the tree may drop it. The tree uses that log to merge a late, out-of-order wire message into canonical position, and to drop an earlier attempt's output when a step retry supersedes it. Once the log is gone, a late wire message merges in arrival order instead. Raise it for a durable agent whose step retries back off longer than the default. Defaults to 120000.
loggeroptionalLogger
Logger instance for diagnostic output.

Returns

ClientSession<VercelSessionInput, VercelOutput, VercelProjection, UIMessage>. A client session whose codec is pre-bound to the Vercel codec.

Create a Vercel agent session

function createAgentSession(options: VercelAgentSessionOptions): AgentSession<VercelOutput, VercelProjection, UIMessage>

A pre-bound version of the core createAgentSession with the Vercel codec already supplied. Construct one inside your HTTP handler when the request arrives.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

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

const ably = new Ably.Realtime({ key: process.env.ABLY_API_KEY });

const invocation = Invocation.fromJSON(await req.json());

const session = createAgentSession({
  client: ably,
  channelName: invocation.sessionName,
});

Parameters

clientrequiredAbly.Realtime
The Ably Realtime client. The caller owns its lifecycle.
channelNamerequiredString
The channel to publish to.
channelModesoptionalAbly.ChannelMode[]
Extra channel modes to request on top of the modes AI Transport always needs. Pass OBJECT_MODES to use Ably LiveObjects.
historyPageSizeoptionalNumber
Wire-message limit fetched per channel-history round trip, used by every run.view pagination on this session. Defaults to 100.
reorderWindowMsoptionalNumber
Advanced. How long, in milliseconds on the Ably message-timestamp timeline, a structurally complete run's event log is kept after its last activity before the tree may drop it. The tree uses that log to merge a late, out-of-order wire message into canonical position, and to drop an earlier attempt's output when a step retry supersedes it. Once the log is gone, a late wire message merges in arrival order instead. Raise it for a durable agent whose step retries back off longer than the default. Defaults to 120000.
loggeroptionalLogger
Logger instance for diagnostic output.

Subscribe to non-fatal session-level errors with session.on('error') rather than a constructor option.

Returns

AgentSession<VercelOutput, VercelProjection, UIMessage>. An agent session whose codec is pre-bound to the Vercel codec.

Create a chat transport

function createChatTransport(session: ClientSession<VercelSessionInput, VercelOutput, VercelProjection, UIMessage>, chatOptions?: ChatTransportOptions): ChatTransport

Wrap a ClientSession in a ChatTransport adapter that satisfies Vercel AI SDK's useChat transport option. The adapter maps useChat's sendMessages and reconnectToStream contract to the session's view.send, view.regenerate, and tool resolution.

JavaScript

1

2

3

4

5

6

7

8

9

10

import { useChat } from '@ai-sdk/react';
import { createChatTransport } from '@ably/ai-transport/vercel';

const chatTransport = createChatTransport(session, {
  prepareSendMessagesRequest: ({ history }) => ({
    body: { history },
  }),
});

const chat = useChat({ transport: chatTransport });

Parameters

sessionrequiredClientSession<VercelSessionInput, VercelOutput, VercelProjection, UIMessage>
The core client session to wrap.
chatOptionsoptionalChatTransportOptions
Hooks for customising request construction.

Returns

ChatTransport. The adapter to pass to useChat's transport option.

ChatTransport

The transport adapter returned by createChatTransport. It is structurally compatible with the AI SDK's internal ChatTransport<UIMessage> interface, extended with close(), streaming, and onStreamingChange for coordinating with useMessageSync.

Properties

sendMessages(options) => Promise<ReadableStream<UIMessageChunk>>
Send messages and return a ReadableStream of UIMessageChunk events.
reconnectToStream(options) => Promise<ReadableStream<UIMessageChunk> | null>
Reconnect to an existing streaming response. Returns null because observer mode handles in-progress streams automatically.
close() => Promise<void>
Close the underlying transport, releasing all resources.
streamingBoolean
Whether a stream this transport returned to useChat is still open, including one that observes a run this client did not open.
onStreamingChange(callback: (streaming: boolean) => void) => () => void
Subscribe to streaming state changes. Used by useMessageSync to gate setMessages calls during active streams.

Example

End-to-end client-side code: open a session, wrap it in a chat transport, and pass it to useChat.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import * as Ably from 'ably';
import { useChat } from '@ai-sdk/react';
import { createClientSession, createChatTransport } from '@ably/ai-transport/vercel';

const ably = new Ably.Realtime({ authUrl: '/api/auth/token' });

const session = createClientSession({
  client: ably,
  channelName: 'conversation-42',
});

await session.connect();

const chatTransport = createChatTransport(session, {
  prepareSendMessagesRequest: ({ history, messages }) => ({
    body: { history, messages },
  }),
});

function Chat() {
  const { messages, sendMessage } = useChat({ transport: chatTransport });
  return (
    <>
      {messages.map((m) => (
        <Message key={m.id} message={m} />
      ))}
      <Composer onSubmit={(text) => sendMessage({ role: 'user', parts: [{ type: 'text', text }] })} />
    </>
  );
}