Lightweight, plug‑and‑play middlewares for LangGraph developers.
Production-ready middleware for LangChain and LangGraph v1 with multi-backend chat history persistence. Store conversations in SQLite, Supabase, or Firebase with zero configuration required.
Key Features:
- ✅ LangChain / LangGraph v1 Compatible: Native middleware pattern support
- ⚡ Zero Config Start: Defaults to in-memory SQLite—no setup needed
- 🔄 Multi-Backend Storage: Switch between SQLite, PostgreSQL, Supabase, Firebase with one parameter
- 🔒 Production Ready: JWT authentication, RLS support, type-safe
- 🧠 Context Engineering: Built-in support for long-term facts, semantic memories, and context management
| Middleware | Description | Supported Backends |
|---|---|---|
| ToolRemover | Removes tool-related messages from the conversation state (pre/post agent). | N/A (no backend needed) |
| ChatSaver | Persists chat histories | SQLite ✅, PostgreSQL ✅, Supabase ✅, Firebase ✅ |
| ContextEngineer | Auto context management with semantic memories | Supabase 🚧 (in progress) |
Core Package (SQLite only):
pip install langmiddleWith Optional Backends:
# For PostgreSQL support
pip install langmiddle[postgres]
# For Supabase support
pip install langmiddle[supabase]
# For Firebase support
pip install langmiddle[firebase]
# All backends
pip install langmiddle[all]from langmiddle.history import ChatSaver, ToolRemover, StorageContext
# Initialize middleware with desired backend
agent = create_agent(
model="gpt-4o",
tools=[],
context_schema=StorageContext,
middleware=[
ToolRemover(),
ChatSaver(backend="sqlite", db_path="./chat_history.db")
],
)
agent.invoke(
input={"messages": [{"role": "user", "content": "Hello!"}]},
context={
"user_id": "***", # User ID in UUID format
"session_id": "***", # Thread ID in UUID format
},
)ContextEngineer provides automatic context and memory management for conversations. It can store, retrieve, and query long-term facts (semantic memories) using the project's supported storage backends.
from langchain.chat_models import init_chat_model
from langchain.embeddings import init_embeddings
from langmiddle.context import ContextEngineer
# Initialize model and embedder
llm = init_chat_model("gpt-4o")
embedder = init_embeddings("text-embedding-3-small")
# When running for **the first time**, create databases in the backend
# Requires connection string for table creations
store = ChatStorage.create(
"supabase",
auto_create_tables=True,
enable_facts=True,
)
# Use in your agent
agent = create_agent(
model="gpt-4o",
tools=[],
context_schema=StorageContext,
middleware=[
ContextEngineer(
model=llm,
embedder=embedder,
backend="supabase",
backend_kwargs={'enable_facts': True},
),
],
)
agent.invoke(
input={"messages": [{"role": "user", "content": "Tell me about my preferences."}]},
context={
"user_id": "***", # User ID in UUID format
"session_id": "***", # Thread ID in UUID format
"auth_token": "***", # JWT token for supabase backend
},
)| Backend | Use Case | Pros | Cons | Setup |
|---|---|---|---|---|
| SQLite | Development, Single-user | Simple, Local, Fast, No setup | Not distributed | None |
| PostgreSQL | Self-hosted, Custom auth | Full control, Standard SQL, Flexible | Manual setup | Connection string |
| Supabase | Production Web Apps | Managed PostgreSQL, RLS, Real-time | Supabase-specific | Environment vars |
| Firebase | Mobile, Google ecosystem | Real-time, Managed, Global | Google-specific | Service account |
# Local file
backend_type="sqlite", db_path="./chat.db"
# In-memory (testing)
backend_type="sqlite", db_path=":memory:"# .env file or environment variables
POSTGRES_CONNECTION_STRING=postgresql://user:password@localhost:5432/dbname# Or pass directly
backend_type="postgres",
connection_string="postgresql://user:password@localhost:5432/dbname",
auto_create_tables=TrueSee PostgreSQL Setup Guide for details.
# .env file or environment variables
SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_anon_key
# To create tables
SUPABASE_CONNECTION_STRING=your_connection_string# Service account credentials file
backend_type="firebase", credentials_path="./firebase-creds.json"
# Or use GOOGLE_APPLICATION_CREDENTIALS environment variableWe welcome contributions! If LangMiddle helped you, please ⭐️ the repo to help others discover it.
Apache License 2.0 - see LICENSE for details.