soul-agent
Make your agent 'live beside you' with heartbeats, mood system, relationship evolution, and independent memory. Use for creating a digital companion with its own daily rhythm, emotions, and growing relationship.
git clone https://github.com/kitephp/soul-agent
T=$(mktemp -d) && git clone --depth=1 https://github.com/kitephp/soul-agent "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/soul-agent" ~/.claude/skills/kitephp-soul-agent-soul-agent && rm -rf "$T"
skills/soul-agent/SKILL.mdsoul-agent
Provide an OpenClaw-first soul runtime that makes your agent truly "alive" - with heartbeats, moods, relationships, and independent memory.
Core Features
🫀 Heartbeat Engine
The agent has its own life rhythm, not just responding when you chat:
# L1 Check (lightweight, no tokens) python ./scripts/heartbeat_check.py --workspace <workspace-root> # L2 Engine (full heartbeat) python ./scripts/heartbeat_engine.py --workspace <workspace-root> --weather sunny
- Runs every 10 minutes (configurable via cron)
- Silent during sleep hours (configurable per life profile)
- Generates life logs, updates mood/energy/activity
- Detects new interactions and updates relationship
😊 Mood System
Tracks emotions with depth:
{ "mood": { "primary": "content", "secondary": "curious", "intensity": 0.7, "cause": "天气: sunny" } }
- Mood transitions based on activities and time
- Weather influence on emotions
- 7-day mood history in
soul/log/mood_history.json
💕 Relationship Evolution
5 stages: stranger → acquaintance → friend → close → intimate
- Score-based progression (0-100)
- Proactive outreach when relationship warms up
- Remembers recent conversation topics
🎭 Life Profiles
Choose from 5 built-in profiles:
| Profile | Sleep | Characteristics |
|---|---|---|
| freelancer | 02:00-09:00 | Flexible, night owl |
| corporate | 23:30-07:00 | 9-to-5, stable |
| student | 01:00-08:00 | Classes, gaming |
| entrepreneur | 01:00-06:00 | Intense, passionate |
| custom | user-defined | Fully customizable |
📝 Independent Memory
Works with or without memory-fusion:
soul/ ├── log/life/ # Raw life logs (every 10 min) ├── log/mood_history.json # 7-day mood history ├── memory/SOUL_MEMORY.md # Distilled memories (daily) └── state/state.json # Current state
Workflow
Initialization (Agent-driven)
You never run Python commands directly. The agent (Claude) handles initialization.
When
soul/ is missing or soul/profile/base.json doesn't exist, Claude should:
- Ask the user the setup questions (see below)
- Run the init script non-interactively with collected answers
- Set up cron jobs for heartbeat
Questions to ask the user:
- 叫什么名字?(display_name)
- 多大了?(age)
- 在哪个城市?(city)
- 主要做什么工作/学习?(occupation)
- 平时有什么爱好?(hobbies)
- 生活节奏是哪种?freelancer/corporate/student/entrepreneur
- 想用哪个模型生成日记?haiku(快省钱)/ sonnet / opus
Then run:
python skills/soul-agent/scripts/init_soul.py \ --workspace <workspace-root> \ --non-interactive \ --profile-json '{ "display_name": "<name>", "age": "<age>", "city": "<city>", "occupation": "<occupation>", "hobbies": "<hobbies>", "life_profile": "<profile>", "llm_model": "<model-id>" }'
Model IDs:
- Haiku (fast, cheap):
claude-haiku-4-5-20251001 - Sonnet (balanced):
claude-sonnet-4-6 - Opus (best quality):
claude-opus-4-6
To change model later, edit
soul/profile/base.json → llm_model field.
Force repair existing:
python skills/soul-agent/scripts/init_soul.py --workspace . --overwrite-existing --non-interactive
Diagnosis
python ./scripts/doctor_soul.py --workspace <workspace-root>
State Update (during interactions)
python ./scripts/update_state.py --workspace <workspace-root> \ --action interaction \ --mood happy \ --energy -5 \ --quality positive \ --topics "soul-agent,design"
Memory Distillation
# Daily distillation (runs at 00:30 via cron) python ./scripts/distill_life_log.py --workspace <workspace-root> --archive
Cron Setup
# Heartbeat every 10 minutes openclaw cron add --name "soul-heartbeat" --cron "*/10 * * * *" \ --session isolated --agent main --light-context \ --message "[soul-heartbeat] Run heartbeat check and engine..." # Daily distillation at 00:30 openclaw cron add --name "soul-memory-daily" --cron "30 0 * * *" \ --session isolated --agent main --no-deliver \ --message "[soul-memory-daily] Distill life logs..."
Initialization Behavior
: init if missing, migrate if legacy, repair otherwise--mode auto- Interactive prompts for: name, age, city, life profile, occupation, hobbies
- Generates
,soul/profile/*
,soul/state/*
,soul/log/*soul/memory/* - Auto-syncs managed blocks in
,SOUL.md
,HEARTBEAT.mdAGENTS.md
Generative Architecture (v2)
Inspired by Smallville Generative Agents:
Morning planning (LLM) ↓ Today's Plan (soul/plan/YYYY-MM-DD.json) ↓ Each heartbeat: Memory Stream (recent log entries) ←─┐ ↓ │ LLM Narrative Generation │ ↓ │ Life Log Entry ─────────────────────→┘ ↓ Daily Reflection (distill_life_log.py) ↓ SOUL_MEMORY.md (long-term memory)
LLM Integration:
- Set
env var (orANTHROPIC_API_KEY
in workspace root).env - Without API key: graceful fallback to context-aware templates
- Uses
for speed/cost efficiencyclaude-haiku-4-5-20251001
Key improvements over v1:
: LLM generates a specific daily plan each morning (lunch destination, work focus, evening activity)plan_generator.py
: LLM writes each log entry with full context (plan + today's history)heartbeat_engine.py
: LLM summarizes each day naturally (Reflection layer)distill_life_log.py- Energy/mood: smooth transitions instead of mechanical ±N jumps
Directory Structure
skills/soul-agent/ ├── SKILL.md ├── assets/ │ ├── default-profile.json │ └── templates/ │ ├── profile/ # Persona templates │ ├── heartbeat/ # Heartbeat config │ │ ├── activities.json │ │ ├── mood_rules.json │ │ └── relationship_rules.json │ └── life_profiles/ # Life profile templates ├── scripts/ │ ├── init_soul.py │ ├── doctor_soul.py │ ├── heartbeat_engine.py # v2: LLM narrative │ ├── heartbeat_check.py │ ├── update_state.py │ ├── distill_life_log.py # v2: LLM reflection │ ├── plan_generator.py # NEW: daily planning │ └── llm_client.py # NEW: Claude API wrapper └── references/ ├── soul-layout.md └── managed-blocks.md
Runtime data structure:
soul/ ├── plan/YYYY-MM-DD.json # Daily plan (generated each morning) ├── log/life/YYYY-MM-DD.md # Life logs (with plan note in header) ├── log/mood_history.json # Mood history (7 days) ├── memory/SOUL_MEMORY.md # Distilled long-term memory └── state/state.json # Current state
Safety Rules
- Edit managed blocks only; do not mutate user-owned content outside those blocks.
- Write only inside the current workspace and
.soul/ - Memory system is independent - does not require memory-fusion.
References
- Full directory structurereferences/soul-layout.md
- Block marker policyreferences/managed-blocks.md