siddhartharya commited on
Commit
6c7c3ab
·
verified ·
1 Parent(s): 1240f05

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -55
app.py CHANGED
@@ -1,12 +1,13 @@
1
  import gradio as gr
2
  import requests
3
  import os
 
4
 
5
- # Load API keys securely from environment variables
6
- proxycurl_api_key = os.getenv("PROXYCURL_API_KEY") # Proxycurl API key
7
- groq_api_key = os.getenv("GROQ_CLOUD_API_KEY") # Groq Cloud API key
8
- firecrawl_api_key = os.getenv("FIRECRAWL_API_KEY") # Firecrawl API key
9
- serp_api_key = os.getenv("SERP_API_KEY") # SERP API key for fetching company URL
10
 
11
  class AutonomousEmailAgent:
12
  def __init__(self, linkedin_url, company_name, role, word_limit, user_name, email, phone, linkedin):
@@ -52,47 +53,37 @@ class AutonomousEmailAgent:
52
  """
53
 
54
  # Send the reasoning prompt to the LLM
55
- url = "https://api.groq.com/openai/v1/chat/completions"
56
- headers = {
57
- "Authorization": f"Bearer {groq_api_key}",
58
- "Content-Type": "application/json",
59
- }
60
-
61
- data = {
62
- "messages": [{"role": "user", "content": reasoning_prompt}],
63
- "model": "llama3-8b-8192"
64
- }
65
-
66
- response = requests.post(url, headers=headers, json=data)
67
- if response.status_code == 200:
68
- reasoning_output = response.json()["choices"][0]["message"]["content"].strip()
69
- print("LLM Reasoning Output:", reasoning_output)
70
-
71
- # Now the LLM takes action based on the reflection
72
- return self.act_on_llm_instructions(reasoning_output)
73
- else:
74
- print(f"Error: {response.status_code}, {response.text}")
75
- return "Error: Unable to complete reasoning."
76
 
77
  # Function to act on the LLM's structured instructions
78
  def act_on_llm_instructions(self, reasoning_output):
79
- # Convert the output to lowercase and trim whitespace for easier parsing
80
  instruction = reasoning_output.lower().strip()
81
 
82
  if "scrape" in instruction:
83
- # Action: Fetch company URL via SERP API before scraping
84
  self.fetch_company_url()
85
  if self.company_url:
86
  self.fetch_company_info_with_firecrawl(self.company_url)
87
- # Reflect again by invoking the LLM to reassess
88
  return self.autonomous_reasoning()
89
 
90
  elif "generate_email" in instruction:
91
- # Action: Proceed to generate the email
92
  return self.generate_email()
93
 
94
  elif "fallback" in instruction:
95
- # Action: Use fallback logic or default values
96
  print("Action: Using fallback values for missing data.")
97
  if not self.company_info:
98
  self.company_info = "A leading company in its field."
@@ -101,7 +92,6 @@ class AutonomousEmailAgent:
101
  return self.generate_email()
102
 
103
  else:
104
- # If the LLM returns an unrecognized instruction, fall back to using the current available data
105
  print("Error: Unrecognized instruction from LLM. Proceeding with available data.")
106
  return self.generate_email()
107
 
@@ -123,7 +113,7 @@ class AutonomousEmailAgent:
123
  print(f"Error fetching company URL: {response.status_code}")
124
  self.company_url = None
125
 
126
- # Action: Fetch LinkedIn data via Proxycurl
127
  def fetch_linkedin_data(self):
128
  if not self.linkedin_url:
129
  print("Action: No LinkedIn URL provided, using default bio.")
@@ -146,7 +136,7 @@ class AutonomousEmailAgent:
146
  self.skills = ["Adaptable", "Hardworking"]
147
  self.experiences = ["Worked across various industries"]
148
 
149
- # Action: Fetch company information via Firecrawl API using company URL
150
  def fetch_company_info_with_firecrawl(self, company_url):
151
  print(f"Fetching company info for {company_url} using Firecrawl.")
152
  headers = {"Authorization": f"Bearer {firecrawl_api_key}"}
@@ -165,13 +155,12 @@ class AutonomousEmailAgent:
165
  print(f"Error: Unable to fetch company info via Firecrawl. Using default info.")
166
  self.company_info = "A leading company in its field."
167
 
168
- # Final Action: Generate the email using Groq Cloud LLM with "Start with Why" framework
169
  def generate_email(self):
170
- print("Action: Generating the email with the gathered information.")
171
 
172
  linkedin_text = f"Please find my LinkedIn profile at {self.linkedin}" if self.linkedin else ""
173
 
174
- # Updated prompt to reflect Simon Sinek's "Start with Why" approach
175
  prompt = f"""
176
  Write a professional job application email applying for the {self.role} position at {self.company_name}.
177
 
@@ -194,33 +183,31 @@ class AutonomousEmailAgent:
194
  Email: {self.email}
195
  Phone: {self.phone}
196
  LinkedIn: {self.linkedin}
197
-
198
  The email should not exceed {self.word_limit} words.
