smart-bot-factory 0.3.7__py3-none-any.whl → 0.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of smart-bot-factory might be problematic. Click here for more details.
- smart_bot_factory/admin/__init__.py +7 -7
- smart_bot_factory/admin/admin_events.py +483 -383
- smart_bot_factory/admin/admin_logic.py +234 -158
- smart_bot_factory/admin/admin_manager.py +68 -53
- smart_bot_factory/admin/admin_tester.py +46 -40
- smart_bot_factory/admin/timeout_checker.py +201 -153
- smart_bot_factory/aiogram_calendar/__init__.py +11 -3
- smart_bot_factory/aiogram_calendar/common.py +12 -18
- smart_bot_factory/aiogram_calendar/dialog_calendar.py +126 -64
- smart_bot_factory/aiogram_calendar/schemas.py +49 -28
- smart_bot_factory/aiogram_calendar/simple_calendar.py +94 -50
- smart_bot_factory/analytics/analytics_manager.py +414 -392
- smart_bot_factory/cli.py +204 -148
- smart_bot_factory/config.py +123 -102
- smart_bot_factory/core/bot_utils.py +474 -332
- smart_bot_factory/core/conversation_manager.py +287 -200
- smart_bot_factory/core/decorators.py +1200 -755
- smart_bot_factory/core/message_sender.py +287 -266
- smart_bot_factory/core/router.py +170 -100
- smart_bot_factory/core/router_manager.py +121 -83
- smart_bot_factory/core/states.py +4 -3
- smart_bot_factory/creation/__init__.py +1 -1
- smart_bot_factory/creation/bot_builder.py +320 -242
- smart_bot_factory/creation/bot_testing.py +440 -365
- smart_bot_factory/dashboard/__init__.py +1 -3
- smart_bot_factory/event/__init__.py +2 -7
- smart_bot_factory/handlers/handlers.py +676 -472
- smart_bot_factory/integrations/openai_client.py +218 -168
- smart_bot_factory/integrations/supabase_client.py +948 -637
- smart_bot_factory/message/__init__.py +18 -22
- smart_bot_factory/router/__init__.py +2 -2
- smart_bot_factory/setup_checker.py +162 -126
- smart_bot_factory/supabase/__init__.py +1 -1
- smart_bot_factory/supabase/client.py +631 -515
- smart_bot_factory/utils/__init__.py +2 -3
- smart_bot_factory/utils/debug_routing.py +38 -27
- smart_bot_factory/utils/prompt_loader.py +153 -120
- smart_bot_factory/utils/user_prompt_loader.py +55 -56
- smart_bot_factory/utm_link_generator.py +123 -116
- {smart_bot_factory-0.3.7.dist-info → smart_bot_factory-0.3.9.dist-info}/METADATA +3 -1
- smart_bot_factory-0.3.9.dist-info/RECORD +59 -0
- smart_bot_factory-0.3.7.dist-info/RECORD +0 -59
- {smart_bot_factory-0.3.7.dist-info → smart_bot_factory-0.3.9.dist-info}/WHEEL +0 -0
- {smart_bot_factory-0.3.7.dist-info → smart_bot_factory-0.3.9.dist-info}/entry_points.txt +0 -0
- {smart_bot_factory-0.3.7.dist-info → smart_bot_factory-0.3.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,31 +2,33 @@
|
|
|
2
2
|
Менеджер роутеров для Smart Bot Factory
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from typing import Dict, List, Any, Optional
|
|
6
5
|
import logging
|
|
6
|
+
from typing import Any, Dict, List, Optional
|
|
7
|
+
|
|
7
8
|
from .router import EventRouter
|
|
8
9
|
|
|
9
10
|
logger = logging.getLogger(__name__)
|
|
10
11
|
|
|
12
|
+
|
|
11
13
|
class RouterManager:
|
|
12
14
|
"""
|
|
13
15
|
Менеджер для управления роутерами событий и их обработчиками
|
|
14
16
|
"""
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
def __init__(self):
|
|
17
19
|
self._routers: List[EventRouter] = []
|
|
18
20
|
self._combined_handlers: Dict[str, Dict[str, Any]] = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
"event_handlers": {},
|
|
22
|
+
"scheduled_tasks": {},
|
|
23
|
+
"global_handlers": {},
|
|
22
24
|
}
|
|
23
|
-
|
|
25
|
+
|
|
24
26
|
logger.info("🔄 Создан менеджер роутеров")
|
|
25
|
-
|
|
27
|
+
|
|
26
28
|
def register_router(self, router: EventRouter):
|
|
27
29
|
"""
|
|
28
30
|
Регистрирует роутер событий в менеджере
|
|
29
|
-
|
|
31
|
+
|
|
30
32
|
Args:
|
|
31
33
|
router: EventRouter для регистрации
|
|
32
34
|
"""
|
|
@@ -36,11 +38,11 @@ class RouterManager:
|
|
|
36
38
|
logger.info(f"✅ Зарегистрирован роутер: {router.name}")
|
|
37
39
|
else:
|
|
38
40
|
logger.warning(f"⚠️ Роутер {router.name} уже зарегистрирован")
|
|
39
|
-
|
|
41
|
+
|
|
40
42
|
def unregister_router(self, router: EventRouter):
|
|
41
43
|
"""
|
|
42
44
|
Отменяет регистрацию роутера событий
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
Args:
|
|
45
47
|
router: EventRouter для отмены регистрации
|
|
46
48
|
"""
|
|
@@ -50,131 +52,167 @@ class RouterManager:
|
|
|
50
52
|
logger.info(f"❌ Отменена регистрация роутера: {router.name}")
|
|
51
53
|
else:
|
|
52
54
|
logger.warning(f"⚠️ Роутер {router.name} не найден в зарегистрированных")
|
|
53
|
-
|
|
55
|
+
|
|
54
56
|
def _update_combined_handlers(self):
|
|
55
57
|
"""Обновляет объединенные обработчики всех роутеров"""
|
|
56
58
|
# Очищаем текущие обработчики
|
|
57
59
|
self._combined_handlers = {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
"event_handlers": {},
|
|
61
|
+
"scheduled_tasks": {},
|
|
62
|
+
"global_handlers": {},
|
|
61
63
|
}
|
|
62
|
-
|
|
63
|
-
logger.debug(
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
logger.debug(
|
|
66
|
+
f"🔍 RouterManager._update_combined_handlers(): обновляем обработчики для {len(self._routers)} роутеров"
|
|
67
|
+
)
|
|
68
|
+
|
|
65
69
|
# Собираем обработчики из всех роутеров
|
|
66
70
|
for router in self._routers:
|
|
67
71
|
logger.debug(f"🔍 Обрабатываем роутер: {router.name}")
|
|
68
|
-
|
|
72
|
+
|
|
69
73
|
# Обработчики событий
|
|
70
74
|
event_handlers = router.get_event_handlers()
|
|
71
|
-
logger.debug(
|
|
75
|
+
logger.debug(
|
|
76
|
+
f"🔍 Роутер {router.name}: {len(event_handlers)} обработчиков событий"
|
|
77
|
+
)
|
|
72
78
|
for event_type, handler_info in event_handlers.items():
|
|
73
|
-
if event_type in self._combined_handlers[
|
|
74
|
-
existing_router = self._combined_handlers[
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
if event_type in self._combined_handlers["event_handlers"]:
|
|
80
|
+
existing_router = self._combined_handlers["event_handlers"][
|
|
81
|
+
event_type
|
|
82
|
+
]["router"]
|
|
83
|
+
logger.warning(
|
|
84
|
+
f"⚠️ Конфликт обработчиков событий '{event_type}' между роутерами {existing_router} и {router.name}"
|
|
85
|
+
)
|
|
86
|
+
self._combined_handlers["event_handlers"][event_type] = handler_info
|
|
87
|
+
|
|
78
88
|
# Запланированные задачи
|
|
79
89
|
scheduled_tasks = router.get_scheduled_tasks()
|
|
80
|
-
logger.debug(
|
|
90
|
+
logger.debug(
|
|
91
|
+
f"🔍 Роутер {router.name}: {len(scheduled_tasks)} запланированных задач: {list(scheduled_tasks.keys())}"
|
|
92
|
+
)
|
|
81
93
|
for task_name, task_info in scheduled_tasks.items():
|
|
82
|
-
if task_name in self._combined_handlers[
|
|
83
|
-
existing_router = self._combined_handlers[
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
94
|
+
if task_name in self._combined_handlers["scheduled_tasks"]:
|
|
95
|
+
existing_router = self._combined_handlers["scheduled_tasks"][
|
|
96
|
+
task_name
|
|
97
|
+
]["router"]
|
|
98
|
+
logger.warning(
|
|
99
|
+
f"⚠️ Конфликт задач '{task_name}' между роутерами {existing_router} и {router.name}"
|
|
100
|
+
)
|
|
101
|
+
self._combined_handlers["scheduled_tasks"][task_name] = task_info
|
|
102
|
+
|
|
87
103
|
# Глобальные обработчики
|
|
88
104
|
global_handlers = router.get_global_handlers()
|
|
89
|
-
logger.debug(
|
|
105
|
+
logger.debug(
|
|
106
|
+
f"🔍 Роутер {router.name}: {len(global_handlers)} глобальных обработчиков"
|
|
107
|
+
)
|
|
90
108
|
for handler_type, handler_info in global_handlers.items():
|
|
91
|
-
if handler_type in self._combined_handlers[
|
|
92
|
-
existing_router = self._combined_handlers[
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
if handler_type in self._combined_handlers["global_handlers"]:
|
|
110
|
+
existing_router = self._combined_handlers["global_handlers"][
|
|
111
|
+
handler_type
|
|
112
|
+
]["router"]
|
|
113
|
+
logger.warning(
|
|
114
|
+
f"⚠️ Конфликт глобальных обработчиков '{handler_type}' между роутерами {existing_router} и {router.name}"
|
|
115
|
+
)
|
|
116
|
+
self._combined_handlers["global_handlers"][handler_type] = handler_info
|
|
117
|
+
|
|
118
|
+
logger.debug(
|
|
119
|
+
f"🔍 RouterManager._update_combined_handlers(): итого - {len(self._combined_handlers['scheduled_tasks'])} задач: {list(self._combined_handlers['scheduled_tasks'].keys())}"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
total_handlers = (
|
|
123
|
+
len(self._combined_handlers["event_handlers"])
|
|
124
|
+
+ len(self._combined_handlers["scheduled_tasks"])
|
|
125
|
+
+ len(self._combined_handlers["global_handlers"])
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
logger.info(
|
|
129
|
+
f"📊 Обновлены объединенные обработчики: {total_handlers} обработчиков из {len(self._routers)} роутеров"
|
|
130
|
+
)
|
|
131
|
+
|
|
104
132
|
def get_event_handlers(self) -> Dict[str, Dict[str, Any]]:
|
|
105
133
|
"""Получает все обработчики событий"""
|
|
106
|
-
return self._combined_handlers[
|
|
107
|
-
|
|
134
|
+
return self._combined_handlers["event_handlers"].copy()
|
|
135
|
+
|
|
108
136
|
def get_scheduled_tasks(self) -> Dict[str, Dict[str, Any]]:
|
|
109
137
|
"""Получает все запланированные задачи"""
|
|
110
|
-
tasks = self._combined_handlers[
|
|
111
|
-
logger.debug(
|
|
138
|
+
tasks = self._combined_handlers["scheduled_tasks"].copy()
|
|
139
|
+
logger.debug(
|
|
140
|
+
f"🔍 RouterManager.get_scheduled_tasks(): возвращаем {len(tasks)} задач: {list(tasks.keys())}"
|
|
141
|
+
)
|
|
112
142
|
return tasks
|
|
113
|
-
|
|
143
|
+
|
|
114
144
|
def get_global_handlers(self) -> Dict[str, Dict[str, Any]]:
|
|
115
145
|
"""Получает все глобальные обработчики"""
|
|
116
|
-
return self._combined_handlers[
|
|
117
|
-
|
|
146
|
+
return self._combined_handlers["global_handlers"].copy()
|
|
147
|
+
|
|
118
148
|
def get_all_handlers(self) -> Dict[str, Dict[str, Any]]:
|
|
119
149
|
"""Получает все обработчики всех типов"""
|
|
120
150
|
all_handlers = {}
|
|
121
|
-
all_handlers.update(self._combined_handlers[
|
|
122
|
-
all_handlers.update(self._combined_handlers[
|
|
123
|
-
all_handlers.update(self._combined_handlers[
|
|
151
|
+
all_handlers.update(self._combined_handlers["event_handlers"])
|
|
152
|
+
all_handlers.update(self._combined_handlers["scheduled_tasks"])
|
|
153
|
+
all_handlers.update(self._combined_handlers["global_handlers"])
|
|
124
154
|
return all_handlers
|
|
125
|
-
|
|
155
|
+
|
|
126
156
|
def get_handlers_for_prompt(self) -> str:
|
|
127
157
|
"""Возвращает описание всех обработчиков для добавления в промпт ИИ"""
|
|
128
158
|
prompt_parts: List[str] = []
|
|
129
|
-
|
|
159
|
+
|
|
130
160
|
if not any(self._combined_handlers.values()):
|
|
131
161
|
return ""
|
|
132
|
-
|
|
133
|
-
if self._combined_handlers[
|
|
162
|
+
|
|
163
|
+
if self._combined_handlers["event_handlers"]:
|
|
134
164
|
prompt_parts.append("ДОСТУПНЫЕ ОБРАБОТЧИКИ СОБЫТИЙ:")
|
|
135
|
-
for event_type, handler_info in self._combined_handlers[
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
165
|
+
for event_type, handler_info in self._combined_handlers[
|
|
166
|
+
"event_handlers"
|
|
167
|
+
].items():
|
|
168
|
+
router_name = handler_info.get("router", "unknown")
|
|
169
|
+
prompt_parts.append(
|
|
170
|
+
f"- {event_type}: {handler_info['name']} (роутер: {router_name})"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if self._combined_handlers["scheduled_tasks"]:
|
|
140
174
|
prompt_parts.append("\nДОСТУПНЫЕ ЗАДАЧИ ДЛЯ ПЛАНИРОВАНИЯ:")
|
|
141
|
-
for task_name, task_info in self._combined_handlers[
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
175
|
+
for task_name, task_info in self._combined_handlers[
|
|
176
|
+
"scheduled_tasks"
|
|
177
|
+
].items():
|
|
178
|
+
router_name = task_info.get("router", "unknown")
|
|
179
|
+
prompt_parts.append(
|
|
180
|
+
f"- {task_name}: {task_info['name']} (роутер: {router_name})"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if self._combined_handlers["global_handlers"]:
|
|
146
184
|
prompt_parts.append("\nДОСТУПНЫЕ ГЛОБАЛЬНЫЕ ОБРАБОТЧИКИ:")
|
|
147
|
-
for handler_type, handler_info in self._combined_handlers[
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
185
|
+
for handler_type, handler_info in self._combined_handlers[
|
|
186
|
+
"global_handlers"
|
|
187
|
+
].items():
|
|
188
|
+
router_name = handler_info.get("router", "unknown")
|
|
189
|
+
prompt_parts.append(
|
|
190
|
+
f"- {handler_type}: {handler_info['name']} (роутер: {router_name})"
|
|
191
|
+
)
|
|
192
|
+
|
|
151
193
|
return "\n".join(prompt_parts)
|
|
152
|
-
|
|
194
|
+
|
|
153
195
|
def get_router_by_name(self, name: str) -> Optional[EventRouter]:
|
|
154
196
|
"""Получает роутер событий по имени"""
|
|
155
197
|
for router in self._routers:
|
|
156
198
|
if router.name == name:
|
|
157
199
|
return router
|
|
158
200
|
return None
|
|
159
|
-
|
|
201
|
+
|
|
160
202
|
def get_router_stats(self) -> Dict[str, Any]:
|
|
161
203
|
"""Получает статистику по роутерам"""
|
|
162
|
-
stats = {
|
|
163
|
-
|
|
164
|
-
"routers": []
|
|
165
|
-
}
|
|
166
|
-
|
|
204
|
+
stats = {"total_routers": len(self._routers), "routers": []}
|
|
205
|
+
|
|
167
206
|
for router in self._routers:
|
|
168
207
|
router_stats = {
|
|
169
208
|
"name": router.name,
|
|
170
209
|
"event_handlers": len(router.get_event_handlers()),
|
|
171
210
|
"scheduled_tasks": len(router.get_scheduled_tasks()),
|
|
172
|
-
"global_handlers": len(router.get_global_handlers())
|
|
211
|
+
"global_handlers": len(router.get_global_handlers()),
|
|
173
212
|
}
|
|
174
213
|
stats["routers"].append(router_stats)
|
|
175
|
-
|
|
214
|
+
|
|
176
215
|
return stats
|
|
177
|
-
|
|
216
|
+
|
|
178
217
|
def __repr__(self):
|
|
179
218
|
return f"RouterManager(routers={len(self._routers)}, handlers={len(self.get_all_handlers())})"
|
|
180
|
-
|
smart_bot_factory/core/states.py
CHANGED
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
from aiogram.fsm.state import State, StatesGroup
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
class UserStates(StatesGroup):
|
|
8
9
|
waiting_for_message = State()
|
|
9
10
|
admin_chat = State() # пользователь в диалоге с админом
|
|
10
|
-
|
|
11
|
+
|
|
11
12
|
voice_confirmation = State() # ожидание подтверждения распознанного текста
|
|
12
13
|
voice_editing = State() # редактирование распознанного текста
|
|
13
14
|
|
|
15
|
+
|
|
14
16
|
class AdminStates(StatesGroup):
|
|
15
17
|
admin_mode = State()
|
|
16
18
|
in_conversation = State()
|
|
17
|
-
|
|
19
|
+
|
|
18
20
|
# Состояния для создания события
|
|
19
21
|
create_event_name = State()
|
|
20
22
|
create_event_date = State()
|
|
@@ -23,4 +25,3 @@ class AdminStates(StatesGroup):
|
|
|
23
25
|
create_event_message = State()
|
|
24
26
|
create_event_files = State()
|
|
25
27
|
create_event_confirm = State()
|
|
26
|
-
|