Metadata-Version: 2.4
Name: bubble-memory
Version: 0.11
Summary: Event Sourcing based belief formation system for long-term AI agent memory
Author-email: AutismAccelerator <your.email@example.com>
License: MIT
Project-URL: Homepage, https://github.com/AutismAccelerator/bubble
Project-URL: Repository, https://github.com/AutismAccelerator/bubble
Project-URL: Issues, https://github.com/AutismAccelerator/bubble/issues
Keywords: ai,memory,agent,graph,llm,vector-store
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: falkordb>=1.6.0
Requires-Dist: httpx>=0.28.0
Requires-Dist: numpy>=2.4.4
Requires-Dist: python-dotenv>=1.2.2
Requires-Dist: scikit-learn>=1.8.0
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.86.0; extra == "anthropic"
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == "openai"
Provides-Extra: gemini
Requires-Dist: google-generativeai>=0.8; extra == "gemini"
Provides-Extra: all-providers
Requires-Dist: anthropic>=0.86.0; extra == "all-providers"
Requires-Dist: openai>=1.0; extra == "all-providers"
Requires-Dist: google-generativeai>=0.8; extra == "all-providers"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: anthropic>=0.86.0; extra == "dev"
Dynamic: license-file

# Bubble
A memory system lets your chatbot truly know you and maybe themselves.
## Core Idea
1. Intensity gating. Not everything is equally worth remembering. The more trivial the more accumulation needed in order to form a memory entry.
2. Input decomposition. Input is decomposed into atomic segments that preserve their original meaning, only highly related segments will cluster to form episodes which provide high precision retrieval.
3. Replayability. Human memory functions like an event-sourcing system, under the same experience, nearly identical personality would emerge again.
4. Lightweight and minimal LLM calls.\
**[paper](https://doi.org/10.5281/zenodo.19438945)**

---

## How it works
```
[ raw input ]
                               │
                         ┌─────▼─────┐
                         │ decompose │
                         └─────┬─────┘
                               │
              ┌────────────────┴────────────────┐
          ι ≥ θ                             ι < θ
              │                                 │
        vivid signal                       weak signal
              │                                 │
         ┌────▼────┐                     ┌──────▼──────┐
         │ archive │                     │    pool     │
         └────┬────┘                     │  · · · · ·  │
              │                          │ ·  · ·  · · │
              │                          │  · · · ·  · │
              │                          └──────┬──────┘
              │                                 │
              │                          enough gathered?
              │                                 │
              │                    no ──────────┘
              │                                 │ yes
              │                          ┌──────▼──────┐
              │                          │   cluster   │
              │                          │   + score   │
              │                          └──────┬──────┘
              │                                 │
              └──────────────┬──────────────────┘
                             │
                       ┌─────▼─────┐
                       │  episode  │  immutable
                       └─────┬─────┘
                             │
                     same topic chain?(NLI)
                      yes │       │ no
                          │       │
               ┌──────────▼─┐   ┌▼────────────┐
   joins chain │ ... ──► e  │   │     e       │  new chain
               └──────────┬─┘   └─────┬───────┘
                          │           │
                    ┌─────▼───────────▼─────┐
                    │       snapshot        │
                    │  centroid  │  summary │ 
                    │  (eager)   │  (lazy)  │
                    └───────────┬───────────┘
                                │
                           [ retrieve ]
                                │
               ┌────────────────┴─────────────────┐
           default                            verbose
               │                                  │
         snapshot summary             with episode chain + labels
```
## Setup
### 1.run [Falkordb](https://github.com/falkordb/falkordb) 
```bash
docker run -e REDIS_ARGS="--appendonly yes --appendfsync everysec" -v <PATH>:/var/lib/falkordb/data -p 3000:3000 -p 6379:6379 -d --name falkordb falkordb/falkordb
```
### 2.embedding model(Matryoshka)
**note: command below is cpu version**
```bash
docker run --name tei-embedding -d -p 8997:80 -v <PATH>:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cpu-latest --model-id nomic-ai/nomic-embed-text-v1.5

```
Or embedding cloud api

### 3.NLI model(Optional, but recommended, saves some LLM calls)
**note: command below is cpu version**
```bash
docker run --name tei-nli -d -p 8999:80 -v <PATH>:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cpu-latest --model-id cross-encoder/nli-deberta-v3-small
```


### Necessary configuration in your .env file
```python
ANTHROPIC_API_KEY=
FALKORDB_HOST=localhost
FALKORDB_PORT=6379
BUBBLE_EMBED_DIM=768
BUBBLE_EMBED_ENDPOINT=http://localhost:8997/v1/embeddings

#If you have NLI setup
BUBBLE_ENABLE_NLI=true
BUBBLE_NLI_ENDPOINT=http://localhost:8999/predict
```

## How to use (extremely easy and clean)
### installation
```bash
pip install bubble-memory
or
uv add bubble-memory
```
### ingest
```python
import bubble
bubble.process(user_id, content, prior)
```
prior: the context of the content, for example prior messages
### retrieve
```python
import bubble
memory_user = await bubble.retrieve(user_id, query)
```

## Replayability 
Memory episodes are archived in `<project root>/data/archive` as jsonl\
You can reconstruct your whole memory graph by a single command ! WITHOUT A SINGLE LLM CALL !
```python
python -m bubble.main replay <user_id>
```

## Tuning/Customization
See [.env.example](.env.example) for ALL tunable arguments.

## Limitations
Bubble is currently an experimental project for personal use.\
Current `promotion formula`, tunable variables might not be the best.\
`prompts` might have much room to improve. Patch **bubble.decomposer._SYSTEM** if it doesn't fit your use case.\
\
Leave a star if you like this work. Contributions are welcome.
