Skip to content

Conversation

@giles17
Copy link
Contributor

@giles17 giles17 commented Feb 3, 2026

Motivation and Context

This PR refactors hosted tool support from standalone Hosted*Tool classes to @staticmethod factory methods on the chat clients that support them. This is a breaking change that improves API discoverability and makes tool support explicit per client

Breaking Changes

Removed classes:

  • HostedCodeInterpreterTool
  • HostedWebSearchTool
  • HostedImageGenerationTool
  • HostedFileSearchTool
  • HostedMCPTool

Migration:

# BEFORE (old API - removed)
from agent_framework import HostedCodeInterpreterTool, HostedWebSearchTool
tool = HostedCodeInterpreterTool()
search = HostedWebSearchTool(additional_properties={"user_location": {...}})

# AFTER (new API)
from agent_framework.openai import OpenAIResponsesClient

tool = OpenAIResponsesClient.get_code_interpreter_tool()
search = OpenAIResponsesClient.get_web_search_tool(user_location={"city": "Seattle"})

#3586

Description

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings February 3, 2026 04:29
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation python lab Agent Framework Lab labels Feb 3, 2026
@github-actions github-actions bot changed the title [BREAKING] Replace Hosted*Tool classes with client static factory methods Python: [BREAKING] Replace Hosted*Tool classes with client static factory methods Feb 3, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a breaking change that refactors hosted tool support from standalone Hosted*Tool classes to static factory methods on chat clients. This improves API discoverability by making tool support explicit per client type.

Changes:

  • Removed HostedCodeInterpreterTool, HostedWebSearchTool, HostedFileSearchTool, HostedImageGenerationTool, and HostedMCPTool classes
  • Added static factory methods (get_code_interpreter_tool(), get_web_search_tool(), etc.) to relevant client classes
  • Introduced protocol classes (SupportsCodeInterpreterTool, SupportsWebSearchTool, etc.) for runtime checking of tool support
  • Updated all samples, tests, and documentation to use the new API

Reviewed changes

Copilot reviewed 119 out of 119 changed files in this pull request and generated no comments.

Show a summary per file
File Description
python/packages/core/agent_framework/_clients.py Added tool support protocol definitions
python/packages/core/agent_framework/openai/_chat_client.py Added get_web_search_tool() static method
python/packages/core/agent_framework/openai/_assistants_client.py Added get_code_interpreter_tool() and get_file_search_tool() static methods
python/packages/core/agent_framework/openai/_responses_client.py Added static methods for all hosted tools (code interpreter, web search, file search, image generation, MCP)
python/packages/azure-ai/agent_framework_azure_ai/_client.py Added Azure-specific get_mcp_tool() implementation
python/packages/anthropic/agent_framework_anthropic/_chat_client.py Added static methods for Anthropic-supported tools
Multiple sample files Updated to use new static factory methods instead of Hosted*Tool classes
Multiple test files Updated test assertions to check for dict-based tools instead of class instances
python/packages/declarative/agent_framework_declarative/_loader.py Updated to create dict-based tools directly

@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 3, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/anthropic/agent_framework_anthropic
   _chat_client.py36814959%427, 467, 490, 492, 507, 529–532, 541, 543, 574–578, 580, 582–583, 585, 590–591, 593, 626–627, 636, 638–639, 644, 661–662, 707, 717, 733, 742, 744, 748–749, 792–794, 796, 809–810, 817–819, 823–825, 829–832, 843, 845, 867, 877, 899–905, 912–913, 921–922, 930–933, 940–941, 947–948, 954–955, 961, 969–971, 975, 982–983, 989–990, 996–997, 1003, 1011–1014, 1021–1022, 1041, 1048–1049, 1068, 1090, 1092, 1101–1102, 1108, 1130–1131, 1137–1138, 1147–1157, 1164–1170, 1177–1183, 1190–1199, 1206–1209
packages/azure-ai/agent_framework_azure_ai
   _chat_client.py5018183%319, 377, 380, 383, 386–387, 389–395, 568, 829–830, 832, 835, 838, 841–846, 849, 851, 859, 871–873, 877, 880–881, 889–892, 902, 910–913, 915–916, 918–919, 926, 934–935, 943–944, 949–950, 954–961, 966, 969, 977, 983, 991–993, 996, 1018–1019, 1152, 1180, 1195, 1231, 1320, 1336, 1344, 1358, 1478
   _client.py1923084%344, 346, 395, 423–426, 469, 506, 508, 568, 570–571, 573–574, 576–579, 581–582, 584–586, 588–591, 593, 640
   _shared.py2822491%113, 154, 158, 166, 180, 252, 295, 307–309, 338, 340, 342, 346, 422, 438–439, 452, 454, 482, 523, 530, 542, 561
packages/core/agent_framework
   _clients.py77494%292, 336, 484, 486
   _mcp.py3915386%126, 188, 197, 260, 268, 289, 379, 446, 481, 483, 487–488, 490–491, 545, 560, 578, 619, 725, 738–743, 765, 786, 789–791, 806–807, 813–815, 834, 843, 846–848, 863–864, 868–872, 889–893, 1033
   _tools.py7088288%213–215, 240–241, 343, 345, 365, 383, 397, 409, 414, 416, 423, 456, 512–514, 555, 577–605, 640, 648, 889, 1226, 1313–1317, 1339–1340, 1456, 1458, 1524, 1616, 1622, 1664–1665, 1678–1679, 1722, 1806, 1844–1845, 1884–1886, 1924–1925, 1935, 1992–1993, 2000–2001
packages/core/agent_framework/openai
   _assistant_provider.py1101190%156–157, 169, 294, 360, 475–480
   _assistants_client.py2762989%402, 416, 419, 421–422, 425, 428, 431–432, 443, 468, 470, 472, 474, 476, 481, 484, 487, 491, 502, 587, 672, 699, 736–739, 791, 808
   _chat_client.py2742291%179, 236–237, 241, 332, 339, 420–427, 429–432, 442, 527, 564, 580
   _responses_client.py5666887%254, 259, 261–262, 273, 291, 299, 322, 402, 493, 496, 551, 555, 557, 559, 561, 637, 647, 652, 695, 753, 767, 784, 797, 852, 931, 936, 940–942, 946–947, 970, 1039, 1061–1062, 1077–1078, 1096–1097, 1228–1229, 1245, 1247, 1322–1330, 1378, 1433, 1448, 1484–1485, 1487–1489, 1503–1505, 1515–1516, 1522, 1537
   _shared.py1251588%63, 69–72, 150, 152, 159, 161, 174, 250, 274, 333–334, 336
TOTAL16309202587% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3799 221 💤 0 ❌ 0 🔥 1m 8s ⏱️

@giles17 giles17 changed the title Python: [BREAKING] Replace Hosted*Tool classes with client static factory methods Python: [BREAKING] Replace Hosted*Tool classes with tool methods Feb 3, 2026
Copy link
Member

@eavanvalkenburg eavanvalkenburg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of notes, overall I think we will have to move to remove some additional pieces of from tools and streamline things even more, I would expect only the functionTool to be handled in the each clients prepare code, everything else should already be setup correctly.

"description": tool.description,
"input_schema": tool.parameters(),
})
elif isinstance(tool, MutableMapping):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this goal is to not have to do anything here, just get FunctionTool and the rest is pass through

@@ -189,8 +182,7 @@ def __str__(self) -> str:
class BaseTool(SerializationMixin):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think now only FunctionTool derives from this, so let's fold them together and remove this basetool. The same for the ToolProtocol I don't think we need that anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should FunctionTool replace ToolProtocol in files?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation lab Agent Framework Lab python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants