Metadata-Version: 2.4
Name: dial-agentframework
Version: 0.10.0
Summary: Official Dial tools for the Microsoft Agent Framework — phone numbers, SMS, OTP, and voice calls
Requires-Python: >=3.11
Requires-Dist: agent-framework-core>=1.0
Requires-Dist: dial-sdk
Description-Content-Type: text/markdown

# dial-agentframework

Official Dial tools for the [Microsoft Agent Framework](https://learn.microsoft.com/en-us/agent-framework/) —
give a `ChatAgent` 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 Agent Framework sibling of [`dial-langchain`](https://pypi.org/project/dial-langchain/) and
[`dial-crewai`](https://pypi.org/project/dial-crewai/): each tool is an `agent_framework.FunctionTool`
(built with the `tool` decorator) 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 Agent Framework tools.

> Targeting the original **AutoGen** (`autogen-agentchat`) instead? Use
> [`dial-autogen`](https://pypi.org/project/dial-autogen/).

## Install

```bash
pip install dial-agentframework
```

This pulls in `dial-sdk` and `agent-framework-core`. The Agent Framework keeps each model
provider in its own package, so also install a chat client — e.g. `agent-framework-openai`
(below) or, for Azure OpenAI, the framework's Azure integration.

## Give the tools to an agent

Build one `DialClient`, pass it to `dial_tools`, and hand the result to an `Agent`. Every
tool shares that one client — a single connection pool for the whole agent session — and
you own its lifecycle (`await client.close()` when done):

```python
from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient  # pip install agent-framework-openai
from dial_sdk import DialClient, DialConfig
from dial_agentframework import dial_tools

dial = DialClient(DialConfig(api_key="sk_live_..."))  # close with `await dial.close()`

agent = Agent(
    OpenAIChatClient(),  # or an Azure OpenAI client for enterprise/Azure deployments
    name="phone_agent",
    instructions="You operate the team's Dial phone number for SMS, OTP, and voice calls.",
    tools=dial_tools(dial),
)

result = await agent.run("Text +14155550123 from pn_abc saying our table is ready.")
print(result.text)
```

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

> **Azure OpenAI:** install the framework's Azure integration and swap in its Azure
> OpenAI chat client — the Dial tools are identical regardless of which provider drives the agent.

### Or pick individual tools

Each builder returns one `AIFunction`:

```python
from dial_agentframework import send_message_tool, wait_for_message_tool

tools = [
    send_message_tool(dial),
    wait_for_message_tool(dial),
]
```

## Available tools

Each builder takes your shared `DialClient`:

| Builder | Tool name | Action |
|---|---|---|
| `list_numbers_tool` | `list_numbers` | List your phone numbers |
| `purchase_number_tool` | `purchase_number` | Provision a new number (billable) |
| `set_number_properties_tool` | `set_number_properties` | Update a number's nickname / inbound instruction |
| `send_message_tool` | `send_message` | Send an SMS (optionally MMS) |
| `list_messages_tool` | `list_messages` | List recent messages |
| `make_call_tool` | `make_call` | Place an AI voice call |
| `list_calls_tool` | `list_calls` | List recent calls |
| `get_call_tool` | `get_call` | Fetch one call by id |
| `get_billing_tool` | `get_billing` | Credit balance, subscription, per-number mode |
| `wait_for_message_tool` | `wait_for_message` | Block until the next inbound SMS arrives, or time out |

## OTP flow

The point of phone identity for an agent: send a code and read the reply.
`wait_for_message` 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 `wait_for_message` to read the inbound code,
3. enter it back into the signup form.

See [`examples/signup_agentframework.ipynb`](./examples/signup_agentframework.ipynb) for a runnable agent.

## Notes

- The Agent Framework runs tools in an async loop, so these tools are **async-native** —
  no async→sync bridge.
- `send_message` is a write action and **isn't idempotent** — a re-invoke after a
  failure can send a duplicate. `make_call` accepts an `idempotency_key`.
- `wait_for_message` 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 [Microsoft Agent Framework integration docs](https://docs.getdial.ai/documentation/sdks/agentframework)
for the full guide.
