Irakoze commited on
Commit
ae60efb
·
verified ·
1 Parent(s): cfb4f82

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +302 -0
  2. requirements.txt +13 -0
app.py ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import json
4
+ import logging
5
+ import os
6
+ from dotenv import load_dotenv
7
+ from typing import Dict, List, Tuple
8
+ # Load environment variables
9
+ load_dotenv()
10
+ # Configure logging
11
+ logging.basicConfig(
12
+ filename='gradio_frontend.log',
13
+ level=logging.INFO,
14
+ format='%(asctime)s - %(levelname)s - %(message)s'
15
+ )
16
+
17
+ # API Configuration
18
+ API_BASE_URL=os.getenv("API_BASE_URL")
19
+ async def process_query(message: str, language: str, mode: str, chat_history: List[Dict]) -> Tuple[str, str]:
20
+ """Make API request to get chatbot response"""
21
+ try:
22
+ payload = {
23
+ "message": message,
24
+ "language": language,
25
+ "mode": mode
26
+ }
27
+
28
+ response = requests.post(
29
+ f"{API_BASE_URL}/api/query",
30
+ json=payload
31
+ )
32
+ response.raise_for_status()
33
+
34
+ result = response.json()
35
+ return result["answer"], result.get("id")
36
+
37
+ except requests.RequestException as e:
38
+ logging.error(f"API request failed: {str(e)}")
39
+ return f"Sorry, there was an error processing your request: {str(e)}", None
40
+
41
+ async def submit_feedback(feedback_type: str, full_chat_history: List[Dict], language_choice: str, mode: str) -> str:
42
+ """Submit feedback via API"""
43
+ try:
44
+ if mode == "Private":
45
+ return "Feedback is disabled in private mode."
46
+
47
+ if not full_chat_history or len(full_chat_history) < 2:
48
+ return "No recent interaction to provide feedback for."
49
+
50
+ # Get the last assistant message with an ID
51
+ assistant_messages = [msg for msg in full_chat_history
52
+ if msg.get("role") == "assistant" and "id" in msg]
53
+
54
+ if not assistant_messages:
55
+ logging.error("No assistant messages with ID found in chat history")
56
+ return "No response found to provide feedback for."
57
+
58
+ last_message = assistant_messages[-1]
59
+ question_id = last_message.get("id")
60
+
61
+ if not question_id:
62
+ logging.error(f"No ID found in last message: {last_message}")
63
+ return "Question ID not found. Please try asking another question."
64
+
65
+ logging.info(f"Submitting feedback for question ID: {question_id}")
66
+
67
+ # Submit feedback
68
+ payload = {
69
+ "question_id": question_id,
70
+ "feedback_type": feedback_type,
71
+ "language": language_choice,
72
+ "mode": mode
73
+ }
74
+
75
+ response = requests.post(
76
+ f"{API_BASE_URL}/api/feedback",
77
+ json=payload
78
+ )
79
+ response.raise_for_status()
80
+
81
+ return "Thanks for your feedback! Your response has been recorded."
82
+
83
+ except requests.RequestException as e:
84
+ logging.error(f"Failed to submit feedback: {str(e)}")
85
+ return f"Sorry, there was an error submitting your feedback: {str(e)}"
86
+ except Exception as e:
87
+ logging.error(f"Unexpected error in submit_feedback: {str(e)}")
88
+ return "An unexpected error occurred. Please try again."
89
+
90
+ # Create Gradio interface
91
+ with gr.Blocks(title="RRA FAQ Chatbot") as demo:
92
+ full_chat_history = gr.State([]) # Add this line
93
+
94
+ gr.Markdown(
95
+ """
96
+ # RRA FAQ Chatbot
97
+ Ask tax-related questions in English or Kinyarwanda
98
+ """
99
+ )
100
+
101
+ # Add mode selector
102
+ with gr.Row():
103
+ interaction_mode = gr.Radio(
104
+ choices=["Normal", "Private"],
105
+ value="Normal",
106
+ label="Interaction Mode",
107
+ info="Normal: Stores interactions to improve service | Private: No data storage"
108
+ )
109
+
110
+ with gr.Row():
111
+ gr.Markdown(
112
+ """
113
+ > 📝 **Data Storage Notice:**
114
+ > - Normal Mode: Questions and interactions are stored to improve our service
115
+ > - Private Mode: No data is stored, feedback feature is disabled
116
+ """
117
+ )
118
+
119
+ # Add language selector
120
+ language = gr.Radio(
121
+ choices=["English", "Kinyarwanda"],
122
+ value="English",
123
+ label="Select Language / Hitamo Ururimi"
124
+ )
125
+
126
+ chatbot = gr.Chatbot(
127
+ value=[],
128
+ show_label=False,
129
+ height=400
130
+ )
131
+
132
+ with gr.Row():
133
+ msg = gr.Textbox(
134
+ label="Ask your question",
135
+ placeholder="Type your tax-related question here...",
136
+ show_label=False
137
+ )
138
+ submit = gr.Button("Send")
139
+
140
+ # Add feedback section
141
+ feedback_container = gr.Row(visible=True)
142
+ with feedback_container:
143
+ with gr.Column(scale=2):
144
+ feedback_label = gr.Markdown("Was this response helpful?")
145
+ with gr.Column(scale=1):
146
+ feedback_positive = gr.Button("👍 Helpful")
147
+ with gr.Column(scale=1):
148
+ feedback_negative = gr.Button("👎 Not Helpful")
149
+
150
+ # Add feedback status message
151
+ feedback_status = gr.Markdown("")
152
+
153
+ async def respond(message, lang, mode, chat_history, full_chat_history):
154
+ """Process a user message and update chat history"""
155
+ try:
156
+ if chat_history is None:
157
+ chat_history = []
158
+ if full_chat_history is None:
159
+ full_chat_history = []
160
+
161
+ # Get response from API
162
+ bot_message, question_id = await process_query(message, lang, mode, chat_history)
163
+ if not bot_message:
164
+ return "", chat_history, full_chat_history
165
+
166
+ # Build new messages
167
+ user_message = {
168
+ "content": message,
169
+ "role": "user"
170
+ }
171
+
172
+ assistant_message = {
173
+ "content": bot_message,
174
+ "role": "assistant",
175
+ "id": question_id # Store ID in the message
176
+ }
177
+
178
+ # Append to full chat history
179
+ new_full_history = full_chat_history + [user_message, assistant_message]
180
+
181
+ # Prepare messages for chatbot display
182
+ new_chat_history = chat_history + [[message, bot_message]]
183
+ return "", new_chat_history, new_full_history
184
+
185
+ except Exception as e:
186
+ logging.error(f"Error in respond function: {e}")
187
+ return "", chat_history, full_chat_history
188
+
189
+ def update_mode(mode: str):
190
+ """Update UI when mode changes"""
191
+ is_private = (mode == "Private")
192
+ return {
193
+ feedback_container: gr.update(visible=not is_private),
194
+ feedback_status: gr.update(value="" if not is_private else "Feedback is disabled in private mode")
195
+ }
196
+
197
+ # Connect feedback buttons
198
+ async def submit_positive_feedback(full_chat_history, language_choice, mode):
199
+ return await submit_feedback("positive", full_chat_history, language_choice, mode)
200
+
201
+ async def submit_negative_feedback(full_chat_history, language_choice, mode):
202
+ return await submit_feedback("negative", full_chat_history, language_choice, mode)
203
+
204
+ feedback_positive.click(
205
+ fn=submit_positive_feedback,
206
+ inputs=[full_chat_history, language, interaction_mode],
207
+ outputs=feedback_status
208
+ )
209
+
210
+ feedback_negative.click(
211
+ fn=submit_negative_feedback,
212
+ inputs=[full_chat_history, language, interaction_mode],
213
+ outputs=feedback_status
214
+ )
215
+
216
+ # Update UI when mode changes
217
+ interaction_mode.change(
218
+ fn=update_mode,
219
+ inputs=[interaction_mode],
220
+ outputs=[feedback_container, feedback_status]
221
+ )
222
+
223
+ # Example questions
224
+ with gr.Row() as english_examples_row:
225
+ gr.Examples(
226
+ examples=[
227
+ "What is VAT in Rwanda?",
228
+ "How do I register for taxes?",
229
+ "What are the tax payment deadlines?",
230
+ "How can I get a TIN number?",
231
+ "How do I get purchase code?"
232
+ ],
233
+ inputs=msg,
234
+ label="English Examples"
235
+ )
236
+
237
+ with gr.Row(visible=False) as kinyarwanda_examples_row:
238
+ gr.Examples(
239
+ examples=[
240
+ "Ese VAT ni iki mu Rwanda?",
241
+ "Nabona TIN number nte?",
242
+ "Ni ryari tugomba kwishyura imisoro?",
243
+ "Ese nandikwa nte ku musoro?",
244
+ "Ni gute nabone kode yo kugura?"
245
+ ],
246
+ inputs=msg,
247
+ label="Kinyarwanda Examples"
248
+ )
249
+
250
+ def toggle_language_interface(language_choice):
251
+ if language_choice == "English":
252
+ placeholder_text = "Type your tax-related question here..."
253
+ return {
254
+ msg: gr.update(placeholder=placeholder_text),
255
+ english_examples_row: gr.update(visible=True),
256
+ kinyarwanda_examples_row: gr.update(visible=False)
257
+ }
258
+ else:
259
+ placeholder_text = "Andika ibibazo bijyanye n'umusoro hano"
260
+ return {
261
+ msg: gr.update(placeholder=placeholder_text),
262
+ english_examples_row: gr.update(visible=False),
263
+ kinyarwanda_examples_row: gr.update(visible=True)
264
+ }
265
+
266
+ # Connect user inputs
267
+ msg.submit(
268
+ respond,
269
+ [msg, language, interaction_mode, chatbot, full_chat_history],
270
+ [msg, chatbot, full_chat_history]
271
+ )
272
+ submit.click(
273
+ respond,
274
+ [msg, language, interaction_mode, chatbot, full_chat_history],
275
+ [msg, chatbot, full_chat_history]
276
+ )
277
+
278
+ # Update interface on language change
279
+ language.change(
280
+ fn=toggle_language_interface,
281
+ inputs=language,
282
+ outputs=[msg, english_examples_row, kinyarwanda_examples_row]
283
+ )
284
+
285
+ gr.Markdown(
286
+ """
287
+ ### About
288
+ - Created by: [Cedric](mailto:[email protected])
289
+ - Data source: [RRA Website FAQ](https://www.rra.gov.rw/en/domestic-tax-services/faqs)
290
+
291
+ **Disclaimer:** This chatbot provides general tax information. For official guidance,
292
+ consult RRA or call 3004.
293
+ """
294
+ )
295
+
296
+ if __name__ == "__main__":
297
+ try:
298
+ demo.launch(share=False)
299
+ logging.info("Gradio app launched successfully.")
300
+ except Exception as launch_error:
301
+ logging.critical(f"Failed to launch Gradio app: {launch_error}")
302
+ raise
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=4.14.0
2
+ python-dotenv>=1.0.0
3
+ langchain>=0.1.0
4
+ langchain-community>=0.0.13
5
+ langchain-groq>=0.1.1
6
+ cohere>=4.37
7
+ langchain-groq==0.2.0
8
+ langchain-qdrant
9
+ langchain-cohere
10
+ qdrant-client>=1.7.0
11
+ requests>=2.31.0
12
+ qdrant-client
13
+ fastembed==0.4.1