LamiaYT commited on
Commit
d3c0517
Β·
1 Parent(s): cccb073
Files changed (1) hide show
  1. app.py +185 -235
app.py CHANGED
@@ -17,382 +17,332 @@ from transformers import AutoModelForCausalLM, AutoTokenizer, GenerationConfig
17
  import torch
18
  import time
19
  import gc
20
- import threading
21
- from concurrent.futures import ThreadPoolExecutor, as_completed
 
 
 
22
 
23
  # --- Load Environment Variables ---
24
  load_dotenv()
25
  SERPER_API_KEY = os.getenv("SERPER_API_KEY")
26
 
27
- # --- Constants ---
28
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
29
- MAX_STEPS = 4 # Reduced from 6
30
- MAX_TOKENS = 128 # Reduced from 256
31
  MODEL_NAME = "microsoft/Phi-3-mini-4k-instruct"
32
- TIMEOUT_PER_QUESTION = 30 # 30 seconds max per question
 
33
 
34
- # --- Configure Environment for Hugging Face Spaces ---
35
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
36
  os.environ["HF_HUB_DISABLE_SYMLINKS_WARNING"] = "1"
37
  os.environ["BITSANDBYTES_NOWELCOME"] = "1"
38
 
39
- print("Loading model (CPU-optimized)...")
40
  start_time = time.time()
41
 
42
- # Load model with aggressive optimization
43
  model = AutoModelForCausalLM.from_pretrained(
44
  MODEL_NAME,
45
  trust_remote_code=True,
46
  torch_dtype=torch.float32,
47
  device_map="cpu",
48
  low_cpu_mem_usage=True,
49
- use_cache=False,
50
- attn_implementation="eager" # Use eager attention for better CPU performance
51
  )
52
 
53
  tokenizer = AutoTokenizer.from_pretrained(
54
  MODEL_NAME,
55
- use_fast=True, # Changed to True for faster tokenization
56
- trust_remote_code=True
 
57
  )
58
 
59
  if tokenizer.pad_token is None:
60
  tokenizer.pad_token = tokenizer.eos_token
61
 
 
 
 
 
 
 
 
 
 
 
 
62
  load_time = time.time() - start_time
63
  print(f"Model loaded in {load_time:.2f} seconds")
64
 
65
- # --- Optimized Tools ---
66
  def web_search(query: str) -> str:
67
- """Search the web with timeout and result limiting"""
68
  try:
69
  if SERPER_API_KEY:
70
- params = {'q': query, 'num': 2, 'hl': 'en', 'gl': 'us'}
71
  headers = {'X-API-KEY': SERPER_API_KEY, 'Content-Type': 'application/json'}
72
  response = requests.post(
73
  'https://google.serper.dev/search',
74
  headers=headers,
75
  json=params,
76
- timeout=5 # Reduced timeout
77
  )
78
  results = response.json()
79
- if 'organic' in results:
80
- return json.dumps([f"{r['title']}: {r['snippet'][:100]}" for r in results['organic'][:2]])
81
- return "No results found"
82
  else:
83
  with DDGS() as ddgs:
84
- results = [r for r in ddgs.text(query, max_results=2)]
85
- return json.dumps([f"{r['title']}: {r['body'][:100]}" for r in results])
86
- except Exception as e:
87
- return f"Search error: {str(e)}"
 
88
 
89
  def calculator(expression: str) -> str:
90
- """Fast mathematical evaluation"""
91
  try:
92
- expression = re.sub(r'[^\d+\-*/().\s]', '', expression)
93
- result = numexpr.evaluate(expression)
 
 
94
  return str(float(result))
95
- except Exception as e:
96
- return f"Calculation error: {str(e)}"
97
 
98
  def read_pdf(file_path: str) -> str:
99
- """Extract text from PDF with length limit"""
100
  try:
101
  text = extract_text(file_path)
102
- return text[:1000] if text else "No text found in PDF" # Reduced limit
103
- except Exception as e:
104
- return f"PDF read error: {str(e)}"
105
 
