LangChain middleware for routing sensitive tool calls through Beav3r approvals.
Project description
beav3r-sdk-langchain
beav3r-sdk-langchain adds Beav3r approval enforcement to LangChain tool execution.
Use it when an agent can call tools that should be approved, denied, or delayed based on Beav3r policy before the underlying tool actually runs.
Requirements
- Python 3.10+
beav3r-sdklangchainlanggraph- an LLM model provider package such as
langchain-openai
Install
From PyPI
python3 -m pip install beav3r-sdk beav3r-sdk-langchain langchain-openai
From source
Install the base SDK first, then this adapter:
cd ../beav3r-sdk-py
python3 -m pip install .
cd ../beav3r-sdk-langchain
python3 -m pip install .
python3 -m pip install langchain-openai
This integration is model-provider agnostic. It works with any LangChain-compatible LLM
provider as long as the agent can invoke tools through LangChain middleware. The examples in
this repository use OpenAI through langchain-openai as the default provider adapter.
Environment endpoints:
- Staging:
https://staging.server.beav3r.ai - Production:
https://server.beav3r.ai
Runtime requirements
From the agent process, you typically need:
BEAV3R_BASE_URLBEAV3R_API_KEY- credentials for the selected LLM model provider
For the included example script in this repository, that means:
OPENAI_API_KEY- optionally
OPENAI_BASE_URL - optionally
MODEL_NAME
You do not need signer device credentials in the LangChain app for normal request-time approval checks. Device credentials are only needed for signer-side flows such as approval submission or signed device reads.
On the Beav3r side you still need:
- a running Beav3r server
- a project API key with permission to request actions
- policy rules that match the
actionTypeand attributes you send - at least one paired signer when a policy path requires human approval
Quick start
from __future__ import annotations
import os
from beav3r_sdk import Beav3r
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_beav3r import Beav3rApprovalMiddleware, Beav3rToolConfig
def send_usdt(amount: int, recipient: str) -> str:
"""Send a USDT payment."""
return f"Sent {amount} USDT to {recipient}"
client = Beav3r(
base_url=os.environ["BEAV3R_BASE_URL"],
agent_id="langchain_demo",
api_key=os.environ["BEAV3R_API_KEY"],
)
model = ChatOpenAI(
model=os.environ.get("MODEL_NAME", "gpt-4.1-mini"),
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1"),
temperature=0,
)
agent = create_agent(
model=model,
tools=[send_usdt],
middleware=[
Beav3rApprovalMiddleware(
client,
tool_configs={
"send_usdt": Beav3rToolConfig(action_type="payments.send_usdt"),
},
)
],
)
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "Send 25 USDT to 0x1111111111111111111111111111111111111111.",
}
]
}
)
print(result)
The snippet above uses OpenAI via ChatOpenAI. The same middleware pattern applies to other
LangChain-compatible model providers, but the default example configuration targets OpenAI.
Behavior specification
Beav3rApprovalMiddleware intercepts each LangChain tool call before execution.
For each protected tool call it sends a Beav3r action request with:
actionTypepayloadattributes- optional
actionId
The default mapping is:
actionType: the configuredBeav3rToolConfig.action_type, otherwise the tool name, or"{action_namespace}.{tool_name}"ifaction_namespaceis configuredpayload: the tool argumentsattributes:tool_nameplus scalar tool arguments
For example, this tool call:
send_usdt(amount=25, recipient="0x1111...")
becomes this Beav3r request by default:
{
"actionType": "payments.send_usdt",
"payload": {
"amount": 25,
"recipient": "0x1111..."
},
"attributes": {
"tool_name": "send_usdt",
"amount": 25,
"recipient": "0x1111..."
}
}
Decision handling
approvedorexecuted: the original tool handler runsdenied,rejected,expired, or any other non-approved final status: the middleware returns aToolMessageexplaining that the tool was blockedpending: the middleware raisesBeav3rApprovalPendingError
Configuration reference
Beav3rApprovalMiddleware(...) accepts:
client: a configuredbeav3r_sdk.Beav3rclienttool_configs: per-tool configuration mapprotect_all_tools: whenTrue, every tool is protected unless explicitly disabledaction_namespace: optional prefix used to derive default action typespoll_interval_ms: polling interval passed toguard_and_waittimeout_ms: timeout passed toguard_and_wait
Beav3rToolConfig(...) accepts:
action_type: explicit Beav3r action typepayload_builder: callable that builds the Beav3r payload from the LangChain requestattributes_builder: callable that builds the Beav3r attributes from the LangChain requestaction_id_builder: callable that supplies a custom Beav3r action idpoll_interval_ms: per-tool polling overridetimeout_ms: per-tool timeout override
Protecting specific tools
middleware = Beav3rApprovalMiddleware(
client,
protect_all_tools=False,
tool_configs={
"send_usdt": Beav3rToolConfig(action_type="payments.send_usdt"),
"search_docs": False,
},
)
Example agent
A runnable example lives in examples/simple_agent.py.
Run it after installing the base SDK, this package, and langchain-openai.
The example script defaults to OpenAI:
export BEAV3R_BASE_URL=https://staging.server.beav3r.ai
export BEAV3R_API_KEY=bvr_test_...
export OPENAI_API_KEY=...
# Optional overrides:
# export OPENAI_BASE_URL=https://api.openai.com/v1
# export MODEL_NAME=gpt-4.1-mini
python3 examples/simple_agent.py
If policy marks payments.send_usdt above a threshold as approval-gated, the middleware
will pause execution until Beav3r returns a final decision.
Docker example
For an isolated local run without installing into the active Python environment:
export BEAV3R_BASE_URL=https://staging.server.beav3r.ai
export BEAV3R_API_KEY=bvr_test_...
export OPENAI_API_KEY=...
# Optional overrides:
# export OPENAI_BASE_URL=https://api.openai.com/v1
# export MODEL_NAME=gpt-4.1-mini
bash scripts/run_simple_agent_docker.sh
The script uses Python 3.11 in Docker, installs the sibling beav3r-sdk-py repository,
installs this adapter plus langchain-openai, and runs the example agent.
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 beav3r_sdk_langchain-0.1.2.tar.gz.
File metadata
- Download URL: beav3r_sdk_langchain-0.1.2.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a8d6636078b81c654bc086f9817498bc5a822e7d0cdead7539b394e63334fe7
|
|
| MD5 |
acfa93676bc7794c8b3e9055c177ef2a
|
|
| BLAKE2b-256 |
03e39587aaf2d48fa7eefaa22db138a013c6042a022a68fe42156e8b35a59038
|
File details
Details for the file beav3r_sdk_langchain-0.1.2-py3-none-any.whl.
File metadata
- Download URL: beav3r_sdk_langchain-0.1.2-py3-none-any.whl
- Upload date:
- Size: 6.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0b6b0c07a06f4a0b0e54b5cd6eab982a323234bff3184e046449e975cd5fae9
|
|
| MD5 |
62210a1804616f4e024baa414b535d3d
|
|
| BLAKE2b-256 |
9df93df14f9856efe28175167ca5a9c6096ca6b9b1c1ba6c485c65d4438087ea
|