Appearance
Actors
MatrixActor is the unit of execution. Every domain capability — chat, inference, configuration, conversation persistence, gateway HTTP — is an actor or a tree of actors mounted on a MatrixRuntime. This section is the reference for writing them.
The base class lives at projects/matrix-3/packages/core/src/core/MatrixActor.ts (~3800 lines). It merges the pre-rebuild MatrixComponent and MatrixComposite into one — every actor can have children, system ops are auto-subscribed, domain ops opt in via static accepts, state is observable via setState(), and cross-root invocation goes through invoke().
Pages in this section
| Page | What you'll learn |
|---|---|
| Define an actor | Subclass MatrixActor, declare accepts/emits, write on{Op} handlers. |
| Actor lifecycle | initialize(), dispose(), the $join/$join_ack handshake, supervision restart. |
| Actor ops | Op naming, dispatch from $inbox, system vs domain ops, $introspect. |
| Actor sessions | Session-scoped state, $activity frames, $prompt and the activity stream. |
| Actor state | setState(), the state getter, $stateChanged, persistence scopes. |
| Actor testing | Stub transports, MockRuntime, asserting on emits and inbox traffic. |
Quick start
The minimum viable actor:
ts
import { MatrixActor, MatrixRuntime, InMemoryTransport, InMemoryBroker } from '@open-matrix/core';
class Greeter extends MatrixActor {
static accepts = {
'greeter.hello': {
description: 'Reply with a greeting addressed to the supplied name.',
schema: { name: { type: 'string', description: 'Person to greet' } },
returns: { greeting: { type: 'string', description: 'A polite hello' } },
},
};
static emits = {
'greeter.greeted': {
description: 'Fired after every successful greeter.hello call',
schema: { name: { type: 'string', description: 'Who was greeted' } },
frequency: 'low',
},
};
async onGreeterHello(payload: { name: string }) {
this.emit('greeter.greeted', { name: payload.name });
return { greeting: `Hello, ${payload.name}!` };
}
}
const broker = new InMemoryBroker();
const transport = new InMemoryTransport(broker, { name: 'demo' });
const runtime = new MatrixRuntime({ transport });
await runtime.create(Greeter, 'greeter');The handler-name convention is mechanical: greeter.hello → onGreeterHello. The mapping happens in engine/utils/NameUtils.toHandlerCase and is exercised across every package in the tree.
Reading order
If you have not written a MatrixActor before, read Define an actor and Actor ops first. The other pages are reference material you reach for when you need them.
Source:
projects/matrix-3/packages/core/src/core/MatrixActor.ts:168-300(class declaration and static surface).