Ark4u commited on
Commit
cd6addd
Β·
verified Β·
1 Parent(s): 10cfbc7

Deploy ArkAssistant smolagent (Hugging Face Agents Course Unit 1)

Browse files
.agents/skills/deploy-space/SKILL.md ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: deploy-space
3
+ description: Validates and deploys the ArkAssistant smolagent workspace to Hugging Face Spaces. Use when asked to test, validate, check, or deploy this project to Hugging Face Spaces.
4
+ ---
5
+
6
+ # Deploy Space Skill
7
+
8
+ This skill guides the automated validation and deployment process for the ArkAssistant Hugging Face Space repository (`Ark4u/First_agent_template`).
9
+
10
+ ## Pre-Deployment Verification Checklist
11
+
12
+ Always run these verification steps prior to deployment:
13
+
14
+ 1. **Tool Sanity Verification**:
15
+ Ensure all external APIs and tools respond correctly without error:
16
+ ```bash
17
+ .venv/bin/python test_agent.py --test-tools
18
+ ```
19
+
20
+ 2. **Syntax Compilation Check**:
21
+ Confirm that all Python source files compile cleanly:
22
+ ```bash
23
+ .venv/bin/python -m py_compile app.py Gradio_UI.py deploy_space.py test_agent.py tools/*.py
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`.
31
+
32
+ ## Deployment Execution
33
+
34
+ Run the deployment script:
35
+ ```bash
36
+ .venv/bin/python deploy_space.py
37
+ ```
38
+
39
+ The script will prompt for confirmation or use the `HF_TOKEN` from the environment.
40
+ Once uploaded, monitor the Space build logs at:
41
+ https://huggingface.co/spaces/Ark4u/First_agent_template
AGENTS.md CHANGED
@@ -1,32 +1,55 @@
1
- # OmniAssistant - Hugging Face Agents Course Project
2
 
3
- This workspace contains the complete implementation for the **Hugging Face Agents Course (Unit 1)** project.
 
 
 
 
 
 
 
4
 
5
  ## Project Structure
6
 
7
- - `app.py`: Main entry point for the agent. Runs a `CodeAgent` with Gradio UI.
 
 
8
  - `prompts.yaml`: System prompts and agent templates.
9
  - `requirements.txt`: Package dependencies for the agent and Hugging Face Space.
10
  - `README.md`: Space card metadata for Gradio on Hugging Face Spaces.
11
  - `deploy_space.py`: Automated deploy script to upload the workspace to `Ark4u/First_agent_template` on Hugging Face.
12
- - `tools/`: Modular tools provided to the agent:
13
- - `web_search.py` (DuckDuckGo search)
14
- - `get_weather.py` (Live weather via wttr.in)
15
- - `search_wikipedia.py` (Wikipedia REST API)
16
- - `get_current_time_in_timezone.py` (IANA timezone local time)
17
- - `final_answer.py` (Final answer tool)
 
18
 
19
  ## Environment & Commands
20
 
21
  - **Local Virtual Environment**: `.venv/bin/python`
22
- - **Run Gradio UI Locally**:
 
23
  ```bash
24
- .venv/bin/python app.py
25
  ```
26
- - **Run with Local Ollama (Offline)**:
 
27
  ```bash
28
- USE_OLLAMA=true .venv/bin/python app.py
29
  ```
 
 
 
 
 
 
 
 
 
 
 
30
  - **Deploy to Hugging Face Spaces**:
31
  ```bash
32
  .venv/bin/python deploy_space.py
 
1
+ # ArkAssistant - Hugging Face Agents Course Project
2
 
3
+ This workspace contains the complete implementation for the **Hugging Face Agents Course (Unit 1 & Unit 2)** project, featuring a Hierarchical Multi-Agent System built with `smolagents`.
4
+
5
+ ## System Architecture
6
+
7
+ - **`ArkAssistant_Manager`** (`app.py`): Top-level orchestrator agent that parses complex user inquiries and coordinates specialist sub-agents.
8
+ - **`web_researcher`** (`research_agent`): Specialist agent equipped with `web_search`, `search_wikipedia`, and `visit_webpage` for deep web querying and documentation browsing.
9
+ - **`local_info_specialist`** (`local_info_agent`): Specialist agent equipped with `get_weather` and `get_current_time_in_timezone`.
10
+ - **`final_answer` & `image_generation_tool`**: Direct manager tools to conclude inquiries or generate visual images.
11
 
12
  ## Project Structure
13
 
14
+ - `app.py`: Main entry point and multi-agent pipeline with Gradio UI.
15
+ - `test_agent.py`: Fast CLI test runner for direct queries and tool verification without launching a browser.
16
+ - `Gradio_UI.py`: Gradio interface with ZeroGPU compatibility and step-by-step agent visualization.
17
  - `prompts.yaml`: System prompts and agent templates.
18
  - `requirements.txt`: Package dependencies for the agent and Hugging Face Space.
19
  - `README.md`: Space card metadata for Gradio on Hugging Face Spaces.
20
  - `deploy_space.py`: Automated deploy script to upload the workspace to `Ark4u/First_agent_template` on Hugging Face.
21
+ - `tools/`: Modular tools:
22
+ - `web_search.py`: DuckDuckGo web search.
23
+ - `visit_webpage.py`: Webpage scraper and markdown converter (`VisitWebpageTool`).
24
+ - `search_wikipedia.py`: Wikipedia REST API lookups.
25
+ - `get_weather.py`: Live weather via wttr.in.
26
+ - `get_current_time_in_timezone.py`: IANA timezone local time converter.
27
+ - `final_answer.py`: Final response delivery tool.
28
 
29
  ## Environment & Commands
30
 
31
  - **Local Virtual Environment**: `.venv/bin/python`
32
+
33
+ - **Sanity Check All Tools (Fast, No LLM)**:
34
  ```bash
35
+ .venv/bin/python test_agent.py --test-tools
36
  ```
37
+
38
+ - **Run CLI Agent Query**:
39
  ```bash
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
51
+ ```
52
+
53
  - **Deploy to Hugging Face Spaces**:
54
  ```bash
55
  .venv/bin/python deploy_space.py
Gradio_UI.py CHANGED
@@ -37,6 +37,11 @@ except Exception:
37
  spaces = _MockSpaces()
38
 
39
 
 
 
 
 
 
40
  def pull_messages_from_step(
41
  step_log: MemoryStep,
42
  ):
@@ -201,7 +206,6 @@ class GradioUI:
201
  if not os.path.exists(file_upload_folder):
202
  os.mkdir(file_upload_folder)
203
 
204
- @spaces.GPU(duration=120)
205
  def interact_with_agent(self, prompt, messages):
206
  import gradio as gr
207
 
@@ -302,6 +306,10 @@ class GradioUI:
302
  [stored_messages, text_input],
303
  ).then(self.interact_with_agent, [stored_messages, chatbot], [chatbot])
304
 
 
 
 
 
305
  is_space = bool(os.getenv("SPACE_ID"))
306
  launch_kwargs = {
307
  "debug": True,
 
37
  spaces = _MockSpaces()
38
 
39
 
40
+ @spaces.GPU
41
+ def _zero_gpu_init():
42
+ return "ready"
43
+
44
+
45
  def pull_messages_from_step(
46
  step_log: MemoryStep,
47
  ):
 
206
  if not os.path.exists(file_upload_folder):
207
  os.mkdir(file_upload_folder)
208
 
 
209
  def interact_with_agent(self, prompt, messages):
210
  import gradio as gr
211
 
 
306
  [stored_messages, text_input],
307
  ).then(self.interact_with_agent, [stored_messages, chatbot], [chatbot])
308
 
309
+ # ZeroGPU initialization trigger
310
+ dummy_btn = gr.Button(visible=False)
311
+ dummy_btn.click(_zero_gpu_init)
312
+
313
  is_space = bool(os.getenv("SPACE_ID"))
