Skip to content

chrbailey/MyPersona

Repository files navigation

MyPersona — Emotional Memory for AI Agents

Add emotional memory to any AI agent. Track user mood, detect when stated values diverge from revealed behavior, and store memories that fade naturally over time — intense moments persist, mundane ones dissolve.

MyPersona is a Python library and MCP server that gives AI agents emotional intelligence: not just remembering what users said, but how they felt — and using that to predict what they'll actually do versus what they claim they'll do.

Built with Claude Opus 4.6 | MIT License | ~3,400 LOC | 141 tests

Status: v0.2 experimental. Core pipeline (mood detection, dual engines, gap analysis, governance) is test-covered and works offline. Pinecone-backed memory storage requires a PINECONE_API_KEY; the agent loop requires ANTHROPIC_API_KEY. See "What this is NOT" below for scope limits.

MyPersona Demo

What Problem Does This Solve?

Current AI memory systems store facts. They don't store emotional context. This means:

  • An agent can't tell if a user wanted to do something or felt obligated to
  • All memories have equal weight — a crisis and a lunch order persist identically
  • There's no model for behavioral prediction — only recall of stated intentions
  • Emotionally intense memories (layoffs, breakthroughs, conflicts) get no special treatment

MyPersona solves this with a dual-engine architecture based on Self-Discrepancy Theory (Higgins, 1987):

Engine Tracks Signals
Engine 1 — Persona (Should-Self) What authority, rules, and social pressure say you should value Compliance language, authority references, espoused beliefs
Engine 2 — Reward (Want-Self) What actually energizes you, revealed through behavior Positive valence, approach behavior, elaboration, excitement
Gap Layer Where the engines diverge — predicts action vs. intention Theatre score: high gap = user will likely follow Want-Self at moment of decision

When To Use This

  • You're building an AI agent that interacts with users over multiple sessions and needs to remember emotional context
  • You want to detect when a user says they'll do X but their behavior signals they'll actually do Y
  • You need memory that naturally prioritizes what mattered — not just what happened recently
  • You want human-in-the-loop governance over emotionally intense memories before they're stored

What This Is NOT

  • Not a production-ready memory backend. Pinecone is optional; without it memory features are limited to in-process state plus the local SQLite timeline.
  • Not a clinical or diagnostic tool. "Mood", "gap" and "theatre score" are useful engineering signals, not psychological assessments.
  • Not model-agnostic. The agent loop assumes Claude Opus 4.6 extended thinking. The pure-Python engines (mood, dual-engine, gap, decay) do not need an LLM and can be used standalone.
  • Not an MCP memory store like knowledge-store. MyPersona models emotional state and conflict. Pair it with a retrieval store — it does not replace one.

Quick Start (60 seconds)

git clone https://github.com/chrbailey/MyPersona.git
cd MyPersona
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

# Run the full test suite (no API keys needed)
python3 -m pytest tests/ -q        # 141 tests, ~0.4s

# Run the offline demo (no API keys needed)
python3 -m demo.run_demo --fast

MCP Server Integration

MyPersona runs as an MCP server over stdio. Any MCP-compatible client (Claude Code, Claude Desktop, custom agents) can use it.

Register with Claude Code

claude mcp add mypersona -- python3.11 -m src.server

12 Tools (verified against src/server.py)

Tool What It Does When To Call It
detect_mood Analyze emotional signals in a user message (valence, arousal, quadrant, confidence) On each user message, before downstream reasoning
get_emotional_timeline Mood history for a topic over time When you need trend data across a conversation
query_beliefs Current beliefs with Bayesian confidence levels To understand the user's belief landscape
update_belief Update a belief's strength After receiving new evidence about a belief
search_memories Semantic search over emotional memories When recalling relevant past interactions
store_emotional_memory Store a memory with current mood state attached (governance-gated for intense events) When a significant moment should be persisted
manage_authority Add or update an authority source in the trust hierarchy When learning who the user defers to
get_influence_analysis Influence sources, compliance tendency, reward profile For dashboard / diagnostic views
get_gap_analysis Dual-engine gap analysis — where stated values ≠ revealed behavior To surface theatre between Should-Self and Want-Self
explain_behavior Explain seemingly irrational behavior using the engine gap When the user asks "why did I do that?"
list_holds Governance holds — actions paused for human review For approval UIs
resolve_hold Approve or reject a paused action Human-in-the-loop decision

