Quickstart
Initialize a runtime, join a human and an agent, and let the agent think when someone else sends a message.
This walkthrough matches the example in the Mozaik README: define a runtime, register a situation handler, join a human and an agent, then sendMessage. The agent does not need a separate "start inference" call — it reacts through a specification that matches message.sent.
Full example
import {
defineRuntime,
RuntimeState,
createAgent,
createHuman,
SituationSpecification,
Agent,
type SituationHandler,
type SituationContext,
} from '@mozaik-ai/core';
class AppState extends RuntimeState {}
const { initializeRuntime, join, sendMessage, runLoop } = defineRuntime<AppState>();
initializeRuntime({ state: new AppState() });
class WhenOthersSendAMessage extends SituationSpecification {
isSatisfiedBy({ event, participant }: SituationContext): boolean {
return event.type === 'message.sent' && event.producerId !== participant.getId();
}
}
const thinkOnMessage: SituationHandler = {
specification: new WhenOthersSendAMessage(),
processor: {
apply({ event, participant }) {
if (!(participant instanceof Agent)) return;
const { message } = event.payload as { message: string };
runLoop(participant.getId(), message, {
model: 'gpt-5.5',
context: participant.getMemory().getContext(),
tools: participant.getTools(),
});
},
},
};
const agent = createAgent({
name: 'Assistant',
capabilities: ['inference'],
instruction: 'You are a helpful teammate.',
tools: [],
handlers: [thinkOnMessage],
});
const human = createHuman({ name: 'User', capabilities: [], handlers: [] });
join(human);
join(agent);
sendMessage('Hello', human.getId());defineRuntime returns the functions for this session. They are not top-level package exports — keep them in module scope (or re-export them yourself). Call initializeRuntime once before join, sendMessage, or runLoop.
What this is doing
defineRuntime<AppState>()— Creates the session API typed to yourRuntimeStatesubclass.initializeRuntime({ state })— Instantiates the runtime. Calling it twice throws"Runtime already initialized".WhenOthersSendAMessage— ASituationSpecificationthat matchesmessage.sentfrom someone other than this participant.runLoop— Starts one agent turn (context update, inference, tools, answer). It returnsvoidand keeps running in the background.sendMessage('Hello', human.getId())— Publishesmessage.sent. The agent's handler matches and starts the loop.
Do not await runLoop or sendMessage inside a processor. Both return immediately while the runtime keeps delivering events.
What you'll need
- A provider API key — see Installation.
- A model name on
InferenceInput(for example'gpt-5.5'). The provider is resolved from that name — see Models. - For human input, call
sendMessagefrom your UI or I/O layer when the user acts.