Skip to main content

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.

Python 3.10+ License: MIT

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_id is set, add() writes to a thread; otherwise it writes to the knowledge graph.
  • search() targets the knowledge graph.
  • get() and delete() 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unicontext-0.1.0.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unicontext-0.1.0-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

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

Hashes for unicontext-0.1.0.tar.gz
Algorithm Hash digest
SHA256 64b18166d6753b7c1e6b33890f9905c79a1d01cd4c6fff08a5c09add31d8612e
MD5 3d4808bc496010fa8f13f572de8d616c
BLAKE2b-256 9c1d3a6bfeabe84b982e8d42c763a38e516fcc60342be888fcfb35eb55e9bf68

See more details on using hashes here.

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

Hashes for unicontext-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 51520a684af3910446efd9eaa1949440f3518a669061c378cd5e690bdb296e80
MD5 6c93f7db694dd08835c77094140aae07
BLAKE2b-256 5541cccd73cf3bc12ae74670252f7df1e86791a720cdb5c423377d136f6e0948

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page