MADtoBAD commited on
Commit
87c390c
·
verified ·
1 Parent(s): 93ede06

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +225 -207
app.py CHANGED
@@ -1,223 +1,241 @@
1
- import gradio as gr
2
- from transformers import pipeline
3
- from ddgs import DDGS
4
- import re
5
-
6
- class ImprovedAIAgent:
7
- def __init__(self):
8
- print("Initializing Improved AI Agent...")
9
-
10
- # Используем более подходящую модель для вопросов и ответов
11
- self.model = pipeline(
12
- "text-generation",
13
- model="microsoft/DialoGPT-medium", # Более качественная чем small
14
- max_length=400,
15
- temperature=0.7,
16
- do_sample=True
17
- )
18
-
19
- # Инициализируем поиск
20
- self.ddgs = DDGS()
21
- print("AI Agent ready!")
22
 
23
- def needs_web_search(self, question):
24
- """Определяем, нужен ли поиск в интернете для этого вопроса"""
25
- question_lower = question.lower()
 
 
 
26
 
27
- # Ключевые слова, которые требуют актуальной информации
28
- search_keywords = [
29
- 'current', 'today', 'now', 'latest', 'recent', 'weather',
30
- 'news', '2024', '2023', 'update', 'breaking',
31
- 'how to', 'tutorial', 'guide', 'steps to'
32
- ]
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- # Вопросы, начинающиеся с what, who, when, where (фактологические)
35
- factual_patterns = [
36
- 'what is', 'who is', 'when did', 'where is', 'which country',
37
- 'capital of', 'population of', 'president of'
38
- ]
 
39
 
40
- return (any(keyword in question_lower for keyword in search_keywords) or
41
- any(question_lower.startswith(pattern) for pattern in factual_patterns))
42
-
43
- def search_web(self, query):
44
- """Поиск в интернете через DuckDuckGo"""
45
- try:
46
- results = list(self.ddgs.text(query, max_results=2))
47
- if results:
48
- # Собираем информацию из результатов
49
- combined_info = []
50
- for result in results:
51
- text = result.get('body', '')
52
- if text and len(text) > 20: # Фильтруем слишком короткие
53
- combined_info.append(text[:300]) # Ограничиваем длину
54
-
55
- if combined_info:
56
- return " ".join(combined_info)
57
- return None
58
- except Exception as e:
59
- print(f"Search error: {e}")
60
- return None
61
-
62
- def chat(self, message, history):
63
- """
64
- Основная функция для общения с агентом
65
- """
66
- print(f"User asked: {message}")
67
 
68
- try:
69
- # Определяем, нужен ли поиск в интернете
70
- if self.needs_web_search(message):
71
- search_result = self.search_web(message)
72
-
73
- if search_result:
74
- # Используем найденную информацию
75
- prompt = f"""Based on this information: {search_result}
76
-
77
- Please answer this question: {message}
78
-
79
- Provide a clear and accurate answer:"""
80
- else:
81
- # Если поиск не дал результатов
82
- prompt = f"""Please answer this question: {message}
83
-
84
- If you don't know the answer, please say so."""
85
- else:
86
- # Для общих вопросов используем обычный промпт
87
- prompt = f"User: {message}\nAssistant:"
88
-
89
- # Генерируем ответ
90
- response = self.model(
91
- prompt,
92
- max_length=500,
93
- num_return_sequences=1,
94
- temperature=0.7,
95
- do_sample=True,
96
- pad_token_id=50256,
97
- repetition_penalty=1.2
98
- )
99
-
100
- # Извлекаем ответ
101
- full_text = response[0]['generated_text']
102
-
103
- # Извлекаем только ответ ассистента
104
- if "Assistant:" in full_text:
105
- answer = full_text.split("Assistant:")[-1].strip()
106
- elif "answer:" in full_text.lower():
107
- # Ищем после "answer:"
108
- answer_match = re.search(r'answer:\s*(.*)', full_text, re.IGNORECASE)
109
- answer = answer_match.group(1).strip() if answer_match else full_text
110
- else:
111
- # Убираем промпт из ответа
112
- answer = full_text.replace(prompt, "").strip()
113
-
114
- # Очищаем ответ
115
- clean_response = self.clean_answer(answer)
116
 
117
- # Проверяем, не является ли ответ бессмысленным
118
- if self.is_nonsense_response(clean_response, message):
119
- clean_response = "I'm not sure about that. Could you provide more context or rephrase your question?"
120
 
121
- print(f"Assistant: {clean_response[:100]}...")
122
- return clean_response
123
-
124
- except Exception as e:
125
- print(f"Error: {e}")
126
- return "I'm here to help! What would you like to know?"
127
-
128
- def is_nonsense_response(self, response, question):
129
- """Проверяем, является ли ответ бессмысленным"""
130
- if not response or len(response) < 5:
131
- return True
132
-
133
- response_lower = response.lower()
134
- question_lower = question.lower()
135
 
136
- # Если ответ повторяет вопрос
137
- if question_lower in response_lower and len(response) < len(question) + 10:
138
- return True
139
-
140
- # Если ответ содержит явно неподходящие фразы
141
- nonsense_phrases = [
142
- 'the user asked', 'please answer', 'based on this information',
143
- 'provide a clear', 'i cannot answer', 'as an ai'
144
- ]
145
 
146
- if any(phrase in response_lower for phrase in nonsense_phrases):
147
- return True
 
148
 
149
- return False
150
-
151
- def clean_answer(self, answer):
152
- """
153
- Убираем техническую информацию из ответа агента
154
- """
155
- if not answer:
156
- return "I don't have an answer for that question."
157
-
158
- # Убираем технические фразы
159
- clean_patterns = [
160
- r'based on this information:.*?provide a clear answer:',
161
- r'please answer this question:.*?if you don\'t know',
162
- r'user:.*?assistant:',
163
- ]
164
-
165
- for pattern in clean_patterns:
166
- answer = re.sub(pattern, '', answer, flags=re.IGNORECASE | re.DOTALL)
167
-
168
- # Разбиваем на строки и фильтруем
169
- lines = answer.split('\n')
170
- clean_lines = []
171
-
172
- for line in lines:
173
- line = line.strip()
174
- if line and len(line) > 3:
175
- # Пропускаем технические строки
176
- if any(word in line.lower() for word in ['tool:', 'searching', 'step', 'using tool']):
177
- continue
178
- clean_lines.append(line)
179
-
180
- # Собираем обратно в текст
181
- result = ' '.join(clean_lines)
182
-
183
- # Убираем лишние пробелы
184
- result = re.sub(r'\s+', ' ', result).strip()
185
-
186
- # Если ответ слишком длинный, обрезаем
187
- if len(result) > 800:
188
- result = result[:797] + "..."
189
 
190
- return result if result else "I couldn't find a clear answer to that question."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- # Создаем экземпляр агента
193
- ai_agent = ImprovedAIAgent()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
- # Создаем интерфейс чата
196
- with gr.Blocks(title="My AI Assistant") as chat_interface:
197
- gr.Markdown("# My AI Assistant")
198
- gr.Markdown("Ask me anything! I can search the internet for current information.")
199
 
200
- # Создаем чат-интерфейс
201
- chatbot = gr.Chatbot(height=400)
202
- msg = gr.Textbox(
203
- label="Your question",
204
- placeholder="Ask me anything...",
205
- lines=2
206
- )
207
- clear_btn = gr.Button("Clear Chat")
 
 
 
 
208
 
209
- def respond(message, chat_history):
210
- # Получаем ответ от агента
211
- bot_response = ai_agent.chat(message, chat_history)
212
- # Добавляем в историю чата
213
- chat_history.append((message, bot_response))
214
- return "", chat_history
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
- # Обработчики событий
217
- msg.submit(respond, [msg, chatbot], [msg, chatbot])
218
- clear_btn.click(lambda: None, None, chatbot, queue=False)
219
-
220
- # Запускаем приложение
221
- if __name__ == "__main__":
222
- print("Starting AI Chat Assistant...")
223
- chat_interface.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smolagents import CodeAgent, HfApiModel, load_tool, tool, DuckDuckGoSearchTool
2
+ import datetime
3
+ import requests
4
+ import pytz
5
+ import yaml
6
+ import base64
7
+ import os
8
+ import io
9
+ from PIL import Image
10
+ from tools.final_answer import FinalAnswerTool
11
+ from Gradio_UI import GradioUI
12
+
13
+ # 1. функции-инструменты
 
 
 
 
 
 
 
 
14
 
