Python: [BREAKING] Renamed create_agent to as_agent (#3249)

* Renamed create_agent to as_agent

* Override for as_agent

* Added override
This commit is contained in:
Dmytro Struk
2026-01-16 11:21:52 -08:00
committed by GitHub
Unverified
parent a151f10cc2
commit 5687e13221
163 changed files with 498 additions and 358 deletions
@@ -4,18 +4,21 @@ import ast
import json
import re
import sys
from collections.abc import AsyncIterable, Mapping, MutableMapping, MutableSequence, Sequence
from collections.abc import AsyncIterable, Callable, Mapping, MutableMapping, MutableSequence, Sequence
from typing import Any, ClassVar, Generic, TypedDict
from agent_framework import (
AGENT_FRAMEWORK_USER_AGENT,
BaseChatClient,
ChatAgent,
ChatMessage,
ChatMessageStoreProtocol,
ChatOptions,
ChatResponse,
ChatResponseUpdate,
CitationAnnotation,
Contents,
ContextProvider,
DataContent,
FunctionApprovalRequestContent,
FunctionApprovalResponseContent,
@@ -23,6 +26,7 @@ from agent_framework import (
FunctionResultContent,
HostedFileContent,
HostedMCPTool,
Middleware,
Role,
TextContent,
TextSpanRegion,
@@ -1162,3 +1166,59 @@ class AzureAIAgentClient(BaseChatClient[TAzureAIAgentOptions], Generic[TAzureAIA
The service URL for the chat client, or None if not set.
"""
return self.agents_client._config.endpoint # type: ignore
@override
def as_agent(
self,
*,
id: str | None = None,
name: str | None = None,
description: str | None = None,
instructions: str | None = None,
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
| Sequence[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
| None = None,
default_options: TAzureAIAgentOptions | None = None,
chat_message_store_factory: Callable[[], ChatMessageStoreProtocol] | None = None,
context_provider: ContextProvider | None = None,
middleware: Sequence[Middleware] | None = None,
**kwargs: Any,
) -> ChatAgent[TAzureAIAgentOptions]:
"""Convert this chat client to a ChatAgent.
This method creates a ChatAgent instance with this client pre-configured.
It does NOT create an agent on the Azure AI service - the actual agent
will be created on the server during the first invocation (run).
For creating and managing persistent agents on the server, use
:class:`~agent_framework_azure_ai.AzureAIAgentsProvider` instead.
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.
instructions: Optional instructions for the agent.
tools: The tools to use for the request.
default_options: A TypedDict containing chat options.
chat_message_store_factory: Factory function to create an instance of ChatMessageStoreProtocol.
context_provider: Context providers to include during agent invocation.
middleware: List of middleware to intercept agent and function invocations.
kwargs: Any additional keyword arguments.
Returns:
A ChatAgent instance configured with this chat client.
"""
return super().as_agent(
id=id,
name=name,
description=description,
instructions=instructions,
tools=tools,
default_options=default_options,
chat_message_store_factory=chat_message_store_factory,
context_provider=context_provider,
middleware=middleware,
**kwargs,
)
@@ -1,14 +1,19 @@
# Copyright (c) Microsoft. All rights reserved.
import sys
from collections.abc import Mapping, MutableSequence
from collections.abc import Callable, Mapping, MutableMapping, MutableSequence, Sequence
from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypedDict, TypeVar, cast
from agent_framework import (
AGENT_FRAMEWORK_USER_AGENT,
ChatAgent,
ChatMessage,
ChatMessageStoreProtocol,
ContextProvider,
HostedMCPTool,
Middleware,
TextContent,
ToolProtocol,
get_logger,
use_chat_middleware,
use_function_invocation,
@@ -511,3 +516,59 @@ class AzureAIClient(OpenAIBaseResponsesClient[TAzureAIClientOptions], Generic[TA
mcp["require_approval"] = {"never": {"tool_names": list(never_require_approvals)}}
return mcp
@override
def as_agent(
self,
*,
id: str | None = None,
name: str | None = None,
description: str | None = None,
instructions: str | None = None,
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
| Sequence[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
| None = None,
default_options: TAzureAIClientOptions | None = None,
chat_message_store_factory: Callable[[], ChatMessageStoreProtocol] | None = None,
context_provider: ContextProvider | None = None,
middleware: Sequence[Middleware] | None = None,
**kwargs: Any,
) -> ChatAgent[TAzureAIClientOptions]:
"""Convert this chat client to a ChatAgent.
This method creates a ChatAgent instance with this client pre-configured.
It does NOT create an agent on the Azure AI service - the actual agent
will be created on the server during the first invocation (run).
For creating and managing persistent agents on the server, use
:class:`~agent_framework_azure_ai.AzureAIProjectAgentProvider` instead.
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.
instructions: Optional instructions for the agent.
tools: The tools to use for the request.
default_options: A TypedDict containing chat options.
chat_message_store_factory: Factory function to create an instance of ChatMessageStoreProtocol.
context_provider: Context providers to include during agent invocation.
middleware: List of middleware to intercept agent and function invocations.
kwargs: Any additional keyword arguments.
Returns:
A ChatAgent instance configured with this chat client.
"""
return super().as_agent(
id=id,
name=name,
description=description,
instructions=instructions,
tools=tools,
default_options=default_options,
chat_message_store_factory=chat_message_store_factory,
context_provider=context_provider,
middleware=middleware,
**kwargs,
)
@@ -104,13 +104,13 @@ class AgentFunctionApp(DFAppBase):
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
# Create agents with unique names
weather_agent = AzureOpenAIChatClient(...).create_agent(
weather_agent = AzureOpenAIChatClient(...).as_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
math_agent = AzureOpenAIChatClient(...).create_agent(
math_agent = AzureOpenAIChatClient(...).as_agent(
name="MathAgent",
instructions="You are a helpful math assistant.",
tools=[calculate],
@@ -377,7 +377,7 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
"""
return "Unknown"
def create_agent(
def as_agent(
self,
*,
id: str | None = None,
@@ -428,7 +428,7 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
client = OpenAIChatClient(model_id="gpt-4")
# Create an agent using the convenience method
agent = client.create_agent(
agent = client.as_agent(
name="assistant",
instructions="You are a helpful assistant.",
default_options={"temperature": 0.7, "max_tokens": 500},
@@ -710,9 +710,9 @@ class HandoffBuilder:
from agent_framework.openai import OpenAIChatClient
client = OpenAIChatClient()
triage = client.create_agent(instructions="...", name="triage_agent")
refund = client.create_agent(instructions="...", name="refund_agent")
billing = client.create_agent(instructions="...", name="billing_agent")
triage = client.as_agent(instructions="...", name="triage_agent")
refund = client.as_agent(instructions="...", name="refund_agent")
billing = client.as_agent(instructions="...", name="billing_agent")
builder = HandoffBuilder().participants([triage, refund, billing])
builder.with_start_agent(triage)
@@ -9,8 +9,12 @@ from collections.abc import (
Mapping,
MutableMapping,
MutableSequence,
Sequence,
)
from typing import Any, Generic, Literal, TypedDict, cast
from typing import TYPE_CHECKING, Any, Generic, Literal, TypedDict, cast
if TYPE_CHECKING:
from .._agents import ChatAgent
from openai import AsyncOpenAI
from openai.types.beta.threads import (
@@ -28,11 +32,14 @@ from openai.types.beta.threads.runs import RunStep
from pydantic import ValidationError
from .._clients import BaseChatClient
from .._middleware import use_chat_middleware
from .._memory import ContextProvider
from .._middleware import Middleware, use_chat_middleware
from .._threads import ChatMessageStoreProtocol
from .._tools import (
AIFunction,
HostedCodeInterpreterTool,
HostedFileSearchTool,
ToolProtocol,
use_function_invocation,
)
from .._types import (
@@ -761,3 +768,59 @@ class OpenAIAssistantsClient(
self.assistant_name = agent_name
if description and not self.assistant_description:
self.assistant_description = description
@override
def as_agent(
self,
*,
id: str | None = None,
name: str | None = None,
description: str | None = None,
instructions: str | None = None,
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
| Sequence[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
| None = None,
default_options: TOpenAIAssistantsOptions | None = None,
chat_message_store_factory: Callable[[], ChatMessageStoreProtocol] | None = None,
context_provider: ContextProvider | None = None,
middleware: Sequence[Middleware] | None = None,
**kwargs: Any,
) -> "ChatAgent[TOpenAIAssistantsOptions]":
"""Convert this chat client to a ChatAgent.
This method creates a ChatAgent instance with this client pre-configured.
It does NOT create an assistant on the OpenAI service - the actual assistant
will be created on the server during the first invocation (run).
For creating and managing persistent assistants on the server, use
:class:`~agent_framework.openai.OpenAIAssistantProvider` instead.
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.
instructions: Optional instructions for the agent.
tools: The tools to use for the request.
default_options: A TypedDict containing chat options.
chat_message_store_factory: Factory function to create an instance of ChatMessageStoreProtocol.
context_provider: Context providers to include during agent invocation.
middleware: List of middleware to intercept agent and function invocations.
kwargs: Any additional keyword arguments.
Returns:
A ChatAgent instance configured with this chat client.
"""
return super().as_agent(
id=id,
name=name,
description=description,
instructions=instructions,
tools=tools,
default_options=default_options,
chat_message_store_factory=chat_message_store_factory,
context_provider=context_provider,
middleware=middleware,
**kwargs,
)
@@ -72,7 +72,7 @@ class WorkflowFactory:
# Pre-register agents for InvokeAzureAgent actions
chat_client = AzureOpenAIChatClient()
agent = chat_client.create_agent(name="MyAgent", instructions="You are helpful.")
agent = chat_client.as_agent(name="MyAgent", instructions="You are helpful.")
factory = WorkflowFactory(agents={"MyAgent": agent})
workflow = factory.create_workflow_from_yaml_path("workflow.yaml")
@@ -115,8 +115,8 @@ class WorkflowFactory:
# With pre-registered agents
client = AzureOpenAIChatClient()
agents = {
"WriterAgent": client.create_agent(name="Writer", instructions="Write content."),
"ReviewerAgent": client.create_agent(name="Reviewer", instructions="Review content."),
"WriterAgent": client.as_agent(name="Writer", instructions="Write content."),
"ReviewerAgent": client.as_agent(name="Reviewer", instructions="Review content."),
}
factory = WorkflowFactory(agents=agents)
@@ -533,14 +533,14 @@ class WorkflowFactory:
WorkflowFactory()
.register_agent(
"Writer",
client.create_agent(
client.as_agent(
name="Writer",
instructions="Write content.",
),
)
.register_agent(
"Reviewer",
client.create_agent(
client.as_agent(
name="Reviewer",
instructions="Review content.",
),
@@ -169,7 +169,7 @@ class FoundryLocalClient(OpenAIBaseChatClient[TFoundryLocalChatOptions], Generic
client = FoundryLocalClient(model_id="phi-4-mini")
agent = client.create_agent(
agent = client.as_agent(
name="LocalAgent",
instructions="You are a helpful agent.",
tools=get_weather,
@@ -65,7 +65,7 @@ async def main() -> None:
print(
f"- {model.alias} for {model.task} - id={model.id} - {(model.file_size_mb / 1000):.2f} GB - {model.license}"
)
agent = client.create_agent(
agent = client.as_agent(
name="LocalAgent",
instructions="You are a helpful agent.",
tools=get_weather,
@@ -49,7 +49,7 @@ async def create_gaia_agent() -> AsyncIterator[ChatAgent]:
"""
async with (
AzureCliCredential() as credential,
AzureAIAgentClient(credential=credential).create_agent(
AzureAIAgentClient(credential=credential).as_agent(
name="GaiaAgent",
instructions="Solve tasks to your best ability. Use Bing Search to find "
"information and Code Interpreter to perform calculations and data analysis.",
@@ -49,7 +49,7 @@ async def create_gaia_agent() -> AsyncIterator[ChatAgent]:
"""
chat_client = OpenAIResponsesClient()
async with chat_client.create_agent(
async with chat_client.as_agent(
name="GaiaAgent",
instructions="Solve tasks to your best ability. Use Web Search to find "
"information and Code Interpreter to perform calculations and data analysis.",