Sebunya commited on
Commit
aeaaca1
·
verified ·
1 Parent(s): 959b3e1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -51
app.py CHANGED
@@ -2,11 +2,6 @@ import uuid
2
  import os
3
  import gradio as gr
4
  import pandas as pd
5
- import torch
6
- import numpy as np
7
- from sentence_transformers import util
8
- import google.generativeai as genai
9
- import chromadb
10
  from langchain_chroma import Chroma
11
  import gspread
12
  from google.oauth2.service_account import Credentials
@@ -14,68 +9,187 @@ from langgraph.checkpoint.sqlite import SqliteSaver
14
  import sqlite3
15
  import json
16
  from datetime import datetime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- # Your RAG pipeline functions
19
- def get_context_and_answer(query, history, session_id):
20
- # TODO: Replace with your real retrieval + generation logic
21
- # Currently just returns a dummy response
22
- return f"Echo: {query} (Session: {session_id})"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
- # Main respond function
25
- def respond(message, history, session_id):
26
- if not session_id:
27
- session_id = str(uuid.uuid4())
28
 
29
- history = history or []
30
 
31
- # Append user message
32
- history.append({"role": "user", "content": message})
33
 
34
- # Get assistant's reply
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  response = get_context_and_answer(message, history, session_id)
 
 
 
36
 
37
- # Append assistant's reply
38
- history.append({"role": "assistant", "content": response})
39
 
40
- return "", history
41
 
42
- # Build the Gradio interface
43
- def create_interface():
44
- with gr.Blocks() as demo:
45
- gr.Markdown("""
46
- ## ASKXENO
47
 
48
- **Welcome to XENO AI Support!**
49
- I can help you with questions about XENO financial services including:
50
- - Account management and setup
51
- - Transaction processes and fees
52
- - Platform features and troubleshooting
53
- - General service information
54
- """)
55
 
56
- session_id_box = gr.Textbox(label="Session ID", value=str(uuid.uuid4()), interactive=True)
57
 
58
- chatbot = gr.Chatbot(label="XENO Assistant", bubble_full_width=False, height=500, type="messages")
59
 
60
- with gr.Row():
61
- msg = gr.Textbox(
62
- label="Your Message",
63
- placeholder="Type your question here...",
64
- scale=8
65
- )
66
- send_btn = gr.Button("Send", scale=1)
67
 
68
- clear_btn = gr.Button("Clear Chat")
69
 
70
- # Submit via Enter
71
- msg.submit(respond, [msg, chatbot, session_id_box], [msg, chatbot])
72
- # Submit via Send button
73
- send_btn.click(respond, [msg, chatbot, session_id_box], [msg, chatbot])
74
- # Clear chat
75
- clear_btn.click(lambda: ("", []), None, [msg, chatbot])
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  return demo
78
 
 
79
  if __name__ == "__main__":
80
- app = create_interface()
81
- app.launch(server_name="0.0.0.0", server_port=7860)
 
2
  import os
3
  import gradio as gr
4
  import pandas as pd
 
 
 
 
 
5
  from langchain_chroma import Chroma
6
  import gspread
7
  from google.oauth2.service_account import Credentials
 
9
  import sqlite3
10
  import json
11
  from datetime import datetime
