Skip to content

Python: feat(foundry): add experimental hosted tool factories on FoundryChatClient#5958

Open
eavanvalkenburg wants to merge 3 commits into
microsoft:mainfrom
eavanvalkenburg:feat/foundry-hosted-tool-factories
Open

Python: feat(foundry): add experimental hosted tool factories on FoundryChatClient#5958
eavanvalkenburg wants to merge 3 commits into
microsoft:mainfrom
eavanvalkenburg:feat/foundry-hosted-tool-factories

Conversation

@eavanvalkenburg
Copy link
Copy Markdown
Member

Motivation and Context

Agent Framework's FoundryChatClient exposes static helpers (get_code_interpreter_tool, get_file_search_tool, get_web_search_tool, get_image_generation_tool, get_mcp_tool) for building Foundry-hosted tool configurations without needing a client instance. The Foundry SDK ships several more hosted tools — Azure AI Search, SharePoint, Fabric, Memory Search, Computer Use, Browser Automation, Bing Custom Search, A2A — and there was no equivalent helper for any of them, so developers had to reach into azure.ai.projects.models directly and assemble the nested parameter types by hand.

This PR fills that gap and lays groundwork for an upcoming to_prompt_agent() converter (separate PR) that wants a portable, instance-free way to construct any Foundry-hosted tool.

Description

  • Adds eight new @experimental static factories on FoundryChatClient, one per missing hosted tool. Each wraps the matching azure.ai.projects.models type (AzureAISearchTool, SharepointPreviewTool, MicrosoftFabricPreviewTool, MemorySearchPreviewTool, ComputerUsePreviewTool, BrowserAutomationPreviewTool, BingCustomSearchPreviewTool, A2APreviewTool) and hides the nested parameter/resource shapes behind a flat, keyword-only signature.
  • All eight are tagged with the new ExperimentalFeature.FOUNDRY_TOOLS feature id (the existing GA factories are unchanged).
  • SDK lookups go through a small _require_sdk_class() helper that resolves the preview classes from azure.ai.projects.models lazily and raises a clear ImportError if the installed azure-ai-projects is too old to expose them — older SDK installs continue to import the package fine and only fail when an unsupported factory is actually called.
  • README updated with a new "Hosted tool factories" section listing the GA factories and the experimental additions, plus a callout for the new ExperimentalFeature.FOUNDRY_TOOLS tag.

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.

…lient

Adds eight new `@experimental` static factory methods on `FoundryChatClient`
covering Foundry-hosted tools that previously had no helper:

- get_azure_ai_search_tool
- get_sharepoint_tool
- get_fabric_tool
- get_memory_search_tool
- get_computer_use_tool
- get_browser_automation_tool
- get_bing_custom_search_tool
- get_a2a_tool

All factories are marked with the new `ExperimentalFeature.FOUNDRY_TOOLS` tag
and resolve the underlying `azure-ai-projects` preview classes lazily through
a `_require_sdk_class` helper so older SDK versions still import cleanly and
fail with a clear `ImportError` only on use.

Tests cover each factory's return type and field wiring, the experimental
metadata, and the missing-SDK-class fallback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 19, 2026 18:23
Copy link
Copy Markdown
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

Note

Copilot was unable to run its full agentic suite in this review.

Adds experimental, instance-free hosted tool factory helpers to FoundryChatClient, with lazy resolution of preview SDK classes to preserve import compatibility with older azure-ai-projects versions.

Changes:

  • Added _require_sdk_class() helper to lazily resolve preview tool classes and raise a clear ImportError when missing.
  • Added eight new @experimental static hosted-tool factories (Azure AI Search, SharePoint, Fabric, Memory Search, Computer Use, Browser Automation, Bing Custom Search, A2A).
  • Added unit tests for the new factories and documented the new factory list + experimental feature flag in the README.

Reviewed changes

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

File Description
python/packages/foundry/agent_framework_foundry/_chat_client.py Adds lazy SDK-class resolver and eight experimental hosted tool factories.
python/packages/foundry/tests/foundry/test_foundry_chat_client.py Adds unit tests validating factory output shapes, experimental metadata, and missing-class error behavior.
python/packages/foundry/README.md Documents GA vs experimental hosted-tool factories and the lazy SDK resolution behavior.
python/packages/core/agent_framework/_feature_stage.py Introduces ExperimentalFeature.FOUNDRY_TOOLS feature id.