Example: Detecting a Gap

After several interactions where a user complies on documentation but lights up when talking about shipping:

# Via MCP tool call
gap = await call_tool("get_gap_analysis", {})
# Returns something like:
# {
#   "theatre_score": 0.67,
#   "topic_gaps": [{
#     "topic": "documentation",
#     "persona_opinion": 0.82,   # high — authority says it matters
#     "reward_opinion": 0.31,    # low — no genuine engagement
#     "gap_magnitude": 0.51,
#     "conflict_severity": "significant",
#     "predicted_behavior": "Will procrastinate on docs, prioritize shipping"
#   }]
# }

Python Library Usage

Use the components directly without MCP (no API keys required):

from src.engines import MoodDetector, GapAnalyzer, PersonaEngine
from src.memory import emotional_decay, GovernanceLayer
from src.belief import TruthLayer

# Detect mood from text — pure Python, no LLM
mood = MoodDetector().detect("I can't believe it, everyone got laid off")
# MoodState(valence=-0.95, arousal=+0.45, quadrant=STRESSED, confidence=0.9)

# Compute how fast a memory fades
retention = emotional_decay(hours=720, encoding_weight=1.5, intensity=0.9)
# 0.47 — flashbulb memory still 47% retrievable after 30 days

retention = emotional_decay(hours=720, encoding_weight=0.3, intensity=0.2)
# 0.02 — mundane memory effectively gone after 30 days

How It Works

User Message ──▶ Mood Detector ──▶ valence + arousal + signals
                      │
       ┌──────────────┼──────────────┐
       ▼              ▼              ▼
  Authority      Compliance      Belief
    Graph         Detector       Extractor
       │              │              │
       ▼              ▼              ▼
  ┌─────────────────────────────────────┐
  │     Engine 1 — Persona (Should)     │
  │  authority weight × trust + comply  │
  └──────────────┬──────────────────────┘
                 ▼
  ┌─────────────────────────────────────┐
  │        Gap Layer (Theatre)          │ ◀── divergence score
  │   | persona - reward | per topic    │
  └──────────────┬──────────────────────┘
                 ▼
  ┌─────────────────────────────────────┐
  │     Engine 2 — Reward (Want)        │
  │  valence × approach/avoid + reward  │
  └──────────────┬──────────────────────┘
                 │
      ┌──────────┼──────────┐
      ▼          ▼          ▼
  Encoding   Governance  Introspective
   Weight      Gate       Narration
      │          │          │
      ▼          ▼          ▼
  ┌─────────────────────────────────────┐
  │     Emotional Memory (Pinecone)     │
  │  R = e^(-t/S), S ~ encoding weight  │
  └─────────────────────────────────────┘

Key Concepts

Emotional Decay (FadeMem): Memories fade on an Ebbinghaus forgetting curve, modulated by emotional intensity. Flashbulb memories (encoding weight ~1.5) retain ~47% after 30 days. Mundane memories (encoding weight ~0.3) drop to ~2%. This means the agent's memory naturally self-curates over time — what mattered persists, what didn't dissolves.

Governance Gate: Memories with extreme encoding weight (flashbulb events) or high engine conflict are held for human approval before storage. This prevents the agent from permanently encoding crisis moments or conflicted states without oversight.

Introspective Narration: The agent builds a self-model and reports what it knows (confident), what it's guessing (moderate), and where it's blind (no data). Uses Opus 4.6 extended thinking with adaptive budget: more emotional complexity → more thinking tokens (5,000–16,000 range).

