Metadata-Version: 2.5
Name: crewai-agentgate
Version: 0.1.0
Summary: Gate any CrewAI tool behind human approval in Slack or Microsoft Teams, via AgentGate.
Project-URL: Homepage, https://useagentgate.com
Project-URL: Repository, https://github.com/shakirriyaz/agentgate
Project-URL: Documentation, https://useagentgate.com/docs
Author-email: AgentGate <hello@useagentgate.com>
License: MIT
Keywords: agents,approval,crewai,human-in-the-loop,slack,teams
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: crewai>=0.80.0
Requires-Dist: useagentgate>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# crewai-agentgate

Gate any CrewAI tool behind human approval in Slack or Microsoft Teams — one wrapper, no rewrite.

```bash
pip install crewai-agentgate
```

## Usage

```python
from agentgate import AgentGate
from crewai_agentgate import ApprovalRequiredTool

gate = AgentGate(api_key="ag_your_key")

gated_publish = ApprovalRequiredTool(
    wrapped_tool=publish_content_tool,   # any existing CrewAI BaseTool
    gate=gate,
    risk_tier="high",
    timeout_minutes=15,
)
```

Give `gated_publish` to an `Agent` anywhere `publish_content_tool` would have gone — same
name, same input schema, same output type. The only difference: before it actually runs, it
posts a request to Slack/Teams and blocks until a human clicks Approve or Reject.

```python
publisher = Agent(
    role="Content Publisher",
    goal="Publish approved content to the appropriate platforms",
    tools=[gated_publish],
)
```

If rejected, the tool call returns the rejection reason as its output instead of
raising — so the agent sees "the action was rejected because X" and can react to it,
rather than crashing the crew.

## Why wrap instead of rewrite

Most human-in-the-loop patterns require restructuring how you build the tool. This
doesn't — it wraps a `BaseTool` you already have. Your tool's logic, its args schema,
and its name are all unchanged; approval is a layer around it, not a rewrite of it.

## Parameters

| Parameter | What it does |
|---|---|
| `wrapped_tool` | The existing `BaseTool` to gate. Required. |
| `gate` | An `AgentGate` (async) or `AgentGateSync` instance. Required. |
| `risk_tier` | `low` / `medium` / `high` / `critical`. Defaults to `medium`. |
| `timeout_minutes` | Auto-rejects if nobody responds in time. Defaults to `30`. |
| `approver` | Optional Slack handle to `@mention` directly, e.g. `"@sarah"`. |
| `slack_channel` | Optional override of the default connected channel. |

## Requires

An AgentGate server — self-hosted or hosted at [useagentgate.com](https://useagentgate.com) —
connected to Slack and/or Teams. See the [AgentGate docs](https://useagentgate.com/docs).

## License

MIT