15
+ @tool
16
+ def web_search(query: str) -> str:
17
+ """Search the web for information using DuckDuckGo.
18
+
19
+ Args:
20
+ query: The search query to look up
21
 
22
+ Returns:
23
+ Search results from DuckDuckGo
24
+ """
25
+ try:
26
+ search_tool = DuckDuckGoSearchTool()
27
+ results = search_tool(query)
28
+ if not results or "No results found" in results:
29
+ return f"Поиск не дал результатов для запроса: '{query}'. Попробуйте другой запрос."
30
+ return f"**Результаты поиска по '{query}':**\n\n{results}"
31
+ except Exception as e:
32
+ return f"Ошибка поиска: {str(e)}"
33
+
34
+ @tool
35
+ def get_weather(city: str) -> str:
36
+ """Get current weather for a city using reliable weather services.
37
+
38
+ Args:
39
+ city: The name of the city to get weather for (e.g., 'Moscow', 'London')
40
 
41
+ Returns:
42
+ Current weather information in Celsius
43
+ """
44
+ try:
45
+ url = f"https://wttr.in/{city}?format=%C+%t+%h+%w&m&lang=ru"
46
+ response = requests.get(url, timeout=10)
47
 
48
+ if response.status_code == 200 and response.text.strip():
49
+ data = response.text.strip()
50
+ if '°F' in data:
51
+ data = data.replace('°F', '°C')
52
+ return f"Погода в {city}:\n{data}"
53
+
54
+ url2 = f"https://wttr.in/{city}?format=%C+%t+%h+%w+%P&m&lang=ru"
55
+ response2 = requests.get(url2, timeout=10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ if response2.status_code == 200 and response2.text.strip():
58
+ data = response2.text.strip()
59
+ if '°F' in data:
60
+ data = data.replace('°F', '°C')
61
+ return f"Погода в {city}:\n{data}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
+ return f"Данные о погоде в {city} временно недоступны. Попробуйте позже или проверьте на сайте gismeteo.ru"
 
 
64
 
65
+ except Exception as e:
66
+ return f"Ошибка при получении погоды: {str(e)}"
67
+
68
+ @tool
69
+ def get_weather_detailed(city: str) -> str:
70
+ """Get detailed weather forecast for a city.
71
+
72
+ Args:
73
+ city: The name of the city
 
 
 
 
 
74
 
75
+ Returns:
76
+ Detailed weather information in Celsius
77
+ """
78
+ try:
79
+ url = f"https://wttr.in/{city}?m&lang=ru"
80
+ response = requests.get(url, timeout=10)
 
 
 
81
 
82
+ if response.status_code == 200:
83
+ lines = response.text.split('\n')
84
+ short_forecast = '\n'.join(lines[:8]) # Первые 8 строк
85
 
86
+ short_forecast = short_forecast.replace('°F', '°C')
87
+ return f"Подробный прогноз для {city}:\n{short_forecast}"
88
+ else:
89
+ return f"Не удалось получить подробный прогноз для {city}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
+ except Exception as e:
92
+ return f"Ошибка: {str(e)}"
93
+
94
+ @tool
95
+ def get_current_time() -> str:
96
+ """Get current local time.
97
+
98
+ Returns:
99
+ Current date and time
100
+ """
101
+ try:
102
+ current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
103
+ return f"Текущее время: {current_time}"
104
+ except Exception as e:
105
+ return f"Ошибка получения времени: {str(e)}"
106
+
107
+ @tool
108
+ def get_current_time_in_timezone(timezone: str) -> str:
109
+ """Get current local time in specified timezone.
110
+
111
+ Args:
112
+ timezone: A valid timezone (e.g., 'America/New_York', 'Europe/Moscow')
113
+
114
+ Returns:
115
+ Current time in the specified timezone
116
+ """
117
+ try:
118
+ tz = pytz.timezone(timezone)
119
+ local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
120
+ return f"Текущее время в {timezone}: {local_time}"
121
+ except Exception as e:
122
+ return f"Ошибка получения времени для часового пояса '{timezone}': {str(e)}"
123
+
124
+ @tool
125
+ def how_are_you() -> str:
126
+ """Answer questions about how you are doing.
127
+
128
+ Returns:
129
+ Friendly response about current status
130
+ """
131
+ responses = [
132
+ "У меня всё отлично! Готов помочь вам с любыми вопросами.",
133
+ "Прекрасно себя чувствую! Что хотели бы узнать?",
134
+ "Всё хорошо, спасибо! Чем могу быть полезен?",
135
+ "Отлично! Готов к работе и жду ваших вопросов.",
136
+ "Замечательно! Как ваши дела?"
137
+ ]
138
+ import random
139
+ return random.choice(responses)
140
+
141
+ @tool
142
+ def what_are_you_doing() -> str:
143
+ """Answer questions about what you are currently doing.
144
+
145
+ Returns:
146
+ Description of current activities
147
+ """
148
+ responses = [
149
+ "Я общаюсь с вами и готов помочь с поиском информации!",
150
+ "В данный момент я помогаю пользователям находить ответы на их вопросы.",
151
+ "Я работаю ассистентом - ищу информацию в интернете, сообщаю о погоде и текущем времени.",
152
+ "Сейчас я здесь, чтобы помочь вам! Чем могу быть полезен?",
153
+ "Я анализирую ваш запрос и готовлю полезный ответ."
154
+ ]
155
+ import random
156
+ return random.choice(responses)
157
 
158
+ @tool
159
+ def calculate_math(expression: str) -> str:
160
+ """Calculate mathematical expressions safely.
161
+
162
+ Args:
163
+ expression: A mathematical expression (e.g., '2+2', '5*3/2')
164
+
165
+ Returns:
166
+ Result of the calculation
167
+ """
168
+ try:
169
+ allowed_chars = set('0123456789+-*/.() ')
170
+ if all(c in allowed_chars for c in expression):
171
+ result = eval(expression)
172
+ return f"Результат: {result}"
173
+ else:
174
+ return "Используйте только цифры и +-*/.()"
175
+ except:
176
+ return "Ошибка в выражении"
177
 
178
+ @tool
179
+ def suggest_weather_sources(city: str) -> str:
180
+ """Suggest reliable weather sources for a city.
 
181
 
182
+ Args:
183
+ city: The name of the city
184
+
185
+ Returns:
186
+ List of reliable weather sources
187
+ """
188
+ sources = [
189
+ f"Gismeteo: https://www.gismeteo.ru/weather-{city.lower()}-4368/",
190
+ f"Yandex.Погода: https://yandex.ru/pogoda/{city.lower()}",
191
+ f"Weather.com: https://weather.com/weather/today/l/{city}",
192
+ f"AccuWeather: https://www.accuweather.com/ru/ru/{city.lower()}/weather-forecast"
193
+ ]
194
 
195
+ return f"Надежные источники погоды для {city}:\n" + "\n".join(sources)
196
+
197
+ # 2. остальные объекты
198
+
199
+ final_answer = FinalAnswerTool()
200
+
201
+ model = HfApiModel(
202
+ max_tokens=2096,
203
+ temperature=0.5,
204
+ model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
205
+ custom_role_conversions=None,
206
+ )
207
+
208
+ with open("prompts.yaml", 'r') as stream:
209
+ prompt_templates = yaml.safe_load(stream)
210
+
211
+ if "final_answer" not in prompt_templates:
212
+ prompt_templates["final_answer"] = {
213
+ "pre_messages": "Based on my research: ",
214
+ "post_messages": ""
215
+ }
216
 
217
+ # Создаем агента с новым именем и обновленными инструментами
218
+ agent = CodeAgent(
219
+ model=model,
220
+ tools=[
221
+ final_answer,
222
+ web_search,
223
+ get_weather,
224
+ get_weather_detailed,
225
+ get_current_time,
226
+ get_current_time_in_timezone,
227
+ how_are_you,
228
+ what_are_you_doing,
229
+ calculate_math,
230
+ suggest_weather_sources
231
+ ],
232
+ max_steps=8,
233
+ verbosity_level=1,
234
+ grammar=None,
235
+ planning_interval=None,
236
+ name="WeatherTimeBot", # Новое имя агента
237
+ description="Ассистент для поиска информации, прогноза погоды и определения времени",
238
+ prompt_templates=prompt_templates
239
+ )
240
+
241
+ GradioUI(agent).launch()