dial-agentframework 0.19.2__tar.gz → 0.21.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.19.2 → dial_agentframework-0.21.0}/PKG-INFO +2 -2
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/dial_agentframework/tools.py +16 -4
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/pyproject.toml +2 -2
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/tests/test_tools.py +35 -5
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/uv.lock +2 -2
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/.gitignore +0 -0
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/README.md +0 -0
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/dial_agentframework/__init__.py +0 -0
- {dial_agentframework-0.19.2 → dial_agentframework-0.21.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.21.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.33.0
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
|
|
10
10
|
# dial-agentframework
|
|
@@ -115,7 +115,8 @@ def set_number_properties_tool(client: DialClient) -> FunctionTool:
|
|
|
115
115
|
description=(
|
|
116
116
|
"Update a Dial phone number's properties: its inbound instruction (the system "
|
|
117
117
|
"prompt its AI voice agent uses on inbound calls), its nickname, and/or whether "
|
|
118
|
-
"calling is switched on at all (calling_enabled)
|
|
118
|
+
"calling is switched on at all (calling_enabled) or forwards inbound calls to "
|
|
119
|
+
"another phone (forward_to). "
|
|
119
120
|
"On iMessage numbers you can also set the display identity (first/last name "
|
|
120
121
|
"and avatar photo) shown to recipients. Provide at least one."
|
|
121
122
|
),
|
|
@@ -173,6 +174,12 @@ def set_number_properties_tool(client: DialClient) -> FunctionTool:
|
|
|
173
174
|
"the number is unaffected. Takes effect on the next call — a call already in "
|
|
174
175
|
"progress is not ended. Omit to leave it unchanged.",
|
|
175
176
|
] = None,
|
|
177
|
+
forward_to: Annotated[
|
|
178
|
+
Optional[str],
|
|
179
|
+
"Forward inbound calls to this phone number (E.164) instead of having the AI "
|
|
180
|
+
"voice agent answer; the call ends if that phone is busy or doesn't answer. "
|
|
181
|
+
"Pass an empty string to stop forwarding. Omitted leaves it unchanged.",
|
|
182
|
+
] = None,
|
|
176
183
|
) -> str:
|
|
177
184
|
kwargs: dict = {}
|
|
178
185
|
if inbound_instruction is not None:
|
|
@@ -199,17 +206,21 @@ def set_number_properties_tool(client: DialClient) -> FunctionTool:
|
|
|
199
206
|
# False is a real value here; only None means "leave unchanged".
|
|
200
207
|
if calling_enabled is not None:
|
|
201
208
|
kwargs["calling_enabled"] = calling_enabled
|
|
209
|
+
# Empty string stops forwarding (sent as null); None means "leave unchanged".
|
|
210
|
+
if forward_to is not None:
|
|
211
|
+
kwargs["forward_to"] = forward_to or None
|
|
202
212
|
if not kwargs:
|
|
203
213
|
return (
|
|
204
214
|
"Provide at least one of inbound_instruction, inbound_voice_gender, "
|
|
205
215
|
"inbound_language, nickname, max_call_duration_seconds, calling_enabled, "
|
|
206
|
-
"first_name, last_name, or avatar_url."
|
|
216
|
+
"forward_to, first_name, last_name, or avatar_url."
|
|
207
217
|
)
|
|
208
218
|
number = await client.set_number_properties(number_id, **kwargs)
|
|
209
219
|
nick = f' | nickname: "{number.nickname}"' if number.nickname else ""
|
|
210
220
|
# Reported only when off, so a messaging-only line isn't a silent surprise.
|
|
211
221
|
calling = "" if number.calling_enabled else " | calling: off (messaging only)"
|
|
212
|
-
|
|
222
|
+
fwd = f" | forwarding calls to {number.forward_to}" if number.forward_to else ""
|
|
223
|
+
return f"Updated {number.number} (id: {number.id}){nick}{calling}{fwd}"
|
|
213
224
|
|
|
214
225
|
return set_number_properties
|
|
215
226
|
|
|
@@ -288,7 +299,8 @@ def list_groups_tool(client: DialClient) -> FunctionTool:
|
|
|
288
299
|
if not groups:
|
|
289
300
|
return "No groups found."
|
|
290
301
|
return "\n".join(
|
|
291
|
-
f"{g.id}: {g.name or '(unnamed)'} (since {g.created_at})"
|
|
302
|
+
f"{g.id} ({g.channel}): {g.name or '(unnamed)'} (since {g.created_at})"
|
|
303
|
+
for g in groups
|
|
292
304
|
)
|
|
293
305
|
|
|
294
306
|
return list_groups
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dial-agentframework"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.21.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.33.0",
|
|
12
12
|
]
|
|
13
13
|
|
|
14
14
|
[tool.uv.sources]
|
|
@@ -35,6 +35,7 @@ class _FakeNumber:
|
|
|
35
35
|
country = "US"
|
|
36
36
|
nickname = None
|
|
37
37
|
calling_enabled = True
|
|
38
|
+
forward_to = None
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class FakeClient:
|
|
@@ -162,22 +163,23 @@ def test_send_message_into_a_group():
|
|
|
162
163
|
|
|
163
164
|
def test_list_groups_renders_ids_names_and_an_unnamed_group():
|
|
164
165
|
class _FakeGroup:
|
|
165
|
-
def __init__(self, id, name, created_at):
|
|
166
|
+
def __init__(self, id, channel, name, created_at):
|
|
166
167
|
self.id = id
|
|
168
|
+
self.channel = channel
|
|
167
169
|
self.name = name
|
|
168
170
|
self.created_at = created_at
|
|
169
171
|
|
|
170
172
|
client = FakeClient(
|
|
171
173
|
list_groups=[
|
|
172
|
-
_FakeGroup("grp_1", "Planning bday party", "2026-09-01T00:00:00Z"),
|
|
173
|
-
_FakeGroup("grp_2", None, "2026-09-02T00:00:00Z"),
|
|
174
|
+
_FakeGroup("grp_1", "whatsapp", "Planning bday party", "2026-09-01T00:00:00Z"),
|
|
175
|
+
_FakeGroup("grp_2", "imessage", None, "2026-09-02T00:00:00Z"),
|
|
174
176
|
]
|
|
175
177
|
)
|
|
176
178
|
out = _run(list_groups_tool(client))
|
|
177
179
|
|
|
178
|
-
assert "grp_1: Planning bday party" in out
|
|
180
|
+
assert "grp_1 (whatsapp): Planning bday party" in out
|
|
179
181
|
# A group no line could name is still listed — never hidden.
|
|
180
|
-
assert "grp_2: (unnamed)" in out
|
|
182
|
+
assert "grp_2 (imessage): (unnamed)" in out
|
|
181
183
|
|
|
182
184
|
|
|
183
185
|
def test_stop_typing_invokes_client():
|
|
@@ -297,6 +299,34 @@ def test_set_number_properties_omits_unprovided_name_fields():
|
|
|
297
299
|
assert kwargs["nickname"] == "Support"
|
|
298
300
|
|
|
299
301
|
|
|
302
|
+
def test_set_number_properties_forwards_forward_to():
|
|
303
|
+
client = FakeClient(set_number_properties=_FakeNumber())
|
|
304
|
+
tool = set_number_properties_tool(client)
|
|
305
|
+
_run(tool, number_id="pn_9", forward_to="+18005550100")
|
|
306
|
+
|
|
307
|
+
assert client.calls["set_number_properties"]["kwargs"]["forward_to"] == "+18005550100"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def test_set_number_properties_empty_forward_to_stops_forwarding():
|
|
311
|
+
# An empty string is sent to the SDK as None — an explicit null that stops
|
|
312
|
+
# forwarding — rather than being swallowed like an omitted argument.
|
|
313
|
+
client = FakeClient(set_number_properties=_FakeNumber())
|
|
314
|
+
tool = set_number_properties_tool(client)
|
|
315
|
+
_run(tool, number_id="pn_9", forward_to="")
|
|
316
|
+
|
|
317
|
+
kwargs = client.calls["set_number_properties"]["kwargs"]
|
|
318
|
+
assert "forward_to" in kwargs
|
|
319
|
+
assert kwargs["forward_to"] is None
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def test_set_number_properties_omits_unprovided_forward_to():
|
|
323
|
+
client = FakeClient(set_number_properties=_FakeNumber())
|
|
324
|
+
tool = set_number_properties_tool(client)
|
|
325
|
+
_run(tool, number_id="pn_9", nickname="Support")
|
|
326
|
+
|
|
327
|
+
assert "forward_to" not in client.calls["set_number_properties"]["kwargs"]
|
|
328
|
+
|
|
329
|
+
|
|
300
330
|
def test_make_call_passes_idempotency_key():
|
|
301
331
|
client = FakeClient(make_call=_FakeCall())
|
|
302
332
|
tool = make_call_tool(client)
|
|
@@ -345,7 +345,7 @@ wheels = [
|
|
|
345
345
|
|
|
346
346
|
[[package]]
|
|
347
347
|
name = "dial-agentframework"
|
|
348
|
-
version = "0.
|
|
348
|
+
version = "0.21.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.33.0"
|
|
372
372
|
source = { editable = "../sdk-python" }
|
|
373
373
|
dependencies = [
|
|
374
374
|
{ name = "httpx" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dial_agentframework-0.19.2 → dial_agentframework-0.21.0}/examples/signup_agentframework.ipynb
RENAMED
|
File without changes
|