dial-agentframework 0.18.0__tar.gz → 0.19.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.
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: dial-agentframework
3
- Version: 0.18.0
3
+ Version: 0.19.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.28.0
7
+ Requires-Dist: dial-sdk>=0.30.0
8
8
  Description-Content-Type: text/markdown
9
9
 
10
10
  # dial-agentframework
@@ -6,6 +6,7 @@ from .tools import (
6
6
  list_messages_tool,
7
7
  list_groups_tool,
8
8
  list_contacts_tool,
9
+ lookup_number_tool,
9
10
  send_message_tool,
10
11
  reply_to_message_tool,
11
12
  start_typing_tool,
@@ -25,6 +26,7 @@ __all__ = [
25
26
  "list_messages_tool",
26
27
  "list_groups_tool",
27
28
  "list_contacts_tool",
29
+ "lookup_number_tool",
28
30
  "send_message_tool",
29
31
  "reply_to_message_tool",
30
32
  "start_typing_tool",
@@ -523,6 +523,43 @@ def list_contacts_tool(client: DialClient) -> FunctionTool:
523
523
  return list_contacts
524
524
 
525
525
 
526
+ # ── Lookup ───────────────────────────────────────────────────────────────────
527
+
528
+
529
+ def lookup_number_tool(client: DialClient) -> FunctionTool:
530
+ @tool(
531
+ name="lookup_number",
532
+ description=(
533
+ "Check what channels a phone number can receive on, before sending to it. "
534
+ "Works on ANY number in the world - it doesn't have to be one of your "
535
+ "numbers, and you don't have to have messaged it before. The answer "
536
+ "describes the number you asked about, not your own line, and it is "
537
+ "point-in-time rather than a property of the number: someone who changes "
538
+ "device or turns a service off stops being reachable. Treat a yes as a "
539
+ "strong signal for picking a channel rather than a promise that the send "
540
+ "will land. A lookup that fails raises rather than reporting no, so a no "
541
+ "always means the number genuinely isn't reachable there."
542
+ ),
543
+ )
544
+ async def lookup_number(
545
+ number: Annotated[
546
+ str,
547
+ "The phone number to look up, in E.164 - e.g. +14155550123. Any number in "
548
+ "the world, not just one of your own.",
549
+ ],
550
+ ) -> str:
551
+ result = await client.lookup_number(number)
552
+ # Rendered by name, so a channel added to the API after this SDK shipped is
553
+ # reported rather than silently dropped.
554
+ channels = ", ".join(
555
+ f"{channel}: {'yes' if supported else 'no'}"
556
+ for channel, supported in result.supports.items()
557
+ )
558
+ return f"{result.number} - {channels}"
559
+
560
+ return lookup_number
561
+
562
+
526
563
  # ── Calls ────────────────────────────────────────────────────────────────────
527
564
 
528
565
 
@@ -750,6 +787,7 @@ def dial_tools(client: DialClient) -> list[FunctionTool]:
750
787
  list_messages_tool(client),
751
788
  list_groups_tool(client),
752
789
  list_contacts_tool(client),
790
+ lookup_number_tool(client),
753
791
  send_message_tool(client),
754
792
  reply_to_message_tool(client),
755
793
  start_typing_tool(client),
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dial-agentframework"
3
- version = "0.18.0"
3
+ version = "0.19.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.28.0",
11
+ "dial-sdk>=0.30.0",
12
12
  ]
13
13
 
14
14
  [tool.uv.sources]
@@ -11,6 +11,7 @@ from dial_agentframework import (
11
11
  stop_typing_tool,
12
12
  wait_for_message_tool,
13
13
  list_groups_tool,
14
+ lookup_number_tool,
14
15
  )
15
16
 
16
17
 
@@ -71,6 +72,7 @@ def test_dial_tools_bundles_all_fifteen():
71
72
  "list_messages",
72
73
  "list_groups",
73
74
  "list_contacts",
75
+ "lookup_number",
74
76
  "send_message",
75
77
  "reply_to_message",
76
78
  "start_typing",
@@ -340,3 +342,31 @@ def test_tools_share_one_client():
340
342
  client = FakeClient()
341
343
  tools = dial_tools(client)
342
344
  assert all(t is not None for t in tools)
345
+
346
+
347
+ def test_lookup_number_renders_every_channel_it_is_given():
348
+ # Rendered by name, so a channel the API adds after this SDK ships is reported
349
+ # rather than silently dropped.
350
+ class _FakeLookup:
351
+ number = "+14155550123"
352
+ supports = {"imessage": True, "whatsapp": False}
353
+
354
+ client = FakeClient(lookup_number=_FakeLookup())
355
+ out = _run(lookup_number_tool(client), number="+14155550123")
356
+
357
+ assert "+14155550123" in out
358
+ assert "imessage: yes" in out
359
+ assert "whatsapp: no" in out
360
+
361
+
362
+ def test_lookup_number_passes_the_number_through_untouched():
363
+ # Normalization belongs to the server, so the SDK must not pre-chew the input.
364
+ class _FakeLookup:
365
+ number = "+14155550123"
366
+ supports = {"imessage": True}
367
+
368
+ client = FakeClient(lookup_number=_FakeLookup())
369
+ _run(lookup_number_tool(client), number="+1 (415) 555-0123")
370
+
371
+ call = client.calls["lookup_number"]
372
+ assert "+1 (415) 555-0123" in (list(call["args"]) + list(call["kwargs"].values()))