106
  def read_webpage(url: str) -> str:
107
- """Fast webpage reading with aggressive limits"""
108
  try:
109
- headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}
110
- response = requests.get(url, timeout=5, headers=headers) # Reduced timeout
111
- response.raise_for_status()
112
  soup = BeautifulSoup(response.text, 'html.parser')
113
-
114
- for script in soup(["script", "style"]):
115
- script.decompose()
116
-
117
  text = soup.get_text(separator=' ', strip=True)
118
- return text[:1000] if text else "No text found on webpage" # Reduced limit
119
- except Exception as e:
120
- return f"Webpage read error: {str(e)}"
121
 
122
  TOOLS = {
123
  "web_search": web_search,
124
- "calculator": calculator,
125
  "read_pdf": read_pdf,
126
  "read_webpage": read_webpage
127
  }
128
 
129
- # --- Optimized GAIA Agent ---
130
- class GAIA_Agent:
131
  def __init__(self):
132
  self.tools = TOOLS
133
- self.system_prompt = (
134
- "You are a GAIA problem solver. Tools: {web_search, calculator, read_pdf, read_webpage}.\n"
135
- "Be concise and direct. Use tools efficiently.\n"
136
- "Tool format: ```json\n{'tool': 'tool_name', 'args': {'arg1': value}}```\n"
137
- "End with: Final Answer: [exact answer]"
138
  )
139
 
140
  def __call__(self, question: str) -> str:
141
  start_time = time.time()
142
- print(f"Processing: {question[:50]}...")
143
 
144
  try:
145
- history = [f"Question: {question}"]
146
 
147
  for step in range(MAX_STEPS):
148
- # Check timeout
149
  if time.time() - start_time > TIMEOUT_PER_QUESTION:
150
- return "TIMEOUT: Question took too long"
 
 
151
 
152
- prompt = self._build_prompt(history)
153
- response = self._call_model(prompt)
 
 
154
 
155
- if "Final Answer" in response:
156
- answer = response.split("Final Answer:")[-1].strip()
157
- elapsed = time.time() - start_time
158
- print(f"Completed in {elapsed:.1f}s: {answer[:30]}...")
159
- return answer
160
-
161
- tool_call = self._parse_tool_call(response)
162
- if tool_call:
163
- tool_name, args = tool_call
164
- observation = self._use_tool(tool_name, args)
165
- history.append(f"Action: {tool_name}")
166
- history.append(f"Result: {observation}")
167
  else:
168
- history.append(f"Thought: {response}")
169
 
170
- # Aggressive memory cleanup
171
- gc.collect()
 
172
 
173
- return "Could not solve within step limit"
174
 
175
  except Exception as e:
176
- print(f"Agent error: {str(e)}")
177
- return f"Error: {str(e)}"
178
 
179
- def _build_prompt(self, history: List[str]) -> str:
180
- prompt = "<|system|>\n" + self.system_prompt + "<|end|>\n"
181
- prompt += "<|user|>\n" + "\n".join(history) + "<|end|>\n"
182
- prompt += "<|assistant|>"
183
- return prompt
184
-
185
- def _call_model(self, prompt: str) -> str:
186
  try:
 
 
 
187
  inputs = tokenizer(
188
- prompt,
189
- return_tensors="pt",
190
  truncation=True,
191
- max_length=2048, # Reduced context
192
  padding=False
193
  )
194
 
195
- generation_config = GenerationConfig(
196
- max_new_tokens=MAX_TOKENS,
197
- temperature=0.1, # Less randomness for faster convergence
198
- do_sample=True,
199
- pad_token_id=tokenizer.pad_token_id,
200
- eos_token_id=tokenizer.eos_token_id,
201
- use_cache=False
202
- )
203
-
204
  with torch.no_grad():
205
  outputs = model.generate(
206
  inputs.input_ids,
207
- generation_config=generation_config,
208
  attention_mask=inputs.attention_mask
209
  )
210
 
