Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
146ee97
Initial port of Dialogs from Bot Framework Python
rodrigobr-msft Apr 10, 2026
c21e8c8
Merge branch 'main' of https://github.com/microsoft/Agents-for-python…
rodrigobr-msft Apr 10, 2026
b7e8751
Cleaning up Dialogs code and preparing the Dialogs sample
rodrigobr-msft Apr 16, 2026
50c6dc4
Initial working Dialogues sample
rodrigobr-msft Apr 16, 2026
f5846df
Updating dev setup scripts to install microsoft-agents-hosting-dialog…
rodrigobr-msft Apr 16, 2026
addbc6b
Improvement to dialog test coverage
rodrigobr-msft Apr 16, 2026
f7db6c4
Reorganizing test_samples directory for ActivityHandler-based samples
rodrigobr-msft Apr 17, 2026
df94811
Ported custom dialogs sample
rodrigobr-msft Apr 17, 2026
c9bae1c
Porting complex dialogs
rodrigobr-msft Apr 17, 2026
1e19661
Replacing 'bot' with 'agent'
rodrigobr-msft Apr 17, 2026
40a3830
Adding microsoft-agents-hosting-dialogs install in azdo and github pi…
rodrigobr-msft Apr 17, 2026
6555ddd
Adding more test cases to dialogs
rodrigobr-msft Apr 17, 2026
76375dd
Improving integration test coverage of dialogs
rodrigobr-msft Apr 17, 2026
8a3af5d
Removing .infra.json file
rodrigobr-msft Apr 17, 2026
e25706f
Addressing PR comments
rodrigobr-msft Apr 17, 2026
3098e63
Updates to test samples
rodrigobr-msft Apr 17, 2026
d6ca148
Updating dependencies
rodrigobr-msft Apr 17, 2026
09a2b9f
Addressing PR comments
rodrigobr-msft Apr 17, 2026
4bd5c81
Merge branch 'main' into users/robrandao/dialogs
rodrigobr-msft Apr 17, 2026
57b3ebe
Changes to test samples
rodrigobr-msft Apr 17, 2026
eb4c79a
Small tweaks to dialog code imports
rodrigobr-msft Apr 20, 2026
f860354
Addressing final PR comments
rodrigobr-msft Apr 20, 2026
453ecc4
Formatting
rodrigobr-msft Apr 20, 2026
370d2fc
Fixing OAuthPrompt port
rodrigobr-msft Apr 21, 2026
12361be
Fixes to OAuthPrompt port
rodrigobr-msft Apr 21, 2026
d36d732
Initial work porting bot-authentication sample
rodrigobr-msft Apr 21, 2026
6d09ccd
Working auth samples for dialogs
rodrigobr-msft Apr 22, 2026
99f04e4
Updating test samples
rodrigobr-msft Apr 22, 2026
e9bec80
Temporarily moving dialogs tests out of tests folder
rodrigobr-msft Apr 28, 2026
10ec71b
Reverting extra changes to other packages
rodrigobr-msft Apr 28, 2026
a274172
Formatting
rodrigobr-msft Apr 28, 2026
8942632
Reverting agent state tests
rodrigobr-msft Apr 28, 2026
a427c2e
Removing proactive tests
rodrigobr-msft Apr 28, 2026
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 .azdo/ci-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ steps:
python -m pip install ./dist/microsoft_agents_authentication_msal*.whl
python -m pip install ./dist/microsoft_agents_copilotstudio_client*.whl
python -m pip install ./dist/microsoft_agents_hosting_aiohttp*.whl
python -m pip install ./dist/microsoft_agents_hosting_dialogs*.whl
python -m pip install ./dist/microsoft_agents_hosting_teams*.whl
python -m pip install ./dist/microsoft_agents_storage_blob*.whl
python -m pip install ./dist/microsoft_agents_storage_cosmos*.whl
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ jobs:
python -m pip install ./dist/microsoft_agents_authentication_msal*.whl
python -m pip install ./dist/microsoft_agents_copilotstudio_client*.whl
python -m pip install ./dist/microsoft_agents_hosting_aiohttp*.whl
python -m pip install ./dist/microsoft_agents_hosting_dialogs*.whl
python -m pip install ./dist/microsoft_agents_hosting_teams*.whl
python -m pip install ./dist/microsoft_agents_storage_blob*.whl
python -m pip install ./dist/microsoft_agents_storage_cosmos*.whl
Expand Down
Empty file.
89 changes: 89 additions & 0 deletions dev/hosting_dialogs/choices/test_channel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from typing import List, Tuple

import pytest

from microsoft_agents.activity import (
Activity,
ActivityTypes,
Channels,
ConversationAccount,
ChannelAccount,
)
from microsoft_agents.hosting.core import TurnContext
from microsoft_agents.hosting.dialogs.choices import Channel
from tests._common.testing_objects import MockTestingAdapter


