Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -14,65 +14,62 @@ SUBMIT_URL = "https://agents-course-unit4-scoring.hf.space/submit"
|
|
| 14 |
FILES_URL = "https://agents-course-unit4-scoring.hf.space/files"
|
| 15 |
FILES_DIR = "files"
|
| 16 |
SYSTEM_PROMPT = "You are a helpful AI assistant tasked with answering questions accurately. Provide concise and accurate answers in the format requested by the question."
|
| 17 |
-
|
| 18 |
-
|
| 19 |
|
| 20 |
# --- AssistantAgent Implementation ---
|
| 21 |
class AssistantAgent:
|
| 22 |
def __init__(self, system_prompt: str):
|
| 23 |
self.system_prompt = system_prompt
|
| 24 |
-
self.headers = {
|
| 25 |
-
"Authorization": f"Bearer {XAI_API_KEY}",
|
| 26 |
-
"Content-Type": "application/json"
|
| 27 |
-
}
|
| 28 |
|
| 29 |
-
def
|
|
|
|
| 30 |
payload = {
|
| 31 |
-
"
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
],
|
| 35 |
-
"model": "grok-3-latest",
|
| 36 |
-
"stream": False,
|
| 37 |
-
"temperature": 0
|
| 38 |
}
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
def check_commutative(self, table: str) -> str:
|
| 47 |
try:
|
| 48 |
-
# Tách các dòng của bảng
|
| 49 |
rows = table.strip().split('\n')
|
| 50 |
-
if len(rows) < 3:
|
| 51 |
return "Error: Table format is invalid (not enough rows)."
|
| 52 |
|
| 53 |
-
# Lấy danh sách phần tử từ dòng đầu tiên (header)
|
| 54 |
header = rows[0].split('|')
|
| 55 |
-
if len(header) < 3:
|
| 56 |
return "Error: Table format is invalid (header too short)."
|
| 57 |
|
| 58 |
-
elements = header[1:-1][1:]
|
| 59 |
num_elements = len(elements)
|
| 60 |
if num_elements < 1:
|
| 61 |
return "Error: No elements found in table header."
|
| 62 |
|
| 63 |
-
# Kiểm tra số dòng dữ liệu (phải khớp với số phần tử + 2 dòng header)
|
| 64 |
if len(rows) != num_elements + 2:
|
| 65 |
return f"Error: Table row count ({len(rows)}) does not match expected ({num_elements + 2})."
|
| 66 |
|
| 67 |
-
# Kiểm tra định dạng dòng phân cách
|
| 68 |
if not rows[1].startswith('|---'):
|
| 69 |
return "Error: Table format is invalid (missing separator row)."
|
| 70 |
|
| 71 |
-
# Xây dựng bảng phép toán
|
| 72 |
operation = {}
|
| 73 |
for i in range(2, len(rows)):
|
| 74 |
cols = rows[i].split('|')
|
| 75 |
-
if len(cols) != num_elements + 2:
|
| 76 |
return f"Error: Row {i} has incorrect number of columns (expected {num_elements + 2}, got {len(cols)})."
|
| 77 |
|
| 78 |
for j in range(1, len(cols) - 1):
|
|
@@ -81,7 +78,6 @@ class AssistantAgent:
|
|
| 81 |
return f"Error: Invalid value '{val}' in table (not in {elements})."
|
| 82 |
operation[(elements[i - 2], elements[j - 1])] = val
|
| 83 |
|
| 84 |
-
# Tìm các cặp không giao hoán: a*b != b*a
|
| 85 |
non_commutative = set()
|
| 86 |
for a in elements:
|
| 87 |
for b in elements:
|
|
@@ -121,11 +117,11 @@ class AssistantAgent:
|
|
| 121 |
answers = []
|
| 122 |
for i in range(0, len(questions), batch_size):
|
| 123 |
batch = questions[i:i + batch_size]
|
| 124 |
-
prompt = "
|
| 125 |
for idx, (question, _) in enumerate(batch, 1):
|
| 126 |
prompt += f"{idx}. {question}\n"
|
| 127 |
|
| 128 |
-
batch_answers = self.
|
| 129 |
if "Error" in batch_answers:
|
| 130 |
answers.extend([batch_answers] * len(batch))
|
| 131 |
else:
|
|
@@ -134,8 +130,8 @@ class AssistantAgent:
|
|
| 134 |
answer = batch_answers[idx].split('. ', 1)[1] if idx < len(batch_answers) and '. ' in batch_answers[idx] else "Error: Could not parse answer."
|
| 135 |
answers.append(answer)
|
| 136 |
if i + batch_size < len(questions):
|
| 137 |
-
print("Waiting
|
| 138 |
-
time.sleep(
|
| 139 |
return answers
|
| 140 |
|
| 141 |
def process_file(self, question: str, file_path: str) -> str:
|
|
@@ -175,7 +171,7 @@ class AssistantAgent:
|
|
| 175 |
except Exception as e:
|
| 176 |
return f"Error reading Excel file: {e}"
|
| 177 |
else:
|
| 178 |
-
return "Error:
|
| 179 |
|
| 180 |
def __call__(self, question: str, file_path: str = None) -> str:
|
| 181 |
if "provide the subset of S involved in any possible counter-examples" in question:
|
|
@@ -351,7 +347,7 @@ with gr.Blocks() as demo:
|
|
| 351 |
1. Log in to your Hugging Face account using the button below.
|
| 352 |
2. Click 'Run Evaluation & Submit All Answers' to fetch questions, run the agent, and submit answers.
|
| 353 |
---
|
| 354 |
-
**Note:** This is a setup for the Final Assignment Template. Agent uses
|
| 355 |
"""
|
| 356 |
)
|
| 357 |
|
|
|
|
| 14 |
FILES_URL = "https://agents-course-unit4-scoring.hf.space/files"
|
| 15 |
FILES_DIR = "files"
|
| 16 |
SYSTEM_PROMPT = "You are a helpful AI assistant tasked with answering questions accurately. Provide concise and accurate answers in the format requested by the question."
|
| 17 |
+
GEMINI_API_KEY = "AIzaSyBvImpFo9o5Dz8OL_mfFEoRijeUyYBvXiI"
|
| 18 |
+
GEMINI_API_URL = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={GEMINI_API_KEY}"
|
| 19 |
|
| 20 |
# --- AssistantAgent Implementation ---
|
| 21 |
class AssistantAgent:
|
| 22 |
def __init__(self, system_prompt: str):
|
| 23 |
self.system_prompt = system_prompt
|
| 24 |
+
self.headers = {"Content-Type": "application/json"}
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
+
def call_gemini_api(self, prompt: str) -> str:
|
| 27 |
+
retry_delay = 60 # Chờ 60 giây nếu gặp lỗi quota
|
| 28 |
payload = {
|
| 29 |
+
"contents": [{
|
| 30 |
+
"parts": [{"text": prompt}]
|
| 31 |
+
}]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
}
|
| 33 |
+
for attempt in range(3):
|
| 34 |
+
try:
|
| 35 |
+
response = requests.post(GEMINI_API_URL, headers=self.headers, json=payload, timeout=10)
|
| 36 |
+
response.raise_for_status()
|
| 37 |
+
return response.json()["candidates"][0]["content"]["parts"][0]["text"].strip()
|
| 38 |
+
except requests.exceptions.RequestException as e:
|
| 39 |
+
if "429" in str(e):
|
| 40 |
+
retry_delay = max(retry_delay, 60)
|
| 41 |
+
print(f"Quota error, retrying after {retry_delay} seconds... (Attempt {attempt + 1}/3)")
|
| 42 |
+
time.sleep(retry_delay)
|
| 43 |
+
retry_delay += 10
|
| 44 |
+
else:
|
| 45 |
+
return f"Error calling Gemini API: {e}"
|
| 46 |
+
return "Error: Exceeded retry attempts due to quota limits."
|
| 47 |
|
| 48 |
def check_commutative(self, table: str) -> str:
|
| 49 |
try:
|
|
|
|
| 50 |
rows = table.strip().split('\n')
|
| 51 |
+
if len(rows) < 3:
|
| 52 |
return "Error: Table format is invalid (not enough rows)."
|
| 53 |
|
|
|
|
| 54 |
header = rows[0].split('|')
|
| 55 |
+
if len(header) < 3:
|
| 56 |
return "Error: Table format is invalid (header too short)."
|
| 57 |
|
| 58 |
+
elements = header[1:-1][1:]
|
| 59 |
num_elements = len(elements)
|
| 60 |
if num_elements < 1:
|
| 61 |
return "Error: No elements found in table header."
|
| 62 |
|
|
|
|
| 63 |
if len(rows) != num_elements + 2:
|
| 64 |
return f"Error: Table row count ({len(rows)}) does not match expected ({num_elements + 2})."
|
| 65 |
|
|
|
|
| 66 |
if not rows[1].startswith('|---'):
|
| 67 |
return "Error: Table format is invalid (missing separator row)."
|
| 68 |
|
|
|
|
| 69 |
operation = {}
|
| 70 |
for i in range(2, len(rows)):
|
| 71 |
cols = rows[i].split('|')
|
| 72 |
+
if len(cols) != num_elements + 2:
|
| 73 |
return f"Error: Row {i} has incorrect number of columns (expected {num_elements + 2}, got {len(cols)})."
|
| 74 |
|
| 75 |
for j in range(1, len(cols) - 1):
|
|
|
|
| 78 |
return f"Error: Invalid value '{val}' in table (not in {elements})."
|
| 79 |
operation[(elements[i - 2], elements[j - 1])] = val
|
| 80 |
|
|
|
|
| 81 |
non_commutative = set()
|
| 82 |
for a in elements:
|
| 83 |
for b in elements:
|
|
|
|
| 117 |
answers = []
|
| 118 |
for i in range(0, len(questions), batch_size):
|
| 119 |
batch = questions[i:i + batch_size]
|
| 120 |
+
prompt = f"{self.system_prompt}\nAnswer the following questions concisely:\n"
|
| 121 |
for idx, (question, _) in enumerate(batch, 1):
|
| 122 |
prompt += f"{idx}. {question}\n"
|
| 123 |
|
| 124 |
+
batch_answers = self.call_gemini_api(prompt)
|
| 125 |
if "Error" in batch_answers:
|
| 126 |
answers.extend([batch_answers] * len(batch))
|
| 127 |
else:
|
|
|
|
| 130 |
answer = batch_answers[idx].split('. ', 1)[1] if idx < len(batch_answers) and '. ' in batch_answers[idx] else "Error: Could not parse answer."
|
| 131 |
answers.append(answer)
|
| 132 |
if i + batch_size < len(questions):
|
| 133 |
+
print("Waiting 60 seconds before next batch to avoid rate limit...")
|
| 134 |
+
time.sleep(60)
|
| 135 |
return answers
|
| 136 |
|
| 137 |
def process_file(self, question: str, file_path: str) -> str:
|
|
|
|
| 171 |
except Exception as e:
|
| 172 |
return f"Error reading Excel file: {e}"
|
| 173 |
else:
|
| 174 |
+
return "Error: Gemini API does not support non-text files (e.g., images). Please provide a text description instead."
|
| 175 |
|
| 176 |
def __call__(self, question: str, file_path: str = None) -> str:
|
| 177 |
if "provide the subset of S involved in any possible counter-examples" in question:
|
|
|
|
| 347 |
1. Log in to your Hugging Face account using the button below.
|
| 348 |
2. Click 'Run Evaluation & Submit All Answers' to fetch questions, run the agent, and submit answers.
|
| 349 |
---
|
| 350 |
+
**Note:** This is a setup for the Final Assignment Template. Agent uses Gemini API (gemini-2.0-flash) with optimized batch processing.
|
| 351 |
"""
|
| 352 |
)
|
| 353 |
|