Ark4u commited on
Commit
2acf84f
·
verified ·
1 Parent(s): 307aecf

Deploy ArkAssistant smolagent (Hugging Face Agents Course Unit 1)

Browse files
.agents/skills/deploy-space/SKILL.md CHANGED
@@ -24,7 +24,7 @@ Always run these verification steps prior to deployment:
24
  ```
25
 
26
  3. **Dependency Check**:
27
- Ensure all imported packages in `tools/` and `app.py` (e.g., `markdownify`, `smolagents`, `ddgs`, `litellm`) are declared in `requirements.txt`.
28
 
29
  4. **Ignore Patterns**:
30
  Verify that sensitive files (`.env`), cache folders (`__pycache__`, `.gradio`), and the virtual environment (`.venv`) are listed in `deploy_space.py`'s `ignore_patterns`.
 
24
  ```
25
 
26
  3. **Dependency Check**:
27
+ Ensure all imported packages in `tools/` and `app.py` (e.g., `markdownify`, `smolagents`, `ddgs`) are declared in `requirements.txt`.
28
 
29
  4. **Ignore Patterns**:
30
  Verify that sensitive files (`.env`), cache folders (`__pycache__`, `.gradio`), and the virtual environment (`.venv`) are listed in `deploy_space.py`'s `ignore_patterns`.
AGENTS.md CHANGED
@@ -28,7 +28,16 @@ This workspace contains the complete implementation for the **Hugging Face Agent
28
 
29
  ## Environment & Commands
30
 
31
- - **Local Virtual Environment**: `.venv/bin/python`
 
 
 
 
 
 
 
 
 
32
 
33
  - **Sanity Check All Tools (Fast, No LLM)**:
34
  ```bash
@@ -40,11 +49,6 @@ This workspace contains the complete implementation for the **Hugging Face Agent
40
  .venv/bin/python test_agent.py "What is the capital of Japan and what is the weather there?"
41
  ```
42
 
43
- - **Run CLI Agent Query with Local Ollama (Offline)**:
44
- ```bash
45
- USE_OLLAMA=true .venv/bin/python test_agent.py "What is the time in UTC?"
46
- ```
47
-
48
  - **Run Gradio Web UI Locally**:
49
  ```bash
50
  .venv/bin/python app.py
 
28
 
29
  ## Environment & Commands
30
 
31
+ Cloud inference only. `HF_TOKEN` and `MODEL_ID` are configured in `.env`;
32
+ local Ollama execution is intentionally disabled. Hugging Face Inference
33
+ Providers require available credits or a PRO plan; without them the API returns
34
+ HTTP 402 before the agent can start.
35
+
36
+ - **Create the project virtual environment**:
37
+ ```bash
38
+ uv venv .venv
39
+ uv pip install --python .venv/bin/python -r requirements.txt
40
+ ```
41
 
42
  - **Sanity Check All Tools (Fast, No LLM)**:
43
  ```bash
 
49
  .venv/bin/python test_agent.py "What is the capital of Japan and what is the weather there?"
50
  ```
51
 
 
 
 
 
 
52
  - **Run Gradio Web UI Locally**:
53
  ```bash
54
  .venv/bin/python app.py
app.py CHANGED
@@ -1,127 +1,61 @@
1
- import datetime
2
  import os
3
- from urllib.parse import quote
4
- import pytz
5
- import requests
6
  import yaml
7
  from dotenv import load_dotenv
 
8
 
9
- from smolagents import CodeAgent, DuckDuckGoSearchTool, load_tool, tool
10
  from tools.final_answer import FinalAnswerTool
 
 
 
11
  from tools.visit_webpage import VisitWebpageTool
12
- from Gradio_UI import GradioUI
13
 
14
  load_dotenv()
15
 