211
- full_response = tokenizer.decode(outputs[0], skip_special_tokens=True)
212
- response = full_response.split("<|assistant|>")[-1].strip()
 
213
 
214
  # Immediate cleanup
215
  del inputs, outputs
216
- torch.cuda.empty_cache() if torch.cuda.is_available() else None
217
 
218
  return response
219
 
220
  except Exception as e:
221
- return f"Generation error: {str(e)}"
222
 
223
- def _parse_tool_call(self, text: str) -> Optional[Tuple[str, Dict]]:
224
  try:
225
- json_match = re.search(r'```json\s*({.*?})\s*```', text, re.DOTALL)
226
- if json_match:
227
- tool_call = json.loads(json_match.group(1))
228
- if "tool" in tool_call and "args" in tool_call:
229
- return tool_call["tool"], tool_call["args"]
 
 
 
 
 
 
 
 
230
  except:
231
  pass
232
- return None
233
-
234
- def _use_tool(self, tool_name: str, args: Dict) -> str:
235
- if tool_name not in self.tools:
236
- return f"Unknown tool: {tool_name}"
237
-
238
- try:
239
- result = self.tools[tool_name](**args)
240
- return str(result)[:300] # Truncate results
241
- except Exception as e:
242
- return f"Tool error: {str(e)}"
243
 
244
- # --- Optimized Evaluation Runner ---
245
  def run_and_submit_all(profile: gr.OAuthProfile | None):
246
- """Fast evaluation with parallel processing where possible"""
247
- space_id = os.getenv("SPACE_ID")
248
-
249
  if not profile:
250
- return "Please Login to Hugging Face with the button.", None
251
 
252
  username = profile.username
 
 
 
253
  api_url = DEFAULT_API_URL
254
- questions_url = f"{api_url}/questions"
255
- submit_url = f"{api_url}/submit"
256
-
257
- try:
258
- agent = GAIA_Agent()
259
- except Exception as e:
260
- return f"Error initializing agent: {e}", None
261
-
262
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
263
-
264
- # Fetch Questions
265
  try:
266
- response = requests.get(questions_url, timeout=15)
267
- response.raise_for_status()
268
- questions_data = response.json()
269
- if not questions_data:
270
- return "No questions found.", None
271
- print(f"Processing {len(questions_data)} questions...")
272
  except Exception as e:
273
- return f"Error fetching questions: {e}", None
274
 
275
- # Process questions with progress tracking
276
- results_log = []
277
- answers_payload = []
278
- total_start = time.time()
279
 
280
- for i, item in enumerate(questions_data):
281
  task_id = item.get("task_id")
282
- question_text = item.get("question")
283
 
284
- if not task_id or question_text is None:
285
  continue
286
 
 
 
287
  try:
288
- print(f"[{i+1}/{len(questions_data)}] Processing {task_id}...")
289
- submitted_answer = agent(question_text)
290
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
291
- results_log.append({
292
- "Task ID": task_id,
293
- "Question": question_text[:80] + "..." if len(question_text) > 80 else question_text,
294
- "Answer": submitted_answer[:100] + "..." if len(submitted_answer) > 100 else submitted_answer
295
  })
296
-
297
- # Memory cleanup every few questions
298
- if i % 3 == 0:
299
- gc.collect()
300
-
301
  except Exception as e:
302
- error_answer = f"ERROR: {str(e)}"
303
- answers_payload.append({"task_id": task_id, "submitted_answer": error_answer})
304
- results_log.append({
305
- "Task ID": task_id,
306
- "Question": question_text[:80] + "..." if len(question_text) > 80 else question_text,
307
- "Answer": error_answer
308
  })
309
-
310
- total_time = time.time() - total_start
311
- print(f"All questions processed in {total_time:.1f} seconds")
312
-
313
- if not answers_payload:
314
- return "No answers generated.", pd.DataFrame(results_log)
315
-
 
316
  # Submit results
317
- submission_data = {
318
- "username": username.strip(),
319
- "agent_code": agent_code,
320
- "answers": answers_payload
321
- }
322
-
323
  try:
