Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/pages/docs/ai-transport/api/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ See the individual reference pages for the full API.
| --- | --- | --- |
| Core | `@ably/ai-transport` | `createClientSession`, `createAgentSession`, `Invocation`, `Codec` interface |
| React | `@ably/ai-transport/react` | `ClientSessionProvider`, `useClientSession`, `useView`, `useTree`, `useCreateView`, `useMessagesWithSeed`, `useAblyMessages`, `createSessionHooks` |
| Vercel | `@ably/ai-transport/vercel` | `UIMessageCodec`, Vercel-bound `createClientSession` and `createAgentSession`, `createChatTransport`, `vercelRunOutcome` |
| Vercel | `@ably/ai-transport/vercel` | `createUIMessageCodec`, Vercel-bound `createClientSession` and `createAgentSession`, `createChatTransport`, `vercelRunOutcome` |
| Vercel React | `@ably/ai-transport/vercel/react` | `ChatTransportProvider`, `useChatTransport`, `useMessageSync`, `useMessagesWithSeed`, plus the Vercel-baked re-exports of `ClientSessionProvider`, `useClientSession`, `useView`, `useCreateView`, `useTree`, and `useAblyMessages` |

<Aside data-type='note'>
Expand Down Expand Up @@ -82,8 +82,8 @@ The Vercel entry points re-export the core factories with the codec pre-bound. I
link: '/docs/ai-transport/api/javascript/vercel/chat-transport',
},
{
title: 'UIMessageCodec',
description: 'The pre-built codec for the Vercel AI SDK and its type parameters.',
title: 'createUIMessageCodec',
description: 'The factory for the pre-built Vercel AI SDK codec, and its type parameters.',
image: 'icon-tech-vercel',
link: '/docs/ai-transport/api/javascript/vercel/codec',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Construct one with `createAgentSession` from the core entry point. For Vercel `U
```javascript
import * as Ably from 'ably';
import { createAgentSession, Invocation } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

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

Expand All @@ -24,7 +24,7 @@ const invocation = Invocation.fromJSON(await req.json());
const session = createAgentSession({
client: ably,
channelName: invocation.sessionName,
codec: UIMessageCodec,
codec: createUIMessageCodec(),
});

await session.connect();
Expand Down Expand Up @@ -54,14 +54,14 @@ Construct an `AgentSession` bound to an Ably channel. The session does not attac
```javascript
import * as Ably from 'ably';
import { createAgentSession } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

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

const session = createAgentSession({
client: ably,
channelName: 'conversation-42',
codec: UIMessageCodec,
codec: createUIMessageCodec(),
});
```
</Code>
Expand Down Expand Up @@ -609,7 +609,7 @@ An HTTP handler that sets up the session, creates a Run, rebuilds the conversati
```javascript
import * as Ably from 'ably';
import { createAgentSession, Invocation } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

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

Expand All @@ -619,7 +619,7 @@ export async function POST(req: Request) {
const session = createAgentSession({
client: ably,
channelName: invocation.sessionName,
codec: UIMessageCodec,
codec: createUIMessageCodec(),
});

await session.connect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ Construct one with `createClientSession` from the core entry point. For Vercel `
```javascript
import * as Ably from 'ably';
import { createClientSession } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

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

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

await session.connect();
Expand Down Expand Up @@ -83,14 +83,14 @@ Construct a `ClientSession` bound to an Ably channel. The session does not attac
```javascript
import * as Ably from 'ably';
import { createClientSession } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

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

const session = createClientSession({
client: ably,
channelName: 'conversation-42',
codec: UIMessageCodec,
codec: createUIMessageCodec(),
});
```
</Code>
Expand Down Expand Up @@ -224,7 +224,7 @@ Publish a codec input event that targets this Run. The steering message carries

<Code>
```javascript
const { published, outcome } = activeRun.steer(UIMessageCodec.createUserMessage({
const { published, outcome } = activeRun.steer(createUIMessageCodec().createUserMessage({
id: crypto.randomUUID(),
role: 'user',
parts: [{ type: 'text', text: 'Also include vegan options.' }],
Expand Down Expand Up @@ -342,14 +342,14 @@ End-to-end usage covering construction, connect, send, and teardown.
```javascript
import * as Ably from 'ably';
import { createClientSession } from '@ably/ai-transport';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

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

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

await session.connect();
Expand All @@ -358,7 +358,7 @@ session.view.on('update', () => {
render(session.view.getMessages().map(({ message }) => message));
});

const clientRun = await session.view.send(UIMessageCodec.createUserMessage({
const clientRun = await session.view.send(createUIMessageCodec().createUserMessage({
id: crypto.randomUUID(),
role: 'user',
parts: [{ type: 'text', text: 'Plan a 3-day trip to Lisbon.' }],
Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/ai-transport/api/javascript/core/codec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ redirect_from:

The `Codec` interface is the bridge between an AI framework and Ably channel messages. It describes the wire as a flat stream of input and output events and folds those events into a per-Run projection that the SDK extracts messages from for the conversation tree.

Implement `Codec<TInput, TOutput, TProjection, TMessage>` to integrate any AI framework with AI Transport. The SDK ships [`UIMessageCodec`](/docs/ai-transport/api/javascript/vercel/codec) for the Vercel AI SDK. For other frameworks, implement the methods below.
Implement `Codec<TInput, TOutput, TProjection, TMessage>` to integrate any AI framework with AI Transport. The SDK ships the Vercel codec via [`createUIMessageCodec()`](/docs/ai-transport/api/javascript/vercel/codec) for the Vercel AI SDK. For other frameworks, implement the methods below.

<Code>
```typescript
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: "ChatTransport"
meta_description: "API reference for the AI Transport Vercel ChatTransport adapter and the Vercel-bound createClientSession and createAgentSession factories."
meta_keywords: "Vercel AI SDK, AI Transport, ChatTransport, createChatTransport, createClientSession, createAgentSession, UIMessageCodec, Ably"
meta_keywords: "Vercel AI SDK, AI Transport, ChatTransport, createChatTransport, createClientSession, createAgentSession, createUIMessageCodec, Ably"
redirect_from:
- /docs/ai-transport/api-reference/vercel
- /docs/ai-transport/api/javascript/vercel
---

The Vercel entry point pre-binds the [`UIMessageCodec`](/docs/ai-transport/api/javascript/vercel/codec) and exposes a `ChatTransport` adapter that satisfies the contract Vercel AI SDK's `useChat` hook expects. Use these factories whenever you build a chat UI on top of `useChat` so you do not have to wire the codec yourself.
The Vercel entry point pre-binds the [Vercel codec](/docs/ai-transport/api/javascript/vercel/codec) and exposes a `ChatTransport` adapter that satisfies the contract Vercel AI SDK's `useChat` hook expects. Use these factories whenever you build a chat UI on top of `useChat` so you do not have to wire the codec yourself.

<Code>
```javascript
Expand All @@ -33,7 +33,7 @@ React-side wiring (`ChatTransportProvider`, `useChatTransport`, `useMessageSync`

<MethodSignature>{`function createClientSession(options: VercelClientSessionOptions): ClientSession<VercelInput, VercelOutput, VercelProjection, UIMessage>`}</MethodSignature>

A pre-bound version of the core [`createClientSession`](/docs/ai-transport/api/javascript/core/client-session#constructor) with `codec: UIMessageCodec` already supplied. The `api` default is set on [`createChatTransport`](#create-chat-transport), not here.
A pre-bound version of the core [`createClientSession`](/docs/ai-transport/api/javascript/core/client-session#constructor) with the Vercel codec already supplied. The `api` default is set on [`createChatTransport`](#create-chat-transport), not here.

<Code>
```javascript
Expand Down Expand Up @@ -65,13 +65,13 @@ const session = createClientSession({

### Returns <a id="create-client-session-returns"/>

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

## Create a Vercel agent session <a id="create-agent-session"/>

<MethodSignature>{`function createAgentSession(options: VercelAgentSessionOptions): AgentSession<VercelOutput, VercelProjection, UIMessage>`}</MethodSignature>

A pre-bound version of the core [`createAgentSession`](/docs/ai-transport/api/javascript/core/agent-session#constructor) with `codec: UIMessageCodec` already supplied. Construct one inside your HTTP handler when the request arrives.
A pre-bound version of the core [`createAgentSession`](/docs/ai-transport/api/javascript/core/agent-session#constructor) with the Vercel codec already supplied. Construct one inside your HTTP handler when the request arrives.

<Code>
```javascript
Expand Down Expand Up @@ -108,7 +108,7 @@ Subscribe to non-fatal session-level errors with [`session.on('error')`](/docs/a

### Returns <a id="create-agent-session-returns"/>

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

## Create a chat transport <a id="create-chat-transport"/>

Expand Down
36 changes: 21 additions & 15 deletions src/pages/docs/ai-transport/api/javascript/vercel/codec.mdx
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
---
title: "UIMessageCodec"
meta_description: "API reference for UIMessageCodec, the pre-built AI Transport codec for the Vercel AI SDK."
meta_keywords: "Vercel AI SDK, AI Transport, UIMessageCodec, VercelInput, VercelOutput, VercelProjection, codec, Ably"
title: "createUIMessageCodec"
meta_description: "API reference for createUIMessageCodec, the factory for the pre-built AI Transport codec for the Vercel AI SDK."
meta_keywords: "Vercel AI SDK, AI Transport, createUIMessageCodec, UIMessageCodec, VercelInput, VercelOutput, VercelProjection, codec, Ably"
---

`UIMessageCodec` is the pre-built codec for the Vercel AI SDK. It implements [`Codec<VercelInput, VercelOutput, VercelProjection, UIMessage>`](/docs/ai-transport/api/javascript/core/codec) so a session can encode `UIMessageChunk` events out and decode them back into `UIMessage` objects without a custom implementation.
`createUIMessageCodec()` returns the pre-built codec for the Vercel AI SDK. The returned codec implements [`Codec<VercelInput, VercelOutput, VercelProjection, UIMessage>`](/docs/ai-transport/api/javascript/core/codec) so a session can encode `UIMessageChunk` events out and decode them back into `UIMessage` objects without a custom implementation.

You rarely import `UIMessageCodec` directly. The Vercel-pre-bound [`createClientSession`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-client-session) and [`createAgentSession`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-agent-session) already supply it. Import it explicitly when you build a codec wrapper, run the encoder or decoder outside of a session, or compose `UIMessageCodec` into a different codec.
You rarely call `createUIMessageCodec()` yourself. The Vercel-pre-bound [`createClientSession`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-client-session) and [`createAgentSession`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-agent-session) already supply the codec. Call it explicitly when you build a codec wrapper, run the encoder or decoder outside of a session, or compose the codec into a different codec.

<Code>
```javascript
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

const decoder = UIMessageCodec.createDecoder();
const projection = UIMessageCodec.init();
const codec = createUIMessageCodec();
const decoder = codec.createDecoder();
const projection = codec.init();
```
</Code>

## Properties <a id="properties"/>

`UIMessageCodec` is a value, not a type. It satisfies the full [`Codec`](/docs/ai-transport/api/javascript/core/codec) interface for the Vercel `TInput`, `TOutput`, `TProjection`, and `TMessage` parameters listed below.
`createUIMessageCodec()` is a factory, not a type. Each call returns a fresh, stateless codec value that satisfies the full [`Codec`](/docs/ai-transport/api/javascript/core/codec) interface for the Vercel `TInput`, `TOutput`, `TProjection`, and `TMessage` parameters listed below. Because the codec is stateless, hold a single instance at module scope (or, in React, `useMemo(() => createUIMessageCodec(), [])`) and reuse it rather than calling the factory inline on every render.

<Table id='UIMessageCodecProperties'>

Expand All @@ -40,6 +41,10 @@ const projection = UIMessageCodec.init();

## Type parameters <a id="types"/>

`createUIMessageCodec` is generic over the AI SDK's three `UIMessage` type parameters — `createUIMessageCodec<TMetadata, TDataParts, TTools>()`. Supplying concrete types specialises the codec so `getMessages` (and a session's `view.getMessages()`) return messages whose `metadata`, data parts, and tool parts carry your types instead of the SDK defaults; omitting them preserves the default inference. The same parameters thread through [`createClientSession`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-client-session), [`createAgentSession`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-agent-session), and [`createChatTransport`](/docs/ai-transport/api/javascript/vercel/chat-transport#create-chat-transport). See [Typed messages](/docs/ai-transport/frameworks/vercel-ai-sdk-ui#typed-messages) for the end-to-end pattern.

`VercelInput`, `VercelOutput`, and `VercelProjection` are likewise generic over the same three parameters, each defaulting to the SDK default. The tables below show the default instantiation.

<Table id='VercelInput'>

| Property | Description | Type |
Expand Down Expand Up @@ -72,21 +77,22 @@ Decode a single Ably message and fold the resulting events into a fresh projecti

<Code>
```javascript
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } from '@ably/ai-transport/vercel';

const decoder = UIMessageCodec.createDecoder();
let projection = UIMessageCodec.init();
const codec = createUIMessageCodec();
const decoder = codec.createDecoder();
let projection = codec.init();

channel.subscribe((message) => {
if (!message.serial) return; // live channel-subscribe messages always carry one
const { inputs, outputs } = decoder.decode(message);
for (const input of inputs) {
projection = UIMessageCodec.fold(projection, input, { serial: message.serial });
projection = codec.fold(projection, input, { serial: message.serial });
}
for (const output of outputs) {
projection = UIMessageCodec.fold(projection, output, { serial: message.serial });
projection = codec.fold(projection, output, { serial: message.serial });
}
render(UIMessageCodec.getMessages(projection).map((entry) => entry.message));
render(codec.getMessages(projection).map((entry) => entry.message));
});
```
</Code>
10 changes: 5 additions & 5 deletions src/pages/docs/ai-transport/api/react/core/providers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ Nest multiple providers with distinct `channelName` values to manage more than o
import * as Ably from 'ably';
import { AblyProvider } from 'ably/react';
import { ClientSessionProvider } from '@ably/ai-transport/react';
import { UIMessageCodec } from '@ably/ai-transport/vercel';
import { createUIMessageCodec } 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}>
<ClientSessionProvider channelName="conversation-42" codec={createUIMessageCodec()}>
<Chat />
</ClientSessionProvider>
</AblyProvider>
Expand Down Expand Up @@ -126,15 +126,15 @@ Nested providers with distinct channel names and a child component that addresse
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';
import { createUIMessageCodec } 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}>
<ClientSessionProvider channelName="ai:main" codec={createUIMessageCodec()}>
<ClientSessionProvider channelName="ai:aux" codec={createUIMessageCodec()}>
<Chat />
</ClientSessionProvider>
</ClientSessionProvider>
Expand Down
Loading