16
- # --- Custom Tools ---
17
-
18
- @tool
19
- def get_current_time_in_timezone(timezone: str) -> str:
20
- """A tool that fetches the current local time in a specified timezone.
21
- Args:
22
- timezone: A string representing a valid IANA timezone (e.g., 'America/New_York', 'Europe/Paris', 'Asia/Kolkata', 'UTC').
23
- """
24
- try:
25
- import datetime
26
- import pytz
27
- tz = pytz.timezone(timezone)
28
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
29
- return f"The current local time in {timezone} is: {local_time}"
30
- except Exception as e:
31
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
32
-
33
- @tool
34
- def get_weather(location: str) -> str:
35
- """Fetches the current live weather report and temperature for a given city or location.
36
- Args:
37
- location: The name of the city or location (e.g., 'Paris', 'Tokyo', 'San Francisco').
38
- """
39
- try:
40
- import requests
41
- from urllib.parse import quote
42
- encoded_loc = quote(location)
43
- url = f"https://wttr.in/{encoded_loc}?format=%C+%t+(feels+like+%f)+wind:+%w"
44
- headers = {"User-Agent": "HF-Agents-Course-ArkAssistant/1.0"}
45
- resp = requests.get(url, headers=headers, timeout=10)
46
- if resp.status_code == 200 and resp.text:
47
- return f"Weather for {location}: {resp.text.strip()}"
48
- return f"Could not retrieve weather for {location} (status code {resp.status_code})."
49
- except Exception as e:
50
- return f"Error fetching weather for '{location}': {str(e)}"
51
-
52
- @tool
53
- def search_wikipedia(query: str) -> str:
54
- """Fetches an encyclopedic summary of a topic from Wikipedia.
55
- Args:
56
- query: The subject or topic name to search on Wikipedia (e.g., 'Alan Turing', 'Artificial intelligence').
57
- """
58
- try:
59
- import requests
60
- from urllib.parse import quote
61
- encoded_query = quote(query)
62
- url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{encoded_query}"
63
- headers = {"User-Agent": "HF-Agents-Course-ArkAssistant/1.0"}
64
- resp = requests.get(url, headers=headers, timeout=10)
65
- if resp.status_code == 200:
66
- data = resp.json()
67
- extract = data.get("extract", "")
68
- title = data.get("title", query)
69
- if extract:
70
- return f"**{title}**: {extract}"
71
- return f"No extract available for '{query}'."
72
- elif resp.status_code == 404:
73
- return f"No Wikipedia article found for '{query}'."
74
- else:
75
- return f"Wikipedia query returned status code {resp.status_code}."
76
- except Exception as e:
77
- return f"Error querying Wikipedia for '{query}': {str(e)}"
78
-
79
  # --- Core Tools & Agent Setup ---
80
 
81
  final_answer = FinalAnswerTool()
82
  web_search = DuckDuckGoSearchTool()
83
  visit_webpage = VisitWebpageTool()
84
 
 
 
 
 
 
 
85
  # Image generation tool from Hugging Face Hub
86
  image_generation_tool = None
87
  try:
88
- hf_token = os.getenv("HF_TOKEN")
89
  image_generation_tool = load_tool(
90
  "agents-course/text-to-image",
91
  trust_remote_code=True,
92
- token=hf_token
93
  )
94
  except Exception as e:
95
  print(f"Notice: text-to-image tool could not be loaded: {e}")
96
 
97
- # Model Configuration
98
- try:
99
- from smolagents import HfApiModel as HfModel
100
- except ImportError:
101
- from smolagents import InferenceClientModel as HfModel
102
-
103
- hf_token = os.getenv("HF_TOKEN")
104
- use_ollama = os.getenv("USE_OLLAMA", "").lower() in ("true", "1")
105
-
106
- if use_ollama or (not hf_token and os.getenv("OLLAMA_ENABLED", "").lower() in ("true", "1")):
107
- print("Using local Ollama model for agent execution...")
108
  from smolagents import LiteLLMModel
 
109
  model = LiteLLMModel(
110
- model_id=os.getenv("OLLAMA_MODEL", "ollama_chat/qwen2.5-coder:3b"),
111
  api_base=os.getenv("OLLAMA_API_BASE", "http://127.0.0.1:11434"),
112
- num_ctx=8192
 
113
  )
114
  else:
115
- model_id = os.getenv("MODEL_ID", "Qwen/Qwen2.5-Coder-32B-Instruct")
116
- model_kwargs = {
117
- "max_tokens": 2096,
118
- "temperature": 0.5,
119
- "model_id": model_id,
120
- "custom_role_conversions": None,
121
- }
122
- if hf_token:
123
- model_kwargs["token"] = hf_token
124
- model = HfModel(**model_kwargs)
125
 
126
  # Load prompt templates
127
  prompts_file = os.path.join(os.path.dirname(__file__), "prompts.yaml")
