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
| Property | Type | Description |
|---|---|---|
id | string | World ID |
name | string | World name |
description | string | null | World description |
accessPolicy | string | 'closed' or 'open' |
responseRule | string | 'target', 'all', or 'ai' |
data | WorldData | Full 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 IDReference mode — link an existing persona
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 responsesworld.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.