Metadata-Version: 2.4
Name: dial-crewai
Version: 0.10.0
Summary: Official Dial CrewAI tools — phone numbers, SMS, OTP, and voice calls for multi-agent crews
Requires-Python: >=3.11
Requires-Dist: crewai>=0.80
Requires-Dist: dial-sdk
Description-Content-Type: text/markdown

# dial-crewai

Official Dial tools for [CrewAI](https://crewai.com) — give a multi-agent crew the
ability to send SMS, receive OTP codes, and place AI voice calls through
[Dial](https://getdial.ai). Agents automating signups and web tasks get a real
phone identity.

It's the CrewAI sibling of [`dial-langchain`](https://pypi.org/project/dial-langchain/):
each tool is a `crewai.tools.BaseTool` subclass wrapping the [`dial-sdk`](https://pypi.org/project/dial-sdk/)
client. It adds nothing to the REST contract — it just shapes Dial's operations into
CrewAI tools.

## Install

```bash
pip install dial-crewai
```

This pulls in `dial-sdk` and `crewai`.

## Give the tools to a crew

Build one `DialClient`, pass it to `dial_tools`, and hand the list to an agent. Every
tool shares that one client — a single connection pool for the whole crew:

```python
from crewai import Agent, Crew, Task
from dial_sdk import DialClient, DialConfig
from dial_crewai import dial_tools

dial = DialClient(DialConfig(api_key="sk_live_..."))

phone_agent = Agent(
    role="Phone identity agent",
    goal="Send and receive SMS so the crew can complete phone-verified signups",
    backstory="You operate the crew's Dial phone number.",
    tools=dial_tools(dial),
)
```

`DialConfig` also takes an optional `base_url` to target a non-default deployment.

### Or pick individual tools

```python
from dial_crewai import SendMessageTool, WaitForMessageTool

tools = [
    SendMessageTool(client=dial),
    WaitForMessageTool(client=dial),
]
```

## Available tools

Each tool takes your shared `DialClient` (`client=`):

| Tool | Action |
|---|---|
| `ListNumbersTool` | List your phone numbers |
| `PurchaseNumberTool` | Provision a new number (billable) |
| `SetNumberPropertiesTool` | Update a number's nickname / inbound instruction |
| `SendMessageTool` | Send an SMS (optionally MMS) |
| `ListMessagesTool` | List recent messages |
| `MakeCallTool` | Place an AI voice call |
| `ListCallsTool` | List recent calls |
| `GetCallTool` | Fetch one call by id |
| `GetBillingTool` | Credit balance, subscription, per-number mode |
| `WaitForMessageTool` | Block until the next inbound SMS arrives, or time out |

## OTP flow

The point of phone identity for a crew: send a code and read the reply.
`WaitForMessageTool` blocks until the next inbound SMS arrives, so an agent can:

1. trigger a signup that texts a code to your Dial number,
2. call `WaitForMessageTool` to read the inbound code,
3. enter it back into the signup form.

See [`examples/signup_crew.py`](./examples/signup_crew.py) for a runnable crew.

## Notes

- The `dial-sdk` client is async; these tools are **sync-first** (`_run`) with an
  async→sync bridge, and also expose `_arun` for async crews. The shared client's
  requests run on a single background event loop, so the connection pool is reused
  across calls; a sync crew needn't close the client explicitly.
- `SendMessageTool` is a write action and **isn't idempotent** — a re-invoke after a
  failure can send a duplicate. `MakeCallTool` accepts an `idempotency_key`.
- `WaitForMessageTool` is backed by Dial's **presence-based** event stream — for
  durable, at-least-once delivery, register a
  [webhook](https://docs.getdial.ai/documentation/platform/webhooks).

See the [CrewAI integration docs](https://docs.getdial.ai/documentation/sdks/crewai)
for the full guide.
