File size: 8,070 Bytes
2305e0b
87c390c
40f9320
87c390c
 
9c5afb3
2305e0b
36dc97d
2305e0b
 
36dc97d
 
2305e0b
36dc97d
2305e0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40f9320
 
 
 
 
 
 
 
87c390c
 
40f9320
2305e0b
87c390c
40f9320
 
 
 
 
 
 
 
2305e0b
40f9320
 
 
 
 
 
 
 
 
 
 
87c390c
40f9320
87c390c
 
40f9320
2305e0b
40f9320
 
 
87c390c
40f9320
 
2305e0b
40f9320
 
 
 
 
 
 
 
 
 
2305e0b
40f9320
 
 
 
 
 
 
 
2305e0b
87c390c
 
 
 
 
 
2305e0b
87c390c
 
2305e0b
87c390c
 
 
 
 
 
 
 
 
52b0c91
87c390c
40f9320
2305e0b
40f9320
 
 
 
 
 
de90e17
40f9320
0efc50e
2305e0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9c5afb3
2305e0b
 
 
 
 
 
 
 
 
 
 
87c390c
40f9320
 
 
 
 
7663d57
87c390c
 
40f9320
 
2305e0b
87c390c
 
40f9320
 
 
87c390c
 
2305e0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from smolagents import CodeAgent, DuckDuckGoSearchTool, tool
import datetime
import requests
import pytz
import yaml

# Создаем свой собственный инструмент для финального ответа
@tool
def final_answer(answer: str) -> str:
    """Provide the final answer to the user. Use this when you have the answer to the user's question.
    
    Args:
        answer: The final answer to present to the user
    """
    return answer

# Инструменты (tools), используемые агентом:
# - web_search: поиск в интернете через DuckDuckGo
# - get_weather: получение текущей погоды для города
# - get_weather_detailed: подробный прогноз погоды
# - convert_fahrenheit_to_celsius: конвертация температуры
# - get_current_time_in_timezone: время в указанном часовом поясе
# - calculate_math: вычисление математических выражений
# - suggest_weather_sources: рекомендации источников погоды
# - final_answer: инструмент для финального ответа

@tool
def web_search(query: str) -> str:
    """Search the web for information using DuckDuckGo."""
    try:
        search_tool = DuckDuckGoSearchTool()
        results = search_tool(query)
        if not results or "No results found" in results:
            return f"Поиск не дал результатов для запроса: '{query}'. Попробуйте другой запрос."
        return f"**Результаты поиска по '{query}':**\n\n{results}"
    except Exception as e:
        return f"Ошибка поиска: {str(e)}"

@tool
def get_weather(city: str) -> str:
    """Get current weather for a city using reliable weather services."""
    try:
        url = f"https://wttr.in/{city}?format=%C+%t+%h+%w&m&lang=ru"
        response = requests.get(url, timeout=10)
        
        if response.status_code == 200 and response.text.strip():
            data = response.text.strip()
            if '°F' in data:
                data = data.replace('°F', '°C')
            return f"Погода в {city}:\n{data}"
        
        url2 = f"https://wttr.in/{city}?format=%C+%t+%h+%w+%P&m&lang=ru"
        response2 = requests.get(url2, timeout=10)
        
        if response2.status_code == 200 and response2.text.strip():
            data = response2.text.strip()
            if '°F' in data:
                data = data.replace('°F', '°C')
            return f"Погода в {city}:\n{data}"
            
        return f"Данные о погоде в {city} временно недоступны. Попробуйте позже или проверьте на сайте gismeteo.ru"
            
    except Exception as e:
        return f"Ошибка при получении погоды: {str(e)}"

@tool
def get_weather_detailed(city: str) -> str:
    """Get detailed weather forecast for a city."""
    try:
        url = f"https://wttr.in/{city}?m&lang=ru"
        response = requests.get(url, timeout=10)
        
        if response.status_code == 200:
            lines = response.text.split('\n')
            short_forecast = '\n'.join(lines[:8])
            short_forecast = short_forecast.replace('°F', '°C')
            return f"Подробный прогноз для {city}:\n{short_forecast}"
        else:
            return f"Не удалось получить подробный прогноз для {city}"
            
    except Exception as e:
        return f"Ошибка: {str(e)}"

