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.

component_test_service.py 7.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # api/validator/test_service.py
  2. import asyncio
  3. from typing import Any, Dict, List, Optional
  4. from autogen_core import ComponentModel
  5. from autogen_core.models import ChatCompletionClient, UserMessage
  6. from pydantic import BaseModel
  7. class ComponentTestResult(BaseModel):
  8. status: bool
  9. message: str
  10. data: Optional[Any] = None
  11. logs: List[str] = []
  12. class ComponentTestRequest(BaseModel):
  13. component: ComponentModel
  14. model_client: Optional[Dict[str, Any]] = None
  15. timeout: Optional[int] = 30
  16. class ComponentTestService:
  17. @staticmethod
  18. async def test_agent(
  19. component: ComponentModel, model_client: Optional[ChatCompletionClient] = None
  20. ) -> ComponentTestResult:
  21. """Test an agent component with a simple message"""
  22. try:
  23. from autogen_agentchat.agents import AssistantAgent
  24. from autogen_agentchat.messages import TextMessage
  25. from autogen_core import CancellationToken
  26. # Try to load the agent
  27. try:
  28. # Construct the agent with the model client if provided
  29. if model_client:
  30. component.config["model_client"] = model_client
  31. agent = AssistantAgent.load_component(component)
  32. logs = ["Agent component loaded successfully"]
  33. except Exception as e:
  34. return ComponentTestResult(
  35. status=False,
  36. message=f"Failed to initialize agent: {str(e)}",
  37. logs=[f"Agent initialization error: {str(e)}"],
  38. )
  39. # Test the agent with a simple message
  40. test_question = "What is 2+2? Keep it brief."
  41. try:
  42. response = await agent.on_messages(
  43. [TextMessage(content=test_question, source="user")],
  44. cancellation_token=CancellationToken(),
  45. )
  46. # Check if we got a valid response
  47. status = response and response.chat_message is not None
  48. if status:
  49. logs.append(
  50. f"Agent responded with: {response.chat_message.to_text()} to the question : {test_question}"
  51. )
  52. else:
  53. logs.append("Agent did not return a valid response")
  54. return ComponentTestResult(
  55. status=status,
  56. message="Agent test completed successfully" if status else "Agent test failed - no valid response",
  57. data=response.chat_message.model_dump() if status else None,
  58. logs=logs,
  59. )
  60. except Exception as e:
  61. return ComponentTestResult(
  62. status=False,
  63. message=f"Error during agent response: {str(e)}",
  64. logs=logs + [f"Agent response error: {str(e)}"],
  65. )
  66. except Exception as e:
  67. return ComponentTestResult(
  68. status=False, message=f"Error testing agent component: {str(e)}", logs=[f"Exception: {str(e)}"]
  69. )
  70. @staticmethod
  71. async def test_model(
  72. component: ComponentModel, model_client: Optional[ChatCompletionClient] = None
  73. ) -> ComponentTestResult:
  74. """Test a model component with a simple prompt"""
  75. try:
  76. # Use the component itself as a model client
  77. model = ChatCompletionClient.load_component(component)
  78. # Prepare a simple test message
  79. test_question = "What is 2+2? Give me only the answer."
  80. messages = [UserMessage(content=test_question, source="user")]
  81. # Try to get a response
  82. response = await model.create(messages=messages)
  83. # Test passes if we got a response with content
  84. status = response and response.content is not None
  85. logs = ["Model component loaded successfully"]
  86. if status:
  87. logs.append(f"Model responded with: {response.content} (Query:{test_question})")
  88. else:
  89. logs.append("Model did not return a valid response")
  90. return ComponentTestResult(
  91. status=status,
  92. message="Model test completed successfully" if status else "Model test failed - no valid response",
  93. data=response.model_dump() if status else None,
  94. logs=logs,
  95. )
  96. except Exception as e:
  97. return ComponentTestResult(
  98. status=False, message=f"Error testing model component: {str(e)}", logs=[f"Exception: {str(e)}"]
  99. )
  100. @staticmethod
  101. async def test_tool(component: ComponentModel) -> ComponentTestResult:
  102. """Test a tool component with sample inputs"""
  103. # Placeholder for tool test logic
  104. return ComponentTestResult(
  105. status=True, message="Tool test not yet implemented", logs=["Tool component loaded successfully"]
  106. )
  107. @staticmethod
  108. async def test_team(
  109. component: ComponentModel, model_client: Optional[ChatCompletionClient] = None
  110. ) -> ComponentTestResult:
  111. """Test a team component with a simple task"""
  112. # Placeholder for team test logic
  113. return ComponentTestResult(
  114. status=True, message="Team test not yet implemented", logs=["Team component loaded successfully"]
  115. )
  116. @staticmethod
  117. async def test_termination(component: ComponentModel) -> ComponentTestResult:
  118. """Test a termination component with sample message history"""
  119. # Placeholder for termination test logic
  120. return ComponentTestResult(
  121. status=True,
  122. message="Termination test not yet implemented",
  123. logs=["Termination component loaded successfully"],
  124. )
  125. @classmethod
  126. async def test_component(
  127. cls, component: ComponentModel, timeout: int = 60, model_client: Optional[ChatCompletionClient] = None
  128. ) -> ComponentTestResult:
  129. """Test a component based on its type with appropriate test inputs"""
  130. try:
  131. # Get component type
  132. component_type = component.component_type
  133. # Select test method based on component type
  134. test_method = {
  135. "agent": cls.test_agent,
  136. "model": cls.test_model,
  137. "tool": cls.test_tool,
  138. "team": cls.test_team,
  139. "termination": cls.test_termination,
  140. }.get(component_type or "unknown")
  141. if not test_method:
  142. return ComponentTestResult(status=False, message=f"Unknown component type: {component_type}")
  143. # Determine if the test method accepts a model_client parameter
  144. accepts_model_client = component_type in ["agent", "model", "team"]
  145. # Run test with timeout
  146. try:
  147. if accepts_model_client:
  148. result = await asyncio.wait_for(test_method(component, model_client), timeout=timeout)
  149. else:
  150. result = await asyncio.wait_for(test_method(component), timeout=timeout)
  151. return result
  152. except asyncio.TimeoutError:
  153. return ComponentTestResult(status=False, message=f"Component test exceeded the {timeout}s timeout")
  154. except Exception as e:
  155. return ComponentTestResult(status=False, message=f"Error testing component: {str(e)}")