199
  """
200
 
201
- url = "https://api.groq.com/openai/v1/chat/completions"
202
- headers = {
203
- "Authorization": f"Bearer {groq_api_key}",
204
- "Content-Type": "application/json",
205
- }
 
 
 
206
 
207
- data = {
208
- "messages": [{"role": "user", "content": prompt}],
209
- "model": "llama3-8b-8192"
210
- }
 
211
 
212
- response = requests.post(url, headers=headers, json=data)
213
- if response.status_code == 200:
214
- return response.json()["choices"][0]["message"]["content"].strip()
215
- else:
216
- print(f"Error: {response.status_code}, {response.text}")
217
- return "Error generating email. Please check your API key or try again later."
218
 
219
  # Main loop following ReAct pattern
220
  def run(self):
221
  self.fetch_linkedin_data() # Fetch LinkedIn data
222
- # Let LLM autonomously decide and act
223
- return self.autonomous_reasoning()
224
 
225
  # Define the Gradio interface and the main app logic
226
  def gradio_ui():
 
1
  import gradio as gr
2
  import requests
3
  import os
4
+ from openai import OpenAI
5
 
6
+ # Initialize the NVIDIA LLM client
7
+ client = OpenAI(
8
+ base_url="https://integrate.api.nvidia.com/v1",
9
+ api_key=os.getenv("NVIDIA_API_KEY") # Use your NVIDIA API key
10
+ )
11
 
12
  class AutonomousEmailAgent:
13
  def __init__(self, linkedin_url, company_name, role, word_limit, user_name, email, phone, linkedin):
 
53
  """
54
 
55
  # Send the reasoning prompt to the LLM
56
+ completion = client.chat.completions.create(
57
+ model="nvidia/llama-3.1-nemotron-70b-instruct",
58
+ messages=[{"role": "user", "content": reasoning_prompt}],
59
+ temperature=0.5,
60
+ top_p=1,
61
+ max_tokens=1024,
62
+ stream=True
63
+ )
64
+
65
+ reasoning_output = ""
66
+ for chunk in completion:
67
+ if chunk.choices[0].delta.content is not None:
68
+ print(chunk.choices[0].delta.content, end="")
69
+ reasoning_output += chunk.choices[0].delta.content
70
+
71
+ return self.act_on_llm_instructions(reasoning_output)
 
 
 
 
 
72
 
73
  # Function to act on the LLM's structured instructions
74
  def act_on_llm_instructions(self, reasoning_output):
 
75
  instruction = reasoning_output.lower().strip()
76
 
77
  if "scrape" in instruction:
 
78
  self.fetch_company_url()
79
  if self.company_url:
80
  self.fetch_company_info_with_firecrawl(self.company_url)
 
81
  return self.autonomous_reasoning()
82
 
83
  elif "generate_email" in instruction:
 
84
  return self.generate_email()
85
 
86
  elif "fallback" in instruction:
 
87
  print("Action: Using fallback values for missing data.")
88
  if not self.company_info:
89
  self.company_info = "A leading company in its field."
 
92
  return self.generate_email()
93
 
94
  else:
 
95
  print("Error: Unrecognized instruction from LLM. Proceeding with available data.")
96
  return self.generate_email()
97
 
 
113
  print(f"Error fetching company URL: {response.status_code}")
114
  self.company_url = None
115
 
116
+ # Fetch LinkedIn data via Proxycurl
117
  def fetch_linkedin_data(self):
118
  if not self.linkedin_url:
119
  print("Action: No LinkedIn URL provided, using default bio.")
 
136
  self.skills = ["Adaptable", "Hardworking"]
137
  self.experiences = ["Worked across various industries"]
138
 
139
+ # Fetch company information via Firecrawl API using company URL
140
  def fetch_company_info_with_firecrawl(self, company_url):
141
  print(f"Fetching company info for {company_url} using Firecrawl.")
142
  headers = {"Authorization": f"Bearer {firecrawl_api_key}"}
 
155
  print(f"Error: Unable to fetch company info via Firecrawl. Using default info.")
156
  self.company_info = "A leading company in its field."
157
 
158
+ # Final Action: Generate the email using NVIDIA LLM with "Start with Why" framework
159
  def generate_email(self):
160
+ print("Action: Generating the email using NVIDIA LLM with the gathered information.")
161
 
162
  linkedin_text = f"Please find my LinkedIn profile at {self.linkedin}" if self.linkedin else ""
163
 
 
164
  prompt = f"""
165
  Write a professional job application email applying for the {self.role} position at {self.company_name}.
166
 
 
183
  Email: {self.email}
184
  Phone: {self.phone}
185
  LinkedIn: {self.linkedin}
186
+
187
  The email should not exceed {self.word_limit} words.
188
  """
189
 
190
+ completion = client.chat.completions.create(
191
+ model="nvidia/llama-3.1-nemotron-70b-instruct",
192
+ messages=[{"role": "user", "content": prompt}],
193
+ temperature=0.5,
194
+ top_p=1,
195
+ max_tokens=1024,
196
+ stream=True
197
+ )
198
 
199
+ generated_email = ""
200
+ for chunk in completion:
201
+ if chunk.choices[0].delta.content is not None:
202
+ print(chunk.choices[0].delta.content, end="")
203
+ generated_email += chunk.choices[0].delta.content
204
 
205
+ return generated_email
 
 
 
 
 
206
 
207
  # Main loop following ReAct pattern
208
  def run(self):
209
  self.fetch_linkedin_data() # Fetch LinkedIn data
210
+ return self.autonomous_reasoning() # Let the LLM autonomously decide and act
 
211
 
212
  # Define the Gradio interface and the main app logic
213
  def gradio_ui():