Skip to content

LangChain

Wrap a LangChain AgentExecutor in a TapPass session. Every LLM call and tool invocation emits a structured audit event. Every server-side governance decision surfaces as a typed exception.

pip install 'tappass[langchain]'
from langchain.agents import AgentExecutor
from tappass.integrations.langchain import guard_agent
executor = AgentExecutor(agent=my_agent, tools=[...])
with guard_agent(executor, tappass_url="https://tappass.example.com", api_key="tp_...") as session:
result = session.invoke({"input": "Summarize Q4 revenue"})
print(session.audit_url)
from tappass.integrations.langchain import guard_agent_async
async with guard_agent_async(executor, tappass_url=..., api_key="tp_...") as session:
result = await session.ainvoke({"input": "Summarize Q4 revenue"})

When you want per-tool audit events without wrapping the full executor, use guard_tools:

from tappass.integrations.langchain import guard_tools
governed = guard_tools(
[search_tool, email_tool],
tappass_url="https://tappass.example.com",
api_key="tp_...",
)
# Pass `governed` to your agent or runnable

Each tool call is audited. Correlation IDs are inherited from the active tappass_session if one is open.

from tappass import GovernanceDecision, PolicyBlockError
try:
with guard_agent(executor, tappass_url=..., api_key="tp_...") as session:
session.invoke({"input": "Show all SSNs"})
except PolicyBlockError as e:
print(f"Blocked by {e.blocked_by}: {e.reason}")
print(f"See {e.audit_url}")
except GovernanceDecision as e:
print(f"Governance: {e}")

The 0.5 TapPassCallbackHandler and agent.govern(tools) patterns are replaced by guard_agent (full executor) and guard_tools (tool-only). See the migration guide.