Skip to main content

memx - memory layer


Lightweight and extensible memory layer for LLMs.



Important Disclaimer: Lock the package version and run your own tests :)

🔥 Key Features

  • Framework agnostic: Use your preferred AI agent framework.
  • No vendor lock-in: Use your preferred cloud provider or infrastructure. No third-party api keys; your data, your rules.
  • Multiple backends: Seamlessly move from your local POC to production deployment (SQLite, MongoDB, PostgreSQL, Redis).
  • Sync and async api: Highly compatible with modern and legacy frameworks.
  • No forced schema: As long it is a list of json serializable objects.
  • Resumable memory: Perfect for chat applications and REST APIs.
  • Robust: Get production-ready code with minimal effort.
  • No esoteric patching: You have 100% control over the things you persist (and the things you don't). Act as a sidecar for your framework without touching your libraries under the hood.

⚙️ Installation

From pypi:

pip install memx-ai

🚀 Quickstart

OpenAI

Simple conversation using OpenAI Python library

# https://platform.openai.com/docs/guides/conversation-state?api-mode=responses
# tested on openai==2.6.1

from openai import OpenAI
from memx.engine.sqlite import SQLiteEngine

sqlite_uri = "sqlite+aiosqlite:///message-storage.db"
engine = SQLiteEngine(sqlite_uri, "memx-messages", setup=True)
m1 = engine.create_session()  # create a new session

client = OpenAI()

m1.sync.add([{"role": "user", "content": "tell me a good joke about programmers"}])

first_response = client.responses.create(
    model="gpt-4o-mini", input=m1.sync.get(), store=False
)

print(first_response.output_text)

m1.sync.add(
    [{"role": r.role, "content": r.content[0].text} for r in first_response.output]
)

m1.sync.add([{"role": "user", "content": "tell me another"}])

second_response = client.responses.create(
    model="gpt-4o-mini", input=m1.sync.get(), store=False
)

m1.sync.add(
    [{"role": r.role, "content": r.content[0].text} for r in second_response.output]
)

print(f"\n\n{second_response.output_text}")

print(m1.sync.get())

Pydantic AI

Message history with async Pydantic AI + OpenAI

# Reference: https://ai.pydantic.dev/message-history/

import asyncio

import orjson
from pydantic_ai import Agent, ModelMessagesTypeAdapter

from memx.engine.sqlite import SQLiteEngine

agent = Agent("openai:gpt-4o-mini")


async def main():
    sqlite_uri = "sqlite+aiosqlite:///message_store.db"
    engine = SQLiteEngine(sqlite_uri, "memx-messages", setup=True)
    m1 = engine.create_session()  # create a new session

    result1 = await agent.run('Where does "hello world" come from?')

    # it is your responsibility to add the messages as a list[dict]
    messages = orjson.loads(result1.new_messages_json())

    await m1.add(messages)  # messages: list[dict] must be json serializable

    session_id = m1.get_id()
    print("Messages added with session_id: ", session_id)

    # resume the conversation from 'another' memory
    m2 = await engine.get_session(session_id)
    old_messages = ModelMessagesTypeAdapter.validate_python(await m2.get())

    print("Past messages:\n", old_messages)

    result2 = await agent.run(
        "Could you tell me more about the authors?", message_history=old_messages
    )
    print("\n\nContext aware result:\n", result2.output)


if __name__ == "__main__":
    asyncio.run(main())

You can change the memory backend with minimal modifications. Same API to add and get messages.

from memx.engine.mongodb import MongoDBEngine
from memx.engine.postgres import PostgresEngine
from memx.engine.redis import RedisEngine
from memx.engine.sqlite import SQLiteEngine

# SQLite backend
sqlite_uri = "sqlite+aiosqlite:///message_store.db"
e1 = SQLiteEngine(sqlite_uri, "memx-messages", setup=True)
m1 = e1.create_session() # memory session ready to go

# PostgreSQL backend
pg_uri = "postgresql+psycopg://admin:1234@localhost:5433/test-database"
e2 = PostgresEngine(pg_uri, "memx-messages", setup=True)
m2 = e2.create_session()

# MongoDB backend
mongodb_uri = "mongodb://admin:1234@localhost:27017"
e3 = MongoDBEngine(mongodb_uri, "memx-test", "memx-messages")
m3 = e3.create_session()

# Redis backend
redis_uri = "redis://default:1234@localhost:6379/0"
e4 = RedisEngine(redis_uri, setup=True)
m4 = e4.create_session()

More examples...

🧪 Tests

uv run pytest tests -vs

📝 Tasks

  • Add mongodb backend
  • Add SQLite backend
  • Add Postgres backend
  • Add redis backend
  • Add tests
  • Publish on pypi
  • Add full sync support
  • Add docstrings
  • Add TTL to mongodb
  • Add TTL to redis

Metadata

Release files for memx-ai 0.1.17

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for memx-ai 0.1.17
File Size Uploaded Provenance
memx_ai-0.1.17.tar.gz 24.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for memx-ai 0.1.17
File Interpreter ABI Platform
memx_ai-0.1.17-py3-none-any.whl Python 3 none any Details

Total release size: 54.5 kB

Release files / memx_ai-0.1.17.tar.gz

Download URL memx_ai-0.1.17.tar.gz
Size 24.9 kB
Tags Source
SHA-256 checksum
How to use checksums
14dc840785e9f63ad65111c55281383d1cdb4daddcbbcc491933ff1ac7c2db9f
BLAKE2b-256 checksum
How to use checksums
bf2c807c20013a1763e3e33445261ace90342e43349616a9b5ff322c6f7ca591
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / memx_ai-0.1.17-py3-none-any.whl

Download URL memx_ai-0.1.17-py3-none-any.whl
Size 29.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f995cff16db8907431448559e787543c582446b53a1d75c0f44d7dcd6465add8
BLAKE2b-256 checksum
How to use checksums
870b79ab187d4b86dcd6f114952b40cb4155bc5ca9ec69ae1d294e5ee6bf9125
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Security for memx-ai 0.1.17

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for memx_ai-0.1.17.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page