Resources
11Install
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.pywatchespulse_state.jsonmtime 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 logCLI Commands
Run heartbeat manually
PULSE_WORKSPACE=/path/to/pulse python3 heartbeat_runner.pyBuffer 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.mdWatch logs
tail -f pulse.logProbability 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_countspersists 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>&1Chat Integration
Mood is injected into chat via OpenClaw preamble:
agents.default.preamble: /path/to/pulse/mood_injection.mdThe 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 presenceConfiguration
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": {}
}