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.
Install
Section titled “Install”pip install 'tappass[langchain]'Govern an agent executor
Section titled “Govern an agent executor”from langchain.agents import AgentExecutorfrom 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)Async variant
Section titled “Async variant”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"})Tool-only wrapping (low-level)
Section titled “Tool-only wrapping (low-level)”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 runnableEach tool call is audited. Correlation IDs are inherited from the active tappass_session if one is open.
Handling governance decisions
Section titled “Handling governance decisions”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}")Migrating from 0.5
Section titled “Migrating from 0.5”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.