EDON governance for LangChain agents — govern, audit, and enforce every tool call
Project description
langchain-edon ·

Runtime governance for LangChain agents. Evaluate and enforce every tool call before it executes — ALLOW, BLOCK, or escalate to a human.
pip install langchain-edon
What this does
langchain-edon wraps your LangChain tools so every call goes through EDON before execution. Your agent keeps using tools exactly as before — EDON just intercepts each call and checks it against your policy.
Agent decides to call a tool
↓
EDON evaluates the action
↓
ALLOW → tool executes normally
BLOCK → EdonBlockedError raised
HUMAN_REQUIRED → escalation raised
Every decision is logged to a tamper-evident audit trail.
Quickstart (2 minutes)
1. Install
pip install langchain-edon langchain-openai
2. Wrap your tools
import os
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_edon import EdonGuard
# Define your tools as normal
tools = [DuckDuckGoSearchRun()]
# Wrap them — same interface, now governed
governed_tools = EdonGuard.wrap_tools(
tools=tools,
api_key=os.environ["EDON_API_KEY"],
agent_id="research-agent",
)
# Build your agent exactly as before
llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful research assistant."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, governed_tools, prompt)
executor = AgentExecutor(agent=agent, tools=governed_tools)
result = executor.invoke({"input": "What is the latest news about AI governance?"})
print(result["output"])
# Every tool call was evaluated by EDON before it ran
Two integration patterns
Pattern 1: EdonGuard (enforcing)
Wraps tools so EDON evaluates each call before execution. Blocked actions raise an exception and the tool never runs.
from langchain_edon import EdonGuard
from edon.exceptions import EdonBlockedError, EdonEscalatedError
governed_tools = EdonGuard.wrap_tools(
tools=[search_tool, email_tool, calendar_tool],
api_key="your-edon-key",
agent_id="my-agent",
raise_on_block=True, # default — raises EdonBlockedError on BLOCK
)
# Or softer mode — returns error string to LLM instead of raising
governed_tools = EdonGuard.wrap_tools(
tools=tools,
api_key="your-edon-key",
raise_on_block=False, # LLM sees "[EDON BLOCKED] ..." as tool output
)
Pattern 2: EdonCallbackHandler (audit-only)
Logs all tool calls to EDON without blocking anything. Use for observability and audit trails.
from langchain_edon import EdonCallbackHandler
handler = EdonCallbackHandler(
api_key=os.environ["EDON_API_KEY"],
agent_id="my-agent",
verbose=True, # prints [EDON] tool_name -> ALLOW (12ms) to stdout
)
executor = AgentExecutor(
agent=agent,
tools=tools, # unmodified tools — not blocked
callbacks=[handler], # all calls logged to EDON
)
You can combine both — use EdonGuard for enforcement on high-risk tools and EdonCallbackHandler for full observability:
from langchain_edon import EdonGuard, EdonCallbackHandler
governed = EdonGuard.wrap_tools(
tools=[email_tool, delete_tool],
api_key="your-key",
agent_id="my-agent",
)
handler = EdonCallbackHandler(api_key="your-key", agent_id="my-agent")
executor = AgentExecutor(
agent=agent,
tools=governed + [search_tool], # governed + ungoverned mixed
callbacks=[handler],
)
Handling blocked actions
from edon.exceptions import EdonBlockedError, EdonEscalatedError
try:
result = executor.invoke({"input": "Delete all user records"})
except EdonBlockedError as e:
print(f"Blocked: {e.reason}")
print(f"Code: {e.reason_code}") # e.g. "OUT_OF_SCOPE"
print(f"Audit: {e.action_id}") # trace the decision
except EdonEscalatedError as e:
print(f"Needs human: {e.question}")
# Send e.question to your human-in-the-loop queue
Parameters
| Parameter | Default | Description |
|---|---|---|
api_key |
EDON_API_KEY env |
Your EDON API key |
base_url |
EDON_BASE_URL or cloud |
EDON gateway URL |
agent_id |
"langchain-agent" |
Agent identifier in audit trail |
intent_id |
None |
Pin to a specific intent contract |
raise_on_block |
True |
Raise exception on BLOCK/ESCALATE |
Environment variables
export EDON_API_KEY=your-key
export EDON_BASE_URL=https://edon-gateway.fly.dev # or your self-hosted URL
export EDON_AGENT_ID=research-agent # optional default
Self-hosting
Point at your own EDON gateway:
governed_tools = EdonGuard.wrap_tools(
tools=tools,
api_key="your-token",
base_url="http://localhost:8000",
)
Links
- Core SDK: github.com/EDONCORE/edon-python
- Console: edoncore.com/console
- Docs: docs.edoncore.com
- Issues: github.com/EDONCORE/langchain-edon/issues
License
MIT © EDON Core
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_edon-0.1.0.tar.gz.
File metadata
- Download URL: langchain_edon-0.1.0.tar.gz
- Upload date:
- Size: 5.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7491adb277ba661e8aeaddc982a382137d5a73666fdb7507c6d38fba0e00b19d
|
|
| MD5 |
f77a28280cd6e92aff703ea31f5cf8ed
|
|
| BLAKE2b-256 |
05481bd7d36a640bf898c9c38dfaebb825cde6d63bd5aa4fbfa354d58ec29f50
|
File details
Details for the file langchain_edon-0.1.0-py3-none-any.whl.
File metadata
- Download URL: langchain_edon-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04a8cc2857a035cc34f5bd7287729a4e94ad055d42d6548f3303b0e56ee4df72
|
|
| MD5 |
bae36ce38c70ce10b1e2b172df3d5e04
|
|
| BLAKE2b-256 |
af0946900e26407481f1853342f35f328e5bc032ed37c7bd8e926ca95f739d18
|