{"slug": "introducing-ai-transport-v0-3-0", "title": "Introducing AI Transport v0.3.0", "summary": "Ably released AI Transport v0.3.0, adding first-class support for presence and LiveObjects to AI sessions, enabling real-time visibility of online participants and synchronized shared state. The update also introduces a declarative codec interface, moving event ordering and de-duplication into the transport layer.", "body_md": "Last week we [introduced AI Transport v0.2.0](https://ably.com/blog/introducing-ai-transport-v0-2-0) and made one idea the centre of the design: **the session is the channel**. Every input, output, and lifecycle event for an AI conversation is just a message published to an Ably channel, which is what makes a session durable, multi-party, and resumable.\n\nIn v0.3.0, we added first-class support for [presence](https://ably.com/docs/ai-transport/features/agent-presence) and [LiveObjects](https://ably.com/docs/ai-transport/features/liveobjects) to AI sessions, allowing you and your agent to see who's online and update shared state in real time.\n\nWe made the codec interface declarative, moved event ordering and de-duplication into the transport. Now you can write a codec as a simple description of the wire format, and the transport will handle reordering, de-duplication, and replay for you.\n\n## See who's online with presence\n\nThe presence object is just the same [presence API](https://ably.com/docs/presence-occupancy/presence) you know from Ably Pub/Sub. The client and agent session objects now expose it as `session.presence`\n\n, so you can enter, leave, and subscribe to presence events on the session's channel:\n\n``` js\nconst session = createClientSession({ client: ably, channelName });\n\nawait session.presence.enter({ role: 'user' });\n\nsession.presence.subscribe((member) => {\n  console.log(member.clientId, member.action); // 'enter' | 'leave' | ...\n});\n```\n\nAgents and users enter the same set, distinguished by `clientId`\n\n, so \"is the agent online?\" and \"who else is watching this conversation?\" are all answered by the same API. You can also use presence data to update per-participant state which other clients can see in realtime, like a \"typing...\" indicator or a cursor position in a shared document.\n\nOur ably-js presence React hooks work out-of-the-box in a SessionProvider. The session providers now mount an ably-js `<ChannelProvider>`\n\nfor the session's channel, so ably-js's own `usePresence`\n\nand `usePresenceListener`\n\nhooks just work for any component underneath:\n\n```\nfunction OnlineList() {\n  usePresence({ channelName: 'ai:demo' });\n  const { presenceData } = usePresenceListener({ channelName: 'ai:demo' });\n\n  return (\n    <ul>\n      {presenceData.map((m) => <li key={m.clientId}>{m.clientId}</li>)}\n    </ul>\n  );\n}\n```\n\n## LiveObjects for the state that lives next to the chat\n\nSome state belongs in the conversation; some lives beside it. A document the agent is editing, task progress, votes, settings. [LiveObjects](https://ably.com/docs/liveobjects) enables synchronized shared state on the same channel as the conversation. Sessions now expose it as `session.object`\n\n.\n\n``` js\ntype SessionState = { status: string };\n\nconst root = await session.object.get<SessionState>();\nawait root.set('status', 'reviewing');\n\nroot.subscribe(() => {\n  console.log(root.get('status').value());\n});\n```\n\nThe API is symmetric, an agent can publish structured state mid-run (progress, a todo list, a shared document, client selection state) and every client on the session sees it update live or can update it themselves, with late joiners synced on attachment.\n\nUnlike presence, LiveObjects isn't enabled by default. Object operations need channel modes that aren't in Ably's default set, and the LiveObjects plugin needs to be loaded, see [Enable LiveObjects](https://ably.com/docs/ai-transport/features/liveobjects#enable).\n\n## Codecs are now declarative\n\nA codec teaches the transport your wire format: how to encode and decode events. In v0.2.0 that meant writing a reducer that also had to de-duplicate against the stream's high-water-mark and reason about event ordering. That's exactly the kind of thing the transport should own, not you.\n\nSo we moved it. **Event ordering, de-duplication, and replay now live in the transport**, and codecs are written with a new declarative `defineCodec`\n\nAPI plus a small set of header-field helpers. You describe the inputs, outputs, and headers; the transport folds each node in canonical serial order behind the scenes:\n\n``` js\nimport { defineCodec, strField, enumField } from '@ably/ai-transport';\n\nconst codec = defineCodec<MyInput, MyOutput>()({\n  reducer: { init, fold, getMessages },\n\n  // Outputs the agent streams back: a chunked text family, then a discrete \"finish\".\n  output: (b) => [\n    b.stream('text', { start: 'text-start', delta: 'text-delta', end: 'text-end' }),\n    b.event('finish', { fields: { reason: enumField('reason', 'stop', 'length') } }),\n  ],\n\n  // Inputs the client publishes.\n  input: (b) => [\n    b.event('user-message', { fields: { role: strField('role') } }),\n  ],\n});\n```\n\nSee [our codec interface docs](https://github.com/ably/ably-ai-transport-js/blob/main/docs/internals/codec-interface.md) for further information.\n\n## Get started\n\nAI Transport v0.3.0 is available now:\n\n```\nnpm install @ably/ai-transport\n```\n\n**Read the docs**—[Presence](https://ably.com/docs/),[LiveObjects](https://ably.com/docs/liveobjects), and the codec interface.** See the source**—[ably/ably-ai-transport-js](https://github.com/ably/ably-ai-transport-js).** Sign up free**— 6M messages a month on the free tier.\n\nWe're excited to see what you build.", "url": "https://wpnews.pro/news/introducing-ai-transport-v0-3-0", "canonical_source": "https://ably.com/blog/introducing-ai-transport-v0-3-0", "published_at": "2026-06-23 16:24:13+00:00", "updated_at": "2026-06-24 00:09:22.942927+00:00", "lang": "en", "topics": ["ai-tools", "ai-infrastructure", "ai-agents"], "entities": ["Ably", "AI Transport", "LiveObjects", "SessionProvider", "ChannelProvider"], "alternates": {"html": "https://wpnews.pro/news/introducing-ai-transport-v0-3-0", "markdown": "https://wpnews.pro/news/introducing-ai-transport-v0-3-0.md", "text": "https://wpnews.pro/news/introducing-ai-transport-v0-3-0.txt", "jsonld": "https://wpnews.pro/news/introducing-ai-transport-v0-3-0.jsonld"}}