Skip to content

Agents vs Chat

Chat is the conversation app. system.agents is the substrate the conversation runs on. The bridge between them is ConversationSurface, a custom element shipped by @open-matrix/chat-component.

ConversationSurface — the bridge

ConversationSurface is an embeddable conversation panel. From the agent-platform side it is a normal client of the system.agents accepts list:

  • It addresses a TargetRef (the actor the conversation is about).
  • It calls $prompt on system.agents with prompt text + target snapshot.
  • It listens for activity frames keyed to the request and renders them.
  • It uses $sessionList to populate the session picker.
  • It uses session_state.read to load message history.

From the Chat side, ConversationSurface is just a custom element you drop into a panel. Chat does not duplicate any of this logic — ChatApp.ts:1628 reads transcripts from system.agents, never from a chat-local store.

Why you target ConversationSurface, not system.agents directly

You technically can call $prompt on system.agents from any browser actor, but ConversationSurface adds:

  • Target snapshot. Builds a snapshot of the target actor (its accepts, emits, state, children) so the LLM has structured context.
  • Session continuity. Resumes the most recent session for the (targetKey, profileKey) pair instead of starting a fresh one each turn.
  • Activity rendering. Knows how to interpret $thinking, $token, $response, $toolCall, $toolResult frames.
  • Permission prompts. Renders approval UIs when system.agents emits an approval-required frame.

If you bypass it, you get a generic chatbot without target context, without session resume, and without rendered traces. The agent-orchestration document at projects/matrix-3/packages/docs/content/architecture/agent-orchestration.md:82-89 codifies this: "Target system.agents through ConversationSurface, not directly."

What Chat owns vs what system.agents owns

ConcernOwner
Conversation UI (bubbles, scroll, markdown rendering)Chat package
Session list UI, session-picker, "new conversation"Chat package, but reads from system.agents
Session record (id, target_key, principal_id, turn_count, messages)system.agents.memory SQLite store
LLM call, oracle loop, tool executionAgentActor (child of AgentsRoot)
Activity frames (the wire format streaming up to Chat)Emitted by AgentActor, not by Chat
Inference provider, credentialssystem.inference + Factotum

Chat could be replaced (different UI, different shell) and the cognitive contract would be unchanged. That is the design intent.

See also

Source: projects/matrix-3/packages/chat/src/ChatApp.ts:1628, projects/matrix-3/packages/chat-component/src/ConversationSurface.ts, projects/matrix-3/packages/docs/content/architecture/agent-orchestration.md (canonical "go through ConversationSurface" guidance).