smart-bot-factory 0.1.0__py3-none-any.whl → 0.1.2__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,31 @@
1
+ Metadata-Version: 2.4
2
+ Name: smart-bot-factory
3
+ Version: 0.1.2
4
+ Summary: Библиотека для создания умных чат-ботов
5
+ Author-email: Kopatych <kopatych@example.com>
6
+ License: MIT
7
+ Keywords: chatbot,cli,openai,supabase,telegram
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Framework :: AsyncIO
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Communications :: Chat
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.9
22
+ Requires-Dist: aiofiles>=23.0.0
23
+ Requires-Dist: aiogram>=3.4.1
24
+ Requires-Dist: click>=8.0.0
25
+ Requires-Dist: openai>=1.12.0
26
+ Requires-Dist: project-root-finder>=1.9
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
+ Requires-Dist: twine>=6.2.0
@@ -0,0 +1,4 @@
1
+ smart_bot_factory-0.1.2.dist-info/METADATA,sha256=AL-uAGQGwU2fP4IK06oAHnPxnaE0Zssy1T026JeuQCE,1206
2
+ smart_bot_factory-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
3
+ smart_bot_factory-0.1.2.dist-info/entry_points.txt,sha256=ybKEAI0WSb7WoRiey7QE-HHfn88UGV7nxLDxXq7b7SU,50
4
+ smart_bot_factory-0.1.2.dist-info/RECORD,,
@@ -1,30 +0,0 @@
1
- """
2
- Smart Bot Factory - библиотека для создания умных чат-ботов
3
- """
4
-
5
- from .core.bot_builder import BotBuilder
6
- from .events.decorators import event_handler, schedule_task
7
- from .integrations import (
8
- OpenAIClient,
9
- SupabaseClient,
10
- Config,
11
- ConversationManager,
12
- AdminManager,
13
- PromptLoader
14
- )
15
- from .services import send_message_by_ai, send_message_by_human
16
-
17
- __version__ = "0.1.0"
18
- __all__ = [
19
- 'BotBuilder',
20
- 'event_handler',
21
- 'schedule_task',
22
- 'OpenAIClient',
23
- 'SupabaseClient',
24
- 'Config',
25
- 'ConversationManager',
26
- 'AdminManager',
27
- 'PromptLoader',
28
- 'send_message_by_ai',
29
- 'send_message_by_human'
30
- ]
smart_bot_factory/cli.py DELETED
@@ -1,624 +0,0 @@
1
- """
2
- CLI интерфейс для Smart Bot Factory
3
- """
4
-
5
- import os
6
- import sys
7
- import click
8
- import subprocess
9
- import shutil
10
- from pathlib import Path
11
-
12
- # from .core.bot_creator import create_new_bot, list_available_bots
13
-
14
- @click.group()
15
- def cli():
16
- """Smart Bot Factory - инструмент для создания умных чат-ботов"""
17
- pass
18
-
19
- @cli.command()
20
- @click.argument("bot_id")
21
- @click.argument("template", required=False, default="base")
22
- def create(bot_id: str, template: str = "base"):
23
- """Создать нового бота"""
24
- success = create_new_bot_structure(template, bot_id)
25
- if not success:
26
- sys.exit(1)
27
-
28
- @cli.command()
29
- def list():
30
- """Показать список доступных ботов"""
31
- bots = list_bots_in_bots_folder()
32
- if not bots:
33
- click.echo("Нет доступных ботов")
34
- return
35
-
36
- click.echo("📋 Доступные боты:")
37
- for bot in sorted(bots):
38
- click.echo(f" - {bot}")
39
-
40
- @cli.command()
41
- @click.argument("bot_id")
42
- def run(bot_id: str):
43
- """Запустить бота"""
44
- try:
45
- # Проверяем существование бота
46
- bot_path = Path("bots") / bot_id
47
- if not bot_path.exists():
48
- raise click.ClickException(f"Бот {bot_id} не найден в папке bots/")
49
-
50
- # Проверяем наличие основного файла бота в корневой директории
51
- bot_file = Path(f"{bot_id}.py")
52
- if not bot_file.exists():
53
- raise click.ClickException(f"Файл {bot_id}.py не найден в корневой директории")
54
-
55
- # Проверяем наличие .env файла
56
- env_file = bot_path / ".env"
57
- if not env_file.exists():
58
- raise click.ClickException(f"Файл .env не найден для бота {bot_id}")
59
-
60
- # Загружаем .env файл перед запуском бота
61
- from dotenv import load_dotenv
62
- load_dotenv(env_file)
63
- click.echo(f"📄 Загружен .env файл: {env_file}")
64
-
65
- # Запускаем бота из корневой директории
66
- click.echo(f"🚀 Запускаем бота {bot_id}...")
67
- subprocess.run([sys.executable, str(bot_file)], check=True)
68
-
69
- except subprocess.CalledProcessError as e:
70
- click.echo(f"❌ Ошибка при запуске бота: {e}", err=True)
71
- sys.exit(1)
72
- except Exception as e:
73
- click.echo(f"❌ Ошибка: {e}", err=True)
74
- sys.exit(1)
75
-
76
- @cli.command()
77
- @click.argument("bot_id")
78
- @click.option("--file", help="Запустить тесты только из указанного файла")
79
- @click.option("-v", "--verbose", is_flag=True, help="Подробный вывод")
80
- @click.option("--max-concurrent", default=5, help="Максимальное количество потоков")
81
- def test(bot_id: str, file: str = None, verbose: bool = False, max_concurrent: int = 5):
82
- """Запустить тесты бота"""
83
- try:
84
- # Проверяем существование бота
85
- bot_path = Path("bots") / bot_id
86
- if not bot_path.exists():
87
- raise click.ClickException(f"Бот {bot_id} не найден в папке bots/")
88
-
89
- # Проверяем наличие скрипта тестирования
90
- testing_script = Path("bot_testing.py")
91
- if not testing_script.exists():
92
- raise click.ClickException("Скрипт bot_testing.py не найден")
93
-
94
- # Проверяем наличие тестов
95
- tests_dir = bot_path / "tests"
96
- if not tests_dir.exists():
97
- click.echo(f"⚠️ Тесты не найдены для бота {bot_id}")
98
- return
99
-
100
- # Ищем YAML файлы с тестами
101
- yaml_files = [str(f.name) for f in tests_dir.glob("*.yaml")]
102
-
103
- if not yaml_files:
104
- click.echo(f"⚠️ YAML тесты не найдены для бота {bot_id}")
105
- return
106
-
107
- click.echo(f"🧪 Запускаем тесты для бота {bot_id}...")
108
-
109
- # Формируем команду для запуска через uv
110
- cmd = [sys.executable, "bot_testing.py", bot_id]
111
-
112
- if file:
113
- cmd.append(file)
114
-
115
- if verbose:
116
- cmd.append("-v")
117
-
118
- if max_concurrent != 5:
119
- cmd.extend(["--max-concurrent", str(max_concurrent)])
120
-
121
- # Запускаем тесты
122
- result = subprocess.run(cmd, check=False)
123
-
124
- if result.returncode == 0:
125
- click.echo("✅ Все тесты пройдены")
126
- else:
127
- click.echo("❌ Есть ошибки в тестах")
128
- sys.exit(1)
129
-
130
- except subprocess.CalledProcessError as e:
131
- click.echo(f"❌ Ошибка при запуске тестов: {e}", err=True)
132
- sys.exit(1)
133
- except Exception as e:
134
- click.echo(f"❌ Ошибка: {e}", err=True)
135
- sys.exit(1)
136
-
137
- @cli.command()
138
- @click.argument("bot_id")
139
- def config(bot_id: str):
140
- """Настроить конфигурацию бота"""
141
- try:
142
- # Проверяем существование бота
143
- bot_path = Path("bots") / bot_id
144
- if not bot_path.exists():
145
- raise click.ClickException(f"Бот {bot_id} не найден в папке bots/")
146
-
147
- # Открываем .env файл в редакторе
148
- env_file = bot_path / ".env"
149
- if not env_file.exists():
150
- raise click.ClickException(f"Файл .env не найден для бота {bot_id}")
151
-
152
- # Определяем редактор
153
- editor = os.environ.get('EDITOR', 'notepad' if os.name == 'nt' else 'nano')
154
-
155
- click.echo(f"📝 Открываем конфигурацию бота {bot_id}...")
156
- subprocess.run([editor, str(env_file)], check=True)
157
-
158
- except subprocess.CalledProcessError as e:
159
- click.echo(f"❌ Ошибка при открытии редактора: {e}", err=True)
160
- sys.exit(1)
161
- except Exception as e:
162
- click.echo(f"❌ Ошибка: {e}", err=True)
163
- sys.exit(1)
164
-
165
- @cli.command()
166
- @click.argument("bot_id")
167
- @click.option("--list", "list_prompts", is_flag=True, help="Показать список промптов")
168
- @click.option("--edit", "edit_prompt", help="Редактировать промпт")
169
- @click.option("--add", "add_prompt", help="Добавить новый промпт")
170
- def prompts(bot_id: str, list_prompts: bool = False, edit_prompt: str = None, add_prompt: str = None):
171
- """Управление промптами бота"""
172
- try:
173
- # Проверяем существование бота
174
- bot_path = Path("bots") / bot_id
175
- if not bot_path.exists():
176
- raise click.ClickException(f"Бот {bot_id} не найден в папке bots/")
177
-
178
- prompts_dir = bot_path / "prompts"
179
- if not prompts_dir.exists():
180
- raise click.ClickException(f"Папка промптов не найдена для бота {bot_id}")
181
-
182
- if list_prompts:
183
- # Показываем список промптов
184
- prompt_files = [f.name for f in prompts_dir.glob("*.txt")]
185
-
186
- if not prompt_files:
187
- click.echo("Промпты не найдены")
188
- return
189
-
190
- click.echo(f"📋 Промпты бота {bot_id}:")
191
- for prompt_file in sorted(prompt_files):
192
- click.echo(f" - {prompt_file[:-4]}")
193
-
194
- elif edit_prompt:
195
- # Редактируем промпт
196
- prompt_file = prompts_dir / f"{edit_prompt}.txt"
197
- if not prompt_file.exists():
198
- raise click.ClickException(f"Промпт {edit_prompt} не найден")
199
-
200
- editor = os.environ.get('EDITOR', 'notepad' if os.name == 'nt' else 'nano')
201
- click.echo(f"📝 Редактируем промпт {edit_prompt}...")
202
- subprocess.run([editor, str(prompt_file)], check=True)
203
-
204
- elif add_prompt:
205
- # Добавляем новый промпт
206
- prompt_file = prompts_dir / f"{add_prompt}.txt"
207
- if prompt_file.exists():
208
- raise click.ClickException(f"Промпт {add_prompt} уже существует")
209
-
210
- # Создаем файл с базовым содержимым
211
- prompt_file.write_text(
212
- f"# Промпт: {add_prompt}\n\n"
213
- "Введите содержимое промпта здесь...",
214
- encoding='utf-8'
215
- )
216
-
217
- # Открываем в редакторе
218
- editor = os.environ.get('EDITOR', 'notepad' if os.name == 'nt' else 'nano')
219
- click.echo(f"📝 Создаем новый промпт {add_prompt}...")
220
- subprocess.run([editor, str(prompt_file)], check=True)
221
-
222
- else:
223
- # Показываем справку
224
- click.echo("Использование:")
225
- click.echo(" sbf prompts <bot_id> --list # Показать список промптов")
226
- click.echo(" sbf prompts <bot_id> --edit <prompt_name> # Редактировать промпт")
227
- click.echo(" sbf prompts <bot_id> --add <prompt_name> # Добавить новый промпт")
228
-
229
- except subprocess.CalledProcessError as e:
230
- click.echo(f"❌ Ошибка при открытии редактора: {e}", err=True)
231
- sys.exit(1)
232
- except Exception as e:
233
- click.echo(f"❌ Ошибка: {e}", err=True)
234
- sys.exit(1)
235
-
236
- @cli.command()
237
- @click.argument("bot_id")
238
- @click.option("--force", "-f", is_flag=True, help="Удалить без подтверждения")
239
- def rm(bot_id: str, force: bool = False):
240
- """Удалить бота и все его файлы"""
241
- try:
242
- # Проверяем существование бота
243
- bot_path = Path("bots") / bot_id
244
- if not bot_path.exists():
245
- raise click.ClickException(f"Бот {bot_id} не найден в папке bots/")
246
-
247
- # Проверяем наличие основного файла бота в корневой директории
248
- bot_file = Path(f"{bot_id}.py")
249
- if not bot_file.exists():
250
- raise click.ClickException(f"Файл {bot_id}.py не найден в корневой директории")
251
-
252
- # Показываем что будет удалено
253
- click.echo(f"🗑️ Будет удалено:")
254
- click.echo(f" - Файл запускалки: {bot_file}")
255
- click.echo(f" - Папка бота: {bot_path}")
256
-
257
- # Запрашиваем подтверждение если не указан --force
258
- if not force:
259
- if not click.confirm(f"Вы уверены, что хотите удалить бота {bot_id}?"):
260
- click.echo("❌ Удаление отменено")
261
- return
262
-
263
- # Удаляем файл запускалки
264
- if bot_file.exists():
265
- bot_file.unlink()
266
- click.echo(f"✅ Файл {bot_file} удален")
267
-
268
- # Удаляем папку бота
269
- if bot_path.exists():
270
- import shutil
271
- shutil.rmtree(bot_path)
272
- click.echo(f"✅ Папка {bot_path} удалена")
273
-
274
- click.echo(f"🎉 Бот {bot_id} полностью удален")
275
-
276
- except Exception as e:
277
- click.echo(f"❌ Ошибка при удалении бота: {e}", err=True)
278
- sys.exit(1)
279
-
280
- @cli.command()
281
- def link():
282
- """Создать UTM-ссылку для бота"""
283
- try:
284
- # Проверяем наличие скрипта генерации ссылок
285
- link_script = Path("utm_link_generator.py")
286
- if not link_script.exists():
287
- raise click.ClickException("Скрипт utm_link_generator.py не найден")
288
-
289
- # Запускаем ваш скрипт генерации ссылок
290
- click.echo("🔗 Запускаем генератор UTM-ссылок...")
291
- subprocess.run([sys.executable, "utm_link_generator.py"], check=True)
292
-
293
- except subprocess.CalledProcessError as e:
294
- click.echo(f"❌ Ошибка при запуске генератора ссылок: {e}", err=True)
295
- sys.exit(1)
296
- except Exception as e:
297
- click.echo(f"❌ Ошибка: {e}", err=True)
298
- sys.exit(1)
299
-
300
- def create_new_bot_structure(template: str, bot_id: str) -> bool:
301
- """Создает новую структуру бота в папке bots/"""
302
- try:
303
- # Создаем папку bots если её нет
304
- bots_dir = Path("bots")
305
- bots_dir.mkdir(exist_ok=True)
306
-
307
- # Создаем папку для нового бота
308
- bot_dir = bots_dir / bot_id
309
- if bot_dir.exists():
310
- click.echo(f"❌ Бот {bot_id} уже существует")
311
- return False
312
-
313
- bot_dir.mkdir()
314
-
315
- # Создаем структуру папок
316
- (bot_dir / "prompts").mkdir()
317
- (bot_dir / "tests").mkdir()
318
- (bot_dir / "reports").mkdir()
319
- (bot_dir / "welcome_files").mkdir()
320
-
321
- if template == "base":
322
- # Используем growthmed-october-24 как базовый шаблон
323
- copy_from_growthmed_template(bot_dir, bot_id)
324
- else:
325
- # Используем другой шаблон из папки bots
326
- copy_from_bot_template(template, bot_dir, bot_id)
327
-
328
- click.echo(f"✅ Бот {bot_id} создан в папке bots/{bot_id}/")
329
- click.echo(f"📝 Не забудьте настроить .env файл перед запуском")
330
- return True
331
-
332
- except Exception as e:
333
- click.echo(f"❌ Ошибка при создании бота: {e}")
334
- return False
335
-
336
- def list_bots_in_bots_folder() -> list:
337
- """Возвращает список ботов из папки bots/"""
338
- bots_dir = Path("bots")
339
- if not bots_dir.exists():
340
- return []
341
-
342
- bots = []
343
- for item in bots_dir.iterdir():
344
- if item.is_dir() and Path(f"{item.name}.py").exists():
345
- bots.append(item.name)
346
-
347
- return bots
348
-
349
- def create_bot_template(bot_id: str) -> str:
350
- """Создает шаблон основного файла бота"""
351
- return f'''#!/usr/bin/env python3
352
- """
353
- Бот {bot_id} - создан с помощью Smart Bot Factory
354
- """
355
-
356
- import asyncio
357
- import sys
358
- import os
359
- from pathlib import Path
360
-
361
- # Добавляем корень проекта в путь
362
- project_root = Path(__file__).parent
363
- sys.path.insert(0, str(project_root))
364
-
365
- # Устанавливаем переменные окружения ДО импорта библиотеки
366
- bot_id = "{bot_id}"
367
- config_dir = Path("bots") / bot_id
368
- prompts_dir = config_dir / "prompts"
369
-
370
- if prompts_dir.exists():
371
- os.environ["PROMT_FILES_DIR"] = str(prompts_dir)
372
- print(f"📁 Установлен путь к промптам: {{prompts_dir}}")
373
-
374
- # Загружаем .env файл ДО импорта библиотеки
375
- env_file = config_dir / ".env"
376
- if env_file.exists():
377
- from dotenv import load_dotenv
378
- load_dotenv(env_file)
379
- print(f"📄 Загружен .env файл: {{env_file}}")
380
- else:
381
- print(f"⚠️ .env файл не найден: {{env_file}}")
382
-
383
- from smart_bot_factory import (
384
- BotBuilder,
385
- event_handler,
386
- schedule_task,
387
- send_message_by_human,
388
- send_message_by_ai
389
- )
390
-
391
- # =============================================================================
392
- # ОБРАБОТЧИКИ СОБЫТИЙ
393
- # =============================================================================
394
-
395
- @event_handler("example_event", "Пример обработчика события")
396
- async def handle_example_event(user_id: int, event_data: dict):
397
- """Пример обработчика события"""
398
- # Отправляем подтверждение пользователю
399
- await send_message_by_human(
400
- user_id=user_id,
401
- message_text="✅ Событие обработано!"
402
- )
403
-
404
- return {{
405
- "status": "success",
406
- "message": "Событие обработано"
407
- }}
408
-
409
- # =============================================================================
410
- # ЗАПЛАНИРОВАННЫЕ ЗАДАЧИ
411
- # =============================================================================
412
-
413
- @schedule_task("example_task", "Пример запланированной задачи")
414
- async def example_task(user_id: int, message: str):
415
- """Пример запланированной задачи"""
416
- # Отправляем сообщение
417
- await send_message_by_human(
418
- user_id=user_id,
419
- message_text=f"🔔 Напоминание: {{message}}"
420
- )
421
-
422
- return {{
423
- "status": "sent",
424
- "user_id": user_id,
425
- "message": message
426
- }}
427
-
428
- # =============================================================================
429
- # ОСНОВНАЯ ФУНКЦИЯ
430
- # =============================================================================
431
-
432
- async def main():
433
- """Основная функция запуска бота"""
434
- try:
435
- # Создаем и собираем бота
436
- bot_builder = BotBuilder("{bot_id}")
437
- await bot_builder.build()
438
-
439
- # Запускаем бота
440
- await bot_builder.start()
441
-
442
- except Exception as e:
443
- print(f"❌ Ошибка запуска бота: {{e}}")
444
- raise
445
-
446
- if __name__ == "__main__":
447
- asyncio.run(main())
448
- '''
449
-
450
- def create_env_template(bot_id: str) -> str:
451
- """Создает шаблон .env файла"""
452
- return f'''# Telegram
453
- TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
454
-
455
- # Supabase
456
- SUPABASE_URL=https://your-project.supabase.co
457
- SUPABASE_KEY=your_supabase_anon_key
458
-
459
- # OpenAI
460
- OPENAI_API_KEY=sk-your-openai-api-key
461
- OPENAI_MODEL=gpt-5-mini
462
- OPENAI_MAX_TOKENS=1500
463
- OPENAI_TEMPERATURE=0.7
464
-
465
- # Промпты (каталог)
466
- PROMT_FILES_DIR=prompts
467
-
468
- # Файл после приветствия с подписью (если он есть - грузим его в папку welcome_file, если нет - ничего не делаем)
469
- WELCOME_FILE_URL=welcome_files/
470
- WELCOME_FILE_MSG=welcome_file_msg.txt
471
-
472
- # 🆕 Администраторы (через запятую)
473
- # Укажите Telegram ID админов
474
- ADMIN_TELEGRAM_IDS=123456789,987654321
475
- ADMIN_SESSION_TIMEOUT_MINUTES=30
476
-
477
- # 🆕 Режим отладки (показывать JSON пользователям)
478
- DEBUG_MODE=false
479
-
480
- # Дополнительные настройки
481
- MAX_CONTEXT_MESSAGES=50
482
- LOG_LEVEL=INFO
483
- MESSAGE_PARSE_MODE=Markdown
484
-
485
- # Настройки продаж
486
- LEAD_QUALIFICATION_THRESHOLD=7
487
- SESSION_TIMEOUT_HOURS=24
488
-
489
- # ⚠️ ВАЖНО: BOT_ID теперь НЕ нужен в .env!
490
- # Bot ID автоматически определяется из имени файла запускалки
491
- # Например: python {bot_id}.py → BOT_ID = {bot_id}
492
- '''
493
-
494
- def copy_from_growthmed_template(bot_dir: Path, bot_id: str):
495
- """Копирует шаблон из growthmed-october-24"""
496
- try:
497
- # Создаем основной файл бота в корневой директории проекта
498
- bot_file = Path(f"{bot_id}.py")
499
- bot_file.write_text(create_bot_template(bot_id), encoding='utf-8')
500
-
501
- # Копируем .env файл в папку бота
502
- env_file = bot_dir / ".env"
503
- env_file.write_text(create_env_template(bot_id), encoding='utf-8')
504
-
505
- # Копируем промпты из growthmed-october-24
506
- source_prompts = Path("configs/growthmed-october-24/prompts")
507
- target_prompts = bot_dir / "prompts"
508
-
509
- if source_prompts.exists():
510
- for prompt_file in source_prompts.glob("*.txt"):
511
- shutil.copy2(prompt_file, target_prompts / prompt_file.name)
512
- click.echo(f"📋 Промпты скопированы из growthmed-october-24")
513
- else:
514
- # Fallback к базовым промптам
515
- create_basic_prompts(target_prompts)
516
- click.echo(f"📋 Созданы базовые промпты")
517
-
518
- except Exception as e:
519
- click.echo(f"⚠️ Ошибка при копировании шаблона: {e}")
520
- # Fallback к базовым промптам
521
- create_basic_prompts(bot_dir / "prompts")
522
-
523
- def copy_from_bot_template(template: str, bot_dir: Path, bot_id: str):
524
- """Копирует шаблон из существующего бота"""
525
- try:
526
- template_dir = Path("bots") / template
527
- if not template_dir.exists():
528
- raise click.ClickException(f"Шаблон {template} не найден")
529
-
530
- # Копируем основной файл бота в корневую директорию
531
- template_bot_file = Path(f"{template}.py")
532
- if template_bot_file.exists():
533
- bot_file = Path(f"{bot_id}.py")
534
- shutil.copy2(template_bot_file, bot_file)
535
-
536
- # Заменяем название бота в файле
537
- content = bot_file.read_text(encoding='utf-8')
538
- content = content.replace(f'BotBuilder("{template}")', f'BotBuilder("{bot_id}")')
539
- content = content.replace(f'bot_id="{template}"', f'bot_id="{bot_id}"')
540
- bot_file.write_text(content, encoding='utf-8')
541
-
542
- # Копируем .env файл
543
- template_env = template_dir / ".env"
544
- if template_env.exists():
545
- env_file = bot_dir / ".env"
546
- shutil.copy2(template_env, env_file)
547
-
548
- # Заменяем BOT_ID в .env
549
- env_content = env_file.read_text(encoding='utf-8')
550
- env_content = env_content.replace(f'BOT_ID={template}', f'BOT_ID={bot_id}')
551
- env_file.write_text(env_content, encoding='utf-8')
552
-
553
- # Копируем промпты
554
- template_prompts = template_dir / "prompts"
555
- target_prompts = bot_dir / "prompts"
556
-
557
- if template_prompts.exists():
558
- for prompt_file in template_prompts.glob("*.txt"):
559
- shutil.copy2(prompt_file, target_prompts / prompt_file.name)
560
-
561
- # Копируем тесты
562
- template_tests = template_dir / "tests"
563
- target_tests = bot_dir / "tests"
564
-
565
- if template_tests.exists():
566
- for test_file in template_tests.glob("*"):
567
- if test_file.is_file():
568
- shutil.copy2(test_file, target_tests / test_file.name)
569
-
570
- click.echo(f"📋 Шаблон скопирован из {template}")
571
-
572
- except Exception as e:
573
- click.echo(f"❌ Ошибка при копировании шаблона {template}: {e}")
574
- raise
575
-
576
- def create_basic_prompts(prompts_dir: Path):
577
- """Создает базовые промпты"""
578
- # Системный промпт
579
- (prompts_dir / "system_prompt.txt").write_text(
580
- "Ты - помощник. Твоя задача помогать пользователям с их вопросами.\n"
581
- "Будь дружелюбным и полезным.",
582
- encoding='utf-8'
583
- )
584
-
585
- # Приветственное сообщение
586
- (prompts_dir / "welcome_message.txt").write_text(
587
- "👋 Привет! Я ваш помощник.\n\n"
588
- "Чем могу помочь?",
589
- encoding='utf-8'
590
- )
591
-
592
- # Финальные инструкции
593
- (prompts_dir / "final_instructions.txt").write_text(
594
- """<instruction>
595
- КРИТИЧЕСКИ ВАЖНО: В НАЧАЛЕ КАЖДОГО своего ответа добавляй служебную информацию в формате:
596
-
597
- {
598
- "этап": id,
599
- "качество": 1-10,
600
- "события": [
601
- {
602
- "тип": тип события,
603
- "инфо": детали события
604
- }
605
- ],
606
- "файлы": [],
607
- "каталоги": []
608
- }
609
-
610
- ДОСТУПНЫЕ ОБРАБОТЧИКИ СОБЫТИЙ:
611
- - example_event: Пример обработчика события. Используй для демонстрации.
612
- Пример: {"тип": "example_event", "инфо": {"data": "пример данных"}}
613
-
614
- ДОСТУПНЫЕ ЗАПЛАНИРОВАННЫЕ ЗАДАЧИ:
615
- - example_task: Пример запланированной задачи. Используй для демонстрации.
616
- Пример: {"тип": "example_task", "инфо": "через 1 час: напомнить о чем-то"}
617
-
618
- Используй эти обработчики и задачи, когда это уместно в диалоге.
619
- </instruction>""",
620
- encoding='utf-8'
621
- )
622
-
623
- if __name__ == "__main__":
624
- cli()