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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -34
app.py CHANGED
@@ -15,24 +15,20 @@ from langchain_huggingface import HuggingFaceEmbeddings
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,7 +55,6 @@ def save_to_json(user_msg, combined_ans, mode):
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,7 +75,6 @@ def process_pdf_to_markdown(pdf_path, extract_images=True):
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,7 +91,6 @@ def process_main_paper(file_obj):
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,27 +119,23 @@ def transcribe_audio(audio_path):
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,23 +148,26 @@ def ask_qwen(prompt, image_paths):
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,7 +220,6 @@ Context: {context}
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,7 +230,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
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,7 +254,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
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,18 +262,15 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
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,7 +282,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
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,5 +293,4 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
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()
 
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
  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
  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
  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
  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
  })
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
  Task: Generate a draft for a paper about: {question} [/INST]"""
221
  return ask_mistral(prompt)
222
 
 
223
  # ==========================================
224
  # 5. GRADIO UI
225
  # ==========================================
 
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
 
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
  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
  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
  send_btn.click(respond, [msg_input, chatbot, mode_radio], [msg_input, chatbot])
294
 
295
  print("πŸš€ Launching Production Research Scientist Lab...")
 
296
  demo.launch()