Conversation
The actual chat with an Agent. This is where every prompt the Consumer sends triggers a flow run.
URL shape
/c/cmncvl3u50000o77w4p2u0xpc/cmocx3yf90001od7wyz5j08zl
│ │
│ └─ agent ID (cuid) — same value as the Agent ID in /org
└─ space ID (cuid)
What's on the page
- Empty-state heading when no messages yet: "Start a conversation with
<Agent Display Name>". - Message input bar at the bottom — "Type a message…" placeholder.
- Action icons in the input bar (left to right):
- Undo ↶
- Redo ↷
- Copy ⎘
- AUTO 🌐 — language / mode toggle (defaults to AUTO; lets the user pick a specific behaviour, TBD exact options)
- Microphone 🎤 — voice input
- Send ➤ (paper-plane icon)
The exact behaviour of each icon (what AUTO toggles between, what voice input produces) needs to be confirmed by stepping through the live UI.
What happens when the Consumer sends a message
Behind the scenes:
- The Consumer's message is sent to the Keen runtime tagged with
<spaceId>and<agentId>. - The runtime looks up the Agent in
/org, reads its Start Flow and Start Node. - The flow file is resolved inside the Space's project folder.
- Execution begins at the Start Node — your flow runs.
- Anything the flow narrates via the
ChatMgrstreaming helpers (below) shows up in this chat surface in real time. - The flow ends; the chat is ready for the next message.
The Consumer never sees node names, dictionary contents, or any flow internals. They only see what
ChatMgrexplicitly writes out.
What the Consumer sees while the flow runs
ChatMgr is the side-channel a flow uses to narrate itself while it runs. Every call is fire-and-forget and is interim narration — none of these is the final answer (the final answer is what the flow returns). The available helpers:
| Helper | What the Consumer sees |
|---|---|
ChatMgr.writeOut(text) | A normal message bubble in the conversation. |
ChatMgr.writeThinking(text) | A transient "thinking" indicator. |
ChatMgr.writeError(text) | An error-styled message. (Reports only — it does not route the flow to the error edge; that still requires a throw.) |
ChatMgr.writeAgentStart(mainSessionId, subSessionId, agentName, flowEntry) | Marks the start of a sub-agent run. |
ChatMgr.writeAgentProgress(subSessionId, current, total, message) | A sub-agent progress tick (e.g. "3 of 7"). |
ChatMgr.writeAgentStream(subSessionId, content, isPartial) | A streamed chunk of a sub-agent's output. |
ChatMgr.writeAgentEnd(subSessionId, status, result, duration) | Marks a sub-agent run end. |
ChatMgr.writeFiles(files) | Pushes file attachments to the conversation. |
See Script Node — Chat API for how to call these from inside a Script Node.
Two things called a "session" — keep them apart
⚠️ The platform uses the word "session" for two different lifetimes.
- Chat session (per login). A unique chat id is generated when the Consumer connects after logging in. It is the per-connection identifier the runtime uses to route this Consumer's messages and progress events; it persists across the Consumer's activity within that login and is wiped on logout (or when the connection drops, which also cancels any in-flight flow run). This is the "unique chat ID" the login footer mentions.
- Flow
sessionobject (per run). The shared object that flow code reads fromsystem/sessionis per-request — one prompt → one flow run → one session lifetime. It is not the per-login chat session, and it is size-bounded (1.5 MB) and reclaimed when the run ends. See Script Node — Session API for the exact cap.
Conversation history
Each agentNode call persists its turn to a per-agent, per-chat conversation history, which is what gives an Agent cross-turn memory within a chat. History is isolated per tenant: for partner-integrated deployments every history row is partitioned by the tenant key, so one tenant's conversations can never be read or overwritten by another. (First-party / contract-less runs still stream the answer to the Consumer, but cross-turn persistence is skipped.)
Related
- Agent picker — how a Consumer arrives here.
- Organization → Agents — the admin-side Agent settings that determine which flow runs.
- Script Node libraries — what flow code can do that affects this surface.