molroomolroo
Concepts

Proactive Behavior

Characters that initiate interactions based on psychological needs.

Proactive Behavior

By default, molroo characters only respond when spoken to. Proactive behavior changes that -- it allows characters to initiate interactions on their own, driven by psychological needs rather than arbitrary timers.

A character with proactive behavior enabled might reach out after a period of silence because they miss the user, or share an emotional thought that has been building up, or seek interaction to fulfill an unmet need. These behaviors emerge from the same psychological model that drives the rest of the emotion engine.

Proactive behavior is disabled by default. You must explicitly enable it per session.

Trigger Types

There are three distinct psychological mechanisms that can trigger proactive behavior:

1. Attachment Seeking

Based on Bowlby's attachment theory, characters develop proximity-seeking behavior when separated from their attachment figure (the user). The longer the absence, the stronger the urge to reach out.

This is not a simple timer. The intensity of the attachment-seeking impulse depends on:

  • How long the user has been absent
  • The character's attachment style (see Relationship Tracking)
  • The character's current emotional state
  • The strength of the established bond

A character with a secure attachment style might send a casual check-in after a day of silence. A character with an anxious attachment style might reach out much sooner, with greater urgency.

2. Need Deficit

Grounded in self-determination theory, characters have three basic psychological needs: autonomy, competence, and relatedness. When any of these needs drops below the character's baseline, they are motivated to seek interaction to fulfill the deficit.

NeedWhat Triggers ItExample Behavior
RelatednessProlonged isolation, lack of meaningful connection"I've been thinking about our last conversation..."
CompetenceRepeated failures, lack of engagementSeeking validation or sharing an accomplishment
AutonomyFeeling controlled or constrainedAsserting preferences, initiating a new topic

3. Emotional Overflow

Some emotions are too strong to contain, regardless of how much time has passed. When a character experiences intense emotion -- whether positive or negative -- it can trigger a proactive action driven by the need to share or express that state.

Emotional overflow bypasses the normal idle-time checks. A character who just received devastating news might reach out immediately, not because they have been alone for long, but because the emotion demands expression.

Enabling Proactive Behavior

Enable proactive behavior for a session via the preferences endpoint:

curl -X PUT https://api.molroo.io/v1/proactive/SESSION_ID/preferences \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "triggers": {
      "attachment_seeking": true,
      "need_deficit": true,
      "emotional_overflow": true
    },
    "min_interval_seconds": 3600
  }'

You can enable or disable individual trigger types. The min_interval_seconds field prevents the character from reaching out too frequently.

Receiving Proactive Actions

There are three ways to receive proactive actions from a character:

WebSocket

If your application uses a WebSocket connection, proactive actions are pushed to the client automatically via the server's alarm system. This is the most responsive option.

const ws = new WebSocket("wss://api.molroo.io/v1/ws?session_id=SESSION_ID");
 
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === "proactive_action") {
    // data.trigger_type: "attachment_seeking" | "need_deficit" | "emotional_overflow"
    // data.prompt_data: same structure as turn response prompt_data
    // data.suggested_message: a natural language message the character wants to send
    handleProactiveAction(data);
  }
};

REST Polling

For simpler architectures, poll the proactive endpoint periodically:

async function checkProactive(sessionId) {
  const response = await fetch(
    `https://api.molroo.io/v1/proactive/${sessionId}`,
    { headers: { Authorization: `Bearer ${API_KEY}` } }
  );
  const data = await response.json();
 
  if (data.pending_action) {
    // A proactive action is waiting
    // data.pending_action.trigger_type
    // data.pending_action.prompt_data
    // data.pending_action.suggested_message
    handleProactiveAction(data.pending_action);
  }
}
 
// Poll every 5 minutes
setInterval(() => checkProactive("SESSION_ID"), 5 * 60 * 1000);

Webhooks

Register a webhook URL to receive proactive actions as HTTP callbacks:

curl -X POST https://api.molroo.io/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/molroo",
    "events": ["proactive_action"],
    "session_id": "SESSION_ID"
  }'

Your endpoint will receive POST requests with the proactive action payload whenever the character initiates.

What Comes Back

A proactive action includes the same prompt_data structure as a normal turn response, plus metadata about the trigger:

{
  "type": "proactive_action",
  "trigger_type": "attachment_seeking",
  "urgency": 0.72,
  "suggested_message": "Hey... it's been a while. How have you been?",
  "prompt_data": {
    "system": { "..." },
    "context": { "..." },
    "instruction": { "..." },
    "formatted": { "..." }
  }
}

The suggested_message is a pre-generated message you can use directly, or you can take the prompt_data and generate your own response through your LLM pipeline -- just as you would with a normal turn.

Design Considerations

Set reasonable intervals. A character that reaches out every 10 minutes feels intrusive, not lifelike. Start with intervals of 1-4 hours and adjust based on your application's context.

Respect user preferences. Give your users a way to mute or adjust proactive behavior. Not everyone wants to be contacted unprompted.

Proactive actions consume turns. Each proactive action counts against your plan's turn limit, just like a regular turn. Monitor usage if proactive behavior is enabled across many sessions.

For the psychological need system that drives need-deficit triggers, see the needs field in prompt_data. For how attachment style evolves, see Relationship Tracking.

On this page