decionis-langchain
Gate any LangChain tool call or LangGraph node on a signed Decionis Decision Dossier. The agent picks the tool; Decionis decides whether the call is allowed to fire — and records every verdict as a verifiable proof artifact.
pip install decionis-langchain
Why
LangChain agents can be jailbroken, prompt-injected, or simply hallucinated into firing tools that move money, change pricing, send refunds, or delete data. Wrapping the tool with Decionis means:
- Every tool invocation gets a signed Decision Dossier — the policy
verdict (
ALLOW/BLOCK/REVIEW_REQUIRED/ESCALATE), the agent identity, the call arguments, and a public verify URL. - Blocked calls short-circuit before the inner tool runs — the LLM sees a structured refusal carrying the dossier id; the caller's audit log keeps the proof.
- Shadow mode records verdicts without blocking, so a team can roll out policy gradually and review the would-have-blocked rate before enforcing.
Quick start — wrap a LangChain tool
from decionis import DecionisClient
from decionis_langchain import DecionisGateTool
from langchain_core.tools import tool
@tool
def send_refund(customer_id: str, amount_usd: int) -> str:
"""Issue a refund. Idempotent on customer_id + amount + day."""
...
client = DecionisClient(api_key="…", base_url="https://api.decionis.com")
gated_refund = DecionisGateTool.wrap(
inner_tool=send_refund,
client=client,
tenant_id="org-uuid",
workflow_key="refund_execution",
site_base_url="https://decionis.com",
)
agent.bind_tools([gated_refund])
When the LLM picks send_refund, Decionis evaluates the call first. On
ALLOW the inner tool runs and the dossier id rides along on the result. On
any blocking verdict the wrapper raises DecionisGateRefusal with the
dossier id, reason codes, and the public verify URL.
Quick start — LangGraph node
from langgraph.graph import StateGraph, END
from decionis_langchain import decionis_gate_node
graph = StateGraph(MyState)
graph.add_node("plan", plan_node)
graph.add_node(
"gate",
decionis_gate_node(
client=client,
tenant_id="org-uuid",
workflow_key="refund_execution",
site_base_url="https://decionis.com",
# Pull the agent's chosen action out of the state to evaluate it.
extract_call=lambda s: (s["proposed_tool"], s["proposed_args"]),
),
)
graph.add_node("execute", execute_node)
graph.add_node("refuse", refuse_node)
graph.add_edge("plan", "gate")
graph.add_conditional_edges(
"gate",
lambda s: s["decionis"]["outcome"],
{"allowed": "execute", "blocked": "refuse"},
)
graph.add_edge("execute", END)
graph.add_edge("refuse", END)
The node writes a JSON-serializable record under state["decionis"] so the
graph stays checkpointable and the conditional edge can branch on
allowed or blocked. In enforcement an ERROR verdict routes to blocked.
Shadow-mode rollout
Same pattern as the GitHub Action: ship in shadow first, review the verdict distribution, then flip to enforce.
The end-to-end PLG funnel — pick a surface → install in shadow → watch verdicts → flip — is walked at decionis.com/shadow-mode.
DecionisGateTool.wrap(
inner_tool=send_refund,
client=client,
tenant_id="org-uuid",
workflow_key="refund_execution",
shadow_mode=True, # ← every verdict recorded; inner tool always runs
)
In shadow mode the gate never raises — even on BLOCK — so existing
agent behaviour is unchanged. Verdicts still flow into the dossier ledger so
the rollout team can grade policy fit before enforcing.
That includes a failed decision request (a timeout, an HTTP error, no
connection): in shadow mode the tool runs anyway, the gate logs a warning, and
on_decision receives the failure as error, with decision=None. The
LangGraph node routes to allowed and records the failure under error. In
enforcement the request's error is raised and the tool does not run.
Tunables
| Argument | Default | Purpose |
|---|---|---|
tenant_id |
required | Decionis org / tenant id. |
workflow_key |
required | Policy bundle key (e.g. refund_execution). |
client |
required | A decionis.DecionisClient instance. |
block_statuses |
(BLOCK, REVIEW_REQUIRED, ESCALATE, ERROR) |
Which verdicts cause the gate to short-circuit. Pass (BLOCK,) to let review verdicts through with their dossier still recorded. |
shadow_mode |
False |
Run policy but never block. |
site_base_url |
None |
Override to build a public verify URL (/verify/decision-dossiers/<id>?sig=…&source=langchain_agent) when the SDK doesn't supply one. |
actor |
{"type": "ai_agent", "framework":"…"} |
Extra actor metadata (model name, session id) for the dossier. |
on_decision |
None |
Observer callback (GateResult) -> None. Use for in-app telemetry. Exceptions in the observer never break the gate. |
Honesty notes
shadow_mode=Trueis the only switch that lets the inner tool run on a blocking verdict; the default never silently passes aBLOCK.DecionisGateRefusal.verify_urlis the same artifact link Slack / Teams / LinkedIn unfurl with the OG card. Forward it to a reviewer when you want the proof one click away.- The wrapper preserves the inner tool's name, description, and args schema unchanged so the LLM's tool selection behaviour does not drift.
Compatibility
- Python ≥ 3.10
decionis≥ 0.2langchain-core≥ 0.3langgraph≥ 0.2 (only required if you usedecionis_gate_node)
Release files for decionis-langchain 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 | |
|---|---|---|---|
| decionis_langchain-0.1.0.tar.gz | 11.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| decionis_langchain-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.1 kB
Release files / decionis_langchain-0.1.0.tar.gz
| Download URL | decionis_langchain-0.1.0.tar.gz |
|---|---|
| Size | 11.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f87fd3df815ecd558edec84df8f6a19d36ec6e40ecb66710a96f05031a483089
|
|
BLAKE2b-256 checksum How to use checksums |
bf85549d42e3e86b68a68354f25ca78c8c9655143f249f73add17d9c87206a15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / decionis_langchain-0.1.0-py3-none-any.whl
| Download URL | decionis_langchain-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
62c076e47f8cf9378391393275acf80e7cdd26ed43f99d21bfa9a863a344743a
|
|
BLAKE2b-256 checksum How to use checksums |
14bf994fb2225a7275627189bcfe7e46fedd427d74022941fe99af7d80fecb56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|