afouda commited on
Commit
6cde267
·
verified ·
1 Parent(s): c6f374c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -97
app.py CHANGED
@@ -2,13 +2,14 @@ import os
2
  import re
3
  import asyncio
4
  import gradio as gr
 
 
5
  import RAG_Domain_know_doc
6
  from web_search import search_autism
7
  from RAG import rag_autism
8
- from openai import OpenAI # Corrected import
9
  from dotenv import load_dotenv
10
- import Old_Document
11
- from datetime import datetime
12
  import User_Specific_Documents
13
  from prompt_template import (
14
  Prompt_template_translation,
@@ -22,25 +23,18 @@ from prompt_template import (
22
  Prompt_template_User_document_prompt
23
  )
24
 
25
- GEMINI_API_KEY="AIzaSyCUCivstFpC9pq_jMHMYdlPrmh9Bx97dFo"
26
- TAVILY_API_KEY="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"
27
- OPENAI_API_KEY="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"
28
- QDRANT_API_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOiJtIiwiZXhwIjoxNzUxMDUxNzg4fQ.I9J-K7OM0BtcNKgj2d4uVM8QYAHYfFCVAyP4rlZkK2E"
29
- QDRANT_URL="https://6a3aade6-e8ad-4a6c-a579-21f5af90b7e8.us-east4-0.gcp.cloud.qdrant.io"
30
- OPENAI_API_KEY="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"
31
- WEAVIATE_URL="https://xbvlj5rpqyiswspww0tthq.c0.us-west3.gcp.weaviate.cloud"
32
- WEAVIATE_API_KEY="RU9acU1CYnNRTjY1S1ZFc18zNS9tQktaWlcwTzFEUjlscEVCUGF4YU5xRWx2MDhmTUtIdUhnOWdOTGVZPV92MjAw"
33
- DEEPINFRA_API_KEY="285LUJulGIprqT6hcPhiXtcrphU04FG4"
34
- DEEPINFRA_BASE_URL="https://api.deepinfra.com/v1/openai"
35
  # Initialize OpenAI client
36
- env = os.getenv("ENVIRONMENT", "production")
37
  openai = OpenAI(
38
  api_key=DEEPINFRA_API_KEY,
39
  base_url="https://api.deepinfra.com/v1/openai",
40
  )
41
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
42
- # Rest of your code remains unchanged
43
- # Helper to call chat completion synchronously
 
44
  def call_llm(model: str, messages: list[dict], temperature: float = 0.0, **kwargs) -> str:
45
  resp = openai.chat.completions.create(
46
  model=model,
@@ -50,127 +44,108 @@ def call_llm(model: str, messages: list[dict], temperature: float = 0.0, **kwarg
50
  )
51
  return resp.choices[0].message.content.strip()
52
 
53
- # Basic greeting detection
54
  def is_greeting(text: str) -> bool:
55
  return bool(re.search(r"\b(hi|hello|hey|good (morning|afternoon|evening))\b", text, re.I))
56
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
 
58
  def process_query(query: str, first_turn: bool = False):
59
  intro = ""
60
  process_log = []
61
 
62
  if first_turn and (not query or query.strip() == ""):
63
  intro = "Hello! I’m Wisal, an AI assistant developed by Compumacy AI, specializing in Autism Spectrum Disorders. How can I help you today?"
64
- process_log.append(intro)
 
65
  _save_process_log(process_log)
66
  return intro
67
- # 0: Handle simple greetings
 
 
68
  if is_greeting(query):
69
  greeting = intro + "Hello! I’m Wisal, your AI assistant developed by Compumacy AI. How can I help you today?"
70
- process_log.append(f"Greeting detected.\n{greeting}")
71
  _save_process_log(process_log)
72
  return greeting
73
 
74
- # 1: Translation & Rephrasing
75
  corrected_query = call_llm(
76
  model="Qwen/Qwen3-32B",
77
- messages=[{"role": "user", "content": Prompt_template_translation.format(query=query)}],
78
- reasoning_effort="none"
79
  )
80
  process_log.append(f"Corrected Query: {corrected_query}")
81
-
82
 
83
- # 2: Relevance Check
84
  relevance = call_llm(
85
  model="Qwen/Qwen3-32B",
86
- messages=[{"role": "user", "content": Prompt_template_relevance.format(corrected_query=corrected_query)}],
87
- reasoning_effort="none"
88
  )
89
  process_log.append(f"Relevance: {relevance}")
90
  if relevance != "RELATED":
91
- process_log.append(f"Query not related. Returning: {relevance}")
92
  _save_process_log(process_log)
93
- return intro + relevance
94
 
95
- # Step 3: Web Search
96
  web_search_resp = asyncio.run(search_autism(corrected_query))
97
  web_answer = web_search_resp.get("answer", "")
98
  process_log.append(f"Web Search Answer: {web_answer}")
99
 
100
- # Step 4: LLM Generation
101
- gen_prompt = Prompt_template_LLM_Generation.format(new_query=corrected_query)
102
  generated = call_llm(
103
  model="Qwen/Qwen3-32B",
104
- messages=[{"role": "user", "content": gen_prompt}],
105
- reasoning_effort="none"
106
  )
107
  process_log.append(f"LLM Generated: {generated}")
108
 
109
- # Step 5: RAG
110
  rag_resp = asyncio.run(rag_autism(corrected_query, top_k=3))
111
  rag_contexts = rag_resp.get("answer", [])
112
  process_log.append(f"RAG Contexts: {rag_contexts}")
113
 
114
- # 6) Reranking (now across 3 candidates)
115
  rag_text = "\n".join(f"[{i+1}] {c}" for i, c in enumerate(rag_contexts))
116
  answers_list = f"[1] {generated}\n[2] {web_answer}\n{rag_text}"
117
- rerank_prompt = Prompt_template_Reranker.format(
118
- new_query=corrected_query,
119
- answers_list=answers_list
120
- )
121
  reranked = call_llm(
122
  model="Qwen/Qwen3-32B",
123
- messages=[{"role":"user","content":rerank_prompt}],
124
- reasoning_effort="none"
125
  )
126
  process_log.append(f"Reranked: {reranked}")
127
 
128
- # 7) Wisal final‐answer generation
129
- wisal_prompt = Prompt_template_Wisal.format(
130
- new_query=corrected_query,
131
- document=reranked # use reranked output here
132
- )
133
  wisal = call_llm(
134
  model="Qwen/Qwen3-32B",
135
- messages=[{"role":"user","content":wisal_prompt}],
136
- reasoning_effort="none"
137
  )
138
  process_log.append(f"Wisal Final Answer: {wisal}")
139
 
140
- # 8) Hallucination Check
141
- halluc_prompt = Prompt_template_Halluciations.format(
142
- new_query=corrected_query,
143
- answer=wisal,
144
- document=generated
145
- )
146
  halluc = call_llm(
147
  model="Qwen/Qwen3-32B",
148
- messages=[{"role": "user", "content": halluc_prompt}],
149
- reasoning_effort="none"
150
  )
151
  process_log.append(f"Hallucination Check: {halluc}")
152
  score = int(halluc.split("Score: ")[1]) if "Score: " in halluc else 3
153
 
154
- # 9) Paraphrase if needed
155
  if score in (2, 3):
156
  paraphrase = call_llm(
157
  model="Qwen/Qwen3-32B",
158
- messages=[{"role": "user", "content": Prompt_template_paraphrasing.format(document=generated)}],
159
- reasoning_effort="none"
160
  )
161
  process_log.append(f"Paraphrased: {paraphrase}")
162
- context_prompt = Prompt_template_Wisal.format(new_query=corrected_query, document=paraphrase)
163
  final_doc = call_llm(
164
  model="Qwen/Qwen3-32B",
165
- messages=[{"role": "user", "content": context_prompt}],
166
- reasoning_effort="none"
167
  )
168
  process_log.append(f"Wisal with Paraphrase: {final_doc}")
169
  else:
170
  final_doc = wisal
171
 
172
- # 10) Translate back if needed (improved: only if input is not English)
173
- import langdetect
174
  try:
175
  detected_lang = langdetect.detect(query)
176
  except Exception:
@@ -178,45 +153,24 @@ def process_query(query: str, first_turn: bool = False):
178
  if detected_lang != "en":
179
  result = call_llm(
180
  model="Qwen/Qwen3-32B",
181
- messages=[{"role": "user", "content": Prompt_template_Translate_to_original.format(query=query, document=final_doc)}],
182
- reasoning_effort="none"
183
  )
184
  process_log.append(f"Translated Back: {result}")
185
  else:
186
  result = final_doc
187
  process_log.append(f"Final Result: {result}")
188
 
 
189
  _save_process_log(process_log)
190
  return intro + result
191
 
 
192
  def main_pipeline_with_doc_and_history(query, doc_file, doc_type, history):
193
  response = main_pipeline_with_doc(query, doc_file, doc_type)
194
  updated_history = history + f"\nUser: {query}\nWisal: {response}\n"
195
  return response, updated_history
196
 
197
- # Utility to save process log to a txt file
198
- def _save_process_log(log_lines, filename="process_output.txt"):
199
- # Ensure logs directory exists
200
- logs_dir = os.path.join(os.path.dirname(__file__), "logs")
201
- os.makedirs(logs_dir, exist_ok=True)
202
- # Unique filename per question (timestamped)
203
- timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f")
204
- log_filename = os.path.join(logs_dir, f"log_{timestamp}.txt")
205
- try:
206
- with open(log_filename, "w", encoding="utf-8") as f:
207
- for line in log_lines:
208
- f.write(str(line) + "\n\n")
209
- except Exception as e:
210
- pass
211
-
212
-
213
- # Gradio UI for main pipeline, RAG_Domain_know_doc, and User_Specific_Documents , Old_Document
214
- def main_pipeline_interface(query):
215
- return process_query(query, first_turn=True)
216
-
217
-
218
  def main_pipeline_with_doc(query, doc_file, doc_type):
219
- # If no document, use main pipeline
220
  if doc_file is None or doc_type == "None":
221
  return process_query(query, first_turn=True)
222
 
@@ -226,21 +180,15 @@ def main_pipeline_with_doc(query, doc_file, doc_type):
226
 
227
  save_path = os.path.join(upload_dir, safe_filename)
228
 
229
- # 💡 Check if doc_file is file-like (has `.read()`) or path-like (str or NamedString)
230
  if hasattr(doc_file, 'read'):
231
- # File-like object
232
  file_bytes = doc_file.read()
233
  else:
234
- # It's a path (NamedString), read from file path
235
  with open(str(doc_file), 'rb') as f:
236
  file_bytes = f.read()
237
 
238
- # Save the file content
239
  with open(save_path, "wb") as f:
240
  f.write(file_bytes)
241
 
242
-
243
- # Route to correct document handler
244
  if doc_type == "Knowledge Document":
245
  status = RAG_Domain_know_doc.ingest_file(save_path)
246
  answer = RAG_Domain_know_doc.answer_question(query)
@@ -290,4 +238,6 @@ with gr.Blocks(title="Wisal Main Pipeline & RAG") as demo:
290
 
291
  if __name__ == "__main__":
292
  demo.launch(debug=True)
293
-
 
 
 
2
  import re
3
  import asyncio
4
  import gradio as gr
5
+ from datetime import datetime
6
+ import langdetect
7
  import RAG_Domain_know_doc
8
  from web_search import search_autism
9
  from RAG import rag_autism
10
+ from openai import OpenAI
11
  from dotenv import load_dotenv
12
+ import Old_Document
 
13
  import User_Specific_Documents
14
  from prompt_template import (
15
  Prompt_template_translation,
 
23
  Prompt_template_User_document_prompt
24
  )
25
 
26
+ # API Keys and Constants
27
+ DEEPINFRA_API_KEY = "285LUJulGIprqT6hcPhiXtcrphU04FG4"
28
+
 
 
 
 
 
 
 
29
  # Initialize OpenAI client
 
30
  openai = OpenAI(
31
  api_key=DEEPINFRA_API_KEY,
32
  base_url="https://api.deepinfra.com/v1/openai",
33
  )
34
+
35
+ SESSION_ID = datetime.now().strftime("%Y%m%d_%H%M%S")
36
+
37
+ # Chat Completion Helper
38
  def call_llm(model: str, messages: list[dict], temperature: float = 0.0, **kwargs) -> str:
39
  resp = openai.chat.completions.create(
40
  model=model,
 
44
  )
45
  return resp.choices[0].message.content.strip()
46
 
47
+ # Greeting Detection
48
  def is_greeting(text: str) -> bool:
49
  return bool(re.search(r"\b(hi|hello|hey|good (morning|afternoon|evening))\b", text, re.I))
50
 
51
+ # Logging
52
+ def _save_process_log(log_lines, filename=None):
53
+ logs_dir = os.path.join(os.path.dirname(__file__), "logs")
54
+ os.makedirs(logs_dir, exist_ok=True)
55
+ log_filename = filename or os.path.join(logs_dir, f"chat_session_{SESSION_ID}.txt")
56
+ try:
57
+ with open(log_filename, "a", encoding="utf-8") as f:
58
+ f.write("=" * 50 + "\n")
59
+ for line in log_lines:
60
+ f.write(str(line) + "\n\n")
61
+ except Exception as e:
62
+ print("Logging error:", e)
63
 
64
+ # Main Process Function
65
  def process_query(query: str, first_turn: bool = False):
66
  intro = ""
67
  process_log = []
68
 
69
  if first_turn and (not query or query.strip() == ""):
70
  intro = "Hello! I’m Wisal, an AI assistant developed by Compumacy AI, specializing in Autism Spectrum Disorders. How can I help you today?"
71
+ process_log.append("User: [empty or first turn]")
72
+ process_log.append(f"Wisal: {intro}")
73
  _save_process_log(process_log)
74
  return intro
75
+
76
+ process_log.append(f"User: {query}")
77
+
78
  if is_greeting(query):
79
  greeting = intro + "Hello! I’m Wisal, your AI assistant developed by Compumacy AI. How can I help you today?"
80
+ process_log.append(f"Wisal: {greeting}")
81
  _save_process_log(process_log)
82
  return greeting
83
 
 
84
  corrected_query = call_llm(
85
  model="Qwen/Qwen3-32B",
86
+ messages=[{"role": "user", "content": Prompt_template_translation.format(query=query)}]
 
87
  )
88
  process_log.append(f"Corrected Query: {corrected_query}")
 
89
 
 
90
  relevance = call_llm(
91
  model="Qwen/Qwen3-32B",
92
+ messages=[{"role": "user", "content": Prompt_template_relevance.format(corrected_query=corrected_query)}]
 
93
  )
94
  process_log.append(f"Relevance: {relevance}")
95
  if relevance != "RELATED":
96
+ process_log.append(f"Wisal: {relevance}")
97
  _save_process_log(process_log)
98
+ return relevance
99
 
 
100
  web_search_resp = asyncio.run(search_autism(corrected_query))
101
  web_answer = web_search_resp.get("answer", "")
102
  process_log.append(f"Web Search Answer: {web_answer}")
103
 
 
 
104
  generated = call_llm(
105
  model="Qwen/Qwen3-32B",
106
+ messages=[{"role": "user", "content": Prompt_template_LLM_Generation.format(new_query=corrected_query)}]
 
107
  )
108
  process_log.append(f"LLM Generated: {generated}")
109
 
 
110
  rag_resp = asyncio.run(rag_autism(corrected_query, top_k=3))
111
  rag_contexts = rag_resp.get("answer", [])
112
  process_log.append(f"RAG Contexts: {rag_contexts}")
113
 
 
114
  rag_text = "\n".join(f"[{i+1}] {c}" for i, c in enumerate(rag_contexts))
115
  answers_list = f"[1] {generated}\n[2] {web_answer}\n{rag_text}"
 
 
 
 
116
  reranked = call_llm(
117
  model="Qwen/Qwen3-32B",
118
+ messages=[{"role": "user", "content": Prompt_template_Reranker.format(new_query=corrected_query, answers_list=answers_list)}]
 
119
  )
120
  process_log.append(f"Reranked: {reranked}")
121
 
 
 
 
 
 
122
  wisal = call_llm(
123
  model="Qwen/Qwen3-32B",
124
+ messages=[{"role": "user", "content": Prompt_template_Wisal.format(new_query=corrected_query, document=reranked)}]
 
125
  )
126
  process_log.append(f"Wisal Final Answer: {wisal}")
127
 
 
 
 
 
 
 
128
  halluc = call_llm(
129
  model="Qwen/Qwen3-32B",
130
+ messages=[{"role": "user", "content": Prompt_template_Halluciations.format(new_query=corrected_query, answer=wisal, document=generated)}]
 
131
  )
132
  process_log.append(f"Hallucination Check: {halluc}")
133
  score = int(halluc.split("Score: ")[1]) if "Score: " in halluc else 3
134
 
 
135
  if score in (2, 3):
136
  paraphrase = call_llm(
137
  model="Qwen/Qwen3-32B",
138
+ messages=[{"role": "user", "content": Prompt_template_paraphrasing.format(document=generated)}]
 
139
  )
140
  process_log.append(f"Paraphrased: {paraphrase}")
 
141
  final_doc = call_llm(
142
  model="Qwen/Qwen3-32B",
143
+ messages=[{"role": "user", "content": Prompt_template_Wisal.format(new_query=corrected_query, document=paraphrase)}]
 
144
  )
145
  process_log.append(f"Wisal with Paraphrase: {final_doc}")
146
  else:
147
  final_doc = wisal
148
 
 
 
149
  try:
150
  detected_lang = langdetect.detect(query)
151
  except Exception:
 
153
  if detected_lang != "en":
154
  result = call_llm(
155
  model="Qwen/Qwen3-32B",
156
+ messages=[{"role": "user", "content": Prompt_template_Translate_to_original.format(query=query, document=final_doc)}]
 
157
  )
158
  process_log.append(f"Translated Back: {result}")
159
  else:
160
  result = final_doc
161
  process_log.append(f"Final Result: {result}")
162
 
163
+ process_log.append(f"Wisal: {result}")
164
  _save_process_log(process_log)
165
  return intro + result
166
 
167
+ # Gradio Interface
168
  def main_pipeline_with_doc_and_history(query, doc_file, doc_type, history):
169
  response = main_pipeline_with_doc(query, doc_file, doc_type)
170
  updated_history = history + f"\nUser: {query}\nWisal: {response}\n"
171
  return response, updated_history
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  def main_pipeline_with_doc(query, doc_file, doc_type):
 
174
  if doc_file is None or doc_type == "None":
175
  return process_query(query, first_turn=True)
176
 
 
180
 
181
  save_path = os.path.join(upload_dir, safe_filename)
182
 
 
183
  if hasattr(doc_file, 'read'):
 
184
  file_bytes = doc_file.read()
185
  else:
 
186
  with open(str(doc_file), 'rb') as f:
187
  file_bytes = f.read()
188
 
 
189
  with open(save_path, "wb") as f:
190
  f.write(file_bytes)
191
 
 
 
192
  if doc_type == "Knowledge Document":
193
  status = RAG_Domain_know_doc.ingest_file(save_path)
194
  answer = RAG_Domain_know_doc.answer_question(query)
 
238
 
239
  if __name__ == "__main__":
240
  demo.launch(debug=True)
241
+
242
+
243
+