@@ -137,7 +71,7 @@ research_agent = CodeAgent(
137
  max_steps=5,
138
  verbosity_level=1,
139
  name="web_researcher",
140
- description="A specialist researcher that searches DuckDuckGo, queries Wikipedia, and reads webpage content to gather accurate facts and summaries.",
141
  prompt_templates=prompt_templates
142
  )
143
 
@@ -148,10 +82,31 @@ local_info_agent = CodeAgent(
148
  max_steps=4,
149
  verbosity_level=1,
150
  name="local_info_specialist",
151
- description="A specialist agent that fetches real-time live weather reports and calculates current time in timezones worldwide.",
152
  prompt_templates=prompt_templates
153
  )
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  # Manager Agent: Coordinates specialists and synthesizes the final response
156
  manager_tools = [final_answer]
157
  if image_generation_tool is not None:
 
 
1
  import os
2
+
 
 
3
  import yaml
4
  from dotenv import load_dotenv
5
+ from smolagents import CodeAgent, InferenceClientModel, load_tool
6
 
7
+ from Gradio_UI import GradioUI
8
  from tools.final_answer import FinalAnswerTool
9
+ from tools.get_current_time_in_timezone import get_current_time_in_timezone
10
+ from tools.get_weather import get_weather
11
+ from tools.search_wikipedia import search_wikipedia
12
  from tools.visit_webpage import VisitWebpageTool
13
+ from tools.web_search import DuckDuckGoSearchTool
14
 
15
  load_dotenv()
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  # --- Core Tools & Agent Setup ---
18
 
19
  final_answer = FinalAnswerTool()
20
  web_search = DuckDuckGoSearchTool()
21
  visit_webpage = VisitWebpageTool()
22
 
23
+ hf_token = os.getenv("HF_TOKEN")
24
+ if not hf_token:
25
+ raise RuntimeError(
26
+ "HF_TOKEN is required. Local model execution is disabled in this project."
27
+ )
28
+
29
  # Image generation tool from Hugging Face Hub
30
  image_generation_tool = None
31
  try:
 
32
  image_generation_tool = load_tool(
33
  "agents-course/text-to-image",
34
  trust_remote_code=True,
35
+ token=hf_token,
36
  )
37
  except Exception as e:
38
  print(f"Notice: text-to-image tool could not be loaded: {e}")
39
 
40
+ # Model configuration (cloud by default; Ollama supported for local learning/testing)
41
+ model_id = os.getenv("MODEL_ID", "Qwen/Qwen2.5-Coder-32B-Instruct")
42
+ if "ollama" in model_id.lower():
 
 
 
 
 
 
 
 
43
  from smolagents import LiteLLMModel
44
+
45
  model = LiteLLMModel(
46
+ model_id=model_id,
47
  api_base=os.getenv("OLLAMA_API_BASE", "http://127.0.0.1:11434"),
48
+ num_ctx=int(os.getenv("OLLAMA_NUM_CTX", "8192")),
49
+ temperature=0.5,
50
  )
51
  else:
52
+ model = InferenceClientModel(
53
+ model_id=model_id,
54
+ token=hf_token,
55
+ max_tokens=2096,
56
+ temperature=0.5,
57
+ custom_role_conversions=None,
58
+ )
 
 
 
59
 
60
  # Load prompt templates
61
  prompts_file = os.path.join(os.path.dirname(__file__), "prompts.yaml")
 
71
  max_steps=5,
72
  verbosity_level=1,
73
  name="web_researcher",
74
+ description="A specialist researcher that searches DuckDuckGo, queries Wikipedia, and reads webpage content to gather accurate facts and summaries. ALWAYS call this agent with a 'task' argument, e.g. web_researcher(task='Find the capital of Japan').",
75
  prompt_templates=prompt_templates
76
  )
77
 
 
82
  max_steps=4,
83
  verbosity_level=1,
84
  name="local_info_specialist",
85
+ description="A specialist agent that fetches real-time live weather reports and calculates current time in timezones worldwide. ALWAYS call this agent with a 'task' argument, e.g. local_info_specialist(task='Get current weather in Tokyo'). Never call weather() or get_weather() directly from the manager.",
86
  prompt_templates=prompt_templates
87
  )
88
 
