File size: 4,692 Bytes
9ada6bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import os
import requests
import openai
import gradio as gr
from openai_swarm import Agent, Swarm

# Fetch API keys from environment variables
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
PROXYCURL_API_KEY = os.getenv("PROXYCURL_API_KEY")
FIRECRAWL_API_KEY = os.getenv("FIRECRAWL_API_KEY")

# Function to fetch LinkedIn data using Proxycurl API
def fetch_linkedin_data(linkedin_url):
    headers = {'Authorization': f'Bearer {PROXYCURL_API_KEY}'}
    response = requests.get(f"https://api.proxycurl.com/v1/linkedin/{linkedin_url}", headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        return {"error": "Unable to fetch LinkedIn data"}

# Function to fetch company information using Firecrawl API
def fetch_company_info(company_url):
    headers = {'Authorization': f'Bearer {FIRECRAWL_API_KEY}'}
    response = requests.get(f"https://api.firecrawl.com/v1/scrape?url={company_url}", headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        return {"error": "Unable to fetch company information"}

# Function to structure the email using the "Start with Why" model
def structure_email(user_data, linkedin_info, company_info):
    why = f"I am passionate about {company_info.get('mission', 'your mission')} because it aligns with my experience as {linkedin_info.get('current_role', 'a professional')}."
    how = f"My skills in {user_data['role']} match the requirements and goals of your organization."
    what = f"I can bring my experience in {linkedin_info.get('skills', 'relevant skills')} to help achieve {company_info.get('goal', 'your company goals')}."
    structured_input = f"{why}\n\n{how}\n\n{what}"
    return structured_input

# Function to generate email content using Nvidia Nemotron LLM
def generate_email_content(api_key, prompt):
    openai.api_key = api_key
    response = openai.Completion.create(
        model="nemotron-70b",
        prompt=prompt,
        max_tokens=500
    )
    return response.choices[0].text

# Function to validate the generated email for professional tone and completeness
def validate_email(email_content):
    # Basic validation: check if the email contains key sections (can be expanded)
    return "Why" in email_content and "How" in email_content and "What" in email_content

# Define the ReAct Agent using Swarm framework
class EmailAgent(Agent):
    def __init__(self, user_data):
        super().__init__()
        self.user_data = user_data
        self.iterations = 0

    def act(self):
        linkedin_info = fetch_linkedin_data(self.user_data['linkedin_url'])
        company_info = fetch_company_info(self.user_data['company_url'])
        if "error" in linkedin_info or "error" in company_info:
            return "Error fetching data. Please check the LinkedIn and company URLs."
        
        prompt = structure_email(self.user_data, linkedin_info, company_info)
        email_content = generate_email_content(OPENAI_API_KEY, prompt)
        return email_content

    def react(self, output):
        # React based on the generated email's validity
        if validate_email(output):
            return output
        else:
            # If invalid, refine prompt or retry (up to 3 iterations)
            self.iterations += 1
            if self.iterations < 3:
                refined_prompt = f"Refined: {output}"
                return generate_email_content(OPENAI_API_KEY, refined_prompt)
            else:
                return "Unable to generate a valid email after 3 attempts."

# Define the main function to run the agent within the Swarm
def run_agent(name, email, phone, linkedin_url, company_url, role):
    user_data = {
        "name": name,
        "email": email,
        "phone": phone,
        "linkedin_url": linkedin_url,
        "company_url": company_url,
        "role": role
    }
    
    # Initialize the swarm and add the EmailAgent
    email_swarm = Swarm()
    agent = EmailAgent(user_data)
    email_swarm.add_agent(agent)
    
    # Run the swarm to get the final email content
    result = email_swarm.run()
    return result

# Set up the Gradio interface
final_interface = gr.Interface(
    fn=run_agent,
    inputs=[
        gr.Textbox(label="Name"),
        gr.Textbox(label="Email"),
        gr.Textbox(label="Phone Number"),
        gr.Textbox(label="LinkedIn Profile URL"),
        gr.Textbox(label="Company URL or Name"),
        gr.Textbox(label="Role Being Applied For")
    ],
    outputs="text",
    title="Email Writing AI Agent",
    description="Autonomously generate a professional email tailored to the job application."
)

if __name__ == "__main__":
    final_interface.launch()