← All posts

Agents live in chat - the thread is the task

Message an agent in a DM, or name it in a channel, and that thread becomes the task. The agent's work, its state and the decision on anything it cannot undo all sit under the message that asked for it.

Oct 19, 2026 · 10 min read · Kash Gohil · LinkedIn · X

Until this week, working with a Rezee agent happened in two places. You asked in chat, and a mention got a short reply loop of a few turns. When the work needed more, or reached an action that needs a person, the agent created a separate task. Then it replied with a link. The task lived on a page under Agents. Nobody else in the room saw it.

That split was our decision, and we wrote down why. A chat message did not seem like the right place for a state machine. And two places to approve something is how one of them ends up weaker than the other. The second half of that argument still holds. The first half did not survive contact with how people actually work. They talk to agents where they talk to each other, and a page in another part of the app is a page nobody watches.

So we moved the task into the conversation. A task now has a home thread in chat. The thread draws the task, shows what it is doing, and holds the decision. There is still exactly one gate.

A DM to an agent is a task

Open a DM with an agent and write to it. You do not need an @. Saying something directly to an agent is asking it.

Say kash opens a DM with kobeni and writes:

Take REZ-42. The sandbox RFC says what the shape should be.

That message becomes the root of a task, and the thread under it is the task. Each top-level message in the DM starts its own task. One DM can hold several pieces of work side by side without mixing them up. One thread holds one task, and the database enforces it.

A reply in the thread is said to the task. It is not stored as a chat message. It becomes a turn in the task's own record, the same record the agent reads when it resumes. Three things follow from that:

  • A reply while the agent works is a correction. It picks the reply up mid-run.
  • A reply to a finished, failed or stopped task sends it back to work, with everything it already read.
  • A reply to a question the agent asked is the answer, and the run carries on from where it stopped.

A group DM behaves like a channel. A message there is said to the room, and an agent in it acts when somebody names it.

A mention in a channel makes that thread a task

In a channel, you name the agent. Say aki writes this in #security:

@kobeni Rotation is REZ-48. Take the sandbox side once web#131 lands.

The task is homed in that message's thread. If aki wrote it inside an existing thread, the task takes that thread instead. The agent gets the conversation with the prompt: up to ten earlier messages, oldest first, each cut to 500 characters. It reads the thread's messages when the mention is in a thread, and the room's messages when it is not. "Take the sandbox side" means nothing without the lines above it.

Some edge cases had to have an answer:

  • Two agents named in one message. The first one named takes the thread. Each of the others opens its own thread in the same room. Its short root says "Picking up @aki's message from above."
  • A thread that already holds a task. Anybody newly named there works in a new thread, because one thread holds one task.
  • An edited message. Only the handles the edit added start work. An agent that already has the message is not asked twice.
  • A message from an agent. It starts nothing. A task needs a human delegator for its gate to ask, and one agent handing work to another is a handoff, which already exists.
  • A message from a guest. The @ still highlights, and the agent still sits in the room. It does not take a guest's sentence as an instruction. The agent's tools reach the whole workspace, and anybody in a shared room can type "ignore your instructions".

Mentions in doc comments and in review threads work as before. We want to see what chat tasks cost before we move those too.

The thread draws the task the way its page does

The task page and the thread now use one component to draw a task. It is shaped like chat on purpose. A run of steps from one author is one message. The tool calls between two of the agent's sentences fold into one card. A proposal carries its decision inside it.

Nothing is copied into chat to make this work. The thread renders the task's step record directly. That record is the one the approval gate post describes, and it is the only one. The page and the thread cannot disagree, because there is nothing to disagree about.

The box under the thread changes with the task's state, because each state asks for a different thing:

  • While it works: "Add something for @kobeni while it works"
  • After it finishes: "Reply to @kobeni, and it picks the task back up"
  • When it has asked a question: "Answer @kobeni, and it carries on"
  • When it waits for a decision, there is no box. The line reads "Approve or reject the proposal above, and the task carries on."

The thread header has two more controls: stop the task, and open the task page.

More people can read a thread than can open the work behind it. A task is reachable through every repository, project and doc it names, and a task that names none of them is every member's. A reader who cannot open the task sees one line under the root, "A task you cannot open", and nothing else.

The state, under the message and in the rail

Under the root message, one line says what the task is doing, from the reader's side:

  • kobeni is working
  • kobeni needs your approval to the person who delegated it, and is waiting for approval to everybody else
  • kobeni has a question for you, or asked a question
  • finished, failed, was stopped, ran out of credit

The line moves on the same workspace update that moves the task, so you do not reload anything.

Task steps are not chat messages, so they never make a room unread. A busy agent would otherwise light up the sidebar all day. Instead, the chat rail shows a second count beside the unread count: the tasks in that room that wait on you. Two states count, a proposal for you to decide and a question for you to answer. Nothing else does.

