molroo docs
SDK Reference

MolrooWorld

Main entry point class — world creation, chat, events, ticking, mutations, and snapshots.

MolrooWorld

MolrooWorld is the main SDK class for interacting with a molroo world instance. It provides methods for chat, events, time progression, mutations, snapshots, and querying world state.

import { MolrooWorld } from '@molroo-ai/sdk';

Static Methods

MolrooWorld.create(config, setup)

Create a new world on the molroo API and return a connected instance.

static async create(
  config: {
    baseUrl: string;
    apiKey: string;
    llm?: LLMAdapter;
    storage?: StorageAdapter;
    memory?: MemoryAdapter;
    events?: EventAdapter;
  },
  setup: CreateWorldInput,
): Promise<MolrooWorld>

Parameters:

ParameterTypeDescription
config.baseUrlstringBase URL of the molroo API (e.g., 'https://api.molroo.io')
config.apiKeystringAPI key for authentication
config.llmLLMAdapterOptional LLM adapter for generating responses
config.storageStorageAdapterOptional storage adapter for snapshot backup
config.memoryMemoryAdapterOptional memory adapter for episode persistence
config.eventsEventAdapterOptional event adapter for SDK-level events
setupCreateWorldInputWorld definition, entities, spaces, and persona configs

Example:

const world = await MolrooWorld.create(
  { baseUrl: 'https://api.molroo.io', apiKey: 'key', llm },
  {
    definition: {
      identity: { name: 'Cafe World', genre: 'slice-of-life', tone: 'warm' },
    },
    entities: [
      { name: 'user', type: 'user' },
      { name: 'Sera', type: 'persona' },
    ],
    personaConfigs: {
      Sera: {
        identity: { name: 'Sera', role: 'barista' },
        personality: { O: 0.7, C: 0.6, E: 0.8, A: 0.9, N: 0.3, H: 0.8 },
      },
    },
  },
);

MolrooWorld.connect(config, worldId)

Connect to an existing world by ID. Verifies the world exists and fetches persona configs.

static async connect(
  config: {
    baseUrl: string;
    apiKey: string;
    llm?: LLMAdapter;
    storage?: StorageAdapter;
    memory?: MemoryAdapter;
    events?: EventAdapter;
  },
  worldId: string,
): Promise<MolrooWorld>

Example:

const world = await MolrooWorld.connect(
  { baseUrl: 'https://api.molroo.io', apiKey: 'key', llm },
  'existing-world-id',
);

MolrooWorld.listWorlds(config)

List all worlds for the authenticated tenant.

static async listWorlds(config: {
  baseUrl: string;
  apiKey: string;
}): Promise<{ worlds: WorldSummary[]; nextCursor?: string }>

Example:

const { worlds } = await MolrooWorld.listWorlds({
  baseUrl: 'https://api.molroo.io',
  apiKey: 'key',
});

for (const w of worlds) {
  console.log(w.id, w.definition.identity?.name);
}

Properties

PropertyTypeDescription
idstringUnique identifier for this world instance
worldIdstringAlias for id

Chat

chat(to, message, options?)

Send a message to an entity and get an emotion-processed response.

With LLM adapter: Fetches world context, generates a response via the configured LLM, then sends it to the API for emotion processing.

Without LLM adapter: Requires options.appraisal to be provided. Sends the message directly to the API for emotion-only computation.

async chat(
  to: string,
  message: string,
  options?: ChatOptions,
): Promise<ChatResult>

Parameters:

ParameterTypeDescription
tostringTarget entity name (e.g., 'Sera')
messagestringThe message text to send
options.fromstringSender name. Defaults to 'user'
options.appraisalAppraisalVectorManual appraisal — skips LLM, uses emotion-only mode
options.includeStatebooleanInclude full internal state in result
options.historyArray<{ role, content }>Conversation history for LLM context
options.propagateToSpacebooleanOverride world-level groupAwareness (false = whisper)

Returns: ChatResult

Example (with LLM):

const result = await world.chat('Sera', 'How are you today?');

console.log(result.response.text);
// "I'm doing great! The morning rush was fun."

