Skip to main content

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:

  1. The Consumer's message is sent to the Keen runtime tagged with <spaceId> and <agentId>.
  2. The runtime looks up the Agent in /org, reads its Start Flow and Start Node.
  3. The flow file is resolved inside the Space's project folder.
  4. Execution begins at the Start Node — your flow runs.
  5. Anything the flow narrates via the ChatMgr streaming helpers (below) shows up in this chat surface in real time.
  6. 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 ChatMgr explicitly 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:

HelperWhat 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 session object (per run). The shared object that flow code reads from system/session is 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.)