🧬 SoulAdapt
An adaptation & sincerity layer for AI companions. Companion to SoulMemory.
🎯 Why SoulAdapt?
Most AI companions either invent memories or treat every user exactly the same. SoulAdapt fixes both:
- 🎛️ Adapts how the AI talks: style, sensitive topics, interests
- 💎 Never invents: calibrates honesty to the real memory signal
- 🪶 Zero dependencies: pure Python standard library
- 🤝 Compatible, not dependent: works with SoulMemory or any object with
.recall()
✨ Features
| Feature | Description |
|---|---|
observe() |
Learn something about the user |
learn_from() |
Auto-extract observations from user text (ES/EN) |
observations() |
What the companion learned, strongest first |
forget_observation() |
Unlearn something |
decide() |
How to respond: style, avoid-list, interests, honesty, tone |
prompt_context() |
Ready-to-paste context string for LLM prompts |
SincerityEngine |
distance → confidence → assertive / hedged / admit (EN/ES) |
habits() |
Detect routines from the memory timeline (day + topic) |
bring_up() |
Proactive topic suggestions (interests + habits) |
decay_observations() |
Fade unvalidated observations over time |
📦 Installation
pip install souladapt
🚀 Quick Start
Standalone (no memory connected)
from souladapt import SoulAdapt
adapt = SoulAdapt("adapt.db")
adapt.observe("Prefiere respuestas cortas", category="style")
adapt.observe("Ruptura con Ana", category="sensitive")
d = adapt.decide("hola")
# → {'style': ['Prefiere respuestas cortas'],
# 'avoid': ['Ruptura con Ana'], 'interests': [],
# 'memories': [], 'confidence': None, 'honesty': 'neutral'}
Connected to SoulMemory
from soulmemory import SoulMemory # optional extra: pip install souladapt[soulmemory]
from souladapt import SoulAdapt
mem = SoulMemory("memory.db")
adapt = SoulAdapt("adapt.db", memory=mem)
d = adapt.decide("¿qué sabes de Ana?")
# → honesty calibrated from real recall distances
💎 The three honesty levels
confidence ≥ 0.75 → assertive "You had coffee with Ana."
0.45 – 0.75 → hedged "If I remember correctly: ..."
< 0.45 → admit "I don't have a clear memory..."
The AI never invents: if the memory is weak, it admits it.
🎭 Mood-based tone
When connected to a memory with emotional_timeline(), decide()
reads the user's current mood and recommends a tone:
sadness / fear -> gentle (soft, warm) anger / disgust -> careful (calm, respectful) joy / surprise -> energetic (match the energy)
🤖 Auto-learning
adapt.learn_from('Prefiero respuestas cortas') # -> style
adapt.learn_from("Me encantan los gatos") # → interests
adapt.learn_from("No me hables de política") # → sensitive
📅 Habits & proactivity
When connected to a memory with timeline(), SoulAdapt notices
routines and can bring them up like a friend:
adapt.habits()
# → [{'day': 'Monday', 'topic': 'running', 'count': 2}]
adapt.bring_up()
# → ['Le gustan los gatos', 'running (usually on Mondays)']
And like human assumptions, observations that are never re-validated fade away:
adapt.decay_observations(max_age_days=30)
🤝 The contract (duck typing)
SoulAdapt never imports SoulMemory. Any object satisfies the contract if it has:
.recall(query, limit) → list of dicts with "content" and "distance"
SoulMemory satisfies it out of the box. So does your own memory system.
️ Observation categories
style → how to talk to the user ("short answers", "casual tone")
sensitive → topics to handle with care ("breakup with Ana")
interests → what they like ("cats", "gym")
general → everything else
📚 API Reference
SoulAdapt(db_path="souladapt.db", memory=None)
Create an adapter. memory is any SoulMemory-like object (optional).
observe(content, category="general")
Register something learned about the user. Repeated observations get reinforced, not duplicated.
observations(category=None)
Get learned observations, strongest first.
forget_observation(observation_id)
Delete an observation: the companion unlearns it.
decide(query, limit=3)
Decide HOW the AI should respond. Returns style hints, topics to avoid, interests, evaluated memories, confidence and honesty level.
habits(min_count=2)
Detect routines from the connected memory's timeline. Returns a list of dicts with day, topic and count.
bring_up(limit=2)
Suggest topics to mention proactively: interests + habits.
decay_observations(max_age_days=30, fade=0.2, min_weight=0.3)
Fade or delete observations not reinforced recently.
close()
Close the database connection.
🎬 Examples
python examples/demo_adapt.py # standalone + connected to SoulMemory
🗺️ Roadmap
- Observations (reinforcement learning-lite)
-
decide()adaptation layer -
SincerityEngine(3 honesty levels) - Auto-learning (
learn_from(), ES/EN) - Mood-based tone adaptation
- Bilingual sincerity phrases
-
prompt_context()for LLM integration - Habit & routine detection
- Observation decay (unlearning over time)
- Proactive suggestions (
bring_up()) - Multi-user support
- Unified profile + tone presets
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- SoulMemory — the memory layer this adapts to
Made with ❤️ as part of the Soul ecosystem
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file souladapt-0.3.0.tar.gz.
File metadata
- Download URL: souladapt-0.3.0.tar.gz
- Upload date:
- Size: 15.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
deb60fa752444a4b8d9c2152fb86229da722169206378c99a6b283ae63b52d71
|
|
| MD5 |
2dc40a74c65527b17766be09deb254be
|
|
| BLAKE2b-256 |
39d6db9709ebbacf99c96114b6a9532cbbc9c09c32226edbc60c9a9e4a196a64
|
File details
Details for the file souladapt-0.3.0-py3-none-any.whl.
File metadata
- Download URL: souladapt-0.3.0-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7923de7f3a7cc7ef293e21901dddcbf6c4e3e1f89cbd8302fc16a4a01ccb556
|
|
| MD5 |
519a517b0c1d26c38dbf67a553ae5194
|
|
| BLAKE2b-256 |
5870351f6b70db7a871877c4d43155f6c5241c511ea52795002a54973c1953a4
|