Skip to content

Chat integration

Chat is the dedicated conversation app. Its integration with system.agents is mediated by ConversationSurface (a custom element shipped from @open-matrix/chat-component) — Chat itself contains zero LLM code.

How Chat embeds ConversationSurface

html
<!-- In Chat's template, conceptually -->
<conversation-surface
  target-ref="<TargetRef encoded>"
  profile-key="default"
  backend-mount="system.agents">
</conversation-surface>

ConversationSurface:

  • Issues $prompt to system.agents with the target ref + the user's text.
  • Subscribes to activity frames matched by requestId.
  • Renders streaming inference.token, tool.call, tool.result, response.partial, response.final frames.
  • Pulls session list via $sessionList and shows it as a picker.
  • Loads message history via session_state.read (or directly via loadMessages in test/admin paths).

What works

  • The full $prompt round-trip with streaming response rendering.
  • Markdown rendering of assistant messages.
  • Error attribution for failed inference (the surface knows whether the failure was on system.agents or system.inference).
  • Up to 62 actor types responding to ConversationSurface (per the working notes in MEMORY.md).

What's partial

From the working notes (MEMORY.md § ConversationSurface):

  • Session list — works in Director chat tab; Chat's standalone session list is incomplete.
  • Session persistence across page reload — works at the system.agents layer; the Chat shell does not always restore the active session id from URL state.
  • Session resume — no UI affordance to "resume the session from yesterday on this target" beyond clicking the session in the picker.

These are Chat-side gaps. The agent-platform layer fully supports all three.

What Chat MUST NOT bypass

Any temptation to call inference directly from Chat — import { infer } from '@open-matrix/inference' — is wrong. Inference must flow through system.agents so:

  • Activity frames are emitted.
  • Sessions are recorded.
  • Memory is consulted per the active profile.
  • Trace replay can replay the conversation.

ChatApp.ts:3292 even pre-formats an error message that mentions system.agents/inference reachability for that reason — the user-facing error correctly attributes "no provider" to the right boundary.

Recipe — embedding ConversationSurface from another package

ts
import '@open-matrix/chat-component';

class MyPanel extends MatrixActorHtmlElement {
  static accepts = { 'panel.show': { targetRef: 'object' } };

  protected get template(): string {
    return `<conversation-surface
      backend-mount="system.agents"
      profile-key="explain"
      target-ref="${JSON.stringify(this._targetRef)}">
    </conversation-surface>`;
  }
  // ...
}

The web component owns its own session lifecycle. The host page just supplies the target ref and the chosen profile.

See also

Source: projects/matrix-3/packages/chat/src/ChatApp.ts:1628,3292, projects/matrix-3/packages/chat-component/src/ConversationSurface.ts. Working-notes status: ~/.claude/projects/.../memory/MEMORY.md § ConversationSurface & Silent Prompt Failure.