Skip to main content
Not all agent work is triggered and structured — a lot of it starts as a question. Chat in the Komodor Agentic Operation Platform (KAOP) is a conversation with a real agent, not a generic model wrapper, and every turn is recorded with the same evidence as any other run. This page covers how chat works, what the transcript shows you, and how History ties conversations and runs into one timeline.

Two kinds of record, one timeline

KAOP keeps two session-like records, and they answer different questions: History presents both in one ledger, newest first. A chat row resumes the conversation; a run row opens the evidence.

Chatting with an agent

The responses in a chat come from an agent’s worker — the same worker that would serve any other invocation — so an agent answers in chat with the tools, permissions, knowledge, and skills it has everywhere else. The built-in chat assistant is available from the start, and any agent you register joins the chat picker by advertising chat capability on its agent card:
In Fleet, a chat-capable agent gets chat actions alongside Run; an agent that does not advertise chat keeps the structured run-and-evidence flow. The capability is checked on every send, not only when a session is created, so an agent that stops advertising chat also stops serving sessions that already exist. You can switch the model for a session from the chat header. The list is curated by the control plane rather than free text, and every requested model is validated.

What a turn actually does

Sending a message is not a shortcut around the platform — it goes through it:
1

Your message is persisted

Before anything is invoked, so a refresh mid-answer never loses what you asked.
2

The session's agent is invoked, as a run

The turn creates an ordinary run against that agent, marked as a chat turn and carrying the session it belongs to.
3

The reply streams back as it is produced

Incremental text, including for agents that are only reachable over their live worker connection.
4

The assistant message is persisted, and the run keeps its evidence

The conversation is resumable, and the turn’s traces, logs, and tool calls are available exactly as they would be for any other invocation.
The consequence worth internalising: a chat answer is as auditable as a scheduled one. There is no lower-fidelity path for conversational work.

Tool calls and evidence in the transcript

The transcript is the primary object, not a chrome-free chat box. As an agent works, what it does appears inline:
  • Tool calls render as their own rows — which tool, with what arguments, and what came back — interleaved with the agent’s narration in the order they happened.
  • Consecutive tool calls are grouped into rounds, so parallel calls issued in one model turn read as one round of work rather than a flat list, and each result stays with the call it answers.
  • Data the agent pulled and drafts it produced appear as their own transcript entries rather than being flattened into prose.
  • Timestamps are stamped when an event is emitted, not when it reaches the control plane, so the order and spacing you read is the order and spacing that happened.
History’s own list shows a per-run tool-call count alongside each row, counted once per tool call. For the full trace tree, the logs, and the artifacts behind a turn, open its run — see Runs & evidence.

Resumable sessions

Sessions are addressable, so you can bookmark one or send someone a link to it: Resuming is not a replay: the transcript is loaded from the control plane with each message’s status, so a session reopens in the state it was actually left in — complete, errored, or interrupted. You can rename a session, change its model, or delete it.

Waiting for a worker

A turn’s run is created queued and claimed by a worker, which means a chat can be waiting on capacity rather than on the model. That wait is stated rather than shown as a frozen cursor, and it travels on the stream as its own frames. The streaming endpoints emit text/event-stream frames:
The two transport frames behave in ways worth knowing if you are building against the API:
  • queued_behind is a queue position, not a duration — the number of runs for the same agent that a worker would claim before this one. 0 therefore means nothing is ahead of it: the wait is for a worker to come free or come online, not for a queue to drain.
  • The frame is resent whenever that position changes, so a client can count it down. A queue that is not moving sends nothing.
  • Nothing is sent for the wait’s first look at the run. Every run starts out queued, so reporting the first look would put a queue notice in front of the reader on every single message. The trade-off is deliberate: the notice appears one poll into a real wait rather than instantly.
  • dequeued marks the end of the wait, sent when a worker claims the run. A claimed run is still silent while it starts up and thinks, so the end of the wait has to be announced or the notice outlives the queue.
  • A queued run that never reaches a worker sends no dequeued. Cancelled or failed outright, there was no handoff to report, and the terminal frame that follows carries its own content.
Neither frame carries assistant text. Render both as transport state — a status line, a spinner label — and never as part of the reply. Folding them into the message persists them into the transcript, where they get replayed on every reload.
Errors arrive as {"type":"error","message":"…"} in place of the terminal message frame.

When an agent cannot answer

A failure is shown, not swallowed. When a turn cannot produce an answer — a model-provider billing, credential, or rate-limit problem, or a worker runtime failure — the transcript renders an error card explaining what went wrong and who can fix it, instead of an empty reply. The underlying run keeps its classified failure alongside whatever evidence it collected first.

Continuing from a run

A finished run’s page carries a composer beneath its output: Continue this investigation. You type a follow-up, pick who answers, and pick where it continues.
  • In KAOP chat. The new session opens as a real transcript rather than one machine-formatted prompt: the run’s own input becomes the prior user turn, its output — or, for a failed run, its failure reason — becomes the prior assistant turn, and your follow-up is the next message. A trailing line names the run so the agent can fetch its full transcript, logs, and trace rather than working from an excerpt.
  • By re-running the agent. When the run saved a session snapshot it is revivable: Re-run the agent re-executes it with its tools and the earlier context, producing a new run in the same thread. That is different from talking about the run, and it is the right choice when you want the work redone rather than explained.
  • By handing it to a local coding agent. Claude Code or Codex, or the prompt copied to your clipboard. These handoffs carry only your follow-up, the run id, and the run’s URL — never the evidence itself. The coding agent fetches the run over the KAOP MCP server under your own permissions, so nothing sensitive lands in shell history or a clipboard manager. See Connect coding agents.
Any chat-capable agent may answer, defaulting to the run’s own agent when it can chat. When a different agent has to answer instead, the composer says so inline — the substitution is never silent.

The History ledger

History combines chat sessions and runs, newest first, and filters by type (all, chats, runs), run status, agent, and free-text search. Two behaviors to know:
  • Chat rows absorb their turns. The per-turn runs behind a conversation are folded into the session’s row rather than listed a second time, so a long chat does not bury everything else.
  • The list is capped, and says so. When a page comes back full, the table prints a truncation notice rather than implying you are looking at everything. Search is evaluated on the server — over run and session ids, a row’s title, and the agent’s display name or slug — so looking for something older than the current page finds it.

Chat API

Chat endpoints live under /api/v1/chat: You can pass a friendly agent slug wherever an agent_id is expected — KAOP resolves it to the agent’s stable id.

Next steps

Runs & evidence

The evidence behind every chat turn.

Build from scratch

Make your own agent chat-capable.

Channels

The same conversational pattern, in Slack.

Connect coding agents

Hand a run to Claude Code or Codex with your own permissions.