smart-bot-factory 0.2.5__tar.gz → 0.2.6__tar.gz
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-0.2.5 → smart_bot_factory-0.2.6}/PKG-INFO +1 -1
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/best-valera.py +248 -248
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/pyproject.toml +1 -1
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/creation/bot_builder.py +41 -4
- smart_bot_factory-0.2.6/smart_bot_factory/utils/__init__.py +10 -0
- smart_bot_factory-0.2.6/smart_bot_factory/utils/user_prompt_loader.py +56 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/uv.lock +1 -1
- smart_bot_factory-0.2.5/smart_bot_factory/utils/__init__.py +0 -9
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.claude/settings.local.json +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.env.example +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.github/ISSUE_TEMPLATE//342/234/250-/320/267/320/260/320/277/321/200/320/276/321/201-/321/204/321/203/320/275/320/272/321/206/320/270/320/270.md" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.github/ISSUE_TEMPLATE//360/237/220/233-/320/261/320/260/320/263-/321/200/320/265/320/277/320/276/321/200/321/202.md" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.github/workflows/ci.yml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.github/workflows/publish-private.yml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.github/workflows/publish.yml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.gitignore +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/.python-version +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/CLIENTS_USAGE.md +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/Dockerfile +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/LICENSE +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/README.md +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/1sales_context.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/2product_info.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/3objection_handling.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/final_instructions.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/help_message.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/welcome_message.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/tests/quick_scenarios.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/tests/realistic_scenarios.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/tests/scenario_examples.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/welcome_files/welcome_file_msg.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/welcome_files//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/2product_info.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/3objection_handling.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/final_instructions.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/help_message.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/welcome_message.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/tests/quick_scenarios.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/tests/realistic_scenarios.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/tests/scenario_examples.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/welcome_files/welcome_file_msg.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/welcome_files//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/configs/valera/cats//320/224/320/276/320/263/320/276/320/262/320/276/321/200.pdf" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/configs/valera/cats//320/272/320/276/320/275/320/270.jpg" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/configs/valera/cats//320/272/320/276/321/202.jpg" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/configs/valera/cats//320/273/320/265/321/201.jpg" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/configs/valera/tests/fixes_elina.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/configs/valera/welcome_file//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/create_tag.sh +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/docker-compose.yml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/env.example +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/requirements.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/save_backup.sh +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/save_fixes.sh +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/admin_logic.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/admin_manager.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/admin_migration.sql +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/admin_tester.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/timeout_checker.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/analytics/analytics_manager.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/cli.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/config.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/prompts/1sales_context.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/prompts/2product_info.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/prompts/3objection_handling.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/prompts/final_instructions.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/prompts/help_message.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/prompts/welcome_message.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064229.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064335.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064638.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/tests/quick_scenarios.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/tests/realistic_scenarios.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/tests/scenario_examples.yaml +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/welcome_file/welcome_file_msg.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/configs/growthmed-october-24/welcome_file//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/bot_utils.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/conversation_manager.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/decorators.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/message_sender.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/router.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/router_manager.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/states.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/telegram_router.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/creation/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/creation/bot_testing.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/event/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/handlers/handlers.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/integrations/openai_client.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/integrations/supabase_client.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/message/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/router/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/setup_checker.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/supabase/__init__.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/supabase/client.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/table/database_structure.sql +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/table/schema.sql +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/utils/debug_routing.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/utils/prompt_loader.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/utm_link_generator.py +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/system_prompt_example.txt +0 -0
- {smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/valera.py +0 -0
|
@@ -1,248 +1,248 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import logging
|
|
3
|
-
|
|
4
|
-
from smart_bot_factory.router import EventRouter, TelegramRouter
|
|
5
|
-
from smart_bot_factory.message import send_message_by_human, send_message_to_users_by_stage, send_message
|
|
6
|
-
from smart_bot_factory.supabase import SupabaseClient
|
|
7
|
-
from smart_bot_factory.creation import BotBuilder
|
|
8
|
-
|
|
9
|
-
logger = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
# =============================================================================
|
|
12
|
-
# СОЗДАНИЕ РОУТЕРОВ
|
|
13
|
-
# =============================================================================
|
|
14
|
-
|
|
15
|
-
# Роутер для событий (бизнес-логика)
|
|
16
|
-
event_router = EventRouter("best-valera_events")
|
|
17
|
-
|
|
18
|
-
# Роутер для Telegram (команды и сообщения)
|
|
19
|
-
telegram_router_1 = TelegramRouter("best-valera_telegram")
|
|
20
|
-
telegram_router_2 = TelegramRouter("best-valera_telegram_2")
|
|
21
|
-
|
|
22
|
-
supabase_client = SupabaseClient("best-valera")
|
|
23
|
-
|
|
24
|
-
# =============================================================================
|
|
25
|
-
# ИНИЦИАЛИЗАЦИЯ BOT BUILDER (нужен для декоратора on_start)
|
|
26
|
-
# =============================================================================
|
|
27
|
-
|
|
28
|
-
bot_builder = BotBuilder("best-valera")
|
|
29
|
-
|
|
30
|
-
# =============================================================================
|
|
31
|
-
# TELEGRAM ОБРАБОТЧИКИ (используем прямой aiogram API)
|
|
32
|
-
# =============================================================================
|
|
33
|
-
|
|
34
|
-
from aiogram import F
|
|
35
|
-
from aiogram.filters import Command
|
|
36
|
-
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
|
37
|
-
from aiogram.fsm.context import FSMContext
|
|
38
|
-
|
|
39
|
-
# =============================================================================
|
|
40
|
-
# ОБРАБОТЧИК on_start (вызывается после стандартного /start)
|
|
41
|
-
# =============================================================================
|
|
42
|
-
|
|
43
|
-
@bot_builder.on_start
|
|
44
|
-
async def custom_start_handler(user_id: int, session_id: str, message: Message, state: FSMContext):
|
|
45
|
-
"""
|
|
46
|
-
Вызывается после стандартной логики /start
|
|
47
|
-
Здесь можно отправить дополнительные сообщения, кнопки и т.д.
|
|
48
|
-
"""
|
|
49
|
-
# Пример: отправляем сообщение с кнопками
|
|
50
|
-
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
|
51
|
-
[InlineKeyboardButton(text="📖 Каталог", callback_data="catalog")],
|
|
52
|
-
[InlineKeyboardButton(text="💰 Цены", callback_data="prices")],
|
|
53
|
-
[InlineKeyboardButton(text="📞 Связаться", callback_data="contact")]
|
|
54
|
-
])
|
|
55
|
-
|
|
56
|
-
await message.answer(
|
|
57
|
-
"🎯 Что вас интересует?",
|
|
58
|
-
reply_markup=keyboard
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
# =============================================================================
|
|
62
|
-
# ХУКИ ДЛЯ КАСТОМИЗАЦИИ ОБРАБОТКИ СООБЩЕНИЙ
|
|
63
|
-
# =============================================================================
|
|
64
|
-
|
|
65
|
-
# ХУК 1: Валидация сообщений
|
|
66
|
-
@bot_builder.validate_message
|
|
67
|
-
async def validate_service_names(message, supabase_client):
|
|
68
|
-
"""Проверяем корректность названий услуг"""
|
|
69
|
-
# Пример: блокируем неправильные названия
|
|
70
|
-
incorrect_names = ["массаш", "педекюр", "макияш"]
|
|
71
|
-
|
|
72
|
-
if message.text:
|
|
73
|
-
for incorrect in incorrect_names:
|
|
74
|
-
if incorrect in message.text.lower():
|
|
75
|
-
await message.answer(
|
|
76
|
-
f"❗ Возможно, вы имели в виду другую услугу?\n"
|
|
77
|
-
f"Пожалуйста, уточните название"
|
|
78
|
-
)
|
|
79
|
-
return False # Прерываем обработку AI
|
|
80
|
-
|
|
81
|
-
return True # Продолжаем обработку
|
|
82
|
-
|
|
83
|
-
# ХУК 2: Обогащение промпта
|
|
84
|
-
@bot_builder.enrich_prompt
|
|
85
|
-
async def add_client_info_to_prompt(system_prompt, user_id, session_id, supabase_client):
|
|
86
|
-
"""Добавляем информацию о клиенте в промпт"""
|
|
87
|
-
try:
|
|
88
|
-
session = await supabase_client.get_active_session(user_id)
|
|
89
|
-
|
|
90
|
-
if session and session.get('metadata'):
|
|
91
|
-
phone = session['metadata'].get('phone')
|
|
92
|
-
name = session['metadata'].get('confirmed_name') or session['metadata'].get('telegram_name')
|
|
93
|
-
|
|
94
|
-
if phone:
|
|
95
|
-
client_info = f"\n\nИНФОРМАЦИЯ О КЛИЕНТЕ:\n- Телефон: {phone}"
|
|
96
|
-
if name:
|
|
97
|
-
client_info += f"\n- Имя: {name}"
|
|
98
|
-
client_info += "\n\n⚠️ ВАЖНО: При создании записи используй ЭТОТ телефон и имя!"
|
|
99
|
-
|
|
100
|
-
return system_prompt + client_info
|
|
101
|
-
except Exception as e:
|
|
102
|
-
logger.error(f"Ошибка обогащения промпта: {e}")
|
|
103
|
-
|
|
104
|
-
return system_prompt
|
|
105
|
-
|
|
106
|
-
# ХУК 3: Обогащение контекста (например, данные из внешнего API)
|
|
107
|
-
@bot_builder.enrich_context
|
|
108
|
-
async def add_external_api_data(messages, user_id, session_id):
|
|
109
|
-
"""Добавляем данные из внешних систем"""
|
|
110
|
-
# Пример: можно добавить расписание из YClients, данные из CRM и т.д.
|
|
111
|
-
# messages.append({
|
|
112
|
-
# "role": "system",
|
|
113
|
-
# "content": "Реальное доступное время: ..."
|
|
114
|
-
# })
|
|
115
|
-
return messages
|
|
116
|
-
|
|
117
|
-
# ХУК 4: Обработка ответа AI
|
|
118
|
-
@bot_builder.process_response
|
|
119
|
-
async def add_promo_to_price_response(response_text, ai_metadata, user_id):
|
|
120
|
-
"""Добавляем промо-код к ответам о ценах"""
|
|
121
|
-
if "цен" in response_text.lower() or "стоимост" in response_text.lower():
|
|
122
|
-
response_text += "\n\n🎁 Промокод FIRST10 для скидки 10% на первый визит!"
|
|
123
|
-
|
|
124
|
-
return response_text, ai_metadata
|
|
125
|
-
|
|
126
|
-
# ХУК 5: Фильтр отправки
|
|
127
|
-
@bot_builder.filter_send
|
|
128
|
-
async def allow_all_messages(user_id, response_text):
|
|
129
|
-
"""Разрешаем все сообщения (можно добавить блокировку по условию)"""
|
|
130
|
-
# Пример: блокировка во время обработки
|
|
131
|
-
# if is_processing(user_id):
|
|
132
|
-
# return False
|
|
133
|
-
return True
|
|
134
|
-
|
|
135
|
-
@telegram_router_1.router.message(Command("price", "цена"))
|
|
136
|
-
async def handle_price_command(message: Message, state: FSMContext):
|
|
137
|
-
"""Обработчик команды /price"""
|
|
138
|
-
await message.answer(
|
|
139
|
-
"💰 Наши цены:\n\n"
|
|
140
|
-
"📦 Базовый пакет - 1000₽\n"
|
|
141
|
-
"📦 Стандартный - 2000₽\n"
|
|
142
|
-
"📦 Премиум - 5000₽"
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
@telegram_router_2.router.message(F.text & (F.text.lower().contains("цена") | F.text.lower().contains("стоимость")))
|
|
146
|
-
async def handle_price_question(message: Message, state: FSMContext):
|
|
147
|
-
"""Обработчик вопросов о цене"""
|
|
148
|
-
await message.answer("💡 Напишите /price чтобы увидеть актуальные цены")
|
|
149
|
-
|
|
150
|
-
# Обработчики callback'ов от кнопок в on_start
|
|
151
|
-
@telegram_router_1.router.callback_query(F.data == "catalog")
|
|
152
|
-
async def handle_catalog(callback: CallbackQuery, state: FSMContext):
|
|
153
|
-
"""Обработка кнопки Каталог"""
|
|
154
|
-
await callback.answer()
|
|
155
|
-
|
|
156
|
-
# Пример: используем send_message с файлами
|
|
157
|
-
await send_message(
|
|
158
|
-
message=callback.message,
|
|
159
|
-
text="📖 Вот наш каталог товаров:\n\n1. Товар 1\n2. Товар 2\n3. Товар 3",
|
|
160
|
-
supabase_client=supabase_client,
|
|
161
|
-
files_list=[], # Можно добавить файлы: ["catalog.pdf"]
|
|
162
|
-
parse_mode="Markdown"
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
@telegram_router_1.router.callback_query(F.data == "prices")
|
|
166
|
-
async def handle_prices(callback: CallbackQuery, state: FSMContext):
|
|
167
|
-
"""Обработка кнопки Цены"""
|
|
168
|
-
await callback.answer()
|
|
169
|
-
await callback.message.answer("💰 Наши цены:\n\n📦 Базовый - 1000₽\n📦 Премиум - 5000₽")
|
|
170
|
-
|
|
171
|
-
@telegram_router_1.router.callback_query(F.data == "contact")
|
|
172
|
-
async def handle_contact(callback: CallbackQuery, state: FSMContext):
|
|
173
|
-
"""Обработка кнопки Связаться"""
|
|
174
|
-
await callback.answer()
|
|
175
|
-
await callback.message.answer("📞 Свяжитесь с нами:\n\nТелефон: +7 (999) 123-45-67\nEmail: info@example.com")
|
|
176
|
-
|
|
177
|
-
# =============================================================================
|
|
178
|
-
# ОБРАБОТЧИКИ СОБЫТИЙ (бизнес-логика)
|
|
179
|
-
# =============================================================================
|
|
180
|
-
|
|
181
|
-
@event_router.event_handler("example_event")
|
|
182
|
-
async def handle_example_event(user_id: int, event_data: str):
|
|
183
|
-
"""Пример обработчика события"""
|
|
184
|
-
await send_message_by_human(
|
|
185
|
-
user_id=user_id,
|
|
186
|
-
message_text=f"✅ Событие обработано! Данные: {event_data}"
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
return {
|
|
190
|
-
"status": "success",
|
|
191
|
-
"message": "Событие обработано"
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
# =============================================================================
|
|
195
|
-
# ВРЕМЕННЫЕ ЗАДАЧИ ДЛЯ ОДНОГО ПОЛЬЗОВАТЕЛЯ
|
|
196
|
-
# =============================================================================
|
|
197
|
-
|
|
198
|
-
@event_router.schedule_task("send_reminder", delay="1h")
|
|
199
|
-
async def send_user_reminder(user_id: int, reminder_text: str):
|
|
200
|
-
"""Отправляет напоминание пользователю"""
|
|
201
|
-
await send_message_by_human(
|
|
202
|
-
user_id=user_id,
|
|
203
|
-
message_text=f"🔔 Напоминание: {reminder_text}"
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
"status": "reminder_sent",
|
|
208
|
-
"message": f"Напоминание отправлено пользователю {user_id}"
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
# =============================================================================
|
|
212
|
-
# ГЛОБАЛЬНЫЕ ОБРАБОТЧИКИ (для всех пользователей)
|
|
213
|
-
# =============================================================================
|
|
214
|
-
|
|
215
|
-
@event_router.global_handler("mass_notification", delay="1h", notify=True)
|
|
216
|
-
async def send_global_announcement(announcement_text: str):
|
|
217
|
-
"""Отправляет анонс всем пользователям бота"""
|
|
218
|
-
|
|
219
|
-
await send_message_to_users_by_stage(
|
|
220
|
-
stage="introduction",
|
|
221
|
-
message_text=announcement_text,
|
|
222
|
-
bot_id="best-valera"
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
# =============================================================================
|
|
226
|
-
# ОСНОВНАЯ ФУНКЦИЯ
|
|
227
|
-
# =============================================================================
|
|
228
|
-
|
|
229
|
-
async def main():
|
|
230
|
-
"""Основная функция запуска бота"""
|
|
231
|
-
try:
|
|
232
|
-
# bot_builder уже создан выше (для декоратора @bot_builder.on_start)
|
|
233
|
-
|
|
234
|
-
# Регистрируем роутеры ПЕРЕД сборкой (можно по одному или несколько сразу)
|
|
235
|
-
bot_builder.register_routers(event_router) # Роутеры событий
|
|
236
|
-
bot_builder.register_telegram_routers(telegram_router_1, telegram_router_2) # Telegram роутеры
|
|
237
|
-
|
|
238
|
-
await bot_builder.build()
|
|
239
|
-
|
|
240
|
-
# Запускаем бота
|
|
241
|
-
await bot_builder.start()
|
|
242
|
-
|
|
243
|
-
except Exception as e:
|
|
244
|
-
print(f"❌ Ошибка запуска бота: {e}")
|
|
245
|
-
raise
|
|
246
|
-
|
|
247
|
-
if __name__ == "__main__":
|
|
248
|
-
asyncio.run(main())
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from smart_bot_factory.router import EventRouter, TelegramRouter
|
|
5
|
+
from smart_bot_factory.message import send_message_by_human, send_message_to_users_by_stage, send_message
|
|
6
|
+
from smart_bot_factory.supabase import SupabaseClient
|
|
7
|
+
from smart_bot_factory.creation import BotBuilder
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# СОЗДАНИЕ РОУТЕРОВ
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
# Роутер для событий (бизнес-логика)
|
|
16
|
+
event_router = EventRouter("best-valera_events")
|
|
17
|
+
|
|
18
|
+
# Роутер для Telegram (команды и сообщения)
|
|
19
|
+
telegram_router_1 = TelegramRouter("best-valera_telegram")
|
|
20
|
+
telegram_router_2 = TelegramRouter("best-valera_telegram_2")
|
|
21
|
+
|
|
22
|
+
supabase_client = SupabaseClient("best-valera")
|
|
23
|
+
|
|
24
|
+
# =============================================================================
|
|
25
|
+
# ИНИЦИАЛИЗАЦИЯ BOT BUILDER (нужен для декоратора on_start)
|
|
26
|
+
# =============================================================================
|
|
27
|
+
|
|
28
|
+
bot_builder = BotBuilder("best-valera")
|
|
29
|
+
|
|
30
|
+
# =============================================================================
|
|
31
|
+
# TELEGRAM ОБРАБОТЧИКИ (используем прямой aiogram API)
|
|
32
|
+
# =============================================================================
|
|
33
|
+
|
|
34
|
+
from aiogram import F
|
|
35
|
+
from aiogram.filters import Command
|
|
36
|
+
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
|
37
|
+
from aiogram.fsm.context import FSMContext
|
|
38
|
+
|
|
39
|
+
# =============================================================================
|
|
40
|
+
# ОБРАБОТЧИК on_start (вызывается после стандартного /start)
|
|
41
|
+
# =============================================================================
|
|
42
|
+
|
|
43
|
+
@bot_builder.on_start
|
|
44
|
+
async def custom_start_handler(user_id: int, session_id: str, message: Message, state: FSMContext):
|
|
45
|
+
"""
|
|
46
|
+
Вызывается после стандартной логики /start
|
|
47
|
+
Здесь можно отправить дополнительные сообщения, кнопки и т.д.
|
|
48
|
+
"""
|
|
49
|
+
# Пример: отправляем сообщение с кнопками
|
|
50
|
+
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
|
51
|
+
[InlineKeyboardButton(text="📖 Каталог", callback_data="catalog")],
|
|
52
|
+
[InlineKeyboardButton(text="💰 Цены", callback_data="prices")],
|
|
53
|
+
[InlineKeyboardButton(text="📞 Связаться", callback_data="contact")]
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
await message.answer(
|
|
57
|
+
"🎯 Что вас интересует?",
|
|
58
|
+
reply_markup=keyboard
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# =============================================================================
|
|
62
|
+
# ХУКИ ДЛЯ КАСТОМИЗАЦИИ ОБРАБОТКИ СООБЩЕНИЙ
|
|
63
|
+
# =============================================================================
|
|
64
|
+
|
|
65
|
+
# ХУК 1: Валидация сообщений
|
|
66
|
+
@bot_builder.validate_message
|
|
67
|
+
async def validate_service_names(message, supabase_client):
|
|
68
|
+
"""Проверяем корректность названий услуг"""
|
|
69
|
+
# Пример: блокируем неправильные названия
|
|
70
|
+
incorrect_names = ["массаш", "педекюр", "макияш"]
|
|
71
|
+
|
|
72
|
+
if message.text:
|
|
73
|
+
for incorrect in incorrect_names:
|
|
74
|
+
if incorrect in message.text.lower():
|
|
75
|
+
await message.answer(
|
|
76
|
+
f"❗ Возможно, вы имели в виду другую услугу?\n"
|
|
77
|
+
f"Пожалуйста, уточните название"
|
|
78
|
+
)
|
|
79
|
+
return False # Прерываем обработку AI
|
|
80
|
+
|
|
81
|
+
return True # Продолжаем обработку
|
|
82
|
+
|
|
83
|
+
# ХУК 2: Обогащение промпта
|
|
84
|
+
@bot_builder.enrich_prompt
|
|
85
|
+
async def add_client_info_to_prompt(system_prompt, user_id, session_id, supabase_client):
|
|
86
|
+
"""Добавляем информацию о клиенте в промпт"""
|
|
87
|
+
try:
|
|
88
|
+
session = await supabase_client.get_active_session(user_id)
|
|
89
|
+
|
|
90
|
+
if session and session.get('metadata'):
|
|
91
|
+
phone = session['metadata'].get('phone')
|
|
92
|
+
name = session['metadata'].get('confirmed_name') or session['metadata'].get('telegram_name')
|
|
93
|
+
|
|
94
|
+
if phone:
|
|
95
|
+
client_info = f"\n\nИНФОРМАЦИЯ О КЛИЕНТЕ:\n- Телефон: {phone}"
|
|
96
|
+
if name:
|
|
97
|
+
client_info += f"\n- Имя: {name}"
|
|
98
|
+
client_info += "\n\n⚠️ ВАЖНО: При создании записи используй ЭТОТ телефон и имя!"
|
|
99
|
+
|
|
100
|
+
return system_prompt + client_info
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.error(f"Ошибка обогащения промпта: {e}")
|
|
103
|
+
|
|
104
|
+
return system_prompt
|
|
105
|
+
|
|
106
|
+
# ХУК 3: Обогащение контекста (например, данные из внешнего API)
|
|
107
|
+
@bot_builder.enrich_context
|
|
108
|
+
async def add_external_api_data(messages, user_id, session_id):
|
|
109
|
+
"""Добавляем данные из внешних систем"""
|
|
110
|
+
# Пример: можно добавить расписание из YClients, данные из CRM и т.д.
|
|
111
|
+
# messages.append({
|
|
112
|
+
# "role": "system",
|
|
113
|
+
# "content": "Реальное доступное время: ..."
|
|
114
|
+
# })
|
|
115
|
+
return messages
|
|
116
|
+
|
|
117
|
+
# ХУК 4: Обработка ответа AI
|
|
118
|
+
@bot_builder.process_response
|
|
119
|
+
async def add_promo_to_price_response(response_text, ai_metadata, user_id):
|
|
120
|
+
"""Добавляем промо-код к ответам о ценах"""
|
|
121
|
+
if "цен" in response_text.lower() or "стоимост" in response_text.lower():
|
|
122
|
+
response_text += "\n\n🎁 Промокод FIRST10 для скидки 10% на первый визит!"
|
|
123
|
+
|
|
124
|
+
return response_text, ai_metadata
|
|
125
|
+
|
|
126
|
+
# ХУК 5: Фильтр отправки
|
|
127
|
+
@bot_builder.filter_send
|
|
128
|
+
async def allow_all_messages(user_id, response_text):
|
|
129
|
+
"""Разрешаем все сообщения (можно добавить блокировку по условию)"""
|
|
130
|
+
# Пример: блокировка во время обработки
|
|
131
|
+
# if is_processing(user_id):
|
|
132
|
+
# return False
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
@telegram_router_1.router.message(Command("price", "цена"))
|
|
136
|
+
async def handle_price_command(message: Message, state: FSMContext):
|
|
137
|
+
"""Обработчик команды /price"""
|
|
138
|
+
await message.answer(
|
|
139
|
+
"💰 Наши цены:\n\n"
|
|
140
|
+
"📦 Базовый пакет - 1000₽\n"
|
|
141
|
+
"📦 Стандартный - 2000₽\n"
|
|
142
|
+
"📦 Премиум - 5000₽"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
@telegram_router_2.router.message(F.text & (F.text.lower().contains("цена") | F.text.lower().contains("стоимость")))
|
|
146
|
+
async def handle_price_question(message: Message, state: FSMContext):
|
|
147
|
+
"""Обработчик вопросов о цене"""
|
|
148
|
+
await message.answer("💡 Напишите /price чтобы увидеть актуальные цены")
|
|
149
|
+
|
|
150
|
+
# Обработчики callback'ов от кнопок в on_start
|
|
151
|
+
@telegram_router_1.router.callback_query(F.data == "catalog")
|
|
152
|
+
async def handle_catalog(callback: CallbackQuery, state: FSMContext):
|
|
153
|
+
"""Обработка кнопки Каталог"""
|
|
154
|
+
await callback.answer()
|
|
155
|
+
|
|
156
|
+
# Пример: используем send_message с файлами
|
|
157
|
+
await send_message(
|
|
158
|
+
message=callback.message,
|
|
159
|
+
text="📖 Вот наш каталог товаров:\n\n1. Товар 1\n2. Товар 2\n3. Товар 3",
|
|
160
|
+
supabase_client=supabase_client,
|
|
161
|
+
files_list=[], # Можно добавить файлы: ["catalog.pdf"]
|
|
162
|
+
parse_mode="Markdown"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
@telegram_router_1.router.callback_query(F.data == "prices")
|
|
166
|
+
async def handle_prices(callback: CallbackQuery, state: FSMContext):
|
|
167
|
+
"""Обработка кнопки Цены"""
|
|
168
|
+
await callback.answer()
|
|
169
|
+
await callback.message.answer("💰 Наши цены:\n\n📦 Базовый - 1000₽\n📦 Премиум - 5000₽")
|
|
170
|
+
|
|
171
|
+
@telegram_router_1.router.callback_query(F.data == "contact")
|
|
172
|
+
async def handle_contact(callback: CallbackQuery, state: FSMContext):
|
|
173
|
+
"""Обработка кнопки Связаться"""
|
|
174
|
+
await callback.answer()
|
|
175
|
+
await callback.message.answer("📞 Свяжитесь с нами:\n\nТелефон: +7 (999) 123-45-67\nEmail: info@example.com")
|
|
176
|
+
|
|
177
|
+
# =============================================================================
|
|
178
|
+
# ОБРАБОТЧИКИ СОБЫТИЙ (бизнес-логика)
|
|
179
|
+
# =============================================================================
|
|
180
|
+
|
|
181
|
+
@event_router.event_handler("example_event")
|
|
182
|
+
async def handle_example_event(user_id: int, event_data: str):
|
|
183
|
+
"""Пример обработчика события"""
|
|
184
|
+
await send_message_by_human(
|
|
185
|
+
user_id=user_id,
|
|
186
|
+
message_text=f"✅ Событие обработано! Данные: {event_data}"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
"status": "success",
|
|
191
|
+
"message": "Событие обработано"
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# =============================================================================
|
|
195
|
+
# ВРЕМЕННЫЕ ЗАДАЧИ ДЛЯ ОДНОГО ПОЛЬЗОВАТЕЛЯ
|
|
196
|
+
# =============================================================================
|
|
197
|
+
|
|
198
|
+
@event_router.schedule_task("send_reminder", delay="1h")
|
|
199
|
+
async def send_user_reminder(user_id: int, reminder_text: str):
|
|
200
|
+
"""Отправляет напоминание пользователю"""
|
|
201
|
+
await send_message_by_human(
|
|
202
|
+
user_id=user_id,
|
|
203
|
+
message_text=f"🔔 Напоминание: {reminder_text}"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
"status": "reminder_sent",
|
|
208
|
+
"message": f"Напоминание отправлено пользователю {user_id}"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
# =============================================================================
|
|
212
|
+
# ГЛОБАЛЬНЫЕ ОБРАБОТЧИКИ (для всех пользователей)
|
|
213
|
+
# =============================================================================
|
|
214
|
+
|
|
215
|
+
@event_router.global_handler("mass_notification", delay="1h", notify=True)
|
|
216
|
+
async def send_global_announcement(announcement_text: str):
|
|
217
|
+
"""Отправляет анонс всем пользователям бота"""
|
|
218
|
+
|
|
219
|
+
await send_message_to_users_by_stage(
|
|
220
|
+
stage="introduction",
|
|
221
|
+
message_text=announcement_text,
|
|
222
|
+
bot_id="best-valera"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# =============================================================================
|
|
226
|
+
# ОСНОВНАЯ ФУНКЦИЯ
|
|
227
|
+
# =============================================================================
|
|
228
|
+
|
|
229
|
+
async def main():
|
|
230
|
+
"""Основная функция запуска бота"""
|
|
231
|
+
try:
|
|
232
|
+
# bot_builder уже создан выше (для декоратора @bot_builder.on_start)
|
|
233
|
+
|
|
234
|
+
# Регистрируем роутеры ПЕРЕД сборкой (можно по одному или несколько сразу)
|
|
235
|
+
bot_builder.register_routers(event_router) # Роутеры событий
|
|
236
|
+
bot_builder.register_telegram_routers(telegram_router_1, telegram_router_2) # Telegram роутеры
|
|
237
|
+
|
|
238
|
+
await bot_builder.build()
|
|
239
|
+
|
|
240
|
+
# Запускаем бота
|
|
241
|
+
await bot_builder.start()
|
|
242
|
+
|
|
243
|
+
except Exception as e:
|
|
244
|
+
print(f"❌ Ошибка запуска бота: {e}")
|
|
245
|
+
raise
|
|
246
|
+
|
|
247
|
+
if __name__ == "__main__":
|
|
248
|
+
asyncio.run(main())
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/creation/bot_builder.py
RENAMED
|
@@ -55,6 +55,9 @@ class BotBuilder:
|
|
|
55
55
|
self._response_processors: List = [] # Обработка ответа AI
|
|
56
56
|
self._send_filters: List = [] # Фильтры перед отправкой пользователю
|
|
57
57
|
|
|
58
|
+
# Кастомный PromptLoader
|
|
59
|
+
self._custom_prompt_loader = None
|
|
60
|
+
|
|
58
61
|
# Флаги инициализации
|
|
59
62
|
self._initialized = False
|
|
60
63
|
|
|
@@ -175,10 +178,16 @@ class BotBuilder:
|
|
|
175
178
|
else:
|
|
176
179
|
logger.info(f"✅ Router Manager уже был создан ранее")
|
|
177
180
|
|
|
178
|
-
# Prompt Loader
|
|
179
|
-
self.
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
# Prompt Loader (используем кастомный если установлен)
|
|
182
|
+
if self._custom_prompt_loader:
|
|
183
|
+
self.prompt_loader = self._custom_prompt_loader
|
|
184
|
+
logger.info(f"✅ Используется кастомный Prompt Loader: {type(self.prompt_loader).__name__}")
|
|
185
|
+
else:
|
|
186
|
+
self.prompt_loader = PromptLoader(
|
|
187
|
+
prompts_dir=self.config.PROMT_FILES_DIR
|
|
188
|
+
)
|
|
189
|
+
logger.info(f"✅ Используется стандартный Prompt Loader")
|
|
190
|
+
|
|
182
191
|
await self.prompt_loader.validate_prompts()
|
|
183
192
|
logger.info(f"✅ Prompt Loader инициализирован")
|
|
184
193
|
|
|
@@ -365,6 +374,34 @@ class BotBuilder:
|
|
|
365
374
|
"""Получает список обработчиков on_start"""
|
|
366
375
|
return self._start_handlers.copy()
|
|
367
376
|
|
|
377
|
+
def set_prompt_loader(self, prompt_loader):
|
|
378
|
+
"""
|
|
379
|
+
Устанавливает кастомный PromptLoader
|
|
380
|
+
|
|
381
|
+
Должен быть вызван ДО build()
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
prompt_loader: Экземпляр PromptLoader или его наследника (например UserPromptLoader)
|
|
385
|
+
|
|
386
|
+
Example:
|
|
387
|
+
from smart_bot_factory.utils import UserPromptLoader
|
|
388
|
+
|
|
389
|
+
# Использовать UserPromptLoader с автопоиском prompts_dir
|
|
390
|
+
custom_loader = UserPromptLoader("my-bot")
|
|
391
|
+
bot_builder.set_prompt_loader(custom_loader)
|
|
392
|
+
|
|
393
|
+
# Или кастомный наследник
|
|
394
|
+
class MyPromptLoader(UserPromptLoader):
|
|
395
|
+
def __init__(self, bot_id):
|
|
396
|
+
super().__init__(bot_id)
|
|
397
|
+
self.extra_file = self.prompts_dir / 'extra.txt'
|
|
398
|
+
|
|
399
|
+
my_loader = MyPromptLoader("my-bot")
|
|
400
|
+
bot_builder.set_prompt_loader(my_loader)
|
|
401
|
+
"""
|
|
402
|
+
self._custom_prompt_loader = prompt_loader
|
|
403
|
+
logger.info(f"✅ Установлен кастомный PromptLoader: {type(prompt_loader).__name__}")
|
|
404
|
+
|
|
368
405
|
# ========== ХУКИ ДЛЯ КАСТОМИЗАЦИИ ОБРАБОТКИ СООБЩЕНИЙ ==========
|
|
369
406
|
|
|
370
407
|
def validate_message(self, handler):
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UserPromptLoader - упрощенный PromptLoader для пользователей библиотеки
|
|
3
|
+
с автоматическим поиском prompts_dir от корня проекта
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from .prompt_loader import PromptLoader
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UserPromptLoader(PromptLoader):
|
|
14
|
+
"""
|
|
15
|
+
PromptLoader для пользователей библиотеки с автоматическим поиском prompts_dir
|
|
16
|
+
|
|
17
|
+
Автоматически находит папку prompts для указанного бота от корня проекта
|
|
18
|
+
Наследуется от базового PromptLoader - все методы доступны
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, bot_id: str, prompts_subdir: str = "prompts"):
|
|
22
|
+
"""
|
|
23
|
+
Инициализация загрузчика промптов с автоматическим поиском
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
bot_id: Идентификатор бота
|
|
27
|
+
prompts_subdir: Подпапка с промптами (по умолчанию "prompts")
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
# Автоматически найдет bots/my-bot/prompts
|
|
31
|
+
loader = UserPromptLoader("my-bot")
|
|
32
|
+
|
|
33
|
+
# Или кастомную подпапку
|
|
34
|
+
loader = UserPromptLoader("my-bot", "custom_prompts")
|
|
35
|
+
|
|
36
|
+
# Наследование для кастомизации
|
|
37
|
+
class MyLoader(UserPromptLoader):
|
|
38
|
+
def __init__(self, bot_id):
|
|
39
|
+
super().__init__(bot_id)
|
|
40
|
+
# Добавить свою логику
|
|
41
|
+
self.extra_file = self.prompts_dir / 'extra.txt'
|
|
42
|
+
"""
|
|
43
|
+
from project_root_finder import root
|
|
44
|
+
|
|
45
|
+
# Автоматически определяем путь к промптам
|
|
46
|
+
prompts_dir = root / "bots" / bot_id / prompts_subdir
|
|
47
|
+
|
|
48
|
+
if not prompts_dir.exists():
|
|
49
|
+
logger.warning(f"⚠️ Папка промптов не найдена: {prompts_dir}")
|
|
50
|
+
logger.warning(f" Создайте папку или проверьте bot_id")
|
|
51
|
+
|
|
52
|
+
# Вызываем базовую инициализацию
|
|
53
|
+
super().__init__(str(prompts_dir))
|
|
54
|
+
|
|
55
|
+
logger.info(f"✅ UserPromptLoader создан для bot_id '{bot_id}': {prompts_dir}")
|
|
56
|
+
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Utils модули smart_bot_factory
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from ..integrations.supabase_client import SupabaseClient
|
|
6
|
-
from ..utils.prompt_loader import PromptLoader
|
|
7
|
-
from ..utils.debug_routing import setup_debug_handlers
|
|
8
|
-
|
|
9
|
-
__all__ = ['SupabaseClient', 'PromptLoader', 'setup_debug_handlers']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/1sales_context.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/2product_info.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/3objection_handling.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/final_instructions.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/help_message.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/prompts/welcome_message.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/tests/quick_scenarios.yaml
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/tests/realistic_scenarios.yaml
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/best-valera/tests/scenario_examples.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/3objection_handling.txt
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/prompts/final_instructions.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/tests/realistic_scenarios.yaml
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/tests/scenario_examples.yaml
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/bots/valera/welcome_files/welcome_file_msg.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/admin_manager.py
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/admin_migration.sql
RENAMED
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/admin/timeout_checker.py
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/analytics/analytics_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/conversation_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/message_sender.py
RENAMED
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/router_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/core/telegram_router.py
RENAMED
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/creation/bot_testing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/integrations/openai_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/table/database_structure.sql
RENAMED
|
File without changes
|
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/utils/debug_routing.py
RENAMED
|
File without changes
|
{smart_bot_factory-0.2.5 → smart_bot_factory-0.2.6}/smart_bot_factory/utils/prompt_loader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|