The best apps are becoming places where people and AI work together in realtime. We built an AI slideshow editor as an example of this future, a tool featuring agent presence, multiplayer editing, AI comments, and more.
Increasingly, the best software is built around collaboration: people and AI
agents working together in the same documents, in realtime. Live presence,
conflict-free editing, comments, and notifications are becoming the baseline for
modern productivity apps, and not just extras bolted on at the end.
To show what that future looks like, we built an AI slideshow editor. It’s one
example of this new kind of app—a shared canvas where humans and agents
collaborate, each able to see and build on the other’s work as it happens.
In the apps of the future, agents won’t run as invisible background jobs—they’ll
be participants you can watch working alongside you. When an AI makes a change,
every connected user should feel their presence and see their modifications
happen in realtime, like you would with a human collaborator.
Live presence is the first thing that makes a productivity app feel alive, and
in this future it applies to agents too. Any server-side workflow or agent
should be able to connect to your app, make changes, and broadcast where it
is—so everyone can see what it’s working on, not just the result when it’s done.
Presence is especially simple with Liveblocks, and can be slotted into any
workflow and app in minutes. Let’s take a look a simple example of an agent
editing a title field.
To build this, call
setPresence
from your back end with the agent’s information and presence data, and it
appears live in the room like any other user.
In the front-end, you can fetch the agent’s presence data with
useOthers, and render custom
presence UI with it. useOthers returns a list of every connected users, so
we’ll filter the results to only return the agent.
functionAgentPresence(){const others =useOthers();const agent = others.find(({ id })=> id ==="agent-123"); // { editing: "title-1", status: "Thinking…" }console.log(agent.presence); return<Cursorpresence={agent.presence}/>;}
For humans and agents to coexist in the same document, you need a sync engine.
Editing the same data simultaneously, without overwriting each other’s work, is
hard—and it’s the problem every productivity app eventually runs into.
With one in place, any number of humans and agents can work together at once.
Each change is merged and resolved automatically, so nobody’s edits get lost—no
matter how many collaborators, human or otherwise, are in the room. The best
sync engines capture the intent behind every change, not just the final state—so
when you change the theme, the text someone else is editing stays untouched.
Liveblocks Storage
is our sync engine designed to power apps like Pitch and Figma, and it works by
using the intent behind changes to automatically merge conflicting changes into
a coherent state. In the slideshow editor, the slides, text elements, and themes
all live in Storage.
To change a background color, like in the video above, fetch the current
background color with
useStorage, and create a
function to change it with
useMutation.
You can also make modifications to Liveblocks Storage from the server with
mutateStorage, which is
how agents edit the same document as your users.
const{ text: background }=awaitgenerateText({ model:openai("gpt-5.5"), prompt:`Select a background hex code. User prompt: ${prompt}`,}); await liveblocks.mutateStorage("my-room-id",async({ root })=>{ root.set("background", background);});
All changes made from the client or server are sent in realtime to every
connected user, and conflicts are automatically resolved. Learn more in our
documentation under
get started with multiplayer editing.
AI without context is rarely useful. Ask an agent to “make this larger” in a
generic chat window and it has to guess what “this” is, and a confident wrong
guess is worse than no answer at all. Additionally, when AI work together with
humans, it’s particularly helpful to read the conversation before the agent was
called into action.
Commenting sections are a natural interface for requesting work, whether from an
agent or a teammate. Threads can be anchored to specific elements on the page,
so “this” is never ambiguous, and the AI has the context it needs from the
conversation to work effectively.
Our Comments components provide ready-made commenting you can
integrate into your app. With
useThreads, you can fetch
the threads in the current room, and render them with the
Thread component.
Users can create new threads with
Composer. To attach a new
thread to a specific element on the page, you can use metadata to reference the
element. You can also add the AI assistant as a user you can @ mention inside
the composer, helpful for triggering the request.
To pass the thread’s context into the agent, use
getThread
in your back end.
const thread =await liveblocks.getThread("my-room-id","thread-123"); const{ text }=awaitgenerateText({ model:openai("gpt-5.5"), prompt:` A user requested a change, see the latest message. The thread is anchored to ${thread.metadata.element}.`, messages: thread.comments.map((comment)=>({ role: comment.user.id ==="agent-123"?"assistant":"user", content: comment.text,})),});
Additionally, when a user is tagged in a comment, instead of an agent, they’ll
receive a new
notification in their
inbox. The same primitives that power agent collaboration power human
collaboration too.
AI agents are becoming native users of software. They need to read, write, and
coordinate inside the same documents as humans, with the same presence,
conflict-free editing, and comments that people rely on. The slideshow editor is
just one example—the same foundation works for design tools, docs, whiteboards,
dashboards, and anything else people build together.
The apps that get this right will feel like the future. The ones that don’t will
feel like single-player tools with a chatbot bolted on.