-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: ABX
-
None
-
Python Drivers
-
None
-
None
-
None
-
None
-
None
-
None
TL;DR
LlamaIndex's modern Memory API persists short-term chat history through the AsyncDBChatStore interface, but the only implementation today is SQL-based. MongoDB users who want the modern memory features are therefore forced to run a separate SQL database just for chat history. Add a MongoDBChatStore(AsyncDBChatStore) implementation to the existing llama-index-storage-chat-store-mongo package so MongoDB can be used as a single persistence backend.
Context
What LlamaIndex is. LlamaIndex is a Python framework for building LLM applications (retrieval-augmented generation, chatbots, agents). It stores state in pluggable "stores" so you can swap the underlying database.
Concept Overview:
- Chat store — the component that persists a conversation's messages so they survive across requests/restarts, keyed by a session id (e.g., one key per user or per conversation).
- Memory (the "new" memory path) — the current, recommended memory abstraction in llama-index-core. It manages short-term memory as a first-in-first-out (FIFO) queue of recent messages, and long-term memory through pluggable "memory blocks" (e.g., extracted facts, or a vector index of older messages). When the short-term queue exceeds a token limit, the oldest messages "waterfall" out and are flushed into the long-term blocks. A backend that only stores an undifferentiated list of messages cannot support this waterfall, which is why a dedicated AsyncDBChatStore implementation is required.
- AsyncDBChatStore — the async, database-backed interface the Memory class uses for that short-term FIFO queue. It is the interface a new backend must implement.
- ChatMemoryBuffer (the "legacy" memory path) — the older memory abstraction. It uses a different interface (BaseChatStore) and has no memory blocks and no archival/waterfall.
Who this is for. People already storing their application data in MongoDB who want the modern memory features — specifically long-term memory (automatically extracted facts, or semantic recall of older messages via a vector store) rather than just a raw message log — without having to run a second, SQL database alongside MongoDB.
The problem. MongoDB already has a chat store — MongoChatStore — but it implements only the legacy BaseChatStore interface, so it works with ChatMemoryBuffer, not the modern Memory class. There is currently no MongoDB implementation of AsyncDBChatStore; the only implementation is SQLAlchemyChatStore (SQLite/Postgres/etc.). As a result, a MongoDB-based deployment that wants the modern memory features must stand up a second, SQL database purely for short-term chat history.
Desired Experience
Today, Option A — modern Memory, but forced onto a SQL database (not MongoDB). Long-term memory blocks work, but chat history lives in a second database:
from llama_index.core.memory import Memory memory = Memory.from_defaults( session_id="user_123", token_limit=40000, # a second, SQL database purely for chat history: async_database_uri="postgresql+asyncpg://u:pw@localhost/db", )
Today, Option B — MongoDB works, but only via the legacy path. Single backend, but no memory blocks and no archival waterfall (raw message log only):
from llama_index.core.memory import ChatMemoryBuffer from llama_index.storage.chat_store.mongo import MongoChatStore # legacy BaseChatStore memory = ChatMemoryBuffer.from_defaults( token_limit=40000, chat_store=MongoChatStore(mongo_uri="mongodb://localhost:27017", db_name="app"), chat_store_key="user_123", ) # Only stores/returns recent messages. No fact extraction, no vector recall of old messages.
Desired, after this ticket — modern Memory persisted entirely to MongoDB. Single backend and full modern feature set:
from llama_index.core.memory import Memory from llama_index.core.memory import FactExtractionMemoryBlock, VectorMemoryBlock from llama_index.storage.chat_store.mongo import MongoDBChatStore # NEW, AsyncDBChatStore memory = Memory.from_defaults( session_id="user_123", token_limit=40000, # short-term FIFO chat history now lives in MongoDB, not SQL: # Note parameter `mongo_uri` changed to `uri` to be consistent with the modern interface (implemented in INTPYTHON-1048) chat_store=MongoDBChatStore(uri="mongodb://localhost:27017", db_name="app"), # long-term memory blocks still work; everything persists to the one MongoDB backend: memory_blocks=[ FactExtractionMemoryBlock(...), # extracts durable facts from the conversation VectorMemoryBlock(...), # semantic recall of older, waterfalled messages ], ) # Add messages, exceed the token limit, and the oldest messages waterfall from the # short-term MongoDB queue into the long-term blocks — all on MongoDB, no SQL database. await memory.aput(ChatMessage(role="user", content="...")) history = await memory.aget() # merged short-term + long-term, read back from MongoDB
Task
Goals:
- Add a new class MongoDBChatStore that subclasses AsyncDBChatStore and implements all of its abstract methods, backed by a MongoDB collection.
- Ship it inside the existing llama-index-storage-chat-store-mongo package (alongside, not replacing, the legacy MongoChatStore) and export it from the package's _init_.py.
- Make the new class usable directly as the chat_store argument to Memory.from_defaults(...), delivering the "Desired" example above.
Where:
- Package to extend: llama-index-storage-chat-store-mongo
- Source file (contains the legacy MongoChatStore): base.py
- Package exports to update: _init_.py
- Package metadata to update: pyproject.toml
- Interface to implement: base_db.py (AsyncDBChatStore)
- Reference implementation to mirror: sql.py (SQLAlchemyChatStore)
(Product) Acceptance Criteria
- [ ] A MongoDB user can construct MongoDBChatStore(...) and pass it as the chat_store argument to Memory.from_defaults(...), exactly as in the "Desired" example above.
- [ ] MongoDBChatStore passes the equivalent of every test in the SQL store's suite, run against MongoDB: test_sql.py (add/get messages, batch add, count, set/replace, delete one, delete all for a key, delete oldest, archive oldest, get with limit/offset, get keys, and dump/load).
- [ ] The legacy MongoChatStore remains present and unchanged, so existing users are unaffected.
- [ ] Chat store identifies itself via client metadata on connections it creates (driver-info handshake, 'llamaindex-chat_store').
- [ ] A follow up DOCSP ticket to update LlamaIndex documentation has been created
References
- Memory (concepts, memory blocks, waterfall) — official docs: Memory module guide
- Memory usage example — official docs: Memory in LlamaIndex
- Related community request: run-llama/llama_index issue #18979