From effb795d154ffeb248c3a26c57f3606a68a559bc Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 30 Jun 2026 22:40:00 +0100 Subject: [PATCH 1/3] docs(ai-transport): resync Vercel getting-started with SDK 0.3.0 Replace the outdated useClientSession + createChatTransport client wiring with ChatTransportProvider / useChatTransport / useMessageSync from @ably/ai-transport/vercel/react. Cancel the active Run via session.cancel from the stop button, correct the Node prerequisite to 22+, and bump the AI Transport JS version to 0.3. --- src/data/languages/languageData.ts | 2 +- .../getting-started/vercel-ai-sdk.mdx | 41 +++++++++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/data/languages/languageData.ts b/src/data/languages/languageData.ts index b7bbd5e8a2..e1788fdb19 100644 --- a/src/data/languages/languageData.ts +++ b/src/data/languages/languageData.ts @@ -44,7 +44,7 @@ export default { android: '1.2', }, aiTransport: { - javascript: '0.2', + javascript: '0.3', }, spaces: { javascript: '0.5', diff --git a/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx b/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx index 367e0e942d..bb7affba61 100644 --- a/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx +++ b/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx @@ -24,7 +24,7 @@ For direct access to the conversation tree, branching, and pagination, see [Get ## Prerequisites -- Node.js 20 or later. +- Node.js 22 or later. - An [Ably account](https://ably.com/sign-up) with an API key. - An Anthropic API key, or any other model provider supported by Vercel AI SDK. @@ -107,30 +107,37 @@ export async function POST(req) { ## Create the chat component -Create `app/chat.tsx`. The component uses Vercel's `useChat` hook with `createChatTransport` from `@ably/ai-transport/vercel`. The Vercel wrapper owns the agent-invocation POST; `useChat` calls into it as if it were the default HTTP transport. +Create `app/chat.tsx`. The component reads the chat transport from the nearest [`ChatTransportProvider`](/docs/ai-transport/api/react/vercel/chat-transport-provider) with [`useChatTransport`](/docs/ai-transport/api/react/vercel/use-chat-transport) and passes it to Vercel's `useChat` hook. The transport owns the agent-invocation POST; `useChat` calls into it as if it were the default HTTP transport. [`useMessageSync`](/docs/ai-transport/api/react/vercel/use-message-sync) feeds channel updates back into `useChat`, so other clients see messages they did not publish. ```javascript 'use client'; -import { useMemo, useState } from 'react'; +import { useState } from 'react'; import { useChat } from '@ai-sdk/react'; -import { useClientSession } from '@ably/ai-transport/react'; -import { createChatTransport } from '@ably/ai-transport/vercel'; +import { useChatTransport, useMessageSync } from '@ably/ai-transport/vercel/react'; -export function Chat({ chatId }) { +export function Chat() { const [input, setInput] = useState(''); - const { session } = useClientSession(); + const { session, chatTransport, chatTransportError } = useChatTransport(); - const chatTransport = useMemo(() => createChatTransport(session), [session]); - - const { messages, sendMessage, status, stop } = useChat({ - id: chatId, + const { messages, setMessages, sendMessage, status } = useChat({ transport: chatTransport, }); + useMessageSync({ setMessages }); + + if (chatTransportError) { + return
Failed to connect: {chatTransportError.message}
; + } + const isStreaming = status === 'submitted' || status === 'streaming'; + const stop = () => { + const activeRun = session.view.runs().find((run) => run.status === 'active'); + if (activeRun) void session.cancel(activeRun.runId); + }; + return (
{messages.map((msg) => ( @@ -164,7 +171,7 @@ export function Chat({ chatId }) { ## Wire it together -Create `app/page.tsx`. `Providers` sets up an authenticated Ably client. [`ClientSessionProvider`](/docs/ai-transport/api/react/core/providers) constructs the underlying [`ClientSession`](/docs/ai-transport/api/javascript/core/client-session) bound to the channel. +Create `app/page.tsx`. `Providers` sets up an authenticated Ably client. [`ChatTransportProvider`](/docs/ai-transport/api/react/vercel/chat-transport-provider) constructs the underlying [`ClientSession`](/docs/ai-transport/api/javascript/core/client-session) bound to the channel and the [`ChatTransport`](/docs/ai-transport/api/javascript/vercel/chat-transport) over it. It POSTs invocations to `/api/chat` by default, matching the agent route above; set `api` to point elsewhere. Update `channelName` to match a namespace with the AIT [channel rules](/docs/ai-transport/getting-started/channel-rules) configured. @@ -175,8 +182,7 @@ Update `channelName` to match a namespace with the AIT [channel rules](/docs/ai- import { useEffect, useState } from 'react'; 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 { ChatTransportProvider } from '@ably/ai-transport/vercel/react'; import { Chat } from './chat'; function Providers({ children }) { @@ -193,12 +199,11 @@ function Providers({ children }) { } export default function Page() { - const chatId = 'conversations:my-chat-session'; return ( - - - + + + ); } From 953cd9eb3d806c5d6cf302ec796111a154f49ffb Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 30 Jun 2026 22:55:24 +0100 Subject: [PATCH 2/3] docs(ai-transport): surface the channel-rule requirement on every entry point The mutableMessages channel rule was only documented on the dedicated channel-rules page and buried as one inline line in the tutorials. Add a prominent "Configure the channel rule" step (heading + callout) to the Vercel and Core SDK getting-started guides, and cross-link the channel-rules page from the overview and both framework pages. Also correct the Core SDK Node prerequisite to 22+. --- .../ai-transport/frameworks/vercel-ai-sdk-core.mdx | 4 ++++ .../ai-transport/frameworks/vercel-ai-sdk-ui.mdx | 4 ++++ .../docs/ai-transport/getting-started/core-sdk.mdx | 12 +++++++++++- .../ai-transport/getting-started/vercel-ai-sdk.mdx | 10 ++++++++++ src/pages/docs/ai-transport/index.mdx | 4 ++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-core.mdx b/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-core.mdx index 841c2bfad2..f5a7b2303a 100644 --- a/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-core.mdx +++ b/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-core.mdx @@ -9,6 +9,10 @@ intro: "Vercel AI SDK Core gives you streamText for orchestrating LLMs on the se Ready to build? See [Get started with Vercel AI SDK](/docs/ai-transport/getting-started/vercel-ai-sdk). + + ## What Vercel AI SDK Core brings | Capability | Description | diff --git a/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-ui.mdx b/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-ui.mdx index 7571e99ba3..9d06816657 100644 --- a/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-ui.mdx +++ b/src/pages/docs/ai-transport/frameworks/vercel-ai-sdk-ui.mdx @@ -11,6 +11,10 @@ redirect_from: Ready to build? See [Get started with Vercel AI SDK](/docs/ai-transport/getting-started/vercel-ai-sdk). + + ## What Vercel AI SDK UI brings | Capability | Description | diff --git a/src/pages/docs/ai-transport/getting-started/core-sdk.mdx b/src/pages/docs/ai-transport/getting-started/core-sdk.mdx index 32849f8f6d..6d11529c04 100644 --- a/src/pages/docs/ai-transport/getting-started/core-sdk.mdx +++ b/src/pages/docs/ai-transport/getting-started/core-sdk.mdx @@ -18,7 +18,7 @@ To use AI Transport with Vercel's `useChat` for message management, see [Get sta ## Prerequisites -- Node.js 20 or later. +- Node.js 22 or later. - An [Ably account](https://ably.com/sign-up) with an API key. - An Anthropic API key, or any other model provider you prefer. @@ -36,6 +36,16 @@ Create an auth endpoint at `/api/auth/token` that returns an Ably JWT to the cli The client below uses `authUrl: '/api/auth/token'` to fetch tokens from this endpoint. +## Configure the channel rule + +AI Transport streams each response by appending tokens to a single channel message. That requires the **Message annotations, updates, deletes, and appends** channel rule (`mutableMessages`) on the namespace your conversations live on. + +In your Ably dashboard, enable **Message annotations, updates, deletes, and appends** on the `conversations` namespace. See [Configure the channel rule](/docs/ai-transport/getting-started/channel-rules) for the dashboard, Control API, and CLI steps. + + + ## Create the agent route Create `app/api/chat/route.ts`. The agent receives an [Invocation](/docs/ai-transport/concepts/invocations), creates an [AgentSession](/docs/ai-transport/api/javascript/core/agent-session), starts a [Run](/docs/ai-transport/concepts/runs), hydrates the conversation, pipes the LLM stream, and ends the Run. diff --git a/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx b/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx index bb7affba61..5156d0d703 100644 --- a/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx +++ b/src/pages/docs/ai-transport/getting-started/vercel-ai-sdk.mdx @@ -42,6 +42,16 @@ Create an auth endpoint at `/api/auth/token` that returns an Ably JWT to the cli The client below uses `authUrl: '/api/auth/token'` to fetch tokens from this endpoint. +## Configure the channel rule + +AI Transport streams each response by appending tokens to a single channel message. That requires the **Message annotations, updates, deletes, and appends** channel rule (`mutableMessages`) on the namespace your conversations live on. + +In your Ably dashboard, enable **Message annotations, updates, deletes, and appends** on the `conversations` namespace. See [Configure the channel rule](/docs/ai-transport/getting-started/channel-rules) for the dashboard, Control API, and CLI steps. + + + ## Create the agent route Create `app/api/chat/route.ts`. The agent receives an [Invocation](/docs/ai-transport/concepts/invocations), creates an [AgentSession](/docs/ai-transport/api/javascript/core/agent-session) pre-bound to `UIMessageCodec`, starts a Run, hydrates the conversation, pipes the LLM stream, and ends the Run. diff --git a/src/pages/docs/ai-transport/index.mdx b/src/pages/docs/ai-transport/index.mdx index 6e2a80383b..5cc184cd5a 100644 --- a/src/pages/docs/ai-transport/index.mdx +++ b/src/pages/docs/ai-transport/index.mdx @@ -46,6 +46,10 @@ AI Transport is for conversations between a user and an AI agent. If you are bui ]} + + ## Read next - [Concepts](/docs/ai-transport/concepts): the building blocks (sessions, turns, transport, codec, conversation tree, infrastructure). From 47be22c6da1345eb5315edfe5152571c8d145529 Mon Sep 17 00:00:00 2001 From: owenpearson Date: Tue, 30 Jun 2026 23:04:25 +0100 Subject: [PATCH 3/3] add 93002 to ai transport error codes doc --- src/pages/docs/ai-transport/api/errors.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/docs/ai-transport/api/errors.mdx b/src/pages/docs/ai-transport/api/errors.mdx index e3597de0d1..a9b8c7ec58 100644 --- a/src/pages/docs/ai-transport/api/errors.mdx +++ b/src/pages/docs/ai-transport/api/errors.mdx @@ -63,6 +63,7 @@ Auth and channel errors come from the Ably platform, not AI Transport. The most | 40300 | Forbidden. | The token is valid but not authorised for this resource. | | 80000 | Channel attach failed. | Check the channel name and capability. | | 90000 | Internal channel error. | Retry the operation. If the error persists, contact support. | +| 93002 | `Can only update/delete/append messages on channels with mutableMessages enabled`. The namespace lacks the `mutableMessages` rule, so AI Transport cannot append stream tokens. This is the most common AI Transport setup failure. | Enable the **Message annotations, updates, deletes, and appends** rule on the namespace. See [Configure the channel rule](/docs/ai-transport/getting-started/channel-rules). | The full Ably error code list lives at [Ably error codes](/docs/sdks/error-codes).