Metadata-Version: 2.4
Name: kanoniv-mem0
Version: 0.1.0
Summary: Identity resolution for mem0. Same person, different IDs = unified memory.
Project-URL: Homepage, https://kanoniv.com
Project-URL: Documentation, https://docs.kanoniv.com/sdks/memory
Project-URL: Repository, https://github.com/kanoniv/kanoniv-mem0
Author-email: Kanoniv <hello@kanoniv.com>
License: Apache-2.0
Keywords: ai-agents,identity-resolution,kanoniv,mem0,memory
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: kanoniv[cloud]>=0.3.8
Requires-Dist: mem0ai>=0.1.0
Description-Content-Type: text/markdown

# kanoniv-mem0

Identity resolution for [mem0](https://github.com/mem0ai/mem0). Same person, different IDs = unified memory.

## The Problem

mem0 stores memories keyed by `user_id`. If two agents use different identifiers for the same person, mem0 treats them as separate users:

```python
from mem0 import Memory
m = Memory()

m.add("Prefers annual billing", user_id="bill@acme.com")
m.add("Needs 50 seat quote", user_id="william.smith@acme.com")

m.search("billing", user_id="bill@acme.com")
# Only finds 1 memory. The other is invisible.
```

Bill and William Smith are the same person. But mem0 doesn't know that.

## The Fix

```python
from kanoniv_mem0 import KanonivMemory
m = KanonivMemory(kanoniv_api_key="kn_live_...")

m.add("Prefers annual billing", user_id="bill@acme.com")
m.add("Needs 50 seat quote", user_id="william.smith@acme.com")

m.search("billing", user_id="bill@acme.com")
# Finds BOTH memories. Same canonical entity.
```

`KanonivMemory` resolves every `user_id` to a canonical entity via [Kanoniv's](https://kanoniv.com) identity graph before mem0 stores or retrieves anything. Different IDs that belong to the same person get the same `entity_id`. Memories unify automatically.

## Install

```bash
pip install kanoniv-mem0
```

## Quick Start

```python
from kanoniv_mem0 import KanonivMemory

# Drop-in replacement for mem0's Memory
m = KanonivMemory(kanoniv_api_key="kn_live_...")

# Agent A - support agent
m.add(
    "I'm Bill, VP of Engineering at Acme. Switch us to annual billing.",
    user_id="bill@acme.com",
)

# Agent B - sales agent (different email, same person)
m.add(
    "This is William Smith. Quote me for 50 Enterprise seats.",
    user_id="william.smith@acme.com",
)

# Agent C - searches by either ID, gets everything
results = m.search("billing", user_id="bill@acme.com")
# Returns memories from BOTH agents

results = m.get_all(user_id="william.smith@acme.com")
# Returns ALL memories for this person, regardless of which ID was used
```

## How It Works

```
Your code                KanonivMemory              mem0
   |                         |                        |
   | add(user_id="bill@..")  |                        |
   |------------------------>|                        |
   |                         | resolve("bill@..")     |
   |                         |-----> Kanoniv API      |
   |                         |<----- entity_id: ENT_7f|
   |                         |                        |
   |                         | add(user_id="ENT_7f")  |
   |                         |----------------------->|
   |                         |                        | store
```

1. You call `add()` or `search()` with any `user_id` (email, phone, name, internal ID)
2. `KanonivMemory` calls Kanoniv's resolve endpoint to get the canonical `entity_id`
3. The canonical ID is passed to mem0 as the `user_id`
4. Different identifiers for the same person resolve to the same entity
5. mem0 stores and retrieves using the unified ID

The resolve call adds ~5ms (sub-ms if cached in Kanoniv's Redis layer). Results are also cached locally per session.

## API

`KanonivMemory` is a drop-in replacement for `mem0.Memory`. All the same methods work:

| Method | Identity Resolved? | Description |
|--------|:-:|---|
| `add()` | Yes | Add memories from messages |
| `search()` | Yes | Search memories by query |
| `get_all()` | Yes | Get all memories for a user |
| `delete_all()` | Yes | Delete all memories for a user |
| `get()` | No | Get a specific memory by ID |
| `update()` | No | Update a specific memory |
| `delete()` | No | Delete a specific memory |
| `history()` | No | Get memory change history |
| `reset()` | No | Reset all memories |

### Additional methods

```python
# Check how a user_id resolves
m.get_entity_id("bill@acme.com")
# -> "ENT_7f82..."

# Same person, same entity
m.get_entity_id("william.smith@acme.com")
# -> "ENT_7f82..."

# Clear the local resolve cache
m.clear_cache()
```

## Configuration

```python
m = KanonivMemory(
    # mem0 config (optional - pass any mem0 MemoryConfig or dict)
    config={"vector_store": {"provider": "qdrant", ...}},

    # Kanoniv config
    kanoniv_api_key="kn_live_...",       # Get free key at app.kanoniv.com
    kanoniv_base_url="https://api.kanoniv.com",  # Default
    source_name="mem0",                  # Source name in identity graph
    cache_resolves=True,                 # Cache resolve results (default: True)
)
```

### Using Kanoniv's sandbox (free, no limits during development)

```python
m = KanonivMemory(
    kanoniv_api_key="kn_test_...",  # Sandbox keys start with kn_test_
)
```

Sandbox gives you 1,000 entities for free, instant reset, full API access.

## Graceful Degradation

If Kanoniv's API is unreachable, `KanonivMemory` falls back to using the raw `user_id` - exactly like vanilla mem0. Memory still works, you just lose cross-ID unification until the connection is restored. No data loss, no errors.

## Why Kanoniv?

[Kanoniv](https://kanoniv.com) is deterministic identity infrastructure for AI systems. It resolves records to canonical entities using configurable matching rules (email, phone, name, company), probabilistic scoring, and constraint-based merging.

- **Deterministic**: Same input always produces the same entity_id
- **Real-time**: Resolve calls return in <10ms
- **Explainable**: Every resolution includes confidence scores and match reasons
- **Multi-signal**: Matches on email, phone, name, company, and custom fields

Get a free API key at [app.kanoniv.com](https://app.kanoniv.com).

## License

Apache 2.0