console.log(result.response.emotion.discrete.primary);
// 'joy'

console.log(result.response.emotion.vad);
// { V: 0.65, A: 0.42, D: 0.38 }

Example (emotion-only, no LLM):

const result = await world.chat('Sera', 'Hello', {
  appraisal: {
    goal_relevance: 0.5,
    goal_congruence: 0.8,
    expectedness: 0.6,
    controllability: 0.5,
    agency: 0,
    norm_compatibility: 0.7,
  },
});
// result.response.text will be empty — only emotion data is returned

getContext(entityNameOrId)

Get the world context from the perspective of a specific entity. Returns spatial awareness, nearby entities, recent events, and world state. This is the data the SDK uses to build LLM prompts.

async getContext(entityNameOrId: string): Promise<WorldContext>

Returns: WorldContext

Example:

const ctx = await world.getContext('Sera');

console.log(ctx.whoAmI);       // 'Sera'
console.log(ctx.whereAmI);     // 'Main Cafe'
console.log(ctx.whoIsHere);    // ['user', 'Mika']
console.log(ctx.whatHappened);  // recent WorldEvent[]

Events

event(input)

Dispatch a world event that affects one or more entities. Events can carry an appraisal (cognitive evaluation) or a direct stimulus (raw physiological/emotional manipulation).

async event(input: EventInput): Promise<EventResult>

Parameters: See EventInput

Returns: EventResult

Example (appraisal-based):

const result = await world.event({
  type: 'surprise_party',
  target: 'Sera',
  payload: { description: 'Everyone jumps out and yells surprise!' },
  appraisal: {
    goal_relevance: 0.8,
    goal_congruence: 0.9,
    expectedness: 0.1,
    controllability: 0.2,
    agency: -0.5,
    norm_compatibility: 0.8,
  },
});

console.log(result.affected[0].response.emotion.discrete.primary);
// 'surprise'

Example (stimulus-based):

await world.event({
  type: 'battle_start',
  target: 'Sera',
  stimulus: {
    vadDelta: { A: 0.3, V: -0.2 },
    bodyBudgetDelta: -0.1,
  },
});

Tick / Time

tick(seconds)

Advance world time by the specified number of seconds. Processes emotion decay, pending events, and phase transitions.

async tick(seconds: number): Promise<TickResult>

Returns: TickResult

Example:

const result = await world.tick(60); // advance 1 minute
console.log(result.elapsedSeconds);   // 60
console.log(result.phaseChanged);     // undefined or { from, to, triggerId }

timeJump(seconds, milestoneEvent?)

Jump forward in time with an optional milestone event. Unlike tick(), time jumps can span large periods.

async timeJump(
  seconds: number,
  milestoneEvent?: Record<string, unknown>,
): Promise<TickResult>

Example:

// Jump 1 hour with a milestone
const result = await world.timeJump(3600, {
  type: 'storm_arrives',
  description: 'A sudden thunderstorm hits the area.',
});

Query

query(include?)

Query world state, selecting which data sections to include. If include is omitted, returns all sections.

async query(include?: QueryInclude[]): Promise<QueryData>

Parameters:

ParameterTypeDescription
includeQueryInclude[]Data sections: 'entities', 'spaces', 'environment', 'definition', 'phase'

Returns: QueryData

Example:

const data = await world.query(['entities', 'spaces']);

for (const entity of data.entities ?? []) {
  console.log(entity.name, entity.type, entity.spaceId);
}

Mutate

mutate(ops)

Execute one or more mutation operations on the world atomically. Supports adding/removing entities, moving entities, setting relationships, managing spaces/connections, updating environment, and managing facts/phases.

async mutate(ops: MutateOp[]): Promise<MutateResult>

Parameters: Array of MutateOp operations.

Returns: MutateResult

Example:

const result = await world.mutate([
  { op: 'add_entity', name: 'Mika', type: 'persona' },
  { op: 'move_entity', target: 'Mika', toSpace: 'Kitchen' },
  { op: 'set_relationship', entityA: 'Sera', entityB: 'Mika', relationship: { type: 'colleague', trust: 0.7 } },
  { op: 'update_environment', environment: { weather: 'rainy' } },
]);

