Skip to content

Commit 7fd38dd

Browse files
marklyszethinkallqingyun-wusonichi
authored
Ability to add MessageTransforms to the GroupChat's Select Speaker nested chat (speaker_selection_method='auto') (microsoft#2)
* Initial commit with ability to add transforms to GroupChat * Added tests * Tidy up * Tidy up of variable names and commented out test * Tidy up comment * Update import to relative * Added documentation topic for transform messages for speaker selection. * Formatting for test_groupchat.py * Further formatting on test_groupchat.py * Tweak to test * Added Long Context Handling to tag for documentation --------- Co-authored-by: Li Jiang <[email protected]> Co-authored-by: Qingyun Wu <[email protected]> Co-authored-by: Chi Wang <[email protected]>
1 parent c47ea3a commit 7fd38dd

File tree

5 files changed

+366
-2
lines changed

5 files changed

+366
-2
lines changed

autogen/agentchat/contrib/capabilities/transform_messages.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
import copy
88
from typing import Dict, List
99

10-
from autogen import ConversableAgent
11-
1210
from ....formatting_utils import colored
11+
from ...conversable_agent import ConversableAgent
1312
from .transforms import MessageTransform
1413

1514

autogen/agentchat/groupchat.py

+21
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from ..runtime_logging import log_new_agent, logging_enabled
2222
from .agent import Agent
2323
from .chat import ChatResult
24+
from .contrib.capabilities import transform_messages
2425
from .conversable_agent import ConversableAgent
2526

2627
logger = logging.getLogger(__name__)
@@ -82,6 +83,8 @@ def custom_speaker_selection_func(
8283
of times until a single agent is returned or it exhausts the maximum attempts.
8384
Applies only to "auto" speaker selection method.
8485
Default is 2.
86+
- select_speaker_transform_messages: (optional) the message transformations to apply to the nested select speaker agent-to-agent chat messages.
87+
Takes a TransformMessages object, defaults to None and is only utilised when the speaker selection method is "auto".
8588
- select_speaker_auto_verbose: whether to output the select speaker responses and selections
8689
If set to True, the outputs from the two agents in the nested select speaker chat will be output, along with
8790
whether the responses were successful, or not, in selecting an agent
@@ -138,6 +141,7 @@ def custom_speaker_selection_func(
138141
The names are case-sensitive and should not be abbreviated or changed.
139142
The only names that are accepted are {agentlist}.
140143
Respond with ONLY the name of the speaker and DO NOT provide a reason."""
144+
select_speaker_transform_messages: Optional[transform_messages.TransformMessages] = None
141145
select_speaker_auto_verbose: Optional[bool] = False
142146
role_for_select_speaker_messages: Optional[str] = "system"
143147

@@ -255,6 +259,15 @@ def __post_init__(self):
255259
elif self.max_retries_for_selecting_speaker < 0:
256260
raise ValueError("max_retries_for_selecting_speaker must be greater than or equal to zero")
257261

262+
# Load message transforms here (load once for the Group Chat so we don't have to re-initiate it and it maintains the cache across subsequent select speaker calls)
263+
if self.select_speaker_transform_messages is not None:
264+
if isinstance(self.select_speaker_transform_messages, transform_messages.TransformMessages):
265+
self._speaker_selection_transforms = self.select_speaker_transform_messages
266+
else:
267+
raise ValueError("select_speaker_transform_messages must be None or MessageTransforms.")
268+
else:
269+
self._speaker_selection_transforms = None
270+
258271
# Validate select_speaker_auto_verbose
259272
if self.select_speaker_auto_verbose is None or not isinstance(self.select_speaker_auto_verbose, bool):
260273
raise ValueError("select_speaker_auto_verbose cannot be None or non-bool")
@@ -661,6 +674,10 @@ def validate_speaker_name(recipient, messages, sender, config) -> Tuple[bool, Un
661674
else:
662675
start_message = messages[-1]
663676

677+
# Add the message transforms, if any, to the speaker selection agent
678+
if self._speaker_selection_transforms is not None:
679+
self._speaker_selection_transforms.add_to_agent(speaker_selection_agent)
680+
664681
# Run the speaker selection chat
665682
result = checking_agent.initiate_chat(
666683
speaker_selection_agent,
@@ -755,6 +772,10 @@ def validate_speaker_name(recipient, messages, sender, config) -> Tuple[bool, Un
755772
else:
756773
start_message = messages[-1]
757774

775+
# Add the message transforms, if any, to the speaker selection agent
776+
if self._speaker_selection_transforms is not None:
777+
self._speaker_selection_transforms.add_to_agent(speaker_selection_agent)
778+
758779
# Run the speaker selection chat
759780
result = await checking_agent.a_initiate_chat(
760781
speaker_selection_agent,

ms_code/test_groupchat.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from typing import Any, Dict, List, Optional
2+
3+
import pytest
4+
5+
from autogen import Agent, AssistantAgent, GroupChat, GroupChatManager
6+
from autogen.agentchat.contrib.capabilities import transform_messages, transforms
7+
8+
9+
def test_select_speaker_transform_messages():
10+
"""Tests adding transform messages to a GroupChat for speaker selection when in 'auto' mode"""
11+
12+
# Test adding a TransformMessages to a group chat
13+
test_add_transforms = transform_messages.TransformMessages(
14+
transforms=[
15+
transforms.MessageHistoryLimiter(max_messages=10),
16+
transforms.MessageTokenLimiter(max_tokens=3000, max_tokens_per_message=500, min_tokens=300),
17+
]
18+
)
19+
20+
print(GroupChat.__module__) # Prints the module where GroupChat is defined
21+
import inspect
22+
23+
# Get the file where GroupChat is defined
24+
print(inspect.getfile(GroupChat))
25+
26+
coder = AssistantAgent(name="Coder", llm_config=None)
27+
groupchat = GroupChat(messages=[], agents=[coder], select_speaker_transform_messages=test_add_transforms)
28+
29+
# Ensure the transform have been added to the GroupChat
30+
assert groupchat._speaker_selection_transforms == test_add_transforms
31+
32+
# Attempt to add a non MessageTransforms object, such as a list of transforms
33+
with pytest.raises(ValueError, match="select_speaker_transform_messages must be None or MessageTransforms."):
34+
groupchat = GroupChat(
35+
messages=[],
36+
agents=[coder],
37+
select_speaker_transform_messages=List[transforms.MessageHistoryLimiter(max_messages=10)],
38+
)
39+
40+
# Ensure if we don't pass any transforms in, none are on the GroupChat
41+
groupchat_missing = GroupChat(messages=[], agents=[coder])
42+
43+
assert groupchat_missing._speaker_selection_transforms is None
44+
45+
# Ensure we can pass in None
46+
groupchat_none = GroupChat(
47+
messages=[],
48+
agents=[coder],
49+
select_speaker_transform_messages=None,
50+
)
51+
52+
assert groupchat_none._speaker_selection_transforms is None
53+
54+
55+
test_select_speaker_transform_messages()

test/agentchat/test_groupchat.py

+42
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import autogen
2020
from autogen import Agent, AssistantAgent, GroupChat, GroupChatManager
21+
from autogen.agentchat.contrib.capabilities import transform_messages, transforms
2122
from autogen.exception_utils import AgentNameConflict, UndefinedNextAgent
2223

2324

@@ -2067,6 +2068,46 @@ def test_manager_resume_messages():
20672068
return_agent, return_message = manager.resume(messages="Let's get this conversation started.")
20682069

20692070

2071+
def test_select_speaker_transform_messages():
2072+
"""Tests adding transform messages to a GroupChat for speaker selection when in 'auto' mode"""
2073+
2074+
# Test adding a TransformMessages to a group chat
2075+
test_add_transforms = transform_messages.TransformMessages(
2076+
transforms=[
2077+
transforms.MessageHistoryLimiter(max_messages=10),
2078+
transforms.MessageTokenLimiter(max_tokens=3000, max_tokens_per_message=500, min_tokens=300),
2079+
]
2080+
)
2081+
2082+
coder = AssistantAgent(name="Coder", llm_config=None)
2083+
groupchat = GroupChat(messages=[], agents=[coder], select_speaker_transform_messages=test_add_transforms)
2084+
2085+
# Ensure the transform have been added to the GroupChat
2086+
assert groupchat._speaker_selection_transforms == test_add_transforms
2087+
2088+
# Attempt to add a non MessageTransforms object, such as a list of transforms
2089+
with pytest.raises(ValueError, match="select_speaker_transform_messages must be None or MessageTransforms."):
2090+
groupchat = GroupChat(
2091+
messages=[],
2092+
agents=[coder],
2093+
select_speaker_transform_messages=[transforms.MessageHistoryLimiter(max_messages=10)],
2094+
)
2095+
2096+
# Ensure if we don't pass any transforms in, none are on the GroupChat
2097+
groupchat_missing = GroupChat(messages=[], agents=[coder])
2098+
2099+
assert groupchat_missing._speaker_selection_transforms is None
2100+
2101+
# Ensure we can pass in None
2102+
groupchat_none = GroupChat(
2103+
messages=[],
2104+
agents=[coder],
2105+
select_speaker_transform_messages=None,
2106+
)
2107+
2108+
assert groupchat_none._speaker_selection_transforms is None
2109+
2110+
20702111
def test_manager_resume_message_assignment():
20712112
"""Tests that the messages passed in are assigned to agents correctly"""
20722113

@@ -2140,5 +2181,6 @@ def test_manager_resume_message_assignment():
21402181
# test_manager_resume_functions()
21412182
# test_manager_resume_returns()
21422183
# test_manager_resume_messages()
2184+
# test_select_speaker_transform_messages()
21432185
test_manager_resume_message_assignment()
21442186
pass

0 commit comments

Comments
 (0)