Spaces:
Sleeping
Sleeping
Update app.py
Browse filessome weird copy paste issues
app.py
CHANGED
|
@@ -146,155 +146,7 @@ class Me:
|
|
| 146 |
)
|
| 147 |
return system_prompt
|
| 148 |
|
| 149 |
-
|
| 150 |
-
from dotenv import load_dotenv
|
| 151 |
-
from openai import OpenAI
|
| 152 |
-
import json
|
| 153 |
-
import os
|
| 154 |
-
from pypdf import PdfReader
|
| 155 |
-
import gradio as gr
|
| 156 |
-
import csv
|
| 157 |
-
|
| 158 |
-
# Load environment variables
|
| 159 |
-
load_dotenv(override=True)
|
| 160 |
-
|
| 161 |
-
GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/"
|
| 162 |
-
google_api_key = os.getenv("GOOGLE_API_KEY","AIzaSyDGXQliok_IEo51FGx_7EWiJ_WlCj0e0qc")
|
| 163 |
-
gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)
|
| 164 |
-
|
| 165 |
-
# CSV files for logging
|
| 166 |
-
USER_CSV = "user_details.csv"
|
| 167 |
-
UNKNOWN_CSV = "unknown_questions.csv"
|
| 168 |
-
|
| 169 |
-
# Ensure CSV files exist with headers
|
| 170 |
-
for file, headers in [(USER_CSV, ["email", "name", "notes"]),
|
| 171 |
-
(UNKNOWN_CSV, ["question"])]:
|
| 172 |
-
if not os.path.exists(file):
|
| 173 |
-
with open(file, "w", newline="", encoding="utf-8") as f:
|
| 174 |
-
writer = csv.writer(f)
|
| 175 |
-
writer.writerow(headers)
|
| 176 |
-
|
| 177 |
-
# Functions to log user details and unknown questions
|
| 178 |
-
def record_user_details(email, name="Name not provided", notes="not provided"):
|
| 179 |
-
with open(USER_CSV, "a", newline="", encoding="utf-8") as f:
|
| 180 |
-
writer = csv.writer(f)
|
| 181 |
-
writer.writerow([email, name, notes])
|
| 182 |
-
return {"recorded": "ok"}
|
| 183 |
-
|
| 184 |
-
def record_unknown_question(question):
|
| 185 |
-
with open(UNKNOWN_CSV, "a", newline="", encoding="utf-8") as f:
|
| 186 |
-
writer = csv.writer(f)
|
| 187 |
-
writer.writerow([question])
|
| 188 |
-
return {"recorded": "ok"}
|
| 189 |
-
|
| 190 |
-
# JSON definitions for tools
|
| 191 |
-
record_user_details_json = {
|
| 192 |
-
"name": "record_user_details",
|
| 193 |
-
"description": "Record user info when they provide email",
|
| 194 |
-
"parameters": {
|
| 195 |
-
"type": "object",
|
| 196 |
-
"properties": {
|
| 197 |
-
"email": {"type": "string", "description": "The user's email"},
|
| 198 |
-
"name": {"type": "string", "description": "User's name"},
|
| 199 |
-
"notes": {"type": "string", "description": "Extra info"}
|
| 200 |
-
},
|
| 201 |
-
"required": ["email"],
|
| 202 |
-
"additionalProperties": False
|
| 203 |
-
}
|
| 204 |
-
}
|
| 205 |
-
|
| 206 |
-
record_unknown_question_json = {
|
| 207 |
-
"name": "record_unknown_question",
|
| 208 |
-
"description": "Record any unanswered question",
|
| 209 |
-
"parameters": {
|
| 210 |
-
"type": "object",
|
| 211 |
-
"properties": {
|
| 212 |
-
"question": {"type": "string", "description": "The question not answered"},
|
| 213 |
-
},
|
| 214 |
-
"required": ["question"],
|
| 215 |
-
"additionalProperties": False
|
| 216 |
-
}
|
| 217 |
-
}
|
| 218 |
-
|
| 219 |
-
tools = [
|
| 220 |
-
{"type": "function", "function": record_user_details_json},
|
| 221 |
-
{"type": "function", "function": record_unknown_question_json}
|
| 222 |
-
]
|
| 223 |
-
|
| 224 |
-
class Me:
|
| 225 |
-
def __init__(self):
|
| 226 |
-
self.openai = gemini
|
| 227 |
-
self.name = "SnehaLeela"
|
| 228 |
-
|
| 229 |
-
# Load profile JSON
|
| 230 |
-
with open("profile.json", "r", encoding="utf-8") as f:
|
| 231 |
-
self.profile = json.load(f)
|
| 232 |
-
|
| 233 |
-
# Set attributes for easier access
|
| 234 |
-
self.personal_info = self.profile.get("personal_info", {})
|
| 235 |
-
self.expertise = self.profile.get("expertise", [])
|
| 236 |
-
self.experience = self.profile.get("experience", [])
|
| 237 |
-
self.education = self.profile.get("education", [])
|
| 238 |
-
self.friends = self.profile.get("friends", [])
|
| 239 |
-
|
| 240 |
-
# Handle tool calls
|
| 241 |
-
def handle_tool_call(self, tool_calls):
|
| 242 |
-
results = []
|
| 243 |
-
for tool_call in tool_calls:
|
| 244 |
-
tool_name = tool_call.function.name
|
| 245 |
-
arguments = json.loads(tool_call.function.arguments)
|
| 246 |
-
tool = globals().get(tool_name)
|
| 247 |
-
result = tool(**arguments) if tool else {}
|
| 248 |
-
results.append({"role": "tool", "content": json.dumps(result), "tool_call_id": tool_call.id})
|
| 249 |
-
return results
|
| 250 |
-
|
| 251 |
-
# System prompt for LLM
|
| 252 |
-
def system_prompt(self):
|
| 253 |
-
# Combine experience into text
|
| 254 |
-
experience_text = ""
|
| 255 |
-
for company in self.experience:
|
| 256 |
-
experience_text += f"{company['company']}"
|
| 257 |
-
if 'location' in company:
|
| 258 |
-
experience_text += f" ({company['location']})"
|
| 259 |
-
for role in company.get('roles', []):
|
| 260 |
-
experience_text += f"\n- {role['title']} ({role.get('years', '')})"
|
| 261 |
-
for hl in role.get('highlights', []):
|
| 262 |
-
experience_text += f"\n • {hl}"
|
| 263 |
-
experience_text += "\n"
|
| 264 |
-
|
| 265 |
-
expertise_text = ", ".join(self.expertise)
|
| 266 |
-
|
| 267 |
-
education_text = ""
|
| 268 |
-
if hasattr(self, 'education') and self.education:
|
| 269 |
-
highest = self.education[0].get("highest_degree", {})
|
| 270 |
-
education_text = f"{highest.get('degree','')} in {highest.get('field_of_study','')} from {highest.get('university','')} ({highest.get('start_year','')}–{highest.get('end_year','')})"
|
| 271 |
-
|
| 272 |
-
# Optional: prepare friends text for fun
|
| 273 |
-
friends_text = ""
|
| 274 |
-
if hasattr(self, 'friends') and self.friends:
|
| 275 |
-
friends_list = []
|
| 276 |
-
for f in self.friends:
|
| 277 |
-
friends_list.append(f"{f.get('Name','')} ({f.get('Company','')}): {f.get('Description','')}")
|
| 278 |
-
friends_text = "\n".join(friends_list)
|
| 279 |
-
|
| 280 |
-
system_prompt = (
|
| 281 |
-
f"You are acting as {self.personal_info['name']} (aka {self.personal_info.get('nickname','')}). "
|
| 282 |
-
f"Answer questions about {self.personal_info['name']}'s career, background, skills, and experience. "
|
| 283 |
-
f"Represent {self.personal_info['name']} faithfully. "
|
| 284 |
-
f"If you don't know an answer, use record_unknown_question tool. "
|
| 285 |
-
f"If the user engages in discussion, try to steer them towards providing their email using record_user_details tool.\n\n"
|
| 286 |
-
f"## Summary:\n{self.personal_info['summary']}\n\n"
|
| 287 |
-
f"## Interests:\n{', '.join(self.personal_info.get('personal_interests', []))}\n\n"
|
| 288 |
-
f"## Travel History:\n{', '.join(self.personal_info.get('travel_history', []))}\n\n"
|
| 289 |
-
f"## Education:\n{education_text}\n\n"
|
| 290 |
-
f"## Expertise:\n{expertise_text}\n\n"
|
| 291 |
-
f"## Experience:\n{experience_text}\n\n"
|
| 292 |
-
f"## Friends (for fun):\n{friends_text}\n\n"
|
| 293 |
-
f"## LinkedIn Profile:\nhttps://www.linkedin.com/in/sneha-leela-0a450349/\n\n"
|
| 294 |
-
f"Chat with the user staying in character as {self.personal_info['name']}."
|
| 295 |
-
)
|
| 296 |
-
return system_prompt
|
| 297 |
-
|
| 298 |
# Main chat function
|
| 299 |
def chat(self, message, history):
|
| 300 |
# ✅ Convert Gradio's history (list of lists) into role/content dicts
|
|
@@ -360,38 +212,3 @@ if __name__ == "__main__":
|
|
| 360 |
title="SnehaLeela's Careerbot",
|
| 361 |
#css=css_code
|
| 362 |
).launch(share=True)
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
# Custom CSS with your local image
|
| 367 |
-
css_code = """
|
| 368 |
-
div {
|
| 369 |
-
background-image: url("file/Gemini_Generated.png"); /* Your local image */
|
| 370 |
-
background-size: cover;
|
| 371 |
-
background-position: center;
|
| 372 |
-
background-repeat: no-repeat;
|
| 373 |
-
}
|
| 374 |
-
|
| 375 |
-
.gradio-container {
|
| 376 |
-
background-color: rgba(255, 255, 255, 0.6); /* Optional overlay for readability */
|
| 377 |
-
}
|
| 378 |
-
|
| 379 |
-
.chat-message.user {
|
| 380 |
-
background-color: rgba(208, 230, 255, 0.8);
|
| 381 |
-
}
|
| 382 |
-
|
| 383 |
-
.chat-message.bot {
|
| 384 |
-
background-color: rgba(224, 255, 224, 0.8);
|
| 385 |
-
}
|
| 386 |
-
"""
|
| 387 |
-
|
| 388 |
-
# Launch Gradio interface
|
| 389 |
-
if __name__ == "__main__":
|
| 390 |
-
me = Me()
|
| 391 |
-
#gr.ChatInterface(me.chat, type="messages",theme="NoCrypt/miku",).launch(share=True)
|
| 392 |
-
gr.ChatInterface(
|
| 393 |
-
me.chat,
|
| 394 |
-
#theme="NoCrypt/miku",
|
| 395 |
-
title="SnehaLeela's Careerbot",
|
| 396 |
-
#css=css_code
|
| 397 |
-
).launch(share=True)
|
|
|
|
| 146 |
)
|
| 147 |
return system_prompt
|
| 148 |
|
| 149 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
# Main chat function
|
| 151 |
def chat(self, message, history):
|
| 152 |
# ✅ Convert Gradio's history (list of lists) into role/content dicts
|
|
|
|
| 212 |
title="SnehaLeela's Careerbot",
|
| 213 |
#css=css_code
|
| 214 |
).launch(share=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|