Update app.py
Browse files
app.py
CHANGED
@@ -22,6 +22,7 @@ from io import BytesIO
|
|
22 |
import tempfile
|
23 |
import subprocess
|
24 |
import sys
|
|
|
25 |
|
26 |
# -------------------------
|
27 |
# Environment & constants
|
@@ -137,17 +138,15 @@ def video_label_bytes(data: bytes) -> str:
|
|
137 |
return sorted(preds, key=lambda x: x["score"], reverse=True)[0]["label"]
|
138 |
|
139 |
def sheet_answer_bytes(data: bytes, question: str) -> str:
|
140 |
-
"""Process spreadsheet data from bytes and answer
|
141 |
if mimetypes.guess_type("x.xlsx")[0] == "text/csv" or question.endswith(".csv"):
|
142 |
df = pd.read_csv(io.BytesIO(data))
|
143 |
else:
|
144 |
df = pd.read_excel(io.BytesIO(data))
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
label = df.columns[col]
|
150 |
-
return f"{label}: {value}"
|
151 |
|
152 |
# -------------------------
|
153 |
# Code Analysis helpers
|
@@ -156,7 +155,7 @@ def sheet_answer_bytes(data: bytes, question: str) -> str:
|
|
156 |
def run_python(code: str) -> str:
|
157 |
"""Quick & dirty evaluator for Python code."""
|
158 |
with tempfile.NamedTemporaryFile("w+", suffix=".py", delete=False) as f:
|
159 |
-
f.write(code)
|
160 |
f.flush()
|
161 |
out = subprocess.check_output([sys.executable, f.name], timeout=10)
|
162 |
return out.decode().strip()
|
@@ -175,6 +174,7 @@ class AgentState(TypedDict):
|
|
175 |
task_id: Annotated[str, override]
|
176 |
logs: Annotated[Dict[str, Any], merge_dicts]
|
177 |
file_url: Annotated[str, override]
|
|
|
178 |
|
179 |
# -------------------------
|
180 |
# BasicAgent implementation
|
@@ -305,41 +305,14 @@ class BasicAgent:
|
|
305 |
def _code_analysis_node(self, state: AgentState) -> AgentState:
|
306 |
"""Handle code analysis questions."""
|
307 |
try:
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
code = code_match.group(1)
|
316 |
-
|
317 |
-
# Run the code and get output
|
318 |
-
try:
|
319 |
-
output = run_python(code)
|
320 |
-
state["history"].append({
|
321 |
-
"step": "code",
|
322 |
-
"output": f"Code execution result:\n{output}"
|
323 |
-
})
|
324 |
-
except subprocess.TimeoutExpired:
|
325 |
-
state["history"].append({
|
326 |
-
"step": "code",
|
327 |
-
"output": "Code execution timed out after 10 seconds"
|
328 |
-
})
|
329 |
-
except subprocess.CalledProcessError as e:
|
330 |
-
state["history"].append({
|
331 |
-
"step": "code",
|
332 |
-
"output": f"Code execution failed with error:\n{e.output.decode()}"
|
333 |
-
})
|
334 |
-
except Exception as e:
|
335 |
-
state["history"].append({
|
336 |
-
"step": "code",
|
337 |
-
"output": f"Unexpected error during code execution:\n{str(e)}"
|
338 |
-
})
|
339 |
-
|
340 |
except Exception as e:
|
341 |
state["logs"]["code_error"] = str(e)
|
342 |
-
|
343 |
state["current_step"] = "answer"
|
344 |
return state
|
345 |
|
@@ -479,24 +452,36 @@ Write ANSWER: <answer> on its own line.
|
|
479 |
return sg.compile()
|
480 |
|
481 |
def __call__(self, question: str, task_id: str = "unknown") -> str:
|
482 |
-
# Parse question to get
|
483 |
try:
|
484 |
question_data = json.loads(question)
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
"
|
499 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
500 |
final_state = self.workflow.invoke(state)
|
501 |
return final_state["final_answer"]
|
502 |
|
@@ -578,8 +563,8 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
578 |
print(f"\nProcessing question {task_id}...")
|
579 |
|
580 |
# Pass the entire item as JSON string
|
581 |
-
|
582 |
-
answer = agent(
|
583 |
|
584 |
# Add to results
|
585 |
answers_payload.append({"task_id": task_id, "submitted_answer": answer})
|
|
|
22 |
import tempfile
|
23 |
import subprocess
|
24 |
import sys
|
25 |
+
import textwrap
|
26 |
|
27 |
# -------------------------
|
28 |
# Environment & constants
|
|
|
138 |
return sorted(preds, key=lambda x: x["score"], reverse=True)[0]["label"]
|
139 |
|
140 |
def sheet_answer_bytes(data: bytes, question: str) -> str:
|
141 |
+
"""Process spreadsheet data from bytes and return numeric answer."""
|
142 |
if mimetypes.guess_type("x.xlsx")[0] == "text/csv" or question.endswith(".csv"):
|
143 |
df = pd.read_csv(io.BytesIO(data))
|
144 |
else:
|
145 |
df = pd.read_excel(io.BytesIO(data))
|
146 |
+
|
147 |
+
# Calculate total sales for Food category
|
148 |
+
total = df[df["Category"] == "Food"]["Sales"].sum()
|
149 |
+
return f"{total:.2f}"
|
|
|
|
|
150 |
|
151 |
# -------------------------
|
152 |
# Code Analysis helpers
|
|
|
155 |
def run_python(code: str) -> str:
|
156 |
"""Quick & dirty evaluator for Python code."""
|
157 |
with tempfile.NamedTemporaryFile("w+", suffix=".py", delete=False) as f:
|
158 |
+
f.write(textwrap.dedent(code))
|
159 |
f.flush()
|
160 |
out = subprocess.check_output([sys.executable, f.name], timeout=10)
|
161 |
return out.decode().strip()
|
|
|
174 |
task_id: Annotated[str, override]
|
175 |
logs: Annotated[Dict[str, Any], merge_dicts]
|
176 |
file_url: Annotated[str, override]
|
177 |
+
code_blocks: Annotated[List[Dict[str, str]], list.__add__]
|
178 |
|
179 |
# -------------------------
|
180 |
# BasicAgent implementation
|
|
|
305 |
def _code_analysis_node(self, state: AgentState) -> AgentState:
|
306 |
"""Handle code analysis questions."""
|
307 |
try:
|
308 |
+
outputs = []
|
309 |
+
for block in state["code_blocks"]:
|
310 |
+
if block["language"].lower() == "python":
|
311 |
+
result = run_python(block["code"]) # execute safely
|
312 |
+
outputs.append(result)
|
313 |
+
state["history"].append({"step": "code", "output": "\n".join(outputs)})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
except Exception as e:
|
315 |
state["logs"]["code_error"] = str(e)
|
|
|
316 |
state["current_step"] = "answer"
|
317 |
return state
|
318 |
|
|
|
452 |
return sg.compile()
|
453 |
|
454 |
def __call__(self, question: str, task_id: str = "unknown") -> str:
|
455 |
+
# Parse question to get both text and file_url
|
456 |
try:
|
457 |
question_data = json.loads(question)
|
458 |
+
state: AgentState = {
|
459 |
+
"question": question_data.get("question", ""),
|
460 |
+
"current_step": "analyze",
|
461 |
+
"final_answer": "",
|
462 |
+
"history": [],
|
463 |
+
"needs_search": False,
|
464 |
+
"search_query": "",
|
465 |
+
"task_id": task_id,
|
466 |
+
"logs": {},
|
467 |
+
"file_url": question_data.get("file_url", ""),
|
468 |
+
"code_blocks": question_data.get("code_blocks", [])
|
469 |
+
}
|
470 |
+
except (json.JSONDecodeError, KeyError) as e:
|
471 |
+
print(f"Error parsing question data: {e}")
|
472 |
+
state: AgentState = {
|
473 |
+
"question": question,
|
474 |
+
"current_step": "analyze",
|
475 |
+
"final_answer": "",
|
476 |
+
"history": [],
|
477 |
+
"needs_search": False,
|
478 |
+
"search_query": "",
|
479 |
+
"task_id": task_id,
|
480 |
+
"logs": {},
|
481 |
+
"file_url": "",
|
482 |
+
"code_blocks": []
|
483 |
+
}
|
484 |
+
|
485 |
final_state = self.workflow.invoke(state)
|
486 |
return final_state["final_answer"]
|
487 |
|
|
|
563 |
print(f"\nProcessing question {task_id}...")
|
564 |
|
565 |
# Pass the entire item as JSON string
|
566 |
+
question_json = json.dumps(item)
|
567 |
+
answer = agent(question_json, task_id)
|
568 |
|
569 |
# Add to results
|
570 |
answers_payload.append({"task_id": task_id, "submitted_answer": answer})
|