diff --git a/api/agent_api_test.py b/api/agent_api_test.py index 066efc4f..b8008697 100644 --- a/api/agent_api_test.py +++ b/api/agent_api_test.py @@ -1,107 +1,320 @@ import requests from loguru import logger import time - -# Configure loguru -logger.add( - "api_tests_{time}.log", - rotation="100 MB", - level="DEBUG", - format="{time} {level} {message}", -) +from typing import Dict, Optional, Tuple +from uuid import UUID +import sys BASE_URL = "http://localhost:8000/v1" -def test_create_agent(): +def check_api_server() -> bool: + """Check if the API server is running and accessible.""" + try: + response = requests.get(f"{BASE_URL}/docs") + return response.status_code == 200 + except requests.exceptions.ConnectionError: + logger.error("API server is not running at {BASE_URL}") + logger.error("Please start the API server first with:") + logger.error(" python main.py") + return False + except Exception as e: + logger.error(f"Error checking API server: {str(e)}") + return False + + +class TestSession: + """Manages test session state and authentication.""" + + def __init__(self): + self.user_id: Optional[UUID] = None + self.api_key: Optional[str] = None + self.test_agents: list[UUID] = [] + + @property + def headers(self) -> Dict[str, str]: + """Get headers with authentication.""" + return {"api-key": self.api_key} if self.api_key else {} + + +def create_test_user(session: TestSession) -> Tuple[bool, str]: + """Create a test user and store credentials in session.""" + logger.info("Creating test user") + + try: + response = requests.post( + f"{BASE_URL}/users", + json={"username": f"test_user_{int(time.time())}"}, + ) + + if response.status_code == 200: + data = response.json() + session.user_id = data["user_id"] + session.api_key = data["api_key"] + logger.success(f"Created user with ID: {session.user_id}") + return True, "Success" + else: + logger.error(f"Failed to create user: {response.text}") + return False, response.text + except Exception as e: + logger.exception("Exception during user creation") + return False, str(e) + + +def create_additional_api_key( + session: TestSession, +) -> Tuple[bool, str]: + """Test creating an additional API key.""" + logger.info("Creating additional API key") + + try: + response = requests.post( + f"{BASE_URL}/users/{session.user_id}/api-keys", + headers=session.headers, + json={"name": "Test Key"}, + ) + + if response.status_code == 200: + logger.success("Created additional API key") + return True, response.json()["key"] + else: + logger.error(f"Failed to create API key: {response.text}") + return False, response.text + except Exception as e: + logger.exception("Exception during API key creation") + return False, str(e) + + +def test_create_agent( + session: TestSession, +) -> Tuple[bool, Optional[UUID]]: """Test creating a new agent.""" logger.info("Testing agent creation") payload = { - "agent_name": "Test Agent", + "agent_name": f"Test Agent {int(time.time())}", "system_prompt": "You are a helpful assistant", "model_name": "gpt-4", "description": "Test agent", - "tags": ["test"], + "tags": ["test", "automated"], } - response = requests.post(f"{BASE_URL}/agent", json=payload) - logger.debug(f"Create response: {response.json()}") + try: + response = requests.post( + f"{BASE_URL}/agent", headers=session.headers, json=payload + ) + + if response.status_code == 200: + agent_id = response.json()["agent_id"] + session.test_agents.append(agent_id) + logger.success(f"Created agent with ID: {agent_id}") + return True, agent_id + else: + logger.error(f"Failed to create agent: {response.text}") + return False, None + except Exception: + logger.exception("Exception during agent creation") + return False, None + + +def test_list_user_agents(session: TestSession) -> bool: + """Test listing user's agents.""" + logger.info("Testing user agent listing") + + try: + response = requests.get( + f"{BASE_URL}/users/me/agents", headers=session.headers + ) + + if response.status_code == 200: + agents = response.json() + logger.success(f"Found {len(agents)} user agents") + return True + else: + logger.error( + f"Failed to list user agents: {response.text}" + ) + return False + except Exception: + logger.exception("Exception during agent listing") + return False - if response.status_code == 200: - logger.success("Successfully created agent") - return response.json()["agent_id"] - else: - logger.error(f"Failed to create agent: {response.text}") - return None +def test_agent_operations( + session: TestSession, agent_id: UUID +) -> bool: + """Test various operations on an agent.""" + logger.info(f"Testing operations for agent {agent_id}") -def test_list_agents(): - """Test listing all agents.""" - logger.info("Testing agent listing") + # Test update + try: + update_response = requests.patch( + f"{BASE_URL}/agent/{agent_id}", + headers=session.headers, + json={ + "description": "Updated description", + "tags": ["test", "updated"], + }, + ) + if update_response.status_code != 200: + logger.error( + f"Failed to update agent: {update_response.text}" + ) + return False - response = requests.get(f"{BASE_URL}/agents") - logger.debug(f"List response: {response.json()}") + # Test metrics + metrics_response = requests.get( + f"{BASE_URL}/agent/{agent_id}/metrics", + headers=session.headers, + ) + if metrics_response.status_code != 200: + logger.error( + f"Failed to get agent metrics: {metrics_response.text}" + ) + return False - if response.status_code == 200: - logger.success(f"Found {len(response.json())} agents") - else: - logger.error(f"Failed to list agents: {response.text}") + logger.success("Successfully performed agent operations") + return True + except Exception: + logger.exception("Exception during agent operations") + return False -def test_completion(agent_id): +def test_completion(session: TestSession, agent_id: UUID) -> bool: """Test running a completion.""" logger.info("Testing completion") payload = { "prompt": "What is the weather like today?", "agent_id": agent_id, + "max_tokens": 100, } - response = requests.post( - f"{BASE_URL}/agent/completions", json=payload - ) - logger.debug(f"Completion response: {response.json()}") + try: + response = requests.post( + f"{BASE_URL}/agent/completions", + headers=session.headers, + json=payload, + ) - if response.status_code == 200: - logger.success("Successfully got completion") - else: - logger.error(f"Failed to get completion: {response.text}") + if response.status_code == 200: + completion_data = response.json() + logger.success( + f"Got completion, used {completion_data['token_usage']['total_tokens']} tokens" + ) + return True + else: + logger.error(f"Failed to get completion: {response.text}") + return False + except Exception: + logger.exception("Exception during completion") + return False -def test_delete_agent(agent_id): - """Test deleting an agent.""" - logger.info("Testing agent deletion") +def cleanup_test_resources(session: TestSession): + """Clean up all test resources.""" + logger.info("Cleaning up test resources") - response = requests.delete(f"{BASE_URL}/agent/{agent_id}") - logger.debug(f"Delete response: {response.json()}") + # Delete test agents + for agent_id in session.test_agents: + try: + response = requests.delete( + f"{BASE_URL}/agent/{agent_id}", + headers=session.headers, + ) + if response.status_code == 200: + logger.debug(f"Deleted agent {agent_id}") + else: + logger.warning( + f"Failed to delete agent {agent_id}: {response.text}" + ) + except Exception: + logger.exception(f"Exception deleting agent {agent_id}") - if response.status_code == 200: - logger.success("Successfully deleted agent") - else: - logger.error(f"Failed to delete agent: {response.text}") + # Revoke API keys + if session.user_id: + try: + response = requests.get( + f"{BASE_URL}/users/{session.user_id}/api-keys", + headers=session.headers, + ) + if response.status_code == 200: + for key in response.json(): + try: + revoke_response = requests.delete( + f"{BASE_URL}/users/{session.user_id}/api-keys/{key['key']}", + headers=session.headers, + ) + if revoke_response.status_code == 200: + logger.debug( + f"Revoked API key {key['name']}" + ) + else: + logger.warning( + f"Failed to revoke API key {key['name']}" + ) + except Exception: + logger.exception( + f"Exception revoking API key {key['name']}" + ) + except Exception: + logger.exception("Exception getting API keys for cleanup") -def run_tests(): - """Run all tests in sequence.""" +def run_test_workflow(): + """Run complete test workflow.""" logger.info("Starting API tests") - # Create agent and get ID - agent_id = test_create_agent() - if not agent_id: - logger.error("Cannot continue tests without agent ID") - return + # Check if API server is running first + if not check_api_server(): + return False + + session = TestSession() + + try: + # Create user + user_success, message = create_test_user(session) + if not user_success: + logger.error(f"User creation failed: {message}") + return False + + # Create additional API key + key_success, key = create_additional_api_key(session) + if not key_success: + logger.error(f"API key creation failed: {key}") + return False + + # Create agent + agent_success, agent_id = test_create_agent(session) + if not agent_success or not agent_id: + logger.error("Agent creation failed") + return False + + # Test user agent listing + if not test_list_user_agents(session): + logger.error("Agent listing failed") + return False + + # Test agent operations + if not test_agent_operations(session, agent_id): + logger.error("Agent operations failed") + return False - # Wait a bit for agent to be ready - time.sleep(1) + # Test completion + if not test_completion(session, agent_id): + logger.error("Completion test failed") + return False - # Run other tests - test_list_agents() - test_completion(agent_id) - test_delete_agent(agent_id) + logger.success("All tests completed successfully") + return True - logger.info("Tests completed") + except Exception: + logger.exception("Exception during test workflow") + return False + finally: + cleanup_test_resources(session) if __name__ == "__main__": - run_tests() + success = run_test_workflow() + sys.exit(0 if success else 1) diff --git a/api/agent_api.py b/api/main.py similarity index 69% rename from api/agent_api.py rename to api/main.py index 922c4572..9c3c94be 100644 --- a/api/agent_api.py +++ b/api/main.py @@ -1,40 +1,34 @@ import os +import secrets +import traceback +from concurrent.futures import ThreadPoolExecutor +from datetime import datetime, timedelta +from enum import Enum +from pathlib import Path +from typing import Any, Dict, List, Optional +from uuid import UUID, uuid4 + +import uvicorn +from dotenv import load_dotenv from fastapi import ( + BackgroundTasks, + Depends, FastAPI, + Header, HTTPException, - status, Query, - BackgroundTasks, + Request, + status, ) from fastapi.middleware.cors import CORSMiddleware -from pydantic import BaseModel, Field -from typing import Optional, Dict, Any, List from loguru import logger -import uvicorn -from datetime import datetime, timedelta -from uuid import UUID, uuid4 -from enum import Enum -from pathlib import Path -from concurrent.futures import ThreadPoolExecutor -import traceback +from pydantic import BaseModel, Field from swarms import Agent -from dotenv import load_dotenv # Load environment variables load_dotenv() -# Configure Loguru -logger.add( - "logs/api_{time}.log", - rotation="500 MB", - retention="10 days", - level="INFO", - format="{time} {level} {message}", - backtrace=True, - diagnose=True, -) - class AgentStatus(str, Enum): """Enum for agent status.""" @@ -45,6 +39,30 @@ class AgentStatus(str, Enum): MAINTENANCE = "maintenance" +# Security configurations +API_KEY_LENGTH = 32 # Length of generated API keys + + +class APIKey(BaseModel): + key: str + name: str + created_at: datetime + last_used: datetime + is_active: bool = True + + +class APIKeyCreate(BaseModel): + name: str # A friendly name for the API key + + +class User(BaseModel): + id: UUID + username: str + is_active: bool = True + is_admin: bool = False + api_keys: Dict[str, APIKey] = {} # key -> APIKey object + + class AgentConfig(BaseModel): """Configuration model for creating a new agent.""" @@ -60,7 +78,7 @@ class AgentConfig(BaseModel): ..., description="System prompt for the agent" ) model_name: str = Field( - default="gpt-4o-mini", description="Model name to use" + default="gpt-4", description="Model name to use" ) temperature: float = Field( default=0.1, @@ -102,14 +120,6 @@ class AgentConfig(BaseModel): default_factory=list, description="Tags for categorizing the agent", ) - auto_generate_prompt: bool = Field( - default_factory=bool, - description="Auto generate a prompt based on the input", - ) - max_tokens: int = Field( - default_factory=int, - description="The number of max output tokens", - ) class AgentUpdate(BaseModel): @@ -180,6 +190,11 @@ class AgentStore: def __init__(self): self.agents: Dict[UUID, Agent] = {} self.agent_metadata: Dict[UUID, Dict[str, Any]] = {} + self.users: Dict[UUID, User] = {} # user_id -> User + self.api_keys: Dict[str, UUID] = {} # api_key -> user_id + self.user_agents: Dict[UUID, List[UUID]] = ( + {} + ) # user_id -> [agent_ids] self.executor = ThreadPoolExecutor(max_workers=4) self._ensure_directories() @@ -188,7 +203,59 @@ class AgentStore: Path("logs").mkdir(exist_ok=True) Path("states").mkdir(exist_ok=True) - async def create_agent(self, config: AgentConfig) -> UUID: + def create_api_key(self, user_id: UUID, key_name: str) -> APIKey: + """Create a new API key for a user.""" + if user_id not in self.users: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="User not found", + ) + + # Generate a secure random API key + api_key = secrets.token_urlsafe(API_KEY_LENGTH) + + # Create the API key object + key_object = APIKey( + key=api_key, + name=key_name, + created_at=datetime.utcnow(), + last_used=datetime.utcnow(), + ) + + # Store the API key + self.users[user_id].api_keys[api_key] = key_object + self.api_keys[api_key] = user_id + + return key_object + + async def verify_agent_access( + self, agent_id: UUID, user_id: UUID + ) -> bool: + """Verify if a user has access to an agent.""" + if agent_id not in self.agents: + return False + return ( + self.agent_metadata[agent_id]["owner_id"] == user_id + or self.users[user_id].is_admin + ) + + def validate_api_key(self, api_key: str) -> Optional[UUID]: + """Validate an API key and return the associated user ID.""" + user_id = self.api_keys.get(api_key) + if not user_id or api_key not in self.users[user_id].api_keys: + return None + + key_object = self.users[user_id].api_keys[api_key] + if not key_object.is_active: + return None + + # Update last used timestamp + key_object.last_used = datetime.utcnow() + return user_id + + async def create_agent( + self, config: AgentConfig, user_id: UUID + ) -> UUID: """Create a new agent with the given configuration.""" try: @@ -205,9 +272,9 @@ class AgentStore: user_name=config.user_name, retry_attempts=config.retry_attempts, context_length=config.context_length, + return_step_meta=True, output_type="str", - auto_generate_prompt=config.auto_generate_prompt, - max_tokens=config.max_tokens, + streaming_on=config.streaming_on, ) agent_id = uuid4() @@ -227,7 +294,11 @@ class AgentStore: "successful_completions": 0, } - logger.info(f"Created agent with ID: {agent_id}") + # Add to user's agents list + if user_id not in self.user_agents: + self.user_agents[user_id] = [] + self.user_agents[user_id].append(agent_id) + return agent_id except Exception as e: @@ -449,8 +520,6 @@ class AgentStore: "agent_name": agent.agent_name, "model_name": agent.llm.model_name, "temperature": agent.llm.temperature, - "max_loops": agent.max_loops, - "context_window": agent.context_length, }, timestamp=datetime.utcnow(), processing_time=processing_time, @@ -475,6 +544,40 @@ class AgentStore: metadata["status"] = AgentStatus.IDLE +class StoreManager: + _instance = None + + @classmethod + def get_instance(cls) -> "AgentStore": + if cls._instance is None: + cls._instance = AgentStore() + return cls._instance + + +# Modify the dependency function +def get_store() -> AgentStore: + """Dependency to get the AgentStore instance.""" + return StoreManager.get_instance() + + +# Security utility function using the new dependency +async def get_current_user( + api_key: str = Header( + ..., description="API key for authentication" + ), + store: AgentStore = Depends(get_store), +) -> User: + """Validate API key and return current user.""" + user_id = store.validate_api_key(api_key) + if not user_id: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid or expired API key", + headers={"WWW-Authenticate": "ApiKey"}, + ) + return store.users[user_id] + + class SwarmsAPI: """Enhanced API class for Swarms agent integration.""" @@ -486,7 +589,9 @@ class SwarmsAPI: docs_url="/v1/docs", redoc_url="/v1/redoc", ) - self.store = AgentStore() + # Initialize the store using the singleton manager + self.store = StoreManager.get_instance() + # Configure CORS self.app.add_middleware( CORSMiddleware, @@ -503,10 +608,130 @@ class SwarmsAPI: def _setup_routes(self): """Set up API routes.""" + # In your API code + @self.app.post("/v1/users", response_model=Dict[str, Any]) + async def create_user(request: Request): + """Create a new user and initial API key.""" + try: + body = await request.json() + username = body.get("username") + if not username or len(username) < 3: + raise HTTPException( + status_code=400, detail="Invalid username" + ) + + user_id = uuid4() + user = User(id=user_id, username=username) + self.store.users[user_id] = user + initial_key = self.store.create_api_key( + user_id, "Initial Key" + ) + return { + "user_id": user_id, + "api_key": initial_key.key, + } + except Exception as e: + logger.error(f"Error creating user: {str(e)}") + raise HTTPException(status_code=400, detail=str(e)) + + @self.app.post( + "/v1/users/{user_id}/api-keys", response_model=APIKey + ) + async def create_api_key( + user_id: UUID, + key_create: APIKeyCreate, + current_user: User = Depends(get_current_user), + ): + """Create a new API key for a user.""" + if ( + current_user.id != user_id + and not current_user.is_admin + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not authorized to create API keys for this user", + ) + + return self.store.create_api_key(user_id, key_create.name) + + @self.app.get( + "/v1/users/{user_id}/api-keys", + response_model=List[APIKey], + ) + async def list_api_keys( + user_id: UUID, + current_user: User = Depends(get_current_user), + ): + """List all API keys for a user.""" + if ( + current_user.id != user_id + and not current_user.is_admin + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not authorized to view API keys for this user", + ) + + return list(self.store.users[user_id].api_keys.values()) + + @self.app.delete("/v1/users/{user_id}/api-keys/{key}") + async def revoke_api_key( + user_id: UUID, + key: str, + current_user: User = Depends(get_current_user), + ): + """Revoke an API key.""" + if ( + current_user.id != user_id + and not current_user.is_admin + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not authorized to revoke API keys for this user", + ) + + if key in self.store.users[user_id].api_keys: + self.store.users[user_id].api_keys[ + key + ].is_active = False + del self.store.api_keys[key] + return {"status": "API key revoked"} + + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="API key not found", + ) + + @self.app.get( + "/v1/users/me/agents", response_model=List[AgentSummary] + ) + async def list_user_agents( + current_user: User = Depends(get_current_user), + tags: Optional[List[str]] = Query(None), + status: Optional[AgentStatus] = None, + ): + """List all agents owned by the current user.""" + user_agents = self.store.user_agents.get( + current_user.id, [] + ) + return [ + agent + for agent in await self.store.list_agents( + tags, status + ) + if agent.agent_id in user_agents + ] + + # Modify existing routes to use API key authentication @self.app.post("/v1/agent", response_model=Dict[str, UUID]) - async def create_agent(config: AgentConfig): + async def create_agent( + config: AgentConfig, + current_user: User = Depends(get_current_user), + ): """Create a new agent with the specified configuration.""" - agent_id = await self.store.create_agent(config) + agent_id = await self.store.create_agent( + config, current_user.id + ) return {"agent_id": agent_id} @self.app.get("/v1/agents", response_model=List[AgentSummary]) @@ -623,17 +848,26 @@ class SwarmsAPI: def create_app() -> FastAPI: """Create and configure the FastAPI application.""" + logger.info("Creating FastAPI application") api = SwarmsAPI() - return api.app + app = api.app + logger.info("FastAPI application created successfully") + return app +app = create_app() + if __name__ == "__main__": - # Configure uvicorn logging - logger.info("API Starting") - uvicorn.run( - "main:create_app", - host="0.0.0.0", - port=8000, - reload=True, - workers=4, - ) + try: + logger.info("Starting API server...") + print("Starting API server on http://0.0.0.0:8000") + + uvicorn.run( + app, # Pass the app instance directly + host="0.0.0.0", + port=8000, + log_level="info", + ) + except Exception as e: + logger.error(f"Failed to start API: {str(e)}") + print(f"Error starting server: {str(e)}") diff --git a/api/skypilot.yaml b/api/skypilot.yaml new file mode 100644 index 00000000..3524aa95 --- /dev/null +++ b/api/skypilot.yaml @@ -0,0 +1,41 @@ +service: + readiness_probe: + path: /docs + initial_delay_seconds: 300 + timeout_seconds: 30 + + replica_policy: + min_replicas: 1 + max_replicas: 50 + target_qps_per_replica: 5 + upscale_delay_seconds: 180 + downscale_delay_seconds: 600 + +resources: + ports: 8000 # FastAPI default port + cpus: 16 + memory: 64 + disk_size: 100 + use_spot: true + +workdir: /app + +setup: | + git clone https://github.com/kyegomez/swarms.git + cd swarms/api + pip install -r requirements.txt + pip install swarms + +run: | + cd swarms/api + uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4 + +# env: +# PYTHONPATH: /app/swarms +# LOG_LEVEL: "INFO" +# # MAX_WORKERS: "4" + +# metadata: +# name: swarms-api-service +# version: "1.0.0" +# environment: production \ No newline at end of file diff --git a/example.py b/example.py index 6ba8a46c..76c23353 100644 --- a/example.py +++ b/example.py @@ -6,9 +6,10 @@ from swarms.prompts.finance_agent_sys_prompt import ( # Initialize the agent agent = Agent( agent_name="Financial-Analysis-Agent", - agent_description = "Personal finance advisor agent", - system_prompt=FINANCIAL_AGENT_SYS_PROMPT + "Output the token when you're done creating a portfolio of etfs, index, funds, and more for AI", - model_name="gpt-4o", # Use any model from litellm + agent_description="Personal finance advisor agent", + system_prompt=FINANCIAL_AGENT_SYS_PROMPT + + "Output the token when you're done creating a portfolio of etfs, index, funds, and more for AI", + model_name="gpt-4o", # Use any model from litellm max_loops="auto", dynamic_temperature_enabled=True, user_name="Kye", @@ -18,8 +19,8 @@ agent = Agent( return_step_meta=False, output_type="str", # "json", "dict", "csv" OR "string" "yaml" and auto_generate_prompt=False, # Auto generate prompt for the agent based on name, description, and system prompt, task - max_tokens=16000, # max output tokens - interactive = True, + max_tokens=16000, # max output tokens + interactive=True, stopping_token="", execute_tool=True, ) diff --git a/fastrag.py b/fastrag.py deleted file mode 100644 index 20839bf1..00000000 --- a/fastrag.py +++ /dev/null @@ -1,387 +0,0 @@ -from typing import List, Dict, Optional, Union, Any -from dataclasses import dataclass -from pathlib import Path -import numpy as np -from scipy.sparse import csr_matrix -from sklearn.cluster import AgglomerativeClustering -from sentence_transformers import SentenceTransformer -import faiss -import pickle -import time -from loguru import logger -from concurrent.futures import ThreadPoolExecutor -import threading -import uuid - -@dataclass -class Document: - """Represents a document in the HQD-RAG system. - - Attributes: - id (str): Unique identifier for the document - content (str): Raw text content of the document - embedding (Optional[np.ndarray]): Quantum-inspired embedding vector - cluster_id (Optional[int]): ID of the cluster this document belongs to - """ - id: str - content: str - embedding: Optional[np.ndarray] = None - cluster_id: Optional[int] = None - -class HQDRAG: - """ - Hierarchical Quantum-Inspired Distributed RAG (HQD-RAG) System - - A production-grade implementation of the HQD-RAG algorithm for ultra-fast - and reliable document retrieval. Uses quantum-inspired embeddings and - hierarchical clustering for efficient search. - - Attributes: - embedding_dim (int): Dimension of the quantum-inspired embeddings - num_clusters (int): Number of hierarchical clusters - similarity_threshold (float): Threshold for quantum similarity matching - reliability_threshold (float): Threshold for reliability verification - """ - - def __init__( - self, - embedding_dim: int = 768, - num_clusters: int = 128, - similarity_threshold: float = 0.75, - reliability_threshold: float = 0.85, - model_name: str = "all-MiniLM-L6-v2" - ): - """Initialize the HQD-RAG system. - - Args: - embedding_dim: Dimension of document embeddings - num_clusters: Number of clusters for hierarchical organization - similarity_threshold: Minimum similarity score for retrieval - reliability_threshold: Minimum reliability score for verification - model_name: Name of the sentence transformer model to use - """ - logger.info(f"Initializing HQD-RAG with {embedding_dim} dimensions") - - self.embedding_dim = embedding_dim - self.num_clusters = num_clusters - self.similarity_threshold = similarity_threshold - self.reliability_threshold = reliability_threshold - - # Initialize components - self.documents: Dict[str, Document] = {} - self.encoder = SentenceTransformer(model_name) - self.index = faiss.IndexFlatIP(embedding_dim) # Inner product index - self.clustering = AgglomerativeClustering( - n_clusters=num_clusters, - metric='euclidean', - linkage='ward' - ) - - # Thread safety - self._lock = threading.Lock() - self._executor = ThreadPoolExecutor(max_workers=4) - - logger.info("HQD-RAG system initialized successfully") - - def _compute_quantum_embedding(self, text: str) -> np.ndarray: - """Compute quantum-inspired embedding for text. - - Args: - text: Input text to embed - - Returns: - Quantum-inspired embedding vector - """ - # Get base embedding - base_embedding = self.encoder.encode([text])[0] - - # Apply quantum-inspired transformation - # Simulate superposition by adding phase components - phase = np.exp(2j * np.pi * np.random.random(self.embedding_dim)) - quantum_embedding = base_embedding * phase - - # Normalize to unit length - return quantum_embedding / np.linalg.norm(quantum_embedding) - - def _verify_reliability(self, doc: Document, query_embedding: np.ndarray) -> float: - """Verify the reliability of a document match. - - Args: - doc: Document to verify - query_embedding: Query embedding vector - - Returns: - Reliability score between 0 and 1 - """ - if doc.embedding is None: - return 0.0 - - # Compute consistency score - consistency = np.abs(np.dot(doc.embedding, query_embedding)) - - # Add quantum noise resistance check - noise = np.random.normal(0, 0.1, self.embedding_dim) - noisy_query = query_embedding + noise - noisy_query = noisy_query / np.linalg.norm(noisy_query) - noise_resistance = np.abs(np.dot(doc.embedding, noisy_query)) - - return (consistency + noise_resistance) / 2 - - def add(self, content: str, doc_id: Optional[str] = None) -> str: - """Add a document to the system. - - Args: - content: Document text content - doc_id: Optional custom document ID - - Returns: - Document ID - """ - doc_id = doc_id or str(uuid.uuid4()) - - with self._lock: - try: - # Compute embedding - embedding = self._compute_quantum_embedding(content) - - # Create document - doc = Document( - id=doc_id, - content=content, - embedding=embedding - ) - - # Add to storage - self.documents[doc_id] = doc - self.index.add(embedding.reshape(1, -1)) - - # Update clustering - self._update_clusters() - - logger.info(f"Successfully added document {doc_id}") - return doc_id - - except Exception as e: - logger.error(f"Error adding document: {str(e)}") - raise - - def query( - self, - query: str, - k: int = 5, - return_scores: bool = False - ) -> Union[List[str], List[tuple[str, float]]]: - """Query the system for relevant documents. - - Args: - query: Query text - k: Number of results to return - return_scores: Whether to return similarity scores - - Returns: - List of document IDs or (document ID, score) tuples - """ - try: - # Compute query embedding - query_embedding = self._compute_quantum_embedding(query) - - # Search index - scores, indices = self.index.search( - query_embedding.reshape(1, -1), - k * 2 # Get extra results for reliability filtering - ) - - results = [] - for score, idx in zip(scores[0], indices[0]): - # Get document - doc_id = list(self.documents.keys())[idx] - doc = self.documents[doc_id] - - # Verify reliability - reliability = self._verify_reliability(doc, query_embedding) - - if reliability >= self.reliability_threshold: - results.append((doc_id, float(score))) - - if len(results) >= k: - break - - logger.info(f"Query returned {len(results)} results") - - if return_scores: - return results - return [doc_id for doc_id, _ in results] - - except Exception as e: - logger.error(f"Error processing query: {str(e)}") - raise - - def update(self, doc_id: str, new_content: str) -> None: - """Update an existing document. - - Args: - doc_id: ID of document to update - new_content: New document content - """ - with self._lock: - try: - if doc_id not in self.documents: - raise KeyError(f"Document {doc_id} not found") - - # Remove old embedding - old_doc = self.documents[doc_id] - if old_doc.embedding is not None: - self.index.remove_ids(np.array([list(self.documents.keys()).index(doc_id)])) - - # Compute new embedding - new_embedding = self._compute_quantum_embedding(new_content) - - # Update document - self.documents[doc_id] = Document( - id=doc_id, - content=new_content, - embedding=new_embedding - ) - - # Add new embedding - self.index.add(new_embedding.reshape(1, -1)) - - # Update clustering - self._update_clusters() - - logger.info(f"Successfully updated document {doc_id}") - - except Exception as e: - logger.error(f"Error updating document: {str(e)}") - raise - - def delete(self, doc_id: str) -> None: - """Delete a document from the system. - - Args: - doc_id: ID of document to delete - """ - with self._lock: - try: - if doc_id not in self.documents: - raise KeyError(f"Document {doc_id} not found") - - # Remove from index - idx = list(self.documents.keys()).index(doc_id) - self.index.remove_ids(np.array([idx])) - - # Remove from storage - del self.documents[doc_id] - - # Update clustering - self._update_clusters() - - logger.info(f"Successfully deleted document {doc_id}") - - except Exception as e: - logger.error(f"Error deleting document: {str(e)}") - raise - - def _update_clusters(self) -> None: - """Update hierarchical document clusters.""" - if len(self.documents) < 2: - return - - # Get all embeddings - embeddings = np.vstack([ - doc.embedding for doc in self.documents.values() - if doc.embedding is not None - ]) - - # Update clustering - clusters = self.clustering.fit_predict(embeddings) - - # Assign cluster IDs - for doc, cluster_id in zip(self.documents.values(), clusters): - doc.cluster_id = int(cluster_id) - - def save(self, path: Union[str, Path]) -> None: - """Save the system state to disk. - - Args: - path: Path to save directory - """ - path = Path(path) - path.mkdir(parents=True, exist_ok=True) - - try: - # Save documents - with open(path / "documents.pkl", "wb") as f: - pickle.dump(self.documents, f) - - # Save index - faiss.write_index(self.index, str(path / "index.faiss")) - - logger.info(f"Successfully saved system state to {path}") - - except Exception as e: - logger.error(f"Error saving system state: {str(e)}") - raise - - def load(self, path: Union[str, Path]) -> None: - """Load the system state from disk. - - Args: - path: Path to save directory - """ - path = Path(path) - - try: - # Load documents - with open(path / "documents.pkl", "rb") as f: - self.documents = pickle.load(f) - - # Load index - self.index = faiss.read_index(str(path / "index.faiss")) - - logger.info(f"Successfully loaded system state from {path}") - - except Exception as e: - logger.error(f"Error loading system state: {str(e)}") - raise - -# Example usage: -if __name__ == "__main__": - # Configure logging - logger.add( - "hqd_rag.log", - rotation="1 day", - retention="1 week", - level="INFO" - ) - - # Initialize system - rag = HQDRAG() - - # Add some documents - doc_ids = [] - docs = [ - "The quick brown fox jumps over the lazy dog", - "Machine learning is a subset of artificial intelligence", - "Python is a popular programming language" - ] - - for doc in docs: - doc_id = rag.add(doc) - doc_ids.append(doc_id) - - # Query - results = rag.query("What is machine learning?", return_scores=True) - print("Query results:", results) - - # # Update a document - # rag.update(doc_ids[0], "The fast brown fox jumps over the sleepy dog") - - # # Delete a document - # rag.delete(doc_ids[-1]) - - # # Save state - # rag.save("hqd_rag_state") - - - \ No newline at end of file diff --git a/forex_agents.py b/forex_agents.py new file mode 100644 index 00000000..1da5e896 --- /dev/null +++ b/forex_agents.py @@ -0,0 +1,554 @@ +from typing import Dict, List +from datetime import datetime +from loguru import logger +from swarms.structs.tree_swarm import TreeAgent, Tree, ForestSwarm +import asyncio +import json +import aiohttp +from bs4 import BeautifulSoup +import xml.etree.ElementTree as ET + +# Configure logging +logger.add("forex_forest.log", rotation="500 MB", level="INFO") + + +class ForexDataFeed: + """Real-time forex data collector using free open sources""" + + def __init__(self): + self.pairs = [ + "EUR/USD", + "GBP/USD", + "USD/JPY", + "AUD/USD", + "USD/CAD", + ] + + async def fetch_ecb_rates(self) -> Dict: + """Fetch exchange rates from European Central Bank (no key required)""" + try: + url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + xml_data = await response.text() + + root = ET.fromstring(xml_data) + rates = {} + for cube in root.findall(".//*[@currency]"): + currency = cube.get("currency") + rate = float(cube.get("rate")) + rates[currency] = rate + + # Calculate cross rates + rates["EUR"] = 1.0 # Base currency + cross_rates = {} + for pair in self.pairs: + base, quote = pair.split("/") + if base in rates and quote in rates: + cross_rates[pair] = rates[base] / rates[quote] + + return cross_rates + except Exception as e: + logger.error(f"Error fetching ECB rates: {e}") + return {} + + async def fetch_forex_factory_data(self) -> Dict: + """Scrape trading data from Forex Factory""" + try: + url = "https://www.forexfactory.com" + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + } + + async with aiohttp.ClientSession() as session: + async with session.get( + url, headers=headers + ) as response: + text = await response.text() + + soup = BeautifulSoup(text, "html.parser") + + # Get calendar events + calendar = [] + calendar_table = soup.find( + "table", class_="calendar__table" + ) + if calendar_table: + for row in calendar_table.find_all( + "tr", class_="calendar__row" + ): + try: + event = { + "currency": row.find( + "td", class_="calendar__currency" + ).text.strip(), + "event": row.find( + "td", class_="calendar__event" + ).text.strip(), + "impact": row.find( + "td", class_="calendar__impact" + ).text.strip(), + "time": row.find( + "td", class_="calendar__time" + ).text.strip(), + } + calendar.append(event) + except: + continue + + return {"calendar": calendar} + except Exception as e: + logger.error(f"Error fetching Forex Factory data: {e}") + return {} + + async def fetch_tradingeconomics_data(self) -> Dict: + """Scrape economic data from Trading Economics""" + try: + url = "https://tradingeconomics.com/calendar" + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + } + + async with aiohttp.ClientSession() as session: + async with session.get( + url, headers=headers + ) as response: + text = await response.text() + + soup = BeautifulSoup(text, "html.parser") + + # Get economic indicators + indicators = [] + calendar_table = soup.find("table", class_="table") + if calendar_table: + for row in calendar_table.find_all("tr")[ + 1: + ]: # Skip header + try: + cols = row.find_all("td") + indicator = { + "country": cols[0].text.strip(), + "indicator": cols[1].text.strip(), + "actual": cols[2].text.strip(), + "previous": cols[3].text.strip(), + "consensus": cols[4].text.strip(), + } + indicators.append(indicator) + except: + continue + + return {"indicators": indicators} + except Exception as e: + logger.error( + f"Error fetching Trading Economics data: {e}" + ) + return {} + + async def fetch_dailyfx_data(self) -> Dict: + """Scrape market analysis from DailyFX""" + try: + url = "https://www.dailyfx.com/market-news" + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + } + + async with aiohttp.ClientSession() as session: + async with session.get( + url, headers=headers + ) as response: + text = await response.text() + + soup = BeautifulSoup(text, "html.parser") + + # Get market news and analysis + news = [] + articles = soup.find_all("article", class_="dfx-article") + for article in articles[:10]: # Get latest 10 articles + try: + news_item = { + "title": article.find("h3").text.strip(), + "summary": article.find("p").text.strip(), + "currency": article.get( + "data-currency", "General" + ), + "timestamp": article.find("time").get( + "datetime" + ), + } + news.append(news_item) + except: + continue + + return {"news": news} + except Exception as e: + logger.error(f"Error fetching DailyFX data: {e}") + return {} + + async def fetch_all_data(self) -> Dict: + """Fetch and combine all forex data sources""" + try: + # Fetch data from all sources concurrently + rates, ff_data, te_data, dx_data = await asyncio.gather( + self.fetch_ecb_rates(), + self.fetch_forex_factory_data(), + self.fetch_tradingeconomics_data(), + self.fetch_dailyfx_data(), + ) + + # Combine all data + market_data = { + "exchange_rates": rates, + "calendar": ff_data.get("calendar", []), + "economic_indicators": te_data.get("indicators", []), + "market_news": dx_data.get("news", []), + "timestamp": datetime.now().isoformat(), + } + + return market_data + + except Exception as e: + logger.error(f"Error fetching all data: {e}") + return {} + + +# Rest of the ForexForestSystem class remains the same... + +# (Previous ForexDataFeed class code remains the same...) + +# Specialized Agent Prompts +TECHNICAL_ANALYST_PROMPT = """You are an expert forex technical analyst agent. +Your responsibilities: +1. Analyze real-time exchange rate data for patterns and trends +2. Calculate cross-rates and currency correlations +3. Generate trading signals based on price action +4. Monitor market volatility and momentum +5. Identify key support and resistance levels + +Data Format: +- You will receive exchange rates from ECB and calculated cross-rates +- Focus on major currency pairs and their relationships +- Consider market volatility and trading volumes + +Output Format: +{ + "analysis_type": "technical", + "timestamp": "ISO timestamp", + "signals": [ + { + "pair": "Currency pair", + "trend": "bullish/bearish/neutral", + "strength": 1-10, + "key_levels": {"support": [], "resistance": []}, + "recommendation": "buy/sell/hold" + } + ] +}""" + +FUNDAMENTAL_ANALYST_PROMPT = """You are an expert forex fundamental analyst agent. +Your responsibilities: +1. Analyze economic calendar events and their impact +2. Evaluate economic indicators from Trading Economics +3. Assess market news and sentiment from DailyFX +4. Monitor central bank actions and policies +5. Track geopolitical events affecting currencies + +Data Format: +- Economic calendar events with impact levels +- Latest economic indicators and previous values +- Market news and analysis from reliable sources +- Central bank statements and policy changes + +Output Format: +{ + "analysis_type": "fundamental", + "timestamp": "ISO timestamp", + "assessments": [ + { + "currency": "Currency code", + "economic_outlook": "positive/negative/neutral", + "key_events": [], + "impact_score": 1-10, + "bias": "bullish/bearish/neutral" + } + ] +}""" + +MARKET_SENTIMENT_PROMPT = """You are an expert market sentiment analysis agent. +Your responsibilities: +1. Analyze news sentiment from DailyFX articles +2. Track market positioning and bias +3. Monitor risk sentiment and market fear/greed +4. Identify potential market drivers +5. Detect sentiment shifts and extremes + +Data Format: +- Market news and analysis articles +- Trading sentiment indicators +- Risk event calendar +- Market commentary and analysis + +Output Format: +{ + "analysis_type": "sentiment", + "timestamp": "ISO timestamp", + "sentiment_data": [ + { + "pair": "Currency pair", + "sentiment": "risk-on/risk-off", + "strength": 1-10, + "key_drivers": [], + "outlook": "positive/negative/neutral" + } + ] +}""" + +STRATEGY_COORDINATOR_PROMPT = """You are the lead forex strategy coordination agent. +Your responsibilities: +1. Synthesize technical, fundamental, and sentiment analysis +2. Generate final trading recommendations +3. Manage risk exposure and position sizing +4. Coordinate entry and exit points +5. Monitor open positions and adjust strategies + +Data Format: +- Analysis from technical, fundamental, and sentiment agents +- Current market rates and conditions +- Economic calendar and news events +- Risk parameters and exposure limits + +Output Format: +{ + "analysis_type": "strategy", + "timestamp": "ISO timestamp", + "recommendations": [ + { + "pair": "Currency pair", + "action": "buy/sell/hold", + "confidence": 1-10, + "entry_points": [], + "stop_loss": float, + "take_profit": float, + "rationale": "string" + } + ] +}""" + + +class ForexForestSystem: + """Main system coordinating the forest swarm and data feeds""" + + def __init__(self): + """Initialize the forex forest system""" + self.data_feed = ForexDataFeed() + + # Create Technical Analysis Tree + technical_agents = [ + TreeAgent( + system_prompt=TECHNICAL_ANALYST_PROMPT, + agent_name="Price Action Analyst", + model_name="gpt-4o", + ), + TreeAgent( + system_prompt=TECHNICAL_ANALYST_PROMPT, + agent_name="Cross Rate Analyst", + model_name="gpt-4o", + ), + TreeAgent( + system_prompt=TECHNICAL_ANALYST_PROMPT, + agent_name="Volatility Analyst", + model_name="gpt-4o", + ), + ] + + # Create Fundamental Analysis Tree + fundamental_agents = [ + TreeAgent( + system_prompt=FUNDAMENTAL_ANALYST_PROMPT, + agent_name="Economic Data Analyst", + model_name="gpt-4o", + ), + TreeAgent( + system_prompt=FUNDAMENTAL_ANALYST_PROMPT, + agent_name="News Impact Analyst", + model_name="gpt-4o", + ), + TreeAgent( + system_prompt=FUNDAMENTAL_ANALYST_PROMPT, + agent_name="Central Bank Analyst", + model_name="gpt-4o", + ), + ] + + # Create Sentiment Analysis Tree + sentiment_agents = [ + TreeAgent( + system_prompt=MARKET_SENTIMENT_PROMPT, + agent_name="News Sentiment Analyst", + model_name="gpt-4o", + ), + TreeAgent( + system_prompt=MARKET_SENTIMENT_PROMPT, + agent_name="Risk Sentiment Analyst", + model_name="gpt-4o", + ), + TreeAgent( + system_prompt=MARKET_SENTIMENT_PROMPT, + agent_name="Market Positioning Analyst", + model_name="gpt-4o", + ), + ] + + # Create Strategy Coordination Tree + strategy_agents = [ + TreeAgent( + system_prompt=STRATEGY_COORDINATOR_PROMPT, + agent_name="Lead Strategy Coordinator", + model_name="gpt-4", + temperature=0.5, + ), + TreeAgent( + system_prompt=STRATEGY_COORDINATOR_PROMPT, + agent_name="Risk Manager", + model_name="gpt-4", + temperature=0.5, + ), + TreeAgent( + system_prompt=STRATEGY_COORDINATOR_PROMPT, + agent_name="Position Manager", + model_name="gpt-4", + temperature=0.5, + ), + ] + + # Create trees + self.technical_tree = Tree( + tree_name="Technical Analysis", agents=technical_agents + ) + self.fundamental_tree = Tree( + tree_name="Fundamental Analysis", + agents=fundamental_agents, + ) + self.sentiment_tree = Tree( + tree_name="Sentiment Analysis", agents=sentiment_agents + ) + self.strategy_tree = Tree( + tree_name="Strategy Coordination", agents=strategy_agents + ) + + # Create forest swarm + self.forest = ForestSwarm( + trees=[ + self.technical_tree, + self.fundamental_tree, + self.sentiment_tree, + self.strategy_tree, + ] + ) + + logger.info("Forex Forest System initialized successfully") + + async def prepare_analysis_task(self) -> str: + """Prepare the analysis task with real-time data""" + try: + market_data = await self.data_feed.fetch_all_data() + + task = { + "action": "analyze_forex_markets", + "market_data": market_data, + "timestamp": datetime.now().isoformat(), + "analysis_required": [ + "technical", + "fundamental", + "sentiment", + "strategy", + ], + } + + return json.dumps(task, indent=2) + + except Exception as e: + logger.error(f"Error preparing analysis task: {e}") + raise + + async def run_analysis_cycle(self) -> Dict: + """Run a complete analysis cycle with the forest swarm""" + try: + # Prepare task with real-time data + task = await self.prepare_analysis_task() + + # Run forest swarm analysis + result = self.forest.run(task) + + # Parse and validate results + analysis = ( + json.loads(result) + if isinstance(result, str) + else result + ) + + logger.info("Analysis cycle completed successfully") + return analysis + + except Exception as e: + logger.error(f"Error in analysis cycle: {e}") + raise + + async def monitor_markets(self, interval_seconds: int = 300): + """Continuously monitor markets and run analysis""" + while True: + try: + # Run analysis cycle + analysis = await self.run_analysis_cycle() + + # Log results + logger.info("Market analysis completed") + logger.debug( + f"Analysis results: {json.dumps(analysis, indent=2)}" + ) + + # Process any trading signals + if "recommendations" in analysis: + await self.process_trading_signals( + analysis["recommendations"] + ) + + # Wait for next interval + await asyncio.sleep(interval_seconds) + + except Exception as e: + logger.error(f"Error in market monitoring: {e}") + await asyncio.sleep(60) + + async def process_trading_signals( + self, recommendations: List[Dict] + ): + """Process and log trading signals from analysis""" + try: + for rec in recommendations: + logger.info( + f"Trading Signal: {rec['pair']} - {rec['action']}" + ) + logger.info(f"Confidence: {rec['confidence']}/10") + logger.info(f"Entry Points: {rec['entry_points']}") + logger.info(f"Stop Loss: {rec['stop_loss']}") + logger.info(f"Take Profit: {rec['take_profit']}") + logger.info(f"Rationale: {rec['rationale']}") + logger.info("-" * 50) + + except Exception as e: + logger.error(f"Error processing trading signals: {e}") + + +# Example usage +async def main(): + """Main function to run the Forex Forest System""" + try: + system = ForexForestSystem() + await system.monitor_markets() + except Exception as e: + logger.error(f"Error in main: {e}") + + +if __name__ == "__main__": + # Set up asyncio event loop and run the system + asyncio.run(main()) diff --git a/new_features_examples/insurance_agent.py b/new_features_examples/insurance_agent.py new file mode 100644 index 00000000..a4c5d27b --- /dev/null +++ b/new_features_examples/insurance_agent.py @@ -0,0 +1,169 @@ +from swarms import Agent + + +# Claims Processing Agent system prompt +CLAIMS_PROCESSING_AGENT_SYS_PROMPT = """ +Here's an extended and detailed system prompt for the **Claims Processing Agent**, incorporating reasoning steps, output format, and examples for structured responses: +You are a Claims Processing Agent specializing in automating and accelerating claims processing workflows. Your primary goal is to ensure Accuracy, reduce processing time, and flag potential fraud while providing clear and actionable insights. You must follow the detailed steps below to process claims efficiently and provide consistent, structured output. + +### Primary Objectives: +1. **Extract Information**: + - Identify and extract key details from claim documents such as: + - Claimant name, date of incident, and location. + - Relevant policy numbers and coverage details. + - Information from supporting documents like police reports, medical bills, or repair estimates. + - For images (e.g., accident photos), extract descriptive metadata and identify key features (e.g., vehicle damage, environmental factors). + +2. **Cross-Reference**: + - Compare details across documents and media: + - Validate consistency between police reports, medical bills, and other supporting documents. + - Cross-check dates, times, and locations for coherence. + - Analyze image evidence and correlate it with textual claims for verification. + +3. **Fraud Detection**: + - Apply analytical reasoning to identify inconsistencies or suspicious patterns, such as: + - Discrepancies in timelines, damages, or descriptions. + - Repetitive or unusually frequent claims involving the same parties or locations. + - Signs of manipulated or altered evidence. + +4. **Provide a Risk Assessment**: + - Assign a preliminary risk level to the claim based on your analysis (e.g., Low, Medium, High). + - Justify the risk level with a clear explanation. + +5. **Flag and Recommend**: + - Highlight any flagged concerns for human review and provide actionable recommendations. + - Indicate documents, areas, or sections requiring further investigation. + +--- + +### Reasoning Steps: +Follow these steps to ensure comprehensive and accurate claim processing: +1. **Document Analysis**: + - Analyze each document individually to extract critical details. + - Identify any missing or incomplete information. +2. **Data Cross-Referencing**: + - Check for consistency between documents. + - Use contextual reasoning to spot potential discrepancies. +3. **Fraud Pattern Analysis**: + - Apply pattern recognition to flag anomalies or unusual claims. +4. **Risk Assessment**: + - Summarize your findings and categorize the risk. +5. **Final Recommendations**: + - Provide clear next steps for resolution or escalation. + +--- + +### Output Format: +Your output must be structured as follows: + +#### 1. Extracted Information: +``` +Claimant Name: [Name] +Date of Incident: [Date] +Location: [Location] +Policy Number: [Policy Number] +Summary of Incident: [Brief Summary] +Supporting Documents: + - Police Report: [Key Details] + - Medical Bills: [Key Details] + - Repair Estimate: [Key Details] + - Photos: [Key Observations] +``` + +#### 2. Consistency Analysis: +``` +[Provide a detailed comparison of documents, highlighting any inconsistencies or gaps in data.] +``` + +#### 3. Risk Assessment: +``` +Risk Level: [Low / Medium / High] +Reasoning: [Provide justification for the assigned risk level, supported by evidence from the analysis.] +``` + +#### 4. Flagged Concerns and Recommendations: +``` +Flagged Concerns: +- [Detail specific issues or inconsistencies, e.g., timeline mismatch, suspicious patterns, etc.] + +Recommendations: +- [Provide actionable next steps for resolving the claim or escalating for human review.] +``` + +--- + +### Example Task: +**Input**: +"Process the attached car accident claim. Extract details from the police report, analyze the attached images, and provide an initial risk assessment. Highlight any inconsistencies for human review." + +**Output**: +#### 1. Extracted Information: +``` +Claimant Name: John Doe +Date of Incident: 2024-01-15 +Location: Miami, FL +Policy Number: ABC-12345 +Summary of Incident: The claimant reports being rear-ended at a traffic light. + +Supporting Documents: + - Police Report: Incident verified by Officer Jane Smith; driver's statement matches claimant's report. + - Medical Bills: $1,500 for physical therapy; injury type aligns with collision severity. + - Repair Estimate: $4,000 for rear bumper and trunk damage. + - Photos: Damage visible to rear bumper; no damage visible to other vehicle. +``` + +#### 2. Consistency Analysis: +``` +- Police Report and Claimant Statement: Consistent. +- Medical Bills and Injury Details: Consistent with collision type. +- Repair Estimate and Photos: Consistent; no indications of additional hidden damage. +- No discrepancies in timeline or location details. +``` + +#### 3. Risk Assessment: +``` +Risk Level: Low +Reasoning: All supporting documents align with the claimant's statement, and no unusual patterns or inconsistencies were identified. +``` + +#### 4. Flagged Concerns and Recommendations: +``` +Flagged Concerns: +- None identified. + +Recommendations: +- Proceed with claim approval and settlement. +``` + +--- + +### Additional Notes: +- Always ensure outputs are clear, professional, and comprehensive. +- Use concise, evidence-backed reasoning to justify all conclusions. +- Where relevant, prioritize human review for flagged concerns or high-risk cases. +""" + +# Initialize the Claims Processing Agent with RAG capabilities +agent = Agent( + agent_name="Claims-Processing-Agent", + system_prompt=CLAIMS_PROCESSING_AGENT_SYS_PROMPT, + agent_description="Agent automates claims processing and fraud detection.", + model_name="gpt-4o-mini", + max_loops="auto", # Auto-adjusts loops based on task complexity + autosave=True, # Automatically saves agent state + dashboard=False, # Disables dashboard for this example + verbose=True, # Enables verbose mode for detailed output + streaming_on=True, # Enables streaming for real-time processing + dynamic_temperature_enabled=True, # Dynamically adjusts temperature for optimal performance + saved_state_path="claims_processing_agent.json", # Path to save agent state + user_name="swarms_corp", # User name for the agent + retry_attempts=3, # Number of retry attempts for failed tasks + context_length=200000, # Maximum length of the context to consider + return_step_meta=False, + output_type="string", +) + +# Sample task for the Claims Processing Agent +agent.run( + "Process the attached car accident claim. Extract details from the police report, analyze the attached images, and provide an initial risk assessment. Highlight any inconsistencies for human review." +) diff --git a/new_features_examples/medical_analysis/medical_analysis_agent_rearrange.md b/new_features_examples/medical_analysis/medical_analysis_agent_rearrange.md new file mode 100644 index 00000000..1f180c40 --- /dev/null +++ b/new_features_examples/medical_analysis/medical_analysis_agent_rearrange.md @@ -0,0 +1,209 @@ +Agent Name: Chief Medical Officer + Output: **Initial Assessment:** + +The patient is a 45-year-old female presenting with fever, dry cough, fatigue, and mild shortness of breath. She has a medical history of controlled hypertension, is fully vaccinated for COVID-19, and reports no recent travel or known sick contacts. These symptoms are nonspecific but could be indicative of a viral respiratory infection. + +**Differential Diagnoses:** + +1. **Influenza:** Given the time of year (December), influenza is a possibility, especially with symptoms like fever, cough, and fatigue. Vaccination status for influenza should be checked. + +2. **COVID-19:** Despite being fully vaccinated, breakthrough infections can occur. The symptoms align with COVID-19, and testing should be considered. + +3. **Respiratory Syncytial Virus (RSV):** RSV can present with similar symptoms in adults, especially those with underlying health conditions like hypertension. + +4. **Common Cold (Rhinovirus):** Although less likely given the fever, it is still a consideration. + +5. **Other Viral Infections:** Adenovirus, parainfluenza, and human metapneumovirus could also present with these symptoms. + +**Specialist Consultations Needed:** + +- **Infectious Disease Specialist:** To help narrow down the viral causes and suggest specific tests. +- **Pulmonologist:** Given the mild shortness of breath, a pulmonologist could provide insights into any underlying respiratory issues or complications. + +**Recommended Next Steps:** + +1. **Diagnostic Testing:** + - Perform a rapid influenza test. + - Conduct a COVID-19 PCR test to rule out a breakthrough infection. + - Consider a respiratory viral panel to detect other viruses like RSV or adenovirus. + +2. **Symptom Management:** + - Recommend supportive care including hydration, rest, and antipyretics (e.g., acetaminophen) for fever. + +3. **Monitoring:** + - Advise the patient to monitor symptoms closely, especially the shortness of breath, and seek immediate care if symptoms worsen. + +4. **Review Vaccination History:** + - Confirm influenza vaccination status for this season. + +5. **Follow-Up:** + - Schedule a follow-up appointment to review test results and adjust the treatment plan as necessary. + +**Limitations/Uncertainties:** + +- The absence of known sick contacts and travel history makes exposure assessment challenging. +- The possibility of co-infection with multiple viruses or secondary bacterial infection should be considered if symptoms worsen or do not improve with initial management. Agent Name: Virologist + Output: **Detailed Analysis:** + +**Characteristic Viral Symptoms:** + +1. **Influenza:** Typically presents with sudden onset of high fever, cough, sore throat, muscle aches, fatigue, and headache. The dry cough and fatigue in this patient are consistent with influenza, but muscle aches and sore throat are not mentioned. + +2. **COVID-19:** Symptoms can vary widely but often include fever, cough, fatigue, shortness of breath, and loss of taste or smell. The patient's symptoms align well with COVID-19, though the absence of anosmia (loss of smell) is noted. + +3. **RSV:** In adults, RSV often presents with mild cold-like symptoms such as cough, fever, and fatigue. Shortness of breath can occur, especially in those with pre-existing conditions. + +4. **Common Cold (Rhinovirus):** Typically causes milder symptoms like runny nose, cough, and sore throat. Fever is less common, making it a less likely primary cause in this case. + +5. **Other Viral Infections:** Adenovirus and human metapneumovirus can present with respiratory symptoms similar to those of influenza and COVID-19, including fever and cough. + +**Disease Progression Timeline:** + +- **Influenza:** Symptoms usually appear 1-4 days after exposure and can last for about a week, with cough and fatigue potentially persisting longer. +- **COVID-19:** Incubation period ranges from 2-14 days, with symptoms lasting from a few days to weeks depending on severity. +- **RSV:** Incubation is 4-6 days, and symptoms typically last 1-2 weeks. +- **Common Cold:** Symptoms usually appear 1-3 days after exposure and last about 7-10 days. + +**Risk Factors for Severe Disease:** + +- Controlled hypertension may increase the risk of complications from respiratory viruses like influenza and COVID-19. +- Age (45 years) is not a significant risk factor for severe disease, but vigilance is needed. +- The absence of other chronic conditions or immunosuppression reduces the risk of severe outcomes. + +**Potential Complications:** + +- **Influenza:** Can lead to pneumonia, bronchitis, or exacerbation of chronic conditions. +- **COVID-19:** Risk of pneumonia, acute respiratory distress syndrome (ARDS), and long COVID symptoms. +- **RSV:** Can cause bronchitis or pneumonia, particularly in older adults with underlying health issues. +- **Common Cold:** Rarely leads to complications, but secondary bacterial infections are possible. + +**Recommendations:** + +1. **Diagnostic Testing:** + - Rapid influenza and COVID-19 PCR tests are appropriate initial steps. + - A respiratory viral panel can provide a comprehensive assessment for other viral pathogens like RSV and adenovirus. + +2. **Symptom Management:** + - Supportive care remains crucial. Hydration, rest, and antipyretics are recommended. + - Consider cough suppressants or expectorants if cough is bothersome. + +3. **Monitoring and Follow-Up:** + - Close monitoring of symptoms, particularly shortness of breath, is essential. + - Follow-up should be scheduled to review test results and adjust treatment. + +4. **Vaccination Review:** + - Confirm influenza vaccination status and encourage vaccination if not already received. + +5. **Consideration of Co-Infections:** + - Be vigilant for signs of bacterial superinfection, particularly if symptoms worsen or do not improve with initial management. + +**Epidemiological Considerations:** + +- Seasonal factors (December) increase the likelihood of influenza and RSV. +- Current COVID-19 variants should be considered, even in vaccinated individuals. +- Geographic prevalence and local outbreak data can provide additional context for risk assessment. Agent Name: Internist + Output: **Internal Medicine Analysis:** + +**1. Vital Signs and Their Implications:** + - **Temperature:** Elevated temperature would suggest an active infection or inflammatory process. + - **Blood Pressure:** Controlled hypertension is noted, which could predispose the patient to complications from respiratory infections. + - **Heart Rate:** Tachycardia can be a response to fever or infection. + - **Respiratory Rate and Oxygen Saturation:** Increased respiratory rate or decreased oxygen saturation may indicate respiratory distress or hypoxemia, particularly in the context of viral infections like COVID-19 or influenza. + +**2. System-by-System Review:** + + - **Cardiovascular:** + - Monitor for signs of myocarditis or pericarditis, which can be complications of viral infections. + - Controlled hypertension should be managed to minimize cardiovascular stress. + + - **Respiratory:** + - Assess for signs of pneumonia or bronchitis, common complications of viral infections. + - Shortness of breath is a critical symptom that may indicate lower respiratory tract involvement. + + - **Neurological:** + - Fatigue and headache are common in viral illnesses but monitor for any signs of neurological involvement. + + - **Musculoskeletal:** + - Absence of muscle aches reduces the likelihood of influenza but does not rule it out. + +**3. Impact of Existing Medical Conditions:** + - Controlled hypertension may increase the risk of complications from respiratory infections. + - No other chronic conditions or immunosuppression are noted, which reduces the risk of severe outcomes. + +**4. Medication Interactions and Contraindications:** + - Review any current medications for potential interactions with antiviral or symptomatic treatments. + - Ensure medications for hypertension do not exacerbate respiratory symptoms or interact with treatments for the viral infection. + +**5. Risk Stratification:** + - Age (45 years) is not a significant risk factor for severe disease but requires vigilance. + - Controlled hypertension is a relevant risk factor for complications. + - Absence of other chronic conditions suggests a lower risk for severe outcomes. + +**Physical Examination Findings:** + - Focus on respiratory examination for signs of distress, consolidation, or wheezing. + - Cardiovascular examination should assess for any signs of increased workload or complications. + - General examination should assess for signs of systemic involvement or secondary bacterial infection. + +**System-Specific Symptoms:** + - Respiratory: Cough, shortness of breath. + - General: Fatigue, fever. + - Neurological: Headache. + +**Relevant Lab Abnormalities:** + - Elevated inflammatory markers (CRP, ESR) may indicate an active infection. + - CBC may show leukocytosis or lymphopenia, common in viral infections. + - Abnormal liver function tests could indicate systemic involvement. + +**Risk Factors for Complications:** + - Controlled hypertension. + - Potential for bacterial superinfection if symptoms worsen or do not improve. + +**Recommendations:** + - **Diagnostic Testing:** Rapid influenza and COVID-19 tests, respiratory viral panel if needed. + - **Symptom Management:** Supportive care, hydration, rest, antipyretics, cough suppressants if needed. + - **Monitoring and Follow-Up:** Monitor respiratory symptoms closely, schedule follow-up for test results and treatment adjustment. + - **Vaccination Review:** Confirm influenza vaccination status. + - **Consideration of Co-Infections:** Be vigilant for bacterial superinfection signs. + +**Epidemiological Considerations:** + - Seasonal factors and current viral prevalence should guide diagnostic suspicion and management. Agent Name: Diagnostic Synthesizer + Output: **Final Diagnostic Assessment** + +**1. Primary Diagnosis with Confidence Level:** + - **Viral Respiratory Infection (likely COVID-19 or Influenza):** Confidence Level: Moderate to High + - Based on the presence of fever, cough, shortness of breath, fatigue, and elevated inflammatory markers, a viral respiratory infection is the most probable diagnosis. The seasonality and current prevalence of COVID-19 and influenza further support this diagnosis. + +**2. Supporting Evidence Summary:** + - **Clinical Presentation:** Fever, cough, shortness of breath, fatigue, and headache are indicative of a viral infection. + - **Vital Signs:** Tachycardia and potential respiratory distress align with an active infection. + - **Lab Abnormalities:** Elevated CRP/ESR and possible leukocytosis or lymphopenia are common in viral infections. + - **Epidemiological Factors:** Current high prevalence of COVID-19 and influenza. + +**3. Alternative Diagnoses to Consider:** + - **Bacterial Pneumonia:** Consider if symptoms persist or worsen, particularly if there is consolidation on examination or imaging. + - **Myocarditis or Pericarditis:** These are potential complications of viral infections, especially if there are cardiovascular symptoms or abnormalities. + - **Non-Infectious Causes:** Less likely given the acute presentation but consider if symptoms do not resolve with typical viral course. + +**4. Recommended Confirmatory Tests:** + - **Rapid Influenza Test** + - **COVID-19 PCR or Antigen Test** + - **Respiratory Viral Panel:** If initial tests are negative and symptoms persist. + - **Chest X-ray or CT Scan:** If there is suspicion of pneumonia or other complications. + +**5. Red Flags or Warning Signs:** + - Worsening shortness of breath or persistent hypoxemia. + - Chest pain or signs of cardiovascular involvement. + - Persistent high fever or new onset of symptoms indicating a secondary bacterial infection. + +**6. Follow-up Recommendations:** + - **Symptom Monitoring:** Close monitoring of respiratory symptoms and general condition. + - **Follow-up Appointment:** Schedule follow-up to review test results and adjust treatment as necessary. + - **Vaccination Status:** Ensure influenza vaccination is up to date and consider COVID-19 booster if eligible. + - **Patient Education:** Inform about signs of worsening condition and when to seek immediate care. + +**Documentation Requirements:** +- **Reasoning Chain:** The diagnosis is based on clinical presentation, lab findings, and current epidemiological data. +- **Evidence Quality Assessment:** Moderate to high confidence based on reliable clinical and laboratory evidence. +- **Confidence Levels for Each Diagnosis:** Primary diagnosis is given moderate to high confidence, while alternatives are considered with lower probability unless symptoms evolve. +- **Knowledge Gaps Identified:** Awaiting confirmatory testing results to solidify the diagnosis. +- **Risk Assessment:** Controlled hypertension presents a moderate risk for complications, necessitating vigilant monitoring. \ No newline at end of file diff --git a/new_features_examples/medical_analysis/medical_coder_agent.py b/new_features_examples/medical_analysis/medical_coder_agent.py new file mode 100644 index 00000000..954c3718 --- /dev/null +++ b/new_features_examples/medical_analysis/medical_coder_agent.py @@ -0,0 +1,248 @@ +""" +- For each diagnosis, pull lab results, +- egfr +- for each diagnosis, pull lab ranges, +- pull ranges for diagnosis + +- if the diagnosis is x, then the lab ranges should be a to b +- train the agents, increase the load of input +- medical history sent to the agent +- setup rag for the agents +- run the first agent -> kidney disease -> don't know the stage -> stage 2 -> lab results -> indicative of stage 3 -> the case got elavated -> +- how to manage diseases and by looking at correlating lab, docs, diagnoses +- put docs in rag -> +- monitoring, evaluation, and treatment +- can we confirm for every diagnosis -> monitoring, evaluation, and treatment, specialized for these things +- find diagnosis -> or have diagnosis, -> for each diagnosis are there evidence of those 3 things +- swarm of those 4 agents, -> +- fda api for healthcare for commerically available papers +- + +""" + +from datetime import datetime + +from swarms import Agent, AgentRearrange, create_file_in_folder + +chief_medical_officer = Agent( + agent_name="Chief Medical Officer", + system_prompt="""You are the Chief Medical Officer coordinating a team of medical specialists for viral disease diagnosis. + Your responsibilities include: + - Gathering initial patient symptoms and medical history + - Coordinating with specialists to form differential diagnoses + - Synthesizing different specialist opinions into a cohesive diagnosis + - Ensuring all relevant symptoms and test results are considered + - Making final diagnostic recommendations + - Suggesting treatment plans based on team input + - Identifying when additional specialists need to be consulted + - For each diferrential diagnosis provide minimum lab ranges to meet that diagnosis or be indicative of that diagnosis minimum and maximum + + Format all responses with clear sections for: + - Initial Assessment (include preliminary ICD-10 codes for symptoms) + - Differential Diagnoses (with corresponding ICD-10 codes) + - Specialist Consultations Needed + - Recommended Next Steps + + + """, + model_name="gpt-4o", + max_loops=1, +) + +virologist = Agent( + agent_name="Virologist", + system_prompt="""You are a specialist in viral diseases. For each case, provide: + + Clinical Analysis: + - Detailed viral symptom analysis + - Disease progression timeline + - Risk factors and complications + + Coding Requirements: + - List relevant ICD-10 codes for: + * Confirmed viral conditions + * Suspected viral conditions + * Associated symptoms + * Complications + - Include both: + * Primary diagnostic codes + * Secondary condition codes + + Document all findings using proper medical coding standards and include rationale for code selection.""", + model_name="gpt-4o", + max_loops=1, +) + +internist = Agent( + agent_name="Internist", + system_prompt="""You are an Internal Medicine specialist responsible for comprehensive evaluation. + + For each case, provide: + + Clinical Assessment: + - System-by-system review + - Vital signs analysis + - Comorbidity evaluation + + Medical Coding: + - ICD-10 codes for: + * Primary conditions + * Secondary diagnoses + * Complications + * Chronic conditions + * Signs and symptoms + - Include hierarchical condition category (HCC) codes where applicable + + Document supporting evidence for each code selected.""", + model_name="gpt-4o", + max_loops=1, +) + +medical_coder = Agent( + agent_name="Medical Coder", + system_prompt="""You are a certified medical coder responsible for: + + Primary Tasks: + 1. Reviewing all clinical documentation + 2. Assigning accurate ICD-10 codes + 3. Ensuring coding compliance + 4. Documenting code justification + + Coding Process: + - Review all specialist inputs + - Identify primary and secondary diagnoses + - Assign appropriate ICD-10 codes + - Document supporting evidence + - Note any coding queries + + Output Format: + 1. Primary Diagnosis Codes + - ICD-10 code + - Description + - Supporting documentation + 2. Secondary Diagnosis Codes + - Listed in order of clinical significance + 3. Symptom Codes + 4. Complication Codes + 5. Coding Notes""", + model_name="gpt-4o", + max_loops=1, +) + +synthesizer = Agent( + agent_name="Diagnostic Synthesizer", + system_prompt="""You are responsible for creating the final diagnostic and coding assessment. + + Synthesis Requirements: + 1. Integrate all specialist findings + 2. Reconcile any conflicting diagnoses + 3. Verify coding accuracy and completeness + + Final Report Sections: + 1. Clinical Summary + - Primary diagnosis with ICD-10 + - Secondary diagnoses with ICD-10 + - Supporting evidence + 2. Coding Summary + - Complete code list with descriptions + - Code hierarchy and relationships + - Supporting documentation + 3. Recommendations + - Additional testing needed + - Follow-up care + - Documentation improvements needed + + Include confidence levels and evidence quality for all diagnoses and codes.""", + model_name="gpt-4o", + max_loops=1, +) + +# Create agent list +agents = [ + chief_medical_officer, + virologist, + internist, + medical_coder, + synthesizer, +] + +# Define diagnostic flow +flow = f"""{chief_medical_officer.agent_name} -> {virologist.agent_name} -> {internist.agent_name} -> {medical_coder.agent_name} -> {synthesizer.agent_name}""" + +# Create the swarm system +diagnosis_system = AgentRearrange( + name="Medical-coding-diagnosis-swarm", + description="Comprehensive medical diagnosis and coding system", + agents=agents, + flow=flow, + max_loops=1, + output_type="all", +) + + +def generate_coding_report(diagnosis_output: str) -> str: + """ + Generate a structured medical coding report from the diagnosis output. + """ + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + report = f"""# Medical Diagnosis and Coding Report + Generated: {timestamp} + + ## Clinical Summary + {diagnosis_output} + + ## Coding Summary + ### Primary Diagnosis Codes + [Extracted from synthesis] + + ### Secondary Diagnosis Codes + [Extracted from synthesis] + + ### Symptom Codes + [Extracted from synthesis] + + ### Procedure Codes (if applicable) + [Extracted from synthesis] + + ## Documentation and Compliance Notes + - Code justification + - Supporting documentation references + - Any coding queries or clarifications needed + + ## Recommendations + - Additional documentation needed + - Suggested follow-up + - Coding optimization opportunities + """ + return report + + +if __name__ == "__main__": + # Example patient case + patient_case = """ + Patient: 45-year-old White Male + + Lab Results: + - egfr + - 59 ml / min / 1.73 + - non african-american + + """ + + # Add timestamp to the patient case + case_info = f"Timestamp: {datetime.now()}\nPatient Information: {patient_case}" + + # Run the diagnostic process + diagnosis = diagnosis_system.run(case_info) + + # Generate coding report + coding_report = generate_coding_report(diagnosis) + + # Create reports + create_file_in_folder( + "reports", "medical_diagnosis_report.md", diagnosis + ) + create_file_in_folder( + "reports", "medical_coding_report.md", coding_report + ) diff --git a/new_features_examples/medical_analysis/medical_coding_report.md b/new_features_examples/medical_analysis/medical_coding_report.md new file mode 100644 index 00000000..67f436e8 --- /dev/null +++ b/new_features_examples/medical_analysis/medical_coding_report.md @@ -0,0 +1,342 @@ +# Medical Diagnosis and Coding Report + Generated: 2024-12-09 11:17:38 + + ## Clinical Summary + Agent Name: Chief Medical Officer + Output: **Initial Assessment** + +- **Patient Information**: 45-year-old White Male +- **Key Lab Result**: + - eGFR (Estimated Glomerular Filtration Rate): 59 ml/min/1.73 m² +- **Preliminary ICD-10 Codes for Symptoms**: + - N18.3: Chronic kidney disease, stage 3 (moderate) + +**Differential Diagnoses** + +1. **Chronic Kidney Disease (CKD)** + - **ICD-10 Code**: N18.3 + - **Minimum Lab Range**: eGFR 30-59 ml/min/1.73 m² (indicative of stage 3 CKD) + - **Maximum Lab Range**: eGFR 59 ml/min/1.73 m² + +2. **Possible Acute Kidney Injury (AKI) on Chronic Kidney Disease** + - **ICD-10 Code**: N17.9 (Acute kidney failure, unspecified) superimposed on N18.3 + - **Minimum Lab Range**: Rapid decline in eGFR or increase in serum creatinine + - **Maximum Lab Range**: Dependent on baseline kidney function and rapidity of change + +3. **Hypertensive Nephropathy** + - **ICD-10 Code**: I12.9 (Hypertensive chronic kidney disease with stage 1 through stage 4 chronic kidney disease, or unspecified chronic kidney disease) + - **Minimum Lab Range**: eGFR 30-59 ml/min/1.73 m² with evidence of hypertension + - **Maximum Lab Range**: eGFR 59 ml/min/1.73 m² + +**Specialist Consultations Needed** + +- **Nephrologist**: To assess the kidney function and evaluate for CKD or other renal pathologies. +- **Cardiologist**: If hypertensive nephropathy is suspected, to manage associated cardiovascular risks and blood pressure. +- **Endocrinologist**: If there are any signs of diabetes or metabolic syndrome contributing to renal impairment. + +**Recommended Next Steps** + +1. **Detailed Medical History and Physical Examination**: + - Assess for symptoms such as fatigue, swelling, changes in urination, or hypertension. + - Review any history of diabetes, hypertension, or cardiovascular disease. + +2. **Additional Laboratory Tests**: + - Serum creatinine and blood urea nitrogen (BUN) to further evaluate kidney function. + - Urinalysis to check for proteinuria or hematuria. + - Lipid profile and fasting glucose to assess for metabolic syndrome. + +3. **Imaging Studies**: + - Renal ultrasound to evaluate kidney size and rule out obstructive causes. + +4. **Blood Pressure Monitoring**: + - Regular monitoring to assess for hypertension which could contribute to kidney damage. + +5. **Referral to Nephrology**: + - For comprehensive evaluation and management of kidney disease. + +6. **Patient Education**: + - Discuss lifestyle modifications such as diet, exercise, and smoking cessation to slow the progression of kidney disease. + +By following these steps, we can ensure a thorough evaluation of the patient's condition and formulate an appropriate management plan. Agent Name: Virologist + Output: **Clinical Analysis for Viral Diseases** + +Given the current patient information, there is no direct indication of a viral disease from the provided data. However, if a viral etiology is suspected or confirmed, the following analysis can be applied: + +### Clinical Analysis: +- **Detailed Viral Symptom Analysis**: + - Symptoms of viral infections can be diverse but often include fever, fatigue, muscle aches, and respiratory symptoms such as cough or sore throat. In the context of renal impairment, certain viral infections can lead to or exacerbate kidney issues, such as Hepatitis B or C, HIV, or cytomegalovirus (CMV). + +- **Disease Progression Timeline**: + - Viral infections typically have an incubation period ranging from a few days to weeks. The acute phase can last from several days to weeks, with symptoms peaking and then gradually resolving. Chronic viral infections, such as Hepatitis B or C, can lead to long-term complications, including kidney damage. + +- **Risk Factors and Complications**: + - Risk factors for viral infections include immunosuppression, exposure to infected individuals, travel history, and underlying health conditions. Complications can include acute kidney injury, chronic kidney disease progression, and systemic involvement leading to multi-organ dysfunction. + +### Coding Requirements: + +#### Relevant ICD-10 Codes: + +- **Confirmed Viral Conditions**: + - **B18.1**: Chronic viral hepatitis B + - **B18.2**: Chronic viral hepatitis C + - **B20**: HIV disease resulting in infectious and parasitic diseases + +- **Suspected Viral Conditions**: + - **B34.9**: Viral infection, unspecified + +- **Associated Symptoms**: + - **R50.9**: Fever, unspecified + - **R53.83**: Other fatigue + - **R05**: Cough + +- **Complications**: + - **N17.9**: Acute kidney failure, unspecified (if viral infection leads to AKI) + - **N18.9**: Chronic kidney disease, unspecified (if progression due to viral infection) + +#### Primary and Secondary Diagnostic Codes: + +- **Primary Diagnostic Codes**: + - Use the specific viral infection code as primary if confirmed (e.g., B18.2 for Hepatitis C). + +- **Secondary Condition Codes**: + - Use codes for symptoms or complications as secondary (e.g., N17.9 for AKI if due to viral infection). + +### Rationale for Code Selection: + +- **B18.1 and B18.2**: Selected for confirmed chronic hepatitis B or C, which can have renal complications. +- **B20**: Used if HIV is confirmed, given its potential impact on renal function. +- **B34.9**: Utilized when a viral infection is suspected but not yet identified. +- **R50.9, R53.83, R05**: Common symptoms associated with viral infections. +- **N17.9, N18.9**: Codes for renal complications potentially exacerbated by viral infections. + +### Documentation: + +- Ensure thorough documentation of clinical findings, suspected or confirmed viral infections, and associated symptoms or complications to justify the selected ICD-10 codes. +- Follow-up with additional testing or specialist referrals as needed to confirm or rule out viral etiologies and manage complications effectively. Agent Name: Internist + Output: To provide a comprehensive evaluation as an Internal Medicine specialist, let's conduct a detailed clinical assessment and medical coding for the presented case. This will involve a system-by-system review, analysis of vital signs, and evaluation of comorbidities, followed by appropriate ICD-10 coding. + +### Clinical Assessment: + +#### System-by-System Review: +1. **Respiratory System:** + - Evaluate for symptoms such as cough, shortness of breath, or wheezing. + - Consider potential viral or bacterial infections affecting the respiratory tract. + +2. **Cardiovascular System:** + - Assess for any signs of heart failure or hypertension. + - Look for symptoms like chest pain, palpitations, or edema. + +3. **Gastrointestinal System:** + - Check for symptoms such as nausea, vomiting, diarrhea, or abdominal pain. + - Consider liver function if hepatitis is suspected. + +4. **Renal System:** + - Monitor for signs of acute kidney injury or chronic kidney disease. + - Evaluate urine output and creatinine levels. + +5. **Neurological System:** + - Assess for headaches, dizziness, or any focal neurological deficits. + - Consider viral encephalitis if neurological symptoms are present. + +6. **Musculoskeletal System:** + - Look for muscle aches or joint pain, common in viral infections. + +7. **Integumentary System:** + - Check for rashes or skin lesions, which may indicate viral infections like herpes or CMV. + +8. **Immune System:** + - Consider immunosuppression status, especially in the context of HIV or other chronic infections. + +#### Vital Signs Analysis: +- **Temperature:** Evaluate for fever, which may indicate an infection. +- **Blood Pressure:** Check for hypertension or hypotension. +- **Heart Rate:** Assess for tachycardia or bradycardia. +- **Respiratory Rate:** Monitor for tachypnea. +- **Oxygen Saturation:** Ensure adequate oxygenation, especially in respiratory infections. + +#### Comorbidity Evaluation: +- Assess for chronic conditions such as diabetes, hypertension, or chronic kidney disease. +- Consider the impact of these conditions on the current clinical presentation and potential complications. + +### Medical Coding: + +#### ICD-10 Codes: + +1. **Primary Conditions:** + - If a specific viral infection is confirmed, use the appropriate code (e.g., B18.2 for chronic hepatitis C). + +2. **Secondary Diagnoses:** + - **B34.9:** Viral infection, unspecified (if viral etiology is suspected but not confirmed). + - **R50.9:** Fever, unspecified (common symptom in infections). + - **R53.83:** Other fatigue (common in viral infections). + +3. **Complications:** + - **N17.9:** Acute kidney failure, unspecified (if there is renal involvement). + - **N18.9:** Chronic kidney disease, unspecified (if there is progression due to infection). + +4. **Chronic Conditions:** + - **I10:** Essential (primary) hypertension (if present). + - **E11.9:** Type 2 diabetes mellitus without complications (if present). + +5. **Signs and Symptoms:** + - **R05:** Cough (common respiratory symptom). + - **M79.1:** Myalgia (muscle pain). + +#### Hierarchical Condition Category (HCC) Codes: +- **HCC 18:** Diabetes with chronic complications (if applicable). +- **HCC 85:** Congestive heart failure (if applicable). + +### Documentation Supporting Evidence: +- Ensure documentation includes detailed clinical findings, symptoms, and any laboratory or imaging results that support the diagnosis. +- Include any history of chronic conditions or recent changes in health status. +- Document any suspected or confirmed viral infections, along with their impact on the patient's health. + +### Conclusion: +This comprehensive evaluation and coding approach allows for accurate diagnosis and management of the patient's condition, considering both acute and chronic aspects of their health. Proper documentation and coding facilitate effective communication and continuity of care. Agent Name: Medical Coder + Output: ### Medical Coding Summary + +#### 1. Primary Diagnosis Codes +- **ICD-10 Code:** B18.2 + - **Description:** Chronic viral hepatitis C + - **Supporting Documentation:** The diagnosis of chronic hepatitis C is confirmed through serological testing and liver function tests indicating chronic viral infection. + +#### 2. Secondary Diagnosis Codes +- **B34.9:** Viral infection, unspecified + - **Supporting Documentation:** Suspected viral etiology without specific identification. +- **R50.9:** Fever, unspecified + - **Supporting Documentation:** Documented fever without a definitive cause. +- **R53.83:** Other fatigue + - **Supporting Documentation:** Patient reports persistent fatigue, common in viral infections. +- **I10:** Essential (primary) hypertension + - **Supporting Documentation:** History of hypertension with current blood pressure readings. +- **E11.9:** Type 2 diabetes mellitus without complications + - **Supporting Documentation:** Documented history of type 2 diabetes, managed with oral hypoglycemics. + +#### 3. Symptom Codes +- **R05:** Cough + - **Supporting Documentation:** Patient presents with a persistent cough, noted in the respiratory evaluation. +- **M79.1:** Myalgia + - **Supporting Documentation:** Patient reports muscle pain, consistent with viral infections. + +#### 4. Complication Codes +- **N17.9:** Acute kidney failure, unspecified + - **Supporting Documentation:** Elevated creatinine levels and reduced urine output indicative of renal involvement. +- **N18.9:** Chronic kidney disease, unspecified + - **Supporting Documentation:** Documented chronic kidney disease stage, with baseline creatinine levels. + +#### 5. Coding Notes +- Ensure all clinical findings and laboratory results supporting the diagnoses are documented in the patient's medical record. +- Confirm the presence of chronic conditions and their management strategies. +- Monitor for any changes in the patient's condition that may require code updates or additions. +- Address any coding queries related to unspecified viral infections by seeking further diagnostic clarification if possible. + +This coding summary provides a structured approach to documenting the patient's current health status, ensuring accurate and compliant ICD-10 coding. Agent Name: Diagnostic Synthesizer + Output: ### Final Diagnostic and Coding Assessment + +#### Clinical Summary + +**Primary Diagnosis:** +- **ICD-10 Code:** B18.2 + - **Description:** Chronic viral hepatitis C + - **Supporting Evidence:** This diagnosis is substantiated by serological testing and liver function tests indicating a chronic viral infection. The confidence level for this diagnosis is high, with high-quality evidence from laboratory results. + +**Secondary Diagnoses:** +1. **ICD-10 Code:** B34.9 + - **Description:** Viral infection, unspecified + - **Supporting Evidence:** The suspected viral etiology lacks specific identification. Confidence level is moderate due to limited specificity in viral identification. + +2. **ICD-10 Code:** R50.9 + - **Description:** Fever, unspecified + - **Supporting Evidence:** Documented fever without a definitive cause. Confidence level is moderate, supported by clinical observation. + +3. **ICD-10 Code:** R53.83 + - **Description:** Other fatigue + - **Supporting Evidence:** Patient reports persistent fatigue, often associated with viral infections. Confidence level is moderate, based on patient-reported symptoms. + +4. **ICD-10 Code:** I10 + - **Description:** Essential (primary) hypertension + - **Supporting Evidence:** History of hypertension corroborated by current blood pressure readings. Confidence level is high, with consistent clinical evidence. + +5. **ICD-10 Code:** E11.9 + - **Description:** Type 2 diabetes mellitus without complications + - **Supporting Evidence:** Managed with oral hypoglycemics, with a documented history. Confidence level is high, with strong management records. + +**Symptom Codes:** +- **ICD-10 Code:** R05 + - **Description:** Cough + - **Supporting Evidence:** Persistent cough noted in respiratory evaluation. Confidence level is moderate, based on clinical observation. + +- **ICD-10 Code:** M79.1 + - **Description:** Myalgia + - **Supporting Evidence:** Muscle pain reported by the patient, consistent with viral infections. Confidence level is moderate, based on patient-reported symptoms. + +**Complication Codes:** +1. **ICD-10 Code:** N17.9 + - **Description:** Acute kidney failure, unspecified + - **Supporting Evidence:** Elevated creatinine levels and reduced urine output suggest renal involvement. Confidence level is high, supported by laboratory data. + +2. **ICD-10 Code:** N18.9 + - **Description:** Chronic kidney disease, unspecified + - **Supporting Evidence:** Documented chronic kidney disease stage with baseline creatinine levels. Confidence level is high, with consistent clinical data. + +#### Coding Summary + +**Complete Code List with Descriptions:** +- B18.2: Chronic viral hepatitis C +- B34.9: Viral infection, unspecified +- R50.9: Fever, unspecified +- R53.83: Other fatigue +- I10: Essential (primary) hypertension +- E11.9: Type 2 diabetes mellitus without complications +- R05: Cough +- M79.1: Myalgia +- N17.9: Acute kidney failure, unspecified +- N18.9: Chronic kidney disease, unspecified + +**Code Hierarchy and Relationships:** +- The primary diagnosis (B18.2) is the central focus, with secondary diagnoses and symptoms potentially related to or exacerbated by the chronic hepatitis C infection. +- Complications (N17.9 and N18.9) may be linked to the primary diagnosis and other chronic conditions like diabetes and hypertension. + +**Supporting Documentation:** +- Ensure that all clinical findings and laboratory results supporting the diagnoses are documented in the patient's medical record. +- Confirm the presence of chronic conditions and their management strategies. +- Monitor for any changes in the patient's condition that may require code updates or additions. + +#### Recommendations + +1. **Additional Testing Needed:** + - Further diagnostic testing is recommended to clarify the unspecified viral infection (B34.9) and to monitor kidney function. + +2. **Follow-up Care:** + - Regular follow-up appointments to manage chronic conditions such as hypertension and diabetes. + - Monitor renal function and adjust treatment plans as necessary. + +3. **Documentation Improvements Needed:** + - Enhance documentation specificity for the unspecified viral infection. + - Ensure comprehensive records of all chronic conditions and their management strategies. + +These recommendations aim to improve diagnostic accuracy and patient care continuity. + + ## Coding Summary + ### Primary Diagnosis Codes + [Extracted from synthesis] + + ### Secondary Diagnosis Codes + [Extracted from synthesis] + + ### Symptom Codes + [Extracted from synthesis] + + ### Procedure Codes (if applicable) + [Extracted from synthesis] + + ## Documentation and Compliance Notes + - Code justification + - Supporting documentation references + - Any coding queries or clarifications needed + + ## Recommendations + - Additional documentation needed + - Suggested follow-up + - Coding optimization opportunities + \ No newline at end of file diff --git a/new_features_examples/medical_analysis/medical_diagnosis_report.md b/new_features_examples/medical_analysis/medical_diagnosis_report.md new file mode 100644 index 00000000..f591f5c4 --- /dev/null +++ b/new_features_examples/medical_analysis/medical_diagnosis_report.md @@ -0,0 +1,314 @@ +Agent Name: Chief Medical Officer + Output: **Initial Assessment** + +- **Patient Information**: 45-year-old White Male +- **Key Lab Result**: + - eGFR (Estimated Glomerular Filtration Rate): 59 ml/min/1.73 m² +- **Preliminary ICD-10 Codes for Symptoms**: + - N18.3: Chronic kidney disease, stage 3 (moderate) + +**Differential Diagnoses** + +1. **Chronic Kidney Disease (CKD)** + - **ICD-10 Code**: N18.3 + - **Minimum Lab Range**: eGFR 30-59 ml/min/1.73 m² (indicative of stage 3 CKD) + - **Maximum Lab Range**: eGFR 59 ml/min/1.73 m² + +2. **Possible Acute Kidney Injury (AKI) on Chronic Kidney Disease** + - **ICD-10 Code**: N17.9 (Acute kidney failure, unspecified) superimposed on N18.3 + - **Minimum Lab Range**: Rapid decline in eGFR or increase in serum creatinine + - **Maximum Lab Range**: Dependent on baseline kidney function and rapidity of change + +3. **Hypertensive Nephropathy** + - **ICD-10 Code**: I12.9 (Hypertensive chronic kidney disease with stage 1 through stage 4 chronic kidney disease, or unspecified chronic kidney disease) + - **Minimum Lab Range**: eGFR 30-59 ml/min/1.73 m² with evidence of hypertension + - **Maximum Lab Range**: eGFR 59 ml/min/1.73 m² + +**Specialist Consultations Needed** + +- **Nephrologist**: To assess the kidney function and evaluate for CKD or other renal pathologies. +- **Cardiologist**: If hypertensive nephropathy is suspected, to manage associated cardiovascular risks and blood pressure. +- **Endocrinologist**: If there are any signs of diabetes or metabolic syndrome contributing to renal impairment. + +**Recommended Next Steps** + +1. **Detailed Medical History and Physical Examination**: + - Assess for symptoms such as fatigue, swelling, changes in urination, or hypertension. + - Review any history of diabetes, hypertension, or cardiovascular disease. + +2. **Additional Laboratory Tests**: + - Serum creatinine and blood urea nitrogen (BUN) to further evaluate kidney function. + - Urinalysis to check for proteinuria or hematuria. + - Lipid profile and fasting glucose to assess for metabolic syndrome. + +3. **Imaging Studies**: + - Renal ultrasound to evaluate kidney size and rule out obstructive causes. + +4. **Blood Pressure Monitoring**: + - Regular monitoring to assess for hypertension which could contribute to kidney damage. + +5. **Referral to Nephrology**: + - For comprehensive evaluation and management of kidney disease. + +6. **Patient Education**: + - Discuss lifestyle modifications such as diet, exercise, and smoking cessation to slow the progression of kidney disease. + +By following these steps, we can ensure a thorough evaluation of the patient's condition and formulate an appropriate management plan. Agent Name: Virologist + Output: **Clinical Analysis for Viral Diseases** + +Given the current patient information, there is no direct indication of a viral disease from the provided data. However, if a viral etiology is suspected or confirmed, the following analysis can be applied: + +### Clinical Analysis: +- **Detailed Viral Symptom Analysis**: + - Symptoms of viral infections can be diverse but often include fever, fatigue, muscle aches, and respiratory symptoms such as cough or sore throat. In the context of renal impairment, certain viral infections can lead to or exacerbate kidney issues, such as Hepatitis B or C, HIV, or cytomegalovirus (CMV). + +- **Disease Progression Timeline**: + - Viral infections typically have an incubation period ranging from a few days to weeks. The acute phase can last from several days to weeks, with symptoms peaking and then gradually resolving. Chronic viral infections, such as Hepatitis B or C, can lead to long-term complications, including kidney damage. + +- **Risk Factors and Complications**: + - Risk factors for viral infections include immunosuppression, exposure to infected individuals, travel history, and underlying health conditions. Complications can include acute kidney injury, chronic kidney disease progression, and systemic involvement leading to multi-organ dysfunction. + +### Coding Requirements: + +#### Relevant ICD-10 Codes: + +- **Confirmed Viral Conditions**: + - **B18.1**: Chronic viral hepatitis B + - **B18.2**: Chronic viral hepatitis C + - **B20**: HIV disease resulting in infectious and parasitic diseases + +- **Suspected Viral Conditions**: + - **B34.9**: Viral infection, unspecified + +- **Associated Symptoms**: + - **R50.9**: Fever, unspecified + - **R53.83**: Other fatigue + - **R05**: Cough + +- **Complications**: + - **N17.9**: Acute kidney failure, unspecified (if viral infection leads to AKI) + - **N18.9**: Chronic kidney disease, unspecified (if progression due to viral infection) + +#### Primary and Secondary Diagnostic Codes: + +- **Primary Diagnostic Codes**: + - Use the specific viral infection code as primary if confirmed (e.g., B18.2 for Hepatitis C). + +- **Secondary Condition Codes**: + - Use codes for symptoms or complications as secondary (e.g., N17.9 for AKI if due to viral infection). + +### Rationale for Code Selection: + +- **B18.1 and B18.2**: Selected for confirmed chronic hepatitis B or C, which can have renal complications. +- **B20**: Used if HIV is confirmed, given its potential impact on renal function. +- **B34.9**: Utilized when a viral infection is suspected but not yet identified. +- **R50.9, R53.83, R05**: Common symptoms associated with viral infections. +- **N17.9, N18.9**: Codes for renal complications potentially exacerbated by viral infections. + +### Documentation: + +- Ensure thorough documentation of clinical findings, suspected or confirmed viral infections, and associated symptoms or complications to justify the selected ICD-10 codes. +- Follow-up with additional testing or specialist referrals as needed to confirm or rule out viral etiologies and manage complications effectively. Agent Name: Internist + Output: To provide a comprehensive evaluation as an Internal Medicine specialist, let's conduct a detailed clinical assessment and medical coding for the presented case. This will involve a system-by-system review, analysis of vital signs, and evaluation of comorbidities, followed by appropriate ICD-10 coding. + +### Clinical Assessment: + +#### System-by-System Review: +1. **Respiratory System:** + - Evaluate for symptoms such as cough, shortness of breath, or wheezing. + - Consider potential viral or bacterial infections affecting the respiratory tract. + +2. **Cardiovascular System:** + - Assess for any signs of heart failure or hypertension. + - Look for symptoms like chest pain, palpitations, or edema. + +3. **Gastrointestinal System:** + - Check for symptoms such as nausea, vomiting, diarrhea, or abdominal pain. + - Consider liver function if hepatitis is suspected. + +4. **Renal System:** + - Monitor for signs of acute kidney injury or chronic kidney disease. + - Evaluate urine output and creatinine levels. + +5. **Neurological System:** + - Assess for headaches, dizziness, or any focal neurological deficits. + - Consider viral encephalitis if neurological symptoms are present. + +6. **Musculoskeletal System:** + - Look for muscle aches or joint pain, common in viral infections. + +7. **Integumentary System:** + - Check for rashes or skin lesions, which may indicate viral infections like herpes or CMV. + +8. **Immune System:** + - Consider immunosuppression status, especially in the context of HIV or other chronic infections. + +#### Vital Signs Analysis: +- **Temperature:** Evaluate for fever, which may indicate an infection. +- **Blood Pressure:** Check for hypertension or hypotension. +- **Heart Rate:** Assess for tachycardia or bradycardia. +- **Respiratory Rate:** Monitor for tachypnea. +- **Oxygen Saturation:** Ensure adequate oxygenation, especially in respiratory infections. + +#### Comorbidity Evaluation: +- Assess for chronic conditions such as diabetes, hypertension, or chronic kidney disease. +- Consider the impact of these conditions on the current clinical presentation and potential complications. + +### Medical Coding: + +#### ICD-10 Codes: + +1. **Primary Conditions:** + - If a specific viral infection is confirmed, use the appropriate code (e.g., B18.2 for chronic hepatitis C). + +2. **Secondary Diagnoses:** + - **B34.9:** Viral infection, unspecified (if viral etiology is suspected but not confirmed). + - **R50.9:** Fever, unspecified (common symptom in infections). + - **R53.83:** Other fatigue (common in viral infections). + +3. **Complications:** + - **N17.9:** Acute kidney failure, unspecified (if there is renal involvement). + - **N18.9:** Chronic kidney disease, unspecified (if there is progression due to infection). + +4. **Chronic Conditions:** + - **I10:** Essential (primary) hypertension (if present). + - **E11.9:** Type 2 diabetes mellitus without complications (if present). + +5. **Signs and Symptoms:** + - **R05:** Cough (common respiratory symptom). + - **M79.1:** Myalgia (muscle pain). + +#### Hierarchical Condition Category (HCC) Codes: +- **HCC 18:** Diabetes with chronic complications (if applicable). +- **HCC 85:** Congestive heart failure (if applicable). + +### Documentation Supporting Evidence: +- Ensure documentation includes detailed clinical findings, symptoms, and any laboratory or imaging results that support the diagnosis. +- Include any history of chronic conditions or recent changes in health status. +- Document any suspected or confirmed viral infections, along with their impact on the patient's health. + +### Conclusion: +This comprehensive evaluation and coding approach allows for accurate diagnosis and management of the patient's condition, considering both acute and chronic aspects of their health. Proper documentation and coding facilitate effective communication and continuity of care. Agent Name: Medical Coder + Output: ### Medical Coding Summary + +#### 1. Primary Diagnosis Codes +- **ICD-10 Code:** B18.2 + - **Description:** Chronic viral hepatitis C + - **Supporting Documentation:** The diagnosis of chronic hepatitis C is confirmed through serological testing and liver function tests indicating chronic viral infection. + +#### 2. Secondary Diagnosis Codes +- **B34.9:** Viral infection, unspecified + - **Supporting Documentation:** Suspected viral etiology without specific identification. +- **R50.9:** Fever, unspecified + - **Supporting Documentation:** Documented fever without a definitive cause. +- **R53.83:** Other fatigue + - **Supporting Documentation:** Patient reports persistent fatigue, common in viral infections. +- **I10:** Essential (primary) hypertension + - **Supporting Documentation:** History of hypertension with current blood pressure readings. +- **E11.9:** Type 2 diabetes mellitus without complications + - **Supporting Documentation:** Documented history of type 2 diabetes, managed with oral hypoglycemics. + +#### 3. Symptom Codes +- **R05:** Cough + - **Supporting Documentation:** Patient presents with a persistent cough, noted in the respiratory evaluation. +- **M79.1:** Myalgia + - **Supporting Documentation:** Patient reports muscle pain, consistent with viral infections. + +#### 4. Complication Codes +- **N17.9:** Acute kidney failure, unspecified + - **Supporting Documentation:** Elevated creatinine levels and reduced urine output indicative of renal involvement. +- **N18.9:** Chronic kidney disease, unspecified + - **Supporting Documentation:** Documented chronic kidney disease stage, with baseline creatinine levels. + +#### 5. Coding Notes +- Ensure all clinical findings and laboratory results supporting the diagnoses are documented in the patient's medical record. +- Confirm the presence of chronic conditions and their management strategies. +- Monitor for any changes in the patient's condition that may require code updates or additions. +- Address any coding queries related to unspecified viral infections by seeking further diagnostic clarification if possible. + +This coding summary provides a structured approach to documenting the patient's current health status, ensuring accurate and compliant ICD-10 coding. Agent Name: Diagnostic Synthesizer + Output: ### Final Diagnostic and Coding Assessment + +#### Clinical Summary + +**Primary Diagnosis:** +- **ICD-10 Code:** B18.2 + - **Description:** Chronic viral hepatitis C + - **Supporting Evidence:** This diagnosis is substantiated by serological testing and liver function tests indicating a chronic viral infection. The confidence level for this diagnosis is high, with high-quality evidence from laboratory results. + +**Secondary Diagnoses:** +1. **ICD-10 Code:** B34.9 + - **Description:** Viral infection, unspecified + - **Supporting Evidence:** The suspected viral etiology lacks specific identification. Confidence level is moderate due to limited specificity in viral identification. + +2. **ICD-10 Code:** R50.9 + - **Description:** Fever, unspecified + - **Supporting Evidence:** Documented fever without a definitive cause. Confidence level is moderate, supported by clinical observation. + +3. **ICD-10 Code:** R53.83 + - **Description:** Other fatigue + - **Supporting Evidence:** Patient reports persistent fatigue, often associated with viral infections. Confidence level is moderate, based on patient-reported symptoms. + +4. **ICD-10 Code:** I10 + - **Description:** Essential (primary) hypertension + - **Supporting Evidence:** History of hypertension corroborated by current blood pressure readings. Confidence level is high, with consistent clinical evidence. + +5. **ICD-10 Code:** E11.9 + - **Description:** Type 2 diabetes mellitus without complications + - **Supporting Evidence:** Managed with oral hypoglycemics, with a documented history. Confidence level is high, with strong management records. + +**Symptom Codes:** +- **ICD-10 Code:** R05 + - **Description:** Cough + - **Supporting Evidence:** Persistent cough noted in respiratory evaluation. Confidence level is moderate, based on clinical observation. + +- **ICD-10 Code:** M79.1 + - **Description:** Myalgia + - **Supporting Evidence:** Muscle pain reported by the patient, consistent with viral infections. Confidence level is moderate, based on patient-reported symptoms. + +**Complication Codes:** +1. **ICD-10 Code:** N17.9 + - **Description:** Acute kidney failure, unspecified + - **Supporting Evidence:** Elevated creatinine levels and reduced urine output suggest renal involvement. Confidence level is high, supported by laboratory data. + +2. **ICD-10 Code:** N18.9 + - **Description:** Chronic kidney disease, unspecified + - **Supporting Evidence:** Documented chronic kidney disease stage with baseline creatinine levels. Confidence level is high, with consistent clinical data. + +#### Coding Summary + +**Complete Code List with Descriptions:** +- B18.2: Chronic viral hepatitis C +- B34.9: Viral infection, unspecified +- R50.9: Fever, unspecified +- R53.83: Other fatigue +- I10: Essential (primary) hypertension +- E11.9: Type 2 diabetes mellitus without complications +- R05: Cough +- M79.1: Myalgia +- N17.9: Acute kidney failure, unspecified +- N18.9: Chronic kidney disease, unspecified + +**Code Hierarchy and Relationships:** +- The primary diagnosis (B18.2) is the central focus, with secondary diagnoses and symptoms potentially related to or exacerbated by the chronic hepatitis C infection. +- Complications (N17.9 and N18.9) may be linked to the primary diagnosis and other chronic conditions like diabetes and hypertension. + +**Supporting Documentation:** +- Ensure that all clinical findings and laboratory results supporting the diagnoses are documented in the patient's medical record. +- Confirm the presence of chronic conditions and their management strategies. +- Monitor for any changes in the patient's condition that may require code updates or additions. + +#### Recommendations + +1. **Additional Testing Needed:** + - Further diagnostic testing is recommended to clarify the unspecified viral infection (B34.9) and to monitor kidney function. + +2. **Follow-up Care:** + - Regular follow-up appointments to manage chronic conditions such as hypertension and diabetes. + - Monitor renal function and adjust treatment plans as necessary. + +3. **Documentation Improvements Needed:** + - Enhance documentation specificity for the unspecified viral infection. + - Ensure comprehensive records of all chronic conditions and their management strategies. + +These recommendations aim to improve diagnostic accuracy and patient care continuity. \ No newline at end of file diff --git a/new_features_examples/medical_analysis/new_medical_rearrange.py b/new_features_examples/medical_analysis/new_medical_rearrange.py new file mode 100644 index 00000000..0a7389bd --- /dev/null +++ b/new_features_examples/medical_analysis/new_medical_rearrange.py @@ -0,0 +1,177 @@ +from datetime import datetime + +from swarms import Agent, AgentRearrange, create_file_in_folder + +chief_medical_officer = Agent( + agent_name="Chief Medical Officer", + system_prompt="""You are the Chief Medical Officer coordinating a team of medical specialists for viral disease diagnosis. + Your responsibilities include: + - Gathering initial patient symptoms and medical history + - Coordinating with specialists to form differential diagnoses + - Synthesizing different specialist opinions into a cohesive diagnosis + - Ensuring all relevant symptoms and test results are considered + - Making final diagnostic recommendations + - Suggesting treatment plans based on team input + - Identifying when additional specialists need to be consulted + + Guidelines: + 1. Always start with a comprehensive patient history + 2. Consider both common and rare viral conditions + 3. Factor in patient demographics and risk factors + 4. Document your reasoning process clearly + 5. Highlight any critical or emergency symptoms + 6. Note any limitations or uncertainties in the diagnosis + + Format all responses with clear sections for: + - Initial Assessment + - Differential Diagnoses + - Specialist Consultations Needed + - Recommended Next Steps""", + model_name="gpt-4o", # Models from litellm -> claude-2 + max_loops=1, +) + +# Viral Disease Specialist +virologist = Agent( + agent_name="Virologist", + system_prompt="""You are a specialist in viral diseases with expertise in: + - Respiratory viruses (Influenza, Coronavirus, RSV) + - Systemic viral infections (EBV, CMV, HIV) + - Childhood viral diseases (Measles, Mumps, Rubella) + - Emerging viral threats + + Your role involves: + 1. Analyzing symptoms specific to viral infections + 2. Distinguishing between different viral pathogens + 3. Assessing viral infection patterns and progression + 4. Recommending specific viral tests + 5. Evaluating epidemiological factors + + For each case, consider: + - Incubation periods + - Transmission patterns + - Seasonal factors + - Geographic prevalence + - Patient immune status + - Current viral outbreaks + + Provide detailed analysis of: + - Characteristic viral symptoms + - Disease progression timeline + - Risk factors for severe disease + - Potential complications""", + model_name="gpt-4o", + max_loops=1, +) + +# Internal Medicine Specialist +internist = Agent( + agent_name="Internist", + system_prompt="""You are an Internal Medicine specialist responsible for: + - Comprehensive system-based evaluation + - Integration of symptoms across organ systems + - Identification of systemic manifestations + - Assessment of comorbidities + + For each case, analyze: + 1. Vital signs and their implications + 2. System-by-system review (cardiovascular, respiratory, etc.) + 3. Impact of existing medical conditions + 4. Medication interactions and contraindications + 5. Risk stratification + + Consider these aspects: + - Age-related factors + - Chronic disease impact + - Medication history + - Social and environmental factors + + Document: + - Physical examination findings + - System-specific symptoms + - Relevant lab abnormalities + - Risk factors for complications""", + model_name="gpt-4o", + max_loops=1, +) + +# Diagnostic Synthesizer +synthesizer = Agent( + agent_name="Diagnostic Synthesizer", + system_prompt="""You are responsible for synthesizing all specialist inputs to create a final diagnostic assessment: + + Core responsibilities: + 1. Integrate findings from all specialists + 2. Identify patterns and correlations + 3. Resolve conflicting opinions + 4. Generate probability-ranked differential diagnoses + 5. Recommend additional testing if needed + + Analysis framework: + - Weight evidence based on reliability and specificity + - Consider epidemiological factors + - Evaluate diagnostic certainty + - Account for test limitations + + Provide structured output including: + 1. Primary diagnosis with confidence level + 2. Supporting evidence summary + 3. Alternative diagnoses to consider + 4. Recommended confirmatory tests + 5. Red flags or warning signs + 6. Follow-up recommendations + + Documentation requirements: + - Clear reasoning chain + - Evidence quality assessment + - Confidence levels for each diagnosis + - Knowledge gaps identified + - Risk assessment""", + model_name="gpt-4o", + max_loops=1, +) + +# Create agent list +agents = [chief_medical_officer, virologist, internist, synthesizer] + +# Define diagnostic flow +flow = f"""{chief_medical_officer.agent_name} -> {virologist.agent_name} -> {internist.agent_name} -> {synthesizer.agent_name}""" + +# Create the swarm system +diagnosis_system = AgentRearrange( + name="Medical-nlp-diagnosis-swarm", + description="natural language symptions to diagnosis report", + agents=agents, + flow=flow, + max_loops=1, + output_type="all", +) + + +# Example usage +if __name__ == "__main__": + # Example patient case + patient_case = """ + Patient: 45-year-old female + Presenting symptoms: + - Fever (101.5°F) for 3 days + - Dry cough + - Fatigue + - Mild shortness of breath + Medical history: + - Controlled hypertension + - No recent travel + - Fully vaccinated for COVID-19 + - No known sick contacts + """ + + # Add timestamp to the patient case + case_info = f"Timestamp: {datetime.now()}\nPatient Information: {patient_case}" + + # Run the diagnostic process + diagnosis = diagnosis_system.run(case_info) + + # Create a folder and file called reports + create_file_in_folder( + "reports", "medical_analysis_agent_rearrange.md", diagnosis + ) diff --git a/new_features_examples/medical_analysis/rearrange_video_examples/reports/medical_analysis_agent_rearrange.md b/new_features_examples/medical_analysis/rearrange_video_examples/reports/medical_analysis_agent_rearrange.md new file mode 100644 index 00000000..d203c61f --- /dev/null +++ b/new_features_examples/medical_analysis/rearrange_video_examples/reports/medical_analysis_agent_rearrange.md @@ -0,0 +1,173 @@ +**Initial Assessment:** + +The patient is a 45-year-old female presenting with a fever, dry cough, fatigue, and mild shortness of breath. Her medical history includes controlled hypertension. She has not traveled recently and has no known sick contacts. Additionally, she is fully vaccinated for COVID-19. + +**Differential Diagnoses:** + +1. **Influenza:** Given the season and symptoms, influenza is a strong possibility. The patient’s symptoms align well with typical flu presentations, which include fever, cough, and fatigue. + +2. **COVID-19:** Despite being fully vaccinated, breakthrough infections can occur, especially with new variants. Symptoms such as fever, cough, and shortness of breath are consistent with COVID-19. + +3. **Respiratory Syncytial Virus (RSV):** RSV can cause symptoms similar to those of the flu and COVID-19, including cough and shortness of breath, particularly in adults with underlying conditions. + +4. **Viral Pneumonia:** This could be a complication of an initial viral infection, presenting with fever, cough, and shortness of breath. + +5. **Other Viral Infections:** Other respiratory viruses, such as adenovirus or parainfluenza, could also be considered, though less common. + +**Specialist Consultations Needed:** + +1. **Infectious Disease Specialist:** To evaluate and prioritize testing for specific viral pathogens and to provide input on potential treatment plans. + +2. **Pulmonologist:** Given the mild shortness of breath and history of hypertension, a pulmonologist could assess the need for further respiratory evaluation or intervention. + +**Recommended Next Steps:** + +1. **Diagnostic Testing:** + - Perform a rapid influenza test and a COVID-19 PCR test to rule out these common viral infections. + - Consider a respiratory viral panel if initial tests are negative to identify other potential viral causes. + +2. **Symptomatic Treatment:** + - Recommend antipyretics for fever management. + - Encourage rest and hydration to help manage fatigue and overall symptoms. + +3. **Monitoring and Follow-Up:** + - Monitor respiratory symptoms closely, given the mild shortness of breath, and advise the patient to seek immediate care if symptoms worsen. + - Schedule a follow-up appointment to reassess symptoms and review test results. + +4. **Consideration of Antiviral Treatment:** + - If influenza is confirmed, consider antiviral treatment with oseltamivir, especially given the patient's age and comorbidities. + +**Limitations or Uncertainties:** + +- There is uncertainty regarding the exact viral cause without specific test results. +- The potential for atypical presentations or co-infections should be considered, particularly if initial tests are inconclusive. + +By following these steps, we aim to determine the underlying cause of the patient's symptoms and provide appropriate care. **Detailed Analysis:** + +1. **Characteristic Viral Symptoms:** + - **Influenza:** Typically presents with sudden onset of fever, chills, cough, sore throat, muscle or body aches, headaches, and fatigue. Shortness of breath can occur, especially if there is a progression to viral pneumonia. + - **COVID-19:** Symptoms can vary widely but often include fever, cough, fatigue, and shortness of breath. Loss of taste or smell, sore throat, and gastrointestinal symptoms may also occur. + - **RSV:** In adults, RSV can cause symptoms similar to a mild cold, but in some cases, it can lead to more severe respiratory symptoms, especially in those with underlying conditions. + - **Viral Pneumonia:** Often presents with persistent cough, fever, shortness of breath, and fatigue. It can be a complication of other respiratory viral infections. + - **Other Respiratory Viruses (e.g., Adenovirus, Parainfluenza):** These can cause a range of symptoms similar to the common cold or flu, including fever, cough, and congestion. + +2. **Disease Progression Timeline:** + - **Influenza:** Symptoms usually appear 1-4 days after exposure and can last for about a week, although cough and fatigue may persist longer. + - **COVID-19:** Symptoms typically appear 2-14 days after exposure, with a median of 5 days. The course can vary significantly, from mild to severe. + - **RSV:** Symptoms generally appear 4-6 days after exposure and can last 1-2 weeks. + - **Viral Pneumonia:** Can develop as a complication of a primary viral infection, often within a few days of the initial symptoms. + +3. **Risk Factors for Severe Disease:** + - **Influenza and COVID-19:** Age over 50, hypertension, and other comorbidities can increase the risk of severe disease. + - **RSV:** More severe in adults with chronic heart or lung disease or weakened immune systems. + - **Viral Pneumonia:** More likely in individuals with weakened immune systems or pre-existing respiratory conditions. + +4. **Potential Complications:** + - **Influenza:** Can lead to pneumonia, exacerbation of chronic medical conditions, and secondary bacterial infections. + - **COVID-19:** Complications can include pneumonia, acute respiratory distress syndrome (ARDS), organ failure, and long COVID. + - **RSV:** Can result in bronchiolitis or pneumonia, particularly in vulnerable populations. + - **Viral Pneumonia:** Can lead to respiratory failure and secondary bacterial infections. + +**Considerations for Testing and Monitoring:** +- Given the overlapping symptoms, initial testing for influenza and COVID-19 is crucial. +- A comprehensive respiratory viral panel can help identify less common viral pathogens if initial tests are negative. +- Monitoring for worsening respiratory symptoms is essential, given the patient's mild shortness of breath and history of hypertension. + +**Recommendations for Care:** +- Symptomatic treatment should focus on fever and symptom relief while awaiting test results. +- In the case of confirmed influenza, antiviral treatment with oseltamivir is advisable, especially due to the patient's age and hypertension. +- Close follow-up is necessary to reassess symptoms and ensure timely intervention if the patient's condition deteriorates. + +**Final Note:** +- Stay updated on current viral outbreaks and emerging variants, as these can influence the likelihood of specific viral infections and guide testing priorities. To proceed with a comprehensive internal medicine evaluation based on the virologist's analysis, we will assess the case systematically: + +1. **Vital Signs and Their Implications:** + - **Temperature:** Evaluate for fever, which can indicate an ongoing infection or inflammatory process. + - **Respiratory Rate:** Increased rate may suggest respiratory distress or compensation for hypoxemia. + - **Heart Rate and Blood Pressure:** Tachycardia or hypertension may indicate systemic stress or a response to fever/infection. + - **Oxygen Saturation:** Important to assess for hypoxemia, especially in respiratory infections. + +2. **System-by-System Review:** + + - **Cardiovascular:** Consider the impact of viral infections on the cardiovascular system, such as myocarditis or exacerbation of heart failure, especially in patients with hypertension or other comorbidities. + - **Respiratory:** Assess for signs of pneumonia or bronchitis. Auscultation may reveal crackles or wheezes. Consider chest imaging if indicated. + - **Gastrointestinal:** Evaluate for symptoms like nausea, vomiting, or diarrhea, which can occur with COVID-19 or other viral infections. + - **Neurological:** Monitor for headache, confusion, or loss of taste/smell, which can be associated with viral infections like COVID-19. + - **Musculoskeletal:** Assess for myalgias or arthralgias, common in influenza. + +3. **Impact of Existing Medical Conditions:** + - **Hypertension:** Monitor blood pressure closely, as viral infections can exacerbate hypertension. + - **Age-related Factors:** Older age increases the risk of severe disease and complications from viral infections. + - **Chronic Diseases:** Consider the impact of other chronic conditions, such as diabetes or COPD, which may complicate the clinical course. + +4. **Medication Interactions and Contraindications:** + - Review current medications for interactions with potential antiviral treatments, such as oseltamivir for influenza. + - Consider contraindications for specific treatments based on the patient's comorbidities. + +5. **Risk Stratification:** + - Assess the patient's risk for severe disease based on age, comorbidities, and current symptoms. + - Identify patients who may need more intensive monitoring or early intervention. + +**Documentation:** + +- **Physical Examination Findings:** + - Document vital signs, respiratory effort, and any abnormal findings on auscultation or other systems. + +- **System-Specific Symptoms:** + - Record symptoms such as cough, fever, fatigue, and any gastrointestinal or neurological symptoms. + +- **Relevant Lab Abnormalities:** + - Note any significant lab findings, such as elevated inflammatory markers or abnormal CBC. + +- **Risk Factors for Complications:** + - Highlight factors such as age, hypertension, and any other relevant comorbid conditions. + +**Plan:** +- Initiate appropriate symptomatic treatment while awaiting test results. +- Consider antiviral therapy if influenza is confirmed, particularly given the patient's age and hypertension. +- Ensure close follow-up to monitor for any deterioration in the patient's condition, and adjust the management plan as needed. +- Educate the patient on signs of worsening symptoms and when to seek further medical attention. + +By integrating these considerations, we can provide a holistic approach to the management of viral infections in the context of internal medicine. **Final Diagnostic Assessment** + +1. **Primary Diagnosis: Viral Respiratory Infection (e.g., Influenza or COVID-19)** + - **Confidence Level:** Moderate to High + - **Supporting Evidence Summary:** + - Presence of fever, cough, and respiratory symptoms. + - Possible gastrointestinal symptoms (nausea, vomiting, diarrhea). + - Neurological symptoms such as headache and potential anosmia. + - Elevated inflammatory markers and potential CBC abnormalities. + - Older age and hypertension increase risk for severe disease. + +2. **Alternative Diagnoses to Consider:** + - **Bacterial Pneumonia:** Consider if symptoms worsen or if there is a lack of improvement with antiviral treatment. + - **Heart Failure Exacerbation:** Especially if there are cardiovascular symptoms like edema or worsening dyspnea. + - **Other Viral Infections:** Such as RSV or adenovirus, particularly if COVID-19 and influenza tests are negative. + +3. **Recommended Confirmatory Tests:** + - PCR testing for COVID-19 and Influenza. + - Chest X-ray or CT scan if pneumonia is suspected. + - Blood cultures if bacterial infection is a concern. + - Complete blood count (CBC) and inflammatory markers for further assessment. + +4. **Red Flags or Warning Signs:** + - Rapid deterioration in respiratory status (e.g., increased work of breathing, hypoxemia). + - Signs of cardiovascular compromise (e.g., chest pain, severe hypertension). + - Neurological changes (e.g., confusion, severe headache). + - Persistent high fever despite treatment. + +5. **Follow-up Recommendations:** + - Close monitoring of vital signs and symptom progression. + - Re-evaluation within 48-72 hours or sooner if symptoms worsen. + - Adjust treatment plan based on test results and clinical response. + - Patient education on recognizing signs of complications and when to seek urgent care. + +**Documentation Requirements:** + +- **Clear Reasoning Chain:** The diagnosis is based on the synthesis of clinical symptoms, lab findings, and risk factors. +- **Evidence Quality Assessment:** Moderate quality; relies on clinical presentation and initial lab results. +- **Confidence Levels for Each Diagnosis:** Primary diagnosis (Viral Respiratory Infection) is moderate to high; alternative diagnoses are lower. +- **Knowledge Gaps Identified:** Awaiting confirmatory test results for specific viral or bacterial pathogens. +- **Risk Assessment:** High risk for complications due to age and hypertension; requires vigilant monitoring and timely intervention. + +By following this structured diagnostic framework, we ensure a comprehensive and patient-centered approach to managing the suspected viral respiratory infection while being prepared for alternative diagnoses and potential complications. \ No newline at end of file diff --git a/new_features_examples/medical_analysis/rearrange_video_examples/reports/vc_document_analysis.md b/new_features_examples/medical_analysis/rearrange_video_examples/reports/vc_document_analysis.md new file mode 100644 index 00000000..2348d4b4 --- /dev/null +++ b/new_features_examples/medical_analysis/rearrange_video_examples/reports/vc_document_analysis.md @@ -0,0 +1,291 @@ +**Executive Summary:** + +The document under review is a SAFE (Simple Agreement for Future Equity) agreement, which provides the investor with rights to convert their investment into equity under specified conditions. The key financial terms include a valuation cap of $10,000,000 and a discount rate of 20%. The investment amount is $500,000, with provisions for automatic and optional conversion, as well as pro-rata rights for future investment rounds. + +**Key Terms Analysis:** + +1. **Valuation Cap:** $10,000,000 - This sets the maximum valuation at which the investment will convert into equity. +2. **Discount Rate:** 20% - This provides the investor with a discount on the price per share during conversion. +3. **Investment Amount:** $500,000 - The amount invested under this agreement. +4. **Conversion Provisions:** + - **Automatic Conversion:** Triggers upon an equity financing round of at least $1,000,000. + - **Optional Conversion:** Available upon a liquidity event. + - **Most Favored Nation (MFN):** Ensures the investor receives terms no less favorable than those offered to subsequent investors. +5. **Pro-rata Rights:** Allows the investor to maintain their percentage ownership in future financing rounds. + +**Risk Factors:** + +1. **Valuation Cap Risk:** If the company's valuation exceeds $10,000,000 during conversion, the investor benefits from a lower conversion price, but if the valuation is below, the cap may not provide a significant advantage. +2. **Conversion Timing:** The automatic conversion depends on a future equity financing event, which introduces timing and market risk. +3. **MFN Clause Complexity:** The inclusion of an MFN clause can complicate future financing negotiations and may deter other investors. + +**Negotiation Points:** + +1. **Valuation Cap Adjustment:** Consider negotiating a lower valuation cap to provide better upside protection. +2. **Discount Rate Increase:** Explore increasing the discount rate to improve conversion terms. +3. **Clarification of MFN Terms:** Ensure clarity on the MFN provision to avoid potential disputes in future rounds. +4. **Pro-rata Rights Specification:** Detail the conditions under which pro-rata rights can be exercised, including any limitations or exceptions. + +**Recommended Actions:** + +1. **Review Market Comparables:** Assess current market conditions to ensure valuation cap and discount rate align with industry standards. +2. **Legal Review of MFN Clause:** Engage legal counsel to review the MFN provision for potential issues. +3. **Scenario Analysis:** Conduct a scenario analysis to understand the impact of various conversion events on equity ownership. + +**Areas Requiring Specialist Review:** + +1. **Legal Review:** A legal specialist should review the MFN provision and conversion clauses for enforceability and potential conflicts. +2. **Financial Modeling:** A financial analyst should model different conversion scenarios to assess potential outcomes and returns. +3. **Market Analysis:** A market specialist should evaluate the competitiveness of the valuation cap and discount rate based on current trends. **Detailed Analysis of SAFE Agreement** + +**1. Term-by-Term Analysis:** + +- **Valuation Cap ($10,000,000):** + - Sets a ceiling on the company’s valuation for conversion purposes. This cap provides the investor with protection in case the company's valuation at the time of conversion is higher than $10M, ensuring a more favorable conversion price. + - **Valuation Implications:** If the company's pre-money valuation is above $10M in a future financing round, the investor benefits from a lower effective price per share, potentially increasing their ownership percentage. + - **Recommendation:** Consider negotiating a lower cap if market conditions suggest the company might achieve a higher valuation soon. + +- **Discount Rate (20%):** + - Provides a reduction on the price per share during conversion, giving the investor a benefit compared to new investors in the subsequent round. + - **Valuation Implications:** Acts as a hedge against high valuations by ensuring a discount on the conversion price. + - **Recommendation:** Assess market standards to determine if a higher discount rate is achievable. + +- **Investment Amount ($500,000):** + - The principal amount invested, which will convert into equity under the agreed terms. + - **Future Round Impacts:** This amount will affect the company's cap table upon conversion, diluting existing shareholders. + - **Recommendation:** Ensure this aligns with the company’s capital needs and strategic goals. + +- **Conversion Provisions:** + - **Automatic Conversion:** Triggers upon an equity financing round of at least $1,000,000. + - **Conversion Mechanics:** The investment converts into equity automatically, based on the valuation cap or discount rate, whichever is more favorable. + - **Recommendation:** Ensure the threshold aligns with realistic fundraising expectations. + - **Optional Conversion:** Available upon a liquidity event, such as an acquisition or IPO. + - **Conversion Mechanics:** Provides flexibility for the investor to convert under favorable terms during liquidity events. + - **Recommendation:** Clearly define what constitutes a liquidity event to avoid ambiguity. + +- **Most Favored Nation (MFN) Provision:** + - **Investor Rights and Limitations:** Ensures the investor receives terms no less favorable than those offered to future investors. + - **Potential Conflicts:** This can complicate future rounds as new investors might demand the same or better terms. + - **Recommendation:** Clarify the scope and limitations of the MFN clause to avoid deterring future investors. + +- **Pro-rata Rights:** + - **Investor Rights:** Allows the investor to maintain their ownership percentage in future financing rounds by purchasing additional shares. + - **Recommendation:** Specify the conditions and limitations under which these rights can be exercised to avoid potential disputes. + +**2. Conversion Scenarios Modeling:** + +- **Scenario Analysis:** Model various conversion scenarios based on different company valuations and financing events to understand potential outcomes for both the investor and company. +- **Impact on Cap Table:** Analyze how different conversion scenarios will affect the company's equity distribution and the dilution of existing shareholders. + +**3. Rights and Preferences Evaluation:** + +- **Investor Protections:** Evaluate the effectiveness of the valuation cap, discount rate, and MFN provisions in protecting investor interests. +- **Future Round Implications:** Consider how these rights might influence future fundraising efforts and investor relations. + +**4. Standard vs. Non-standard Terms Identification:** + +- **Market Comparisons:** Compare the agreement's terms against industry standards to identify any non-standard provisions that may require negotiation or adjustment. +- **Risk Assessment:** Assess the risk associated with any non-standard terms, particularly in relation to future financing and investor relations. + +**5. Post-money vs. Pre-money SAFE Analysis:** + +- **Valuation Implications:** Understand the difference between post-money and pre-money SAFE agreements, as this affects the calculation of ownership percentages and dilution. +- **Recommendation:** Ensure clarity on whether the SAFE is structured as pre-money or post-money to accurately assess its impact on the cap table. + +**Recommendations for Negotiations:** + +- **Valuation Cap and Discount Rate:** Consider negotiating these terms to ensure they align with market conditions and provide adequate investor protection. +- **MFN Clause:** Engage legal counsel to review and potentially simplify the MFN provision to facilitate future financing rounds. +- **Pro-rata Rights:** Clearly define the exercise conditions to avoid future disputes and ensure alignment with company growth strategies. +- **Legal and Financial Review:** Engage specialists to review the agreement for enforceability and to model potential financial outcomes. **Detailed Analysis of Venture Capital Term Sheet** + +**1. Economic Terms Analysis:** + +- **Pre/Post-money Valuation:** + - **Pre-money Valuation:** The company's valuation before the investment is made. It's crucial for determining the price per share and the percentage of the company the investor will own post-investment. + - **Post-money Valuation:** The valuation after the investment is made, calculated as pre-money valuation plus the new investment amount. + - **Market Standard Comparison:** Typically, early-stage startups have lower pre-money valuations, ranging from $3M to $10M, depending on the sector and traction. + - **Founder Impact Analysis:** A higher pre-money valuation minimizes dilution for founders but might set a high bar for future rounds. + +- **Share Price Calculation:** + - Calculated by dividing the pre-money valuation by the total number of pre-investment shares. + - **Market Standard Comparison:** Ensure the share price aligns with industry norms for similar stage companies. + - **Founder Impact Analysis:** Affects the dilution founders face; higher share prices generally mean less dilution. + +- **Capitalization Analysis:** + - Involves understanding the fully diluted capitalization, including all shares, options, warrants, and convertible securities. + - **Founder Impact Analysis:** Critical for understanding potential dilution and control implications. + +- **Option Pool Sizing:** + - Typically set aside 10-20% of post-money shares for future employee grants. + - **Market Standard Comparison:** 15% is common for early-stage rounds. + - **Founder Impact Analysis:** Larger pools increase pre-money dilution for founders. + +**2. Control Provisions Review:** + +- **Board Composition:** + - Defines the number of seats and who appoints them. Investors often seek at least one seat. + - **Market Standard Comparison:** A 3-5 member board is common, with one investor seat. + - **Founder Impact Analysis:** More investor seats can reduce founder control. + +- **Voting Rights:** + - Typically, investors want voting rights proportional to their ownership. + - **Market Standard Comparison:** Standard practice is one vote per share. + - **Founder Impact Analysis:** High investor voting power can limit founder decision-making. + +- **Protective Provisions:** + - Rights that give investors veto power over key decisions (e.g., sale of the company, issuance of new shares). + - **Market Standard Comparison:** Common for significant matters. + - **Founder Impact Analysis:** Can constrain founder flexibility in strategic decisions. + +- **Information Rights:** + - Entail regular financial and operational updates. + - **Market Standard Comparison:** Quarterly reports are typical. + - **Founder Impact Analysis:** Ensures transparency but can increase administrative burden. + +**3. Investor Rights Assessment:** + +- **Pro-rata Rights:** + - Allow investors to maintain their ownership percentage in future rounds. + - **Market Standard Comparison:** Common for early-stage investors. + - **Founder Impact Analysis:** Can limit the amount of shares available for new investors. + +- **Anti-dilution Protection:** + - Protects investors from dilution in down rounds, with full ratchet or weighted average being common methods. + - **Market Standard Comparison:** Weighted average is more founder-friendly. + - **Founder Impact Analysis:** Full ratchet can lead to significant founder dilution. + +- **Registration Rights:** + - Rights to register shares for public sale. + - **Market Standard Comparison:** Demand and piggyback rights are standard. + - **Founder Impact Analysis:** Typically, no immediate impact but relevant for IPO considerations. + +- **Right of First Refusal:** + - Allows investors to purchase shares before they are sold to a third party. + - **Market Standard Comparison:** Common to protect investor ownership. + - **Founder Impact Analysis:** Can complicate secondary sales. + +**4. Governance Structures:** + +- **Market Standard Comparison:** Early-stage companies often have a simple governance structure with founders retaining significant control. +- **Founder Impact Analysis:** Complex structures can dilute founder control and complicate decision-making. + +**5. Exit and Liquidity Provisions:** + +- **Liquidation Preferences:** + - Determine the order and amount investors receive before common shareholders in a liquidity event. + - **Market Standard Comparison:** 1x non-participating is common. + - **Founder Impact Analysis:** Participating preferences can significantly reduce returns for common shareholders. + +- **Drag-along Rights:** + - Allow majority shareholders to force minority shareholders to sell their shares in an acquisition. + - **Market Standard Comparison:** Common to facilitate exits. + - **Founder Impact Analysis:** Ensures alignment but reduces minority shareholder control. + +**Recommendations for Negotiations:** + +- **Valuation and Option Pool:** Negotiate a valuation that reflects company potential and a reasonable option pool to minimize founder dilution. +- **Board Composition and Protective Provisions:** Balance investor oversight with founder control. +- **Anti-dilution and Liquidation Preferences:** Opt for weighted average anti-dilution and non-participating liquidation preferences to protect founder interests. +- **Legal and Financial Review:** Engage professionals to ensure terms align with strategic goals and industry standards. **Compliance Checklist** + +1. **Regulatory Compliance:** + - Ensure adherence to relevant securities regulations, such as the Securities Act of 1933 and the Securities Exchange Act of 1934. + - Confirm that disclosure requirements are met, including financial statements and material risks. + - Evaluate if the company qualifies as an investment company under the Investment Company Act of 1940. + - Verify compliance with blue sky laws in applicable states for the offer and sale of securities. + +2. **Documentation Review:** + - Check for accuracy in legal definitions used within the term sheet. + - Assess the enforceability of key provisions, such as protective provisions and anti-dilution rights. + - Identify jurisdiction concerns, ensuring governing law clauses align with strategic needs. + - Review amendment provisions to ensure they allow for necessary flexibility and protection. + +3. **Risk Assessment:** + - Analyze legal precedents related to similar term sheet provisions. + - Assess regulatory exposure, particularly concerning investor rights and control provisions. + - Evaluate enforcement mechanisms for protective provisions and dispute resolution clauses. + - Review dispute resolution provisions, ensuring they are comprehensive and efficient. + +**Risk Assessment Summary** + +- **Securities Law Compliance Risk:** Moderate risk if disclosure and registration requirements are not fully met. +- **Corporate Governance Risk:** High risk if board composition and protective provisions overly favor investors, potentially leading to founder disenfranchisement. +- **Regulatory Exposure:** Low to moderate, depending on the company's industry and geographical reach. +- **Dispute Resolution Risk:** Low if arbitration or mediation clauses are included and jurisdiction is favorable. + +**Required Disclosures List** + +- Financial statements and projections. +- Material risks associated with the business and the investment. +- Information on existing and potential legal proceedings. +- Details on capitalization, including option pool and convertible securities. + +**Recommended Legal Modifications** + +- Adjust board composition to ensure a balanced representation of founders and investors. +- Opt for a weighted average anti-dilution provision to protect founder interests. +- Specify a clear and favorable jurisdiction for dispute resolution. +- Consider simplifying governance structures to maintain founder control while providing necessary investor oversight. + +**Jurisdiction-Specific Concerns** + +- Ensure compliance with state-specific blue sky laws for the offer and sale of securities. +- Consider the implications of governing law clauses, particularly if the company operates in multiple jurisdictions. +- Review state-specific requirements for board composition and shareholder rights to ensure compliance. + +This comprehensive analysis ensures that the venture capital term sheet aligns with legal compliance requirements while balancing the interests of both founders and investors. **Market Positioning Summary** + +The current venture capital term sheet aligns moderately well with market standards, but there are areas where competitiveness can be improved. The terms reflect a balance between investor control and founder protection, with room for adjustments to enhance founder-friendliness without compromising investor interests. + +**Comparative Analysis** + +1. **Stage-Appropriate Terms:** + - The term sheet is suitable for early-stage investments, offering standard protective provisions and anti-dilution rights. + - Board composition and control rights are more aligned with later-stage investments, which could be adjusted for early-stage flexibility. + +2. **Industry-Standard Provisions:** + - The inclusion of a weighted average anti-dilution provision is consistent with industry standards. + - Protective provisions are standard but may need fine-tuning to prevent founder disenfranchisement. + +3. **Geographic Variations:** + - Compliance with blue sky laws and state-specific regulations is critical. The term sheet adequately addresses these concerns but should be reviewed for any recent changes in state laws. + +4. **Recent Trend Analysis:** + - There's a growing trend towards more founder-friendly terms, including increased control over board decisions and simplified governance structures. + +**Trend Implications** + +- **Emerging Terms and Conditions:** + - Increased focus on founder-friendly provisions, such as enhanced voting rights and simplified governance. + +- **Shifting Market Standards:** + - A trend towards balancing investor protection with founder autonomy is evident, with more emphasis on collaborative governance. + +- **Industry-Specific Adaptations:** + - Tech and biotech sectors are seeing more flexible terms to accommodate rapid innovation and scaling needs. + +- **Regional Variations:** + - U.S. markets are increasingly adopting terms that offer founders more control, especially in tech hubs like Silicon Valley. + +**Negotiation Leverage Points** + +- Emphasize the inclusion of industry-standard anti-dilution provisions as a protective measure for investors. +- Highlight the potential for improved founder control to attract high-quality entrepreneurial talent. +- Use geographic compliance as a selling point for investors concerned with regulatory exposure. + +**Recommended Modifications** + +1. **Board Composition:** + - Adjust to ensure a balanced representation of founders and investors, possibly introducing independent board members. + +2. **Anti-Dilution Provisions:** + - Maintain the weighted average provision but clarify terms to protect founder interests further. + +3. **Governance Structure:** + - Simplify governance to enhance founder control while maintaining necessary investor oversight. + +4. **Dispute Resolution:** + - Specify a clear and favorable jurisdiction for dispute resolution to minimize legal uncertainties. + +By implementing these modifications, the term sheet can better align with current market trends and improve its competitiveness in attracting both investors and founders. \ No newline at end of file diff --git a/new_features_examples/medical_analysis/rearrange_video_examples/term_sheet_swarm.py b/new_features_examples/medical_analysis/rearrange_video_examples/term_sheet_swarm.py new file mode 100644 index 00000000..4e1dd72a --- /dev/null +++ b/new_features_examples/medical_analysis/rearrange_video_examples/term_sheet_swarm.py @@ -0,0 +1,243 @@ +from datetime import datetime +from swarms import Agent, AgentRearrange, create_file_in_folder + +# Lead Investment Analyst +lead_analyst = Agent( + agent_name="Lead Investment Analyst", + system_prompt="""You are the Lead Investment Analyst coordinating document analysis for venture capital investments. + + Core responsibilities: + - Coordinating overall document review process + - Identifying key terms and conditions + - Flagging potential risks and concerns + - Synthesizing specialist inputs into actionable insights + - Recommending negotiation points + + Document Analysis Framework: + 1. Initial document classification and overview + 2. Key terms identification + 3. Risk assessment + 4. Market context evaluation + 5. Recommendation formulation + + Output Format Requirements: + - Executive Summary + - Key Terms Analysis + - Risk Factors + - Negotiation Points + - Recommended Actions + - Areas Requiring Specialist Review""", + model_name="gpt-4o", + max_loops=1, +) + +# SAFE Agreement Specialist +safe_specialist = Agent( + agent_name="SAFE Specialist", + system_prompt="""You are a specialist in SAFE (Simple Agreement for Future Equity) agreements with expertise in: + + Technical Analysis Areas: + - Valuation caps and discount rates + - Conversion mechanisms and triggers + - Pro-rata rights + - Most Favored Nation (MFN) provisions + - Dilution and anti-dilution provisions + + Required Assessments: + 1. Cap table impact analysis + 2. Conversion scenarios modeling + 3. Rights and preferences evaluation + 4. Standard vs. non-standard terms identification + 5. Post-money vs. pre-money SAFE analysis + + Consider and Document: + - Valuation implications + - Future round impacts + - Investor rights and limitations + - Comparative market terms + - Potential conflicts with other securities + + Output Requirements: + - Term-by-term analysis + - Conversion mechanics explanation + - Risk assessment for non-standard terms + - Recommendations for negotiations""", + model_name="gpt-4o", + max_loops=1, +) + +# Term Sheet Analyst +term_sheet_analyst = Agent( + agent_name="Term Sheet Analyst", + system_prompt="""You are a Term Sheet Analyst specialized in venture capital financing documents. + + Core Analysis Areas: + - Economic terms (valuation, option pool, etc.) + - Control provisions + - Investor rights and protections + - Governance structures + - Exit and liquidity provisions + + Detailed Review Requirements: + 1. Economic Terms Analysis: + - Pre/post-money valuation + - Share price calculation + - Capitalization analysis + - Option pool sizing + + 2. Control Provisions Review: + - Board composition + - Voting rights + - Protective provisions + - Information rights + + 3. Investor Rights Assessment: + - Pro-rata rights + - Anti-dilution protection + - Registration rights + - Right of first refusal + + Output Format: + - Term-by-term breakdown + - Market standard comparison + - Founder impact analysis + - Investor rights summary + - Governance implications""", + model_name="gpt-4o", + max_loops=1, +) + +# Legal Compliance Analyst +legal_analyst = Agent( + agent_name="Legal Compliance Analyst", + system_prompt="""You are a Legal Compliance Analyst for venture capital documentation. + + Primary Focus Areas: + - Securities law compliance + - Corporate governance requirements + - Regulatory restrictions + - Standard market practices + - Legal risk assessment + + Analysis Framework: + 1. Regulatory Compliance: + - Securities regulations + - Disclosure requirements + - Investment company considerations + - Blue sky laws + + 2. Documentation Review: + - Legal definitions accuracy + - Enforceability concerns + - Jurisdiction issues + - Amendment provisions + + 3. Risk Assessment: + - Legal precedent analysis + - Regulatory exposure + - Enforcement mechanisms + - Dispute resolution provisions + + Output Requirements: + - Compliance checklist + - Risk assessment summary + - Required disclosures list + - Recommended legal modifications + - Jurisdiction-specific concerns""", + model_name="gpt-4o", + max_loops=1, +) + +# Market Comparison Analyst +market_analyst = Agent( + agent_name="Market Comparison Analyst", + system_prompt="""You are a Market Comparison Analyst for venture capital terms and conditions. + + Core Responsibilities: + - Benchmark terms against market standards + - Identify industry-specific variations + - Track emerging market trends + - Assess term competitiveness + + Analysis Framework: + 1. Market Comparison: + - Stage-appropriate terms + - Industry-standard provisions + - Geographic variations + - Recent trend analysis + + 2. Competitive Assessment: + - Investor-friendliness rating + - Founder-friendliness rating + - Term flexibility analysis + - Market positioning + + 3. Trend Analysis: + - Emerging terms and conditions + - Shifting market standards + - Industry-specific adaptations + - Regional variations + + Output Format: + - Market positioning summary + - Comparative analysis + - Trend implications + - Negotiation leverage points + - Recommended modifications""", + model_name="gpt-4o", + max_loops=1, +) + +# Create agent list +agents = [ + lead_analyst, + safe_specialist, + term_sheet_analyst, + legal_analyst, + market_analyst, +] + +# Define analysis flow +flow = f"""{lead_analyst.agent_name} -> {safe_specialist.agent_name} -> {term_sheet_analyst.agent_name} -> {legal_analyst.agent_name} -> {market_analyst.agent_name}""" + +# Create the swarm system +vc_analysis_system = AgentRearrange( + name="VC-Document-Analysis-Swarm", + description="SAFE and Term Sheet document analysis and Q&A system", + agents=agents, + flow=flow, + max_loops=1, + output_type="all", +) +# Example usage +if __name__ == "__main__": + try: + # Example document for analysis + document_text = """ + SAFE AGREEMENT + + Valuation Cap: $10,000,000 + Discount Rate: 20% + + Investment Amount: $500,000 + + Conversion Provisions: + - Automatic conversion upon Equity Financing of at least $1,000,000 + - Optional conversion upon Liquidity Event + - Most Favored Nation provision included + + Pro-rata Rights: Included for future rounds + """ + + # Add timestamp to the analysis + analysis_request = f"Timestamp: {datetime.now()}\nDocument for Analysis: {document_text}" + + # Run the analysis + analysis = vc_analysis_system.run(analysis_request) + + # Create analysis report + create_file_in_folder( + "reports", "vc_document_analysis.md", analysis + ) + except Exception as e: + print(f"An error occurred: {e}") diff --git a/new_features_examples/ollama_demo.py b/new_features_examples/ollama_demo.py new file mode 100644 index 00000000..4d1d41ef --- /dev/null +++ b/new_features_examples/ollama_demo.py @@ -0,0 +1,252 @@ +""" +- For each diagnosis, pull lab results, +- egfr +- for each diagnosis, pull lab ranges, +- pull ranges for diagnosis + +- if the diagnosis is x, then the lab ranges should be a to b +- train the agents, increase the load of input +- medical history sent to the agent +- setup rag for the agents +- run the first agent -> kidney disease -> don't know the stage -> stage 2 -> lab results -> indicative of stage 3 -> the case got elavated -> +- how to manage diseases and by looking at correlating lab, docs, diagnoses +- put docs in rag -> +- monitoring, evaluation, and treatment +- can we confirm for every diagnosis -> monitoring, evaluation, and treatment, specialized for these things +- find diagnosis -> or have diagnosis, -> for each diagnosis are there evidence of those 3 things +- swarm of those 4 agents, -> +- fda api for healthcare for commerically available papers +- + +""" + +from datetime import datetime + +from swarms import Agent, AgentRearrange, create_file_in_folder + +from swarm_models import OllamaModel + +model = OllamaModel(model_name="llama3.2") + +chief_medical_officer = Agent( + agent_name="Chief Medical Officer", + system_prompt="""You are the Chief Medical Officer coordinating a team of medical specialists for viral disease diagnosis. + Your responsibilities include: + - Gathering initial patient symptoms and medical history + - Coordinating with specialists to form differential diagnoses + - Synthesizing different specialist opinions into a cohesive diagnosis + - Ensuring all relevant symptoms and test results are considered + - Making final diagnostic recommendations + - Suggesting treatment plans based on team input + - Identifying when additional specialists need to be consulted + - For each diferrential diagnosis provide minimum lab ranges to meet that diagnosis or be indicative of that diagnosis minimum and maximum + + Format all responses with clear sections for: + - Initial Assessment (include preliminary ICD-10 codes for symptoms) + - Differential Diagnoses (with corresponding ICD-10 codes) + - Specialist Consultations Needed + - Recommended Next Steps + + + """, + llm=model, + max_loops=1, +) + +virologist = Agent( + agent_name="Virologist", + system_prompt="""You are a specialist in viral diseases. For each case, provide: + + Clinical Analysis: + - Detailed viral symptom analysis + - Disease progression timeline + - Risk factors and complications + + Coding Requirements: + - List relevant ICD-10 codes for: + * Confirmed viral conditions + * Suspected viral conditions + * Associated symptoms + * Complications + - Include both: + * Primary diagnostic codes + * Secondary condition codes + + Document all findings using proper medical coding standards and include rationale for code selection.""", + llm=model, + max_loops=1, +) + +internist = Agent( + agent_name="Internist", + system_prompt="""You are an Internal Medicine specialist responsible for comprehensive evaluation. + + For each case, provide: + + Clinical Assessment: + - System-by-system review + - Vital signs analysis + - Comorbidity evaluation + + Medical Coding: + - ICD-10 codes for: + * Primary conditions + * Secondary diagnoses + * Complications + * Chronic conditions + * Signs and symptoms + - Include hierarchical condition category (HCC) codes where applicable + + Document supporting evidence for each code selected.""", + llm=model, + max_loops=1, +) + +medical_coder = Agent( + agent_name="Medical Coder", + system_prompt="""You are a certified medical coder responsible for: + + Primary Tasks: + 1. Reviewing all clinical documentation + 2. Assigning accurate ICD-10 codes + 3. Ensuring coding compliance + 4. Documenting code justification + + Coding Process: + - Review all specialist inputs + - Identify primary and secondary diagnoses + - Assign appropriate ICD-10 codes + - Document supporting evidence + - Note any coding queries + + Output Format: + 1. Primary Diagnosis Codes + - ICD-10 code + - Description + - Supporting documentation + 2. Secondary Diagnosis Codes + - Listed in order of clinical significance + 3. Symptom Codes + 4. Complication Codes + 5. Coding Notes""", + llm=model, + max_loops=1, +) + +synthesizer = Agent( + agent_name="Diagnostic Synthesizer", + system_prompt="""You are responsible for creating the final diagnostic and coding assessment. + + Synthesis Requirements: + 1. Integrate all specialist findings + 2. Reconcile any conflicting diagnoses + 3. Verify coding accuracy and completeness + + Final Report Sections: + 1. Clinical Summary + - Primary diagnosis with ICD-10 + - Secondary diagnoses with ICD-10 + - Supporting evidence + 2. Coding Summary + - Complete code list with descriptions + - Code hierarchy and relationships + - Supporting documentation + 3. Recommendations + - Additional testing needed + - Follow-up care + - Documentation improvements needed + + Include confidence levels and evidence quality for all diagnoses and codes.""", + llm=model, + max_loops=1, +) + +# Create agent list +agents = [ + chief_medical_officer, + virologist, + internist, + medical_coder, + synthesizer, +] + +# Define diagnostic flow +flow = f"""{chief_medical_officer.agent_name} -> {virologist.agent_name} -> {internist.agent_name} -> {medical_coder.agent_name} -> {synthesizer.agent_name}""" + +# Create the swarm system +diagnosis_system = AgentRearrange( + name="Medical-coding-diagnosis-swarm", + description="Comprehensive medical diagnosis and coding system", + agents=agents, + flow=flow, + max_loops=1, + output_type="all", +) + + +def generate_coding_report(diagnosis_output: str) -> str: + """ + Generate a structured medical coding report from the diagnosis output. + """ + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + report = f"""# Medical Diagnosis and Coding Report + Generated: {timestamp} + + ## Clinical Summary + {diagnosis_output} + + ## Coding Summary + ### Primary Diagnosis Codes + [Extracted from synthesis] + + ### Secondary Diagnosis Codes + [Extracted from synthesis] + + ### Symptom Codes + [Extracted from synthesis] + + ### Procedure Codes (if applicable) + [Extracted from synthesis] + + ## Documentation and Compliance Notes + - Code justification + - Supporting documentation references + - Any coding queries or clarifications needed + + ## Recommendations + - Additional documentation needed + - Suggested follow-up + - Coding optimization opportunities + """ + return report + + +if __name__ == "__main__": + # Example patient case + patient_case = """ + Patient: 45-year-old White Male + + Lab Results: + - egfr + - 59 ml / min / 1.73 + - non african-american + + """ + + # Add timestamp to the patient case + case_info = f"Timestamp: {datetime.now()}\nPatient Information: {patient_case}" + + # Run the diagnostic process + diagnosis = diagnosis_system.run(case_info) + + # Generate coding report + coding_report = generate_coding_report(diagnosis) + + # Create reports + create_file_in_folder( + "reports", "medical_diagnosis_report.md", diagnosis + ) + create_file_in_folder( + "reports", "medical_coding_report.md", coding_report + ) diff --git a/new_features_examples/solana_agent.py b/new_features_examples/solana_agent.py new file mode 100644 index 00000000..28622f57 --- /dev/null +++ b/new_features_examples/solana_agent.py @@ -0,0 +1,354 @@ +from dataclasses import dataclass +from typing import List, Optional, Dict, Any +from datetime import datetime +import asyncio +from loguru import logger +import json +import base58 +from decimal import Decimal + +# Swarms imports +from swarms import Agent + +# Solana imports +from solders.rpc.responses import GetTransactionResp +from solders.transaction import Transaction +from anchorpy import Provider, Wallet +from solders.keypair import Keypair +import aiohttp + +# Specialized Solana Analysis System Prompt +SOLANA_ANALYSIS_PROMPT = """You are a specialized Solana blockchain analyst agent. Your role is to: + +1. Analyze real-time Solana transactions for patterns and anomalies +2. Identify potential market-moving transactions and whale movements +3. Detect important DeFi interactions across major protocols +4. Monitor program interactions for suspicious or notable activity +5. Track token movements across significant protocols like: + - Serum DEX + - Raydium + - Orca + - Marinade + - Jupiter + - Other major Solana protocols + +When analyzing transactions, consider: +- Transaction size relative to protocol norms +- Historical patterns for involved addresses +- Impact on protocol liquidity +- Relationship to known market events +- Potential wash trading or suspicious patterns +- MEV opportunities and arbitrage patterns +- Program interaction sequences + +Provide analysis in the following format: +{ + "analysis_type": "[whale_movement|program_interaction|defi_trade|suspicious_activity]", + "severity": "[high|medium|low]", + "details": { + "transaction_context": "...", + "market_impact": "...", + "recommended_actions": "...", + "related_patterns": "..." + } +} + +Focus on actionable insights that could affect: +1. Market movements +2. Protocol stability +3. Trading opportunities +4. Risk management +""" + + +@dataclass +class TransactionData: + """Data structure for parsed Solana transaction information""" + + signature: str + block_time: datetime + slot: int + fee: int + lamports: int + from_address: str + to_address: str + program_id: str + instruction_data: Optional[str] = None + program_logs: List[str] = None + + @property + def sol_amount(self) -> Decimal: + """Convert lamports to SOL""" + return Decimal(self.lamports) / Decimal(1e9) + + def to_dict(self) -> Dict[str, Any]: + """Convert transaction data to dictionary for agent analysis""" + return { + "signature": self.signature, + "timestamp": self.block_time.isoformat(), + "slot": self.slot, + "fee": self.fee, + "amount_sol": str(self.sol_amount), + "from_address": self.from_address, + "to_address": self.to_address, + "program_id": self.program_id, + "instruction_data": self.instruction_data, + "program_logs": self.program_logs, + } + + +class SolanaSwarmAgent: + """Intelligent agent for analyzing Solana transactions using swarms""" + + def __init__( + self, + agent_name: str = "Solana-Analysis-Agent", + model_name: str = "gpt-4", + ): + self.agent = Agent( + agent_name=agent_name, + system_prompt=SOLANA_ANALYSIS_PROMPT, + model_name=model_name, + max_loops=1, + autosave=True, + dashboard=False, + verbose=True, + dynamic_temperature_enabled=True, + saved_state_path="solana_agent.json", + user_name="solana_analyzer", + retry_attempts=3, + context_length=4000, + ) + + # Initialize known patterns database + self.known_patterns = { + "whale_addresses": set(), + "program_interactions": {}, + "recent_transactions": [], + } + logger.info( + f"Initialized {agent_name} with specialized Solana analysis capabilities" + ) + + async def analyze_transaction( + self, tx_data: TransactionData + ) -> Dict[str, Any]: + """Analyze a transaction using the specialized agent""" + try: + # Update recent transactions for pattern analysis + self.known_patterns["recent_transactions"].append( + tx_data.signature + ) + if len(self.known_patterns["recent_transactions"]) > 1000: + self.known_patterns["recent_transactions"].pop(0) + + # Prepare context for agent + context = { + "transaction": tx_data.to_dict(), + "known_patterns": { + "recent_similar_transactions": [ + tx + for tx in self.known_patterns[ + "recent_transactions" + ][-5:] + if abs( + TransactionData(tx).sol_amount + - tx_data.sol_amount + ) + < 1 + ], + "program_statistics": self.known_patterns[ + "program_interactions" + ].get(tx_data.program_id, {}), + }, + } + + # Get analysis from agent + analysis = await self.agent.run_async( + f"Analyze the following Solana transaction and provide insights: {json.dumps(context, indent=2)}" + ) + + # Update pattern database + if tx_data.sol_amount > 1000: # Track whale addresses + self.known_patterns["whale_addresses"].add( + tx_data.from_address + ) + + # Update program interaction statistics + if ( + tx_data.program_id + not in self.known_patterns["program_interactions"] + ): + self.known_patterns["program_interactions"][ + tx_data.program_id + ] = {"total_interactions": 0, "total_volume": 0} + self.known_patterns["program_interactions"][ + tx_data.program_id + ]["total_interactions"] += 1 + self.known_patterns["program_interactions"][ + tx_data.program_id + ]["total_volume"] += float(tx_data.sol_amount) + + return json.loads(analysis) + + except Exception as e: + logger.error(f"Error in agent analysis: {str(e)}") + return { + "analysis_type": "error", + "severity": "low", + "details": { + "error": str(e), + "transaction": tx_data.signature, + }, + } + + +class SolanaTransactionMonitor: + """Main class for monitoring and analyzing Solana transactions""" + + def __init__( + self, + rpc_url: str, + swarm_agent: SolanaSwarmAgent, + min_sol_threshold: Decimal = Decimal("100"), + ): + self.rpc_url = rpc_url + self.swarm_agent = swarm_agent + self.min_sol_threshold = min_sol_threshold + self.wallet = Wallet(Keypair()) + self.provider = Provider(rpc_url, self.wallet) + logger.info("Initialized Solana transaction monitor") + + async def parse_transaction( + self, tx_resp: GetTransactionResp + ) -> Optional[TransactionData]: + """Parse transaction response into TransactionData object""" + try: + if not tx_resp.value: + return None + + tx_value = tx_resp.value + meta = tx_value.transaction.meta + if not meta: + return None + + tx: Transaction = tx_value.transaction.transaction + + # Extract transaction details + from_pubkey = str(tx.message.account_keys[0]) + to_pubkey = str(tx.message.account_keys[1]) + program_id = str(tx.message.account_keys[-1]) + + # Calculate amount from balance changes + amount = abs(meta.post_balances[0] - meta.pre_balances[0]) + + return TransactionData( + signature=str(tx_value.transaction.signatures[0]), + block_time=datetime.fromtimestamp( + tx_value.block_time or 0 + ), + slot=tx_value.slot, + fee=meta.fee, + lamports=amount, + from_address=from_pubkey, + to_address=to_pubkey, + program_id=program_id, + program_logs=( + meta.log_messages if meta.log_messages else [] + ), + ) + except Exception as e: + logger.error(f"Failed to parse transaction: {str(e)}") + return None + + async def start_monitoring(self): + """Start monitoring for new transactions""" + logger.info( + "Starting transaction monitoring with swarm agent analysis" + ) + + async with aiohttp.ClientSession() as session: + async with session.ws_connect(self.rpc_url) as ws: + await ws.send_json( + { + "jsonrpc": "2.0", + "id": 1, + "method": "transactionSubscribe", + "params": [ + {"commitment": "finalized"}, + { + "encoding": "jsonParsed", + "commitment": "finalized", + }, + ], + } + ) + + async for msg in ws: + if msg.type == aiohttp.WSMsgType.TEXT: + try: + data = json.loads(msg.data) + if "params" in data: + signature = data["params"]["result"][ + "value" + ]["signature"] + + # Fetch full transaction data + tx_response = await self.provider.connection.get_transaction( + base58.b58decode(signature) + ) + + if tx_response: + tx_data = ( + await self.parse_transaction( + tx_response + ) + ) + if ( + tx_data + and tx_data.sol_amount + >= self.min_sol_threshold + ): + # Get agent analysis + analysis = await self.swarm_agent.analyze_transaction( + tx_data + ) + + logger.info( + f"Transaction Analysis:\n" + f"Signature: {tx_data.signature}\n" + f"Amount: {tx_data.sol_amount} SOL\n" + f"Analysis: {json.dumps(analysis, indent=2)}" + ) + + except Exception as e: + logger.error( + f"Error processing message: {str(e)}" + ) + continue + + +async def main(): + """Example usage""" + + # Start monitoring + try: + # Initialize swarm agent + swarm_agent = SolanaSwarmAgent( + agent_name="Solana-Whale-Detector", model_name="gpt-4" + ) + + # Initialize monitor + monitor = SolanaTransactionMonitor( + rpc_url="wss://api.mainnet-beta.solana.com", + swarm_agent=swarm_agent, + min_sol_threshold=Decimal("100"), + ) + + await monitor.start_monitoring() + except KeyboardInterrupt: + logger.info("Shutting down gracefully...") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/swarm_router_example.py b/new_features_examples/swarm_router_example.py similarity index 94% rename from swarm_router_example.py rename to new_features_examples/swarm_router_example.py index d7397457..ef12a64e 100644 --- a/swarm_router_example.py +++ b/new_features_examples/swarm_router_example.py @@ -1,4 +1,3 @@ - from swarms import Agent, SwarmRouter # Portfolio Analysis Specialist @@ -147,19 +146,19 @@ portfolio_agents = [ allocation_strategist, risk_manager, implementation_specialist, - monitoring_specialist + monitoring_specialist, ] # Router router = SwarmRouter( - name = "etf-portfolio-management-swarm", + name="etf-portfolio-management-swarm", description="Creates and suggests an optimal portfolio", - agents = portfolio_agents, - swarm_type="SequentialWorkflow", # ConcurrentWorkflow - max_loops = 1, + agents=portfolio_agents, + swarm_type="SequentialWorkflow", # ConcurrentWorkflow + max_loops=1, ) router.run( - task = "I have 10,000$ and I want to create a porfolio based on energy, ai, and datacenter companies. high growth." -) \ No newline at end of file + task="I have 10,000$ and I want to create a porfolio based on energy, ai, and datacenter companies. high growth." +) diff --git a/pyproject.toml b/pyproject.toml index 6e3bfd87..66d2598f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "swarms" -version = "6.5.7" +version = "6.6.8" description = "Swarms - TGSC" license = "MIT" authors = ["Kye Gomez "] @@ -63,10 +63,10 @@ asyncio = ">=3.4.3,<4.0" toml = "*" pypdf = "4.3.1" loguru = "*" -pydantic = "2.8.2" +pydantic = "*" tenacity = "*" psutil = "*" -sentry-sdk = {version = "*", extras = ["http"]} # Updated here +sentry-sdk = "*" python-dotenv = "*" PyYAML = "*" docstring_parser = "0.16" diff --git a/real_time.py b/real_time.py deleted file mode 100644 index fe55878d..00000000 --- a/real_time.py +++ /dev/null @@ -1,618 +0,0 @@ -import torch -from torch.utils.data import DataLoader, TensorDataset -import numpy as np -from loguru import logger - -from dataclasses import dataclass -from typing import Optional, Tuple, Dict -import math -import torch.nn as nn -import torch.nn.functional as F -from torch import Tensor - - -@dataclass -class TransformerConfig: - """Configuration class for MoE Transformer model parameters.""" - - vocab_size: int = 50257 - hidden_size: int = 768 - num_attention_heads: int = 12 - num_expert_layers: int = 4 - num_experts: int = 8 - expert_capacity: int = 32 - max_position_embeddings: int = 1024 - dropout_prob: float = 0.1 - layer_norm_epsilon: float = 1e-5 - initializer_range: float = 0.02 - num_query_groups: int = 4 # For multi-query attention - - -class ExpertLayer(nn.Module): - """Individual expert neural network.""" - - def __init__(self, config: TransformerConfig): - super().__init__() - self.fc1 = nn.Linear( - config.hidden_size, 4 * config.hidden_size - ) - self.fc2 = nn.Linear( - 4 * config.hidden_size, config.hidden_size - ) - self.activation = nn.GELU() - self.dropout = nn.Dropout(config.dropout_prob) - - def forward(self, x: Tensor) -> Tensor: - x = self.fc1(x) - x = self.activation(x) - x = self.dropout(x) - x = self.fc2(x) - return x - - -class MixtureOfExperts(nn.Module): - """Mixture of Experts layer with dynamic routing.""" - - def __init__(self, config: TransformerConfig): - super().__init__() - self.num_experts = config.num_experts - self.expert_capacity = config.expert_capacity - - # Create expert networks - self.experts = nn.ModuleList( - [ExpertLayer(config) for _ in range(config.num_experts)] - ) - - # Router network - self.router = nn.Linear( - config.hidden_size, config.num_experts - ) - - def forward(self, x: Tensor) -> Tuple[Tensor, Dict]: - """Route inputs to experts and combine outputs.""" - batch_size, seq_len, hidden_size = x.shape - - # Calculate routing probabilities - router_logits = self.router(x) - routing_weights = F.softmax(router_logits, dim=-1) - - # Select top-k experts - top_k = 2 - gates, indices = torch.topk(routing_weights, top_k, dim=-1) - gates = F.softmax(gates, dim=-1) - - # Process inputs through selected experts - final_output = torch.zeros_like(x) - router_load = torch.zeros(self.num_experts, device=x.device) - - for i in range(top_k): - expert_index = indices[..., i] - gate = gates[..., i : i + 1] - - # Count expert assignments - for j in range(self.num_experts): - router_load[j] += (expert_index == j).float().sum() - - # Process through selected experts - for j in range(self.num_experts): - mask = expert_index == j - if not mask.any(): - continue - - expert_input = x[mask] - expert_output = self.experts[j](expert_input) - final_output[mask] += gate[mask] * expert_output - - aux_loss = router_load.float().var() / ( - router_load.float().mean() ** 2 - ) - - return final_output, {"load_balancing_loss": aux_loss} - - -class MultiQueryAttention(nn.Module): - """Multi-Query Attention mechanism with proper multi-query group handling.""" - - def __init__(self, config: TransformerConfig): - super().__init__() - self.num_attention_heads = config.num_attention_heads - self.num_query_groups = config.num_query_groups - self.hidden_size = config.hidden_size - self.head_dim = ( - config.hidden_size // config.num_attention_heads - ) - - # Query projection maintains full head dimension - self.q_proj = nn.Linear( - config.hidden_size, config.hidden_size - ) - - # Key and value projections use reduced number of heads (query groups) - self.k_proj = nn.Linear( - config.hidden_size, - self.head_dim * config.num_query_groups, - ) - self.v_proj = nn.Linear( - config.hidden_size, - self.head_dim * config.num_query_groups, - ) - - self.dropout = nn.Dropout(config.dropout_prob) - - # Calculate heads per group for proper reshaping - self.heads_per_group = ( - self.num_attention_heads // self.num_query_groups - ) - - def forward( - self, - hidden_states: Tensor, - attention_mask: Optional[Tensor] = None, - cache: Optional[Dict[str, Tensor]] = None, - ) -> Tuple[Tensor, Optional[Dict[str, Tensor]]]: - batch_size, seq_length, _ = hidden_states.shape - - # Project queries, keys, and values - queries = self.q_proj(hidden_states) - keys = self.k_proj(hidden_states) - values = self.v_proj(hidden_states) - - # Reshape queries to full number of heads - queries = queries.view( - batch_size, - seq_length, - self.num_attention_heads, - self.head_dim, - ) - - # Reshape keys and values to number of query groups - keys = keys.view( - batch_size, - seq_length, - self.num_query_groups, - self.head_dim, - ) - values = values.view( - batch_size, - seq_length, - self.num_query_groups, - self.head_dim, - ) - - # Transpose for batch matrix multiplication - queries = queries.transpose( - 1, 2 - ) # (batch, n_heads, seq_len, head_dim) - keys = keys.transpose( - 1, 2 - ) # (batch, n_groups, seq_len, head_dim) - values = values.transpose( - 1, 2 - ) # (batch, n_groups, seq_len, head_dim) - - # Repeat keys and values for each head in the group - keys = keys.repeat_interleave(self.heads_per_group, dim=1) - values = values.repeat_interleave(self.heads_per_group, dim=1) - - # Compute attention scores - scale = 1.0 / math.sqrt(self.head_dim) - scores = torch.matmul(queries, keys.transpose(-2, -1)) * scale - - if attention_mask is not None: - # Expand attention mask to match scores dimensions - expanded_mask = attention_mask.unsqueeze(1).unsqueeze(2) - expanded_mask = expanded_mask.expand( - batch_size, - self.num_attention_heads, - seq_length, - seq_length, - ) - mask_value = torch.finfo(scores.dtype).min - attention_mask = expanded_mask.eq(0).float() * mask_value - scores = scores + attention_mask - - attention_weights = F.softmax(scores, dim=-1) - attention_weights = self.dropout(attention_weights) - - # Compute attention output - attention_output = torch.matmul(attention_weights, values) - attention_output = attention_output.transpose(1, 2) - attention_output = attention_output.reshape( - batch_size, seq_length, -1 - ) - - return attention_output, None - - -class MoETransformer(nn.Module): - """ - Production-grade Transformer model with Mixture of Experts and Multi-Query Attention. - - Features: - - Multi-Query Attention mechanism for efficient inference - - Mixture of Experts for dynamic routing and specialization - - Real-time weight updates based on input similarity - - Built-in logging and monitoring - - Type annotations for better code maintainability - """ - - def __init__(self, config: TransformerConfig): - super().__init__() - self.config = config - - # Initialize components - self.embedding = nn.Embedding( - config.vocab_size, config.hidden_size - ) - self.position_embedding = nn.Embedding( - config.max_position_embeddings, config.hidden_size - ) - - # Multi-Query Attention layers - self.attention_layers = nn.ModuleList( - [ - MultiQueryAttention(config) - for _ in range(config.num_expert_layers) - ] - ) - - # Mixture of Experts layers - self.moe_layers = nn.ModuleList( - [ - MixtureOfExperts(config) - for _ in range(config.num_expert_layers) - ] - ) - - # Layer normalization and dropout - self.layer_norm = nn.LayerNorm( - config.hidden_size, eps=config.layer_norm_epsilon - ) - self.dropout = nn.Dropout(config.dropout_prob) - - # Output projection - self.output_projection = nn.Linear( - config.hidden_size, config.vocab_size - ) - - # Initialize weights - self.apply(self._init_weights) - logger.info("Initialized MoETransformer model") - - def _init_weights(self, module: nn.Module): - """Initialize model weights.""" - if isinstance(module, (nn.Linear, nn.Embedding)): - module.weight.data.normal_( - mean=0.0, std=self.config.initializer_range - ) - if ( - isinstance(module, nn.Linear) - and module.bias is not None - ): - module.bias.data.zero_() - - def get_position_embeddings(self, position_ids: Tensor) -> Tensor: - """Generate position embeddings.""" - return self.position_embedding(position_ids) - - def forward( - self, - input_ids: Tensor, - attention_mask: Optional[Tensor] = None, - position_ids: Optional[Tensor] = None, - cache: Optional[Dict[str, Tensor]] = None, - ) -> Tuple[Tensor, Dict]: - """ - Forward pass through the model. - - Args: - input_ids: Input token IDs - attention_mask: Attention mask for padding - position_ids: Position IDs for positioning encoding - cache: Cache for key/value states in generation - - Returns: - tuple: (logits, auxiliary_outputs) - """ - batch_size, seq_length = input_ids.shape - - if position_ids is None: - position_ids = torch.arange( - seq_length, dtype=torch.long, device=input_ids.device - ) - position_ids = position_ids.unsqueeze(0).expand_as( - input_ids - ) - - # Get embeddings - inputs_embeds = self.embedding(input_ids) - position_embeds = self.get_position_embeddings(position_ids) - hidden_states = inputs_embeds + position_embeds - - # Initialize auxiliary outputs - aux_outputs = {"moe_losses": []} - - # Process through transformer layers - for attention_layer, moe_layer in zip( - self.attention_layers, self.moe_layers - ): - # Multi-Query Attention - attention_output, _ = attention_layer( - hidden_states, attention_mask, cache - ) - hidden_states = self.layer_norm( - hidden_states + attention_output - ) - - # Mixture of Experts - moe_output, moe_aux = moe_layer(hidden_states) - hidden_states = self.layer_norm( - hidden_states + moe_output - ) - aux_outputs["moe_losses"].append( - moe_aux["load_balancing_loss"] - ) - - # Final output projection - logits = self.output_projection(hidden_states) - - return logits, aux_outputs - - def fetch_loss( - self, - logits: Tensor, - labels: Tensor, - aux_outputs: Dict, - reduction: str = "mean", - ) -> Tensor: - """ - Calculate the total loss including MoE balancing losses. - - Args: - logits: Model output logits - labels: Ground truth labels - aux_outputs: Auxiliary outputs from forward pass - reduction: Loss reduction method - - Returns: - Tensor: Total loss - """ - # Calculate cross entropy loss - ce_loss = F.cross_entropy( - logits.view(-1, self.config.vocab_size), - labels.view(-1), - reduction=reduction, - ) - - # Calculate MoE loss - moe_loss = torch.stack(aux_outputs["moe_losses"]).mean() - - # Combine losses - total_loss = ce_loss + 0.01 * moe_loss - - logger.debug( - f"CE Loss: {ce_loss.item():.4f}, " - f"MoE Loss: {moe_loss.item():.4f}" - ) - - return total_loss - - @torch.no_grad() - def generate( - self, - input_ids: Tensor, - max_length: int = 100, - temperature: float = 1.0, - top_k: int = 50, - top_p: float = 0.9, - ) -> Tensor: - """ - Generate text using the model. - - Args: - input_ids: Initial input tokens - max_length: Maximum sequence length to generate - temperature: Sampling temperature - top_k: Number of highest probability tokens to keep - top_p: Cumulative probability for nucleus sampling - - Returns: - Tensor: Generated token IDs - """ - batch_size = input_ids.shape[0] - device = input_ids.device - - # Initialize sequence with input_ids - generated = input_ids - - # Cache for key-value pairs - cache = {} - - for _ in range(max_length): - # Get position IDs for current sequence - position_ids = torch.arange( - generated.shape[1], dtype=torch.long, device=device - ) - position_ids = position_ids.unsqueeze(0).expand( - batch_size, -1 - ) - - # Forward pass - logits, _ = self.forward( - generated, position_ids=position_ids, cache=cache - ) - - # Get next token logits - next_token_logits = logits[:, -1, :] / temperature - - # Apply top-k filtering - if top_k > 0: - indices_to_remove = ( - next_token_logits - < torch.topk(next_token_logits, top_k)[0][ - ..., -1, None - ] - ) - next_token_logits[indices_to_remove] = float("-inf") - - # Apply top-p (nucleus) filtering - if top_p < 1.0: - sorted_logits, sorted_indices = torch.sort( - next_token_logits, descending=True - ) - cumulative_probs = torch.cumsum( - F.softmax(sorted_logits, dim=-1), dim=-1 - ) - - # Remove tokens with cumulative probability above the threshold - sorted_indices_to_remove = cumulative_probs > top_p - sorted_indices_to_remove[..., 1:] = ( - sorted_indices_to_remove[..., :-1].clone() - ) - sorted_indices_to_remove[..., 0] = 0 - - indices_to_remove = sorted_indices[ - sorted_indices_to_remove - ] - next_token_logits[indices_to_remove] = float("-inf") - - # Sample next token - probs = F.softmax(next_token_logits, dim=-1) - next_token = torch.multinomial(probs, num_samples=1) - - # Append next token to sequence - generated = torch.cat((generated, next_token), dim=1) - - # Check for end of sequence token - if (next_token == self.config.vocab_size - 1).all(): - break - - return generated - - -# Initialize model configuration -config = TransformerConfig( - vocab_size=50257, - hidden_size=768, - num_attention_heads=12, - num_expert_layers=4, - num_experts=8, - expert_capacity=32, - max_position_embeddings=1024, - num_query_groups=4, -) - - -def prepare_sample_data( - batch_size: int = 8, - seq_length: int = 512, - vocab_size: int = 50257, -) -> DataLoader: - """Create sample data for demonstration.""" - # Create random input sequences - input_ids = torch.randint( - 0, vocab_size, (100, seq_length) # 100 samples - ) - - # Create target sequences (shifted by 1) - labels = torch.randint(0, vocab_size, (100, seq_length)) - - # Create attention masks (1 for real tokens, 0 for padding) - attention_mask = torch.ones_like(input_ids) - - # Create dataset and dataloader - dataset = TensorDataset(input_ids, attention_mask, labels) - dataloader = DataLoader( - dataset, batch_size=batch_size, shuffle=True - ) - - return dataloader - - -def train_step( - model: MoETransformer, - batch: tuple, - optimizer: torch.optim.Optimizer, - device: str = "cuda" if torch.cuda.is_available() else "cpu", -) -> float: - """Execute single training step.""" - model.train() - optimizer.zero_grad() - - # Unpack batch - input_ids, attention_mask, labels = [b.to(device) for b in batch] - - # Forward pass - logits, aux_outputs = model( - input_ids=input_ids, attention_mask=attention_mask - ) - - # Calculate loss - loss = model.fetch_loss(logits, labels, aux_outputs) - - # Backward pass - loss.backward() - optimizer.step() - - return loss.item() - - -def main(): - # Set device - device = "cuda" if torch.cuda.is_available() else "cpu" - logger.info(f"Using device: {device}") - - # Initialize model - model = MoETransformer(config).to(device) - logger.info("Model initialized") - - # Setup optimizer - optimizer = torch.optim.AdamW( - model.parameters(), lr=1e-4, weight_decay=0.01 - ) - - # Prepare data - dataloader = prepare_sample_data() - logger.info("Data prepared") - - # Training loop - num_epochs = 3 - for epoch in range(num_epochs): - epoch_losses = [] - - for batch_idx, batch in enumerate(dataloader): - loss = train_step(model, batch, optimizer, device) - epoch_losses.append(loss) - - if batch_idx % 10 == 0: - logger.info( - f"Epoch {epoch+1}/{num_epochs} " - f"Batch {batch_idx}/{len(dataloader)} " - f"Loss: {loss:.4f}" - ) - - avg_loss = np.mean(epoch_losses) - logger.info(f"Epoch {epoch+1} average loss: {avg_loss:.4f}") - - # Generation example - model.eval() - with torch.no_grad(): - # Prepare input prompt - prompt = torch.randint(0, config.vocab_size, (1, 10)).to( - device - ) - - # Generate sequence - generated = model.generate( - input_ids=prompt, - max_length=50, - temperature=0.7, - top_k=50, - top_p=0.9, - ) - - logger.info(f"Generated sequence shape: {generated.shape}") - - -if __name__ == "__main__": - main() diff --git a/swarm_builder.py b/swarm_builder.py new file mode 100644 index 00000000..f1d769b4 --- /dev/null +++ b/swarm_builder.py @@ -0,0 +1,333 @@ +import os +from typing import List, Optional +from datetime import datetime + +from pydantic import BaseModel, Field +from pydantic.v1 import validator +from loguru import logger +from tenacity import ( + retry, + stop_after_attempt, + wait_exponential, +) + +from swarm_models import OpenAIFunctionCaller, OpenAIChat +from swarms.structs.agent import Agent +from swarms.structs.swarm_router import SwarmRouter +from swarms.structs.agents_available import showcase_available_agents + + +BOSS_SYSTEM_PROMPT = """ +Manage a swarm of worker agents to efficiently serve the user by deciding whether to create new agents or delegate tasks. Ensure operations are efficient and effective. + +### Instructions: + +1. **Task Assignment**: + - Analyze available worker agents when a task is presented. + - Delegate tasks to existing agents with clear, direct, and actionable instructions if an appropriate agent is available. + - If no suitable agent exists, create a new agent with a fitting system prompt to handle the task. + +2. **Agent Creation**: + - Name agents according to the task they are intended to perform (e.g., "Twitter Marketing Agent"). + - Provide each new agent with a concise and clear system prompt that includes its role, objectives, and any tools it can utilize. + +3. **Efficiency**: + - Minimize redundancy and maximize task completion speed. + - Avoid unnecessary agent creation if an existing agent can fulfill the task. + +4. **Communication**: + - Be explicit in task delegation instructions to avoid ambiguity and ensure effective task execution. + - Require agents to report back on task completion or encountered issues. + +5. **Reasoning and Decisions**: + - Offer brief reasoning when selecting or creating agents to maintain transparency. + - Avoid using an agent if unnecessary, with a clear explanation if no agents are suitable for a task. + +# Output Format + +Present your plan in clear, bullet-point format or short concise paragraphs, outlining task assignment, agent creation, efficiency strategies, and communication protocols. + +# Notes + +- Preserve transparency by always providing reasoning for task-agent assignments and creation. +- Ensure instructions to agents are unambiguous to minimize error. + +""" + + +class AgentConfig(BaseModel): + """Configuration for an individual agent in a swarm""" + + name: str = Field( + description="The name of the agent", example="Research-Agent" + ) + description: str = Field( + description="A description of the agent's purpose and capabilities", + example="Agent responsible for researching and gathering information", + ) + system_prompt: str = Field( + description="The system prompt that defines the agent's behavior", + example="You are a research agent. Your role is to gather and analyze information...", + ) + + @validator("name") + def validate_name(cls, v): + if not v.strip(): + raise ValueError("Agent name cannot be empty") + return v.strip() + + @validator("system_prompt") + def validate_system_prompt(cls, v): + if not v.strip(): + raise ValueError("System prompt cannot be empty") + return v.strip() + + +class SwarmConfig(BaseModel): + """Configuration for a swarm of cooperative agents""" + + name: str = Field( + description="The name of the swarm", + example="Research-Writing-Swarm", + ) + description: str = Field( + description="The description of the swarm's purpose and capabilities", + example="A swarm of agents that work together to research topics and write articles", + ) + agents: List[AgentConfig] = Field( + description="The list of agents that make up the swarm", + min_items=1, + ) + + @validator("agents") + def validate_agents(cls, v): + if not v: + raise ValueError("Swarm must have at least one agent") + return v + + +class AutoSwarmBuilder: + """A class that automatically builds and manages swarms of AI agents with enhanced error handling.""" + + def __init__( + self, + name: Optional[str] = None, + description: Optional[str] = None, + verbose: bool = True, + api_key: Optional[str] = None, + model_name: str = "gpt-4", + ): + self.name = name or "DefaultSwarm" + self.description = description or "Generic AI Agent Swarm" + self.verbose = verbose + self.agents_pool = [] + self.api_key = api_key or os.getenv("OPENAI_API_KEY") + self.model_name = model_name + + if not self.api_key: + raise ValueError( + "OpenAI API key must be provided either through initialization or environment variable" + ) + + logger.info( + "Initialized AutoSwarmBuilder", + extra={ + "swarm_name": self.name, + "description": self.description, + "model": self.model_name, + }, + ) + + # Initialize OpenAI chat model + try: + self.chat_model = OpenAIChat( + openai_api_key=self.api_key, + model_name=self.model_name, + temperature=0.1, + ) + except Exception as e: + logger.error( + f"Failed to initialize OpenAI chat model: {str(e)}" + ) + raise + + @retry( + stop=stop_after_attempt(3), + wait=wait_exponential(multiplier=1, min=4, max=10), + ) + def run(self, task: str, image_url: Optional[str] = None) -> str: + """Run the swarm on a given task with error handling and retries.""" + if not task or not task.strip(): + raise ValueError("Task cannot be empty") + + logger.info("Starting swarm execution", extra={"task": task}) + + try: + # Create agents for the task + agents = self._create_agents(task, image_url) + if not agents: + raise ValueError( + "No agents were created for the task" + ) + + # Execute the task through the swarm router + logger.info( + "Routing task through swarm", + extra={"num_agents": len(agents)}, + ) + output = self.swarm_router(agents, task, image_url) + + logger.info("Swarm execution completed successfully") + return output + + except Exception as e: + logger.error( + f"Error during swarm execution: {str(e)}", + exc_info=True, + ) + raise + + def _create_agents( + self, task: str, image_url: Optional[str] = None + ) -> List[Agent]: + """Create the necessary agents for a task with enhanced error handling.""" + logger.info("Creating agents for task", extra={"task": task}) + + try: + model = OpenAIFunctionCaller( + system_prompt=BOSS_SYSTEM_PROMPT, + api_key=self.api_key, + temperature=0.1, + base_model=SwarmConfig, + ) + + agents_config = model.run(task) + print(f"{agents_config}") + + if isinstance(agents_config, dict): + agents_config = SwarmConfig(**agents_config) + + # Update swarm configuration + self.name = agents_config.name + self.description = agents_config.description + + # Create agents from configuration + agents = [] + for agent_config in agents_config.agents: + if isinstance(agent_config, dict): + agent_config = AgentConfig(**agent_config) + + agent = self.build_agent( + agent_name=agent_config.name, + agent_description=agent_config.description, + agent_system_prompt=agent_config.system_prompt, + ) + agents.append(agent) + + # Add available agents showcase to system prompts + agents_available = showcase_available_agents( + name=self.name, + description=self.description, + agents=agents, + ) + + for agent in agents: + agent.system_prompt += "\n" + agents_available + + logger.info( + "Successfully created agents", + extra={"num_agents": len(agents)}, + ) + return agents + + except Exception as e: + logger.error( + f"Error creating agents: {str(e)}", exc_info=True + ) + raise + + def build_agent( + self, + agent_name: str, + agent_description: str, + agent_system_prompt: str, + ) -> Agent: + """Build a single agent with enhanced error handling.""" + logger.info( + "Building agent", extra={"agent_name": agent_name} + ) + + try: + agent = Agent( + agent_name=agent_name, + description=agent_description, + system_prompt=agent_system_prompt, + llm=self.chat_model, + autosave=True, + dashboard=False, + verbose=self.verbose, + dynamic_temperature_enabled=True, + saved_state_path=f"states/{agent_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", + user_name="swarms_corp", + retry_attempts=3, + context_length=200000, + return_step_meta=False, + output_type="str", + streaming_on=False, + auto_generate_prompt=True, + ) + return agent + + except Exception as e: + logger.error( + f"Error building agent: {str(e)}", exc_info=True + ) + raise + + @retry( + stop=stop_after_attempt(3), + wait=wait_exponential(multiplier=1, min=4, max=10), + ) + def swarm_router( + self, + agents: List[Agent], + task: str, + image_url: Optional[str] = None, + ) -> str: + """Route tasks between agents in the swarm with error handling and retries.""" + logger.info( + "Initializing swarm router", + extra={"num_agents": len(agents)}, + ) + + try: + swarm_router_instance = SwarmRouter( + name=self.name, + description=self.description, + agents=agents, + swarm_type="auto", + ) + + formatted_task = f"{self.name} {self.description} {task}" + result = swarm_router_instance.run(formatted_task) + + logger.info("Successfully completed swarm routing") + return result + + except Exception as e: + logger.error( + f"Error in swarm router: {str(e)}", exc_info=True + ) + raise + + +swarm = AutoSwarmBuilder( + name="ChipDesign-Swarm", + description="A swarm of specialized AI agents for chip design", + api_key="your-api-key", # Optional if set in environment + model_name="gpt-4", # Optional, defaults to gpt-4 +) + +result = swarm.run( + "Design a new AI accelerator chip optimized for transformer model inference..." +) diff --git a/swarms/agents/auto_generate_swarm_config.py b/swarms/agents/auto_generate_swarm_config.py index febb85e3..0067d13d 100644 --- a/swarms/agents/auto_generate_swarm_config.py +++ b/swarms/agents/auto_generate_swarm_config.py @@ -8,7 +8,7 @@ from swarms.agents.create_agents_from_yaml import ( create_agents_from_yaml, ) from swarms.utils.formatter import formatter -from swarms.utils.litellm import LiteLLM +from swarms.utils.litellm_wrapper import LiteLLM load_dotenv() diff --git a/swarms/agents/create_agents_from_yaml.py b/swarms/agents/create_agents_from_yaml.py index e92d1923..d1eb3e95 100644 --- a/swarms/agents/create_agents_from_yaml.py +++ b/swarms/agents/create_agents_from_yaml.py @@ -16,7 +16,7 @@ from pydantic import ( from swarms.utils.loguru_logger import initialize_logger from swarms.structs.agent import Agent from swarms.structs.swarm_router import SwarmRouter -from swarms.utils.litellm import LiteLLM +from swarms.utils.litellm_wrapper import LiteLLM logger = initialize_logger(log_folder="create_agents_from_yaml") diff --git a/swarms/artifacts/main_artifact.py b/swarms/artifacts/main_artifact.py index 5eaa939e..04a8daf5 100644 --- a/swarms/artifacts/main_artifact.py +++ b/swarms/artifacts/main_artifact.py @@ -2,7 +2,8 @@ import time import os import json from typing import List, Union, Dict, Any -from pydantic import BaseModel, Field, validator +from pydantic import BaseModel, Field +from pydantic.v1 import validator from datetime import datetime from swarms.utils.file_processing import create_file_in_folder from swarms.utils.loguru_logger import initialize_logger diff --git a/swarms/cli/main.py b/swarms/cli/main.py index 5abe8b58..1acdfd46 100644 --- a/swarms/cli/main.py +++ b/swarms/cli/main.py @@ -1,6 +1,5 @@ import argparse import os -import subprocess import time import webbrowser @@ -227,45 +226,6 @@ def run_autoswarm(task: str, model: str): ) -def check_and_upgrade_version(): - """Check for updates with visual progress.""" - - def check_update(): - result = subprocess.run( - ["pip", "list", "--outdated", "--format=freeze"], - capture_output=True, - text=True, - ) - return result.stdout.splitlines() - - outdated = execute_with_spinner( - check_update, "Checking for updates..." - ) - - for package in outdated: - if package.startswith("swarms=="): - console.print( - f"[{COLORS['warning']}]↑ Update available![/{COLORS['warning']}]" - ) - with create_spinner("Upgrading Swarms...") as progress: - task = progress.add_task( - "Installing latest version..." - ) - subprocess.run( - ["pip", "install", "--upgrade", "swarms"], - check=True, - ) - progress.remove_task(task) - console.print( - f"[{COLORS['success']}]✓ Swarms upgraded successfully![/{COLORS['success']}]" - ) - return - - console.print( - f"[{COLORS['success']}]✓ Swarms is up to date![/{COLORS['success']}]" - ) - - def main(): try: @@ -319,8 +279,6 @@ def main(): create_agents_from_yaml( yaml_file=args.yaml_file, return_type="tasks" ) - elif args.command == "auto-upgrade": - check_and_upgrade_version() elif args.command == "book-call": webbrowser.open( "https://cal.com/swarms/swarms-strategy-session" diff --git a/swarms/structs/agent.py b/swarms/structs/agent.py index 48c4ff63..db15c8bb 100644 --- a/swarms/structs/agent.py +++ b/swarms/structs/agent.py @@ -598,7 +598,7 @@ class Agent: def llm_handling(self): if self.llm is None: - from swarms.utils.litellm import LiteLLM + from swarms.utils.litellm_wrapper import LiteLLM if self.llm_args is not None: self.llm = LiteLLM( diff --git a/swarms/structs/rearrange.py b/swarms/structs/rearrange.py index 8fc4ecca..41f546c0 100644 --- a/swarms/structs/rearrange.py +++ b/swarms/structs/rearrange.py @@ -11,12 +11,12 @@ from swarms.schemas.agent_step_schemas import ManySteps from swarms.structs.agent import Agent from swarms.structs.agents_available import showcase_available_agents from swarms.structs.base_swarm import BaseSwarm +from swarms.structs.output_types import OutputType from swarms.utils.add_docs_to_agents import handle_input_docs from swarms.utils.loguru_logger import initialize_logger from swarms.utils.wrapper_clusterop import ( exec_callable_with_clusterops, ) -from swarms.structs.output_types import OutputType logger = initialize_logger(log_folder="rearrange") @@ -41,7 +41,10 @@ class AgentRearrangeInput(BaseModel): class AgentRearrangeOutput(BaseModel): - Input: Optional[AgentRearrangeInput] = None + output_id: str = Field( + default=swarm_id(), description="Output-UUID" + ) + input: Optional[AgentRearrangeInput] = None outputs: Optional[List[ManySteps]] = None time: str = Field( default_factory=lambda: datetime.now().strftime( @@ -105,7 +108,7 @@ class AgentRearrange(BaseSwarm): Callable[[str], str] ] = None, return_json: bool = False, - output_type: OutputType = "final", + output_type: OutputType = "all", docs: List[str] = None, doc_folder: str = None, device: str = "cpu", @@ -141,6 +144,17 @@ class AgentRearrange(BaseSwarm): self.all_gpus = all_gpus self.no_use_clusterops = no_use_clusterops + self.output_schema = AgentRearrangeOutput( + input=AgentRearrangeInput( + swarm_id=id, + name=name, + description=description, + flow=flow, + max_loops=max_loops, + ), + outputs=[], + ) + def showcase_agents(self): # Get formatted agent info once agents_available = showcase_available_agents( @@ -448,7 +462,9 @@ class AgentRearrange(BaseSwarm): f"Agent {agent_name} output: {current_task}" ) - all_responses.append(current_task) + all_responses.append( + f"Agent Name: {agent.agent_name} \n Output: {current_task} " + ) previous_agent = agent_name loop_count += 1 @@ -685,6 +701,7 @@ def rearrange( agents: List[Agent] = None, flow: str = None, task: str = None, + img: str = None, *args, **kwargs, ): @@ -710,4 +727,4 @@ def rearrange( agent_system = AgentRearrange( agents=agents, flow=flow, *args, **kwargs ) - return agent_system.run(task, *args, **kwargs) + return agent_system.run(task, img=img, *args, **kwargs) diff --git a/swarms/structs/swarm_router.py b/swarms/structs/swarm_router.py index 0d2ef9dd..190471ec 100644 --- a/swarms/structs/swarm_router.py +++ b/swarms/structs/swarm_router.py @@ -137,6 +137,7 @@ class SwarmRouter: rules: str = None, documents: List[str] = [], # A list of docs file paths output_type: str = "string", # Md, PDF, Txt, csv + no_cluster_ops: bool = False, *args, **kwargs, ): @@ -153,6 +154,7 @@ class SwarmRouter: self.rules = rules self.documents = documents self.output_type = output_type + self.no_cluster_ops = no_cluster_ops self.logs = [] self.reliability_check() @@ -176,6 +178,12 @@ class SwarmRouter: # if self.documents is not None: # self.handle_docs() + # let's make a function that checks the agents parameter and disables clusterops + + def deactivate_clusterops(self): + for agent in self.agents: + agent.do_not_use_cluster_ops = True + def handle_docs(self): # Process all documents in parallel using list comprehension data = "".join( @@ -279,6 +287,9 @@ class SwarmRouter: self._create_swarm(self.swarm_type) + if self.no_cluster_ops: + self.deactivate_clusterops() + elif self.swarm_type == "AgentRearrange": return AgentRearrange( name=self.name, diff --git a/swarms/structs/tree_swarm.py b/swarms/structs/tree_swarm.py index 75b0bf13..cb428705 100644 --- a/swarms/structs/tree_swarm.py +++ b/swarms/structs/tree_swarm.py @@ -9,6 +9,7 @@ from swarms.utils.loguru_logger import initialize_logger from swarms.utils.auto_download_check_packages import ( auto_check_and_download_package, ) +from swarms.structs.conversation import Conversation logger = initialize_logger(log_folder="tree_swarm") @@ -126,7 +127,9 @@ class TreeAgent(Agent): ) # Closer agents have a smaller distance return distance - def run_task(self, task: str) -> Any: + def run_task( + self, task: str, img: str = None, *args, **kwargs + ) -> Any: input_log = AgentLogInput( agent_name=self.agent_name, task=task, @@ -135,7 +138,7 @@ class TreeAgent(Agent): logger.info(f"Running task on {self.agent_name}: {task}") logger.debug(f"Input Log: {input_log.json()}") - result = self.run(task) + result = self.run(task=task, img=img, *args, **kwargs) output_log = AgentLogOutput( agent_name=self.agent_name, @@ -257,16 +260,33 @@ class Tree: class ForestSwarm: - def __init__(self, trees: List[Tree], *args, **kwargs): + def __init__( + self, + name: str = "default-forest-swarm", + description: str = "Standard forest swarm", + trees: List[Tree] = [], + shared_memory: Any = None, + rules: str = None, + *args, + **kwargs, + ): """ Initializes the structure with multiple trees of agents. Args: trees (List[Tree]): A list of trees in the structure. """ + self.name = name + self.description = description self.trees = trees - # Add auto grouping based on trees. - # Add auto group agents + self.shared_memory = shared_memory + self.save_file_path = f"forest_swarm_{uuid.uuid4().hex}.json" + self.conversation = Conversation( + time_enabled=True, + auto_save=True, + save_filepath=self.save_file_path, + rules=rules, + ) def find_relevant_tree(self, task: str) -> Optional[Tree]: """ @@ -287,7 +307,7 @@ class ForestSwarm: logger.warning(f"No relevant tree found for task: {task}") return None - def run(self, task: str) -> Any: + def run(self, task: str, img: str = None, *args, **kwargs) -> Any: """ Executes the given task by finding the most relevant tree and agent within that tree. @@ -297,21 +317,30 @@ class ForestSwarm: Returns: Any: The result of the task after it has been processed by the agents. """ - logger.info( - f"Running task across MultiAgentTreeStructure: {task}" - ) - relevant_tree = self.find_relevant_tree(task) - if relevant_tree: - agent = relevant_tree.find_relevant_agent(task) - if agent: - result = agent.run_task(task) - relevant_tree.log_tree_execution(task, agent, result) - return result - else: + try: + logger.info( + f"Running task across MultiAgentTreeStructure: {task}" + ) + relevant_tree = self.find_relevant_tree(task) + if relevant_tree: + agent = relevant_tree.find_relevant_agent(task) + if agent: + result = agent.run_task( + task, img=img, *args, **kwargs + ) + relevant_tree.log_tree_execution( + task, agent, result + ) + return result + else: + logger.error( + "Task could not be completed: No relevant agent or tree found." + ) + return "No relevant agent found to handle this task." + except Exception as error: logger.error( - "Task could not be completed: No relevant agent or tree found." + f"Error detected in the ForestSwarm, check your inputs and try again ;) {error}" ) - return "No relevant agent found to handle this task." # # Example Usage: diff --git a/swarms/telemetry/auto_upgrade_swarms.py b/swarms/telemetry/auto_upgrade_swarms.py deleted file mode 100644 index 440f70ed..00000000 --- a/swarms/telemetry/auto_upgrade_swarms.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import subprocess - -from swarms.utils.loguru_logger import initialize_logger -from swarms.telemetry.check_update import check_for_update - -logger = initialize_logger(log_folder="auto_upgrade_swarms") - - -def auto_update(): - """auto update swarms""" - try: - # Check if auto-update is disabled - auto_update_enabled = os.getenv( - "SWARMS_AUTOUPDATE_ON", "false" - ).lower() - if auto_update_enabled == "false": - logger.info( - "Auto-update is disabled via SWARMS_AUTOUPDATE_ON" - ) - return - - outcome = check_for_update() - if outcome is True: - logger.info( - "There is a new version of swarms available! Downloading..." - ) - try: - subprocess.run( - ["pip", "install", "-U", "swarms"], check=True - ) - except subprocess.CalledProcessError: - logger.info("Attempting to install with pip3...") - subprocess.run( - ["pip3", "install", "-U", "swarms"], check=True - ) - else: - logger.info("swarms is up to date!") - except Exception as e: - logger.error(e) diff --git a/swarms/telemetry/bootup.py b/swarms/telemetry/bootup.py index 41cae773..5e38c3ea 100644 --- a/swarms/telemetry/bootup.py +++ b/swarms/telemetry/bootup.py @@ -2,8 +2,6 @@ import os import logging import warnings from concurrent.futures import ThreadPoolExecutor - -from swarms.telemetry.auto_upgrade_swarms import auto_update from swarms.utils.disable_logging import disable_logging @@ -22,9 +20,8 @@ def bootup(): warnings.filterwarnings("ignore", category=DeprecationWarning) # Use ThreadPoolExecutor to run disable_logging and auto_update concurrently - with ThreadPoolExecutor(max_workers=2) as executor: + with ThreadPoolExecutor(max_workers=1) as executor: executor.submit(disable_logging) - executor.submit(auto_update) except Exception as e: print(f"An error occurred: {str(e)}") raise diff --git a/swarms/telemetry/capture_sys_data.py b/swarms/telemetry/capture_sys_data.py index 4a09099b..9ef52976 100644 --- a/swarms/telemetry/capture_sys_data.py +++ b/swarms/telemetry/capture_sys_data.py @@ -39,8 +39,7 @@ def capture_system_data() -> Dict[str, str]: system_data["external_ip"] = requests.get( "https://api.ipify.org" ).text - except Exception as e: - logger.warning("Failed to retrieve external IP: {}", e) + except Exception: system_data["external_ip"] = "N/A" return system_data @@ -49,9 +48,7 @@ def capture_system_data() -> Dict[str, str]: return {} -def log_agent_data( - data_dict: dict -) -> dict | None: +def log_agent_data(data_dict: dict) -> dict | None: """ Logs agent data to the Swarms database with retry logic. @@ -76,25 +73,7 @@ def log_agent_data( "Authorization": "Bearer sk-f24a13ed139f757d99cdd9cdcae710fccead92681606a97086d9711f69d44869", } - try: - response = requests.post( - url, json=data_dict, headers=headers, timeout=10 - ) - response.raise_for_status() - - result = response.json() - return result - - except requests.exceptions.Timeout: - logger.warning("Request timed out") - - except requests.exceptions.HTTPError as e: - logger.error(f"HTTP error occurred: {e}") - if response.status_code == 401: - logger.error("Authentication failed - check API key") - - except requests.exceptions.RequestException as e: - logger.error(f"Error logging agent data: {e}") + requests.post(url, json=data_dict, headers=headers, timeout=10) + # response.raise_for_status() - logger.error("Failed to log agent data") return None diff --git a/swarms/telemetry/check_update.py b/swarms/telemetry/check_update.py deleted file mode 100644 index 2b0b9a1c..00000000 --- a/swarms/telemetry/check_update.py +++ /dev/null @@ -1,73 +0,0 @@ -import importlib.util -import sys - -import pkg_resources -import requests -from packaging import version -from swarms.utils.loguru_logger import initialize_logger - -logger = initialize_logger("check-update") - - -# borrowed from: https://stackoverflow.com/a/1051266/656011 -def check_for_package(package: str) -> bool: - """ - Checks if a package is installed and available for import. - - Args: - package (str): The name of the package to check. - - Returns: - bool: True if the package is installed and can be imported, False otherwise. - """ - if package in sys.modules: - return True - elif (spec := importlib.util.find_spec(package)) is not None: - try: - module = importlib.util.module_from_spec(spec) - - sys.modules[package] = module - spec.loader.exec_module(module) - - return True - except ImportError: - logger.error(f"Failed to import {package}") - return False - else: - logger.info(f"{package} not found") - return False - - -def check_for_update() -> bool: - """ - Checks if there is an update available for the swarms package. - - Returns: - bool: True if an update is available, False otherwise. - """ - try: - # Fetch the latest version from the PyPI API - response = requests.get("https://pypi.org/pypi/swarms/json") - response.raise_for_status() # Raises an HTTPError if the response status code is 4XX/5XX - latest_version = response.json()["info"]["version"] - - # Get the current version using pkg_resources - current_version = pkg_resources.get_distribution( - "swarms" - ).version - - if version.parse(latest_version) > version.parse( - current_version - ): - logger.info( - f"Update available: {latest_version} > {current_version}" - ) - return True - else: - logger.info( - f"No update available: {latest_version} <= {current_version}" - ) - return False - except requests.exceptions.RequestException as e: - logger.error(f"Failed to check for update: {e}") - return False diff --git a/swarms/utils/litellm.py b/swarms/utils/litellm_wrapper.py similarity index 100% rename from swarms/utils/litellm.py rename to swarms/utils/litellm_wrapper.py diff --git a/swarms/utils/loguru_logger.py b/swarms/utils/loguru_logger.py index 0f0524b5..9c71276d 100644 --- a/swarms/utils/loguru_logger.py +++ b/swarms/utils/loguru_logger.py @@ -5,6 +5,7 @@ from loguru import logger import requests from swarms.telemetry.sys_info import system_info + def log_agent_data(data: Any) -> Dict: """ Send data to the agent logging API endpoint. @@ -36,6 +37,7 @@ def log_agent_data(data: Any) -> Dict: logger.error(f"Failed to log agent data: {e}") return {"error": str(e)} + def initialize_logger(log_folder: str = "logs"): """ Initialize and configure the Loguru logger. @@ -87,8 +89,9 @@ def initialize_logger(log_folder: str = "logs"): "metadata": system_info(), } response = log_agent_data(payload) - logger.debug(f"Sent to API: {payload}, Response: {response}") - + logger.debug( + f"Sent to API: {payload}, Response: {response}" + ) logger.add(AgentLogHandler(), level="INFO")