jisaacso219 commited on
Commit
3f68a6f
·
verified ·
1 Parent(s): 1bc184f

Update app.py

Browse files

made personal info load from google drive

Files changed (1) hide show
  1. app.py +136 -134
app.py CHANGED
@@ -1,134 +1,136 @@
1
- from dotenv import load_dotenv
2
- from openai import OpenAI
3
- import json
4
- import os
5
- import requests
6
- from PyPDF2 import PdfReader
7
- import gradio as gr
8
-
9
-
10
- load_dotenv(override=True)
11
-
12
- def push(text):
13
- requests.post(
14
- "https://api.pushover.net/1/messages.json",
15
- data={
16
- "token": os.getenv("PUSHOVER_TOKEN"),
17
- "user": os.getenv("PUSHOVER_USER"),
18
- "message": text,
19
- }
20
- )
21
-
22
-
23
- def record_user_details(email, name="Name not provided", notes="not provided"):
24
- push(f"Recording {name} with email {email} and notes {notes}")
25
- return {"recorded": "ok"}
26
-
27
- def record_unknown_question(question):
28
- push(f"Recording {question}")
29
- return {"recorded": "ok"}
30
-
31
- record_user_details_json = {
32
- "name": "record_user_details",
33
- "description": "Use this tool to record that a user is interested in being in touch and provided an email address",
34
- "parameters": {
35
- "type": "object",
36
- "properties": {
37
- "email": {
38
- "type": "string",
39
- "description": "The email address of this user"
40
- },
41
- "name": {
42
- "type": "string",
43
- "description": "The user's name, if they provided it"
44
- }
45
- ,
46
- "notes": {
47
- "type": "string",
48
- "description": "Any additional information about the conversation that's worth recording to give context"
49
- }
50
- },
51
- "required": ["email"],
52
- "additionalProperties": False
53
- }
54
- }
55
-
56
- record_unknown_question_json = {
57
- "name": "record_unknown_question",
58
- "description": "Always use this tool to record any question that couldn't be answered as you didn't know the answer",
59
- "parameters": {
60
- "type": "object",
61
- "properties": {
62
- "question": {
63
- "type": "string",
64
- "description": "The question that couldn't be answered"
65
- },
66
- },
67
- "required": ["question"],
68
- "additionalProperties": False
69
- }
70
- }
71
-
72
- tools = [{"type": "function", "function": record_user_details_json},
73
- {"type": "function", "function": record_unknown_question_json}]
74
-
75
-
76
- class Me:
77
-
78
- def __init__(self):
79
- self.openai = OpenAI()
80
- self.name = "Jacob Isaacson"
81
- reader = PdfReader("me/Linkedin.pdf")
82
- self.linkedin = ""
83
- for page in reader.pages:
84
- text = page.extract_text()
85
- if text:
86
- self.linkedin += text
87
- with open("me/summary.txt", "r", encoding="utf-8") as f:
88
- self.summary = f.read()
89
-
90
-
91
- def handle_tool_call(self, tool_calls):
92
- results = []
93
- for tool_call in tool_calls:
94
- tool_name = tool_call.function.name
95
- arguments = json.loads(tool_call.function.arguments)
96
- print(f"Tool called: {tool_name}", flush=True)
97
- tool = globals().get(tool_name)
98
- result = tool(**arguments) if tool else {}
99
- results.append({"role": "tool","content": json.dumps(result),"tool_call_id": tool_call.id})
100
- return results
101
-
102
- def system_prompt(self):
103
- system_prompt = f"You are acting as {self.name}. You are answering questions on {self.name}'s website, \
104
- particularly questions related to {self.name}'s career, background, skills and experience. \
105
- Your responsibility is to represent {self.name} for interactions on the website as faithfully as possible. \
106
- You are given a summary of {self.name}'s background and LinkedIn profile which you can use to answer questions. \
107
- Be professional and engaging, as if talking to a potential client or future employer who came across the website. \
108
- 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. \
109
- 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. "
110
-
111
- system_prompt += f"\n\n## Summary:\n{self.summary}\n\n## LinkedIn Profile:\n{self.linkedin}\n\n"
112
- system_prompt += f"With this context, please chat with the user, always staying in character as {self.name}."
113
- return system_prompt
114
-
115
- def chat(self, message, history):
116
- messages = [{"role": "system", "content": self.system_prompt()}] + history + [{"role": "user", "content": message}]
117
- done = False
118
- while not done:
119
- response = self.openai.chat.completions.create(model="gpt-4o-mini", messages=messages, tools=tools)
120
- if response.choices[0].finish_reason=="tool_calls":
121
- message = response.choices[0].message
122
- tool_calls = message.tool_calls
123
- results = self.handle_tool_call(tool_calls)
124
- messages.append(message)
125
- messages.extend(results)
126
- else:
127
- done = True
128
- return response.choices[0].message.content
129
-
130
-
131
- if __name__ == "__main__":
132
- me = Me()
133
- gr.ChatInterface(me.chat, type="messages").launch()
134
-
 
 
 
