Mohit0708 commited on
Commit
a10d9c7
Β·
verified Β·
1 Parent(s): c9de391

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -18
app.py CHANGED
@@ -15,20 +15,24 @@ from langchain_huggingface import HuggingFaceEmbeddings
15
  from langchain_community.vectorstores import Chroma
16
 
17
  # ==========================================
18
- # 2. CONNECT TO AI APIS (OpenAI-Compatible)
19
  # ==========================================
20
  print("⏳ Connecting to Hugging Face APIs...")
21
 
 
22
  HF_TOKEN = os.environ.get("HF_TOKEN")
23
 
24
  if not HF_TOKEN:
25
  print("⚠️ WARNING: HF_TOKEN not found! The AI will not be able to generate responses.")
26
 
27
- # Initialize a single, generic client
28
- # We do NOT bind the model name here to prevent the "text-generation" tagging error
29
- hf_client = InferenceClient(api_key=HF_TOKEN)
30
 
31
- # Local Embeddings & Whisper
 
 
 
 
32
  embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
33
  whisper_model = whisper.load_model("base")
34
 
@@ -55,6 +59,7 @@ def save_to_json(user_msg, combined_ans, mode):
55
  with open(chat_history_file, "w") as f: json.dump(history, f, indent=4)
56
 
57
  def process_pdf_to_markdown(pdf_path, extract_images=True):
 
58
  global main_extracted_images
59
  output_image_dir = "extracted_images"
60
 
@@ -75,6 +80,7 @@ def process_pdf_to_markdown(pdf_path, extract_images=True):
75
  except Exception as e:
76
  return ""
77
 
 
78
  def process_main_paper(file_obj):
79
  global main_paper_retriever
80
  main_paper_retriever = None
@@ -91,6 +97,7 @@ def process_main_paper(file_obj):
91
  except Exception as e:
92
  return f"❌ Error: {str(e)}"
93
 
 
94
  def process_brainstorm_papers(file_list):
95
  global brainstorm_retriever
96
  brainstorm_retriever = None
@@ -119,23 +126,27 @@ def transcribe_audio(audio_path):
119
  return whisper_model.transcribe(audio_path)["text"].strip()
120
 
121
  # ==========================================
122
- # 4. INTELLIGENCE LAYERS (STRICT CHAT ROUTING)
123
  # ==========================================
124
 
 
 
125
  def ask_mistral(prompt):
126
  try:
 
127
  messages = [{"role": "user", "content": prompt}]
128
- # This explicitly hits the /v1/chat/completions route
129
- response = hf_client.chat.completions.create(
130
- model="mistralai/Mistral-7B-Instruct-v0.3",
131
- messages=messages,
132
- max_tokens=1000,
133
  temperature=0.3
134
  )
135
  return response.choices[0].message.content
136
  except Exception as e:
137
  return f"⚠️ API Error (Mistral): {str(e)}"
138
 
 
139
  def ask_qwen(prompt, image_paths):
140
  try:
141
  messages = [{"role": "user", "content": []}]
@@ -148,26 +159,23 @@ def ask_qwen(prompt, image_paths):
148
  })
149
  messages[0]["content"].append({"type": "text", "text": prompt})
150
 
151
- # Enforce chat completions route for Vision model too
152
- response = hf_client.chat.completions.create(
153
- model="Qwen/Qwen2-VL-7B-Instruct",
154
- messages=messages,
155
- max_tokens=150
156
- )
157
  return response.choices[0].message.content
158
  except Exception as e:
159
- return f"⚠️ API Error (Qwen - Server busy): {str(e)}"
160
 
161
  # MODE 1: CHAT WITH MAIN PAPER
162
  def get_main_paper_response(question):
163
  global main_paper_retriever, main_extracted_images
164
  vision_context = ""
165
 
 
166
  if main_extracted_images:
167
  images_to_process = main_extracted_images[:3]
168
  vision_prompt = f"Relate these images to: {question}"
169
  vision_context = ask_qwen(vision_prompt, images_to_process)
170
 
 
171
  if main_paper_retriever:
172
  docs = main_paper_retriever.invoke(question)
173
  text_context = "\n\n".join(d.page_content for d in docs)