89
+ # Make managed agents tolerant of common argument names (query/question/etc.)
90
+ def _adapt_managed_agent(agent):
91
+ original_call = agent.__call__
92
+
93
+ def _call(task=None, **kwargs):
94
+ if task is None:
95
+ for key in ("task", "query", "question", "request", "prompt"):
96
+ if key in kwargs:
97
+ task = kwargs.pop(key)
98
+ break
99
+ if task is None and kwargs:
100
+ task = list(kwargs.values())[0]
101
+ kwargs = {}
102
+ return original_call(task, **kwargs)
103
+
104
+ agent.__call__ = _call
105
+ return agent
106
+
107
+ research_agent = _adapt_managed_agent(research_agent)
108
+ local_info_agent = _adapt_managed_agent(local_info_agent)
109
+
110
  # Manager Agent: Coordinates specialists and synthesizes the final response
111
  manager_tools = [final_answer]
112
  if image_generation_tool is not None:
prompts.yaml CHANGED
@@ -219,8 +219,8 @@
219
 
220
  {%- if managed_agents and managed_agents.values() | list %}
221
  You can also give tasks to team members.
222
- Calling a team member works the same as for calling a tool: simply, the only argument you can give in the call is 'request', a long string explaining your request.
223
- Given that this team member is a real human, you should be very verbose in your request.
224
  Here is a list of the team members that you can call:
225
  {%- for agent in managed_agents.values() %}
226
  - {{ agent.name }}: {{ agent.description }}
 
219
 
220
  {%- if managed_agents and managed_agents.values() | list %}
221
  You can also give tasks to team members.
222
+ Calling a team member works the same as for calling a tool: simply, the only argument you can give in the call is 'task', a long string explaining your task.
223
+ Given that this team member is a real human, you should be very verbose in your task.
224
  Here is a list of the team members that you can call:
225
  {%- for agent in managed_agents.values() %}
226
  - {{ agent.name }}: {{ agent.description }}
requirements.txt CHANGED
@@ -1,10 +1,10 @@
 
 
 
1
  markdownify
2
- smolagents
3
- requests
4
- duckduckgo_search
5
  pandas
6
- pytz
7
- python-dotenv
8
  pillow
9
- litellm
10
- ddgs
 
 
 
1
+ ddgs
2
+ gradio>=5.23,<7
3
+ huggingface_hub
4
  markdownify
 
 
 
5
  pandas
 
 
6
  pillow
7
+ python-dotenv
8
+ pytz
9
+ requests
10
+ smolagents>=1.26,<2
test_agent.py CHANGED
@@ -1,94 +1,101 @@
1
  #!/usr/bin/env python3
2
- """
3
- CLI Test Runner for ArkAssistant smolagent
4
  Usage:
5
  # Run a test query against the manager agent:
6
  .venv/bin/python test_agent.py "What is the capital of France and what is the current time there?"
7
 
8
- # Run with local Ollama offline model:
9
- USE_OLLAMA=true .venv/bin/python test_agent.py "What is the weather in London?"
10
-
11
  # Sanity check all tools without calling the LLM:
12
  .venv/bin/python test_agent.py --test-tools
 
 
13
  """
14
 
15
- import os
16
  import sys
17
 
18
- def run_tools_sanity():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  print("=" * 60)
20
  print("🔬 Running Sanity Check on ArkAssistant Tools (No LLM Calls)")
21
  print("=" * 60)
22
-
23
- # 1. Weather
24
- try:
25
- from app import get_weather
26
- w = get_weather("London")
27
- print(f"✅ Weather Tool: {w[:80]}...")
28
- except Exception as e:
29
- print(f"❌ Weather Tool Failed: {e}")
30
 
31
- # 2. Timezone
32
- try:
33
- from app import get_current_time_in_timezone
34
- t = get_current_time_in_timezone("UTC")
35
- print(f"✅ Timezone Tool: {t}")
36
- except Exception as e:
37
- print(f"❌ Timezone Tool Failed: {e}")
38
 
39
- # 3. Wikipedia
40
- try:
41
- from app import search_wikipedia
42
- wiki = search_wikipedia("Alan Turing")
43
- print(f"✅ Wikipedia Tool: {wiki[:80]}...")
44
- except Exception as e:
45
- print(f"❌ Wikipedia Tool Failed: {e}")
46
 
