ak0601 commited on
Commit
9ae4e14
·
verified ·
1 Parent(s): 99cddfb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -37
app.py CHANGED
@@ -576,7 +576,7 @@ async def generate_campaign_sequences(campaign_id: int, request: GenerateSequenc
576
  return {
577
  "ok": True,
578
  "message": "Sequences generated and saved successfully",
579
- "generated_sequences": [seq.dict() for seq in generated_sequences],
580
  "save_result": result
581
  }
582
 
@@ -836,6 +836,16 @@ def generate_template_welcome_closing_messages(lead_data: Dict[str, Any]) -> Dic
836
  }
837
 
838
  async def generate_sequences_with_llm(job_description: str) -> List[CampaignSequence]:
 
 
 
 
 
 
 
 
 
 
839
  """Generate email sequences using LangChain and OpenAI based on job description"""
840
 
841
  if not LANGCHAIN_AVAILABLE:
@@ -848,46 +858,34 @@ async def generate_sequences_with_llm(job_description: str) -> List[CampaignSequ
848
  return await generate_template_sequences(job_description)
849
 
850
  llm = ChatOpenAI(
851
- model="gpt-4",
852
  temperature=0.7,
853
  openai_api_key=openai_api_key
854
  )
 
855
 
856
- system_prompt = """You are an expert email sequence generator for recruitment campaigns.
857
-
858
  Generate ONLY the subject lines and email body content for 3 professional email sequences.
859
-
 
 
860
  Email Sequence Structure:
861
- 1. INTRODUCTION (Day 1): Ask for consent and interest in the role
862
- 2. OUTREACH (Day 3): Provide detailed job information
863
  3. FOLLOW-UP (Day 5): Follow up on updates and next steps
864
-
865
  Requirements:
866
- - First sequence needs 2 A/B testing variants (A and B)
867
- - Second and third sequences are follow-ups (no subject line needed)
868
  - All emails should be HTML formatted with proper <br> tags
869
  - Professional but friendly tone
870
  - Include clear call-to-actions
871
  - Focus on building consent and trust
872
-
873
  Respond with ONLY a JSON object containing the email content:
874
- {
875
- "sequence1_variant_a": {
876
- "subject": "Subject line for variant A",
877
- "body": "HTML formatted email body for variant A"
878
- },
879
- "sequence1_variant_b": {
880
- "subject": "Subject line for variant B",
881
- "body": "HTML formatted email body for variant B"
882
- },
883
- "sequence2": {
884
- "body": "HTML formatted email body for outreach"
885
- },
886
- "sequence3": {
887
- "body": "HTML formatted email body for follow-up"
888
- }
889
- }
890
-
891
  IMPORTANT: Respond with ONLY valid JSON. No additional text."""
892
 
893
  prompt_template = ChatPromptTemplate.from_messages([
@@ -896,19 +894,121 @@ async def generate_sequences_with_llm(job_description: str) -> List[CampaignSequ
896
  ])
897
 
898
  messages = prompt_template.format_messages(job_description=job_description)
899
- response = await llm.ainvoke(messages)
900
 
901
  try:
902
- content = response.content.strip()
 
903
 
904
- if content.startswith("```json"):
905
- content = content[7:]
906
- if content.endswith("```"):
907
- content = content[:-3]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
908
 
909
- content = content.strip()
910
- parsed_data = json.loads(content)
911
- sequences = create_sequences_from_content(parsed_data, job_description)
912
  return sequences
913
 
914
  except Exception as parse_error:
 
576
  return {
577
  "ok": True,
578
  "message": "Sequences generated and saved successfully",
579
+ "generated_sequences": [seq for seq in generated_sequences],
580
  "save_result": result
581
  }
582
 
 
836
  }
837
 
838
  async def generate_sequences_with_llm(job_description: str) -> List[CampaignSequence]:
839
+ class email_seq(BaseModel):
840
+ subject: str = Field(description="Subject line for the email")
841
+ body: str = Field(description="Body of the email")
842
+ class structure(BaseModel):
843
+ introduction: email_seq = Field(description="Email sequence for sequence 1 asking for consent and interest in the role")
844
+ email_sequence_2: email_seq = Field(description="Email sequence for sequence 2 following up on updates and next steps")
845
+ email_sequence_3: email_seq = Field(description="Email sequence for sequence 3 Another variant on following up on updates and next steps")
846
+
847
+
848
+
849
  """Generate email sequences using LangChain and OpenAI based on job description"""
850
 
851
  if not LANGCHAIN_AVAILABLE:
 
858
  return await generate_template_sequences(job_description)
859
 
860
  llm = ChatOpenAI(
861
+ model="gpt-4o",
862
  temperature=0.7,
863
  openai_api_key=openai_api_key
864
  )
865
+ str_llm = llm.with_structured_output(structure)
866
 
867
+ system_prompt = """You are an expert email sequence template generator for recruitment campaigns.
868
+
869
  Generate ONLY the subject lines and email body content for 3 professional email sequences.
870
+ Write the email on behalf of Ali Taghikhani, CEO SRN
871
+ In the templates use placeholders like, welcome_message, closing message, first_name, company,title only.
872
+
873
  Email Sequence Structure:
874
+ 1. INTRODUCTION (Day 1): Ask for consent and interest in the role, In the starting use the welcome message placeholder, and in the end use closing message template along with the name and title of sender.placeholders must be used like this {{first_name}}
875
+ 2. OUTREACH (Day 3): Provide detailed job information
876
  3. FOLLOW-UP (Day 5): Follow up on updates and next steps
877
+
878
  Requirements:
879
+ - First sequence will only ask about the consent and interest in the role, no other information is needed.
880
+ - Second and third sequences are follow-ups (no subject line needed) in the 3rd sequence try providing some information about the role and the company.
881
  - All emails should be HTML formatted with proper <br> tags
882
  - Professional but friendly tone
883
  - Include clear call-to-actions
884
  - Focus on building consent and trust
885
+
886
  Respond with ONLY a JSON object containing the email content:
887
+
888
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
889
  IMPORTANT: Respond with ONLY valid JSON. No additional text."""
890
 
891
  prompt_template = ChatPromptTemplate.from_messages([
 
894
  ])
895
 
896
  messages = prompt_template.format_messages(job_description=job_description)
897
+ response = await str_llm.ainvoke(messages)
898
 
899
  try:
900
+ # Handle the response structure correctly
901
+ sequences = []
902
 
903
+ # Sequence 1: Introduction with A/B variants
904
+ if hasattr(response, 'introduction') and response.introduction:
905
+ # Check if body is a string or dict
906
+ intro_body = response.introduction.body
907
+ if isinstance(intro_body, dict):
908
+ # If it's a dict, extract the content
909
+ intro_body = str(intro_body)
910
+
911
+ sequences.append(CampaignSequence(
912
+ seq_number=1,
913
+ seq_delay_details=SeqDelayDetails(delay_in_days=1),
914
+ seq_variants=[
915
+ SeqVariant(
916
+ subject=response.introduction.subject,
917
+ email_body=intro_body,
918
+ variant_label="A"
919
+ )
920
+ ]
921
+ ))
922
+
923
+ # Sequence 2: Outreach
924
+ if hasattr(response, 'email_sequence_2') and response.email_sequence_2:
925
+ seq2_body = response.email_sequence_2.body
926
+ if isinstance(seq2_body, dict):
927
+ seq2_body = str(seq2_body)
928
+
929
+ sequences.append(CampaignSequence(
930
+ seq_number=2,
931
+ seq_delay_details=SeqDelayDetails(delay_in_days=3),
932
+ subject="",
933
+ email_body=seq2_body
934
+ ))
935
+
936
+ # Sequence 3: Follow-up
937
+ if hasattr(response, 'email_sequence_3') and response.email_sequence_3:
938
+ seq3_body = response.email_sequence_3.body
939
+ if isinstance(seq3_body, dict):
940
+ seq3_body = str(seq3_body)
941
+
942
+ sequences.append(CampaignSequence(
943
+ seq_number=3,
944
+ seq_delay_details=SeqDelayDetails(delay_in_days=5),
945
+ subject="",
946
+ email_body=seq3_body
947
+ ))
948
+
949
+ # Fill with templates if needed
950
+ while len(sequences) < 3:
951
+ if len(sequences) == 0:
952
+ sequences.append(CampaignSequence(
953
+ seq_number=1,
954
+ seq_delay_details=SeqDelayDetails(delay_in_days=1),
955
+ seq_variants=[
956
+ SeqVariant(
957
+ subject=f"Quick question about {job_description}",
958
+ email_body=f"""<p>Hi there,<br><br>
959
+ I came across your profile and noticed your experience in {job_description}.
960
+ I'm reaching out because we have some exciting opportunities that might be a great fit for your background.<br><br>
961
+ Before I share more details, I wanted to ask: Are you currently open to exploring new opportunities in this space?<br><br>
962
+ Would you be interested in hearing more about the roles we have available?<br><br>
963
+ Best regards,<br>
964
+ [Your Name]</p>""",
965
+ variant_label="A"
966
+ ),
967
+ SeqVariant(
968
+ subject=f"Interested in {job_description} opportunities?",
969
+ email_body=f"""<p>Hello,<br><br>
970
+ I hope this message finds you well. I'm a recruiter specializing in {job_description} positions.<br><br>
971
+ I'd love to connect and share some opportunities that align with your expertise.
972
+ Are you currently open to exploring new roles in this space?<br><br>
973
+ If so, I can send you specific details about the positions we have available.<br><br>
974
+ Thanks,<br>
975
+ [Your Name]</p>""",
976
+ variant_label="B"
977
+ )
978
+ ]
979
+ ))
980
+ elif len(sequences) == 1:
981
+ sequences.append(CampaignSequence(
982
+ seq_number=2,
983
+ seq_delay_details=SeqDelayDetails(delay_in_days=3),
984
+ subject="",
985
+ email_body=f"""<p>Hi,<br><br>
986
+ Thanks for your interest! Here are more details about the {job_description} opportunities:<br><br>
987
+ <strong>Role Details:</strong><br>
988
+ • [Specific responsibilities]<br>
989
+ • [Required skills and experience]<br>
990
+ • [Team and company information]<br><br>
991
+ <strong>Benefits:</strong><br>
992
+ • [Compensation and benefits]<br>
993
+ • [Growth opportunities]<br>
994
+ • [Work environment]<br><br>
995
+ Would you be interested in a quick call to discuss this role in more detail?<br><br>
996
+ Best regards,<br>
997
+ [Your Name]</p>"""
998
+ ))
999
+ elif len(sequences) == 2:
1000
+ sequences.append(CampaignSequence(
1001
+ seq_number=3,
1002
+ seq_delay_details=SeqDelayDetails(delay_in_days=5),
1003
+ subject="",
1004
+ email_body=f"""<p>Hi,<br><br>
1005
+ Just wanted to follow up on the {job_description} opportunity I shared.<br><br>
1006
+ Have you had a chance to review the information? I'd love to hear your thoughts and answer any questions.<br><br>
1007
+ If you're interested, I can help schedule next steps. If not, no worries at all!<br><br>
1008
+ Thanks for your time!<br>
1009
+ [Your Name]</p>"""
1010
+ ))
1011
 
 
 
 
1012
  return sequences
1013
 
1014
  except Exception as parse_error: