Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -2,20 +2,17 @@ import os
|
|
| 2 |
import gradio as gr
|
| 3 |
import requests
|
| 4 |
import inspect
|
|
|
|
| 5 |
import pandas as pd
|
| 6 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, VisitWebpageTool, InferenceClientModel, tool,OpenAIServerModel
|
| 7 |
import re
|
| 8 |
from huggingface_hub import InferenceClient
|
| 9 |
import base64
|
| 10 |
|
| 11 |
-
# (Keep Constants as is)
|
| 12 |
# --- Constants ---
|
| 13 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 14 |
|
| 15 |
-
#
|
| 16 |
-
# ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
|
| 17 |
-
|
| 18 |
-
|
| 19 |
|
| 20 |
@tool
|
| 21 |
def analyze_image_tool(image_path: str, question: str) -> str:
|
|
@@ -73,44 +70,116 @@ def download_task_file(task_id: str) -> str:
|
|
| 73 |
if matches:
|
| 74 |
filename = matches[0]
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
return f"File downloaded successfully! The file is located at: {filepath}. You can now write python code to open and read this file."
|
| 83 |
else:
|
| 84 |
return f"Failed to download file. HTTP Status: {response.status_code}. The file might not exist for this task."
|
| 85 |
except Exception as e:
|
| 86 |
return f"An error occurred while downloading: {e}"
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
search_tool = DuckDuckGoSearchTool()
|
| 89 |
visit_webpage_tool = VisitWebpageTool()
|
| 90 |
|
|
|
|
|
|
|
| 91 |
model = OpenAIServerModel(
|
| 92 |
-
model_id="llama-3.
|
| 93 |
api_base="https://api.groq.com/openai/v1",
|
| 94 |
api_key=os.getenv("GROQ_API_KEY")
|
| 95 |
)
|
| 96 |
manager_system_prompt="""
|
| 97 |
-
You are
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
def create_new_agent():
|
| 107 |
return CodeAgent(
|
| 108 |
-
tools=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
model=model,
|
| 110 |
instructions=manager_system_prompt,
|
| 111 |
-
max_steps=
|
| 112 |
-
additional_authorized_imports=["pandas", "openpyxl", "PyPDF2", "json", "csv", "re"]
|
| 113 |
)
|
|
|
|
|
|
|
|
|
|
| 114 |
def run_and_submit_all( profile: gr.OAuthProfile | None):
|
| 115 |
"""
|
| 116 |
Fetches all questions, runs the manager_agent on them, submits all answers,
|
|
|
|
| 2 |
import gradio as gr
|
| 3 |
import requests
|
| 4 |
import inspect
|
| 5 |
+
import tempfile
|
| 6 |
import pandas as pd
|
| 7 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, VisitWebpageTool, InferenceClientModel, tool,OpenAIServerModel
|
| 8 |
import re
|
| 9 |
from huggingface_hub import InferenceClient
|
| 10 |
import base64
|
| 11 |
|
|
|
|
| 12 |
# --- Constants ---
|
| 13 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 14 |
|
| 15 |
+
#--- tools ---
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
@tool
|
| 18 |
def analyze_image_tool(image_path: str, question: str) -> str:
|
|
|
|
| 70 |
if matches:
|
| 71 |
filename = matches[0]
|
| 72 |
|
| 73 |
+
temp_dir = tempfile.gettempdir()
|
| 74 |
+
filepath = os.path.join(temp_dir, filename)
|
| 75 |
+
|
| 76 |
+
with open(filepath, 'wb') as f:
|
| 77 |
+
f.write(response.content)
|
| 78 |
+
|
| 79 |
return f"File downloaded successfully! The file is located at: {filepath}. You can now write python code to open and read this file."
|
| 80 |
else:
|
| 81 |
return f"Failed to download file. HTTP Status: {response.status_code}. The file might not exist for this task."
|
| 82 |
except Exception as e:
|
| 83 |
return f"An error occurred while downloading: {e}"
|
| 84 |
|
| 85 |
+
@tool
|
| 86 |
+
def transcribe_audio_tool(audio_path: str) -> str:
|
| 87 |
+
"""
|
| 88 |
+
Transcribes an audio or video file (mp3, mp4, wav) to text.
|
| 89 |
+
Use this tool AFTER downloading a media file using download_task_file if the question requires knowing what is spoken in the file.
|
| 90 |
+
|
| 91 |
+
Args:
|
| 92 |
+
audio_path: The local path to the audio/video file.
|
| 93 |
+
"""
|
| 94 |
+
try:
|
| 95 |
+
api_key = os.getenv("GROQ_API_KEY")
|
| 96 |
+
if not api_key:
|
| 97 |
+
return "Error: GROQ_API_KEY not found in environment."
|
| 98 |
+
|
| 99 |
+
headers = {"Authorization": f"Bearer {api_key}"}
|
| 100 |
+
url = "https://api.groq.com/openai/v1/audio/transcriptions"
|
| 101 |
+
|
| 102 |
+
print(f"Transcribing audio file {audio_path}...")
|
| 103 |
+
with open(audio_path, "rb") as f:
|
| 104 |
+
files = {"file": (os.path.basename(audio_path), f)}
|
| 105 |
+
data = {"model": "whisper-large-v3"}
|
| 106 |
+
response = requests.post(url, headers=headers, files=files, data=data)
|
| 107 |
+
|
| 108 |
+
response.raise_for_status()
|
| 109 |
+
return response.json().get("text", "No text could be extracted.")
|
| 110 |
+
except Exception as e:
|
| 111 |
+
return f"Error transcribing audio: {str(e)}"
|
| 112 |
+
|
| 113 |
+
@tool
|
| 114 |
+
def read_webpage_clean_tool(url: str) -> str:
|
| 115 |
+
"""
|
| 116 |
+
Reads a webpage and extracts clean Markdown text.
|
| 117 |
+
Use this tool when VisitWebpageTool fails or when you need to read articles, documentation, or bypass JavaScript rendering.
|
| 118 |
+
|
| 119 |
+
Args:
|
| 120 |
+
url: The full URL of the webpage to read.
|
| 121 |
+
"""
|
| 122 |
+
try:
|
| 123 |
+
print(f"Fetching clean text from: {url}")
|
| 124 |
+
jina_url = f"https://r.jina.ai/{url}"
|
| 125 |
+
response = requests.get(jina_url, timeout=20)
|
| 126 |
+
response.raise_for_status()
|
| 127 |
+
# Restrict length to prevent context window overflow
|
| 128 |
+
return response.text[:8000]
|
| 129 |
+
except Exception as e:
|
| 130 |
+
return f"Error reading webpage with clean tool: {str(e)}"
|
| 131 |
search_tool = DuckDuckGoSearchTool()
|
| 132 |
visit_webpage_tool = VisitWebpageTool()
|
| 133 |
|
| 134 |
+
#--- agent ---
|
| 135 |
+
|
| 136 |
model = OpenAIServerModel(
|
| 137 |
+
model_id="llama-3.3-70b-versatile",
|
| 138 |
api_base="https://api.groq.com/openai/v1",
|
| 139 |
api_key=os.getenv("GROQ_API_KEY")
|
| 140 |
)
|
| 141 |
manager_system_prompt="""
|
| 142 |
+
You are an advanced AI assistant designed to solve complex, multi-step tasks from the GAIA benchmark.
|
| 143 |
+
You MUST strictly adhere to the ReAct (Reason, Act, Observe) framework for EVERY step you take.
|
| 144 |
+
|
| 145 |
+
Your process must look like this:
|
| 146 |
+
1. **Thought:** Carefully analyze the current state. What information do you have? What is missing? Plan your next exact move step-by-step.
|
| 147 |
+
2. **Action:** Execute your plan by calling the appropriate tool or writing Python code.
|
| 148 |
+
3. **Observation:** Review the output of your tool or code. (If code fails, your next Thought must be how to fix it).
|
| 149 |
+
|
| 150 |
+
Repeat this loop until you are 100% confident you have the final answer.
|
| 151 |
+
|
| 152 |
+
**Specific Guidelines for Tools and Code:**
|
| 153 |
+
1. **Information Gathering:** If the prompt mentions a file, use `download_task_file` FIRST to retrieve the local file path.
|
| 154 |
+
2. **Analysis via Code:** Write Python code to open, read, and analyze downloaded files (using pandas, json, PyPDF2, etc.). ALWAYS use `print()` in your code to output intermediate data, statistics, or rows so you can see the results in your next step.
|
| 155 |
+
3. **Vision/Images:** If the task involves an image, pass the local image path and your specific question to `analyze_image_tool`.
|
| 156 |
+
4. **Audio/Video:** If the task involves a spoken media file, use `transcribe_audio_tool` to get the transcript.
|
| 157 |
+
5. **Web Scraping:** Use `read_webpage_clean_tool` to fetch clean text from URLs if standard web browsing fails.
|
| 158 |
+
6. **Self-Correction:** Do not guess the final answer. If your Python code throws an error, read the traceback carefully, fix the code, and try again.
|
| 159 |
+
|
| 160 |
+
Finish your answer strictly with the following template: FINAL ANSWER: [YOUR FINAL ANSWER].
|
| 161 |
+
YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings.
|
| 162 |
+
If you are asked for a number, don't use a comma to write your number neither use units such as $ or percent sign unless specified otherwise.
|
| 163 |
+
If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise.
|
| 164 |
+
If you are asked for a comma separated list, apply the above rules depending on whether the element to be put in the list is a number or a string."""
|
| 165 |
def create_new_agent():
|
| 166 |
return CodeAgent(
|
| 167 |
+
tools=[
|
| 168 |
+
search_tool,
|
| 169 |
+
download_task_file,
|
| 170 |
+
visit_webpage_tool,
|
| 171 |
+
analyze_image_tool,
|
| 172 |
+
transcribe_audio_tool,
|
| 173 |
+
read_webpage_clean_tool
|
| 174 |
+
],
|
| 175 |
model=model,
|
| 176 |
instructions=manager_system_prompt,
|
| 177 |
+
max_steps=10,
|
| 178 |
+
additional_authorized_imports=["pandas", "openpyxl", "PyPDF2", "json", "csv", "re", "math", "datetime"]
|
| 179 |
)
|
| 180 |
+
|
| 181 |
+
#--- run ---
|
| 182 |
+
|
| 183 |
def run_and_submit_all( profile: gr.OAuthProfile | None):
|
| 184 |
"""
|
| 185 |
Fetches all questions, runs the manager_agent on them, submits all answers,
|