patrickcmd commited on
Commit
76d637d
Β·
verified Β·
1 Parent(s): fedd4c1

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. README.md +3 -9
  2. app.py +138 -0
  3. me/linkedin.pdf +0 -0
  4. me/summary.md +66 -0
  5. requirements.txt +5 -0
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: Career Conversation Assistant
3
- emoji: πŸ“š
4
- colorFrom: green
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 6.9.0
8
  app_file: app.py
9
- pinned: false
 
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: career_conversation_assistant
 
 
 
 
 
3
  app_file: app.py
4
+ sdk: gradio
5
+ sdk_version: 5.49.1
6
  ---
 
 
app.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ from openai import OpenAI
3
+ import json
4
+ import os
5
+ import requests
6
+ from pypdf import PdfReader
7
+ import pymupdf.layout # activate PyMuPDF-Layout in pymupdf
8
+ import pymupdf4llm
9
+ import gradio as gr
10
+
11
+
12
+ load_dotenv(override=True)
13
+
14
+ def push(text):
15
+ requests.post(
16
+ "https://api.pushover.net/1/messages.json",
17
+ data={
18
+ "token": os.getenv("PUSHOVER_TOKEN"),
19
+ "user": os.getenv("PUSHOVER_USER"),
20
+ "message": text,
21
+ }
22
+ )
23
+
24
+
25
+ def record_user_details(email, name="Name not provided", notes="not provided"):
26
+ push(f"Recording {name} with email {email} and notes {notes}")
27
+ return {"recorded": "ok"}
28
+
29
+ def record_unknown_question(question):
30
+ push(f"Recording {question}")
31
+ return {"recorded": "ok"}
32
+
33
+ record_user_details_json = {
34
+ "name": "record_user_details",
35
+ "description": "Use this tool to record that a user is interested in being in touch and provided an email address",
36
+ "parameters": {
37
+ "type": "object",
38
+ "properties": {
39
+ "email": {
40
+ "type": "string",
41
+ "description": "The email address of this user"
42
+ },
43
+ "name": {
44
+ "type": "string",
45
+ "description": "The user's name, if they provided it"
46
+ }
47
+ ,
48
+ "notes": {
49
+ "type": "string",
50
+ "description": "Any additional information about the conversation that's worth recording to give context"
51
+ }
52
+ },
53
+ "required": ["email"],
54
+ "additionalProperties": False
55
+ }
56
+ }
57
+
58
+ record_unknown_question_json = {
59
+ "name": "record_unknown_question",
60
+ "description": "Always use this tool to record any question that couldn't be answered as you didn't know the answer",
61
+ "parameters": {
62
+ "type": "object",
63
+ "properties": {
64
+ "question": {
65
+ "type": "string",
66
+ "description": "The question that couldn't be answered"
67
+ },
68
+ },
69
+ "required": ["question"],
70
+ "additionalProperties": False
71
+ }
72
+ }
73
+
74
+ tools = [{"type": "function", "function": record_user_details_json},
75
+ {"type": "function", "function": record_unknown_question_json}]
76
+
77
+
78
+ class Me:
79
+
80
+ def __init__(self):
81
+ self.openai = OpenAI()
82
+ self.name = "Patrick Walukagga"
83
+ # reader = PdfReader("me/linkedin.pdf")
84
+ self.linkedin = ""
85
+ # for page in reader.pages:
86
+ # text = page.extract_text()
87
+ # if text:
88
+ # self.linkedin += text
89
+ self.linkedin = pymupdf4llm.to_markdown("me/linkedin.pdf")
90
+
91
+ with open("me/summary.md", "r", encoding="utf-8") as f:
92
+ self.summary = f.read()
93
+
94
+
95
+ def handle_tool_call(self, tool_calls):
96
+ results = []
97
+ for tool_call in tool_calls:
98
+ tool_name = tool_call.function.name
99
+ arguments = json.loads(tool_call.function.arguments)
100
+ print(f"Tool called: {tool_name}", flush=True)
101
+ tool = globals().get(tool_name)
102
+ result = tool(**arguments) if tool else {}
103
+ results.append({"role": "tool","content": json.dumps(result),"tool_call_id": tool_call.id})
104
+ return results
105
+
106
+ def system_prompt(self):
107
+ system_prompt = f"You are acting as {self.name}. You are answering questions on {self.name}'s website, \
108
+ particularly questions related to {self.name}'s career, background, skills and experience. \
109
+ Your responsibility is to represent {self.name} for interactions on the website as faithfully as possible. \
110
+ You are given a summary of {self.name}'s background and LinkedIn profile which you can use to answer questions. \
111
+ Be professional and engaging, as if talking to a potential client or future employer who came across the website. \
112
+ If you don't know the answer to any question, use your record_unknown_question tool to record the question that you couldn't answer, even if it's about something trivial or unrelated to career. \
113
+ If the user is engaging in discussion, try to steer them towards getting in touch via email; ask for their email and record it using your record_user_details tool. "
114
+
115
+ system_prompt += f"\n\n## Summary:\n{self.summary}\n\n## LinkedIn Profile:\n{self.linkedin}\n\n"
116
+ system_prompt += f"With this context, please chat with the user, always staying in character as {self.name}."
117
+ return system_prompt
118
+
119
+ def chat(self, message, history):
120
+ messages = [{"role": "system", "content": self.system_prompt()}] + history + [{"role": "user", "content": message}]
121
+ done = False
122
+ while not done:
123
+ response = self.openai.chat.completions.create(model="gpt-4o-mini", messages=messages, tools=tools)
124
+ if response.choices[0].finish_reason=="tool_calls":
125
+ message = response.choices[0].message
126
+ tool_calls = message.tool_calls
127
+ results = self.handle_tool_call(tool_calls)
128
+ messages.append(message)
129
+ messages.extend(results)
130
+ else:
131
+ done = True
132
+ return response.choices[0].message.content
133
+
134
+
135
+ if __name__ == "__main__":
136
+ me = Me()
137
+ gr.ChatInterface(me.chat, type="messages").launch()
138
+
me/linkedin.pdf ADDED
Binary file (60 kB). View file
 
