Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions python/packages/ag-ui/agent_framework_ag_ui/_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import Any, cast

from ag_ui.core import BaseEvent
from agent_framework import AgentProtocol
from agent_framework import SupportsAgentRun

from ._run import run_agent_stream

Expand Down Expand Up @@ -65,13 +65,13 @@ def _normalize_state_schema(state_schema: Any | None) -> dict[str, Any]:
class AgentFrameworkAgent:
"""Wraps Agent Framework agents for AG-UI protocol compatibility.

Translates between Agent Framework's AgentProtocol and AG-UI's event-based
Translates between Agent Framework's SupportsAgentRun and AG-UI's event-based
protocol. Follows a simple linear flow: RunStarted -> content events -> RunFinished.
"""

def __init__(
self,
agent: AgentProtocol,
agent: SupportsAgentRun,
name: str | None = None,
description: str | None = None,
state_schema: Any | None = None,
Expand Down
8 changes: 4 additions & 4 deletions python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import Any

from ag_ui.encoder import EventEncoder
from agent_framework import AgentProtocol
from agent_framework import SupportsAgentRun
from fastapi import FastAPI
from fastapi.params import Depends
from fastapi.responses import StreamingResponse
Expand All @@ -21,7 +21,7 @@

def add_agent_framework_fastapi_endpoint(
app: FastAPI,
agent: AgentProtocol | AgentFrameworkAgent,
agent: SupportsAgentRun | AgentFrameworkAgent,
path: str = "/",
state_schema: Any | None = None,
predict_state_config: dict[str, dict[str, str]] | None = None,
Expand All @@ -34,7 +34,7 @@ def add_agent_framework_fastapi_endpoint(

Args:
app: The FastAPI application
agent: The agent to expose (can be raw AgentProtocol or wrapped)
agent: The agent to expose (can be raw SupportsAgentRun or wrapped)
path: The endpoint path
state_schema: Optional state schema for shared state management; accepts dict or Pydantic model/class
predict_state_config: Optional predictive state update configuration.
Expand All @@ -47,7 +47,7 @@ def add_agent_framework_fastapi_endpoint(
authentication checks, rate limiting, or other middleware-like behavior.
Example: `dependencies=[Depends(verify_api_key)]`
"""
if isinstance(agent, AgentProtocol):
if isinstance(agent, SupportsAgentRun):
wrapped_agent = AgentFrameworkAgent(
agent=agent,
state_schema=state_schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from agent_framework import BaseChatClient

if TYPE_CHECKING:
from agent_framework import AgentProtocol
from agent_framework import SupportsAgentRun

logger = logging.getLogger(__name__)

Expand All @@ -29,7 +29,7 @@ def _collect_mcp_tool_functions(mcp_tools: list[Any]) -> list[Any]:
return functions


def collect_server_tools(agent: "AgentProtocol") -> list[Any]:
def collect_server_tools(agent: "SupportsAgentRun") -> list[Any]:
"""Collect server tools from an agent.

This includes both regular tools from default_options and MCP tools.
Expand Down Expand Up @@ -64,7 +64,7 @@ def collect_server_tools(agent: "AgentProtocol") -> list[Any]:
return server_tools


def register_additional_client_tools(agent: "AgentProtocol", client_tools: list[Any] | None) -> None:
def register_additional_client_tools(agent: "SupportsAgentRun", client_tools: list[Any] | None) -> None:
"""Register client tools as additional declaration-only tools to avoid server execution.

Args:
Expand Down
6 changes: 3 additions & 3 deletions python/packages/ag-ui/agent_framework_ag_ui/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
ToolCallStartEvent,
)
from agent_framework import (
AgentProtocol,
AgentThread,
ChatMessage,
Content,
SupportsAgentRun,
prepare_function_call_results,
)
from agent_framework._middleware import FunctionMiddlewarePipeline
Expand Down Expand Up @@ -579,7 +579,7 @@ def _handle_step_based_approval(messages: list[Any]) -> list[BaseEvent]:
async def _resolve_approval_responses(
messages: list[Any],
tools: list[Any],
agent: AgentProtocol,
agent: SupportsAgentRun,
run_kwargs: dict[str, Any],
) -> None:
"""Execute approved function calls and replace approval content with results.
Expand Down Expand Up @@ -741,7 +741,7 @@ def _build_messages_snapshot(

async def run_agent_stream(
input_data: dict[str, Any],
agent: AgentProtocol,
agent: SupportsAgentRun,
config: "AgentConfig",
) -> "AsyncGenerator[BaseEvent, None]":
"""Run agent and yield AG-UI events.
Expand Down
8 changes: 4 additions & 4 deletions python/packages/ag-ui/tests/ag_ui/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import pytest
from agent_framework import (
AgentProtocol,
AgentResponse,
AgentResponseUpdate,
AgentThread,
Expand All @@ -20,6 +19,7 @@
ChatResponse,
ChatResponseUpdate,
Content,
SupportsAgentRun,
)
from agent_framework._clients import TOptions_co
from agent_framework._middleware import ChatMiddlewareLayer
Expand Down Expand Up @@ -149,8 +149,8 @@ async def _stream(
return _stream


class StubAgent(AgentProtocol):
"""Minimal AgentProtocol stub for orchestrator tests."""
class StubAgent(SupportsAgentRun):
"""Minimal SupportsAgentRun stub for orchestrator tests."""

def __init__(
self,
Expand Down Expand Up @@ -238,6 +238,6 @@ def stream_from_updates_fixture() -> Callable[[list[ChatResponseUpdate]], Stream


@pytest.fixture
def stub_agent() -> type[AgentProtocol]:
def stub_agent() -> type[SupportsAgentRun]:
"""Return the StubAgent class for creating test instances."""
return StubAgent # type: ignore[return-value]
2 changes: 1 addition & 1 deletion python/packages/ag-ui/tests/ag_ui/test_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def _build(response_text: str = "Test response"):


async def test_add_endpoint_with_agent_protocol(build_chat_client):
"""Test adding endpoint with raw AgentProtocol."""
"""Test adding endpoint with raw SupportsAgentRun."""
app = FastAPI()
agent = ChatAgent(name="test", instructions="Test agent", chat_client=build_chat_client())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import azure.durable_functions as df
import azure.functions as func
from agent_framework import AgentProtocol, get_logger
from agent_framework import SupportsAgentRun, get_logger
from agent_framework_durabletask import (
DEFAULT_MAX_POLL_RETRIES,
DEFAULT_POLL_INTERVAL_SECONDS,
Expand Down Expand Up @@ -51,12 +51,12 @@ class AgentMetadata:
"""Metadata for a registered agent.

Attributes:
agent: The agent instance implementing AgentProtocol
agent: The agent instance implementing SupportsAgentRun
http_endpoint_enabled: Whether HTTP endpoint is enabled for this agent
mcp_tool_enabled: Whether MCP tool endpoint is enabled for this agent
"""

agent: AgentProtocol
agent: SupportsAgentRun
http_endpoint_enabled: bool
mcp_tool_enabled: bool

Expand Down Expand Up @@ -145,7 +145,7 @@ def my_orchestration(context):
- Full access to all Azure Functions capabilities

Attributes:
agents: Dictionary of agent name to AgentProtocol instance
agents: Dictionary of agent name to SupportsAgentRun instance
enable_health_check: Whether health check endpoint is enabled
enable_http_endpoints: Whether HTTP endpoints are created for agents
enable_mcp_tool_trigger: Whether MCP tool triggers are created for agents
Expand All @@ -160,7 +160,7 @@ def my_orchestration(context):

def __init__(
self,
agents: list[AgentProtocol] | None = None,
agents: list[SupportsAgentRun] | None = None,
http_auth_level: func.AuthLevel = func.AuthLevel.FUNCTION,
enable_health_check: bool = True,
enable_http_endpoints: bool = True,
Expand Down Expand Up @@ -222,25 +222,25 @@ def __init__(
logger.debug("[AgentFunctionApp] Initialization complete")

@property
def agents(self) -> dict[str, AgentProtocol]:
def agents(self) -> dict[str, SupportsAgentRun]:
"""Returns dict of agent names to agent instances.

Returns:
Dictionary mapping agent names to their AgentProtocol instances.
Dictionary mapping agent names to their SupportsAgentRun instances.
"""
return {name: metadata.agent for name, metadata in self._agent_metadata.items()}

def add_agent(
self,
agent: AgentProtocol,
agent: SupportsAgentRun,
callback: AgentResponseCallbackProtocol | None = None,
enable_http_endpoint: bool | None = None,
enable_mcp_tool_trigger: bool | None = None,
) -> None:
"""Add an agent to the function app after initialization.

Args:
agent: The Microsoft Agent Framework agent instance (must implement AgentProtocol)
agent: The Microsoft Agent Framework agent instance (must implement SupportsAgentRun)
The agent must have a 'name' attribute.
callback: Optional callback invoked during agent execution
enable_http_endpoint: Optional flag to enable/disable HTTP endpoint for this agent.
Expand Down Expand Up @@ -322,7 +322,7 @@ def get_agent(

def _setup_agent_functions(
self,
agent: AgentProtocol,
agent: SupportsAgentRun,
agent_name: str,
callback: AgentResponseCallbackProtocol | None,
enable_http_endpoint: bool,
Expand Down Expand Up @@ -484,7 +484,7 @@ async def http_start(req: func.HttpRequest, client: df.DurableOrchestrationClien

def _setup_agent_entity(
self,
agent: AgentProtocol,
agent: SupportsAgentRun,
agent_name: str,
callback: AgentResponseCallbackProtocol | None,
) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from typing import Any, cast

import azure.durable_functions as df
from agent_framework import AgentProtocol, get_logger
from agent_framework import SupportsAgentRun, get_logger
from agent_framework_durabletask import (
AgentEntity,
AgentEntityStateProviderMixin,
Expand Down Expand Up @@ -46,13 +46,13 @@ def _get_thread_id_from_entity(self) -> str:


def create_agent_entity(
agent: AgentProtocol,
agent: SupportsAgentRun,
callback: AgentResponseCallbackProtocol | None = None,
) -> Callable[[df.DurableEntityContext], None]:
"""Factory function to create an agent entity class.

Args:
agent: The Microsoft Agent Framework agent instance (must implement AgentProtocol)
agent: The Microsoft Agent Framework agent instance (must implement SupportsAgentRun)
callback: Optional callback invoked during streaming and final responses

Returns:
Expand Down
2 changes: 1 addition & 1 deletion python/packages/chatkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ and [OpenAI ChatKit (Python)](https://github.com/openai/chatkit-python/).
Specifically, it mirrors the [Agent SDK integration](https://github.com/openai/chatkit-python/blob/main/docs/server.md#agents-sdk-integration), and provides the following helpers:

- `stream_agent_response`: A helper to convert a streamed `AgentResponseUpdate`
from a Microsoft Agent Framework agent that implements `AgentProtocol` to ChatKit events.
from a Microsoft Agent Framework agent that implements `SupportsAgentRun` to ChatKit events.
- `ThreadItemConverter`: A extendable helper class to convert ChatKit thread items to
`ChatMessage` objects that can be consumed by an Agent Framework agent.
- `simple_to_agent_input`: A helper function that uses the default implementation
Expand Down
2 changes: 1 addition & 1 deletion python/packages/core/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ agent_framework/

### Agents (`_agents.py`)

- **`AgentProtocol`** - Protocol defining the agent interface
- **`SupportsAgentRun`** - Protocol defining the agent interface
- **`BaseAgent`** - Abstract base class for agents
- **`ChatAgent`** - Main agent class wrapping a chat client with tools, instructions, and middleware

Expand Down
20 changes: 10 additions & 10 deletions python/packages/core/agent_framework/_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,14 @@ class _RunContext(TypedDict):
finalize_kwargs: dict[str, Any]


__all__ = ["AgentProtocol", "BareAgent", "BaseAgent", "ChatAgent", "RawChatAgent"]
__all__ = ["BareAgent", "BaseAgent", "ChatAgent", "RawChatAgent", "SupportsAgentRun"]


# region Agent Protocol


@runtime_checkable
class AgentProtocol(Protocol):
class SupportsAgentRun(Protocol):
"""A protocol for an agent that can be invoked.

This protocol defines the interface that all agents must implement,
Expand All @@ -185,11 +185,11 @@ class AgentProtocol(Protocol):
Examples:
.. code-block:: python

from agent_framework import AgentProtocol
from agent_framework import SupportsAgentRun


# Any class implementing the required methods is compatible
# No need to inherit from AgentProtocol or use any framework classes
# No need to inherit from SupportsAgentRun or use any framework classes
class CustomAgent:
def __init__(self):
self.id = "custom-agent-001"
Expand Down Expand Up @@ -218,7 +218,7 @@ def get_new_thread(self, **kwargs):

# Verify the instance satisfies the protocol
instance = CustomAgent()
assert isinstance(instance, AgentProtocol)
assert isinstance(instance, SupportsAgentRun)
"""

id: str
Expand Down Expand Up @@ -297,7 +297,7 @@ class BaseAgent(SerializationMixin):

Note:
BaseAgent cannot be instantiated directly as it doesn't implement the
``run()`` and other methods required by AgentProtocol.
``run()`` and other methods required by SupportsAgentRun.
Use a concrete implementation like ChatAgent or create a subclass.

Examples:
Expand Down Expand Up @@ -451,7 +451,7 @@ def as_tool(
A FunctionTool that can be used as a tool by other agents.

Raises:
TypeError: If the agent does not implement AgentProtocol.
TypeError: If the agent does not implement SupportsAgentRun.
ValueError: If the agent tool name cannot be determined.

Examples:
Expand All @@ -468,9 +468,9 @@ def as_tool(
# Use the tool with another agent
coordinator = ChatAgent(chat_client=client, name="coordinator", tools=research_tool)
"""
# Verify that self implements AgentProtocol
if not isinstance(self, AgentProtocol):
raise TypeError(f"Agent {self.__class__.__name__} must implement AgentProtocol to be used as a tool")
# Verify that self implements SupportsAgentRun
if not isinstance(self, SupportsAgentRun):
raise TypeError(f"Agent {self.__class__.__name__} must implement SupportsAgentRun to be used as a tool")

tool_name = name or _sanitize_agent_name(self.name)
if tool_name is None:
Expand Down
6 changes: 3 additions & 3 deletions python/packages/core/agent_framework/_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
if TYPE_CHECKING:
from pydantic import BaseModel

from ._agents import AgentProtocol
from ._agents import SupportsAgentRun
from ._clients import ChatClientProtocol
from ._threads import AgentThread
from ._tools import FunctionTool
Expand Down Expand Up @@ -64,7 +64,7 @@
"function_middleware",
]

TAgent = TypeVar("TAgent", bound="AgentProtocol")
AgentT = TypeVar("AgentT", bound="SupportsAgentRun")
TContext = TypeVar("TContext")
TUpdate = TypeVar("TUpdate")

Expand Down Expand Up @@ -154,7 +154,7 @@ async def process(self, context: AgentContext, next):
def __init__(
self,
*,
agent: AgentProtocol,
agent: SupportsAgentRun,
messages: list[ChatMessage],
thread: AgentThread | None = None,
options: Mapping[str, Any] | None = None,
Expand Down
Loading
Loading