47
- # 4. Visit Webpage
48
- try:
49
- from app import visit_webpage
50
- res = visit_webpage("https://httpbin.org/html")
51
- print(f"✅ Visit Webpage Tool: Extracted {len(res)} characters.")
52
- except Exception as e:
53
- print(f"❌ Visit Webpage Tool Failed: {e}")
54
-
55
- # 5. DuckDuckGo Web Search
56
- try:
57
- from app import web_search
58
- sr = web_search("smolagents Hugging Face")
59
- print(f"✅ Web Search Tool: {sr[:80]}...")
60
- except Exception as e:
61
- print(f"❌ Web Search Tool Failed: {e}")
62
 
63
  print("=" * 60)
64
- print("All tool sanity checks complete.")
65
- print("=" * 60)
 
 
 
 
 
 
66
 
67
- def main():
68
  args = sys.argv[1:]
69
-
70
  if "--test-tools" in args:
71
- run_tools_sanity()
72
- return
73
 
74
- # Check for prompt argument
75
- prompt = " ".join([a for a in args if not a.startswith("--")])
76
  if not prompt:
77
  prompt = "What is the current time in UTC and what is the weather in Paris?"
78
  print(f"No prompt provided. Using default test prompt:\n '{prompt}'\n")
79
 
80
- print(f"🚀 Initializing ArkAssistant Agent...")
81
- from app import agent
82
-
83
- print(f"🤖 Running Agent Task: \"{prompt}\"")
84
- print("-" * 60)
85
  try:
 
 
 
 
86
  response = agent.run(prompt)
87
  print("-" * 60)
88
  print(f"\n🎯 Agent Final Answer:\n{response}")
89
- except Exception as e:
90
- print(f"\n❌ Error during agent execution: {e}")
91
- sys.exit(1)
 
 
 
 
 
 
 
 
92
 
93
  if __name__ == "__main__":
94
- main()
 
1
  #!/usr/bin/env python3
2
+ """CLI test runner for ArkAssistant.
3
+
4
  Usage:
5
  # Run a test query against the manager agent:
6
  .venv/bin/python test_agent.py "What is the capital of France and what is the current time there?"
7
 
 
 
 
8
  # Sanity check all tools without calling the LLM:
9
  .venv/bin/python test_agent.py --test-tools
10
+
11
+ The project uses the Hugging Face Inference API and requires HF_TOKEN in .env.
12
  """
13
 
 
14
  import sys
15
 
16
+ from tools.get_current_time_in_timezone import get_current_time_in_timezone
17
+ from tools.get_weather import get_weather
18
+ from tools.search_wikipedia import search_wikipedia
19
+ from tools.visit_webpage import VisitWebpageTool
20
+ from tools.web_search import DuckDuckGoSearchTool
21
+
22
+
23
+ def _require_result(result: str) -> str:
24
+ text = str(result).strip()
25
+ if not text:
26
+ raise RuntimeError("tool returned an empty result")
27
+ if text.lower().startswith("error"):
28
+ raise RuntimeError(text)
29
+ return text
30
+
31
+
32
+ def run_tools_sanity() -> int:
33
  print("=" * 60)
34
  print("🔬 Running Sanity Check on ArkAssistant Tools (No LLM Calls)")
35
  print("=" * 60)
 
 
 
 
 
 
 
 
36
 
37
+ visit_webpage = VisitWebpageTool()
38
+ web_search = DuckDuckGoSearchTool()
39
+ failures: list[str] = []
 
 
 
 
40
 
41
+ checks = [
42
+ ("Weather", lambda: get_weather("London")),
43
+ ("Timezone", lambda: get_current_time_in_timezone("UTC")),
44
+ ("Wikipedia", lambda: search_wikipedia("Alan Turing")),
45
+ ("Visit Webpage", lambda: visit_webpage("https://httpbin.org/html")),
46
+ ("Web Search", lambda: web_search("smolagents Hugging Face")),
47
+ ]
48
 
49
+ for name, check in checks:
50
+ try:
51
+ result = _require_result(check())
52
+ preview = result.replace("\n", " ")[:100]
53
+ print(f"✅ {name} Tool: {preview}")
54
+ except Exception as exc:
55
+ failures.append(f"{name}: {exc}")
56
+ print(f"❌ {name} Tool Failed: {exc}")
 
 
 
 
 
 
 
57
 
58
  print("=" * 60)
59
+ if failures:
60
+ print(f"❌ {len(failures)} tool check(s) failed.")
61
+ for failure in failures:
62
+ print(f" - {failure}")
63
+ return 1
64
+ print("✅ All tool sanity checks passed.")
65
+ return 0
66
+
67
 
