LangChain memory with emotional intelligence by NeurobloomAI
Project description
๐ง 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
- ๐ Documentation
- ๐ฌ Discord Community
- ๐ Issue Tracker
- ๐ง Email 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! โญ
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pact_langchain-0.1.0.tar.gz.
File metadata
- Download URL: pact_langchain-0.1.0.tar.gz
- Upload date:
- Size: 17.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dedb4b76b7919c3cce1739617846623335bfe5f6669409ca23cfe9c01939f7ad
|
|
| MD5 |
b1c5faa1cfeace7feb26d9fcc65c2677
|
|
| BLAKE2b-256 |
5666031bb9c285f553c4aea4795da6ff49cb5482b39127b6583ec725700ab7bf
|
File details
Details for the file pact_langchain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pact_langchain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcc73b19568d32600bdf7d1b593932c67f2c42090e75f4b13df1176ade8791fd
|
|
| MD5 |
0ac0ac1fa3292d1f08da131b609b3aa0
|
|
| BLAKE2b-256 |
ef2a56a6bc8120473cd960996b4427af1b2fb5733eb07e3e83e0548c13ff58dc
|