for (const r of result.results) {
  console.log(r.op, r.ok, r.error);
}

Entity Management

Convenience methods that wrap mutate() for common entity operations.

addEntity(input)

Add a new entity to the world.

async addEntity(input: {
  name: string;
  type?: string;     // Defaults to 'secondary'
  profile?: UserProfile;
  spaceId?: string;
}): Promise<MutateOp & { data?: unknown }>

Example:

await world.addEntity({
  name: 'Mika',
  type: 'persona',
  spaceId: 'kitchen',
});

removeEntity(target)

Remove an entity from the world.

async removeEntity(target: string): Promise<void>

moveEntity(target, toSpace)

Move an entity to a different space.

async moveEntity(target: string, toSpace: string): Promise<void>

Example:

await world.moveEntity('Sera', 'Kitchen');

Space

addSpace(input)

Add a new space to the world.

async addSpace(input: {
  name: string;
  spaceType?: string;
  capacity?: number;
}): Promise<MutateOp & { data?: unknown }>

Example:

await world.addSpace({ name: 'Rooftop', spaceType: 'physical', capacity: 10 });

Relationship

setRelationship(entityA, entityB, relationship)

Set a relationship between two entities.

async setRelationship(
  entityA: string,
  entityB: string,
  relationship: RelationshipInput,
): Promise<void>

Parameters: See RelationshipInput

Example:

await world.setRelationship('Sera', 'Mika', {
  type: 'best_friend',
  strength: 0.9,
  trust: 0.85,
});

Environment

updateEnvironment(environment)

Update the world environment (weather, location, ambiance, etc.).

async updateEnvironment(environment: Partial<EnvironmentInput>): Promise<void>

Example:

await world.updateEnvironment({
  weather: 'thunderstorm',
  ambiance: 'tense and quiet',
});

Definition

updateDefinition(definition)

Update the world definition (identity, rules, culture, etc.). Merges with existing definition.

async updateDefinition(definition: Record<string, unknown>): Promise<void>

Example:

await world.updateDefinition({
  identity: { tone: 'dark' },
  rules: { narrative: { violenceLevel: 'high' } },
});

Snapshot

snapshot()

Get a full snapshot of the world state, including all entities, spaces, environment, knowledge, progression, and persona snapshots.

async snapshot(): Promise<WorldSnapshot>

Returns: WorldSnapshot


loadSnapshot(snapshot)

Restore the world state from a previously saved snapshot.

async loadSnapshot(snapshot: WorldSnapshot): Promise<void>

Example:

// Save
const snap = await world.snapshot();

// ... later ...

// Restore
await world.loadSnapshot(snap);

saveSnapshotToStorage(key?)

Save the current world snapshot to external storage. Requires a StorageAdapter to be configured.

async saveSnapshotToStorage(key?: string): Promise<WorldSnapshot>
ParameterTypeDefaultDescription
keystringsnapshots/{worldId}/latest.jsonStorage key

loadSnapshotFromStorage(key?)

Load a world snapshot from external storage and apply it. Requires a StorageAdapter to be configured.

async loadSnapshotFromStorage(key?: string): Promise<void>

Throws MolrooApiError with code STORAGE_NOT_FOUND if the snapshot does not exist at the given key.


Persona Configs

fetchPersonaConfigs()

Fetch persona configs from the API and cache locally. Called automatically by MolrooWorld.connect().

async fetchPersonaConfigs(): Promise<Record<string, PersonaConfigData>>

getPersonaConfig(entityName)

Get the cached persona config for a specific entity. Returns undefined if not cached.

getPersonaConfig(entityName: string): PersonaConfigData | undefined

Example:

const config = world.getPersonaConfig('Sera');
console.log(config?.personality); // { O: 0.7, C: 0.6, E: 0.8, ... }
console.log(config?.identity);    // { name: 'Sera', role: 'barista', ... }

Lifecycle

destroy()

Soft-delete this world. Can be restored with restore().

async destroy(): Promise<void>

restore()

Restore a previously soft-deleted world.

async restore(): Promise<void>

On this page