dial-agentframework 0.17.0__tar.gz → 0.18.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/PKG-INFO +4 -3
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/README.md +2 -1
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/dial_agentframework/__init__.py +2 -0
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/dial_agentframework/tools.py +86 -5
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/pyproject.toml +2 -2
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/tests/test_tools.py +2 -1
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/uv.lock +2 -2
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/.gitignore +0 -0
- {dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/examples/signup_agentframework.ipynb +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: dial-agentframework
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: Official Dial tools for the Microsoft Agent Framework — phone numbers, SMS, OTP, and voice calls
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: agent-framework-core>=1.0
|
|
7
|
-
Requires-Dist: dial-sdk>=0.
|
|
7
|
+
Requires-Dist: dial-sdk>=0.28.0
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
|
|
10
10
|
# dial-agentframework
|
|
@@ -85,7 +85,8 @@ Each builder takes your shared `DialClient`:
|
|
|
85
85
|
| `set_number_properties_tool` | `set_number_properties` | Update a number's nickname / inbound instruction |
|
|
86
86
|
| `send_message_tool` | `send_message` | Send an SMS (optionally MMS) |
|
|
87
87
|
| `reply_to_message_tool` | `reply_to_message` | Reply or react to a message |
|
|
88
|
-
| `list_messages_tool` | `list_messages` | List recent messages |
|
|
88
|
+
| `list_messages_tool` | `list_messages` | List recent messages (`contact` for one conversation, `search` by text) |
|
|
89
|
+
| `list_contacts_tool` | `list_contacts` | List the numbers your lines have talked to |
|
|
89
90
|
| `make_call_tool` | `make_call` | Place an AI voice call |
|
|
90
91
|
| `list_calls_tool` | `list_calls` | List recent calls |
|
|
91
92
|
| `get_call_tool` | `get_call` | Fetch one call by id |
|
|
@@ -76,7 +76,8 @@ Each builder takes your shared `DialClient`:
|
|
|
76
76
|
| `set_number_properties_tool` | `set_number_properties` | Update a number's nickname / inbound instruction |
|
|
77
77
|
| `send_message_tool` | `send_message` | Send an SMS (optionally MMS) |
|
|
78
78
|
| `reply_to_message_tool` | `reply_to_message` | Reply or react to a message |
|
|
79
|
-
| `list_messages_tool` | `list_messages` | List recent messages |
|
|
79
|
+
| `list_messages_tool` | `list_messages` | List recent messages (`contact` for one conversation, `search` by text) |
|
|
80
|
+
| `list_contacts_tool` | `list_contacts` | List the numbers your lines have talked to |
|
|
80
81
|
| `make_call_tool` | `make_call` | Place an AI voice call |
|
|
81
82
|
| `list_calls_tool` | `list_calls` | List recent calls |
|
|
82
83
|
| `get_call_tool` | `get_call` | Fetch one call by id |
|
|
@@ -5,6 +5,7 @@ from .tools import (
|
|
|
5
5
|
set_number_properties_tool,
|
|
6
6
|
list_messages_tool,
|
|
7
7
|
list_groups_tool,
|
|
8
|
+
list_contacts_tool,
|
|
8
9
|
send_message_tool,
|
|
9
10
|
reply_to_message_tool,
|
|
10
11
|
start_typing_tool,
|
|
@@ -23,6 +24,7 @@ __all__ = [
|
|
|
23
24
|
"set_number_properties_tool",
|
|
24
25
|
"list_messages_tool",
|
|
25
26
|
"list_groups_tool",
|
|
27
|
+
"list_contacts_tool",
|
|
26
28
|
"send_message_tool",
|
|
27
29
|
"reply_to_message_tool",
|
|
28
30
|
"start_typing_tool",
|
|
@@ -221,8 +221,10 @@ def list_messages_tool(client: DialClient) -> FunctionTool:
|
|
|
221
221
|
@tool(
|
|
222
222
|
name="list_messages",
|
|
223
223
|
description=(
|
|
224
|
-
"List recent inbound and outbound messages on the account.
|
|
225
|
-
"
|
|
224
|
+
"List recent inbound and outbound messages on the account. Unfiltered this "
|
|
225
|
+
"is the newest 100 messages across every conversation, so pass contact to "
|
|
226
|
+
"read one person's conversation, group_id to read one group's, or search to "
|
|
227
|
+
"find a message by its text anywhere in the history."
|
|
226
228
|
),
|
|
227
229
|
)
|
|
228
230
|
async def list_messages(
|
|
@@ -237,9 +239,24 @@ def list_messages_tool(client: DialClient) -> FunctionTool:
|
|
|
237
239
|
"Restrict to one group conversation (from list_groups). Combines with the "
|
|
238
240
|
"other filters.",
|
|
239
241
|
] = None,
|
|
242
|
+
contact: Annotated[
|
|
243
|
+
Optional[str],
|
|
244
|
+
"One contact's conversation: messages exchanged with this number (E.164), "
|
|
245
|
+
"both directions, across every line on the account. Group messages are never "
|
|
246
|
+
"included - use group_id for those.",
|
|
247
|
+
] = None,
|
|
248
|
+
search: Annotated[
|
|
249
|
+
Optional[str],
|
|
250
|
+
"Case-insensitive substring match on the message body. Searches the whole "
|
|
251
|
+
"history, then returns the 100 most recent matches.",
|
|
252
|
+
] = None,
|
|
240
253
|
) -> str:
|
|
241
254
|
messages = await client.list_messages(
|
|
242
|
-
number_id=number_id,
|
|
255
|
+
number_id=number_id,
|
|
256
|
+
direction=direction,
|
|
257
|
+
group_id=group_id,
|
|
258
|
+
contact=contact,
|
|
259
|
+
search=search,
|
|
243
260
|
)
|
|
244
261
|
if not messages:
|
|
245
262
|
return "No messages found."
|
|
@@ -453,13 +470,69 @@ def stop_typing_tool(client: DialClient) -> FunctionTool:
|
|
|
453
470
|
return stop_typing
|
|
454
471
|
|
|
455
472
|
|
|
473
|
+
# ── Contacts ─────────────────────────────────────────────────────────────────
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def list_contacts_tool(client: DialClient) -> FunctionTool:
|
|
477
|
+
@tool(
|
|
478
|
+
name="list_contacts",
|
|
479
|
+
description=(
|
|
480
|
+
"List every number the account's lines have exchanged a message or a call "
|
|
481
|
+
"with, newest activity first, with per-contact counts and a summary of the "
|
|
482
|
+
"most recent interaction. Derived from history - there is no address book to "
|
|
483
|
+
"add anyone to. Counts span every line, so one person reached on two of your "
|
|
484
|
+
"numbers is one contact. Groups are not contacts; use list_groups for those. "
|
|
485
|
+
"Pass a contact's number to list_messages as contact to read that "
|
|
486
|
+
"conversation."
|
|
487
|
+
),
|
|
488
|
+
)
|
|
489
|
+
async def list_contacts(
|
|
490
|
+
limit: Annotated[Optional[int], "Max contacts to return (1-1000; default 100)"] = None,
|
|
491
|
+
starting_after: Annotated[
|
|
492
|
+
Optional[str],
|
|
493
|
+
"ISO-8601 cursor - the last_at of the last contact you received. Only "
|
|
494
|
+
"contacts with strictly older activity are returned.",
|
|
495
|
+
] = None,
|
|
496
|
+
) -> str:
|
|
497
|
+
page = await client.list_contacts(limit=limit, starting_after=starting_after)
|
|
498
|
+
if not page.contacts:
|
|
499
|
+
return "No contacts found."
|
|
500
|
+
lines = []
|
|
501
|
+
for c in page.contacts:
|
|
502
|
+
if c.last_kind == "call":
|
|
503
|
+
preview = f"{c.last_direction} call"
|
|
504
|
+
if c.last_call_duration:
|
|
505
|
+
preview += f", {c.last_call_duration}s"
|
|
506
|
+
elif c.last_redacted:
|
|
507
|
+
preview = "(deleted by retention)"
|
|
508
|
+
elif not c.last_body:
|
|
509
|
+
preview = f"({c.last_media_count} media)" if c.last_media_count else ""
|
|
510
|
+
else:
|
|
511
|
+
preview = c.last_body[:50]
|
|
512
|
+
lines.append(
|
|
513
|
+
f"{c.number} | {c.message_count} msg, {c.call_count} call | "
|
|
514
|
+
f"{c.last_at} | {preview}"
|
|
515
|
+
)
|
|
516
|
+
if page.has_more:
|
|
517
|
+
# Named so the model can ask for the next page instead of assuming this is all.
|
|
518
|
+
lines.append(
|
|
519
|
+
f"(more contacts: call again with starting_after={page.contacts[-1].last_at})"
|
|
520
|
+
)
|
|
521
|
+
return "\n".join(lines)
|
|
522
|
+
|
|
523
|
+
return list_contacts
|
|
524
|
+
|
|
525
|
+
|
|
456
526
|
# ── Calls ────────────────────────────────────────────────────────────────────
|
|
457
527
|
|
|
458
528
|
|
|
459
529
|
def list_calls_tool(client: DialClient) -> FunctionTool:
|
|
460
530
|
@tool(
|
|
461
531
|
name="list_calls",
|
|
462
|
-
description=
|
|
532
|
+
description=(
|
|
533
|
+
"List recent inbound and outbound calls on the account. Pass contact to read "
|
|
534
|
+
"one person's call history."
|
|
535
|
+
),
|
|
463
536
|
)
|
|
464
537
|
async def list_calls(
|
|
465
538
|
number_id: Annotated[
|
|
@@ -468,8 +541,15 @@ def list_calls_tool(client: DialClient) -> FunctionTool:
|
|
|
468
541
|
direction: Annotated[
|
|
469
542
|
Optional[str], "Filter by direction: 'inbound' or 'outbound'"
|
|
470
543
|
] = None,
|
|
544
|
+
contact: Annotated[
|
|
545
|
+
Optional[str],
|
|
546
|
+
"One contact's calls: exchanged with this number (E.164), both directions, "
|
|
547
|
+
"across every line on the account.",
|
|
548
|
+
] = None,
|
|
471
549
|
) -> str:
|
|
472
|
-
calls = await client.list_calls(
|
|
550
|
+
calls = await client.list_calls(
|
|
551
|
+
number_id=number_id, direction=direction, contact=contact
|
|
552
|
+
)
|
|
473
553
|
if not calls:
|
|
474
554
|
return "No calls found."
|
|
475
555
|
return "\n".join(
|
|
@@ -669,6 +749,7 @@ def dial_tools(client: DialClient) -> list[FunctionTool]:
|
|
|
669
749
|
set_number_properties_tool(client),
|
|
670
750
|
list_messages_tool(client),
|
|
671
751
|
list_groups_tool(client),
|
|
752
|
+
list_contacts_tool(client),
|
|
672
753
|
send_message_tool(client),
|
|
673
754
|
reply_to_message_tool(client),
|
|
674
755
|
start_typing_tool(client),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dial-agentframework"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.18.0"
|
|
4
4
|
description = "Official Dial tools for the Microsoft Agent Framework — phone numbers, SMS, OTP, and voice calls"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -8,7 +8,7 @@ dependencies = [
|
|
|
8
8
|
# Core has `tool` + `FunctionTool` (all this package needs). Chat clients ship in
|
|
9
9
|
# separate integration packages (agent-framework-openai, …) the user installs.
|
|
10
10
|
"agent-framework-core>=1.0",
|
|
11
|
-
"dial-sdk>=0.
|
|
11
|
+
"dial-sdk>=0.28.0",
|
|
12
12
|
]
|
|
13
13
|
|
|
14
14
|
[tool.uv.sources]
|
|
@@ -61,7 +61,7 @@ def _run(tool, **args) -> str:
|
|
|
61
61
|
# ── Tools ────────────────────────────────────────────────────────────────────
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
def
|
|
64
|
+
def test_dial_tools_bundles_all_fifteen():
|
|
65
65
|
names = sorted(t.name for t in dial_tools(FakeClient()))
|
|
66
66
|
assert names == sorted(
|
|
67
67
|
[
|
|
@@ -70,6 +70,7 @@ def test_dial_tools_bundles_all_fourteen():
|
|
|
70
70
|
"set_number_properties",
|
|
71
71
|
"list_messages",
|
|
72
72
|
"list_groups",
|
|
73
|
+
"list_contacts",
|
|
73
74
|
"send_message",
|
|
74
75
|
"reply_to_message",
|
|
75
76
|
"start_typing",
|
|
@@ -345,7 +345,7 @@ wheels = [
|
|
|
345
345
|
|
|
346
346
|
[[package]]
|
|
347
347
|
name = "dial-agentframework"
|
|
348
|
-
version = "0.
|
|
348
|
+
version = "0.18.0"
|
|
349
349
|
source = { editable = "." }
|
|
350
350
|
dependencies = [
|
|
351
351
|
{ name = "agent-framework-core" },
|
|
@@ -368,7 +368,7 @@ dev = [{ name = "pytest", specifier = ">=8" }]
|
|
|
368
368
|
|
|
369
369
|
[[package]]
|
|
370
370
|
name = "dial-sdk"
|
|
371
|
-
version = "0.
|
|
371
|
+
version = "0.28.0"
|
|
372
372
|
source = { editable = "../sdk-python" }
|
|
373
373
|
dependencies = [
|
|
374
374
|
{ name = "httpx" },
|
|
File without changes
|
{dial_agentframework-0.17.0 → dial_agentframework-0.18.0}/examples/signup_agentframework.ipynb
RENAMED
|
File without changes
|