324
- response = requests.post(submit_url, json=submission_data, timeout=60)
325
- response.raise_for_status()
326
- result_data = response.json()
 
 
 
 
 
327
 
328
- final_status = (
329
- f"βœ… Submission Successful!\n"
330
- f"User: {result_data.get('username')}\n"
331
- f"Score: {result_data.get('score', 'N/A')}% "
332
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
333
- f"Processing Time: {total_time:.1f}s\n"
334
- f"Message: {result_data.get('message', 'No message')}"
335
  )
336
 
337
- results_df = pd.DataFrame(results_log)
338
- return final_status, results_df
339
 
340
  except Exception as e:
341
- error_msg = f"❌ Submission Failed: {str(e)}"
342
- results_df = pd.DataFrame(results_log)
343
- return error_msg, results_df
344
 
345
- # --- Gradio Interface ---
346
- with gr.Blocks(title="GAIA Agent - Fast Mode") as demo:
347
- gr.Markdown("# πŸš€ GAIA Agent Evaluation (Optimized)")
348
- gr.Markdown(
349
- """
350
- **Fast Mode Optimizations:**
351
- - Reduced max steps: 4 per question
352
- - Shorter token generation: 128 tokens max
353
- - 30s timeout per question
354
- - Aggressive memory management
355
-
356
- **Usage:** Login β†’ Click Run β†’ View Results
357
- """
358
- )
359
 
360
- with gr.Row():
361
- gr.LoginButton()
362
-
363
- with gr.Row():
364
- run_button = gr.Button("πŸƒβ€β™‚οΈ Run Fast Evaluation", variant="primary", size="lg")
365
 
366
- with gr.Row():
367
- status_output = gr.Textbox(
368
- label="πŸ“Š Status & Results",
369
- lines=6,
370
- interactive=False,
371
- placeholder="Ready to run evaluation..."
372
- )
373
 
374
- with gr.Row():
375
- results_table = gr.DataFrame(
376
- label="πŸ“ Questions & Answers",
377
- wrap=True,
378
- interactive=False
379
- )
380
 
381
- run_button.click(
382
- fn=run_and_submit_all,
383
- outputs=[status_output, results_table],
384
- show_progress=True
385
- )
386
 
387
  if __name__ == "__main__":
388
- print("πŸš€ GAIA Agent Fast Mode Starting...")
389
- print(f"βš™οΈ Max Steps: {MAX_STEPS}, Max Tokens: {MAX_TOKENS}")
390
- print(f"⏱️ Timeout per question: {TIMEOUT_PER_QUESTION}s")
391
 
392
  demo.launch(
393
- debug=False,
394
- share=False,
395
  server_name="0.0.0.0",
396
  server_port=7860,
 
397
  show_error=True
398
  )
 
17
  import torch
18
  import time
19
  import gc
20
+ import warnings
21
+
22
+ # Suppress warnings
23
+ warnings.filterwarnings("ignore")
24
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
25
 
26
  # --- Load Environment Variables ---
27
  load_dotenv()
28
  SERPER_API_KEY = os.getenv("SERPER_API_KEY")
29
 
30
+ # --- Constants (ULTRA FAST MODE) ---
31
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
32
+ MAX_STEPS = 3 # Reduced to 3
33
+ MAX_TOKENS = 64 # Very short responses
34
  MODEL_NAME = "microsoft/Phi-3-mini-4k-instruct"
35
+ TIMEOUT_PER_QUESTION = 15 # 15 seconds max
36
+ MAX_CONTEXT = 1024 # Very short context
37
 
38
+ # --- Configure Environment ---
39
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
40
  os.environ["HF_HUB_DISABLE_SYMLINKS_WARNING"] = "1"
41
  os.environ["BITSANDBYTES_NOWELCOME"] = "1"
42
 
43
+ print("Loading model (ULTRA FAST mode)...")
44
  start_time = time.time()
45
 
