thortain

SKILL.md — Pulse Mood Engine

```

thortain 0 Updated 2mo ago

Resources

11
GitHub

Install

npx skillscat add thortain/eunoia

Install via the SkillsCat registry.

SKILL.md

SKILL.md — Pulse Mood Engine

Pulse is a personality-driven AI mood system for the agent, powered by Pulse — an LLM-driven mood engine that uses sub-agents to infer emotional state from conversation.

What It Does

  • Tracks a 6-dimension mood vector: agreeableness, warmth, snark, energy, openness, focus
  • Reads buffered messages every 5 minutes via cron
  • Spawns a MiniMax sub-agent to analyze how user's words affected the agent's mood
  • Rolls probability — significant mood shifts are persisted, small ones are subtle
  • Updates pulse_state.json (written every heartbeat, not just on trigger)
  • Writes mood_injection.md (updated every heartbeat so Discord presence always reflects current mood)
  • presence_bridge.py watches pulse_state.json mtime and reconnects to push updated Discord presence

Mood Dimensions

Dimension Range Meaning
agreeableness 0.0–1.0 0.0 = cold/hostile, 1.0 = warm/kind
warmth 0.0–1.0 Emotional warmth and affection
snark 0.0–1.0 0.0 = earnest/sincere, 1.0 = snarky/teasing
energy 0.0–1.0 0.0 = tired/slow, 1.0 = wired/alert
openness 0.0–1.0 0.0 = guarded, 1.0 = open/candid
focus 0.0–1.0 0.0 = scattered, 1.0 = sharp/focused

Files

pulse/
├── heartbeat_runner.py       # Cron task: read buffer → sub-agent → update state
├── pulse_state.json         # Persisted mood state (written every heartbeat)
├── mood_injection.md        # Auto-written, prepended to OpenClaw system prompt (updated every heartbeat)
├── buffer_message.py         # Buffer a message for heartbeat processing
├── presence_bridge.py       # Daemon: watches pulse_state.json, reconnects on mtime change
├── config.py / config.json   # Workspace paths + Discord token
├── memory/                   # Buffered messages (last 20)
│   └── heartbeat-buffer.json
└── pulse.log                 # Runner activity log

CLI Commands

Run heartbeat manually

PULSE_WORKSPACE=/path/to/pulse python3 heartbeat_runner.py

Buffer a message

python3 buffer_message.py user "message text"
python3 buffer_message.py assistant "response text"

View current mood

cat pulse_state.json
cat mood_injection.md

Watch logs

tail -f pulse.log

Probability Curve

Small mood shifts have low probability of triggering a write. Big shifts are near-certain.

TOTAL_DELTA_MAG Probability
< 0.20 0% (no trigger)
0.20 0%
0.30 4%
0.40 30%
0.45 58%
0.50+ 100%

NASTINESS override: If the sub-agent rates user ≥ 4 (insulting/degrading), probability is forced to at least 80%.

Diminishing Returns

  • Repeated messages in the same buffer cycle: x2→×0.4, x3+→×0.15 delta weight
  • emotional_theme_counts persists across heartbeats with ×0.7 decay per cycle — repeated triggers fade naturally
  • Sub-agent prompt receives current theme frequencies so it can factor repetition into its analysis

Cron Setup

# Add to crontab (every 5 minutes)
*/5 * * * * PATH=/home/USER/.npm-global/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PULSE_WORKSPACE=/path/to/pulse /usr/bin/python3 /path/to/pulse/heartbeat_runner.py >> /path/to/pulse/pulse.log 2>&1

Chat Integration

Mood is injected into chat via OpenClaw preamble:

agents.default.preamble: /path/to/pulse/mood_injection.md

The heartbeat_runner.py regenerates mood_injection.md every heartbeat cycle.

Architecture

Cron (every 5 min)
  └─→ heartbeat_runner.py
         ├─→ Read last 10 messages from memory/heartbeat-buffer.json
         ├─→ Read current dims from pulse_state.json
         ├─→ Apply ×0.7 decay to emotional_theme_counts
         ├─→ Spawn MiniMax sub-agent with mood dims + messages + theme counts
         ├─→ Parse structured JSON output: deltas, NASTINESS, DISCORD_STATUS, MOOD_TAG, EMOTIONAL_THEMES
         ├─→ Increment emotional_theme_counts for themes that fired
         ├─→ Roll probability
         ├─→ If triggered: write pulse_state.json + mood_injection.md
         ├─→ Always: write pulse_state.json (mtime update) + mood_injection.md
         └─→ presence_bridge detects mtime change → reconnects → updates Discord presence

Configuration

Edit config.json:

{
    "token": "YOUR_DISCORD_BOT_TOKEN",
    "workspace": "/path/to/pulse",
    "paths": {
        "pulse_state": "pulse_state.json",
        "mood_injection": "mood_injection.md",
        "heartbeat_buffer": "memory/heartbeat-buffer.json",
        "log": "pulse.log"
    }
}

Seed Defaults (first run)

{
  "dims": {
    "agreeableness": 0.65,
    "warmth": 0.65,
    "snark": 0.50,
    "energy": 0.60,
    "openness": 0.65,
    "focus": 0.65
  },
  "last_status": "Neutral",
  "last_updated": null,
  "emotional_theme_counts": {}
}