Integrating LangChain
Wrap your tool array once with `guard.wrap()`. Every tool call, including ones you add next month, is governed at the boundary.
The integration point is the tool-executor boundary, not each tool. Wrapping individual tools is the most common integration mistake — the tool someone adds in a hurry next month is the one that ends up ungoverned.
Install
$ pip install cirvixWrap the tool list
from langchain.agents import AgentExecutorfrom cirvix.integrations.langchain import guard tools = guard.wrap( my_langchain_tools, agent="pr-triage", environment=os.environ.get("CIRVIX_ENV", "local"), policy_dir="./policies",) executor = AgentExecutor(agent=agent, tools=tools)result = executor.invoke({"input": "Summarize PR #4821"})Denials become observations, not crashes
A denied call raises CirvixDenied at the tool boundary, which the wrapper converts into a tool observation the agent's next planning step can see — the same denial shape as every other SDK and the CLI.
# Observation returned to the agent, not an unhandled exception:{ "error": "cirvix.policy.denied", "policy": "deny-dotenv-read", "reason": "Reading .env* is denied outside an approved secrets flow.", "remediation": 'secrets.get("STRIPE_KEY")',}Note
LangGraph nodes wrap the same way —
guard.wrap() on a node's tool list rather than the whole graph.Edit this page on GitHub
Was this page helpful?