46
+ # Minimal model loading
47
  model = AutoModelForCausalLM.from_pretrained(
48
  MODEL_NAME,
49
  trust_remote_code=True,
50
  torch_dtype=torch.float32,
51
  device_map="cpu",
52
  low_cpu_mem_usage=True,
53
+ use_cache=False
 
54
  )
55
 
56
  tokenizer = AutoTokenizer.from_pretrained(
57
  MODEL_NAME,
58
+ use_fast=True,
59
+ trust_remote_code=True,
60
+ padding_side="left"
61
  )
62
 
63
  if tokenizer.pad_token is None:
64
  tokenizer.pad_token = tokenizer.eos_token
65
 
66
+ # Pre-compile generation config
67
+ GENERATION_CONFIG = GenerationConfig(
68
+ max_new_tokens=MAX_TOKENS,
69
+ temperature=0.3,
70
+ do_sample=True,
71
+ pad_token_id=tokenizer.pad_token_id,
72
+ eos_token_id=tokenizer.eos_token_id,
73
+ use_cache=False,
74
+ repetition_penalty=1.1
75
+ )
76
+
77
  load_time = time.time() - start_time
78
  print(f"Model loaded in {load_time:.2f} seconds")
79
 
80
+ # --- Lightning Fast Tools ---
81
  def web_search(query: str) -> str:
82
+ """Ultra-fast web search"""
83
  try:
84
  if SERPER_API_KEY:
85
+ params = {'q': query[:100], 'num': 1} # Single result
86
  headers = {'X-API-KEY': SERPER_API_KEY, 'Content-Type': 'application/json'}
87
  response = requests.post(
88
  'https://google.serper.dev/search',
89
  headers=headers,
90
  json=params,
91
+ timeout=3
92
  )
93
  results = response.json()
94
+ if 'organic' in results and results['organic']:
95
+ return f"{results['organic'][0]['title']}: {results['organic'][0]['snippet'][:200]}"
96
+ return "No results"
97
  else:
98
  with DDGS() as ddgs:
99
+ for result in ddgs.text(query, max_results=1):
100
+ return f"{result['title']}: {result['body'][:200]}"
101
+ return "No results"
102
+ except:
103
+ return "Search failed"
104
 
105
  def calculator(expression: str) -> str:
106
+ """Lightning calculator"""
107
  try:
108
+ clean_expr = re.sub(r'[^\d+\-*/().\s]', '', str(expression))
109
+ if not clean_expr.strip():
110
+ return "Invalid expression"
111
+ result = eval(clean_expr) # Simple eval for speed
112
  return str(float(result))
113
+ except:
114
+ return "Calc error"
115
 
116
  def read_pdf(file_path: str) -> str:
117
+ """Fast PDF reader"""
118
  try:
119
  text = extract_text(file_path)
120
+ return text[:500] if text else "No PDF text"
121
+ except:
122
+ return "PDF error"
123
 
124
  def read_webpage(url: str) -> str:
125
+ """Fast webpage reader"""
126
  try:
127
+ response = requests.get(url, timeout=3, headers={'User-Agent': 'Bot'})
 
 
128
  soup = BeautifulSoup(response.text, 'html.parser')
 
 
 
 
129
  text = soup.get_text(separator=' ', strip=True)
130
+ return text[:500] if text else "No webpage text"
131
+ except:
132
+ return "Webpage error"
133
 
134
  TOOLS = {
135
  "web_search": web_search,
136
+ "calculator": calculator,
137
  "read_pdf": read_pdf,
138
  "read_webpage": read_webpage
139
  }
140
 
141
+ # --- Ultra Fast Agent ---
142
+ class FastGAIA_Agent:
143
  def __init__(self):
144
  self.tools = TOOLS
145
+ self.prompt_template = (
146
+ "<|system|>You solve GAIA questions fast. Tools: web_search, calculator, read_pdf, read_webpage.\n"
147
+ "Format: ```json\n{\"tool\": \"name\", \"args\": {\"key\": \"value\"}}```\n"
148
+ "Always end with: Final Answer: [answer]<|end|>\n"
149
+ "<|user|>{history}<|end|>\n<|assistant|>"
150
  )
