Mozaik

Architecture

Environment, participants, capabilities, and generators — how the four pieces fit together.

Mozaik has four moving parts. They are deliberately decoupled so you can change one without touching the others.

flowchart LR
  Human[BaseHumanParticipant] -->|streamInput| Env(("AgenticEnvironment"))
  Agent[BaseAgentParticipant] -->|"runInference / executeFunctionCall"| Env
  Observer[Custom Participant] -->|join| Env
  Env -->|onContextItem| Human
  Env -->|onContextItem| Agent
  Env -->|onContextItem| Observer

The four pieces

PieceResponsibility
AgenticEnvironmentA broadcast bus. Receives items via deliverContextItem and fans them out to every joined participant's onContextItem callback. No central scheduler.
ParticipantThe single abstraction for humans, agents, observers, and tools. Joins an environment and reacts to items via onContextItem(source, item).
CapabilitiesWhat a participant can produce. InputCapable streams input items; InferenceCapable streams model output; FunctionCallCapable streams tool outputs. Capability methods are non-blocking — they return Promise<void> and emit items in the background.
GeneratorsThe pluggable I/O behind the capabilities: InputItemSource, InferenceRunner, FunctionCallRunner. Swap any of them without changing the participant or the environment.

How items flow

At runtime, every layer trades the same currency: typed ContextItems.

  1. A capability method (streamInput, runInference, executeFunctionCall) is invoked on a participant.
  2. The participant's generator yields items as they are produced.
  3. Each item is delivered to the environment via deliverContextItem(initiator, item).
  4. The environment dispatches onContextItem(source, item) on every other participant — synchronously and without awaiting them, so a slow listener never blocks producers or other listeners.
  5. Listening participants choose to observe, react (by triggering their own capabilities), or ignore.

Because each capability invocation is a fresh promise wrapping an async iterable, multiple participants can produce items into the same environment concurrently without any of them blocking on another.

How to choose a starting point

  • Single agent reacting to user input — start with BaseHumanParticipant + BaseAgentParticipant and the Quickstart.
  • Add observability without changing agent logic — add a passive observer that just logs in onContextItem.
  • Multi-agent collaborationjoin() more Participants. They all see the same items in real time and can react independently.
  • Custom input, model, or tool execution — build a generator and pass it into BaseAgentParticipant.
  • Direct, single-shot inference — call OpenAIResponses yourself with a ModelContext.

On this page