LamiaYT commited on
Commit
c549c70
·
1 Parent(s): 51e7f46

Initial commit with LlamaIndex-based agent

Browse files
Files changed (1) hide show
  1. app.py +99 -31
app.py CHANGED
@@ -43,6 +43,7 @@ class SmartAgent:
43
  model_options = [
44
  "microsoft/DialoGPT-medium", # Much smaller, works well for chat
45
  "google/flan-t5-base", # Good for reasoning tasks
 
46
  "HuggingFaceH4/zephyr-7b-beta" # Original (may fail in limited memory)
47
  ]
48
 
@@ -54,12 +55,13 @@ class SmartAgent:
54
  self.llm = HuggingFaceLLM(
55
  model_name=model_name,
56
  tokenizer_name=model_name,
57
- context_window=512, # Reduced context window
58
- max_new_tokens=128, # Reduced max tokens
59
  generate_kwargs={
60
- "temperature": 0.7,
61
  "do_sample": True,
62
- "pad_token_id": 0 # Prevent padding issues
 
63
  },
64
  device_map="auto",
65
  # Add memory optimization parameters
@@ -67,7 +69,9 @@ class SmartAgent:
67
  "torch_dtype": torch.float16, # Use half precision
68
  "low_cpu_mem_usage": True,
69
  "load_in_8bit": True, # Enable 8-bit quantization if available
70
- }
 
 
71
  )
72
  print(f"Successfully loaded model: {model_name}")
73
 
@@ -88,8 +92,24 @@ class SmartAgent:
88
  )
89
  print(f"Successfully loaded fallback model: {fallback_model}")
90
  except Exception as e2:
91
- print(f"All model loading attempts failed: {e2}")
92
- raise Exception("Unable to load any language model")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  # Define tools with real implementations
95
  self.tools = [
@@ -129,20 +149,21 @@ class SmartAgent:
129
 
130
  try:
131
  with DDGS() as ddgs:
132
- results = list(ddgs.text(query, max_results=3))
133
  if results:
134
  formatted_results = []
135
  for i, r in enumerate(results, 1):
136
  title = r.get('title', 'No title')
137
- body = r.get('body', 'No description')[:200]
138
  url = r.get('href', '')
139
- formatted_results.append(f"{i}. {title}\n{body}...\nSource: {url}")
 
140
  return "\n\n".join(formatted_results)
141
  else:
142
- return "No search results found for the query."
143
  except Exception as e:
144
  print(f"Web search error: {e}")
145
- return f"Error during web search: {str(e)}"
146
 
147
  def math_calculator(self, expression: str) -> str:
148
  """Safe math evaluation using SymPy"""
@@ -171,34 +192,81 @@ class SmartAgent:
171
 
172
  def __call__(self, question: str) -> str:
173
  print(f"Processing question (first 50 chars): {question[:50]}...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  try:
175
  if self.agent:
 
176
  response = self.agent.query(question)
177
- return str(response)
178
- else:
179
- # Fallback: Direct tool usage based on question content
180
- question_lower = question.lower()
181
- if any(word in question_lower for word in ['calculate', 'math', 'equation', '+', '-', '*', '/', '=']):
182
- # Try math calculator
183
- math_terms = []
184
- for word in question.split():
185
- if any(char in word for char in '0123456789+-*/()'):
186
- math_terms.append(word)
187
- if math_terms:
188
- expression = ' '.join(math_terms)
189
- return self.math_calculator(expression)
190
 
191
- if any(word in question_lower for word in ['search', 'find', 'what is', 'current', 'latest', 'news']):
192
- # Try web search
193
- return self.web_search(question)
 
194
 
195
- # Default response
196
- return f"I understand you're asking: {question[:100]}... However, I'm having trouble processing this with the current model configuration. Please try rephrasing your question or breaking it into smaller parts."
 
 
197
 
198
  except Exception as e:
199
  print(f"Agent error: {str(e)}")
200
  print(f"Full traceback: {traceback.format_exc()}")
201
- return f"Error processing question: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
 
204
  # --- Memory cleanup function ---
 
43
  model_options = [
44
  "microsoft/DialoGPT-medium", # Much smaller, works well for chat
45
  "google/flan-t5-base", # Good for reasoning tasks
46
+ "microsoft/DialoGPT-small", # Smallest fallback
47
  "HuggingFaceH4/zephyr-7b-beta" # Original (may fail in limited memory)
48
  ]
49
 
 
55
  self.llm = HuggingFaceLLM(
56
  model_name=model_name,
57
  tokenizer_name=model_name,
58
+ context_window=1024, # Increased for better reasoning
59
+ max_new_tokens=256, # Increased for better responses
60
  generate_kwargs={
61
+ "temperature": 0.3, # Lower temperature for more focused responses
62
  "do_sample": True,
63
+ "top_p": 0.9,
64
+ "repetition_penalty": 1.1
65
  },
66
  device_map="auto",
67
  # Add memory optimization parameters
 
69
  "torch_dtype": torch.float16, # Use half precision
70
  "low_cpu_mem_usage": True,
71
  "load_in_8bit": True, # Enable 8-bit quantization if available
72
+ },
73
+ # Add system message for better instruction following
74
+ system_message="You are a helpful AI assistant that can search the web and perform calculations. Always provide detailed, accurate answers."
75
  )
76
  print(f"Successfully loaded model: {model_name}")
77
 
 
92
  )
93
  print(f"Successfully loaded fallback model: {fallback_model}")
94
  except Exception as e2:
95
+ print(f"Flan-T5 also failed: {e2}")
96
+ # Try an even more basic approach with a very small model
97
+ try:
98
+ basic_model = "microsoft/DialoGPT-small"
99
+ print(f"Final fallback to: {basic_model}")
100
+ self.llm = HuggingFaceLLM(
101
+ model_name=basic_model,
102
+ tokenizer_name=basic_model,
103
+ context_window=512,
104
+ max_new_tokens=128,
105
+ generate_kwargs={"temperature": 0.3, "do_sample": True},
106
+ device_map="cpu", # Force CPU to avoid memory issues
107
+ model_kwargs={"low_cpu_mem_usage": True}
108
+ )
109
+ print(f"Successfully loaded final fallback: {basic_model}")
110
+ except Exception as e3:
111
+ print(f"All model loading attempts failed: {e3}")
112
+ raise Exception("Unable to load any language model")
113
 
114
  # Define tools with real implementations
115
  self.tools = [
 
149
 
150
  try:
151
  with DDGS() as ddgs:
152
+ results = list(ddgs.text(query, max_results=5)) # Get more results
153
  if results:
154
  formatted_results = []
155
  for i, r in enumerate(results, 1):
156
  title = r.get('title', 'No title')
157
+ body = r.get('body', 'No description')[:300] # More context
158
  url = r.get('href', '')
159
+ formatted_results.append(f"{i}. **{title}**\n{body}...\nSource: {url}")
160
+
161
  return "\n\n".join(formatted_results)
162
  else:
163
+ return f"No search results found for '{query}'. Try rephrasing your search terms."
164
  except Exception as e:
165
  print(f"Web search error: {e}")
166
+ return f"Error during web search for '{query}': {str(e)}"
167
 
168
  def math_calculator(self, expression: str) -> str:
169
  """Safe math evaluation using SymPy"""
 
192
 
193
  def __call__(self, question: str) -> str:
194
  print(f"Processing question (first 50 chars): {question[:50]}...")
195
+
196
+ # Enhanced reasoning approach
197
+ question_lower = question.lower()
198
+
199
+ # Check if we need to analyze files
200
+ if any(word in question_lower for word in ['file', 'excel', 'csv', 'spreadsheet', 'data', 'attached']):
201
+ return "I cannot access attached files in this environment. Please ensure the file is accessible via a direct URL or describe the data content directly in your question."
202
+
203
+ # Check if we need web search
204
+ needs_web_search = any(word in question_lower for word in [
205
+ 'current', 'latest', 'recent', 'today', 'news', 'who is', 'what is',
206
+ 'competition', 'winner', 'recipient', 'nationality', 'country',
207
+ 'malko', 'century', 'award', 'born', 'died'
208
+ ])
209
+
210
+ # Check if we need math calculation
211
+ needs_calculation = any(word in question_lower for word in [
212
+ 'calculate', 'compute', 'sum', 'total', 'average', 'percentage',
213
+ 'equation', 'solve', 'math', 'number'
214
+ ]) or any(char in question for char in '+-*/=()0123456789')
215
+
216
  try:
217
  if self.agent:
218
+ # Try using the ReAct agent first
219
  response = self.agent.query(question)
220
+ response_str = str(response)
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
+ # Check if the response is too short or nonsensical
223
+ if len(response_str.strip()) < 3 or response_str.strip() in ['!', '?', 'what', 'I', 'The', 'A']:
224
+ print("Agent gave a poor response, trying direct tool approach...")
225
+ return self._direct_tool_approach(question, needs_web_search, needs_calculation)
226
 
227
+ return response_str
228
+ else:
229
+ # Use direct tool approach
230
+ return self._direct_tool_approach(question, needs_web_search, needs_calculation)
231
 
232
  except Exception as e:
233
  print(f"Agent error: {str(e)}")
234
  print(f"Full traceback: {traceback.format_exc()}")
235
+ # Try direct tool approach as fallback
236
+ try:
237
+ return self._direct_tool_approach(question, needs_web_search, needs_calculation)
238
+ except:
239
+ return f"I apologize, but I'm having technical difficulties processing your question. The question appears to be: {question[:100]}..."
240
+
241
+ def _direct_tool_approach(self, question: str, needs_web_search: bool, needs_calculation: bool) -> str:
242
+ """Direct tool usage when agent fails"""
243
+
244
+ if needs_web_search:
245
+ # Extract key search terms
246
+ search_terms = []
247
+ important_words = question.split()
248
+ for word in important_words:
249
+ if len(word) > 3 and word.lower() not in ['what', 'when', 'where', 'who', 'how', 'the', 'and', 'or', 'but', 'from', 'with']:
250
+ search_terms.append(word)
251
+
252
+ search_query = ' '.join(search_terms[:5]) # Limit to 5 key terms
253
+ print(f"Performing web search for: {search_query}")
254
+
255
+ search_result = self.web_search(search_query)
256
+ return f"Based on my web search for '{search_query}':\n\n{search_result}\n\nPlease review the search results above to find the specific information you're looking for."
257
+
258
+ if needs_calculation:
259
+ # Try to extract mathematical expressions
260
+ import re
261
+ # Look for mathematical expressions
262
+ math_patterns = re.findall(r'[\d+\-*/().\s]+', question)
263
+ for pattern in math_patterns:
264
+ if any(char in pattern for char in '+-*/') and any(char.isdigit() for char in pattern):
265
+ result = self.math_calculator(pattern.strip())
266
+ return f"Mathematical calculation result: {result}"
267
+
268
+ # Default response with better reasoning
269
+ return f"I understand you're asking about: {question[:150]}... However, I need more specific information or context to provide an accurate answer. Could you please rephrase your question or provide additional details?"
270
 
271
 
272
  # --- Memory cleanup function ---