Skip to content

Commit 50e73aa

Browse files
authored
Merge branch 'main' into main
2 parents 7f9956c + 957ec00 commit 50e73aa

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

autogen/agentchat/conversable_agent.py

+85
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,77 @@ def check_termination_and_human_reply(
755755

756756
return False, None
757757

758+
async def a_check_termination_and_human_reply(
759+
self,
760+
messages: Optional[List[Dict]] = None,
761+
sender: Optional[Agent] = None,
762+
config: Optional[Any] = None,
763+
) -> Tuple[bool, Union[str, Dict, None]]:
764+
"""(async) Check if the conversation should be terminated, and if human reply is provided."""
765+
if config is None:
766+
config = self
767+
if messages is None:
768+
messages = self._oai_messages[sender]
769+
message = messages[-1]
770+
reply = ""
771+
no_human_input_msg = ""
772+
if self.human_input_mode == "ALWAYS":
773+
reply = await self.a_get_human_input(
774+
f"Provide feedback to {sender.name}. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: "
775+
)
776+
no_human_input_msg = "NO HUMAN INPUT RECEIVED." if not reply else ""
777+
# if the human input is empty, and the message is a termination message, then we will terminate the conversation
778+
reply = reply if reply or not self._is_termination_msg(message) else "exit"
779+
else:
780+
if self._consecutive_auto_reply_counter[sender] >= self._max_consecutive_auto_reply_dict[sender]:
781+
if self.human_input_mode == "NEVER":
782+
reply = "exit"
783+
else:
784+
# self.human_input_mode == "TERMINATE":
785+
terminate = self._is_termination_msg(message)
786+
reply = await self.a_get_human_input(
787+
f"Please give feedback to {sender.name}. Press enter or type 'exit' to stop the conversation: "
788+
if terminate
789+
else f"Please give feedback to {sender.name}. Press enter to skip and use auto-reply, or type 'exit' to stop the conversation: "
790+
)
791+
no_human_input_msg = "NO HUMAN INPUT RECEIVED." if not reply else ""
792+
# if the human input is empty, and the message is a termination message, then we will terminate the conversation
793+
reply = reply if reply or not terminate else "exit"
794+
elif self._is_termination_msg(message):
795+
if self.human_input_mode == "NEVER":
796+
reply = "exit"
797+
else:
798+
# self.human_input_mode == "TERMINATE":
799+
reply = await self.a_get_human_input(
800+
f"Please give feedback to {sender.name}. Press enter or type 'exit' to stop the conversation: "
801+
)
802+
no_human_input_msg = "NO HUMAN INPUT RECEIVED." if not reply else ""
803+
# if the human input is empty, and the message is a termination message, then we will terminate the conversation
804+
reply = reply or "exit"
805+
806+
# print the no_human_input_msg
807+
if no_human_input_msg:
808+
print(colored(f"\n>>>>>>>> {no_human_input_msg}", "red"), flush=True)
809+
810+
# stop the conversation
811+
if reply == "exit":
812+
# reset the consecutive_auto_reply_counter
813+
self._consecutive_auto_reply_counter[sender] = 0
814+
return True, None
815+
816+
# send the human reply
817+
if reply or self._max_consecutive_auto_reply_dict[sender] == 0:
818+
# reset the consecutive_auto_reply_counter
819+
self._consecutive_auto_reply_counter[sender] = 0
820+
return True, reply
821+
822+
# increment the consecutive_auto_reply_counter
823+
self._consecutive_auto_reply_counter[sender] += 1
824+
if self.human_input_mode != "NEVER":
825+
print(colored("\n>>>>>>>> USING AUTO REPLY...", "red"), flush=True)
826+
827+
return False, None
828+
758829
def generate_reply(
759830
self,
760831
messages: Optional[List[Dict]] = None,
@@ -891,6 +962,20 @@ def get_human_input(self, prompt: str) -> str:
891962
reply = input(prompt)
892963
return reply
893964

965+
async def a_get_human_input(self, prompt: str) -> str:
966+
"""(Async) Get human input.
967+
968+
Override this method to customize the way to get human input.
969+
970+
Args:
971+
prompt (str): prompt for the human input.
972+
973+
Returns:
974+
str: human input.
975+
"""
976+
reply = input(prompt)
977+
return reply
978+
894979
def run_code(self, code, **kwargs):
895980
"""Run the code and return the result.
896981
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import asyncio
2+
import autogen
3+
import pytest
4+
from test_assistant_agent import KEY_LOC, OAI_CONFIG_LIST
5+
6+
7+
@pytest.mark.asyncio
8+
async def test_async_get_human_input():
9+
try:
10+
import openai
11+
except ImportError:
12+
return
13+
config_list = autogen.config_list_from_json(OAI_CONFIG_LIST, KEY_LOC)
14+
15+
# create an AssistantAgent instance named "assistant"
16+
assistant = autogen.AssistantAgent(
17+
name="assistant",
18+
max_consecutive_auto_reply=2,
19+
llm_config={"request_timeout": 600, "seed": 41, "config_list": config_list, "temperature": 0},
20+
)
21+
22+
user_proxy = autogen.UserProxyAgent(name="user", human_input_mode="ALWAYS", code_execution_config=False)
23+
24+
async def custom_a_get_human_input(prompt):
25+
return "This is a test"
26+
27+
user_proxy.a_get_human_input = custom_a_get_human_input
28+
29+
user_proxy.register_reply([autogen.Agent, None], autogen.ConversableAgent.a_check_termination_and_human_reply)
30+
31+
await user_proxy.a_initiate_chat(assistant, clear_history=True, message="Hello.")
32+
33+
34+
if __name__ == "__main__":
35+
test_async_get_human_input()

0 commit comments

Comments
 (0)