CoACT initialize (#292)
This commit is contained in:
18
mm_agents/coact/autogen/agentchat/group/patterns/__init__.py
Normal file
18
mm_agents/coact/autogen/agentchat/group/patterns/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from .auto import AutoPattern
|
||||
from .manual import ManualPattern
|
||||
from .pattern import DefaultPattern
|
||||
from .random import RandomPattern
|
||||
from .round_robin import RoundRobinPattern
|
||||
|
||||
__all__ = [
|
||||
"AutoPattern",
|
||||
"DefaultPattern",
|
||||
"ManualPattern",
|
||||
"RandomPattern",
|
||||
"RoundRobinPattern",
|
||||
]
|
||||
159
mm_agents/coact/autogen/agentchat/group/patterns/auto.py
Normal file
159
mm_agents/coact/autogen/agentchat/group/patterns/auto.py
Normal file
@@ -0,0 +1,159 @@
|
||||
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple, Union
|
||||
|
||||
from ..context_variables import ContextVariables
|
||||
from ..targets.group_manager_target import GroupManagerSelectionMessage, GroupManagerTarget
|
||||
from ..targets.transition_target import TransitionTarget
|
||||
from .pattern import Pattern
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...conversable_agent import ConversableAgent
|
||||
from ...groupchat import GroupChat, GroupChatManager
|
||||
from ..group_tool_executor import GroupToolExecutor
|
||||
|
||||
|
||||
class AutoPattern(Pattern):
|
||||
"""AutoPattern implements a flexible pattern where agents are selected based on their expertise.
|
||||
|
||||
In this pattern, a group manager automatically selects the next agent to speak based on the context
|
||||
of the conversation and agent descriptions. The after_work is always set to "group_manager" as
|
||||
this is the defining characteristic of this pattern.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
initial_agent: "ConversableAgent",
|
||||
agents: list["ConversableAgent"],
|
||||
user_agent: Optional["ConversableAgent"] = None,
|
||||
group_manager_args: Optional[dict[str, Any]] = None,
|
||||
context_variables: Optional[ContextVariables] = None,
|
||||
selection_message: Optional[GroupManagerSelectionMessage] = None,
|
||||
exclude_transit_message: bool = True,
|
||||
summary_method: Optional[Union[str, Callable[..., Any]]] = "last_msg",
|
||||
):
|
||||
"""Initialize the AutoPattern.
|
||||
|
||||
The after_work is always set to group_manager selection, which is the defining
|
||||
characteristic of this pattern. You can customize the selection message used
|
||||
by the group manager when selecting the next agent.
|
||||
|
||||
Args:
|
||||
initial_agent: The first agent to speak in the group chat.
|
||||
agents: List of all agents participating in the chat.
|
||||
user_agent: Optional user proxy agent.
|
||||
group_manager_args: Optional arguments for the GroupChatManager.
|
||||
context_variables: Initial context variables for the chat.
|
||||
selection_message: Custom message to use when the group manager is selecting agents.
|
||||
exclude_transit_message: Whether to exclude transit messages from the conversation.
|
||||
summary_method: Method for summarizing the conversation.
|
||||
"""
|
||||
# Create the group_manager after_work with the provided selection message
|
||||
group_manager_after_work = GroupManagerTarget(selection_message=selection_message)
|
||||
|
||||
super().__init__(
|
||||
initial_agent=initial_agent,
|
||||
agents=agents,
|
||||
user_agent=user_agent,
|
||||
group_manager_args=group_manager_args,
|
||||
context_variables=context_variables,
|
||||
group_after_work=group_manager_after_work,
|
||||
exclude_transit_message=exclude_transit_message,
|
||||
summary_method=summary_method,
|
||||
)
|
||||
|
||||
# Store the selection message for potential use
|
||||
self.selection_message = selection_message
|
||||
|
||||
def prepare_group_chat(
|
||||
self,
|
||||
max_rounds: int,
|
||||
messages: Union[list[dict[str, Any]], str],
|
||||
) -> Tuple[
|
||||
list["ConversableAgent"],
|
||||
list["ConversableAgent"],
|
||||
Optional["ConversableAgent"],
|
||||
ContextVariables,
|
||||
"ConversableAgent",
|
||||
TransitionTarget,
|
||||
"GroupToolExecutor",
|
||||
"GroupChat",
|
||||
"GroupChatManager",
|
||||
list[dict[str, Any]],
|
||||
Any,
|
||||
list[str],
|
||||
list[Any],
|
||||
]:
|
||||
"""Prepare the group chat for organic agent selection.
|
||||
|
||||
Ensures that:
|
||||
1. The group manager has a valid LLM config
|
||||
2. All agents have appropriate descriptions for the group manager to use
|
||||
|
||||
Args:
|
||||
max_rounds: Maximum number of conversation rounds.
|
||||
messages: Initial message(s) to start the conversation.
|
||||
|
||||
Returns:
|
||||
Tuple containing all necessary components for the group chat.
|
||||
"""
|
||||
# Validate that group_manager_args has an LLM config which is required for this pattern
|
||||
if not self.group_manager_args.get("llm_config", False):
|
||||
# Check if any agent has an LLM config we can use
|
||||
has_llm_config = any(getattr(agent, "llm_config", False) for agent in self.agents)
|
||||
|
||||
if not has_llm_config:
|
||||
raise ValueError(
|
||||
"AutoPattern requires the group_manager_args to include an llm_config, "
|
||||
"or at least one agent to have an llm_config"
|
||||
)
|
||||
|
||||
# Check that all agents have descriptions for effective group manager selection
|
||||
for agent in self.agents:
|
||||
if not hasattr(agent, "description") or not agent.description:
|
||||
agent.description = f"Agent {agent.name}"
|
||||
|
||||
# Use the parent class's implementation to prepare the agents and group chat
|
||||
components = super().prepare_group_chat(
|
||||
max_rounds=max_rounds,
|
||||
messages=messages,
|
||||
)
|
||||
|
||||
# Extract the group_after_work and the rest of the components
|
||||
(
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
_,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
) = components
|
||||
|
||||
# Ensure we're using the group_manager after_work
|
||||
group_after_work = self.group_after_work
|
||||
|
||||
# Return all components with our group_after_work
|
||||
return (
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
)
|
||||
176
mm_agents/coact/autogen/agentchat/group/patterns/manual.py
Normal file
176
mm_agents/coact/autogen/agentchat/group/patterns/manual.py
Normal file
@@ -0,0 +1,176 @@
|
||||
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple, Union
|
||||
|
||||
from ..context_variables import ContextVariables
|
||||
from ..group_tool_executor import GroupToolExecutor
|
||||
from ..targets.transition_target import AskUserTarget, TransitionTarget
|
||||
from .pattern import Pattern
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...conversable_agent import ConversableAgent
|
||||
from ...groupchat import GroupChat, GroupChatManager
|
||||
|
||||
|
||||
class ManualPattern(Pattern):
|
||||
"""ManualPattern will ask the user to nominate the next agent to speak at each turn."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
initial_agent: "ConversableAgent",
|
||||
agents: list["ConversableAgent"],
|
||||
user_agent: Optional["ConversableAgent"] = None,
|
||||
group_manager_args: Optional[dict[str, Any]] = None,
|
||||
context_variables: Optional[ContextVariables] = None,
|
||||
exclude_transit_message: bool = True,
|
||||
summary_method: Optional[Union[str, Callable[..., Any]]] = "last_msg",
|
||||
):
|
||||
"""Initialize the ManualPattern.
|
||||
|
||||
The after_work is always set to ask_user, which will prompt the user for the next agent
|
||||
|
||||
Args:
|
||||
initial_agent: The first agent to speak in the group chat.
|
||||
agents: List of all agents participating in the chat.
|
||||
user_agent: Optional user proxy agent.
|
||||
group_manager_args: Optional arguments for the GroupChatManager.
|
||||
context_variables: Initial context variables for the chat.
|
||||
exclude_transit_message: Whether to exclude transit messages from the conversation.
|
||||
summary_method: Method for summarizing the conversation.
|
||||
"""
|
||||
# The group after work will be to ask the user
|
||||
group_after_work = AskUserTarget()
|
||||
|
||||
super().__init__(
|
||||
initial_agent=initial_agent,
|
||||
agents=agents,
|
||||
user_agent=user_agent,
|
||||
group_manager_args=group_manager_args,
|
||||
context_variables=context_variables,
|
||||
group_after_work=group_after_work,
|
||||
exclude_transit_message=exclude_transit_message,
|
||||
summary_method=summary_method,
|
||||
)
|
||||
|
||||
def prepare_group_chat(
|
||||
self,
|
||||
max_rounds: int,
|
||||
messages: Union[list[dict[str, Any]], str],
|
||||
) -> Tuple[
|
||||
list["ConversableAgent"],
|
||||
list["ConversableAgent"],
|
||||
Optional["ConversableAgent"],
|
||||
ContextVariables,
|
||||
"ConversableAgent",
|
||||
TransitionTarget,
|
||||
"GroupToolExecutor",
|
||||
"GroupChat",
|
||||
"GroupChatManager",
|
||||
list[dict[str, Any]],
|
||||
Any,
|
||||
list[str],
|
||||
list[Any],
|
||||
]:
|
||||
"""Prepare the group chat for organic agent selection.
|
||||
|
||||
Ensures that:
|
||||
1. The group manager has a valid LLM config
|
||||
2. All agents have appropriate descriptions for the group manager to use
|
||||
|
||||
Args:
|
||||
max_rounds: Maximum number of conversation rounds.
|
||||
messages: Initial message(s) to start the conversation.
|
||||
|
||||
Returns:
|
||||
Tuple containing all necessary components for the group chat.
|
||||
"""
|
||||
# Use the parent class's implementation to prepare the agents and group chat
|
||||
components = super().prepare_group_chat(
|
||||
max_rounds=max_rounds,
|
||||
messages=messages,
|
||||
)
|
||||
|
||||
# Extract the group_after_work and the rest of the components
|
||||
(
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
_,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
) = components
|
||||
|
||||
# Ensure we're using the group_manager after_work
|
||||
group_after_work = self.group_after_work
|
||||
|
||||
# Set up the allowed speaker transitions to exclude user_agent and GroupToolExecutor
|
||||
self._setup_allowed_transitions(groupchat, user_agent, tool_executor)
|
||||
|
||||
# Return all components with our group_after_work
|
||||
return (
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
)
|
||||
|
||||
def _setup_allowed_transitions(
|
||||
self, groupchat: "GroupChat", user_agent: Optional["ConversableAgent"], tool_executor: "GroupToolExecutor"
|
||||
) -> None:
|
||||
"""Set up the allowed speaker transitions for the group chat so that when a user selects the next agent the tool executor and user agent don't appear as options.
|
||||
|
||||
Creates transitions where:
|
||||
1. Any agent can speak after any other agent, including themselves
|
||||
2. The user_agent and GroupToolExecutor are excluded from transitions
|
||||
|
||||
Args:
|
||||
groupchat: The GroupChat instance to configure
|
||||
user_agent: The user agent to exclude from transitions
|
||||
tool_executor: The GroupToolExecutor to exclude from transitions
|
||||
"""
|
||||
# NOTE: THIS IS NOT WORKING - THE TRANSITIONS ARE NOT BEING KEPT?!
|
||||
"""
|
||||
# Get all agents in the group chat
|
||||
all_agents = groupchat.agents
|
||||
|
||||
# Filter out user_agent and group tool executor
|
||||
eligible_agents = []
|
||||
for agent in all_agents:
|
||||
# Skip user_agent
|
||||
if agent == user_agent:
|
||||
continue
|
||||
|
||||
# Skip GroupToolExecutor
|
||||
if isinstance(agent, GroupToolExecutor):
|
||||
continue
|
||||
|
||||
eligible_agents.append(agent)
|
||||
|
||||
# Create a fully connected graph among eligible agents
|
||||
# Each agent can be followed by any other eligible agent
|
||||
allowed_transitions = {}
|
||||
for agent in eligible_agents:
|
||||
# For each agent, every other eligible agent can follow
|
||||
allowed_transitions[agent] = eligible_agents
|
||||
|
||||
# Set the transitions in the group chat
|
||||
groupchat.allowed_speaker_transitions_dict = allowed_transitions
|
||||
"""
|
||||
294
mm_agents/coact/autogen/agentchat/group/patterns/pattern.py
Normal file
294
mm_agents/coact/autogen/agentchat/group/patterns/pattern.py
Normal file
@@ -0,0 +1,294 @@
|
||||
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Patterns of agent orchestrations
|
||||
# Uses the group chat or the agents' handoffs to create a pattern
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple, Union
|
||||
|
||||
from ..context_variables import ContextVariables
|
||||
from ..group_utils import (
|
||||
create_group_manager,
|
||||
create_group_transition,
|
||||
link_agents_to_group_manager,
|
||||
prepare_group_agents,
|
||||
process_initial_messages,
|
||||
setup_context_variables,
|
||||
)
|
||||
from ..targets.transition_target import TerminateTarget, TransitionTarget
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...agent import Agent
|
||||
from ...conversable_agent import ConversableAgent
|
||||
from ...groupchat import GroupChat, GroupChatManager
|
||||
from ..group_tool_executor import GroupToolExecutor
|
||||
|
||||
|
||||
class Pattern(ABC):
|
||||
"""Base abstract class for all orchestration patterns.
|
||||
|
||||
Patterns provide a reusable way to define how agents interact within a group chat.
|
||||
Each pattern encapsulates the logic for setting up agents, configuring handoffs,
|
||||
and determining the flow of conversation.
|
||||
|
||||
This is an abstract base class and should not be instantiated directly.
|
||||
Use one of the concrete pattern implementations like AutoPattern,
|
||||
RoundRobinPattern, RandomPattern, or ManualPattern.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
initial_agent: "ConversableAgent",
|
||||
agents: list["ConversableAgent"],
|
||||
user_agent: Optional["ConversableAgent"] = None,
|
||||
group_manager_args: Optional[dict[str, Any]] = None,
|
||||
context_variables: Optional[ContextVariables] = None,
|
||||
group_after_work: Optional[TransitionTarget] = None,
|
||||
exclude_transit_message: bool = True,
|
||||
summary_method: Optional[Union[str, Callable[..., Any]]] = "last_msg",
|
||||
):
|
||||
"""Initialize the pattern with the required components.
|
||||
|
||||
Args:
|
||||
initial_agent: The first agent to speak in the group chat.
|
||||
agents: List of all agents participating in the chat.
|
||||
user_agent: Optional user proxy agent.
|
||||
group_manager_args: Optional arguments for the GroupChatManager.
|
||||
context_variables: Initial context variables for the chat.
|
||||
group_after_work: Default after work transition behavior when no specific next agent is determined.
|
||||
exclude_transit_message: Whether to exclude transit messages from the conversation.
|
||||
summary_method: Method for summarizing the conversation.
|
||||
"""
|
||||
self.initial_agent = initial_agent
|
||||
self.agents = agents
|
||||
self.user_agent = user_agent
|
||||
self.group_manager_args = group_manager_args or {}
|
||||
self.context_variables = context_variables or ContextVariables()
|
||||
self.group_after_work = group_after_work if group_after_work is not None else TerminateTarget()
|
||||
self.exclude_transit_message = exclude_transit_message
|
||||
self.summary_method = summary_method
|
||||
|
||||
@abstractmethod
|
||||
def prepare_group_chat(
|
||||
self,
|
||||
max_rounds: int,
|
||||
messages: Union[list[dict[str, Any]], str],
|
||||
) -> Tuple[
|
||||
list["ConversableAgent"],
|
||||
list["ConversableAgent"],
|
||||
Optional["ConversableAgent"],
|
||||
ContextVariables,
|
||||
"ConversableAgent",
|
||||
TransitionTarget,
|
||||
"GroupToolExecutor",
|
||||
"GroupChat",
|
||||
"GroupChatManager",
|
||||
list[dict[str, Any]],
|
||||
"ConversableAgent",
|
||||
list[str],
|
||||
list["Agent"],
|
||||
]:
|
||||
"""Prepare the group chat for orchestration.
|
||||
|
||||
This is the main method called by initiate_group_chat to set up the pattern.
|
||||
Subclasses must implement or extend this method to define pattern-specific behavior.
|
||||
|
||||
Args:
|
||||
max_rounds: Maximum number of conversation rounds.
|
||||
messages: Initial message(s) to start the conversation.
|
||||
|
||||
Returns:
|
||||
Tuple containing:
|
||||
- List of agents involved in the group chat
|
||||
- List of wrapped agents
|
||||
- User agent, if applicable
|
||||
- Context variables for the group chat
|
||||
- Initial agent for the group chat
|
||||
- Group-level after work transition for the group chat
|
||||
- Tool executor for the group chat
|
||||
- GroupChat instance
|
||||
- GroupChatManager instance
|
||||
- Processed messages
|
||||
- Last agent to speak
|
||||
- List of group agent names
|
||||
- List of temporary user agents
|
||||
"""
|
||||
from ...groupchat import GroupChat
|
||||
|
||||
# Prepare the agents using the existing helper function
|
||||
tool_executor, wrapped_agents = prepare_group_agents(
|
||||
self.agents, self.context_variables, self.exclude_transit_message
|
||||
)
|
||||
|
||||
# Process the initial messages BEFORE creating the GroupChat
|
||||
# This will create a temporary user agent if needed
|
||||
processed_messages, last_agent, group_agent_names, temp_user_list = process_initial_messages(
|
||||
messages, self.user_agent, self.agents, wrapped_agents
|
||||
)
|
||||
|
||||
# Create transition function (has enclosed state for initial agent)
|
||||
group_transition = create_group_transition(
|
||||
initial_agent=self.initial_agent,
|
||||
tool_execution=tool_executor,
|
||||
group_agent_names=group_agent_names,
|
||||
user_agent=self.user_agent,
|
||||
group_after_work=self.group_after_work,
|
||||
)
|
||||
|
||||
# Create the group chat - now we use temp_user_list if no user_agent
|
||||
groupchat = GroupChat(
|
||||
agents=[tool_executor]
|
||||
+ self.agents
|
||||
+ wrapped_agents
|
||||
+ ([self.user_agent] if self.user_agent else temp_user_list),
|
||||
messages=[],
|
||||
max_round=max_rounds,
|
||||
speaker_selection_method=group_transition,
|
||||
)
|
||||
|
||||
# Create the group manager
|
||||
manager = create_group_manager(groupchat, self.group_manager_args, self.agents, self.group_after_work)
|
||||
|
||||
# Point all agent's context variables to this function's context_variables
|
||||
setup_context_variables(
|
||||
tool_execution=tool_executor,
|
||||
agents=self.agents,
|
||||
manager=manager,
|
||||
user_agent=self.user_agent,
|
||||
context_variables=self.context_variables,
|
||||
)
|
||||
|
||||
# Link all agents with the GroupChatManager to allow access to the group chat
|
||||
link_agents_to_group_manager(groupchat.agents, manager)
|
||||
|
||||
return (
|
||||
self.agents,
|
||||
wrapped_agents,
|
||||
self.user_agent,
|
||||
self.context_variables,
|
||||
self.initial_agent,
|
||||
self.group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
) # type: ignore[return-value]
|
||||
|
||||
@classmethod
|
||||
def create_default(
|
||||
cls,
|
||||
initial_agent: "ConversableAgent",
|
||||
agents: list["ConversableAgent"],
|
||||
user_agent: Optional["ConversableAgent"] = None,
|
||||
group_manager_args: Optional[dict[str, Any]] = None,
|
||||
context_variables: Optional[ContextVariables] = None,
|
||||
exclude_transit_message: bool = True,
|
||||
summary_method: Optional[Union[str, Callable[..., Any]]] = "last_msg",
|
||||
) -> "DefaultPattern":
|
||||
"""Create a default pattern with minimal configuration.
|
||||
|
||||
This replaces the need for a separate BasePattern class by providing
|
||||
a factory method that creates a simple DefaultPattern instance.
|
||||
|
||||
Args:
|
||||
initial_agent: The first agent to speak in the group chat.
|
||||
agents: List of all agents participating in the chat.
|
||||
user_agent: Optional user proxy agent.
|
||||
group_manager_args: Optional arguments for the GroupChatManager.
|
||||
context_variables: Initial context variables for the chat.
|
||||
exclude_transit_message: Whether to exclude transit messages from the conversation.
|
||||
summary_method: Method for summarizing the conversation.
|
||||
|
||||
Returns:
|
||||
A DefaultPattern instance with basic configuration.
|
||||
"""
|
||||
return DefaultPattern(
|
||||
initial_agent=initial_agent,
|
||||
agents=agents,
|
||||
user_agent=user_agent,
|
||||
group_manager_args=group_manager_args,
|
||||
context_variables=context_variables,
|
||||
exclude_transit_message=exclude_transit_message,
|
||||
summary_method=summary_method,
|
||||
)
|
||||
|
||||
|
||||
class DefaultPattern(Pattern):
|
||||
"""DefaultPattern implements a minimal pattern for simple agent interactions.
|
||||
|
||||
This replaces the previous BasePattern and provides a concrete implementation
|
||||
of the Pattern abstract base class.
|
||||
"""
|
||||
|
||||
def prepare_group_chat(
|
||||
self,
|
||||
max_rounds: int,
|
||||
messages: Union[list[dict[str, Any]], str],
|
||||
) -> Tuple[
|
||||
list["ConversableAgent"],
|
||||
list["ConversableAgent"],
|
||||
Optional["ConversableAgent"],
|
||||
ContextVariables,
|
||||
"ConversableAgent",
|
||||
TransitionTarget,
|
||||
"GroupToolExecutor",
|
||||
"GroupChat",
|
||||
"GroupChatManager",
|
||||
list[dict[str, Any]],
|
||||
Any,
|
||||
list[str],
|
||||
list[Any],
|
||||
]:
|
||||
"""Prepare the group chat with default configuration.
|
||||
|
||||
This implementation calls the parent class method but ensures that
|
||||
the group_after_work in the returned tuple is the pattern's own.
|
||||
|
||||
Args:
|
||||
max_rounds: Maximum number of conversation rounds.
|
||||
messages: Initial message(s) to start the conversation.
|
||||
|
||||
Returns:
|
||||
Tuple containing all necessary components for the group chat.
|
||||
"""
|
||||
# Use the parent class's implementation to prepare the agents and group chat
|
||||
(
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
_, # Ignore the group_after_work from parent
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
) = super().prepare_group_chat(
|
||||
max_rounds=max_rounds,
|
||||
messages=messages,
|
||||
)
|
||||
|
||||
# Return all components with our group_after_work
|
||||
return (
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
self.group_after_work, # Use our own group_after_work
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
)
|
||||
106
mm_agents/coact/autogen/agentchat/group/patterns/random.py
Normal file
106
mm_agents/coact/autogen/agentchat/group/patterns/random.py
Normal file
@@ -0,0 +1,106 @@
|
||||
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional, Tuple, Union
|
||||
|
||||
from ..context_variables import ContextVariables
|
||||
from ..targets.transition_target import RandomAgentTarget, TransitionTarget
|
||||
from .pattern import Pattern
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...conversable_agent import ConversableAgent
|
||||
from ...groupchat import GroupChat, GroupChatManager
|
||||
from ..group_tool_executor import GroupToolExecutor
|
||||
|
||||
|
||||
class RandomPattern(Pattern):
|
||||
"""RandomPattern implements a random agent selection process."""
|
||||
|
||||
def _generate_handoffs(
|
||||
self,
|
||||
initial_agent: "ConversableAgent",
|
||||
agents: list["ConversableAgent"],
|
||||
user_agent: Optional["ConversableAgent"],
|
||||
) -> None:
|
||||
"""Generate handoffs between agents in a random fashion."""
|
||||
agent_list = agents + ([user_agent] if user_agent is not None else [])
|
||||
|
||||
for agent in agent_list:
|
||||
# Get the list of agents except itself
|
||||
other_agents = [a for a in agent_list if a != agent]
|
||||
|
||||
# Create a random after work
|
||||
agent.handoffs.set_after_work(target=RandomAgentTarget(agents=other_agents))
|
||||
|
||||
def prepare_group_chat(
|
||||
self,
|
||||
max_rounds: int,
|
||||
messages: Union[list[dict[str, Any]], str],
|
||||
) -> Tuple[
|
||||
list["ConversableAgent"],
|
||||
list["ConversableAgent"],
|
||||
Optional["ConversableAgent"],
|
||||
ContextVariables,
|
||||
"ConversableAgent",
|
||||
TransitionTarget,
|
||||
"GroupToolExecutor",
|
||||
"GroupChat",
|
||||
"GroupChatManager",
|
||||
list[dict[str, Any]],
|
||||
Any,
|
||||
list[str],
|
||||
list[Any],
|
||||
]:
|
||||
"""Prepare the group chat for organic agent selection.
|
||||
|
||||
Ensures that:
|
||||
1. The group manager has a valid LLM config
|
||||
2. All agents have appropriate descriptions for the group manager to use
|
||||
|
||||
Args:
|
||||
max_rounds: Maximum number of conversation rounds.
|
||||
messages: Initial message(s) to start the conversation.
|
||||
|
||||
Returns:
|
||||
Tuple containing all necessary components for the group chat.
|
||||
"""
|
||||
# Use the parent class's implementation to prepare the agents and group chat
|
||||
(
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
) = super().prepare_group_chat(
|
||||
max_rounds=max_rounds,
|
||||
messages=messages,
|
||||
)
|
||||
|
||||
# Create the random handoffs between agents
|
||||
self._generate_handoffs(initial_agent=initial_agent, agents=agents, user_agent=user_agent)
|
||||
|
||||
# Return all components with our group_after_work
|
||||
return (
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
)
|
||||
117
mm_agents/coact/autogen/agentchat/group/patterns/round_robin.py
Normal file
117
mm_agents/coact/autogen/agentchat/group/patterns/round_robin.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional, Tuple, Union
|
||||
|
||||
from ..context_variables import ContextVariables
|
||||
from ..targets.transition_target import AgentTarget, TransitionTarget
|
||||
from .pattern import Pattern
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...conversable_agent import ConversableAgent
|
||||
from ...groupchat import GroupChat, GroupChatManager
|
||||
from ..group_tool_executor import GroupToolExecutor
|
||||
|
||||
|
||||
class RoundRobinPattern(Pattern):
|
||||
"""RoundRobinPattern implements a round robin with handoffs between agents."""
|
||||
|
||||
def _generate_handoffs(
|
||||
self,
|
||||
initial_agent: "ConversableAgent",
|
||||
agents: list["ConversableAgent"],
|
||||
user_agent: Optional["ConversableAgent"],
|
||||
) -> None:
|
||||
"""Generate handoffs between agents in a round-robin fashion."""
|
||||
# Create a list of the agents and the user_agent but put the initial_agent first
|
||||
agent_list = [initial_agent]
|
||||
|
||||
# Add the rest of the agents, excluding the initial_agent and user_agent
|
||||
for agent in agents:
|
||||
if agent != initial_agent and (user_agent is None or agent != user_agent):
|
||||
agent_list.append(agent)
|
||||
|
||||
# Add the user_agent last if it exists
|
||||
if user_agent is not None:
|
||||
agent_list.append(user_agent)
|
||||
|
||||
# Create handoffs in a round-robin fashion
|
||||
for i, agent in enumerate(agent_list):
|
||||
# Last agent hands off to the first agent
|
||||
# Otherwise agent hands off to the next one
|
||||
handoff_target = agent_list[0] if i == len(agent_list) - 1 else agent_list[i + 1]
|
||||
|
||||
agent.handoffs.set_after_work(target=AgentTarget(agent=handoff_target))
|
||||
|
||||
def prepare_group_chat(
|
||||
self,
|
||||
max_rounds: int,
|
||||
messages: Union[list[dict[str, Any]], str],
|
||||
) -> Tuple[
|
||||
list["ConversableAgent"],
|
||||
list["ConversableAgent"],
|
||||
Optional["ConversableAgent"],
|
||||
ContextVariables,
|
||||
"ConversableAgent",
|
||||
TransitionTarget,
|
||||
"GroupToolExecutor",
|
||||
"GroupChat",
|
||||
"GroupChatManager",
|
||||
list[dict[str, Any]],
|
||||
Any,
|
||||
list[str],
|
||||
list[Any],
|
||||
]:
|
||||
"""Prepare the group chat for organic agent selection.
|
||||
|
||||
Ensures that:
|
||||
1. The group manager has a valid LLM config
|
||||
2. All agents have appropriate descriptions for the group manager to use
|
||||
|
||||
Args:
|
||||
max_rounds: Maximum number of conversation rounds.
|
||||
messages: Initial message(s) to start the conversation.
|
||||
|
||||
Returns:
|
||||
Tuple containing all necessary components for the group chat.
|
||||
"""
|
||||
# Use the parent class's implementation to prepare the agents and group chat
|
||||
(
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
) = super().prepare_group_chat(
|
||||
max_rounds=max_rounds,
|
||||
messages=messages,
|
||||
)
|
||||
|
||||
# Create the handoffs between agents
|
||||
self._generate_handoffs(initial_agent=initial_agent, agents=agents, user_agent=user_agent)
|
||||
|
||||
# Return all components with our group_after_work
|
||||
return (
|
||||
agents,
|
||||
wrapped_agents,
|
||||
user_agent,
|
||||
context_variables,
|
||||
initial_agent,
|
||||
group_after_work,
|
||||
tool_executor,
|
||||
groupchat,
|
||||
manager,
|
||||
processed_messages,
|
||||
last_agent,
|
||||
group_agent_names,
|
||||
temp_user_list,
|
||||
)
|
||||
Reference in New Issue
Block a user