Spaces:
Running
Running
| 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() | |