Skip to content
/docs

CrewAI Integration

Protect CrewAI tools with direct Veto API checks.

CrewAI is a Python framework. The local SDK in this repository is the TypeScript veto-sdk, so it does not currently publish veto.integrations.crewai.

Use a guarded BaseTool while a native Python helper is not available.

Guard a CrewAI tool

import httpx
import os
from crewai.tools import BaseTool
from pydantic import BaseModel, Field

async def veto_guard(tool_name: str, args: dict):
    response = await httpx.AsyncClient().post(
        "https://api.veto.so/v1/validate",
        headers={"X-Veto-API-Key": os.environ["VETO_API_KEY"]},
        json={"toolName": tool_name, "arguments": args},
        timeout=10,
    )
    response.raise_for_status()
    decision = response.json()
    if decision["decision"] != "allow":
        raise RuntimeError(decision.get("reason") or decision["decision"])

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

    async def _arun(self, amount: float, to_account: str) -> str:
        await veto_guard(self.name, {
            "amount": amount,
            "to_account": to_account,
        })
        return f"Transferred ${amount} to {to_account}"

Register tools for Charter

import { Veto } from "veto-sdk";

const veto = await Veto.init();

await veto.registerTools([
  {
    name: "transfer_funds",
    description: "Transfer money between accounts",
    parameters: [
      { name: "amount", type: "number", required: true },
      { name: "to_account", type: "string", required: true },
    ],
  },
]);

const res = await fetch("https://api.veto.so/v1/charter/turn", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Veto-API-Key": process.env.VETO_API_KEY!,
  },
  body: JSON.stringify({
    message: "Transfers over $1,000 require finance approval.",
    mode: "compile",
    surface: "api",
  }),
});
const draft = await res.json();

Use the returned verification link to approve the policy before it goes live.