MemorySync
Integrations

LangChain Memory

Give any LangChain chain or agent persistent memory with two packages: langchain-memorysync for Python and memorysync-langchain for Node.js. Both work on langchain-core 0.3.x and 1.x.

RunnableWithMessageHistory keeps the transcript in conversation history and sends user messages to fact extraction, while a context provider recalls cross-session memory for the prompt.

What the integration provides

PieceWhat it does
MemorySyncChatMessageHistoryA BaseChatMessageHistory implementation, so RunnableWithMessageHistory persists transcripts in MemorySync instead of process memory.
Context providerOne call that returns a grouped, prompt-ready context block from hierarchical recall, for personalising a system prompt.
Agent toolsFive structured memory tools for agents, covered in LangChain Tools.

Install

pip install langchain-memorysync

Set MEMORYSYNC_API_KEY in the environment, or pass the key explicitly. Keys come from the dashboard or npx memorysync-cli init. The cURL tabs on this page show the REST call each operation makes.

Persist chat history

Wrap any runnable with RunnableWithMessageHistory and hand it a MemorySync-backed history per session. Each exchange is written as soon as the chain finishes the turn and read back in order, so a restarted process resumes where the conversation left off.

from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_memorysync import MemorySyncChatMessageHistory
chain_with_history = RunnableWithMessageHistory(
chain,
lambda session_id: MemorySyncChatMessageHistory(
session_id=session_id,
user_id="user-123",
),
input_messages_key="input",
history_messages_key="history",
)
chain_with_history.invoke(
{"input": "My name is Ada."},
config={"configurable": {"session_id": "thread-42"}},
)

Each message is kept in the session’s conversation history exactly as written, so short answers like "yes" survive. The full LangChain message — tool calls included — is stored with the turn and reconstructed exactly on read. The transcript is not part of the user’s memories: MemorySync extracts the durable facts from the user’s messages and stores those as memories, which is what recall and the context provider return.

Sessions and users

ParameterMeaning
session_idThe conversation thread. Reads and clear() touch only this thread.
user_idThe end user the turns belong to. Defaults to the session id; pass a stable user id to share memory across that user’s sessions.
max_messagesCap on how many trailing messages a read returns, so a long transcript cannot blow the prompt budget. Writes are unaffected.
read_onlyBlocks writes and clear() for safe transcript inspection.

Prompt-ready recall context

For personalisation beyond the current thread, the context provider returns a grouped, type-labelled block built by hierarchical recall — ready to place in a system prompt. It returns an empty string when the user has no relevant memories, because a new user is a normal state, not an error.

from langchain_memorysync import MemorySyncContextProvider
provider = MemorySyncContextProvider(user_id="user-123")
context = provider.get_context("What should I cook tonight?")
prompt = f"Relevant memories:\n{context}\n\nAnswer the user."

Complete example: a chatbot that remembers

Everything above in one runnable program: per-session transcripts through the history class, cross-session personalisation through the context provider, and an LLM in the middle. Stop the process, start it again, and the conversation resumes where it left off — with what the user told you last week already in the system prompt.

import os
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI
from langchain_memorysync import (
MemorySyncChatMessageHistory,
MemorySyncContextProvider,
)
USER_ID = "customer-7"
llm = ChatOpenAI(model="your-model")
provider = MemorySyncContextProvider(user_id=USER_ID)
prompt = ChatPromptTemplate.from_messages([
(
"system",
"You are a helpful travel assistant.\n"
"Relevant memories about this user:\n{memories}",
),
MessagesPlaceholder(variable_name="history"),
("human", "{input}"),
])
chat = RunnableWithMessageHistory(
prompt | llm,
lambda session_id: MemorySyncChatMessageHistory(
session_id=session_id,
user_id=USER_ID,
max_messages=30,
),
input_messages_key="input",
history_messages_key="history",
)
def chat_turn(text: str, session_id: str) -> str:
# Long-term memories from every past session, not just this thread.
memories = provider.get_context(text) or "None yet."
reply = chat.invoke(
{"input": text, "memories": memories},
config={"configurable": {"session_id": session_id}},
)
return reply.content
if __name__ == "__main__":
print("Travel assistant (empty line to quit)")
while True:
text = input("you: ").strip()
if not text:
break
print("assistant:", chat_turn(text, session_id="trip-planning-1"))

Supported versions

PackageRegistrylangchain-coreRuntime
langchain-memorysync 1.2.0PyPI0.3+ (tested on 0.3.x and 1.x)Python 3.10+
memorysync-langchain 1.2.0npm0.3+ peer dependency (tested on 0.3.x and 1.x)Node 18+

Both packages run their full test suites against langchain-core 0.3.x and 1.x on every commit, so an upgrade on your side is not a leap of faith.

Where to go next

Was this page helpful?