Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -38,107 +38,84 @@ def record_unknown_question(question):
|
|
| 38 |
writer.writerow([question])
|
| 39 |
return {"recorded": "ok"}
|
| 40 |
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
tools = [
|
| 43 |
-
{"
|
| 44 |
-
{"
|
| 45 |
]
|
| 46 |
|
| 47 |
class Me:
|
| 48 |
-
def __init__(self):
|
| 49 |
-
self.openai = gemini
|
| 50 |
-
self.name = "SnehaLeela"
|
| 51 |
-
|
| 52 |
-
# Load profile JSON
|
| 53 |
-
with open("profile.json", "r", encoding="utf-8") as f:
|
| 54 |
-
self.profile = json.load(f)
|
| 55 |
-
|
| 56 |
-
# Set attributes for easier access
|
| 57 |
-
self.personal_info = self.profile.get("personal_info", {})
|
| 58 |
-
self.expertise = self.profile.get("expertise", [])
|
| 59 |
-
self.experience = self.profile.get("experience", [])
|
| 60 |
-
self.education = self.profile.get("education", [])
|
| 61 |
-
self.friends = self.profile.get("friends", [])
|
| 62 |
-
|
| 63 |
# Handle tool calls
|
| 64 |
def handle_tool_call(self, tool_calls):
|
| 65 |
results = []
|
| 66 |
-
for
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
return results
|
| 74 |
|
| 75 |
# System prompt for LLM
|
| 76 |
-
def system_prompt(self):
|
| 77 |
-
# Combine experience into text
|
| 78 |
-
experience_text = ""
|
| 79 |
-
for company in self.experience:
|
| 80 |
-
experience_text += f"{company['company']}"
|
| 81 |
-
if 'location' in company:
|
| 82 |
-
experience_text += f" ({company['location']})"
|
| 83 |
-
for role in company.get('roles', []):
|
| 84 |
-
experience_text += f"\n- {role['title']} ({role.get('years', '')})"
|
| 85 |
-
for hl in role.get('highlights', []):
|
| 86 |
-
experience_text += f"\n • {hl}"
|
| 87 |
-
experience_text += "\n"
|
| 88 |
-
|
| 89 |
expertise_text = ", ".join(self.expertise)
|
| 90 |
|
| 91 |
education_text = ""
|
| 92 |
-
if self.education:
|
| 93 |
highest = self.education[0].get("highest_degree", {})
|
| 94 |
education_text = f"{highest.get('degree','')} in {highest.get('field_of_study','')} from {highest.get('university','')} ({highest.get('start_year','')}–{highest.get('end_year','')})"
|
| 95 |
-
|
|
|
|
| 96 |
friends_text = ""
|
| 97 |
-
if self.friends:
|
| 98 |
friends_list = []
|
| 99 |
for f in self.friends:
|
| 100 |
friends_list.append(f"{f.get('Name','')} ({f.get('Company','')}): {f.get('Description','')}")
|
| 101 |
friends_text = "\n".join(friends_list)
|
| 102 |
-
|
| 103 |
system_prompt = (
|
| 104 |
-
f"You are acting as {self.personal_info
|
| 105 |
-
f"Answer questions about {self.personal_info
|
| 106 |
-
f"Represent {self.personal_info
|
| 107 |
f"If you don't know an answer, use record_unknown_question tool. "
|
| 108 |
f"If the user engages in discussion, try to steer them towards providing their email using record_user_details tool.\n\n"
|
| 109 |
-
f"## Summary:\n{self.personal_info
|
| 110 |
f"## Interests:\n{', '.join(self.personal_info.get('personal_interests', []))}\n\n"
|
| 111 |
f"## Travel History:\n{', '.join(self.personal_info.get('travel_history', []))}\n\n"
|
| 112 |
f"## Education:\n{education_text}\n\n"
|
| 113 |
-
f"## Expertise:\n{expertise_text}\n\n"
|
| 114 |
f"## Experience:\n{experience_text}\n\n"
|
| 115 |
f"## Friends (for fun):\n{friends_text}\n\n"
|
| 116 |
f"## LinkedIn Profile:\nhttps://www.linkedin.com/in/sneha-leela-0a450349/\n\n"
|
| 117 |
-
f"Chat with the user staying in character as {self.personal_info
|
| 118 |
)
|
| 119 |
-
return system_prompt
|
| 120 |
-
|
| 121 |
-
# Main chat function
|
| 122 |
-
def chat(self, message, history):
|
| 123 |
-
messages = [{"role": "system", "content": self.system_prompt()}] + history + [{"role": "user", "content": message}]
|
| 124 |
-
done = False
|
| 125 |
-
while not done:
|
| 126 |
-
response = self.openai.chat.completions.create(
|
| 127 |
-
model="gemini-2.5-flash-preview-05-20",
|
| 128 |
-
messages=messages,
|
| 129 |
-
tools=tools
|
| 130 |
-
)
|
| 131 |
-
if response.choices[0].finish_reason == "tool_calls":
|
| 132 |
-
message = response.choices[0].message
|
| 133 |
-
tool_calls = message.tool_calls
|
| 134 |
-
results = self.handle_tool_call(tool_calls)
|
| 135 |
-
messages.append(message)
|
| 136 |
-
messages.extend(results)
|
| 137 |
-
else:
|
| 138 |
-
done = True
|
| 139 |
-
return response.choices[0].message.content
|
| 140 |
-
|
| 141 |
-
# Launch Gradio interface
|
| 142 |
-
if __name__ == "__main__":
|
| 143 |
-
me = Me()
|
| 144 |
-
gr.ChatInterface(me.chat, type="messages").launch(share=True)
|
|
|
|
| 38 |
writer.writerow([question])
|
| 39 |
return {"recorded": "ok"}
|
| 40 |
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
# JSON definitions for tools
|
| 44 |
+
record_user_details_json = {
|
| 45 |
+
"name": "record_user_details",
|
| 46 |
+
"description": "Record user info when they provide email",
|
| 47 |
+
"parameters": {
|
| 48 |
+
"type": "object",
|
| 49 |
+
"properties": {
|
| 50 |
+
"email": {"type": "string", "description": "The user's email"},
|
| 51 |
+
"name": {"type": "string", "description": "User's name"},
|
| 52 |
+
"notes": {"type": "string", "description": "Extra info"}
|
| 53 |
+
},
|
| 54 |
+
"required": ["email"],
|
| 55 |
+
"additionalProperties": False
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
record_unknown_question_json = {
|
| 60 |
+
"name": "record_unknown_question",
|
| 61 |
+
"description": "Record any unanswered question",
|
| 62 |
+
"parameters": {
|
| 63 |
+
"type": "object",
|
| 64 |
+
"properties": {
|
| 65 |
+
"question": {"type": "string", "description": "The question not answered"},
|
| 66 |
+
},
|
| 67 |
+
"required": ["question"],
|
| 68 |
+
"additionalProperties": False
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
tools = [
|
| 73 |
+
{"type": "function", "function": record_user_details_json},
|
| 74 |
+
{"type": "function", "function": record_unknown_question_json}
|
| 75 |
]
|
| 76 |
|
| 77 |
class Me:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
# Handle tool calls
|
| 79 |
def handle_tool_call(self, tool_calls):
|
| 80 |
results = []
|
| 81 |
+
for tool_call in tool_calls:
|
| 82 |
+
tool_name = tool_call.function.name
|
| 83 |
+
arguments = json.loads(tool_call.function.arguments)
|
| 84 |
+
tool = globals().get(tool_name)
|
| 85 |
+
result = tool(**arguments) if tool else {}
|
| 86 |
+
results.append({"role": "tool", "content": json.dumps(result), "tool_call_id": tool_call.id})
|
| 87 |
+
|
| 88 |
return results
|
| 89 |
|
| 90 |
# System prompt for LLM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
expertise_text = ", ".join(self.expertise)
|
| 92 |
|
| 93 |
education_text = ""
|
| 94 |
+
if hasattr(self, 'education') and self.education:
|
| 95 |
highest = self.education[0].get("highest_degree", {})
|
| 96 |
education_text = f"{highest.get('degree','')} in {highest.get('field_of_study','')} from {highest.get('university','')} ({highest.get('start_year','')}–{highest.get('end_year','')})"
|
| 97 |
+
|
| 98 |
+
# Optional: prepare friends text for fun
|
| 99 |
friends_text = ""
|
| 100 |
+
if hasattr(self, 'friends') and self.friends:
|
| 101 |
friends_list = []
|
| 102 |
for f in self.friends:
|
| 103 |
friends_list.append(f"{f.get('Name','')} ({f.get('Company','')}): {f.get('Description','')}")
|
| 104 |
friends_text = "\n".join(friends_list)
|
| 105 |
+
|
| 106 |
system_prompt = (
|
| 107 |
+
f"You are acting as {self.personal_info['name']} (aka {self.personal_info.get('nickname','')}). "
|
| 108 |
+
f"Answer questions about {self.personal_info['name']}'s career, background, skills, and experience. "
|
| 109 |
+
f"Represent {self.personal_info['name']} faithfully. "
|
| 110 |
f"If you don't know an answer, use record_unknown_question tool. "
|
| 111 |
f"If the user engages in discussion, try to steer them towards providing their email using record_user_details tool.\n\n"
|
| 112 |
+
f"## Summary:\n{self.personal_info['summary']}\n\n"
|
| 113 |
f"## Interests:\n{', '.join(self.personal_info.get('personal_interests', []))}\n\n"
|
| 114 |
f"## Travel History:\n{', '.join(self.personal_info.get('travel_history', []))}\n\n"
|
| 115 |
f"## Education:\n{education_text}\n\n"
|
|
|
|
| 116 |
f"## Experience:\n{experience_text}\n\n"
|
| 117 |
f"## Friends (for fun):\n{friends_text}\n\n"
|
| 118 |
f"## LinkedIn Profile:\nhttps://www.linkedin.com/in/sneha-leela-0a450349/\n\n"
|
| 119 |
+
f"Chat with the user staying in character as {self.personal_info['name']}."
|
| 120 |
)
|
| 121 |
+
return system_prompt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|