Chris
commited on
Commit
Β·
8430ff4
1
Parent(s):
da22b37
Final 6.2.3
Browse files- src/app.py +181 -155
src/app.py
CHANGED
|
@@ -723,20 +723,27 @@ Please log in to access GAIA evaluation with Qwen models and LangGraph workflow.
|
|
| 723 |
def run_and_submit_all(profile: gr.OAuthProfile | None):
|
| 724 |
"""
|
| 725 |
Fetches all questions from Unit 4 API, runs the GAIA Agent with LangGraph workflow,
|
| 726 |
-
and displays the results.
|
| 727 |
"""
|
| 728 |
start_time = time.time()
|
| 729 |
|
| 730 |
# Initialize result logger
|
| 731 |
result_logger = GAIAResultLogger()
|
| 732 |
|
| 733 |
-
#
|
| 734 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 735 |
|
| 736 |
# Get space info for code submission
|
| 737 |
space_id = os.getenv("SPACE_ID")
|
| 738 |
|
| 739 |
-
# Priority order for token: 1) HF_TOKEN env var, 2) OAuth token
|
| 740 |
hf_token = os.getenv("HF_TOKEN")
|
| 741 |
oauth_token = None
|
| 742 |
username = "unknown_user"
|
|
@@ -747,18 +754,29 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 747 |
username = "hf_token_user"
|
| 748 |
elif profile:
|
| 749 |
username = f"{profile.username}"
|
|
|
|
|
|
|
| 750 |
oauth_token = getattr(profile, 'oauth_token', None) or getattr(profile, 'token', None)
|
| 751 |
-
logger.info(f"User logged in: {username}, OAuth token available: {oauth_token is not None}")
|
| 752 |
|
| 753 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 754 |
if oauth_token:
|
|
|
|
|
|
|
|
|
|
| 755 |
try:
|
| 756 |
headers = {"Authorization": f"Bearer {oauth_token}"}
|
| 757 |
test_response = requests.get("https://huggingface.co/api/whoami", headers=headers, timeout=5)
|
| 758 |
|
| 759 |
if test_response.status_code == 401:
|
| 760 |
logger.error("β OAuth token has insufficient scopes for Qwen model inference")
|
| 761 |
-
return "Authentication Error: Your OAuth token lacks inference permissions. Please logout and login again
|
| 762 |
elif test_response.status_code == 200:
|
| 763 |
logger.info("β
OAuth token validated successfully")
|
| 764 |
else:
|
|
@@ -766,13 +784,18 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 766 |
|
| 767 |
except Exception as e:
|
| 768 |
logger.warning(f"β οΈ Could not validate OAuth token: {e}")
|
|
|
|
|
|
|
|
|
|
| 769 |
else:
|
| 770 |
logger.error("β No authentication provided")
|
| 771 |
-
return "Authentication Required: Please login with HuggingFace
|
| 772 |
|
| 773 |
if not oauth_token:
|
| 774 |
-
return "Authentication Required: Valid token with inference permissions needed for Qwen model access.", None,
|
| 775 |
|
|
|
|
|
|
|
| 776 |
api_url = DEFAULT_API_URL
|
| 777 |
questions_url = f"{api_url}/questions"
|
| 778 |
submit_url = f"{api_url}/submit"
|
|
@@ -784,6 +807,9 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 784 |
|
| 785 |
if not agent.initialized:
|
| 786 |
return "System Error: GAIA Agent failed to initialize with LangGraph workflow", None, auth_status, None, None, None
|
|
|
|
|
|
|
|
|
|
| 787 |
except ValueError as ve:
|
| 788 |
logger.error(f"Authentication error: {ve}")
|
| 789 |
return f"Authentication Error: {ve}", None, auth_status, None, None, None
|
|
@@ -818,10 +844,10 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 818 |
logger.error(f"An unexpected error occurred fetching questions: {e}")
|
| 819 |
return f"An unexpected error occurred fetching questions: {e}", None, auth_status, None, None, None
|
| 820 |
|
| 821 |
-
# 3. Run GAIA Agent
|
| 822 |
results_log = []
|
| 823 |
answers_payload = []
|
| 824 |
-
logger.info(f"Running GAIA Agent on {len(questions_data)} questions...")
|
| 825 |
|
| 826 |
for i, item in enumerate(questions_data, 1):
|
| 827 |
task_id = item.get("task_id")
|
|
@@ -839,6 +865,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 839 |
"Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
|
| 840 |
"Submitted Answer": submitted_answer[:200] + "..." if len(submitted_answer) > 200 else submitted_answer
|
| 841 |
})
|
|
|
|
| 842 |
except Exception as e:
|
| 843 |
logger.error(f"Error running GAIA agent on task {task_id}: {e}")
|
| 844 |
error_answer = f"AGENT ERROR: {str(e)}"
|
|
@@ -853,13 +880,13 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 853 |
logger.error("GAIA Agent did not produce any answers to submit.")
|
| 854 |
return "GAIA Agent did not produce any answers to submit.", pd.DataFrame(results_log), auth_status, None, None, None
|
| 855 |
|
| 856 |
-
# 4. Prepare
|
| 857 |
submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
|
| 858 |
-
status_update = f"GAIA Agent finished
|
| 859 |
logger.info(status_update)
|
| 860 |
|
| 861 |
-
# 5. Submit
|
| 862 |
-
logger.info(f"Submitting {len(answers_payload)} answers to: {submit_url}")
|
| 863 |
try:
|
| 864 |
response = requests.post(submit_url, json=submission_data, timeout=120)
|
| 865 |
response.raise_for_status()
|
|
@@ -884,17 +911,18 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 884 |
summary_file = logged_files.get("summary")
|
| 885 |
|
| 886 |
final_status = (
|
| 887 |
-
f"π GAIA Agent
|
| 888 |
-
f"User: {result_data.get('username')}\n"
|
| 889 |
-
f"Overall Score: {result_data.get('score', 'N/A')}% "
|
| 890 |
f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
|
| 891 |
-
f"Execution Time: {execution_time:.2f} seconds\n"
|
| 892 |
-
f"
|
| 893 |
-
f"π Results saved to {len([f for f in [csv_file, json_file, summary_file] if f])} files for
|
| 894 |
)
|
| 895 |
-
logger.info("
|
| 896 |
results_df = pd.DataFrame(results_log)
|
| 897 |
return final_status, results_df, auth_status, csv_file, json_file, summary_file
|
|
|
|
| 898 |
except requests.exceptions.HTTPError as e:
|
| 899 |
error_detail = f"Server responded with status {e.response.status_code}."
|
| 900 |
try:
|
|
@@ -902,22 +930,22 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
| 902 |
error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
|
| 903 |
except requests.exceptions.JSONDecodeError:
|
| 904 |
error_detail += f" Response: {e.response.text[:500]}"
|
| 905 |
-
status_message = f"Submission Failed: {error_detail}"
|
| 906 |
logger.error(status_message)
|
| 907 |
results_df = pd.DataFrame(results_log)
|
| 908 |
return status_message, results_df, auth_status, None, None, None
|
| 909 |
except requests.exceptions.Timeout:
|
| 910 |
-
status_message = "Submission Failed: The request timed out."
|
| 911 |
logger.error(status_message)
|
| 912 |
results_df = pd.DataFrame(results_log)
|
| 913 |
return status_message, results_df, auth_status, None, None, None
|
| 914 |
except requests.exceptions.RequestException as e:
|
| 915 |
-
status_message = f"Submission Failed: Network error - {e}"
|
| 916 |
logger.error(status_message)
|
| 917 |
results_df = pd.DataFrame(results_log)
|
| 918 |
return status_message, results_df, auth_status, None, None, None
|
| 919 |
except Exception as e:
|
| 920 |
-
status_message = f"An unexpected error occurred during submission: {e}"
|
| 921 |
logger.error(status_message)
|
| 922 |
results_df = pd.DataFrame(results_log)
|
| 923 |
return status_message, results_df, auth_status, None, None, None
|
|
@@ -1415,87 +1443,103 @@ Please log in to access GAIA evaluation features with full inference access.
|
|
| 1415 |
def refresh_auth_status(request: gr.Request):
|
| 1416 |
"""Refresh authentication status display with enhanced debugging"""
|
| 1417 |
try:
|
| 1418 |
-
#
|
| 1419 |
-
|
|
|
|
|
|
|
|
|
|
| 1420 |
|
| 1421 |
-
# Try
|
| 1422 |
-
|
| 1423 |
-
|
| 1424 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1425 |
|
| 1426 |
-
#
|
| 1427 |
-
|
| 1428 |
-
|
| 1429 |
-
|
|
|
|
| 1430 |
|
| 1431 |
-
|
| 1432 |
-
|
|
|
|
| 1433 |
|
| 1434 |
-
|
| 1435 |
-
oauth_token = None
|
| 1436 |
-
for attr in ['oauth_token', 'token', 'access_token', 'id_token']:
|
| 1437 |
-
token = getattr(profile, attr, None)
|
| 1438 |
-
if token:
|
| 1439 |
-
oauth_token = token
|
| 1440 |
-
logger.info(f"π Found token via {attr}: {len(token) if token else 0} chars")
|
| 1441 |
-
break
|
| 1442 |
-
|
| 1443 |
-
if not oauth_token and hasattr(profile, '__dict__'):
|
| 1444 |
-
logger.info(f"π Profile attributes: {list(profile.__dict__.keys())}")
|
| 1445 |
-
else:
|
| 1446 |
-
logger.warning("β οΈ No OAuth profile found in request")
|
| 1447 |
-
|
| 1448 |
-
# Check for HF_TOKEN as fallback
|
| 1449 |
-
hf_token = os.getenv("HF_TOKEN")
|
| 1450 |
-
if hf_token:
|
| 1451 |
-
logger.info("β
HF_TOKEN environment variable available")
|
| 1452 |
-
else:
|
| 1453 |
-
logger.info("βΉοΈ No HF_TOKEN environment variable")
|
| 1454 |
|
| 1455 |
return format_auth_status(profile)
|
| 1456 |
|
| 1457 |
except Exception as e:
|
| 1458 |
logger.error(f"β Error in refresh_auth_status: {e}")
|
| 1459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1460 |
|
| 1461 |
def check_login_state(request: gr.Request):
|
| 1462 |
"""Check if user is logged in and update UI accordingly with enhanced detection"""
|
| 1463 |
try:
|
| 1464 |
-
|
|
|
|
| 1465 |
|
| 1466 |
-
#
|
| 1467 |
-
|
| 1468 |
-
|
| 1469 |
-
user = getattr(request, 'user', None)
|
| 1470 |
-
if user and hasattr(user, 'username'):
|
| 1471 |
-
# Create a minimal profile object if we have user info
|
| 1472 |
-
class MockProfile:
|
| 1473 |
-
def __init__(self, username):
|
| 1474 |
-
self.username = username
|
| 1475 |
-
self.oauth_token = None
|
| 1476 |
-
profile = MockProfile(user.username)
|
| 1477 |
-
logger.info(f"π Created mock profile for user: {user.username}")
|
| 1478 |
|
| 1479 |
-
if
|
| 1480 |
-
#
|
| 1481 |
-
|
| 1482 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1483 |
button_update = gr.update(interactive=True, value="π Run GAIA Evaluation & Submit All Answers")
|
| 1484 |
-
logger.info(
|
| 1485 |
return auth_status, button_update
|
| 1486 |
else:
|
| 1487 |
-
#
|
| 1488 |
auth_status = format_auth_status(None)
|
| 1489 |
-
|
| 1490 |
-
|
| 1491 |
-
logger.info("βΉοΈ No user login detected")
|
| 1492 |
return auth_status, button_update
|
| 1493 |
|
| 1494 |
except Exception as e:
|
| 1495 |
logger.error(f"β Error in check_login_state: {e}")
|
| 1496 |
# Return safe defaults
|
| 1497 |
auth_status = f"### β Error\n\nError checking login state: {str(e)}"
|
| 1498 |
-
button_update = gr.update(interactive=False, value="π Login
|
| 1499 |
return auth_status, button_update
|
| 1500 |
|
| 1501 |
# Set up automatic login state checking
|
|
@@ -1540,99 +1584,81 @@ Please log in to access GAIA evaluation features with full inference access.
|
|
| 1540 |
scopes_list = oauth_scopes.split()
|
| 1541 |
debug_info.append(f"**Available Scopes**: {', '.join(scopes_list)}")
|
| 1542 |
debug_info.append(f"**Has inference-api scope**: {'inference-api' in scopes_list}")
|
|
|
|
|
|
|
| 1543 |
|
| 1544 |
-
# Check
|
| 1545 |
-
debug_info.append("\n##
|
| 1546 |
-
profile = getattr(request, 'oauth_profile', None)
|
| 1547 |
-
user = getattr(request, 'user', None)
|
| 1548 |
-
session = getattr(request, 'session', None)
|
| 1549 |
-
|
| 1550 |
-
debug_info.append(f"**Profile Object**: {profile is not None}")
|
| 1551 |
-
debug_info.append(f"**User Object**: {user is not None}")
|
| 1552 |
-
debug_info.append(f"**Session Object**: {session is not None}")
|
| 1553 |
-
|
| 1554 |
-
# Try to access Gradio's built-in OAuth info
|
| 1555 |
try:
|
| 1556 |
-
|
| 1557 |
-
|
| 1558 |
-
|
| 1559 |
-
|
| 1560 |
-
|
| 1561 |
-
state_attrs = [attr for attr in state.__dict__.keys() if 'oauth' in attr.lower() or 'user' in attr.lower() or 'auth' in attr.lower()]
|
| 1562 |
-
if state_attrs:
|
| 1563 |
-
debug_info.append(f"**State Auth Attributes**: {', '.join(state_attrs)}")
|
| 1564 |
-
except Exception as state_error:
|
| 1565 |
-
debug_info.append(f"**State Check Error**: {state_error}")
|
| 1566 |
-
|
| 1567 |
-
if profile:
|
| 1568 |
-
debug_info.append(f"**Profile Type**: {type(profile)}")
|
| 1569 |
-
debug_info.append(f"**Profile Username**: {getattr(profile, 'username', 'N/A')}")
|
| 1570 |
-
|
| 1571 |
-
# Check all profile attributes
|
| 1572 |
-
if hasattr(profile, '__dict__'):
|
| 1573 |
-
attrs = list(profile.__dict__.keys())
|
| 1574 |
-
debug_info.append(f"**Profile Attributes**: {', '.join(attrs)}")
|
| 1575 |
|
| 1576 |
-
|
| 1577 |
-
|
| 1578 |
-
|
| 1579 |
-
|
| 1580 |
-
|
| 1581 |
-
|
| 1582 |
-
# Try to extract OAuth token using different methods
|
| 1583 |
-
oauth_token = None
|
| 1584 |
-
token_source = None
|
| 1585 |
-
for attr in ['oauth_token', 'token', 'access_token', 'id_token', 'bearer_token']:
|
| 1586 |
-
token = getattr(profile, attr, None)
|
| 1587 |
-
if token:
|
| 1588 |
-
oauth_token = token
|
| 1589 |
-
token_source = attr
|
| 1590 |
-
break
|
| 1591 |
-
|
| 1592 |
-
if oauth_token:
|
| 1593 |
-
debug_info.append(f"**Token Found**: Via {token_source}, {len(oauth_token)} chars")
|
| 1594 |
-
|
| 1595 |
-
# Test the token
|
| 1596 |
-
scope_info = check_oauth_scopes(oauth_token)
|
| 1597 |
-
debug_info.append(f"**Token Valid**: {scope_info.get('logged_in', False)}")
|
| 1598 |
-
debug_info.append(f"**Detected Scopes**: {', '.join(scope_info.get('scopes', []))}")
|
| 1599 |
-
debug_info.append(f"**Can Read**: {scope_info.get('can_read', False)}")
|
| 1600 |
-
debug_info.append(f"**Can Inference**: {scope_info.get('can_inference', False)}")
|
| 1601 |
-
else:
|
| 1602 |
-
debug_info.append("**Token Found**: β No OAuth token found in profile")
|
| 1603 |
-
|
| 1604 |
-
if user:
|
| 1605 |
-
debug_info.append(f"**User Type**: {type(user)}")
|
| 1606 |
-
if hasattr(user, '__dict__'):
|
| 1607 |
-
user_attrs = list(user.__dict__.keys())
|
| 1608 |
-
debug_info.append(f"**User Attributes**: {', '.join(user_attrs)}")
|
| 1609 |
|
| 1610 |
-
#
|
| 1611 |
debug_info.append("\n## π§ Environment Variables")
|
| 1612 |
hf_token = os.getenv("HF_TOKEN")
|
| 1613 |
debug_info.append(f"**HF_TOKEN Available**: {hf_token is not None}")
|
| 1614 |
if hf_token:
|
| 1615 |
debug_info.append(f"**HF_TOKEN Length**: {len(hf_token)} chars")
|
| 1616 |
|
| 1617 |
-
|
| 1618 |
-
|
| 1619 |
-
|
| 1620 |
-
|
| 1621 |
-
debug_info.append(f"**Auth Headers**: {', '.join(auth_headers)}")
|
| 1622 |
|
| 1623 |
# Gradio-specific OAuth checks
|
| 1624 |
debug_info.append("\n## π¨ Gradio OAuth Integration")
|
| 1625 |
try:
|
| 1626 |
-
# Check if we're in an authenticated Gradio context
|
| 1627 |
import gradio as gr
|
| 1628 |
debug_info.append(f"**Gradio Version**: {gr.__version__}")
|
| 1629 |
-
|
| 1630 |
-
# Try to access OAuth through Gradio's context
|
| 1631 |
-
# This might work differently in newer Gradio versions
|
| 1632 |
|
| 1633 |
except Exception as gradio_error:
|
| 1634 |
debug_info.append(f"**Gradio OAuth Error**: {gradio_error}")
|
| 1635 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1636 |
return "\n".join(debug_info)
|
| 1637 |
|
| 1638 |
except Exception as e:
|
|
|
|
| 723 |
def run_and_submit_all(profile: gr.OAuthProfile | None):
|
| 724 |
"""
|
| 725 |
Fetches all questions from Unit 4 API, runs the GAIA Agent with LangGraph workflow,
|
| 726 |
+
and displays the results. Handles OAuth authentication at runtime.
|
| 727 |
"""
|
| 728 |
start_time = time.time()
|
| 729 |
|
| 730 |
# Initialize result logger
|
| 731 |
result_logger = GAIAResultLogger()
|
| 732 |
|
| 733 |
+
# Check OAuth environment configuration first
|
| 734 |
+
oauth_client_id = os.getenv("OAUTH_CLIENT_ID")
|
| 735 |
+
oauth_scopes = os.getenv("OAUTH_SCOPES")
|
| 736 |
+
|
| 737 |
+
if not oauth_client_id:
|
| 738 |
+
return "β OAuth not configured. Please add 'hf_oauth: true' to README.md", None, format_auth_status(None), None, None, None
|
| 739 |
+
|
| 740 |
+
if not oauth_scopes or "inference-api" not in oauth_scopes:
|
| 741 |
+
return f"β Missing inference-api scope. Current scopes: {oauth_scopes}. Please add 'inference-api' scope to README.md", None, format_auth_status(None), None, None, None
|
| 742 |
|
| 743 |
# Get space info for code submission
|
| 744 |
space_id = os.getenv("SPACE_ID")
|
| 745 |
|
| 746 |
+
# Priority order for token: 1) HF_TOKEN env var, 2) OAuth token from profile
|
| 747 |
hf_token = os.getenv("HF_TOKEN")
|
| 748 |
oauth_token = None
|
| 749 |
username = "unknown_user"
|
|
|
|
| 754 |
username = "hf_token_user"
|
| 755 |
elif profile:
|
| 756 |
username = f"{profile.username}"
|
| 757 |
+
|
| 758 |
+
# Try multiple ways to extract OAuth token
|
| 759 |
oauth_token = getattr(profile, 'oauth_token', None) or getattr(profile, 'token', None)
|
|
|
|
| 760 |
|
| 761 |
+
if not oauth_token:
|
| 762 |
+
for attr in ['access_token', 'id_token', 'bearer_token']:
|
| 763 |
+
token = getattr(profile, attr, None)
|
| 764 |
+
if token:
|
| 765 |
+
oauth_token = token
|
| 766 |
+
logger.info(f"π Found OAuth token via {attr}")
|
| 767 |
+
break
|
| 768 |
+
|
| 769 |
if oauth_token:
|
| 770 |
+
logger.info(f"β
User logged in: {username}, OAuth token extracted successfully")
|
| 771 |
+
|
| 772 |
+
# Test OAuth token validity
|
| 773 |
try:
|
| 774 |
headers = {"Authorization": f"Bearer {oauth_token}"}
|
| 775 |
test_response = requests.get("https://huggingface.co/api/whoami", headers=headers, timeout=5)
|
| 776 |
|
| 777 |
if test_response.status_code == 401:
|
| 778 |
logger.error("β OAuth token has insufficient scopes for Qwen model inference")
|
| 779 |
+
return "Authentication Error: Your OAuth token lacks inference permissions. Please logout and login again to refresh your OAuth session.", None, format_auth_status(profile), None, None, None
|
| 780 |
elif test_response.status_code == 200:
|
| 781 |
logger.info("β
OAuth token validated successfully")
|
| 782 |
else:
|
|
|
|
| 784 |
|
| 785 |
except Exception as e:
|
| 786 |
logger.warning(f"β οΈ Could not validate OAuth token: {e}")
|
| 787 |
+
else:
|
| 788 |
+
logger.warning(f"β οΈ User {username} logged in but no OAuth token found")
|
| 789 |
+
return f"OAuth Token Missing: Could not extract authentication token for user {username}. Please logout and login again.", None, format_auth_status(profile), None, None, None
|
| 790 |
else:
|
| 791 |
logger.error("β No authentication provided")
|
| 792 |
+
return "Authentication Required: Please login with HuggingFace. Your Space has OAuth configured but you need to login first.", None, format_auth_status(None), None, None, None
|
| 793 |
|
| 794 |
if not oauth_token:
|
| 795 |
+
return "Authentication Required: Valid token with inference permissions needed for Qwen model access.", None, format_auth_status(profile), None, None, None
|
| 796 |
|
| 797 |
+
# Get authentication status for display
|
| 798 |
+
auth_status = format_auth_status(profile)
|
| 799 |
api_url = DEFAULT_API_URL
|
| 800 |
questions_url = f"{api_url}/questions"
|
| 801 |
submit_url = f"{api_url}/submit"
|
|
|
|
| 807 |
|
| 808 |
if not agent.initialized:
|
| 809 |
return "System Error: GAIA Agent failed to initialize with LangGraph workflow", None, auth_status, None, None, None
|
| 810 |
+
|
| 811 |
+
logger.info("β
GAIA Agent initialized successfully")
|
| 812 |
+
|
| 813 |
except ValueError as ve:
|
| 814 |
logger.error(f"Authentication error: {ve}")
|
| 815 |
return f"Authentication Error: {ve}", None, auth_status, None, None, None
|
|
|
|
| 844 |
logger.error(f"An unexpected error occurred fetching questions: {e}")
|
| 845 |
return f"An unexpected error occurred fetching questions: {e}", None, auth_status, None, None, None
|
| 846 |
|
| 847 |
+
# 3. Run GAIA Agent on questions
|
| 848 |
results_log = []
|
| 849 |
answers_payload = []
|
| 850 |
+
logger.info(f"π€ Running GAIA Agent on {len(questions_data)} questions with LangGraph workflow...")
|
| 851 |
|
| 852 |
for i, item in enumerate(questions_data, 1):
|
| 853 |
task_id = item.get("task_id")
|
|
|
|
| 865 |
"Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
|
| 866 |
"Submitted Answer": submitted_answer[:200] + "..." if len(submitted_answer) > 200 else submitted_answer
|
| 867 |
})
|
| 868 |
+
logger.info(f"β
Question {i} processed successfully")
|
| 869 |
except Exception as e:
|
| 870 |
logger.error(f"Error running GAIA agent on task {task_id}: {e}")
|
| 871 |
error_answer = f"AGENT ERROR: {str(e)}"
|
|
|
|
| 880 |
logger.error("GAIA Agent did not produce any answers to submit.")
|
| 881 |
return "GAIA Agent did not produce any answers to submit.", pd.DataFrame(results_log), auth_status, None, None, None
|
| 882 |
|
| 883 |
+
# 4. Prepare and submit results
|
| 884 |
submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
|
| 885 |
+
status_update = f"π GAIA Agent finished processing {len(answers_payload)} questions. Submitting results for user '{username}'..."
|
| 886 |
logger.info(status_update)
|
| 887 |
|
| 888 |
+
# 5. Submit to Unit 4 API
|
| 889 |
+
logger.info(f"π€ Submitting {len(answers_payload)} answers to: {submit_url}")
|
| 890 |
try:
|
| 891 |
response = requests.post(submit_url, json=submission_data, timeout=120)
|
| 892 |
response.raise_for_status()
|
|
|
|
| 911 |
summary_file = logged_files.get("summary")
|
| 912 |
|
| 913 |
final_status = (
|
| 914 |
+
f"π GAIA Agent Evaluation Complete!\n"
|
| 915 |
+
f"π€ User: {result_data.get('username')}\n"
|
| 916 |
+
f"π Overall Score: {result_data.get('score', 'N/A')}% "
|
| 917 |
f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
|
| 918 |
+
f"β±οΈ Execution Time: {execution_time:.2f} seconds\n"
|
| 919 |
+
f"π¬ API Response: {result_data.get('message', 'No message received.')}\n\n"
|
| 920 |
+
f"π Results saved to {len([f for f in [csv_file, json_file, summary_file] if f])} files for download."
|
| 921 |
)
|
| 922 |
+
logger.info("β
GAIA evaluation completed successfully")
|
| 923 |
results_df = pd.DataFrame(results_log)
|
| 924 |
return final_status, results_df, auth_status, csv_file, json_file, summary_file
|
| 925 |
+
|
| 926 |
except requests.exceptions.HTTPError as e:
|
| 927 |
error_detail = f"Server responded with status {e.response.status_code}."
|
| 928 |
try:
|
|
|
|
| 930 |
error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
|
| 931 |
except requests.exceptions.JSONDecodeError:
|
| 932 |
error_detail += f" Response: {e.response.text[:500]}"
|
| 933 |
+
status_message = f"β Submission Failed: {error_detail}"
|
| 934 |
logger.error(status_message)
|
| 935 |
results_df = pd.DataFrame(results_log)
|
| 936 |
return status_message, results_df, auth_status, None, None, None
|
| 937 |
except requests.exceptions.Timeout:
|
| 938 |
+
status_message = "β Submission Failed: The request timed out."
|
| 939 |
logger.error(status_message)
|
| 940 |
results_df = pd.DataFrame(results_log)
|
| 941 |
return status_message, results_df, auth_status, None, None, None
|
| 942 |
except requests.exceptions.RequestException as e:
|
| 943 |
+
status_message = f"β Submission Failed: Network error - {e}"
|
| 944 |
logger.error(status_message)
|
| 945 |
results_df = pd.DataFrame(results_log)
|
| 946 |
return status_message, results_df, auth_status, None, None, None
|
| 947 |
except Exception as e:
|
| 948 |
+
status_message = f"β An unexpected error occurred during submission: {e}"
|
| 949 |
logger.error(status_message)
|
| 950 |
results_df = pd.DataFrame(results_log)
|
| 951 |
return status_message, results_df, auth_status, None, None, None
|
|
|
|
| 1443 |
def refresh_auth_status(request: gr.Request):
|
| 1444 |
"""Refresh authentication status display with enhanced debugging"""
|
| 1445 |
try:
|
| 1446 |
+
# Use Gradio's built-in OAuth support
|
| 1447 |
+
# In newer Gradio versions with HF Spaces, OAuth info should be accessible
|
| 1448 |
+
profile = None
|
| 1449 |
+
oauth_token = None
|
| 1450 |
+
username = None
|
| 1451 |
|
| 1452 |
+
# Try to get OAuth info from request
|
| 1453 |
+
if hasattr(request, 'user') and request.user:
|
| 1454 |
+
username = getattr(request.user, 'username', None)
|
| 1455 |
+
if username:
|
| 1456 |
+
# Create a profile-like object if we have user info
|
| 1457 |
+
class GradioProfile:
|
| 1458 |
+
def __init__(self, username):
|
| 1459 |
+
self.username = username
|
| 1460 |
+
self.oauth_token = None
|
| 1461 |
+
profile = GradioProfile(username)
|
| 1462 |
+
|
| 1463 |
+
# Alternative: Check session or headers for OAuth token
|
| 1464 |
+
if hasattr(request, 'session'):
|
| 1465 |
+
session = request.session
|
| 1466 |
+
oauth_token = session.get('oauth_token') or session.get('access_token')
|
| 1467 |
|
| 1468 |
+
# Check request headers for authorization
|
| 1469 |
+
if hasattr(request, 'headers'):
|
| 1470 |
+
auth_header = request.headers.get('authorization', '')
|
| 1471 |
+
if auth_header.startswith('Bearer '):
|
| 1472 |
+
oauth_token = auth_header[7:]
|
| 1473 |
|
| 1474 |
+
# If we found a token, add it to the profile
|
| 1475 |
+
if oauth_token and profile:
|
| 1476 |
+
profile.oauth_token = oauth_token
|
| 1477 |
|
| 1478 |
+
logger.info(f"π OAuth Debug - Profile: {profile is not None}, Username: {username}, Token: {oauth_token is not None}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1479 |
|
| 1480 |
return format_auth_status(profile)
|
| 1481 |
|
| 1482 |
except Exception as e:
|
| 1483 |
logger.error(f"β Error in refresh_auth_status: {e}")
|
| 1484 |
+
|
| 1485 |
+
# Fallback: Check environment variables and provide helpful info
|
| 1486 |
+
oauth_scopes = os.getenv("OAUTH_SCOPES")
|
| 1487 |
+
oauth_client_id = os.getenv("OAUTH_CLIENT_ID")
|
| 1488 |
+
|
| 1489 |
+
if oauth_client_id and oauth_scopes:
|
| 1490 |
+
return f"""
|
| 1491 |
+
### π OAuth Configuration Detected
|
| 1492 |
+
|
| 1493 |
+
**π Space OAuth**: β
Configured with scopes: {oauth_scopes}
|
| 1494 |
+
|
| 1495 |
+
**β οΈ Authentication Detection Issue**: {str(e)}
|
| 1496 |
+
|
| 1497 |
+
**π§ Gradio OAuth Integration**: The Space has OAuth enabled, but we're having trouble accessing your authentication status through the Gradio interface.
|
| 1498 |
+
|
| 1499 |
+
**π‘ This is likely a Gradio version compatibility issue**. Your login should still work for the GAIA evaluation.
|
| 1500 |
+
|
| 1501 |
+
**π― Try This**: Click "π Run GAIA Evaluation & Submit All Answers" button - it may work even if the status display has issues.
|
| 1502 |
+
"""
|
| 1503 |
+
else:
|
| 1504 |
+
return f"### β Authentication Error\n\nError checking auth status: {str(e)}"
|
| 1505 |
|
| 1506 |
def check_login_state(request: gr.Request):
|
| 1507 |
"""Check if user is logged in and update UI accordingly with enhanced detection"""
|
| 1508 |
try:
|
| 1509 |
+
# Simplified approach - just try to determine if user is logged in
|
| 1510 |
+
# without accessing request.user directly
|
| 1511 |
|
| 1512 |
+
# Check if OAuth environment is configured
|
| 1513 |
+
oauth_client_id = os.getenv("OAUTH_CLIENT_ID")
|
| 1514 |
+
oauth_scopes = os.getenv("OAUTH_SCOPES")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1515 |
|
| 1516 |
+
if oauth_client_id and oauth_scopes:
|
| 1517 |
+
# OAuth is configured, assume user can log in
|
| 1518 |
+
# Enable the button and let the actual authentication happen at runtime
|
| 1519 |
+
auth_status = f"""
|
| 1520 |
+
### π OAuth Configured Space
|
| 1521 |
+
|
| 1522 |
+
**π OAuth Status**: Space is configured with OAuth scopes: {oauth_scopes}
|
| 1523 |
+
|
| 1524 |
+
**π― Ready for GAIA Evaluation**: Click the button below to start evaluation with your HuggingFace login.
|
| 1525 |
+
|
| 1526 |
+
**π‘ Note**: Authentication happens when you click "Run GAIA Evaluation" - you'll be prompted to login if needed.
|
| 1527 |
+
"""
|
| 1528 |
button_update = gr.update(interactive=True, value="π Run GAIA Evaluation & Submit All Answers")
|
| 1529 |
+
logger.info("β
OAuth environment detected, enabling GAIA evaluation")
|
| 1530 |
return auth_status, button_update
|
| 1531 |
else:
|
| 1532 |
+
# No OAuth configured
|
| 1533 |
auth_status = format_auth_status(None)
|
| 1534 |
+
button_update = gr.update(interactive=False, value="π OAuth Not Configured")
|
| 1535 |
+
logger.info("βΉοΈ No OAuth environment detected")
|
|
|
|
| 1536 |
return auth_status, button_update
|
| 1537 |
|
| 1538 |
except Exception as e:
|
| 1539 |
logger.error(f"β Error in check_login_state: {e}")
|
| 1540 |
# Return safe defaults
|
| 1541 |
auth_status = f"### β Error\n\nError checking login state: {str(e)}"
|
| 1542 |
+
button_update = gr.update(interactive=False, value="π Login Error")
|
| 1543 |
return auth_status, button_update
|
| 1544 |
|
| 1545 |
# Set up automatic login state checking
|
|
|
|
| 1584 |
scopes_list = oauth_scopes.split()
|
| 1585 |
debug_info.append(f"**Available Scopes**: {', '.join(scopes_list)}")
|
| 1586 |
debug_info.append(f"**Has inference-api scope**: {'inference-api' in scopes_list}")
|
| 1587 |
+
else:
|
| 1588 |
+
debug_info.append("**β οΈ No OAuth scopes configured**")
|
| 1589 |
|
| 1590 |
+
# Check README.md OAuth configuration
|
| 1591 |
+
debug_info.append("\n## π README.md OAuth Configuration")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1592 |
try:
|
| 1593 |
+
with open('README.md', 'r') as f:
|
| 1594 |
+
readme_content = f.read()
|
| 1595 |
+
has_oauth = 'hf_oauth: true' in readme_content
|
| 1596 |
+
has_scopes = 'hf_oauth_scopes:' in readme_content
|
| 1597 |
+
has_inference = 'inference-api' in readme_content
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1598 |
|
| 1599 |
+
debug_info.append(f"**hf_oauth: true**: {has_oauth}")
|
| 1600 |
+
debug_info.append(f"**hf_oauth_scopes defined**: {has_scopes}")
|
| 1601 |
+
debug_info.append(f"**inference-api scope**: {has_inference}")
|
| 1602 |
+
except Exception as readme_error:
|
| 1603 |
+
debug_info.append(f"**README.md check error**: {readme_error}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1604 |
|
| 1605 |
+
# Environment Variables
|
| 1606 |
debug_info.append("\n## π§ Environment Variables")
|
| 1607 |
hf_token = os.getenv("HF_TOKEN")
|
| 1608 |
debug_info.append(f"**HF_TOKEN Available**: {hf_token is not None}")
|
| 1609 |
if hf_token:
|
| 1610 |
debug_info.append(f"**HF_TOKEN Length**: {len(hf_token)} chars")
|
| 1611 |
|
| 1612 |
+
space_host = os.getenv("SPACE_HOST")
|
| 1613 |
+
space_id = os.getenv("SPACE_ID")
|
| 1614 |
+
debug_info.append(f"**SPACE_HOST**: {space_host}")
|
| 1615 |
+
debug_info.append(f"**SPACE_ID**: {space_id}")
|
|
|
|
| 1616 |
|
| 1617 |
# Gradio-specific OAuth checks
|
| 1618 |
debug_info.append("\n## π¨ Gradio OAuth Integration")
|
| 1619 |
try:
|
|
|
|
| 1620 |
import gradio as gr
|
| 1621 |
debug_info.append(f"**Gradio Version**: {gr.__version__}")
|
| 1622 |
+
debug_info.append(f"**OAuth Profile Support**: Gradio should handle OAuth automatically in HF Spaces")
|
|
|
|
|
|
|
| 1623 |
|
| 1624 |
except Exception as gradio_error:
|
| 1625 |
debug_info.append(f"**Gradio OAuth Error**: {gradio_error}")
|
| 1626 |
|
| 1627 |
+
# Authentication Test
|
| 1628 |
+
debug_info.append("\n## π§ͺ Authentication Test")
|
| 1629 |
+
|
| 1630 |
+
if oauth_client_id and oauth_scopes:
|
| 1631 |
+
debug_info.append("**β
OAuth Environment**: Properly configured")
|
| 1632 |
+
|
| 1633 |
+
if "inference-api" in oauth_scopes:
|
| 1634 |
+
debug_info.append("**β
inference-api Scope**: Available for Qwen model access")
|
| 1635 |
+
debug_info.append("**π― Expected Behavior**: Login should provide Qwen model access")
|
| 1636 |
+
else:
|
| 1637 |
+
debug_info.append("**β inference-api Scope**: Missing - Qwen models won't work")
|
| 1638 |
+
debug_info.append("**π§ Fix**: Add 'inference-api' to hf_oauth_scopes in README.md")
|
| 1639 |
+
else:
|
| 1640 |
+
debug_info.append("**β OAuth Environment**: Not properly configured")
|
| 1641 |
+
|
| 1642 |
+
# Success Indicators
|
| 1643 |
+
debug_info.append("\n## β
Success Indicators")
|
| 1644 |
+
|
| 1645 |
+
if oauth_client_id:
|
| 1646 |
+
debug_info.append("- β
OAuth is enabled for this Space")
|
| 1647 |
+
else:
|
| 1648 |
+
debug_info.append("- β OAuth is not enabled (missing OAUTH_CLIENT_ID)")
|
| 1649 |
+
|
| 1650 |
+
if oauth_scopes and "inference-api" in oauth_scopes:
|
| 1651 |
+
debug_info.append("- β
inference-api scope is configured")
|
| 1652 |
+
debug_info.append("- β
Should have Qwen model access when logged in")
|
| 1653 |
+
else:
|
| 1654 |
+
debug_info.append("- β inference-api scope is missing")
|
| 1655 |
+
debug_info.append("- β Will not have Qwen model access")
|
| 1656 |
+
|
| 1657 |
+
# Login status detection (avoid AuthenticationMiddleware error)
|
| 1658 |
+
debug_info.append("\n## π€ Login Status")
|
| 1659 |
+
debug_info.append("**Note**: Due to Gradio OAuth integration, login status is detected at runtime")
|
| 1660 |
+
debug_info.append("**Current Status**: Check by clicking 'Run GAIA Evaluation' - you'll be prompted to login if needed")
|
| 1661 |
+
|
| 1662 |
return "\n".join(debug_info)
|
| 1663 |
|
| 1664 |
except Exception as e:
|