12
+ import re
13
+ # Open the Google Sheet
14
+ sheet = client_gspread.open("Response_Log").sheet1
15
+
16
+ def log_response(question, answer, source_ids, knowledge_pairs, session_id):
17
+ """
18
+ Log a question, answer, source IDs, and knowledge base question-answer pairs to the Google Sheet.
19
+
20
+ knowledge_answer_2 = knowledge_pairs[1][1] if len(knowledge_pairs) > 1 else "N/A"
21
+ row = [
22
+ timestamp,
23
+ session_id,
24
+ question,
25
+ answer,
26
+ source_ids,
27
+ with open("/tmp/response_log.txt", "a") as f:
28
+ f.write(f"{timestamp},{question},{answer},{source_ids},{knowledge_question_1},{knowledge_answer_1},{knowledge_question_2},{knowledge_answer_2}\n")
29
+
30
+ # === LangGraph Memory Setup ===
31
+ conn = sqlite3.connect("xeno_memory.db", check_same_thread=False)
32
+ memory = SqliteSaver(conn=conn)
33
 
34
+ def update_memory(config, user_message, assistant_message):
35
+ full_checkpoint = memory.get(config) or {}
36
+ messages = full_checkpoint.get("channel_values", {}).get("messages", [])
37
+
38
+ messages.append({"role": "user", "content": user_message})
39
+ messages.append({"role": "assistant", "content": assistant_message})
40
+
41
+ checkpoint_to_save = {
42
+ "v": 1,
43
+ "id": str(uuid.uuid4()),
44
+ "ts": datetime.now().isoformat(),
45
+ "channel_values": {"messages": messages},
46
+ "channel_versions": {},
47
+ "versions_seen": {},
48
+ }
49
+
50
+ memory.put(config, checkpoint_to_save, {}, {})
51
+
52
+ # === Intent Classification System ===
53
+ class IntentClassifier:
54
+ def __init__(self):
55
+ knowledge_pairs.append((question, answer))
56
+ return formatted_context, source_ids, knowledge_pairs
57
+
58
+ # === LLM Generation (Refactored) ===
59
+ def generate_xeno_response(context, question, chat_history):
60
+ """Generates a response but does NOT handle memory."""
61
+ model = genai.GenerativeModel(llm_model_name)
62
+ formatted_history = "\n".join(
63
+ [f"{msg['role'].capitalize()}: {msg['content']}" for msg in chat_history]
64
+ ) if chat_history else "None"
65
+
66
+ prompt = f"{SYSTEM_PROMPT}\n### HISTORY ###\n{formatted_history}\n### CONTEXT ###\n{context}\n### QUESTION ###\n{question}"
67
+
68
+ response = model.generate_content(prompt)
69
+ return response.text.strip()
70
+
71
+
72
+ # === Main Interface Logic (Refactored) ===
73
+ def get_context_and_answer(message, history, session_id="default"):
74
+ """
75
+ Handles intent classification, RAG, and memory updates in one place.
76
+ """
77
+ config = {"configurable": {"thread_id": str(session_id), "checkpoint_ns": ""}}
78
+
79
+
80
+ full_checkpoint = memory.get(config) or {}
81
+ chat_history = full_checkpoint.get("channel_values", {}).get("messages", [])
82
+ intent, direct_response = intent_classifier.classify_intent(message)
83
+
84
+
85
+ answer = ""
86
+ source_ids = "N/A"
87
+ knowledge_pairs = []
88
+
89
+ if intent != 'query':
90
+ answer = direct_response
91
+ else:
92
+ if len(message.strip()) < 3:
93
+ answer = "I'd be happy to help! Could you please provide more details about what you'd like to know?"
94
+ else:
95
+ try:
96
+ queried_results = retriever.invoke(message)
97
+ query_embedding = genai.embed_content(model=embedding_model, content=message, task_type="retrieval_query")['embedding']
98
+
99
+ doc_embeddings = [genai.embed_content(model=embedding_model, content=doc.page_content, task_type="retrieval_document")['embedding'] for doc in queried_results]
100
+
101
+ cosine_scores = util.cos_sim(torch.tensor(query_embedding).float(), torch.tensor(doc_embeddings).float())[0].tolist()
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+ if max(cosine_scores) < 0.4:
120
+ answer = "I'm sorry, I couldn't find specific information for your question. Could you try rephrasing it, or contact XENO support directly?"
121
+ else:
122
+ context, source_ids_list, knowledge_pairs = process_context(queried_results, cosine_scores)
123
+ answer = generate_xeno_response(context, message, chat_history)
124
+ source_ids = ", ".join(source_ids_list)
125
+
126
+ except Exception as e:
127
+ print(f"Error during RAG processing: {e}")
128
+ answer = "I apologize, but I'm having a technical issue. Please try again shortly or contact XENO support."
129
 
 
 
 
 
130
 
 
131
 
 
 
132
 
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+ update_memory(config, message, answer)
142
+ log_response(message, answer, source_ids, knowledge_pairs, session_id)
143
+
144
+ return answer
145
+
146
+ # === Enhanced Gradio UI ===
147
+ def respond(message, history, session_id):
148
+ """Gradio's main response function."""
149
+ if not session_id:
150
+ session_id = str(uuid.uuid4())
151
+
152
  response = get_context_and_answer(message, history, session_id)
153
+
154
+ config = {"configurable": {"thread_id": str(session_id), "checkpoint_ns": ""}}
155
+ updated_messages = (memory.get(config) or {}).get("messages", [])
156
 
 
 
157
 
 
158
 
 
 
 
 
 
159
 
 
 
 
 
 
 
 
160
 
 
161
 
 
162
 
 
 
 
 
 
 
 
163
 
 
164
 
 
 
 
 
 
 
165
 
166
+
167
+ history.append({"role": "user", "content": message})
168
+ history.append({"role": "assistant", "content": response})
169
+
170
+ return "", history
171
+ def create_interface():
172
+ with gr.Blocks() as demo:
173
+ gr.Markdown("""ASKXENO
174
+
175
+ **Welcome to XENO AI Support!**
176
+ I can help you with questions about XENO financial services including:
177
+ • Account management and setup
178
+ • Transaction processes and fees
179
+ • Platform features and troubleshooting
180
+ • General service information
181
+ *Simply type your question below to get started!*
182
+ """)
183
+
184
+ session_id_box = gr.Textbox(label="Session ID", value=str(uuid.uuid4()), interactive=True)
185
+
186
+ chatbot = gr.Chatbot(label="XENO Assistant", bubble_full_width=False, height=500, type="messages")
187
+ msg = gr.Textbox(label="Your Message", placeholder="Type your question here...")
188
+
189
+ msg.submit(respond, [msg, chatbot, session_id_box], [msg, chatbot])
190
  return demo
191
 
192
+
193
  if __name__ == "__main__":
194
+ iface = create_interface()
195
+ iface.launch(share=False, server_name="0.0.0.0", server_port=7860, , ssr_mode=False)