Spaces:
Sleeping
Sleeping
Integrate lead_scoring_agent into research_agent.py - Add score_lead() in run_pipeline()
Browse files- research_agent.py +33 -14
research_agent.py
CHANGED
|
@@ -2,12 +2,16 @@ import csv
|
|
| 2 |
import json
|
| 3 |
import logging
|
| 4 |
from typing import Any, Dict, List
|
|
|
|
|
|
|
| 5 |
|
| 6 |
class ResearchAgent:
|
| 7 |
"""
|
| 8 |
Collects, augments, audits, and outputs lead and signal data for outreach,
|
| 9 |
with robust error/memory handling and dynamic variable mapping.
|
|
|
|
| 10 |
"""
|
|
|
|
| 11 |
def __init__(self, db: Any = None, schema: Dict[str, Any] = None):
|
| 12 |
self.db = db
|
| 13 |
self.schema = schema or {}
|
|
@@ -17,7 +21,7 @@ class ResearchAgent:
|
|
| 17 |
self.refined = []
|
| 18 |
self.mcp_updates = []
|
| 19 |
logging.basicConfig(level=logging.INFO)
|
| 20 |
-
|
| 21 |
def map_raw_data(self, raw_lead: Dict[str, Any], signals: Dict[str, Any], dynamic_vars: Dict[str, Any]) -> Dict[str, Any]:
|
| 22 |
mapped = {}
|
| 23 |
try:
|
|
@@ -29,7 +33,7 @@ class ResearchAgent:
|
|
| 29 |
self.errors.append(f"Mapping error: {e}")
|
| 30 |
logging.error(f"Mapping error: {e}")
|
| 31 |
return mapped
|
| 32 |
-
|
| 33 |
def handle_loop_errors(self, data_list: List[Dict[str, Any]]):
|
| 34 |
for idx, entry in enumerate(data_list):
|
| 35 |
try:
|
|
@@ -37,19 +41,19 @@ class ResearchAgent:
|
|
| 37 |
except Exception as e:
|
| 38 |
self.errors.append(f"Loop error at {idx}: {e}")
|
| 39 |
logging.warning(f"Loop error at {idx}: {e}")
|
| 40 |
-
|
| 41 |
def memory_management(self, current: Dict[str, Any]):
|
| 42 |
self.memory.append(current)
|
| 43 |
if len(self.memory) > 50:
|
| 44 |
dropped = self.memory.pop(0)
|
| 45 |
logging.info(f"Dropped old memory: {dropped}")
|
| 46 |
-
|
| 47 |
def refine_profile(self, profile: Dict[str, Any], messaging_signals: Dict[str, Any]) -> Dict[str, Any]:
|
| 48 |
"""Output the most outreach-ready version of the profile."""
|
| 49 |
refined = {**profile, **messaging_signals}
|
| 50 |
self.refined.append(refined)
|
| 51 |
return refined
|
| 52 |
-
|
| 53 |
def handoff(self, profiles: List[Dict[str, Any]], target: str = 'csv', path: str = 'handoff.csv'):
|
| 54 |
"""Wire/export to csv/mcp/db."""
|
| 55 |
try:
|
|
@@ -68,7 +72,7 @@ class ResearchAgent:
|
|
| 68 |
except Exception as e:
|
| 69 |
self.errors.append(f"Handoff error: {e}")
|
| 70 |
logging.error(f"Handoff error: {e}")
|
| 71 |
-
|
| 72 |
def audit(self, profiles: List[Dict[str, Any]]):
|
| 73 |
"""Audit field completeness, error/correction, and handoff readiness."""
|
| 74 |
required_fields = self.schema.get('required', set())
|
|
@@ -77,7 +81,7 @@ class ResearchAgent:
|
|
| 77 |
if missing:
|
| 78 |
self.errors.append(f"Profile {idx} missing: {missing}")
|
| 79 |
logging.warning(f"Profile {idx} missing: {missing}")
|
| 80 |
-
|
| 81 |
def export_refined_for_outreach(self, out_path: str = 'refined_for_outreach.csv'):
|
| 82 |
try:
|
| 83 |
with open(out_path, 'w', newline='') as f:
|
|
@@ -87,18 +91,33 @@ class ResearchAgent:
|
|
| 87 |
except Exception as e:
|
| 88 |
self.errors.append(f"Export error: {e}")
|
| 89 |
logging.error(f"Export error: {e}")
|
| 90 |
-
|
| 91 |
def get_messaging_recommendations(self, profile: Dict[str, Any]) -> Dict[str, Any]:
|
| 92 |
"""Stub: Replace with your ML/model recommendation logic."""
|
| 93 |
recs = {"recommendation": f"Personalize outreach for {profile.get('name', 'Unknown')}"}
|
| 94 |
return recs
|
| 95 |
-
|
| 96 |
def run_pipeline(self, leads, signals_list, dynamic_vars_list):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
for raw_lead, signals, dynamic_vars in zip(leads, signals_list, dynamic_vars_list):
|
|
|
|
| 98 |
mapped = self.map_raw_data(raw_lead, signals, dynamic_vars)
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
self.audit(self.profiles)
|
| 104 |
-
self.handoff(self.refined)
|
|
|
|
| 2 |
import json
|
| 3 |
import logging
|
| 4 |
from typing import Any, Dict, List
|
| 5 |
+
# Import lead_scoring_agent for lead scoring integration
|
| 6 |
+
from lead_scoring_agent import score_lead
|
| 7 |
|
| 8 |
class ResearchAgent:
|
| 9 |
"""
|
| 10 |
Collects, augments, audits, and outputs lead and signal data for outreach,
|
| 11 |
with robust error/memory handling and dynamic variable mapping.
|
| 12 |
+
Integrates lead_scoring_agent to score leads as first logic step in pipeline.
|
| 13 |
"""
|
| 14 |
+
|
| 15 |
def __init__(self, db: Any = None, schema: Dict[str, Any] = None):
|
| 16 |
self.db = db
|
| 17 |
self.schema = schema or {}
|
|
|
|
| 21 |
self.refined = []
|
| 22 |
self.mcp_updates = []
|
| 23 |
logging.basicConfig(level=logging.INFO)
|
| 24 |
+
|
| 25 |
def map_raw_data(self, raw_lead: Dict[str, Any], signals: Dict[str, Any], dynamic_vars: Dict[str, Any]) -> Dict[str, Any]:
|
| 26 |
mapped = {}
|
| 27 |
try:
|
|
|
|
| 33 |
self.errors.append(f"Mapping error: {e}")
|
| 34 |
logging.error(f"Mapping error: {e}")
|
| 35 |
return mapped
|
| 36 |
+
|
| 37 |
def handle_loop_errors(self, data_list: List[Dict[str, Any]]):
|
| 38 |
for idx, entry in enumerate(data_list):
|
| 39 |
try:
|
|
|
|
| 41 |
except Exception as e:
|
| 42 |
self.errors.append(f"Loop error at {idx}: {e}")
|
| 43 |
logging.warning(f"Loop error at {idx}: {e}")
|
| 44 |
+
|
| 45 |
def memory_management(self, current: Dict[str, Any]):
|
| 46 |
self.memory.append(current)
|
| 47 |
if len(self.memory) > 50:
|
| 48 |
dropped = self.memory.pop(0)
|
| 49 |
logging.info(f"Dropped old memory: {dropped}")
|
| 50 |
+
|
| 51 |
def refine_profile(self, profile: Dict[str, Any], messaging_signals: Dict[str, Any]) -> Dict[str, Any]:
|
| 52 |
"""Output the most outreach-ready version of the profile."""
|
| 53 |
refined = {**profile, **messaging_signals}
|
| 54 |
self.refined.append(refined)
|
| 55 |
return refined
|
| 56 |
+
|
| 57 |
def handoff(self, profiles: List[Dict[str, Any]], target: str = 'csv', path: str = 'handoff.csv'):
|
| 58 |
"""Wire/export to csv/mcp/db."""
|
| 59 |
try:
|
|
|
|
| 72 |
except Exception as e:
|
| 73 |
self.errors.append(f"Handoff error: {e}")
|
| 74 |
logging.error(f"Handoff error: {e}")
|
| 75 |
+
|
| 76 |
def audit(self, profiles: List[Dict[str, Any]]):
|
| 77 |
"""Audit field completeness, error/correction, and handoff readiness."""
|
| 78 |
required_fields = self.schema.get('required', set())
|
|
|
|
| 81 |
if missing:
|
| 82 |
self.errors.append(f"Profile {idx} missing: {missing}")
|
| 83 |
logging.warning(f"Profile {idx} missing: {missing}")
|
| 84 |
+
|
| 85 |
def export_refined_for_outreach(self, out_path: str = 'refined_for_outreach.csv'):
|
| 86 |
try:
|
| 87 |
with open(out_path, 'w', newline='') as f:
|
|
|
|
| 91 |
except Exception as e:
|
| 92 |
self.errors.append(f"Export error: {e}")
|
| 93 |
logging.error(f"Export error: {e}")
|
| 94 |
+
|
| 95 |
def get_messaging_recommendations(self, profile: Dict[str, Any]) -> Dict[str, Any]:
|
| 96 |
"""Stub: Replace with your ML/model recommendation logic."""
|
| 97 |
recs = {"recommendation": f"Personalize outreach for {profile.get('name', 'Unknown')}"}
|
| 98 |
return recs
|
| 99 |
+
|
| 100 |
def run_pipeline(self, leads, signals_list, dynamic_vars_list):
|
| 101 |
+
"""
|
| 102 |
+
Run the research pipeline with lead scoring integration.
|
| 103 |
+
Calls score_lead() as first logic step after mapping.
|
| 104 |
+
"""
|
| 105 |
for raw_lead, signals, dynamic_vars in zip(leads, signals_list, dynamic_vars_list):
|
| 106 |
+
# Map raw data
|
| 107 |
mapped = self.map_raw_data(raw_lead, signals, dynamic_vars)
|
| 108 |
+
|
| 109 |
+
# FIRST LOGIC STEP: Score the lead using lead_scoring_agent
|
| 110 |
+
scored_profile = score_lead(mapped)
|
| 111 |
+
logging.info(f"Lead scored: {scored_profile.get('name', 'Unknown')} - Score: {scored_profile.get('lead_score', 'N/A')}")
|
| 112 |
+
|
| 113 |
+
# Continue with memory management and profiling
|
| 114 |
+
self.memory_management(scored_profile)
|
| 115 |
+
self.profiles.append(scored_profile)
|
| 116 |
+
|
| 117 |
+
# Get messaging recommendations and refine
|
| 118 |
+
messaging = self.get_messaging_recommendations(scored_profile)
|
| 119 |
+
refined = self.refine_profile(scored_profile, messaging)
|
| 120 |
+
|
| 121 |
+
# Audit and handoff
|
| 122 |
self.audit(self.profiles)
|
| 123 |
+
self.handoff(self.refined)
|