class TestChannel:
def test_supports_suggested_actions(self):
actual = Channel.supports_suggested_actions(Channels.facebook, 5)
assert actual

def test_supports_suggested_actions_many(self):
supports_suggested_actions_data: List[Tuple[str, int, bool]] = [
(Channels.line, 13, True),
(Channels.line, 14, False),
(Channels.skype, 10, True),
(Channels.skype, 11, False),
(Channels.kik, 20, True),
(Channels.kik, 21, False),
(Channels.emulator, 100, True),
(Channels.emulator, 101, False),
(Channels.direct_line_speech, 100, True),
]

for channel, button_cnt, expected in supports_suggested_actions_data:
actual = Channel.supports_suggested_actions(channel, button_cnt)
assert (
expected == actual
), f"channel={channel}, button_cnt={button_cnt}: expected {expected}, got {actual}"

def test_supports_card_actions_many(self):
supports_card_action_data: List[Tuple[str, int, bool]] = [
(Channels.line, 99, True),
(Channels.line, 100, False),
(Channels.slack, 100, True),
(Channels.skype, 3, True),
(Channels.skype, 5, False),
(Channels.direct_line_speech, 99, True),
]

for channel, button_cnt, expected in supports_card_action_data:
actual = Channel.supports_card_actions(channel, button_cnt)
assert (
expected == actual
), f"channel={channel}, button_cnt={button_cnt}: expected {expected}, got {actual}"

def test_supports_suggested_actions_accepts_string_channel_id(self):
assert Channel.supports_suggested_actions("facebook", 5)
assert not Channel.supports_suggested_actions("facebook", 11)

def test_supports_card_actions_accepts_string_channel_id(self):
assert Channel.supports_card_actions("msteams", 3)
assert not Channel.supports_card_actions("msteams", 4)

def test_should_return_channel_id_from_context_activity(self):
adapter = MockTestingAdapter(channel_id=Channels.facebook)
test_activity = Activity(
type=ActivityTypes.message,
channel_id=Channels.facebook,
conversation=ConversationAccount(id="test"),
from_property=ChannelAccount(id="user"),
)
test_context = TurnContext(adapter, test_activity)
channel_id = Channel.get_channel_id(test_context)
assert Channels.facebook == channel_id

def test_should_return_empty_from_context_activity_missing_channel(self):
adapter = MockTestingAdapter()
test_activity = Activity(
type=ActivityTypes.message,
conversation=ConversationAccount(id="test"),
from_property=ChannelAccount(id="user"),
)
test_context = TurnContext(adapter, test_activity)
channel_id = Channel.get_channel_id(test_context)
assert "" == channel_id
29 changes: 29 additions & 0 deletions dev/hosting_dialogs/choices/test_choice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from typing import List

import pytest

from microsoft_agents.hosting.dialogs.choices import Choice
from microsoft_agents.activity import CardAction


class TestChoice:
def test_value_round_trips(self) -> None:
choice = Choice()
expected = "any"
choice.value = expected
assert expected is choice.value

def test_action_round_trips(self) -> None:
choice = Choice()
expected = CardAction(type="imBack", title="Test Action")
choice.action = expected
assert expected is choice.action

def test_synonyms_round_trips(self) -> None:
choice = Choice()
expected: List[str] = []
choice.synonyms = expected
assert expected is choice.synonyms
237 changes: 237 additions & 0 deletions dev/hosting_dialogs/choices/test_choice_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from typing import List

import pytest

from microsoft_agents.hosting.dialogs.choices import (
Choice,
ChoiceFactory,
ChoiceFactoryOptions,
)
from microsoft_agents.activity import (
ActionTypes,
Activity,
ActivityTypes,
Attachment,
AttachmentLayoutTypes,
CardAction,
HeroCard,
InputHints,
SuggestedActions,
Channels,
)


class TestChoiceFactory:
color_choices: List[Choice] = [Choice("red"), Choice("green"), Choice("blue")]
choices_with_actions: List[Choice] = [
Choice(
"ImBack",
action=CardAction(
type=ActionTypes.im_back, title="ImBack Action", value="ImBack Value"
),
),
Choice(
"MessageBack",
action=CardAction(
type=ActionTypes.message_back,
title="MessageBack Action",
value="MessageBack Value",
),
),
Choice(
"PostBack",
action=CardAction(
type=ActionTypes.post_back,
title="PostBack Action",
value="PostBack Value",
),
),
]

def test_inline_should_render_choices_inline(self):
activity = ChoiceFactory.inline(TestChoiceFactory.color_choices, "select from:")
assert "select from: (1) red, (2) green, or (3) blue" == activity.text

