smart-bot-factory 0.1.2__py3-none-any.whl → 0.1.4__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.

Files changed (61) hide show
  1. smart_bot_factory/__init__.py +33 -0
  2. smart_bot_factory/admin/__init__.py +16 -0
  3. smart_bot_factory/admin/admin_logic.py +430 -0
  4. smart_bot_factory/admin/admin_manager.py +141 -0
  5. smart_bot_factory/admin/admin_migration.sql +136 -0
  6. smart_bot_factory/admin/admin_tester.py +151 -0
  7. smart_bot_factory/admin/timeout_checker.py +499 -0
  8. smart_bot_factory/analytics/__init__.py +7 -0
  9. smart_bot_factory/analytics/analytics_manager.py +355 -0
  10. smart_bot_factory/cli.py +768 -0
  11. smart_bot_factory/config.py +235 -0
  12. smart_bot_factory/configs/growthmed-helper/env_example.txt +1 -0
  13. smart_bot_factory/configs/growthmed-helper/prompts/1sales_context.txt +9 -0
  14. smart_bot_factory/configs/growthmed-helper/prompts/2product_info.txt +582 -0
  15. smart_bot_factory/configs/growthmed-helper/prompts/3objection_handling.txt +66 -0
  16. smart_bot_factory/configs/growthmed-helper/prompts/final_instructions.txt +232 -0
  17. smart_bot_factory/configs/growthmed-helper/prompts/help_message.txt +28 -0
  18. smart_bot_factory/configs/growthmed-helper/prompts/welcome_message.txt +7 -0
  19. smart_bot_factory/configs/growthmed-helper/welcome_file/welcome_file_msg.txt +16 -0
  20. smart_bot_factory/configs/growthmed-helper/welcome_file//342/225/250/320/267/342/225/250/342/225/241/342/225/250/342/225/221 /342/225/250/342/225/227/342/225/250/342/225/225/342/225/244/320/221/342/225/244/320/222 /342/225/250/342/224/220/342/225/250/342/225/233 152/342/225/250/320/264/342/225/250/320/247 /342/225/250/342/225/225 323/342/225/250/320/264/342/225/250/320/247 /342/225/250/342/224/244/342/225/250/342/225/227/342/225/244/320/237 /342/225/250/342/225/235/342/225/250/342/225/241/342/225/250/342/224/244/342/225/250/342/225/225/342/225/244/320/226/342/225/250/342/225/225/342/225/250/342/225/234/342/225/244/320/233.pdf +0 -0
  21. smart_bot_factory/configs/growthmed-october-24/prompts/1sales_context.txt +16 -0
  22. smart_bot_factory/configs/growthmed-october-24/prompts/2product_info.txt +582 -0
  23. smart_bot_factory/configs/growthmed-october-24/prompts/3objection_handling.txt +66 -0
  24. smart_bot_factory/configs/growthmed-october-24/prompts/final_instructions.txt +212 -0
  25. smart_bot_factory/configs/growthmed-october-24/prompts/help_message.txt +28 -0
  26. smart_bot_factory/configs/growthmed-october-24/prompts/welcome_message.txt +8 -0
  27. smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064229.txt +818 -0
  28. smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064335.txt +32 -0
  29. smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064638.txt +35 -0
  30. smart_bot_factory/configs/growthmed-october-24/tests/quick_scenarios.yaml +66 -0
  31. smart_bot_factory/configs/growthmed-october-24/tests/realistic_scenarios.yaml +108 -0
  32. smart_bot_factory/configs/growthmed-october-24/tests/scenario_examples.yaml +46 -0
  33. smart_bot_factory/configs/growthmed-october-24/welcome_file/welcome_file_msg.txt +16 -0
  34. smart_bot_factory/configs/growthmed-october-24/welcome_file//342/225/250/320/267/342/225/250/342/225/241/342/225/250/342/225/221 /342/225/250/342/225/227/342/225/250/342/225/225/342/225/244/320/221/342/225/244/320/222 /342/225/250/342/224/220/342/225/250/342/225/233 152/342/225/250/320/264/342/225/250/320/247 /342/225/250/342/225/225 323/342/225/250/320/264/342/225/250/320/247 /342/225/250/342/224/244/342/225/250/342/225/227/342/225/244/320/237 /342/225/250/342/225/235/342/225/250/342/225/241/342/225/250/342/224/244/342/225/250/342/225/225/342/225/244/320/226/342/225/250/342/225/225/342/225/250/342/225/234/342/225/244/320/233.pdf +0 -0
  35. smart_bot_factory/core/__init__.py +22 -0
  36. smart_bot_factory/core/bot_utils.py +703 -0
  37. smart_bot_factory/core/conversation_manager.py +536 -0
  38. smart_bot_factory/core/decorators.py +230 -0
  39. smart_bot_factory/core/message_sender.py +249 -0
  40. smart_bot_factory/core/states.py +14 -0
  41. smart_bot_factory/creation/__init__.py +8 -0
  42. smart_bot_factory/creation/bot_builder.py +329 -0
  43. smart_bot_factory/creation/bot_testing.py +986 -0
  44. smart_bot_factory/database/database_structure.sql +57 -0
  45. smart_bot_factory/database/schema.sql +1094 -0
  46. smart_bot_factory/handlers/handlers.py +583 -0
  47. smart_bot_factory/integrations/__init__.py +9 -0
  48. smart_bot_factory/integrations/openai_client.py +435 -0
  49. smart_bot_factory/integrations/supabase_client.py +592 -0
  50. smart_bot_factory/setup_checker.py +476 -0
  51. smart_bot_factory/utils/__init__.py +9 -0
  52. smart_bot_factory/utils/debug_routing.py +103 -0
  53. smart_bot_factory/utils/prompt_loader.py +427 -0
  54. smart_bot_factory/utm_link_generator.py +106 -0
  55. smart_bot_factory-0.1.4.dist-info/METADATA +126 -0
  56. smart_bot_factory-0.1.4.dist-info/RECORD +59 -0
  57. smart_bot_factory-0.1.4.dist-info/licenses/LICENSE +24 -0
  58. smart_bot_factory-0.1.2.dist-info/METADATA +0 -31
  59. smart_bot_factory-0.1.2.dist-info/RECORD +0 -4
  60. {smart_bot_factory-0.1.2.dist-info → smart_bot_factory-0.1.4.dist-info}/WHEEL +0 -0
  61. {smart_bot_factory-0.1.2.dist-info → smart_bot_factory-0.1.4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,329 @@
1
+ """
2
+ Строитель ботов для Smart Bot Factory
3
+ """
4
+
5
+ import os
6
+ import sys
7
+ import asyncio
8
+ import logging
9
+ from pathlib import Path
10
+ from typing import Optional, Dict, Any, List
11
+
12
+ from ..config import Config
13
+ from ..integrations.openai_client import OpenAIClient
14
+ from ..integrations.supabase_client import SupabaseClient
15
+ from ..core.conversation_manager import ConversationManager
16
+ from ..admin.admin_manager import AdminManager
17
+ from ..utils.prompt_loader import PromptLoader
18
+ from ..core.decorators import get_handlers_for_prompt
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ class BotBuilder:
23
+ """
24
+ Строитель ботов, который использует существующие файлы проекта
25
+ и добавляет новые возможности через декораторы
26
+ """
27
+
28
+ def __init__(self, bot_id: str, config_dir: Optional[Path] = None):
29
+ """
30
+ Инициализация строителя бота
31
+
32
+ Args:
33
+ bot_id: Идентификатор бота
34
+ config_dir: Путь к директории конфигурации (по умолчанию configs/bot_id)
35
+ """
36
+ self.bot_id = bot_id
37
+ self.config_dir = config_dir or Path("bots") / bot_id
38
+
39
+ # Компоненты бота
40
+ self.config: Optional[Config] = None
41
+ self.openai_client: Optional[OpenAIClient] = None
42
+ self.supabase_client: Optional[SupabaseClient] = None
43
+ self.conversation_manager: Optional[ConversationManager] = None
44
+ self.admin_manager: Optional[AdminManager] = None
45
+ self.prompt_loader: Optional[PromptLoader] = None
46
+
47
+ # Флаги инициализации
48
+ self._initialized = False
49
+
50
+ logger.info(f"🏗️ Создан BotBuilder для бота: {bot_id}")
51
+
52
+ async def build(self) -> 'BotBuilder':
53
+ """
54
+ Строит и инициализирует все компоненты бота
55
+
56
+ Returns:
57
+ BotBuilder: Возвращает self для цепочки вызовов
58
+ """
59
+ if self._initialized:
60
+ logger.warning(f"⚠️ Бот {self.bot_id} уже инициализирован")
61
+ return self
62
+
63
+ try:
64
+ logger.info(f"🚀 Начинаем сборку бота {self.bot_id}")
65
+
66
+ # 1. Инициализируем конфигурацию
67
+ await self._init_config()
68
+
69
+ # 2. Инициализируем клиенты
70
+ await self._init_clients()
71
+
72
+ # 3. Инициализируем менеджеры
73
+ await self._init_managers()
74
+
75
+ # 4. Обновляем промпты с информацией о доступных инструментах
76
+ await self._update_prompts_with_tools()
77
+
78
+ self._initialized = True
79
+ logger.info(f"✅ Бот {self.bot_id} успешно собран и готов к работе")
80
+
81
+ return self
82
+
83
+ except Exception as e:
84
+ logger.error(f"❌ Ошибка при сборке бота {self.bot_id}: {e}")
85
+ raise
86
+
87
+ async def _init_config(self):
88
+ """Инициализация конфигурации"""
89
+ logger.info(f"⚙️ Инициализация конфигурации для {self.bot_id}")
90
+
91
+ # Устанавливаем BOT_ID в переменные окружения
92
+ os.environ['BOT_ID'] = self.bot_id
93
+
94
+ # Загружаем .env файл если существует
95
+ env_file = self.config_dir / ".env"
96
+ if env_file.exists():
97
+ from dotenv import load_dotenv
98
+ load_dotenv(env_file)
99
+ logger.info(f"📄 Загружен .env файл: {env_file}")
100
+
101
+ # Устанавливаем путь к промптам относительно папки бота
102
+ prompts_subdir = os.environ.get("PROMT_FILES_DIR", "prompts")
103
+ logger.info(f"🔍 PROMT_FILES_DIR из .env: {prompts_subdir}")
104
+
105
+ prompts_dir = self.config_dir / prompts_subdir
106
+ logger.info(f"🔍 Путь к промптам: {prompts_dir}")
107
+ logger.info(f"🔍 Существует ли папка: {prompts_dir.exists()}")
108
+
109
+ # ВАЖНО: Устанавливаем правильный путь ДО создания Config
110
+ os.environ["PROMT_FILES_DIR"] = str(prompts_dir)
111
+ logger.info(f"📁 Установлен путь к промптам: {prompts_dir}")
112
+
113
+ # Создаем конфигурацию
114
+ logger.info(f"🔍 PROMT_FILES_DIR перед созданием Config: {os.environ.get('PROMT_FILES_DIR')}")
115
+ self.config = Config()
116
+ logger.info(f"✅ Конфигурация инициализирована")
117
+
118
+ async def _init_clients(self):
119
+ """Инициализация клиентов"""
120
+ logger.info(f"🔌 Инициализация клиентов для {self.bot_id}")
121
+
122
+ # OpenAI клиент
123
+ self.openai_client = OpenAIClient(
124
+ api_key=self.config.OPENAI_API_KEY,
125
+ model=self.config.OPENAI_MODEL,
126
+ max_tokens=self.config.OPENAI_MAX_TOKENS,
127
+ temperature=self.config.OPENAI_TEMPERATURE
128
+ )
129
+ logger.info(f"✅ OpenAI клиент инициализирован")
130
+
131
+ # Supabase клиент
132
+ self.supabase_client = SupabaseClient(
133
+ url=self.config.SUPABASE_URL,
134
+ key=self.config.SUPABASE_KEY,
135
+ bot_id=self.bot_id
136
+ )
137
+ await self.supabase_client.initialize()
138
+ logger.info(f"✅ Supabase клиент инициализирован")
139
+
140
+ async def _init_managers(self):
141
+ """Инициализация менеджеров"""
142
+ logger.info(f"👥 Инициализация менеджеров для {self.bot_id}")
143
+
144
+ # Admin Manager
145
+ self.admin_manager = AdminManager(self.config, self.supabase_client)
146
+ await self.admin_manager.sync_admins_from_config()
147
+ logger.info(f"✅ Admin Manager инициализирован")
148
+
149
+ # Conversation Manager
150
+ self.conversation_manager = ConversationManager(self.supabase_client, self.admin_manager)
151
+ logger.info(f"✅ Conversation Manager инициализирован")
152
+
153
+ # Prompt Loader
154
+ self.prompt_loader = PromptLoader(
155
+ prompts_dir=self.config.PROMT_FILES_DIR
156
+ )
157
+ await self.prompt_loader.validate_prompts()
158
+ logger.info(f"✅ Prompt Loader инициализирован")
159
+
160
+ async def _update_prompts_with_tools(self):
161
+ """
162
+ Обновляет промпты информацией о доступных обработчиках событий
163
+ """
164
+ logger.info(f"🔧 Обновление промптов с информацией об обработчиках")
165
+
166
+ # Получаем информацию о доступных обработчиках
167
+ event_handlers_info = get_handlers_for_prompt()
168
+
169
+ # Если есть обработчики, добавляем их в системный промпт
170
+ if event_handlers_info:
171
+ # Сохраняем информацию о обработчиках для использования в handlers.py
172
+ self._tools_prompt = event_handlers_info
173
+
174
+ logger.info(f"✅ Промпты обновлены с информацией об обработчиках")
175
+ else:
176
+ self._tools_prompt = ""
177
+ logger.info(f"ℹ️ Нет зарегистрированных обработчиков")
178
+
179
+ def get_tools_prompt(self) -> str:
180
+ """Возвращает промпт с информацией об инструментах"""
181
+ return getattr(self, '_tools_prompt', '')
182
+
183
+ def get_status(self) -> Dict[str, Any]:
184
+ """Возвращает статус бота"""
185
+ return {
186
+ "bot_id": self.bot_id,
187
+ "initialized": self._initialized,
188
+ "config_dir": str(self.config_dir),
189
+ "components": {
190
+ "config": self.config is not None,
191
+ "openai_client": self.openai_client is not None,
192
+ "supabase_client": self.supabase_client is not None,
193
+ "conversation_manager": self.conversation_manager is not None,
194
+ "admin_manager": self.admin_manager is not None,
195
+ "prompt_loader": self.prompt_loader is not None
196
+ },
197
+ "tools": {
198
+ "event_handlers": len(get_handlers_for_prompt().split('\n')) if get_handlers_for_prompt() else 0
199
+ }
200
+ }
201
+
202
+ async def start(self):
203
+ """
204
+ Запускает бота (аналог main.py)
205
+ """
206
+ if not self._initialized:
207
+ raise RuntimeError(f"Бот {self.bot_id} не инициализирован. Вызовите build() сначала")
208
+
209
+ logger.info(f"🚀 Запускаем бота {self.bot_id}")
210
+
211
+ try:
212
+ # Импортируем необходимые компоненты
213
+ from aiogram import Bot, Dispatcher
214
+ from aiogram.fsm.storage.memory import MemoryStorage
215
+
216
+ # Создаем бота и диспетчер
217
+ bot = Bot(token=self.config.TELEGRAM_BOT_TOKEN)
218
+ storage = MemoryStorage()
219
+ dp = Dispatcher(storage=storage)
220
+
221
+ # Инициализируем базу данных
222
+ await self.supabase_client.initialize()
223
+
224
+ # Синхронизируем админов из конфигурации
225
+ await self.admin_manager.sync_admins_from_config()
226
+
227
+ # Проверяем доступность промптов
228
+ prompts_status = await self.prompt_loader.validate_prompts()
229
+ logger.info(f"Статус промптов: {prompts_status}")
230
+
231
+ # Устанавливаем глобальные переменные ДО импорта обработчиков
232
+ import sys
233
+ import importlib
234
+
235
+ # Устанавливаем глобальные переменные в модулях handlers и admin_logic
236
+ try:
237
+ handlers_module = importlib.import_module('smart_bot_factory.handlers.handlers')
238
+ handlers_module.config = self.config
239
+ handlers_module.bot = bot
240
+ handlers_module.dp = dp
241
+ handlers_module.supabase_client = self.supabase_client
242
+ handlers_module.openai_client = self.openai_client
243
+ handlers_module.prompt_loader = self.prompt_loader
244
+ handlers_module.admin_manager = self.admin_manager
245
+ handlers_module.conversation_manager = self.conversation_manager
246
+ logger.info("✅ Глобальные переменные установлены в handlers")
247
+ except Exception as e:
248
+ logger.warning(f"⚠️ Не удалось установить глобальные переменные в handlers: {e}")
249
+
250
+ try:
251
+ admin_logic_module = importlib.import_module('smart_bot_factory.admin.admin_logic')
252
+ admin_logic_module.config = self.config
253
+ admin_logic_module.bot = bot
254
+ admin_logic_module.dp = dp
255
+ admin_logic_module.supabase_client = self.supabase_client
256
+ admin_logic_module.openai_client = self.openai_client
257
+ admin_logic_module.prompt_loader = self.prompt_loader
258
+ admin_logic_module.admin_manager = self.admin_manager
259
+ admin_logic_module.conversation_manager = self.conversation_manager
260
+ logger.info("✅ Глобальные переменные установлены в admin_logic")
261
+ except Exception as e:
262
+ logger.warning(f"⚠️ Не удалось установить глобальные переменные в admin_logic: {e}")
263
+
264
+ # Также устанавливаем в bot_utils
265
+ try:
266
+ bot_utils_module = importlib.import_module('smart_bot_factory.core.bot_utils')
267
+ bot_utils_module.config = self.config
268
+ bot_utils_module.bot = bot
269
+ bot_utils_module.dp = dp
270
+ bot_utils_module.supabase_client = self.supabase_client
271
+ bot_utils_module.openai_client = self.openai_client
272
+ bot_utils_module.prompt_loader = self.prompt_loader
273
+ bot_utils_module.admin_manager = self.admin_manager
274
+ bot_utils_module.conversation_manager = self.conversation_manager
275
+ logger.info("✅ Глобальные переменные установлены в bot_utils")
276
+ except Exception as e:
277
+ logger.warning(f"⚠️ Не удалось установить глобальные переменные в bot_utils: {e}")
278
+
279
+ # Также устанавливаем в debug_routing
280
+ try:
281
+ from ..utils import debug_routing
282
+ debug_routing.config = self.config
283
+ debug_routing.bot = bot
284
+ debug_routing.dp = dp
285
+ debug_routing.supabase_client = self.supabase_client
286
+ debug_routing.openai_client = self.openai_client
287
+ debug_routing.prompt_loader = self.prompt_loader
288
+ debug_routing.admin_manager = self.admin_manager
289
+ debug_routing.conversation_manager = self.conversation_manager
290
+ logger.info("✅ Глобальные переменные установлены в debug_routing")
291
+ except Exception as e:
292
+ logger.warning(f"⚠️ Не удалось установить глобальные переменные в debug_routing: {e}")
293
+
294
+ # Теперь импортируем и настраиваем обработчики
295
+ from ..handlers.handlers import setup_handlers
296
+ from ..admin.admin_logic import setup_admin_handlers
297
+ from ..core.bot_utils import setup_utils_handlers
298
+
299
+ # Настраиваем обработчики запросов
300
+ setup_utils_handlers(dp) # Утилитарные команды (/status, /help)
301
+ setup_admin_handlers(dp) # Админские команды (/админ, /стат, /чат)
302
+ setup_handlers(dp) # Основные пользовательские обработчики
303
+
304
+ # Логируем информацию о запуске
305
+ logger.info(f"✅ Бот {self.bot_id} запущен и готов к работе!")
306
+ logger.info(f" 📊 Изоляция данных: bot_id = {self.config.BOT_ID}")
307
+ logger.info(f" 👑 Админов настроено: {len(self.config.ADMIN_TELEGRAM_IDS)}")
308
+ logger.info(f" 📝 Загружено промптов: {len(self.config.PROMPT_FILES)}")
309
+
310
+ # Четкое сообщение о запуске
311
+ print(f"\nБОТ {self.bot_id.upper()} УСПЕШНО ЗАПУЩЕН!")
312
+ print(f"Telegram Bot ID: {self.config.BOT_ID}")
313
+ print(f"Админов: {len(self.config.ADMIN_TELEGRAM_IDS)}")
314
+ print(f"Промптов: {len(self.config.PROMPT_FILES)}")
315
+ print(f"Ожидание сообщений...")
316
+ print(f"Для остановки нажмите Ctrl+C\n")
317
+
318
+ # Запуск polling (бесконечная обработка сообщений)
319
+ await dp.start_polling(bot)
320
+
321
+ except Exception as e:
322
+ logger.error(f"❌ Ошибка при запуске бота {self.bot_id}: {e}")
323
+ import traceback
324
+ logger.error(f"Стек ошибки: {traceback.format_exc()}")
325
+ raise
326
+ finally:
327
+ # Очистка ресурсов при завершении
328
+ if 'bot' in locals():
329
+ await bot.session.close()