muzakkirhussain011 commited on
Commit
cddf0a7
·
1 Parent(s): 1a48dce

Add application files

Browse files
Files changed (2) hide show
  1. app.py +145 -28
  2. mcp/agents/autonomous_agent_hf.py +3 -2
app.py CHANGED
@@ -556,15 +556,29 @@ async def setup_client_company(company_name: str, progress=gr.Progress()):
556
  yield f"❌ Agent init failed: {e}"
557
  return
558
 
559
- task = f"""Research {company_name} to understand:
560
- 1. What they do, their products/services
561
  2. Their target market and ideal customers
562
  3. Their industry and market position
563
  4. Their value proposition
564
  5. What type of companies would be good prospects for them
565
 
566
- Save all findings. This is OUR company - we need this to find matching prospects."""
 
 
 
 
 
567
 
 
 
 
 
 
 
 
 
 
568
  try:
569
  async for event in agent.run(task, max_iterations=12):
570
  event_type = event.get("type")
@@ -572,12 +586,13 @@ Save all findings. This is OUR company - we need this to find matching prospects
572
  tool = event.get("tool", "")
573
  if tool == "search_web":
574
  output += f"🔍 Searching for {company_name}...\n"
 
575
  elif tool == "search_news":
576
  output += f"📰 Finding news...\n"
577
  elif tool in ["save_company", "save_fact"]:
578
  output += f"💾 Saving information...\n"
579
  yield output
580
- progress(0.5)
581
  elif event_type == "tool_result":
582
  tool = event.get("tool", "")
583
  result = event.get("result", {})
@@ -585,8 +600,13 @@ Save all findings. This is OUR company - we need this to find matching prospects
585
  count = result.get("count", 0) if isinstance(result, dict) else 0
586
  output += f" ✅ Found {count} results\n"
587
  yield output
 
 
 
 
 
588
  elif event_type == "agent_complete":
589
- final_answer = event.get("final_answer", "")
590
  knowledge_base["client"] = {
591
  "name": company_name,
592
  "raw_research": final_answer,
@@ -598,8 +618,44 @@ Save all findings. This is OUR company - we need this to find matching prospects
598
  yield output
599
  progress(1.0)
600
  return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  except Exception as e:
 
 
 
 
 
 
602
  output += f"\n⚠️ Error: {e}\n"
 
603
  yield output
604
 
605
 
@@ -639,26 +695,42 @@ async def discover_prospects(num_prospects: int = 5, progress=gr.Progress()):
639
  yield f"❌ Agent init failed: {e}"
640
  return
641
 
642
- task = f"""You are finding prospects for {client_name}.
643
 
644
  About {client_name}:
645
  {client_info}
646
 
647
- Your task:
648
- 1. Search for {num_prospects} companies that would be ideal customers for {client_name}
649
- 2. For EACH prospect company found:
650
- a. Research the company thoroughly
651
- b. Find 2-3 decision makers (CEO, VP Sales, CTO, Head of Marketing, etc.)
652
- c. Save the prospect with save_prospect
653
- d. Save each contact with save_contact
654
- e. Draft a personalized outreach email using send_email
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
 
656
  Focus on finding companies that:
657
  - Would benefit from {client_name}'s products/services
658
  - Are in industries that match {client_name}'s target market
659
- - Are the right size and stage
660
 
661
- For each prospect, explain WHY they're a good fit for {client_name}."""
662
 
663
  prospects_found = []
664
  contacts_found = []
@@ -671,6 +743,7 @@ For each prospect, explain WHY they're a good fit for {client_name}."""
671
 
672
  try:
673
  iteration = 0
 
674
  async for event in agent.run(task, max_iterations=25):
675
  event_type = event.get("type")
676
  iteration += 1
@@ -704,9 +777,16 @@ For each prospect, explain WHY they're a good fit for {client_name}."""
704
  }
705
  elif tool == "save_contact":
706
  if isinstance(tool_input, dict):
707
- name = tool_input.get("name", "Unknown")
 
 
 
 
 
 
708
  title = tool_input.get("title", "")
709
- company = tool_input.get("company_name", current_prospect_name or "Unknown")
 
710
  output += f"👤 Found contact: {name} ({title})\n"
711
  # Capture contact data during tool_call
