Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,23 @@ def __call(func: RouteHandler[StateT]) -> RouteHandler[StateT]:

return __call

def end_of_conversation(
self,
*,
auth_handlers: list[str] | None = None,
**kwargs,
) -> _RouteDecorator[RouteHandler[StateT]]:
"""
Register a new end-of-conversation activity event listener as either a decorator or a method.

:param auth_handlers: Optional list of authorization handler IDs for the route.
:type auth_handlers: Optional[list[str]]
:param kwargs: Additional route configuration passed to :meth:`microsoft_agents.hosting.core.AgentApplication.add_route`.
"""
return self.activity(
ActivityTypes.end_of_conversation, auth_handlers=auth_handlers, **kwargs
)

def message(
self,
select: str | re.Pattern[str] | list[str | re.Pattern[str]],
Expand Down
48 changes: 48 additions & 0 deletions tests/hosting_core/app/test_agent_application_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,54 @@ async def handler(context: TurnContext, state: TurnState):
assert result is handler


class TestEndOfConversationRoute:
Comment thread
rodrigobr-msft marked this conversation as resolved.
def setup_method(self):
self.app = _make_app()
self.called = False
self.received_code: str | None = None

@pytest.mark.asyncio
async def test_routes_end_of_conversation_activity(self):
@self.app.end_of_conversation()
async def handler(context: TurnContext, state: TurnState):
self.called = True
self.received_code = context.activity.code

await self.app._on_activity(
_make_context(
_make_activity(
type=ActivityTypes.end_of_conversation,
code="completedSuccessfully",
)
),
TurnState(),
)

assert self.called
assert self.received_code == "completedSuccessfully"

@pytest.mark.asyncio
async def test_does_not_match_other_activity_types(self):
@self.app.end_of_conversation()
async def handler(context: TurnContext, state: TurnState):
self.called = True

await self.app._on_activity(
_make_context(_make_activity(type=ActivityTypes.message)),
TurnState(),
)

assert not self.called

def test_decorator_returns_original_handler(self):
async def handler(context: TurnContext, state: TurnState):
pass

result = self.app.end_of_conversation()(handler)

assert result is handler


class TestMessageRoute:
def setup_method(self):
self.app = _make_app()
Expand Down
Loading