@tool
def convert_fahrenheit_to_celsius(f_temp: float) -> str:
    """Convert Fahrenheit temperature to Celsius."""
    try:
        c_temp = (f_temp - 32) * 5/9
        return f"{f_temp}°F = {c_temp:.1f}°C"
    except Exception as e:
        return f"Ошибка конвертации: {str(e)}"

@tool
def get_current_time_in_timezone(timezone: str) -> str:
    """Get current local time in specified timezone."""
    try:
        tz = pytz.timezone(timezone)
        local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
        return f"Текущее время в {timezone}: {local_time}"
    except Exception as e:
        return f"Ошибка получения времени для часового пояса '{timezone}': {str(e)}"

@tool
def calculate_math(expression: str) -> str:
    """Calculate mathematical expressions safely."""
    try:
        allowed_chars = set('0123456789+-*/.() ')
        if all(c in allowed_chars for c in expression):
            result = eval(expression)
            return f"Результат: {result}"
        else:
            return "Используйте только цифры и +-*/.()"
    except:
        return "Ошибка в выражении"

@tool
def suggest_weather_sources(city: str) -> str:
    """Suggest reliable weather sources for a city."""
    sources = [
        f"Gismeteo: https://www.gismeteo.ru/weather-{city.lower()}-4368/",
        f"Yandex.Погода: https://yandex.ru/pogoda/{city.lower()}",
        f"Weather.com: https://weather.com/weather/today/l/{city}",
        f"AccuWeather: https://www.accuweather.com/ru/ru/{city.lower()}/weather-forecast"
    ]
    
    return f"Надежные источники погоды для {city}:\n" + "\n".join(sources)

# Используем локальную модель вместо HfApiModel
try:
    from smolagents import TransformersModel
    
    model = TransformersModel(
        model_id='Qwen/Qwen2.5-Coder-1.5B',
        max_tokens=2096,
        temperature=0.5
    )
except ImportError:
    # Если TransformersModel недоступен, используем LiteLLM
    from smolagents import LiteLLMModel
    model = LiteLLMModel(
        model_id='gpt-3.5-turbo',
        max_tokens=2096,
        temperature=0.5
    )

# Загружаем промпты, если файл существует, иначе создаем базовый шаблон
try:
    with open("prompts.yaml", 'r') as stream:
        prompt_templates = yaml.safe_load(stream)
except FileNotFoundError:
    prompt_templates = {
        "final_answer": {
            "pre_messages": "Based on my research: ",
            "post_messages": ""
        }
    }

if "final_answer" not in prompt_templates:
    prompt_templates["final_answer"] = {
        "pre_messages": "Based on my research: ",
        "post_messages": ""
    }
    
agent = CodeAgent(
    model=model,
    tools=[final_answer, web_search, get_weather, get_weather_detailed, convert_fahrenheit_to_celsius, get_current_time_in_timezone, calculate_math, suggest_weather_sources],
    max_steps=8,
    verbosity_level=0,
    grammar=None,
    planning_interval=None,
    name=None,
    description=None,
    prompt_templates=prompt_templates
)

# Простой консольный интерфейс вместо GradioUI
def main():
    print("🤖 ИИ-агент готов к работе!")
    print("Доступные функции: поиск в интернете, погода, время, математические вычисления")
    print("Введите 'выход' или 'exit' для завершения работы\n")
    
    while True:
        try:
            user_input = input("Ваш вопрос: ").strip()
            
            if user_input.lower() in ['выход', 'exit', 'quit']:
                print("До свидания!")
                break
                
            if not user_input:
                continue
                
            print("🤔 Думаю...")
            response = agent.run(user_input)
            print(f"🤖 Ответ: {response}\n")
            
        except KeyboardInterrupt:
            print("\nДо свидания!")
            break
        except Exception as e:
            print(f"❌ Произошла ошибка: {e}\n")

if __name__ == "__main__":
    main()