VoicesColeby's picture
Initial upload: app.py
f825de5 verified
Raw
History Blame Contribute Delete
4.16 kB
"""
HF Agents Course — Unit 1 first agent.
A smolagents CodeAgent named *Alfred* with a non-trivial toolkit:
- DuckDuckGo web search (smolagents default tool)
- Visit + read a webpage (smolagents default tool)
- get_current_time_in_timezone — timezone-aware clock
- convert_currency — FX conversion via the (open) exchangerate.host API
- final_answer — terminal tool that closes the loop
The agent uses `InferenceClientModel` (HF Inference Providers) so the only
secret you need on the Space is HF_TOKEN.
Deployment:
1. Set Space secret `HF_TOKEN` (a token with inference permission).
2. Push `app.py`, `requirements.txt`, and `prompts.yaml`.
3. The Gradio UI is launched by `GradioUI(agent).launch()`.
"""
from __future__ import annotations
import datetime
import os
import pytz
import requests
import yaml
from smolagents import (
CodeAgent,
DuckDuckGoSearchTool,
GradioUI,
InferenceClientModel,
VisitWebpageTool,
tool,
)
from smolagents.default_tools import FinalAnswerTool
# ----- Tools ----------------------------------------------------------------
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""Return the current local time for an IANA timezone.
Args:
timezone: An IANA timezone name, e.g. 'America/New_York', 'Asia/Tokyo',
'Europe/London', 'UTC'.
"""
try:
tz = pytz.timezone(timezone)
except pytz.UnknownTimeZoneError:
return (
f"Unknown timezone '{timezone}'. Use an IANA name "
"(e.g. 'America/New_York', 'Asia/Tokyo', 'UTC')."
)
now = datetime.datetime.now(tz)
return now.strftime("%Y-%m-%d %H:%M:%S %Z (UTC%z)")
@tool
def convert_currency(amount: float, source: str, target: str) -> str:
"""Convert `amount` from currency `source` to currency `target` using
a live FX rate from the open exchangerate.host API.
Args:
amount: Numeric amount in the source currency.
source: 3-letter ISO currency code, e.g. 'USD'.
target: 3-letter ISO currency code, e.g. 'EUR'.
Returns:
Human-readable conversion string, e.g. "100 USD = 92.35 EUR @ 0.9235".
"""
src, tgt = source.upper(), target.upper()
try:
r = requests.get(
"https://api.exchangerate.host/convert",
params={"from": src, "to": tgt, "amount": amount},
timeout=10,
)
r.raise_for_status()
data = r.json()
except Exception as exc: # noqa: BLE001
return f"FX lookup failed: {exc}"
if not data.get("success", True) or "result" not in data:
return f"FX lookup returned no result for {src}->{tgt}: {data}"
rate = data.get("info", {}).get("rate")
result = data["result"]
rate_str = f" @ {rate:.4f}" if rate else ""
return f"{amount} {src} = {result:.2f} {tgt}{rate_str}"
# ----- Model + Prompts ------------------------------------------------------
MODEL_ID = os.environ.get("AGENT_MODEL_ID", "Qwen/Qwen2.5-Coder-32B-Instruct")
model = InferenceClientModel(
max_tokens=2096,
temperature=0.5,
model_id=MODEL_ID,
custom_role_conversions=None,
)
# Optional: prompts.yaml override. If absent we use smolagents' built-in defaults.
prompt_templates = None
prompts_path = os.path.join(os.path.dirname(__file__), "prompts.yaml")
if os.path.exists(prompts_path):
with open(prompts_path, "r", encoding="utf-8") as fh:
prompt_templates = yaml.safe_load(fh)
# ----- Agent ----------------------------------------------------------------
final_answer = FinalAnswerTool()
agent = CodeAgent(
model=model,
tools=[
DuckDuckGoSearchTool(),
VisitWebpageTool(),
get_current_time_in_timezone,
convert_currency,
final_answer,
],
max_steps=6,
verbosity_level=1,
prompt_templates=prompt_templates,
name="Alfred",
description=(
"Alfred is a butler agent who can search the web, read webpages, "
"tell you the current time in any timezone, and convert currencies."
),
)
if __name__ == "__main__":
GradioUI(agent).launch()