Python: Fix as_agent() not defaulting name/description from client properties (#4484)

* 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>

* 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>

* Update docstrings to document name/description defaulting behavior

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Giles Odigwe
2026-03-05 12:12:11 -08:00
committed by GitHub
Unverified
parent 8bf4235f4e
commit ce7b5b17c1
4 changed files with 94 additions and 8 deletions
@@ -1461,8 +1461,9 @@ class AzureAIAgentClient(
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.
@@ -1475,8 +1476,8 @@ class AzureAIAgentClient(
"""
return super().as_agent(
id=id,
name=name,
description=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,
@@ -1189,8 +1189,9 @@ class RawAzureAIClient(RawOpenAIResponsesClient[AzureAIClientOptionsT], Generic[
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.
@@ -1203,8 +1204,8 @@ class RawAzureAIClient(RawOpenAIResponsesClient[AzureAIClientOptionsT], Generic[
"""
return super().as_agent(
id=id,
name=name,
description=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,
@@ -509,6 +509,48 @@ 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
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")
@@ -546,6 +546,48 @@ 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
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)