Universal Python SDK for AI memory/context providers with HTTP-first architecture
Project description
UniContext
Universal Python SDK for agent memory and context with a unified API across multiple providers.
UniContext is HTTP-first: built-in providers call provider REST APIs via httpx. Switch providers by changing the provider name and API key.
Features
- Unified, provider-agnostic client API
- Typed models and input validation
- Consistent error types across providers
- Shared HTTP transport (connection pooling)
Installation
From PyPI:
pip install unicontext
From source (development):
pip install -e .
Optional development tools:
pip install -e ".[dev]"
Quick start
This example uses Letta (archives mode) because it has synchronous IDs you can get() and delete() immediately.
from unicontext import MemoryInput, Scope, SearchQuery, create_client
client = create_client(provider="letta", api_key="YOUR_LETTA_API_KEY")
scope = Scope(user_id="user_123")
created = client.add(MemoryInput(text="User prefers Python for backend"), scope)
hits = client.search(SearchQuery(query="backend", scope=scope, limit=5))
for hit in hits:
print(hit.record.content)
fetched = client.get(memory_id=created.id, scope=scope)
print(fetched.content)
client.delete(memory_id=created.id, scope=scope)
Switching providers
from unicontext import create_client
mem0 = create_client(provider="mem0", api_key="YOUR_MEM0_API_KEY")
supermemory = create_client(provider="supermemory", api_key="YOUR_SUPERMEMORY_API_KEY")
zep = create_client(provider="zep", api_key="YOUR_ZEP_API_KEY")
letta = create_client(provider="letta", api_key="YOUR_LETTA_API_KEY")
Core concepts
Scope
Scope selects where the memory lives (user, agent, thread, tags).
from unicontext import Scope
Scope(user_id="user_123")
Scope(user_id="user_123", thread_id="thread_456")
Scope(user_id="user_123", tags=["preferences", "onboarding"])
Inputs
MemoryInput must provide exactly one of text or messages.
from unicontext import MemoryInput
MemoryInput(text="User prefers dark mode")
MemoryInput(messages=[{"role": "user", "content": "Hi"}])
Provider notes
UniContext normalizes the public API, but providers have different semantics.
Mem0
add()is asynchronous; the returned ID may be an event ID.- Use
search()after processing completes to retrieve the finalized memory ID.
import time
from unicontext import MemoryInput, Scope, SearchQuery, create_client
client = create_client(provider="mem0", api_key="YOUR_MEM0_API_KEY")
scope = Scope(user_id="user_123")
client.add(MemoryInput(text="User likes espresso"), scope)
time.sleep(20)
hits = client.search(SearchQuery(query="espresso", scope=scope, limit=5))
if hits:
memory_id = hits[0].record.id
client.delete(memory_id=memory_id, scope=scope)
Supermemory
- Scope is primarily tag-driven.
delete_by_scope()requires at least one tag to reduce accidental deletes.
Zep
- Dual routing: if
scope.thread_idis set,add()writes to a thread; otherwise it writes to the knowledge graph. search()targets the knowledge graph.get()anddelete()are not supported for graph records.
Letta
- Default mode uses archives and passages.
- If you do not provide an archive ID, UniContext auto-creates and caches one per
scope.user_id.
Error handling
from unicontext import Scope, SearchQuery, create_client
from unicontext.exceptions import AuthError, ProviderError, ValidationError
client = create_client(provider="letta", api_key="YOUR_LETTA_API_KEY")
scope = Scope(user_id="user_123")
try:
client.search(SearchQuery(query="hello", scope=scope, limit=5))
except ValidationError as e:
print(e.message)
except AuthError as e:
print(e.message)
except ProviderError as e:
print(e.message)
Development
Run unit tests:
python -m pytest -v
Run the pre-release checks:
python scripts/pre_release.py
Project details
Release history Release notifications | RSS feed
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 unicontext-0.1.0.tar.gz.
File metadata
- Download URL: unicontext-0.1.0.tar.gz
- Upload date:
- Size: 20.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64b18166d6753b7c1e6b33890f9905c79a1d01cd4c6fff08a5c09add31d8612e
|
|
| MD5 |
3d4808bc496010fa8f13f572de8d616c
|
|
| BLAKE2b-256 |
9c1d3a6bfeabe84b982e8d42c763a38e516fcc60342be888fcfb35eb55e9bf68
|
File details
Details for the file unicontext-0.1.0-py3-none-any.whl.
File metadata
- Download URL: unicontext-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51520a684af3910446efd9eaa1949440f3518a669061c378cd5e690bdb296e80
|
|
| MD5 |
6c93f7db694dd08835c77094140aae07
|
|
| BLAKE2b-256 |
5541cccd73cf3bc12ae74670252f7df1e86791a720cdb5c423377d136f6e0948
|