|
- import pytest
- from autogen.agentchat import ConversableAgent
-
-
- @pytest.fixture
- def conversable_agent():
- return ConversableAgent(
- "conversable_agent_0",
- max_consecutive_auto_reply=10,
- code_execution_config=False,
- llm_config=False,
- human_input_mode="NEVER",
- )
-
-
- def test_trigger():
- agent = ConversableAgent("a0", max_consecutive_auto_reply=0, llm_config=False, human_input_mode="NEVER")
- agent1 = ConversableAgent("a1", max_consecutive_auto_reply=0, human_input_mode="NEVER")
- agent.register_reply(agent1, lambda recipient, messages, sender, config: (True, "hello"))
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello"
- agent.register_reply("a1", lambda recipient, messages, sender, config: (True, "hello a1"))
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello a1"
- agent.register_reply(
- ConversableAgent, lambda recipient, messages, sender, config: (True, "hello conversable agent")
- )
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello conversable agent"
- agent.register_reply(
- lambda sender: sender.name.startswith("a"), lambda recipient, messages, sender, config: (True, "hello a")
- )
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello a"
- agent.register_reply(
- lambda sender: sender.name.startswith("b"), lambda recipient, messages, sender, config: (True, "hello b")
- )
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello a"
- agent.register_reply(
- ["agent2", agent1], lambda recipient, messages, sender, config: (True, "hello agent2 or agent1")
- )
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello agent2 or agent1"
- agent.register_reply(
- ["agent2", "agent3"], lambda recipient, messages, sender, config: (True, "hello agent2 or agent3")
- )
- agent1.initiate_chat(agent, message="hi")
- assert agent1.last_message(agent)["content"] == "hello agent2 or agent1"
- pytest.raises(ValueError, agent.register_reply, 1, lambda recipient, messages, sender, config: (True, "hi"))
- pytest.raises(ValueError, agent._match_trigger, 1, agent1)
-
-
- def test_context():
- agent = ConversableAgent("a0", max_consecutive_auto_reply=0, llm_config=False, human_input_mode="NEVER")
- agent1 = ConversableAgent("a1", max_consecutive_auto_reply=0, human_input_mode="NEVER")
- agent1.send(
- {
- "content": "hello {name}",
- "context": {
- "name": "there",
- },
- },
- agent,
- )
- # expect hello {name} to be printed
- agent1.send(
- {
- "content": lambda context: f"hello {context['name']}",
- "context": {
- "name": "there",
- },
- },
- agent,
- )
- # expect hello there to be printed
- agent.llm_config = {"allow_format_str_template": True}
- agent1.send(
- {
- "content": "hello {name}",
- "context": {
- "name": "there",
- },
- },
- agent,
- )
- # expect hello there to be printed
-
-
- def test_generate_code_execution_reply():
- agent = ConversableAgent(
- "a0", max_consecutive_auto_reply=10, code_execution_config=False, llm_config=False, human_input_mode="NEVER"
- )
-
- dummy_messages = [
- {
- "content": "no code block",
- "role": "user",
- },
- {
- "content": "no code block",
- "role": "user",
- },
- ]
-
- code_message = {
- "content": '```python\nprint("hello world")\n```',
- "role": "user",
- }
-
- # scenario 1: if code_execution_config is not provided, the code execution should return false, none
- assert agent.generate_code_execution_reply(dummy_messages, config=False) == (False, None)
-
- # scenario 2: if code_execution_config is provided, but no code block is found, the code execution should return false, none
- assert agent.generate_code_execution_reply(dummy_messages, config={}) == (False, None)
-
- # scenario 3: if code_execution_config is provided, and code block is found, but it's not within the range of last_n_messages, the code execution should return false, none
- assert agent.generate_code_execution_reply([code_message] + dummy_messages, config={"last_n_messages": 1}) == (
- False,
- None,
- )
-
- # scenario 4: if code_execution_config is provided, and code block is found, and it's within the range of last_n_messages, the code execution should return true, code block
- agent._code_execution_config = {"last_n_messages": 3, "use_docker": False}
- assert agent.generate_code_execution_reply([code_message] + dummy_messages) == (
- True,
- "exitcode: 0 (execution succeeded)\nCode output: \nhello world\n",
- )
- assert agent._code_execution_config["last_n_messages"] == 3
-
-
- def test_max_consecutive_auto_reply():
- agent = ConversableAgent("a0", max_consecutive_auto_reply=2, llm_config=False, human_input_mode="NEVER")
- agent1 = ConversableAgent("a1", max_consecutive_auto_reply=0, human_input_mode="NEVER")
- assert agent.max_consecutive_auto_reply() == agent.max_consecutive_auto_reply(agent1) == 2
- agent.update_max_consecutive_auto_reply(1)
- assert agent.max_consecutive_auto_reply() == agent.max_consecutive_auto_reply(agent1) == 1
-
- agent1.initiate_chat(agent, message="hello")
- assert agent._consecutive_auto_reply_counter[agent1] == 1
- agent1.initiate_chat(agent, message="hello again")
- # with auto reply because the counter is reset
- assert agent1.last_message(agent)["role"] == "user"
- assert len(agent1.chat_messages[agent]) == 2
- assert len(agent.chat_messages[agent1]) == 2
-
- assert agent._consecutive_auto_reply_counter[agent1] == 1
- agent1.send(message="bye", recipient=agent)
- # no auto reply
- assert agent1.last_message(agent)["role"] == "assistant"
-
- agent1.initiate_chat(agent, clear_history=False, message="hi")
- assert len(agent1.chat_messages[agent]) > 2
- assert len(agent.chat_messages[agent1]) > 2
-
- assert agent1.reply_at_receive[agent] == agent.reply_at_receive[agent1] is True
- agent1.stop_reply_at_receive(agent)
- assert agent1.reply_at_receive[agent] is False and agent.reply_at_receive[agent1] is True
-
-
- def test_conversable_agent():
- dummy_agent_1 = ConversableAgent(name="dummy_agent_1", human_input_mode="ALWAYS")
- dummy_agent_2 = ConversableAgent(name="dummy_agent_2", human_input_mode="TERMINATE")
-
- # monkeypatch.setattr(sys, "stdin", StringIO("exit"))
- dummy_agent_1.receive("hello", dummy_agent_2) # receive a str
- # monkeypatch.setattr(sys, "stdin", StringIO("TERMINATE\n\n"))
- dummy_agent_1.receive(
- {
- "content": "hello {name}",
- "context": {
- "name": "dummy_agent_2",
- },
- },
- dummy_agent_2,
- ) # receive a dict
- assert "context" in dummy_agent_1.chat_messages[dummy_agent_2][-1]
- # receive dict without openai fields to be printed, such as "content", 'function_call'. There should be no error raised.
- pre_len = len(dummy_agent_1.chat_messages[dummy_agent_2])
- with pytest.raises(ValueError):
- dummy_agent_1.receive({"message": "hello"}, dummy_agent_2)
- assert pre_len == len(
- dummy_agent_1.chat_messages[dummy_agent_2]
- ), "When the message is not an valid openai message, it should not be appended to the oai conversation."
-
- # monkeypatch.setattr(sys, "stdin", StringIO("exit"))
- dummy_agent_1.send("TERMINATE", dummy_agent_2) # send a str
- # monkeypatch.setattr(sys, "stdin", StringIO("exit"))
- dummy_agent_1.send(
- {
- "content": "TERMINATE",
- },
- dummy_agent_2,
- ) # send a dict
-
- # send dict with no openai fields
- pre_len = len(dummy_agent_1.chat_messages[dummy_agent_2])
- with pytest.raises(ValueError):
- dummy_agent_1.send({"message": "hello"}, dummy_agent_2)
-
- assert pre_len == len(
- dummy_agent_1.chat_messages[dummy_agent_2]
- ), "When the message is not a valid openai message, it should not be appended to the oai conversation."
-
- # update system message
- dummy_agent_1.update_system_message("new system message")
- assert dummy_agent_1.system_message == "new system message"
-
-
- def test_generate_reply():
- def add_num(num_to_be_added):
- given_num = 10
- return num_to_be_added + given_num
-
- dummy_agent_2 = ConversableAgent(name="user_proxy", human_input_mode="TERMINATE", function_map={"add_num": add_num})
- messsages = [{"function_call": {"name": "add_num", "arguments": '{ "num_to_be_added": 5 }'}, "role": "assistant"}]
-
- # when sender is None, messages is provided
- assert (
- dummy_agent_2.generate_reply(messages=messsages, sender=None)["content"] == "15"
- ), "generate_reply not working when sender is None"
-
- # when sender is provided, messages is None
- dummy_agent_1 = ConversableAgent(name="dummy_agent_1", human_input_mode="ALWAYS")
- dummy_agent_2._oai_messages[dummy_agent_1] = messsages
- assert (
- dummy_agent_2.generate_reply(messages=None, sender=dummy_agent_1)["content"] == "15"
- ), "generate_reply not working when messages is None"
-
-
- def test_generate_reply_raises_on_messages_and_sender_none(conversable_agent):
- with pytest.raises(AssertionError):
- conversable_agent.generate_reply(messages=None, sender=None)
-
-
- @pytest.mark.asyncio
- async def test_a_generate_reply_raises_on_messages_and_sender_none(conversable_agent):
- with pytest.raises(AssertionError):
- await conversable_agent.a_generate_reply(messages=None, sender=None)
-
-
- if __name__ == "__main__":
- test_trigger()
- # test_context()
- # test_max_consecutive_auto_reply()
- # test_conversable_agent(pytest.monkeypatch)
|