Comment thread python/packages/foundry/tests/foundry/test_foundry_chat_client.py Outdated
Comment thread python/packages/foundry/tests/foundry/test_foundry_chat_client.py Outdated
Comment thread python/packages/foundry/tests/foundry/test_foundry_chat_client.py
Comment thread python/packages/foundry/agent_framework_foundry/_chat_client.py Outdated
@moonbox3 moonbox3 added documentation Improvements or additions to documentation python labels May 19, 2026
* Skip preview-tool tests gracefully (`_skip_if_sdk_class_missing`) when
  the installed `azure-ai-projects` does not expose the required preview
  class, matching the lazy-import guard in production code so the test
  suite stays green on older SDK installs.
* Add `filterwarnings("ignore::FutureWarning")` to each new tool-factory
  test (and the parametrized metadata test) so they remain stable under
  strict warning configurations \u2014 the global dedup in
  `_feature_stage._WARNED_FEATURES` makes `pytest.warns` brittle across
  ordered runs.
* Use `monkeypatch.setattr(..., None, raising=False)` instead of
  `delattr` in the missing-SDK-class test so it works for modules that
  implement PEP 562 `__getattr__`.
* Split the long `get_bing_custom_search_tool` return into two lines for
  readability.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot changed the title feat(foundry): add experimental hosted tool factories on FoundryChatClient Python: feat(foundry): add experimental hosted tool factories on FoundryChatClient May 19, 2026
@eavanvalkenburg
Copy link
Copy Markdown
Member Author

All four Copilot review comments are addressed in fcd47cf0f and the threads are resolved.

The CI failures on this PR are unrelated to the changes — every failing job (pre-commit, mypy, samples, package checks, tests on 3.13/windows) dies in the shared uv sync --all-packages --all-extras --dev -U setup step with the same resolver error:

Because there are no versions of durabletask and agent-framework-durabletask depends on durabletask>=1.3.0,<2, we can conclude that agent-framework-durabletask's requirements are unsatisfiable.

The -U flag is pulling a newer environment where the durabletask constraint no longer resolves for the python_full_version >= '3.11' and sys_platform == 'darwin' split. The local checks (uv run poe check-packages -P foundry, mypy -P foundry, test -P foundry) all pass cleanly. A rerun once the workspace pin or PyPI state is corrected should make this green.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 86%

✓ Correctness

The PR is well-implemented with no correctness bugs found. The factory methods correctly construct nested SDK objects, the lazy import helper properly surfaces ImportError for missing SDK symbols, decorator interaction with @staticmethod preserves metadata as expected, and tests are thorough with proper warning suppression. The existing review thread items have been addressed (monkeypatch uses setattr with None, tests have filterwarnings marks).

✓ Security Reliability

The PR adds eight experimental Foundry tool factories with a lazy SDK class resolution helper. The implementation is generally sound, but three factories (get_azure_ai_search_tool, get_memory_search_tool, get_bing_custom_search_tool) construct parameter dicts where **kwargs is spread after explicit keys, allowing kwargs to silently override security-sensitive values like project_connection_id. This is inconsistent with get_a2a_tool in the same PR which correctly puts kwargs as the base and applies explicit params on top.

✓ Test Coverage

Test coverage for the new experimental hosted tool factories is thorough. Each of the 8 new factories has a dedicated happy-path test with meaningful assertions on nested structure, a parametrized test verifies experimental metadata, an error-path test covers SDK class resolution failure, and all tests gracefully skip on older SDK versions. The filterwarnings marks correctly handle ExperimentalWarning (subclass of FutureWarning). No significant coverage gaps found.

✓ Design Approach

I did not find a blocking design-approach problem in the factory implementations themselves. The one issue worth tightening is the README’s warning semantics: the new factories all share the same ExperimentalFeature.FOUNDRY_TOLS, and the feature-stage system emits warnings once per feature ID, so the docs currently over-promise a per-factory warning behavior.


Automated review by eavanvalkenburg's agents

Comment thread python/packages/foundry/agent_framework_foundry/_chat_client.py Outdated
Comment thread python/packages/foundry/README.md Outdated
* Reorder the dict-literal kwargs assembly in get_azure_ai_search_tool,
  get_memory_search_tool, and get_bing_custom_search_tool so explicit
  parameters always take precedence over **kwargs (matching the safe
  pattern already used in get_a2a_tool). This prevents a caller
  passing `project_connection_id`, `index_name`, `memory_store_name`,
  `scope`, or `instance_name` through `**kwargs` from silently
  overriding the explicit security-sensitive arguments.
* Update the README experimental note to reflect once-per-feature-id
  dedup semantics of `_feature_stage._WARNED_FEATURES` rather than
  claiming a per-factory "first use" warning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants