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
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ def run_stream(
cancellation_token: CancellationToken | None = None,
) -> AsyncGenerator[InnerMessage | ChatMessage | TaskResult, None]:
"""Run the task and produces a stream of messages and the final result
as the last item in the stream."""
:class:`TaskResult` as the last item in the stream."""
...
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(
self,
participants: List[ChatAgent],
group_chat_manager_class: type[BaseGroupChatManager],
termination_condition: TerminationCondition | None = None,
):
if len(participants) == 0:
raise ValueError("At least one participant is required.")
Expand All @@ -41,6 +42,7 @@ def __init__(
self._participants = participants
self._team_id = str(uuid.uuid4())
self._base_group_chat_manager_class = group_chat_manager_class
self._termination_condition = termination_condition

@abstractmethod
def _create_group_chat_manager_factory(
Expand Down Expand Up @@ -72,12 +74,12 @@ async def run(
task: str,
*,
cancellation_token: CancellationToken | None = None,
termination_condition: TerminationCondition | None = None,
) -> TaskResult:
"""Run the team and return the result. The base implementation uses
:meth:`run_stream` to run the team and then returns the final result."""
async for message in self.run_stream(
task, cancellation_token=cancellation_token, termination_condition=termination_condition
task,
cancellation_token=cancellation_token,
):
if isinstance(message, TaskResult):
return message
Expand All @@ -88,10 +90,9 @@ async def run_stream(
task: str,
*,
cancellation_token: CancellationToken | None = None,
termination_condition: TerminationCondition | None = None,
) -> AsyncGenerator[InnerMessage | ChatMessage | TaskResult, None]:
"""Run the team and produces a stream of messages and the final result
as the last item in the stream."""
of the type :class:`TaskResult` as the last item in the stream."""
# Create the runtime.
runtime = SingleThreadedAgentRuntime()

Expand Down Expand Up @@ -131,7 +132,7 @@ async def run_stream(
group_topic_type=group_topic_type,
participant_topic_types=participant_topic_types,
participant_descriptions=participant_descriptions,
termination_condition=termination_condition,
termination_condition=self._termination_condition,
),
)
# Add subscriptions for the group chat manager.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class RoundRobinGroupChat(BaseGroupChat):

Args:
participants (List[BaseChatAgent]): The participants in the group chat.
tools (List[Tool], optional): The tools to use in the group chat. Defaults to None.
termination_condition (TerminationCondition, optional): The termination condition for the group chat. Defaults to None.
Without a termination condition, the group chat will run indefinitely.

Raises:
ValueError: If no participants are provided or if participant names are not unique.
Expand All @@ -65,7 +66,7 @@ class RoundRobinGroupChat(BaseGroupChat):
from autogen_ext.models import OpenAIChatCompletionClient
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.task import StopMessageTermination
from autogen_agentchat.task import TextMentionTermination


async def main() -> None:
Expand All @@ -79,8 +80,9 @@ async def get_weather(location: str) -> str:
model_client=model_client,
tools=[get_weather],
)
team = RoundRobinGroupChat([assistant])
stream = team.run_stream("What's the weather in New York?", termination_condition=StopMessageTermination())
termination = TextMentionTermination("TERMINATE")
team = RoundRobinGroupChat([assistant], termination_condition=termination)
stream = team.run_stream("What's the weather in New York?")
async for message in stream:
print(message)

Expand All @@ -95,27 +97,31 @@ async def get_weather(location: str) -> str:
from autogen_ext.models import OpenAIChatCompletionClient
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.task import StopMessageTermination
from autogen_agentchat.task import TextMentionTermination


async def main() -> None:
model_client = OpenAIChatCompletionClient(model="gpt-4o")

agent1 = AssistantAgent("Assistant1", model_client=model_client)
agent2 = AssistantAgent("Assistant2", model_client=model_client)
team = RoundRobinGroupChat([agent1, agent2])
stream = team.run_stream("Tell me some jokes.", termination_condition=StopMessageTermination())
termination = TextMentionTermination("TERMINATE")
team = RoundRobinGroupChat([agent1, agent2], termination_condition=termination)
stream = team.run_stream("Tell me some jokes.")
async for message in stream:
print(message)


