File size: 5,745 Bytes
1a5bf3e
 
 
 
e7e5eff
1a5bf3e
 
f1dfb77
e7e5eff
 
1a5bf3e
 
 
 
e7e5eff
 
 
1a5bf3e
 
 
d613f4a
 
1afe904
130c5cc
1a5bf3e
82b3117
 
1a5bf3e
 
af5b41b
82b3117
1a5bf3e
 
af5b41b
82b3117
e7e5eff
f0a0781
 
 
e7e5eff
 
 
 
 
f0a0781
e7e5eff
 
 
 
 
1afe904
e7e5eff
 
 
f0a0781
e7e5eff
 
 
 
 
130c5cc
e7e5eff
 
82b3117
e7e5eff
 
 
 
 
1a5bf3e
 
 
 
e7e5eff
82b3117
e7e5eff
 
1afe904
e7e5eff
af5b41b
 
e7e5eff
af5b41b
 
 
f1dfb77
 
82b3117
e7e5eff
 
 
af5b41b
1afe904
d613f4a
af5b41b
 
 
1afe904
e7e5eff
f1dfb77
1a5bf3e
 
a46eb6c
82b3117
1a5bf3e
 
 
1afe904
1a5bf3e
3b604ac
 
e7e5eff
1a5bf3e
 
e7e5eff
 
 
 
 
 
3b604ac
e7e5eff
 
130c5cc
 
 
e7e5eff
 
3b604ac
a46eb6c
af5b41b
a46eb6c
af5b41b
d327678
f0a0781
e7e5eff
 
 
1a5bf3e
 
130c5cc
 
3b604ac
 
130c5cc
82b3117
af5b41b
1afe904
a4cd905
1afe904
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8c6424
1afe904
 
 
 
 
 
 
 
 
 
 
a4cd905
 
1afe904
a4cd905
75665b3
d327678
 
 
a4cd905
af5b41b
d327678
af5b41b
82b3117
d327678
 
 
 
 
 
82b3117
af5b41b
82b3117
1afe904
1a5bf3e
130c5cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import os
import json
import requests
from pypdf import PdfReader
from openai import OpenAI
import gradio as gr

OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
BASE_URL = "https://integrate.api.nvidia.com/v1"
MODEL = "meta/llama3-8b-instruct"

PUSHOVER_TOKEN = os.environ.get("PUSHOVER_TOKEN")
PUSHOVER_USER = os.environ.get("PUSHOVER_USER")

client = OpenAI(api_key=OPENAI_API_KEY, base_url=BASE_URL)

def push(text):
    try:
        if not PUSHOVER_TOKEN or not PUSHOVER_USER:
            return
        requests.post(
            "https://api.pushover.net/1/messages.json",
            data={"token": PUSHOVER_TOKEN, "user": PUSHOVER_USER, "message": text},
            timeout=5
        )
    except:
        pass

def record_user_details(email, name="Name not provided", notes="not provided"):
    push(f"Lead → {name} | {email} | {notes}")
    return {"status": "ok"}

def record_unknown_question(question):
    push(f"Unknown → {question}")
    return {"status": "ok"}

globals()["record_user_details"] = record_user_details
globals()["record_unknown_question"] = record_unknown_question

tools = [
    {
        "type": "function",
        "function": {
            "name": "record_user_details",
            "description": "Record user's interest and email.",
            "parameters": {
                "type": "object",
                "properties": {
                    "email": {"type": "string"},
                    "name": {"type": "string"},
                    "notes": {"type": "string"}
                },
                "required": ["email"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "record_unknown_question",
            "description": "Record unknown question.",
            "parameters": {
                "type": "object",
                "properties": {"question": {"type": "string"}},
                "required": ["question"]
            }
        }
    }
]

class Me:
    def __init__(self):
        self.name = "Ayush Tyagi"
        self.summary = ""
        self.linkedin = ""

        if os.path.exists("me/summary.txt"):
            self.summary = open("me/summary.txt", "r", encoding="utf-8").read()

        pdf_path = "me/Ayush_linkdin.pdf"
        if os.path.exists(pdf_path):
            text = []
            reader = PdfReader(pdf_path)
            for page in reader.pages:
                t = page.extract_text()
                if t:
                    text.append(t)
            self.linkedin = "\n\n".join(text)

    def system_prompt(self):
        return f"""
You are acting as {self.name}.
Answer questions about his background, skills, and experience.

STRICT RULES:
- Never reveal personal address or sensitive location information.
- If unsure, call record_unknown_question.
- If user shows interest, ask for email and call record_user_details.

Summary:
{self.summary}

LinkedIn:
{self.linkedin}
"""

    def chat(self, message, history):
        messages = [{"role": "system", "content": self.system_prompt()}]

        for msg in history:
            messages.append(msg)

        messages.append({"role": "user", "content": message})

        while True:
            response = client.chat.completions.create(
                model=MODEL,
                messages=messages,
                tools=tools,
                tool_choice="auto",
                max_tokens=500
            )

            choice = response.choices[0]
            msg = choice.message
            finish = choice.finish_reason

            if finish == "tool_calls":
                for tool_call in msg.tool_calls:
                    func = tool_call.function
                    fname = func.name
                    args = json.loads(func.arguments)
                    result = globals()[fname](**args)
                    messages.append({"role": "tool", "content": json.dumps(result)})
                continue

            return msg.content

me = Me()

def respond(user_message, history):
    bot_reply = me.chat(user_message, history)
    history.append({"role": "user", "content": user_message})
    history.append({"role": "assistant", "content": bot_reply})
    return "", history


# UI
with gr.Blocks(css="""
    body, .gradio-container { 
        background-color: #0d0d0d; 
        color: white;
    }

    .gr-button { 
        background-color: #ff4da6 !important;
        color: black !important; 
        font-weight: 600 !important; 
    }

    .gr-button:hover { 
        background-color: #ff1a8c !important; 
    }

    #chatbot {
        background: url('bg_desktop.jpg') no-repeat center;
        background-size: cover;
        border-radius: 12px;
        padding: 10px;
    }

    @media (max-width: 600px) {
        #chatbot {
            background-size: contain;
            background-position: top;
        }
    }
""") as ui:

    chatbot = gr.Chatbot(type="messages", height=420, elem_id="chatbot")

    with gr.Row():
        btn_about = gr.Button("Who are you?")
        btn_contact = gr.Button("Contact Info")
        btn_projects = gr.Button("Latest Projects")

    with gr.Row():
        user_input = gr.Textbox(placeholder="Type your message...", scale=8)
        send_btn = gr.Button("Send", scale=1)

    # Button → fill textbox
    btn_about.click(lambda: "Who are you?", None, user_input)
    btn_contact.click(lambda: "What is Ayush Tyagi's contact information?", None, user_input)
    btn_projects.click(lambda: "Show Ayush Tyagi’s latest projects.", None, user_input)

    # Submit message
    user_input.submit(respond, [user_input, chatbot], [user_input, chatbot])
    send_btn.click(respond, [user_input, chatbot], [user_input, chatbot])


if __name__ == "__main__":
    ui.launch()