From ead9ec9e8b82916e7ca9aed0e9e5c6fb07099a38 Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Mon, 29 Jul 2024 19:08:20 +0800 Subject: [PATCH 1/7] feat: add is_silent param --- autogen/agentchat/conversable_agent.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/autogen/agentchat/conversable_agent.py b/autogen/agentchat/conversable_agent.py index 674c8b9248d7..1a2ac8653f37 100644 --- a/autogen/agentchat/conversable_agent.py +++ b/autogen/agentchat/conversable_agent.py @@ -78,6 +78,7 @@ def __init__( default_auto_reply: Union[str, Dict] = "", description: Optional[str] = None, chat_messages: Optional[Dict[Agent, List[Dict]]] = None, + is_silent: Optional[bool] = None, ): """ Args: @@ -126,6 +127,8 @@ def __init__( chat_messages (dict or None): the previous chat messages that this agent had in the past with other agents. Can be used to give the agent a memory by providing the chat history. This will allow the agent to resume previous had conversations. Defaults to an empty chat history. + is_silent (bool or None): (Experimental) whether to print the message sent. If None, will use the value of + is_silent in each function. """ # we change code_execution_config below and we have to make sure we don't change the input # in case of UserProxyAgent, without this we could even change the default value {} @@ -147,6 +150,7 @@ def __init__( if is_termination_msg is not None else (lambda x: content_str(x.get("content")) == "TERMINATE") ) + self.is_silent = is_silent # Take a copy to avoid modifying the given dict if isinstance(llm_config, dict): try: @@ -263,6 +267,9 @@ def _validate_llm_config(self, llm_config): ) self.client = None if self.llm_config is False else OpenAIWrapper(**self.llm_config) + def _is_silent(self, silent: Optional[bool] = False) -> bool: + return self.is_silent if self.is_silent is not None else silent + @property def name(self) -> str: """Get the name of the agent.""" @@ -604,6 +611,8 @@ def _process_message_before_send( self, message: Union[Dict, str], recipient: Agent, silent: bool ) -> Union[Dict, str]: """Process the message before sending it to the recipient.""" + silent = self._is_silent(silent) + hook_list = self.hook_lists["process_message_before_send"] for hook in hook_list: message = hook(sender=self, message=message, recipient=recipient, silent=silent) @@ -648,6 +657,8 @@ def send( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ + silent = self._is_silent(silent) + message = self._process_message_before_send(message, recipient, silent) # When the agent composes and sends the message, the role of the message is "assistant" # unless it's "function". @@ -698,6 +709,8 @@ async def a_send( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ + silent = self._is_silent(silent) + message = self._process_message_before_send(message, recipient, silent) # When the agent composes and sends the message, the role of the message is "assistant" # unless it's "function". @@ -771,6 +784,8 @@ def _print_received_message(self, message: Union[Dict, str], sender: Agent): iostream.print("\n", "-" * 80, flush=True, sep="") def _process_received_message(self, message: Union[Dict, str], sender: Agent, silent: bool): + silent = self._is_silent(silent) + # When the agent receives a message, the role of the message is "user". (If 'role' exists and is 'function', it will remain unchanged.) valid = self._append_oai_message(message, "user", sender) if logging_enabled(): @@ -813,6 +828,8 @@ def receive( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ + silent = self._is_silent(silent) + self._process_received_message(message, sender, silent) if request_reply is False or request_reply is None and self.reply_at_receive[sender] is False: return @@ -850,6 +867,8 @@ async def a_receive( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ + silent = self._is_silent(silent) + self._process_received_message(message, sender, silent) if request_reply is False or request_reply is None and self.reply_at_receive[sender] is False: return @@ -990,6 +1009,7 @@ def my_message(sender: ConversableAgent, recipient: ConversableAgent, context: d Returns: ChatResult: an ChatResult object. """ + silent = self._is_silent(silent) _chat_info = locals().copy() _chat_info["sender"] = self consolidate_chat_info(_chat_info, uniform_sender=self) @@ -1057,6 +1077,7 @@ async def a_initiate_chat( Returns: ChatResult: an ChatResult object. """ + silent = self._is_silent(silent) _chat_info = locals().copy() _chat_info["sender"] = self consolidate_chat_info(_chat_info, uniform_sender=self) From 199f8245078c16b354fc7e4211a053b271968780 Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Tue, 30 Jul 2024 13:39:44 +0800 Subject: [PATCH 2/7] modify param name --- autogen/agentchat/conversable_agent.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autogen/agentchat/conversable_agent.py b/autogen/agentchat/conversable_agent.py index 1a2ac8653f37..56a091067a19 100644 --- a/autogen/agentchat/conversable_agent.py +++ b/autogen/agentchat/conversable_agent.py @@ -78,7 +78,7 @@ def __init__( default_auto_reply: Union[str, Dict] = "", description: Optional[str] = None, chat_messages: Optional[Dict[Agent, List[Dict]]] = None, - is_silent: Optional[bool] = None, + silent: Optional[bool] = None, ): """ Args: @@ -127,7 +127,7 @@ def __init__( chat_messages (dict or None): the previous chat messages that this agent had in the past with other agents. Can be used to give the agent a memory by providing the chat history. This will allow the agent to resume previous had conversations. Defaults to an empty chat history. - is_silent (bool or None): (Experimental) whether to print the message sent. If None, will use the value of + silent (bool or None): (Experimental) whether to print the message sent. If None, will use the value of is_silent in each function. """ # we change code_execution_config below and we have to make sure we don't change the input @@ -150,7 +150,7 @@ def __init__( if is_termination_msg is not None else (lambda x: content_str(x.get("content")) == "TERMINATE") ) - self.is_silent = is_silent + self.silent = silent # Take a copy to avoid modifying the given dict if isinstance(llm_config, dict): try: @@ -268,7 +268,7 @@ def _validate_llm_config(self, llm_config): self.client = None if self.llm_config is False else OpenAIWrapper(**self.llm_config) def _is_silent(self, silent: Optional[bool] = False) -> bool: - return self.is_silent if self.is_silent is not None else silent + return self.silent if self.silent is not None else silent @property def name(self) -> str: From 2dbcd16f46726668eace4a12a84a4f0f419e525c Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Tue, 30 Jul 2024 14:31:59 +0800 Subject: [PATCH 3/7] param doc --- autogen/agentchat/conversable_agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen/agentchat/conversable_agent.py b/autogen/agentchat/conversable_agent.py index 56a091067a19..4f44c4413c29 100644 --- a/autogen/agentchat/conversable_agent.py +++ b/autogen/agentchat/conversable_agent.py @@ -128,7 +128,7 @@ def __init__( Can be used to give the agent a memory by providing the chat history. This will allow the agent to resume previous had conversations. Defaults to an empty chat history. silent (bool or None): (Experimental) whether to print the message sent. If None, will use the value of - is_silent in each function. + silent in each function. """ # we change code_execution_config below and we have to make sure we don't change the input # in case of UserProxyAgent, without this we could even change the default value {} From 1075b9eaefa072c8dfdefa64128e6a08fe74d032 Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Tue, 30 Jul 2024 22:44:12 +0800 Subject: [PATCH 4/7] fix: silent only overwrite agent own --- autogen/agentchat/conversable_agent.py | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/autogen/agentchat/conversable_agent.py b/autogen/agentchat/conversable_agent.py index 4f44c4413c29..fc22d83e3168 100644 --- a/autogen/agentchat/conversable_agent.py +++ b/autogen/agentchat/conversable_agent.py @@ -611,11 +611,9 @@ def _process_message_before_send( self, message: Union[Dict, str], recipient: Agent, silent: bool ) -> Union[Dict, str]: """Process the message before sending it to the recipient.""" - silent = self._is_silent(silent) - hook_list = self.hook_lists["process_message_before_send"] for hook in hook_list: - message = hook(sender=self, message=message, recipient=recipient, silent=silent) + message = hook(sender=self, message=message, recipient=recipient, silent=self._is_silent(silent)) return message def send( @@ -657,9 +655,7 @@ def send( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - silent = self._is_silent(silent) - - message = self._process_message_before_send(message, recipient, silent) + message = self._process_message_before_send(message, recipient, self._is_silent(silent)) # When the agent composes and sends the message, the role of the message is "assistant" # unless it's "function". valid = self._append_oai_message(message, "assistant", recipient) @@ -709,9 +705,7 @@ async def a_send( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - silent = self._is_silent(silent) - - message = self._process_message_before_send(message, recipient, silent) + message = self._process_message_before_send(message, recipient, self._is_silent(silent)) # When the agent composes and sends the message, the role of the message is "assistant" # unless it's "function". valid = self._append_oai_message(message, "assistant", recipient) @@ -784,8 +778,6 @@ def _print_received_message(self, message: Union[Dict, str], sender: Agent): iostream.print("\n", "-" * 80, flush=True, sep="") def _process_received_message(self, message: Union[Dict, str], sender: Agent, silent: bool): - silent = self._is_silent(silent) - # When the agent receives a message, the role of the message is "user". (If 'role' exists and is 'function', it will remain unchanged.) valid = self._append_oai_message(message, "user", sender) if logging_enabled(): @@ -795,7 +787,7 @@ def _process_received_message(self, message: Union[Dict, str], sender: Agent, si raise ValueError( "Received message can't be converted into a valid ChatCompletion message. Either content or function_call must be provided." ) - if not silent: + if not self._is_silent(silent): self._print_received_message(message, sender) def receive( @@ -828,9 +820,7 @@ def receive( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - silent = self._is_silent(silent) - - self._process_received_message(message, sender, silent) + self._process_received_message(message, sender, self._is_silent(silent)) if request_reply is False or request_reply is None and self.reply_at_receive[sender] is False: return reply = self.generate_reply(messages=self.chat_messages[sender], sender=sender) @@ -867,9 +857,7 @@ async def a_receive( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - silent = self._is_silent(silent) - - self._process_received_message(message, sender, silent) + self._process_received_message(message, sender, self._is_silent(silent)) if request_reply is False or request_reply is None and self.reply_at_receive[sender] is False: return reply = await self.a_generate_reply(sender=sender) @@ -1009,7 +997,6 @@ def my_message(sender: ConversableAgent, recipient: ConversableAgent, context: d Returns: ChatResult: an ChatResult object. """ - silent = self._is_silent(silent) _chat_info = locals().copy() _chat_info["sender"] = self consolidate_chat_info(_chat_info, uniform_sender=self) @@ -1077,7 +1064,6 @@ async def a_initiate_chat( Returns: ChatResult: an ChatResult object. """ - silent = self._is_silent(silent) _chat_info = locals().copy() _chat_info["sender"] = self consolidate_chat_info(_chat_info, uniform_sender=self) From b70b7367ab2736735e3c8dae48c078e36da9cfdd Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Wed, 31 Jul 2024 09:22:34 +0800 Subject: [PATCH 5/7] fix: change _is_silent to static method and receive verbose print --- autogen/agentchat/conversable_agent.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/autogen/agentchat/conversable_agent.py b/autogen/agentchat/conversable_agent.py index 8ac77fc58061..59bdb0c9e2cd 100644 --- a/autogen/agentchat/conversable_agent.py +++ b/autogen/agentchat/conversable_agent.py @@ -267,8 +267,9 @@ def _validate_llm_config(self, llm_config): ) self.client = None if self.llm_config is False else OpenAIWrapper(**self.llm_config) - def _is_silent(self, silent: Optional[bool] = False) -> bool: - return self.silent if self.silent is not None else silent + @staticmethod + def _is_silent(agent: Agent, silent: Optional[bool] = False) -> bool: + return agent.silent if agent.silent is not None else silent @property def name(self) -> str: @@ -613,7 +614,9 @@ def _process_message_before_send( """Process the message before sending it to the recipient.""" hook_list = self.hook_lists["process_message_before_send"] for hook in hook_list: - message = hook(sender=self, message=message, recipient=recipient, silent=self._is_silent(silent)) + message = hook( + sender=self, message=message, recipient=recipient, silent=ConversableAgent._is_silent(self, silent) + ) return message def send( @@ -655,7 +658,7 @@ def send( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - message = self._process_message_before_send(message, recipient, self._is_silent(silent)) + message = self._process_message_before_send(message, recipient, ConversableAgent._is_silent(self, silent)) # When the agent composes and sends the message, the role of the message is "assistant" # unless it's "function". valid = self._append_oai_message(message, "assistant", recipient) @@ -705,7 +708,7 @@ async def a_send( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - message = self._process_message_before_send(message, recipient, self._is_silent(silent)) + message = self._process_message_before_send(message, recipient, ConversableAgent._is_silent(self, silent)) # When the agent composes and sends the message, the role of the message is "assistant" # unless it's "function". valid = self._append_oai_message(message, "assistant", recipient) @@ -787,7 +790,8 @@ def _process_received_message(self, message: Union[Dict, str], sender: Agent, si raise ValueError( "Received message can't be converted into a valid ChatCompletion message. Either content or function_call must be provided." ) - if not self._is_silent(silent): + + if not ConversableAgent._is_silent(sender, silent): self._print_received_message(message, sender) def receive( @@ -820,7 +824,7 @@ def receive( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - self._process_received_message(message, sender, self._is_silent(silent)) + self._process_received_message(message, sender, silent) if request_reply is False or request_reply is None and self.reply_at_receive[sender] is False: return reply = self.generate_reply(messages=self.chat_messages[sender], sender=sender) @@ -857,7 +861,7 @@ async def a_receive( Raises: ValueError: if the message can't be converted into a valid ChatCompletion message. """ - self._process_received_message(message, sender, self._is_silent(silent)) + self._process_received_message(message, sender, silent) if request_reply is False or request_reply is None and self.reply_at_receive[sender] is False: return reply = await self.a_generate_reply(sender=sender) From a05dc6ee58f70e2d610ceb4df41c8247b2fc767d Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Wed, 31 Jul 2024 10:11:55 +0800 Subject: [PATCH 6/7] fix test failure --- test/agentchat/test_tool_calls.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/agentchat/test_tool_calls.py b/test/agentchat/test_tool_calls.py index 6a12d2d96edf..e7d45c5918d9 100755 --- a/test/agentchat/test_tool_calls.py +++ b/test/agentchat/test_tool_calls.py @@ -208,6 +208,7 @@ class FakeAgent(autogen.Agent): def __init__(self, name): self._name = name self.received = [] + self.silent = False @property def name(self): @@ -303,6 +304,7 @@ class FakeAgent(autogen.Agent): def __init__(self, name): self._name = name self.received = [] + self.silent = False @property def name(self): From 04efcc387777eeb6fb87a219af9499188a4ea171 Mon Sep 17 00:00:00 2001 From: gongwn1 Date: Thu, 1 Aug 2024 18:16:39 +0800 Subject: [PATCH 7/7] add kwargs for ConversableAgent subclass --- autogen/agentchat/contrib/society_of_mind_agent.py | 2 ++ autogen/agentchat/contrib/web_surfer.py | 2 ++ autogen/agentchat/user_proxy_agent.py | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/autogen/agentchat/contrib/society_of_mind_agent.py b/autogen/agentchat/contrib/society_of_mind_agent.py index 2f6be5088a4d..e76768187c9f 100644 --- a/autogen/agentchat/contrib/society_of_mind_agent.py +++ b/autogen/agentchat/contrib/society_of_mind_agent.py @@ -39,6 +39,7 @@ def __init__( code_execution_config: Union[Dict, Literal[False]] = False, llm_config: Optional[Union[Dict, Literal[False]]] = False, default_auto_reply: Optional[Union[str, Dict, None]] = "", + **kwargs, ): super().__init__( name=name, @@ -50,6 +51,7 @@ def __init__( code_execution_config=code_execution_config, llm_config=llm_config, default_auto_reply=default_auto_reply, + **kwargs, ) self.update_chat_manager(chat_manager) diff --git a/autogen/agentchat/contrib/web_surfer.py b/autogen/agentchat/contrib/web_surfer.py index af07be6d3432..f74915a9b403 100644 --- a/autogen/agentchat/contrib/web_surfer.py +++ b/autogen/agentchat/contrib/web_surfer.py @@ -41,6 +41,7 @@ def __init__( summarizer_llm_config: Optional[Union[Dict, Literal[False]]] = None, default_auto_reply: Optional[Union[str, Dict, None]] = "", browser_config: Optional[Union[Dict, None]] = None, + **kwargs, ): super().__init__( name=name, @@ -53,6 +54,7 @@ def __init__( code_execution_config=code_execution_config, llm_config=llm_config, default_auto_reply=default_auto_reply, + **kwargs, ) self._create_summarizer_client(summarizer_llm_config, llm_config) diff --git a/autogen/agentchat/user_proxy_agent.py b/autogen/agentchat/user_proxy_agent.py index a80296a8355a..d50e4d8b89c5 100644 --- a/autogen/agentchat/user_proxy_agent.py +++ b/autogen/agentchat/user_proxy_agent.py @@ -35,6 +35,7 @@ def __init__( llm_config: Optional[Union[Dict, Literal[False]]] = False, system_message: Optional[Union[str, List]] = "", description: Optional[str] = None, + **kwargs, ): """ Args: @@ -79,6 +80,8 @@ def __init__( Only used when llm_config is not False. Use it to reprogram the agent. description (str): a short description of the agent. This description is used by other agents (e.g. the GroupChatManager) to decide when to call upon this agent. (Default: system_message) + **kwargs (dict): Please refer to other kwargs in + [ConversableAgent](conversable_agent#__init__). """ super().__init__( name=name, @@ -93,6 +96,7 @@ def __init__( description=( description if description is not None else self.DEFAULT_USER_PROXY_AGENT_DESCRIPTIONS[human_input_mode] ), + **kwargs, ) if logging_enabled():