cx_ai_agent_v1 / agents /hunter.py
muzakkirhussain011's picture
Add application files (text files only)
8bab08d
# file: agents/hunter.py
"""
Hunter Agent - Discovers companies dynamically
Now uses web search to find company information instead of static files
"""
import json
from typing import List, Optional
from app.schema import Company, Prospect
from app.config import COMPANIES_FILE, SKIP_WEB_SEARCH
from services.company_discovery import get_company_discovery_service
import logging
logger = logging.getLogger(__name__)
class Hunter:
"""
Discovers companies and creates prospects dynamically
NEW: Can now discover companies from user input (company names)
LEGACY: Still supports loading from seed file for backwards compatibility
"""
def __init__(self, mcp_registry):
self.mcp = mcp_registry
self.store = mcp_registry.get_store_client()
self.discovery = get_company_discovery_service()
async def run(
self,
company_names: Optional[List[str]] = None,
company_ids: Optional[List[str]] = None,
use_seed_file: bool = False
) -> List[Prospect]:
"""
Discover companies and create prospects
Args:
company_names: List of company names to discover (NEW - dynamic mode)
company_ids: List of company IDs from seed file (LEGACY - static mode)
use_seed_file: If True, load from seed file instead of discovery
Returns:
List of Prospect objects
"""
prospects = []
# Mode 1: Dynamic discovery from company names (NEW)
if company_names and not use_seed_file:
logger.info(f"Hunter: Dynamic discovery mode - discovering {len(company_names)} companies")
for company_name in company_names:
try:
logger.info(f"Hunter: Discovering '{company_name}'...")
# Discover company information from web (or use fallback if configured)
company = await self.discovery.discover_company(company_name, skip_search=SKIP_WEB_SEARCH)
if not company:
logger.warning(f"Hunter: Could not discover company '{company_name}'")
# Create a minimal fallback company
company = self._create_fallback_company(company_name)
# Create prospect
prospect = Prospect(
id=company.id,
company=company,
status="new"
)
# Save to store
await self.store.save_prospect(prospect)
prospects.append(prospect)
logger.info(f"Hunter: Successfully created prospect for '{company_name}'")
except Exception as e:
logger.error(f"Hunter: Error discovering '{company_name}': {str(e)}")
# Create fallback and continue
company = self._create_fallback_company(company_name)
prospect = Prospect(
id=company.id,
company=company,
status="new"
)
await self.store.save_prospect(prospect)
prospects.append(prospect)
# Mode 2: Legacy mode - load from seed file (BACKWARDS COMPATIBLE)
else:
logger.info("Hunter: Legacy mode - loading from seed file")
try:
# Load from seed file
with open(COMPANIES_FILE) as f:
companies_data = json.load(f)
for company_data in companies_data:
# Filter by IDs if specified
if company_ids and company_data["id"] not in company_ids:
continue
company = Company(**company_data)
# Create prospect
prospect = Prospect(
id=company.id,
company=company,
status="new"
)
# Save to store
await self.store.save_prospect(prospect)
prospects.append(prospect)
logger.info(f"Hunter: Loaded {len(prospects)} companies from seed file")
except FileNotFoundError:
logger.error(f"Hunter: Seed file not found: {COMPANIES_FILE}")
# If no seed file and no company names provided, return empty
if not company_names:
return []
except Exception as e:
logger.error(f"Hunter: Error loading seed file: {str(e)}")
return []
return prospects
def _create_fallback_company(self, company_name: str) -> Company:
"""Create a minimal fallback company when discovery fails"""
import re
import uuid
# Generate ID
slug = re.sub(r'[^a-zA-Z0-9]', '', company_name.lower())[:20]
company_id = f"{slug}_{str(uuid.uuid4())[:8]}"
# Create minimal company
company = Company(
id=company_id,
name=company_name,
domain=f"{slug}.com",
industry="Technology",
size=100,
pains=[
"Customer experience improvement needed",
"Operational efficiency challenges"
],
notes=[
"Company information discovery in progress",
"Limited data available"
]
)
logger.info(f"Hunter: Created fallback company for '{company_name}'")
return company