wowpixels's picture
Update app.py
6a034fc verified
Raw
History Blame Contribute Delete
7.79 kB
import os
import json
import socket
import requests
import gradio as gr
from huggingface_hub import login
from smolagents import CodeAgent, InferenceClientModel, DuckDuckGoSearchTool, VisitWebpageTool
# Auth
hf_token = os.getenv("HF_TOKEN")
if hf_token:
login(token=hf_token)
print("HF login OK")
else:
print("No HF_TOKEN set")
# Model
MODEL_ID = "Qwen/Qwen2.5-7B-Instruct"
def build_agent(enable_tools: bool):
model = InferenceClientModel(model_id=MODEL_ID, token=hf_token)
tools = [DuckDuckGoSearchTool(), VisitWebpageTool()] if enable_tools else []
return CodeAgent(tools=tools, model=model, max_steps=8)
# Perfume data and logic
CATALOG = [
{"name": "Dior Sauvage EDT", "notes": ["bergamot", "ambroxan", "pepper"], "season": ["spring", "summer"], "style": "fresh", "price": 95, "gender": "masculine"},
{"name": "Chanel Bleu de Chanel EDP", "notes": ["citrus", "incense", "cedar"], "season": ["all"], "style": "fresh-woody", "price": 120, "gender": "masculine"},
{"name": "Creed Aventus", "notes": ["pineapple", "birch", "musk"], "season": ["spring", "summer", "fall"], "style": "fruity-woody", "price": 365, "gender": "masculine"},
{"name": "Maison Francis Kurkdjian Baccarat Rouge 540", "notes": ["saffron", "ambergris", "cedar"], "season": ["fall", "winter"], "style": "ambery", "price": 325, "gender": "unisex"},
{"name": "Le Labo Santal 33", "notes": ["sandalwood", "leather", "violet"], "season": ["fall", "winter", "spring"], "style": "woody", "price": 220, "gender": "unisex"},
{"name": "Tom Ford Black Orchid", "notes": ["truffle", "patchouli", "chocolate"], "season": ["fall", "winter", "night"], "style": "gourmand", "price": 160, "gender": "unisex"},
{"name": "Byredo Gypsy Water", "notes": ["juniper", "lemon", "vanilla"], "season": ["spring", "summer"], "style": "fresh-woody", "price": 205, "gender": "unisex"},
{"name": "Chanel Chance Eau Tendre", "notes": ["grapefruit", "jasmine", "musk"], "season": ["spring", "summer"], "style": "fresh-floral", "price": 120, "gender": "feminine"},
{"name": "YSL Libre EDP", "notes": ["lavender", "orange blossom", "vanilla"], "season": ["fall", "winter"], "style": "floral-amber", "price": 130, "gender": "feminine"},
{"name": "Jo Malone Wood Sage & Sea Salt", "notes": ["sage", "ambrette", "sea salt"], "season": ["summer", "spring"], "style": "fresh-aromatic", "price": 165, "gender": "unisex"},
]
def shortlist_catalog(preferred_notes, season, budget, gender_pref):
notes = [n.strip().lower() for n in preferred_notes.split(",") if n.strip()] if preferred_notes else []
season = (season or "all").lower()
gender_pref = (gender_pref or "unisex").lower()
max_price = float(budget) if budget else 9999.0
def score(item):
s = 0
if season in item["season"] or "all" in item["season"]:
s += 1
if gender_pref in ["any", "unisex"] or gender_pref == item["gender"]:
s += 1
s += sum(1 for n in notes if n in item["notes"])
if item["price"] <= max_price:
s += 1
return s
ranked = sorted(CATALOG, key=score, reverse=True)
top = [p for p in ranked if score(p) > 0][:5]
return top or ranked[:3]
def recommend_perfumes(preferred_notes, season, occasion, budget, gender_pref, use_web_tools):
agent = build_agent(enable_tools=use_web_tools)
shortlist = shortlist_catalog(preferred_notes, season, budget, gender_pref)
prompt = (
"Recommend three perfumes, ranked 1 to 3.\n"
f"Preferred notes: {preferred_notes or 'not specified'}\n"
f"Season: {season or 'any'}\n"
f"Occasion: {occasion or 'any'}\n"
f"Budget cap (USD): {budget or 'no cap'}\n"
f"Gender preference: {gender_pref or 'any'}\n\n"
"Candidates you can consider:\n"
f"{json.dumps(shortlist, indent=2)}\n\n"
"Return a short list with brand and perfume name, brief notes and vibe, why it fits, and approx price or where to sample. Keep it under 120 words."
)
try:
return str(agent.run(prompt))
except Exception as e:
lines = [f"{i+1}. {p['name']} — ${p['price']}{', '.join(p['notes'])}" for i, p in enumerate(shortlist[:3])]
return "Local shortlist:\n" + "\n".join(lines) + f"\nError: {e}"
# GAIA test
GAIA_BASE = "https://agents-course-unit4-scoring.hf.space"
def fetch_random_question():
r = requests.get(f"{GAIA_BASE}/random-question", timeout=15)
r.raise_for_status()
return r.json()
def _check_match(agent_answer, expected_answer):
a = str(agent_answer).strip().lower()
e = str(expected_answer).strip().lower()
if a == e:
return "Exact match"
if e and e in a:
return "Partial match"
return "No match"
def run_agent_on_gaia():
try:
q = fetch_random_question()
except Exception as e:
return f"Error fetching GAIA question: {e}"
question_text = q.get("question") or ""
expected_answer = q.get("final_answer") or ""
try:
agent = build_agent(enable_tools=True)
agent_answer = str(agent.run(question_text))
except Exception as e:
agent_answer = f"Error running agent: {e}"
return (
"### Question\n"
f"{question_text}\n\n"
"### Agent answer\n"
f"{agent_answer}\n\n"
"### Expected answer\n"
f"{expected_answer}\n\n"
"### Match\n"
f"{_check_match(agent_answer, expected_answer)}"
)
# Diagnostics
def net_diagnostics():
results = {}
hosts = {
"gaia": "agents-course-unit4-scoring.hf.space",
"huggingface": "huggingface.co",
"google": "www.google.com",
}
for name, host in hosts.items():
try:
ip = socket.gethostbyname(host)
results[f"dns_{name}"] = f"OK {host} -> {ip}"
except Exception as e:
results[f"dns_{name}"] = f"FAIL {host} -> {e}"
urls = {
"gaia_random_question": f"{GAIA_BASE}/random-question",
"hf_home": "https://huggingface.co",
}
for key, url in urls.items():
try:
r = requests.get(url, timeout=10)
results[f"http_{key}"] = f"{r.status_code} {len(r.content)} bytes"
except Exception as e:
results[f"http_{key}"] = f"FAIL {e}"
return "```\n" + json.dumps(results, indent=2) + "\n```"
# UI
with gr.Blocks(title="Perfume Recommender and GAIA Test") as demo:
with gr.Tab("Perfume"):
with gr.Row():
with gr.Column():
notes = gr.Textbox(label="Preferred notes (comma separated)")
season = gr.Dropdown(label="Season", choices=["any","spring","summer","fall","winter","night"], value="any")
occasion = gr.Dropdown(label="Occasion", choices=["any","work","date","party","gym","formal"], value="any")
budget = gr.Textbox(label="Budget cap in USD")
gender = gr.Dropdown(label="Gender preference", choices=["any","masculine","feminine","unisex"], value="any")
use_tools = gr.Checkbox(label="Use web tools", value=False)
go = gr.Button("Recommend")
with gr.Column():
rec_out = gr.Markdown()
go.click(recommend_perfumes, [notes, season, occasion, budget, gender, use_tools], [rec_out], show_progress="full")
with gr.Tab("GAIA"):
gaia_btn = gr.Button("Get random question and answer")
gaia_out = gr.Markdown()
gaia_btn.click(run_agent_on_gaia, None, [gaia_out], show_progress="full")
with gr.Tab("Diagnostics"):
diag_btn = gr.Button("Network diagnostics")
diag_out = gr.Markdown()
diag_btn.click(net_diagnostics, None, [diag_out], show_progress="minimal")
demo.queue().launch()