Automatic compensation middleware for LangChain agents with dependency-aware rollback
Project description
LangChain Compensation
Automatic compensation middleware for LangChain agents with LIFO (Last-In-First-Out) rollback capabilities. Inspired by the Saga pattern, this package provides automatic rollback of completed actions when a failure occurs in a multi-step agent workflow.
Features
- 🔄 Automatic Rollback: Automatically compensates completed actions when failures occur
- 📚 LIFO Order: Rolls back actions in reverse chronological order (like a transaction stack)
- 🎯 Simple API: Easy-to-use agent factory with compensation mapping
- 🔧 Flexible: Support for custom state mappers to extract compensation parameters
- 🧵 Thread-Safe: Built with thread safety in mind
- 📦 Zero Config: Works out of the box with sensible defaults
Installation
pip install langchain-compensation
Quick Start
from langchain_compensation import create_comp_agent
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.tools import tool
# Define your tools
@tool
def book_flight(destination: str) -> str:
"""Books a flight to the destination."""
return f"flight_id_for_{destination}"
@tool
def cancel_flight(booking_id: str) -> str:
"""Cancels a flight booking."""
return "Cancellation successful"
@tool
def book_hotel(location: str) -> str:
"""Books a hotel at the location."""
if "fail" in location.lower():
return "Error: Hotel booking failed!"
return f"hotel_id_for_{location}"
@tool
def cancel_hotel(booking_id: str) -> str:
"""Cancels a hotel booking."""
return "Cancellation successful"
# Create agent with compensation
model = ChatGoogleGenerativeAI(model="gemini-2.0-flash-exp")
agent = create_comp_agent(
model=model,
tools=[book_flight, cancel_flight, book_hotel, cancel_hotel],
compensation_mapping={
"book_flight": "cancel_flight",
"book_hotel": "cancel_hotel"
}
)
# Run the agent
result = agent.invoke({
"messages": [("user", "Book a flight to London and a hotel in FailCity")]
})
# When hotel booking fails, the flight booking is automatically cancelled!
How It Works
- Track Actions: Compensatable actions are tracked in the agent's state
- Detect Failures: When a tool returns an error, the middleware detects it
- Automatic Rollback: All completed compensatable actions are rolled back in LIFO order
- Continue: The agent continues with the rolled-back state
Advanced Usage
Custom State Mappers
Sometimes you need custom logic to extract compensation parameters from the original result:
def extract_flight_id(result, original_params):
"""Extract booking ID from the result."""
return {"booking_id": result["id"]}
agent = create_comp_agent(
model=model,
tools=tools,
compensation_mapping={"book_flight": "cancel_flight"},
state_mappers={"book_flight": extract_flight_id}
)
With Checkpointer
Use with LangGraph's checkpointing for persistent compensation logs:
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
agent = create_comp_agent(
model=model,
tools=tools,
compensation_mapping={"book_flight": "cancel_flight"},
checkpointer=memory
)
API Reference
create_comp_agent
Creates a LangChain agent with automatic compensation capabilities.
Parameters:
model(BaseChatModel | str | None): The LLM to use for the agenttools(Sequence[BaseTool | Callable]): List of tools available to the agentcompensation_mapping(dict[str, str]): Maps tool names to their compensation toolsstate_mappers(dict[str, Callable] | None): Custom parameter extraction functionssystem_prompt(str | None): Additional system prompt for the agentcheckpointer(Checkpointer | None): Optional checkpointer for state persistence- Other standard LangChain agent parameters
Returns: CompiledStateGraph - A configured agent with compensation middleware
CompensationMiddleware
The core middleware that handles compensation logic.
Parameters:
compensation_mapping(dict[str, str]): Maps tool names to compensation toolstools(list | None): Tools to cache for compensation executionstate_mappers(dict[str, Callable] | None): Custom state mappers
Use Cases
- Travel Booking Systems: Cancel flights/hotels if any part of the trip fails
- E-commerce: Reverse inventory reservations if payment fails
- Multi-step Workflows: Undo completed steps when later steps fail
- Database Operations: Rollback related operations in distributed systems
- API Integrations: Clean up created resources when workflows fail
Requirements
- Python 3.9+
- langchain >= 0.3.0
- langchain-core >= 0.3.0
- langgraph >= 0.2.0
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details
Credits
Inspired by the Saga pattern and built on top of LangChain's middleware system.
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 langchain_compensation-0.2.1.tar.gz.
File metadata
- Download URL: langchain_compensation-0.2.1.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
beb41b399f998c7b596a61d52d045e633b94f55d0642fc99e2dc814e042661dc
|
|
| MD5 |
eee682c3a05eeef40aba6409e825b3ad
|
|
| BLAKE2b-256 |
6e6a3a8ecffc9884ae03b25ad17147f9a516b95eb7601feed9abeeb31b363b6e
|
File details
Details for the file langchain_compensation-0.2.1-py3-none-any.whl.
File metadata
- Download URL: langchain_compensation-0.2.1-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4115b88fcb27a0aa6cedf259251f885405bdc3aef0be2811910e9ee2d7cd7fca
|
|
| MD5 |
ee9533640db92d190c178f169affda25
|
|
| BLAKE2b-256 |
0abba0d45aee6c9477917ec7983a51c5ae992ee1eb2ceb48fd5b7a138e24c222
|