Work that starts elsewhere lands in a DM

Not every task starts in chat. An agent can take an assigned issue or watch for failed CI runs and pushes. It can run on a schedule, work from a doc or a board, or take a handoff from another agent. Each of those tasks now gets a thread in the DM between its agent and the person who delegated it.

The root says where the work came from. When kobeni watches CI and run 1a9d fails on runner, kash's DM with kobeni gets:

From a failed CI run: run 1a9d on runner

That root is quiet. It is marked read for the delegator as it is written, so an agent that watches CI does not turn a DM into a log. The waiting count in the rail is what speaks, and only when the task needs that person. For work an agent starts on its own, the delegator is the person who set the agent up, not whoever pushed the commit.

Every task is now answered the same way, wherever it came from.

Approving in the thread

Here is the full loop. kobeni works REZ-42 in kash's DM. It reads the issue, writes the masking change, and opens web#131. Opening a pull request changes nothing that cannot be changed back, so the agent does it without asking. Then it wants to merge web#131. Merging is gated, so the agent stops.

The thread shows a proposal card. It reads "Waiting for approval" above the agent's own description of the step. Below that are the tool in plain words ("Merge a pull request"), its target, and the full arguments behind a disclosure. While the task waits, Rezee deletes the agent's access token. Under kash's root message the line changes to "kobeni needs your approval". The DM gets a waiting count in the rail, and kash gets an Inbox line and a push notification.

kash now has two choices:

  1. Approve. The merge runs, and the task carries on.
  2. Reject. A box asks kash to tell @kobeni why. The reason is optional. A reason goes into the task as kash's turn, and a "Remember this" checkbox appears. Tick it, and kobeni carries that sentence into every future task.

The buttons in the thread call the same routes as the buttons on the task page. Behind both is one function that checks every decision. It allows the person who delegated the task, or somebody who can manage the workspace. It never allows an agent, even one with an admin role. It also requires that the person can open the task, because a decision is about what the task did. A reader who cannot decide sees "Waiting for @kash or a workspace admin to decide." While the proposal waits, the thread refuses replies. The task needs a decision first.

Which actions stop for a person

The gate is a fixed list in code, not the agent's own judgment. Each tool in Rezee's catalogue is classed as read, write or irreversible. A write is something a person can change back inside the workspace. An irreversible tool has effects that leave the building. Today that is sixteen tools:

  • Code: merge a pull request. Merge or restack a stack of pull requests, and retry or cancel either job. Accept a conflict resolution.
  • Ship: start a pipeline against a ref, re-run a pipeline, start a release train.
  • Design: create a public share link, merge a design branch into its board.
  • Docs: publish a document to the internet.
  • Agents: approve another task's proposal, accept a suggestion.

A test in CI checks this list against the tools the server actually declares, so the two cannot drift apart without a failed build. A workspace can let one named agent take specific gated tools without review, in that agent's definition. The default is that every one of them asks.

Agents Activity is now the history

The Activity tab under Agents used to be where you went to watch and approve. The thread does that now, so Activity became the history of every task you can reach. You can filter it by state (Waiting, Working, Finished), by agent and by origin. A row opens the task's chat thread, where you can answer it. A task from before threads existed has no thread, and its row opens its page.

On the phone

The phone app draws the same thing. A thread whose root started a task shows the task view, with the root message on top in place of the prompt. The state line sits under the root in the room. An approval notification opens the task directly, so a decision is a couple of taps from the lock screen.

MCP clients get it too. The chat tools now describe this behaviour. When an assistant posts a reply into a task's thread, the answer tells it the reply went to the task, not the channel. A client that only knows chat still reaches the agent. More on connecting your own tools is on the MCP page.

What it does not do yet

  • Agents on your own runtime. A DM starts a task only for an agent that Rezee runs. An external runtime claims tasks, but nothing tells it a DM waits for it yet.
  • Files. A task takes words. A reply with an attachment in a task thread is refused.
  • Guests. A guest can read a task thread in a shared channel but cannot answer it.
  • Agents talking to each other in a channel. Handoff covers that, and we did not want two ways to do it.

FAQ

Do I need to @mention an agent in a DM?

No. In a one-to-one DM with an agent, every top-level message starts a task. A reply in that message's thread goes to the same task. In a channel or a group DM you name the agent with @, because there the message is said to the room.

Can a teammate approve a task I delegated?

Only if they can manage the workspace and can also open the task. Otherwise they see the proposal and a line saying who it waits for. An agent can never approve, whatever role it holds.

Is the old task page gone?

No. It draws the same transcript as the thread and calls the same routes, and the thread header links to it. Activity opens the thread first because that is where the conversation is. For how agent identity and the gate work underneath, see agents are just users and the approval gate.