haomd2 commited on
Commit
bd33c7f
·
verified ·
1 Parent(s): c12d369

change model

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