151
 
152
  def __call__(self, question: str) -> str:
153
  start_time = time.time()
 
154
 
155
  try:
156
+ history = f"Question: {question}"
157
 
158
  for step in range(MAX_STEPS):
 
159
  if time.time() - start_time > TIMEOUT_PER_QUESTION:
160
+ return "TIMEOUT"
161
+
162
+ response = self._fast_generate(history)
163
 
164
+ # Quick final answer check
165
+ if "Final Answer:" in response:
166
+ answer = response.split("Final Answer:")[-1].strip().split('\n')[0]
167
+ return answer[:200] # Limit answer length
168
 
169
+ # Quick tool parsing
170
+ tool_result = self._quick_tool_use(response)
171
+ if tool_result:
172
+ history += f"\nAction: {tool_result}"
 
 
 
 
 
 
 
 
173
  else:
174
+ history += f"\nThought: {response[:100]}"
175
 
176
+ # Keep history short
177
+ if len(history) > 800:
178
+ history = history[-800:]
179
 
180
+ return "No solution found"
181
 
182
  except Exception as e:
183
+ return f"Error: {str(e)[:50]}"
 
184
 
185
+ def _fast_generate(self, history: str) -> str:
 
 
 
 
 
 
186
  try:
187
+ prompt = self.prompt_template.format(history=history)
188
+
189
+ # Fast tokenization
190
  inputs = tokenizer(
191
+ prompt,
192
+ return_tensors="pt",
193
  truncation=True,
194
+ max_length=MAX_CONTEXT,
195
  padding=False
196
  )
197
 
198
+ # Fast generation
 
 
 
 
 
 
 
 
199
  with torch.no_grad():
200
  outputs = model.generate(
201
  inputs.input_ids,
202
+ generation_config=GENERATION_CONFIG,
203
  attention_mask=inputs.attention_mask
204
  )
205
 
206
+ # Fast decoding
207
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
208
+ response = response.split("<|assistant|>")[-1].strip()
209
 
210
  # Immediate cleanup
211
  del inputs, outputs
212
+ gc.collect()
213
 
214
  return response
215
 
216
  except Exception as e:
217
+ return f"Gen error: {str(e)}"
218
 
219
+ def _quick_tool_use(self, text: str) -> str:
220
  try:
221
+ # Quick JSON extraction
222
+ json_match = re.search(r'```json\s*({[^}]*})\s*```', text)
223
+ if not json_match:
224
+ return ""
225
+
226
+ tool_data = json.loads(json_match.group(1))
227
+ tool_name = tool_data.get("tool", "")
228
+ args = tool_data.get("args", {})
229
+
230
+ if tool_name in self.tools:
231
+ result = self.tools[tool_name](**args)
232
+ return f"Used {tool_name}: {str(result)[:150]}"
233
+
234
  except:
235
  pass
236
+ return ""
 
 
 
 
 
 
 
 
 
 
237
 
238
+ # --- Lightning Fast Runner ---
239
  def run_and_submit_all(profile: gr.OAuthProfile | None):
 
 
 
240
  if not profile:
241
+ return "❌ Please login first", None
242
 
243
  username = profile.username
244
+
245
+ # Quick setup
246
+ agent = FastGAIA_Agent()
247
  api_url = DEFAULT_API_URL
248
+ space_id = os.getenv("SPACE_ID", "unknown")
249
+
250
+ print(f"πŸš€ ULTRA FAST mode - User: {username}")
251
+
252
+ # Fetch questions quickly
 
 
 
 
 
 
253
  try:
254
+ response = requests.get(f"{api_url}/questions", timeout=10)
255
+ questions = response.json()
256
+ print(f"πŸ“ Got {len(questions)} questions")
 
 
 
257
  except Exception as e:
258
+ return f"❌ Failed to get questions: {e}", None
259
 
260
+ # Process at lightning speed
261
+ results = []
262
+ answers = []
263
+ start_time = time.time()
264
 