@@ -220,6 +228,7 @@ Context: {context}
220
  Task: Generate a draft for a paper about: {question} [/INST]"""
221
  return ask_mistral(prompt)
222
 
 
223
  # ==========================================
224
  # 5. GRADIO UI
225
  # ==========================================
@@ -230,6 +239,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
230
  gr.Markdown("Pipeline: Analyze -> Find Novelty -> Design Setup -> Write Draft")
231
 
232
  with gr.Row():
 
233
  with gr.Column(scale=1):
234
 
235
  mode_radio = gr.Radio(
@@ -254,6 +264,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
254
 
255
  clear_btn = gr.Button("πŸ—‘οΈ Clear Workspace")
256
 
 
257
  with gr.Column(scale=2):
258
  chatbot = gr.Chatbot(label="Lab Assistant", height=700)
259
  audio_input = gr.Audio(sources=["microphone"], type="filepath", label="🎀 Dictate Idea")
@@ -262,15 +273,18 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
262
  msg_input = gr.Textbox(placeholder="Enter your query or research topic...", scale=4)
263
  send_btn = gr.Button("πŸš€ Execute", variant="primary", scale=1)
264
 
 
265
  file_main.change(fn=process_main_paper, inputs=file_main, outputs=status_main)
266
  file_refs.change(fn=process_brainstorm_papers, inputs=file_refs, outputs=status_refs)
267
  audio_input.stop_recording(fn=transcribe_audio, inputs=audio_input, outputs=msg_input)
268
  clear_btn.click(fn=reset_chat, outputs=chatbot)
269
 
 
270
  def respond(message, history, mode):
271
  if not message.strip(): return "", history
272
  if history is None: history = []
273
 
 
274
  if mode == "1. Chat with Paper":
275
  response = get_main_paper_response(message)
276
  elif mode == "2. Brainstorm Novelty":
@@ -282,6 +296,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
282
  else:
283
  response = "Error: Unknown Mode"
284
 
 
285
  final_ans = f"**[{mode}]**\n{response}"
286
  save_to_json(message, final_ans, mode)
287
  history.append({"role": "user", "content": message})
@@ -293,4 +308,5 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
293
  send_btn.click(respond, [msg_input, chatbot, mode_radio], [msg_input, chatbot])
294
 
295
  print("πŸš€ Launching Production Research Scientist Lab...")
 
296
  demo.launch()
 
15
  from langchain_community.vectorstores import Chroma
16
 
17
  # ==========================================
18
+ # 2. CONNECT TO AI APIS (Replaces Local Models)
19
  # ==========================================
20
  print("⏳ Connecting to Hugging Face APIs...")
21
 
22
+ # Get token from environment variable (Set this in HF Spaces Secrets)
23
  HF_TOKEN = os.environ.get("HF_TOKEN")
24
 
25
  if not HF_TOKEN:
26
  print("⚠️ WARNING: HF_TOKEN not found! The AI will not be able to generate responses.")
27
 
28
+ # --- A. Mistral-7B API (The Writer/Scientist) ---
29
+ text_client = InferenceClient("mistralai/Mistral-7B-Instruct-v0.3", token=HF_TOKEN)
 
30
 
31
+ # --- B. Qwen2-VL API (The Eye) ---
32
+ # We use the 7B version since the cloud API handles the compute!
33
+ vision_client = InferenceClient("Qwen/Qwen2-VL-7B-Instruct", token=HF_TOKEN)
34
+
35
+ # --- C. Local Embeddings & Whisper (Runs fine on CPU) ---
36
  embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
37
  whisper_model = whisper.load_model("base")
38
 
 
59
  with open(chat_history_file, "w") as f: json.dump(history, f, indent=4)
60
 
61
  def process_pdf_to_markdown(pdf_path, extract_images=True):
62
+ """Converts PDF to Markdown. Optionally extracts images."""
63
  global main_extracted_images
64
  output_image_dir = "extracted_images"
65
 
 
80
  except Exception as e:
81
  return ""
82
 
83
+ # --- UPLOAD HANDLER 1: MAIN PAPER ---
84
  def process_main_paper(file_obj):
85
  global main_paper_retriever
86
  main_paper_retriever = None
 
97
  except Exception as e:
98
  return f"❌ Error: {str(e)}"
99
 
100
+ # --- UPLOAD HANDLER 2: REFERENCE SET ---
101
  def process_brainstorm_papers(file_list):
102
  global brainstorm_retriever
103
  brainstorm_retriever = None
 
126
  return whisper_model.transcribe(audio_path)["text"].strip()
127
 
128
  # ==========================================
129
+ # 4. INTELLIGENCE LAYERS (API WRAPPERS)
130
  # ==========================================
131
 
132
+ # Helper function to call Mistral API
133
+ # Helper function to call Mistral API (Updated for Conversational Task)
134
  def ask_mistral(prompt):
135
  try:
136
+ # Format the prompt as a chat message
137
  messages = [{"role": "user", "content": prompt}]
138
+
139
+ # Use chat_completion instead of text_generation
140
+ response = text_client.chat_completion(
141
+ messages=messages,
142
+ max_tokens=1000,
143
  temperature=0.3
144
  )
145
  return response.choices[0].message.content
146
  except Exception as e:
147
  return f"⚠️ API Error (Mistral): {str(e)}"
148
 
149
+ # Helper function to call Qwen API
150
  def ask_qwen(prompt, image_paths):
151
  try:
152
  messages = [{"role": "user", "content": []}]
 
159
  })
160
  messages[0]["content"].append({"type": "text", "text": prompt})
161
 
162
+ response = vision_client.chat_completion(messages=messages, max_tokens=150)
 
 
 
 
 
163
  return response.choices[0].message.content
164
  except Exception as e:
165
+ return f"⚠️ API Error (Qwen - Server might be busy): {str(e)}"
166
 
167
  # MODE 1: CHAT WITH MAIN PAPER
168
  def get_main_paper_response(question):
169
  global main_paper_retriever, main_extracted_images
170
  vision_context = ""
171
 
172
+ # Vision Pass
173
  if main_extracted_images:
174
  images_to_process = main_extracted_images[:3]
175
  vision_prompt = f"Relate these images to: {question}"
176
  vision_context = ask_qwen(vision_prompt, images_to_process)
177
 
178
+ # Text Pass
179
  if main_paper_retriever:
180
  docs = main_paper_retriever.invoke(question)
181
  text_context = "\n\n".join(d.page_content for d in docs)
 
228
  Task: Generate a draft for a paper about: {question} [/INST]"""
229
  return ask_mistral(prompt)
230
 
231
+
232
  # ==========================================
233
  # 5. GRADIO UI
234
  # ==========================================
 
239
  gr.Markdown("Pipeline: Analyze -> Find Novelty -> Design Setup -> Write Draft")
240
 
241
  with gr.Row():
242
+ # --- LEFT: CONTROLS ---
243
  with gr.Column(scale=1):
244
 
245
  mode_radio = gr.Radio(
 
264
 
265
  clear_btn = gr.Button("πŸ—‘οΈ Clear Workspace")
266
 
267
+ # --- RIGHT: WORKSPACE ---
268
  with gr.Column(scale=2):
269
  chatbot = gr.Chatbot(label="Lab Assistant", height=700)
270
  audio_input = gr.Audio(sources=["microphone"], type="filepath", label="🎀 Dictate Idea")
 
273
  msg_input = gr.Textbox(placeholder="Enter your query or research topic...", scale=4)
274
  send_btn = gr.Button("πŸš€ Execute", variant="primary", scale=1)
275
 
276
+ # --- HANDLERS ---
277
  file_main.change(fn=process_main_paper, inputs=file_main, outputs=status_main)
278
  file_refs.change(fn=process_brainstorm_papers, inputs=file_refs, outputs=status_refs)
279
  audio_input.stop_recording(fn=transcribe_audio, inputs=audio_input, outputs=msg_input)
280
  clear_btn.click(fn=reset_chat, outputs=chatbot)
281
 
282
+ # --- MAIN ROUTER ---
283
  def respond(message, history, mode):
284
  if not message.strip(): return "", history
285
  if history is None: history = []
286
 
287
+ # Route based on selected Stage
288
  if mode == "1. Chat with Paper":
289
  response = get_main_paper_response(message)
290
  elif mode == "2. Brainstorm Novelty":
 
296
  else:
297
  response = "Error: Unknown Mode"
298
 
299
+ # Log & Update
300
  final_ans = f"**[{mode}]**\n{response}"
301
  save_to_json(message, final_ans, mode)
302
  history.append({"role": "user", "content": message})
 
308
  send_btn.click(respond, [msg_input, chatbot, mode_radio], [msg_input, chatbot])
309
 
310
  print("πŸš€ Launching Production Research Scientist Lab...")
311
+ # In HF Spaces, we don't need share=True
312
  demo.launch()