Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -16,6 +16,10 @@ from youtube_transcript_api import YouTubeTranscriptApi
|
|
| 16 |
|
| 17 |
|
| 18 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
TEXT_MODELS = (
|
| 20 |
"Qwen/Qwen3-235B-A22B-Instruct-2507:cheapest",
|
| 21 |
"openai/gpt-oss-120b:cheapest",
|
|
@@ -172,6 +176,13 @@ def download_attachment(task_id: str, file_name: str) -> str:
|
|
| 172 |
headers={"User-Agent": USER_AGENT},
|
| 173 |
timeout=30,
|
| 174 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
response.raise_for_status()
|
| 176 |
handle = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
|
| 177 |
handle.write(response.content)
|
|
@@ -232,7 +243,7 @@ def extract_attachment(path: str, file_name: str, question: str, token: str) ->
|
|
| 232 |
|
| 233 |
|
| 234 |
def should_search(question: str, has_attachment: bool) -> bool:
|
| 235 |
-
if has_attachment
|
| 236 |
return False
|
| 237 |
reversed_question = question[::-1].lower()
|
| 238 |
if "understand this sentence" in reversed_question:
|
|
@@ -319,16 +330,37 @@ def run_and_submit_all(
|
|
| 319 |
oauth_token: gr.OAuthToken | None,
|
| 320 |
):
|
| 321 |
"""Fetch all questions, solve them, and submit exact-match answers."""
|
| 322 |
-
if profile is None
|
| 323 |
return (
|
| 324 |
-
"Please sign in with Hugging Face
|
| 325 |
None,
|
| 326 |
)
|
| 327 |
|
| 328 |
username = profile.username
|
| 329 |
space_id = os.getenv("SPACE_ID")
|
| 330 |
agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
|
| 331 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
|
| 333 |
try:
|
| 334 |
response = requests.get(f"{DEFAULT_API_URL}/questions", timeout=20)
|
|
@@ -346,9 +378,23 @@ def run_and_submit_all(
|
|
| 346 |
print(f"Solving {index}/{len(questions)}: {task_id}")
|
| 347 |
try:
|
| 348 |
answer = agent.solve(question, task_id, file_name)
|
|
|
|
|
|
|
| 349 |
except Exception as exc:
|
| 350 |
print(f"Agent error on {task_id}: {exc}")
|
| 351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
answers_payload.append({"task_id": task_id, "submitted_answer": answer})
|
| 353 |
results_log.append(
|
| 354 |
{
|
|
@@ -358,6 +404,14 @@ def run_and_submit_all(
|
|
| 358 |
}
|
| 359 |
)
|
| 360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
submission = {
|
| 362 |
"username": username.strip(),
|
| 363 |
"agent_code": agent_code,
|
|
@@ -390,9 +444,10 @@ with gr.Blocks() as demo:
|
|
| 390 |
This agent searches the web, reads benchmark attachments, transcribes audio,
|
| 391 |
and uses a large reasoning model to produce exact-match answers.
|
| 392 |
|
| 393 |
-
1.
|
| 394 |
-
2.
|
| 395 |
-
3.
|
|
|
|
| 396 |
"""
|
| 397 |
)
|
| 398 |
gr.LoginButton()
|
|
|
|
| 16 |
|
| 17 |
|
| 18 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 19 |
+
ATTACHMENT_MIRROR = (
|
| 20 |
+
"https://huggingface.co/spaces/bstraehle/gaia/resolve/"
|
| 21 |
+
"617431ad4021eb2a62ab81488d1ec1cd7d1e3e19/data"
|
| 22 |
+
)
|
| 23 |
TEXT_MODELS = (
|
| 24 |
"Qwen/Qwen3-235B-A22B-Instruct-2507:cheapest",
|
| 25 |
"openai/gpt-oss-120b:cheapest",
|
|
|
|
| 176 |
headers={"User-Agent": USER_AGENT},
|
| 177 |
timeout=30,
|
| 178 |
)
|
| 179 |
+
if response.status_code == 404:
|
| 180 |
+
print(f"Course file endpoint is missing {task_id}; using pinned mirror.")
|
| 181 |
+
response = requests.get(
|
| 182 |
+
f"{ATTACHMENT_MIRROR}/{file_name}",
|
| 183 |
+
headers={"User-Agent": USER_AGENT},
|
| 184 |
+
timeout=30,
|
| 185 |
+
)
|
| 186 |
response.raise_for_status()
|
| 187 |
handle = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
|
| 188 |
handle.write(response.content)
|
|
|
|
| 243 |
|
| 244 |
|
| 245 |
def should_search(question: str, has_attachment: bool) -> bool:
|
| 246 |
+
if has_attachment:
|
| 247 |
return False
|
| 248 |
reversed_question = question[::-1].lower()
|
| 249 |
if "understand this sentence" in reversed_question:
|
|
|
|
| 330 |
oauth_token: gr.OAuthToken | None,
|
| 331 |
):
|
| 332 |
"""Fetch all questions, solve them, and submit exact-match answers."""
|
| 333 |
+
if profile is None:
|
| 334 |
return (
|
| 335 |
+
"Please sign in with Hugging Face first. No answers were submitted.",
|
| 336 |
None,
|
| 337 |
)
|
| 338 |
|
| 339 |
username = profile.username
|
| 340 |
space_id = os.getenv("SPACE_ID")
|
| 341 |
agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
|
| 342 |
+
provider_token = os.getenv("HF_TOKEN")
|
| 343 |
+
if not provider_token and oauth_token is not None:
|
| 344 |
+
provider_token = oauth_token.token
|
| 345 |
+
if not provider_token:
|
| 346 |
+
return (
|
| 347 |
+
"Missing inference credential. Add a private Space secret named HF_TOKEN "
|
| 348 |
+
"with 'Make calls to Inference Providers' permission. No answers were submitted.",
|
| 349 |
+
None,
|
| 350 |
+
)
|
| 351 |
+
|
| 352 |
+
agent = ResearchAgent(provider_token)
|
| 353 |
+
try:
|
| 354 |
+
access_check = agent.ask_model("Reply with exactly: OK")
|
| 355 |
+
if access_check.upper() != "OK":
|
| 356 |
+
raise RuntimeError(f"Unexpected preflight response: {access_check!r}")
|
| 357 |
+
except Exception as exc:
|
| 358 |
+
return (
|
| 359 |
+
"Inference preflight failed, so evaluation was stopped before any submission. "
|
| 360 |
+
"Create a fine-grained Hugging Face token with 'Make calls to Inference "
|
| 361 |
+
f"Providers' permission and save it as the HF_TOKEN Space secret. Detail: {exc}",
|
| 362 |
+
None,
|
| 363 |
+
)
|
| 364 |
|
| 365 |
try:
|
| 366 |
response = requests.get(f"{DEFAULT_API_URL}/questions", timeout=20)
|
|
|
|
| 378 |
print(f"Solving {index}/{len(questions)}: {task_id}")
|
| 379 |
try:
|
| 380 |
answer = agent.solve(question, task_id, file_name)
|
| 381 |
+
if not answer.strip():
|
| 382 |
+
raise RuntimeError("The model returned an empty answer")
|
| 383 |
except Exception as exc:
|
| 384 |
print(f"Agent error on {task_id}: {exc}")
|
| 385 |
+
results_log.append(
|
| 386 |
+
{
|
| 387 |
+
"Task ID": task_id,
|
| 388 |
+
"Question": question,
|
| 389 |
+
"Submitted Answer": f"ERROR (not submitted): {exc}",
|
| 390 |
+
}
|
| 391 |
+
)
|
| 392 |
+
return (
|
| 393 |
+
f"Stopped safely at question {index}/{len(questions)}. "
|
| 394 |
+
"No leaderboard submission was made because at least one answer failed. "
|
| 395 |
+
f"Task {task_id}: {exc}",
|
| 396 |
+
pd.DataFrame(results_log),
|
| 397 |
+
)
|
| 398 |
answers_payload.append({"task_id": task_id, "submitted_answer": answer})
|
| 399 |
results_log.append(
|
| 400 |
{
|
|
|
|
| 404 |
}
|
| 405 |
)
|
| 406 |
|
| 407 |
+
if len(answers_payload) != len(questions) or any(
|
| 408 |
+
not item["submitted_answer"].strip() for item in answers_payload
|
| 409 |
+
):
|
| 410 |
+
return (
|
| 411 |
+
"Safety check stopped submission because the answer set was incomplete.",
|
| 412 |
+
pd.DataFrame(results_log),
|
| 413 |
+
)
|
| 414 |
+
|
| 415 |
submission = {
|
| 416 |
"username": username.strip(),
|
| 417 |
"agent_code": agent_code,
|
|
|
|
| 444 |
This agent searches the web, reads benchmark attachments, transcribes audio,
|
| 445 |
and uses a large reasoning model to produce exact-match answers.
|
| 446 |
|
| 447 |
+
1. Add a private Space secret named `HF_TOKEN` with Inference Providers permission.
|
| 448 |
+
2. Sign in with Hugging Face.
|
| 449 |
+
3. Click **Run Evaluation & Submit All Answers** once.
|
| 450 |
+
4. Keep this tab open while the 20 questions are processed.
|
| 451 |
"""
|
| 452 |
)
|
| 453 |
gr.LoginButton()
|