import os import re import requests import gradio as gr from PIL import Image from pypdf import PdfReader from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel, tool # ১. মডেল সেটআপ (Lightweight & Fast) HF_TOKEN = os.getenv("HF_TOKEN") model = InferenceClientModel( model_id="Qwen/Qwen2.5-Coder-1.5B-Instruct", token=HF_TOKEN ) # ২. কাস্টম ফাইল রিডার টুলস @tool def read_pdf_content(file_path: str) -> str: """Reads and extracts text from a PDF file. Args: file_path: Path to the PDF file. """ try: reader = PdfReader(file_path) text = "" for p in reader.pages: text += p.extract_text() or "" return text[:3000] if text else "No text found." except Exception as e: return f"Error reading PDF: {e}" @tool def inspect_image(file_path: str) -> str: """Inspects image dimensions and metadata. Args: file_path: Path to the image. """ try: with Image.open(file_path) as img: return f"Format: {img.format}, Size: {img.size}, Mode: {img.mode}" except Exception as e: return f"Error reading image: {e}" # ৩. এজেন্ট তৈরি gaia_agent = CodeAgent( tools=[DuckDuckGoSearchTool(), read_pdf_content, inspect_image], model=model, max_steps=5, additional_authorized_imports=["math", "statistics", "re", "json", "datetime"] ) DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" def solve_single_task(question: str, file_path: str = None) -> str: prompt = f"Question: {question}\n" if file_path: prompt += f"Local file available at: {file_path}\n" prompt += "Provide ONLY the concise final answer without explanations, reasoning, or 'FINAL ANSWER' prefix." try: raw = str(gaia_agent.run(prompt)).strip() return re.sub(r'^(FINAL ANSWER|Answer)[:\s]*', '', raw, flags=re.IGNORECASE).strip() except Exception: return "N/A" def run_and_submit_all(profile: gr.OAuthProfile | None): if not profile: return "Please Login to Hugging Face with the button first.", None username = profile.username space_id = os.getenv("SPACE_ID", "Learnix-AI-Lab/Final_Assignment_Template") agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main" questions_url = f"{DEFAULT_API_URL}/questions" submit_url = f"{DEFAULT_API_URL}/submit" try: resp = requests.get(questions_url, timeout=20) resp.raise_for_status() questions_data = resp.json() except Exception as e: return f"Error fetching questions: {e}", None answers_payload = [] display_rows = [] for item in questions_data: task_id = item.get("task_id") q_text = item.get("question") file_name = item.get("file_name") local_path = None if file_name: file_dl_url = f"{DEFAULT_API_URL}/files/{task_id}" dl_resp = requests.get(file_dl_url) if dl_resp.status_code == 200: local_path = f"tmp_{file_name}" with open(local_path, "wb") as f: f.write(dl_resp.content) ans = solve_single_task(q_text, local_path) answers_payload.append({"task_id": task_id, "submitted_answer": ans}) display_rows.append([q_text, ans]) if local_path and os.path.exists(local_path): os.remove(local_path) submit_data = { "username": username, "agent_code": agent_code, "answers": answers_payload } try: sub_resp = requests.post(submit_url, json=submit_data, timeout=30) sub_resp.raise_for_status() result_json = sub_resp.json() score = result_json.get("score", "N/A") return f"Successfully submitted! Your Score: {score}", display_rows except Exception as e: return f"Submission error: {e}", display_rows # ৪. Gradio ইন্টারফেস with gr.Blocks() as demo: gr.Markdown("# 🤖 GAIA Benchmark Evaluator") gr.LoginButton() run_btn = gr.Button("Run Evaluation & Submit All Answers", variant="primary") status_box = gr.Textbox(label="Status / Result", lines=3) results_table = gr.DataFrame(headers=["Question", "Agent Answer"], label="Answers") run_btn.click( fn=run_and_submit_all, outputs=[status_box, results_table] ) if __name__ == "__main__": demo.launch()