decionis-crewai wraps a CrewAI tool so each call asks Decionis first, with the call's own arguments, and the tool runs only on a verdict that allows it. The agent sees the same tool: its name, description and argument schema do not change.
It depends on the decionis SDK (0.2.0, MIT), which pip installs with it. The client needs an organization API key and its tenant id.
from decionis import DecionisClient
from decionis_crewai import DecionisGuardedTool
client = DecionisClient(api_key="...", base_url="https://api.decionis.com")
guarded_refund = DecionisGuardedTool.wrap(
inner_tool=send_refund,
client=client,
tenant_id="your-org-uuid",
workflow_key="refund_execution",
site_base_url="https://decionis.com",
)
refund_agent = Agent(..., tools=[guarded_refund])DecionisGuardedTool wraps a CrewAI BaseTool: _run and _arun ask Decionis first and invoke the inner tool only when it is permitted, with the inner tool's name, description and Pydantic argument schema unchanged.
ALLOW runs the tool. BLOCK, REVIEW_REQUIRED, ESCALATE and ERROR raise DecionisGuardRefusal before it runs, carrying the Decision Dossier id and, when there is one, its verify link.
With shadow_mode=True the decision is still asked for and recorded, and the tool runs whatever the verdict: start here, and remove it once the verdicts match the policy you meant.
The request raises (a timeout after retries, an HTTP error, no connection), and the adapter does not catch it: the tool does not run, in shadow as well as in enforcement.