68
+ def main() -> int:
69
  args = sys.argv[1:]
70
+
71
  if "--test-tools" in args:
72
+ return run_tools_sanity()
 
73
 
74
+ prompt = " ".join(arg for arg in args if not arg.startswith("--"))
 
75
  if not prompt:
76
  prompt = "What is the current time in UTC and what is the weather in Paris?"
77
  print(f"No prompt provided. Using default test prompt:\n '{prompt}'\n")
78
 
79
+ print("🚀 Initializing ArkAssistant Agent...")
 
 
 
 
80
  try:
81
+ from app import agent
82
+
83
+ print(f"🤖 Running Agent Task: \"{prompt}\"")
84
+ print("-" * 60)
85
  response = agent.run(prompt)
86
  print("-" * 60)
87
  print(f"\n🎯 Agent Final Answer:\n{response}")
88
+ return 0
89
+ except Exception as exc:
90
+ message = str(exc)
91
+ print(f"\n❌ Error during agent execution: {message}")
92
+ if "402" in message or "Payment Required" in message:
93
+ print(
94
+ "Hint: Hugging Face Inference has no available credits. "
95
+ "Add credits/PRO or configure another cloud provider in .env."
96
+ )
97
+ return 1
98
+
99
 
100
  if __name__ == "__main__":
101
+ sys.exit(main())
tools/get_current_time_in_timezone.py CHANGED
@@ -1,22 +1,19 @@
1
- from smolagents import Tool
2
- from typing import Any, Optional
3
 
4
- class SimpleTool(Tool):
5
- name = "get_current_time_in_timezone"
6
- description = "A tool that fetches the current local time in a specified timezone."
7
- inputs = {'timezone': {'type': 'string', 'description': "A string representing a valid IANA timezone (e.g., 'America/New_York', 'Europe/Paris', 'Asia/Kolkata', 'UTC')."}}
8
- output_type = "string"
9
 
10
- def forward(self, timezone: str) -> str:
11
- """A tool that fetches the current local time in a specified timezone.
12
- Args:
13
- timezone: A string representing a valid IANA timezone (e.g., 'America/New_York', 'Europe/Paris', 'Asia/Kolkata', 'UTC').
14
- """
15
- try:
16
- import datetime
17
- import pytz
18
- tz = pytz.timezone(timezone)
19
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
20
- return f"The current local time in {timezone} is: {local_time}"
21
- except Exception as e:
22
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
 
 
1
+ import datetime
 
2
 
3
+ import pytz
4
+ from smolagents import tool
 
 
 
5
 
6
+
7
+ @tool
8
+ def get_current_time_in_timezone(timezone: str) -> str:
9
+ """A tool that fetches the current local time in a specified timezone.
10
+
11
+ Args:
12
+ timezone: A valid IANA timezone (e.g., 'America/New_York', 'Europe/Paris', 'Asia/Kolkata', 'UTC').
13
+ """
14
+ try:
15
+ tz = pytz.timezone(timezone)
16
+ local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
17
+ return f"The current local time in {timezone} is: {local_time}"
18
+ except Exception as e:
19
+ return f"Error fetching time for timezone '{timezone}': {str(e)}"
tools/get_weather.py CHANGED
@@ -1,26 +1,23 @@
1
- from smolagents import Tool
2
- from typing import Any, Optional
3
 
4
- class SimpleTool(Tool):
5
- name = "get_weather"
6
- description = "Fetches the current live weather report and temperature for a given city or location."
7
- inputs = {'location': {'type': 'string', 'description': "The name of the city or location (e.g., 'Paris', 'Tokyo', 'San Francisco')."}}
8
- output_type = "string"
9
 
10
- def forward(self, location: str) -> str:
11
- """Fetches the current live weather report and temperature for a given city or location.
12
- Args:
13
- location: The name of the city or location (e.g., 'Paris', 'Tokyo', 'San Francisco').
14
- """
15
- try:
16
- import requests
17
- from urllib.parse import quote
18
- encoded_loc = quote(location)
19
- url = f"https://wttr.in/{encoded_loc}?format=%C+%t+(feels+like+%f)+wind:+%w"
20
- headers = {"User-Agent": "HF-Agents-Course-ArkAssistant/1.0"}
21
- resp = requests.get(url, headers=headers, timeout=10)
22
- if resp.status_code == 200 and resp.text:
23
- return f"Weather for {location}: {resp.text.strip()}"
24
- return f"Could not retrieve weather for {location} (status code {resp.status_code})."
25
- except Exception as e:
26
- return f"Error fetching weather for '{location}': {str(e)}"
 
 
1
+ from urllib.parse import quote
 