314
  launch_kwargs = {
315
  "debug": True,
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: OmniAssistant Smolagent
3
  emoji: πŸ€–
4
  colorFrom: indigo
5
  colorTo: purple
@@ -15,9 +15,9 @@ tags:
15
  - agent-course
16
  ---
17
 
18
- # πŸ€– OmniAssistant - Hugging Face Agents Course (Unit 1)
19
 
20
- OmniAssistant is a multi-functional AI agent built with [`smolagents`](https://github.com/huggingface/smolagents) for Unit 1 of the [Hugging Face Agents Course](https://hf.co/learn/agents-course).
21
 
22
  ## πŸ› οΈ Capabilities & Tools
23
 
 
1
  ---
2
+ title: ArkAssistant Smolagent
3
  emoji: πŸ€–
4
  colorFrom: indigo
5
  colorTo: purple
 
15
  - agent-course
16
  ---
17
 
18
+ # πŸ€– ArkAssistant - Hugging Face Agents Course (Unit 1)
19
 
20
+ ArkAssistant is a multi-functional AI agent built with [`smolagents`](https://github.com/huggingface/smolagents) for Unit 1 of the [Hugging Face Agents Course](https://hf.co/learn/agents-course).
21
 
22
  ## πŸ› οΈ Capabilities & Tools
23
 
app.py CHANGED
@@ -8,6 +8,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 Gradio_UI import GradioUI
12
 
13
  load_dotenv()
@@ -40,7 +41,7 @@ def get_weather(location: str) -> str:
40
  from urllib.parse import quote
41
  encoded_loc = quote(location)
42
  url = f"https://wttr.in/{encoded_loc}?format=%C+%t+(feels+like+%f)+wind:+%w"
43
- headers = {"User-Agent": "HF-Agents-Course-OmniAssistant/1.0"}
44
  resp = requests.get(url, headers=headers, timeout=10)
45
  if resp.status_code == 200 and resp.text:
46
  return f"Weather for {location}: {resp.text.strip()}"
@@ -59,7 +60,7 @@ def search_wikipedia(query: str) -> str:
59
  from urllib.parse import quote
60
  encoded_query = quote(query)
61
  url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{encoded_query}"
62
- headers = {"User-Agent": "HF-Agents-Course-OmniAssistant/1.0"}
63
  resp = requests.get(url, headers=headers, timeout=10)
64
  if resp.status_code == 200:
65
  data = resp.json()
@@ -79,6 +80,7 @@ def search_wikipedia(query: str) -> str:
79
 
80
  final_answer = FinalAnswerTool()
81
  web_search = DuckDuckGoSearchTool()
 
82
 
83
  # Image generation tool from Hugging Face Hub
84
  image_generation_tool = None
@@ -131,11 +133,11 @@ with open(prompts_file, "r") as stream:
131
  # Specialist 1: Web & Wikipedia Researcher
132
  research_agent = CodeAgent(
133
  model=model,
134
- tools=[web_search, search_wikipedia],
135
- max_steps=4,
136
  verbosity_level=1,
137
  name="web_researcher",
138
- description="A specialist researcher that searches DuckDuckGo and queries Wikipedia to gather accurate facts and summaries.",
139
  prompt_templates=prompt_templates
140
  )
141
 
@@ -162,7 +164,7 @@ manager_agent = CodeAgent(
162
  max_steps=8,
163
  verbosity_level=1,
164
  planning_interval=None,
165
- name="OmniAssistant_Manager",
166
  description="A senior manager agent that breaks down user tasks and delegates them to specialized team members (web researcher and local info specialist).",
167
  prompt_templates=prompt_templates
168
  )
 
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()
 
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()}"
 
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()
 
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
 
133
  # Specialist 1: Web & Wikipedia Researcher
134
  research_agent = CodeAgent(
135
  model=model,
136
+ tools=[web_search, search_wikipedia, visit_webpage],
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
 
 
164
  max_steps=8,
165
  verbosity_level=1,
166
  planning_interval=None,
167
+ name="ArkAssistant_Manager",
168
  description="A senior manager agent that breaks down user tasks and delegates them to specialized team members (web researcher and local info specialist).",
169
  prompt_templates=prompt_templates
170
  )
test_agent.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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()
tools/get_weather.py CHANGED
@@ -17,7 +17,7 @@ class SimpleTool(Tool):
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-OmniAssistant/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()}"
 
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()}"
tools/search_wikipedia.py CHANGED
@@ -17,7 +17,7 @@ class SimpleTool(Tool):
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-OmniAssistant/1.0"}
21
  resp = requests.get(url, headers=headers, timeout=10)
22
  if resp.status_code == 200:
23
  data = resp.json()
 
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()
tools/visit_webpage.py CHANGED
@@ -43,4 +43,5 @@ class VisitWebpageTool(Tool):
43
  return f"An unexpected error occurred: {str(e)}"
44
 
45
  def __init__(self, *args, **kwargs):
 
46
  self.is_initialized = False
 
43
  return f"An unexpected error occurred: {str(e)}"
44
 
45
  def __init__(self, *args, **kwargs):
46
+ super().__init__(*args, **kwargs)
47
  self.is_initialized = False