Providers

ClientSessionProvider creates a ClientSession once on mount, connects it, and exposes it to descendants through React context. The hooks in @ably/ai-transport/react read the session via this provider, so wrap every subtree that uses them in one.

Nest multiple providers with distinct channelName values to manage more than one session in the same tree. Each provider merges its slot into the parent registry so descendants can address any registered session by channelName.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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

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

function App() {
  return (
    <AblyProvider client={ably}>
      <ClientSessionProvider channelName="conversation-42" codec={UIMessageCodec}>
        <Chat />
      </ClientSessionProvider>
    </AblyProvider>
  );
}

ClientSessionProvider

The provider reads the Ably Realtime client from the surrounding <AblyProvider> and forwards it, along with the supplied props, to createClientSession. The session is created once on first render via useRef. connect() is invoked from a useEffect so the session is subscribed and attached before the first descendant read.

If createClientSession throws, the error is stored on the slot alongside an undefined session. useClientSession surfaces it as sessionError so the component tree does not crash.

Props

ClientSessionProviderProps extends all ClientSessionOptions except client (which is read from <AblyProvider>).

channelNameString
The channel the session subscribes to. Used as the registry key for nested providers.
codecCodec<TInput, TOutput, TProjection, TMessage>
The codec used to encode and decode events and messages.
clientIdString
The client's identity, used as the Ably publisher clientId for everything the session publishes.
messagesTMessage[]
Initial messages to seed the conversation tree with.
loggerLogger
Logger instance for diagnostic output.
childrenReactNode
Descendant components that consume the session via hooks.

ClientSessionSlot

A single entry in the registry holding the session and any error from construction. useClientSession returns this shape.

sessionClientSession<TInput, TOutput, TProjection, TMessage> or Undefined
The constructed session, or undefined if construction failed.
sessionErrorAbly.ErrorInfo or Undefined
Construction error from createClientSession, or undefined on success.

Bake hook types with createSessionHooks

function createSessionHooks<TInput, TOutput, TProjection, TMessage>(): SessionHooks<TInput, TOutput, TProjection, TMessage>

A factory that captures the codec's four type parameters once and returns a bundle of type-safe hooks plus a narrowed ClientSessionProvider. Hook call sites need no type parameters once you have called the factory.

Use this when you have one codec for the whole app and want call sites that look like const view = useView({ limit: 30 }) without generics. The Vercel React entry point already exports a bundle baked to the Vercel types.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// session.ts: shared module
import { createSessionHooks } from '@ably/ai-transport/react';
import type {
  VercelInput,
  VercelOutput,
  VercelProjection,
} from '@ably/ai-transport/vercel';
import type { UIMessage } from 'ai';

export const {
  ClientSessionProvider,
  useClientSession,
  useView,
  useTree,
  useCreateView,
  useAblyMessages,
} = createSessionHooks<VercelInput, VercelOutput, VercelProjection, UIMessage>();

The factory takes four type parameters. Omitting them leaves every hook inferred as unknown; pass them explicitly so call sites stay type-safe.

Returns

ClientSessionProviderComponentType<ClientSessionProviderProps>
ClientSessionProvider narrowed to the captured types. No JSX type params needed.
useClientSessionFunction
Type-narrowed useClientSession.
useViewFunction
Type-narrowed useView.
useTreeFunction
Type-narrowed useTree.
useAblyMessagesFunction
Type-narrowed useAblyMessages.
useCreateViewFunction
Type-narrowed useCreateView.

Example

Nested providers with distinct channel names and a child component that addresses each session by name.

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

import * as Ably from 'ably';
import { AblyProvider } from 'ably/react';
import { ClientSessionProvider, useClientSession } from '@ably/ai-transport/react';
import { UIMessageCodec } from '@ably/ai-transport/vercel';

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

function App() {
  return (
    <AblyProvider client={ably}>
      <ClientSessionProvider channelName="ai:main" codec={UIMessageCodec}>
        <ClientSessionProvider channelName="ai:aux" codec={UIMessageCodec}>
          <Chat />
        </ClientSessionProvider>
      </ClientSessionProvider>
    </AblyProvider>
  );
}

function Chat() {
  const { session: main } = useClientSession({ channelName: 'ai:main' });
  const { session: aux, sessionError } = useClientSession({ channelName: 'ai:aux' });

  if (sessionError) return <ErrorBanner error={sessionError} />;
  return <SplitPane mainSession={main} auxSession={aux} />;
}