molroo docs
SDK Reference

World

World class for multi-persona operations — personas, actions, relationships, interactions.

World

World instances are returned by molroo.createWorld() or molroo.getWorld(). They are not constructed directly.

import { Molroo } from '@molroo-io/sdk';

const molroo = new Molroo({ apiKey: 'mk_live_...' });
const world = await molroo.createWorld({ name: 'Cafe' });

Properties

PropertyTypeDescription
idstringWorld ID
namestringWorld name
descriptionstring | nullWorld description
accessPolicystring'closed' or 'open'
responseRulestring'target', 'all', or 'ai'
dataWorldDataFull world data (read-only)

World Lifecycle

// Update properties
await world.update({ name: 'Renamed World' });

// Soft-delete
await world.delete();

Personas

Adding personas

world.addPersona() supports three modes:

Inline mode — define config on the fly

Create a persona directly inside the world. Best for quick prototyping or one-off characters.

const ref = await world.addPersona({
  configId: 'sera',
  displayName: 'Sera',
  config: {
    personality: { O: 0.7, C: 0.6, E: 0.8, A: 0.9, N: 0.3, H: 0.8 },
    identity: {
      name: 'Sera',
      role: 'friendly barista',
      speakingStyle: 'warm and casual',
    },
  },
});
console.log(ref.id); // persona instance ID

Reference a persona you've already created via molroo.createPersona(). The persona retains its own emotional state and memory across worlds.

await world.addPersona({
  personaId: 'prs_abc123',
  displayName: 'Sera',
});

Instance mode — pass a MolrooPersona directly

The most ergonomic approach. Create a persona via the unified Molroo client, then pass it straight into a world.

import { createOpenAI } from '@ai-sdk/openai';

const molroo = new Molroo({ apiKey: 'mk_live_...' });
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY! });

const sera = await molroo.createPersona(
  {
    identity: { name: 'Sera', role: 'barista', speakingStyle: 'warm' },
    personality: { O: 0.7, C: 0.6, E: 0.8, A: 0.9, N: 0.3, H: 0.8 },
  },
  { llm: openai('gpt-4o-mini') },
);

const world = await molroo.createWorld({ name: 'Cafe' });
await world.addPersona(sera);

Instance mode uses reference mode under the hood. The persona's emotional state, memory, and configuration all live in the Persona API — the world just holds a reference.

Managing personas

// List personas
const personas = await world.listPersonas();

// Get persona with emotional state
const persona = await world.getPersona('sera');

// Remove persona
await world.removePersona('sera');

Interactions

world.interact() — action-based interaction

Execute an action against a persona. This is the core operation — it triggers the emotion engine and returns the persona's emotional response.

const result = await world.interact({
  target: 'sera',        // persona config ID
  action: 'greet',       // action name
  actor: 'user-1',       // optional, defaults to 'anonymous'
  actorType: 'user',     // optional: 'user' | 'persona'
});

console.log(result.emotion);  // updated VAD
console.log(result.mood);     // mood state
console.log(result.somatic);  // somatic responses

world.persona().react() — LLM-powered response

Get a WorldPersona handle, then call react() for a full LLM response with emotional context.

const seraHandle = world.persona('sera', { llm });

const { text, state } = await seraHandle.react({
  message: 'What do you recommend today?',
  from: 'user-1',
});

console.log(text);
// "Oh you have to try our new lavender oat latte — it's been my favorite this week!"

console.log(state.emotion.discrete);
// { primary: 'enthusiastic', intensity: 0.78 }

world.persona().getPromptContext() — BYOL (Bring Your Own LLM)

If you want full control over the LLM call, fetch the prompt context and use it with any provider.

const ctx = await seraHandle.getPromptContext();

// ctx.system  — full system prompt with persona identity, emotion, relationships
// ctx.context — structured state for injection

// Use with any LLM
const response = await myLlm.generate({
  system: ctx.system,
  messages: [{ role: 'user', content: 'How are you today?' }],
});

Actions

// Create a custom action
const action = await world.createAction({
  name: 'hug',
  description: 'A warm embrace',
  appraisalVector: {
    goalRelevance: 0.8,
    goalCongruence: 0.9,
    expectedness: 0.5,
    controllability: 0.7,
    agency: 0.6,
    normCompatibility: 0.8,
  },
});

// List all actions (defaults + custom)
const actions = await world.listActions();

// Delete a custom action
await world.deleteAction(action.id);

Relationships

Define how personas relate to each other. Relationships affect emotional reactions and prompt context.

// Set a relationship
await world.setRelationship({
  source: { type: 'user', id: 'user-1' },
  target: { type: 'persona', id: 'sera' },
  trust: 0.8,
  strength: 0.6,
});

// List relationships
const relationships = await world.listRelationships();

// Delete a relationship
await world.deleteRelationship('rel-123');

Events

// Get event log
const { events, nextCursor } = await world.getEvents({ limit: 20 });

Advanced: Low-Level Client

For advanced use cases, you can use the raw openapi-fetch client directly:

import { createWorldClient } from '@molroo-io/sdk/world';

const client = createWorldClient({
  baseUrl: 'https://api.molroo.io',
  apiKey: 'mk_live_...',
});

// Raw typed HTTP calls
const { data } = await client.GET('/worlds');

This is the same client used internally by Molroo and World. It provides full type-safe access to all endpoints via path strings, but requires manual params.path wiring and result envelope unwrapping.

On this page