From d7e2db5d77ca38dc9fe8e9344dfa9d4c07fd18c7 Mon Sep 17 00:00:00 2001 From: Giles Odigwe Date: Wed, 4 Mar 2026 15:52:04 -0800 Subject: [PATCH 1/3] Fix as_agent() not defaulting name/description from client properties AzureAIClient.as_agent() and AzureAIAgentClient.as_agent() now fall back to self.agent_name and self.agent_description when name/description are not explicitly passed. This ensures Agent.name is populated for telemetry spans without requiring callers to repeat the name. Fixes #4471 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../agent_framework_azure_ai/_chat_client.py | 4 +-- .../agent_framework_azure_ai/_client.py | 4 +-- .../tests/test_azure_ai_agent_client.py | 31 +++++++++++++++++++ .../azure-ai/tests/test_azure_ai_client.py | 31 +++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py index 2c0498b1e4..f7fe797236 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py @@ -1488,8 +1488,8 @@ def as_agent( """ return super().as_agent( id=id, - name=name, - description=description, + name=name or self.agent_name, + description=description or self.agent_description, instructions=instructions, tools=tools, default_options=default_options, diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_client.py index 61c4a09e94..3ca8daa64a 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_client.py @@ -1195,8 +1195,8 @@ def as_agent( """ return super().as_agent( id=id, - name=name, - description=description, + name=name or self.agent_name, + description=description or self.agent_description, instructions=instructions, tools=tools, default_options=default_options, diff --git a/python/packages/azure-ai/tests/test_azure_ai_agent_client.py b/python/packages/azure-ai/tests/test_azure_ai_agent_client.py index 6c18352195..91369ca6fa 100644 --- a/python/packages/azure-ai/tests/test_azure_ai_agent_client.py +++ b/python/packages/azure-ai/tests/test_azure_ai_agent_client.py @@ -509,6 +509,37 @@ async def test_azure_ai_chat_client_prepare_options_merges_instructions_from_mes assert "concise" in instructions_text.lower() +def test_as_agent_uses_client_agent_name_as_default(mock_agents_client: MagicMock) -> None: + """Test that as_agent() defaults Agent.name to client.agent_name when name is not provided.""" + client = create_test_azure_ai_chat_client(mock_agents_client, agent_name="my_agent") + client.agent_description = "my description" + + agent = client.as_agent(instructions="You are helpful.") + + assert agent.name == "my_agent" + assert agent.description == "my description" + + +def test_as_agent_explicit_name_overrides_client_agent_name(mock_agents_client: MagicMock) -> None: + """Test that an explicit name passed to as_agent() takes precedence over client.agent_name.""" + client = create_test_azure_ai_chat_client(mock_agents_client, agent_name="client_name") + client.agent_description = "client description" + + agent = client.as_agent(name="explicit_name", description="explicit description", instructions="You are helpful.") + + assert agent.name == "explicit_name" + assert agent.description == "explicit description" + + +def test_as_agent_no_name_anywhere(mock_agents_client: MagicMock) -> None: + """Test that Agent.name is None when neither as_agent name nor client.agent_name is provided.""" + client = create_test_azure_ai_chat_client(mock_agents_client) + + agent = client.as_agent(instructions="You are helpful.") + + assert agent.name is None + + async def test_azure_ai_chat_client_inner_get_response(mock_agents_client: MagicMock) -> None: """Test _inner_get_response method.""" client = create_test_azure_ai_chat_client(mock_agents_client, agent_id="test-agent") diff --git a/python/packages/azure-ai/tests/test_azure_ai_client.py b/python/packages/azure-ai/tests/test_azure_ai_client.py index e2145618c0..b81e4fcf61 100644 --- a/python/packages/azure-ai/tests/test_azure_ai_client.py +++ b/python/packages/azure-ai/tests/test_azure_ai_client.py @@ -546,6 +546,37 @@ def test_update_agent_name_and_description(mock_project_client: MagicMock) -> No mock_update.assert_called_once_with(None) +def test_as_agent_uses_client_agent_name_as_default(mock_project_client: MagicMock) -> None: + """Test that as_agent() defaults Agent.name to client.agent_name when name is not provided.""" + client = create_test_azure_ai_client(mock_project_client, agent_name="my_agent") + client.agent_description = "my description" + + agent = client.as_agent(instructions="You are helpful.") + + assert agent.name == "my_agent" + assert agent.description == "my description" + + +def test_as_agent_explicit_name_overrides_client_agent_name(mock_project_client: MagicMock) -> None: + """Test that an explicit name passed to as_agent() takes precedence over client.agent_name.""" + client = create_test_azure_ai_client(mock_project_client, agent_name="client_name") + client.agent_description = "client description" + + agent = client.as_agent(name="explicit_name", description="explicit description", instructions="You are helpful.") + + assert agent.name == "explicit_name" + assert agent.description == "explicit description" + + +def test_as_agent_no_name_anywhere(mock_project_client: MagicMock) -> None: + """Test that Agent.name is None when neither as_agent name nor client.agent_name is provided.""" + client = create_test_azure_ai_client(mock_project_client) + + agent = client.as_agent(instructions="You are helpful.") + + assert agent.name is None + + async def test_async_context_manager(mock_project_client: MagicMock) -> None: """Test async context manager functionality.""" client = create_test_azure_ai_client(mock_project_client, should_close_client=True) From 431b36e51d6d9b08f95755b2e6c6f2e41cd65afe Mon Sep 17 00:00:00 2001 From: Giles Odigwe Date: Wed, 4 Mar 2026 16:01:14 -0800 Subject: [PATCH 2/3] Address review: use is None checks instead of truthiness Switch from name or self.agent_name to explicit is None checks so that callers can intentionally pass empty strings without them being replaced by client defaults. Added edge-case tests for empty strings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../azure-ai/agent_framework_azure_ai/_chat_client.py | 4 ++-- .../azure-ai/agent_framework_azure_ai/_client.py | 4 ++-- .../azure-ai/tests/test_azure_ai_agent_client.py | 11 +++++++++++ .../packages/azure-ai/tests/test_azure_ai_client.py | 11 +++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py index f7fe797236..3cd25c0aeb 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py @@ -1488,8 +1488,8 @@ def as_agent( """ return super().as_agent( id=id, - name=name or self.agent_name, - description=description or self.agent_description, + name=self.agent_name if name is None else name, + description=self.agent_description if description is None else description, instructions=instructions, tools=tools, default_options=default_options, diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_client.py index 3ca8daa64a..6496c1ac7b 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_client.py @@ -1195,8 +1195,8 @@ def as_agent( """ return super().as_agent( id=id, - name=name or self.agent_name, - description=description or self.agent_description, + name=self.agent_name if name is None else name, + description=self.agent_description if description is None else description, instructions=instructions, tools=tools, default_options=default_options, diff --git a/python/packages/azure-ai/tests/test_azure_ai_agent_client.py b/python/packages/azure-ai/tests/test_azure_ai_agent_client.py index 91369ca6fa..4d20add20a 100644 --- a/python/packages/azure-ai/tests/test_azure_ai_agent_client.py +++ b/python/packages/azure-ai/tests/test_azure_ai_agent_client.py @@ -540,6 +540,17 @@ def test_as_agent_no_name_anywhere(mock_agents_client: MagicMock) -> None: assert agent.name is None +def test_as_agent_empty_string_preserves_explicit_value(mock_agents_client: MagicMock) -> None: + """Test that empty-string name/description are preserved and do not fall back to client defaults.""" + client = create_test_azure_ai_chat_client(mock_agents_client, agent_name="client_name") + client.agent_description = "client description" + + agent = client.as_agent(name="", description="", instructions="You are helpful.") + + assert agent.name == "" + assert agent.description == "" + + async def test_azure_ai_chat_client_inner_get_response(mock_agents_client: MagicMock) -> None: """Test _inner_get_response method.""" client = create_test_azure_ai_chat_client(mock_agents_client, agent_id="test-agent") diff --git a/python/packages/azure-ai/tests/test_azure_ai_client.py b/python/packages/azure-ai/tests/test_azure_ai_client.py index b81e4fcf61..8760197284 100644 --- a/python/packages/azure-ai/tests/test_azure_ai_client.py +++ b/python/packages/azure-ai/tests/test_azure_ai_client.py @@ -577,6 +577,17 @@ def test_as_agent_no_name_anywhere(mock_project_client: MagicMock) -> None: assert agent.name is None +def test_as_agent_empty_string_preserves_explicit_value(mock_project_client: MagicMock) -> None: + """Test that empty-string name/description are preserved and do not fall back to client defaults.""" + client = create_test_azure_ai_client(mock_project_client, agent_name="client_name") + client.agent_description = "client description" + + agent = client.as_agent(name="", description="", instructions="You are helpful.") + + assert agent.name == "" + assert agent.description == "" + + async def test_async_context_manager(mock_project_client: MagicMock) -> None: """Test async context manager functionality.""" client = create_test_azure_ai_client(mock_project_client, should_close_client=True) From 420ce1e3269b4b17f59d051075e61ffa8b7af61b Mon Sep 17 00:00:00 2001 From: Giles Odigwe Date: Wed, 4 Mar 2026 16:07:45 -0800 Subject: [PATCH 3/3] Update docstrings to document name/description defaulting behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../azure-ai/agent_framework_azure_ai/_chat_client.py | 5 +++-- python/packages/azure-ai/agent_framework_azure_ai/_client.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py index 3cd25c0aeb..7236c36a32 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py @@ -1474,8 +1474,9 @@ def as_agent( Keyword Args: id: The unique identifier for the agent. Will be created automatically if not provided. - name: The name of the agent. - description: A brief description of the agent's purpose. + name: The name of the agent. Defaults to the client's ``agent_name`` when None. + description: A brief description of the agent's purpose. Defaults to the client's + ``agent_description`` when None. instructions: Optional instructions for the agent. tools: The tools to use for the request. default_options: A TypedDict containing chat options. diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_client.py index 6496c1ac7b..93b287ae54 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_client.py @@ -1181,8 +1181,9 @@ def as_agent( Keyword Args: id: The unique identifier for the agent. Will be created automatically if not provided. - name: The name of the agent. - description: A brief description of the agent's purpose. + name: The name of the agent. Defaults to the client's ``agent_name`` when None. + description: A brief description of the agent's purpose. Defaults to the client's + ``agent_description`` when None. instructions: Optional instructions for the agent. tools: The tools to use for the request. default_options: A TypedDict containing chat options.