712
  pending_contact = {
@@ -734,15 +814,21 @@ For each prospect, explain WHY they're a good fit for {client_name}."""
734
  tool = event.get("tool", "")
735
  result = event.get("result", {})
736
 
737
- if tool == "save_prospect" and pending_prospect:
738
- prospects_found.append(pending_prospect)
739
- output += f" ✅ Prospect saved\n"
740
- pending_prospect = None
 
 
 
741
 
742
- elif tool == "save_contact" and pending_contact:
743
- contacts_found.append(pending_contact)
744
- output += f" ✅ Contact saved\n"
745
- pending_contact = None
 
 
 
746
 
747
  elif tool == "send_email":
748
  output += f" ✅ Email drafted\n"
@@ -756,13 +842,19 @@ For each prospect, explain WHY they're a good fit for {client_name}."""
756
 
757
  yield output
758
 
 
 
 
 
 
 
759
  elif event_type == "agent_complete":
760
  # Save all to knowledge base
761
  knowledge_base["prospects"].extend(prospects_found)
762
  knowledge_base["contacts"].extend(contacts_found)
763
  knowledge_base["emails"].extend(emails_drafted)
764
 
765
- final_answer = event.get("final_answer", "")
766
 
767
  output += "\n---\n\n"
768
  output += f"## ✅ Discovery Complete!\n\n"
@@ -787,7 +879,32 @@ For each prospect, explain WHY they're a good fit for {client_name}."""
787
 
788
  output += "\n---\n\n"
789
  output += f"## ⏱️ Discovery Summary (Partial)\n\n"
790
- output += f"Found {len(prospects_found)} prospects, {len(contacts_found)} contacts\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  yield output
792
  return
793
 
 
556
  yield f"❌ Agent init failed: {e}"
557
  return
558
 
559
+ task = f"""Research {company_name} to understand their business. Use search_web to find information about:
560
+ 1. What {company_name} does - their products/services
561
  2. Their target market and ideal customers
562
  3. Their industry and market position
563
  4. Their value proposition
564
  5. What type of companies would be good prospects for them
565
 
566
+ Use the save_company tool to save information about {company_name}:
567
+ - company_id: "{company_name.lower().replace(' ', '_')}"
568
+ - name: "{company_name}"
569
+ - domain: their website domain
570
+ - industry: their industry
571
+ - description: brief company description
572
 
573
+ After researching, provide a comprehensive summary of:
574
+ - What {company_name} does
575
+ - Who their ideal customers are
576
+ - What industries/company types would benefit from their services
577
+
578
+ This is OUR company - we need this information to find matching prospects."""
579
+
580
+ last_research = "" # Track last AI response for fallback
581
+ search_count = 0
582
  try:
583
  async for event in agent.run(task, max_iterations=12):
584
  event_type = event.get("type")
 
586
  tool = event.get("tool", "")
587
  if tool == "search_web":
588
  output += f"🔍 Searching for {company_name}...\n"
589
+ search_count += 1
590
  elif tool == "search_news":
591
  output += f"📰 Finding news...\n"
592
  elif tool in ["save_company", "save_fact"]:
593
  output += f"💾 Saving information...\n"
594
  yield output
595
+ progress(0.3 + min(search_count * 0.1, 0.4))
596
  elif event_type == "tool_result":
597
  tool = event.get("tool", "")
598
  result = event.get("result", {})
 
600
  count = result.get("count", 0) if isinstance(result, dict) else 0
601
  output += f" ✅ Found {count} results\n"
602
  yield output
603
+ elif event_type == "thought":
604
+ # Capture AI thoughts for potential use as research summary
605
+ thought = event.get("thought", "")
606
+ if thought and len(thought) > len(last_research):
607
+ last_research = thought
608
  elif event_type == "agent_complete":
609
+ final_answer = event.get("final_answer", "") or last_research
610
  knowledge_base["client"] = {
611
  "name": company_name,
612
  "raw_research": final_answer,
 
618
  yield output
619
  progress(1.0)
620
  return
621
+ elif event_type == "agent_max_iterations":
622
+ # Still save what we have
623
+ final_answer = last_research or f"Research completed for {company_name}. Ready to find prospects."
624
+ knowledge_base["client"] = {
625
+ "name": company_name,
626
+ "raw_research": final_answer,
627
+ "researched_at": datetime.now().strftime("%Y-%m-%d %H:%M")
628
+ }
629
+ output += f"\n---\n\n## ✅ {company_name} Profile Complete!\n\n"
630
+ output += "**Next step:** Go to the **Prospects** tab and click **'🔍 Find Prospects'** to let AI discover potential customers.\n\n"
631
+ if final_answer:
632
+ output += f"---\n\n### 📋 Research Summary\n\n{final_answer}"
633
+ yield output
634
+ progress(1.0)
635
+ return
636
+ elif event_type == "agent_error":
637
+ error_msg = event.get("error", "Unknown error")
638
+ # Still save basic profile so user can proceed
639
+ knowledge_base["client"] = {
640
+ "name": company_name,
641
+ "raw_research": last_research or f"{company_name} - manual research may be needed.",
642
+ "researched_at": datetime.now().strftime("%Y-%m-%d %H:%M")
643
+ }
644
+ output += f"\n⚠️ AI encountered an issue: {error_msg}\n"
645
+ output += f"\n---\n\n## ⚠️ {company_name} Setup (Partial)\n\n"
646
+ output += "**Note:** Some research may be incomplete. You can still proceed to find prospects.\n\n"
647
+ yield output
648
+ progress(1.0)
649
+ return
650
  except Exception as e:
651
+ # Save basic profile on exception so user can still proceed
652
+ knowledge_base["client"] = {
653
+ "name": company_name,
654
+ "raw_research": last_research or f"{company_name} - setup interrupted.",
655
+ "researched_at": datetime.now().strftime("%Y-%m-%d %H:%M")
656
+ }
657
  output += f"\n⚠️ Error: {e}\n"
658
+ output += f"\n**Note:** Basic profile saved. You can still try to find prospects.\n"
659
  yield output
660
 
661
 
 
695
  yield f"❌ Agent init failed: {e}"
696
  return
697
 
698
+ task = f"""You are an AI sales agent finding prospects for {client_name}.
699
 
700
  About {client_name}:
701
  {client_info}
702
 
703
+ IMPORTANT: You MUST use the tools to save data. Follow these steps for EACH prospect:
704
+
705
+ 1. Use search_web to find {num_prospects} companies that would be ideal customers for {client_name}
706
+ 2. For EACH company found, you MUST:
707
+ a. Use save_prospect tool with these parameters:
708
+ - prospect_id: unique ID like "prospect_1"
709
+ - company_id: unique ID like "company_1"
710
+ - company_name: the company name
711
+ - company_domain: the company website domain
712
+ - fit_score: 1-100 score
713
+ - metadata: {{"summary": "company description", "industry": "their industry", "fit_reason": "why they're a good fit"}}
714
+
715
+ b. Use save_contact tool for 2-3 decision makers with:
716
+ - contact_id: unique ID
717
+ - company_id: same as above
718
+ - email: their email if known or generate likely format like "[email protected]"
719
+ - first_name: their first name
720
+ - last_name: their last name
721
+ - title: their job title (CEO, VP Sales, CTO, etc.)
722
+
723
+ c. Use send_email tool to draft outreach:
724
+ - to: the contact email
725
+ - subject: personalized subject line
726
+ - body: personalized email body
727
+ - prospect_id: the prospect_id from step a
728
 
729
  Focus on finding companies that:
730
  - Would benefit from {client_name}'s products/services
731
  - Are in industries that match {client_name}'s target market
 
732
 
733
+ After processing all {num_prospects} prospects, provide a brief summary of what you found."""
734
 
735
  prospects_found = []
736
  contacts_found = []
 
743
 
744
  try:
745
  iteration = 0
746
+ last_final_answer = "" # Track the last complete response from AI
747
  async for event in agent.run(task, max_iterations=25):
748
  event_type = event.get("type")
749
  iteration += 1
 
777
  }
778
  elif tool == "save_contact":
779
  if isinstance(tool_input, dict):
780
+ # Handle both "name" and "first_name/last_name" formats
781
+ first_name = tool_input.get("first_name", "")
782
+ last_name = tool_input.get("last_name", "")
783
+ if first_name or last_name:
784
+ name = f"{first_name} {last_name}".strip()
785
+ else:
786
+ name = tool_input.get("name", "Unknown")
787
  title = tool_input.get("title", "")
788
+ # Get company from company_id or current context
789
+ company = tool_input.get("company_name") or tool_input.get("company_id") or current_prospect_name or "Unknown"
790
  output += f"👤 Found contact: {name} ({title})\n"
791
  # Capture contact data during tool_call
792
  pending_contact = {
 
814
  tool = event.get("tool", "")
815
  result = event.get("result", {})
816
 
817
+ if tool == "save_prospect":
818
+ if pending_prospect:
819
+ prospects_found.append(pending_prospect)
820
+ output += f" ✅ Prospect saved: {pending_prospect.get('name', 'Unknown')}\n"
821
+ pending_prospect = None
822
+ else:
823
+ output += f" ✅ Prospect saved\n"
824
 
825
+ elif tool == "save_contact":
826
+ if pending_contact:
827
+ contacts_found.append(pending_contact)
828
+ output += f" ✅ Contact saved: {pending_contact.get('name', 'Unknown')}\n"
829
+ pending_contact = None
830
+ else:
831
+ output += f" ✅ Contact saved\n"
832
 
833
  elif tool == "send_email":
834
  output += f" ✅ Email drafted\n"
 
842
 
843
  yield output
844
 
845
+ elif event_type == "thought":
846
+ # Capture AI thoughts/responses as potential final answer
847
+ thought = event.get("thought", "")
848
+ if thought:
849
+ last_final_answer = thought
850
+
851
  elif event_type == "agent_complete":
852
  # Save all to knowledge base
853
  knowledge_base["prospects"].extend(prospects_found)
854
  knowledge_base["contacts"].extend(contacts_found)
855
  knowledge_base["emails"].extend(emails_drafted)
856
 
857
+ final_answer = event.get("final_answer", "") or last_final_answer
858
 
859
  output += "\n---\n\n"
860
  output += f"## ✅ Discovery Complete!\n\n"
 
879
 
880
  output += "\n---\n\n"
881
  output += f"## ⏱️ Discovery Summary (Partial)\n\n"
882
+ output += f"| Metric | Count |\n"
883
+ output += f"|--------|-------|\n"
884
+ output += f"| Prospects Found | {len(prospects_found)} |\n"
885
+ output += f"| Decision Makers | {len(contacts_found)} |\n"
886
+ output += f"| Emails Drafted | {len(emails_drafted)} |\n\n"
887
+ if last_final_answer:
888
+ output += "---\n\n### 📋 AI Summary\n\n"
889
+ output += last_final_answer
890
+ yield output
891
+ return
892
+
893
+ elif event_type == "agent_error":
894
+ # Save what we found so far even on error
895
+ knowledge_base["prospects"].extend(prospects_found)
896
+ knowledge_base["contacts"].extend(contacts_found)
897
+ knowledge_base["emails"].extend(emails_drafted)
898
+
899
+ error_msg = event.get("error", "Unknown error")
900
+ output += f"\n⚠️ AI Error: {error_msg}\n"
901
+ output += f"\n---\n\n"
902
+ output += f"## ⚠️ Discovery Interrupted\n\n"
903
+ output += f"| Metric | Count |\n"
904
+ output += f"|--------|-------|\n"
905
+ output += f"| Prospects Found | {len(prospects_found)} |\n"
906
+ output += f"| Decision Makers | {len(contacts_found)} |\n"
907
+ output += f"| Emails Drafted | {len(emails_drafted)} |\n\n"
908
  yield output
909
  return
910
 
mcp/agents/autonomous_agent_hf.py CHANGED
@@ -305,10 +305,11 @@ When you have completed the task, provide a summary of what you accomplished."""
305
  final_content = assistant_message.content or ""
306
 
307
  if final_content:
 
308
  yield {
309
  "type": "thought",
310
- "thought": final_content[:200] + "..." if len(final_content) > 200 else final_content,
311
- "message": f"AI Response"
312
  }
313
 
314
  # Check if this looks like a final answer (after at least one iteration)
 
305
  final_content = assistant_message.content or ""
306
 
307
  if final_content:
308
+ # Yield full thought content for capture, truncated for display message
309
  yield {
310
  "type": "thought",
311
+ "thought": final_content, # Full content for capture
312
+ "message": f"AI Response: {final_content[:100]}..." if len(final_content) > 100 else f"AI Response: {final_content}"
313
  }
314
 
315
  # Check if this looks like a final answer (after at least one iteration)