By Nathan Tarbert
September 10, 2026

One agent, three surfaces: Slack, Teams, and React

Most teams build the agent three times.

One for the web app. One for the Slack bot. One for Teams. Three codebases, three sets of tools, three places for the behavior to quietly drift apart until a user asks the same question in two places and gets two different answers.

The agent was never the hard part. The surfaces are.

In this session, Tyler Slaton wires up an agent once with CopilotKit and AG-UI, then ships it into three places people already work. Same brain, same tools, same state — one agent with three front doors. Recording is at the top of this post. Very few slides, mostly code.

Why the surfaces are the expensive part

Look at what usually happens when an agent goes multi-surface.

You start with the web app, because that's where you can control the whole experience. You build a chat panel, stream tokens into it, render some custom components when the agent calls a tool, and wire up an approval flow so nobody's agent books a flight unsupervised.

Then someone asks for it in Slack. Slack has its own event model, its own Block Kit UI, its own idea of what an interactive message is. None of your React components come with you. So you write an adapter. Then you write a second approval flow, because Slack's buttons post back through a completely different path than your web app's did. Then Teams shows up with Adaptive Cards and a different auth story, and you write it a third time.

Now you have three implementations of the same agent behavior, and the interesting bugs live in the seams. A user approves an action in Slack; the web app still shows it as pending. The agent asks a clarifying question in Teams and has no idea it already asked the same thing an hour ago in the browser. Every surface has its own partial view of the truth.

That's the problem AG-UI exists to solve. The agent emits a stream of typed events — messages, tool calls, state deltas, requests for input — and each surface is responsible for one thing: rendering those events in its own native idiom. The agent doesn't know or care whether it's talking to a React app or a Slack thread.

What is covered

Connecting an agent to a React frontend. The starting point, and the fastest way to see what the protocol is doing for you. Streaming, tool call lifecycle, state sync, interrupts — all of it comes over AG-UI rather than being something you hand-roll on top of a raw model API. Worth watching even if React is the only surface you care about, because it makes the event stream legible.

Taking that same agent into Slack and Teams without a rewrite. This is the part most people want to see, and the honest version of it is about where the surface-specific code starts and stops. There is some. It's smaller than you'd guess, and it lives at the rendering edge — not in your agent, not in your tool definitions, not in your state.

Generative UI per surface. The agent doesn't return walls of text. It returns components, and each platform renders them in its own native form: an approval card in Slack, a scheduler grid in Teams, a full generative UI panel in React. Same agent event, three renderings. This is the difference between an agent that feels bolted onto a chat window and one that feels like part of the product.

Human in the loop across surfaces. A user can approve, reject, or edit an action from wherever they happen to be — and the agent sees one decision, not three. If someone approves in Slack, the React panel reflects it. There's no reconciliation logic you have to write, because there was never more than one decision to reconcile.

Shared state for the web, threads context in channels between the agent and every surface. Tyler flags this as the part most implementations get wrong, and it's the right thing to flag. Multi-surface agents fall apart on state, not on transport. When each surface keeps its own copy of what the agent is doing, they diverge — and users are very good at noticing.

Why this matters

If you're running an agent in production on one surface and someone has already asked "can we get this in Slack?", this session is the shape of the answer.

If you're earlier than that — still deciding how to structure the agent — it's arguably more useful now than later. The cost of going multi-surface is mostly determined by decisions you make before you ship the first one. Agents built around a protocol boundary extend cheaply. Agents built around a specific UI get rewritten.

If you're evaluating AG-UI and want to know what the protocol actually buys you rather than what a spec document claims, watching one agent get three front doors in real time is a decent test.

Get started

Everything in this session is open source, and you can run the same setup locally.

If you're wiring an agent into a surface we didn't cover, or you hit a seam we didn't hit, tell us about it in our communities.

Want to bring CopilotKit into your stack? Talk to our engineers and we'll help you set it up.

Follow CopilotKit on Twitter for updates. If you get stuck, reach out in the CopilotKit or AG-UI communities.

Are you ready?

Stay in the know

Subscribe to our blog and get updates on CopilotKit in your inbox.