system-prompts-and-models-o.../salesflow-saas/backend/app/agents/discovery/prospecting_crew.py
2026-04-04 18:04:21 +03:00

134 lines
4.8 KiB
Python

import os
import json
import logging
from typing import Dict, Any
try:
from crewai import Agent, Task, Crew, Process
from langchain_anthropic import ChatAnthropic
CREWAI_AVAILABLE = True
except ImportError:
CREWAI_AVAILABLE = False
from app.agents.memory_layer import empire_memory
logger = logging.getLogger("dealix.prospecting_crew")
class ProspectingCrewRunner:
"""
Layer 2: Specialized CrewAI Squad for deeply researching and qualifying leads.
"""
def __init__(self):
self.llm = self._init_llm()
def _init_llm(self):
if not CREWAI_AVAILABLE:
return None
# Default to Claude 3 Haiku for speed/cost, Opus/Sonnet if needed for complexity
api_key = os.getenv("ANTHROPIC_API_KEY", "")
if not api_key:
# Fallback to GROQ if Anthropic is not available, though langchain_anthropic specifically requires Anthropic
# We will return None and the Crew will fail gracefully or we handle it.
return None
try:
return ChatAnthropic(
model="claude-3-haiku-20240307",
temperature=0.4,
anthropic_api_key=api_key
)
except Exception as e:
logger.error(f"Failed to initialize ChatAnthropic: {e}")
return None
def run_enrichment(self, lead_data: Dict) -> Dict:
"""
Executes the Crew to enrich a lead.
"""
company_name = lead_data.get("name", "Unknown Company")
sector = lead_data.get("category", "")
city = lead_data.get("city", "")
if not CREWAI_AVAILABLE or not self.llm:
logger.warning("CrewAI or Anthropic LLM not available. Returning empty enrichment.")
return {}
# 1. Inject Mem0 Self-Healing Memory
mem_context = empire_memory.get_context(company_name, context_type="discovery")
# 2. Define Agents
intent_detector = Agent(
role="Enterprise Intent Detector",
goal=f"Analyze intent signals for {company_name} to see if they are ready to buy AI automation services.",
backstory="You are a brilliant data analyst who spots buying signals across public footprints.",
verbose=False,
allow_delegation=False,
llm=self.llm
)
researcher = Agent(
role="Enterprise Account Researcher",
goal=f"Deeply research {company_name} (Sector: {sector}, City: {city}) and extract key pain points and budget markers.",
backstory="You are an elite B2B SDR with a 99% accuracy rate. You look for inefficiencies.",
verbose=False,
allow_delegation=False,
llm=self.llm
)
personalizer = Agent(
role="Multi-Channel Personalizer",
goal="Craft the perfect outreach strategy and opener based on research and existing memory context.",
backstory="You are a persuasive copywriter mastering enterprise psychology. You write to C-levels.",
verbose=False,
allow_delegation=False,
llm=self.llm
)
# 3. Define Tasks
task1 = Task(
description=f"Analyze {company_name}. Is there growth or struggle? Return a short summary.",
agent=intent_detector,
expected_output="A short paragraph on company growth and potential intent."
)
task2 = Task(
description=f"Extract pain points for {company_name} given previous insights. Memory Context: {mem_context}",
agent=researcher,
expected_output="A bulleted list of 3 major pain points assuming they lack AI automation.",
context=[task1]
)
task3 = Task(
description=f"Write a highly personalized 2-sentence opener for WhatsApp/Email addressed to the CEO of {company_name}. Use the pain points extracted.",
agent=personalizer,
expected_output="A compelling personalized message opener.",
context=[task2]
)
# 4. Run the Crew
try:
crew = Crew(
agents=[intent_detector, researcher, personalizer],
tasks=[task1, task2, task3],
process=Process.sequential
)
result = crew.kickoff()
final_output = str(result)
# Store in Episodic Memory
empire_memory.add_insight(
company_name=company_name,
insight=f"Generated Personalized Opener: {final_output}"
)
return {
"personalized_opener": final_output,
"crew_enrichment_success": True
}
except Exception as e:
logger.error(f"CrewAI execution failed: {e}")
return {"crew_enrichment_error": str(e)}