Commit ·
78a1b32
1
Parent(s): 174b92b
.....
Browse files
app.py
CHANGED
|
@@ -18,8 +18,8 @@ from collections import defaultdict
|
|
| 18 |
import tempfile
|
| 19 |
|
| 20 |
try:
|
| 21 |
-
import google.
|
| 22 |
-
from google.
|
| 23 |
except ImportError:
|
| 24 |
genai = None
|
| 25 |
GenerationConfig = None
|
|
@@ -27,7 +27,7 @@ except ImportError:
|
|
| 27 |
HarmBlockThreshold = None
|
| 28 |
FinishReason = None
|
| 29 |
HarmProbability = None
|
| 30 |
-
print("WARNING: google-genai library not found. Install with: pip install google-genai")
|
| 31 |
|
| 32 |
try:
|
| 33 |
from duckduckgo_search import DDGS
|
|
@@ -761,24 +761,31 @@ class GeneralRAGPipeline:
|
|
| 761 |
class GaiaLevel1Agent:
|
| 762 |
def __init__(self, api_url: str = DEFAULT_API_URL):
|
| 763 |
self.api_url = api_url
|
| 764 |
-
# Changed self.llm_model to self.genai_client and store model name separately
|
| 765 |
self.genai_client: Optional[Any] = None
|
| 766 |
self.llm_model_name: str = 'gemini-2.5-flash-preview-05-20'
|
| 767 |
self.rag_pipeline = GeneralRAGPipeline(DEFAULT_RAG_CONFIG)
|
| 768 |
|
| 769 |
if genai and GOOGLE_GEMINI_API_KEY:
|
| 770 |
try:
|
| 771 |
-
genai.configure
|
| 772 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 773 |
gaia_logger.info(f"Google GenAI Client initialized. Will use model '{self.llm_model_name}'.")
|
| 774 |
except Exception as e:
|
| 775 |
-
# Updated error message to reflect client initialization
|
| 776 |
gaia_logger.error(f"Error initializing Google GenAI Client or configuring for model '{self.llm_model_name}': {e}", exc_info=True)
|
| 777 |
-
self.genai_client = None
|
| 778 |
else:
|
| 779 |
-
gaia_logger.warning("Google GenAI library (google.
|
| 780 |
|
| 781 |
-
# Updated check for genai_client availability
|
| 782 |
if not self.genai_client:
|
| 783 |
gaia_logger.warning("Google GenAI Client unavailable. LLM capabilities limited/unavailable.")
|
| 784 |
|
|
@@ -1061,9 +1068,7 @@ class GaiaLevel1Agent:
|
|
| 1061 |
default_model_answer = "Information not available in provided context"
|
| 1062 |
default_reasoning = "LLM processing failed or context insufficient."
|
| 1063 |
|
| 1064 |
-
# Updated check to use self.genai_client
|
| 1065 |
if not self.genai_client or not genai or not GenerationConfig or not FinishReason or not HarmCategory or not HarmBlockThreshold:
|
| 1066 |
-
# Updated warning message
|
| 1067 |
gaia_logger.warning("Google GenAI Client or necessary enums/configs not available for answer formulation.")
|
| 1068 |
reasoning = "Google GenAI Client or its configuration components not available for answer formulation."
|
| 1069 |
answer_val = default_model_answer
|
|
@@ -1146,11 +1151,9 @@ class GaiaLevel1Agent:
|
|
| 1146 |
{"category": HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, "threshold": HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE},
|
| 1147 |
]
|
| 1148 |
|
| 1149 |
-
# Updated LLM call to use self.genai_client.models.generate_content
|
| 1150 |
-
# Model name is prefixed with "models/" and contents is a list.
|
| 1151 |
response = self.genai_client.models.generate_content(
|
| 1152 |
-
model=f"models/{self.llm_model_name}",
|
| 1153 |
-
contents=[final_prompt],
|
| 1154 |
generation_config=gen_config,
|
| 1155 |
safety_settings=safety_settings
|
| 1156 |
)
|
|
@@ -1158,12 +1161,10 @@ class GaiaLevel1Agent:
|
|
| 1158 |
if hasattr(response, 'prompt_feedback') and response.prompt_feedback.block_reason:
|
| 1159 |
reason_text = response.prompt_feedback.block_reason.name
|
| 1160 |
block_details = "; ".join([f"{sr.category.name}: {sr.probability.name}" for sr in response.prompt_feedback.safety_ratings if hasattr(sr, 'blocked') and sr.blocked])
|
| 1161 |
-
# Updated log message for clarity
|
| 1162 |
gaia_logger.warning(f"Google GenAI prompt blocked. Reason: {reason_text}. Details: {block_details}")
|
| 1163 |
return {"model_answer": "LLM Error: Prompt blocked", "reasoning_trace": f"My input was blocked by the LLM provider (Reason: {reason_text}). Details: {block_details}"}
|
| 1164 |
|
| 1165 |
if not response.candidates:
|
| 1166 |
-
# Updated log message
|
| 1167 |
gaia_logger.warning("Google GenAI response has no candidates.")
|
| 1168 |
return {"model_answer": "LLM Error: No response", "reasoning_trace": "LLM did not provide any response candidates."}
|
| 1169 |
|
|
@@ -1177,7 +1178,6 @@ class GaiaLevel1Agent:
|
|
| 1177 |
for sr in candidate.safety_ratings if (hasattr(sr,'blocked') and sr.blocked) or (hasattr(sr,'probability') and HarmProbability and sr.probability.value >= HarmProbability.MEDIUM.value)
|
| 1178 |
]
|
| 1179 |
if relevant_ratings: safety_ratings_str = "; ".join(relevant_ratings)
|
| 1180 |
-
# Updated log message
|
| 1181 |
gaia_logger.warning(f"Google GenAI candidate did not finish successfully. Reason: {reason_name}. Safety Ratings: {safety_ratings_str if safety_ratings_str else 'N/A'}")
|
| 1182 |
|
| 1183 |
user_message = "LLM Error: Response incomplete"
|
|
@@ -1195,7 +1195,6 @@ class GaiaLevel1Agent:
|
|
| 1195 |
return self._parse_llm_output(llm_answer_text)
|
| 1196 |
|
| 1197 |
except ValueError as ve:
|
| 1198 |
-
# Updated log message
|
| 1199 |
if "finish_reason" in str(ve).lower() and ("part" in str(ve).lower() or "candidate" in str(ve).lower()):
|
| 1200 |
gaia_logger.error(f"ValueError accessing Google GenAI response.text, likely due to non-STOP finish_reason not caught explicitly: {ve}", exc_info=False)
|
| 1201 |
fr_from_ex = "Unknown (from ValueError)"
|
|
@@ -1203,11 +1202,10 @@ class GaiaLevel1Agent:
|
|
| 1203 |
if match_fr: fr_from_ex = match_fr.group(1)
|
| 1204 |
return {"model_answer": "LLM Error: Invalid response state",
|
| 1205 |
"reasoning_trace": f"Could not parse LLM response. Finish reason possibly {fr_from_ex}. Details: {str(ve)[:150]}"}
|
| 1206 |
-
else:
|
| 1207 |
gaia_logger.error(f"ValueError during Google GenAI call or processing: {ve}", exc_info=True)
|
| 1208 |
return {"model_answer": "LLM Error: Value error", "reasoning_trace": f"A value error occurred: {str(ve)}"}
|
| 1209 |
except Exception as e:
|
| 1210 |
-
# Updated log and error messages
|
| 1211 |
gaia_logger.error(f"Error calling Google GenAI API: {e}", exc_info=True)
|
| 1212 |
error_type_name = type(e).__name__
|
| 1213 |
error_message = str(e)
|
|
@@ -1335,12 +1333,11 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 1335 |
except Exception as e: return f"Error fetching questions: {e}", None
|
| 1336 |
|
| 1337 |
results_log_for_gradio, answers_for_api_submission = [], []
|
| 1338 |
-
GEMINI_RPM_LIMIT = int(os.getenv("GEMINI_RPM_LIMIT", "10"))
|
| 1339 |
-
# Ensuring sleep_llm calculation is robust, e.g. GEMINI_RPM_LIMIT can't be 0.
|
| 1340 |
if GEMINI_RPM_LIMIT <= 0:
|
| 1341 |
gaia_logger.warning(f"GEMINI_RPM_LIMIT is {GEMINI_RPM_LIMIT}, which is invalid. Defaulting to 1 RPM for safety (60s sleep).")
|
| 1342 |
-
GEMINI_RPM_LIMIT = 1
|
| 1343 |
-
sleep_llm = (60.0 / GEMINI_RPM_LIMIT) + 0.5
|
| 1344 |
gaia_logger.info(f"Using Gemini RPM limit: {GEMINI_RPM_LIMIT}, LLM call sleep: {sleep_llm:.2f}s")
|
| 1345 |
|
| 1346 |
|
|
@@ -1403,12 +1400,13 @@ with gr.Blocks(title="GAIA RAG Agent - Advanced") as demo:
|
|
| 1403 |
2. Click 'Run Evaluation & Submit All Answers' to process all questions from the GAIA benchmark and submit them.
|
| 1404 |
---
|
| 1405 |
This agent utilizes Retrieval-Augmented Generation (RAG) with multiple search providers, advanced file processing (CSV, JSON, Excel, PDF, Audio Transcription), and experimental video analysis capabilities (bird species identification/counting in YouTube videos) via Hugging Face Transformers. Answers are formulated by a Large Language Model (Google GenAI).
|
| 1406 |
-
"""
|
| 1407 |
)
|
| 1408 |
gr.LoginButton()
|
| 1409 |
run_button = gr.Button("Run Evaluation & Submit All Answers", variant="primary")
|
| 1410 |
status_output = gr.Textbox(label="Status / Submission Result", lines=5, interactive=False)
|
| 1411 |
-
|
|
|
|
| 1412 |
run_button.click(fn=run_and_submit_all, inputs=[], outputs=[status_output, results_table])
|
| 1413 |
|
| 1414 |
if __name__ == "__main__":
|
|
@@ -1427,7 +1425,8 @@ if __name__ == "__main__":
|
|
| 1427 |
("librosa", librosa), ("openpyxl", openpyxl), ("pdfplumber", pdfplumber),
|
| 1428 |
("yt_dlp", yt_dlp), ("cv2 (opencv-python)", cv2), ("BeautifulSoup", BeautifulSoup),
|
| 1429 |
("duckduckgo_search", DDGS), ("googleapiclient", build_google_search_service),
|
| 1430 |
-
("tavily", TavilyClient),
|
|
|
|
| 1431 |
]
|
| 1432 |
for lib_name, lib_var in libraries_to_check:
|
| 1433 |
print(f"✅ {lib_name} lib found." if lib_var else f"⚠️ WARNING: {lib_name} lib missing (functionality may be impaired).")
|
|
@@ -1435,14 +1434,14 @@ if __name__ == "__main__":
|
|
| 1435 |
if missing_keys: print(f"\n--- PLEASE SET MISSING ENV VARS FOR FULL FUNCTIONALITY: {', '.join(missing_keys)} ---\n")
|
| 1436 |
else: print("\n--- All major API Key Environment Variables found. ---")
|
| 1437 |
|
| 1438 |
-
gemini_rpm_env = os.getenv("GEMINI_RPM_LIMIT", "10")
|
| 1439 |
try:
|
| 1440 |
gemini_rpm_val = int(gemini_rpm_env)
|
| 1441 |
-
if gemini_rpm_val <= 0: gemini_rpm_val = 10
|
| 1442 |
except ValueError:
|
| 1443 |
-
gemini_rpm_val = 10
|
| 1444 |
gaia_logger.warning(f"GEMINI_RPM_LIMIT ('{gemini_rpm_env}') is not a valid integer. Defaulting to {gemini_rpm_val} RPM.")
|
| 1445 |
-
print(f"--- Using GEMINI_RPM_LIMIT: {gemini_rpm_val} (Ensure this matches your Google GenAI API plan limits) ---")
|
| 1446 |
|
| 1447 |
|
| 1448 |
print("-"*(60 + len(" GAIA Level 1 Agent - RAG, FileProc, Video Analysis ")) + "\n")
|
|
|
|
| 18 |
import tempfile
|
| 19 |
|
| 20 |
try:
|
| 21 |
+
import google.genai as genai # Corrected: Import the new SDK package
|
| 22 |
+
from google.genai.types import GenerationConfig, HarmCategory, HarmBlockThreshold, FinishReason, HarmProbability # Corrected: Types from the new SDK
|
| 23 |
except ImportError:
|
| 24 |
genai = None
|
| 25 |
GenerationConfig = None
|
|
|
|
| 27 |
HarmBlockThreshold = None
|
| 28 |
FinishReason = None
|
| 29 |
HarmProbability = None
|
| 30 |
+
print("WARNING: google-genai library not found. Install with: pip install google-genai") # This warning is correct
|
| 31 |
|
| 32 |
try:
|
| 33 |
from duckduckgo_search import DDGS
|
|
|
|
| 761 |
class GaiaLevel1Agent:
|
| 762 |
def __init__(self, api_url: str = DEFAULT_API_URL):
|
| 763 |
self.api_url = api_url
|
|
|
|
| 764 |
self.genai_client: Optional[Any] = None
|
| 765 |
self.llm_model_name: str = 'gemini-2.5-flash-preview-05-20'
|
| 766 |
self.rag_pipeline = GeneralRAGPipeline(DEFAULT_RAG_CONFIG)
|
| 767 |
|
| 768 |
if genai and GOOGLE_GEMINI_API_KEY:
|
| 769 |
try:
|
| 770 |
+
# The genai.configure call is no longer needed if GOOGLE_API_KEY env var is set,
|
| 771 |
+
# or if the API key is passed directly to genai.Client()
|
| 772 |
+
# However, keeping it for now as it doesn't hurt if GOOGLE_GEMINI_API_KEY is set.
|
| 773 |
+
# If GOOGLE_API_KEY (the generic one) is intended for the client, it's often picked up automatically.
|
| 774 |
+
# For clarity, if GOOGLE_GEMINI_API_KEY is specific and different, ensure Client uses it.
|
| 775 |
+
# The new SDK typically uses GOOGLE_API_KEY from env.
|
| 776 |
+
# If GOOGLE_GEMINI_API_KEY is specifically for GenAI and different from a general GOOGLE_API_KEY,
|
| 777 |
+
# it should be passed to Client() if the client supports an api_key argument,
|
| 778 |
+
# or ensure genai.configure(api_key=GOOGLE_GEMINI_API_KEY) correctly sets it for the client.
|
| 779 |
+
# The migration guide implies genai.configure() still works or the client picks it up.
|
| 780 |
+
genai.configure(api_key=GOOGLE_GEMINI_API_KEY)
|
| 781 |
+
self.genai_client = genai.Client()
|
| 782 |
gaia_logger.info(f"Google GenAI Client initialized. Will use model '{self.llm_model_name}'.")
|
| 783 |
except Exception as e:
|
|
|
|
| 784 |
gaia_logger.error(f"Error initializing Google GenAI Client or configuring for model '{self.llm_model_name}': {e}", exc_info=True)
|
| 785 |
+
self.genai_client = None
|
| 786 |
else:
|
| 787 |
+
gaia_logger.warning("Google GenAI library (google.genai) or GOOGLE_GEMINI_API_KEY missing. LLM capabilities will be unavailable.")
|
| 788 |
|
|
|
|
| 789 |
if not self.genai_client:
|
| 790 |
gaia_logger.warning("Google GenAI Client unavailable. LLM capabilities limited/unavailable.")
|
| 791 |
|
|
|
|
| 1068 |
default_model_answer = "Information not available in provided context"
|
| 1069 |
default_reasoning = "LLM processing failed or context insufficient."
|
| 1070 |
|
|
|
|
| 1071 |
if not self.genai_client or not genai or not GenerationConfig or not FinishReason or not HarmCategory or not HarmBlockThreshold:
|
|
|
|
| 1072 |
gaia_logger.warning("Google GenAI Client or necessary enums/configs not available for answer formulation.")
|
| 1073 |
reasoning = "Google GenAI Client or its configuration components not available for answer formulation."
|
| 1074 |
answer_val = default_model_answer
|
|
|
|
| 1151 |
{"category": HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, "threshold": HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE},
|
| 1152 |
]
|
| 1153 |
|
|
|
|
|
|
|
| 1154 |
response = self.genai_client.models.generate_content(
|
| 1155 |
+
model=f"models/{self.llm_model_name}",
|
| 1156 |
+
contents=[final_prompt],
|
| 1157 |
generation_config=gen_config,
|
| 1158 |
safety_settings=safety_settings
|
| 1159 |
)
|
|
|
|
| 1161 |
if hasattr(response, 'prompt_feedback') and response.prompt_feedback.block_reason:
|
| 1162 |
reason_text = response.prompt_feedback.block_reason.name
|
| 1163 |
block_details = "; ".join([f"{sr.category.name}: {sr.probability.name}" for sr in response.prompt_feedback.safety_ratings if hasattr(sr, 'blocked') and sr.blocked])
|
|
|
|
| 1164 |
gaia_logger.warning(f"Google GenAI prompt blocked. Reason: {reason_text}. Details: {block_details}")
|
| 1165 |
return {"model_answer": "LLM Error: Prompt blocked", "reasoning_trace": f"My input was blocked by the LLM provider (Reason: {reason_text}). Details: {block_details}"}
|
| 1166 |
|
| 1167 |
if not response.candidates:
|
|
|
|
| 1168 |
gaia_logger.warning("Google GenAI response has no candidates.")
|
| 1169 |
return {"model_answer": "LLM Error: No response", "reasoning_trace": "LLM did not provide any response candidates."}
|
| 1170 |
|
|
|
|
| 1178 |
for sr in candidate.safety_ratings if (hasattr(sr,'blocked') and sr.blocked) or (hasattr(sr,'probability') and HarmProbability and sr.probability.value >= HarmProbability.MEDIUM.value)
|
| 1179 |
]
|
| 1180 |
if relevant_ratings: safety_ratings_str = "; ".join(relevant_ratings)
|
|
|
|
| 1181 |
gaia_logger.warning(f"Google GenAI candidate did not finish successfully. Reason: {reason_name}. Safety Ratings: {safety_ratings_str if safety_ratings_str else 'N/A'}")
|
| 1182 |
|
| 1183 |
user_message = "LLM Error: Response incomplete"
|
|
|
|
| 1195 |
return self._parse_llm_output(llm_answer_text)
|
| 1196 |
|
| 1197 |
except ValueError as ve:
|
|
|
|
| 1198 |
if "finish_reason" in str(ve).lower() and ("part" in str(ve).lower() or "candidate" in str(ve).lower()):
|
| 1199 |
gaia_logger.error(f"ValueError accessing Google GenAI response.text, likely due to non-STOP finish_reason not caught explicitly: {ve}", exc_info=False)
|
| 1200 |
fr_from_ex = "Unknown (from ValueError)"
|
|
|
|
| 1202 |
if match_fr: fr_from_ex = match_fr.group(1)
|
| 1203 |
return {"model_answer": "LLM Error: Invalid response state",
|
| 1204 |
"reasoning_trace": f"Could not parse LLM response. Finish reason possibly {fr_from_ex}. Details: {str(ve)[:150]}"}
|
| 1205 |
+
else:
|
| 1206 |
gaia_logger.error(f"ValueError during Google GenAI call or processing: {ve}", exc_info=True)
|
| 1207 |
return {"model_answer": "LLM Error: Value error", "reasoning_trace": f"A value error occurred: {str(ve)}"}
|
| 1208 |
except Exception as e:
|
|
|
|
| 1209 |
gaia_logger.error(f"Error calling Google GenAI API: {e}", exc_info=True)
|
| 1210 |
error_type_name = type(e).__name__
|
| 1211 |
error_message = str(e)
|
|
|
|
| 1333 |
except Exception as e: return f"Error fetching questions: {e}", None
|
| 1334 |
|
| 1335 |
results_log_for_gradio, answers_for_api_submission = [], []
|
| 1336 |
+
GEMINI_RPM_LIMIT = int(os.getenv("GEMINI_RPM_LIMIT", "10"))
|
|
|
|
| 1337 |
if GEMINI_RPM_LIMIT <= 0:
|
| 1338 |
gaia_logger.warning(f"GEMINI_RPM_LIMIT is {GEMINI_RPM_LIMIT}, which is invalid. Defaulting to 1 RPM for safety (60s sleep).")
|
| 1339 |
+
GEMINI_RPM_LIMIT = 1
|
| 1340 |
+
sleep_llm = (60.0 / GEMINI_RPM_LIMIT) + 0.5
|
| 1341 |
gaia_logger.info(f"Using Gemini RPM limit: {GEMINI_RPM_LIMIT}, LLM call sleep: {sleep_llm:.2f}s")
|
| 1342 |
|
| 1343 |
|
|
|
|
| 1400 |
2. Click 'Run Evaluation & Submit All Answers' to process all questions from the GAIA benchmark and submit them.
|
| 1401 |
---
|
| 1402 |
This agent utilizes Retrieval-Augmented Generation (RAG) with multiple search providers, advanced file processing (CSV, JSON, Excel, PDF, Audio Transcription), and experimental video analysis capabilities (bird species identification/counting in YouTube videos) via Hugging Face Transformers. Answers are formulated by a Large Language Model (Google GenAI).
|
| 1403 |
+
"""
|
| 1404 |
)
|
| 1405 |
gr.LoginButton()
|
| 1406 |
run_button = gr.Button("Run Evaluation & Submit All Answers", variant="primary")
|
| 1407 |
status_output = gr.Textbox(label="Status / Submission Result", lines=5, interactive=False)
|
| 1408 |
+
# Removed height argument from gr.DataFrame as it's causing a TypeError
|
| 1409 |
+
results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
|
| 1410 |
run_button.click(fn=run_and_submit_all, inputs=[], outputs=[status_output, results_table])
|
| 1411 |
|
| 1412 |
if __name__ == "__main__":
|
|
|
|
| 1425 |
("librosa", librosa), ("openpyxl", openpyxl), ("pdfplumber", pdfplumber),
|
| 1426 |
("yt_dlp", yt_dlp), ("cv2 (opencv-python)", cv2), ("BeautifulSoup", BeautifulSoup),
|
| 1427 |
("duckduckgo_search", DDGS), ("googleapiclient", build_google_search_service),
|
| 1428 |
+
("tavily", TavilyClient),
|
| 1429 |
+
("google.genai", genai) # Corrected library name in check
|
| 1430 |
]
|
| 1431 |
for lib_name, lib_var in libraries_to_check:
|
| 1432 |
print(f"✅ {lib_name} lib found." if lib_var else f"⚠️ WARNING: {lib_name} lib missing (functionality may be impaired).")
|
|
|
|
| 1434 |
if missing_keys: print(f"\n--- PLEASE SET MISSING ENV VARS FOR FULL FUNCTIONALITY: {', '.join(missing_keys)} ---\n")
|
| 1435 |
else: print("\n--- All major API Key Environment Variables found. ---")
|
| 1436 |
|
| 1437 |
+
gemini_rpm_env = os.getenv("GEMINI_RPM_LIMIT", "10")
|
| 1438 |
try:
|
| 1439 |
gemini_rpm_val = int(gemini_rpm_env)
|
| 1440 |
+
if gemini_rpm_val <= 0: gemini_rpm_val = 10
|
| 1441 |
except ValueError:
|
| 1442 |
+
gemini_rpm_val = 10
|
| 1443 |
gaia_logger.warning(f"GEMINI_RPM_LIMIT ('{gemini_rpm_env}') is not a valid integer. Defaulting to {gemini_rpm_val} RPM.")
|
| 1444 |
+
print(f"--- Using GEMINI_RPM_LIMIT: {gemini_rpm_val} (Ensure this matches your Google GenAI API plan limits) ---")
|
| 1445 |
|
| 1446 |
|
| 1447 |
print("-"*(60 + len(" GAIA Level 1 Agent - RAG, FileProc, Video Analysis ")) + "\n")
|