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
1 change: 1 addition & 0 deletions samples/python/autopilot-agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ participate in Microsoft Teams conversations.
| [Hello World](hello-world/README.md) | A minimal agent that responds to Teams direct messages, group chats, and channel messages that mention it. Interactively create or reuse its Foundry project and model deployment. |
| [Foundry Toolbox](foundry-toolbox/README.md) | Combine Microsoft Learn and Bing-backed Web Search in one Foundry Toolbox to answer questions about Microsoft guidance and current public web information. |
| [Meeting Assistant](meeting-assistant/README.md) | Post meeting agenda reminders and transcript-grounded closure reports. |
| [Routines](routines/README.md) | Create timers and recurring reminders, inspect their stored schedule, and disable them from a personal Teams chat. |

Start with the [Hello World walkthrough](hello-world/README.md#step-1-install-the-prerequisites).
It contains the complete sequence: prerequisites, permissions, sign-in,
Expand Down
21 changes: 21 additions & 0 deletions samples/python/autopilot-agents/routines/.agentignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.azure/
.agentignore
.git/
.gitignore
.github/
.pytest_cache/
.venv/
.vscode/
__pycache__/
*.py[cod]
AGENTS.md
README.md
azure.yaml
pyproject.toml
tests/
scripts/
infra/
.dockerignore
Dockerfile
.env
.env.*
7 changes: 7 additions & 0 deletions samples/python/autopilot-agents/routines/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.azure/
.venv/
.vscode/
__pycache__/
*.py[cod]
.env
.env.*
348 changes: 348 additions & 0 deletions samples/python/autopilot-agents/routines/README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions samples/python/autopilot-agents/routines/agent/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Agent package."""
7 changes: 7 additions & 0 deletions samples/python/autopilot-agents/routines/agent/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Run the agent with ``python -m agent``."""

from .app import main


if __name__ == "__main__":
main()
70 changes: 70 additions & 0 deletions samples/python/autopilot-agents/routines/agent/activity_routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Activity selectors for the Microsoft Teams surfaces supported by this agent."""

from __future__ import annotations

from collections.abc import Callable

from microsoft_agents.activity import Activity
from microsoft_agents.hosting.core import TurnContext

ActivityMatcher = Callable[[Activity], bool]
MESSAGE_DELIVERY_EVENT_NAME = (
"application/vnd.microsoft.routines.messageDelivery.v1"
)


def selector(matcher: ActivityMatcher) -> Callable[[TurnContext], bool]:
"""Adapt an activity predicate for ``AgentApplication.add_route``."""
return lambda context: matcher(context.activity)


def teams_direct_message(activity: Activity) -> bool:
return (
_is_message_on(activity, "msteams")
and activity.conversation is not None
and activity.conversation.conversation_type == "personal"
)


def teams_routine_delivery_event(activity: Activity) -> bool:
return (
activity.type == "event"
and activity.channel_id is not None
and activity.channel_id.channel == "msteams"
and activity.name == MESSAGE_DELIVERY_EVENT_NAME
)


def teams_group_chat_message(activity: Activity) -> bool:
return (
_is_message_on(activity, "msteams")
and activity.conversation is not None
and activity.conversation.conversation_type == "groupChat"
)


def teams_tagged_channel_message(activity: Activity) -> bool:
return (
_is_message_on(activity, "msteams")
and activity.conversation is not None
and activity.conversation.conversation_type == "channel"
and _agent_is_mentioned(activity)
)


def _is_message_on(activity: Activity, channel: str) -> bool:
return (
activity.type == "message"
and activity.channel_id is not None
and activity.channel_id.channel == channel
)


def _agent_is_mentioned(activity: Activity) -> bool:
if activity.recipient is None:
return False

return any(
mention.mentioned is not None and mention.mentioned.id == activity.recipient.id
for mention in activity.get_mentions()
)
Loading
Loading