File size: 7,704 Bytes
10e9b7d 79a6984 eccf8e4 c1074ea b6cd9a2 3ab99c9 12850a5 0e1fcc9 b6cd9a2 023211e 12850a5 b6cd9a2 b02d70e b6cd9a2 84944af 023211e 5ca79a2 023211e 5ca79a2 023211e 5ca79a2 49436c1 023211e 49436c1 023211e 0c05b5e d27baf3 62ebd37 5ca79a2 62ebd37 5ca79a2 62ebd37 5ca79a2 d27baf3 023211e d27baf3 62ebd37 1a70103 b6cd9a2 b02d70e b6cd9a2 9e89eb7 023211e 81c9217 023211e 81c9217 fa3e9dc 81c9217 b02d70e 81c9217 b02d70e 9e89eb7 31243f4 1af702d b6cd9a2 023211e 1af702d 67bae22 1af702d b6cd9a2 023211e b02d70e 023211e 67bae22 394713d b6cd9a2 40795a7 fa3e9dc 9f04c9f 62c58dd fa3e9dc 79a6984 fa3e9dc 79a6984 dbdcf6f 023211e dbdcf6f 023211e dbdcf6f fa3e9dc 79a6984 023211e fa3e9dc 79a6984 9f04c9f b6cd9a2 b02d70e b6cd9a2 3c4371f b6cd9a2 0f7618e b6cd9a2 0f7618e b6cd9a2 0f7618e b6cd9a2 0f7618e 5ca79a2 b6cd9a2 5ca79a2 b6cd9a2 0f7618e b6cd9a2 31243f4 b6cd9a2 0f7618e b6cd9a2 5ca79a2 b6cd9a2 81c9217 b6cd9a2 0f7618e b6cd9a2 0f7618e b6cd9a2 0f7618e b6cd9a2 b02d70e b6cd9a2 e80aab9 31243f4 0f7618e b6cd9a2 0f7618e 7e4a06b b668b47 0f7618e b6cd9a2 e80aab9 81c9217 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | import os
import re
import requests
import pandas as pd
import yaml
import gradio as gr
from datetime import datetime
from typing import Optional
import pytz
import wikipedia
from smolagents import CodeAgent, HfApiModel, tool
from tools.final_answer import FinalAnswerTool
from tools.web_search import DuckDuckGoSearchTool
from tools.visit_webpage import VisitWebpageTool
# -----------------------------------------------------------------------------
# 1) IMPORT YOUR NEW TOOLS
# -----------------------------------------------------------------------------
from tools.search_tools import simple_search, archive_search
from tools.page_navigation_tools import (
find_on_page_ctrl_f,
find_next,
page_down,
page_up,
)
# -----------------------------------------------------------------------------
# 2) YOUR CUSTOM TOOLS (with proper docstrings for Args)
# -----------------------------------------------------------------------------
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""
Fetches the current local time in a specified timezone.
Args:
timezone: A string representing a valid timezone (e.g., 'America/New_York').
"""
try:
tz = pytz.timezone(timezone)
now = datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return f"The current local time in {timezone} is: {now}"
except Exception as e:
return f"Error fetching time for timezone '{timezone}': {e}"
@tool
def wiki(query: str) -> str:
"""
Searches Wikipedia for a query and returns the page content (English).
Args:
query: The Wikipedia page title or search term.
"""
try:
wikipedia.set_lang("en")
page = wikipedia.page(query, auto_suggest=False)
return page.content
except Exception as e:
return f"Error fetching Wikipedia page for '{query}': {e}"
# -----------------------------------------------------------------------------
# 3) LOAD PROMPTS & RAG MAP
# -----------------------------------------------------------------------------
with open("prompts.yaml", "r") as f:
prompt_templates = yaml.safe_load(f)
# top-level key in prompts.yaml must now be `rag_fallbacks:`
rag_fallbacks = prompt_templates.get("rag_fallbacks", {})
@tool
def rag_fallback(question: str) -> str:
"""
Returns a pre‐cached answer if the question matches any RAG key.
Args:
question: The user’s question.
"""
q_low = question.lower()
for key, val in rag_fallbacks.items():
tokens = re.findall(r"\w+", key.lower())
tokens = [t for t in tokens if len(t) > 2]
if tokens and all(tok in q_low for tok in tokens):
return val
return ""
# -----------------------------------------------------------------------------
# 4) INSTANTIATE TOOLS & AGENT
# -----------------------------------------------------------------------------
final_answer = FinalAnswerTool()
web_search = DuckDuckGoSearchTool()
visit_webpage = VisitWebpageTool()
class BasicAgent:
def __init__(self):
model = HfApiModel(
model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
max_tokens=2096,
temperature=0.2, # more conservative
)
self.agent = CodeAgent(
model=model,
tools=[
final_answer,
web_search,
visit_webpage,
# our new tools:
simple_search,
archive_search,
find_on_page_ctrl_f,
find_next,
page_down,
page_up,
# legacy tools:
wiki,
get_current_time_in_timezone,
rag_fallback,
],
max_steps=10, # allow enough steps to chain browse → navigate
verbosity_level=1,
name="Son_of_Anton",
description="Your friendly AI agent to help you with any task",
prompt_templates=prompt_templates,
)
self.rag_fallbacks = rag_fallbacks
def __call__(self, question: str) -> str:
try:
raw_ans = self.agent.run(question)
except Exception:
raw_ans = ""
ans_str = str(raw_ans).strip().lower()
# manual fallback if nothing useful came out
if (
not ans_str
or ans_str.startswith("i'm sorry")
or "unanswered" in ans_str
or "none" in ans_str
or "error" in ans_str
):
for key, val in self.rag_fallbacks.items():
tokens = re.findall(r"\w+", key.lower())
tokens = [t for t in tokens if len(t) > 2]
if tokens and all(tok in question.lower() for tok in tokens):
return val
return raw_ans
# -----------------------------------------------------------------------------
# 5) EVALUATION LOGIC (unchanged)
# -----------------------------------------------------------------------------
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
def run_and_submit_all(profile: Optional[gr.OAuthProfile]):
if profile is None:
return "Please log in with Hugging Face to submit.", None
space_id = os.getenv("SPACE_ID")
questions_url = f"{DEFAULT_API_URL}/questions"
submit_url = f"{DEFAULT_API_URL}/submit"
try:
r = requests.get(questions_url, timeout=15)
r.raise_for_status()
questions = r.json()
except Exception as e:
return f"Error fetching questions: {e}", None
if not questions:
return "No questions returned.", None
agent = BasicAgent()
logs = []
answers = []
for item in questions:
tid = item.get("task_id")
q = item.get("question")
if not tid or not q:
continue
ans = agent(q)
logs.append({"Task ID": tid, "Question": q, "Answer": ans})
answers.append({"task_id": tid, "submitted_answer": ans})
if not answers:
return "Agent produced no answers.", pd.DataFrame(logs)
try:
payload = {
"username": profile.username,
"agent_code": f"https://huggingface.co/spaces/{space_id}/tree/main",
"answers": answers,
}
r2 = requests.post(submit_url, json=payload, timeout=60)
r2.raise_for_status()
res = r2.json()
status = (
f"✔ Submission Successful!\n"
f"User: {res.get('username')}\n"
f"Score: {res.get('score')}% "
f"({res.get('correct_count')}/"
f"{res.get('total_attempted')})\n"
f"{res.get('message','')}"
)
return status, pd.DataFrame(logs)
except Exception as e:
return f"Submission Failed: {e}", pd.DataFrame(logs)
# -----------------------------------------------------------------------------
# 6) GRADIO EVALUATION UI (unchanged)
# -----------------------------------------------------------------------------
with gr.Blocks() as demo:
gr.Markdown("# Basic Agent Evaluation Runner")
gr.Markdown("""
**Instructions**
1. Log in with your Hugging Face account.
2. Click “Run Evaluation & Submit All Answers” below.
""")
gr.LoginButton()
btn = gr.Button("Run Evaluation & Submit All Answers")
out_s = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
out_df= gr.DataFrame(label="Questions and Agent Answers", wrap=True)
btn.click(run_and_submit_all, [], [out_s, out_df])
if __name__ == "__main__":
demo.launch(debug=True, share=False)
|