|
- # api/validator/test_service.py
- import asyncio
- from typing import Any, Dict, List, Optional
-
- from autogen_core import ComponentModel
- from autogen_core.models import ChatCompletionClient, UserMessage
- from pydantic import BaseModel
-
-
- class ComponentTestResult(BaseModel):
- status: bool
- message: str
- data: Optional[Any] = None
- logs: List[str] = []
-
-
- class ComponentTestRequest(BaseModel):
- component: ComponentModel
- model_client: Optional[Dict[str, Any]] = None
- timeout: Optional[int] = 30
-
-
- class ComponentTestService:
- @staticmethod
- async def test_agent(
- component: ComponentModel, model_client: Optional[ChatCompletionClient] = None
- ) -> ComponentTestResult:
- """Test an agent component with a simple message"""
- try:
- from autogen_agentchat.agents import AssistantAgent
- from autogen_agentchat.messages import TextMessage
- from autogen_core import CancellationToken
-
- # If model_client is provided, use it; otherwise, use the component's model (if applicable)
- agent_config = component.config or {}
-
- # Try to load the agent
- try:
- # Construct the agent with the model client if provided
- if model_client:
- agent_config["model_client"] = model_client
-
- agent = AssistantAgent(name=agent_config.get("name", "assistant"), **agent_config)
-
- logs = ["Agent component loaded successfully"]
- except Exception as e:
- return ComponentTestResult(
- status=False,
- message=f"Failed to initialize agent: {str(e)}",
- logs=[f"Agent initialization error: {str(e)}"],
- )
-
- # Test the agent with a simple message
- test_question = "What is 2+2? Keep it brief."
- try:
- response = await agent.on_messages(
- [TextMessage(content=test_question, source="user")],
- cancellation_token=CancellationToken(),
- )
-
- # Check if we got a valid response
- status = response and response.chat_message is not None
-
- if status:
- logs.append(
- f"Agent responded with: {response.chat_message.to_text()} to the question : {test_question}"
- )
- else:
- logs.append("Agent did not return a valid response")
-
- return ComponentTestResult(
- status=status,
- message="Agent test completed successfully" if status else "Agent test failed - no valid response",
- data=response.chat_message.model_dump() if status else None,
- logs=logs,
- )
- except Exception as e:
- return ComponentTestResult(
- status=False,
- message=f"Error during agent response: {str(e)}",
- logs=logs + [f"Agent response error: {str(e)}"],
- )
-
- except Exception as e:
- return ComponentTestResult(
- status=False, message=f"Error testing agent component: {str(e)}", logs=[f"Exception: {str(e)}"]
- )
-
- @staticmethod
- async def test_model(
- component: ComponentModel, model_client: Optional[ChatCompletionClient] = None
- ) -> ComponentTestResult:
- """Test a model component with a simple prompt"""
- try:
- # Use the component itself as a model client
- model = ChatCompletionClient.load_component(component)
-
- # Prepare a simple test message
- test_question = "What is 2+2? Give me only the answer."
- messages = [UserMessage(content=test_question, source="user")]
-
- # Try to get a response
- response = await model.create(messages=messages)
-
- # Test passes if we got a response with content
- status = response and response.content is not None
-
- logs = ["Model component loaded successfully"]
- if status:
- logs.append(f"Model responded with: {response.content} (Query:{test_question})")
- else:
- logs.append("Model did not return a valid response")
-
- return ComponentTestResult(
- status=status,
- message="Model test completed successfully" if status else "Model test failed - no valid response",
- data=response.model_dump() if status else None,
- logs=logs,
- )
- except Exception as e:
- return ComponentTestResult(
- status=False, message=f"Error testing model component: {str(e)}", logs=[f"Exception: {str(e)}"]
- )
-
- @staticmethod
- async def test_tool(component: ComponentModel) -> ComponentTestResult:
- """Test a tool component with sample inputs"""
- # Placeholder for tool test logic
- return ComponentTestResult(
- status=True, message="Tool test not yet implemented", logs=["Tool component loaded successfully"]
- )
-
- @staticmethod
- async def test_team(
- component: ComponentModel, model_client: Optional[ChatCompletionClient] = None
- ) -> ComponentTestResult:
- """Test a team component with a simple task"""
- # Placeholder for team test logic
- return ComponentTestResult(
- status=True, message="Team test not yet implemented", logs=["Team component loaded successfully"]
- )
-
- @staticmethod
- async def test_termination(component: ComponentModel) -> ComponentTestResult:
- """Test a termination component with sample message history"""
- # Placeholder for termination test logic
- return ComponentTestResult(
- status=True,
- message="Termination test not yet implemented",
- logs=["Termination component loaded successfully"],
- )
-
- @classmethod
- async def test_component(
- cls, component: ComponentModel, timeout: int = 60, model_client: Optional[ChatCompletionClient] = None
- ) -> ComponentTestResult:
- """Test a component based on its type with appropriate test inputs"""
- try:
- # Get component type
- component_type = component.component_type
-
- # Select test method based on component type
- test_method = {
- "agent": cls.test_agent,
- "model": cls.test_model,
- "tool": cls.test_tool,
- "team": cls.test_team,
- "termination": cls.test_termination,
- }.get(component_type or "unknown")
-
- if not test_method:
- return ComponentTestResult(status=False, message=f"Unknown component type: {component_type}")
-
- # Determine if the test method accepts a model_client parameter
- accepts_model_client = component_type in ["agent", "model", "team"]
-
- # Run test with timeout
- try:
- if accepts_model_client:
- result = await asyncio.wait_for(test_method(component, model_client), timeout=timeout)
- else:
- result = await asyncio.wait_for(test_method(component), timeout=timeout)
- return result
- except asyncio.TimeoutError:
- return ComponentTestResult(status=False, message=f"Component test exceeded the {timeout}s timeout")
-
- except Exception as e:
- return ComponentTestResult(status=False, message=f"Error testing component: {str(e)}")
|