Mozaik

Participants

Humans, agents, and observers — factories, manifests, and situation handlers.

A participant is anyone who can join the runtime. Mozaik ships two factories:

RoleFactoryWhat it carries
HumancreateHuman({ name, capabilities, handlers })A manifest and situation handlers. Typically calls sendMessage.
AgentcreateAgent({ name, capabilities, instruction, tools, handlers })Manifest, handlers, an instruction, tools, and memory (agent.getMemory().getContext()). Typically starts thinking with runLoop.
ObserverEither factory, handlers onlyNever calls sendMessage or runLoop — only reacts.

Every participant has a manifest (id, name, role, capabilities) and a list of situation handlers. Identity is the manifest; behavior is the handlers you register — not method overrides on a base class.

import { createAgent, createHuman } from '@mozaik-ai/core';

const human = createHuman({ name: 'User', capabilities: [], handlers: [] });

const agent = createAgent({
  name: 'Assistant',
  capabilities: ['inference'],
  instruction: 'You are a helpful teammate.',
  tools: [],
  handlers: [],
});

id is a UUID assigned at creation (crypto.randomUUID()). role is "human" or "agent" depending on the factory. The role is which functions a participant calls and which specifications it registers. A critic that only watches model.answer from others is still just a participant.

Manifest and accessors

MethodReturns
getId()Manifest id.
getManifest(){ id, name, role, capabilities }.
getHandlers() / setHandlers(handlers)The situation handler list.

Agents also expose:

MethodReturns
getMemory()Memory — call getContext() for the agent's ModelContext.
getTools()The Tool[] passed to createAgent.
getDeveloperMessage()The instruction string.

createAgent writes the instruction into memory as a DeveloperMessageItem before you join. Pass that context into runLoop so the model sees it:

runLoop(agent.getId(), message, {
  model: 'gpt-5.5',
  context: agent.getMemory().getContext(),
  tools: agent.getTools(),
});

Observer

An observer is the same factories with processors that only take side actions — log, persist, render — and never call sendMessage or runLoop:

import { createHuman, SituationSpecification, type SituationHandler, type SituationContext } from '@mozaik-ai/core';

class WhenModelAnswers extends SituationSpecification {
  isSatisfiedBy({ event }: SituationContext): boolean {
    return event.type === 'model.answer';
  }
}

const transcript: SituationHandler = {
  specification: new WhenModelAnswers(),
  processor: {
    apply({ event }) {
      console.log('[model.answer]', event.producerId, event.payload);
    },
  },
};

const observer = createHuman({ name: 'Transcript', capabilities: [], handlers: [transcript] });
join(observer);

On this page