You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_userproxy_agent.py 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import asyncio
  2. from typing import Optional, Sequence
  3. import pytest
  4. from autogen_agentchat.agents import UserProxyAgent
  5. from autogen_agentchat.base import Response
  6. from autogen_agentchat.messages import ChatMessage, HandoffMessage, TextMessage
  7. from autogen_core import CancellationToken
  8. @pytest.mark.asyncio
  9. async def test_basic_input() -> None:
  10. """Test basic message handling with custom input"""
  11. def custom_input(prompt: str) -> str:
  12. return "The height of the eiffel tower is 324 meters. Aloha!"
  13. agent = UserProxyAgent(name="test_user", input_func=custom_input)
  14. messages = [TextMessage(content="What is the height of the eiffel tower?", source="assistant")]
  15. response = await agent.on_messages(messages, CancellationToken())
  16. assert isinstance(response, Response)
  17. assert isinstance(response.chat_message, TextMessage)
  18. assert response.chat_message.content == "The height of the eiffel tower is 324 meters. Aloha!"
  19. assert response.chat_message.source == "test_user"
  20. @pytest.mark.asyncio
  21. async def test_async_input() -> None:
  22. """Test handling of async input function"""
  23. async def async_input(prompt: str, token: Optional[CancellationToken] = None) -> str:
  24. await asyncio.sleep(0.1)
  25. return "async response"
  26. agent = UserProxyAgent(name="test_user", input_func=async_input)
  27. messages = [TextMessage(content="test prompt", source="assistant")]
  28. response = await agent.on_messages(messages, CancellationToken())
  29. assert isinstance(response.chat_message, TextMessage)
  30. assert response.chat_message.content == "async response"
  31. assert response.chat_message.source == "test_user"
  32. @pytest.mark.asyncio
  33. async def test_handoff_handling() -> None:
  34. """Test handling of handoff messages"""
  35. def custom_input(prompt: str) -> str:
  36. return "handoff response"
  37. agent = UserProxyAgent(name="test_user", input_func=custom_input)
  38. messages: Sequence[ChatMessage] = [
  39. TextMessage(content="Initial message", source="assistant"),
  40. HandoffMessage(content="Handing off to user for confirmation", source="assistant", target="test_user"),
  41. ]
  42. response = await agent.on_messages(messages, CancellationToken())
  43. assert isinstance(response.chat_message, HandoffMessage)
  44. assert response.chat_message.content == "handoff response"
  45. assert response.chat_message.source == "test_user"
  46. assert response.chat_message.target == "assistant"
  47. # The latest message if is a handoff message, it must be addressed to this agent.
  48. messages = [
  49. TextMessage(content="Initial message", source="assistant"),
  50. HandoffMessage(content="Handing off to user for confirmation", source="assistant", target="other_agent"),
  51. ]
  52. with pytest.raises(RuntimeError):
  53. await agent.on_messages(messages, CancellationToken())
  54. # No handoff message if the latest message is not a handoff message addressed to this agent.
  55. messages = [
  56. TextMessage(content="Initial message", source="assistant"),
  57. HandoffMessage(content="Handing off to other agent", source="assistant", target="other_agent"),
  58. TextMessage(content="Another message", source="other_agent"),
  59. ]
  60. response = await agent.on_messages(messages, CancellationToken())
  61. assert isinstance(response.chat_message, TextMessage)
  62. @pytest.mark.asyncio
  63. async def test_cancellation() -> None:
  64. """Test cancellation during message handling"""
  65. async def cancellable_input(prompt: str, token: Optional[CancellationToken] = None) -> str:
  66. await asyncio.sleep(0.1)
  67. if token and token.is_cancelled():
  68. raise asyncio.CancelledError()
  69. return "cancellable response"
  70. agent = UserProxyAgent(name="test_user", input_func=cancellable_input)
  71. messages = [TextMessage(content="test prompt", source="assistant")]
  72. token = CancellationToken()
  73. async def cancel_after_delay() -> None:
  74. await asyncio.sleep(0.05)
  75. token.cancel()
  76. with pytest.raises(asyncio.CancelledError):
  77. await asyncio.gather(agent.on_messages(messages, token), cancel_after_delay())
  78. @pytest.mark.asyncio
  79. async def test_error_handling() -> None:
  80. """Test error handling with problematic input function"""
  81. def failing_input(_: str) -> str:
  82. raise ValueError("Input function failed")
  83. agent = UserProxyAgent(name="test_user", input_func=failing_input)
  84. messages = [TextMessage(content="test prompt", source="assistant")]
  85. with pytest.raises(RuntimeError) as exc_info:
  86. await agent.on_messages(messages, CancellationToken())
  87. assert "Failed to get user input" in str(exc_info.value)