sw-api / tests /agent_evals /auto_test_eval.py
patrickbdevaney's picture
v1 attempt at hf space api
ffcf62f
import json
import os
import platform
import sys
import traceback
from dataclasses import dataclass
from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple
import psutil
import requests
from loguru import logger
from swarm_models import OpenAIChat
from swarms.structs.agent import Agent
@dataclass
class SwarmSystemInfo:
"""System information for Swarms issue reports."""
os_name: str
os_version: str
python_version: str
cpu_usage: float
memory_usage: float
disk_usage: float
swarms_version: str # Added Swarms version tracking
cuda_available: bool # Added CUDA availability check
gpu_info: Optional[str] # Added GPU information
class SwarmsIssueReporter:
"""
Production-grade GitHub issue reporter specifically designed for the Swarms library.
Automatically creates detailed issues for the https://github.com/kyegomez/swarms repository.
Features:
- Swarms-specific error categorization
- Automatic version and dependency tracking
- CUDA and GPU information collection
- Integration with Swarms logging system
- Detailed environment information
"""
REPO_OWNER = "kyegomez"
REPO_NAME = "swarms"
ISSUE_CATEGORIES = {
"agent": ["agent", "automation"],
"memory": ["memory", "storage"],
"tool": ["tools", "integration"],
"llm": ["llm", "model"],
"performance": ["performance", "optimization"],
"compatibility": ["compatibility", "environment"],
}
def __init__(
self,
github_token: str,
rate_limit: int = 10,
rate_period: int = 3600,
log_file: str = "swarms_issues.log",
enable_duplicate_check: bool = True,
):
"""
Initialize the Swarms Issue Reporter.
Args:
github_token (str): GitHub personal access token
rate_limit (int): Maximum number of issues to create per rate_period
rate_period (int): Time period for rate limiting in seconds
log_file (str): Path to log file
enable_duplicate_check (bool): Whether to check for duplicate issues
"""
self.github_token = github_token
self.rate_limit = rate_limit
self.rate_period = rate_period
self.enable_duplicate_check = enable_duplicate_check
self.github_token = os.getenv("GITHUB_API_KEY")
# Initialize logging
log_path = os.path.join(os.getcwd(), "logs", log_file)
os.makedirs(os.path.dirname(log_path), exist_ok=True)
logger.add(
log_path,
rotation="1 day",
retention="1 month",
compression="zip",
)
# Issue tracking
self.issues_created = []
self.last_issue_time = datetime.now()
def _get_swarms_version(self) -> str:
"""Get the installed version of Swarms."""
try:
import swarms
return swarms.__version__
except:
return "Unknown"
def _get_gpu_info(self) -> Tuple[bool, Optional[str]]:
"""Get GPU information and CUDA availability."""
try:
import torch
cuda_available = torch.cuda.is_available()
if cuda_available:
gpu_info = torch.cuda.get_device_name(0)
return cuda_available, gpu_info
return False, None
except:
return False, None
def _get_system_info(self) -> SwarmSystemInfo:
"""Collect system and Swarms-specific information."""
cuda_available, gpu_info = self._get_gpu_info()
return SwarmSystemInfo(
os_name=platform.system(),
os_version=platform.version(),
python_version=sys.version,
cpu_usage=psutil.cpu_percent(),
memory_usage=psutil.virtual_memory().percent,
disk_usage=psutil.disk_usage("/").percent,
swarms_version=self._get_swarms_version(),
cuda_available=cuda_available,
gpu_info=gpu_info,
)
def _categorize_error(
self, error: Exception, context: Dict
) -> List[str]:
"""Categorize the error and return appropriate labels."""
error_str = str(error).lower()
type(error).__name__
labels = ["bug", "automated"]
# Check error message and context for category keywords
for (
category,
category_labels,
) in self.ISSUE_CATEGORIES.items():
if any(
keyword in error_str for keyword in category_labels
):
labels.extend(category_labels)
break
# Add severity label based on error type
if issubclass(type(error), (SystemError, MemoryError)):
labels.append("severity:critical")
elif issubclass(type(error), (ValueError, TypeError)):
labels.append("severity:medium")
else:
labels.append("severity:low")
return list(set(labels)) # Remove duplicates
def _format_swarms_issue_body(
self,
error: Exception,
system_info: SwarmSystemInfo,
context: Dict,
) -> str:
"""Format the issue body with Swarms-specific information."""
return f"""
## Swarms Error Report
- **Error Type**: {type(error).__name__}
- **Error Message**: {str(error)}
- **Swarms Version**: {system_info.swarms_version}
## Environment Information
- **OS**: {system_info.os_name} {system_info.os_version}
- **Python Version**: {system_info.python_version}
- **CUDA Available**: {system_info.cuda_available}
- **GPU**: {system_info.gpu_info or "N/A"}
- **CPU Usage**: {system_info.cpu_usage}%
- **Memory Usage**: {system_info.memory_usage}%
- **Disk Usage**: {system_info.disk_usage}%
## Stack Trace
{traceback.format_exc()}
## Context
{json.dumps(context, indent=2)}
## Dependencies
{self._get_dependencies_info()}
## Time of Occurrence
{datetime.now().isoformat()}
---
*This issue was automatically generated by SwarmsIssueReporter*
"""
def _get_dependencies_info(self) -> str:
"""Get information about installed dependencies."""
try:
import pkg_resources
deps = []
for dist in pkg_resources.working_set:
deps.append(f"- {dist.key} {dist.version}")
return "\n".join(deps)
except:
return "Unable to fetch dependency information"
# First, add this method to your SwarmsIssueReporter class
def _check_rate_limit(self) -> bool:
"""Check if we're within rate limits."""
now = datetime.now()
time_diff = (now - self.last_issue_time).total_seconds()
if (
len(self.issues_created) >= self.rate_limit
and time_diff < self.rate_period
):
logger.warning("Rate limit exceeded for issue creation")
return False
# Clean up old issues from tracking
self.issues_created = [
time
for time in self.issues_created
if (now - time).total_seconds() < self.rate_period
]
return True
def report_swarms_issue(
self,
error: Exception,
agent: Optional[Agent] = None,
context: Dict[str, Any] = None,
priority: str = "normal",
) -> Optional[int]:
"""
Report a Swarms-specific issue to GitHub.
Args:
error (Exception): The exception to report
agent (Optional[Agent]): The Swarms agent instance that encountered the error
context (Dict[str, Any]): Additional context about the error
priority (str): Issue priority ("low", "normal", "high", "critical")
Returns:
Optional[int]: Issue number if created successfully
"""
try:
if not self._check_rate_limit():
logger.warning(
"Skipping issue creation due to rate limit"
)
return None
# Collect system information
system_info = self._get_system_info()
# Prepare context with agent information if available
full_context = context or {}
if agent:
full_context.update(
{
"agent_name": agent.agent_name,
"agent_description": agent.agent_description,
"max_loops": agent.max_loops,
"context_length": agent.context_length,
}
)
# Create issue title
title = f"[{type(error).__name__}] {str(error)[:100]}"
if agent:
title = f"[Agent: {agent.agent_name}] {title}"
# Get appropriate labels
labels = self._categorize_error(error, full_context)
labels.append(f"priority:{priority}")
# Create the issue
url = f"https://api.github.com/repos/{self.REPO_OWNER}/{self.REPO_NAME}/issues"
data = {
"title": title,
"body": self._format_swarms_issue_body(
error, system_info, full_context
),
"labels": labels,
}
response = requests.post(
url,
headers={
"Authorization": f"token {self.github_token}"
},
json=data,
)
response.raise_for_status()
issue_number = response.json()["number"]
logger.info(
f"Successfully created Swarms issue #{issue_number}"
)
return issue_number
except Exception as e:
logger.error(f"Error creating Swarms issue: {str(e)}")
return None
# Setup the reporter with your GitHub token
reporter = SwarmsIssueReporter(
github_token=os.getenv("GITHUB_API_KEY")
)
# Force an error to test the reporter
try:
# This will raise an error since the input isn't valid
# Create an agent that might have issues
model = OpenAIChat(model_name="gpt-4o")
agent = Agent(agent_name="Test-Agent", max_loops=1)
result = agent.run(None)
raise ValueError("test")
except Exception as e:
# Report the issue
issue_number = reporter.report_swarms_issue(
error=e,
agent=agent,
context={"task": "test_run"},
priority="high",
)
print(f"Created issue number: {issue_number}")