2
 
3
+ import requests
4
+ from smolagents import tool
 
 
 
5
 
6
+
7
+ @tool
8
+ def get_weather(location: str) -> str:
9
+ """Fetches the current live weather report and temperature for a given city or location.
10
+
11
+ Args:
12
+ location: The name of the city or location (e.g., 'Paris', 'Tokyo', 'San Francisco').
13
+ """
14
+ try:
15
+ encoded_loc = quote(location)
16
+ url = f"https://wttr.in/{encoded_loc}?format=%C+%t+(feels+like+%f)+wind:+%w"
17
+ headers = {"User-Agent": "HF-Agents-Course-ArkAssistant/1.0"}
18
+ resp = requests.get(url, headers=headers, timeout=10)
19
+ if resp.status_code == 200 and resp.text:
20
+ return f"Weather for {location}: {resp.text.strip()}"
21
+ return f"Could not retrieve weather for {location} (status code {resp.status_code})."
22
+ except Exception as e:
23
+ return f"Error fetching weather for '{location}': {str(e)}"
tools/search_wikipedia.py CHANGED
@@ -1,34 +1,30 @@
1
- from smolagents import Tool
2
- from typing import Any, Optional
3
 
4
- class SimpleTool(Tool):
5
- name = "search_wikipedia"
6
- description = "Fetches an encyclopedic summary of a topic from Wikipedia."
7
- inputs = {'query': {'type': 'string', 'description': "The subject or topic name to search on Wikipedia (e.g., 'Alan Turing', 'Artificial intelligence')."}}
8
- output_type = "string"
9
 
10
- def forward(self, query: str) -> str:
11
- """Fetches an encyclopedic summary of a topic from Wikipedia.
12
- Args:
13
- query: The subject or topic name to search on Wikipedia (e.g., 'Alan Turing', 'Artificial intelligence').
14
- """
15
- try:
16
- import requests
17
- from urllib.parse import quote
18
- encoded_query = quote(query)
19
- url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{encoded_query}"
20
- headers = {"User-Agent": "HF-Agents-Course-ArkAssistant/1.0"}
21
- resp = requests.get(url, headers=headers, timeout=10)
22
- if resp.status_code == 200:
23
- data = resp.json()
24
- extract = data.get("extract", "")
25
- title = data.get("title", query)
26
- if extract:
27
- return f"**{title}**: {extract}"
28
- return f"No extract available for '{query}'."
29
- elif resp.status_code == 404:
30
- return f"No Wikipedia article found for '{query}'."
31
- else:
32
- return f"Wikipedia query returned status code {resp.status_code}."
33
- except Exception as e:
34
- return f"Error querying Wikipedia for '{query}': {str(e)}"
 
1
+ from urllib.parse import quote
 
2
 
3
+ import requests
4
+ from smolagents import tool
 
 
 
5
 
6
+
7
+ @tool
8
+ def search_wikipedia(query: str) -> str:
9
+ """Fetches an encyclopedic summary of a topic from Wikipedia.
10
+
11
+ Args:
12
+ query: The subject or topic name to search on Wikipedia (e.g., 'Alan Turing', 'Artificial intelligence').
13
+ """
14
+ try:
15
+ encoded_query = quote(query)
16
+ url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{encoded_query}"
17
+ headers = {"User-Agent": "HF-Agents-Course-ArkAssistant/1.0"}
18
+ resp = requests.get(url, headers=headers, timeout=10)
19
+ if resp.status_code == 200:
20
+ data = resp.json()
21
+ extract = data.get("extract", "")
22
+ title = data.get("title", query)
23
+ if extract:
24
+ return f"**{title}**: {extract}"
25
+ return f"No extract available for '{query}'."
26
+ if resp.status_code == 404:
27
+ return f"No Wikipedia article found for '{query}'."
28
+ return f"Wikipedia query returned status code {resp.status_code}."
29
+ except Exception as e:
30
+ return f"Error querying Wikipedia for '{query}': {str(e)}"