Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -78,7 +78,7 @@ def load_json_data(path):
|
|
78 |
if isinstance(data, dict):
|
79 |
return "\n".join(f"{k}: {v}" for k, v in data.items() if not isinstance(v, (dict, list)))
|
80 |
elif isinstance(data, list):
|
81 |
-
return "\n\n".join("\n".join(f"{k}: {v}" for k, v in item.items() if
|
82 |
else:
|
83 |
return json.dumps(data, ensure_ascii=False, indent=2)
|
84 |
except Exception as e:
|
@@ -104,7 +104,7 @@ def retrieve_chunks(question, index, embed_model, text_chunks, k=3):
|
|
104 |
# ---------------- Groq Answer Generator ----------------
|
105 |
def generate_answer_with_groq(question, context):
|
106 |
url = "https://api.groq.com/openai/v1/chat/completions"
|
107 |
-
api_key = os.
|
108 |
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
|
109 |
prompt = f"Customer asked: '{question}'\n\nHere is the relevant information to help:\n{context}"
|
110 |
payload = {
|
@@ -132,6 +132,17 @@ def fetch_latest_incoming_message(client, conversation_sid):
|
|
132 |
def send_twilio_message(client, conversation_sid, body):
|
133 |
return client.conversations.v1.conversations(conversation_sid).messages.create(author="system", body=body)
|
134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
# ---------------- Knowledge Base Setup ----------------
|
136 |
def setup_knowledge_base():
|
137 |
folder = "docs"
|
@@ -147,40 +158,42 @@ def setup_knowledge_base():
|
|
147 |
text += load_json_data(path) + "\n"
|
148 |
elif f.endswith(".csv"):
|
149 |
with open(path, newline='', encoding='utf-8') as csvfile:
|
150 |
-
reader = csv.
|
151 |
-
for row in reader
|
152 |
-
text += ' | '.join(f"{k}: {v}" for k, v in row.items()) + "\n"
|
153 |
return text
|
154 |
|
155 |
-
# ----------------
|
156 |
-
def process_messages_loop(
|
157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
while True:
|
|
|
|
|
|
|
|
|
|
|
159 |
message = fetch_latest_incoming_message(twilio_client, conversation_sid)
|
160 |
-
if message and message[
|
161 |
-
|
162 |
-
|
163 |
-
|
|
|
164 |
send_twilio_message(twilio_client, conversation_sid, answer)
|
165 |
-
|
166 |
time.sleep(5)
|
167 |
|
168 |
# ---------------- Streamlit UI ----------------
|
169 |
-
st.title("
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
index = faiss.IndexFlatL2(len(embeddings[0]))
|
176 |
-
index.add(np.array(embeddings))
|
177 |
-
|
178 |
-
# Automatically fetch conversation SID
|
179 |
-
conversations = twilio_client.conversations.v1.conversations.list(limit=5)
|
180 |
-
conversation_sid = conversations[0].sid if conversations else None
|
181 |
-
|
182 |
-
if conversation_sid:
|
183 |
-
st.success(f"Monitoring Twilio conversation SID: {conversation_sid}")
|
184 |
-
threading.Thread(target=process_messages_loop, args=(conversation_sid, index, chunks, tokenizer, embed_model), daemon=True).start()
|
185 |
-
else:
|
186 |
-
st.error("No active Twilio conversation found.")
|
|
|
78 |
if isinstance(data, dict):
|
79 |
return "\n".join(f"{k}: {v}" for k, v in data.items() if not isinstance(v, (dict, list)))
|
80 |
elif isinstance(data, list):
|
81 |
+
return "\n\n".join("\n".join(f"{k}: {v}" for k, v in item.items() if isinstance(item, dict)) for item in data)
|
82 |
else:
|
83 |
return json.dumps(data, ensure_ascii=False, indent=2)
|
84 |
except Exception as e:
|
|
|
104 |
# ---------------- Groq Answer Generator ----------------
|
105 |
def generate_answer_with_groq(question, context):
|
106 |
url = "https://api.groq.com/openai/v1/chat/completions"
|
107 |
+
api_key = os.getenv("GROQ_API_KEY")
|
108 |
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
|
109 |
prompt = f"Customer asked: '{question}'\n\nHere is the relevant information to help:\n{context}"
|
110 |
payload = {
|
|
|
132 |
def send_twilio_message(client, conversation_sid, body):
|
133 |
return client.conversations.v1.conversations(conversation_sid).messages.create(author="system", body=body)
|
134 |
|
135 |
+
def get_latest_whatsapp_conversation_sid(client):
|
136 |
+
try:
|
137 |
+
conversations = client.conversations.v1.conversations.list(limit=20)
|
138 |
+
for convo in sorted(conversations, key=lambda c: c.date_created, reverse=True):
|
139 |
+
messages = convo.messages.list(limit=1)
|
140 |
+
if messages and any(m.author.startswith("whatsapp:") for m in messages):
|
141 |
+
return convo.sid
|
142 |
+
except Exception as e:
|
143 |
+
print("Error fetching latest conversation SID:", e)
|
144 |
+
return None
|
145 |
+
|
146 |
# ---------------- Knowledge Base Setup ----------------
|
147 |
def setup_knowledge_base():
|
148 |
folder = "docs"
|
|
|
158 |
text += load_json_data(path) + "\n"
|
159 |
elif f.endswith(".csv"):
|
160 |
with open(path, newline='', encoding='utf-8') as csvfile:
|
161 |
+
reader = csv.reader(csvfile)
|
162 |
+
text += "\n".join(", ".join(row) for row in reader) + "\n"
|
|
|
163 |
return text
|
164 |
|
165 |
+
# ---------------- App Logic ----------------
|
166 |
+
def process_messages_loop():
|
167 |
+
embed_model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
|
168 |
+
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
|
169 |
+
knowledge_text = setup_knowledge_base()
|
170 |
+
text_chunks = chunk_text(knowledge_text, tokenizer)
|
171 |
+
embeddings = embed_model.encode(text_chunks)
|
172 |
+
index = faiss.IndexFlatL2(embeddings.shape[1])
|
173 |
+
index.add(embeddings)
|
174 |
+
|
175 |
+
seen_sids = set()
|
176 |
+
|
177 |
while True:
|
178 |
+
conversation_sid = get_latest_whatsapp_conversation_sid(twilio_client)
|
179 |
+
if not conversation_sid:
|
180 |
+
time.sleep(5)
|
181 |
+
continue
|
182 |
+
|
183 |
message = fetch_latest_incoming_message(twilio_client, conversation_sid)
|
184 |
+
if message and message["sid"] not in seen_sids and message["timestamp"] > APP_START_TIME:
|
185 |
+
seen_sids.add(message["sid"])
|
186 |
+
question = message["body"]
|
187 |
+
chunks = retrieve_chunks(question, index, embed_model, text_chunks)
|
188 |
+
answer = generate_answer_with_groq(question, "\n\n".join(chunks))
|
189 |
send_twilio_message(twilio_client, conversation_sid, answer)
|
190 |
+
|
191 |
time.sleep(5)
|
192 |
|
193 |
# ---------------- Streamlit UI ----------------
|
194 |
+
st.title("ToyShop WhatsApp Assistant (Groq + Twilio)")
|
195 |
+
|
196 |
+
if st.button("Start WhatsApp Bot"):
|
197 |
+
thread = threading.Thread(target=process_messages_loop)
|
198 |
+
thread.start()
|
199 |
+
st.success("WhatsApp assistant started and monitoring for new messages.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|