Guard.verify(...) with the active policy’s content scanner before each tool call.
What the adapter does and does not do
The CrewAI wrapper runs the content gate (PII detection, policy-specific content rules) on each tool call. It does not checkrequired_capabilities or deduct cost_cents - that surface is intentionally narrow because CrewAI tool signatures vary and the wrapper auto-extracts the first string argument as the content to scan. For capability + budget enforcement on a CrewAI tool, compose with @guard.wrap(...) underneath (see “Defence in depth” below).
A blocked call returns the string "[CERTIOR BLOCKED] {reason}" rather than raising; CrewAI surfaces that as the tool’s output, and the agent’s reasoning loop sees it.
Pattern 1: decorate one tool
certior_tool_wrapper(guard=None, policy="default", tool_name="") is the full signature. When guard is omitted, the wrapper builds its own Guard(policy=policy). tool_name is what appears in the audit log (defaults to the function’s __name__).
Pattern 2: guard every tool in an existing crew
guard_crew_tools(crew, guard) walks every agent’s tools list and replaces each tool’s function with the same content-scanned wrapper. The crew is mutated in place and also returned for chaining.
Defence in depth: add capability + budget
The wrapper covers the content gate. To also enforce capability and budget, decorate the underlying function with@guard.wrap(...) first - that path raises CertiorBlocked on a capability or budget miss before the function body runs:
@guard.wrap above @certior_tool_wrapper, capability + budget is checked first (raising CertiorBlocked on a miss); only if that passes does the content scan run (returning the blocked-string on a miss).
See also
- OpenAI guide - same gate via
verify_tool_calls(). - Custom loop - direct
Guard.verify()/@guard.wrap().