Installation
Quick Start
Using Middleware with create_agent
The simplest way to add Veto to a LangChain agent is with middleware:
Middleware Options
Both TypeScript and Python middleware accept optional callbacks:Error Handling
By default, denied tool calls return aToolMessage to the model indicating the denial. Set throwOnDeny: true to raise an exception instead:
LangGraph ToolNode Integration
For LangGraph workflows, wrap yourToolNode to add validation:
Callback Handler (Observability)
For observability without blocking execution, use the callback handler:The callback handler does not block tool execution β it only logs validation results. Use middleware to enforce policies.
Complete Example
Hereβs a complete example with LangChain and Veto:How It Works
The LangChain middleware intercepts tool calls through thewrapToolCall / wrap_tool_call middleware hook:
- Agent decides to call a tool (e.g.,
send_email) - Middleware intercepts the tool call before execution
- Veto validates arguments against your rules:
- Deterministic checks (e.g.,
tomust end with@company.com) - Optional LLM checks (e.g., βis this email professional?β)
- Deterministic checks (e.g.,
- Decision:
- Allow: Modified arguments (if any) forwarded to original handler
- Deny: Returns
ToolMessagewith reason (or throws ifthrowOnDeny: true)
Advanced: Argument Modification
Veto can modify tool arguments based on rules (e.g., sanitize input, redact data). Modified arguments are automatically forwarded:TypeScript API Reference
createVetoLangChainMiddleware(veto, options?)
Create LangChain middleware that validates tool calls.
Parameters:
veto: Veto- Initialized Veto instanceoptions?: VetoLangChainMiddlewareOptionsonAllow?: (toolName, args) => void | Promise<void>onDeny?: (toolName, args, reason) => void | Promise<void>throwOnDeny?: boolean- Throw instead of returning ToolMessage (default:false)
{ name: string, wrapToolCall: Function }
createVetoToolNode(veto, toolNode, options?)
Wrap a LangGraph ToolNode with Veto validation.
Parameters:
veto: Veto- Initialized Veto instancetoolNode: ToolNode- LangGraph ToolNode instanceoptions?: VetoToolNodeOptions- Same as middleware options
createVetoCallbackHandler(veto, options?)
Create a callback handler for observability (non-blocking).
Parameters:
veto: Veto- Initialized Veto instanceoptions?: VetoCallbackOptionslogAllowed?: boolean- Log allowed calls (default:false)logDenied?: boolean- Log denied calls (default:true)
BaseCallbackHandler
Python API Reference
VetoMiddleware(veto, *, on_allow, on_deny, throw_on_deny)
Class-based LangChain middleware.
Parameters:
veto: Veto- Initialized Veto instanceon_allow: Callable | None- Callback for allowed callson_deny: Callable | None- Callback for denied callsthrow_on_deny: bool- Raise exception instead of returning ToolMessage (default:False)
create_veto_tool_node(veto, tool_node, *, on_allow, on_deny)
Wrap a LangGraph ToolNode with Veto validation.
Parameters:
veto: Veto- Initialized Veto instancetool_node: ToolNode- LangGraph ToolNode instanceon_allow: Callable | None- Callback for allowed callson_deny: Callable | None- Callback for denied calls
VetoCallbackHandler(veto, *, log_allowed, log_denied)
Callback handler for observability.
Parameters:
veto: Veto- Initialized Veto instancelog_allowed: bool- Log allowed calls (default:False)log_denied: bool- Log denied calls (default:True)
Next Steps
Configure Rules
Define validation rules for your tools
LangGraph Guide
Build a LangGraph workflow with Veto
Error Handling
Handle denied tool calls gracefully
API Reference
Full Veto API documentation

