File size: 6,779 Bytes
92a8aaa
 
 
 
 
 
 
 
 
9b5b26a
92a8aaa
9b5b26a
92a8aaa
 
9b5b26a
c19d193
6aae614
9b5b26a
92a8aaa
 
c1c11e5
 
 
 
 
 
 
 
 
 
 
 
 
92a8aaa
 
 
9b5b26a
92a8aaa
9b5b26a
92a8aaa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9b5b26a
92a8aaa
9b5b26a
 
 
 
c1c11e5
9b5b26a
92a8aaa
9b5b26a
 
 
92a8aaa
9b5b26a
 
 
 
 
 
 
 
 
 
 
8c01ffb
92a8aaa
6aae614
ae7a494
c1c11e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae7a494
c1c11e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c01ffb
92a8aaa
861422e
 
92a8aaa
 
 
 
 
 
 
 
 
 
 
 
 
 
8fe992b
92a8aaa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c01ffb
 
92a8aaa
8c01ffb
 
92a8aaa
 
861422e
8fe992b
 
c1c11e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
from smolagents import (
    CodeAgent,
    ToolCallingAgent,
    HfApiModel,
    DuckDuckGoSearchTool,
    LiteLLMModel,
    tool,
    load_tool,
)
import datetime
import re
import requests
from markdownify import markdownify
from requests.exceptions import RequestException
import pytz
import yaml
from tools.final_answer import FinalAnswerTool
from Gradio_UI import GradioUI
from huggingface_hub import login

# Handle Hugging Face authentication
# Option 1: Use token from environment variable (recommended for production)
import os

# Try to get token from environment variable
hf_token = os.environ.get("HUGGINGFACE_TOKEN")
if hf_token:
    # Use token without interactive prompt
    login(token=hf_token)
else:
    # Option 2: Skip login and use API without authentication
    print("No Hugging Face token found in environment. Running without authentication.")
    # You may encounter rate limits without authentication

# Set model ID
model_id = "Qwen/Qwen2.5-Coder-32B-Instruct"

# Web browsing tool
@tool
def visit_webpage(url: str) -> str:
    """Visits a webpage at the given URL and returns its content as a markdown string.
    
    Args:
        url: The URL of the webpage to visit.
        
    Returns:
        The content of the webpage converted to Markdown, or an error message if the request fails.
    """
    try:
        # Send a GET request to the URL
        response = requests.get(url)
        response.raise_for_status()  # Raise an exception for bad status codes
        
        # Convert the HTML content to Markdown
        markdown_content = markdownify(response.text).strip()
        
        # Remove multiple line breaks
        markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content)
        
        return markdown_content
    except RequestException as e:
        return f"Error fetching the webpage: {str(e)}"
    except Exception as e:
        return f"An unexpected error occurred: {str(e)}"

# Custom tool example
@tool
def my_custom_tool(arg1: str, arg2: int) -> str:
    """A tool that does nothing yet 
    
    Args:
        arg1: the first argument
        arg2: the second argument
    """
    return "What magic will you build?"

# Timezone tool
@tool
def get_current_time_in_timezone(timezone: str) -> str:
    """A tool that fetches the current local time in a specified timezone.
    
    Args:
        timezone: A string representing a valid timezone (e.g., 'America/New_York').
    """
    try:
        # Create timezone object
        tz = pytz.timezone(timezone)
        # Get current time in that timezone
        local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
        return f"The current local time in {timezone} is: {local_time}"
    except Exception as e:
        return f"Error fetching time for timezone '{timezone}': {str(e)}"

# Initialize final answer tool
final_answer = FinalAnswerTool()

# Import image generation tool from Hub with error handling
try:
    image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
    print("Successfully loaded image generation tool")
except Exception as e:
    print(f"Failed to load image generation tool: {e}")
    # Create a simple placeholder tool
    @tool
    def image_generation_tool(prompt: str) -> str:
        """A placeholder for image generation when the real tool fails to load.
        
        Args:
            prompt: Description of the image to generate
        """
        return f"Image generation unavailable. Your prompt was: {prompt}"

# Initialize model with fallback options
try:
    # Try to use primary model
    model = HfApiModel(
        max_tokens=2096,
        temperature=0.5,
        model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
        custom_role_conversions=None,
    )
    print("Using primary model: Qwen/Qwen2.5-Coder-32B-Instruct")
except Exception as e:
    print(f"Failed to initialize primary model: {e}")
    # Fallback to alternative endpoint
    try:
        model = HfApiModel(
            max_tokens=2096,
            temperature=0.5,
            model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud',
            custom_role_conversions=None,
        )
        print("Using fallback endpoint model")
    except Exception as e2:
        print(f"Failed to initialize fallback model: {e2}")
        # Last resort: try a smaller model
        model = HfApiModel(
            max_tokens=2096,
            temperature=0.5,
            model_id='Qwen/Qwen2-7B-Instruct',  # Smaller model as last resort
            custom_role_conversions=None,
        )
        print("Using smaller fallback model: Qwen/Qwen2-7B-Instruct")

# Load prompt templates
with open("prompts.yaml", 'r') as stream:
    prompt_templates = yaml.safe_load(stream)

# ===== MULTI-AGENT SYSTEM SETUP =====
# 1. Create specialized web search agent
web_agent = ToolCallingAgent(
    tools=[DuckDuckGoSearchTool(), visit_webpage],
    model=model,
    max_steps=10,
    name="web_search_agent",
    description="Runs web searches for you and can visit webpages to extract information.",
)

# 2. Create time agent for timezone operations
time_agent = ToolCallingAgent(
    tools=[get_current_time_in_timezone],
    model=model,
    max_steps=3,
    name="time_agent",
    description="Handles time-related queries and timezone conversions.",
)

# 3. Create creative agent for image generation
creative_agent = ToolCallingAgent(
    tools=[image_generation_tool, my_custom_tool],
    model=model,
    max_steps=5,
    name="creative_agent",
    description="Creates images and handles other creative tasks.",
)

# 4. Create manager agent (main agent)
manager_agent = CodeAgent(
    model=model,
    tools=[final_answer],  # The manager can directly use the final_answer tool
    managed_agents=[web_agent, time_agent, creative_agent],  # Manages three specialized agents
    max_steps=6,
    verbosity_level=1,
    additional_authorized_imports=["time", "numpy", "pandas"],  # For data calculations
    grammar=None,
    planning_interval=None,
    name="manager_agent",
    description="Coordinates specialized agents to solve complex problems.",
    prompt_templates=prompt_templates
)

# Main execution block with error handling
def main():
    try:
        print("Starting Multi-Agent System UI...")
        # Initialize Gradio UI with the manager agent
        ui = GradioUI(manager_agent)
        ui.launch()
        return True
    except Exception as e:
        print(f"Error starting application: {e}")
        import traceback
        traceback.print_exc()
        return False

# Execute main function if run directly
if __name__ == "__main__":
    success = main()
    if not success:
        print("Application failed to start properly. Check logs for details.")