langchain_model / app.py
saadawaissheikh's picture
Update app.py
bd3ea7d verified
raw
history blame
4.66 kB
import os
import requests
import gradio as gr
from gtts import gTTS
from datetime import datetime
from openpyxl import Workbook, load_workbook
import re
from langchain.memory import ConversationBufferMemory
# ========== CONFIGURATION ==========
API_KEY = "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"
MODEL = "google/gemma-3n-e2b-it:free"
MENU = {
"Cheeseburger": 5.99,
"Fries": 2.99,
"Coke": 1.99,
"Pizza": 12.99,
"Chicken Wings": 7.99,
"Salad": 6.99
}
memory = ConversationBufferMemory(return_messages=True)
order = []
customer_name = ""
# ========== Excel Setup ==========
EXCEL_FILE = "orders.xlsx"
def setup_excel():
if not os.path.exists(EXCEL_FILE):
wb = Workbook()
ws = wb.active
ws.title = "Orders"
ws.append(["Order ID", "Date", "Customer", "Items", "Total", "Time"])
wb.save(EXCEL_FILE)
setup_excel()
def save_to_excel(name, items):
wb = load_workbook(EXCEL_FILE)
ws = wb.active
order_id = f"ORD{ws.max_row:04d}"
now = datetime.now()
total = sum(qty * MENU[item] for item, qty in items)
items_str = ", ".join(f"{qty} x {item}" for item, qty in items)
ws.append([order_id, now.strftime("%Y-%m-%d"), name, items_str, f"${total:.2f}", now.strftime("%H:%M:%S")])
wb.save(EXCEL_FILE)
return order_id
# ========== Text-to-Speech ==========
def clean_text(text):
text = re.sub(r"\*\*(.*?)\*\*", r"\1", text)
text = re.sub(r"Bot\s*:\s*", "", text, flags=re.IGNORECASE)
return text.strip()
def speak(text, filename="response.mp3"):
cleaned = clean_text(text)
tts = gTTS(text=cleaned)
tts.save(filename)
return filename
# ========== OpenRouter API ==========
def generate_response(user_input):
global customer_name, order
memory.chat_memory.add_user_message(user_input)
menu_description = "\n".join([f"{item}: ${price}" for item, price in MENU.items()])
order_summary = ", ".join([f"{qty} x {item}" for item, qty in order]) if order else "No items yet"
context = f"""
You are a helpful, kind restaurant assistant at 'PandaAI'.
MENU:
{menu_description}
Customer name: {customer_name}
Current order: {order_summary}
Instructions:
- Ask for name if not known.
- Show menu if requested.
- Extract item names and quantities from messages.
- Say 'Order summary' and ask 'Confirm?' when user is done.
- Respond only as the bot, no need to prefix with \"Bot:\".
- Keep tone human, natural, and friendly.
Conversation:
"""
for msg in memory.chat_memory.messages:
if msg.type == "human":
context += f"\nCustomer: {msg.content}"
else:
context += f"\nBot: {msg.content}"
context += f"\nCustomer: {user_input}\nBot:"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": MODEL,
"messages": [{"role": "user", "content": context}],
}
try:
response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
response.raise_for_status()
reply = response.json()["choices"][0]["message"]["content"]
memory.chat_memory.add_ai_message(reply)
return reply
except Exception as e:
return f"❌ OpenRouter Error: {str(e)}"
# ========== Chat Logic ==========
def handle_chat(user_input):
global customer_name, order
bot_reply = generate_response(user_input)
if "my name is" in user_input.lower():
customer_name = user_input.split("my name is")[-1].strip().split()[0].title()
for item in MENU:
if item.lower() in user_input.lower():
qty = 1
for word in user_input.lower().split():
if word.isdigit():
qty = int(word)
break
order.append((item, qty))
if "confirm" in user_input.lower() or "yes" in user_input.lower():
if customer_name and order:
order_id = save_to_excel(customer_name, order)
bot_reply += f"\nβœ… Your order ID is {order_id}. Thank you for ordering from Saad's Restaurant!"
audio_file = speak(bot_reply)
return bot_reply, audio_file
# ========== Gradio UI ==========
gr.Interface(
fn=handle_chat,
inputs=gr.Textbox(label="πŸ‘€ You", placeholder="Type your order..."),
outputs=[
gr.Textbox(label="πŸ€– Bot Response"),
gr.Audio(label="πŸ”Š Speaking", autoplay=True)
],
title="πŸ” PandaAI",
description="Smart restaurant assistant powered by LangChain memory and OpenRouter API.",
theme="soft"
).launch(share=True)