oniwaka's picture
Update app.py
e005ae3 verified
# app.py - Versione completa con tutte le importazioni
import gradio as gr
import requests
import json
import os
import re
from typing import Dict, List, Any, Optional
# Importazioni smolagents corrette
from smolagents import CodeAgent, tool, TransformersModel
class GAIAAgentFixed:
def __init__(self):
self.setup_model()
self.setup_agent()
def setup_model(self):
"""Configura il modello usando TransformersModel"""
try:
# Usa SmolLM che Γ¨ leggero e efficiente
self.model = TransformersModel(model_id="HuggingFaceTB/SmolLM-135M-Instruct")
except Exception as e:
print(f"Errore caricamento modello: {e}")
# Fallback a un modello piΓΉ piccolo se disponibile
self.model = TransformersModel(model_id="microsoft/DialoGPT-small")
def setup_agent(self):
"""Configura l'agente con tools"""
self.agent = CodeAgent(
tools=[
self.analyze_image,
self.transcribe_audio,
self.extract_text_from_file,
self.perform_calculation,
self.web_search
],
model=self.model,
max_iterations=8,
additional_authorized_imports=['datetime', 'pandas', 'numpy', 'requests', 're']
)
@tool
def analyze_image(self, image_path: str, question: str) -> str:
"""Analizza immagini per domande GAIA"""
try:
# Per ora implementazione base - in produzione useresti un modello vision
if os.path.exists(image_path):
return f"Immagine analizzata: {image_path}. Domanda: {question}"
else:
return "File immagine non trovato"
except Exception as e:
return f"Errore analisi immagine: {str(e)}"
@tool
def transcribe_audio(self, audio_path: str) -> str:
"""Trascrizione audio"""
try:
if os.path.exists(audio_path):
return f"Audio trascritto da: {audio_path}"
else:
return "File audio non trovato"
except Exception as e:
return f"Errore trascrizione: {str(e)}"
@tool
def extract_text_from_file(self, file_path: str) -> str:
"""Estrae testo da vari formati di file"""
try:
if not os.path.exists(file_path):
return "File non trovato"
if file_path.endswith('.txt'):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
return content[:2000] + "..." if len(content) > 2000 else content
elif file_path.endswith('.csv'):
try:
import pandas as pd
df = pd.read_csv(file_path)
return df.head(10).to_string()
except ImportError:
return "Pandas non disponibile per file CSV"
elif file_path.endswith(('.xlsx', '.xls')):
try:
import pandas as pd
df = pd.read_excel(file_path)
return df.head(10).to_string()
except ImportError:
return "Pandas non disponibile per file Excel"
else:
return f"Formato file non supportato: {file_path}"
except Exception as e:
return f"Errore lettura file: {str(e)}"
@tool
def perform_calculation(self, expression: str) -> str:
"""Calcoli matematici precisi"""
try:
# Sanitizza l'espressione per sicurezza
safe_expr = re.sub(r'[^0-9+\-*/().\s]', '', expression)
if not safe_expr.strip():
return "Espressione matematica non valida"
result = eval(safe_expr)
return str(result)
except ZeroDivisionError:
return "Errore: divisione per zero"
except Exception as e:
return f"Errore calcolo: {str(e)}"
@tool
def web_search(self, query: str) -> str:
"""Ricerca web simulata (placeholder)"""
return f"Risultati ricerca simulata per: {query}"
def solve_question(self, question: str, file_path: Optional[str] = None) -> str:
"""Risolve domande GAIA"""
system_prompt = f"""
Risolvi questa domanda GAIA Level 1 fornendo una risposta precisa.
REGOLE IMPORTANTI:
1. Leggi attentamente la domanda
2. Se c'Γ¨ un file, analizzalo prima di rispondere
3. Fornisci SOLO la risposta finale senza prefissi o spiegazioni
4. Per numeri: solo il valore numerico
5. Per liste: usa il formato richiesto nella domanda
6. Per Yes/No: rispondi solo "Yes" o "No"
DOMANDA: {question}
{f"FILE DISPONIBILE: {file_path}" if file_path else "NESSUN FILE"}
Risolvi passo dopo passo e fornisci la risposta finale:
"""
try:
response = self.agent.run(system_prompt)
return self._clean_answer(response, question)
except Exception as e:
return f"Errore risoluzione: {str(e)}"
def _clean_answer(self, raw_answer: str, question: str) -> str:
"""Pulisce la risposta per EXACT MATCH"""
# Rimuovi prefissi comuni
prefixes = [
"Final Answer:", "Risposta:", "Answer:", "Il risultato Γ¨:",
"La risposta Γ¨:", "Risposta finale:", "ANSWER:", "RISPOSTA:",
"The answer is:", "Result:", "Output:"
]
cleaned = str(raw_answer).strip()
for prefix in prefixes:
if cleaned.startswith(prefix):
cleaned = cleaned[len(prefix):].strip()
# Formattazione specifica per tipo di domanda
question_lower = question.lower()
if "how many" in question_lower or "count" in question_lower:
# Estrai solo il numero per domande di conteggio
numbers = re.findall(r'\d+', cleaned)
if numbers:
return numbers[0]
if "yes or no" in question_lower or ("yes" in question_lower and "no" in question_lower):
# Standardizza risposte yes/no
if "yes" in cleaned.lower():
return "Yes"
elif "no" in cleaned.lower():
return "No"
if "list" in question_lower and "comma" in question_lower:
# Formatta liste separate da virgole
cleaned = re.sub(r'\s*,\s*', ', ', cleaned)
return cleaned.strip()
class GAIAEvaluator:
def __init__(self):
self.base_url = "https://huggingface.co/spaces/huggingface-projects/gaia-benchmark-scoring/api"
try:
self.agent = GAIAAgentFixed()
self.agent_ready = True
except Exception as e:
print(f"Errore inizializzazione agente: {e}")
self.agent_ready = False
def test_single_question(self, username: str) -> Dict:
"""Testa una singola domanda"""
if not self.agent_ready:
return {"error": "Agente non inizializzato correttamente"}
try:
# Domande di test per verificare il funzionamento
test_questions = [
"What is 15 + 27?",
"How many letters are in the word 'hello'?",
"Is 10 greater than 5? Answer yes or no."
]
results = []
for question in test_questions:
answer = self.agent.solve_question(question)
results.append({
"question": question,
"answer": answer
})
return {
"username": username,
"test_results": results,
"status": "Test completato con successo"
}
except Exception as e:
return {"error": str(e)}
def fetch_real_question(self) -> Dict:
"""Prova a recuperare una domanda reale dall'API"""
try:
response = requests.get(f"{self.base_url}/random-question", timeout=10)
if response.status_code == 200:
return response.json()
else:
return {"error": f"API non disponibile: {response.status_code}"}
except Exception as e:
return {"error": f"Errore connessione API: {str(e)}"}
def create_interface():
evaluator = GAIAEvaluator()
def test_agent(username):
if not username:
return "⚠️ Inserisci il tuo username Hugging Face"
# Test con domande locali
result = evaluator.test_single_question(username)
if "error" in result:
return f"❌ Errore: {result['error']}"
output = f"""
## πŸ§ͺ Test Agente GAIA
**Username:** {username}
**Status:** βœ… Agente funzionante
### πŸ“ Risultati Test:
"""
for i, test in enumerate(result['test_results'], 1):
output += f"""
**Test {i}:**
- Domanda: {test['question']}
- Risposta: `{test['answer']}`
"""
return output
def test_api_connection():
"""Testa la connessione all'API GAIA"""
result = evaluator.fetch_real_question()
if "error" in result:
return f"❌ API non raggiungibile: {result['error']}"
else:
return f"βœ… API connessa. Domanda esempio: {result.get('Question', 'N/A')[:100]}..."
# Interfaccia Gradio
with gr.Blocks(title="πŸ† GAIA Agent - Fixed Version") as iface:
gr.Markdown("# πŸ† GAIA Agent - Versione Corretta")
gr.Markdown("Agente GAIA con importazioni corrette e gestione errori robusta")
with gr.Tab("πŸ§ͺ Test Agente"):
with gr.Row():
username_input = gr.Textbox(
label="Username Hugging Face",
placeholder="il-tuo-username"
)
test_btn = gr.Button("πŸ§ͺ Testa Agente", variant="primary")
output_display = gr.Markdown()
test_btn.click(
fn=test_agent,
inputs=[username_input],
outputs=[output_display]
)
with gr.Tab("🌐 Test API"):
api_test_btn = gr.Button("πŸ”— Testa Connessione API", variant="secondary")
api_output = gr.Markdown()
api_test_btn.click(
fn=test_api_connection,
outputs=[api_output]
)
gr.Markdown("""
### πŸ”§ Correzioni Implementate:
- βœ… Importazioni corrette: `from smolagents import CodeAgent, tool, TransformersModel`
- βœ… Gestione errori robusta per inizializzazione modello
- βœ… Fallback per modelli non disponibili
- βœ… Test locali per verificare funzionamento
- βœ… Validazione input e sanitizzazione
### πŸ“‹ Requisiti:
```
smolagents>=1.8.0
transformers>=4.35.0
torch>=2.0.0
gradio==5.33.0
```
""")
return iface
if __name__ == "__main__":
print("===== Avvio Applicazione GAIA Agent =====")
try:
iface = create_interface()
iface.launch()
except Exception as e:
print(f"Errore avvio applicazione: {e}")