1
+ from dotenv import load_dotenv
2
+ from openai import OpenAI
3
+ import json
4
+ import os
5
+ import requests
6
+ from PyPDF2 import PdfReader
7
+ from io import BytesIO
8
+ import gradio as gr
9
+
10
+ load_dotenv(override=True)
11
+
12
+ def push(text):
13
+ requests.post(
14
+ "https://api.pushover.net/1/messages.json",
15
+ data={
16
+ "token": os.getenv("PUSHOVER_TOKEN"),
17
+ "user": os.getenv("PUSHOVER_USER"),
18
+ "message": text,
19
+ }
20
+ )
21
+
22
+ def record_user_details(email, name="Name not provided", notes="not provided"):
23
+ push(f"Recording {name} with email {email} and notes {notes}")
24
+ return {"recorded": "ok"}
25
+
26
+ def record_unknown_question(question):
27
+ push(f"Recording {question}")
28
+ return {"recorded": "ok"}
29
+
30
+ record_user_details_json = {
31
+ "name": "record_user_details",
32
+ "description": "Use this tool to record that a user is interested in being in touch and provided an email address",
33
+ "parameters": {
34
+ "type": "object",
35
+ "properties": {
36
+ "email": {
37
+ "type": "string",
38
+ "description": "The email address of this user"
39
+ },
40
+ "name": {
41
+ "type": "string",
42
+ "description": "The user's name, if they provided it"
43
+ },
44
+ "notes": {
45
+ "type": "string",
46
+ "description": "Any additional information about the conversation that's worth recording to give context"
47
+ }
48
+ },
49
+ "required": ["email"],
50
+ "additionalProperties": False
51
+ }
52
+ }
53
+
54
+ record_unknown_question_json = {
55
+ "name": "record_unknown_question",
56
+ "description": "Always use this tool to record any question that couldn't be answered as you didn't know the answer",
57
+ "parameters": {
58
+ "type": "object",
59
+ "properties": {
60
+ "question": {
61
+ "type": "string",
62
+ "description": "The question that couldn't be answered"
63
+ },
64
+ },
65
+ "required": ["question"],
66
+ "additionalProperties": False
67
+ }
68
+ }
69
+
70
+ tools = [{"type": "function", "function": record_user_details_json},
71
+ {"type": "function", "function": record_unknown_question_json}]
72
+
73
+ class Me:
74
+
75
+ def __init__(self):
76
+ self.openai = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
77
+ self.name = "Jacob Isaacson"
78
+
79
+ # Load LinkedIn PDF from Google Drive
80
+ linkedin_url = "https://drive.google.com/uc?export=download&id=1xz2RowkImpI8odYv8zvKdlRHaKfILn40"
81
+ pdf_response = requests.get(linkedin_url)
82
+ reader = PdfReader(BytesIO(pdf_response.content))
83
+ self.linkedin = ""
84
+ for page in reader.pages:
85
+ text = page.extract_text()
86
+ if text:
87
+ self.linkedin += text
88
+
89
+ # Load summary.txt from Google Drive
90
+ summary_url = "https://drive.google.com/uc?export=download&id=1hjJz082YFSVjFtpO0pwT6Tyy3eLYYj6-"
91
+ summary_response = requests.get(summary_url)
92
+ self.summary = summary_response.text
93
+
94
+ def handle_tool_call(self, tool_calls):
95
+ results = []
96
+ for tool_call in tool_calls:
97
+ tool_name = tool_call.function.name
98
+ arguments = json.loads(tool_call.function.arguments)
99
+ print(f"Tool called: {tool_name}", flush=True)
100
+ tool = globals().get(tool_name)
101
+ result = tool(**arguments) if tool else {}
102
+ results.append({"role": "tool", "content": json.dumps(result), "tool_call_id": tool_call.id})
103
+ return results
104
+
105
+ def system_prompt(self):
106
+ system_prompt = f"You are acting as {self.name}. You are answering questions on {self.name}'s website, \
107
+ particularly questions related to {self.name}'s career, background, skills and experience. \
108
+ Your responsibility is to represent {self.name} for interactions on the website as faithfully as possible. \
109
+ You are given a summary of {self.name}'s background and LinkedIn profile which you can use to answer questions. \
110
+ Be professional and engaging, as if talking to a potential client or future employer who came across the website. \
111
+ 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. \
112
+ 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."
113
+
114
+ system_prompt += f"\n\n## Summary:\n{self.summary}\n\n## LinkedIn Profile:\n{self.linkedin}\n\n"
115
+ system_prompt += f"With this context, please chat with the user, always staying in character as {self.name}."
116
+ return system_prompt
117
+
118
+ def chat(self, message, history):
119
+ messages = [{"role": "system", "content": self.system_prompt()}] + history + [{"role": "user", "content": message}]
120
+ done = False
121
+ while not done:
122
+ response = self.openai.chat.completions.create(model="gpt-4o-mini", messages=messages, tools=tools)
123
+ if response.choices[0].finish_reason == "tool_calls":
124
+ message = response.choices[0].message
125
+ tool_calls = message.tool_calls
126
+ results = self.handle_tool_call(tool_calls)
127
+ messages.append(message)
128
+ messages.extend(results)
129
+ else:
130
+ done = True
131
+ return response.choices[0].message.content
132
+
133
+
134
+ if __name__ == "__main__":
135
+ me = Me()
136
+ gr.ChatInterface(me.chat, type="messages").launch()