def test_should_render_choices_as_a_list(self):
activity = ChoiceFactory.list_style(
TestChoiceFactory.color_choices, "select from:"
)
assert "select from:\n\n 1. red\n 2. green\n 3. blue" == activity.text

def test_should_render_unincluded_numbers_choices_as_a_list(self):
activity = ChoiceFactory.list_style(
TestChoiceFactory.color_choices,
"select from:",
options=ChoiceFactoryOptions(include_numbers=False),
)
assert "select from:\n\n - red\n - green\n - blue" == activity.text

def test_should_render_choices_as_suggested_actions(self):
expected = Activity(
type=ActivityTypes.message,
text="select from:",
input_hint=InputHints.expecting_input,
suggested_actions=SuggestedActions(
actions=[
CardAction(type=ActionTypes.im_back, value="red", title="red"),
CardAction(type=ActionTypes.im_back, value="green", title="green"),
CardAction(type=ActionTypes.im_back, value="blue", title="blue"),
]
),
)

activity = ChoiceFactory.suggested_action(
TestChoiceFactory.color_choices, "select from:"
)

assert expected == activity

def test_should_render_choices_as_hero_card(self):
expected = Activity(
type=ActivityTypes.message,
input_hint=InputHints.expecting_input,
attachment_layout=AttachmentLayoutTypes.list,
attachments=[
Attachment(
content=HeroCard(
text="select from:",
buttons=[
CardAction(
type=ActionTypes.im_back, value="red", title="red"
),
CardAction(
type=ActionTypes.im_back, value="green", title="green"
),
CardAction(
type=ActionTypes.im_back, value="blue", title="blue"
),
],
),
content_type="application/vnd.microsoft.card.hero",
)
],
)

activity = ChoiceFactory.hero_card(
TestChoiceFactory.color_choices, "select from:"
)

assert expected == activity

def test_should_automatically_choose_render_style_based_on_channel_type(self):
expected = Activity(
type=ActivityTypes.message,
text="select from:",
input_hint=InputHints.expecting_input,
suggested_actions=SuggestedActions(
actions=[
CardAction(type=ActionTypes.im_back, value="red", title="red"),
CardAction(type=ActionTypes.im_back, value="green", title="green"),
CardAction(type=ActionTypes.im_back, value="blue", title="blue"),
]
),
)
activity = ChoiceFactory.for_channel(
Channels.emulator, TestChoiceFactory.color_choices, "select from:"
)

assert expected == activity

def test_should_choose_correct_styles_for_teams(self):
expected = Activity(
type=ActivityTypes.message,
input_hint=InputHints.expecting_input,
attachment_layout=AttachmentLayoutTypes.list,
attachments=[
Attachment(
content=HeroCard(
text="select from:",
buttons=[
CardAction(
type=ActionTypes.im_back, value="red", title="red"
),
CardAction(
type=ActionTypes.im_back, value="green", title="green"
),
CardAction(
type=ActionTypes.im_back, value="blue", title="blue"
),
],
),
content_type="application/vnd.microsoft.card.hero",
)
],
)
activity = ChoiceFactory.for_channel(
Channels.ms_teams, TestChoiceFactory.color_choices, "select from:"
)
assert expected == activity

def test_should_include_choice_actions_in_suggested_actions(self):
expected = Activity(
type=ActivityTypes.message,
text="select from:",
input_hint=InputHints.expecting_input,
suggested_actions=SuggestedActions(
actions=[
CardAction(
type=ActionTypes.im_back,
value="ImBack Value",
title="ImBack Action",
),
CardAction(
type=ActionTypes.message_back,
value="MessageBack Value",
title="MessageBack Action",
),
CardAction(
type=ActionTypes.post_back,
value="PostBack Value",
title="PostBack Action",
),
]
),
)
activity = ChoiceFactory.suggested_action(
TestChoiceFactory.choices_with_actions, "select from:"
)
assert expected == activity

def test_should_include_choice_actions_in_hero_cards(self):
expected = Activity(
type=ActivityTypes.message,
input_hint=InputHints.expecting_input,
attachment_layout=AttachmentLayoutTypes.list,
attachments=[
Attachment(
content=HeroCard(
text="select from:",
buttons=[
CardAction(
type=ActionTypes.im_back,
value="ImBack Value",
title="ImBack Action",
),
CardAction(
type=ActionTypes.message_back,
value="MessageBack Value",
title="MessageBack Action",
),
CardAction(
type=ActionTypes.post_back,
value="PostBack Value",
title="PostBack Action",
),
],
),
content_type="application/vnd.microsoft.card.hero",
)
],
)
activity = ChoiceFactory.hero_card(
TestChoiceFactory.choices_with_actions, "select from:"
)
assert expected == activity
Loading
Loading