Skip to main content
Open In Colab — run a live crew refused mid-task (needs your own OpenAI key). The CrewAI adapter ships two patterns: decorate a single tool, or wrap every tool in an existing crew at construction time. Both run Guard.verify(...) before each tool call.

What the adapter does

The CrewAI wrapper runs all three gates on each tool call:
  • Capability - pass required_capabilities=[...] to the wrapper (or a capabilities map to guard_crew_tools). A call whose needs aren’t a subset of the agent’s grant is blocked. Omit it for content-gate-only checking.
  • Content - PII detection and policy-specific content rules on the first string argument.
  • Budget - pass cost_cents=... to debit the guard’s budget per call.
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="", *, required_capabilities=None, cost_cents=0) 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__). required_capabilities turns on the capability gate; cost_cents debits the budget.

Pattern 2: guard every tool in an existing crew

guard_crew_tools(crew, guard, capabilities=None) walks every agent’s tools list and replaces each tool’s function with the guarded wrapper. Tools named in capabilities have the capability gate enforced; the others are content-gate-only. The crew is mutated in place and also returned for chaining.

Raise instead of returning a blocked string

The wrapper returns "[CERTIOR BLOCKED] {reason}" so the agent’s reasoning loop can see it. If you’d rather halt hard on a capability or budget miss, also decorate the underlying function with @guard.wrap(...) - that path raises CertiorBlocked before the body runs:
Decorator order matters here. Python applies decorators bottom-up but at call time the outer wrapper runs first. With @guard.wrap above @certior_tool_wrapper, capability + budget is checked first (raising CertiorBlocked on a miss); only if that passes does the inner wrapper run.

See also