me/summary.md ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸ‘‹πŸΎ Hi, I'm **Patrick Walukagga**
2
+ ### **Backend Engineer | Cloud & Data Engineering | AI/ML Tooling | 2Γ— AWS Certified**
3
+ *(Kampala, Uganda)*
4
+
5
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue?style=for-the-badge&logo=linkedin)](https://linkedin.com/in/patrick-walukagga-53261382)
6
+ [![GitHub](https://img.shields.io/badge/GitHub-PatrickCmd-black?style=for-the-badge&logo=github)](https://github.com/PatrickCmd)
7
+ [![Email](https://img.shields.io/badge/Email-Contact%20Me-red?style=for-the-badge&logo=gmail)](mailto:p.walukagga@gmail.com)
8
+ [![AWS SAA](https://img.shields.io/badge/AWS-SAA--C03-orange?style=for-the-badge&logo=amazonaws)]()
9
+ [![Python](https://img.shields.io/badge/Python-Backend-blue?style=for-the-badge&logo=python)]()
10
+
11
+ ---
12
+
13
+ ## πŸš€ About Me
14
+ Back-End Software Engineer with **4+ years** building scalable backend systems, cloud-native services, and ML-powered applications. Strong in **Python, Django, FastAPI, PostgreSQL, Docker, AWS**, and modern data pipelines. Passionate about turning complex technical challenges into clean, maintainable systems.
15
+
16
+ **Core strengths:**
17
+ πŸ’‘ Backend systems β€’ βš™οΈ Distributed systems β€’ ☁️ Cloud Engineering β€’ πŸ“Š Data Pipelines β€’ πŸ€– ML/AI Integration
18
+
19
+ ---
20
+
21
+ ## πŸ› οΈ Tech Stack & Tools
22
+
23
+ ### **Languages**
24
+ 🐍 Python β€’ πŸ’Ύ SQL β€’ πŸ–₯️ Bash
25
+
26
+ ### **Backend & APIs**
27
+ ⚑ Django β€’ FastAPI β€’ Flask β€’ GraphQL
28
+ πŸ”Œ REST APIs β€’ Microservices β€’ Systems Integration
29
+
30
+ ### **Cloud & DevOps**
31
+ ☁️ AWS (2Γ— Certified) β€’ GCP
32
+ 🐳 Docker β€’ CI/CD β€’ GitHub Actions β€’ Nginx β€’ Gunicorn
33
+
34
+ ### **Databases**
35
+ 🟦 PostgreSQL β€’ 🟧 MySQL
36
+
37
+ ### **Data & ML**
38
+ πŸ“ˆ Pandas β€’ NumPy
39
+ πŸ€– ML tooling β€’ LLM integration β€’ ASR/TTS backends
40
+
41
+ ---
42
+
43
+ ## πŸŽ“ Certifications
44
+
45
+ - 🟧 **AWS Solutions Architect – Associate**
46
+ - 🟧 **AWS Cloud Practitioner**
47
+ - 🟦 **PCEP – Certified Python Programmer**
48
+ - πŸŽ“ Applied Data Science Lab – WQU
49
+ - πŸ’‘ GitHub Copilot Fundamentals
50
+
51
+ ---
52
+
53
+ ## ✨ Fun Facts
54
+ - I love building AI-enabled backend systems
55
+ - I'm passionate about cloud-native automation
56
+ - I enjoy solving real-world problems with technology
57
+ - Always learning, always exploring
58
+
59
+ ---
60
+
61
+ ## πŸ“« Connect With Me
62
+ **Email:** p.walukagga@gmail.com
63
+ **LinkedIn:** https://linkedin.com/in/patrick-walukagga-53261382
64
+ **GitHub:** https://github.com/PatrickCmd
65
+ **Portfolio:** https://patrickcmd.dev
66
+
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ openai
2
+ gradio
3
+ pypdf
4
+ pymupdf4llm
5
+ requests