265
+ for i, item in enumerate(questions):
266
  task_id = item.get("task_id")
267
+ question = item.get("question", "")
268
 
269
+ if not task_id:
270
  continue
271
 
272
+ print(f"⚑ [{i+1}/{len(questions)}] {task_id[:8]}...")
273
+
274
  try:
275
+ answer = agent(question)
276
+ answers.append({"task_id": task_id, "submitted_answer": answer})
277
+ results.append({
278
+ "ID": task_id[:8],
279
+ "Question": question[:60] + "...",
280
+ "Answer": answer[:80] + "..." if len(answer) > 80 else answer
 
281
  })
 
 
 
 
 
282
  except Exception as e:
283
+ error_ans = f"ERROR: {str(e)[:30]}"
284
+ answers.append({"task_id": task_id, "submitted_answer": error_ans})
285
+ results.append({
286
+ "ID": task_id[:8],
287
+ "Question": question[:60] + "...",
288
+ "Answer": error_ans
289
  })
290
+
291
+ # Quick memory cleanup
292
+ if i % 5 == 0:
293
+ gc.collect()
294
+
295
+ total_time = time.time() - start_time
296
+ print(f"⏱️ Completed in {total_time:.1f}s ({total_time/len(questions):.1f}s per question)")
297
+
298
  # Submit results
 
 
 
 
 
 
299
  try:
300
+ submission = {
301
+ "username": username,
302
+ "agent_code": f"https://huggingface.co/spaces/{space_id}/tree/main",
303
+ "answers": answers
304
+ }
305
+
306
+ response = requests.post(f"{api_url}/submit", json=submission, timeout=30)
307
+ result = response.json()
308
 
309
+ status = (
310
+ f"🎯 ULTRA FAST RESULTS\n"
311
+ f"πŸ‘€ User: {result.get('username', username)}\n"
312
+ f"πŸ“Š Score: {result.get('score', 'N/A')}% "
313
+ f"({result.get('correct_count', '?')}/{result.get('total_attempted', '?')})\n"
314
+ f"⏱️ Time: {total_time:.1f}s ({total_time/len(questions):.1f}s/question)\n"
315
+ f"πŸ’¬ {result.get('message', 'Completed!')}"
316
  )
317
 
318
+ return status, pd.DataFrame(results)
 
319
 
320
  except Exception as e:
321
+ error_status = f"❌ Submission failed: {str(e)}\n⏱️ Processing time: {total_time:.1f}s"
322
+ return error_status, pd.DataFrame(results)
 
323
 
324
+ # --- Ultra Simple UI ---
325
+ with gr.Blocks(title="GAIA Agent - ULTRA FAST") as demo:
326
+ gr.Markdown("# ⚑ GAIA Agent - ULTRA FAST MODE")
327
+ gr.Markdown("**Speed settings:** 3 steps max β€’ 64 tokens β€’ 15s timeout β€’ Lightning tools")
 
 
 
 
 
 
 
 
 
 
328
 
329
+ gr.LoginButton()
 
 
 
 
330
 
331
+ run_btn = gr.Button("πŸš€ RUN ULTRA FAST", variant="primary", size="lg")
 
 
 
 
 
 
332
 
333
+ status = gr.Textbox(label="πŸ“Š Results", lines=6, interactive=False)
334
+ table = gr.DataFrame(label="πŸ“‹ Answers", interactive=False)
 
 
 
 
335
 
336
+ run_btn.click(run_and_submit_all, outputs=[status, table], show_progress=True)
 
 
 
 
337
 
338
  if __name__ == "__main__":
339
+ print("⚑ ULTRA FAST GAIA Agent Starting...")
340
+ print(f"βš™οΈ {MAX_STEPS} steps, {MAX_TOKENS} tokens, {TIMEOUT_PER_QUESTION}s timeout")
 
341
 
342
  demo.launch(
343
+ share=True, # Added share=True for public link
 
344
  server_name="0.0.0.0",
345
  server_port=7860,
346
+ debug=False,
347
  show_error=True
348
  )