Subjective Logic: Beliefs are represented as (belief, disbelief, uncertainty) triples, not simple probabilities. This means the agent distinguishes between "I believe X" and "I have no data about X" — both might show 50% probability, but uncertainty tells them apart.

Research Foundations

Concept Source How It's Used
Self-Discrepancy Theory Higgins (1987) Dual-engine: Should-Self vs Want-Self
Ebbinghaus Forgetting Curve FadeMem (2025) emotional_decay() — memories fade unless emotionally reinforced
Zettelkasten Memory Links A-Mem (2024) Bidirectional memory graph with one-hop expansion on search
Subjective Logic Josang (2016) Belief triples, trust discounting through authority chains
Circumplex Model of Affect Russell (1980) 4-quadrant mood detection (excited/calm/stressed/low)
Want/Should Conflict Bazerman et al. (1998) Gap layer predicts action vs. stated intention

File Structure

src/
├── models.py    (379 lines)   Data models — MoodState, EngineOpinion, GapAnalysis, etc.
├── engines.py   (825 lines)   Signal processing — mood, authority, compliance, reward, gap
├── memory.py    (388 lines)   Storage + governance — Pinecone, decay, audit trail
├── belief.py    (533 lines)   Bayesian belief system — subjective logic, trust, fusion
├── agent.py     (835 lines)   Agent loop — context assembly, Opus 4.6 adaptive thinking
└── server.py    (466 lines)   MCP server — 12 tools over stdio

tests/                         141 tests across 13 files (~0.4s)
demo/run_demo.py               5 scripted scenarios with Rich CLI rendering

Demo

Five scripted scenarios demonstrate the pipeline without API keys:

python3 -m demo.run_demo --fast       # All 5 scenarios, no pauses
python3 -m demo.run_demo --scenario 3 # Single scenario
python3 -m demo.run_demo --list       # List scenarios
python3 -m demo.run_demo --live       # Real Opus 4.6 API (needs ANTHROPIC_API_KEY)
# Scenario Demonstrates
1 The Compliant Employee Authority builds Engine 1 — boss + policy shape the Should-Self
2 The Hidden Passion Engine 2 activates — approach signals, positive valence, elaboration
3 Theatre Detection Gap Layer surfaces divergence: comply on docs, light up on shipping
4 Flashbulb Memory Crisis triggers governance hold — intense memory needs human approval
5 The Self-Aware Agent Introspective narration — agent reports uncertainty and blind spots

Tests

python3 -m pytest tests/ -v    # 141 tests, ~0.4s

CI runs the suite on Python 3.11 and 3.12. See .github/workflows/tests.yml.

Requirements

  • Python 3.11+
  • Dependencies: anthropic, pinecone, rich, mcp, httpx, pyyaml, python-dotenv
  • Optional: ANTHROPIC_API_KEY for live agent mode, PINECONE_API_KEY for persistent memory

Known Limitations

  • Mood detector is English-only. Signal patterns (regex + keyword tables) are calibrated on English text. Other languages will likely score near-neutral.
  • Theatre score is a signal, not a prediction. A high theatre score means "these two engines disagree on this topic" — it is not a probability that the user will behave theatrically. Treat it as a flag, not a forecast.
  • Pinecone coupling. Persistent memory assumes Pinecone. Swapping in another vector store requires editing src/memory.py.
  • No auth on the MCP server. The stdio MCP server trusts its caller. Do not expose it over a network without wrapping it in an authenticated transport.
  • Single-user model. There is no multi-user namespacing; run one instance per user / agent identity.

Contributing

See CONTRIBUTING.md. Security issues: SECURITY.md. Changes: CHANGELOG.md.

License

MIT

About

Emotional memory for AI agents — dual-engine mood tracking, behavioral prediction, and governed memory that fades naturally over time. MCP server with 12 tools. Built with Opus 4.6.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages