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
Metadata
Release files for langchain-edon 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 | |
|---|---|---|---|
| langchain_edon-0.1.0.tar.gz | 5.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langchain_edon-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.5 kB
Release files / langchain_edon-0.1.0.tar.gz
| Download URL | langchain_edon-0.1.0.tar.gz |
|---|---|
| Size | 5.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7491adb277ba661e8aeaddc982a382137d5a73666fdb7507c6d38fba0e00b19d
|
|
BLAKE2b-256 checksum How to use checksums |
05481bd7d36a640bf898c9c38dfaebb825cde6d63bd5aa4fbfa354d58ec29f50
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / langchain_edon-0.1.0-py3-none-any.whl
| Download URL | langchain_edon-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
04a8cc2857a035cc34f5bd7287729a4e94ad055d42d6548f3303b0e56ee4df72
|
|
BLAKE2b-256 checksum How to use checksums |
af0946900e26407481f1853342f35f328e5bc032ed37c7bd8e926ca95f739d18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|