CrewAI Integration
Use Veto with CrewAI tools to validate agent actions before execution.
Veto integrates with CrewAI by wrapping BaseTool instances.
You can use either:
wrap_crewai_tools(veto, tools)for an explicit integration call, orveto.wrap([...]), which auto-detects CrewAIBaseToolinstances and delegates to the CrewAI integration.
Python only — CrewAI is a Python framework.
Installation
pip install veto crewaiQuick start
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
from veto import Veto
from veto.integrations.crewai import wrap_crewai_tools
veto = await Veto.init()
class TransferInput(BaseModel):
amount: float = Field(description="Amount to transfer")
to_account: str = Field(description="Destination account")
class TransferFundsTool(BaseTool):
name: str = "transfer_funds"
description: str = "Transfer money between accounts"
args_schema: type[BaseModel] = TransferInput
def _run(self, amount: float, to_account: str) -> str:
return f"Transferred ${amount} to {to_account}"
# Wrap tools with Veto validation
tools = [TransferFundsTool()]
safe_tools = wrap_crewai_tools(veto, tools)
# Equivalent auto-detection path:
# safe_tools = veto.wrap(tools)How it works
For each BaseTool, Veto:
- Reads
tool.name - Builds an args dict using
args_schema.model_fields+ runtime args/kwargs - Calls
await veto.guard(tool_name, args_dict) - Executes
_run()(or_arun()when present) only if allowed
CrewAI calls _run/_arun
|
v
veto.guard(...)
|
+----+----+
| |
allow deny
| |
v v
run tool ToolCallDeniedError- Allowed:
_run()/_arun()executes normally - Denied: Raises
ToolCallDeniedError
Using with Crew
from crewai import Agent, Task, Crew
# Wrap tools before passing to the agent (either API works)
safe_tools = wrap_crewai_tools(veto, [TransferFundsTool()])
# safe_tools = veto.wrap([TransferFundsTool()])
agent = Agent(
role="Financial Assistant",
goal="Help users manage their finances safely",
tools=safe_tools,
)
task = Task(
description="Transfer $500 to ACC-001",
agent=agent,
)
crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()Example output
Tool: transfer_funds (type: TransferFundsTool)
Tool: get_balance (type: GetBalanceTool)
transfer_funds(200) -> Transferred $200 to ACC-001 # allowed
transfer_funds(5000) -> DENIED: Tool call denied: # blocked by policy
transfer_funds - Amount 5000 exceeds limit of 1000
get_balance('ACC-001') -> Balance for ACC-001: $5,000 # allowed
total_calls: 3
allowed_calls: 2
denied_calls: 1Notes
- CrewAI requires Python < 3.14. If you're using Python 3.14+, use a compatible Python version.
- The
args_schema(Pydantic model) is used by CrewAI for input validation. Veto adds policy-level validation on top. - Both
_run()and_arun()methods are wrapped when available.