Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -5,18 +5,29 @@ from gtts import gTTS
|
|
5 |
from datetime import datetime
|
6 |
from openpyxl import Workbook, load_workbook
|
7 |
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
from langchain.memory import ConversationBufferMemory
|
10 |
from langchain.chains import ConversationChain
|
|
|
11 |
|
12 |
-
# ==========
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
|
|
|
20 |
MENU = {
|
21 |
"Cheeseburger": 5.99,
|
22 |
"Fries": 2.99,
|
@@ -26,12 +37,9 @@ MENU = {
|
|
26 |
"Salad": 6.99
|
27 |
}
|
28 |
|
29 |
-
chat_history = []
|
30 |
-
order = []
|
31 |
-
customer_name = ""
|
32 |
-
|
33 |
# ========== Excel Setup ==========
|
34 |
EXCEL_FILE = "orders.xlsx"
|
|
|
35 |
def setup_excel():
|
36 |
if not os.path.exists(EXCEL_FILE):
|
37 |
wb = Workbook()
|
@@ -54,8 +62,8 @@ def save_to_excel(name, items):
|
|
54 |
|
55 |
# ========== TTS ==========
|
56 |
def clean_text(text):
|
57 |
-
text = re.sub(r"\*\*(.*?)\*\*", r"\1", text)
|
58 |
-
text = re.sub(r"Bot\s*:\s*", "", text, flags=re.IGNORECASE)
|
59 |
return text.strip()
|
60 |
|
61 |
def speak(text, filename="response.mp3"):
|
@@ -64,44 +72,87 @@ def speak(text, filename="response.mp3"):
|
|
64 |
tts.save(filename)
|
65 |
return filename
|
66 |
|
67 |
-
# ==========
|
68 |
-
|
69 |
-
global customer_name, order
|
70 |
-
|
71 |
-
bot_reply = conversation.predict(input=user_input)
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
-
|
|
|
78 |
for item in MENU:
|
79 |
-
if item.lower() in
|
80 |
qty = 1
|
81 |
-
for word in
|
82 |
if word.isdigit():
|
83 |
qty = int(word)
|
84 |
break
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
-
# Confirm order
|
88 |
if "confirm" in user_input.lower() or "yes" in user_input.lower():
|
89 |
-
if customer_name and
|
90 |
-
order_id = save_to_excel(customer_name,
|
91 |
-
|
92 |
|
93 |
-
|
94 |
-
return
|
95 |
|
96 |
# ========== Gradio UI ==========
|
97 |
gr.Interface(
|
98 |
fn=handle_chat,
|
99 |
-
inputs=gr.Textbox(label="π€ You", placeholder="Type your
|
100 |
outputs=[
|
101 |
-
gr.Textbox(label="π€ Bot
|
102 |
-
gr.Audio(label="π
|
103 |
],
|
104 |
title="π SysTaurant Voice Bot (LangChain + Gemini)",
|
105 |
-
description="
|
106 |
theme="soft"
|
107 |
).launch(share=True)
|
|
|
5 |
from datetime import datetime
|
6 |
from openpyxl import Workbook, load_workbook
|
7 |
|
8 |
+
# ========== Install dependencies if missing ==========
|
9 |
+
try:
|
10 |
+
import google.generativeai as genai
|
11 |
+
except ImportError:
|
12 |
+
import subprocess
|
13 |
+
subprocess.run(["pip", "install", "google-generativeai", "langchain", "langchain-community", "tiktoken"], check=True)
|
14 |
+
import google.generativeai as genai
|
15 |
+
|
16 |
+
from langchain.chat_models import ChatGoogleGenerativeAI
|
17 |
from langchain.memory import ConversationBufferMemory
|
18 |
from langchain.chains import ConversationChain
|
19 |
+
from langchain.prompts import PromptTemplate
|
20 |
|
21 |
+
# ========== Gemini API Setup ==========
|
22 |
+
genai.configure(api_key="AIzaSyBJFmohAmhmqXQlM3fVxj8MLegVb26kyJk")
|
23 |
|
24 |
+
llm = ChatGoogleGenerativeAI(
|
25 |
+
model="gemini-1.5-flash-latest",
|
26 |
+
temperature=0.7,
|
27 |
+
convert_system_message_to_human=True
|
28 |
+
)
|
29 |
|
30 |
+
# ========== Menu ==========
|
31 |
MENU = {
|
32 |
"Cheeseburger": 5.99,
|
33 |
"Fries": 2.99,
|
|
|
37 |
"Salad": 6.99
|
38 |
}
|
39 |
|
|
|
|
|
|
|
|
|
40 |
# ========== Excel Setup ==========
|
41 |
EXCEL_FILE = "orders.xlsx"
|
42 |
+
|
43 |
def setup_excel():
|
44 |
if not os.path.exists(EXCEL_FILE):
|
45 |
wb = Workbook()
|
|
|
62 |
|
63 |
# ========== TTS ==========
|
64 |
def clean_text(text):
|
65 |
+
text = re.sub(r"\*\*(.*?)\*\*", r"\1", text)
|
66 |
+
text = re.sub(r"Bot\s*:\s*", "", text, flags=re.IGNORECASE)
|
67 |
return text.strip()
|
68 |
|
69 |
def speak(text, filename="response.mp3"):
|
|
|
72 |
tts.save(filename)
|
73 |
return filename
|
74 |
|
75 |
+
# ========== LangChain Memory & Prompt ==========
|
76 |
+
memory = ConversationBufferMemory()
|
|
|
|
|
|
|
77 |
|
78 |
+
custom_template = """
|
79 |
+
You are a friendly and professional restaurant assistant at 'Systaurant'.
|
80 |
+
|
81 |
+
Here is the menu:
|
82 |
+
Cheeseburger: $5.99
|
83 |
+
Fries: $2.99
|
84 |
+
Coke: $1.99
|
85 |
+
Pizza: $12.99
|
86 |
+
Chicken Wings: $7.99
|
87 |
+
Salad: $6.99
|
88 |
+
|
89 |
+
Rules:
|
90 |
+
- If name not known, ask for it.
|
91 |
+
- If menu is requested, show it.
|
92 |
+
- Extract item names and quantities.
|
93 |
+
- When user is done, say 'Order summary' and ask 'Confirm?'.
|
94 |
+
- If confirmed, generate order ID.
|
95 |
+
- Keep tone friendly and human.
|
96 |
+
- Don't prefix messages with "Bot:".
|
97 |
+
|
98 |
+
{history}
|
99 |
+
Customer: {input}
|
100 |
+
Bot:"""
|
101 |
+
|
102 |
+
prompt = PromptTemplate(input_variables=["history", "input"], template=custom_template)
|
103 |
+
|
104 |
+
conversation = ConversationChain(
|
105 |
+
llm=llm,
|
106 |
+
memory=memory,
|
107 |
+
prompt=prompt
|
108 |
+
)
|
109 |
+
|
110 |
+
# ========== Chat Logic ==========
|
111 |
+
chat_order = []
|
112 |
+
customer_name = ""
|
113 |
|
114 |
+
def extract_order_info(text):
|
115 |
+
items = []
|
116 |
for item in MENU:
|
117 |
+
if item.lower() in text.lower():
|
118 |
qty = 1
|
119 |
+
for word in text.split():
|
120 |
if word.isdigit():
|
121 |
qty = int(word)
|
122 |
break
|
123 |
+
items.append((item, qty))
|
124 |
+
return items
|
125 |
+
|
126 |
+
def handle_chat(user_input):
|
127 |
+
global chat_order, customer_name
|
128 |
+
|
129 |
+
response = conversation.predict(input=user_input)
|
130 |
+
|
131 |
+
# Detect name
|
132 |
+
if "my name is" in user_input.lower():
|
133 |
+
customer_name = user_input.split("my name is")[-1].strip().split()[0].title()
|
134 |
+
|
135 |
+
# Add items
|
136 |
+
chat_order += extract_order_info(user_input)
|
137 |
|
138 |
+
# Confirm and save order
|
139 |
if "confirm" in user_input.lower() or "yes" in user_input.lower():
|
140 |
+
if customer_name and chat_order:
|
141 |
+
order_id = save_to_excel(customer_name, chat_order)
|
142 |
+
response += f"\nβ
Your order ID is {order_id}. Thank you for ordering!"
|
143 |
|
144 |
+
audio_path = speak(response)
|
145 |
+
return response, audio_path
|
146 |
|
147 |
# ========== Gradio UI ==========
|
148 |
gr.Interface(
|
149 |
fn=handle_chat,
|
150 |
+
inputs=gr.Textbox(label="π€ You", placeholder="Type your message..."),
|
151 |
outputs=[
|
152 |
+
gr.Textbox(label="π€ Bot"),
|
153 |
+
gr.Audio(label="π Response", autoplay=True)
|
154 |
],
|
155 |
title="π SysTaurant Voice Bot (LangChain + Gemini)",
|
156 |
+
description="Smart voice ordering assistant with memory and Excel logging.",
|
157 |
theme="soft"
|
158 |
).launch(share=True)
|