asyncio.run(main())
"""

def __init__(self, participants: List[ChatAgent]):
def __init__(
self, participants: List[ChatAgent], termination_condition: TerminationCondition | None = None
) -> None:
super().__init__(
participants,
group_chat_manager_class=RoundRobinGroupChatManager,
termination_condition=termination_condition,
)

def _create_group_chat_manager_factory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class SelectorGroupChat(BaseGroupChat):
must have unique names and at least two participants.
model_client (ChatCompletionClient): The ChatCompletion model client used
to select the next speaker.
termination_condition (TerminationCondition, optional): The termination condition for the group chat. Defaults to None.
Without a termination condition, the group chat will run indefinitely.
selector_prompt (str, optional): The prompt template to use for selecting the next speaker.
Must contain '{roles}', '{participants}', and '{history}' to be filled in.
allow_repeated_speaker (bool, optional): Whether to allow the same speaker to be selected
Expand All @@ -187,10 +189,11 @@ class SelectorGroupChat(BaseGroupChat):

.. code-block:: python

import asyncio
from autogen_ext.models import OpenAIChatCompletionClient
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.task import StopMessageTermination
from autogen_agentchat.task import TextMentionTermination


async def main() -> None:
Expand Down Expand Up @@ -223,20 +226,24 @@ async def book_trip() -> str:
tools=[lookup_flight],
description="Helps with flight booking.",
)
team = SelectorGroupChat([travel_advisor, hotel_agent, flight_agent], model_client=model_client)
stream = team.run_stream("Book a 3-day trip to new york.", termination_condition=StopMessageTermination())
termination = TextMentionTermination("TERMINATE")
team = SelectorGroupChat(
[travel_advisor, hotel_agent, flight_agent],
model_client=model_client,
termination_condition=termination,
)
stream = team.run_stream("Book a 3-day trip to new york.")
async for message in stream:
print(message)


import asyncio

asyncio.run(main())

A team with a custom selector function:

.. code-block:: python

import asyncio
from autogen_ext.models import OpenAIChatCompletionClient
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import SelectorGroupChat
Expand Down Expand Up @@ -273,15 +280,19 @@ def selector_func(messages):
return "Agent2"
return None

team = SelectorGroupChat([agent1, agent2], model_client=model_client, selector_func=selector_func)
termination = TextMentionTermination("Correct!")
team = SelectorGroupChat(
[agent1, agent2],
model_client=model_client,
selector_func=selector_func,
termination_condition=termination,
)

stream = team.run_stream("What is 1 + 1?", termination_condition=TextMentionTermination("Correct!"))
stream = team.run_stream("What is 1 + 1?")
async for message in stream:
print(message)


import asyncio

asyncio.run(main())
"""

Expand All @@ -290,6 +301,7 @@ def __init__(
participants: List[ChatAgent],
model_client: ChatCompletionClient,
*,
termination_condition: TerminationCondition | None = None,
selector_prompt: str = """You are in a role play game. The following roles are available:
{roles}.
Read the following conversation. Then select the next role from {participants} to play. Only return the role.
Expand All @@ -301,7 +313,9 @@ def __init__(
allow_repeated_speaker: bool = False,
selector_func: Callable[[Sequence[ChatMessage]], str | None] | None = None,
):
super().__init__(participants, group_chat_manager_class=SelectorGroupChatManager)
super().__init__(
participants, group_chat_manager_class=SelectorGroupChatManager, termination_condition=termination_condition
)
# Validate the participants.
if len(participants) < 2:
raise ValueError("At least two participants are required for SelectorGroupChat.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class Swarm(BaseGroupChat):

Args:
participants (List[ChatAgent]): The agents participating in the group chat. The first agent in the list is the initial speaker.
termination_condition (TerminationCondition, optional): The termination condition for the group chat. Defaults to None.
Without a termination condition, the group chat will run indefinitely.

Examples:

Expand All @@ -81,18 +83,23 @@ async def main() -> None:
"Bob", model_client=model_client, system_message="You are Bob and your birthday is on 1st January."
)

team = Swarm([agent1, agent2])
termination = MaxMessageTermination(3)
team = Swarm([agent1, agent2], termination_condition=termination)

stream = team.run_stream("What is bob's birthday?", termination_condition=MaxMessageTermination(3))
stream = team.run_stream("What is bob's birthday?")
async for message in stream:
print(message)


asyncio.run(main())
"""

def __init__(self, participants: List[ChatAgent]):
super().__init__(participants, group_chat_manager_class=SwarmGroupChatManager)
def __init__(
self, participants: List[ChatAgent], termination_condition: TerminationCondition | None = None
) -> None:
super().__init__(
participants, group_chat_manager_class=SwarmGroupChatManager, termination_condition=termination_condition
)
# The first participant must be able to produce handoff messages.
first_participant = self._participants[0]
if HandoffMessage not in first_participant.produced_message_types:
Expand Down
Loading
Loading