smart-bot-factory 0.1.0__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.

@@ -0,0 +1,246 @@
1
+ """
2
+ Интеграция с Telegram API через существующие функции
3
+ """
4
+
5
+ import logging
6
+ from typing import Optional, Dict, Any, List
7
+ from aiogram import Bot
8
+ from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
9
+ from aiogram.utils.media_group import MediaGroupBuilder
10
+ from aiogram.types import FSInputFile
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ class TelegramIntegration:
15
+ """Интеграция с Telegram API через существующие функции из bot_utils.py"""
16
+
17
+ def __init__(self, bot_token: str):
18
+ """
19
+ Инициализация интеграции
20
+
21
+ Args:
22
+ bot_token: Токен Telegram бота
23
+ """
24
+ self.bot = Bot(token=bot_token)
25
+ self._bot_token = bot_token
26
+
27
+ async def send_message(
28
+ self,
29
+ user_id: int,
30
+ text: str,
31
+ parse_mode: Optional[str] = None,
32
+ reply_markup: Optional[InlineKeyboardMarkup] = None,
33
+ files_list: List[str] = None,
34
+ directories_list: List[str] = None
35
+ ) -> Dict[str, Any]:
36
+ """
37
+ Отправляет сообщение пользователю через существующую функцию send_message
38
+
39
+ Args:
40
+ user_id: ID пользователя в Telegram
41
+ text: Текст сообщения
42
+ parse_mode: Режим парсинга (Markdown, HTML, None)
43
+ reply_markup: Клавиатура для сообщения
44
+ files_list: Список файлов для отправки
45
+ directories_list: Список каталогов для отправки
46
+
47
+ Returns:
48
+ Результат отправки
49
+ """
50
+ try:
51
+ # Создаем фиктивное сообщение для использования существующей функции
52
+ from aiogram.types import User, Chat
53
+ from aiogram.types import Message as MessageType
54
+
55
+ # Создаем фиктивного пользователя
56
+ fake_user = User(
57
+ id=user_id,
58
+ is_bot=False,
59
+ first_name="User"
60
+ )
61
+
62
+ # Создаем фиктивный чат
63
+ fake_chat = Chat(
64
+ id=user_id,
65
+ type="private"
66
+ )
67
+
68
+ # Создаем фиктивное сообщение
69
+ fake_message = MessageType(
70
+ message_id=1,
71
+ from_user=fake_user,
72
+ chat=fake_chat,
73
+ date=0,
74
+ content_type="text",
75
+ text=""
76
+ )
77
+
78
+ # Импортируем существующую функцию
79
+ from ..integrations import send_message
80
+
81
+ # Используем существующую функцию
82
+ await send_message(
83
+ fake_message,
84
+ text,
85
+ files_list=files_list or [],
86
+ directories_list=directories_list or [],
87
+ **({"parse_mode": parse_mode} if parse_mode else {}),
88
+ **({"reply_markup": reply_markup} if reply_markup else {})
89
+ )
90
+
91
+ return {
92
+ "status": "success",
93
+ "user_id": user_id,
94
+ "text": text,
95
+ "message": "Сообщение отправлено через существующую функцию"
96
+ }
97
+
98
+ except Exception as e:
99
+ logger.error(f"Ошибка отправки сообщения пользователю {user_id}: {e}")
100
+ return {
101
+ "status": "error",
102
+ "error": str(e),
103
+ "user_id": user_id
104
+ }
105
+
106
+ async def send_document(
107
+ self,
108
+ user_id: int,
109
+ document_path: str,
110
+ caption: Optional[str] = None,
111
+ parse_mode: Optional[str] = None
112
+ ) -> Dict[str, Any]:
113
+ """
114
+ Отправляет документ пользователю
115
+
116
+ Args:
117
+ user_id: ID пользователя в Telegram
118
+ document_path: Путь к документу
119
+ caption: Подпись к документу
120
+ parse_mode: Режим парсинга
121
+
122
+ Returns:
123
+ Результат отправки
124
+ """
125
+ try:
126
+ document = FSInputFile(document_path)
127
+ message = await self.bot.send_document(
128
+ chat_id=user_id,
129
+ document=document,
130
+ caption=caption,
131
+ parse_mode=parse_mode
132
+ )
133
+
134
+ return {
135
+ "status": "success",
136
+ "message_id": message.message_id,
137
+ "user_id": user_id,
138
+ "document_path": document_path
139
+ }
140
+
141
+ except Exception as e:
142
+ logger.error(f"Ошибка отправки документа пользователю {user_id}: {e}")
143
+ return {
144
+ "status": "error",
145
+ "error": str(e),
146
+ "user_id": user_id
147
+ }
148
+
149
+ async def send_photo(
150
+ self,
151
+ user_id: int,
152
+ photo_path: str,
153
+ caption: Optional[str] = None,
154
+ parse_mode: Optional[str] = None
155
+ ) -> Dict[str, Any]:
156
+ """
157
+ Отправляет фото пользователю
158
+
159
+ Args:
160
+ user_id: ID пользователя в Telegram
161
+ photo_path: Путь к фото
162
+ caption: Подпись к фото
163
+ parse_mode: Режим парсинга
164
+
165
+ Returns:
166
+ Результат отправки
167
+ """
168
+ try:
169
+ photo = FSInputFile(photo_path)
170
+ message = await self.bot.send_photo(
171
+ chat_id=user_id,
172
+ photo=photo,
173
+ caption=caption,
174
+ parse_mode=parse_mode
175
+ )
176
+
177
+ return {
178
+ "status": "success",
179
+ "message_id": message.message_id,
180
+ "user_id": user_id,
181
+ "photo_path": photo_path
182
+ }
183
+
184
+ except Exception as e:
185
+ logger.error(f"Ошибка отправки фото пользователю {user_id}: {e}")
186
+ return {
187
+ "status": "error",
188
+ "error": str(e),
189
+ "user_id": user_id
190
+ }
191
+
192
+ async def send_chat_action(self, user_id: int, action: str) -> Dict[str, Any]:
193
+ """
194
+ Отправляет действие чата (typing, uploading_photo, etc.)
195
+
196
+ Args:
197
+ user_id: ID пользователя в Telegram
198
+ action: Действие (typing, uploading_photo, uploading_document, etc.)
199
+
200
+ Returns:
201
+ Результат отправки действия
202
+ """
203
+ try:
204
+ await self.bot.send_chat_action(chat_id=user_id, action=action)
205
+
206
+ return {
207
+ "status": "success",
208
+ "user_id": user_id,
209
+ "action": action
210
+ }
211
+
212
+ except Exception as e:
213
+ logger.error(f"Ошибка отправки действия пользователю {user_id}: {e}")
214
+ return {
215
+ "status": "error",
216
+ "error": str(e),
217
+ "user_id": user_id
218
+ }
219
+
220
+ def create_keyboard(self, buttons: List[List[Dict[str, str]]]) -> InlineKeyboardMarkup:
221
+ """
222
+ Создает клавиатуру из кнопок
223
+
224
+ Args:
225
+ buttons: Список рядов кнопок [[{"text": "Кнопка", "callback_data": "data"}], ...]
226
+
227
+ Returns:
228
+ InlineKeyboardMarkup
229
+ """
230
+ keyboard_buttons = []
231
+
232
+ for row in buttons:
233
+ row_buttons = []
234
+ for button in row:
235
+ row_buttons.append(InlineKeyboardButton(
236
+ text=button["text"],
237
+ callback_data=button.get("callback_data", "")
238
+ ))
239
+ keyboard_buttons.append(row_buttons)
240
+
241
+ return InlineKeyboardMarkup(inline_keyboard=keyboard_buttons)
242
+
243
+ async def close(self):
244
+ """Закрывает сессию бота"""
245
+ if self.bot:
246
+ await self.bot.session.close()
@@ -0,0 +1,19 @@
1
+ """
2
+ Инструменты AI для Smart Bot Factory
3
+ """
4
+
5
+ from .decorators import (
6
+ ai_tool,
7
+ get_ai_tools,
8
+ get_openai_tools_schema,
9
+ get_tools_for_prompt,
10
+ execute_ai_tool
11
+ )
12
+
13
+ __all__ = [
14
+ 'ai_tool',
15
+ 'get_ai_tools',
16
+ 'get_openai_tools_schema',
17
+ 'get_tools_for_prompt',
18
+ 'execute_ai_tool'
19
+ ]
@@ -0,0 +1,140 @@
1
+ """
2
+ Декораторы для инструментов AI (Function Calling)
3
+ """
4
+
5
+ import json
6
+ import logging
7
+ from typing import Callable, Any, Dict, List, Optional
8
+ from functools import wraps
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # Глобальный реестр инструментов AI
13
+ _ai_tools: Dict[str, Dict[str, Any]] = {}
14
+
15
+ def ai_tool(name: str, description: str, parameters_schema: Dict[str, Any]):
16
+ """
17
+ Декоратор для регистрации инструмента AI (Function Calling)
18
+
19
+ Args:
20
+ name: Название инструмента
21
+ description: Описание инструмента для AI
22
+ parameters_schema: JSON Schema параметров
23
+
24
+ Example:
25
+ @ai_tool(
26
+ name="book_appointment",
27
+ description="Записать пользователя на прием к врачу",
28
+ parameters_schema={
29
+ "type": "object",
30
+ "properties": {
31
+ "user_id": {"type": "integer", "description": "ID пользователя"},
32
+ "service": {"type": "string", "description": "Название услуги"},
33
+ "datetime": {"type": "string", "description": "Дата и время"}
34
+ },
35
+ "required": ["user_id", "service", "datetime"]
36
+ }
37
+ )
38
+ async def book_appointment(user_id: int, service: str, datetime: str):
39
+ # Логика записи на прием
40
+ return {"status": "success", "appointment_id": "123"}
41
+ """
42
+ def decorator(func: Callable) -> Callable:
43
+ _ai_tools[name] = {
44
+ 'handler': func,
45
+ 'description': description,
46
+ 'parameters_schema': parameters_schema,
47
+ 'name': func.__name__
48
+ }
49
+
50
+ logger.info(f"🔧 Зарегистрирован AI инструмент '{name}': {func.__name__}")
51
+
52
+ @wraps(func)
53
+ async def wrapper(*args, **kwargs):
54
+ try:
55
+ logger.info(f"🤖 AI вызывает инструмент '{name}'")
56
+ result = await func(*args, **kwargs)
57
+ logger.info(f"✅ AI инструмент '{name}' выполнен успешно")
58
+ return result
59
+ except Exception as e:
60
+ logger.error(f"❌ Ошибка в AI инструменте '{name}': {e}")
61
+ raise
62
+
63
+ return wrapper
64
+ return decorator
65
+
66
+ def get_ai_tools() -> Dict[str, Dict[str, Any]]:
67
+ """Возвращает все зарегистрированные AI инструменты"""
68
+ return _ai_tools.copy()
69
+
70
+ def get_openai_tools_schema() -> List[Dict[str, Any]]:
71
+ """
72
+ Возвращает схему инструментов в формате OpenAI Function Calling
73
+ """
74
+ tools = []
75
+ for tool_name, tool_info in _ai_tools.items():
76
+ tools.append({
77
+ "type": "function",
78
+ "function": {
79
+ "name": tool_name,
80
+ "description": tool_info['description'],
81
+ "parameters": tool_info['parameters_schema']
82
+ }
83
+ })
84
+
85
+ return tools
86
+
87
+ def get_tools_for_prompt() -> str:
88
+ """
89
+ Возвращает описание всех AI инструментов для добавления в промпт
90
+ """
91
+ if not _ai_tools:
92
+ return ""
93
+
94
+ prompt_parts = ["ДОСТУПНЫЕ ИНСТРУМЕНТЫ AI:"]
95
+
96
+ for tool_name, tool_info in _ai_tools.items():
97
+ prompt_parts.append(f"- {tool_name}: {tool_info['description']}")
98
+
99
+ # Добавляем информацию о параметрах
100
+ required_params = tool_info['parameters_schema'].get('required', [])
101
+ if required_params:
102
+ prompt_parts.append(f" Обязательные параметры: {', '.join(required_params)}")
103
+
104
+ return "\n".join(prompt_parts)
105
+
106
+ async def execute_ai_tool(tool_name: str, arguments: Dict[str, Any]) -> Any:
107
+ """Выполняет AI инструмент по имени с аргументами"""
108
+ if tool_name not in _ai_tools:
109
+ raise ValueError(f"AI инструмент '{tool_name}' не найден")
110
+
111
+ tool_info = _ai_tools[tool_name]
112
+ handler = tool_info['handler']
113
+
114
+ # Валидируем аргументы по схеме
115
+ _validate_tool_arguments(tool_name, arguments, tool_info['parameters_schema'])
116
+
117
+ return await handler(**arguments)
118
+
119
+ def _validate_tool_arguments(tool_name: str, arguments: Dict[str, Any], schema: Dict[str, Any]):
120
+ """Валидирует аргументы инструмента по JSON Schema"""
121
+ required_params = schema.get('required', [])
122
+
123
+ # Проверяем обязательные параметры
124
+ for param in required_params:
125
+ if param not in arguments:
126
+ raise ValueError(f"Отсутствует обязательный параметр '{param}' для инструмента '{tool_name}'")
127
+
128
+ # Проверяем типы параметров
129
+ properties = schema.get('properties', {})
130
+ for param_name, param_value in arguments.items():
131
+ if param_name in properties:
132
+ param_schema = properties[param_name]
133
+ expected_type = param_schema.get('type')
134
+
135
+ if expected_type == 'integer' and not isinstance(param_value, int):
136
+ raise ValueError(f"Параметр '{param_name}' должен быть integer для инструмента '{tool_name}'")
137
+ elif expected_type == 'string' and not isinstance(param_value, str):
138
+ raise ValueError(f"Параметр '{param_name}' должен быть string для инструмента '{tool_name}'")
139
+ elif expected_type == 'boolean' and not isinstance(param_value, bool):
140
+ raise ValueError(f"Параметр '{param_name}' должен быть boolean для инструмента '{tool_name}'")
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: smart-bot-factory
3
+ Version: 0.1.0
4
+ Summary: Библиотека для создания умных чат-ботов
5
+ Author-email: Kopatych <kopatych@example.com>
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: chatbot,cli,openai,supabase,telegram
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Framework :: AsyncIO
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Communications :: Chat
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: aiofiles>=23.0.0
24
+ Requires-Dist: aiogram>=3.4.1
25
+ Requires-Dist: click>=8.0.0
26
+ Requires-Dist: openai>=1.12.0
27
+ Requires-Dist: python-dotenv>=1.0.1
28
+ Requires-Dist: pytz>=2023.3
29
+ Requires-Dist: pyyaml>=6.0.2
30
+ Requires-Dist: supabase>=2.3.4
31
+ Description-Content-Type: text/markdown
32
+
33
+ # Smart Bot Factory
34
+
35
+ Библиотека для создания умных чат-ботов с использованием OpenAI, Telegram и Supabase.
36
+
37
+ ## Установка
38
+
39
+ ```bash
40
+ pip install smart-bot-factory
41
+ ```
42
+
43
+ ## Быстрый старт
44
+
45
+ 1. Создайте нового бота:
46
+ ```bash
47
+ sbf create my-bot
48
+ ```
49
+
50
+ 2. Настройте конфигурацию в `bots/my-bot/.env`
51
+
52
+ 3. Запустите бота:
53
+ ```bash
54
+ sbf run my-bot
55
+ ```
56
+
57
+ ## Возможности
58
+
59
+ - 🤖 Интеграция с OpenAI GPT для умных ответов
60
+ - 📱 Поддержка Telegram Bot API через aiogram
61
+ - 💾 Хранение данных в Supabase
62
+ - 🔄 Система событий и обработчиков
63
+ - ⏰ Планировщик задач
64
+ - 🧪 Встроенная система тестирования
65
+ - 📝 Управление промптами
66
+ - 🛠️ Удобный CLI интерфейс
67
+
68
+ ## CLI команды
69
+
70
+ ```bash
71
+ # Создать нового бота
72
+ sbf create my-bot
73
+
74
+ # Запустить бота
75
+ sbf run my-bot
76
+
77
+ # Показать список ботов
78
+ sbf list
79
+
80
+ # Управление промптами
81
+ sbf prompts my-bot --list
82
+ sbf prompts my-bot --edit welcome_message
83
+ sbf prompts my-bot --add new_prompt
84
+
85
+ # Запустить тесты
86
+ sbf test my-bot
87
+ ```
88
+
89
+ ## Пример использования
90
+
91
+ ```python
92
+ from smart_bot_factory import BotBuilder, event_handler, schedule_task
93
+
94
+ # Обработчик события
95
+ @event_handler("book_appointment", "Запись на прием")
96
+ async def handle_booking(user_id: int, event_data: dict):
97
+ # Логика обработки записи на прием
98
+ return {"status": "success"}
99
+
100
+ # Запланированная задача
101
+ @schedule_task("send_reminder", "Отправка напоминания")
102
+ async def send_reminder(user_id: int, message: str):
103
+ # Логика отправки напоминания
104
+ return {"status": "sent"}
105
+
106
+ # Запуск бота
107
+ async def main():
108
+ bot = BotBuilder("my-bot")
109
+ await bot.build()
110
+ await bot.start()
111
+
112
+ if __name__ == "__main__":
113
+ asyncio.run(main())
114
+ ```
115
+
116
+ ## Требования
117
+
118
+ - Python 3.9+
119
+ - OpenAI API ключ
120
+ - Telegram Bot Token
121
+ - Supabase проект
122
+
123
+ ## Лицензия
124
+
125
+ MIT
@@ -0,0 +1,18 @@
1
+ smart_bot_factory/__init__.py,sha256=K8NaQbzJRtSH69ZRqg33C-G7KHWfy4bC1lYz9BJdEco,682
2
+ smart_bot_factory/cli.py,sha256=jiYWmjAsWmUyReYX7hsCwC73h7Ee1mo-R9VWkpKF0AM,25542
3
+ smart_bot_factory/core/__init__.py,sha256=inF93r4_Dmddkj1LnBgum9t6QFVU0BQHzUP5HLPZ8s0,103
4
+ smart_bot_factory/core/bot_builder.py,sha256=VhgYwZPev7zMLTv7pqEOOssJZGhLRV4zcEU8dQ_97N4,17727
5
+ smart_bot_factory/events/__init__.py,sha256=0CXtlpKSx_FfI_PlhjaZGKuS90_W_kJ1cI_Y8vYOhGA,602
6
+ smart_bot_factory/events/decorators.py,sha256=7CTnx_43hFUTmWUFSrFjPiFJY4w-7_-bdj0wpjX88mc,9378
7
+ smart_bot_factory/integrations/__init__.py,sha256=OaW31B0PdDwV5yrVrE2RRDOQ9PgOLk8JcLqDCuOiwKg,3788
8
+ smart_bot_factory/integrations/bot_utils_integration.py,sha256=i8JY3ybGvAhP9mKFNhf9vJdUD54bS5LbRXpjDfN-d8s,9769
9
+ smart_bot_factory/services/__init__.py,sha256=N-mB1AqREqRriUURTP1mWFtFMOpYSMvSbGpMJmnpFHc,288
10
+ smart_bot_factory/services/message_sender.py,sha256=MxfT9dLOpdKvS52dhWcCJRTIYXAjPNaSi72sa6ds0yM,9336
11
+ smart_bot_factory/services/telegram_integration.py,sha256=Khul3Zze6gUv8Jg0FCy8ObcIW6rrnVH1ylov6XRnp78,8905
12
+ smart_bot_factory/tools/__init__.py,sha256=MEEHtoK5mdlnhpan3_GZqt_eIXJqeADuNyljgbEaPy8,344
13
+ smart_bot_factory/tools/decorators.py,sha256=618PaQpQRMKDktCed_dAvDRaffAbhAEH193fNKCeC8M,6201
14
+ smart_bot_factory-0.1.0.dist-info/METADATA,sha256=7utCRN8K98XElbp1JfmYumG1q5c54Pcll7Yz6ZX9cBA,3488
15
+ smart_bot_factory-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ smart_bot_factory-0.1.0.dist-info/entry_points.txt,sha256=ybKEAI0WSb7WoRiey7QE-HHfn88UGV7nxLDxXq7b7SU,50
17
+ smart_bot_factory-0.1.0.dist-info/licenses/LICENSE,sha256=U7oalxgqok6_z5dMIGmENJY5j6sDnGeQtzcStVQUl6M,1086
18
+ smart_bot_factory-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ sbf = smart_bot_factory.cli:cli
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kopatych
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.