darrenphodgson76's picture
Update app.py
2ce2d7e verified
raw
history blame
4.99 kB
import os
import openai # ← official OpenAI client
from openai import OpenAI
import gradio as gr
import requests
import pandas as pd
from smolagents import DuckDuckGoSearchTool, tool
# --- Constants ---
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
# --- Configure OpenAI SDK & Client ---
openai_api_key = os.getenv("OPENAI_API_KEY")
if not openai_api_key:
raise RuntimeError("Set OPENAI_API_KEY in your Space secrets or env!")
openai.api_key = openai_api_key
client = OpenAI() # new client object
# --- Tool Definitions ---
@tool
def summarize_query(query: str) -> str:
"""
Provides a structured summary to reframe a query if search results are unclear or poor.
Args:
query (str): The search query that needs summarization.
Returns:
str: A concise summary of key facts about the given query.
"""
return f"Summarize and reframe: {query}"
search_tool = DuckDuckGoSearchTool()
# --- ReACT + Scratchpad + Auto‐Retry Instruction Prompt ---
instruction_prompt = """
You are a high-precision AI agent. Internally, you may follow the ReACT pattern—thinking step-by-step, invoking tools, observing results, retrying if needed—but you must NOT show any of that. Instead, after you finish reasoning privately, output **exactly** one line:
FINAL ANSWER: [your concise answer]
Rules for the final answer:
- If it’s a number, output only the digits (no commas, units, or extra text).
- If it’s a list, output a comma-separated list with no extra punctuation or articles.
- If it’s a string, output only the words, no “um,” “the,” or other fillers.
"""
# --- BasicAgent using the new OpenAI client ---
class BasicAgent:
def __init__(self):
print("SmolAgent (GPT-4.1) with ReACT, Scratchpad & Retry initialized.")
def __call__(self, question: str) -> str:
# Build the full prompt
prompt = instruction_prompt.strip() + "\n\nQUESTION: " + question.strip()
print(f"Agent prompt (first 150 chars): {prompt[:150]}…")
# Call GPT-4.1 via the new client.responses.create API
try:
response = client.responses.create(
model="gpt-4.1",
input=prompt
)
return response.output_text
except Exception as e:
return f"AGENT ERROR: {e}"
# --- Gradio / HF‐Spaces submission logic ---
def run_and_submit_all(profile: gr.OAuthProfile | None):
if not profile:
return "Please log in to Hugging Face using the login button above.", None
username = profile.username
space_id = os.getenv("SPACE_ID", "")
agent = BasicAgent()
agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
# 1. Fetch questions
try:
resp = requests.get(f"{DEFAULT_API_URL}/questions", timeout=15)
resp.raise_for_status()
questions = resp.json() or []
except Exception as e:
return f"Error fetching questions: {e}", None
# 2. Run agent on each question
logs, payload = [], []
for item in questions:
tid = item.get("task_id")
q = item.get("question")
if not tid or q is None:
continue
ans = agent(q)
logs.append({"Task ID": tid, "Question": q, "Submitted Answer": ans})
payload.append({"task_id": tid, "submitted_answer": ans})
if not payload:
return "Agent did not produce any answers.", pd.DataFrame(logs)
# 3. Submit answers
submission = {"username": username, "agent_code": agent_code, "answers": payload}
try:
post = requests.post(f"{DEFAULT_API_URL}/submit", json=submission, timeout=60)
post.raise_for_status()
res = post.json()
status = (
f"Submission Successful!\n"
f"User: {res.get('username')}\n"
f"Overall Score: {res.get('score', 'N/A')}% "
f"({res.get('correct_count', '?')}/{res.get('total_attempted', '?')})\n"
f"Message: {res.get('message', '')}"
)
return status, pd.DataFrame(logs)
except Exception as e:
return f"Submission Failed: {e}", pd.DataFrame(logs)
# --- Gradio Interface ---
with gr.Blocks() as demo:
gr.Markdown("# SmolAgent GAIA Runner (GPT-4.1) 🚀")
gr.Markdown(
"""
**Instructions:**
1. Clone this space.
2. In Settings → Secrets add `OPENAI_API_KEY`.
3. Log in to Hugging Face.
4. Click **Run Evaluation & Submit All Answers**.
**Note:** Evaluation may take several minutes.
"""
)
gr.LoginButton()
run_btn = gr.Button("Run Evaluation & Submit All Answers")
status_out = gr.Textbox(label="Status", lines=5, interactive=False)
table_out = gr.DataFrame(label="Questions & Answers", wrap=True)
run_btn.click(fn=run_and_submit_all, outputs=[status_out, table_out])
if __name__ == "__main__":
demo.launch(debug=True, share=False)