Appearance
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
$prompttosystem.agentswith 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.finalframes. - Pulls session list via
$sessionListand shows it as a picker. - Loads message history via
session_state.read(or directly vialoadMessagesin test/admin paths).
What works
- The full
$promptround-trip with streaming response rendering. - Markdown rendering of assistant messages.
- Error attribution for failed inference (the surface knows whether the failure was on
system.agentsorsystem.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.agentslayer; 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.