Python: Allow AzureOpenAIResponsesClient creation with Foundry project endpoint (#3814)

* Initial plan

* feat: extend AzureOpenAIResponsesClient to support Foundry project endpoints

Add project_client and project_endpoint parameters to allow creating
the client via an Azure AI Foundry project. When provided, the client
uses AIProjectClient.get_openai_client() to obtain the OpenAI client.
The azure-ai-projects package is imported lazily and only required
when using the project endpoint path.

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* fix: address code review - remove duplicate MagicMock imports in tests

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* fix: add type field to Responses API input items and add Foundry sample

- Add 'type: message' to input items in _prepare_message_for_openai
  to comply with the Responses API schema requirement
- Filter out empty dicts from unsupported content types to prevent
  sending items with invalid empty type values
- Add azure_responses_client_with_foundry.py sample demonstrating
  AzureOpenAIResponsesClient with project_endpoint
- Update README and pyrightconfig.samples.json accordingly

* updates to response format and setup

* fix: patch AIProjectClient at correct module path in test

Patch agent_framework.azure._responses_client.AIProjectClient instead of
azure.ai.projects.aio.AIProjectClient since the import is at module level.

* docs: add Foundry sample to READMEs and document AZURE_AI_PROJECT_ENDPOINT env var

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
This commit is contained in:
Copilot
2026-02-11 15:46:25 +00:00
committed by GitHub
co-authored by copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> eavanvalkenburg eavanvalkenburg
parent 235c578059
commit a427af91a9
12 changed files with 349 additions and 28 deletions
@@ -798,12 +798,8 @@ def test_chat_message_with_error_content() -> None:
result = client._prepare_message_for_openai(message, call_id_to_id)
# Message should be prepared with empty content list since ErrorContent returns {}
assert len(result) == 1
prepared_message = result[0]
assert prepared_message["role"] == "assistant"
# Content should be a list with empty dict since ErrorContent returns {}
assert prepared_message.get("content") == [{}]
# Message should be empty since ErrorContent is filtered out
assert len(result) == 0
def test_chat_message_with_usage_content() -> None:
@@ -823,12 +819,8 @@ def test_chat_message_with_usage_content() -> None:
result = client._prepare_message_for_openai(message, call_id_to_id)
# Message should be prepared with empty content list since UsageContent returns {}
assert len(result) == 1
prepared_message = result[0]
assert prepared_message["role"] == "assistant"
# Content should be a list with empty dict since UsageContent returns {}
assert prepared_message.get("content") == [{}]
# Message should be empty since UsageContent is filtered out
assert len(result) == 0
def test_hosted_file_content_preparation() -> None: