Nebulixlabs commited on
Commit
c719842
Β·
verified Β·
1 Parent(s): d9b859c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -20
app.py CHANGED
@@ -54,7 +54,6 @@ def load_ai_model():
54
  global ai_generator
55
  print("πŸ€– Loading 500M Parameter AI Model (Qwen2.5-0.5B)... This may take a minute.")
56
  try:
57
- # Qwen 0.5B ek chota aur bohot smart model hai jo CPU par achha chalta hai
58
  model_id = "Qwen/Qwen2.5-0.5B-Instruct"
59
  ai_generator = pipeline(
60
  "text-generation",
@@ -69,28 +68,24 @@ def load_ai_model():
69
 
70
  # --- 3. ASYNC AI INFERENCE HELPERS ---
71
  def _generate_text(prompt: str, max_tokens: int):
72
- # Chat template format for Instruct models
73
  messages = [{"role": "user", "content": prompt}]
74
  result = ai_generator(
75
  messages,
76
  max_new_tokens=max_tokens,
77
  do_sample=True,
78
- temperature=0.7,
79
  top_p=0.9
80
  )
81
- # Return extracted AI response
82
  return result[0]['generated_text'][-1]['content']
83
 
84
  async def run_ai_task(prompt: str, max_tokens: int = 150):
85
  if not ai_generator:
86
  return "AI model is not initialized."
87
 
88
- # Check if AI is overloaded
89
  if ai_semaphore.locked():
90
  return "⚠️ AI Servers are currently at full capacity handling other users. Please try again in a few seconds."
91
 
92
  async with ai_semaphore:
93
- # Run Heavy AI task in a separate thread so FastAPI doesn't block
94
  loop = asyncio.get_event_loop()
95
  response = await loop.run_in_executor(None, _generate_text, prompt, max_tokens)
96
  return response
@@ -109,11 +104,10 @@ async def log_query_encrypted(req_id: str, query: str):
109
  @asynccontextmanager
110
  async def lifespan(app: FastAPI):
111
  load_dataset()
112
- # Load AI in background so server starts immediately
113
  asyncio.get_event_loop().run_in_executor(None, load_ai_model)
114
  yield
115
 
116
- app = FastAPI(title="AI Enhanced Search Engine", lifespan=lifespan)
117
  app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
118
 
119
 
@@ -132,7 +126,6 @@ def perform_core_search(query: str):
132
 
133
  scored_results.sort(key=lambda x: x[0], reverse=True)
134
 
135
- # 🌟 SMART FILTER PREDICTION 🌟
136
  best_score = scored_results[0][0] if scored_results else 0
137
  if best_score > 85:
138
  prediction = "High confidence: We found exact matches for your query."
@@ -164,12 +157,10 @@ async def standard_search(q: str = Query(...), background_tasks: BackgroundTasks
164
  background_tasks.add_task(log_query_encrypted, req_id, q)
165
 
166
  is_adult = any(word in q.lower() for word in ["porn", "sex", "xxx", "nude"])
167
-
168
  results, prediction = perform_core_search(q)
169
 
170
- # AI Summary Generation (Short summary based on top 2 results)
171
  ai_summary = "AI Summary not available."
172
- if results and not ai_semaphore.locked(): # Only generate if not overloaded
173
  context = " ".join([r.get("title", "") + ". " + r.get("description", "") for r in results[:2]])
174
  prompt = f"Summarize the following search results about '{q}' in 2 short sentences. Results: {context}"
175
  ai_summary = await run_ai_task(prompt, max_tokens=60)
@@ -189,9 +180,39 @@ async def standard_search(q: str = Query(...), background_tasks: BackgroundTasks
189
  return JSONResponse(content=response, headers={"X-Safety-Message": "you are safe you can do anything"})
190
  return response
191
 
192
- # 🌟 NEW: AI RAG MODE ENDPOINT 🌟
 
193
  @app.get("/aimode")
194
- async def ai_mode_search(q: str = Query(...), background_tasks: BackgroundTasks = BackgroundTasks()):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  req_id = str(uuid.uuid4())
196
  background_tasks.add_task(log_query_encrypted, req_id, q)
197
 
@@ -200,30 +221,43 @@ async def ai_mode_search(q: str = Query(...), background_tasks: BackgroundTasks
200
  if not results:
201
  return {
202
  "ai_response": f"I couldn't find any information about '{q}' in my database to give you an accurate answer.",
 
203
  "results": []
204
  }
205
 
206
- # Build RAG Context from Top 3 results
207
  context = ""
208
- for i, r in enumerate(results[:3]):
209
- context += f"Source {i+1}: {r.get('title', '')} - {r.get('description', '')}\n"
 
 
 
 
210
 
211
- prompt = f"""You are a helpful Search Engine AI. Answer the user's query based ONLY on the provided search results. Be concise and polite.
 
 
 
 
 
 
212
  User Query: {q}
213
 
214
  Search Results Data:
215
  {context}
216
 
 
217
  Answer:"""
218
 
 
219
  ai_reply = await run_ai_task(prompt, max_tokens=250)
220
 
221
  return {
222
  "request_id": req_id,
223
  "ai_response": ai_reply,
224
  "smart_prediction": prediction,
225
- "sources_used": len(results[:3]),
226
- "results": results[:5] # Send top 5 results along with AI answer
227
  }
228
 
229
  if __name__ == "__main__":
 
54
  global ai_generator
55
  print("πŸ€– Loading 500M Parameter AI Model (Qwen2.5-0.5B)... This may take a minute.")
56
  try:
 
57
  model_id = "Qwen/Qwen2.5-0.5B-Instruct"
58
  ai_generator = pipeline(
59
  "text-generation",
 
68
 
69
  # --- 3. ASYNC AI INFERENCE HELPERS ---
70
  def _generate_text(prompt: str, max_tokens: int):
 
71
  messages = [{"role": "user", "content": prompt}]
72
  result = ai_generator(
73
  messages,
74
  max_new_tokens=max_tokens,
75
  do_sample=True,
76
+ temperature=0.6, # Thoda kam temperature taaki precise answer de
77
  top_p=0.9
78
  )
 
79
  return result[0]['generated_text'][-1]['content']
80
 
81
  async def run_ai_task(prompt: str, max_tokens: int = 150):
82
  if not ai_generator:
83
  return "AI model is not initialized."
84
 
 
85
  if ai_semaphore.locked():
86
  return "⚠️ AI Servers are currently at full capacity handling other users. Please try again in a few seconds."
87
 
88
  async with ai_semaphore:
 
89
  loop = asyncio.get_event_loop()
90
  response = await loop.run_in_executor(None, _generate_text, prompt, max_tokens)
91
  return response
 
104
  @asynccontextmanager
105
  async def lifespan(app: FastAPI):
106
  load_dataset()
 
107
  asyncio.get_event_loop().run_in_executor(None, load_ai_model)
108
  yield
109
 
110
+ app = FastAPI(title="Nebulix AI Search Engine", lifespan=lifespan)
111
  app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
112
 
113
 
 
126
 
127
  scored_results.sort(key=lambda x: x[0], reverse=True)
128
 
 
129
  best_score = scored_results[0][0] if scored_results else 0
130
  if best_score > 85:
131
  prediction = "High confidence: We found exact matches for your query."
 
157
  background_tasks.add_task(log_query_encrypted, req_id, q)
158
 
159
  is_adult = any(word in q.lower() for word in ["porn", "sex", "xxx", "nude"])
 
160
  results, prediction = perform_core_search(q)
161
 
 
162
  ai_summary = "AI Summary not available."
163
+ if results and not ai_semaphore.locked():
164
  context = " ".join([r.get("title", "") + ". " + r.get("description", "") for r in results[:2]])
165
  prompt = f"Summarize the following search results about '{q}' in 2 short sentences. Results: {context}"
166
  ai_summary = await run_ai_task(prompt, max_tokens=60)
 
180
  return JSONResponse(content=response, headers={"X-Safety-Message": "you are safe you can do anything"})
181
  return response
182
 
183
+
184
+ # 🌟 FAST AI MODE (Short Answer: 20-25 Tokens) 🌟
185
  @app.get("/aimode")
186
+ async def ai_mode_short(q: str = Query(...), background_tasks: BackgroundTasks = BackgroundTasks()):
187
+ req_id = str(uuid.uuid4())
188
+ background_tasks.add_task(log_query_encrypted, req_id, q)
189
+
190
+ results, prediction = perform_core_search(q)
191
+
192
+ if not results:
193
+ return {"ai_response": "No relevant info found.", "results": []}
194
+
195
+ context = " ".join([f"{r.get('title', '')} - {r.get('description', '')}" for r in results[:2]])
196
+
197
+ prompt = f"""You are a smart Search Assistant. Answer the user's query based on the context in exactly 20 to 25 words. Be direct.
198
+ User Query: {q}
199
+ Context: {context}
200
+ Short Answer:"""
201
+
202
+ # Max tokens limited to 35 to ensure the answer stays around 20-25 words
203
+ ai_reply = await run_ai_task(prompt, max_tokens=35)
204
+
205
+ return {
206
+ "request_id": req_id,
207
+ "ai_response": ai_reply,
208
+ "smart_prediction": prediction,
209
+ "results": results[:5]
210
+ }
211
+
212
+
213
+ # 🌟 NEW: SMART CHAT RAG MODE (Deep Answer: 250 Tokens + URLs) 🌟
214
+ @app.get("/aimodechat")
215
+ async def ai_mode_chat(q: str = Query(...), background_tasks: BackgroundTasks = BackgroundTasks()):
216
  req_id = str(uuid.uuid4())
217
  background_tasks.add_task(log_query_encrypted, req_id, q)
218
 
 
221
  if not results:
222
  return {
223
  "ai_response": f"I couldn't find any information about '{q}' in my database to give you an accurate answer.",
224
+ "sources": [],
225
  "results": []
226
  }
227
 
228
+ # Build Deep RAG Context & Extract Sources
229
  context = ""
230
+ sources_used = []
231
+
232
+ for i, r in enumerate(results[:4]): # Top 4 results for deep context
233
+ url = r.get("url", "#")
234
+ title = r.get("title", "Unknown Title")
235
+ desc = r.get("description", "")
236
 
237
+ context += f"Source {i+1} [{title}]: {desc}\n"
238
+ sources_used.append({"id": i+1, "title": title, "url": url})
239
+
240
+ prompt = f"""You are Nebulix AI, a highly intelligent and helpful search assistant.
241
+ Your task is to provide a comprehensive, well-structured, and accurate answer to the user's query using ONLY the provided search results.
242
+ If the search results do not contain the answer, politely say so.
243
+
244
  User Query: {q}
245
 
246
  Search Results Data:
247
  {context}
248
 
249
+ Provide a detailed response (up to 250 tokens). Do not include the prompt in your output.
250
  Answer:"""
251
 
252
+ # Generating full 250 tokens deep answer
253
  ai_reply = await run_ai_task(prompt, max_tokens=250)
254
 
255
  return {
256
  "request_id": req_id,
257
  "ai_response": ai_reply,
258
  "smart_prediction": prediction,
259
+ "sources": sources_used, # Includes URLs explicitly
260
+ "results": results[:5]
261
  }
262
 
263
  if __name__ == "__main__":