kpalatel's picture
Update agent.py
9c753c0 verified
Raw
History Blame Contribute Delete
4.17 kB
import os
import re
import smolagents
from smolagents import CodeAgent, DuckDuckGoSearchTool, tool
@tool
def calculate_math(expression: str) -> str:
"""Useful for evaluating math expressions or numerical problems safely.
Args:
expression: A valid mathematical string to evaluate, like '2 + 2' or '312 * 43'.
"""
try:
allowed_chars = "0123456789+-*/(). "
cleaned = "".join(c for c in expression if c in allowed_chars)
if cleaned:
return str(eval(cleaned))
return "Error: Invalid characters in math expression."
except Exception as e:
return f"Error executing calculation: {str(e)}"
class CourseEvaluationAgent:
def __init__(self):
print("[Agent System] Initializing Adaptive Bootstrapper...")
hf_token = os.getenv("HF_TOKEN")
model_name = "Qwen/Qwen2.5-Coder-32B-Instruct"
# --- DYNAMIC CLASS DETECTION ---
# We check the library metadata directly to find the right class
self.model = None
for class_name in ["InferenceClientModel", "HfApiModel", "HfApiEngine", "LiteLLMModel"]:
if hasattr(smolagents, class_name):
try:
TargetClass = getattr(smolagents, class_name)
print(f"[Agent System] Trying class: {class_name}")
# Try instantiating with keyword parameters
if class_name == "HfApiEngine":
self.model = TargetClass(model_id=model_name, token=hf_token)
else:
self.model = TargetClass(model_id=model_name, token=hf_token)
print(f"[Agent System] Successfully bound engine via {class_name}!")
break
except Exception as inner_e:
print(f"[Agent System] {class_name} failed setup: {inner_e}")
continue
# Ultimate fallback: If classes fail, see if ApiModel works directly
if self.model is None and hasattr(smolagents, "ApiModel"):
try:
self.model = getattr(smolagents, "ApiModel")(model_id=model_name, token=hf_token)
print("[Agent System] Bound engine via base ApiModel fallback.")
except Exception:
pass
# If everything failed, we let CodeAgent try raw string fallback
if self.model is None:
print("[Agent System] Warning: Forcing direct string fallback mode.")
self.model = model_name
# --- BUILD CODE AGENT ---
# Safely pass our resolved backend configuration to the agent
self.agent = CodeAgent(
tools=[DuckDuckGoSearchTool(), calculate_math],
model=self.model,
max_steps=5,
verbosity_level=1
)
# Inject styling rules cleanly
if "system_prompt" in self.agent.prompt_templates:
self.agent.prompt_templates["system_prompt"] += (
"\n\nCRITICAL SYSTEM RULE:\n"
"Your final response after using tools MUST contain ONLY the direct, raw answer text "
"(e.g., '42', 'Paris', 'John Doe'). Absolutely DO NOT include conversational padding like "
"'The answer is' or summary sentences. Output just the clean answer string."
)
def run_task(self, question: str) -> str:
try:
output = self.agent.run(question)
final_ans = str(output).strip()
# Post-processing to strip out accidental conversational wrappers
clean_patterns = [
r"^[Tt]he answer is\s*[:\-]?\s*",
r"^[Ff]inal [Aa]nswer\s*[:\-]?\s*",
r"^[\"']",
r"[\"']$"
]
for pattern in clean_patterns:
final_ans = re.sub(pattern, "", final_ans)
return final_ans.strip()
except Exception as e:
print(f"[CRITICAL AGENT EXCEPTION]: {str(e)}")
return f"Runtime error: {str(e)[:50]}"