🧠 PACT for LangChain
Drop-in memory replacement that makes your agents remember what matters.
The Problem
Your LangChain agent forgets things. Important things.
# Standard LangChain memory
conversation.memory.save_context(
{"input": "I'm really frustrated with this bug"},
{"output": "I understand. Let's debug it."}
)
# 10 messages later...
conversation.memory.load_memory_variables({})
# Returns: Everything, including irrelevant details
# Missing: The emotional context that matters
Result: Your agent treats every message the same. No emotional awareness. No prioritization. Just a wall of text.
The Solution
PACT Memory tracks what matters - emotions, context, and relationships.
from pact_langchain import PACTMemory
memory = PACTMemory(api_key="your_key")
conversation = ConversationChain(llm=llm, memory=memory)
# Same interface, better memory
conversation.predict(input="I'm really frustrated with this bug")
# PACT tracks: emotional_state="frustrated", priority="high"
# 10 messages later...
memory.load_memory_variables({})
# Returns: Relevant context + emotional state + consolidated summary
# Your agent knows the user is frustrated and prioritizes accordingly
Installation
pip install pact-langchain
Requirements:
- Python 3.8+
- LangChain 0.1.0+
- PACT API key (get one at neurobloom.ai)
Quick Start
Quick Start
pip install pact-langchain
from pact_langchain import PACTMemory
# Use with deployed API
memory = PACTMemory(
api_key="your-key",
api_url="https://pact-hx.onrender.com" # Live API!
)
# Save conversation
memory.save_context(
{"input": "Hello!"},
{"output": "Hi there!"}
)
# Load context
context = memory.load_memory_variables({})
Basic Usage (Drop-in Replacement)
from langchain.llms import OpenAI
from langchain.chains import ConversationChain
from pact_langchain import PACTMemory
# Replace this:
# from langchain.memory import ConversationBufferMemory
# memory = ConversationBufferMemory()
# With this:
memory = PACTMemory(api_key="sk_test_...")
# Everything else stays the same
llm = OpenAI(temperature=0.7)
conversation = ConversationChain(llm=llm, memory=memory)
conversation.predict(input="Hi, I'm working on a Python project")
conversation.predict(input="I'm stuck on async functions")
conversation.predict(input="This is really frustrating!")
# PACT automatically:
# ✅ Tracks emotional progression (calm → frustrated)
# ✅ Identifies key topics (Python, async, debugging)
# ✅ Consolidates old context to save tokens
With Emotional Context
memory = PACTMemory(
api_key="sk_test_...",
emotional_tracking=True,
return_emotional_context=True
)
conversation = ConversationChain(llm=llm, memory=memory)
conversation.predict(input="I just got promoted!")
# Behind the scenes: emotional_state="excited", valence=0.8
# Access emotional state directly
state = memory.get_emotional_state()
print(state)
# {
# "current_emotion": "excited",
# "valence": 0.8,
# "trend": "positive",
# "key_emotions": ["joy", "pride"]
# }
With Context Consolidation
memory = PACTMemory(
api_key="sk_test_...",
context_consolidation=True,
consolidation_threshold=10 # Consolidate after 10 messages
)
# After 10 messages, PACT automatically:
# 1. Summarizes old context
# 2. Keeps recent messages
# 3. Preserves emotional and topical highlights
# 4. Saves you tokens 💰
# Force consolidation manually
summary = memory.force_consolidation()
print(summary["consolidated_summary"])
# "User is debugging a Python async issue, feeling frustrated but making progress..."
Side-by-Side Comparison
Standard LangChain Memory
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.save_context(
{"input": "I'm excited about this project!"},
{"output": "That's great!"}
)
memory.save_context(
{"input": "Actually, I'm really stressed now."},
{"output": "I can help with that."}
)
# Load memory
context = memory.load_memory_variables({})
print(context["history"])
# Human: I'm excited about this project!
# AI: That's great!
# Human: Actually, I'm really stressed now.
# AI: I can help with that.
# ❌ No emotional tracking
# ❌ No context prioritization
# ❌ No consolidation
# ❌ Grows unbounded (token explosion)
PACT Memory
from pact_langchain import PACTMemory
memory = PACTMemory(api_key="sk_test_...")
memory.save_context(
{"input": "I'm excited about this project!"},
{"output": "That's great!"}
)
memory.save_context(
{"input": "Actually, I'm really stressed now."},
{"output": "I can help with that."}
)
# Load memory
context = memory.load_memory_variables({})
print(context["history"])
# [Same conversation history]
print(context["emotional_state"])
# "stressed" (tracks emotional shift)
print(context["context_summary"])
# "User's emotional state shifted from excited to stressed regarding project"
# ✅ Emotional tracking
# ✅ Context prioritization
# ✅ Automatic consolidation
# ✅ Token-efficient
Features
| Feature | Standard LangChain | PACT Memory |
|---|---|---|
| Drop-in replacement | ✅ | ✅ |
| Emotional tracking | ❌ | ✅ |
| Context consolidation | ❌ | ✅ |
| Priority management | ❌ | ✅ |
| Token optimization | ❌ | ✅ |
| Relationship patterns | ❌ | ✅ |
| Memory visualization | ❌ | ✅ |
| Async support | ✅ | ✅ |
Advanced Usage
Custom Configuration
memory = PACTMemory(
api_key="sk_test_...",
# Emotional tracking
emotional_tracking=True,
return_emotional_context=True,
# Context management
context_consolidation=True,
consolidation_threshold=15, # Consolidate after N messages
max_token_limit=2000, # Max tokens in context
# API settings
api_url="https://api.neurobloom.ai/pact/v1" # Custom endpoint
)
Accessing Memory Graph
# Get full memory graph structure
graph = memory.get_context_graph()
# Structure:
# {
# "nodes": [
# {"id": "msg_1", "type": "message", "content": "...", "emotion": "excited"},
# {"id": "topic_python", "type": "topic", "importance": 0.9}
# ],
# "edges": [
# {"from": "msg_1", "to": "topic_python", "type": "mentions"}
# ]
# }
# Use this for visualization in your own UI
Manual Priority Control
# Mark important topics
memory.set_context_priority(topic="quarterly_goals", priority="high")
memory.set_context_priority(topic="lunch_preferences", priority="low")
# PACT will:
# - Keep high-priority context longer
# - Consolidate low-priority context sooner
# - Retrieve high-priority context first
Async Support
from pact_langchain import AsyncPACTMemory
memory = AsyncPACTMemory(api_key="sk_test_...")
# Use with async chains
async def chat():
context = await memory.aload_memory_variables({})
await memory.asave_context(
{"input": "Hello"},
{"output": "Hi there!"}
)
Real-World Example: Customer Support Bot
from langchain.llms import OpenAI
from langchain.chains import ConversationChain
from pact_langchain import PACTMemory
# Initialize with emotional tracking
memory = PACTMemory(
api_key="sk_prod_...",
emotional_tracking=True,
context_consolidation=True,
consolidation_threshold=20
)
llm = OpenAI(temperature=0.7)
support_bot = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# Customer conversation
support_bot.predict(input="My order hasn't arrived")
# PACT detects: emotion="concerned"
support_bot.predict(input="It's been 3 weeks!")
# PACT detects: emotion="frustrated", escalation=True
support_bot.predict(input="This is unacceptable!")
# PACT detects: emotion="angry", priority="high"
# Check emotional state
state = memory.get_emotional_state()
if state["current_emotion"] == "angry":
# Escalate to human agent
print("⚠️ Customer is angry - escalating to human agent")
# Get context summary for human agent
context = memory.load_memory_variables({})
print(context["context_summary"])
# "Customer ordered 3 weeks ago, item not delivered.
# Emotional progression: concerned → frustrated → angry"
Comparison with Alternatives
vs. ConversationBufferMemory
- ✅ PACT tracks emotions, buffer doesn't
- ✅ PACT consolidates context, buffer grows unbounded
- ✅ PACT prioritizes, buffer treats everything equal
vs. ConversationSummaryMemory
- ✅ PACT preserves emotional nuance, summary loses it
- ✅ PACT uses smart consolidation, summary is aggressive
- ✅ PACT provides graph structure, summary is just text
vs. ConversationKGMemory (Knowledge Graph)
- ✅ PACT includes emotional edges, KG doesn't
- ✅ PACT has built-in consolidation, KG doesn't
- ✅ PACT is a managed service, KG requires manual setup
Pricing
| Plan | Price | Storage | Features |
|---|---|---|---|
| Free | $0 | 10K tokens/month | Basic memory, public data |
| Starter | $20/mo | 100K tokens | Emotional tracking |
| Pro | $99/mo | 1M tokens | Full features, analytics |
| Team | $299/mo | Unlimited | Shared context, priority support |
All plans include:
- Unlimited API calls
- Context consolidation
- 99.9% uptime SLA
- SOC 2 compliance
Examples
Basic Chatbot
# examples/basic_usage.py
from langchain.llms import OpenAI
from langchain.chains import ConversationChain
from pact_langchain import PACTMemory
memory = PACTMemory(api_key="sk_test_...")
llm = OpenAI(temperature=0.7)
conversation = ConversationChain(llm=llm, memory=memory)
while True:
user_input = input("You: ")
if user_input.lower() == "quit":
break
response = conversation.predict(input=user_input)
print(f"Bot: {response}")
# Show emotional state
state = memory.get_emotional_state()
print(f"[Emotion: {state['current_emotion']}]")
Therapy/Coaching Bot
See examples/emotional_tracking_complete.py
Customer Support Agent
Documentation
How It Works
┌─────────────────┐
│ Your LangChain │
│ Agent │
└────────┬────────┘
│
│ save_context() / load_memory_variables()
│
┌────────▼────────┐
│ PACT Memory │ ← Drop-in replacement
│ (This Package) │
└────────┬────────┘
│
│ API calls (REST)
│
┌────────▼────────┐
│ PACT Server │ ← Managed service by NeurobloomAI
│ │ ← Handles emotional analysis
│ │ ← Context consolidation
│ │ ← Graph storage
└─────────────────┘
Under the hood:
- Your agent calls
memory.save_context()like normal - PACT extracts emotional signals from the text
- PACT builds a context graph (topics, relationships, emotions)
- PACT consolidates old context when threshold is hit
- Your agent calls
memory.load_memory_variables() - PACT returns optimized context + emotional metadata
FAQ
Q: Does this work with existing LangChain code?
A: Yes! It's a drop-in replacement for ConversationBufferMemory. Just change the import.
Q: Do I need to change my prompts?
A: No. The emotional context is added as separate variables. Your prompts work as-is, but you can optionally reference {emotional_state} if you want.
Q: How much does it cost?
A: Free tier: 10K tokens/month. Paid plans start at $20/month. See pricing →
Q: Where is my data stored?
A: On PACT's secure servers (SOC 2 compliant). You can also self-host the PACT server.
Q: Can I use this offline?
A: Not yet, but self-hosted version is coming in Q2 2026.
Q: Does it work with LangChain agents?
A: Yes! Works with chains, agents, and any LangChain component that uses memory.
Q: What about privacy?
A: All data is encrypted in transit and at rest. You can delete sessions anytime. See Privacy Policy.
Q: Can I visualize the memory graph?
A: Yes! Use memory.get_context_graph() to export, or use PACT Studio for a visual UI.
Roadmap
- Core memory integration
- Emotional tracking
- Context consolidation
- Async support
- Self-hosted option (Q2 2026)
- Multi-session support (Q2 2026)
- LangSmith integration (Q3 2026)
- Voice tone analysis (Q3 2026)
Contributing
We welcome contributions! See CONTRIBUTING.md
Quick start:
git clone https://github.com/neurobloomai/pact-hx.git
cd pact-hx/packages/langchain
pip install -e ".[dev]"
pytest
Support
License
MIT License - see LICENSE
Acknowledgments
Built with ❤️ for the LangChain community by NeurobloomAI.
Special thanks to:
- LangChain team for the amazing framework
- Early beta testers who provided feedback
- Contributors who made this possible
Star History
If you find this useful, give us a star! ⭐
Release files for pact-langchain 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pact_langchain-0.1.0.tar.gz | 17.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pact_langchain-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.7 kB
Release files / pact_langchain-0.1.0.tar.gz
| Download URL | pact_langchain-0.1.0.tar.gz |
|---|---|
| Size | 17.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dedb4b76b7919c3cce1739617846623335bfe5f6669409ca23cfe9c01939f7ad
|
|
BLAKE2b-256 checksum How to use checksums |
5666031bb9c285f553c4aea4795da6ff49cb5482b39127b6583ec725700ab7bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.13
|
Release files / pact_langchain-0.1.0-py3-none-any.whl
| Download URL | pact_langchain-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fcc73b19568d32600bdf7d1b593932c67f2c42090e75f4b13df1176ade8791fd
|
|
BLAKE2b-256 checksum How to use checksums |
ef2a56a6bc8120473cd960996b4427af1b2fb5733eb07e3e83e0548c13ff58dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.13
|